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

📄 sf_ip.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_ip.c * 11/17/06 * * Library for managing IP addresses of either v6 or v4 families.  */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include <math.h> /* For ceil */#include "sf_ip.h"#ifdef TESTER#define FatalError printf#endif/* Support function .. but could see some external uses */static INLINE int sfip_length(sfip_t *ip) {    ARG_CHECK1(ip, 0);    if(sfip_family(ip) == AF_INET) return 4;    return 16;}/* Support function */static INLINE int sfip_str_to_fam(char *str) {    ARG_CHECK1(str, 0);    if(strchr(str,(int)':')) return AF_INET6;    if(strchr(str,(int)'.')) return AF_INET;    return AF_UNSPEC;}/* Place-holder allocation incase we want to do something more indepth later */static INLINE sfip_t *_sfip_alloc() {    /* Note: using calloc here instead of SnortAlloc since the dynamic libs      * can't presently resolve SnortAlloc */    return (sfip_t*)calloc(sizeof(sfip_t), 1); }/* Masks off 'val' bits from the IP contained within 'ip' */static INLINE int sfip_cidr_mask(sfip_t *ip, int val) {    int i;    unsigned int mask = 0;     unsigned int *p;    int index = (int)ceil(val / 32.0) - 1;       ARG_CHECK1(ip, SFIP_ARG_ERR);    p = ip->ip32;    if( val < 0 ||        ((sfip_family(ip) == AF_INET6) && val > 128) ||        ((sfip_family(ip) == AF_INET) && val > 32) ) {        return SFIP_ARG_ERR;    }        /* Build the netmask by converting "val" into      * the corresponding number of bits that are set */    for(i = 0; i < 32- (val - (index * 32)); i++)        mask = (mask<<1) + 1;    p[index] = htonl((ntohl(p[index]) & ~mask));    index++;    /* 0 off the rest of the IP */    for( ; index<4; index++) p[index] = 0;    return SFIP_SUCCESS;}/* Allocate IP address from a character array describing the IP */sfip_t *sfip_alloc(char *ip, SFIP_RET *status) {    int tmp;    sfip_t *ret;       if(!ip) {        if(status)            *status = SFIP_ARG_ERR;        return NULL;    }    if((ret = _sfip_alloc()) == NULL) {        if(status)             *status = SFIP_ALLOC_ERR;        return NULL;    }        if( (tmp = sfip_pton(ip, ret)) != SFIP_SUCCESS) {        if(status)             *status = tmp;        sfip_free(ret);        return NULL;    }    if(status)         *status = SFIP_SUCCESS;    return ret;}/* Allocate IP address from an array of 8 byte integers */sfip_t *sfip_alloc_raw(void *ip, int family, SFIP_RET *status) {    sfip_t *ret;    if(!ip) {        if(status)            *status = SFIP_ARG_ERR;        return NULL;    }    if((ret = _sfip_alloc()) == NULL) {        if(status)            *status = SFIP_ALLOC_ERR;        return NULL;    }    ret->bits = (family==AF_INET?32:128);    ret->family = family;    /* XXX Replace with appropriate "high speed" copy */    memcpy(ret->ip8, ip, ret->bits/8);    if(status)        *status = SFIP_SUCCESS;    return ret;}/* Support function for _netmask_str_to_bit_count */static INLINE int _count_bits(unsigned int val) {    unsigned int count;     for (count = 0; val; count++) {        val &= val - 1;    }    return count;}/* Support function for sfip_pton.  Used for converting a netmask string * into a number of bits to mask off */static INLINE int _netmask_str_to_bit_count(char *mask, int family) {    u_int32_t buf[4];    int bits;    /* XXX      * Mask not validated.       * Only sfip_pton should be using this function, and using it safely.      * XXX */    if(inet_pton(family, mask, buf) < 1)        return -1;    if(family == AF_INET)        return _count_bits(buf[0]);     bits =  _count_bits(buf[0]);     bits += _count_bits(buf[1]);     bits += _count_bits(buf[2]);     bits += _count_bits(buf[3]);         return bits;}/* Parses "src" and stores results in "dst" */SFIP_RET sfip_pton(char *src, sfip_t *dst) {    char *mask;    char *sfip_buf;    char *ip;    int bits;    if(!dst || !src)         return SFIP_ARG_ERR;                if((sfip_buf = strdup(src)) == NULL)         return SFIP_ALLOC_ERR;    ip = sfip_buf;    dst->family = sfip_str_to_fam(src);    /* skip whitespace or opening bracket */    while(isspace((int)*ip) || *ip == '[')        ip++;    /* check for and extract a mask in CIDR form */    if( (mask = strchr(ip, (int)'/')) != NULL ) {        /* NULL out this character so inet_pton will see the          * correct ending to the IP string */        *mask = 0;        mask++;        /* verify a leading digit */        if(((dst->family == AF_INET6) && !isxdigit((int)*mask)) ||           ((dst->family == AF_INET) && !isdigit((int)*mask))) {            free(sfip_buf);                                      return SFIP_CIDR_ERR;        }        /* Check if there's a netmask here instead of the number of bits */        if(strchr(mask, (int)'.') || strchr(mask, (int)':'))             bits = _netmask_str_to_bit_count(mask, sfip_str_to_fam(mask));        else            bits = atoi(mask);    }    /* We've already skipped the leading whitespace, if there is more      * whitespace, then there's probably a netmask specified after it. */    else if( (mask = strchr(ip, (int)' ')) != NULL ||            /* If this is IPv4, ia ':' may used specified to indicate a netmask */             (dst->family == AF_INET && (mask = strchr(ip, (int)':')) != NULL) ) {        *mask = 0;  /* Now the IP will end at this point */        /* skip whitespace */        do {             mask++;        } while(isspace((int)*mask));        /* Make sure we're either looking at a valid digit, or a leading         * colon, such as can be the case with IPv6 */        if((dst->family == AF_INET && isdigit((int)*mask)) ||           (dst->family == AF_INET6 && (isxdigit((int)*mask) || *mask == ':'))) {             bits = _netmask_str_to_bit_count(mask, sfip_str_to_fam(mask));        }         /* No netmask */        else {             if(dst->family == AF_INET) bits = 32;            else bits = 128;                }    }    /* No netmask */    else {        if(dst->family == AF_INET) bits = 32;        else bits = 128;            }    if(inet_pton(dst->family, ip, dst->ip8) < 1) {        free(sfip_buf);                                  return SFIP_INET_PARSE_ERR;    }    /* Store mask */    dst->bits = bits;    /* Apply mask */    if(sfip_cidr_mask(dst, bits) != SFIP_SUCCESS) {        free(sfip_buf);        return SFIP_INVALID_MASK;    }        free(sfip_buf);    return SFIP_SUCCESS;}/* Sets existing IP, "dst", to be source IP, "src" */SFIP_RET sfip_set_raw(sfip_t *dst, void *src, int family) {        ARG_CHECK3(dst, src, dst->ip32, SFIP_ARG_ERR);    dst->family = family;    if(family == AF_INET) {        dst->ip32[0] = *(u_int32_t*)src;        memset(&dst->ip32[1], 0, 12);        dst->bits = 32;    } else if(family == AF_INET6) {        memcpy(dst->ip8, src, 16);        dst->bits = 128;    } else {        return SFIP_ARG_ERR;    }        return SFIP_SUCCESS;}/* Sets existing IP, "dst", to be source IP, "src" */SFIP_RET sfip_set_ip(sfip_t *dst, sfip_t *src) {    ARG_CHECK2(dst, src, SFIP_ARG_ERR);    dst->family = src->family;    dst->bits = src->bits;    dst->ip32[0] = src->ip32[0];    dst->ip32[1] = src->ip32[1];    dst->ip32[2] = src->ip32[2];    dst->ip32[3] = src->ip32[3];    return SFIP_SUCCESS;}/* Obfuscates an IP * Makes 'ip': ob | (ip & mask) */void sfip_obfuscate(sfip_t *ob, sfip_t *ip) {    unsigned int *ob_p, *ip_p;    int index, i;    unsigned int mask = 0;    if(!ob || !ip)        return;    ob_p = ob->ip32;    ip_p = ip->ip32;    /* Build the netmask by converting "val" into      * the corresponding number of bits that are set */    index = (int)ceil(ob->bits / 32.0) - 1;    for(i = 0; i < 32- (ob->bits - (index * 32)); i++)        mask = (mask<<1) + 1;    /* Note: The old-Snort obfuscation code uses !mask for masking.     * hence, this code uses the same algorithm as sfip_cidr_mask     * except the mask below is not negated. */    ip_p[index] = htonl((ntohl(ip_p[index]) & mask));    index++;    /* 0 off the rest of the IP */    for( ; index<4; index++) ip_p[index] = 0;    /* OR remaining pieces */    ip_p[0] |= ob_p[0];

⌨️ 快捷键说明

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