00001 #include "decode_ip_defrag.h"
00002 #include "../packets/packet.h"
00003 #include "../engine/cache.h"
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <netinet/in.h>
00007 #include <arpa/inet.h>
00008 #include <string.h>
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 extern GlobalVars Globals;
00019
00020 int IPDecoderID;
00021 Cache* FragCache;
00022 pthread_mutex_t FragMutex;
00023 int FragLockID;
00024
00025 struct defrag_item{
00026 int begin;
00027 int end;
00028 int PacketSlot;
00029 IPData* idata;
00030 int more;
00031 char done;
00032 };
00033
00034
00035
00036
00037
00038
00039 unsigned short checksum(unsigned short *b1, unsigned int len1, unsigned short *b2, unsigned int len2)
00040 {
00041 unsigned int sum = 0;
00042
00043 if(b1 != (unsigned short *)NULL)
00044 {
00045 while(len1 > 1)
00046 {
00047 sum += *((unsigned short *)b1 ++);
00048
00049 if(sum & 0x80000000)
00050 {
00051 sum = (sum & 0xffff) + (sum >> 16);
00052 }
00053
00054 len1 -= 2;
00055 }
00056
00057
00058 if(len1)
00059 {
00060 sum += (unsigned short) * (unsigned char*) b1;
00061 }
00062 }
00063
00064 if(b2 != (unsigned short*)NULL)
00065 {
00066 while(len2 > 1)
00067 {
00068 sum += *((unsigned short*)b2 ++);
00069
00070 if(sum & 0x80000000)
00071 {
00072 sum = (sum & 0xffff) + (sum >> 16);
00073 }
00074
00075 len2 -= 2;
00076 }
00077
00078 if(len2)
00079 {
00080 sum += (unsigned short) * (unsigned char*) b2;
00081 }
00082 }
00083
00084 while(sum >> 16)
00085 sum = (sum & 0xffff) + (sum >> 16);
00086
00087 return (unsigned short) ~sum;
00088 }
00089
00090
00091
00092
00093
00094
00095 int RebuildPacket(struct defrag_item* Frags, int NumFrags){
00096 PacketRec* newp;
00097 IPData* idata;
00098 int i;
00099 int flags;
00100 int offset;
00101 int first_header_len;
00102 int offset_to_ip;
00103 int PacketSlot;
00104
00105
00106 PacketSlot=GetEmptyPacket();
00107
00108 newp=&Globals.Packets[PacketSlot];
00109
00110
00111 newp->LargePacket=TRUE;
00112 newp->RawPacket=calloc(MAX_PACKET_SIZE,1);
00113
00114
00115 newp->InterfaceNum=Globals.Packets[Frags[0].PacketSlot].InterfaceNum;
00116 newp->tv=Globals.Packets[Frags[0].PacketSlot].tv;
00117
00118 for (i=0;i<NumFrags;i++){
00119 if (!GetDataByID(Frags[i].PacketSlot, IPDecoderID, (void**)&idata)){
00120 printf("Failed to get IP data in slot %i\n",PacketSlot);
00121 return FALSE;
00122 }
00123
00124 flags=ntohs(idata->Header->frag_off) / 8192;
00125 offset=ntohs(idata->Header->frag_off) & 0x1FFF;
00126
00127 if (offset==0){
00128 offset_to_ip=((int)idata->Header) - ((int)Globals.Packets[Frags[i].PacketSlot].RawPacket);
00129 first_header_len=idata->Header->ihl*4;
00130 newp->PacketLen=Globals.Packets[Frags[i].PacketSlot].PacketLen;
00131 memcpy(newp->RawPacket, Globals.Packets[Frags[i].PacketSlot].RawPacket, newp->PacketLen);
00132 }
00133 }
00134
00135 for (i=0;i<NumFrags;i++){
00136 if (!GetDataByID(Frags[i].PacketSlot, IPDecoderID, (void**)&idata)){
00137 printf("2Failed to get IP data\n");
00138 return FALSE;
00139 }
00140
00141 flags=ntohs(idata->Header->frag_off) / 8192;
00142 offset=ntohs(idata->Header->frag_off) & 0x1FFF;
00143
00144 if (offset!=0){
00145 memcpy(newp->RawPacket+(offset*8)+offset_to_ip+first_header_len,
00146 Globals.Packets[Frags[i].PacketSlot].RawPacket+(idata->Header->ihl*4)+offset_to_ip,
00147 ntohs(idata->Header->tot_len)-(idata->Header->ihl*4));
00148 #ifdef DEBUG
00149 printf("This fragment has %i bytes\n", ntohs(idata->Header->tot_len)-(idata->Header->ihl*4));
00150 #endif
00151 newp->PacketLen+=ntohs(idata->Header->tot_len)-(idata->Header->ihl*4);
00152 }
00153 }
00154
00155 for (i=0;i<NumFrags;i++){
00156 if (!GetDataByID(Frags[i].PacketSlot, IPDecoderID, (void**)&idata)){
00157 printf("3Failed to get IP data\n");
00158 return FALSE;
00159 }
00160
00161 flags=ntohs(idata->Header->frag_off) / 8192;
00162 offset=ntohs(idata->Header->frag_off) & 0x1FFF;
00163
00164 if (offset==0){
00165 ((struct ip_header*)(newp->RawPacket+offset_to_ip))->frag_off=0;
00166 ((struct ip_header*)(newp->RawPacket+offset_to_ip))->tot_len=htons(newp->PacketLen-14);
00167 ((struct ip_header*)(newp->RawPacket+offset_to_ip))->check=0;
00168 ((struct ip_header*)(newp->RawPacket+offset_to_ip))->check=checksum(
00169 (unsigned short*)(newp->RawPacket+offset_to_ip),
00170 ((struct ip_header*)(newp->RawPacket+offset_to_ip))->ihl*4,
00171 NULL,
00172 0
00173 );
00174 }
00175 }
00176
00177 #ifdef DEBUG
00178 for (i=0;i<10;i++){
00179 printf("Slot %i is in state %i\n",i, Globals.Packets[i].Status);
00180 }
00181 #endif
00182
00183 return AddPacketToPending(PacketSlot);
00184 }
00185
00186
00187
00188
00189
00190 int SortFragArray(struct defrag_item* Frags, int NumFrags){
00191 int i;
00192 int next;
00193 int all_done;
00194 int found;
00195 int last;
00196
00197 DEBUGPATH;
00198
00199 next=0;
00200 last=FALSE;
00201 while (1){
00202 all_done=TRUE;
00203 found=FALSE;
00204 for (i=0;i<NumFrags;i++){
00205 if (!Frags[i].done){
00206 if (Frags[i].begin < next){
00207 printf("ERROR! Overlapping Fragements\n");
00208
00209 }
00210 if (Frags[i].begin==next){
00211 Frags[i].done=TRUE;
00212 next=Frags[i].end;
00213 all_done=FALSE;
00214 found=TRUE;
00215 #ifdef DEBUG
00216 printf("More is %i\n",Frags[i].more);
00217 #endif
00218 if (!Frags[i].more) last=TRUE;
00219 }
00220 }
00221 }
00222 if (last) break;
00223 if (all_done) break;
00224 if (!found) return FALSE;
00225 }
00226
00227 if (!last) return FALSE;
00228
00229 #ifdef DEBUG
00230 printf("We have all the parts\n");
00231 #endif
00232
00233 return TRUE;
00234 }
00235
00236
00237
00238
00239 void* DecodeIPDefrag(int PacketSlot){
00240 struct defrag_key{
00241 unsigned short IPID;
00242 unsigned int saddr;
00243 unsigned int daddr;
00244 unsigned char proto;
00245 };
00246
00247 CacheItems* CI;
00248 IPDefragData* data=NULL;
00249 IPData* idata;
00250 int flags;
00251 int offset;
00252 struct defrag_key Key;
00253
00254 PacketRec* ThisPacket;
00255 struct defrag_item Frags[128];
00256 int NumFrags;
00257 int i;
00258
00259 PacketRec* p;
00260
00261 DEBUGPATH;
00262
00263 #ifdef DEBUG
00264 printf("----------------------------\n");
00265 printf("Defragmenting IP\n");
00266 #endif
00267
00268 p=&Globals.Packets[PacketSlot];
00269
00270 if (!GetDataByID(PacketSlot, IPDecoderID, (void**)&idata)){
00271 printf("Failed to get ip header data\n");
00272 return NULL;
00273 }
00274
00275 flags=ntohs(idata->Header->frag_off) / 8192;
00276 offset=ntohs(idata->Header->frag_off) & 0x1FFF;
00277
00278 if ( (offset>0) || (flags & FRAG_FLAG_MORE) ){
00279 #ifdef DEBUG
00280 printf("This is a fragment\n");
00281 #endif
00282 p->PassRawPacket=FALSE;
00283 #ifdef DEBUG
00284 if (offset==0){
00285 printf("This is the first Fragment\n");
00286 }else{
00287 printf("Fragment at offset %i\n",offset * 8);
00288 if (flags & FRAG_FLAG_MORE){
00289 printf("More Fragments\n");
00290 }else{
00291 printf("No More Fragments\n");
00292 }
00293 }
00294 #endif
00295
00296 Key.IPID=ntohs(idata->Header->id);
00297 Key.saddr=idata->Header->saddr;
00298 Key.daddr=idata->Header->daddr;
00299 Key.proto=idata->Header->protocol;
00300
00301 printf("ID is %u\n",ntohs(idata->Header->id));
00302 printf("Proto is %u\n",idata->Header->protocol);
00303
00304
00305 hlbr_mutex_lock(&FragMutex, FRAG_LOCK_1, &FragLockID);
00306 CI=CacheGet(FragCache, (unsigned char*)&Key, sizeof(Key), p->tv.tv_sec);
00307 NumFrags=0;
00308 if (CI){
00309 Frags[0].begin=(ntohs(idata->Header->frag_off) & 0x1FFF)*8;
00310 Frags[0].end=Frags[0].begin+ntohs(idata->Header->tot_len)-(idata->Header->ihl*4);
00311 Frags[0].PacketSlot=PacketSlot;
00312 Frags[0].done=FALSE;
00313 Frags[0].more=ntohs(idata->Header->frag_off) / 8192;
00314
00315 if (Frags[0].more & FRAG_FLAG_MORE){
00316 Frags[0].more=TRUE;
00317 }else{
00318 Frags[0].more=FALSE;
00319 }
00320 NumFrags=1;
00321 #ifdef DEBUG
00322 printf("This frag %i-%i\n",Frags[0].begin, Frags[0].end);
00323 #endif
00324
00325 for (i=0;i<CI->NumItems;i++){
00326 ThisPacket=&Globals.Packets[*(int*)CI->Items[i].Data];
00327 if (!GetDataByID(ThisPacket->PacketSlot, IPDecoderID, (void**)&Frags[NumFrags].idata)){
00328 printf("7Failed to get ip header data for the fragment\n");
00329 break;
00330 }
00331 Frags[NumFrags].begin=(ntohs(Frags[NumFrags].idata->Header->frag_off) & 0x1FFF)*8;
00332 Frags[NumFrags].end=Frags[NumFrags].begin+ntohs(Frags[NumFrags].idata->Header->tot_len)-(Frags[NumFrags].idata->Header->ihl*4);
00333 Frags[NumFrags].PacketSlot=ThisPacket->PacketSlot;
00334 Frags[NumFrags].done=FALSE;
00335 Frags[NumFrags].more=ntohs(Frags[NumFrags].idata->Header->frag_off) / 8192;
00336
00337 if (Frags[NumFrags].more & FRAG_FLAG_MORE){
00338 Frags[NumFrags].more=TRUE;
00339 }else{
00340 Frags[NumFrags].more=FALSE;
00341 }
00342 NumFrags++;
00343 }
00344
00345 if (!SortFragArray(Frags, NumFrags)){
00346
00347
00348 printf("Adding slot %i\n",PacketSlot);
00349 CacheAdd(FragCache, (unsigned char*)&Key, sizeof(struct defrag_key), (unsigned char*)&PacketSlot, sizeof(int), Globals.Packets[PacketSlot].tv.tv_sec);
00350 Globals.Packets[PacketSlot].SaveCount++;
00351 #ifdef DEBUG
00352 printf("Still more packets\n");
00353 #endif
00354 }else{
00355
00356 RebuildPacket(Frags, NumFrags);
00357 for (i=0;i<CI->NumItems;i++){
00358 printf("Returning slot %i\n",*(int*)CI->Items[i].Data);
00359 Globals.Packets[*(int*)CI->Items[i].Data].SaveCount--;
00360 printf("SaveCount is now %i\n",Globals.Packets[*(int*)CI->Items[i].Data].SaveCount);
00361 ReturnEmptyPacket(*(int*)CI->Items[i].Data);
00362 }
00363 CacheDelKey(FragCache, (unsigned char*)&Key, sizeof(struct defrag_key), Globals.Packets[PacketSlot].tv.tv_sec);
00364 #ifdef DEBUG
00365 printf("Packet was rebuilt\n");
00366 #endif
00367 }
00368 }else{
00369 printf("Adding slot %i\n",PacketSlot);
00370 CacheAdd(FragCache, (unsigned char*)&Key, sizeof(struct defrag_key), (unsigned char*)&PacketSlot, sizeof(int), Globals.Packets[PacketSlot].tv.tv_sec);
00371 Globals.Packets[PacketSlot].SaveCount++;
00372 #ifdef DEBUG
00373 printf("First piece\n");
00374 #endif
00375 }
00376 hlbr_mutex_unlock(&FragMutex);
00377 }else{
00378 data=calloc(sizeof(IPDefragData),1);
00379 data->IsRebuilt=FALSE;
00380 }
00381
00382 return data;
00383 }
00384
00385
00386
00387
00388 int InitDecoderIPDefrag(){
00389 int DecoderID;
00390
00391 DEBUGPATH;
00392
00393 if ((DecoderID=CreateDecoder("IPDefrag"))==DECODER_NONE){
00394 #ifdef DEBUG
00395 printf("Couldn't Allocate IP Defrag Decoder\n");
00396 #endif
00397 return FALSE;
00398 }
00399
00400 Globals.Decoders[DecoderID].DecodeFunc=DecodeIPDefrag;
00401 if (!DecoderAddDecoder(GetDecoderByName("IP"), DecoderID)){
00402 printf("Failed to Bind IP Defrag Decoder to IP Decoder\n");
00403 return FALSE;
00404 }
00405
00406 IPDecoderID=GetDecoderByName("IP");
00407
00408 FragCache=InitCache(FRAG_TIMEOUT);
00409
00410 return TRUE;
00411 }