Just saw that damien@ has not touched the driver for a long time,
so I'm also sending this here.

----- Forwarded message from Lazaros Koromilas <lo...@2f30.org> -----

Date: Thu, 17 May 2012 15:33:59 +0300
From: Lazaros Koromilas <lo...@2f30.org>
To: Damien Bergamini <dam...@openbsd.org>
Subject: Promiscuous mode for the wpi driver
User-Agent: Mutt/1.5.21 (2010-09-15)

Hello,

I noticed that I could not put my "Intel PRO/Wireless 3945ABG"
in promiscuous mode, and took some time to add support for that.
If not mistaken, the WPI_CMD_ASSOCIATE means "change options while
in associated state", but didn't change the name.  Patch follows.
I've only tested it with tcpdump, though.  Also, promiscuous while
in monitor mode does not make sense to me, so didn't put any checks.
Is that OK?

Thanx,
Lazaros.


Index: if_wpi.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_wpi.c,v
retrieving revision 1.110
diff -u -p -r1.110 if_wpi.c
--- if_wpi.c    2 Jun 2011 18:36:53 -0000       1.110
+++ if_wpi.c    17 May 2012 11:57:19 -0000
@@ -120,6 +120,7 @@ int         wpi_ioctl(struct ifnet *, u_long, c
 int            wpi_cmd(struct wpi_softc *, int, const void *, int, int);
 int            wpi_mrr_setup(struct wpi_softc *);
 void           wpi_updateedca(struct ieee80211com *);
+void           wpi_set_promisc(struct wpi_softc *, int);
 void           wpi_set_led(struct wpi_softc *, uint8_t, uint8_t, uint8_t);
 int            wpi_set_timing(struct wpi_softc *, struct ieee80211_node *);
 void           wpi_power_calibration(struct wpi_softc *);
@@ -2002,12 +2003,21 @@ wpi_ioctl(struct ifnet *ifp, u_long cmd,
                /* FALLTHROUGH */
        case SIOCSIFFLAGS:
                if (ifp->if_flags & IFF_UP) {
-                       if (!(ifp->if_flags & IFF_RUNNING))
+                       if (ifp->if_flags & IFF_RUNNING) {
+                               if (ifp->if_flags & IFF_PROMISC &&
+                                   !(sc->wpi_if_flags & IFF_PROMISC)) {
+                                       wpi_set_promisc(sc, 1);
+                               } else if (!(ifp->if_flags & IFF_PROMISC) &&
+                                   sc->wpi_if_flags & IFF_PROMISC) {
+                                       wpi_set_promisc(sc, 0);
+                               }
+                       } else
                                error = wpi_init(ifp);
                } else {
                        if (ifp->if_flags & IFF_RUNNING)
                                wpi_stop(ifp, 1);
                }
+               sc->wpi_if_flags = ifp->if_flags;
                break;
 
        case SIOCADDMULTI:
@@ -2206,6 +2216,26 @@ wpi_updateedca(struct ieee80211com *ic)
 }
 
 void
+wpi_set_promisc(struct wpi_softc *sc, int turnon)
+{
+       struct wpi_assoc cmd;
+
+       if (turnon)
+               sc->rxon.filter |= htole32(WPI_FILTER_PROMISC |
+                   WPI_FILTER_CTL);
+       else
+               sc->rxon.filter &= ~htole32(WPI_FILTER_PROMISC |
+                   WPI_FILTER_CTL);
+
+       memset(&cmd, 0, sizeof cmd);
+       cmd.flags = sc->rxon.flags;
+       cmd.filter = sc->rxon.filter;
+       cmd.ofdm_mask = sc->rxon.ofdm_mask;
+       cmd.cck_mask = sc->rxon.cck_mask;
+       (void)wpi_cmd(sc, WPI_CMD_ASSOCIATE, &cmd, sizeof cmd, 1);
+}
+
+void
 wpi_set_led(struct wpi_softc *sc, uint8_t which, uint8_t off, uint8_t on)
 {
        struct wpi_cmd_led led;
@@ -3327,6 +3357,7 @@ wpi_init(struct ifnet *ifp)
 
        ifp->if_flags &= ~IFF_OACTIVE;
        ifp->if_flags |= IFF_RUNNING;
+       sc->wpi_if_flags = ifp->if_flags;
 
        if (ic->ic_opmode != IEEE80211_M_MONITOR)
                ieee80211_begin_scan(ifp);
Index: if_wpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/if_wpivar.h,v
retrieving revision 1.23
diff -u -p -r1.23 if_wpivar.h
--- if_wpivar.h 7 Sep 2010 16:21:45 -0000       1.23
+++ if_wpivar.h 17 May 2012 11:57:19 -0000
@@ -144,6 +144,8 @@ struct wpi_softc {
 #define WPI_FLAG_HAS_5GHZ      (1 << 0)
 #define WPI_FLAG_BUSY          (1 << 1)
 
+       int                     wpi_if_flags;
+
        /* Shared area. */
        struct wpi_dma_info     shared_dma;
        struct wpi_shared       *shared;

Reply via email to