⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 该源码是用C语言编写的,实现网络入侵检测系统的功能
💻 C
字号:
/*
** Copyright (C) 1998,1999,2000,2001 Martin Roesch <roesch@clark.net>
** Copyright (C) 2000,2001 Andrew R. Baker <andrewb@uab.edu>
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

/* $Id: parser.c,v 1.6 2001/01/02 08:06:00 roesch Exp $ */

#include "parser.h"
extern char *file_name;
extern char *file_line;
extern RuleListNode *RuleLists;
extern int rule_count;
extern FILE *rule_file;
extern ListHead *head_tmp;

/****************************************************************************
 *
 * Function: ProcessAlertFileOption(char *)
 *
 * Purpose: define the alert file
 *
 * Arguments: filespec => the file specification
 *
 * Returns: void function
 *
 ***************************************************************************/
void ProcessAlertFileOption(char *filespec)
{
    pv.alert_filename = ProcessFileOption(filespec);

#if DEBUG
    printf("alertfile set to: %s\n", pv.alert_filename);
#endif

    return;
}

char *ProcessFileOption(char *filespec)
{
    char *filename;
    char buffer[STD_BUF];

    /* look for ".." in the string and complain and exit if it is found */
    if(strstr(filespec, "..") != NULL)
    {
        FatalError("ERROR: file definition contains \"..\".  Do not do that!\n");
    }

    if(filespec[0] == '/')
    {
        /* absolute filespecs are saved as is */
        filename = strdup(filespec);
    }
    else
    {
        /* relative filespec is considered relative to the log directory */
        /* or /var/log if the log directory has not been set */
        if(pv.log_flag)
        {
            strncpy(buffer, pv.log_dir, STD_BUF - 1);
        }
        else
        {
            strncpy(buffer, "/var/log", STD_BUF - 1);
        }

        strncat(buffer, "/", STD_BUF - strlen(buffer) - 1);
        strncat(buffer, filespec, STD_BUF - strlen(buffer) - 1);
        filename = strdup(buffer);
    }

    printf("ProcessFileOption: %s\n", filename);

    return filename;
}

void ParseConfig(char *rule)
{
    char **toks;
    char **config_decl;
    char *args = NULL;
    char *config;
    int num_toks;

    toks = mSplit(rule, ":", 2, &num_toks, 0);

    if(num_toks >= 1)
    {
        args = toks[1];
    }

    config_decl = mSplit(toks[0], " ", 2, &num_toks, '\\');

    if(num_toks != 2)
    {
        FatalError("Error parsing config: %s\n", rule);
    }

    config = config_decl[1];

#ifdef DEBUG
    printf("Config: %s\n", config);
    printf("Args: %s\n", args);
#endif

    if(!strcasecmp(config, "order"))
    {
        if(!pv.rules_order_flag)
        {
            OrderRuleLists(args);

            return;
        }

#ifdef DEBUG
        else
            printf("Commandline option overiding rule file config\n");
#endif
    }

    if(!strcasecmp(config, "alertfile"))
    {
        toks = mSplit(args, " ", 1, &num_toks, 0);

        ProcessAlertFileOption(toks[0]);

        return;
    }

    FatalError("Error: Unknown config: %s\n", config);

    return;
}

/* verify that we are not reusing some other keyword */
int checkKeyword(char *keyword)
{
    RuleListNode *node = RuleLists;

    if(RuleType(keyword) != RULE_UNKNOWN)
    {
        return 1;
    }

    /* check the declared ruletypes now */
    while(node != NULL)
    {
        if(!strcmp(node->name, keyword))
        {
            return 1;
        }

        node = node->next;
    }

    return 0;
}

