factor out the code that does basic sanity checks on ipv4 headers.
authordlg <dlg@openbsd.org>
Wed, 2 Jun 2021 00:09:57 +0000 (00:09 +0000)
committerdlg <dlg@openbsd.org>
Wed, 2 Jun 2021 00:09:57 +0000 (00:09 +0000)
this will allow these checks to be reused by bridge (where they're
currently duplicated), veb, and tpmr.

ok bluhm@ sashan@

sys/netinet/in.h
sys/netinet/ip_input.c

index 0a2b1d2..432a483 100644 (file)
@@ -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);
index 2c09c32..c8f1a7c 100644 (file)
@@ -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)))