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

📄 sf_ipvar.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
                free(tok);                return SFIP_SUCCESS;             }            free(tok);            return SFIP_UNMATCHED_BRACKET;        }        else {            sfip_node_t *node;            /* Skip leading commas */            for(; *str == ','; str++) ;            /* Check for a negated "any" */            if(negation ^ neg_ip && !strcasecmp(tok, "any")) {                free(tok);                return SFIP_NOT_ANY;            }                /* This should be an IP address! */            /* Allocate new node for this string and add it to "ret" */            if((node = sfipnode_alloc(tok, &ret)) == NULL) {                     free(tok);                return ret;            }            if(negation ^ neg_ip) {                _negate_node(node);            }            /* Check if this is a negated, zero'ed IP (equivalent of a "!any") */            if(!sfip_is_set(node->ip) && (node->flags & SFIP_NEGATED)) {                free(tok);                return SFIP_NOT_ANY;            }            ret = sfvar_add_node(var, node, negation ^ neg_ip);            if(ret != SFIP_SUCCESS ) {                free(tok);                return ret;            }        }        free(tok);        if(*end)            str = end + 1;        else break;    }    return SFIP_SUCCESS;}SFIP_RET sfvar_validate(sfip_var_t *var) {    sfip_node_t *idx, *neg_idx;        if(!var->head || !var->neg_head)        return SFIP_SUCCESS;        for(idx = var->head; idx; idx = idx->next)     {        for(neg_idx = var->neg_head; neg_idx; neg_idx = neg_idx->next)        {            /* A smaller netmask means "less specific" */            if(sfip_bits(neg_idx->ip) <= sfip_bits(idx->ip) &&                /* Verify they overlap */                (sfip_contains(neg_idx->ip, idx->ip) == SFIP_CONTAINS))            {                return SFIP_CONFLICT;            }        }    }        return SFIP_SUCCESS;}/* Allocates and returns a new variable, described by "variable". */sfip_var_t *sfvar_alloc(vartable_t *table, char *variable, SFIP_RET *status) {    sfip_var_t *ret;    char *str, *end;        if(!variable || !(*variable)) {        if(status)            *status = SFIP_ARG_ERR;        return NULL;    }        if( (ret = _alloc_var()) == NULL ) {        if(status)            *status = SFIP_ALLOC_ERR;        return NULL;    }    /* Extract and save the variable's name */    /* Start by skipping leading whitespace or line continuations: '\' */    for(str = variable ; *str && (isspace((int)*str) || *str == '\\'); str++) ;    /* Find the end of the name */    for(end = str; *end && !isspace((int)*end) && *end != '\\'; end++) ;    if(!isalpha((int)*str) && *str != '$' && *str != '!') {        if(status)            *status = SFIP_ARG_ERR;         return NULL;    }    /* Set the new variable's name/key */    if((ret->name = strndup(str, end - str)) == NULL) {        if(status)            *status = SFIP_ALLOC_ERR;        return NULL;    }    /* End points to the end of the name.  Skip past it */    str = end;    /* Everything is treated as a list, even if it's one element that's not     * surrounded by brackets */    if((*status = sfvar_parse_iplist(table, ret, str, 0)) != SFIP_SUCCESS) {        return NULL;    }    if(ret->head &&        (ret->head->flags & SFIP_ANY && ret->head->flags & SFIP_NEGATED)) {        if(status)            *status = SFIP_NOT_ANY;        sfvar_free(ret);        return NULL;    }    if(sfvar_validate(ret) == SFIP_CONFLICT) {        if(status)            *status = SFIP_CONFLICT;        sfvar_free(ret);        return NULL;    }    return ret;}static INLINE sfip_node_t *_sfvar_deep_copy_list(sfip_node_t *idx) {    sfip_node_t *ret, *temp, *prev;    ret = temp = NULL;        for( ; idx; idx = idx->next) {        prev = temp;        if( (temp = (sfip_node_t*)calloc(1, sizeof(sfip_node_t))) == NULL ) { // XXX WALK LIST AND DELETE NODES FIRST            return NULL;        }        if( (temp->ip = (sfip_t*)calloc(1, sizeof(sfip_t))) == NULL ) { // XXX WALK LIST AND DELETE NODES FIRST            return NULL;        }        temp->flags = idx->flags;        temp->addr_flags = idx->addr_flags;        /* If it's an "any", there may be no IP object */        if(idx->ip)            memcpy(temp->ip, idx->ip, sizeof(sfip_t));        if(prev)            prev->next = temp;        else {            ret = temp;        }    }     return ret;}sfip_var_t *sfvar_deep_copy(sfip_var_t *var) {    sfip_var_t *ret;    if(!var)        return NULL;    ret = (sfip_var_t*)SnortAlloc(sizeof(sfip_var_t));    ret->mode = var->mode;    ret->head = _sfvar_deep_copy_list(var->head);    ret->neg_head = _sfvar_deep_copy_list(var->neg_head);    return ret;}/* Support function for sfvar_ip_in  */static INLINE int _sfvar_ip_in4(sfip_var_t *var, sfip_t *ip) {    int match;    sfip_node_t *pos_idx, *neg_idx;    match = 0;    pos_idx = var->head;    neg_idx = var->neg_head;    if(!pos_idx)     {        for( ; neg_idx; neg_idx = neg_idx->next)         {            if(sfip_family(neg_idx->ip) != AF_INET)                 continue;                    if(sfip_fast_cont4(neg_idx->ip, ip))            {                return 0;            }        }         return 1;    }        while(pos_idx)                  {        if(neg_idx)        {            if(sfip_family(neg_idx->ip) == AF_INET &&                sfip_fast_cont4(neg_idx->ip, ip))            {                return 0;            }                    neg_idx = neg_idx->next;        }         /* No more potential negations.  Check if we've already matched. */        else if(match)        {            return 1;        }        if(!match)         {            if(sfip_is_set(pos_idx->ip))            {                if(sfip_family(pos_idx->ip) == AF_INET &&                    sfip_fast_cont4(pos_idx->ip, ip))                {                    match = 1;                }                else                {                    pos_idx = pos_idx->next;                }            }            else            {                match = 1;            }        }    }     return 0;}/* Support function for sfvar_ip_in  */static INLINE int _sfvar_ip_in6(sfip_var_t *var, sfip_t *ip) {    int match;    sfip_node_t *pos_idx, *neg_idx;    match = 0;    pos_idx = var->head;    neg_idx = var->neg_head;    if(!pos_idx)     {        for( ; neg_idx; neg_idx = neg_idx->next)         {            if(sfip_family(neg_idx->ip) != AF_INET6)                 continue;                    if(sfip_fast_cont6(neg_idx->ip, ip))            {                return 0;            }        }         return 1;    }        while(pos_idx)                  {        if(neg_idx)        {            if(sfip_family(neg_idx->ip) == AF_INET6 &&                sfip_fast_cont6(neg_idx->ip, ip))            {                return 0;            }                    neg_idx = neg_idx->next;        }         /* No more potential negations.  Check if we've already matched. */        else if(match)        {            return 1;        }        if(!match)         {            if(sfip_is_set(pos_idx->ip))            {                if(sfip_family(pos_idx->ip) == AF_INET6 &&                    sfip_fast_cont6(pos_idx->ip, ip))                {                     match = 1;                }                else                {                    pos_idx = pos_idx->next;                }            }            else            {                match = 1;            }        }    }     return 0;}/* Returns SFIP_SUCCESS if ip is contained in 'var', SFIP_FAILURE otherwise *//* If either argument is NULL, SFIP_ARG_ERR is returned. */int sfvar_ip_in(sfip_var_t *var, sfip_t *ip) {    if(!var || !ip)        return 0;#if 0    if(var->mode == SFIP_TABLE) {        // XXX    }    else {#endif        /* Since this is a performance-critical function it uses different         * codepaths for IPv6 and IPv4 traffic, rather than the dual-stack          * functions. */        if(sfip_family(ip) == AF_INET)         {            return _sfvar_ip_in4(var, ip);        }        else         {            return _sfvar_ip_in6(var, ip);        }#if 0    }#endif}/* Prints the variable "var" to the file descriptor 'f' */void sfvar_print(FILE *f, sfip_var_t *var) {    if(!f) return;    if(!var || !var->head) {        fprintf(f, "[no variable]\n");        return;    }    fprintf(f, "Name: %s\n", var->name);    if(var->mode == SFIP_LIST) {        if(var->head->flags & SFIP_ANY)             fprintf(f, "\t%p: <any>\n", var->head);        else {             sfip_set_print(f, var->head);        }    } else if(var->mode == SFIP_TABLE) {        // XXX    }}void sfip_set_print(FILE *f, sfip_node_t *p) {     for(; p; p = p->next)  {         if(!p->ip) continue;         if(p->flags & SFIP_NEGATED)             fprintf(f, "\t!%s\n", sfip_to_str(p->ip));         else             fprintf(f, "\t %s\n", sfip_to_str(p->ip));     }}int sfvar_flags(sfip_node_t *node) {    if(node) return node->flags;    return -1;}/* XXX The unit tests for this code are performed within sf_vartable.c */#if 0int main() {    sfip_vtable *table;    sfip_var_t *var;    sfip_t *ip;        /* Test parsing */    /* Allowable arguments:      *      { <ip>[, <ip>, ... , <ip> }     * Where an IP can be in CIDR notation, or be specified with a netmask.     * IPs may also be negated with '!' */    puts("********************************************************************");    puts("Testing parsing:");    var = sfvar_str(" {   1.2.3.4/8,  5.5.5.5 255.255.255.0, any} ");    sfip_print_var(stdout, var);    sfvar_free(var);    puts("");    var = sfvar_str(" {   1.2.3.4,  ffff::3/127, 0.0.0.1} ");    sfip_print_var(stdout, var);    ip = sfip_alloc("1.2.3.5");    printf("(need more of these) 'in': %d\n", sfip_in(var, ip));    puts("also, use 'sfip_in' for the unit tests");    puts("");    return 0;}#endif    

⌨️ 快捷键说明

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