diff options
author | Etan Kissling <etan_kissling@apple.com> | 2021-02-09 23:51:33 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2021-02-19 01:24:07 +0100 |
commit | 51f25df304aeaa6c1b02ef7456a61278ee70c102 (patch) | |
tree | d71730dcf87cd3d309068f0ddf5af6cec3914845 /src | |
parent | 662c8f44d53492d2e0ebd430dadef12d580ec330 (diff) | |
download | libnetfilter_queue-51f25df304aeaa6c1b02ef7456a61278ee70c102.tar.gz |
src: fix IPv6 header handling
This corrects issues in IPv6 header handling that sometimes resulted
in an endless loop.
Signed-off-by: Etan Kissling <etan_kissling@apple.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/extra/ipv6.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/extra/ipv6.c b/src/extra/ipv6.c index 42c5e25..23f64ba 100644 --- a/src/extra/ipv6.c +++ b/src/extra/ipv6.c @@ -67,10 +67,19 @@ int nfq_ip6_set_transport_header(struct pkt_buff *pktb, struct ip6_hdr *ip6h, uint8_t nexthdr = ip6h->ip6_nxt; uint8_t *cur = (uint8_t *)ip6h + sizeof(struct ip6_hdr); - while (nexthdr != target) { + while (nexthdr == IPPROTO_HOPOPTS || + nexthdr == IPPROTO_ROUTING || + nexthdr == IPPROTO_FRAGMENT || + nexthdr == IPPROTO_AH || + nexthdr == IPPROTO_NONE || + nexthdr == IPPROTO_DSTOPTS) { struct ip6_ext *ip6_ext; uint32_t hdrlen; + /* Extension header was requested, we're done. */ + if (nexthdr == target) + break; + /* No more extensions, we're done. */ if (nexthdr == IPPROTO_NONE) { cur = NULL; @@ -107,11 +116,13 @@ int nfq_ip6_set_transport_header(struct pkt_buff *pktb, struct ip6_hdr *ip6h, } else if (nexthdr == IPPROTO_AH) hdrlen = (ip6_ext->ip6e_len + 2) << 2; else - hdrlen = ip6_ext->ip6e_len; + hdrlen = (ip6_ext->ip6e_len + 1) << 3; nexthdr = ip6_ext->ip6e_nxt; cur += hdrlen; } + if (nexthdr != target) + cur = NULL; pktb->transport_header = cur; return cur ? 1 : 0; } |