From: dlg Date: Wed, 2 Jun 2021 00:09:57 +0000 (+0000) Subject: factor out the code that does basic sanity checks on ipv4 headers. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=29fa630fe21c0b5043b202572185b4041c1659ad;p=openbsd 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@ --- diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 0a2b1d2c138..432a483f778 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in.h,v 1.140 2021/01/18 12:22:40 sthen Exp $ */ +/* $OpenBSD: in.h,v 1.141 2021/06/02 00:09:57 dlg Exp $ */ /* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */ /* @@ -772,6 +772,8 @@ struct ifaddr; struct in_ifaddr; void ipv4_input(struct ifnet *, struct mbuf *); +struct mbuf * + ipv4_check(struct ifnet *, struct mbuf *); int in_broadcast(struct in_addr, u_int); int in_canforward(struct in_addr); 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)))