]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
[IPV6]: Find option offset by type.
authorMasahide NAKAMURA <nakam@linux-ipv6.org>
Thu, 24 Aug 2006 02:18:35 +0000 (19:18 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Fri, 22 Sep 2006 22:06:50 +0000 (15:06 -0700)
This is a helper to search option offset from extension header which
can carry TLV option like destination options header.

Mobile IPv6 home address option will use it.

Based on MIPL2 kernel patch.

Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ipv6.h
net/ipv6/exthdrs.c

index ece7e8a84ffd089ef1902581f5c0b690610ec6fa..c4ea1271057601471d513e6b96d25873b4e737b2 100644 (file)
@@ -506,6 +506,8 @@ extern int                  ipv6_skip_exthdr(const struct sk_buff *, int start,
 
 extern int                     ipv6_ext_hdr(u8 nexthdr);
 
+extern int ipv6_find_tlv(struct sk_buff *skb, int offset, int type);
+
 extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk,
                                                  struct ipv6_rt_hdr *hdr);
 
index 8d3a0e17314de11a17b7618b05a7841fcefd487c..50ff49e518bcd846613731c7482c96657bac51bd 100644 (file)
 
 #include <asm/uaccess.h>
 
+int ipv6_find_tlv(struct sk_buff *skb, int offset, int type)
+{
+       int packet_len = skb->tail - skb->nh.raw;
+       struct ipv6_opt_hdr *hdr;
+       int len;
+
+       if (offset + 2 > packet_len)
+               goto bad;
+       hdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
+       len = ((hdr->hdrlen + 1) << 3);
+
+       if (offset + len > packet_len)
+               goto bad;
+
+       offset += 2;
+       len -= 2;
+
+       while (len > 0) {
+               int opttype = skb->nh.raw[offset];
+               int optlen;
+
+               if (opttype == type)
+                       return offset;
+
+               switch (opttype) {
+               case IPV6_TLV_PAD0:
+                       optlen = 1;
+                       break;
+               default:
+                       optlen = skb->nh.raw[offset + 1] + 2;
+                       if (optlen > len)
+                               goto bad;
+                       break;
+               }
+               offset += optlen;
+               len -= optlen;
+       }
+       /* not_found */
+       return -1;
+ bad:
+       return -1;
+}
+
 /*
  *     Parsing tlv encoded headers.
  *