diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2021-06-02 00:09:58 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2021-06-02 00:09:58 +0000 |
commit | d4d3a827aaebaa95656a1e2acc243fd867fab455 (patch) | |
tree | 1f9dcaa528d16f9479461ebdc2babdbade50704d /sys/netinet/ip_input.c | |
parent | f4cfd0dbfdf1e884e1f41a395c27ad3f8cf72e74 (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.c | 55 |
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))) |