[Snort-devel] parser.c cleanups + poor man's port list support (patches)

Daniel J. Roelker droelker at ...402...
Tue Jan 6 10:45:04 EST 2004


Thanks a lot for the patches, Andreas.

The port list feature for rules is definitely on the feature list for
snort.  The problem with just implementing port list functionality is it
that breaks a single rule into multiple rules and may have an affect on
the high-speed rule optimization.  So we're developing port list
functionality in the rule optimization phase.

However, if user's want to test out the port list patch and tell us if
it affects snort performance, please let us know.  Maybe it won't have
as much of an impact as we think, and then maybe we can add a much
simpler port list implementation.  

Just a word of advice to user's that want to try this out, don't put 100
unique ports in the source port and 100 unique ports in the destination
port of a single rule or you'll get 10,000 unique rules out of a single
rule.  Just do the math before you implement a large port list and
combine source and destination port lists in a single rule.

Thanks again Andreas.

Dan

On Tue, 2003-12-30 at 17:42, Andreas Östling wrote:
> 
> Hello,
> 
> While fooling around in parser.c I became aware (after a while) that 
> changes to the rule parsing has to be done in both ParseRule() and 
> ParseDeclaredRuleType() (for user-defined ruletypes) which seems to me a 
> bit weird since they are almost identical. Is there a reason for this 
> that I'm missing? Otherwise I'd suggest that they are joined into one 
> function so it becomes easier to maintain. The attached 
> parser-cleanup.diff is my attempt at a patch that moves the 
> ruletype-specific stuff into ParseRule() and deletes 
> ParseDeclaredRuleType(). A positive side-effect of this is that the syntax 
> checks would then be the same for both type of rules (there are currently 
> stricter/better checks in ParseRule() than in ParseDeclaredRuleType(), 
> which I think is wrong).
> 
> 
> Now over to the port list stuff...
> 
> Many people (including me) have been missing the possibility to specify 
> port lists in rules for a long time, i.e. 
> "alert tcp any any -> any [21,25,...]".
> The issue has been discussed several times but AFAIK nothing has 
> happened since then (?). You could of course do the usual:
> 
> var SOMEPORT 21
> include somefile.rules
> var SOMEPORT 25
> include somefile.rules
> 
> But I find that a bit ugly and hard to maintain if you have many and 
> large port lists. To solve this the right way seemed like too much work so 
> I decided to make a simple workaround that at least solves my problems. 
> The attached parser-portlist.diff makes it possible to specify a list of 
> ports (both source and destination). The list is simply split so that each 
> port creates a new rule.
> 
> So for example this rule:
> alert tcp any any -> any [21,25]
> 
> Expands to these two:
> alert tcp any any -> any 21
> alert tcp any any -> any 25
> 
> And this one:
> alert tcp any [1024,1026] -> any [123,999,12345]
> 
> Expands to these six:
> alert tcp any 1024 -> any 123
> alert tcp any 1024 -> any 999
> alert tcp any 1024 -> any 12345
> alert tcp any 1026 -> any 123
> alert tcp any 1026 -> any 999
> alert tcp any 1026 -> any 12345
> 
> And so on... You can of course use variables as well and also combine it 
> with ranges, like "var SOMEPORTS [1,23,25:30,35]", and then use $SOMEPORTS 
> as port specification.
> 
> The major drawback of doing it this way is obviously that negations 
> (![1,3,5]) don't work, but personally I've never had the need of doing 
> negations on lists anyway (and pass rules with port lists will still 
> work). I've been using the patch for a while with no problems that I know 
> of, but are there any other drawbacks that I'm missing?
> Or are there any work going on that fixes this in a better way soon?
> 
> (note: parser-cleanup.diff must be applied before parser-portlist.diff, 
> or use parser-combined.diff which contains both. All are against HEAD.)
> 
> /Andreas
> ----
> 

> diff snort.org/src/parser.c snort/src/parser.c
> --- snort.org/src/parser.c	Tue Dec 30 21:19:08 2003
> +++ snort/src/parser.c	Tue Dec 30 21:19:57 2003
> @@ -466,6 +466,7 @@
>      int protocol = 0;
>      char *tmp;
>      RuleTreeNode proto_node;
> +    RuleListNode *node = RuleLists;
>  
>      /* chop off the <CR/LF> from the string */
>      strip(prule);
> @@ -575,10 +576,23 @@
>   
>          case RULE_UNKNOWN:
>              DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Unknown rule type, might be declared\n"););
> -            ParseDeclaredRuleType(rule);
> -            mSplitFree(&toks, num_toks);
> -            return;
>  
> +            /* find out if this ruletype has been declared */
> +            while(node != NULL)
> +            {
> +                if(!strcasecmp(node->name, toks[0]))
> +                    break;
> +                node = node->next;
> +            }
> +
> +            if(node == NULL)
> +            {
> +                 FatalError("%s(%d) => Unknown rule type: %s\n",
> +                            file_name, file_line, toks[0]);
> +            }
> +
> +            break; 
> +
>          default:
>              DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Invalid input: %s\n", prule););
>              mSplitFree(&toks, num_toks);
> @@ -601,9 +615,11 @@
>          return;
>      }
>  
> +    if (rule_type == RULE_UNKNOWN)
> +        proto_node.type = node->mode;
> +    else
> +        proto_node.type = rule_type;
>  
> -    proto_node.type = rule_type;
> -
>      /* set the rule protocol */
>      protocol = WhichProto(toks[1]);
>  
> @@ -717,6 +733,10 @@
>              ProcessHeadNode(&proto_node, &Dynamic, protocol);
>              break;
>  
> +        case RULE_UNKNOWN:
> +            ProcessHeadNode(&proto_node, node->RuleList, protocol);
> +            break;
> +
>          default:
>              FatalError("Unable to determine rule type (%s) for processing, exiting!\n", toks[0]);
>      }
> @@ -725,7 +745,10 @@
>  
>      DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Parsing Rule Options...\n"););
>  
> -    ParseRuleOptions(rule, rule_type, protocol);
> +    if (rule_type == RULE_UNKNOWN)
> +        ParseRuleOptions(rule, node->mode, protocol);
> +    else
> +        ParseRuleOptions(rule, rule_type, protocol);
>  
>      mSplitFree(&toks, num_toks);
>  
> @@ -2432,7 +2455,7 @@
>      }
>      else
>      {
> -        FatalError("%s(%d) => bad port number: %s", file_name,
> +        FatalError("%s(%d) => bad port number: %s\n", file_name,
>                     file_line, port);
>      }
>  
> @@ -3961,168 +3984,6 @@
>  
>      return;
>  }
> -
> -
> -/* Adapted from ParseRule in rules.c */
> -void ParseDeclaredRuleType(char *rule)
> -{
> -    char **toks;
> -    int num_toks;
> -    RuleListNode *node;
> -    int protocol;
> -    RuleTreeNode proto_node;
> -
> -    toks = mSplit(rule, " ", 10, &num_toks, 0);
> -    node = RuleLists;
> -
> -    while(node != NULL)
> -    {
> -        if(!strcasecmp(node->name, toks[0]))
> -            break;
> -        node = node->next;
> -    }
> -
> -    /* if we did not find a match, then there is no such ruletype */
> -    if(node == NULL)
> -    {
> -        FatalError("%s(%d) => Unknown rule type: %s\n",
> -                   file_name, file_line, toks[0]);
> -    }
> -
> -#ifdef DEBUG
> -	LogMessage("[**] Rule start\n");
> -	LogMessage("Rule id: %s\n", toks[0]);
> -	LogMessage("Rule type: ");
> -
> -    switch(node->mode)
> -    {
> -        case RULE_PASS:
> -	LogMessage("Pass\n");
> -            break;
> -        case RULE_LOG:
> -	LogMessage("Log\n");
> -            break;
> -        case RULE_ALERT:
> -	LogMessage("Alert\n");
> -            break;
> -        default:
> -	LogMessage("Unknown\n");
> -    }
> -#endif
> -
> -    /* the rest of this function is almost identical to code in ParseRule */
> -    bzero((char *) &proto_node, sizeof(RuleTreeNode));
> -
> -    proto_node.type = node->mode;
> -
> -    /* set the rule protocol */
> -    protocol = WhichProto(toks[1]);
> -
> -    /* Process the IP address and CIDR netmask */
> -    /* changed version 1.2.1 */
> -    /*
> -     * "any" IP's are now set to addr 0, netmask 0, and the normal rules are
> -     * applied instead of checking the flag
> -     */
> -    /*
> -     * if we see a "!<ip number>" we need to set a flag so that we can
> -     * properly deal with it when we are processing packets
> -     */
> -    /*
> -   if( *toks[2] == '!' )    
> -   {
> -       proto_node.flags |= EXCEPT_SRC_IP;
> -       ParseIP(&toks[2][1], (u_long *) & proto_node.sip,
> -               (u_long *) & proto_node.smask);
> -   }
> -   else
> -   {
> -       ParseIP(toks[2], (u_long *) & proto_node.sip,
> -               (u_long *) & proto_node.smask);
> -   }*/
> -
> -    ProcessIP(toks[2], &proto_node, SRC);
> -
> -    /* do the same for the port */
> -    if(ParsePort(toks[3], (u_short *) & proto_node.hsp,
> -                 (u_short *) & proto_node.lsp, toks[1],
> -                 (int *) &proto_node.not_sp_flag))
> -    {
> -        proto_node.flags |= ANY_SRC_PORT;
> -    }
> -
> -    if(proto_node.not_sp_flag)
> -        proto_node.flags |= EXCEPT_SRC_PORT;
> -
> -    /* New in version 1.3: support for bidirectional rules */
> -    /*
> -     * this checks the rule "direction" token and sets the bidirectional flag
> -     * if the token = '<>'
> -     */
> -    if(!strncmp("<>", toks[4], 2))
> -    {
> -        DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Bidirectional rule!\n"););
> -        proto_node.flags |= BIDIRECTIONAL;
> -    }
> -
> -    /* changed version 1.8.4
> -     * Die when someone has tried to define a rule character other than
> -       -> or <>
> -    */
> -    if(strcmp("->", toks[4]) && strcmp("<>", toks[4]))
> -    {
> -	FatalError("%s(%d): Illegal direction specifier: %s\n",
> -		   file_name, file_line, toks[4]);
> -    }
> -    
> -    /* changed version 1.2.1
> -     *
> -     * "any" IP's are now set to addr 0, netmask 0, and the normal rules are
> -     * applied instead of checking the flag
> -     *
> -     * if we see a "!<ip number>" we need to set a flag so that we can
> -     * properly deal with it when we are processing packets
> -     * we found a negated address */
> -
> -    /*
> -   if( *toks[5] == '!' )    
> -   {
> -       DEBUG_WRAP(DebugMessage(DEBUG_RULES, "setting exception flag for dest IP\n"););
> -
> -       proto_node.flags |= EXCEPT_DST_IP;
> -       ParseIP(&toks[5][1], (u_long *) & proto_node.dip,
> -               (u_long *) & proto_node.dmask);
> -   }
> -   else
> -       ParseIP(toks[5], (u_long *) & proto_node.dip,
> -               (u_long *) & proto_node.dmask);
> -*/
> -
> -    ProcessIP(toks[5], &proto_node, DST);
> -
> -    if(ParsePort(toks[6], (u_short *) & proto_node.hdp,
> -                 (u_short *) & proto_node.ldp, toks[1],
> -                 (int *) &proto_node.not_dp_flag))
> -    {
> -        proto_node.flags |= ANY_DST_PORT;
> -    }
> -    if(proto_node.not_dp_flag)
> -        proto_node.flags |= EXCEPT_DST_PORT;
> -
> -    DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"proto_node.flags = 0x%X\n", proto_node.flags););
> -
> -    if(&proto_node == NULL)
> -	LogMessage("NULL proto_node\n");
> -
> -    ProcessHeadNode(&proto_node, node->RuleList, protocol);
> -    rule_count++;
> -    ParseRuleOptions(rule, node->mode, protocol);
> -
> -    mSplitFree(&toks, num_toks);
> -
> -    return;
> -}
> -
>  
>  /* adapted from ParseRuleFule in rules.c */
>  char *ReadLine(FILE * file)
> diff snort.org/src/parser.h snort/src/parser.h
> --- snort.org/src/parser.h	Tue Dec 30 21:19:08 2003
> +++ snort/src/parser.h	Tue Dec 30 21:19:40 2003
> @@ -92,7 +92,6 @@
>  char *ProcessFileOption(char *);
>  void ParseConfig(char *);
>  void ParseRuleTypeDeclaration(FILE*, char *);
> -void ParseDeclaredRuleType(char *);
>  /*void ParseClassificationConfig(char *); */
>  char *ReadLine(FILE *);
>  int checkKeyowrd(char *);
> ----
> 

> diff snort.org/src/parser.c snort/src/parser.c
> --- snort.org/src/parser.c	Tue Dec 30 21:25:50 2003
> +++ snort/src/parser.c	Tue Dec 30 21:26:35 2003
> @@ -460,13 +460,18 @@
>  void ParseRule(FILE *rule_file, char *prule, int inclevel)
>  {
>      char **toks;        /* dbl ptr for mSplit call, holds rule tokens */
> +    char **port_toks;   /* to hold port list tokens */
>      int num_toks;       /* holds number of tokens found by mSplit */
> +    int num_port_toks;  /* holds number of ports found by mSplit on port list */
>      int rule_type;      /* rule type enumeration variable */
>      char rule[PARSERULE_SIZE];
> +    char tmp_rule[PARSERULE_SIZE];
>      int protocol = 0;
>      char *tmp;
>      RuleTreeNode proto_node;
>      RuleListNode *node = RuleLists;
> +    int i;
> +    int j;
>  
>      /* chop off the <CR/LF> from the string */
>      strip(prule);
> @@ -653,7 +658,45 @@
>                     file_name, file_line);
>      }
>  
> -    /* do the same for the port */
> +    /* If port begins with [ and ends with ], it's a list of ports and we
> +     * call ParseRule() recursively for each port, except for the last one
> +     * which we continue to process as usual in this call to ParseRule().
> +     * We do not handle negated port lists.
> +     */
> +    if(strlen(toks[3]) > 2 && toks[3][0] == '[' && toks[3][strlen(toks[3]) - 1] == ']')
> +    {
> +        toks[3][strlen(toks[3]) - 1] = '\0';
> +        port_toks = mSplit(toks[3] + 1, ",", 512, &num_port_toks, 0);
> +
> +        for(i = 0; i < num_port_toks - 1; i++)
> +        {
> +            tmp_rule[0] = '\0';
> +
> +            /* create new rule in tmp_rule by copying each token from old rule to it,
> +             * except for the srcport field where we use a port from the port list
> +             */
> +            for(j = 0; j < num_toks; j++)
> +            {
> +                if(j == 3)
> +                {
> +                    strlcat(tmp_rule, port_toks[i], PARSERULE_SIZE);
> +                }
> +                else
> +                {
> +                    strlcat(tmp_rule, toks[j], PARSERULE_SIZE);
> +                }
> +                strlcat(tmp_rule, " ", PARSERULE_SIZE);
> +            }
> +            ParseRule(rule_file, tmp_rule, inclevel);
> +        }
> +
> +        /* replace list of ports with last port in it for current rule */
> +        strcpy(toks[3], port_toks[num_port_toks - 1]);
> +
> +        mSplitFree(&port_toks, num_port_toks);
> +    }
> +
> +    /* parse source port */
>      if(ParsePort(toks[3], (u_short *) & proto_node.hsp,
>                  (u_short *) & proto_node.lsp, toks[1],
>                  (int *) &proto_node.not_sp_flag))
> @@ -698,6 +741,41 @@
>      /* we found a negated address */
>      ProcessIP(toks[5], &proto_node, DST);
>  
> +    /* parse possible destination port list just as we did for source port list */
> +    if(strlen(toks[6]) > 2 && toks[6][0] == '[' && toks[6][strlen(toks[6]) - 1] == ']')
> +    {
> +        toks[6][strlen(toks[6]) - 1] = '\0';
> +        port_toks = mSplit(toks[6] + 1, ",", 512, &num_port_toks, 0);
> +
> +        for(i = 0; i < num_port_toks - 1; i++)
> +        {
> +            tmp_rule[0] = '\0';
> +
> +            /* create new rule in tmp_rule by copying each token from old rule to it,
> +             * except for the dstport field where we use a port from the port list
> +             */
> +            for(j = 0; j < num_toks; j++)
> +            {
> +                if(j == 6)
> +                {
> +                    strlcat(tmp_rule, port_toks[i], PARSERULE_SIZE);
> +                }
> +                else
> +                {
> +                    strlcat(tmp_rule, toks[j], PARSERULE_SIZE);
> +                }
> +                strlcat(tmp_rule, " ", PARSERULE_SIZE);
> +            }
> +            ParseRule(rule_file, tmp_rule, inclevel);
> +        }
> +
> +        /* replace list of ports with last port in it for current rule */
> +        strcpy(toks[6], port_toks[num_port_toks - 1]);
> +
> +        mSplitFree(&port_toks, num_port_toks);
> +    }
> +
> +    /* parse destination port */
>      if(ParsePort(toks[6], (u_short *) & proto_node.hdp,
>                  (u_short *) & proto_node.ldp, toks[1],
>                  (int *) &proto_node.not_dp_flag))
> ----
> 

