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

📄 ipobj.c

📁 著名的入侵检测系统snort的最新版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************** * * Copyright (C) 2003-2007 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. * ****************************************************************************/ /*   ipobj.c   IP address encapsulation interface   This module provides encapsulation of single IP ADDRESSes as   objects, and collections of IP ADDRESSes as objects*/#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <stdio.h>#include <string.h>#ifndef WIN32#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#endif#include <ctype.h>#include "ipobj.h"#include "util.h"/*   UITLITY SUPPORT*/int  ip_familysize( int family )  /* Use with stack allocated structures */{    if( family == IPV4_FAMILY ) return IPV4_LEN;    if( family == IPV6_FAMILY ) return IPV6_LEN;    return 0;}int ip4_sprintx( char * s, int slen, void * ip4 ){    int  rc;    unsigned char * ip = (unsigned char *) ip4;    rc = SnortSnprintf(s, slen, "%d.%d.%d.%d", ip[3], ip[2], ip[1], ip[0]);    if( rc != SNORT_SNPRINTF_SUCCESS )        return -1;    return 0;}int ip6_sprintx( char * s, int slen, void * ip6 ){    int  rc;    unsigned short * ps = (unsigned short *) ip6;    rc = SnortSnprintf(s, slen, "%.1x:%.1x:%.1x:%.1x:%.1x:%.1x:%.1x:%.1x",                       ps[7], ps[6], ps[5], ps[4], ps[3], ps[2], ps[1], ps[0]);    if( rc != SNORT_SNPRINTF_SUCCESS )        return -1;    return 0;}int ip_sprint( char * s, int slen, IPADDRESS * p ){    if( p->family == IPV4_FAMILY )    {        if( ip4_sprintx( s, slen, p->ip ) )            return -1;          return 0;    }         else if( p->family == IPV6_FAMILY )    {        if( ip6_sprintx( s, slen, p->ip ) )            return -1;          return 0;    }         return -1;}int ip_fprint( FILE * fp, IPADDRESS * p ){    int  stat;    char s[256];    stat = ip_sprint( s, sizeof(s), p );    if( stat )        return stat;    fprintf(fp,"%s",s);    return 0;}/*   INIT FAMILY FOR IP ADDRESS*/static void ip_init ( IPADDRESS * p , int family )  /* Use with stack allocated structures */{    if( p )    {        p->family = family;    }}/*   ALLOCATE/CREATE IP ADDRESS*/IPADDRESS * ip_new ( int family )   /* Dynamic allocation */{    IPADDRESS * p = NULL;    if( family == IPV4_FAMILY )    {        p = ( IPADDRESS * )SnortAlloc( sizeof(IPADDRESS) + IPV4_LEN - 1 );        ip_init( p, family );    }    else if( family == IPV6_FAMILY )    {        p = ( IPADDRESS * )SnortAlloc( sizeof(IPADDRESS) + IPV6_LEN - 1 );        ip_init( p, family );    }    return p;}/*   FREE IP ADDRESS*/void ip_free ( IPADDRESS * p ){    if( p )        free( p );}/*   Get Address Family*/int ip_family( IPADDRESS * p ){    return p->family;}/*   Get Address size - in bytes*/int ip_size( IPADDRESS * p ){    return ip_familysize( p->family ) ;}/*   SET IP ADDRESS*/int ip_set( IPADDRESS * ia, void * ip, int family ){    if( !ia ) return -1;    if( ia->family != family ) return -1;    if(      family == IPV4_FAMILY ) memcpy(ia->ip,ip,IPV4_LEN);    else if( family == IPV6_FAMILY ) memcpy(ia->ip,ip,IPV6_LEN);    return 0;}/*   GET IP ADDRESS*/int ip_get( IPADDRESS * ia, void * ip, int family ){    if( !ia ) return -1;    if( ia->family != family )        return -1;    if(      family == IPV4_FAMILY ) memcpy(ip,ia->ip,IPV4_LEN);    else if( family == IPV6_FAMILY ) memcpy(ip,ia->ip,IPV6_LEN);    return 0;}/*   TEST IP ADDRESS*/int ip_equal( IPADDRESS * ia, void * ip, int family ){    if( !ia ) return -1;    if( ia->family != family )        return 0;    if( ia->family == IPV4_FAMILY )    {        if( memcmp(ip,ia->ip,IPV4_LEN) == 0 )             return 1;    }    else if( ia->family == IPV6_FAMILY )    {        if( memcmp(ip,ia->ip,IPV6_LEN) == 0 )             return 1;    }    return 0;}int ip_eq( IPADDRESS * ia, IPADDRESS * ib ){    if( !ia ) return -1;    if( !ib ) return -1;    if( ia->family != ib->family )        return 0; /* nope */    if( ia->family == IPV4_FAMILY )    {        if( memcmp(ib->ip,ia->ip,IPV4_LEN) == 0 )             return 1;    }    else if( ia->family ==  IPV6_FAMILY )    {        if( memcmp(ib->ip,ia->ip,IPV6_LEN) == 0 )             return 1;    }    return 0;}/*   IP COLLECTION INTERFACE   Snort Accepts:   IP-Address		192.168.1.1   IP-Address/MaskBits	192.168.1.0/24   IP-Address/Mask		192.168.1.0/255.255.255.0   These can all be handled via the CIDR block notation : IP/MaskBits   We use collections (lists) of cidr blocks to represent address blocks   and indivdual addresses.       For a single IPAddress the implied Mask is 32 bits,or 255.255.255.255, or 0xffffffff, or -1.*/static void ipset_init( IPSET * ipc ){    if( ipc )    {        ipc->family = IPV4_FAMILY;          sflist_init( &ipc->cidr_list );    }}static void ipset6_init( IPSET * ipc ){    if( ipc )    {        ipc->family = IPV6_FAMILY;          sflist_init( &ipc->cidr_list );    }}IPSET * ipset_new( int family ){    IPSET * p = (IPSET *)SnortAlloc( sizeof(IPSET));    if( family == IPV4_FAMILY )    {        ipset_init( p );    }    else    {        ipset6_init( p );    }    return p;}IPSET * ipset_copy( IPSET *ipsp ){    int family;    IPSET * newset = NULL;    CIDRBLOCK *cbp;    CIDRBLOCK6 *cbp6;    if(ipsp)    {        family = ipset_family( ipsp );        newset = ipset_new(family) ;        if( family == IPV4_FAMILY )        {            for(cbp =(CIDRBLOCK*)sflist_first( &ipsp->cidr_list );                cbp !=NULL;                cbp =(CIDRBLOCK*)sflist_next( &ipsp->cidr_list ) )            {                ipset_add(newset, &cbp->ip, &cbp->mask, &cbp->portset, cbp->notflag, family);            }        }        else        {            for(cbp6 =(CIDRBLOCK6*)sflist_first( &ipsp->cidr_list );                cbp6 !=NULL;                cbp6 =(CIDRBLOCK6*)sflist_next( &ipsp->cidr_list ) )            {                ipset_add(newset, &cbp6->ip, &cbp6->mask, &cbp6->portset, cbp6->notflag, family);            }        }    }    return newset;}void ipset_free( IPSET * ipc ){    if( ipc )    {        if( ipc->family == IPV4_FAMILY )        {            CIDRBLOCK *p = (CIDRBLOCK *) sflist_first(&ipc->cidr_list);                   while ( p )            {                sflist_free(&p->portset.port_list);                p = (CIDRBLOCK *) sflist_next(&ipc->cidr_list);            }        }        else if( ipc->family == IPV6_FAMILY )        {            CIDRBLOCK6 *p = (CIDRBLOCK6 *) sflist_first(&ipc->cidr_list);                   while ( p )            {                sflist_free(&p->portset.port_list);                p = (CIDRBLOCK6 *) sflist_next(&ipc->cidr_list);            }        }        sflist_free( &ipc->cidr_list );        free( ipc );    }}int ipset_family( IPSET * ipset ){    return ipset->family;	}/*    The user must know what kind of address he's adding,    and the family of the IPSET */int ipset_add( IPSET * ipc, void * vip, void * vmask, void *vport, int notflag , int family ){    if( !ipc ) return -1;    if( ipc->family != family )    {        return -1;    }    if( ipc->family == IPV4_FAMILY )    {        unsigned * ip=(unsigned*)vip;        unsigned * mask=(unsigned*)vmask;        PORTSET  * portset = (PORTSET *) vport;        CIDRBLOCK *p = (CIDRBLOCK*)calloc( 1,sizeof(CIDRBLOCK) );        if(!p) return -1;        p->mask    = *mask;        p->ip      = *ip & *mask;        p->portset = *portset;        p->notflag = notflag;        if( notflag )sflist_add_head( &ipc->cidr_list, p ); // test NOT items 1st        else         sflist_add_tail( &ipc->cidr_list, p );    }    else if( ipc->family == IPV6_FAMILY )    {        int i;        unsigned short * ips = (unsigned short *)vip;        PORTSET  * portset = (PORTSET *) vport;        CIDRBLOCK6 *p6 = (CIDRBLOCK6*)calloc( 1,sizeof(CIDRBLOCK6) );        if(!p6) return -1;        memcpy(p6->mask,vmask,IPV6_LEN);        for(i=0;i<8;i++)        {            p6->ip[i] = (unsigned short)(ips[i] & p6->mask[i]);        }        p6->portset = *portset;        p6->notflag = notflag;        if( notflag ) sflist_add_head( &ipc->cidr_list, p6 ); // always test NOT items 1st        else          sflist_add_tail( &ipc->cidr_list, p6 );    }    else return -1;    return 0;}int ipset_contains( IPSET * ipc, void * ip, void *port, int family ){    PORTRANGE *pr;    unsigned short portu;    if( !ipc ) return 0;    if( ipc->family != family )    {        return 0;    }    if ( port )        portu = *((unsigned short *)port);    else        portu = 0;    if( ipc->family == IPV4_FAMILY )    {        CIDRBLOCK * p;        unsigned  * ipu = (unsigned*)ip;        for(p =(CIDRBLOCK*)sflist_first( &ipc->cidr_list );             p!=0;            p =(CIDRBLOCK*)sflist_next( &ipc->cidr_list ) )        {            if( (p->mask & (*ipu)) == p->ip )            {                for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list);                     pr != 0;                     pr=(PORTRANGE*)sflist_next(&p->portset.port_list) )                {                    /*                      *  If the matching IP has a wildcard port (pr->port_hi == 0 ) or                     *  if the ports actually match.                     */                    if ( (pr->port_hi == 0) ||                         (portu >= pr->port_lo && portu <= pr->port_hi) )                    {                        if( p->notflag )                            return 0;                        return 1;                    }                }            }        }    }    else if( ipc->family == IPV6_FAMILY )    {        CIDRBLOCK6     * p;        unsigned short * ips = (unsigned short *)ip;        unsigned short   mip[8];        for(p = (CIDRBLOCK6*)sflist_first( &ipc->cidr_list );            p!= 0;            p = (CIDRBLOCK6*)sflist_next( &ipc->cidr_list ) )        {                       mip[0] = (unsigned short)(p->mask[0] & ips[0]);            mip[1] = (unsigned short)(p->mask[1] & ips[1]);            mip[2] = (unsigned short)(p->mask[2] & ips[2]);            mip[3] = (unsigned short)(p->mask[3] & ips[3]);            mip[4] = (unsigned short)(p->mask[4] & ips[4]);            mip[5] = (unsigned short)(p->mask[5] & ips[5]);            mip[6] = (unsigned short)(p->mask[6] & ips[6]);            mip[7] = (unsigned short)(p->mask[7] & ips[7]);            if( memcmp(mip,p->ip,IPV6_LEN) == 0 )            {                for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list);                     pr != 0;                     pr=(PORTRANGE*)sflist_next(&p->portset.port_list) )                {                    /*                      * If the caller wants to match any port (portu == 0) or                     *  if the matching IP has a wildcard port (pr->port_hi == 0 ) or                     *  if the ports actually match.                     */                    if ( portu == 0 || pr->port_hi == 0 ||                         (portu >= pr->port_lo && portu <= pr->port_hi) )                    {                                       if( p->notflag )                            return 0;                        return 1;                    }                }            }        }    }    else        return -1;    return 0;}int ipset_print( IPSET * ipc ){    char ip_str[80], mask_str[80];    PORTRANGE * pr;    if( !ipc ) return 0;    if( ipc->family == IPV4_FAMILY )    {        CIDRBLOCK * p;        printf("IPSET-IPV4\n");        for( p =(CIDRBLOCK*)sflist_first( &ipc->cidr_list );             p!=0;             p =(CIDRBLOCK*)sflist_next( &ipc->cidr_list ) )        {            ip4_sprintx(ip_str,  80, &p->ip);            ip4_sprintx(mask_str,80, &p->mask);            if( p->notflag )                printf("CIDR BLOCK: !%s / %s", ip_str,mask_str);            else                printf("CIDR BLOCK: %s / %s",  ip_str,mask_str);            for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list);                 pr != 0;                 pr=(PORTRANGE*)sflist_next(&p->portset.port_list) )            {                printf(" : %d", pr->port_lo);                if ( pr->port_hi != pr->port_lo )                    printf("-%d", pr->port_hi);            }            printf("\n");        }    }    else if( ipc->family == IPV6_FAMILY )    {        CIDRBLOCK6 * p;        printf("IPSET-IPV6\n");        for(p =(CIDRBLOCK6*)sflist_first( &ipc->cidr_list );            p!=0; p =(CIDRBLOCK6*)sflist_next( &ipc->cidr_list ) )        {            ip6_sprintx(ip_str,  80,p->ip);            ip6_sprintx(mask_str,80,p->mask);            if( p->notflag )                printf("CIDR BLOCK: !%s / %s", ip_str,mask_str);            else                printf("CIDR BLOCK: %s / %s",  ip_str,mask_str);             for( pr=(PORTRANGE*)sflist_first(&p->portset.port_list);                 pr != 0;                 pr=(PORTRANGE*)sflist_next(&p->portset.port_list) )            {                printf(" : %d", pr->port_lo);                if ( pr->port_hi != pr->port_lo )                    printf("-%d", pr->port_hi);            }            printf("\n");        }    }    else return -1;    return 0;}static void portset_init( PORTSET * portset ){     sflist_init(&portset->port_list);}static int portset_add(PORTSET * portset, unsigned port_lo, unsigned port_hi){    PORTRANGE *p;    if( !portset ) return -1;    p = (PORTRANGE *) calloc( 1,sizeof(PORTRANGE) );    if(!p) return -1;    p->port_lo = port_lo;    p->port_hi = port_hi;    sflist_add_tail(&portset->port_list, p );    return 0;}/* parsing functions to help make life a bit easier *//*   Port string can be:   25   25 26   25-28   25 28-29   25,26 27 30-35   portset is a list of port ranges.  A port range can be a single port (25-25). */static int port_parse(char *portstr, PORTSET *portset){    unsigned port_lo = 0, port_hi = 0;    char *port1;    char *port_begin;    char *port_end;    char *port2;    char *portset_end;    port_begin = portstr;    portset_end = port_begin + strlen(port_begin);    while (isspace((int)(*port_begin)))        port_begin++;    port_end = strpbrk(port_begin, " \t");    if (port_end == NULL)        port_end = portset_end;    else        *port_end = '\0';    while (port_begin != portset_end)    {        port1 = port_begin;        port2 = strstr(port_begin, "-");

⌨️ 快捷键说明

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