Split checks from frame accepting with header removing in the common
PPP input function. This should fix packet capture on a PPP interfaces.

Also forbid IP/IPv6 frames (without PPP header) passing to BPF on
PPP interfaces to avoid mess.

Initialy this change was made as a part of pipex(4) and ppp(4)
integration work. But, since this change make the core a bit more clear
I would like to publish it now.

Ok?

---
 sys/net/pipex.c | 95 ++++++++++++++++++++++++++++---------------------
 1 file changed, 54 insertions(+), 41 deletions(-)

diff --git sys/net/pipex.c sys/net/pipex.c
index c433e4beaa6..e0066a61598 100644
--- sys/net/pipex.c
+++ sys/net/pipex.c
@@ -970,41 +970,68 @@ drop:
 Static void
 pipex_ppp_input(struct mbuf *m0, struct pipex_session *session, int decrypted)
 {
-       int proto, hlen = 0;
+       int proto, hlen = 0, align = 0;
        struct mbuf *n;
 
        KASSERT(m0->m_pkthdr.len >= PIPEX_PPPMINLEN);
        proto = pipex_ppp_proto(m0, session, 0, &hlen);
+       switch (proto) {
+       case PPP_IP:
+               if (session->ip_forward == 0)
+                       goto drop;
+               if (!decrypted && pipex_session_is_mppe_required(session))
+                       /*
+                        * if ip packet received when mppe
+                        * is required, discard it.
+                        */
+                       goto drop;
+               align = 1;
+               break;
+#ifdef INET6
+       case PPP_IPV6:
+               if (session->ip6_forward == 0)
+                       goto drop;
+               if (!decrypted && pipex_session_is_mppe_required(session))
+                       /*
+                        * if ip packet received when mppe
+                        * is required, discard it.
+                        */
+                       goto drop;
+               align = 1;
+               break;
+#endif
 #ifdef PIPEX_MPPE
-       if (proto == PPP_COMP) {
+       case PPP_COMP:
                if (decrypted)
                        goto drop;
 
                /* checked this on ppp_common_input() already. */
                KASSERT(pipex_session_is_mppe_accepted(session));
-
-               m_adj(m0, hlen);
-               pipex_mppe_input(m0, session);
-               return;
-       }
-       if (proto == PPP_CCP) {
+               break;
+       case PPP_CCP:
                if (decrypted)
                        goto drop;
+               break;
+#endif
+       default:
+               if (decrypted)
+                       goto drop;
+               /* protocol must be checked on pipex_common_input() already */
+               KASSERT(0);
+               goto drop;
+       }
 
 #if NBPFILTER > 0
-           {
+       {
                struct ifnet *ifp = session->pipex_iface->ifnet_this;
+
                if (ifp->if_bpf && ifp->if_type == IFT_PPP)
                        bpf_mtap(ifp->if_bpf, m0, BPF_DIRECTION_IN);
-           }
-#endif
-               m_adj(m0, hlen);
-               pipex_ccp_input(m0, session);
-               return;
        }
 #endif
+
        m_adj(m0, hlen);
-       if (!ALIGNED_POINTER(mtod(m0, caddr_t), uint32_t)) {
+       if (align && !ALIGNED_POINTER(mtod(m0, caddr_t), uint32_t)) {
                n = m_dup_pkt(m0, 0, M_NOWAIT);
                if (n == NULL)
                        goto drop;
@@ -1014,35 +1041,21 @@ pipex_ppp_input(struct mbuf *m0, struct pipex_session 
*session, int decrypted)
 
        switch (proto) {
        case PPP_IP:
-               if (session->ip_forward == 0)
-                       goto drop;
-               if (!decrypted && pipex_session_is_mppe_required(session))
-                       /*
-                        * if ip packet received when mppe
-                        * is required, discard it.
-                        */
-                       goto drop;
                pipex_ip_input(m0, session);
-               return;
+               break;
 #ifdef INET6
        case PPP_IPV6:
-               if (session->ip6_forward == 0)
-                       goto drop;
-               if (!decrypted && pipex_session_is_mppe_required(session))
-                       /*
-                        * if ip packet received when mppe
-                        * is required, discard it.
-                        */
-                       goto drop;
                pipex_ip6_input(m0, session);
-               return;
+               break;
+#endif
+#ifdef PIPEX_MPPE
+       case PPP_COMP:
+               pipex_mppe_input(m0, session);
+               break;
+       case PPP_CCP:
+               pipex_ccp_input(m0, session);
+               break;
 #endif
-       default:
-               if (decrypted)
-                       goto drop;
-               /* protocol must be checked on pipex_common_input() already */
-               KASSERT(0);
-               goto drop;
        }
 
        return;
@@ -1105,7 +1118,7 @@ pipex_ip_input(struct mbuf *m0, struct pipex_session 
*session)
        len = m0->m_pkthdr.len;
 
 #if NBPFILTER > 0
-       if (ifp->if_bpf)
+       if (ifp->if_bpf && ifp->if_type != IFT_PPP)
                bpf_mtap_af(ifp->if_bpf, AF_INET, m0, BPF_DIRECTION_IN);
 #endif
 
@@ -1151,7 +1164,7 @@ pipex_ip6_input(struct mbuf *m0, struct pipex_session 
*session)
        len = m0->m_pkthdr.len;
 
 #if NBPFILTER > 0
-       if (ifp->if_bpf)
+       if (ifp->if_bpf && ifp->if_type != IFT_PPP)
                bpf_mtap_af(ifp->if_bpf, AF_INET6, m0, BPF_DIRECTION_IN);
 #endif
 
-- 
2.26.0

Reply via email to