00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023
00024 #include <sys/types.h>
00025 #include <unistd.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028
00029 #ifdef HAVE_STRINGS_H
00030 #include <strings.h>
00031 #endif
00032
00033 #ifndef WIN32
00034 #include <sys/socket.h>
00035 #include <netinet/in.h>
00036 #include <arpa/inet.h>
00037 #endif
00038 #include <time.h>
00039 #include <errno.h>
00040
00041
00042 #include "plugbase.h"
00043 #include "spo_plugbase.h"
00044 #include "snort.h"
00045 #include "debug.h"
00046 #include "util.h"
00047 #include "log.h"
00048 #include "detect.h"
00049
00050
00051 #include "preprocessors/spp_portscan.h"
00052 #include "preprocessors/spp_rpc_decode.h"
00053 #include "preprocessors/spp_bo.h"
00054 #include "preprocessors/spp_telnet_negotiation.h"
00055 #include "preprocessors/spp_stream4.h"
00056 #include "preprocessors/spp_frag2.h"
00057 #include "preprocessors/spp_arpspoof.h"
00058 #include "preprocessors/spp_conversation.h"
00059 #include "preprocessors/spp_portscan2.h"
00060 #include "preprocessors/spp_perfmonitor.h"
00061 #include "preprocessors/spp_httpinspect.h"
00062 #include "preprocessors/spp_flow.h"
00063 #include "preprocessors/spp_sfportscan.h"
00064 #include "preprocessors/spp_frag3.h"
00065 #include "preprocessors/spp_xlink2state.h"
00066 #include "preprocessors/spp_clamav.h"
00067 #ifdef GIDS
00068 #include "preprocessors/spp_stickydrop.h"
00069 #include "preprocessors/spp_bait_and_switch.h"
00070 #endif
00071
00072
00073 #include "detection-plugins/sp_pattern_match.h"
00074 #include "detection-plugins/sp_tcp_flag_check.h"
00075 #include "detection-plugins/sp_icmp_type_check.h"
00076 #include "detection-plugins/sp_icmp_code_check.h"
00077 #include "detection-plugins/sp_ttl_check.h"
00078 #include "detection-plugins/sp_ip_id_check.h"
00079 #include "detection-plugins/sp_tcp_ack_check.h"
00080 #include "detection-plugins/sp_tcp_seq_check.h"
00081 #include "detection-plugins/sp_dsize_check.h"
00082 #include "detection-plugins/sp_ipoption_check.h"
00083 #include "detection-plugins/sp_rpc_check.h"
00084 #include "detection-plugins/sp_icmp_id_check.h"
00085 #include "detection-plugins/sp_icmp_seq_check.h"
00086 #include "detection-plugins/sp_session.h"
00087 #include "detection-plugins/sp_ip_tos_check.h"
00088 #include "detection-plugins/sp_ip_fragbits.h"
00089 #include "detection-plugins/sp_tcp_win_check.h"
00090 #include "detection-plugins/sp_ip_same_check.h"
00091 #include "detection-plugins/sp_ip_proto.h"
00092 #include "detection-plugins/sp_ip_same_check.h"
00093 #include "detection-plugins/sp_clientserver.h"
00094 #include "detection-plugins/sp_byte_check.h"
00095 #include "detection-plugins/sp_byte_jump.h"
00096 #include "detection-plugins/sp_isdataat.h"
00097 #include "detection-plugins/sp_pcre.h"
00098 #include "detection-plugins/sp_flowbits.h"
00099 #include "detection-plugins/sp_asn1.h"
00100 #ifdef ENABLE_RESPONSE
00101 #include "detection-plugins/sp_react.h"
00102 #include "detection-plugins/sp_respond.h"
00103 #endif
00104 #include "detection-plugins/sp_ftpbounce.h"
00105 #ifdef GIDS
00106 #include "detection-plugins/sp_stickydrop.h"
00107 #include "detection-plugins/sp_bait_and_switch.h"
00108 #endif
00109
00110
00111
00112 #include "output-plugins/spo_alert_syslog.h"
00113 #include "output-plugins/spo_log_tcpdump.h"
00114 #include "output-plugins/spo_database.h"
00115 #include "output-plugins/spo_alert_fast.h"
00116 #include "output-plugins/spo_alert_full.h"
00117 #include "output-plugins/spo_alert_unixsock.h"
00118 #include "output-plugins/spo_csv.h"
00119 #include "output-plugins/spo_unified.h"
00120 #include "output-plugins/spo_log_null.h"
00121 #include "output-plugins/spo_log_ascii.h"
00122 #ifdef GIDS
00123 #include "output-plugins/spo_bait_and_switch.h"
00124 #include "output-plugins/spo_stickydrop.h"
00125 #endif
00126 #ifdef HAVE_LIBPRELUDE
00127 #include "output-plugins/spo_alert_prelude.h"
00128 #endif
00129
00130 #ifdef LINUX
00131 #include "output-plugins/spo_alert_sf_socket.h"
00132 #endif
00133
00134 PluginSignalFuncNode *PluginShutdownList;
00135 PluginSignalFuncNode *PluginCleanExitList;
00136 PluginSignalFuncNode *PluginRestartList;
00137
00138 extern int file_line;
00139 extern char *file_name;
00140
00141
00142
00143
00144
00145 KeywordXlateList *KeywordList;
00146
00147 void InitPlugIns()
00148 {
00149 if(!pv.quiet_flag)
00150 {
00151 LogMessage("Initializing Plug-ins!\n");
00152 }
00153 SetupPatternMatch();
00154 SetupTCPFlagCheck();
00155 SetupIcmpTypeCheck();
00156 SetupIcmpCodeCheck();
00157 SetupTtlCheck();
00158 SetupIpIdCheck();
00159 SetupTcpAckCheck();
00160 SetupTcpSeqCheck();
00161 SetupDsizeCheck();
00162 SetupIpOptionCheck();
00163 SetupRpcCheck();
00164 SetupIcmpIdCheck();
00165 SetupIcmpSeqCheck();
00166 SetupSession();
00167 SetupIpTosCheck();
00168 SetupFragBits();
00169 SetupFragOffset();
00170 SetupTcpWinCheck();
00171 SetupIpProto();
00172 SetupIpSameCheck();
00173 SetupClientServer();
00174 SetupByteTest();
00175 SetupByteJump();
00176 SetupIsDataAt();
00177 SetupPcre();
00178 SetupFlowBits();
00179 SetupAsn1();
00180 #ifdef ENABLE_RESPONSE
00181 SetupReact();
00182 SetupRespond();
00183 #endif
00184 SetupFTPBounce();
00185 #ifdef GIDS
00186 SetupStickyDSp();
00187 #ifndef IPFW
00188 SetupBandSp();
00189 #endif
00190 #endif
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 void RegisterPlugin(char *keyword, void (*func) (char *, OptTreeNode *, int))
00208 {
00209 KeywordXlateList *idx;
00210
00211 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Registering keyword:func => %s:%p\n",
00212 keyword, func););
00213
00214 idx = KeywordList;
00215
00216 if(idx == NULL)
00217 {
00218 KeywordList = (KeywordXlateList *) calloc(sizeof(KeywordXlateList),
00219 sizeof(char));
00220
00221 KeywordList->entry.keyword = (char *) calloc(strlen(keyword) + 1,
00222 sizeof(char));
00223 strncpy(KeywordList->entry.keyword, keyword, strlen(keyword)+1);
00224 KeywordList->entry.func = func;
00225 }
00226 else
00227 {
00228
00229 while(idx->next != NULL)
00230 {
00231 if(!strcasecmp(idx->entry.keyword, keyword))
00232 {
00233 FatalError("RegisterPlugin: Duplicate detection plugin keyword:"
00234 " (%s) (%s)!\n", idx->entry.keyword, keyword);
00235 }
00236 idx = idx->next;
00237 }
00238
00239 idx->next = (KeywordXlateList *) calloc(sizeof(KeywordXlateList),
00240 sizeof(char));
00241
00242 idx = idx->next;
00243
00244 idx->entry.keyword = (char *) calloc(strlen(keyword) + 1, sizeof(char));
00245 strncpy(idx->entry.keyword, keyword, strlen(keyword)+1);
00246 idx->entry.func = func;
00247 }
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 void DumpPlugIns()
00265 {
00266 KeywordXlateList *idx;
00267
00268 if(pv.quiet_flag)
00269 return;
00270
00271 idx = KeywordList;
00272
00273 printf("-------------------------------------------------\n");
00274 printf(" Keyword | Plugin Registered @\n");
00275 printf("-------------------------------------------------\n");
00276 while(idx != NULL)
00277 {
00278 printf("%-13s: %p\n", idx->entry.keyword, idx->entry.func);
00279 idx = idx->next;
00280 }
00281 printf("-------------------------------------------------\n\n");
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 OptFpList *AddOptFuncToList(int (*func) (Packet *, struct _OptTreeNode *,
00298 struct _OptFpList *), OptTreeNode * otn)
00299 {
00300 OptFpList *idx;
00301
00302 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n"););
00303
00304
00305 idx = otn->opt_func;
00306
00307
00308 if(idx == NULL)
00309 {
00310
00311 otn->opt_func = (OptFpList *) calloc(sizeof(OptFpList), sizeof(char));
00312
00313 if(otn->opt_func == NULL)
00314 {
00315 FatalError("new node calloc failed: %s\n",
00316 strerror(errno));
00317 }
00318
00319
00320 otn->opt_func->OptTestFunc = func;
00321
00322 idx = otn->opt_func;
00323 }
00324 else
00325 {
00326
00327 while(idx->next != NULL)
00328 {
00329 idx = idx->next;
00330 }
00331
00332
00333 idx->next = (OptFpList *) calloc(sizeof(OptFpList), sizeof(char));
00334
00335 if(idx->next == NULL)
00336 {
00337 FatalError("AddOptFuncToList new node calloc failed: %s\n",
00338 strerror(errno));
00339 }
00340
00341
00342 idx = idx->next;
00343
00344
00345 idx->OptTestFunc = func;
00346
00347 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set OptTestFunc to %p\n",
00348 func););
00349 }
00350
00351 return idx;
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 void AddRspFuncToList(int (*func) (Packet *, struct _RspFpList *), OptTreeNode * otn, void *params)
00367 {
00368 RspFpList *idx;
00369
00370 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding response to list\n"););
00371
00372
00373 idx = otn->rsp_func;
00374
00375
00376 if(idx == NULL)
00377 {
00378
00379 otn->rsp_func = (RspFpList *) calloc(sizeof(RspFpList), sizeof(char));
00380
00381 if(otn->rsp_func == NULL)
00382 {
00383 FatalError("AddRspFuncToList new node calloc failed: %s\n", strerror(errno));
00384 }
00385
00386 otn->rsp_func->ResponseFunc = func;
00387 otn->rsp_func->params = params;
00388 }
00389 else
00390 {
00391
00392 while(idx->next != NULL)
00393 {
00394 idx = idx->next;
00395 }
00396
00397
00398 idx->next = (RspFpList *) calloc(sizeof(RspFpList), sizeof(char));
00399
00400 if(idx->next == NULL)
00401 {
00402 FatalError("AddRspFuncToList new node calloc failed: %s\n", strerror(errno));
00403 }
00404
00405 idx->next->ResponseFunc = func;
00406 idx->next->params = params;
00407
00408 DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set ResponseFunc to %p\n", func););
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417 PreprocessKeywordList *PreprocessKeywords;
00418 PreprocessFuncNode *PreprocessList;
00419
00420 void InitPreprocessors()
00421 {
00422 if(!pv.quiet_flag)
00423 {
00424 LogMessage("Initializing Preprocessors!\n");
00425 }
00426 SetupPortscan();
00427 SetupPortscanIgnoreHosts();
00428 SetupRpcDecode();
00429 SetupBo();
00430 SetupTelNeg();
00431 SetupStream4();
00432 SetupFrag2();
00433 SetupARPspoof();
00434 SetupConv();
00435 SetupScan2();
00436 SetupHttpInspect();
00437 SetupPerfMonitor();
00438 SetupFlow();
00439 SetupPsng();
00440 SetupFrag3();
00441 SetupXLINK2STATE();
00442 #ifdef CLAMAV
00443 SetupClamAV();
00444 #endif
00445 #ifdef GIDS
00446 SetupStickyDrop();
00447 #ifndef IPFW
00448 SetupBaitAndSwitch();
00449 #endif
00450 #endif
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 void RegisterPreprocessor(char *keyword, void (*func) (u_char *))
00467 {
00468 PreprocessKeywordList *idx;
00469
00470 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:preproc => %s:%p\n", keyword, func););
00471
00472 idx = PreprocessKeywords;
00473
00474 if(idx == NULL)
00475 {
00476
00477 PreprocessKeywords = (PreprocessKeywordList *)
00478 calloc(sizeof(PreprocessKeywordList), sizeof(char));
00479
00480
00481 PreprocessKeywords->entry.keyword = (char *) calloc(strlen(keyword) + 1,
00482 sizeof(char));
00483
00484
00485 strncpy(PreprocessKeywords->entry.keyword, keyword, strlen(keyword)+1);
00486
00487
00488 PreprocessKeywords->entry.func = (void *) func;
00489 }
00490 else
00491 {
00492
00493 while(idx->next != NULL)
00494 {
00495 if(!strcasecmp(idx->entry.keyword, keyword))
00496 {
00497 FatalError("%s(%d) => Duplicate preprocessor keyword!\n",
00498 file_name, file_line);
00499 }
00500 idx = idx->next;
00501 }
00502
00503 idx->next = (PreprocessKeywordList *)
00504 calloc(sizeof(PreprocessKeywordList), sizeof(char));
00505
00506 idx = idx->next;
00507
00508
00509 idx->entry.keyword = (char *) calloc(strlen(keyword) + 1, sizeof(char));
00510
00511
00512 strncpy(idx->entry.keyword, keyword, strlen(keyword)+1);
00513
00514
00515 idx->entry.func = (void *) func;
00516 }
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 void DumpPreprocessors()
00534 {
00535 PreprocessKeywordList *idx;
00536
00537 if(pv.quiet_flag)
00538 return;
00539 idx = PreprocessKeywords;
00540
00541 printf("-------------------------------------------------\n");
00542 printf(" Keyword | Preprocessor @ \n");
00543 printf("-------------------------------------------------\n");
00544 while(idx != NULL)
00545 {
00546 printf("%-13s: %p\n", idx->entry.keyword, idx->entry.func);
00547 idx = idx->next;
00548 }
00549 printf("-------------------------------------------------\n\n");
00550 }
00551
00552
00553 PreprocessFuncNode *AddFuncToPreprocList(void (*func) (Packet *, void *))
00554 {
00555 PreprocessFuncNode *idx;
00556
00557 idx = PreprocessList;
00558
00559 if(idx == NULL)
00560 {
00561 PreprocessList = (PreprocessFuncNode *)
00562 calloc(sizeof(PreprocessFuncNode), sizeof(char));
00563
00564 PreprocessList->func = func;
00565
00566 idx = PreprocessList;
00567 }
00568 else
00569 {
00570 while(idx->next != NULL)
00571 idx = idx->next;
00572
00573 idx->next = (PreprocessFuncNode *)
00574 calloc(sizeof(PreprocessFuncNode), sizeof(char));
00575
00576 idx = idx->next;
00577 idx->func = func;
00578 }
00579
00580 return idx;
00581 }
00582
00583
00584
00585
00586 OutputKeywordList *OutputKeywords;
00587 OutputFuncNode *AlertList;
00588 OutputFuncNode *LogList;
00589 OutputFuncNode *AppendOutputFuncList(void (*) (Packet *,char *,void *,Event*),
00590 void *, OutputFuncNode *);
00591
00592
00593 void InitOutputPlugins()
00594 {
00595 if(!pv.quiet_flag)
00596 {
00597 LogMessage("Initializing Output Plugins!\n");
00598 }
00599 AlertSyslogSetup();
00600 LogTcpdumpSetup();
00601 DatabaseSetup();
00602 AlertFastSetup();
00603 AlertFullSetup();
00604 #ifndef WIN32
00605
00606 AlertUnixSockSetup();
00607 #endif
00608 AlertCSVSetup();
00609 LogNullSetup();
00610 UnifiedSetup();
00611 LogAsciiSetup();
00612 #ifdef LINUX
00613
00614 AlertSFSocket_Setup();
00615 #endif
00616 #ifdef GIDS
00617 AlertStickyDSetup();
00618 #ifndef IPFW
00619 AlertBandSetup();
00620 #endif
00621 #endif
00622 #ifdef HAVE_LIBPRELUDE
00623 AlertPreludeSetup();
00624 #endif
00625 }
00626
00627 int ActivateOutputPlugin(char *plugin_name, char *plugin_options)
00628 {
00629 OutputKeywordNode *plugin;
00630
00631 if(!plugin_name)
00632 return -1;
00633
00634
00635 if(!(plugin = GetOutputPlugin(plugin_name)))
00636 return -1;
00637
00638 switch(plugin->node_type)
00639 {
00640 case NT_OUTPUT_SPECIAL:
00641 plugin->func(plugin_options);
00642 break;
00643 case NT_OUTPUT_ALERT:
00644 plugin->func(plugin_options);
00645 break;
00646 case NT_OUTPUT_LOG:
00647 plugin->func(plugin_options);
00648 break;
00649 }
00650 #ifdef GIDS
00651 if(SppStickydIsRunning())
00652 {
00653 if(!StickyDOutputInitRun())
00654 {
00655 plugin = GetOutputPlugin("alert_StickyD");
00656
00657 if(plugin != NULL)
00658 {
00659 plugin->func(NULL);
00660 }
00661 else
00662 {
00663 LogMessage("Something went wrong with auto enable of alert_StickyD\n\n\n\n");
00664 }
00665 }
00666 else
00667 {
00668 LogMessage("Great, I'm glad you found the alert_StickyD output plugin but there is no need to enable it in the conf as we do it for you \n");
00669 }
00670 }
00671 #ifndef IPFW
00672
00673 if(BaitAndSwitchIsRunning())
00674 {
00675 if(!BaitAndSwitchOutputInitRun())
00676 {
00677 plugin = GetOutputPlugin("alert_BandS");
00678
00679 if(plugin != NULL)
00680 {
00681 plugin->func(NULL);
00682 }
00683 else
00684 {
00685 LogMessage("Something went wrong with auto enable of alert_BandS\n\n\n\n");
00686 }
00687 }
00688 else
00689 {
00690 LogMessage("Great, I'm glad you found the alert_BandS output plugin but there is no need to enable it in the conf as we do it for you \n");
00691 }
00692 }
00693 #endif
00694 #endif
00695
00696 return 0;
00697 }
00698
00699 OutputKeywordNode *GetOutputPlugin(char *plugin_name)
00700 {
00701 OutputKeywordList *list_node;
00702
00703 if(!plugin_name)
00704 return NULL;
00705
00706 list_node = OutputKeywords;
00707
00708 while(list_node)
00709 {
00710 if(strcasecmp(plugin_name, list_node->entry.keyword) == 0)
00711 return &(list_node->entry);
00712 list_node = list_node->next;
00713 }
00714 FatalError("unknown output plugin: '%s'",
00715 plugin_name);
00716
00717 return NULL;
00718 }
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 void RegisterOutputPlugin(char *keyword, int type, void (*func) (u_char *))
00736 {
00737 OutputKeywordList *idx;
00738
00739 DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:output => %s:%p\n",
00740 keyword, func););
00741
00742 idx = OutputKeywords;
00743
00744 if(idx == NULL)
00745 {
00746
00747 OutputKeywords = (OutputKeywordList *) calloc(sizeof(OutputKeywordList),
00748 sizeof(char));
00749
00750 idx = OutputKeywords;
00751 }
00752 else
00753 {
00754
00755 while(idx->next != NULL)
00756 {
00757 if(!strcasecmp(idx->entry.keyword, keyword))
00758 {
00759 FatalError("%s(%d) => Duplicate output keyword!\n",
00760 file_name, file_line);
00761 }
00762 idx = idx->next;
00763 }
00764
00765 idx->next = (OutputKeywordList *) calloc(sizeof(OutputKeywordList),
00766 sizeof(char));
00767
00768 idx = idx->next;
00769 }
00770
00771
00772 idx->entry.keyword = (char *) calloc(strlen(keyword) + 1, sizeof(char));
00773
00774
00775 strncpy(idx->entry.keyword, keyword, strlen(keyword)+1);
00776
00777
00778
00779
00780
00781 idx->entry.node_type = (char) type;
00782
00783
00784 idx->entry.func = (void *) func;
00785 }
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799 void DumpOutputPlugins()
00800 {
00801 OutputKeywordList *idx;
00802
00803 if(pv.quiet_flag)
00804 return;
00805
00806 idx = OutputKeywords;
00807
00808 printf("-------------------------------------------------\n");
00809 printf(" Keyword | Output @ \n");
00810 printf("-------------------------------------------------\n");
00811 while(idx != NULL)
00812 {
00813 printf("%-13s: %p\n", idx->entry.keyword, idx->entry.func);
00814 idx = idx->next;
00815 }
00816 printf("-------------------------------------------------\n\n");
00817 }
00818
00819 extern ListHead *head_tmp;
00820
00821 void AddFuncToOutputList(void (*func) (Packet *, char *, void *, Event *),
00822 char node_type, void *arg)
00823 {
00824 switch(node_type)
00825 {
00826 case NT_OUTPUT_ALERT:
00827 if(head_tmp != NULL)
00828 head_tmp->AlertList = AppendOutputFuncList(func, arg,
00829 head_tmp->AlertList);
00830 else
00831 AlertList = AppendOutputFuncList(func, arg, AlertList);
00832 break;
00833
00834 case NT_OUTPUT_LOG:
00835 if(head_tmp != NULL)
00836 head_tmp->LogList = AppendOutputFuncList(func, arg,
00837 head_tmp->LogList);
00838 else
00839 LogList = AppendOutputFuncList(func, arg, LogList);
00840 break;
00841
00842 default:
00843
00844 FatalError("Unknown nodetype: %i. Possible bug, please report\n",
00845 node_type);
00846 }
00847
00848 return;
00849 }
00850
00851
00852 OutputFuncNode *AppendOutputFuncList(
00853 void (*func) (Packet *, char *, void *, Event *),
00854 void *arg, OutputFuncNode * list)
00855 {
00856 OutputFuncNode *idx = list;
00857
00858 if(idx == NULL)
00859 {
00860 idx = (OutputFuncNode *) calloc(sizeof(OutputFuncNode), sizeof(char));
00861 idx->func = func;
00862 idx->arg = arg;
00863 list = idx;
00864 }
00865 else
00866 {
00867 while(idx->next != NULL)
00868 idx = idx->next;
00869
00870 idx->next = (OutputFuncNode *) calloc(sizeof(OutputFuncNode),
00871 sizeof(char));
00872 idx = idx->next;
00873 idx->func = func;
00874 idx->arg = arg;
00875 }
00876
00877 idx->next = NULL;
00878
00879 return list;
00880 }
00881
00882
00883
00884
00885
00886 void SetOutputList(void (*func) (Packet *, char *, void *, Event *),
00887 char node_type, void *arg)
00888 {
00889 OutputFuncNode *idx;
00890 OutputFuncNode *prev;
00891
00892 switch(node_type)
00893 {
00894 case NT_OUTPUT_ALERT:
00895 prev = AlertList;
00896 break;
00897
00898 case NT_OUTPUT_LOG:
00899 prev = LogList;
00900 break;
00901
00902 default:
00903 return;
00904 }
00905
00906 while(prev != NULL)
00907 {
00908 idx = prev->next;
00909 free(prev);
00910 prev = idx;
00911 }
00912
00913 switch(node_type)
00914 {
00915 case NT_OUTPUT_ALERT:
00916 AlertList = prev;
00917 break;
00918
00919 case NT_OUTPUT_LOG:
00920 LogList = prev;
00921 break;
00922
00923 default:
00924 return;
00925 }
00926
00927 AddFuncToOutputList(func, node_type, arg);
00928
00929 return;
00930 }
00931
00932
00933
00934
00935
00936
00937
00938
00939 int PacketIsIP(Packet * p)
00940 {
00941 if(p->iph != NULL)
00942 return 1;
00943
00944 return 0;
00945 }
00946
00947
00948
00949 int PacketIsTCP(Packet * p)
00950 {
00951 if(p->iph != NULL && p->tcph != NULL)
00952 return 1;
00953
00954 return 0;
00955 }
00956
00957
00958
00959 int PacketIsUDP(Packet * p)
00960 {
00961 if(p->iph != NULL && p->udph != NULL)
00962 return 1;
00963
00964 return 0;
00965 }
00966
00967
00968
00969 int PacketIsICMP(Packet * p)
00970 {
00971 if(p->iph != NULL && p->icmph != NULL)
00972 return 1;
00973
00974 return 0;
00975 }
00976
00977
00978
00979 int DestinationIpIsHomenet(Packet * p)
00980 {
00981 if((p->iph->ip_dst.s_addr & pv.netmask) == pv.homenet)
00982 {
00983 return 1;
00984 }
00985 return 0;
00986 }
00987
00988
00989
00990 int SourceIpIsHomenet(Packet * p)
00991 {
00992 if((p->iph->ip_src.s_addr & pv.netmask) == pv.homenet)
00993 {
00994 return 1;
00995 }
00996 return 0;
00997 }
00998
00999 int CheckNet(struct in_addr * compare, struct in_addr * compare2)
01000 {
01001 if(compare->s_addr == compare2->s_addr)
01002 {
01003 return 1;
01004 }
01005 return 0;
01006 }
01007
01008
01009 void AddFuncToRestartList(void (*func) (int, void *), void *arg)
01010 {
01011 PluginRestartList = AddFuncToSignalList(func, arg, PluginRestartList);
01012 }
01013
01014 void AddFuncToCleanExitList(void (*func) (int, void *), void *arg)
01015 {
01016 PluginCleanExitList = AddFuncToSignalList(func, arg, PluginCleanExitList);
01017 }
01018
01019 void AddFuncToShutdownList(void (*func) (int, void *), void *arg)
01020 {
01021 PluginShutdownList = AddFuncToSignalList(func, arg, PluginShutdownList);
01022 }
01023
01024 PluginSignalFuncNode *AddFuncToSignalList(void (*func) (int, void *), void *arg,
01025 PluginSignalFuncNode * list)
01026 {
01027 PluginSignalFuncNode *idx;
01028
01029 idx = list;
01030
01031 if(idx == NULL)
01032 {
01033 idx = (PluginSignalFuncNode *) calloc(sizeof(PluginSignalFuncNode), sizeof(char));
01034
01035 idx->func = func;
01036 idx->arg = arg;
01037 list = idx;
01038 }
01039 else
01040 {
01041 while(idx->next != NULL)
01042 idx = idx->next;
01043
01044 idx->next = (PluginSignalFuncNode *) calloc(sizeof(PluginSignalFuncNode), sizeof(char));
01045
01046 idx = idx->next;
01047 idx->func = func;
01048 idx->arg = arg;
01049 }
01050 idx->next = NULL;
01051
01052 return list;
01053 }
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068 char *GetUniqueName(char * iface)
01069 {
01070 char * rptr;
01071 static char uniq_name[256];
01072
01073 if (iface == NULL) LogMessage("Interface is NULL. Name may not be unique for the host\n");
01074 #ifndef WIN32
01075 rptr = GetIP(iface);
01076 if(rptr == NULL || !strcmp(rptr, "unknown"))
01077 #endif
01078 {
01079 snprintf(uniq_name, 255, "%s:%s\n",GetHostname(),iface);
01080 rptr = uniq_name;
01081 }
01082 if (pv.verbose_flag) LogMessage("Node unique name is: %s\n", rptr);
01083 return rptr;
01084 }
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099 char *GetIP(char * iface)
01100 {
01101 struct ifreq ifr;
01102 struct sockaddr_in *addr;
01103 int s;
01104
01105 if(iface)
01106 {
01107
01108
01109 s = socket(PF_INET, SOCK_DGRAM, 0);
01110 if(s == -1)
01111 {
01112 FatalError("Problem establishing socket to find IP address for interface: %s\n", iface);
01113 }
01114
01115 strncpy(ifr.ifr_name, iface, strlen(iface) + 1);
01116
01117 #ifndef WIN32
01118 if(ioctl(s, SIOCGIFADDR, &ifr) < 0) return NULL;
01119 else
01120 #endif
01121 {
01122 addr = (struct sockaddr_in *) &ifr.ifr_broadaddr;
01123 }
01124 close(s);
01125
01126 return strdup(inet_ntoa(addr->sin_addr));
01127 }
01128 else
01129 {
01130 return "unknown";
01131 }
01132 }
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 char *GetHostname()
01146 {
01147 #ifdef WIN32
01148 DWORD bufflen = 256;
01149 static char buff[256];
01150 GetComputerName(buff, &bufflen);
01151 return buff;
01152 #else
01153 char * error = "unknown";
01154 if(getenv("HOSTNAME")) return getenv("HOSTNAME");
01155 else if(getenv("HOST")) return getenv("HOST");
01156 else return error;
01157 #endif
01158 }
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172 char *GetTimestamp(register const struct timeval *tvp, int tz)
01173 {
01174 struct tm *lt;
01175 char * buf;
01176 int msec;
01177
01178 buf = (char *)calloc(SMALLBUFFER, sizeof(char));
01179
01180 msec = tvp->tv_usec / 1000;
01181
01182 if(pv.use_utc == 1)
01183 {
01184 lt = gmtime((time_t *)&tvp->tv_sec);
01185 snprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
01186 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
01187 lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
01188 }
01189 else
01190 {
01191 lt = localtime((time_t *)&tvp->tv_sec);
01192 snprintf(buf, SMALLBUFFER,
01193 "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
01194 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
01195 lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz);
01196 }
01197
01198 return buf;
01199 }
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212 int GetLocalTimezone()
01213 {
01214 time_t ut;
01215 struct tm * ltm;
01216 long seconds_away_from_utc;
01217
01218 time(&ut);
01219 ltm = localtime(&ut);
01220
01221 #if defined(WIN32) || defined(SOLARIS) || defined(AIX)
01222
01223
01224 seconds_away_from_utc = timezone;
01225 #else
01226 seconds_away_from_utc = ltm->tm_gmtoff;
01227 #endif
01228
01229 return seconds_away_from_utc/3600;
01230 }
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243 char *GetCurrentTimestamp()
01244 {
01245 struct tm *lt;
01246 struct timezone tz;
01247 struct timeval tv;
01248 struct timeval *tvp;
01249 char * buf;
01250 int tzone;
01251 int msec;
01252
01253 buf = (char *)calloc(SMALLBUFFER, sizeof(char));
01254
01255 bzero((char *)&tz,sizeof(tz));
01256 gettimeofday(&tv,&tz);
01257 tvp = &tv;
01258
01259 msec = tvp->tv_usec/1000;
01260
01261 if(pv.use_utc == 1)
01262 {
01263 lt = gmtime((time_t *)&tvp->tv_sec);
01264 snprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
01265 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
01266 lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
01267 }
01268 else
01269 {
01270 lt = localtime((time_t *)&tvp->tv_sec);
01271
01272 tzone = GetLocalTimezone();
01273
01274 snprintf(buf, SMALLBUFFER,
01275 "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
01276 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
01277 lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tzone);
01278 }
01279
01280 return buf;
01281 }
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298 char * base64(u_char * xdata, int length)
01299 {
01300 int count, cols, bits, c, char_count;
01301 unsigned char alpha[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
01302 char * payloadptr;
01303 char * output;
01304 char_count = 0;
01305 bits = 0;
01306 cols = 0;
01307
01308 output = (char *)malloc( (unsigned int) (length * 1.5 + 4) );
01309
01310 payloadptr = output;
01311
01312 for(count = 0; count < length; count++)
01313 {
01314 c = xdata[count];
01315
01316 if(c > 255)
01317 {
01318 ErrorMessage("plugbase.c->base64(): encountered char > 255 (decimal %d)\n If you see this error message a char is more than one byte on your machine\n This means your base64 results can not be trusted", c);
01319 }
01320
01321 bits += c;
01322 char_count++;
01323
01324 if(char_count == 3)
01325 {
01326 *output = alpha[bits >> 18]; output++;
01327 *output = alpha[(bits >> 12) & 0x3f]; output++;
01328 *output = alpha[(bits >> 6) & 0x3f]; output++;
01329 *output = alpha[bits & 0x3f]; output++;
01330 cols += 4;
01331 if(cols == 72)
01332 {
01333 *output = '\n'; output++;
01334 cols = 0;
01335 }
01336 bits = 0;
01337 char_count = 0;
01338 }
01339 else
01340 {
01341 bits <<= 8;
01342 }
01343 }
01344
01345 if(char_count != 0)
01346 {
01347 bits <<= 16 - (8 * char_count);
01348 *output = alpha[bits >> 18]; output++;
01349 *output = alpha[(bits >> 12) & 0x3f]; output++;
01350 if(char_count == 1)
01351 {
01352 *output = '='; output++;
01353 *output = '='; output++;
01354 }
01355 else
01356 {
01357 *output = alpha[(bits >> 6) & 0x3f];
01358 output++; *output = '=';
01359 output++;
01360 }
01361 }
01362 *output = '\0';
01363 return payloadptr;
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379 char *ascii(u_char *xdata, int length)
01380 {
01381 char *d_ptr, *ret_val;
01382 int i,count = 0;
01383 int size;
01384
01385 if(xdata == NULL)
01386 {
01387 return NULL;
01388 }
01389
01390 for(i=0;i<length;i++)
01391 {
01392 if(xdata[i] == '<')
01393 count+=4;
01394 else if(xdata[i] == '&')
01395 count+=5;
01396 else if(xdata[i] == '>')
01397 count += 4;
01398 }
01399
01400 size = length + count + 1;
01401 ret_val = (char *) malloc(size);
01402
01403 if(ret_val == NULL)
01404 {
01405 LogMessage("plugbase.c: ascii(): Out of memory, can't log anything!\n");
01406 return NULL;
01407 }
01408
01409 memset(ret_val, '\0',(length + count + 1));
01410
01411 d_ptr = ret_val;
01412
01413 for(i=0;i<length;i++)
01414 {
01415 if((xdata[i] > 0x1F) && (xdata[i] < 0x7F))
01416 {
01417 if(xdata[i] == '<')
01418 {
01419 strncpy(d_ptr, "<", size - (d_ptr - ret_val));
01420 d_ptr+=4;
01421 }
01422 else if(xdata[i] == '&')
01423 {
01424 strncpy(d_ptr, "&", size - (d_ptr - ret_val));
01425 d_ptr += 5;
01426 }
01427 else if(xdata[i] == '>')
01428 {
01429 strncpy(d_ptr, ">", size - (d_ptr - ret_val));
01430 d_ptr += 4;
01431 }
01432 else
01433 {
01434 *d_ptr++ = xdata[i];
01435 }
01436 }
01437 else
01438 {
01439 *d_ptr++ = '.';
01440 }
01441 }
01442
01443 *d_ptr++ = '\0';
01444
01445 return ret_val;
01446 }
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461 char *hex(u_char *xdata, int length)
01462 {
01463 int x;
01464 char *rval;
01465 char *buf;
01466
01467 buf = (char *)malloc(length * 2 + 1);
01468 rval = buf;
01469
01470 for(x=0; x < length; x++)
01471 {
01472 snprintf(buf, 3, "%02X", xdata[x]);
01473 buf += 2;
01474 }
01475
01476 rval[length * 2] = '\0';
01477
01478 return rval;
01479 }
01480
01481
01482
01483 char *fasthex(u_char *xdata, int length)
01484 {
01485 char conv[] = "0123456789ABCDEF";
01486 char *retbuf = NULL;
01487 char *index;
01488 char *end;
01489 char *ridx;
01490
01491 index = xdata;
01492 end = xdata + length;
01493 retbuf = (char *) calloc((length*2)+1, sizeof(char));
01494 ridx = retbuf;
01495
01496 while(index < end)
01497 {
01498 *ridx++ = conv[((*index & 0xFF)>>4)];
01499 *ridx++ = conv[((*index & 0xFF)&0x0F)];
01500 index++;
01501 }
01502
01503 return retbuf;
01504 }
01505