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 #ifdef GIDS
00026
00027
00028 #include <sys/types.h>
00029 #include <stdlib.h>
00030 #include <ctype.h>
00031 #include <rpc/types.h>
00032 #include "generators.h"
00033 #include "event_wrapper.h"
00034 #include "assert.h"
00035 #include "util.h"
00036 #include "plugbase.h"
00037 #include "parser.h"
00038 #include "mempool.h"
00039 #include "plugbase.h"
00040 #include "mstring.h"
00041 #include "util.h"
00042 #include "log.h"
00043 #include "parser.h"
00044 #include "detect.h"
00045 #include "rules.h"
00046 #include "decode.h"
00047 #include "debug.h"
00048 #include "ubi_SplayTree.h"
00049 #include "ubi_BinTree.h"
00050
00051 #ifndef WIN32
00052 #include <sys/socket.h>
00053 #include <netinet/in.h>
00054 #include <arpa/inet.h>
00055 #endif
00056
00057 #include "spp_stickydrop.h"
00058 #include "inline.h"
00059
00060 #define MAX_PORTS 64
00061 #define MEM_CHUNK 32
00062 #define DIRECTION_SOURCE 0
00063 #define DIRECTION_DST 1
00064
00065
00066 typedef struct _StickyD
00067 {
00068 ubi_trRoot attackerRoot;
00069 ubi_trRootPtr attackerRootPtr;
00070 MemPool AttackerPool;
00071 u_int32_t max_block_entries;
00072 char log;
00073 FILE *logfile;
00074 char *logpath;
00075
00076 } StickyD;
00077
00078 StickyD stickd;
00079
00080
00081 typedef struct _Attacker
00082 {
00083 ubi_trNode Node;
00084 MemBucket *bucket;
00085 u_int32_t ip;
00086 u_int32_t timeout;
00087 struct timeval blocktime;
00088 struct timeval unblocktime;
00089
00090 } Attacker;
00091
00092 Attacker attacker;
00093
00094 typedef struct _sdhostNode
00095 {
00096 IpAddrSet *address;
00097 u_short hsp;
00098 u_short lsp;
00099 u_int32_t flags;
00100 struct _sdhostNode *nextNode;
00101
00102 } sdHostNode;
00103
00104 sdHostNode *sdignoreList;
00105 int num_ports_from;
00106 int num_ports_to;
00107 u_int32_t *sdignorePortFrom;
00108 u_int32_t *sdignorePortTo;
00109
00110
00111 static void StickyDropInit(u_char *);
00112 static void ParseStickyDropArgs(char *);
00113 void StickyDrop(Packet *, void *);
00114 void SDLog(Packet *);
00115 static int IpAddressCompareFunction(ubi_trItemPtr, ubi_trNodePtr);
00116 static int PruneAttackers(u_int32_t now, int tokill, Attacker *saveme);
00117 static void PreprocCleanExitFunction(int, void *);
00118 static void PreprocRestartFunction(int, void *);
00119
00120
00121 static void sdInitTimeouts(u_char *);
00122 static void ParseSDTimeoutArgs(char *);
00123
00124
00125 void sdInitIgnoreHosts(u_char *);
00126 IpAddrSet* sdIgnoreAllocAddrNode(sdHostNode *);
00127 void sdScanParseIp(char *, sdHostNode *);
00128
00129
00130 void sdInitIgnoreFrom(u_char *);
00131 void sdInitIgnoreTo(u_char *);
00132 void sdInitIgnorePorts(u_char *, u_int32_t **, int *);
00133 u_int32_t sdScanParsePort(char *);
00134
00135 int sdIsIgnored(Packet *, char);
00136 int sdBlockTreeSearch(Packet *, char);
00137
00138 static int s_stickyd_running = 0;
00139
00140 SDtimeout sdt;
00141 extern int do_detect;
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 void SetupStickyDrop()
00157 {
00158
00159
00160
00161
00162 RegisterPreprocessor("stickydrop", StickyDropInit);
00163 RegisterPreprocessor("stickydrop-timeouts",sdInitTimeouts);
00164 RegisterPreprocessor("stickydrop-ignorehosts", sdInitIgnoreHosts);
00165 RegisterPreprocessor("stickydrop-ignoreports-from", sdInitIgnoreFrom);
00166 RegisterPreprocessor("stickydrop-ignoreports-to", sdInitIgnoreTo);
00167 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Preprocessor: StickyDrop is setup...\n"););
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 static void StickyDropInit(u_char *args)
00183 {
00184 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Preprocessor: StickyDrop Initialized\n"););
00185
00186 memset(&stickd, 0, sizeof(StickyD));
00187 ParseStickyDropArgs(args);
00188 stickd.attackerRootPtr = &stickd.attackerRoot;
00189
00190 ubi_trInitTree(stickd.attackerRootPtr, IpAddressCompareFunction, 0);
00191 if(mempool_init(&stickd.AttackerPool , stickd.max_block_entries, sizeof(Attacker)))
00192 {
00193 FatalError("ERROR: Could not alloc memory for stickydrop entries\n");
00194 }
00195 else if(!InlineMode())
00196 {
00197 FatalError("ERROR: We have to be in InlineMode() to use stickydrop\n");
00198 }
00199
00200 s_stickyd_running = 1;
00201 AddFuncToPreprocList(StickyDrop);
00202 AddFuncToCleanExitList(PreprocCleanExitFunction, NULL);
00203 AddFuncToRestartList(PreprocRestartFunction, NULL);
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 static void ParseStickyDropArgs(char *args)
00221 {
00222 int num_toks, s_toks;
00223 char **toks = NULL;
00224 char **stoks;
00225 int i;
00226 char* index;
00227 char logpath[STD_BUF], tmp[STD_BUF];
00228
00229
00230 strlcpy(logpath, pv.log_dir, STD_BUF);
00231 strlcpy(tmp, "/stickyd.log", STD_BUF);
00232 strlcat(logpath, tmp, STD_BUF);
00233
00234 stickd.max_block_entries = 5000;
00235 stickd.log = 0;
00236 if (args)
00237 {
00238
00239 toks = mSplit(args, ",", 5, &num_toks, 0);
00240
00241 i=0;
00242
00243 while (i < num_toks)
00244 {
00245 index = toks[i];
00246
00247 while(isspace((int)*index)) index++;
00248
00249 stoks = mSplit(index, " ", 4, &s_toks, 0);
00250 if(!strcasecmp(stoks[0], "max_entries"))
00251 {
00252 if(isdigit((int)(stoks[1][0])))
00253 {
00254
00255 stickd.max_block_entries = atoi(stoks[1]);
00256 i++;
00257 }
00258 else
00259 {
00260 FatalError("Bad Sticky-Drop Max Entries Arg",file_name,file_line);
00261 }
00262
00263 }
00264 else if(!strcasecmp(stoks[0], "log"))
00265 {
00266 stickd.log = 1;
00267 i++;
00268 }
00269 else if(!strcasecmp(stoks[0], "log-file"))
00270 {
00271 if(isascii((int)(stoks[1][0])))
00272 {
00273 if (stoks[1][0] == '/')
00274 strlcpy (logpath, stoks[1], STD_BUF);
00275 else
00276 {
00277 strlcpy(logpath, pv.log_dir, STD_BUF);
00278 strlcat(logpath, "/", STD_BUF);
00279 strlcat(logpath, stoks[1], STD_BUF);
00280 }
00281 i++;
00282 }
00283 else
00284 {
00285 FatalError(" %s(%d) => '%s' has invalid value '%s'. ",
00286 file_name, file_line,
00287 stoks[0], stoks[1]);
00288 }
00289 }
00290 else
00291 {
00292 FatalError("%s(%d) => option '%s' is undefined. ",
00293 file_name, file_line, stoks[0]);
00294 }
00295
00296 mSplitFree(&stoks, s_toks);
00297 }
00298 mSplitFree(&toks, num_toks);
00299
00300 }
00301 if(stickd.log)
00302 {
00303 stickd.logfile = fopen(logpath, "a+");
00304
00305 if(stickd.logfile == NULL)
00306 {
00307 FatalError("Can't open logfile: %s", stickd.logpath);
00308 }
00309 }
00310 }
00311
00312
00313 static void sdInitTimeouts(u_char *targs)
00314 {
00315 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Preprocessor: stickydrop-timeouts Initialized\n"););
00316
00317 ParseSDTimeoutArgs(targs);
00318 }
00319
00320
00321 static void ParseSDTimeoutArgs(char *targs)
00322 {
00323 int num_toks, s_toks;
00324 char **toks = NULL;
00325 char **stoks;
00326 int i;
00327 char* index;
00328
00329 sdt.sfportscan = 0;
00330 sdt.portscan2 = 0 ;
00331 sdt.clamav = 0;
00332
00333 if (targs)
00334 {
00335
00336 toks = mSplit(targs, ",", 4, &num_toks, 0);
00337
00338 i=0;
00339
00340 while (i < num_toks)
00341 {
00342 index = toks[i];
00343
00344 while(isspace((int)*index)) index++;
00345
00346 stoks = mSplit(index, " ", 1, &s_toks, 0);
00347 if(!strcasecmp(stoks[0], "sfportscan"))
00348 {
00349 if(isdigit((int)(stoks[1][0])))
00350 {
00351
00352 sdt.sfportscan = atoi(stoks[1]);
00353 i++;
00354 }
00355 else
00356 {
00357 FatalError("Bad Sticky-Drop sfportscan timeout entry",file_name,file_line);
00358 }
00359
00360 }
00361 else if(!strcasecmp(stoks[0], "portscan2"))
00362 {
00363 if(isdigit((int)(stoks[1][0])))
00364 {
00365
00366 sdt.portscan2 = atoi(stoks[1]);
00367 i++;
00368 }
00369 else
00370 {
00371 FatalError("Bad Sticky-Drop portscan2 timeout entry",file_name,file_line);
00372 }
00373 }
00374 else if(!strcasecmp(stoks[0], "clamav"))
00375 {
00376 if(isdigit((int)(stoks[1][0])))
00377 {
00378
00379 sdt.clamav = atoi(stoks[1]);
00380 i++;
00381 }
00382 else
00383 {
00384 FatalError("Bad Sticky-Drop clamav timeout entry",file_name,file_line);
00385 }
00386 }
00387 else
00388 {
00389 FatalError("%s(%d) => option '%s' is undefined. ",
00390 file_name, file_line, stoks[0]);
00391 }
00392
00393 mSplitFree(&stoks, s_toks);
00394 }
00395 mSplitFree(&toks, num_toks);
00396
00397 }
00398 }
00399
00400
00401 void sdInitIgnoreHosts(u_char *hosts)
00402 {
00403 char **toks;
00404 int num_toks;
00405 int num_hosts = 0;
00406 sdHostNode *sdcurrentHost;
00407
00408
00409 sdcurrentHost = NULL;
00410 sdignoreList = NULL;
00411
00412 if(hosts == NULL)
00413 {
00414 ErrorMessage(" ERROR: %s(%d)=> No arguments to "
00415 "stickydrop-ignorehosts, ignoring.\n",
00416 file_name, file_line);
00417 return;
00418 }
00419
00420 toks = mSplit(hosts, " ", 127, &num_toks, '\\');
00421
00422 for(num_hosts = 0; num_hosts < num_toks; num_hosts++)
00423 {
00424 if((sdcurrentHost = (sdHostNode *) calloc(1, sizeof(sdHostNode))) == NULL)
00425 {
00426 FatalError("[!] ERROR: Unable to allocate space for "
00427 "sticky-drop IgnoreHost");
00428 }
00429 sdcurrentHost->address = NULL;
00430 sdcurrentHost->nextNode = sdignoreList;
00431 sdignoreList = sdcurrentHost;
00432
00433
00434 sdScanParseIp(toks[num_hosts], sdcurrentHost);
00435 }
00436
00437 mSplitFree(&toks, num_toks);
00438 }
00439
00440
00441 IpAddrSet* sdIgnoreAllocAddrNode(sdHostNode *host)
00442 {
00443 IpAddrSet *idx;
00444
00445 if((idx = (IpAddrSet *) calloc(1, sizeof(IpAddrSet))) == NULL)
00446 {
00447 FatalError("[!] ERROR: Unable to allocate space for "
00448 "stickyd IP addr\n");
00449 }
00450
00451 idx->next = host->address;
00452 host->address = idx;
00453
00454 return idx;
00455 }
00456
00457
00458 void sdScanParseIp(char *addr, sdHostNode *host)
00459 {
00460 char **toks;
00461 int num_toks;
00462 int i, not_flag;
00463 IpAddrSet *tmp_addr;
00464 char *enbracket, *ports;
00465 char *tmp;
00466
00467 if(addr == NULL)
00468 {
00469 ErrorMessage("ERROR %s(%d) => Undefine address in "
00470 "stickydrop-ignorehosts directive, igoring.\n", file_name,
00471 file_line);
00472
00473 return;
00474 }
00475
00476 if(*addr == '!')
00477 {
00478 host->flags |= EXCEPT_SRC_IP;
00479 addr++;
00480 }
00481
00482 if(*addr == '$')
00483 {
00484 if((tmp = VarGet(addr + 1)) == NULL)
00485 {
00486 ErrorMessage("ERROR %s (%d) => Undefined variable \"%s\", "
00487 "ignoring\n", file_name, file_line, addr);
00488
00489 return;
00490 }
00491 }
00492 else
00493 {
00494 tmp = addr;
00495 }
00496
00497 ports = strrchr(tmp, (int)'@');
00498
00499 if (*tmp == '[')
00500 {
00501 enbracket = strrchr(tmp, (int)']');
00502 if (enbracket) *enbracket = '\x0';
00503
00504 if (ports && enbracket && (ports < enbracket))
00505 {
00506 FatalError("[!] ERROR %s(%d) => syntax error in"
00507 "stickydrop-ignorehosts \"%s\"\n",
00508 file_name, file_line, tmp);
00509 }
00510 toks = mSplit(tmp+1, ",", 128, &num_toks, 0);
00511
00512 for(i = 0; i < num_toks; i++)
00513 {
00514 tmp_addr = sdIgnoreAllocAddrNode(host);
00515
00516 ParseIP(toks[i], tmp_addr);
00517 }
00518
00519 mSplitFree(&toks, num_toks);
00520 }
00521 else
00522 {
00523 if (ports) *ports = '\x0';
00524
00525 tmp_addr = sdIgnoreAllocAddrNode(host);
00526 ParseIP(tmp, tmp_addr);
00527 }
00528
00529 if (ports)
00530 {
00531 ports++;
00532 if (ParsePort(ports, &(host->hsp), &(host->lsp), "ip", ¬_flag))
00533 host->flags |= ANY_SRC_PORT;
00534 if (not_flag)
00535 host->flags |= EXCEPT_SRC_PORT;
00536 } else {
00537 host->flags |= ANY_SRC_PORT;
00538 }
00539
00540 }
00541
00542
00543 void sdInitIgnoreFrom(u_char *args)
00544 {
00545 sdInitIgnorePorts(args, &sdignorePortFrom, &num_ports_from);
00546 }
00547
00548
00549 void sdInitIgnoreTo(u_char *args)
00550 {
00551 sdInitIgnorePorts(args, &sdignorePortTo, &num_ports_to);
00552 }
00553
00554
00555 void sdInitIgnorePorts(u_char *list, u_int32_t **ports, int *num)
00556 {
00557 int new_ports, max_ports;
00558 u_int32_t *pool;
00559 char **toks;
00560 int num_toks;
00561
00562 *ports = NULL;
00563 *num = 0;
00564 max_ports = 0;
00565
00566 if(list == NULL)
00567 {
00568 ErrorMessage(" ERROR: %s(%d)=> No arguments to "
00569 "stickydrop-ignoreports, ignoring.\n",
00570 file_name, file_line);
00571 return;
00572 }
00573
00574 toks = mSplit(list, " ", MAX_PORTS, &num_toks, '\\');
00575
00576 for(;*num < num_toks; (*num)++)
00577 {
00578 if(*num >= max_ports)
00579 {
00580 new_ports = max_ports + MEM_CHUNK;
00581 if((pool = (u_int32_t *) calloc(new_ports, sizeof(u_int32_t))) == NULL)
00582 {
00583 FatalError("[!] ERROR: Unable to allocate space for "
00584 "stickydrop-ignoreports");
00585 }
00586 if (*ports != NULL)
00587 {
00588 memcpy(pool, *ports, max_ports * sizeof(u_int32_t));
00589 free(*ports);
00590 }
00591 max_ports = new_ports;
00592 *ports = pool;
00593 }
00594 (*ports)[*num] = sdScanParsePort(toks[*num]);
00595 }
00596
00597 mSplitFree(&toks, num_toks);
00598
00599 }
00600
00601
00602 u_int32_t sdScanParsePort(char *port)
00603 {
00604 char *tmp;
00605
00606 if(port == NULL)
00607 {
00608 FatalError("ERROR %s(%d) => Undefined ports in "
00609 "stickydrop-ignoreports directive\n",
00610 file_name, file_line);
00611 }
00612
00613 if(*port == '$')
00614 {
00615 if((tmp = VarGet(port + 1)) == NULL)
00616 {
00617 FatalError("ERROR %s (%d) => Undefined variable \"%s\"\n",
00618 file_name, file_line, port);
00619
00620 }
00621 }
00622 else
00623 {
00624 tmp = port;
00625 }
00626
00627 if(!isdigit((int)tmp[0]))
00628 {
00629 FatalError("ERROR %s(%d) => Bad port list to "
00630 "stickydrop-ignoreports\n", file_name, file_line);
00631 }
00632
00633 return((u_int32_t)atol(tmp));
00634 }
00635
00636
00637
00638
00639
00640
00641
00642 int sdBlockTreeSearch(Packet *p, char direction)
00643 {
00644 Attacker tmp;
00645 Attacker *searchval;
00646
00647 if(direction == DIRECTION_SOURCE)
00648 {
00649 tmp.ip = (u_int32_t)p->iph->ip_src.s_addr;
00650
00651 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00652 "Going to search for source ip of: of %s\n",inet_ntoa(p->iph->ip_src)););
00653 }
00654 else if(direction == DIRECTION_DST)
00655 {
00656 tmp.ip = (u_int32_t)p->iph->ip_dst.s_addr;
00657
00658 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00659 "Going to search for source ip of: of %s\n",inet_ntoa(p->iph->ip_dst)););
00660
00661 }
00662
00663 searchval = (Attacker *) ubi_sptFind(stickd.attackerRootPtr, (ubi_btItemPtr)&tmp);
00664
00665 if (searchval != NULL)
00666 {
00667
00668
00669
00670 if(p->pkth->ts.tv_sec >= (searchval->unblocktime.tv_sec))
00671 {
00672 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00673 "Pruning out Attacker due to timeout\n"););
00674
00675 PruneAttackers(p->pkth->ts.tv_sec, 1, NULL);
00676
00677 return(0);
00678 }
00679 else if(direction == DIRECTION_SOURCE)
00680 {
00681 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00682 "Attacker %s was found in tree and we haven't past our unblock mark\n",inet_ntoa(p->iph->ip_src)););
00683
00684 return(1);
00685 }
00686 else if(direction == DIRECTION_DST)
00687 {
00688 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00689 "Attacker %s was found in tree and we haven't past our unblock mark\n",inet_ntoa(p->iph->ip_dst)););
00690
00691 return(1);
00692 }
00693 }
00694 else if(direction == DIRECTION_SOURCE)
00695 {
00696 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00697 "ip address %s not found in block tree\n",inet_ntoa(p->iph->ip_src)););
00698
00699 return(0);
00700 }
00701 else if(direction == DIRECTION_DST)
00702 {
00703 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00704 "ip address %s not found in block tree passing\n",inet_ntoa(p->iph->ip_dst)););
00705
00706 return(0);
00707 }
00708
00709
00710 return(0);
00711 }
00712
00713
00714 int sdIsIgnored(Packet *p, char dir)
00715 {
00716 sdHostNode *sdcurrentHost = sdignoreList;
00717 int i;
00718
00719 for(i = 0; i < num_ports_from; i++)
00720 {
00721 if (p->sp == sdignorePortFrom[i])
00722 {
00723 return(1);
00724 }
00725 }
00726
00727 for(i = 0; i < num_ports_to; i++)
00728 {
00729 if (p->dp == sdignorePortTo[i])
00730 {
00731 return(1);
00732 }
00733 }
00734
00735 while(sdcurrentHost)
00736 {
00737
00738
00739
00740
00741 if(dir == DIRECTION_SOURCE)
00742 {
00743 if(CheckAddrPort(sdcurrentHost->address, sdcurrentHost->hsp,
00744 sdcurrentHost->lsp, p, sdcurrentHost->flags, CHECK_SRC))
00745 {
00746 return(1);
00747 }
00748 }
00749 else if(dir == DIRECTION_DST)
00750 {
00751 if(CheckAddrPort(sdcurrentHost->address, sdcurrentHost->hsp,
00752 sdcurrentHost->lsp, p, sdcurrentHost->flags, INVERSE))
00753 {
00754 return(1);
00755 }
00756 }
00757 sdcurrentHost = sdcurrentHost->nextNode;
00758 }
00759 return(0);
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771 void AddIpToBlockTree(Packet *p, char bdirection, u_int32_t timeout)
00772 {
00773 if((bdirection == DIRECTION_SOURCE) && (sdIsIgnored(p, DIRECTION_SOURCE)))
00774 {
00775 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,"Host %s matched ignore list, not adding to block tree.\n",inet_ntoa(p->iph->ip_src)););
00776 return;
00777 }
00778 else if((bdirection == DIRECTION_DST) && (sdIsIgnored(p, DIRECTION_DST)))
00779 {
00780 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,"Host %s matched ignore list, not adding to block tree.\n",inet_ntoa(p->iph->ip_dst)););
00781 return;
00782 }
00783 else if((bdirection == DIRECTION_SOURCE) && (sdBlockTreeSearch(p, DIRECTION_SOURCE)))
00784 {
00785 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,"Host %s already has an entry in block tree, why in the hell is this true we set p->preprocessors and do_detect to 0.\n",inet_ntoa(p->iph->ip_src)););
00786 return;
00787 }
00788 else if((bdirection == DIRECTION_DST) && (sdBlockTreeSearch(p, DIRECTION_DST)))
00789 {
00790 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,"Host %s already has an entry in block tree, why in the hell is this true we set p->preprocessors and do_detect to 0.\n",inet_ntoa(p->iph->ip_dst)););
00791 return;
00792 }
00793
00794 else
00795 {
00796 Attacker *a = NULL;
00797 MemBucket *mb = NULL;
00798
00799
00800 mb = mempool_alloc(&stickd.AttackerPool);
00801
00802 if(mb == NULL)
00803 {
00804
00805 PruneAttackers(p->pkth->ts.tv_sec, 5, NULL);
00806 }
00807
00808 a = (Attacker *) mb->data;
00809 a->bucket = mb;
00810
00811
00812 if(bdirection == DIRECTION_SOURCE)
00813 {
00814 a->ip = (u_int32_t)p->iph->ip_src.s_addr;
00815 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,"AddIpToBlockTree called going to add ip address %s to block tree\n",inet_ntoa(p->iph->ip_src)););
00816 }
00817 else if(bdirection == DIRECTION_DST)
00818 {
00819 a->ip = (u_int32_t)p->iph->ip_dst.s_addr;
00820 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,"AddIpToBlockTree called going to add ip address %s to block tree\n",inet_ntoa(p->iph->ip_dst)););
00821 }
00822 else
00823 {
00824 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00825 "not inserting into tree we need src or dst\n"););
00826
00827 }
00828
00829 a->blocktime.tv_sec = p->pkth->ts.tv_sec;
00830 a->unblocktime.tv_sec = a->blocktime.tv_sec + timeout;
00831 if(ubi_sptInsert(stickd.attackerRootPtr,
00832 (ubi_btNodePtr)a,
00833 (ubi_btNodePtr)a, NULL) == ubi_trFALSE)
00834 {
00835 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00836 "Entry already exists, or something has gone terribly wrong\n"););
00837
00838 mempool_free(&stickd.AttackerPool,a->bucket);
00839 }
00840 else
00841 {
00842 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00843 "Insert into block tree was successful\n"););
00844 do_detect = 0;
00845 p->preprocessors = 0;
00846 InlineDrop();
00847 }
00848 }
00849 }
00850
00851
00852 void SDLog(Packet *p)
00853 {
00854 char src[STD_BUF];
00855 char dst[STD_BUF];
00856 char timestamp[TIMEBUF_SIZE];
00857 char flagString[9];
00858
00859 strlcpy(src, (char *)inet_ntoa(p->iph->ip_src), sizeof(src));
00860 strlcpy(dst, (char *)inet_ntoa(p->iph->ip_dst), sizeof(dst));
00861 ts_print((struct timeval *) &p->pkth->ts, timestamp);
00862
00863 if(p->tcph)
00864 {
00865 CreateTCPFlagString(p, flagString);
00866 fprintf(stickd.logfile,"Dropped %s TCP %s:%u->%s:%u %s\n", timestamp, src, p->sp, dst, p->dp, flagString);
00867
00868 }
00869 else if(p->udph)
00870 {
00871 fprintf(stickd.logfile,"Dropped %s UDP %s:%u->%s:%u\n", timestamp, src, p->sp, dst, p->dp);
00872
00873 }
00874 else if(p->icmph)
00875 {
00876 fprintf(stickd.logfile, "Dropped %s ICMP %s->%s type: %u code: %u \n", timestamp, src, dst, p->icmph->type, p->icmph->code);
00877
00878 }
00879
00880 fflush(stickd.logfile);
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 void StickyDrop(Packet *p, void *context)
00898 {
00899 if(sdBlockTreeSearch(p, DIRECTION_SOURCE))
00900 {
00901 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00902 "Attacker was found, lets log if specified and drop the packet\n"););
00903 if(stickd.log)
00904 {
00905
00906 SDLog(p);
00907 }
00908
00909
00910
00911 do_detect = 0;
00912 p->preprocessors = 0;
00913 InlineDrop();
00914
00915 }
00916 if(sdBlockTreeSearch(p, DIRECTION_DST))
00917 {
00918 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00919 "Attacker was found, lets log if specified and drop the packet\n"););
00920 if(stickd.log)
00921 {
00922
00923 SDLog(p);
00924 }
00925
00926
00927
00928 do_detect = 0;
00929 p->preprocessors = 0;
00930 InlineDrop();
00931
00932 }
00933 else
00934 {
00935 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00936 "ip address not found in drop list passing\n"););
00937 }
00938 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00939 "Calling Global Prune Check \n"););
00940
00941 PruneAttackers(p->pkth->ts.tv_sec,0,NULL);
00942 }
00943
00944
00945 static int IpAddressCompareFunction(ubi_trItemPtr ItemPtr, ubi_trNodePtr NodePtr)
00946 {
00947 Attacker *A = (Attacker *) NodePtr;
00948 Attacker *B = (Attacker *) ItemPtr;
00949
00950 if(A->ip < B->ip)
00951 {
00952 return 1;
00953 }
00954 else if(A->ip > B->ip)
00955 {
00956 return -1;
00957 }
00958
00959 return 0;
00960 }
00961
00962
00963 static void DeleteAttacker(Attacker *a)
00964 {
00965 Attacker *olda;
00966
00967 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP, "Deleteing Attacker %p\n", a);
00968 DebugMessage(DEBUG_STICKYDROP,
00969 "a->ip: %X\n", a->ip);
00970 DebugMessage(DEBUG_STICKYDROP,
00971 "a->blocktime: %u\n", a->blocktime.tv_sec);
00972 DebugMessage(DEBUG_STICKYDROP,
00973 "a->unblocktime: %u\n", a->unblocktime.tv_sec);
00974
00975 );
00976
00977
00978 olda = (Attacker *) ubi_sptRemove(stickd.attackerRootPtr,
00979 (ubi_btNodePtr) a);
00980
00981 mempool_free(&stickd.AttackerPool,a->bucket);
00982 }
00983
00984
00985 static int PruneAttackers(u_int32_t now, int tokill, Attacker *saveme)
00986 {
00987 Attacker *idx;
00988 u_int32_t pruned = 0;
00989
00990 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
00991 "PruneAttackers called now: "
00992 " %u tokill: %d: saveme: %p, count: %u\n",
00993 now, tokill, saveme,
00994 ubi_trCount(stickd.attackerRootPtr)););
00995
00996 if(ubi_trCount(stickd.attackerRootPtr) == 0)
00997 {
00998 return 0;
00999 }
01000
01001 if(tokill == 0)
01002 {
01003 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
01004 "Running Through Global Prune Check Loop\n"););
01005
01006 idx = (Attacker *) ubi_btFirst((ubi_btNodePtr)stickd.attackerRootPtr->root);
01007
01008 if(idx == NULL)
01009 {
01010 return 0;
01011 }
01012
01013 do
01014 {
01015 if(idx == saveme)
01016 {
01017 idx = (Attacker *) ubi_btNext((ubi_btNodePtr)idx);
01018 continue;
01019 }
01020
01021 if((idx->unblocktime.tv_sec) < now)
01022 {
01023 Attacker *savidx = idx;
01024
01025 if(ubi_trCount(stickd.attackerRootPtr) > 1)
01026 {
01027 idx = (Attacker *) ubi_btNext((ubi_btNodePtr)idx);
01028 DEBUG_WRAP(DebugMessage(DEBUG_STICKYDROP,
01029 "pruning stale sticky-drop entry\n"););
01030 DeleteAttacker(savidx);
01031 pruned++;
01032 }
01033 else
01034 {
01035 DeleteAttacker(savidx);
01036 pruned++;
01037 return pruned;
01038 }
01039 }
01040 else
01041 {
01042 if(idx != NULL && ubi_trCount(stickd.attackerRootPtr) > 1)
01043 {
01044 idx = (Attacker *) ubi_btNext((ubi_btNodePtr)idx);
01045 }
01046 else
01047 {
01048 return pruned;
01049 }
01050 }
01051 } while(idx != NULL);
01052
01053 return pruned;
01054 }
01055 else
01056 {
01057 while(tokill-- && ubi_trCount(stickd.attackerRootPtr) > 0)
01058 {
01059 idx = (Attacker *) ubi_btLeafNode((ubi_btNodePtr)stickd.attackerRootPtr);
01060 DeleteAttacker(idx);
01061 return 0;
01062 }
01063 }
01064 return 0;
01065 }
01066
01067
01068 int SppStickydIsRunning(void)
01069 {
01070 return s_stickyd_running;
01071 }
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 static void PreprocCleanExitFunction(int signal, void *data)
01089 {
01090 }
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107 static void PreprocRestartFunction(int signal, void *foo)
01108 {
01109 }
01110
01111
01112 #endif