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

📄 sf_ipvar.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Copyright (C) 1998-2006 Sourcefire, Inc.**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License Version 2 as** published by the Free Software Foundation.  You may not use, modify or** distribute this program under any other version of the GNU General** Public License.**** 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.*//* * Adam Keeton * sf_ipvar.c * 11/17/06 * * Library for IP variables.*/#include <stdlib.h>#include <string.h>#include <ctype.h>#include <stdio.h>#include "util.h"#include "sf_ipvar.h"#include "sf_vartable.h"#define LIST_OPEN '['#define LIST_CLOSE ']'static INLINE sfip_var_t *_alloc_var() {    return (sfip_var_t*)calloc(1, sizeof(sfip_var_t));}void sfvar_free(sfip_var_t *var) {    sfip_node_t *p, *next;    if(!var) return;        if(var->name) free(var->name);    if(var->mode == SFIP_LIST) {        for(p=var->head; p; p=next) {            next = p->next;            if(p->ip) sfip_free(p->ip);            free(p);        }    } else if(var->mode == SFIP_TABLE) {        // XXX    }    free(var);}sfip_node_t *sfipnode_alloc(char *str, SFIP_RET *status) {    sfip_node_t *ret;    if(!str) {        if(status)            *status = SFIP_ARG_ERR;        return NULL;    }    if( (ret = (sfip_node_t*)calloc(1, sizeof(sfip_node_t))) == NULL ) {        if(status)            *status = SFIP_ALLOC_ERR;         return NULL;    }        /* Check if this string starts with a '!', if so,     * then the node needs to be negated */    if(*str == '!') {        str++;        ret->flags |= SFIP_NEGATED;    }         /* Check if this is an "any" */    if(!strncasecmp(str, "any", 3)) {        /* Make sure they're not doing !any, which is meaningless */        if(ret->flags & SFIP_NEGATED) {            if(status)                *status = SFIP_ARG_ERR;            free(ret);            return NULL;        }        ret->flags |= SFIP_ANY;        if( (ret->ip = sfip_alloc("0.0.0.0", status)) == NULL ) {            /* Failed to parse this string, so free and return */            if(status)                *status = SFIP_ALLOC_ERR;             free(ret);            return NULL;        }        if(status)            *status = SFIP_SUCCESS;        if( !(ret->ip = sfip_alloc("0.0.0.0", NULL)) ) {            if(status)                *status = SFIP_FAILURE;            free(ret);            return NULL;        }    }     else if( (ret->ip = sfip_alloc(str, status)) == NULL ) {        /* Failed to parse this string, so free and return */        if(status)             *status = SFIP_INET_PARSE_ERR;        free(ret);        return NULL;    }    /* Check if this is a negated, zero'ed IP (equivalent of a "!any") */    if(!sfip_is_set(ret->ip) && (ret->flags & SFIP_NEGATED)) {        if(status)            *status = SFIP_NOT_ANY;        free(ret);        return NULL;            }    return ret;}/* Deep copy of src added to dst *//* Ordering is not necessarily preserved */SFIP_RET sfvar_add(sfip_var_t *dst, sfip_var_t *src) {    sfip_node_t *oldhead, *oldneg, *idx;    sfip_var_t *copiedvar;    if(!dst || !src) return SFIP_ARG_ERR;    oldhead = dst->head;    oldneg = dst->neg_head;    if((copiedvar = sfvar_deep_copy(src)) == NULL) {        return SFIP_ALLOC_ERR;    }        dst->head = copiedvar->head;    dst->neg_head = copiedvar->neg_head;    free(copiedvar);     if(dst->head) {        for(idx = dst->head; idx->next; idx = idx->next)             ;        idx->next = oldhead;    }     else {        dst->head = oldhead;    }    if(dst->neg_head) {        for(idx = dst->neg_head; idx->next; idx = idx->next)             ;        idx->next = oldneg;     }    else {        dst->neg_head = oldneg;    }    return SFIP_SUCCESS;}SFIP_RET sfvar_add_node(sfip_var_t *var, sfip_node_t *node, int negated) {    sfip_node_t *p;    sfip_node_t *swp;    sfip_node_t **head;    if(!var || !node) return SFIP_ARG_ERR;        /* XXX */    /* As of this writing, 11/20/06, nodes are always added to      * the list, regardless of the mode (list or table). */    if(negated)        head = &var->neg_head;            else        head = &var->head;            if(!(*head)) {        *head = node;        return SFIP_SUCCESS;    }    /* "Anys" should always be inserted first */    /* Otherwise, check if this IP is less than the head's IP */    if((node->flags & SFIP_ANY) ||        (sfip_cmp(node->ip, (*head)->ip) == SFIP_LESSER)) {        node->next = *head;        *head = node;        return SFIP_SUCCESS;    }    /* If we're here, the head node was lesser than the new node */    /* Before searching the list, verify there is atleast two nodes.     * (This saves an extra check during the loop below) */    if(!(*head)->next) {        (*head)->next = node;        return SFIP_SUCCESS;    }    /* Insertion sort */    for(p = *head; p->next; p=p->next) {        if(sfip_cmp(node->ip, p->next->ip) == SFIP_LESSER) {            swp = p->next;            p->next = node;            node->next = swp;            return SFIP_SUCCESS;        }    }    p->next = node;    return SFIP_SUCCESS;    /* XXX Insert new node into routing table *///    sfrt_add(node->ip, }/* Check's if two variables have the same nodes */SFIP_RET sfvar_compare(sfip_var_t *one, sfip_var_t *two) {    sfip_node_t *idx1, *idx2;    int i, match;    int total1 = 0;    int total2 = 0;    char *usage;    /* Walk first list.  For each node, check if there is an equal     * counterpart in the second list.  This method breaks down of there are      * duplicated nodes.  For instance, if one = {a, b} and two = {a, a}.     * Therefore, need additional data structure[s] ('usage') to check off      * which nodes have been accounted for already.      *     * Also, the lists are not necessarily ordered, so comparing      * node-for-node won't work */    if(!one && !two)        return 1;    if((one && !two) || (!one && two))         return 0;    for(idx1 = one->head; idx1; idx1 = idx1->next)         total1++;    for(idx2 = two->head; idx2; idx2 = idx2->next)         total2++;    if(total1 != total2)         return 0;    usage = (char*)SnortAlloc(total1);    for(idx1 = one->head; idx1; idx1 = idx1->next)    {        match = 0;        for(idx2 = two->head, i = 0; idx2; idx2 = idx2->next, i++)        {            if((sfip_cmp(idx1->ip, idx2->ip) == SFIP_EQUAL) && !usage[i])            {                match = 1;                usage[i] = 1;                break;            }        }        if(!match) {            free(usage);            return 0;        }    }    free(usage);    return 1;    return SFIP_SUCCESS;}/* Support function for sfvar_parse_iplist.  Used to  * correctly match up end brackets.   *  (Can't just do strchr(str, ']') because of the  *  [a, [b], c] case, and can't do strrchr because *  of the [a, [b], [c]] case) */char *_find_end_token(char *str) {    int stack = 0;    for(; *str; str++) {        if(*str == LIST_OPEN)            stack++;        else if(*str == LIST_CLOSE)            stack--;        if(!stack) {            return str;        }    }    return NULL;}/* Support function for sfvar_parse_iplist. *  Negates a node */static void _negate_node(sfip_node_t *node) {    if(node->addr_flags & SFIP_NEGATED) {        node->addr_flags &= ~SFIP_NEGATED;        node->flags &= ~SFIP_NEGATED;    }    else {        node->addr_flags |= SFIP_NEGATED;        node->flags |= SFIP_NEGATED;    }}/* Support function for sfvar_parse_iplist. *  Negates a variable */static void _negate_lists(sfip_var_t *var) {    sfip_node_t *node;    sfip_node_t *temp;    for(node = var->head; node; node=node->next)         _negate_node(node);    for(node = var->neg_head; node; node=node->next)         _negate_node(node);        /* Swap lists */    temp = var->head;    var->head = var->neg_head;    var->neg_head = temp;}SFIP_RET sfvar_parse_iplist(vartable_t *table, sfip_var_t *var,                           char *str, int negation) {    char *end, *tok;    SFIP_RET ret;    int neg_ip;    if(!var || !table || !str)         return SFIP_ARG_ERR;    while(*str) {        /* Skip whitespace and leading commas */        if(isspace((int)*str) || *str == ',') {            str++;            continue;        }        neg_ip = 0;        /* Handle multiple negations */        for(; *str == '!'; str++)              neg_ip = !neg_ip;        /* Find end of this token */        for(end = str+1;            *end && !isspace((int)*end) && *end != LIST_CLOSE && *end != ',';            end++) ;        tok = SnortStrndup(str, end - str);        if(*str == LIST_OPEN) {            char *list_tok;            /* Find end of this list */            if((end = _find_end_token(str)) == NULL) {                /* No trailing bracket found */                return SFIP_UNMATCHED_BRACKET;            }                    str++;            list_tok = SnortStrndup(str, end - str);            if((ret = sfvar_parse_iplist(table, var, list_tok,                           negation ^ neg_ip)) != SFIP_SUCCESS) {                free(list_tok);                free(tok);                return ret;            }            free(list_tok);        }         else if(*str == '$') {            sfip_var_t *tmp_var;            if((tmp_var = sfvt_lookup_var(table, tok)) == NULL) {                free(tok);                return SFIP_LOOKUP_FAILURE;            }            sfvar_add(var, tmp_var);            /* Apply the negation */            if(negation ^ neg_ip) {                /* Check for a negated "any" */                if(var->head && var->head->flags & SFIP_ANY) {                    free(tok);                    return SFIP_NOT_ANY;                }                /* Check if this is a negated, zero'ed IP (equivalent of a "!any") */                if(!sfip_is_set(var->head->ip)) {                    free(tok);                    return SFIP_NOT_ANY;                }                _negate_lists(var);            }        }         else if(*str == LIST_CLOSE) {            /* This should be the last character, if not, then this is an             * invalid extra closing bracket */            if(!(*(str+1))) {

⌨️ 快捷键说明

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