void ParseRuleTypeDeclaration(char *rule)
{
    char *input;
    char *keyword;
    char **toks;
    int num_toks;
    int type;
    int rval = 1;
    int i;
    ListHead *listhead = NULL;

    toks = mSplit(rule, " ", 10, &num_toks, 0);
    keyword = strdup(toks[1]);

    /* Verify keyword is unique */
    if(checkKeyword(keyword))
    {
        FatalError("ERROR line %s (%d): Duplicate keyword: %s\n",
                   file_name, file_line, keyword);
    }

#ifdef DEBUG
    printf("Declaring new rule type: %s\n", keyword);
#endif

    if(num_toks > 2)
    {
        if(strcasecmp("{", toks[2]) != 0)
        {
            FatalError("ERROR line %s (%d): Syntax error: %s\n",
                       file_name, file_line, rule);
        }
    }
    else
    {
        input = ReadLine(rule_file);
        for(i=0;i<num_toks;i++)
        {
            free(toks[i]);
        }
        toks = mSplit(input, " ", 2, &num_toks, 0);
        free(input);
    }

    input = ReadLine(rule_file);
    for(i=0;i<num_toks;i++)
    {
        free(toks[i]);
    }
    toks = mSplit(input, " ", 10, &num_toks, 0);

    /* read the type field */
    if(!strcasecmp("type", toks[0]))
    {
        type = RuleType(toks[1]);
        /* verify it is a valid ruletype */
        if((type != RULE_LOG) && (type != RULE_PASS) && (type != RULE_ALERT) &&
           (type != RULE_ACTIVATE) && (type != RULE_DYNAMIC))
        {
            FatalError("ERROR line %s (%d): Invalid type for rule type declaration: %s\n", file_name, file_line, toks[1]);
        }

#ifdef DEBUG
        printf("\ttype(%i): %s\n", type, toks[1]);
#endif

        if(type == RULE_PASS)
        {
            rval = 0;
        }

        listhead = CreateRuleType(keyword, type, rval, NULL);
    }
    else
    {
        FatalError("ERROR line %s (%d): Type not defined for rule file declaration: %s\n", file_name, file_line, keyword);
    }

    free(input);
    input = ReadLine(rule_file);
    for(i=0;i<num_toks;i++)
    {
        free(toks[i]);
    }

    toks = mSplit(input, " ", 2, &num_toks, 0);

    while(strcasecmp("}", toks[0]) != 0)
    {
        if(RuleType(toks[0]) != RULE_OUTPUT)
        {
            FatalError("ERROR line %s (%d): Not an output plugin decleration: %s\n", file_name, file_line, keyword);
        }

        head_tmp = listhead;
        ParseOutputPlugin(input);
        head_tmp = NULL;
        free(input);
        input = ReadLine(rule_file);

        for(i=0;i<num_toks;i++)
        {
            free(toks[i]);
        }
        toks = mSplit(input, " ", 2, &num_toks, 0);
    }

    return;
}


/* Adapted from ParseRule in rules.c */
void ParseDeclaredRuleType(char *rule)
{
    char **toks;
    int num_toks;
    RuleListNode *node;
    int protocol;
    int i;
    RuleTreeNode proto_node;

    toks = mSplit(rule, " ", 10, &num_toks, 0);
    node = RuleLists;

    while(node != NULL)
    {
        if(!strcmp(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("ERROR line %s (%d) => Unknown rule type: %s\n",
                   file_name, file_line, toks[0]);
    }

    printf("[**] Rule start\n");
    printf("Rule id: %s\n", toks[0]);
    printf("Rule type: ");

    switch(node->mode)
    {
        case RULE_PASS:
            printf("Pass\n");
            break;
        case RULE_LOG:
            printf("Log\n");
            break;
        case RULE_ALERT:
            printf("Alert\n");
            break;
        default:
            printf("Unknown\n");
    }

    /* 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))
    {
#ifdef DEBUG
        printf("Bidirectional rule!\n");
#endif
        proto_node.flags |= BIDIRECTIONAL;
    }

    /* 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[5] == '!' )    
   {
#ifdef DEBUG
       printf("setting exception flag for dest IP\n");
#endif
       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;

#ifdef DEBUG
    printf("proto_node.flags = 0x%X\n", proto_node.flags);
#endif

    if(&proto_node == NULL)
        printf("NULL proto_node\n");

    ProcessHeadNode(&proto_node, node->RuleList, protocol);
    rule_count++;
    ParseRuleOptions(rule, node->mode, protocol);
    for(i=0;i<num_toks;i++)
    {
        free(toks[i]);
    }

    return;
}


/* adapted from ParseRuleFule in rules.c */
char *ReadLine(FILE * file)
{
    char buf[STD_BUF];
    char *index;

    bzero((char *) buf, STD_BUF);

    /*
     * Read a line from file and return it. Skip over lines beginning with #,
     * ;, or a newline
     */
    while((fgets(buf, STD_BUF, file)) != NULL)
    {
        file_line++;
        index = buf;
#ifdef DEBUG2

        printf("Got line %s (%d): %s", file_name, file_line, buf);
#endif
        /* if it's not a comment or a <CR>, we return it */
        if((*index != '#') && (*index != 0x0a) && (*index != ';')
           && (index != NULL))
        {
            /* advance through any whitespace at the beginning of ther line */
            while(isspace((int) *index))
                index++;

            /* return a copy of the line */
            return strdup(buf);
        }
    }

    return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -