diff options
author | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2000-01-03 12:58:14 +0000 |
---|---|---|
committer | Angelos D. Keromytis <angelos@cvs.openbsd.org> | 2000-01-03 12:58:14 +0000 |
commit | a316ef81cc6cf2e7c7b0e1ab1165df6439d8af5b (patch) | |
tree | 0efeb72ff1a25d99b899c35fff51c7b1c6bd3d0d | |
parent | 85182a80f7f26112604b964bc5651077a30fd464 (diff) |
Chase down the IPv6 header chain to find the right place swap the Next
Payload value. Note to self: it would be nice if we had a very of
m_copydata() with memory (so it wouldn't need to start the search from
the begining of the mbuf).
-rw-r--r-- | sys/netinet/ipsec_input.c | 89 |
1 files changed, 67 insertions, 22 deletions
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index d85f19abbcb..8f1b1718795 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.5 2000/01/02 11:12:03 angelos Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.6 2000/01/03 12:58:13 angelos Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), @@ -101,8 +101,10 @@ static int ipsec_common_input(struct mbuf *m, int skip, int protoff, int af, int sproto) { #define IPSEC_ISTAT(y,z) (sproto == IPPROTO_ESP ? (y)++ : (z)++) -#define IPSEC_NAME (sproto == IPPROTO_ESP ? "esp_input()" : "ah_input()") - +#define IPSEC_NAME (sproto == IPPROTO_ESP ? (af == AF_INET ? "esp_input()" :\ + "esp6_input()") :\ + (af == AF_INET ? "ah_input()" :\ + "ah6_input()")) union sockaddr_union sunion; struct tdb *tdbp; u_int32_t spi; @@ -574,22 +576,43 @@ int ah6_input(struct mbuf **mp, int *offp, int proto) { struct mbuf *m = *mp; - u_int8_t nxt; + u_int8_t nxt = 0; int protoff; - /* - * XXX assuming that it is first hdr, i.e. - * offp == sizeof(struct ip6_hdr) - */ - if (*offp != sizeof(struct ip6_hdr)) + if (*offp == sizeof(struct ip6_hdr)) + protoff = offsetof(struct ip6_hdr, ip6_nxt); + else { - m_freem(m); - return IPPROTO_DONE; /* not quite */ + /* Chase the header chain... */ + + protoff = sizeof(struct ip6_hdr); + + do + { + protoff += nxt; + m_copydata(m, protoff + offsetof(struct ip6_ext, ip6e_len), + sizeof(u_int8_t), (caddr_t) &nxt); + nxt = (nxt + 1) * 8; + } while (protoff + nxt < *offp); + + /* Malformed packet check */ + if (protoff + nxt != *offp) + { + DPRINTF(("ah6_input(): bad packet header chain\n")); + ahstat.ahs_hdrops++; + m_freem(m); + *mp = NULL; + return IPPROTO_DONE; + } + + protoff += offsetof(struct ip6_ext, ip6e_nxt); } - protoff = offsetof(struct ip6_hdr, ip6_nxt); if (ipsec_common_input(m, *offp, protoff, AF_INET6, proto) != 0) - return IPPROTO_DONE; + { + *mp = NULL; + return IPPROTO_DONE; + } /* Retrieve new protocol */ m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt); @@ -601,22 +624,44 @@ int esp6_input(struct mbuf **mp, int *offp, int proto) { struct mbuf *m = *mp; - u_int8_t nxt; + u_int8_t nxt = 0; int protoff; - /* - * XXX assuming that it is first hdr, i.e. - * offp == sizeof(struct ip6_hdr) - */ - if (*offp != sizeof(struct ip6_hdr)) + if (*offp == sizeof(struct ip6_hdr)) + protoff = offsetof(struct ip6_hdr, ip6_nxt); + else { - m_freem(m); - return IPPROTO_DONE; /* not quite */ + /* Chase the header chain... */ + + protoff = sizeof(struct ip6_hdr); + + do + { + protoff += nxt; + m_copydata(m, protoff + offsetof(struct ip6_ext, ip6e_len), + sizeof(u_int8_t), (caddr_t) &nxt); + nxt = (nxt + 1) * 8; + } while (protoff + nxt < *offp); + + /* Malformed packet check */ + if (protoff + nxt != *offp) + { + DPRINTF(("esp6_input(): bad packet header chain\n")); + espstat.esps_hdrops++; + m_freem(m); + *mp = NULL; + return IPPROTO_DONE; + } + + protoff += offsetof(struct ip6_ext, ip6e_nxt); } protoff = offsetof(struct ip6_hdr, ip6_nxt); if (ipsec_common_input(m, *offp, protoff, AF_INET6, proto) != 0) - return IPPROTO_DONE; + { + *mp = NULL; + return IPPROTO_DONE; + } /* Retrieve new protocol */ m_copydata(m, protoff, sizeof(u_int8_t), (caddr_t) &nxt); |