📄 ipobj.c
字号:
/* 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"/* 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 ){ char stmp[256]; int rc; unsigned char * ip = (unsigned char *) ip4; rc = snprintf(stmp,sizeof(stmp),"%d.%d.%d.%d",ip[3],ip[2],ip[1],ip[0]); if( rc <= 0 ) return -1; if( (rc+1) > slen ) return -1; strcpy(s,stmp); return 0;}int ip6_sprintx( char * s, int slen, void * ip6 ){ char stmp[256]; int rc; unsigned short * ps = (unsigned short*) ip6; rc = snprintf(stmp,sizeof(stmp),"%.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 <= 0 ) return -1; if( (rc+1) > slen ) return -1; strcpy(s,stmp); 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 = malloc( sizeof(IPADDRESS) + IPV4_LEN - 1 ); ip_init( p, family ); } else if( family == IPV6_FAMILY ) { p = malloc( 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 == IPV4_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 *)malloc( 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->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->notflag, family); } } } return newset;}void ipset_free( IPSET * ipc ){ if( ipc ) { 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, 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; CIDRBLOCK *p = (CIDRBLOCK*)malloc( sizeof(CIDRBLOCK) ); if(!p) return -1; p->mask = *mask; p->ip = *ip & *mask; 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; CIDRBLOCK6 *p6 = (CIDRBLOCK6*)malloc( 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->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, int family ){ if( !ipc ) return 0; if( ipc->family != family ) { return 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 ) { 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 ) { if( p->notflag ) return 0; return 1; } } } else return -1; return 0;}int ipset_print( IPSET * ipc ){ char ip_str[80], mask_str[80]; 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\n", ip_str,mask_str); else printf("CIDR BLOCK: %s / %s\n", ip_str,mask_str); } } 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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -