summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEtan Kissling <etan_kissling@apple.com>2021-02-09 23:51:33 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2021-02-19 01:24:07 +0100
commit51f25df304aeaa6c1b02ef7456a61278ee70c102 (patch)
treed71730dcf87cd3d309068f0ddf5af6cec3914845
parent662c8f44d53492d2e0ebd430dadef12d580ec330 (diff)
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>
-rw-r--r--src/extra/ipv6.c15
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;
}