diff options
| author | Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> | 2004-10-21 01:27:38 +0200 |
|---|---|---|
| committer | Patrick McHardy <kaber@coreworks.de> | 2004-10-21 01:27:38 +0200 |
| commit | 2afe6f85921307c4eb674364f133afc93169ecdd (patch) | |
| tree | 88df2b17ea1af84758f0f99e686ba39a142b7a16 | |
| parent | a5082f0c9398a70c0c05a6ddf0744ca8029daab6 (diff) | |
[NETFILTER]: Enable ip6t_rt.c to work without skb_linearize()
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>
| -rw-r--r-- | net/ipv6/netfilter/ip6t_rt.c | 121 |
1 files changed, 59 insertions, 62 deletions
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index 56b675ad8f1e..b5adc1057a9b 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c @@ -50,7 +50,7 @@ match(const struct sk_buff *skb, unsigned int protoff, int *hotdrop) { - struct ipv6_rt_hdr *route = NULL; + struct ipv6_rt_hdr _route, *rh = NULL; const struct ip6t_rt *rtinfo = matchinfo; unsigned int temp; unsigned int len; @@ -58,6 +58,7 @@ match(const struct sk_buff *skb, unsigned int ptr; unsigned int hdrlen = 0; unsigned int ret = 0; + struct in6_addr *ap, _addr; /* type of the 1st exthdr */ nexthdr = skb->nh.ipv6h->nexthdr; @@ -68,7 +69,7 @@ match(const struct sk_buff *skb, temp = 0; while (ip6t_ext_hdr(nexthdr)) { - struct ipv6_opt_hdr *hdr; + struct ipv6_opt_hdr _hdr, *hp; DEBUGP("ipv6_rt header iteration \n"); @@ -84,15 +85,16 @@ match(const struct sk_buff *skb, break; } - hdr=(struct ipv6_opt_hdr *)(skb->data+ptr); + hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr); + BUG_ON(hp == NULL); /* Calculate the header length */ if (nexthdr == NEXTHDR_FRAGMENT) { hdrlen = 8; } else if (nexthdr == NEXTHDR_AUTH) - hdrlen = (hdr->hdrlen+2)<<2; + hdrlen = (hp->hdrlen+2)<<2; else - hdrlen = ipv6_optlen(hdr); + hdrlen = ipv6_optlen(hp); /* ROUTING -> evaluate */ if (nexthdr == NEXTHDR_ROUTING) { @@ -115,7 +117,7 @@ match(const struct sk_buff *skb, break; } - nexthdr = hdr->nexthdr; + nexthdr = hp->nexthdr; len -= hdrlen; ptr += hdrlen; if ( ptr > skb->len ) { @@ -137,20 +139,21 @@ match(const struct sk_buff *skb, return 0; } - route = (struct ipv6_rt_hdr *) (skb->data + ptr); + rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); + BUG_ON(rh == NULL); - DEBUGP("IPv6 RT LEN %u %u ", hdrlen, route->hdrlen); - DEBUGP("TYPE %04X ", route->type); - DEBUGP("SGS_LEFT %u %02X\n", route->segments_left, route->segments_left); + DEBUGP("IPv6 RT LEN %u %u ", hdrlen, rh->hdrlen); + DEBUGP("TYPE %04X ", rh->type); + DEBUGP("SGS_LEFT %u %02X\n", rh->segments_left, rh->segments_left); DEBUGP("IPv6 RT segsleft %02X ", (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], - route->segments_left, + rh->segments_left, !!(rtinfo->invflags & IP6T_RT_INV_SGS)))); DEBUGP("type %02X %02X %02X ", - rtinfo->rt_type, route->type, + rtinfo->rt_type, rh->type, (!(rtinfo->flags & IP6T_RT_TYP) || - ((rtinfo->rt_type == route->type) ^ + ((rtinfo->rt_type == rh->type) ^ !!(rtinfo->invflags & IP6T_RT_INV_TYP)))); DEBUGP("len %02X %04X %02X ", rtinfo->hdrlen, hdrlen, @@ -158,13 +161,13 @@ match(const struct sk_buff *skb, ((rtinfo->hdrlen == hdrlen) ^ !!(rtinfo->invflags & IP6T_RT_INV_LEN)))); DEBUGP("res %02X %02X %02X ", - (rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)route)->bitmap, - !((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap))); + (rtinfo->flags & IP6T_RT_RES), ((struct rt0_hdr *)rh)->bitmap, + !((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)rh)->bitmap))); - ret = (route != NULL) + ret = (rh != NULL) && (segsleft_match(rtinfo->segsleft[0], rtinfo->segsleft[1], - route->segments_left, + rh->segments_left, !!(rtinfo->invflags & IP6T_RT_INV_SGS))) && (!(rtinfo->flags & IP6T_RT_LEN) || @@ -172,13 +175,19 @@ match(const struct sk_buff *skb, !!(rtinfo->invflags & IP6T_RT_INV_LEN))) && (!(rtinfo->flags & IP6T_RT_TYP) || - ((rtinfo->rt_type == route->type) ^ - !!(rtinfo->invflags & IP6T_RT_INV_TYP))) - && - !((rtinfo->flags & IP6T_RT_RES) && (((struct rt0_hdr *)route)->bitmap)); + ((rtinfo->rt_type == rh->type) ^ + !!(rtinfo->invflags & IP6T_RT_INV_TYP))); + + if (ret && (rtinfo->flags & IP6T_RT_RES)) { + u_int32_t *bp, _bitmap; + bp = skb_header_pointer(skb, + ptr + offsetof(struct rt0_hdr, bitmap), + sizeof(_bitmap), &_bitmap); + + ret = (*bp == 0); + } DEBUGP("#%d ",rtinfo->addrnr); - temp = len = ptr = 0; if ( !(rtinfo->flags & IP6T_RT_FST) ){ return ret; } else if (rtinfo->flags & IP6T_RT_FST_NSTRICT) { @@ -187,32 +196,27 @@ match(const struct sk_buff *skb, DEBUGP("There isn't enough space\n"); return 0; } else { + unsigned int i = 0; + DEBUGP("#%d ",rtinfo->addrnr); - ptr = 0; for(temp=0; temp<(unsigned int)((hdrlen-8)/16); temp++){ - len = 0; - while ((u8)(((struct rt0_hdr *)route)-> - addr[temp].s6_addr[len]) == - (u8)(rtinfo->addrs[ptr].s6_addr[len])){ - DEBUGP("%02X?%02X ", - (u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]), - (u8)(rtinfo->addrs[ptr].s6_addr[len])); - len++; - if ( len == 16 ) break; - } - if (len==16) { - DEBUGP("ptr=%d temp=%d;\n",ptr,temp); - ptr++; - } else { - DEBUGP("%02X?%02X ", - (u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]), - (u8)(rtinfo->addrs[ptr].s6_addr[len])); - DEBUGP("!ptr=%d temp=%d;\n",ptr,temp); + ap = skb_header_pointer(skb, + ptr + + sizeof(struct rt0_hdr) + + temp * sizeof(_addr), + sizeof(_addr), + &_addr); + + BUG_ON(ap == NULL); + + if (!ipv6_addr_cmp(ap, &rtinfo->addrs[i])) { + DEBUGP("i=%d temp=%d;\n",i,temp); + i++; } - if (ptr==rtinfo->addrnr) break; + if (i==rtinfo->addrnr) break; } - DEBUGP("ptr=%d len=%d #%d\n",ptr,len, rtinfo->addrnr); - if ( (len == 16) && (ptr == rtinfo->addrnr)) + DEBUGP("i=%d #%d\n", i, rtinfo->addrnr); + if (i == rtinfo->addrnr) return ret; else return 0; } @@ -224,26 +228,19 @@ match(const struct sk_buff *skb, } else { DEBUGP("#%d ",rtinfo->addrnr); for(temp=0; temp<rtinfo->addrnr; temp++){ - len = 0; - while ((u8)(((struct rt0_hdr *)route)-> - addr[temp].s6_addr[len]) == - (u8)(rtinfo->addrs[temp].s6_addr[len])){ - DEBUGP("%02X?%02X ", - (u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]), - (u8)(rtinfo->addrs[temp].s6_addr[len])); - len++; - if ( len == 16 ) break; - } - if (len!=16) { - DEBUGP("%02X?%02X ", - (u8)(((struct rt0_hdr *)route)->addr[temp].s6_addr[len]), - (u8)(rtinfo->addrs[temp].s6_addr[len])); - DEBUGP("!len=%d temp=%d;\n",len,temp); + ap = skb_header_pointer(skb, + ptr + + sizeof(struct rt0_hdr) + + temp * sizeof(_addr), + sizeof(_addr), + &_addr); + BUG_ON(ap == NULL); + + if (ipv6_addr_cmp(ap, &rtinfo->addrs[temp])) break; - } } - DEBUGP("temp=%d len=%d #%d\n",temp,len,rtinfo->addrnr); - if ( (len == 16) && (temp == rtinfo->addrnr) && (temp == (unsigned int)((hdrlen-8)/16))) + DEBUGP("temp=%d #%d\n", temp, rtinfo->addrnr); + if ((temp == rtinfo->addrnr) && (temp == (unsigned int)((hdrlen-8)/16))) return ret; else return 0; } |
