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