summaryrefslogtreecommitdiff
path: root/sys/netinet/ipsec_input.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2021-10-24 22:59:48 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2021-10-24 22:59:48 +0000
commit7def19723a1f3656910a47ebcfb0e81dc7cc7b9f (patch)
treeafac3eebdda3b4a3b1d2e87a23412e165905f392 /sys/netinet/ipsec_input.c
parentb5dac976511df97d1d274a214e5964751069ee6a (diff)
Remove code duplication by merging the v4 and v6 input functions
for ah, esp, and ipcomp. Move common code into ipsec_protoff() which finds the offset of the next protocol field in the previous header. OK tobhe@
Diffstat (limited to 'sys/netinet/ipsec_input.c')
-rw-r--r--sys/netinet/ipsec_input.c262
1 files changed, 91 insertions, 171 deletions
diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c
index 1d8c3fa1201..9711e5213cb 100644
--- a/sys/netinet/ipsec_input.c
+++ b/sys/netinet/ipsec_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec_input.c,v 1.188 2021/10/24 17:08:27 bluhm Exp $ */
+/* $OpenBSD: ipsec_input.c,v 1.189 2021/10/24 22:59:47 bluhm Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -793,19 +793,42 @@ ipsec_sysctl_ipsecstat(void *oldp, size_t *oldlenp, void *newp)
sizeof(ipsecstat)));
}
-/* IPv4 AH wrapper. */
int
-ah4_input(struct mbuf **mp, int *offp, int proto, int af)
+ipsec_input_disabled(struct mbuf **mp, int *offp, int proto, int af)
{
+ switch (af) {
+ case AF_INET:
+ return rip_input(mp, offp, proto, af);
+#ifdef INET6
+ case AF_INET6:
+ return rip6_input(mp, offp, proto, af);
+#endif
+ default:
+ unhandled_af(af);
+ }
+}
+
+int
+ah46_input(struct mbuf **mp, int *offp, int proto, int af)
+{
+ int protoff;
+
if (
#if NPF > 0
((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
#endif
!ah_enable)
- return rip_input(mp, offp, proto, af);
+ return ipsec_input_disabled(mp, offp, proto, af);
+
+ protoff = ipsec_protoff(*mp, *offp, af);
+ if (protoff < 0) {
+ DPRINTF("bad packet header chain");
+ ahstat_inc(ahs_hdrops);
+ m_freemp(mp);
+ return IPPROTO_DONE;
+ }
- ipsec_common_input(mp, *offp, offsetof(struct ip, ip_p), AF_INET,
- proto, 0);
+ ipsec_common_input(mp, *offp, protoff, af, proto, 0);
return IPPROTO_DONE;
}
@@ -819,35 +842,52 @@ ah4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_AH);
}
-/* IPv4 ESP wrapper. */
int
-esp4_input(struct mbuf **mp, int *offp, int proto, int af)
+esp46_input(struct mbuf **mp, int *offp, int proto, int af)
{
+ int protoff;
+
if (
#if NPF > 0
((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
#endif
!esp_enable)
- return rip_input(mp, offp, proto, af);
+ return ipsec_input_disabled(mp, offp, proto, af);
+
+ protoff = ipsec_protoff(*mp, *offp, af);
+ if (protoff < 0) {
+ DPRINTF("bad packet header chain");
+ espstat_inc(esps_hdrops);
+ m_freemp(mp);
+ return IPPROTO_DONE;
+ }
- ipsec_common_input(mp, *offp, offsetof(struct ip, ip_p), AF_INET,
- proto, 0);
+ ipsec_common_input(mp, *offp, protoff, af, proto, 0);
return IPPROTO_DONE;
}
/* IPv4 IPCOMP wrapper */
int
-ipcomp4_input(struct mbuf **mp, int *offp, int proto, int af)
+ipcomp46_input(struct mbuf **mp, int *offp, int proto, int af)
{
+ int protoff;
+
if (
#if NPF > 0
((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
#endif
!ipcomp_enable)
- return rip_input(mp, offp, proto, af);
+ return ipsec_input_disabled(mp, offp, proto, af);
+
+ protoff = ipsec_protoff(*mp, *offp, af);
+ if (protoff < 0) {
+ DPRINTF("bad packet header chain");
+ ipcompstat_inc(ipcomps_hdrops);
+ m_freemp(mp);
+ return IPPROTO_DONE;
+ }
- ipsec_common_input(mp, *offp, offsetof(struct ip, ip_p), AF_INET,
- proto, 0);
+ ipsec_common_input(mp, *offp, protoff, af, proto, 0);
return IPPROTO_DONE;
}
@@ -969,179 +1009,59 @@ esp4_ctlinput(int cmd, struct sockaddr *sa, u_int rdomain, void *v)
ipsec_common_ctlinput(rdomain, cmd, sa, v, IPPROTO_ESP);
}
-#ifdef INET6
-/* IPv6 AH wrapper. */
+/* Find the offset of the next protocol field in the previous header. */
int
-ah6_input(struct mbuf **mp, int *offp, int proto, int af)
+ipsec_protoff(struct mbuf *m, int off, int af)
{
- int l = 0;
- int protoff, nxt;
struct ip6_ext ip6e;
+ int protoff, nxt, l;
- if (
-#if NPF > 0
- ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
-#endif
- !ah_enable)
- return rip6_input(mp, offp, proto, af);
-
- if (*offp < sizeof(struct ip6_hdr)) {
- DPRINTF("bad offset");
- ahstat_inc(ahs_hdrops);
- m_freemp(mp);
- return IPPROTO_DONE;
- } else if (*offp == sizeof(struct ip6_hdr)) {
- protoff = offsetof(struct ip6_hdr, ip6_nxt);
- } else {
- /* Chase down the header chain... */
- protoff = sizeof(struct ip6_hdr);
- nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
-
- do {
- protoff += l;
- m_copydata(*mp, protoff, sizeof(ip6e),
- (caddr_t) &ip6e);
-
- if (nxt == IPPROTO_AH)
- l = (ip6e.ip6e_len + 2) << 2;
- else
- l = (ip6e.ip6e_len + 1) << 3;
-#ifdef DIAGNOSTIC
- if (l <= 0)
- panic("ah6_input: l went zero or negative");
+ switch (af) {
+ case AF_INET:
+ return offsetof(struct ip, ip_p);
+#ifdef INET6
+ case AF_INET6:
+ break;
#endif
-
- nxt = ip6e.ip6e_nxt;
- } while (protoff + l < *offp);
-
- /* Malformed packet check */
- if (protoff + l != *offp) {
- DPRINTF("bad packet header chain");
- ahstat_inc(ahs_hdrops);
- m_freemp(mp);
- return IPPROTO_DONE;
- }
- protoff += offsetof(struct ip6_ext, ip6e_nxt);
+ default:
+ unhandled_af(af);
}
- ipsec_common_input(mp, *offp, protoff, AF_INET6, proto, 0);
- return IPPROTO_DONE;
-}
-/* IPv6 ESP wrapper. */
-int
-esp6_input(struct mbuf **mp, int *offp, int proto, int af)
-{
- int l = 0;
- int protoff, nxt;
- struct ip6_ext ip6e;
+ if (off < sizeof(struct ip6_hdr))
+ return -1;
- if (
-#if NPF > 0
- ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
-#endif
- !esp_enable)
- return rip6_input(mp, offp, proto, af);
+ if (off == sizeof(struct ip6_hdr))
+ return offsetof(struct ip6_hdr, ip6_nxt);
- if (*offp < sizeof(struct ip6_hdr)) {
- DPRINTF("bad offset");
- espstat_inc(esps_hdrops);
- m_freemp(mp);
- return IPPROTO_DONE;
- } else if (*offp == sizeof(struct ip6_hdr)) {
- protoff = offsetof(struct ip6_hdr, ip6_nxt);
- } else {
- /* Chase down the header chain... */
- protoff = sizeof(struct ip6_hdr);
- nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
-
- do {
- protoff += l;
- m_copydata(*mp, protoff, sizeof(ip6e),
- (caddr_t) &ip6e);
-
- if (nxt == IPPROTO_AH)
- l = (ip6e.ip6e_len + 2) << 2;
- else
- l = (ip6e.ip6e_len + 1) << 3;
-#ifdef DIAGNOSTIC
- if (l <= 0)
- panic("esp6_input: l went zero or negative");
-#endif
+ /* Chase down the header chain... */
+ protoff = sizeof(struct ip6_hdr);
+ nxt = (mtod(m, struct ip6_hdr *))->ip6_nxt;
+ l = 0;
- nxt = ip6e.ip6e_nxt;
- } while (protoff + l < *offp);
+ do {
+ protoff += l;
+ m_copydata(m, protoff, sizeof(ip6e),
+ (caddr_t) &ip6e);
- /* Malformed packet check */
- if (protoff + l != *offp) {
- DPRINTF("bad packet header chain");
- espstat_inc(esps_hdrops);
- m_freemp(mp);
- return IPPROTO_DONE;
- }
- protoff += offsetof(struct ip6_ext, ip6e_nxt);
- }
- ipsec_common_input(mp, *offp, protoff, AF_INET6, proto, 0);
- return IPPROTO_DONE;
-
-}
-
-/* IPv6 IPcomp wrapper */
-int
-ipcomp6_input(struct mbuf **mp, int *offp, int proto, int af)
-{
- int l = 0;
- int protoff, nxt;
- struct ip6_ext ip6e;
-
- if (
-#if NPF > 0
- ((*mp)->m_pkthdr.pf.flags & PF_TAG_DIVERTED) ||
-#endif
- !ipcomp_enable)
- return rip6_input(mp, offp, proto, af);
-
- if (*offp < sizeof(struct ip6_hdr)) {
- DPRINTF("bad offset");
- ipcompstat_inc(ipcomps_hdrops);
- m_freemp(mp);
- return IPPROTO_DONE;
- } else if (*offp == sizeof(struct ip6_hdr)) {
- protoff = offsetof(struct ip6_hdr, ip6_nxt);
- } else {
- /* Chase down the header chain... */
- protoff = sizeof(struct ip6_hdr);
- nxt = (mtod(*mp, struct ip6_hdr *))->ip6_nxt;
-
- do {
- protoff += l;
- m_copydata(*mp, protoff, sizeof(ip6e),
- (caddr_t) &ip6e);
- if (nxt == IPPROTO_AH)
- l = (ip6e.ip6e_len + 2) << 2;
- else
- l = (ip6e.ip6e_len + 1) << 3;
+ if (nxt == IPPROTO_AH)
+ l = (ip6e.ip6e_len + 2) << 2;
+ else
+ l = (ip6e.ip6e_len + 1) << 3;
#ifdef DIAGNOSTIC
- if (l <= 0)
- panic("l went zero or negative");
+ if (l <= 0)
+ panic("ah6_input: l went zero or negative");
#endif
- nxt = ip6e.ip6e_nxt;
- } while (protoff + l < *offp);
+ nxt = ip6e.ip6e_nxt;
+ } while (protoff + l < off);
- /* Malformed packet check */
- if (protoff + l != *offp) {
- DPRINTF("bad packet header chain");
- ipcompstat_inc(ipcomps_hdrops);
- m_freemp(mp);
- return IPPROTO_DONE;
- }
+ /* Malformed packet check */
+ if (protoff + l != off)
+ return -1;
- protoff += offsetof(struct ip6_ext, ip6e_nxt);
- }
- ipsec_common_input(mp, *offp, protoff, AF_INET6, proto, 0);
- return IPPROTO_DONE;
+ protoff += offsetof(struct ip6_ext, ip6e_nxt);
+ return protoff;
}
-#endif /* INET6 */
int
ipsec_forward_check(struct mbuf *m, int hlen, int af)