Main Page | Modules | Class List | Directories | File List | Class Members | File Members | Related Pages

fpcreate.c

Go to the documentation of this file.
00001 /*
00002 **  $Id$
00003 ** 
00004 **  fpcreate.c
00005 **
00006 **  Copyright (C) 2002 Sourcefire,Inc
00007 **  Dan Roelker <droelker@sourcefire.com>
00008 **  Marc Norton <mnorton@sourcefire.com>
00009 **
00010 **  NOTES
00011 **  5.7.02 - Initial Checkin. Norton/Roelker
00012 **
00013 **  This program is free software; you can redistribute it and/or modify
00014 **  it under the terms of the GNU General Public License as published by
00015 **  the Free Software Foundation; either version 2 of the License, or
00016 **  (at your option) any later version.
00017 **
00018 **  This program is distributed in the hope that it will be useful,
00019 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021 **  GNU General Public License for more details.
00022 **
00023 **  You should have received a copy of the GNU General Public License
00024 **  along with this program; if not, write to the Free Software
00025 **  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00026 **
00027 */
00028 
00029 #include <stdio.h>
00030 #include <stdlib.h>
00031 #include <string.h>
00032 
00033 #include "rules.h"
00034 #include "parser.h"
00035 #include "fpcreate.h"
00036 #include "fpdetect.h"
00037 #include "sp_pattern_match.h"
00038 #include "sp_icmp_code_check.h"
00039 #include "sp_icmp_type_check.h"
00040 #include "sp_ip_proto.h"
00041 #include "plugin_enum.h"
00042 #include "util.h"
00043 
00044 #include "mpse.h"
00045 #include "bitop.h"
00046 
00047 /*
00048 #define LOCAL_DEBUG
00049 */
00050 
00051 /*
00052 **  Macro for verifying memory allocation and fail
00053 **  accordingly.
00054 */
00055 #define MEMASSERT(p,s) if(!p){printf("No memory - file:%s %s !\n",__FILE__,s); exit(1);}
00056 /*
00057 **  Main variables to this file. 
00058 **
00059 **  The port-rule-maps map the src-dst ports to rules for
00060 **  udp and tcp, for Ip we map the dst port as the protocol, 
00061 **  and for Icmp we map the dst port to the Icmp type. This 
00062 **  allows us to use the decode packet information to in O(1) 
00063 **  select a group of rules to apply to the packet.  These 
00064 **  rules may have uricontent, content, or they may be no content 
00065 **  rules, or any combination. We process the uricontent 1st,
00066 **  than the content, and than the no content rules for udp/tcp 
00067 **  and icmp, than we process the ip rules.
00068 */
00069 static PORT_RULE_MAP *prmTcpRTNX = NULL;
00070 static PORT_RULE_MAP *prmUdpRTNX = NULL;
00071 static PORT_RULE_MAP *prmIpRTNX  = NULL;
00072 static PORT_RULE_MAP *prmIcmpRTNX= NULL;
00073 
00074 static FPDETECT fpDetect;
00075 
00076 /*
00077 **  The following functions are wrappers to the pcrm routines,
00078 **  that utilize the variables that we have intialized by
00079 **  calling fpCreateFastPacketDetection().  These functions
00080 **  are also used in the file fpdetect.c, where we do lookups
00081 **  on the initialized variables.
00082 */
00083 int prmFindRuleGroupIp(int ip_proto, PORT_GROUP **ip_group, PORT_GROUP ** gen)
00084 {
00085     PORT_GROUP *src;
00086     return prmFindRuleGroup( prmIpRTNX, ip_proto, -1, &src, ip_group, gen);
00087 }
00088 
00089 int prmFindRuleGroupIcmp(int type, PORT_GROUP **type_group, PORT_GROUP ** gen)
00090 {
00091     PORT_GROUP *src;
00092     return prmFindRuleGroup( prmIcmpRTNX, type, -1, &src, type_group, gen);
00093 }
00094 
00095 int prmFindRuleGroupTcp(int dport, int sport, PORT_GROUP ** src, 
00096         PORT_GROUP **dst , PORT_GROUP ** gen)
00097 {
00098     return prmFindRuleGroup( prmTcpRTNX, dport, sport, src, dst , gen);
00099 }
00100 
00101 int prmFindRuleGroupUdp(int dport, int sport, PORT_GROUP ** src, 
00102         PORT_GROUP **dst , PORT_GROUP ** gen)
00103 {
00104     return prmFindRuleGroup( prmUdpRTNX, dport, sport, src, dst , gen);
00105 }
00106 
00107 
00108 /*
00109 **  These Otnhas* functions check the otns for different contents.  This
00110 **  helps us decide later what group (uri, content) the otn will go to.
00111 */
00112 static int OtnHasContent( OptTreeNode * otn ) 
00113 {
00114     if( !otn ) return 0;
00115     
00116     if( otn->ds_list[PLUGIN_PATTERN_MATCH] || otn->ds_list[PLUGIN_PATTERN_MATCH_OR] )
00117     {
00118         return 1; 
00119     }
00120 
00121     return 0;
00122 }
00123 
00124 static int OtnHasUriContent( OptTreeNode * otn ) 
00125 {
00126     if( !otn ) return 0;
00127 
00128     if( otn->ds_list[PLUGIN_PATTERN_MATCH_URI] )
00129         return 1; 
00130 
00131     return 0;
00132 }
00133 
00134 /*
00135 **  
00136 **  NAME
00137 **    CheckPorts::
00138 **
00139 **  DESCRIPTION
00140 **    This function returns the port to use for a given signature.
00141 **    Currently, only signatures that have a unique port (meaning that
00142 **    the port is singular and not a range) are added as specific 
00143 **    ports to the port list.  If there is a range of ports in the
00144 **    signature, then it is added as a generic rule.
00145 **
00146 **    This can be refined at any time, and limiting the number of
00147 **    generic rules would be a good idea.
00148 **
00149 **  FORMAL INPUTS
00150 **    u_short - the high port of the signature range
00151 **    u_short - the low port of the signature range
00152 **
00153 **  FORMAL OUTPUT
00154 **    int - -1 means generic, otherwise it is the port
00155 **
00156 */
00157 static int CheckPorts(u_short high_port, u_short low_port)
00158 {
00159     if( high_port == low_port )
00160     {
00161        return high_port;
00162     }
00163     else
00164     {
00165        return -1;
00166     }
00167 }
00168 
00169 /*
00170 **  The following functions deal with the intialization of the 
00171 **  detection engine.  These are set through parser.c with the
00172 **  option 'config detection:'.  This functionality may be 
00173 **  broken out later into it's own file to separate from this
00174 **  file's functionality.
00175 */
00176 
00177 /*
00178 **  Initialize detection options.
00179 */
00180 int fpInitDetectionEngine()
00181 {
00182     memset(&fpDetect, 0x00, sizeof(fpDetect));
00183 
00184     /*
00185     **  We inspect pkts that are going to be rebuilt and
00186     **  reinjected through snort.
00187     */
00188     fpDetect.inspect_stream_insert = 1;
00189     fpDetect.search_method = MPSE_MWM;
00190     fpDetect.debug = 0;
00191     fpDetect.max_queue_events = 5;
00192 
00193     /*
00194     **  This functions gives fpdetect.c the detection configuration
00195     **  set up in fpcreate.
00196     */
00197     fpSetDetectionOptions(&fpDetect);
00198 
00199     return 0;
00200 }
00201 
00202 /*
00203    Search method is set using "config detect: search-method ac | mwm | auto"
00204 */
00205 int fpSetDetectSearchMethod( char * method )
00206 {
00207         LogMessage("Detection:\n");
00208 
00209         if( !strcasecmp(method,"ac-std") )
00210         {
00211            fpDetect.search_method = MPSE_AC ;
00212            LogMessage("   Search-Method = AC-Std\n");
00213            return 0;
00214         }
00215         if( !strcasecmp(method,"ac") )
00216         {
00217            fpDetect.search_method = MPSE_ACF ;
00218            LogMessage("   Search-Method = AC-Full\n");
00219            return 0;
00220         }
00221         if( !strcasecmp(method,"acs") )
00222         {
00223            fpDetect.search_method = MPSE_ACS ;
00224            LogMessage("   Search-Method = AC-Sparse\n");
00225            return 0;
00226         }
00227         if( !strcasecmp(method,"ac-banded") )
00228         {
00229            fpDetect.search_method = MPSE_ACB ;
00230            LogMessage("   Search-Method = AC-Banded\n");
00231            return 0;
00232         }
00233         if( !strcasecmp(method,"ac-sparsebands") )
00234         {
00235            fpDetect.search_method = MPSE_ACSB ;
00236            LogMessage("   Search-Method = AC-Sparse-Bands\n");
00237            return 0;
00238         }
00239 
00240         if( !strcasecmp(method,"mwm") )
00241         {
00242            fpDetect.search_method = MPSE_MWM ;
00243            LogMessage("   Search-Method = Modified Wu-Manber\n");
00244            return 0;
00245         }
00246 
00247         if( !strcasecmp(method,"lowmem") )
00248         {
00249            fpDetect.search_method = MPSE_LOWMEM ;
00250            LogMessage("   Search-Method = Low-Mem Trie\n");
00251            return 0;
00252         }
00253     return 1;   
00254 }
00255 
00256 /*
00257 **  Set the debug mode for the detection engine.
00258 */
00259 int fpSetDebugMode()
00260 {
00261     fpDetect.debug = 1;
00262     return 0;
00263 }
00264 
00265 /*
00266 **  Revert the detection engine back to not inspecting packets
00267 **  that are going to be rebuilt.
00268 */
00269 int fpSetStreamInsert()
00270 {
00271     fpDetect.inspect_stream_insert = 0;
00272     return 0;
00273 }
00274 
00275 /*
00276 **  Sets the maximum number of events to queue up in fpdetect before
00277 **  selecting an event.
00278 */
00279 int fpSetMaxQueueEvents(int iNum)
00280 {
00281     if(iNum <= 0)
00282     {
00283         return 1;
00284     }
00285 
00286     fpDetect.max_queue_events = iNum;
00287 
00288     return 0;
00289 }
00290 
00291 /*
00292 **  Build a Pattern group for the Uri-Content rules in this group
00293 **
00294 **  The patterns added for each rule must be suffcient so if we find any of them
00295 **  we proceed to fully analyze the OTN and RTN against the packet.
00296 **
00297 */
00298 void BuildMultiPatGroupsUri( PORT_GROUP * pg )
00299 {
00300     OptTreeNode      *otn;
00301     RuleTreeNode     *rtn;
00302     OTNX             *otnx; /* otnx->otn & otnx->rtn */
00303     PatternMatchData *pmd;
00304     RULE_NODE        *rnWalk = NULL;
00305     PMX              *pmx;
00306     void             *mpse_obj;
00307     int               method;
00308 
00309     if(!pg || !pg->pgCount)
00310         return;
00311       
00312     /* test for any Content Rules */
00313     if( !prmGetFirstRuleUri(pg) )
00314         return;
00315 
00316     method = fpDetect.search_method;
00317     
00318     mpse_obj = mpseNew(method);
00319     MEMASSERT(mpse_obj,"mpse_obj-uricontent");
00320 
00321     /*  
00322     **  Save the Multi-Pattern data structure for processing Uri's in this 
00323     **  group later during packet analysis.  
00324     */
00325     pg->pgPatDataUri = mpse_obj;
00326       
00327     /*
00328     **  Initialize the BITOP structure for this
00329     **  port group.  This is most likely going to be initialized
00330     **  by the non-uri BuildMultiPattGroup.  If for some reason there
00331     **  is only uri contents in a port group, then we miss the initialization
00332     **  in the content port groups and catch it here.
00333     */
00334     if( boInitBITOP(&(pg->boRuleNodeID),pg->pgCount) )
00335     {
00336         return;
00337     }
00338 
00339     /*
00340     *  Add in all of the URI contents, since these are effectively OR rules.
00341     *  
00342     */
00343     for( rnWalk=pg->pgUriHead; rnWalk; rnWalk=rnWalk->rnNext)
00344     {
00345         otnx = (OTNX *)rnWalk->rnRuleData;
00346 
00347         otn = otnx->otn;
00348         rtn = otnx->rtn;
00349 
00350         /* Add all of the URI contents */     
00351         pmd = otn->ds_list[PLUGIN_PATTERN_MATCH_URI];
00352         while( pmd )
00353         {
00354             if(pmd->pattern_buf) 
00355             {
00356                pmx = (PMX*)malloc(sizeof(PMX) );
00357                MEMASSERT(pmx,"pmx-uricontent");
00358                pmx->RuleNode    = rnWalk;
00359                pmx->PatternMatchData= pmd;
00360 
00361                /*
00362                **  Add the max content length to this otnx
00363                */
00364                if(otnx->content_length < pmd->pattern_size)
00365                    otnx->content_length = pmd->pattern_size;
00366 
00367                 mpseAddPattern(mpse_obj, pmd->pattern_buf, pmd->pattern_size,
00368                 pmd->nocase,  /* NoCase: 1-NoCase, 0-Case */
00369                 pmd->offset,
00370                 pmd->depth,
00371                 pmx, //(unsigned)rnWalk,        /* rule ptr */ 
00372                 //(unsigned)pmd,
00373                 rnWalk->iRuleNodeID );
00374             }
00375             
00376             pmd = pmd->next;
00377         }
00378     }
00379 
00380     /*
00381     **  This function call sets up an optimized pattern match for Uri
00382     **  contents.  This only works if the minimum size of a pattern is
00383     **  2 chars. If we comment this out we use the standard 1 byte bad
00384     **  character shifts
00385     */
00386     mpseLargeShifts( mpse_obj, 1 );
00387     
00388     mpsePrepPatterns( mpse_obj );
00389 }
00390 
00391 /*
00392 **
00393 **   NAME
00394 **     IsPureNotRule
00395 **
00396 **   DESCRIPTION
00397 **     Checks to see if a rule is a pure not rule.  A pure not rule
00398 **     is a rule that has all "not" contents or Uri contents.
00399 **
00400 **   FORMAL INPUTS
00401 **     PatternMatchData * - the match data to check for not contents.
00402 **
00403 **   FORMAL OUTPUTS
00404 **     int - 1 is rule is a pure not, 0 is rule is not a pure not.
00405 **
00406 */
00407 static int IsPureNotRule( PatternMatchData * pmd )
00408 {
00409     int rcnt=0,ncnt=0;
00410 
00411     for( ;pmd; pmd=pmd->next )
00412     {
00413         rcnt++;
00414         if( pmd->exception_flag ) ncnt++;
00415     }
00416 
00417     if( !rcnt ) return 0;
00418     
00419     return ( rcnt == ncnt ) ;  
00420 }
00421 
00422 /*
00423 **
00424 **  NAME
00425 **    FindLongestPattern
00426 **
00427 **  DESCRIPTION
00428 **    This functions selects the longest pattern out of a set of
00429 **    patterns per snort rule.  By picking the longest pattern, we
00430 **    help the pattern matcher speed and the selection criteria during
00431 **    detection.
00432 **
00433 **  FORMAL INPUTS
00434 **    PatternMatchData * - contents to select largest
00435 **
00436 **  FORMAL OUTPUTS 
00437 **    PatternMatchData * - ptr to largest pattern
00438 **
00439 */
00440 static PatternMatchData * FindLongestPattern( PatternMatchData * pmd )
00441 {
00442     PatternMatchData *pmdmax;
00443    
00444     /* Find the 1st pattern that is not a NOT pattern */           
00445         while( pmd && pmd->exception_flag ) pmd=pmd->next;
00446         
00447         if( !pmd ) return NULL;  /* All Patterns are NOT patterns */
00448       
00449         pmdmax = pmd;
00450         
00451         while( pmd )
00452         {
00453             if(pmd->pattern_buf) 
00454             {
00455                 if( (pmd->pattern_size > pmdmax->pattern_size) && 
00456                         !pmd->exception_flag)
00457                 {
00458                     pmdmax = pmd;
00459                 }
00460             }
00461             pmd = pmd->next;
00462         }
00463         
00464         return pmdmax;
00465 }
00466 
00467 /*
00468 *  Build Content-Pattern Information for this group
00469 */
00470 void BuildMultiPatGroup( PORT_GROUP * pg )
00471 {
00472     OptTreeNode      *otn;
00473     RuleTreeNode     *rtn;
00474     OTNX             *otnx; /* otnx->otn & otnx->rtn */
00475     PatternMatchData *pmd, *pmdmax;
00476     RULE_NODE        *rnWalk = NULL;
00477     PMX              *pmx;
00478     void             *mpse_obj;
00479     /*int maxpats; */
00480     int               method;
00481 
00482     if(!pg || !pg->pgCount)
00483         return;
00484      
00485     /* test for any Content Rules */
00486     if( !prmGetFirstRule(pg) )
00487         return;
00488       
00489     method = fpDetect.search_method;
00490 
00491     mpse_obj = mpseNew( method );
00492     MEMASSERT(mpse_obj,"mpse_obj-content");
00493 
00494     /* Save the Multi-Pattern data structure for processing this group later 
00495        during packet analysis.
00496     */
00497     pg->pgPatData = mpse_obj;
00498 
00499     /*
00500     **  Initialize the BITOP structure for this
00501     **  port group.
00502     */
00503     if( boInitBITOP(&(pg->boRuleNodeID),pg->pgCount) )
00504     {
00505         return;
00506     }
00507       
00508     /*
00509     *  For each content rule, add one of the AND contents,
00510     *  and all of the OR contents
00511     */
00512     for(rnWalk=pg->pgHead; rnWalk; rnWalk=rnWalk->rnNext)
00513     {
00514         otnx = (OTNX *)(rnWalk->rnRuleData);
00515 
00516         otn = otnx->otn;
00517         rtn = otnx->rtn;
00518 
00519         /* Add the longest AND patterns, 'content:' patterns*/
00520         pmd = otn->ds_list[PLUGIN_PATTERN_MATCH];
00521 
00522         /*
00523         **  Add all the content's for the Pure Not rules, 
00524         **  because we will check after processing the packet
00525         **  to see if these pure not rules were hit using the
00526         **  bitop functionality.  If they were hit, then there
00527         **  is no event, otherwise there is an event.
00528         */
00529         if( pmd && IsPureNotRule( pmd ) )
00530         {
00531             /*
00532             **  Pure Not Rules are not supported.
00533             */
00534             LogMessage("SNORT DETECTION ENGINE: Pure Not Rule "
00535                        "'%s' not added to detection engine.  "
00536                        "These rules are not supported at this "
00537                        "time.\n", otn->sigInfo.message);
00538 
00539             while( pmd ) 
00540             {
00541                 if( pmd->pattern_buf ) 
00542                 {
00543                     pmx = (PMX*)malloc(sizeof(PMX) );
00544                     MEMASSERT(pmx,"pmx-!content");
00545                     pmx->RuleNode   = rnWalk;
00546                     pmx->PatternMatchData= pmd;
00547 
00548                     mpseAddPattern( mpse_obj, pmd->pattern_buf, 
00549                       pmd->pattern_size, 
00550                       pmd->nocase,  /* NoCase: 1-NoCase, 0-Case */
00551                       pmd->offset, 
00552                       pmd->depth,
00553                       pmx,  
00554                       rnWalk->iRuleNodeID );
00555                 }
00556 
00557                 pmd = pmd->next;
00558             }
00559 
00560             /* Build the list of pure NOT rules for this group */
00561             prmAddNotNode( pg, (int)rnWalk->iRuleNodeID );
00562         }
00563         else
00564         {
00565             /* Add the longest content for normal or mixed contents */
00566            pmdmax = FindLongestPattern( pmd );  
00567            if( pmdmax )
00568            {
00569                pmx = (PMX*)malloc(sizeof(PMX) );
00570                MEMASSERT(pmx,"pmx-content");
00571                pmx->RuleNode    = rnWalk;
00572                pmx->PatternMatchData= pmdmax;
00573 
00574                otnx->content_length = pmdmax->pattern_size;
00575 
00576                mpseAddPattern( mpse_obj, pmdmax->pattern_buf, pmdmax->pattern_size,
00577                  pmdmax->nocase,  /* NoCase: 1-NoCase, 0-Case */
00578                  pmdmax->offset, 
00579                  pmdmax->depth,
00580                  pmx,  
00581                rnWalk->iRuleNodeID );
00582            }
00583         }
00584            
00585         /* Add all of the OR contents 'file-list' content */     
00586         pmd = otn->ds_list[PLUGIN_PATTERN_MATCH_OR];
00587         while( pmd )
00588         {
00589             if(pmd->pattern_buf) 
00590             {
00591                 pmx = (PMX*)malloc(sizeof(PMX) );
00592                 MEMASSERT(pmx,"pmx-uricontent");
00593                 pmx->RuleNode    = rnWalk;
00594                 pmx->PatternMatchData= pmd;
00595 
00596                 mpseAddPattern( mpse_obj, pmd->pattern_buf, pmd->pattern_size,
00597                 pmd->nocase,  /* NoCase: 1-NoCase, 0-Case */
00598                 pmd->offset,
00599                 pmd->depth,
00600                 pmx, //rnWalk,        /* rule ptr */ 
00601                 //(unsigned)pmd,
00602                 rnWalk->iRuleNodeID );
00603             }
00604 
00605             pmd = pmd->next;
00606         }
00607     }
00608 
00609     /*
00610     **  We don't have PrepLongPatterns here, because we've found that
00611     **  the minimum length for the BM shift is not fulfilled by snort's
00612     **  ruleset.  We may add this in later, after initial performance
00613     **  has been verified.
00614     */
00615     
00616     mpsePrepPatterns( mpse_obj );
00617 }
00618 
00619 /*
00620 **
00621 **  NAME
00622 **    BuildMultiPatternGroups::
00623 **
00624 **  DESCRIPTION
00625 **    This is the main function that sets up all the
00626 **    port groups for a given PORT_RULE_MAP.  We iterate
00627 **    through the dst and src ports building up port groups
00628 **    where possible, and then build the generic set.
00629 **
00630 **  FORMAL INPUTS
00631 **    PORT_RULE_MAP * - the port rule map to build
00632 **
00633 **  FORMAL OUTPUTS
00634 **    None
00635 **
00636 */
00637 void BuildMultiPatternGroups( PORT_RULE_MAP * prm )
00638 {
00639     int i;
00640     PORT_GROUP * pg;
00641      
00642     for(i=0;i<MAX_PORTS;i++)
00643     {
00644         pg = prmFindSrcRuleGroup( prm, i );
00645         if(pg)
00646         {
00647             BuildMultiPatGroup( pg );
00648             BuildMultiPatGroupsUri( pg );
00649         }
00650 
00651         pg = prmFindDstRuleGroup( prm, i );
00652         if(pg)
00653         {
00654             BuildMultiPatGroup( pg );
00655             BuildMultiPatGroupsUri( pg );
00656         }
00657     }
00658 
00659     pg = prm->prmGeneric;
00660      
00661     BuildMultiPatGroup( pg );
00662     BuildMultiPatGroupsUri( pg );
00663 }
00664 
00665 
00666 /*
00667 **
00668 **  NAME
00669 **    fpCreateFastPacketDetection::
00670 **
00671 **  DESCRIPTION
00672 **    fpCreateFastPacketDetection initializes and creates the whole
00673 **    FastPacket detection engine.  It reads the list of RTNs and OTNs
00674 **    that snort creates on startup, and adds the RTN/OTN pair for a
00675 **    rule to the appropriate PORT_GROUP.  The routine builds up
00676 **    PORT_RULE_MAPs for TCP, UDP, ICMP, and IP.  More can easily be
00677 **    added if necessary.
00678 **
00679 **    After initialization and setup, stats are printed out about the
00680 **    different PORT_GROUPS.  
00681 **
00682 **  FORMAL INPUTS
00683 **    None
00684 **
00685 **  FORMAL OUTPUTS
00686 **    int - 0 is successful, other is failure.
00687 **
00688 */
00689 int fpCreateFastPacketDetection()
00690 {
00691     RuleListNode *rule;
00692     RuleTreeNode *rtn;
00693     int sport;
00694     int dport;
00695     OptTreeNode * otn;
00696     int iBiDirectional = 0;
00697 
00698     OTNX * otnx;
00699 
00700     extern RuleListNode *RuleLists;
00701 
00702     prmTcpRTNX = prmNewMap();
00703     if(prmTcpRTNX == NULL)
00704         return 1;
00705 
00706     prmUdpRTNX = prmNewMap();
00707     if(prmUdpRTNX == NULL)
00708         return 1;
00709 
00710     prmIpRTNX = prmNewMap();
00711     if(prmIpRTNX == NULL)
00712         return 1;
00713 
00714     prmIcmpRTNX = prmNewMap();
00715     if(prmIcmpRTNX == NULL)
00716         return 1;
00717 
00718     for (rule=RuleLists; rule; rule=rule->next)
00719     {
00720         if(!rule->RuleList)
00721             continue;
00722 
00723         /*
00724         **  Process TCP signatures
00725         */
00726         if(rule->RuleList->TcpList)
00727         {
00728             for(rtn = rule->RuleList->TcpList; rtn != NULL; rtn = rtn->right)
00729             {
00730 #ifdef LOCAL_DEBUG
00731                 printf("** TCP\n");
00732                 printf("** bidirectional = %s\n",
00733                         (rtn->flags & BIDIRECTIONAL) ? "YES" : "NO");
00734                 printf("** not sp_flag = %d\n", rtn->not_sp_flag);
00735                 printf("** not dp_flag = %d\n", rtn->not_dp_flag);
00736                 printf("** hsp = %u\n", rtn->hsp);
00737                 printf("** lsp = %u\n", rtn->lsp);
00738                 printf("** hdp = %u\n", rtn->hdp);
00739                 printf("** ldp = %u\n\n", rtn->ldp);
00740 #endif
00741                 /*
00742                 **  Check for bi-directional rules
00743                 */
00744                 if(rtn->flags & BIDIRECTIONAL)
00745                 {
00746                     iBiDirectional = 1;
00747                 }else{
00748                     iBiDirectional = 0;
00749                 }
00750 
00751 
00752                 sport = CheckPorts(rtn->hsp, rtn->lsp);
00753 
00754                 if( rtn->flags & ANY_SRC_PORT ) sport = -1;
00755 
00756                 if( sport > 0 &&  rtn->not_sp_flag > 0 )
00757                 {
00758                     sport = -1;
00759                 }
00760 
00761                 dport = CheckPorts(rtn->hdp, rtn->ldp);
00762 
00763                 if( rtn->flags & ANY_DST_PORT ) dport = -1;
00764 
00765                 if( dport > 0 && rtn->not_dp_flag > 0 )
00766                 {
00767                     dport = -1;
00768                 }
00769 
00770                 /* Walk OTN list -Add as Content/UriContent, or NoContent */
00771                 for( otn = rtn->down; otn; otn=otn->next )
00772                 {
00773                     otnx = malloc( sizeof(OTNX) );
00774                     MEMASSERT(otnx,"otnx-TCP");
00775 
00776                     otnx->otn = otn;
00777                     otnx->rtn = rtn;
00778                     otnx->content_length = 0;
00779 
00780                     if( OtnHasContent( otn ) )
00781                     {
00782                         if(fpDetect.debug)
00783                         {
00784                             printf("TCP Content-Rule[dst=%d,src=%d] %s\n",
00785                                     dport,sport,otn->sigInfo.message);
00786                         }
00787                         prmAddRule(prmTcpRTNX, dport, sport, otnx);
00788 
00789                         if(iBiDirectional && (sport!=dport))
00790                         {
00791                             /*
00792                             **  We switch the ports.
00793                             */
00794                             prmAddRule(prmTcpRTNX, sport, dport, otnx);
00795                         }
00796                     }
00797                     if( OtnHasUriContent( otn ) )
00798                     {
00799                         if(fpDetect.debug)
00800                         {
00801                             printf("TCP UriContent-Rule[dst=%d,src=%d] %s\n",
00802                                     dport,sport,otn->sigInfo.message);
00803                         }
00804                         prmAddRuleUri(prmTcpRTNX, dport, sport, otnx);
00805 
00806                         if(iBiDirectional && (sport!=dport) )
00807                         {
00808                             /*
00809                             **  We switch the ports.
00810                             */
00811                             prmAddRuleUri(prmTcpRTNX, sport, dport, otnx);
00812                         }
00813                     }
00814                     if( !OtnHasContent( otn ) &&  !OtnHasUriContent( otn ) )
00815                     {
00816                         if(fpDetect.debug)
00817                         {
00818                             printf("TCP NoContent-Rule[dst=%d,src=%d] %s\n",
00819                                     dport,sport,otn->sigInfo.message);
00820                         }
00821                         prmAddRuleNC(prmTcpRTNX, dport, sport, otnx);
00822 
00823                         if(iBiDirectional && (sport!=dport))
00824                         {
00825                             /*
00826                             **  We switch the ports.
00827                             */
00828                             prmAddRuleNC(prmTcpRTNX, sport, dport, otnx);
00829                         }
00830                     }
00831                 }
00832             }
00833         }
00834 
00835         /*
00836         **  Process UDP signatures
00837         */
00838         if(rule->RuleList->UdpList)
00839         {
00840             for(rtn = rule->RuleList->UdpList; rtn != NULL; rtn = rtn->right)
00841             {
00842 #ifdef LOCAL_DEBUG
00843                 printf("** UDP\n");
00844                 printf("** bidirectional = %s\n",
00845                         (rtn->flags & BIDIRECTIONAL) ? "YES" : "NO");
00846                 printf("** not sp_flag = %d\n", rtn->not_sp_flag);
00847                 printf("** not dp_flag = %d\n", rtn->not_dp_flag);
00848                 printf("** hsp = %u\n", rtn->hsp);
00849                 printf("** lsp = %u\n", rtn->lsp);
00850                 printf("** hdp = %u\n", rtn->hdp);
00851                 printf("** ldp = %u\n\n", rtn->ldp);
00852 #endif
00853                 /*
00854                 **  Check for bi-directional rules
00855                 */
00856                 if(rtn->flags & BIDIRECTIONAL)
00857                 {
00858                     iBiDirectional = 1;
00859                 }else{
00860                     iBiDirectional = 0;
00861                 }
00862 
00863                 sport = CheckPorts(rtn->hsp, rtn->lsp);
00864 
00865                 if( rtn->flags & ANY_SRC_PORT ) sport = -1;
00866 
00867                 if(sport > 0 &&  rtn->not_sp_flag > 0 )
00868                 {
00869                     sport = -1;
00870                 }
00871 
00872                 dport = CheckPorts(rtn->hdp, rtn->ldp);
00873 
00874                 if( rtn->flags & ANY_DST_PORT ) dport = -1;
00875 
00876 
00877                 if(dport > 0 && rtn->not_dp_flag > 0 )
00878                 {
00879                     dport = -1;
00880                 }
00881 
00882                 /* Walk OTN list -Add as Content, or NoContent */
00883                 for( otn = rtn->down; otn; otn=otn->next )
00884                 {
00885                     otnx = malloc( sizeof(OTNX) );
00886                     MEMASSERT(otnx,"otnx-UDP");
00887 
00888                     otnx->otn = otn;
00889                     otnx->rtn = rtn;
00890                     otnx->content_length = 0;
00891 
00892                     if( OtnHasContent( otn ) )
00893                     {
00894                         if(fpDetect.debug)
00895                         {
00896                             printf("UDP Content-Rule[dst=%d,src=%d] %s\n",
00897                                     dport,sport,otn->sigInfo.message);
00898                         }
00899                         prmAddRule(prmUdpRTNX, dport, sport, otnx);
00900 
00901                         /*
00902                         **  If rule is bi-directional we switch
00903                         **  the ports.
00904                         */
00905                         if(iBiDirectional && (sport!=dport))
00906                         {
00907                             prmAddRule(prmUdpRTNX, sport, dport, otnx);
00908                         }
00909                     }
00910                     else
00911                     {
00912                         if(fpDetect.debug)
00913                         {
00914                                         printf("UDP NoContent-Rule[dst=%d,src=%d] %s\n",
00915                                     dport,sport,otn->sigInfo.message);
00916                         }
00917                         prmAddRuleNC(prmUdpRTNX, dport, sport, otnx);
00918 
00919                         /*
00920                         **  If rule is bi-directional we switch
00921                         **  the ports.
00922                         */
00923                         if(iBiDirectional && (dport != sport) )
00924                         {
00925                             prmAddRuleNC(prmUdpRTNX, sport, dport, otnx);
00926                         }
00927                     }
00928                 }
00929             }
00930         }
00931 
00932         /*
00933         **  Process ICMP signatures
00934         */
00935         if(rule->RuleList->IcmpList)
00936         {
00937             for(rtn = rule->RuleList->IcmpList; rtn != NULL; rtn = rtn->right)
00938             {
00939                /* Walk OTN list -Add as Content, or NoContent */
00940                 for( otn = rtn->down; otn; otn=otn->next )
00941                 {
00942                     int type;
00943                     IcmpTypeCheckData * IcmpType;
00944 
00945                     otnx = malloc( sizeof(OTNX) );
00946                     MEMASSERT(otnx,"otnx-ICMP");
00947 
00948                     otnx->otn = otn;
00949                     otnx->rtn = rtn;
00950                     otnx->content_length = 0;
00951                     
00952                     IcmpType = (IcmpTypeCheckData *)otn->ds_list[PLUGIN_ICMP_TYPE];
00953                     if( IcmpType && (IcmpType->operator == ICMP_TYPE_TEST_EQ) )
00954                     {
00955                         type = IcmpType->icmp_type;
00956                     }
00957                     else
00958                     {
00959                         type = -1;
00960                     }
00961 
00962                     if( OtnHasContent( otn ) )
00963                     {
00964                         if(fpDetect.debug)
00965                         {
00966                             printf("ICMP Type=%d Content-Rule  %s\n",
00967                                     type,otn->sigInfo.message);
00968                         }
00969                         prmAddRule(prmIcmpRTNX, type, -1, otnx);
00970                     }
00971                     else
00972                     {
00973                         if(fpDetect.debug)
00974                         {
00975                             printf("ICMP Type=%d NoContent-Rule  %s\n",
00976                                     type,otn->sigInfo.message);
00977                         }
00978                         prmAddRuleNC(prmIcmpRTNX, type, -1, otnx);
00979                     }
00980                 }
00981             }
00982         }
00983 
00984         /*
00985         **  Process IP signatures
00986         **
00987         **  NOTE:
00988         **  We may want to revisit this and add IP rules for TCP and
00989         **  UDP into the right port groups using the rule ports, instead
00990         **  of just using the generic port.
00991         */
00992         if(rule->RuleList->IpList)
00993         {
00994             for(rtn = rule->RuleList->IpList; rtn != NULL; rtn = rtn->right)
00995             {
00996                 /* Walk OTN list -Add as Content, or NoContent */
00997                 for( otn=rtn->down; otn; otn=otn->next )
00998                 {
00999                     IpProtoData * IpProto;
01000                     int protocol;
01001                     
01002                     otnx = malloc( sizeof(OTNX) );
01003                     MEMASSERT(otnx,"otnx-IP");
01004 
01005                     otnx->otn = otn;
01006                     otnx->rtn = rtn;
01007                     otnx->content_length = 0;
01008 
01009                     IpProto =  
01010                         (IpProtoData *)otn->ds_list[PLUGIN_IP_PROTO_CHECK] ;
01011 
01012                     if( IpProto )
01013                     {
01014                         protocol = IpProto->protocol;
01015                         if( IpProto->comparison_flag == GREATER_THAN )
01016                             protocol=-1; 
01017                         
01018                         if( IpProto->comparison_flag == LESS_THAN )
01019                             protocol=-1; 
01020 
01021                         if( IpProto->not_flag )
01022                             protocol=-1;
01023                     }
01024                     else
01025                     {
01026                         protocol = -1;
01027                     }
01028                     
01029                     if( OtnHasContent( otn ) )
01030                     {
01031                         if(fpDetect.debug)
01032                         {
01033                             printf("IP Proto=%d Content-Rule %s\n",
01034                                     protocol,otn->sigInfo.message);
01035                         }
01036                         prmAddRule(prmIpRTNX, protocol, -1, otnx);
01037 
01038                         if(protocol == IPPROTO_TCP || protocol == -1)
01039                         {
01040                             prmAddRule(prmTcpRTNX, -1, -1, otnx);
01041                         }
01042                         
01043                         if(protocol == IPPROTO_UDP || protocol == -1)
01044                         {
01045                             prmAddRule(prmUdpRTNX, -1, -1, otnx);
01046                         }
01047 
01048                         if(protocol == IPPROTO_ICMP || protocol == -1)
01049                         {
01050                             prmAddRule(prmIcmpRTNX, -1, -1, otnx);
01051                         }
01052                     }
01053                     else
01054                     {
01055                         if(fpDetect.debug)
01056                         {
01057                             printf("IP Proto=%d NoContent-Rule %s\n",
01058                                     protocol,otn->sigInfo.message);
01059                         }
01060                         prmAddRuleNC(prmIpRTNX, protocol, -1, otnx);
01061 
01062                         if(protocol == IPPROTO_TCP || protocol == -1)
01063                         {
01064                             prmAddRuleNC(prmTcpRTNX, -1, -1, otnx);
01065                         }
01066                         
01067                         if(protocol == IPPROTO_UDP || protocol == -1)
01068                         {
01069                             prmAddRuleNC(prmUdpRTNX, -1, -1, otnx);
01070                         }
01071 
01072                         if(protocol == IPPROTO_ICMP || protocol == -1)
01073                         {
01074                             prmAddRuleNC(prmIcmpRTNX, -1, -1, otnx);
01075                         }
01076                     }
01077                 }
01078             }
01079         }
01080     }
01081 
01082     prmCompileGroups(prmTcpRTNX);
01083     prmCompileGroups(prmUdpRTNX);
01084     prmCompileGroups(prmIcmpRTNX);
01085     prmCompileGroups(prmIpRTNX);
01086 
01087     BuildMultiPatternGroups(prmTcpRTNX);
01088     BuildMultiPatternGroups(prmUdpRTNX);
01089     BuildMultiPatternGroups(prmIcmpRTNX);
01090     BuildMultiPatternGroups(prmIpRTNX);
01091 
01092     if(fpDetect.debug)
01093     {
01094         printf("\n** TCP Rule Group Stats -- ");
01095         prmShowStats(prmTcpRTNX);
01096     
01097         printf("\n** UDP Rule Group Stats -- ");
01098         prmShowStats(prmUdpRTNX);
01099     
01100         printf("\n** ICMP Rule Group Stats -- ");
01101         prmShowStats(prmIcmpRTNX);
01102     
01103         printf("\n** IP Rule Group Stats -- ");
01104         prmShowStats(prmIpRTNX);
01105     }
01106 
01107     return 0;
01108 }
01109 
01110 /*
01111 **  Wrapper for prmShowEventStats
01112 */
01113 int fpShowEventStats()
01114 {
01115     /*
01116     **  If not debug, then we don't print anything.
01117     */
01118     if(!fpDetect.debug)
01119     {
01120         return 1;
01121     }
01122 
01123     printf("\n** TCP Event Stats -- ");  prmShowEventStats(prmTcpRTNX);
01124     printf("\n** UDP Event Stats -- ");  prmShowEventStats(prmUdpRTNX);
01125     printf("\n** ICMP Event Stats -- "); prmShowEventStats(prmIcmpRTNX);
01126     printf("\n** IP Event Stats -- ");    prmShowEventStats(prmIpRTNX);
01127     return 0;
01128 }
01129    
01130 

Generated on Sun May 14 14:51:13 2006 by  doxygen 1.4.2