aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/netfilter/ip6_tables.c
diff options
context:
space:
mode:
authorYasuyuki Kozakai <yasuyuki.kozakai@toshiba.co.jp>2005-09-19 18:34:40 -0400
committerDavid S. Miller <davem@davemloft.net>2005-09-19 18:34:40 -0400
commite674d0f38de6109b59dbe30fba8b296a03229b8e (patch)
tree459271f7cef6319dfa7ca9ab050269c98e551994 /net/ipv6/netfilter/ip6_tables.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/ip6_tables.c')
-rw-r--r--net/ipv6/netfilter/ip6_tables.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 1cb8adb2787..2da514b16d9 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -1955,6 +1955,57 @@ static void __exit fini(void)
1955#endif 1955#endif
1956} 1956}
1957 1957
1958/*
1959 * find specified header up to transport protocol header.
1960 * If found target header, the offset to the header is set to *offset
1961 * and return 0. otherwise, return -1.
1962 *
1963 * Notes: - non-1st Fragment Header isn't skipped.
1964 * - ESP header isn't skipped.
1965 * - The target header may be trancated.
1966 */
1967int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, u8 target)
1968{
1969 unsigned int start = (u8*)(skb->nh.ipv6h + 1) - skb->data;
1970 u8 nexthdr = skb->nh.ipv6h->nexthdr;
1971 unsigned int len = skb->len - start;
1972
1973 while (nexthdr != target) {
1974 struct ipv6_opt_hdr _hdr, *hp;
1975 unsigned int hdrlen;
1976
1977 if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE)
1978 return -1;
1979 hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr);
1980 if (hp == NULL)
1981 return -1;
1982 if (nexthdr == NEXTHDR_FRAGMENT) {
1983 unsigned short _frag_off, *fp;
1984 fp = skb_header_pointer(skb,
1985 start+offsetof(struct frag_hdr,
1986 frag_off),
1987 sizeof(_frag_off),
1988 &_frag_off);
1989 if (fp == NULL)
1990 return -1;
1991
1992 if (ntohs(*fp) & ~0x7)
1993 return -1;
1994 hdrlen = 8;
1995 } else if (nexthdr == NEXTHDR_AUTH)
1996 hdrlen = (hp->hdrlen + 2) << 2;
1997 else
1998 hdrlen = ipv6_optlen(hp);
1999
2000 nexthdr = hp->nexthdr;
2001 len -= hdrlen;
2002 start += hdrlen;
2003 }
2004
2005 *offset = start;
2006 return 0;
2007}
2008
1958EXPORT_SYMBOL(ip6t_register_table); 2009EXPORT_SYMBOL(ip6t_register_table);
1959EXPORT_SYMBOL(ip6t_unregister_table); 2010EXPORT_SYMBOL(ip6t_unregister_table);
1960EXPORT_SYMBOL(ip6t_do_table); 2011EXPORT_SYMBOL(ip6t_do_table);
@@ -1963,6 +2014,7 @@ EXPORT_SYMBOL(ip6t_unregister_match);
1963EXPORT_SYMBOL(ip6t_register_target); 2014EXPORT_SYMBOL(ip6t_register_target);
1964EXPORT_SYMBOL(ip6t_unregister_target); 2015EXPORT_SYMBOL(ip6t_unregister_target);
1965EXPORT_SYMBOL(ip6t_ext_hdr); 2016EXPORT_SYMBOL(ip6t_ext_hdr);
2017EXPORT_SYMBOL(ipv6_find_hdr);
1966 2018
1967module_init(init); 2019module_init(init);
1968module_exit(fini); 2020module_exit(fini);