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

📄 sf_ip.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    ip_p[1] |= ob_p[1];    ip_p[2] |= ob_p[2];    ip_p[3] |= ob_p[3];}/* Check if ip is contained within the network specified by net */ /* Returns SFIP_EQUAL if so.   * XXX sfip_contains assumes that "ip" is  *      not less-specific than "net" XXX*/SFIP_RET sfip_contains(sfip_t *net, sfip_t *ip) {    unsigned int bits, mask, temp, i;    int net_fam, ip_fam;    unsigned int *p1, *p2;    /* SFIP_CONTAINS is returned here due to how IpAddrSetContains      * handles zero'ed IPs" */    ARG_CHECK2(net, ip, SFIP_CONTAINS);    bits = sfip_bits(net);    net_fam = sfip_family(net);    ip_fam = sfip_family(ip);    /* If the families are mismatched, check if we're really comparing     * an IPv4 with a mapped IPv4 (in IPv6) address. */    if(net_fam != ip_fam) {        if(net_fam != AF_INET && !sfip_ismapped(ip))            return SFIP_NOT_CONTAINS;        /* Both are really IPv4.  Only compare last 4 bytes of 'ip'*/        p1 = net->ip32;        p2 = &ip->ip32[3];                /* Mask off bits */        bits = 32 - bits;        temp = (ntohl(*p2) >> bits) << bits;        if(ntohl(*p1) == temp) return SFIP_CONTAINS;        return SFIP_NOT_CONTAINS;    }    p1 = net->ip32;    p2 = ip->ip32;    /* Iterate over each 32 bit segment */    for(i=0; i < bits/32 && i < 4; i++, p1++, p2++) {        if(*p1 != *p2)             return SFIP_NOT_CONTAINS;    }    /* At this point, there are some number of remaining bits to check.     * Mask the bits we don't care about off of "ip" so we can compare     * the ints directly */    temp = ntohl(*p2);    mask = 32 - (bits - 32*i);    temp = (temp >> mask) << mask;    /* If p1 was setup correctly through this library, there is no need to      * mask off any bits of its own. */    if(ntohl(*p1) == temp)         return SFIP_CONTAINS;    return SFIP_NOT_CONTAINS;}void sfip_raw_ntop(int family, const void *ip_raw, char *buf, int bufsize) {    int i;    if(!ip_raw || !buf || !bufsize ||        (family != AF_INET && family != AF_INET6) ||        /* Make sure if it's IPv6 that the buf is large enough. */       /* Need atleast a max of 8 fields of 4 bytes plus 7 for colons in         * between.  Need 1 more byte for null. */       (family == AF_INET6 && bufsize < 8*4 + 7 + 1) ||       /* Make sure if it's IPv4 that the buf is large enough. */       /* 4 fields of 3 numbers, plus 3 dots and a null byte */       (family == AF_INET && bufsize < 3*4 + 4) )    {        if(buf && bufsize > 0) buf[0] = 0;        return;    }    /* 4 fields of at most 3 characters each */    if(family == AF_INET) {        u_int8_t *p = (u_int8_t*)ip_raw;        for(i=0; p < ((u_int8_t*)ip_raw) + 4; p++) {            i += sprintf(&buf[i], "%d", *p);            /* If this is the last iteration, this could technically cause one             *  extra byte to be written past the end. */            if(i < bufsize && ((p + 1) < ((u_int8_t*)ip_raw+4)))                buf[i] = '.';            i++;        }    /* Check if this is really just an IPv4 address represented as 6,      * in compatible format */#if 0    }     else if(!field[0] && !field[1] && !field[2]) {        unsigned char *p = (unsigned char *)(&ip->ip[12]);        for(i=0; p < &ip->ip[16]; p++)              i += sprintf(&buf[i], "%d.", *p);#endif    }     else {        u_int16_t *p = (u_int16_t*)ip_raw;        for(i=0; p < ((u_int16_t*)ip_raw) + 8; p++) {            i += sprintf(&buf[i], "%04x", ntohs(*p));            /* If this is the last iteration, this could technically cause one             *  extra byte to be written past the end. */            if(i < bufsize && ((p + 1) < ((u_int16_t*)ip_raw) + 8))                buf[i] = ':';            i++;        }    }}/* Uses a static buffer to return a string representation of the IP */char *sfip_to_str(sfip_t *ip) {    /* IPv6 addresses will be at most 8 fields, of 4 characters each,      * with 7 colons inbetween, one NULL, and one fudge byte for sloppy use     * in sfip_to_strbuf */    static char buf[8*4 + 7 + 1 + 1];    if(!ip)         return NULL;    sfip_raw_ntop(sfip_family(ip), ip->ip32, buf, sizeof(buf));        return buf;}void sfip_free(sfip_t *ip) {    if(ip) free(ip);}/* Returns 1 if the IP is non-zero. 0 otherwise */int sfip_is_loopback(sfip_t *ip) {    unsigned int *p;    ARG_CHECK1(ip, 0);    if(sfip_family(ip) == AF_INET) {        return (ip->ip8[0] == 0x7f);    }    p = ip->ip32;    /* Check the first two ints in an IPv6 address,     * and verify they're NULL.  If not, it's not a loopback */    if(p[0] || p[1]) return 0;    /* Check if the 3rd int is a mapped IPv4 address or NULL */    /* If it's 0xffff, then we might be carrying an IPv4 loopback address */    if(p[2] != 0xffff && p[2] != 0) return 0;    if(p[3] == 1 ||       /* IPv6 loopback */       ip->ip8[12] == 0x7f /* IPv4 loopback over compatible or mapped IPv6 */      ) return 1;    return 0;}int sfip_ismapped(sfip_t *ip) {    unsigned int *p;    ARG_CHECK1(ip, 0);    if(sfip_family(ip) == AF_INET)         return 0;           p = ip->ip32;    if(p[0] || p[1] || (p[2] != 0xffff && p[2] != 0)) return 0;    return 1;}#ifndef strndup char *strndup(const char *s, size_t n) {    char *ret;     size_t len = strlen(s);    if(len < n) {        n = len;    }     ret = (char*)malloc(n+1);    if(!ret)         return NULL;    strncpy(ret, s, n);    ret[n] = 0;    return ret;}#endif#ifdef TESTER#include <stdio.h>#include <string.h>#define PASS 1#define FAIL 0int sf_ip_failures = 0;/* By using a macro, __LINE__  will be right */#define test(msg, result) { \    if(result == FAIL) { printf("\tFAILED:\t%s\tline %d\n", msg, __LINE__); sf_ip_failures++; } \    else printf("\tPassed:\t%s\n", msg);\}int test_str(sfip_t *ip, char *str) {    char *s = sfip_to_str(ip);    if(!strcmp( s, str) ) return PASS;    printf("\tShould have seen: \"%s\"\n", str);    printf("\tInstead saw:      \"%s\"\n\t", s);    return FAIL;}int sf_ip_unittest() {    unsigned int i = 0xffffffff;    sfip_t *ip[9];    sfip_t conv;       /* Verify the simplest allocation method */    puts("*********************************************************************");    puts("Testing raw allocation:");    ip[0] = sfip_alloc_raw(&i, AF_INET);    test("255.255.255.255", test_str(ip[0], "255.255.255.255"));    /* The following lines verify parsing via sfip_alloc */    /* sfip_alloc should be able to recognize IPv4 and IPv6 addresses,      * and extract and apply netmasks.  IPv6 address can be specified in      * any valid IPv6 notation as recognized by inet_pton.  Netmasks can      * either be specified in IP form or by using CIDR notation */    puts("");    puts("*********************************************************************");    puts("Testing parsing:");    ip[1] = sfip_alloc("192.168.0.1");    test("192.168.0.1", test_str(ip[1], "192.168.0.1"));        ip[2] = sfip_alloc("255.255.255.255/21");    test("255.255.255.255/21", test_str(ip[2], "255.255.248.0"));        ip[3] = sfip_alloc("1.1.255.255      255.255.248.0");    test("1.1.255.255      255.255.248.0", test_str(ip[3], "1.1.248.0"));        ip[4] = sfip_alloc(" 2001:0db8:0000:0000:0000:0000:1428:57ab   ");    test(" 2001:0db8:0000:0000:0000:0000:1428:57ab   ", test_str(ip[4], "2001:0db8:0000:0000:0000:0000:1428:57ab"));        ip[5] = sfip_alloc("ffff:ffff::1");    test("ffff:ffff::1", test_str(ip[5], "ffff:ffff:0000:0000:0000:0000:0000:0001"));        ip[6] = sfip_alloc("fFfF::FfFf:FFFF/127");    test("fFfF::FfFf:FFFF/127", test_str(ip[6], "ffff:0000:0000:0000:0000:0000:ffff:fffe"));        ip[7] = sfip_alloc("ffff::ffff:1/8");    test("ffff::ffff:1/8", test_str(ip[7], "ff00:0000:0000:0000:0000:0000:0000:0000"));    ip[8] = sfip_alloc("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff ::3");    test("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff ::3", test_str(ip[8], "c000:0000:0000:0000:0000:0000:0000:0000"));    /* Free everything and reallocate it. */    /* This will atleast /imply/ memory is being handled somewhat properly. */    puts("");    puts("*********************************************************************");    puts("Verifying deletes:");    /* Make sure we can free: */    for(i=0; i<9; i++) { sfip_free(ip[i]); }    i = 0xffffffff;    /* Reallocate */    ip[0] = sfip_alloc_raw(&i, AF_INET);    ip[1] = sfip_alloc("192.168.0.1");    ip[2] = sfip_alloc("255.255.255.255/21");    ip[3] = sfip_alloc("1.1.255.255      255.255.248.0");    ip[4] = sfip_alloc(" 2001:0db8:0000:0000:0000:0000:1428:57ab   ");    ip[5] = sfip_alloc("ffff:ffff::1");    ip[6] = sfip_alloc("ffff::ffff:FFFF/127");    ip[7] = sfip_alloc("ffff::ffff:1/8");    ip[8] = sfip_alloc("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff ::3");    printf("\tPassed (as best I can tell, since there was no seg fault)\n");    /* The following lines verify that IPs can be converted to different families. */    puts("");    puts("*********************************************************************");    puts("Verifying IPv4<->IPv6 conversions:");    conv = sfip_4to6(ip[0]);    test("ipv4 -> ipv6", test_str(&conv, "0000:0000:0000:0000:0000:ffff:ffff:ffff"));    conv = sfip_6to4(&conv);    /* Converting an IP from v4 to v6 and back to v4 should yield the same IP. */    test("ipv6 -> ipv4", test_str(&conv, "255.255.255.255"));    conv = sfip_6to4(ip[4]);    test("ipv6 -> ipv4", test_str(&conv, "20.40.87.171"));        /* Comparisons can be byte-by-byte, effectively treating an IP that has      * been masked as an unmasked IP (treats the masked bits as zeroed) */    puts("");    puts("*********************************************************************");    puts("Testing byte-by-byte comparisons:");    test("ip[0] > ip[1]", (sfip_cmp(ip[0], ip[1]) == SFIP_GREATER) );    test("ip[1] < ip[2]", (sfip_cmp(ip[1], ip[2]) == SFIP_LESSER) );    test("ip[5] > ip[8]", (sfip_cmp(ip[5], ip[8]) == SFIP_GREATER) );        /* Comparisons can also check if an IP is contained within a given network */    puts("");    puts("*********************************************************************");    puts("Testing network containment comparisons:");    test("ip[0] does not contain ip[1]", (sfip_contains(ip[0], ip[1]) == SFIP_NOT_CONTAINS) );    test("ip[1] does not contain ip[2]", (sfip_contains(ip[1], ip[2]) == SFIP_NOT_CONTAINS) );    test("ip[5] does not contain ip[7]", (sfip_contains(ip[5], ip[7]) == SFIP_NOT_CONTAINS) );    test("ip[7] does contain ip[5]", (sfip_contains(ip[7], ip[5]) == SFIP_CONTAINS) );    test("ip[2] does contain ip[0]", (sfip_contains(ip[2], ip[0]) == SFIP_CONTAINS) );    test("ip[0] does not contain ip[2]", (sfip_contains(ip[0], ip[2]) == SFIP_NOT_CONTAINS) );    test("ip[0] can't be compared to ip[4]", (sfip_contains(ip[0], ip[4]) == SFIP_ARG_ERR) );        puts("*********************************************************************");    puts(" ... Cleaning up");    for(i=0; i<9; i++) { sfip_free(ip[i]); }    printf("\n\tTotal failures: %d\n\n", sf_ip_failures);    return 1;}#endif

⌨️ 快捷键说明

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