diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/exthdrs.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 8d3a0e17314..50ff49e518b 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c @@ -49,6 +49,49 @@ #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. * |