summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAngelos D. Keromytis <angelos@cvs.openbsd.org>2000-01-03 12:58:14 +0000
committerAngelos D. Keromytis <angelos@cvs.openbsd.org>2000-01-03 12:58:14 +0000
commita316ef81cc6cf2e7c7b0e1ab1165df6439d8af5b (patch)
tree0efeb72ff1a25d99b899c35fff51c7b1c6bd3d0d
parent85182a80f7f26112604b964bc5651077a30fd464 (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.c89
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);