> diff snort.org/src/parser.c snort/src/parser.c
> --- snort.org/src/parser.c	Tue Dec 30 21:28:17 2003
> +++ snort/src/parser.c	Tue Dec 30 21:28:30 2003
> @@ -460,12 +460,18 @@
>  void ParseRule(FILE *rule_file, char *prule, int inclevel)
>  {
>      char **toks;        /* dbl ptr for mSplit call, holds rule tokens */
> +    char **port_toks;   /* to hold port list tokens */
>      int num_toks;       /* holds number of tokens found by mSplit */
> +    int num_port_toks;  /* holds number of ports found by mSplit on port list */
>      int rule_type;      /* rule type enumeration variable */
>      char rule[PARSERULE_SIZE];
> +    char tmp_rule[PARSERULE_SIZE];
>      int protocol = 0;
>      char *tmp;
>      RuleTreeNode proto_node;
> +    RuleListNode *node = RuleLists;
> +    int i;
> +    int j;
>  
>      /* chop off the <CR/LF> from the string */
>      strip(prule);
> @@ -575,10 +581,23 @@
>   
>          case RULE_UNKNOWN:
>              DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Unknown rule type, might be declared\n"););
> -            ParseDeclaredRuleType(rule);
> -            mSplitFree(&toks, num_toks);
> -            return;
>  
> +            /* find out if this ruletype has been declared */
> +            while(node != NULL)
> +            {
> +                if(!strcasecmp(node->name, toks[0]))
> +                    break;
> +                node = node->next;
> +            }
> +
> +            if(node == NULL)
> +            {
> +                 FatalError("%s(%d) => Unknown rule type: %s\n",
> +                            file_name, file_line, toks[0]);
> +            }
> +
> +            break; 
> +
>          default:
>              DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Invalid input: %s\n", prule););
>              mSplitFree(&toks, num_toks);
> @@ -601,9 +620,11 @@
>          return;
>      }
>  
> +    if (rule_type == RULE_UNKNOWN)
> +        proto_node.type = node->mode;
> +    else
> +        proto_node.type = rule_type;
>  
> -    proto_node.type = rule_type;
> -
>      /* set the rule protocol */
>      protocol = WhichProto(toks[1]);
>  
> @@ -637,7 +658,45 @@
>                     file_name, file_line);
>      }
>  
> -    /* do the same for the port */
> +    /* If port begins with [ and ends with ], it's a list of ports and we
> +     * call ParseRule() recursively for each port, except for the last one
> +     * which we continue to process as usual in this call to ParseRule().
> +     * We do not handle negated port lists.
> +     */
> +    if(strlen(toks[3]) > 2 && toks[3][0] == '[' && toks[3][strlen(toks[3]) - 1] == ']')
> +    {
> +        toks[3][strlen(toks[3]) - 1] = '\0';
> +        port_toks = mSplit(toks[3] + 1, ",", 512, &num_port_toks, 0);
> +
> +        for(i = 0; i < num_port_toks - 1; i++)
> +        {
> +            tmp_rule[0] = '\0';
> +
> +            /* create new rule in tmp_rule by copying each token from old rule to it,
> +             * except for the srcport field where we use a port from the port list
> +             */
> +            for(j = 0; j < num_toks; j++)
> +            {
> +                if(j == 3)
> +                {
> +                    strlcat(tmp_rule, port_toks[i], PARSERULE_SIZE);
> +                }
> +                else
> +                {
> +                    strlcat(tmp_rule, toks[j], PARSERULE_SIZE);
> +                }
> +                strlcat(tmp_rule, " ", PARSERULE_SIZE);
> +            }
> +            ParseRule(rule_file, tmp_rule, inclevel);
> +        }
> +
> +        /* replace list of ports with last port in it for current rule */
> +        strcpy(toks[3], port_toks[num_port_toks - 1]);
> +
> +        mSplitFree(&port_toks, num_port_toks);
> +    }
> +
> +    /* parse source port */
>      if(ParsePort(toks[3], (u_short *) & proto_node.hsp,
>                  (u_short *) & proto_node.lsp, toks[1],
>                  (int *) &proto_node.not_sp_flag))
> @@ -682,6 +741,41 @@
>      /* we found a negated address */
>      ProcessIP(toks[5], &proto_node, DST);
>  
> +    /* parse possible destination port list just as we did for source port list */
> +    if(strlen(toks[6]) > 2 && toks[6][0] == '[' && toks[6][strlen(toks[6]) - 1] == ']')
> +    {
> +        toks[6][strlen(toks[6]) - 1] = '\0';
> +        port_toks = mSplit(toks[6] + 1, ",", 512, &num_port_toks, 0);
> +
> +        for(i = 0; i < num_port_toks - 1; i++)
> +        {
> +            tmp_rule[0] = '\0';
> +
> +            /* create new rule in tmp_rule by copying each token from old rule to it,
> +             * except for the dstport field where we use a port from the port list
> +             */
> +            for(j = 0; j < num_toks; j++)
> +            {
> +                if(j == 6)
> +                {
> +                    strlcat(tmp_rule, port_toks[i], PARSERULE_SIZE);
> +                }
> +                else
> +                {
> +                    strlcat(tmp_rule, toks[j], PARSERULE_SIZE);
> +                }
> +                strlcat(tmp_rule, " ", PARSERULE_SIZE);
> +            }
> +            ParseRule(rule_file, tmp_rule, inclevel);
> +        }
> +
> +        /* replace list of ports with last port in it for current rule */
> +        strcpy(toks[6], port_toks[num_port_toks - 1]);
> +
> +        mSplitFree(&port_toks, num_port_toks);
> +    }
> +
> +    /* parse destination port */
>      if(ParsePort(toks[6], (u_short *) & proto_node.hdp,
>                  (u_short *) & proto_node.ldp, toks[1],
>                  (int *) &proto_node.not_dp_flag))
> @@ -717,6 +811,10 @@
>              ProcessHeadNode(&proto_node, &Dynamic, protocol);
>              break;
>  
> +        case RULE_UNKNOWN:
> +            ProcessHeadNode(&proto_node, node->RuleList, protocol);
> +            break;
> +
>          default:
>              FatalError("Unable to determine rule type (%s) for processing, exiting!\n", toks[0]);
>      }
> @@ -725,7 +823,10 @@
>  
>      DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Parsing Rule Options...\n"););
>  
> -    ParseRuleOptions(rule, rule_type, protocol);
> +    if (rule_type == RULE_UNKNOWN)
> +        ParseRuleOptions(rule, node->mode, protocol);
> +    else
> +        ParseRuleOptions(rule, rule_type, protocol);
>  
>      mSplitFree(&toks, num_toks);
>  
> @@ -2432,7 +2533,7 @@
>      }
>      else
>      {
> -        FatalError("%s(%d) => bad port number: %s", file_name,
> +        FatalError("%s(%d) => bad port number: %s\n", file_name,
>                     file_line, port);
>      }
>  
> @@ -3961,168 +4062,6 @@
>  
>      return;
>  }
> -
> -
> -/* Adapted from ParseRule in rules.c */
> -void ParseDeclaredRuleType(char *rule)
> -{
> -    char **toks;
> -    int num_toks;
> -    RuleListNode *node;
> -    int protocol;
> -    RuleTreeNode proto_node;
> -
> -    toks = mSplit(rule, " ", 10, &num_toks, 0);
> -    node = RuleLists;
> -
> -    while(node != NULL)
> -    {
> -        if(!strcasecmp(node->name, toks[0]))
> -            break;
> -        node = node->next;
> -    }
> -
> -    /* if we did not find a match, then there is no such ruletype */
> -    if(node == NULL)
> -    {
> -        FatalError("%s(%d) => Unknown rule type: %s\n",
> -                   file_name, file_line, toks[0]);
> -    }
> -
> -#ifdef DEBUG
> -	LogMessage("[**] Rule start\n");
> -	LogMessage("Rule id: %s\n", toks[0]);
> -	LogMessage("Rule type: ");
> -
> -    switch(node->mode)
> -    {
> -        case RULE_PASS:
> -	LogMessage("Pass\n");
> -            break;
> -        case RULE_LOG:
> -	LogMessage("Log\n");
> -            break;
> -        case RULE_ALERT:
> -	LogMessage("Alert\n");
> -            break;
> -        default:
> -	LogMessage("Unknown\n");
> -    }
> -#endif
> -
> -    /* the rest of this function is almost identical to code in ParseRule */
> -    bzero((char *) &proto_node, sizeof(RuleTreeNode));
> -
> -    proto_node.type = node->mode;
> -
> -    /* set the rule protocol */
> -    protocol = WhichProto(toks[1]);
> -
> -    /* Process the IP address and CIDR netmask */
> -    /* changed version 1.2.1 */
> -    /*
> -     * "any" IP's are now set to addr 0, netmask 0, and the normal rules are
> -     * applied instead of checking the flag
> -     */
> -    /*
> -     * if we see a "!<ip number>" we need to set a flag so that we can
> -     * properly deal with it when we are processing packets
> -     */
> -    /*
> -   if( *toks[2] == '!' )    
> -   {
> -       proto_node.flags |= EXCEPT_SRC_IP;
> -       ParseIP(&toks[2][1], (u_long *) & proto_node.sip,
> -               (u_long *) & proto_node.smask);
> -   }
> -   else
> -   {
> -       ParseIP(toks[2], (u_long *) & proto_node.sip,
> -               (u_long *) & proto_node.smask);
> -   }*/
> -
> -    ProcessIP(toks[2], &proto_node, SRC);
> -
> -    /* do the same for the port */
> -    if(ParsePort(toks[3], (u_short *) & proto_node.hsp,
> -                 (u_short *) & proto_node.lsp, toks[1],
> -                 (int *) &proto_node.not_sp_flag))
> -    {
> -        proto_node.flags |= ANY_SRC_PORT;
> -    }
> -
> -    if(proto_node.not_sp_flag)
> -        proto_node.flags |= EXCEPT_SRC_PORT;
> -
> -    /* New in version 1.3: support for bidirectional rules */
> -    /*
> -     * this checks the rule "direction" token and sets the bidirectional flag
> -     * if the token = '<>'
> -     */
> -    if(!strncmp("<>", toks[4], 2))
> -    {
> -        DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Bidirectional rule!\n"););
> -        proto_node.flags |= BIDIRECTIONAL;
> -    }
> -
> -    /* changed version 1.8.4
> -     * Die when someone has tried to define a rule character other than
> -       -> or <>
> -    */
> -    if(strcmp("->", toks[4]) && strcmp("<>", toks[4]))
> -    {
> -	FatalError("%s(%d): Illegal direction specifier: %s\n",
> -		   file_name, file_line, toks[4]);
> -    }
> -    
> -    /* changed version 1.2.1
> -     *
> -     * "any" IP's are now set to addr 0, netmask 0, and the normal rules are
> -     * applied instead of checking the flag
> -     *
> -     * if we see a "!<ip number>" we need to set a flag so that we can
> -     * properly deal with it when we are processing packets
> -     * we found a negated address */
> -
> -    /*
> -   if( *toks[5] == '!' )    
> -   {
> -       DEBUG_WRAP(DebugMessage(DEBUG_RULES, "setting exception flag for dest IP\n"););
> -
> -       proto_node.flags |= EXCEPT_DST_IP;
> -       ParseIP(&toks[5][1], (u_long *) & proto_node.dip,
> -               (u_long *) & proto_node.dmask);
> -   }
> -   else
> -       ParseIP(toks[5], (u_long *) & proto_node.dip,
> -               (u_long *) & proto_node.dmask);
> -*/
> -
> -    ProcessIP(toks[5], &proto_node, DST);
> -
> -    if(ParsePort(toks[6], (u_short *) & proto_node.hdp,
> -                 (u_short *) & proto_node.ldp, toks[1],
> -                 (int *) &proto_node.not_dp_flag))
> -    {
> -        proto_node.flags |= ANY_DST_PORT;
> -    }
> -    if(proto_node.not_dp_flag)
> -        proto_node.flags |= EXCEPT_DST_PORT;
> -
> -    DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"proto_node.flags = 0x%X\n", proto_node.flags););
> -
> -    if(&proto_node == NULL)
> -	LogMessage("NULL proto_node\n");
> -
> -    ProcessHeadNode(&proto_node, node->RuleList, protocol);
> -    rule_count++;
> -    ParseRuleOptions(rule, node->mode, protocol);
> -
> -    mSplitFree(&toks, num_toks);
> -
> -    return;
> -}
> -
>  
>  /* adapted from ParseRuleFule in rules.c */
>  char *ReadLine(FILE * file)
> diff snort.org/src/parser.h snort/src/parser.h
> --- snort.org/src/parser.h	Tue Dec 30 21:28:17 2003
> +++ snort/src/parser.h	Tue Dec 30 21:28:27 2003
> @@ -92,7 +92,6 @@
>  char *ProcessFileOption(char *);
>  void ParseConfig(char *);
>  void ParseRuleTypeDeclaration(FILE*, char *);
> -void ParseDeclaredRuleType(char *);
>  /*void ParseClassificationConfig(char *); */
>  char *ReadLine(FILE *);
>  int checkKeyowrd(char *);
-- 
Daniel Roelker
Software Developer
Sourcefire, Inc.





More information about the Snort-devel mailing list