Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Jul 1998 04:43:18 -0700 (PDT)
From:      max@cca.usart.ru
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   kern/7144: WaveLAN interface moves packets to uper layer while dst addr does not belong to that interface (even while not in allmulti/promisc mode)
Message-ID:  <199807021143.EAA05311@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         7144
>Category:       kern
>Synopsis:       WaveLAN interface moves packets to uper layer while dst addr does not belong to that interface (even while not in allmulti/promisc mode)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul  2 04:50:01 PDT 1998
>Last-Modified:
>Originator:     Max Gotlib
>Organization:
Urals State Academy Of Railway Transport
>Release:        2.2.5-RELEASE ... 3.0-Current
>Environment:
FreeBSD wavegw1.usart.ru 2.2.6-RELEASE FreeBSD 2.2.6-RELEASE #4: Thu Jul  2 16:43:14 ESS 1998     root@relay.usart.ru:/usr/src/sys/compile/WGW  i386

>Description:
This problem can be detected in case several WaveLAN boards equipped
(I detect the problem with ISA full-length WaveLAN-AT/2.4 board)
machines with unidirectional ant.kits are looking at omnidirctional
antenna (WavePoint for example). In that case the WaveLAN boards
will be bombed with retranslated packets (destination eth. address
will be _nither_for_this_board_nor_multicast_nor_broadcast_. But
dui to i82586 architecture, WaveLAN boards are not capable to dial
with ALLMILTY mode (which is emulated via promisc mode by the WaveLAN
driver). And, because of the driver's code, this packets could
be raised to upper layer and confuse the whole protocol-stack.
But, dui to the driver's code, this will not happend if there is
at least one BPF listener on that interface (the propper software
filters will kick that packets off after they are checked by the BPF).

>How-To-Repeat:
In the following network topology:

A -(     ()      )-B---D
          |
          C
(X-( means station X with unidirectional ant., and () meand omnidirectional)
try to "traceroute" station A from station D, while keeping ipfw
aimed to drop all packets with src address of B-D subnet, that are
captured fron wavelan interface (on B station). In that case
B will catch packets, retraslated by C for A, ipfw will drop them, and
the ICMP message will be sent to D (and at least in case, D is
powered with Linux OS, it will ignore "the real traceroute
packets" that will also be delivered to it).
>Fix:
Here is a patch against 2.2.6-RELEASE /sys/i386/isa/if_wl.c:
/***************CUT*******************/
--- if_wl.c-orig        Tue Aug 26 04:34:25 1997
+++ if_wl.c             Thu Jul  2 17:39:09 1998
@@ -1080,7 +1080,6 @@

     m->m_pkthdr.len = clen;

-#ifdef NOTYET
     /* due to fact that controller does not support
      * all multicast mode, we must filter out unicast packets
      * that are not for us.
@@ -1091,13 +1090,23 @@
      *
      * TBD: also discard packets where NWID does not match.
      */
-    if ( (sc->mode & MOD_ENAL) && ((sc->mode & MOD_PROM) != 0) &&
+    if (((sc->mode & MOD_PROM) == 0) &&
         ((eh.ether_dhost[0] & 1) == 0) /* !mcast and !bcast */ &&
         (bcmp(eh.ether_dhost, sc->wl_ac.ac_enaddr,
         sizeof(eh.ether_dhost)) != 0) ) {
         m_freem(m);
         return 1;
     }
+#ifdef MULTICAST
+    /* extra check for multicasts */
+    if (((sc->mode & MOD_PROM) == 0)   && /* !promisc mode */
+        (eh.ether_dhost[0] & 1)        && /* multicast or broadcast */
+         bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh.ether_dhost,
+               sizeof(etherbroadcastaddr)) &&
+         !ether_matchmulti(&sc->wl_ac, eh.ether_dhost)) {
+        m_freem(m);
+        return 1;
+    }
 #endif
 #if NBPFILTER > 0
     /*
@@ -1132,6 +1141,16 @@
            m_freem(m);
            return 1;
        }+#ifdef MULTICAST
+        /* extra check for multicasts */
+        if ((eh.ether_dhost[0] & 1) &&
+            bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh.ether_dhost,
+                 sizeof(etherbroadcastaddr)) &&
+            !ether_matchmulti(&sc->wl_ac, eh.ether_dhost)) {
+            m_freem(m);
+            return 1;
+        }
+#endif
     }
 #endif
/***************CUT***************/
The idea is to enable commented out filter, but to rise it against
in case of non multicast, non broadcast packets with not our's
dst ethernet address while interface is not in promisc mode
(in the last case it will be dropped after the BPF listenet, if one,
will be notified). Several multicast checks were added (following
INRIA's implementation).

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199807021143.EAA05311>