summaryrefslogtreecommitdiff
path: root/net/ipv6/netfilter/ip6t_ah.c
diff options
context:
space:
mode:
authorYasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>2005-09-19 15:34:40 -0700
committerDavid S. Miller <davem@davemloft.net>2005-09-19 15:34:40 -0700
commite674d0f38de6109b59dbe30fba8b296a03229b8e (patch)
tree459271f7cef6319dfa7ca9ab050269c98e551994 /net/ipv6/netfilter/ip6t_ah.c
parent926b50f92a30090da2c1a8675de954c2d9b09732 (diff)
[NETFILTER] ip6tables: remove duplicate code
Some IPv6 matches have very similar loops to find IPv6 extension header and we can unify them. This patch introduces ipv6_find_hdr() to do it. I just checked that it can find the target headers in the packet which has dst,hbh,rt,frag,ah,esp headers. Signed-off-by: Yasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp> Signed-off-by: Harald Welte <laforge@netfilter.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/netfilter/ip6t_ah.c')
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c81
1 files changed, 5 insertions, 76 deletions
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index d5b94f142bb..dde37793d20 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -48,92 +48,21 @@ match(const struct sk_buff *skb,
unsigned int protoff,
int *hotdrop)
{
- struct ip_auth_hdr *ah = NULL, _ah;
+ struct ip_auth_hdr *ah, _ah;
const struct ip6t_ah *ahinfo = matchinfo;
- unsigned int temp;
- int len;
- u8 nexthdr;
unsigned int ptr;
unsigned int hdrlen = 0;
- /*DEBUGP("IPv6 AH entered\n");*/
- /* if (opt->auth == 0) return 0;
- * It does not filled on output */
-
- /* type of the 1st exthdr */
- nexthdr = skb->nh.ipv6h->nexthdr;
- /* pointer to the 1st exthdr */
- ptr = sizeof(struct ipv6hdr);
- /* available length */
- len = skb->len - ptr;
- temp = 0;
-
- while (ip6t_ext_hdr(nexthdr)) {
- struct ipv6_opt_hdr _hdr, *hp;
-
- DEBUGP("ipv6_ah header iteration \n");
-
- /* Is there enough space for the next ext header? */
- if (len < sizeof(struct ipv6_opt_hdr))
- return 0;
- /* No more exthdr -> evaluate */
- if (nexthdr == NEXTHDR_NONE)
- break;
- /* ESP -> evaluate */
- if (nexthdr == NEXTHDR_ESP)
- break;
-
- 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 = (hp->hdrlen+2)<<2;
- else
- hdrlen = ipv6_optlen(hp);
-
- /* AH -> evaluate */
- if (nexthdr == NEXTHDR_AUTH) {
- temp |= MASK_AH;
- break;
- }
-
-
- /* set the flag */
- switch (nexthdr) {
- case NEXTHDR_HOP:
- case NEXTHDR_ROUTING:
- case NEXTHDR_FRAGMENT:
- case NEXTHDR_AUTH:
- case NEXTHDR_DEST:
- break;
- default:
- DEBUGP("ipv6_ah match: unknown nextheader %u\n",nexthdr);
- return 0;
- }
-
- nexthdr = hp->nexthdr;
- len -= hdrlen;
- ptr += hdrlen;
- if (ptr > skb->len) {
- DEBUGP("ipv6_ah: new pointer too large! \n");
- break;
- }
- }
-
- /* AH header not found */
- if (temp != MASK_AH)
+ if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH) < 0)
return 0;
- if (len < sizeof(struct ip_auth_hdr)){
+ ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
+ if (ah == NULL) {
*hotdrop = 1;
return 0;
}
- ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
- BUG_ON(ah == NULL);
+ hdrlen = (ah->hdrlen + 2) << 2;
DEBUGP("IPv6 AH LEN %u %u ", hdrlen, ah->hdrlen);
DEBUGP("RES %04X ", ah->reserved);