00001 #define DEBUG
00002
00003 #define DEBUG_DIRECTION // Debug the find session direction/state code
00004
00005
00006 #include "session.h"
00007 #include "hlbrlib.h"
00008 #include "main_loop.h"
00009 #include "../decoders/decode_ip.h"
00010 #include "../decoders/decode_tcp.h"
00011 #include "../packets/packet.h"
00012 #include <stdio.h>
00013 #include <string.h>
00014 #include <stdlib.h>
00015 #include <arpa/inet.h>
00016 #include <netinet/in.h>
00017
00018
00019 IPB* Sessions[65536+1];
00020 int TCPDecoderID;
00021 int IPDecoderID;
00022 unsigned int SessionCount = 0;
00023 SFunc* CreateFuncs;
00024 SFunc* DestroyFuncs;
00025 extern GlobalVars Globals;
00026
00027 PP* TimeHead;
00028 PP* TimeTail;
00029
00030 #ifdef DEBUG_DIRECTION
00031 #define DBGDIR(a) a
00032 #else
00033 #define DBGDIR(a)
00034 #endif
00035
00036
00037 int RemountTCPStream(int, PP*, TCPData*);
00038 int TCPStream_Unqueue(PP*);
00039
00040
00041
00042
00043
00044
00045
00046 int AddSessionCreateHandler(void (*Func) (PP* Port, void* Data), void* Data){
00047 SFunc* F;
00048
00049 DEBUGPATH;
00050
00051 if (!CreateFuncs){
00052 CreateFuncs=calloc(sizeof(SFunc),1);
00053 CreateFuncs->Func=Func;
00054 CreateFuncs->Data=Data;
00055
00056 return TRUE;
00057 }
00058
00059 F=CreateFuncs;
00060 while (F->Next) F=F->Next;
00061
00062 F->Next=calloc(sizeof(SFunc),1);
00063 F=F->Next;
00064 F->Func=Func;
00065 F->Data=Data;
00066
00067 return TRUE;
00068 }
00069
00070
00071
00072
00073
00074 int AddSessionDestroyHandler(void (*Func) (PP* Port, void* Data), void* Data){
00075 SFunc* F;
00076
00077 DEBUGPATH;
00078
00079 if (!DestroyFuncs){
00080 DestroyFuncs=calloc(sizeof(SFunc),1);
00081 DestroyFuncs->Func=Func;
00082 DestroyFuncs->Data=Data;
00083
00084 return TRUE;
00085 }
00086
00087 F=DestroyFuncs;
00088 while (F->Next) F=F->Next;
00089
00090 F->Next=calloc(sizeof(SFunc),1);
00091 F=F->Next;
00092 F->Func=Func;
00093 F->Data=Data;
00094
00095 return TRUE;
00096 }
00097
00103 void CallCreateFuncs(PP* Port)
00104 {
00105 SFunc* F;
00106
00107 DEBUGPATH;
00108
00109 F = CreateFuncs;
00110
00111 while (F) {
00112 F->Func(Port, F->Data);
00113 F = F->Next;
00114 }
00115 }
00116
00117
00118
00119
00120 void CallDestroyFuncs(PP* Port){
00121 SFunc* F;
00122
00123 DEBUGPATH;
00124
00125 F=DestroyFuncs;
00126
00127 while (F){
00128 F->Func(Port, F->Data);
00129 F=F->Next;
00130 }
00131 }
00132
00133
00134
00135
00136 unsigned short GetHash(unsigned int ip1, unsigned int ip2){
00137 unsigned short hash;
00138 unsigned short v1;
00139
00140 DEBUGPATH;
00141
00142 hash=ip1/65536;
00143 v1=(ip1 & 0x0000FFFF);
00144 hash ^= v1;
00145 v1=ip2/65536;
00146 hash ^= v1;
00147 v1=(ip2 & 0x0000FFFF);
00148 hash ^= v1;
00149
00150
00151 return hash;
00152 }
00153
00154
00155
00156
00157
00158 IPP* FindIPPair(unsigned int IP1, unsigned int IP2)
00159 {
00160 unsigned short Hash;
00161 IPB* Bin;
00162 IPP* Pair;
00163 int i;
00164 unsigned int Top, Bottom, Middle;
00165
00166 DEBUGPATH;
00167
00168 #ifdef DEBUG
00169 printf("%s-",inet_ntoa(*(struct in_addr*)&IP1));
00170 printf("%s\n",inet_ntoa(*(struct in_addr*)&IP2));
00171 #endif
00172
00173 Hash=GetHash(IP1, IP2);
00174
00175 if (!Sessions[Hash]){
00176 #ifdef DEBUG
00177 printf("First IP Pair in this bin %u\n", Hash);
00178 #endif
00179 Sessions[Hash]=calloc(sizeof(IPB),1);
00180 if (!Sessions[Hash]){
00181 printf("Out of memory\n");
00182 return NULL;
00183 }
00184
00185 Bin=Sessions[Hash];
00186 Bin->NumAllocated=IP_START;
00187 Bin->NumIPs=1;
00188 Bin->Pairs=calloc(sizeof(IPP*),IP_START+1);
00189
00190 Bin->Pairs[0]=calloc(sizeof(IPP),1);
00191 Pair=Bin->Pairs[0];
00192
00193 Pair->IP1=IP1;
00194 Pair->IP2=IP2;
00195 Pair->NumAllocated=0;
00196 Pair->NumPorts=0;
00197 Pair->RefuseFromThisIP = 0;
00198 Pair->Parent=Bin;
00199
00200 return Pair;
00201 }
00202
00203
00204 Bin = Sessions[Hash];
00205
00206 Top = Bin->NumIPs-1;
00207 Bottom = 0;
00208 Middle = Bottom + ((Top-Bottom)/2);
00209
00210 do {
00211 Pair=Bin->Pairs[Middle];
00212
00213 if (!Pair) {
00214 printf("Pair was NULL. Tree corrupt\n");
00215 return NULL;
00216 }
00217
00218 if ((Pair->IP1==IP1) && (Pair->IP2==IP2)) {
00219
00220 return Pair;
00221 }
00222
00223 if ( (IP1<Pair->IP1) || ( (IP1==Pair->IP1) && (IP2<Pair->IP2)) ) {
00224 if (Top == Bottom) break;
00225
00226 Top = Middle;
00227 Middle = Bottom + ((Top-Bottom)/2);
00228 }else{
00229 if (Top == Bottom) break;
00230
00231 Bottom = Middle+1;
00232 Middle = Bottom + ((Top-Bottom)/2);
00233 }
00234 } while (1);
00235
00236
00237 #ifdef DEBUG
00238 printf("Creating new pair\n");
00239 #endif
00240
00241 if (Bin->NumIPs == Bin->NumAllocated) {
00242
00243 Bin->Pairs=realloc(Bin->Pairs, sizeof(IPP*)*(Bin->NumAllocated+IP_GROW+2));
00244 if (!Bin->Pairs){
00245 printf("realloc failed\n");
00246 exit(1);
00247 }
00248
00249
00250 for (i = Bin->NumIPs; i < (Bin->NumAllocated+IP_GROW+1); i++) {
00251 Bin->Pairs[i]=NULL;
00252 }
00253
00254 Bin->NumAllocated+=IP_GROW;
00255 }
00256
00257 if ( (IP1>Pair->IP1) || ( (IP1==Pair->IP1) && (IP2>Pair->IP2)) )
00258 Middle++;
00259
00260 memmove(&Bin->Pairs[Middle+1], &Bin->Pairs[Middle], sizeof(IPP*)*(Bin->NumIPs-Middle));
00261
00262 Bin->Pairs[Middle]=calloc(sizeof(IPP),1);
00263 Pair=Bin->Pairs[Middle];
00264 Bin->NumIPs++;
00265
00266 Pair->IP1=IP1;
00267 Pair->IP2=IP2;
00268 Pair->NumAllocated=0;
00269 Pair->NumPorts=0;
00270 Pair->RefuseFromThisIP = 0;
00271 Pair->Parent=Bin;
00272
00273 return Pair;
00274 }
00275
00283 int AddToTime(PP* Port)
00284 {
00285 DEBUGPATH;
00286
00287 if (!TimeHead) {
00288 TimeHead = Port;
00289 TimeTail = Port;
00290 Port->TimeNext = NULL;
00291 Port->TimePrev = NULL;
00292
00293 return TRUE;
00294 }
00295
00296 if (!TimeTail) {
00297 PRINTERROR("TimeTail was NULL. Time chain is corrupted!\n");
00298 return FALSE;
00299 }
00300
00301 if (TimeTail->TimeNext) {
00302 PRINTERROR("TimeTail->Next was not NULL. Time chain is corrupted!\n");
00303 return FALSE;
00304 }
00305
00306 TimeTail->TimeNext = Port;
00307 Port->TimePrev = TimeTail;
00308 Port->TimeNext = NULL;
00309 TimeTail = Port;
00310
00311 return TRUE;
00312 }
00313
00321 int UpdateTime(PP* Port)
00322 {
00323 DEBUGPATH;
00324
00325 if (TimeTail == Port) {
00326
00327 return TRUE;
00328 }
00329
00330 if (TimeHead == Port) {
00331 if (Port->TimeNext == NULL) {
00332
00333 return TRUE;
00334 }
00335
00336 TimeHead = TimeHead->TimeNext;
00337 TimeHead->TimePrev = NULL;
00338
00339 TimeTail->TimeNext = Port;
00340 Port->TimeNext = NULL;
00341 Port->TimePrev = TimeTail;
00342 TimeTail = Port;
00343
00344 return TRUE;
00345 }
00346
00347 Port->TimePrev->TimeNext = Port->TimeNext;
00348 Port->TimeNext->TimePrev = Port->TimePrev;
00349 Port->TimeNext = NULL;
00350 TimeTail->TimeNext = Port;
00351 Port->TimePrev = TimeTail;
00352 TimeTail = Port;
00353
00354 return TRUE;
00355 }
00356
00357
00361 int RemovePort(PP* Port)
00362 {
00363 IPP* Pair;
00364 IPB* Bin;
00365 int Top, Bottom, Middle;
00366 unsigned short Hash;
00367 char Message[1024];
00368
00369 DEBUGPATH;
00370
00371 DBG( PRINT1("Freeing port with SessionID %u\n", Port->SessionID) );
00372
00373
00374 CallDestroyFuncs(Port);
00375
00376
00377 if (Globals.logSession_StartEnd) {
00378 snprintf(Message, 1024,
00379 "End:%4x %d.%d.%d.%d:%d->%d.%d.%d.%d:%d dir:%d pcount:%d\n",
00380 Port->SessionID, IP_BYTES(Pair->IP1), Port->Port1,
00381 IP_BYTES(Pair->IP2), Port->Port2,
00382 Port->Direction, Port->TCPCount);
00383 LogMessage(Message, &(Globals.logSessionFile));
00384 }
00385
00386
00387 Pair = Port->Parent;
00388 Bin = Pair->Parent;
00389
00390
00391 if ( (Port == TimeHead) && (Port == TimeTail) ) {
00392
00393 if (Port->TimeNext || Port->TimePrev) {
00394 PRINTERROR("Error Time chain is corrupt!\n");
00395 return FALSE;
00396 }
00397
00398 TimeHead = NULL;
00399 TimeTail = NULL;
00400 } else if (Port == TimeHead) {
00401 Port->TimeNext->TimePrev = NULL;
00402 TimeHead = Port->TimeNext;
00403 } else if (Port == TimeTail) {
00404 Port->TimePrev->TimeNext = NULL;
00405 TimeTail = Port->TimePrev;
00406 } else {
00407 Port->TimePrev->TimeNext = Port->TimeNext;
00408 Port->TimeNext->TimePrev = Port->TimePrev;
00409 }
00410 Port->TimeNext = NULL;
00411 Port->TimePrev = NULL;
00412
00413
00414 Top = Pair->NumPorts-1;
00415 Bottom = 0;
00416 Middle = Bottom + ((Top-Bottom)/2);
00417
00418 while (1) {
00419 if (Pair->Ports[Middle] == Port) {
00420 break;
00421 }
00422
00423 if ( (Port->Port1 < Pair->Ports[Middle]->Port1) || ( (Port->Port1 == Pair->Ports[Middle]->Port1) && (Port->Port2 < Pair->Ports[Middle]->Port2)) ){
00424 if (Top == Bottom) {
00425 PRINTERROR("Error: Port not found in parent\n");
00426 return FALSE;
00427 }
00428
00429 Top = Middle;
00430 Middle = Bottom + ((Top-Bottom)/2);
00431 } else {
00432 if (Top == Bottom) {
00433 printf("Error: Port not found in parent\n");
00434 return FALSE;
00435 }
00436
00437 Bottom = Middle + 1;
00438 Middle = Bottom + ((Top-Bottom)/2);
00439 }
00440 }
00441
00442
00443 memmove(&Pair->Ports[Middle], &Pair->Ports[Middle+1], sizeof(PP*)*(Pair->NumPorts - Middle - 1));
00444 Pair->NumPorts--;
00445 Pair->Ports[Pair->NumPorts] = NULL;
00446 FREE(Port->Stream0);
00447 FREE(Port->Stream1);
00448 free(Port);
00449 Port = NULL;
00450
00451
00452 if (Pair->NumPorts > 0) return TRUE;
00453
00454
00455 Top = Bin->NumIPs - 1;
00456 Bottom = 0;
00457 Middle = Bottom + ((Top-Bottom)/2);
00458
00459 while (1) {
00460 if (Bin->Pairs[Middle] == Pair) {
00461 break;
00462 }
00463
00464 if ( (Pair->IP1 < Bin->Pairs[Middle]->IP1) || ( (Pair->IP1 == Bin->Pairs[Middle]->IP1) && (Pair->IP2 < Bin->Pairs[Middle]->IP2)) ) {
00465 if (Top == Bottom) {
00466 PRINTERROR("Error: Pair not found in parent\n");
00467 return FALSE;
00468 }
00469
00470 Top = Middle;
00471 Middle = Bottom + ((Top-Bottom)/2);
00472 } else {
00473 if (Top == Bottom) {
00474 PRINTERROR("Error: Pair not found in parent\n");
00475 return FALSE;
00476 }
00477
00478 Bottom = Middle + 1;
00479 Middle = Bottom + ((Top-Bottom)/2);
00480 }
00481 }
00482
00483
00484 memmove(&Bin->Pairs[Middle], &Bin->Pairs[Middle+1], sizeof(IPP*)*(Bin->NumIPs-Middle-1));
00485 Bin->NumIPs--;
00486 Bin->Pairs[Bin->NumIPs] = NULL;
00487
00488 Hash = GetHash(Pair->IP1, Pair->IP2);
00489
00490 free(Pair->Ports);
00491 Pair->Ports = NULL;
00492 free(Pair);
00493 Pair = NULL;
00494
00495
00496 if (Bin->NumIPs>0) return TRUE;
00497
00498 free(Bin->Pairs);
00499 Bin->Pairs = NULL;
00500 free(Sessions[Hash]);
00501 Sessions[Hash] = NULL;
00502
00503 return TRUE;
00504 }
00505
00506
00510 PP* FindPortPair(unsigned short Port1, unsigned short Port2, IPP* Pair, long int Now)
00511 {
00512 int i;
00513 PP* Port;
00514 int Top, Bottom, Middle;
00515 char Message[1024];
00516
00517 DEBUGPATH;
00518
00519 if (!Pair->Ports) {
00520 DBG( PRINTERROR1("First Port Pair in this bin with sessionID %u\n", SessionCount) );
00521 Pair->Ports = calloc(sizeof(PP*), PORT_START+2);
00522 if (!Pair->Ports) {
00523 printf("Out of memory\n");
00524 return NULL;
00525 }
00526
00527 Pair->NumAllocated = PORT_START;
00528 Pair->NumPorts = 1;
00529 Pair->Ports[0] = calloc(sizeof(PP), 1);
00530
00531 Port = Pair->Ports[0];
00532
00533 Port->Port1 = Port1;
00534 Port->Port2 = Port2;
00535 Port->Parent = Pair;
00536 Port->LastTime = Now;
00537 Port->FirstTime = Now;
00538 if (Port->SessionID) {
00539 printf("SessionID was not 0\n");
00540 }
00541 Port->SessionID = SessionCount;
00542
00543
00544
00545 SessionCount++;
00546 DBG( PRINT1("There are %i sessions\n", SessionCount) );
00547 AddToTime(Port);
00548
00549 if (Globals.logSession_StartEnd || Globals.logSession_All) {
00550 snprintf(Message, 1024,
00551 "Start %4x %d.%d.%d.%d:%d->%d.%d.%d.%d:%d dir:%d pcount:%d\n",
00552 Port->SessionID, IP_BYTES(Pair->IP1), Port->Port1,
00553 IP_BYTES(Pair->IP2), Port->Port2,
00554
00555 Port->Direction, Port->TCPCount);
00556 LogMessage(Message, &(Globals.logSessionFile));
00557 }
00558
00559
00560 CallCreateFuncs(Port);
00561
00562 return Port;
00563 }
00564
00565
00566 Top = Pair->NumPorts-1;
00567 Bottom = 0;
00568 Middle = Bottom + ((Top-Bottom)/2);
00569
00570 do {
00571 if (Middle>Pair->NumAllocated) {
00572 PRINTERROR("Tree is corrupted\n");
00573 exit(1);
00574 }
00575
00576 Port = Pair->Ports[Middle];
00577 if (!Port) {
00578 PRINTERROR1("Error: Pointer was NULL Port %i\n", Middle);
00579 return NULL;
00580 }
00581
00582 if ( (Port->Port1 == Port1) && (Port->Port2 == Port2) ) {
00583
00584 Port->LastTime = Now;
00585 UpdateTime(Port);
00586 return Port;
00587 }
00588
00589 if ( (Port1 < Port->Port1) || ( (Port1 == Port->Port1) && (Port2 < Port->Port2) ) ) {
00590 if (Top == Bottom)
00591 break;
00592
00593 Top = Middle;
00594 Middle = Bottom + ((Top-Bottom)/2);
00595 } else {
00596 if (Top == Bottom)
00597 break;
00598
00599 Bottom = Middle + 1;
00600 Middle = Bottom + ((Top-Bottom)/2);
00601 }
00602 } while(1);
00603
00604 DBG( PRINTERROR1("Creating new port with sessionID %u\n", SessionCount) );
00605
00606 if (Pair->NumPorts == Pair->NumAllocated) {
00607
00608 Pair->Ports = realloc(Pair->Ports, sizeof(PP*)*(Pair->NumAllocated+PORT_GROW+2));
00609 if (!Pair->Ports) {
00610 PRINTERROR("realloc failed\n");
00611 exit(1);
00612 }
00613
00614
00615 for (i = Pair->NumPorts; i < (Pair->NumAllocated+PORT_GROW+1); i++) {
00616 Pair->Ports[i] = NULL;
00617 }
00618
00619 Pair->NumAllocated += PORT_GROW;
00620 }
00621
00622 if ((Port1 > Port->Port1) || ( (Port1 == Port->Port1) && (Port2 > Port->Port2) ) )
00623 Middle++;
00624
00625 memmove(&Pair->Ports[Middle+1], &Pair->Ports[Middle], sizeof(PP*)*(Pair->NumPorts-Middle));
00626
00627 Pair->Ports[Middle] = calloc(sizeof(PP),1);
00628 Port = Pair->Ports[Middle];
00629 Pair->NumPorts++;
00630
00631 Port->Port1 = Port1;
00632 Port->Port2 = Port2;
00633 Port->Parent = Pair;
00634 Port->LastTime = Now;
00635 Port->FirstTime = Now;
00636 if (Port->SessionID) {
00637 PRINTERROR("SessionID was not NULL\n");
00638 }
00639 Port->SessionID = SessionCount;
00640
00641
00642 if (Globals.logSession_StartEnd) {
00643 printf(Message, 1024,
00644 "Start %4x %d.%d.%d.%d:%d->%d.%d.%d.%d:%d dir:%d pcount:%d\n",
00645 Port->SessionID,
00646 #ifdef HLBR_LITTLE_ENDIAN
00647 (Pair->IP1 & 0x000000ff), (Pair->IP1 & 0x0000ff00)>>8, (Pair->IP1 & 0x00ff0000)>>16, Pair->IP1>>24, Port->Port1,
00648 (Pair->IP2 & 0x000000ff), (Pair->IP2 & 0x0000ff00)>>8, (Pair->IP2 & 0x00ff0000)>>16, Pair->IP2>>24, Port->Port2,
00649 #else
00650 Pair->IP1>>24, (Pair->IP1 & 0x00ff0000)>>16, (Pair->IP1 & 0x0000ff00)>>8, (Pair->IP1 & 0x000000ff), Port->Port1,
00651 Pair->IP2>>24, (Pair->IP2 & 0x00ff0000)>>16, (Pair->IP2 & 0x0000ff00)>>8, (Pair->IP2 & 0x000000ff), Port->Port2,
00652 #endif
00653
00654 Port->Direction, Port->TCPCount);
00655 LogMessage(Message, &(Globals.logSessionFile));
00656 }
00657
00658 AddToTime(Port);
00659 SessionCount++;
00660 DBG( PRINT1("There are %i sessions\n", SessionCount) );
00661
00662
00663 CallCreateFuncs(Port);
00664
00665 return Port;
00666 }
00667
00668
00677 int TimeoutSessions(long int Now)
00678 {
00679 PP* TimeNext;
00680
00681 DEBUGPATH;
00682
00683 while (TimeHead && (TimeHead->LastTime + SESSION_FORCE_TIMEOUT < Now)) {
00684 TimeNext = TimeHead->TimeNext;
00685 RemovePort(TimeHead);
00686 TimeHead = TimeNext;
00687 }
00688
00689
00690
00691 while (TimeHead && (TimeHead->LastTime + (SESSION_FORCE_TIMEOUT/10) < Now)) {
00692
00693
00694
00695
00696 TimeNext = TimeHead->TimeNext;
00697 RemovePort(TimeHead);
00698 TimeHead = TimeNext;
00699 }
00700
00701 return TRUE;
00702 }
00703
00704
00713 int AssignSessionTCP(int PacketSlot, void* Data)
00714 {
00715 IPData* IData;
00716 TCPData* TData;
00717 unsigned int IP1,IP2;
00718 unsigned short Port1, Port2;
00719 IPP* Pair;
00720 PP* Port;
00721 struct tcp_stream* Stream;
00722 char reassemble = 0;
00723 char outoforder = 0;
00724
00725 DEBUGPATH;
00726
00727 GetDataByID(PacketSlot, IPDecoderID, (void**)&IData);
00728 if (!IData) {
00729 PRINTPKTERROR(PacketSlot, IData, NULL, FALSE);
00730 PRINTERROR("This was supposed to be a TCP packet\n");
00731 return FALSE;
00732 }
00733
00734 TData = (TCPData*)Data;
00735 if (!TData) {
00736 PRINTPKTERROR(PacketSlot, IData, TData, FALSE);
00737 PRINTERROR("TCP Data was NULL\n");
00738 return FALSE;
00739 }
00740
00741
00742 if (IData->Header->saddr < IData->Header->daddr) {
00743 IP1 = IData->Header->saddr;
00744 IP2 = IData->Header->daddr;
00745 Port1 = ntohs(TData->Header->source);
00746 Port2 = ntohs(TData->Header->dest);
00747 } else {
00748 IP1 = IData->Header->daddr;
00749 IP2 = IData->Header->saddr;
00750 Port1 = ntohs(TData->Header->dest);
00751 Port2 = ntohs(TData->Header->source);
00752 }
00753
00754
00755 Pair = FindIPPair(IP1, IP2);
00756 if (!Pair) {
00757 PRINTPKTERROR(PacketSlot, IData, TData, FALSE);
00758 PRINTERROR4("Failed to assign session pair for %d.%d.%d.%d:%d <-> %d.%d.%d.%d:%d\n",
00759 IP_BYTES(IP1), Port1, IP_BYTES(IP2), Port2);
00760 return FALSE;
00761 }
00762
00763 Port = FindPortPair(Port1, Port2, Pair, Globals.Packets[PacketSlot].tv.tv_sec);
00764 if (!Port) {
00765 PRINTPKTERROR(PacketSlot, IData, TData, FALSE);
00766 PRINTSESERROR(Port, FALSE);
00767 PRINTERROR4("Failed to assign session port for %d.%d.%d.%d:%d <-> %d.%d.%d.%d:%d\n",
00768 IP_BYTES(IP1), Port1, IP_BYTES(IP2), Port2);
00769 return FALSE;
00770 }
00771
00772
00773
00774 if ( (Port->ServerState == TCP_STATE_NEW) && (Port->ClientState == TCP_STATE_NEW) ) {
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 if (TData->Header->syn && !(TData->Header->ack || TData->Header->fin || TData->Header->rst) ) {
00790 DBGDIR( printf("Started with a SYN\n") );
00791
00792 if (IP1 == IData->Header->saddr) {
00793 Port->Direction = SESSION_IP2_SERVER;
00794 } else {
00795 Port->Direction = SESSION_IP1_SERVER;
00796 }
00797
00798 Port->ClientState = TCP_STATE_SYN;
00799 Port->ClientSeq = ntohl(TData->Header->seq);
00800 Port->ClientAck = ntohl(TData->Header->ack_seq);
00801 } else if (TData->Header->syn && TData->Header->ack && !(TData->Header->fin || TData->Header->rst) ) {
00802 DBGDIR( printf("Started with a SYN|ACK\n") );
00803
00804 if (IP1 == IData->Header->saddr) {
00805 Port->Direction = SESSION_IP1_SERVER;
00806 } else {
00807 Port->Direction = SESSION_IP2_SERVER;
00808 }
00809
00810 Port->ServerState = TCP_STATE_SYNACK;
00811 Port->ServerSeq = ntohl(TData->Header->seq);
00812 Port->ServerAck = ntohl(TData->Header->ack_seq);
00813 } else if (TData->Header->rst) {
00814 DBGDIR( printf("Started with a RST\n") );
00815
00816 if (IP1 == IData->Header->saddr){
00817 Port->Direction = SESSION_IP1_SERVER;
00818 }else{
00819 Port->Direction = SESSION_IP2_SERVER;
00820 }
00821
00822 Port->ServerState = TCP_STATE_RESET;
00823 Port->ServerSeq = ntohl(TData->Header->seq);
00824 Port->ServerAck = ntohl(TData->Header->ack_seq);
00825 } else if (TData->Header->fin) {
00826 DBGDIR( printf("Started with a FIN\n") );
00827
00828 if (IP1 == IData->Header->saddr) {
00829 Port->Direction = SESSION_IP2_SERVER;
00830 } else {
00831 Port->Direction = SESSION_IP1_SERVER;
00832 }
00833
00834 Port->ClientState = TCP_STATE_DATA;
00835 Port->ClientSeq = ntohl(TData->Header->seq);
00836 Port->ClientAck = ntohl(TData->Header->ack_seq);
00837 } else {
00838
00839
00840
00841 DBGDIR( PRINT("Startup in the middle of a session\n") );
00842
00843 if (IP1 == IData->Header->saddr) {
00844 Port->Direction = SESSION_IP2_SERVER;
00845 }else{
00846 Port->Direction = SESSION_IP1_SERVER;
00847 }
00848
00849 Port->ClientState = TCP_STATE_DATA;
00850 Port->ServerState = TCP_STATE_DATA;
00851 Port->ClientSeq = ntohl(TData->Header->seq);
00852 Port->ClientAck = ntohl(TData->Header->ack_seq);
00853
00854
00855 Port->noreassemble = 1;
00856 }
00857
00858 } else {
00859
00860
00861
00862
00863 if (
00864 ((Port->Direction == SESSION_IP1_SERVER) && (IData->Header->saddr == IP1)) ||
00865 ((Port->Direction == SESSION_IP2_SERVER) && (IData->Header->saddr == IP2))
00866 ) {
00867
00868 DBGDIR( PRINT("This packet came from the server\n") );
00869
00870 if ( (Port->ClientState == TCP_STATE_FIN) && (Port->ServerState == TCP_STATE_FIN) && !(TData->Header->fin || TData->Header->syn || TData->Header->rst) ) {
00871 DBGDIR( PRINT("Final ACK\n") );
00872
00873 if ( (Port->ClientSeq + 1) != ntohl(TData->Header->ack_seq)) {
00874
00875 }
00876 Port->ClientState = TCP_STATE_LATE;
00877 Port->ServerState = TCP_STATE_LATE;
00878 } else if (TData->Header->syn && TData->Header->ack && !(TData->Header->rst || TData->Header->fin) ) {
00879
00880
00881
00882 if ( (Port->ServerState == TCP_STATE_NEW) && (Port->ClientState == TCP_STATE_SYN)) {
00883 DBGDIR( PRINT("Normal SYN|ACK\n") );
00884
00885 Port->ServerState = TCP_STATE_SYNACK;
00886 Port->ServerSeq = ntohl(TData->Header->seq);
00887 Port->ServerAck = ntohl(TData->Header->ack_seq);
00888
00889 if (Port->ServerAck != (Port->ClientSeq+1) ){
00890 DBG( PRINT("SYN|ACK didn't match\n") );
00891 Port->Error = TRUE;
00892 }
00893 } else if (Port->ServerState == TCP_STATE_SYNACK) {
00894 DBGDIR( PRINT("Resend of the SYN|ACK\n") );
00895 if ( (Port->ServerSeq != ntohl(TData->Header->seq)) || (Port->ServerAck != ntohl(TData->Header->ack_seq)) ) {
00896 DBG( PRINT("Reset SYN|ACK didn't match original\n") );
00897 Port->Error = TRUE;
00898 }
00899 }
00900 } else if (TData->Header->rst) {
00901 DBGDIR( PRINT("Server sent a RESET\n") );
00902
00903 Port->ServerState = TCP_STATE_RESET;
00904 Port->ServerSeq = ntohl(TData->Header->seq);
00905 Port->ServerAck = ntohl(TData->Header->ack_seq);
00906 } else if (TData->Header->fin) {
00907 DBGDIR( printf("Server sent a FIN\n") );
00908
00909 Port->ServerState=TCP_STATE_FIN;
00910 Port->ServerSeq=ntohl(TData->Header->seq);
00911 Port->ServerAck=ntohl(TData->Header->ack_seq);
00912 Port->ServerFin=1;
00913 } else {
00914 if ( (Port->ServerState == TCP_STATE_SYNACK) && (Port->ClientState = TCP_STATE_DATA) ){
00915 DBGDIR( PRINT("First Data packet from server\n") );
00916
00917 Port->ServerState = TCP_STATE_DATA;
00918 Port->ServerSeq = ntohl(TData->Header->seq);
00919 Port->ServerAck = ntohl(TData->Header->ack_seq);
00920 reassemble = 1;
00921 } else if (Port->ServerState == TCP_STATE_DATA) {
00922 DBGDIR( printf("Normal Data from Server\n") );
00923
00924 Port->ServerSeq = ntohl(TData->Header->seq);
00925 Port->ServerAck = ntohl(TData->Header->ack_seq);
00926 } else {
00927 DBGDIR( PRINT("Error: This packet was unexpected (1)\n") );
00928 Port->Error = TRUE;
00929 }
00930 }
00931 } else {
00932
00933 DBGDIR( PRINT("This packet came from the client - ") );
00934 PrintPacketSummary(stdout, PacketSlot, IData, TData, TRUE);
00935
00936 if ( (Port->ClientState == TCP_STATE_FIN) && (Port->ServerState == TCP_STATE_FIN) && !(TData->Header->fin || TData->Header->syn || TData->Header->rst) ) {
00937 DBGDIR( PRINT("Final ACK\n") );
00938
00939 if ( (Port->ServerSeq+1) != ntohl(TData->Header->ack_seq)) {
00940
00941 }
00942 Port->ClientState = TCP_STATE_LATE;
00943 Port->ServerState = TCP_STATE_LATE;
00944 } else if (!(TData->Header->fin || TData->Header->rst) ) {
00945 if ( (Port->ClientState == TCP_STATE_SYN) && (Port->ServerState == TCP_STATE_SYNACK) ){
00946
00947 DBGDIR( PRINT("Normal SYN|ACK ACK\n") );
00948
00949 Port->ClientState = TCP_STATE_DATA;
00950 Port->ClientSeq = ntohl(TData->Header->seq);
00951 Port->ClientAck = ntohl(TData->Header->ack_seq);
00952 if (TData->DataLen > 0) {
00953 DBG( PRINT("syn|ack ack has payload?\n") );
00954 reassemble = 1;
00955 }
00956 } else if (Port->ClientState == TCP_STATE_DATA) {
00957 DBGDIR( PRINT("Normal Client Traffic\n") );
00958
00959 Port->ClientSeq = ntohl(TData->Header->seq);
00960 Port->ClientAck = ntohl(TData->Header->ack_seq);
00961 reassemble = 1;
00962 } else {
00963 DBGDIR( PRINT2("Error: This packet was unexpected (2) SrvState:%d CliState:%d\n", Port->ServerState, Port->ClientState) );
00964 }
00965 } else if (TData->Header->rst) {
00966 DBGDIR( PRINT("Client sent a RST\n") );
00967
00968 Port->ClientState = TCP_STATE_RESET;
00969 }else if (TData->Header->fin) {
00970 DBGDIR( PRINT("Client sent a FIN\n") );
00971
00972 Port->ClientState = TCP_STATE_FIN;
00973 } else {
00974 DBGDIR( PRINT("Error: This packet was unexpected (3)\n") );
00975 }
00976 }
00977 }
00978
00979
00980
00981
00982
00983 Port->TCPCount++;
00984 Globals.Packets[PacketSlot].Stream = Port;
00985
00986
00987
00988
00989
00990
00991
00992
00993 DBG( PRINT2("Reassemble:%d noreassemble:%d\n", reassemble, Port->noreassemble) );
00994 if (reassemble && !(Port->noreassemble)) {
00995 if ((Port->Direction == SESSION_IP1_SERVER && IData->Header->saddr == IP2) ||
00996 (Port->Direction == SESSION_IP2_SERVER && IData->Header->saddr == IP1)) {
00997 if (Port->Stream0 == NULL) {
00998 Port->Stream0 = MALLOC(sizeof(struct tcp_stream));
00999 bzero(Port->Stream0, sizeof(struct tcp_stream));
01000 }
01001 Stream = Port->Stream0;
01002 } else {
01003 if (Port->Stream1 == NULL) {
01004 Port->Stream1 = MALLOC(sizeof(struct tcp_stream));
01005 bzero(Port->Stream1, sizeof(struct tcp_stream));
01006 }
01007 Stream = Port->Stream1;
01008 }
01009
01010 #define PIECE_SIZE(p) (p.piece_end - p.piece_start + 1)
01011 #define PAYLOADS_SIZE(s) (s->LastSeq - s->TopSeq + 1)
01012
01013
01014 if (TData->Header->seq == Stream->LastSeq + 1) {
01015
01016 if (Stream->NumPieces == 0) {
01017 Stream->Pieces[0].piece_start = TData->Header->seq;
01018 Stream->Pieces[0].piece_end = TData->Header->seq + TData->DataLen - 1;
01019 Stream->Pieces[0].PacketSlot = PacketSlot;
01020 Stream->TopSeq = Stream->Pieces[0].piece_start;
01021 Stream->LastSeq = Stream->Pieces[0].piece_end;
01022 memcpy(&(Stream->Payloads[0]), TData->Data, TData->DataLen);
01023 BlockPacket(PacketSlot);
01024 Stream->NumPieces++;
01025 } else {
01026 if (Stream->NumPieces == TCP_PAYLOAD_PIECES_SIZE) {
01027
01028 UnblockPacket(Stream->Pieces[0].PacketSlot);
01029 memmove(&(Stream->Payloads[0]),
01030 &(Stream->Payloads[ PIECE_SIZE(Stream->Pieces[0]) ]),
01031 PAYLOADS_SIZE(Stream) - PIECE_SIZE(Stream->Pieces[0]) );
01032 memmove(&(Stream->Pieces[0]), &(Stream->Pieces[1]),
01033 (--Stream->NumPieces) * sizeof(struct tcp_stream_piece) );
01034 Stream->TopSeq = Stream->Pieces[0].piece_start;
01035 }
01036
01037 memcpy(&(Stream->Payloads[PAYLOADS_SIZE(Stream)]),
01038 TData->Data, TData->DataLen);
01039 Stream->LastSeq = TData->Header->seq + TData->DataLen - 1;
01040 Stream->Pieces[Stream->NumPieces].piece_start = TData->Header->seq;
01041 Stream->Pieces[Stream->NumPieces].piece_end = Stream->LastSeq;
01042 Stream->Pieces[Stream->NumPieces].PacketSlot = PacketSlot;
01043 Stream->NumPieces++;
01044
01045 }
01046 } else {
01047
01048
01049
01050 }
01051
01052
01053
01054 printf("O buffer tem:\n");
01055 for (IP1=0; IP1<PAYLOADS_SIZE(Stream); IP1++)
01056 if (Stream->Payloads[IP1] >= 32 && Stream->Payloads[IP1] <= 126)
01057 putchar(Stream->Payloads[IP1]);
01058 else
01059 putchar(46);
01060 putchar(10);
01061
01062 }
01063
01064
01065 TimeoutSessions(Globals.Packets[PacketSlot].tv.tv_sec);
01066
01067 return TRUE;
01068 }
01069
01077 int InitSession()
01078 {
01079 DEBUGPATH;
01080
01081 bzero(Sessions, sizeof(IPB*)*65536);
01082 TimeHead = NULL;
01083 CreateFuncs = NULL;
01084 DestroyFuncs = NULL;
01085
01086 IPDecoderID = GetDecoderByName("IP");
01087 TCPDecoderID = GetDecoderByName("TCP");
01088
01089 return TRUE;
01090 }
01091
01092
01093
01094 #if 0
01095
01100 int RemountTCPStream(int PacketSlot, PP* Port, TCPData* TData)
01101 {
01102
01103 int i;
01104
01105 DEBUGPATH;
01106 DBG( PRINT4("RemountTCPStream: Session:%d TCPCount:%d [%d,%d]\n",
01107 Port->SessionID, Port->TCPCount,
01108 TData->Header->seq, TData->Header->ack_seq) );
01109 #ifdef DEBUG000
01110
01111 PRINTERROR3(" --- TCP stream buffer ---\n %d pieces, TopSeq: %d, LastSeq: %d\n",
01112 Port->Seqs.num_pieces, Port->Seqs.TopSeq, Port->Seqs.LastSeq);
01113 for (i = 0; i < Port->Seqs.num_pieces; i++)
01114 PRINTERROR4(" [%d] %d -> %d PacketSlot:%d\n",
01115 i, Port->Seqs.pieces[i].piece_start,
01116 Port->Seqs.pieces[i].piece_end,
01117 Port->Seqs.pieces[i].PacketSlot);
01118 #endif
01119
01120 if (Port->Seqs.num_pieces == TCP_QUEUE_SIZE)
01121 return FALSE;
01122
01123
01124
01125
01126
01127
01128
01129
01130 if (TData->DataLen == 0)
01131 return TRUE;
01132
01133
01134 if (Port->Seqs.LastSeq == 0 && Port->Seqs.TopSeq == 0) {
01135 DBG( PRINTERROR2("Very first packet of session %d with payload (# of packets: %d)\n", Port->SessionID, Port->TCPCount) );
01136 Port->Seqs.TopSeq = TData->Header->seq - 1;
01137 Port->Seqs.LastSeq = TData->Header->seq - 1;
01138 }
01139
01140
01141 if (TData->Header->seq == Port->Seqs.LastSeq + 1) {
01142 if (Globals.logSession_All)
01143 PRINT2("Session %d: packet %d fits right at buffer's end\n", Port->SessionID, PacketSlot);
01144
01145 if (Port->Seqs.LastSeq - Port->Seqs.TopSeq + 1 >= TCP_CACHE_SIZE) {
01146 PRINTPKTERROR(-1, NULL, TData, FALSE);
01147 PRINTSESERROR(Port, FALSE);
01148 PRINTERROR("out of space in TCP cache\n");
01149 return FALSE;
01150 }
01151 memcpy(TData->Data,
01152 &(Port->Seqs.buffer) + (Port->Seqs.LastSeq - Port->Seqs.TopSeq),
01153 TData->DataLen);
01154
01155
01156 for (i = 0; Port->Seqs.pieces[i].piece_end < Port->Seqs.LastSeq && i < TCP_QUEUE_SIZE; i++);
01157 if (i == TCP_QUEUE_SIZE) {
01158 PRINTERROR("pieces[] out of space?\n");
01159 return FALSE;
01160 }
01161 DBG( PRINTERROR1("\tUsing pieces[%d]...", i) );
01162
01163
01164 if (i < TCP_QUEUE_SIZE - 1) {
01165 DBG( PRINTERROR("\n\tNeed to move other pieces[] forward, to make space\n") );
01166 memmove(&(Port->Seqs.pieces[i+1]), &(Port->Seqs.pieces[i]),
01167 sizeof(struct tcp_stream_piece)*(TCP_QUEUE_SIZE-i));
01168 }
01169 Port->Seqs.pieces[i].piece_start = TData->Header->seq;
01170 Port->Seqs.pieces[i].piece_end = TData->Header->seq + TData->DataLen-1;
01171 Port->Seqs.pieces[i].PacketSlot = PacketSlot;
01172 Port->Seqs.num_pieces++;
01173 Port->Seqs.LastSeq = TData->Header->seq + TData->DataLen - 1;
01174 DBG( PRINTERROR6(" Used: %d->%d, ps:%d, num_pieces:%d, Top/Last:%d/%d\n",
01175 Port->Seqs.pieces[i].piece_start,
01176 Port->Seqs.pieces[i].piece_end,
01177 Port->Seqs.pieces[i].PacketSlot,
01178 Port->Seqs.num_pieces,
01179 Port->Seqs.TopSeq, Port->Seqs.LastSeq) );
01180
01181
01182
01183
01184 while (TCPStream_Unqueue(Port));
01185 } else {
01186
01187 if (Globals.logSession_All)
01188 PRINT2("Session %d: packet %d doesn't fits at buffer's end, queuing it\n", Port->SessionID, PacketSlot);
01189
01190 DBG( PRINTPKTERROR(-1, NULL, TData, FALSE) );
01191 DBG( PRINTSESERROR(Port, FALSE) );
01192 DBG( PRINTERROR2("packet doesn't follows previous one (LastSeq:%d this packet's seq:%d)\n", Port->Seqs.LastSeq, TData->Header->seq) );
01193 if (Port->Seqs.queue_size < TCP_QUEUE_SIZE)
01194 Port->Seqs.queue[i++] = PacketSlot;
01195 BlockPacket(PacketSlot);
01196 }
01197
01198 return TRUE;
01199 }
01200
01205 int TCPStream_Unqueue(PP* Port)
01206 {
01207 TCPData* TData;
01208 int i;
01209
01210 DEBUGPATH;
01211
01212
01213 if (!Port->Seqs.queue_size)
01214 return FALSE;
01215
01216
01217 if (Port->Seqs.queue_size == TCP_QUEUE_SIZE)
01218 return FALSE;
01219
01220 for (i = 0; i < Port->Seqs.queue_size; i++) {
01221 GetDataByID(Port->Seqs.queue[i], TCPDecoderID, (void**)&TData);
01222 if (!TData) {
01223 PrintPacketSummary(stderr, Port->Seqs.queue[i], NULL, TData, FALSE);
01224 PRINTERROR("This was supposed to be a TCP packet\n");
01225 return FALSE;
01226 }
01227
01228
01229 if (TData->Header->seq == Port->Seqs.LastSeq + 1) {
01230 if (TData->DataLen > (TCP_CACHE_SIZE - Port->Seqs.LastSeq - Port->Seqs.TopSeq + 1))
01231
01232
01233 return FALSE;
01234
01235 memcpy(&(Port->Seqs.buffer) + Port->Seqs.LastSeq - Port->Seqs.TopSeq + 1,
01236 TData->Data, TData->DataLen);
01237
01238
01239 Port->Seqs.pieces[Port->Seqs.num_pieces].piece_start = TData->Header->seq;
01240 Port->Seqs.pieces[Port->Seqs.num_pieces].piece_end = TData->Header->seq + TData->DataLen - 1;
01241 Port->Seqs.pieces[Port->Seqs.num_pieces].PacketSlot = Port->Seqs.queue[i];
01242
01243
01244 if (Port->Seqs.queue_size == TCP_QUEUE_SIZE)
01245 Port->Seqs.queue_size--;
01246 else
01247 memmove(&(Port->Seqs.queue[i]),
01248 &(Port->Seqs.queue[i+1]),
01249 (Port->Seqs.queue_size-- - i - 1) * sizeof(int));
01250
01251 return TRUE;
01252
01253
01254 } else if (TData->Header->seq + TData->DataLen - 1 ==
01255 Port->Seqs.TopSeq) {
01256 if (TData->DataLen > (TCP_CACHE_SIZE - Port->Seqs.LastSeq - Port->Seqs.TopSeq + 1))
01257
01258
01259 return FALSE;
01260
01261
01262 memmove(&(Port->Seqs.buffer) + TData->DataLen,
01263 &(Port->Seqs.buffer),
01264 Port->Seqs.LastSeq - Port->Seqs.TopSeq + 1);
01265
01266 memcpy(&(Port->Seqs.buffer), TData->Data, TData->DataLen);
01267
01268
01269 memmove(&(Port->Seqs.pieces[1]), &(Port->Seqs.pieces[0]),
01270 (Port->Seqs.num_pieces - 1) * sizeof(struct tcp_stream_buffer));
01271 Port->Seqs.num_pieces++;
01272
01273
01274 if (Port->Seqs.queue_size == TCP_QUEUE_SIZE)
01275 Port->Seqs.queue_size--;
01276 else
01277 memmove(&(Port->Seqs.queue[i]),
01278 &(Port->Seqs.queue[i+1]),
01279 (Port->Seqs.queue_size-- - i - 1) * sizeof(int));
01280
01281 return TRUE;
01282 } else if (
01283 ((TData->Header->seq < Port->Seqs.LastSeq) &&
01284 (TData->Header->seq > Port->Seqs.TopSeq)) ||
01285 ((Port->Seqs.TopSeq > TData->Header->seq) &&
01286 (Port->Seqs.TopSeq < TData->Header->seq + TData->DataLen - 1)) ) {
01287
01288
01289 Globals.Packets[Port->Seqs.queue[i]].PassRawPacket = FALSE;
01290 if (Globals.Packets[Port->Seqs.queue[i]].Status == PACKET_STATUS_BLOCKED)
01291 TCPRemount_unblock(Port->Seqs.queue[i], TRUE);
01292 return FALSE;
01293 }
01294 }
01295
01296 return FALSE;
01297 }
01298 #endif
01299
01311 int UnblockPacket(int PacketSlot){}
01312 int TCPRemount_unblock(int PacketSlot, int thispacket)
01313 {
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378 }