summaryrefslogtreecommitdiff
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2021-06-02 00:09:58 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2021-06-02 00:09:58 +0000
commitd4d3a827aaebaa95656a1e2acc243fd867fab455 (patch)
tree1f9dcaa528d16f9479461ebdc2babdbade50704d /sys/netinet/ip_input.c
parentf4cfd0dbfdf1e884e1f41a395c27ad3f8cf72e74 (diff)
factor out the code that does basic sanity checks on ipv4 headers.
this will allow these checks to be reused by bridge (where they're currently duplicated), veb, and tpmr. ok bluhm@ sashan@
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r--sys/netinet/ip_input.c55
1 files changed, 38 insertions, 17 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 2c09c327197..c8f1a7c6d3b 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.360 2021/05/15 08:07:20 yasuoka Exp $ */
+/* $OpenBSD: ip_input.c,v 1.361 2021/06/02 00:09:57 dlg Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -244,37 +244,36 @@ ipv4_input(struct ifnet *ifp, struct mbuf *m)
KASSERT(nxt == IPPROTO_DONE);
}
-int
-ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
+struct mbuf *
+ipv4_check(struct ifnet *ifp, struct mbuf *m)
{
- struct mbuf *m = *mp;
- struct rtentry *rt = NULL;
- struct ip *ip;
+ struct ip *ip;
int hlen, len;
- in_addr_t pfrdr = 0;
-
- KASSERT(*offp == 0);
- ipstat_inc(ips_total);
- if (m->m_len < sizeof (struct ip) &&
- (m = *mp = m_pullup(m, sizeof (struct ip))) == NULL) {
- ipstat_inc(ips_toosmall);
- goto bad;
+ if (m->m_len < sizeof(*ip)) {
+ m = m_pullup(m, sizeof(*ip));
+ if (m == NULL) {
+ ipstat_inc(ips_toosmall);
+ return (NULL);
+ }
}
+
ip = mtod(m, struct ip *);
if (ip->ip_v != IPVERSION) {
ipstat_inc(ips_badvers);
goto bad;
}
+
hlen = ip->ip_hl << 2;
- if (hlen < sizeof(struct ip)) { /* minimum header length */
+ if (hlen < sizeof(*ip)) { /* minimum header length */
ipstat_inc(ips_badhlen);
goto bad;
}
if (hlen > m->m_len) {
- if ((m = *mp = m_pullup(m, hlen)) == NULL) {
+ m = m_pullup(m, hlen);
+ if (m == NULL) {
ipstat_inc(ips_badhlen);
- goto bad;
+ return (NULL);
}
ip = mtod(m, struct ip *);
}
@@ -330,6 +329,28 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
m_adj(m, len - m->m_pkthdr.len);
}
+ return (m);
+bad:
+ m_freem(m);
+ return (NULL);
+}
+
+int
+ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp)
+{
+ struct mbuf *m;
+ struct rtentry *rt = NULL;
+ struct ip *ip;
+ int hlen;
+ in_addr_t pfrdr = 0;
+
+ KASSERT(*offp == 0);
+
+ ipstat_inc(ips_total);
+ m = *mp = ipv4_check(ifp, *mp);
+ if (m == NULL)
+ goto bad;
+
#if NCARP > 0
if (carp_lsdrop(ifp, m, AF_INET, &ip->ip_src.s_addr,
&ip->ip_dst.s_addr, (ip->ip_p == IPPROTO_ICMP ? 0 : 1)))