diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2019-08-27 00:49:49 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2019-08-27 00:49:49 +0000 |
commit | 048d6c7bb37386235e1ede7f30e2c0ff9ecce0ce (patch) | |
tree | 5b5893d64f535dfe11fc7c0c086ea9d761f2cf6e /sys/netmpls | |
parent | e3bf06f077d381d1488081a33c2783d2c532a5b5 (diff) |
use m_getptr to get to the right mbuf and offset for the ttl in mpls_gettl.
problem found by and this fix was tested by groos at xiplink dot com
on bugs@
Diffstat (limited to 'sys/netmpls')
-rw-r--r-- | sys/netmpls/mpls_output.c | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/sys/netmpls/mpls_output.c b/sys/netmpls/mpls_output.c index b2be1fcc9fb..62f05b96ad8 100644 --- a/sys/netmpls/mpls_output.c +++ b/sys/netmpls/mpls_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mpls_output.c,v 1.26 2015/12/02 08:47:00 claudio Exp $ */ +/* $OpenBSD: mpls_output.c,v 1.27 2019/08/27 00:49:48 dlg Exp $ */ /* * Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org> @@ -162,41 +162,39 @@ mpls_do_cksum(struct mbuf *m) u_int8_t mpls_getttl(struct mbuf *m, sa_family_t af) { - struct shim_hdr *shim; - struct ip *ip; -#ifdef INET6 - struct ip6_hdr *ip6hdr; -#endif + struct mbuf *n; + int loc, off; u_int8_t ttl = mpls_defttl; /* If the AF is MPLS then inherit the TTL from the present label. */ - if (af == AF_MPLS) { - shim = mtod(m, struct shim_hdr *); - ttl = ntohl(shim->shim_label & MPLS_TTL_MASK); - return (ttl); - } - /* Else extract TTL from the encapsualted packet. */ - switch (*mtod(m, u_char *) >> 4) { - case IPVERSION: - if (!mpls_mapttl_ip) + if (af == AF_MPLS) + loc = 3; + else { + switch (*mtod(m, uint8_t *) >> 4) { + case 4: + if (!mpls_mapttl_ip) + return (ttl); + + loc = offsetof(struct ip, ip_ttl); break; - if (m->m_len < sizeof(*ip)) - break; /* impossible */ - ip = mtod(m, struct ip *); - ttl = ip->ip_ttl; - break; #ifdef INET6 - case IPV6_VERSION >> 4: - if (!mpls_mapttl_ip6) + case 6: + if (!mpls_mapttl_ip6) + break; + + loc = offsetof(struct ip6_hdr, ip6_hlim); break; - if (m->m_len < sizeof(struct ip6_hdr)) - break; /* impossible */ - ip6hdr = mtod(m, struct ip6_hdr *); - ttl = ip6hdr->ip6_hlim; - break; #endif - default: - break; + default: + return (ttl); + } } + + n = m_getptr(m, loc, &off); + if (n == NULL) + return (ttl); + + ttl = *(mtod(n, uint8_t *) + off); + return (ttl); } |