kernels/linux-2.4.0/net/ipv6/netfilter/ip6_tables.c
/* Returns whether matches rule or not. */
Returns whether matches rule or not.
Returns whether matches rule or not .
static inline int
ip6_packet_match(const struct ipv6hdr *ipv6,
		 const char *indev,
		 const char *outdev,
		 const struct ip6t_ip6 *ip6info,
		 int isfrag)
{
	size_t i;
	unsigned long ret;
#define FWINV(bool,invflg) ((bool) ^ !!(ip6info->invflags & invflg))
	if (FWINV(ip6_masked_addrcmp(ipv6->saddr,ip6info->smsk,ip6info->src),
		  IP6T_INV_SRCIP)
	    || FWINV(ip6_masked_addrcmp(ipv6->daddr,ip6info->dmsk,ip6info->dst),
		     IP6T_INV_DSTIP)) {
		dprintf("Source or dest mismatch.\n");
		return 0;
	}
	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
		ret |= (((const unsigned long *)indev)[i]
			^ ((const unsigned long *)ip6info->iniface)[i])
			& ((const unsigned long *)ip6info->iniface_mask)[i];
	}
	if (FWINV(ret != 0, IP6T_INV_VIA_IN)) {
		dprintf("VIA in mismatch (%s vs %s).%s\n",
			indev, ip6info->iniface,
			ip6info->invflags&IP6T_INV_VIA_IN ?" (INV)":"");
		return 0;
	}
	for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
		ret |= (((const unsigned long *)outdev)[i]
			^ ((const unsigned long *)ip6info->outiface)[i])
			& ((const unsigned long *)ip6info->outiface_mask)[i];
	}
	if (FWINV(ret != 0, IP6T_INV_VIA_OUT)) {
		dprintf("VIA out mismatch (%s vs %s).%s\n",
			outdev, ip6info->outiface,
			ip6info->invflags&IP6T_INV_VIA_OUT ?" (INV)":"");
		return 0;
	}
	if((ip6info->flags & IP6T_F_PROTO)) {
		u_int8_t currenthdr = ipv6->nexthdr;
		u_int8_t *hdrptr;
		hdrptr = (u_int8_t *)(ipv6 + 1);
		do {
			if (ip6info->proto == currenthdr) {
				if(ip6info->invflags & IP6T_INV_PROTO)
					return 0;
				return 1;
			}
			currenthdr = ip6_nexthdr(currenthdr, hdrptr);
		} while(currenthdr);
		if (!(ip6info->invflags & IP6T_INV_PROTO))
			return 0;
	}
	return 1;
}
static inline int ip6_packet_match ( const struct ipv6hdr * ipv6 , const char * indev , const char * outdev , const struct ip6t_ip6 * ip6info , int isfrag ) { size_t i ; unsigned long ret ; #define FWINV ( bool , invflg )  ((bool) ^ !!(ip6info->invflags & invflg)) if ( FWINV ( ip6_masked_addrcmp ( ipv6 -> saddr , ip6info -> smsk , ip6info -> src ) , IP6T_INV_SRCIP ) || FWINV ( ip6_masked_addrcmp ( ipv6 -> daddr , ip6info -> dmsk , ip6info -> dst ) , IP6T_INV_DSTIP ) ) { dprintf ( " \n " ) ; return 0 ; } for ( i = 0 , ret = 0 ; i < IFNAMSIZ / sizeof ( unsigned long ) ; i ++ ) { ret |= ( ( ( const unsigned long * ) indev ) [ i ] ^ ( ( const unsigned long * ) ip6info -> iniface ) [ i ] ) & ( ( const unsigned long * ) ip6info -> iniface_mask ) [ i ] ; } if ( FWINV ( ret != 0 , IP6T_INV_VIA_IN ) ) { dprintf ( " \n " , indev , ip6info -> iniface , ip6info -> invflags & IP6T_INV_VIA_IN ? " " : " " ) ; return 0 ; } for ( i = 0 , ret = 0 ; i < IFNAMSIZ / sizeof ( unsigned long ) ; i ++ ) { ret |= ( ( ( const unsigned long * ) outdev ) [ i ] ^ ( ( const unsigned long * ) ip6info -> outiface ) [ i ] ) & ( ( const unsigned long * ) ip6info -> outiface_mask ) [ i ] ; } if ( FWINV ( ret != 0 , IP6T_INV_VIA_OUT ) ) { dprintf ( " \n " , outdev , ip6info -> outiface , ip6info -> invflags & IP6T_INV_VIA_OUT ? " " : " " ) ; return 0 ; } if ( ( ip6info -> flags & IP6T_F_PROTO ) ) { u_int8_t currenthdr = ipv6 -> nexthdr ; u_int8_t * hdrptr ; hdrptr = ( u_int8_t * ) ( ipv6 + 1 ) ; do { if ( ip6info -> proto == currenthdr ) { if ( ip6info -> invflags & IP6T_INV_PROTO ) return 0 ; return 1 ; } currenthdr = ip6_nexthdr ( currenthdr , hdrptr ) ; } while ( currenthdr ) ; if ( ! ( ip6info -> invflags & IP6T_INV_PROTO ) ) return 0 ; } return 1 ; }
Returns whether matches rule or not.
Returns whether matches rule or not .
/*
		dprintf("SRC: %u. Mask: %u. Target: %u.%s\n", ip->saddr,
			ipinfo->smsk.s_addr, ipinfo->src.s_addr,
			ipinfo->invflags & IP6T_INV_SRCIP ? " (INV)" : "");
		dprintf("DST: %u. Mask: %u. Target: %u.%s\n", ip->daddr,
			ipinfo->dmsk.s_addr, ipinfo->dst.s_addr,
			ipinfo->invflags & IP6T_INV_DSTIP ? " (INV)" : "");*/ /* Look for ifname matches; this should unroll nicely. */ /* ... might want to do something with class and flowlabel here ... */ /* look for the desired protocol header */