00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <sys/types.h>
00027 #include <string.h>
00028 #include <stdio.h>
00029 #include <stdlib.h>
00030 #include <time.h>
00031 #ifndef WIN32
00032 #include <sys/time.h>
00033 #include <sys/socket.h>
00034 #include <netinet/in.h>
00035 #include <arpa/inet.h>
00036 #endif
00037 #include <time.h>
00038
00039 #include "rules.h"
00040 #include "log.h"
00041 #include "util.h"
00042 #include "debug.h"
00043 #include "generators.h"
00044 #include "detect.h"
00045 #include "log.h"
00046 #include "plugbase.h"
00047 #include "parser.h"
00048 #include "mstring.h"
00049
00050 #include "snort.h"
00051
00052
00053 void PortscanInit(u_char *);
00054 void ParsePortscanArgs(u_char *);
00055 void PortscanPreprocFunction(Packet *, void *);
00056 void ExtractHeaderInfo(Packet*, struct in_addr*, struct in_addr*, u_short*, u_short*);
00057
00058 void PortscanIgnoreHostsInit(u_char*);
00059 #define MODNAME "spp_portscan"
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 struct spp_timeval
00082 {
00083 time_t tv_sec;
00084 time_t tv_usec;
00085 };
00086
00087 typedef enum _scanType
00088 {
00089 sNONE = 0, sUDP = 1, sSYN = 2, sSYNFIN = 4, sFIN = 8, sNULL = 16,
00090 sXMAS = 32, sFULLXMAS = 64, sRESERVEDBITS = 128, sVECNA = 256, sNOACK = 512, sNMAPID = 1024,
00091 sSPAU = 2048, sINVALIDACK = 4096
00092 } ScanType;
00093
00094
00095 typedef enum _logLevel
00096 {
00097 lNONE = 0, lFILE = 1, lEXTENDED = 2, lPACKET = 4
00098 } LogLevel;
00099
00100
00101
00102 typedef struct _connectionInfo
00103 {
00104 ScanType scanType;
00105 u_short sport;
00106 u_short dport;
00107 struct spp_timeval timestamp;
00108 char tcpFlags[9];
00109 u_char *packetData;
00110 struct _connectionInfo *prevNode;
00111 struct _connectionInfo *nextNode;
00112 } ConnectionInfo;
00113
00114 typedef struct _destinationInfo
00115 {
00116 struct in_addr daddr;
00117 int numberOfConnections;
00118 ConnectionInfo *connectionsList;
00119 struct _destinationInfo *prevNode;
00120 struct _destinationInfo *nextNode;
00121 } DestinationInfo;
00122
00123 typedef struct _sourceInfo
00124 {
00125 struct in_addr saddr;
00126 int numberOfConnections;
00127 int numberOfDestinations;
00128 int numberOfTCPConnections;
00129 int numberOfUDPConnections;
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 int totalNumberOfTCPConnections;
00145 int totalNumberOfUDPConnections;
00146 int totalNumberOfDestinations;
00147
00148 struct spp_timeval firstPacketTime;
00149 struct spp_timeval lastPacketTime;
00150 int reportStealth;
00151
00152 int stealthScanUsed;
00153 int scanDetected;
00154 struct spp_timeval reportTime;
00155
00156 DestinationInfo *destinationsList;
00157 u_int32_t event_id;
00158 struct _sourceInfo *prevNode;
00159 struct _sourceInfo *nextNode;
00160 } SourceInfo;
00161
00162 typedef struct _scanList
00163 {
00164 SourceInfo *listHead;
00165 SourceInfo *lastSource;
00166 long numberOfSources;
00167 } ScanList;
00168
00169 typedef struct _serverNode
00170 {
00171 IpAddrSet *address;
00172
00173
00174
00175 char ignoreFlags;
00176 struct _serverNode *nextNode;
00177 } ServerNode;
00178
00179
00180
00181 typedef struct _CPConfig
00182 {
00183 u_int32_t classification;
00184 u_int32_t priority;
00185 } CPConfig;
00186
00187
00188
00189
00190 int NewScan(ScanList *, Packet *, ScanType);
00191 ConnectionInfo *NewConnection(Packet *, ScanType);
00192 ConnectionInfo *AddConnection(ConnectionInfo *, Packet *, ScanType);
00193 DestinationInfo *NewDestination(Packet *, ScanType);
00194 DestinationInfo *AddDestination(DestinationInfo *, Packet *, ScanType);
00195 SourceInfo *NewSource(Packet *, ScanType);
00196 SourceInfo *AddSource(SourceInfo *, Packet *, ScanType);
00197
00198
00199 void ExpireConnections(ScanList *, struct spp_timeval, struct spp_timeval);
00200 void RemoveConnection(ConnectionInfo *);
00201 void RemoveDestination(DestinationInfo *);
00202 void RemoveSource(SourceInfo *);
00203 void ClearConnectionInfoFromSource(SourceInfo *);
00204
00205
00206 void LogScanInfoToSeparateFile(SourceInfo *);
00207 void AlertIntermediateInfo(SourceInfo *);
00208
00209
00210 ScanList *CreateScanList(void);
00211 ScanType CheckTCPFlags(u_char);
00212 int IsServer(Packet *);
00213
00214
00215 IpAddrSet *PortscanAllocAddrNode();
00216 void PortscanParseIP(char *);
00217 void CreateServerList(u_char *);
00218 IpAddrSet *PortscanIgnoreAllocAddrNode(ServerNode *);
00219 void PortscanIgnoreParseIP(char *, ServerNode *);
00220
00221
00222 ScanList *scanList;
00223 ServerNode *serverList;
00224 ScanType scansToWatch;
00225 CPConfig configdata;
00226
00227
00228 IpAddrSet *homeAddr;
00229 char homeFlags;
00230 struct spp_timeval maxTime;
00231 long maxPorts;
00232 LogLevel logLevel;
00233 enum _timeFormat
00234 {
00235 tLOCAL, tGMT
00236 } timeFormat;
00237 FILE *logFile;
00238 int packetLogSize;
00239
00240
00241
00242 extern u_int32_t event_id;
00243
00244
00245 ConnectionInfo *NewConnection(Packet * p, ScanType scanType)
00246 {
00247 ConnectionInfo *newConnection = (ConnectionInfo *) malloc(sizeof(ConnectionInfo));
00248
00249 newConnection->prevNode = NULL;
00250 newConnection->nextNode = NULL;
00251
00252 newConnection->scanType = scanType;
00253
00254
00255
00256
00257 newConnection->timestamp.tv_sec = p->pkth->ts.tv_sec;
00258 newConnection->timestamp.tv_usec = p->pkth->ts.tv_usec;
00259
00260
00261 newConnection->sport = p->sp;
00262 newConnection->dport = p->dp;
00263
00264 switch(p->iph->ip_proto)
00265 {
00266 case IPPROTO_TCP:
00267 CreateTCPFlagString(p, newConnection->tcpFlags);
00268
00269
00270 if(logLevel & lPACKET)
00271 {
00272
00273
00274
00275
00276
00277
00278 }
00279 break;
00280
00281 case IPPROTO_UDP:
00282 strncpy(newConnection->tcpFlags, "\0", 1);
00283
00284
00285 if(logLevel & lPACKET)
00286 {
00287
00288
00289
00290
00291
00292
00293 }
00294 break;
00295
00296 default:
00297
00298 FatalError(MODNAME ": NewConnection(): Invalid protocol! (%d)\n", p->iph->ip_proto);
00299 break;
00300 }
00301
00302 return(newConnection);
00303 }
00304
00305 ConnectionInfo *AddConnection(ConnectionInfo * currentConnection, Packet * p, ScanType scanType)
00306 {
00307 if(currentConnection->nextNode)
00308 FatalError(MODNAME ": AddConnection(): Not at end of connection list!");
00309
00310 currentConnection->nextNode = NewConnection(p, scanType);
00311 currentConnection->nextNode->prevNode = currentConnection;
00312
00313 return(currentConnection->nextNode);
00314 }
00315
00316
00317 DestinationInfo *NewDestination(Packet * p, ScanType scanType)
00318 {
00319 DestinationInfo *newDestination = (DestinationInfo *) malloc(sizeof(DestinationInfo));
00320
00321 newDestination->prevNode = NULL;
00322 newDestination->nextNode = NULL;
00323 newDestination->daddr = p->iph->ip_dst;
00324 newDestination->connectionsList = NewConnection(p, scanType);
00325 newDestination->numberOfConnections = 1;
00326
00327 return(newDestination);
00328 }
00329
00330
00331 DestinationInfo *AddDestination(DestinationInfo * currentDestination, Packet * p,
00332 ScanType scanType)
00333 {
00334 if(currentDestination->nextNode)
00335 FatalError(MODNAME ": AddDestination(): Not at end of destination list!");
00336
00337 currentDestination->nextNode = NewDestination(p, scanType);
00338 currentDestination->nextNode->prevNode = currentDestination;
00339 return(currentDestination->nextNode);
00340 }
00341
00342
00343 SourceInfo *NewSource(Packet * p, ScanType scanType)
00344 {
00345 SourceInfo *newSource = (SourceInfo *) malloc(sizeof(SourceInfo));
00346
00347 newSource->prevNode = NULL;
00348 newSource->nextNode = NULL;
00349 newSource->saddr = p->iph->ip_src;
00350 newSource->numberOfConnections = 1;
00351
00352 newSource->firstPacketTime.tv_sec = p->pkth->ts.tv_sec;
00353 newSource->firstPacketTime.tv_usec = p->pkth->ts.tv_usec;
00354 newSource->lastPacketTime.tv_sec = p->pkth->ts.tv_sec;
00355 newSource->lastPacketTime.tv_usec = p->pkth->ts.tv_usec;
00356
00357 if(scanType == sUDP)
00358 {
00359 newSource->numberOfUDPConnections = 1;
00360 newSource->numberOfTCPConnections = 0;
00361
00362 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00363 ": NewSource(): %s->numberOfUDPConnections = 1, TCP = 0\n",
00364 inet_ntoa(newSource->saddr)););
00365 }
00366 else
00367 {
00368 newSource->numberOfTCPConnections = 1;
00369 newSource->numberOfUDPConnections = 0;
00370
00371 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00372 ": NewSource(): %s->numberOfTCPConnections = 1, UDP = 0\n",
00373 inet_ntoa(newSource->saddr)););
00374 }
00375
00376 newSource->totalNumberOfTCPConnections = 0;
00377 newSource->totalNumberOfUDPConnections = 0;
00378 newSource->stealthScanUsed = 0;
00379 newSource->scanDetected = 0;
00380 newSource->destinationsList = NewDestination(p, scanType);
00381 newSource->numberOfDestinations = 1;
00382 newSource->totalNumberOfDestinations = 1;
00383 newSource->reportStealth = 0;
00384
00385 return(newSource);
00386 }
00387
00388
00389 SourceInfo *AddSource(SourceInfo * currentSource, Packet * p, ScanType scanType)
00390 {
00391 if(currentSource->nextNode)
00392 FatalError(MODNAME ": AddSource(): Not at end of source list!");
00393
00394 currentSource->nextNode = NewSource(p, scanType);
00395 currentSource->nextNode->prevNode = currentSource;
00396
00397 return(currentSource->nextNode);
00398 }
00399
00400
00401 void RemoveConnection(ConnectionInfo * delConnection)
00402 {
00403
00404
00405
00406
00407 if(delConnection->prevNode || delConnection->nextNode)
00408 {
00409 if(delConnection->prevNode)
00410 {
00411 delConnection->prevNode->nextNode = delConnection->nextNode;
00412 }
00413 else if(delConnection->nextNode)
00414 {
00415 delConnection->nextNode->prevNode = NULL;
00416 }
00417 if(delConnection->nextNode)
00418 {
00419 delConnection->nextNode->prevNode = delConnection->prevNode;
00420 }
00421 else if(delConnection->prevNode)
00422 {
00423 delConnection->prevNode->nextNode = NULL;
00424 }
00425 }
00426 free(delConnection);
00427 }
00428
00429
00430 void RemoveDestination(DestinationInfo * delDestination)
00431 {
00432
00433
00434
00435
00436 if(delDestination->prevNode || delDestination->nextNode)
00437 {
00438 if(delDestination->prevNode)
00439 {
00440 delDestination->prevNode->nextNode = delDestination->nextNode;
00441 }
00442 else if(delDestination->nextNode)
00443 {
00444 delDestination->nextNode->prevNode = NULL;
00445 }
00446 if(delDestination->nextNode)
00447 {
00448 delDestination->nextNode->prevNode = delDestination->prevNode;
00449 }
00450 else if(delDestination->prevNode)
00451 {
00452 delDestination->prevNode->nextNode = NULL;
00453 }
00454 }
00455 free(delDestination);
00456 }
00457
00458
00459 void RemoveSource(SourceInfo * delSource)
00460 {
00461
00462
00463
00464
00465 if(delSource->prevNode || delSource->nextNode)
00466 {
00467 if(delSource->prevNode)
00468 {
00469 delSource->prevNode->nextNode = delSource->nextNode;
00470 }
00471 else if(delSource->nextNode)
00472 {
00473 delSource->nextNode->prevNode = NULL;
00474 }
00475 if(delSource->nextNode)
00476 {
00477 delSource->nextNode->prevNode = delSource->prevNode;
00478 }
00479 else if(delSource->prevNode)
00480 {
00481 delSource->prevNode->nextNode = NULL;
00482 }
00483 }
00484 free(delSource);
00485 }
00486
00487
00488
00489
00490
00491
00492 void ExpireConnections(ScanList * scanList, struct spp_timeval watchPeriod,
00493 struct spp_timeval currentTime)
00494 {
00495 SourceInfo *currentSource = scanList->listHead, *tmpSource;
00496 DestinationInfo *currentDestination, *tmpDestination;
00497 ConnectionInfo *currentConnection, *tmpConnection;
00498
00499
00500 if(!scanList->listHead)
00501 return;
00502
00503 while(currentSource)
00504 {
00505
00506
00507
00508
00509 if(currentSource->scanDetected)
00510 {
00511 currentSource = currentSource->nextNode;
00512 continue;
00513 }
00514 currentDestination = currentSource->destinationsList;
00515
00516 while(currentDestination)
00517 {
00518 currentConnection = currentDestination->connectionsList;
00519
00520 while(currentConnection)
00521 {
00522 if(currentConnection->timestamp.tv_sec + watchPeriod.tv_sec < currentTime.tv_sec)
00523 {
00524
00525 tmpConnection = currentConnection;
00526 currentConnection = currentConnection->nextNode;
00527
00528
00529
00530
00531
00532 if(tmpConnection->prevNode == NULL)
00533 {
00534 currentDestination->connectionsList = tmpConnection->nextNode;
00535 }
00536 if(tmpConnection->scanType == sUDP)
00537 {
00538 currentSource->numberOfUDPConnections--;
00539
00540 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00541 ": ExpireConnections(): %s->numberOfUDPConnections-- (%d)\n",
00542 inet_ntoa(currentSource->saddr),
00543 currentSource->numberOfUDPConnections););
00544
00545 }
00546 else
00547 {
00548 currentSource->numberOfTCPConnections--;
00549 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00550 ": ExpireConnections(): %s->numberOfTCPConnections-- (%d)\n",
00551 inet_ntoa(currentSource->saddr),
00552 currentSource->numberOfTCPConnections););
00553
00554 }
00555
00556 RemoveConnection(tmpConnection);
00557 currentSource->numberOfConnections--;
00558 currentDestination->numberOfConnections--;
00559
00560 }
00561 else
00562 {
00563 currentConnection = currentConnection->nextNode;
00564 }
00565 }
00566
00567 tmpDestination = currentDestination;
00568 currentDestination = currentDestination->nextNode;
00569
00570 if(tmpDestination->numberOfConnections == 0)
00571 {
00572 if(tmpDestination->prevNode == NULL)
00573 {
00574 currentSource->destinationsList = tmpDestination->nextNode;
00575 }
00576 RemoveDestination(tmpDestination);
00577 currentSource->numberOfDestinations--;
00578 }
00579 }
00580
00581 tmpSource = currentSource;
00582 currentSource = currentSource->nextNode;
00583
00584 if(tmpSource->numberOfDestinations == 0)
00585 {
00586
00587 if(tmpSource->prevNode == NULL)
00588 {
00589
00590 scanList->listHead = tmpSource->nextNode;
00591 }
00592 RemoveSource(tmpSource);
00593 scanList->numberOfSources--;
00594 }
00595 }
00596
00597 if(scanList->numberOfSources == 0)
00598 {
00599 scanList->listHead = NULL;
00600 }
00601 }
00602
00603
00604
00605
00606
00607
00608 int NewScan(ScanList * scanList, Packet * p, ScanType scanType)
00609 {
00610 SourceInfo *currentSource = scanList->listHead;
00611 DestinationInfo *currentDestination;
00612 ConnectionInfo *currentConnection;
00613 int matchFound = 0;
00614
00615 struct in_addr saddr;
00616 struct in_addr daddr;
00617 u_short sport;
00618 u_short dport;
00619
00620
00621 if(!scanList->listHead)
00622 {
00623 scanList->listHead = NewSource(p, scanType);
00624 scanList->numberOfSources = 1;
00625 scanList->lastSource = scanList->listHead;
00626 return(scanList->listHead->numberOfConnections);
00627 }
00628 ExtractHeaderInfo(p, &saddr, &daddr, &sport, &dport);
00629
00630 while(!matchFound)
00631 {
00632 if(currentSource->saddr.s_addr == saddr.s_addr)
00633 {
00634 currentDestination = currentSource->destinationsList;
00635
00636 if(currentSource->destinationsList == NULL)
00637 {
00638 currentSource->destinationsList = NewDestination(p, scanType);
00639 currentSource->numberOfConnections++;
00640
00641 if(scanType == sUDP)
00642 {
00643 currentSource->numberOfUDPConnections++;
00644 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00645 ": NewScan(): %s->numberOfUDPConnections++ (%d)\n",
00646 inet_ntoa(currentSource->saddr),
00647 currentSource->numberOfUDPConnections););
00648 }
00649 else
00650 {
00651 currentSource->numberOfTCPConnections++;
00652 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00653 ": NewScan(): %s->numberOfTCPConnections++ (%d)\n",
00654 inet_ntoa(currentSource->saddr),
00655 currentSource->numberOfTCPConnections););
00656 }
00657
00658 currentSource->numberOfDestinations++;
00659 matchFound = 1;
00660 }
00661 currentDestination = currentSource->destinationsList;
00662
00663 while(!matchFound)
00664 {
00665 if(currentDestination->daddr.s_addr == daddr.s_addr)
00666 {
00667 currentConnection = currentDestination->connectionsList;
00668
00669 while(!matchFound)
00670 {
00671
00672
00673
00674
00675
00676 if(currentConnection == NULL)
00677 FatalError(MODNAME ": currentConnection is NULL!!!??\n");
00678
00679 if((currentConnection->dport == dport) && (currentConnection->scanType == scanType))
00680 {
00681
00682
00683
00684
00685 currentConnection->timestamp.tv_sec = p->pkth->ts.tv_sec;
00686 currentConnection->timestamp.tv_usec = p->pkth->ts.tv_usec;
00687 currentConnection->sport = sport;
00688 matchFound = 1;
00689 }
00690 else
00691 {
00692
00693
00694
00695
00696 if(!currentConnection->nextNode)
00697 {
00698 currentConnection = AddConnection(currentConnection, p, scanType);
00699 currentSource->numberOfConnections++;
00700
00701 if(scanType == sUDP)
00702 {
00703 currentSource->numberOfUDPConnections++;
00704 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00705 ": NewScan(): %s->numberOfUDPConnections++ (%d)\n",
00706 inet_ntoa(currentSource->saddr),
00707 currentSource->numberOfUDPConnections););
00708
00709 }
00710 else
00711 {
00712 currentSource->numberOfTCPConnections++;
00713 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00714 ": NewScan(): %s->numberOfTCPConnections++ (%d)\n",
00715 inet_ntoa(currentSource->saddr),
00716 currentSource->numberOfTCPConnections););
00717 }
00718
00719 currentDestination->numberOfConnections++;
00720 matchFound = 1;
00721 }
00722 else
00723 currentConnection = currentConnection->nextNode;
00724 }
00725 }
00726 }
00727 else
00728 {
00729 if(!currentDestination->nextNode)
00730 {
00731 currentDestination = AddDestination(currentDestination, p, scanType);
00732 currentSource->numberOfConnections++;
00733
00734 if(scanType == sUDP)
00735 {
00736 currentSource->numberOfUDPConnections++;
00737 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00738 ": NewScan(): %s->numberOfUDPConnections++ (%d)\n",
00739 inet_ntoa(currentSource->saddr),
00740 currentSource->numberOfUDPConnections););
00741 }
00742 else
00743 {
00744 currentSource->numberOfTCPConnections++;
00745 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00746 ": NewScan(): %s->numberOfTCPConnections++ (%d)\n",
00747 inet_ntoa(currentSource->saddr),
00748 currentSource->numberOfTCPConnections););
00749
00750 }
00751
00752 currentSource->numberOfDestinations++;
00753 currentSource->totalNumberOfDestinations++;
00754 matchFound = 1;
00755 }
00756 else
00757 currentDestination = currentDestination->nextNode;
00758 }
00759 }
00760 }
00761 else
00762 {
00763 if(!currentSource->nextNode)
00764 {
00765 currentSource = AddSource(currentSource, p, scanType);
00766 currentSource->numberOfConnections = 1;
00767
00768 if(scanType == sUDP)
00769 {
00770 currentSource->numberOfUDPConnections = 1;
00771 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,
00772 MODNAME ": NewScan(): %s->numberOfUDPConnections = 1 \n",
00773 inet_ntoa(currentSource->saddr)););
00774 }
00775 else
00776 {
00777 currentSource->numberOfTCPConnections = 1;
00778 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
00779 ": NewScan(): %s->numberOfTCPConnections = 1\n",
00780 inet_ntoa(currentSource->saddr)););
00781
00782 }
00783
00784 scanList->numberOfSources++;
00785 matchFound = 1;
00786 }
00787 else
00788 currentSource = currentSource->nextNode;
00789 }
00790 }
00791
00792 scanList->lastSource = currentSource;
00793 return(currentSource->numberOfConnections);
00794 }
00795
00796
00797 ScanList *CreateScanList(void)
00798 {
00799 ScanList *newList = (ScanList *) malloc(sizeof(ScanList));
00800
00801 newList->listHead = NULL;
00802 newList->lastSource = NULL;
00803 newList->numberOfSources = 0;
00804
00805 return(newList);
00806 }
00807
00808
00809
00810 void PortscanPreprocFunction(Packet * p, void *context)
00811 {
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826 SourceInfo *currentSource;
00827 ScanType scanType;
00828 struct spp_timeval currTime;
00829 char logMessage[180];
00830 int numPorts;
00831 Event event;
00832
00833 if(!(p->preprocessors & PP_PORTSCAN))
00834 {
00835 return;
00836 }
00837
00838
00839 if(p->iph == NULL)
00840 {
00841 return;
00842 }
00843
00844 if(p->packet_flags & PKT_REBUILT_STREAM)
00845 {
00846 return;
00847 }
00848
00849
00850
00851
00852
00853 switch(p->iph->ip_proto)
00854 {
00855 case IPPROTO_TCP:
00856 if(p->tcph == NULL)
00857 {
00858
00859
00860
00861
00862
00863 return;
00864 }
00865 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"spp_portscan: Got TCP pkt\n"););
00866 scanType = CheckTCPFlags(p->tcph->th_flags);
00867 break;
00868
00869 case IPPROTO_UDP:
00870
00871
00872
00873
00874
00875 scanType = sUDP;
00876 break;
00877
00878 default:
00879
00880 return;
00881 break;
00882 }
00883
00884
00885
00886
00887
00888
00889
00890 if(!scanType)
00891 return;
00892
00893
00894
00895
00896
00897 if(!CheckAddrPort(homeAddr, 0, 0, p,
00898 (ANY_DST_PORT | homeFlags), CHECK_DST))
00899 {
00900 return;
00901 }
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911 if(IsServer(p) && !(scanType & sRESERVEDBITS & scansToWatch))
00912 {
00913 scanType &= ~(sSYN | sUDP);
00914 }
00915 if(scanType & scansToWatch)
00916 {
00917 currTime.tv_sec = p->pkth->ts.tv_sec;
00918 currTime.tv_usec = p->pkth->ts.tv_usec;
00919 ExpireConnections(scanList, maxTime, currTime);
00920
00921
00922
00923
00924
00925
00926 numPorts = NewScan(scanList, p, scanType);
00927
00928
00929 scanList->lastSource->lastPacketTime = currTime;
00930
00931 if((numPorts > maxPorts) || (scanType & ~(sSYN | sUDP)))
00932 {
00933 if(scanType & ~(sSYN | sUDP))
00934 {
00935 scanList->lastSource->stealthScanUsed = 1;
00936 scanList->lastSource->reportStealth = 1;
00937 }
00938 if(!scanList->lastSource->scanDetected)
00939 {
00940 if(scanList->lastSource->stealthScanUsed)
00941 {
00942 if(pv.alert_interface_flag)
00943 {
00944 sprintf(logMessage,
00945 MODNAME ": PORTSCAN DETECTED on %s to port %d "
00946 "from %s (STEALTH)",
00947 PRINT_INTERFACE(pv.interface),
00948 p->dp,
00949 inet_ntoa(scanList->lastSource->saddr));
00950 }
00951 else
00952 {
00953 sprintf(logMessage,
00954 MODNAME ": PORTSCAN DETECTED to port %d from "
00955 "%s (STEALTH)",
00956 p->dp,
00957 inet_ntoa(scanList->lastSource->saddr));
00958 }
00959 }
00960 else
00961 {
00962 if(pv.alert_interface_flag)
00963 {
00964 sprintf(logMessage, MODNAME
00965 ": PORTSCAN DETECTED on %s from %s"
00966 " (THRESHOLD %ld connections exceeded in %ld seconds)",
00967 PRINT_INTERFACE(pv.interface),
00968 inet_ntoa(scanList->lastSource->saddr), maxPorts,
00969 (long int) (currTime.tv_sec -
00970 scanList->lastSource->firstPacketTime.tv_sec));
00971 }
00972 else
00973 {
00974 sprintf(logMessage,
00975 MODNAME ": PORTSCAN DETECTED from %s"
00976 " (THRESHOLD %ld connections exceeded in %ld seconds)",
00977 inet_ntoa(scanList->lastSource->saddr), maxPorts,
00978 (long int) (currTime.tv_sec -
00979 scanList->lastSource->firstPacketTime.tv_sec));
00980 }
00981 }
00982
00983 SetEvent(&event, GENERATOR_SPP_PORTSCAN, PORTSCAN_SCAN_DETECT,
00984 1, 0, 0, 0);
00985 CallAlertFuncs(NULL , logMessage, NULL, &event);
00986 scanList->lastSource->scanDetected = 1;
00987 scanList->lastSource->reportTime = currTime;
00988 scanList->lastSource->event_id = event_id;
00989 }
00990 }
00991
00992 currentSource = scanList->listHead;
00993 while(currentSource)
00994 {
00995 if(currentSource->scanDetected)
00996 {
00997 if(currentSource->reportTime.tv_sec + maxTime.tv_sec < currTime.tv_sec)
00998 {
00999 if(currentSource->numberOfConnections == 0)
01000 {
01001
01002 sprintf(logMessage, MODNAME ": End of portscan from %s: TOTAL time(%lds) hosts(%d) TCP(%d) UDP(%d)%s",
01003 inet_ntoa(currentSource->saddr),
01004 (long int) (currentSource->lastPacketTime.tv_sec - currentSource->firstPacketTime.tv_sec),
01005 currentSource->totalNumberOfDestinations,
01006 currentSource->totalNumberOfTCPConnections,
01007 currentSource->totalNumberOfUDPConnections,
01008 (currentSource->reportStealth) ? " STEALTH" : "");
01009 SetEvent(&event, GENERATOR_SPP_PORTSCAN,
01010 PORTSCAN_SCAN_END, 1, 0, 0,
01011 currentSource->event_id);
01012 CallAlertFuncs(NULL , logMessage, NULL, &event);
01013 currentSource->scanDetected = 0;
01014 }
01015 else
01016 {
01017
01018 if(logLevel & lFILE)
01019 LogScanInfoToSeparateFile(currentSource);
01020 if(logLevel & lEXTENDED)
01021 AlertIntermediateInfo(currentSource);
01022
01023 currentSource->totalNumberOfTCPConnections +=
01024 currentSource->numberOfTCPConnections;
01025 currentSource->totalNumberOfUDPConnections +=
01026 currentSource->numberOfUDPConnections;
01027
01028 ClearConnectionInfoFromSource(currentSource);
01029 currentSource->stealthScanUsed = 0;
01030 currentSource->reportTime = currTime;
01031 }
01032 }
01033 }
01034 currentSource = currentSource->nextNode;
01035 }
01036 }
01037 }
01038
01039
01040
01041 void ClearConnectionInfoFromSource(SourceInfo * currentSource)
01042 {
01043 DestinationInfo *currentDestination, *tmpDestination;
01044 ConnectionInfo *currentConnection, *tmpConnection;
01045
01046 currentDestination = currentSource->destinationsList;
01047 while(currentDestination)
01048 {
01049 currentConnection = currentDestination->connectionsList;
01050 while(currentConnection)
01051 {
01052 tmpConnection = currentConnection;
01053 currentConnection = currentConnection->nextNode;
01054
01055 if(tmpConnection->scanType == sUDP)
01056 {
01057 currentSource->numberOfUDPConnections--;
01058 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
01059 ": ClearConnectionInfoFromSource(): %s->numberOfUDPConnections-- (%d)\n",
01060 inet_ntoa(currentSource->saddr), currentSource->numberOfUDPConnections););
01061
01062 }
01063 else
01064 {
01065 currentSource->numberOfTCPConnections--;
01066 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, MODNAME
01067 ": ClearConnectionInfoFromSource(): %s->numberOfTCPConnections-- (%d)\n",
01068 inet_ntoa(currentSource->saddr), currentSource->numberOfTCPConnections););
01069 }
01070
01071 RemoveConnection(tmpConnection);
01072 currentDestination->numberOfConnections--;
01073 currentSource->numberOfConnections--;
01074 }
01075 tmpDestination = currentDestination;
01076 currentDestination = currentDestination->nextNode;
01077 RemoveDestination(tmpDestination);
01078 currentSource->numberOfDestinations--;
01079 }
01080 currentSource->destinationsList = NULL;
01081 }
01082
01083
01084 void SetupPortscan(void)
01085 {
01086 RegisterPreprocessor("portscan", PortscanInit);
01087 }
01088
01089
01090 void PortscanInit(u_char * args)
01091 {
01092 LogMessage("WARNING: the portscan preprocessor will be deprecated in "
01093 "the next release of snort. Please switch to using SFPortscan.\n");
01094 ParsePortscanArgs(args);
01095 scanList = CreateScanList();
01096
01097
01098
01099
01100
01101
01102 serverList = NULL;
01103 AddFuncToPreprocList(PortscanPreprocFunction);
01104 }
01105
01106
01107 ScanType CheckTCPFlags(u_char th_flags)
01108 {
01109 u_char th_flags_cleaned;
01110 ScanType scan = sNONE;
01111
01112
01113
01114
01115
01116 th_flags_cleaned = th_flags & ~(R_RES1 | R_RES2);
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 if(th_flags_cleaned & R_ACK)
01134 {
01135
01136
01137
01138
01139
01140
01141 switch(th_flags_cleaned)
01142 {
01143 case (R_ACK):
01144 case (R_SYN | R_ACK):
01145 case (R_FIN | R_ACK):
01146 case (R_RST | R_ACK):
01147 case (R_ACK | R_PSH):
01148 case (R_ACK | R_URG):
01149 case (R_ACK | R_URG | R_PSH):
01150 case (R_FIN | R_ACK | R_PSH):
01151 case (R_FIN | R_ACK | R_URG):
01152 case (R_FIN | R_ACK | R_URG | R_PSH):
01153 case (R_RST | R_ACK | R_PSH):
01154
01155
01156 break;
01157
01158 case (R_SYN | R_RST | R_ACK | R_FIN | R_PSH | R_URG):
01159 scan |= sFULLXMAS;
01160 break;
01161
01162 case (R_SYN | R_PSH | R_ACK | R_URG):
01163 scan |= sSPAU;
01164 break;
01165
01166 default:
01167 scan |= sINVALIDACK;
01168 break;
01169 }
01170 }
01171 else
01172 {
01173
01174
01175
01176
01177
01178 switch(th_flags_cleaned)
01179 {
01180 case R_SYN:
01181 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "spp_portscan: SYN packet\n"););
01182 scan |= sSYN;
01183 break;
01184
01185 case R_RST:
01186
01187 break;
01188
01189 case R_FIN:
01190 scan |= sFIN;
01191 break;
01192
01193 case (R_SYN | R_FIN):
01194 scan |= sSYNFIN;
01195 break;
01196
01197 case 0:
01198 scan |= sNULL;
01199 break;
01200
01201 case (R_FIN | R_PSH | R_URG):
01202 scan |= sXMAS;
01203 break;
01204
01205 case R_URG:
01206 case R_PSH:
01207 case (R_URG | R_FIN):
01208 case (R_PSH | R_FIN):
01209 case (R_URG | R_PSH):
01210 scan |= sVECNA;
01211 break;
01212
01213 case (R_SYN | R_FIN | R_PSH | R_URG):
01214 scan |= sNMAPID;
01215 break;
01216
01217 default:
01218
01219
01220
01221
01222
01223
01224 scan |= sNOACK;
01225 break;
01226 }
01227 }
01228
01229 return(scan);
01230 }
01231
01232
01233 void ParsePortscanArgs(u_char * args)
01234 {
01235 char **toks;
01236 int numToks;
01237
01238 char *logFileName;
01239
01240 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,MODNAME ": ParsePortscanArgs(): %s\n", args););
01241
01242 logLevel = lNONE;
01243
01244 if(!args)
01245 {
01246 FatalError(MODNAME ": %s (%d) => portscan configuration format: address/mask ports seconds [logfile]\n", file_name, file_line);
01247 }
01248
01249
01250 #ifdef WIN32
01251 toks = mSplit(args, " ", 6, &numToks, 0);
01252 #else
01253 toks = mSplit(args, " ", 6, &numToks, '\\');
01254
01255 #endif
01256
01257 if((numToks < 3) || (numToks > 6))
01258 {
01259 FatalError(MODNAME "%s(%d) => portscan configuration format: address/mask ports seconds [logfile]\n", file_name, file_line);
01260 }
01261
01262 maxPorts = atoi(toks[1]);
01263 maxTime.tv_sec = atoi(toks[2]);
01264 maxTime.tv_usec = 0;
01265
01266 PortscanParseIP(toks[0]);
01267
01268
01269
01270
01271
01272
01273 if(numToks == 4)
01274 {
01275 #ifdef WIN32
01276 logFileName = (char *) calloc(strlen(toks[3]) + 1 + 1, 1);
01277 strncpy(logFileName, toks[3], strlen(toks[3]));
01278 #else
01279 if(pv.log_dir && (*toks[3] != '/'))
01280 {
01281 if(*(pv.log_dir + strlen(pv.log_dir) - 1) != '/')
01282 {
01283 logFileName = (char *)calloc(strlen(pv.log_dir)
01284 + strlen(toks[3]) + 1 + 1, 1);
01285
01286 strncat(logFileName, pv.log_dir, strlen(pv.log_dir) + 1);
01287 strncat(logFileName, "/", 1);
01288 strncat(logFileName, toks[3], strlen(toks[3]));
01289 }
01290 else
01291 {
01292 logFileName = (char *)calloc(strlen(pv.log_dir)
01293 + strlen(toks[3]) + 1, 1);
01294
01295 strncat(logFileName, pv.log_dir, strlen(pv.log_dir) + 1);
01296 strncat(logFileName, toks[3], strlen(toks[3]));
01297 }
01298 }
01299 else
01300 {
01301 logFileName = (char *)calloc(strlen(toks[3]) + 1, 1);
01302
01303 strncat(logFileName, toks[3], strlen(toks[3]) + 1);
01304 }
01305 #endif
01306
01307 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,MODNAME ": logFileName = %s\n", logFileName););
01308
01309 logFile = fopen(logFileName, "a+");
01310 if(!logFile)
01311 {
01312 perror("fopen");
01313 FatalError(MODNAME ": logfile open error (%s)\n", logFileName);
01314 }
01315
01316 logLevel |= lFILE;
01317 }
01318
01319 mSplitFree(&toks, numToks);
01320
01321
01322 if(maxPorts == 0 || maxTime.tv_sec == 0)
01323 {
01324 FatalError(MODNAME ": %s (%d) => portscan configuration format: address/mask ports seconds [logfile]\n", file_name, file_line);
01325 }
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340 scansToWatch = ~(sRESERVEDBITS|sUDP);
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353 logLevel |= lEXTENDED;
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364 packetLogSize = 100;
01365
01366 if(pv.use_utc == 1)
01367 {
01368 timeFormat = tGMT;
01369 if(!pv.quiet_flag)
01370 printf("Using GMT time\n");
01371 }
01372 else
01373 {
01374 timeFormat = tLOCAL;
01375 if(!pv.quiet_flag)
01376 printf("Using LOCAL time\n");
01377 }
01378 }
01379
01380
01381 void LogScanInfoToSeparateFile(SourceInfo * currentSource)
01382 {
01383 DestinationInfo *currentDestination;
01384 ConnectionInfo *currentConnection;
01385 char *scanType;
01386 char *reservedBits;
01387 char *month;
01388 struct tm *time;
01389 char sourceAddress[16], destinationAddress[16];
01390 memset(sourceAddress, '\0', 16);
01391 memset(destinationAddress, '\0', 16);
01392
01393
01394
01395
01396
01397
01398 strncpy(sourceAddress, inet_ntoa(currentSource->saddr), 15);
01399
01400 for(currentDestination = currentSource->destinationsList; currentDestination;
01401 currentDestination = currentDestination->nextNode)
01402 {
01403 strncpy(destinationAddress, inet_ntoa(currentDestination->daddr), 15);
01404
01405 for(currentConnection = currentDestination->connectionsList; currentConnection;
01406 currentConnection = currentConnection->nextNode)
01407 {
01408
01409
01410
01411
01412
01413 time = (timeFormat == tLOCAL) ? localtime((time_t *) & currentConnection->timestamp.tv_sec) : gmtime(¤tConnection->timestamp.tv_sec);
01414
01415 switch(time->tm_mon)
01416 {
01417 case 0:
01418 month = "Jan";
01419 break;
01420 case 1:
01421 month = "Feb";
01422 break;
01423 case 2:
01424 month = "Mar";
01425 break;
01426 case 3:
01427 month = "Apr";
01428 break;
01429 case 4:
01430 month = "May";
01431 break;
01432 case 5:
01433 month = "Jun";
01434 break;
01435 case 6:
01436 month = "Jul";
01437 break;
01438 case 7:
01439 month = "Aug";
01440 break;
01441 case 8:
01442 month = "Sep";
01443 break;
01444 case 9:
01445 month = "Oct";
01446 break;
01447 case 10:
01448 month = "Nov";
01449 break;
01450 case 11:
01451 month = "Dec";
01452 break;
01453 default:
01454 month = "MONTH IS INVALID!!";
01455 break;
01456 }
01457
01458 reservedBits = (currentConnection->scanType & sRESERVEDBITS) ? "RESERVEDBITS" : "";
01459
01460 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"scanType = %x mask = %x result = (%x)\n", currentConnection->scanType, ~sRESERVEDBITS, currentConnection->scanType & ~sRESERVEDBITS););
01461
01462 switch(currentConnection->scanType & ~sRESERVEDBITS)
01463 {
01464 case sUDP:
01465 scanType = "UDP";
01466 break;
01467 case sSYN:
01468 scanType = "SYN";
01469 break;
01470 case sFIN:
01471 scanType = "FIN";
01472 break;
01473 case sSYNFIN:
01474 scanType = "SYNFIN";
01475 break;
01476 case sNULL:
01477 scanType = "NULL";
01478 break;
01479 case sXMAS:
01480 scanType = "XMAS";
01481 break;
01482 case sFULLXMAS:
01483 scanType = "FULLXMAS";
01484 break;
01485 case sVECNA:
01486 scanType = "VECNA";
01487 break;
01488 case sNOACK:
01489 scanType = "NOACK";
01490 break;
01491 case sNMAPID:
01492 scanType = "NMAPID";
01493 break;
01494 case sSPAU:
01495 scanType = "SPAU";
01496 break;
01497 case sINVALIDACK:
01498 scanType = "INVALIDACK";
01499 break;
01500 default:
01501
01502
01503
01504
01505
01506
01507
01508 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"UNKNOWN: scanType = %x (%x)\n", currentConnection->scanType, currentConnection->scanType & ~sRESERVEDBITS););
01509
01510 scanType = "UNKNOWN";
01511 break;
01512 }
01513
01514
01515 fprintf(logFile, "%s %2d %.2d:%.2d:%.2d %s:%d -> %s:%d %s %s %s\n", month, time->tm_mday,
01516 time->tm_hour, time->tm_min, time->tm_sec,
01517 sourceAddress, currentConnection->sport, destinationAddress,
01518 currentConnection->dport, scanType, currentConnection->tcpFlags, reservedBits);
01519 }
01520 }
01521
01522
01523 fflush(logFile);
01524 }
01525
01526
01527
01528
01529
01530 void AlertIntermediateInfo(SourceInfo * currentSource)
01531 {
01532 char logMessage[160];
01533 Event event;
01534
01535 sprintf(logMessage,
01536 MODNAME ": portscan status from %s: %d connections "
01537 "across %d hosts: TCP(%d), UDP(%d)%s",
01538 inet_ntoa(currentSource->saddr),
01539 currentSource->numberOfConnections,
01540 currentSource->numberOfDestinations,
01541 currentSource->numberOfTCPConnections,
01542 currentSource->numberOfUDPConnections,
01543 (currentSource->stealthScanUsed) ? " STEALTH" : "");
01544
01545 SetEvent(&event, GENERATOR_SPP_PORTSCAN,
01546 PORTSCAN_INTER_INFO, 1, 0, 0, currentSource->event_id);
01547 CallAlertFuncs(NULL, logMessage, NULL, &event);
01548
01549 return;
01550 }
01551
01552
01553 void ExtractHeaderInfo(Packet * p, struct in_addr * saddr,
01554 struct in_addr * daddr, u_short * sport,
01555 u_short * dport)
01556 {
01557
01558
01559
01560
01561
01562
01563
01564 *sport = p->sp;
01565 *dport = p->dp;
01566 *saddr = p->iph->ip_src;
01567 *daddr = p->iph->ip_dst;
01568 }
01569
01570
01571
01572
01573
01574 int IsServer(Packet * p)
01575 {
01576 ServerNode *currentServer = serverList;
01577
01578 #ifdef DEBUG
01579 char sourceIP[16], ruleIP[16], ruleNetMask[16];
01580
01581 #endif
01582
01583 while(currentServer)
01584 {
01585
01586
01587
01588
01589 if(CheckAddrPort(currentServer->address, 0, 0, p,
01590 (ANY_SRC_PORT | currentServer->ignoreFlags), CHECK_SRC))
01591 {
01592
01593 #ifdef DEBUG
01594 memset(sourceIP, '\0', 16);
01595 memset(ruleIP, '\0', 16);
01596 memset(ruleNetMask, '\0', 16);
01597 strncpy(sourceIP, inet_ntoa(p->iph->ip_src), 15);
01598 strncpy(ruleIP, inet_ntoa(*(struct in_addr *) & (currentServer->address->ip_addr)), 14);
01599 strncpy(ruleNetMask, inet_ntoa(*(struct in_addr *) & (currentServer->address->netmask)), 15);
01600
01601 printf(MODNAME ": IsServer(): Server %s found in %s/%s!\n", sourceIP, ruleIP, ruleNetMask);
01602 #endif
01603
01604 return(1);
01605 }
01606 currentServer = currentServer->nextNode;
01607 }
01608
01609 return(0);
01610 }
01611
01612
01613 void SetupPortscanIgnoreHosts(void)
01614 {
01615 RegisterPreprocessor("portscan-ignorehosts", PortscanIgnoreHostsInit);
01616 }
01617
01618
01619 void PortscanIgnoreHostsInit(u_char * args)
01620 {
01621 CreateServerList(args);
01622 }
01623
01624
01625
01626
01627
01628
01629
01630 void CreateServerList(u_char * servers)
01631 {
01632 char **toks;
01633 int num_toks;
01634 int num_servers = 0;
01635 ServerNode *currentServer;
01636
01637 #ifdef DEBUG
01638 char ruleIP[16], ruleNetMask[16];
01639 #endif
01640
01641 currentServer = NULL;
01642 serverList = NULL;
01643
01644 if(servers == NULL)
01645 {
01646 FatalError(MODNAME ": %s (%d)=> No arguments to portscan-ignorehosts preprocessor!\n", file_name, file_line);
01647 }
01648
01649 toks = mSplit(servers, " ", 31, &num_toks, '\\');
01650
01651
01652 for(num_servers = 0; num_servers < num_toks; num_servers++)
01653 {
01654 if(currentServer != NULL)
01655 {
01656 currentServer->nextNode = (ServerNode *) calloc(sizeof(ServerNode), sizeof(char));
01657 currentServer = currentServer->nextNode;
01658 }
01659 else
01660 {
01661 currentServer = (ServerNode *) calloc(sizeof(ServerNode), sizeof(char));
01662 serverList = currentServer;
01663 }
01664
01665 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,MODNAME ": CreateServerList(): Adding server %s\n", toks[num_servers]););
01666
01667
01668 PortscanIgnoreParseIP(toks[num_servers], currentServer);
01669
01670
01671 #ifdef DEBUG
01672 memset(ruleIP, '\0', 16);
01673 memset(ruleNetMask, '\0', 16);
01674 strncpy(ruleIP, inet_ntoa(*(struct in_addr *) & currentServer->address->ip_addr), 15);
01675 strncpy(ruleNetMask, inet_ntoa(*(struct in_addr *) & currentServer->address->netmask), 15);
01676 printf(MODNAME ": CreateServerList(): Added server %s/%s\n", ruleIP, ruleNetMask);
01677 #endif
01678
01679 currentServer->nextNode = NULL;
01680 }
01681
01682 mSplitFree(&toks, num_toks);
01683 }
01684
01685
01686
01687 void PortscanParseIP(char *addr)
01688 {
01689 char **toks;
01690 int num_toks;
01691 int i;
01692 IpAddrSet *tmp_addr;
01693 char *tmp;
01694
01695 if(*addr == '!')
01696 {
01697 homeFlags |= EXCEPT_DST_IP;
01698 addr++;
01699 }
01700
01701 if(*addr == '$')
01702 {
01703 if((tmp = VarGet(addr + 1)) == NULL)
01704 {
01705 FatalError("%s(%d) => Undefined variable %s\n", file_name,
01706 file_line, addr);
01707 }
01708 }
01709 else
01710 {
01711 tmp = addr;
01712 }
01713
01714 if (*tmp == '[')
01715 {
01716 *(strrchr(tmp, (int)']')) = 0;
01717
01718 toks = mSplit(tmp+1, ",", 128, &num_toks, 0);
01719
01720 for(i = 0; i < num_toks; i++)
01721 {
01722 tmp_addr = PortscanAllocAddrNode();
01723
01724 ParseIP(toks[i], tmp_addr);
01725 }
01726
01727 mSplitFree(&toks, num_toks);
01728 }
01729 else
01730 {
01731 tmp_addr = PortscanAllocAddrNode();
01732 ParseIP(tmp, tmp_addr);
01733 }
01734 }
01735
01736
01737 void PortscanIgnoreParseIP(char *addr, ServerNode* server)
01738 {
01739 char **toks;
01740 int num_toks;
01741 int i;
01742 IpAddrSet *tmp_addr;
01743 int global_negation_flag;
01744 char *tmp;
01745
01746 if(addr == NULL)
01747 {
01748 FatalError("%s(%d) => Undefined address in portscan-ignorehosts directive\n",
01749 file_name, file_line);
01750 }
01751
01752 if(*addr == '!')
01753 {
01754 global_negation_flag = 1;
01755 addr++;
01756 }
01757
01758 if(*addr == '$')
01759 {
01760 if((tmp = VarGet(addr + 1)) == NULL)
01761 {
01762 FatalError("%s (%d) => Undefined variable %s\n", file_name,
01763 file_line, addr);
01764 }
01765 }
01766 else
01767 {
01768 tmp = addr;
01769 }
01770
01771 if (*tmp == '[')
01772 {
01773 *(strrchr(tmp, (int)']')) = 0;
01774
01775 toks = mSplit(tmp+1, ",", 128, &num_toks, 0);
01776
01777 for(i = 0; i < num_toks; i++)
01778 {
01779 tmp_addr = PortscanIgnoreAllocAddrNode(server);
01780
01781 ParseIP(toks[i], tmp_addr);
01782 }
01783
01784 mSplitFree(&toks, num_toks);
01785 }
01786 else
01787 {
01788 tmp_addr = PortscanIgnoreAllocAddrNode(server);
01789
01790 ParseIP(tmp, tmp_addr);
01791 }
01792 }
01793
01794 IpAddrSet *PortscanAllocAddrNode()
01795 {
01796 IpAddrSet *idx;
01797
01798 if(homeAddr == NULL)
01799 {
01800 homeAddr = (IpAddrSet *) calloc(sizeof(IpAddrSet), sizeof(char));
01801
01802 if(homeAddr == NULL)
01803 {
01804 FatalError("Unable to allocate space for portscan IP addr\n");
01805 }
01806
01807 return homeAddr;
01808 }
01809
01810 idx = homeAddr;
01811
01812 while(idx->next != NULL)
01813 {
01814 idx = idx->next;
01815 }
01816
01817 idx->next = (IpAddrSet *) calloc(sizeof(IpAddrSet), sizeof(char));
01818
01819 idx = idx->next;
01820
01821 if(idx == NULL)
01822 {
01823 FatalError("Unable to allocate space for portscan IP address\n");
01824 }
01825
01826 return idx;
01827 }
01828
01829
01830
01831 IpAddrSet *PortscanIgnoreAllocAddrNode(ServerNode * server)
01832 {
01833 IpAddrSet *idx;
01834
01835 if(server->address == NULL)
01836 {
01837 server->address = (IpAddrSet *) calloc(sizeof(IpAddrSet), sizeof(char));
01838
01839 if(server->address == NULL)
01840 {
01841 FatalError("Unable to allocate space for portscan IP addr\n");
01842 }
01843 return server->address;
01844 }
01845 idx = server->address;
01846
01847 while(idx->next != NULL)
01848 {
01849 idx = idx->next;
01850 }
01851
01852 idx->next = (IpAddrSet *) calloc(sizeof(IpAddrSet), sizeof(char));
01853
01854 idx = idx->next;
01855
01856 if(idx == NULL)
01857 {
01858 FatalError("Unable to allocate space for portscan IP address\n");
01859 }
01860 return idx;
01861 }