From 29fa630fe21c0b5043b202572185b4041c1659ad Mon Sep 17 00:00:00 2001 From: dlg Date: Wed, 2 Jun 2021 00:09:57 +0000 Subject: [PATCH] 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@ --- sys/netinet/in.h | 4 ++- sys/netinet/ip_input.c | 55 +++++++++++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 18 deletions(-) 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))) -- 2.20.1