Could anyone elaborate on the status of this patch? I've had 344 days of uptime 
on a PPC
powerbook using it on 2.4.22 and about 3 months of solid use on 2.6.

If the code looks problematic could someone point out possible deficiencies so 
we can work
toward a satisfactory resolution? I didn't write the code but I'm willing do 
what I have to
in order to get this (wireless scanning) into the official tree.



diff -ur linux-2.6.9/drivers/net/wireless/hermes.c
linux-2.6.9-orinoco/drivers/net/wireless/hermes.c
--- linux-2.6.9/drivers/net/wireless/hermes.c   2004-10-20 15:26:41.000000000 
-0400
+++ linux-2.6.9-orinoco/drivers/net/wireless/hermes.c   2004-10-20 
14:55:01.000000000 -0400
@@ -182,6 +182,10 @@
        if (err)
                return err;

+        for ( k = 0; k < HERMES_NUMPORTS_MAX; k++) {
+               hw->port_enabled[k] = 0;
+       }
+
        reg = hermes_read_regn(hw, EVSTAT);
        k = CMD_INIT_TIMEOUT;
        while ( (! (reg & HERMES_EV_CMD)) && k) {
diff -ur linux-2.6.9/drivers/net/wireless/hermes.h
linux-2.6.9-orinoco/drivers/net/wireless/hermes.h
--- linux-2.6.9/drivers/net/wireless/hermes.h   2004-10-20 15:26:41.000000000 
-0400
+++ linux-2.6.9-orinoco/drivers/net/wireless/hermes.h   2004-10-20 
15:24:55.000000000 -0400
@@ -34,6 +34,10 @@
 #include <linux/if_ether.h>
 #include <asm/byteorder.h>

+#define                HFA384x_PORTTYPE_IBSS                   ((uint16_t)3)
+#define                HFA384x_WEPFLAGS_DISABLE_TXCRYPT        (0x10)
+#define                HFA384x_WEPFLAGS_DISABLE_RXCRYPT        (0x80)
+
 /*
  * Limits and constants
  */
@@ -150,6 +154,11 @@
 /*--- Debugging Commands -----------------------------*/
 #define        HERMES_CMD_TEST                 (0x0038)

+/*--- Debugging Commands -----------------------------*/
+/* We want these in this byte arrangement.  Why is it even being changed? */
+#define        HERMES_CMD_MONITOR              (0x0038)
+#define                HERMES_MONITOR_ENABLE           (0x000b)
+#define                HERMES_MONITOR_DISABLE          (0x000f)

 /* Test command arguments */
 #define                HERMES_TEST_SET_CHANNEL         0x0800
@@ -173,6 +182,38 @@
 #define                HERMES_HOSTSCAN_SYMBOL_BCAST    0x0080

 /*
+ * Configuration RIDs
+ */
+
+#define                HERMES_RID_CNF_PORTTYPE         (0xfc00)
+#define                HERMES_RID_CNF_CHANNEL          (0xfc03)
+#define                HERMES_RID_CNF_PRISM2_WEP_ON    (0xfc28)
+
+/*-- Status Fields --*/
+#define                HERMES_RXSTATUS_MSGTYPE         (0xE000)
+#define                HERMES_RXSTATUS_MACPORT         (0x0700)
+#define                HERMES_RXSTATUS_UNDECR          (0x0002)
+#define                HERMES_RXSTATUS_FCSERR          (0x0001)
+
+/*--------------------------------------------------------------------
+Communication Frames: Test/Get/Set Field Values for Receive Frames
+--------------------------------------------------------------------*/
+#define                HERMES_RXSTATUS_MSGTYPE_GET(value)      (((value) & 
HERMES_RXSTATUS_MSGTYPE) >> 13)
+#define                HERMES_RXSTATUS_MSGTYPE_SET(value)      ((value) << 13)
+#define                HERMES_RXSTATUS_MACPORT_GET(value)      (((value) & 
HERMES_RXSTATUS_MACPORT) >> 8)
+#define                HERMES_RXSTATUS_MACPORT_SET(value)      ((value) << 8)
+#define                HERMES_RXSTATUS_ISUNDECR(value) ((value) & 
HERMES_RXSTATUS_UNDECR)
+#define                HERMES_RXSTATUS_ISFCSERR(value) ((value) & 
HERMES_RXSTATUS_FCSERR)
+
+/*--------------------------------------------------------------------
+Communication Frames: Field Masks for Receive Frames
+--------------------------------------------------------------------*/
+/*-- Offsets --------*/
+#define                HERMES_RX_DATA_LEN_OFF          (44)
+#define                HERMES_RX_80211HDR_OFF          (14)
+#define                HERMES_RX_DATA_OFF                      (60)
+
+/*
  * Frame structures and constants
  */

@@ -181,6 +222,16 @@
 #define HERMES_802_3_OFFSET            (14+32)
 #define HERMES_802_2_OFFSET            (14+32+14)

+struct hermes_rx_descriptor {
+       u16 status;
+       u32 time;
+       u8 silence;
+       u8 signal;
+       u8 rate;
+       u8 rxflow;
+       u32 reserved;
+} __attribute__ ((packed));
+
 #define HERMES_RXSTAT_ERR              (0x0003)
 #define        HERMES_RXSTAT_BADCRC            (0x0001)
 #define        HERMES_RXSTAT_UNDECRYPTABLE     (0x0002)
@@ -353,6 +404,7 @@
 #define HERMES_32BIT_REGSPACING        1

        u16 inten; /* Which interrupts should be enabled? */
+       uint8_t         port_enabled[HERMES_NUMPORTS_MAX];

 #ifdef HERMES_DEBUG_BUFFER
        struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
@@ -406,12 +458,14 @@

 static inline int hermes_enable_port(hermes_t *hw, int port)
 {
+        hw->port_enabled[port] = 1;
        return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
                                 0, NULL);
 }

 static inline int hermes_disable_port(hermes_t *hw, int port)
 {
+        hw->port_enabled[port] = 0;
        return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
                                 0, NULL);
 }
diff -ur linux-2.6.9/drivers/net/wireless/orinoco.c
linux-2.6.9-orinoco/drivers/net/wireless/orinoco.c
--- linux-2.6.9/drivers/net/wireless/orinoco.c  2004-10-20 15:26:41.000000000 
-0400
+++ linux-2.6.9-orinoco/drivers/net/wireless/orinoco.c  2004-10-20 
15:23:04.000000000 -0400
@@ -466,6 +466,7 @@
 #endif

 static int suppress_linkstatus; /* = 0 */
+static int suppress_linkstatus_copy; /* = 0 */
 MODULE_PARM(suppress_linkstatus, "i");

 /********************************************************************/
@@ -562,16 +563,6 @@

 #define ENCAPS_OVERHEAD                (sizeof(encaps_hdr) + 2)

-struct hermes_rx_descriptor {
-       u16 status;
-       u32 time;
-       u8 silence;
-       u8 signal;
-       u8 rate;
-       u8 rxflow;
-       u32 reserved;
-} __attribute__ ((packed));
-
 /********************************************************************/
 /* Function prototypes                                              */
 /********************************************************************/
@@ -786,10 +777,13 @@
                return 1;
        }

-       if (! priv->connected) {
+    if (! priv->connected || dev->type == ARPHRD_IEEE80211_PRISM ||
+        dev->type == ARPHRD_IEEE80211) {
                /* Oops, the firmware hasn't established a connection,
                    silently drop the packet (this seems to be the
                    safest approach). */
+        /* Also silently drop the packet if we're in rfmon, because it won't do
+         * very good things to try to write to the BAP. - Dragorn */
                stats->tx_errors++;
                orinoco_unlock(priv, &flags);
                dev_kfree_skb(skb);
@@ -942,6 +936,24 @@
        hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
 }

+//#define SET_MAC_ADDRESS
+#ifdef SET_MAC_ADDRESS
+static int
+orinoco_set_mac_address(struct net_device *dev, void *addr)
+{
+  struct orinoco_private *priv = dev->priv;
+  struct sockaddr *mac = addr;
+
+  /* Copy the address */
+  memcpy(dev->dev_addr, mac->sa_data, WLAN_ADDR_LEN);
+
+  /* Reconfig the beast */
+  orinoco_reset(priv);
+
+  return 0;
+}
+#endif /* SET_MAC_ADDRESS */
+
 static void orinoco_tx_timeout(struct net_device *dev)
 {
        struct orinoco_private *priv = netdev_priv(dev);
@@ -1027,6 +1039,7 @@
        struct header_struct hdr;
        struct ethhdr *eh;
        int err;
+       struct ieee802_11_hdr hdr80211;

        rxfid = hermes_read_regn(hw, RXFID);

@@ -1043,6 +1056,7 @@

        if (status & HERMES_RXSTAT_ERR) {
                if (status & HERMES_RXSTAT_UNDECRYPTABLE) {
+                       if (dev->type != ARPHRD_ETHER) goto sniffing;
                        wstats->discard.code++;
                        DEBUG(1, "%s: Undecryptable frame on Rx. Frame 
dropped.\n",
                               dev->name);
@@ -1054,6 +1068,7 @@
                goto drop;
        }

+sniffing:
        /* For now we ignore the 802.11 header completely, assuming
            that the card's firmware has handled anything vital */

@@ -1084,6 +1099,11 @@
                goto drop;
        }

+       /* Now handle frame based on port# */
+       switch( HERMES_RXSTATUS_MACPORT_GET(status) )
+       {
+               case 0:
+
        /* We need space for the packet data itself, plus an ethernet
           header, plus 2 bytes so we can align the IP header on a
           32bit boundary, plus 1 byte so we can read in odd length
@@ -1158,6 +1178,26 @@

        return;

+       case 7:
+               if ( ! HERMES_RXSTATUS_ISFCSERR(status) ) {
+                    if (hermes_bap_pread(hw, IRQ_BAP, &hdr80211, 
sizeof(hdr80211),
+                                        rxfid, HERMES_RX_80211HDR_OFF)) {
+                       stats->rx_errors++;
+                    }
+                    else {
+                         /* Copy to wlansnif skb */
+                         orinoco_int_rxmonitor( priv, rxfid, length, &desc, 
&hdr80211);
+                    }
+                 } else {
+                         printk("Received monitor frame: FCSerr set\n");
+                 }
+                 break;
+       default:
+               printk("Received frame on unsupported port=%d\n",
+                       HERMES_RXSTATUS_MACPORT_GET(status) );
+               break;
+       }
+
  drop:
        stats->rx_dropped++;

@@ -1543,6 +1583,8 @@
        hermes_t *hw = &priv->hw;
        int err;
        struct hermes_idstring idbuf;
+    int word;
+    struct hermes_response resp;

        /* Set the MAC address */
        err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
@@ -1737,6 +1779,27 @@
        priv->mc_count = 0;
        __orinoco_set_multicast_list(dev); /* FIXME: what about the xmit_lock */

+    /*
+     * Set the rfmon mode of the card, if we're in rfmon.  Otherwise, the 
firmware
+     * starts sending out a flood of probe requests.  We already reinited the 
firmware
+     * before.
+     *    - Dragorn
+     */
+    if (dev->type == ARPHRD_IEEE80211_PRISM || dev->type == ARPHRD_IEEE80211) {
+        word = HFA384x_PORTTYPE_IBSS;
+        err = hermes_write_wordrec(hw, USER_BAP,
+                                      HERMES_RID_CNF_PORTTYPE, word);
+        if (err)
+            return err;
+
+        /* Enable monitor mode */
+        word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8);
+        err = hermes_docmd_wait(hw, word, 0, &resp);
+        if (err)
+            return err;
+    }
+
+
        return 0;
 }

@@ -1823,6 +1886,17 @@
        if (err)
                return err;

+    /*
+     * If we are in rmfmon mode we need to treat this like going into rfmon 
again,
+     * so re-init the firmware like the rfmon function does.
+     * We'll also need to do some other rfmonish behavior in config_rids
+     *     - Dragorn
+     */
+    if (dev->type == ARPHRD_IEEE80211_PRISM || dev->type == ARPHRD_IEEE80211) {
+        hermes_set_irqmask(hw, 0);
+        hermes_init(hw);
+        hermes_set_irqmask(hw, ORINOCO_INTEN);
+    }

        err = hermes_disable_port(hw, 0);
        if (err) {
@@ -2375,6 +2449,9 @@
        dev->tx_timeout = orinoco_tx_timeout;
        dev->watchdog_timeo = HZ; /* 1 second timeout */
        dev->get_stats = orinoco_get_stats;
+#ifdef SET_MAC_ADDRESS
+       dev->set_mac_address = orinoco_set_mac_address;
+#endif /* SET_MAC_ADDRESS */
        dev->get_wireless_stats = orinoco_get_wireless_stats;
        dev->do_ioctl = orinoco_ioctl;
        dev->change_mtu = orinoco_change_mtu;
@@ -3585,6 +3662,170 @@
        return 0;
 }

+/*----------------------------------------------------------------
+* orinoco_wlansniff
+*
+* Start or stop sniffing.
+*
+* Arguments:
+*      wlandev         wlan device structure
+*      msgp            ptr to msg buffer
+*
+* Returns:
+*      0       success and done
+*      <0   success, but we're waiting for something to finish.
+*      >0   an error occurred while handling the message.
+* Side effects:
+*
+* Call context:
+*      process thread  (usually)
+*      interrupt
+----------------------------------------------------------------*/
+static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq)
+{
+       struct orinoco_private *priv = dev->priv;
+       hermes_t *hw = &(priv->hw);
+       struct hermes_response  resp;
+       int result = 0;
+       uint16_t word;
+
+       int *parms = (int *) wrq->u.name;
+       int enable = parms[0] > 0;
+       unsigned long flags;
+       int noMonitor = dev->type != ARPHRD_IEEE80211_PRISM &&
+                       dev->type != ARPHRD_IEEE80211;
+
+       orinoco_lock(priv, &flags);
+
+       switch (enable)
+       {
+       case P80211ENUM_truth_false:
+               /* Confirm that we're in monitor mode */
+               if ( noMonitor ) {
+                       result = -EFAULT;
+               }
+               /* Disable monitor mode */
+               suppress_linkstatus = suppress_linkstatus_copy;
+               word =  HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8);
+               result = hermes_docmd_wait(hw, word, 0, &resp);
+
+               if ( result ) break;
+
+               /* Disable port 0 */
+               result = hermes_disable_port(hw, 0);
+               if ( result ) break;
+
+               /* Clear the driver state */
+               dev->type = ARPHRD_ETHER;
+
+               /* Restore the wepflags */   //Orinoco doesn't like this
+/*
+               result = hermes_write_wordrec(hw, USER_BAP,
+                               HERMES_RID_CNF_PRISM2_WEP_ON,
+                               priv->presniff_wepflags);
+               if ( result ) break;
+
+*/
+               /* Set the port to its prior type and enable (if necessary) */
+               if (priv->presniff_port_type != 0 ) {
+                       word = priv->presniff_port_type;
+                       result = hermes_write_wordrec(hw, USER_BAP,
+                               HERMES_RID_CNF_PORTTYPE, word);
+                   if ( result ) break;
+
+                       /* Enable the port */
+                       result = hermes_enable_port(hw, 0);
+                   if ( result ) break;
+
+               }
+
+               break;
+       case P80211ENUM_truth_true:
+               // Only do this if we're not in monitor mode already
+               if (noMonitor) {
+                   /* Re-initialize the card before changing channel as 
advised at
+                    * 
http://lists.samba.org/pipermail/wireless/2002-June/004491.html
+                    * by Ian Goldberg.  Implementation by Pat Swieskowski.
+                    */
+                   //          __orinoco_down(dev);
+                   hermes_set_irqmask(hw, 0);
+                   hermes_init(hw);
+                   //          _orinoco_up(dev);
+                   hermes_set_irqmask(hw, ORINOCO_INTEN);
+                   suppress_linkstatus = 1;
+                   /*
+                      __orinoco_stop_irqs(priv);
+                      hermes_reset(hw);
+                      __orinoco_start_irqs(priv, HERMES_EV_RX | 
HERMES_EV_ALLOC |
+                      HERMES_EV_TX | HERMES_EV_TXEXC |
+                      HERMES_EV_WTERR | HERMES_EV_INFO |
+                      HERMES_EV_INFDROP);
+                      */
+                   /* Disable the port (if enabled), only check Port 0 */
+                   if ( hw->port_enabled[0] ) {
+                       /* Save macport 0 state */
+                       result = hermes_read_wordrec(hw, USER_BAP,
+                                                    HERMES_RID_CNF_PORTTYPE,
+                                                    
&(priv->presniff_port_type));
+                       if ( result ) break;
+
+                       /* Save the wepflags state */
+                       result = hermes_read_wordrec(hw, USER_BAP,
+                                                    
HERMES_RID_CNF_PRISM2_WEP_ON,
+                                                    
&(priv->presniff_wepflags));
+                       if ( result ) break;
+                   }
+                   else {
+                       priv->presniff_port_type = 0;
+                   }
+               }
+
+               // Disable the port
+               result = hermes_disable_port(hw, 0);
+               if ( result ) break;
+
+               /* Set the channel we wish to sniff  */
+               if (parms[1] > 0 && parms[1] < 15) {
+                   word = parms[1];
+                   result = hermes_write_wordrec(hw, USER_BAP,
+                                                 HERMES_RID_CNF_CHANNEL, word);
+               } else {
+                   result = -EFAULT;
+               }
+
+               if ( result ) break;
+
+               if (noMonitor) {
+                   /* Set the port type to pIbss */
+                   word = HFA384x_PORTTYPE_IBSS;
+                   result = hermes_write_wordrec(hw, USER_BAP,
+                                                 HERMES_RID_CNF_PORTTYPE, 
word);
+                   if ( result ) break;
+
+                   /* Enable monitor mode */
+                   word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8);
+                   result = hermes_docmd_wait(hw, word, 0, &resp);
+                   if ( result ) break;
+               }
+
+               /* Enable the port */
+               result = hermes_enable_port(hw, 0);
+               if ( result ) break;
+               /* Set the driver state */
+               /* Do we want the prism2 header? */
+               if (parms[0] == 1)
+                 dev->type = ARPHRD_IEEE80211_PRISM;
+               else
+                 dev->type = ARPHRD_IEEE80211;
+               break;
+       default:
+               result = -EFAULT;
+               break;
+       }
+       orinoco_unlock(priv, &flags);
+       return result;
+}
+
 static int
 orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
@@ -3815,6 +4056,9 @@
                                { SIOCIWFIRSTPRIV + 0x7, 0,
                                  IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
                                  "get_ibssport" },
+                               { SIOCIWFIRSTPRIV + 0x8,
+                                 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2,
+                                 0, "monitor" },
                                { SIOCIWLASTPRIV, 0, 0, "dump_recs" },
                        };

@@ -3905,6 +4149,16 @@
                err = orinoco_ioctl_getibssport(dev, wrq);
                break;

+       case SIOCIWFIRSTPRIV + 0x8: /* set sniff (monitor) mode */
+               DEBUG(1, "%s: SIOCIWFIRSTPRIV + 0x8 (monitor)\n",
+                         dev->name);
+               if (! capable(CAP_NET_ADMIN)) {
+                       err = -EPERM;
+                       break;
+               }
+               err = orinoco_wlansniff(dev, wrq);
+               break;
+
        case SIOCIWLASTPRIV:
                err = orinoco_debug_dump_recs(dev);
                if (err)
@@ -4049,6 +4303,7 @@
        int i,j;
        u16 length;
        int err;
+        struct ieee802_11_hdr hdr80211;

        /* I'm not sure: we might have a lock here, so we'd better go
            atomic, just in case. */
@@ -4171,6 +4426,197 @@
 }
 #endif /* 0 */

+/*----------------------------------------------------------------
+* orinoco_int_rxmonitor
+*
+* Helper function for int_rx.  Handles monitor frames.
+* Note that this function allocates space for the FCS and sets it
+* to 0xffffffff.  The hfa384x doesn't give us the FCS value but the
+* higher layers expect it.  0xffffffff is used as a flag to indicate
+* the FCS is bogus.
+*
+* Arguments:
+*      dev             wlan device structure
+*      rxfid           received FID
+*      rxdesc          rx descriptor read from card in int_rx
+*
+* Returns:
+*      nothing
+*
+* Side effects:
+*      Allocates an skb and passes it up via the PF_PACKET interface.
+* Call context:
+*      interrupt
+----------------------------------------------------------------*/
+void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int 
len,
+                            struct hermes_rx_descriptor *rxdesc, struct 
ieee802_11_hdr *hdr)
+{
+       hermes_t                        *hw = &(dev->hw);
+       uint32_t                                hdrlen = 0;
+       uint32_t                                datalen = 0;
+       uint32_t                                skblen = 0;
+       p80211msg_lnxind_wlansniffrm_t  *msg;
+       struct net_device_stats *stats = &dev->stats;
+
+
+       uint8_t                         *datap;
+       uint16_t                                fc;
+       struct sk_buff                  *skb;
+
+       /* Don't forget the status, time, and data_len fields are in host order 
*/
+       /* Figure out how big the frame is */
+       fc = le16_to_cpu(hdr->frame_ctl);
+       switch ( WLAN_GET_FC_FTYPE(fc) )
+       {
+       case WLAN_FTYPE_DATA:
+               if ( WLAN_GET_FC_TODS(fc) && WLAN_GET_FC_FROMDS(fc) ) {
+                       hdrlen = WLAN_HDR_A4_LEN;
+               } else {
+                       hdrlen = WLAN_HDR_A3_LEN;
+               }
+               datalen = len;
+               break;
+       case WLAN_FTYPE_MGMT:
+               hdrlen = WLAN_HDR_A3_LEN;
+               datalen = len;
+               break;
+       case WLAN_FTYPE_CTL:
+               switch ( WLAN_GET_FC_FSTYPE(fc) )
+               {
+               case WLAN_FSTYPE_PSPOLL:
+               case WLAN_FSTYPE_RTS:
+               case WLAN_FSTYPE_CFEND:
+               case WLAN_FSTYPE_CFENDCFACK:
+                       hdrlen = 16;
+                       break;
+               case WLAN_FSTYPE_CTS:
+               case WLAN_FSTYPE_ACK:
+                       hdrlen = 10;
+                       break;
+               }
+               datalen = 0;
+               break;
+       default:
+               printk("unknown frm: fc=0x%04x\n", fc);
+               return;
+       }
+
+       /* Allocate an ind message+framesize skb */
+       skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) +
+         hdrlen + datalen;
+
+       /* sanity check the length */
+       if ( skblen >
+               (sizeof(p80211msg_lnxind_wlansniffrm_t) +
+               WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
+               printk("overlen frm: len=%d\n",
+                       skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+       }
+
+       if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
+               printk("alloc_skb failed trying to allocate %d bytes\n", 
skblen);
+               return;
+       }
+
+       /* only prepend the prism header if in the right mode */
+       if (dev->ndev->type != ARPHRD_IEEE80211_PRISM) {
+         skb_put(skb, skblen - sizeof(p80211msg_lnxind_wlansniffrm_t));
+         datap = skb->data;
+       } else {
+         skb_put(skb, skblen);
+         datap = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
+         msg = (p80211msg_lnxind_wlansniffrm_t*)skb->data;
+
+         /* Initialize the message members */
+         msg->msgcode = DIDmsg_lnxind_wlansniffrm;
+         msg->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
+         strcpy(msg->devname, dev->ndev->name);
+
+         msg->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+         msg->hosttime.status = 0;
+         msg->hosttime.len = 4;
+         msg->hosttime.data = jiffies;
+
+         msg->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+         msg->mactime.status = 0;
+         msg->mactime.len = 4;
+         msg->mactime.data = rxdesc->time;
+
+         msg->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+         msg->channel.status = P80211ENUM_msgitem_status_no_value;
+         msg->channel.len = 4;
+         msg->channel.data = 0;
+
+         msg->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+         msg->rssi.status = P80211ENUM_msgitem_status_no_value;
+         msg->rssi.len = 4;
+         msg->rssi.data = 0;
+
+         msg->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
+         msg->sq.status = P80211ENUM_msgitem_status_no_value;
+         msg->sq.len = 4;
+         msg->sq.data = 0;
+
+         msg->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+         msg->signal.status = 0;
+         msg->signal.len = 4;
+         msg->signal.data = rxdesc->signal;
+
+         msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+         msg->noise.status = 0;
+         msg->noise.len = 4;
+         msg->noise.data = rxdesc->silence;
+
+         msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+         msg->rate.status = 0;
+         msg->rate.len = 4;
+         msg->rate.data = rxdesc->rate / 5; /* set to 802.11 units */
+
+         msg->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+         msg->istx.status = 0;
+         msg->istx.len = 4;
+         msg->istx.data = P80211ENUM_truth_false;
+
+         msg->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+         msg->frmlen.status = 0;
+         msg->frmlen.len = 4;
+         msg->frmlen.data = hdrlen + datalen;
+       }
+
+       /* Copy the 802.11 header to the skb (ctl frames may be less than a 
full header) */
+       memcpy( datap, &(hdr->frame_ctl), hdrlen);
+
+       /* If any, copy the data from the card to the skb */
+       if ( datalen > 0 )
+       {
+               hermes_bap_pread(hw, IRQ_BAP, datap + hdrlen, (datalen+1)&~1,
+                                      rxfid, HERMES_RX_DATA_OFF);
+
+               /* check for unencrypted stuff if WEP bit set. */
+               if (*(datap+1) & 0x40) // wep set
+                 if ((*(datap+hdrlen) == 0xaa) && (*(datap+hdrlen+1) == 0xaa))
+                   *(datap+1) &= 0xbf; // clear wep; it's the 802.2 header!
+       }
+
+       /* pass it up via the PF_PACKET interface */
+       {
+          skb->dev = dev->ndev;
+          skb->dev->last_rx = jiffies;
+
+          skb->mac.raw = skb->data ;
+          skb->ip_summed = CHECKSUM_NONE;
+          skb->pkt_type = PACKET_OTHERHOST;
+          skb->protocol = htons(ETH_P_80211_RAW);  /* XXX ETH_P_802_2? */
+
+          stats->rx_packets++;
+          stats->rx_bytes += skb->len;
+
+          netif_rx(skb);
+       }
+
+       return;
+}
+
 /********************************************************************/
 /* Module initialization                                            */
 /********************************************************************/
@@ -4193,6 +4639,7 @@
 static int __init init_orinoco(void)
 {
        printk(KERN_DEBUG "%s\n", version);
+       suppress_linkstatus_copy = suppress_linkstatus;
        return 0;
 }

diff -ur linux-2.6.9/drivers/net/wireless/orinoco.h
linux-2.6.9-orinoco/drivers/net/wireless/orinoco.h
--- linux-2.6.9/drivers/net/wireless/orinoco.h  2004-10-20 15:26:41.000000000 
-0400
+++ linux-2.6.9-orinoco/drivers/net/wireless/orinoco.h  2004-10-20 
15:10:12.000000000 -0400
@@ -20,6 +20,21 @@
 /* To enable debug messages */
 //#define ORINOCO_DEBUG                3

+#ifndef ETH_P_ECONET
+#define ETH_P_ECONET   0x0018    /* needed for 2.2.x kernels */
+#endif
+
+#define ETH_P_80211_RAW        (ETH_P_ECONET + 1)
+
+#ifndef ARPHRD_IEEE80211
+#define ARPHRD_IEEE80211 801     /* kernel 2.4.6 */
+#endif
+
+#ifndef ARPHRD_IEEE80211_PRISM  /* kernel 2.4.18 */
+#define ARPHRD_IEEE80211_PRISM 802
+#endif
+
+
 #define WIRELESS_SPY           // enable iwspy support

 #define ORINOCO_MAX_KEY_SIZE   14
@@ -30,6 +45,159 @@
        char data[ORINOCO_MAX_KEY_SIZE];
 } __attribute__ ((packed));

+#define WLAN_DEVNAMELEN_MAX 16
+
+/* message data item for INT, BOUNDEDINT, ENUMINT */
+typedef struct p80211item_uint32
+{
+       uint32_t                did             __attribute__ ((packed));
+       uint16_t                status  __attribute__ ((packed));
+       uint16_t                len             __attribute__ ((packed));
+       uint32_t                data    __attribute__ ((packed));
+} __attribute__ ((packed)) p80211item_uint32_t;
+
+typedef struct p80211msg
+{
+       uint32_t        msgcode         __attribute__ ((packed));
+       uint32_t        msglen          __attribute__ ((packed));
+       uint8_t devname[WLAN_DEVNAMELEN_MAX]    __attribute__ ((packed));
+} __attribute__ ((packed)) p80211msg_t;
+
+#define DIDmsg_lnxind_wlansniffrm 0x0041
+#define DIDmsg_lnxind_wlansniffrm_hosttime 0x1041
+#define DIDmsg_lnxind_wlansniffrm_mactime 0x2041
+#define DIDmsg_lnxind_wlansniffrm_channel 0x3041
+#define DIDmsg_lnxind_wlansniffrm_rssi 0x4041
+#define DIDmsg_lnxind_wlansniffrm_sq 0x5041
+#define DIDmsg_lnxind_wlansniffrm_signal 0x6041
+#define DIDmsg_lnxind_wlansniffrm_noise 0x7041
+#define DIDmsg_lnxind_wlansniffrm_rate 0x8041
+#define DIDmsg_lnxind_wlansniffrm_istx 0x9041
+#define DIDmsg_lnxind_wlansniffrm_frmlen 0xA041
+
+typedef struct p80211msg_lnxind_wlansniffrm
+{
+       uint32_t                msgcode;
+       uint32_t                msglen;
+       uint8_t             devname[WLAN_DEVNAMELEN_MAX];
+       p80211item_uint32_t     hosttime;
+       p80211item_uint32_t     mactime;
+       p80211item_uint32_t     channel;
+       p80211item_uint32_t     rssi;
+       p80211item_uint32_t     sq;
+       p80211item_uint32_t     signal;
+       p80211item_uint32_t     noise;
+       p80211item_uint32_t     rate;
+       p80211item_uint32_t     istx;
+       p80211item_uint32_t     frmlen;
+} __attribute__ ((packed)) p80211msg_lnxind_wlansniffrm_t;
+
+#define P80211ENUM_truth_false                 0
+#define P80211ENUM_truth_true                  1
+#define P80211ENUM_resultcode_success          1
+#define P80211ENUM_resultcode_invalid_parameters       2
+#define P80211ENUM_resultcode_not_supported    3
+#define P80211ENUM_resultcode_timeout          4
+#define P80211ENUM_resultcode_too_many_req     5
+#define P80211ENUM_resultcode_refused          6
+#define P80211ENUM_resultcode_bss_already      7
+#define P80211ENUM_resultcode_invalid_access   8
+#define P80211ENUM_resultcode_invalid_mibattribute     9
+#define P80211ENUM_resultcode_cant_set_readonly_mib    10
+#define P80211ENUM_resultcode_implementation_failure   11
+#define P80211ENUM_resultcode_cant_get_writeonly_mib   12
+#define P80211ENUM_msgitem_status_data_ok              0
+#define P80211ENUM_msgitem_status_no_value             1
+#define P80211ENUM_msgitem_status_invalid_itemname     2
+#define P80211ENUM_msgitem_status_invalid_itemdata     3
+#define P80211ENUM_msgitem_status_missing_itemdata     4
+#define P80211ENUM_msgitem_status_incomplete_itemdata  5
+#define P80211ENUM_msgitem_status_invalid_msg_did      6
+#define P80211ENUM_msgitem_status_invalid_mib_did      7
+#define P80211ENUM_msgitem_status_missing_conv_func    8
+#define P80211ENUM_msgitem_status_string_too_long      9
+#define P80211ENUM_msgitem_status_data_out_of_range    10
+#define P80211ENUM_msgitem_status_string_too_short     11
+#define P80211ENUM_msgitem_status_missing_valid_func   12
+#define P80211ENUM_msgitem_status_unknown              13
+#define P80211ENUM_msgitem_status_invalid_did          14
+#define P80211ENUM_msgitem_status_missing_print_func   15
+
+#define WLAN_GET_FC_FTYPE(n)   (((n) & 0x0C) >> 2)
+#define WLAN_GET_FC_FSTYPE(n)  (((n) & 0xF0) >> 4)
+#define WLAN_GET_FC_TODS(n)    (((n) & 0x0100) >> 8)
+#define WLAN_GET_FC_FROMDS(n)  (((n) & 0x0200) >> 9)
+
+/*--- Sizes -----------------------------------------------*/
+#define WLAN_ADDR_LEN                  6
+#define WLAN_CRC_LEN                   4
+#define WLAN_BSSID_LEN                 6
+#define WLAN_BSS_TS_LEN                        8
+#define WLAN_HDR_A3_LEN                        24
+#define WLAN_HDR_A4_LEN                        30
+#define WLAN_SSID_MAXLEN               32
+#define WLAN_DATA_MAXLEN               2312
+
+/*--- Frame Control Field -------------------------------------*/
+/* Frame Types */
+#define WLAN_FTYPE_MGMT                        0x00
+#define WLAN_FTYPE_CTL                 0x01
+#define WLAN_FTYPE_DATA                        0x02
+
+/* Frame subtypes */
+/* Management */
+#define WLAN_FSTYPE_ASSOCREQ           0x00
+#define WLAN_FSTYPE_ASSOCRESP          0x01
+#define WLAN_FSTYPE_REASSOCREQ         0x02
+#define WLAN_FSTYPE_REASSOCRESP                0x03
+#define WLAN_FSTYPE_PROBEREQ           0x04
+#define WLAN_FSTYPE_PROBERESP          0x05
+#define WLAN_FSTYPE_BEACON             0x08
+#define WLAN_FSTYPE_ATIM               0x09
+#define WLAN_FSTYPE_DISASSOC           0x0a
+#define WLAN_FSTYPE_AUTHEN             0x0b
+#define WLAN_FSTYPE_DEAUTHEN           0x0c
+
+/* Control */
+#define WLAN_FSTYPE_PSPOLL             0x0a
+#define WLAN_FSTYPE_RTS                        0x0b
+#define WLAN_FSTYPE_CTS                        0x0c
+#define WLAN_FSTYPE_ACK                        0x0d
+#define WLAN_FSTYPE_CFEND              0x0e
+#define WLAN_FSTYPE_CFENDCFACK         0x0f
+
+/* Data */
+#define WLAN_FSTYPE_DATAONLY           0x00
+#define WLAN_FSTYPE_DATA_CFACK         0x01
+#define WLAN_FSTYPE_DATA_CFPOLL                0x02
+#define WLAN_FSTYPE_DATA_CFACK_CFPOLL  0x03
+#define WLAN_FSTYPE_NULL               0x04
+#define WLAN_FSTYPE_CFACK              0x05
+#define WLAN_FSTYPE_CFPOLL             0x06
+#define WLAN_FSTYPE_CFACK_CFPOLL       0x07
+
+/*----------------------------------------------------------------*/
+/* Magic number, a quick test to see we're getting the desired struct */
+
+#define P80211_IOCTL_MAGIC     (0x4a2d464dUL)
+
+/*================================================================*/
+/* Types */
+
+/*----------------------------------------------------------------*/
+/* A ptr to the following structure type is passed as the third */
+/*  argument to the ioctl system call when issuing a request to */
+/*  the p80211 module. */
+
+typedef struct p80211ioctl_req
+{
+       char    name[WLAN_DEVNAMELEN_MAX] __attribute__ ((packed));
+       void    *data           __attribute__ ((packed));
+       uint32_t        magic   __attribute__ ((packed));
+       uint16_t        len     __attribute__ ((packed));
+       uint32_t        result  __attribute__ ((packed));
+} __attribute__ ((packed)) p80211ioctl_req_t;
+
 struct orinoco_private {
        void *card;     /* Pointer to card dependent structure */
        int (*hard_reset)(struct orinoco_private *);
@@ -90,6 +258,9 @@
        /* Configuration dependent variables */
        int port_type, createibss;
        int promiscuous, mc_count;
+
+       uint16_t                presniff_port_type;
+       uint16_t                presniff_wepflags;
 };

 #ifdef ORINOCO_DEBUG
@@ -141,4 +312,12 @@
        spin_unlock_irqrestore(&priv->lock, *flags);
 }

+/*================================================================*/
+/* Function Declarations */
+
+struct ieee802_11_hdr;
+
+void orinoco_int_rxmonitor( struct orinoco_private *dev, uint16_t rxfid, int 
len,
+                            struct hermes_rx_descriptor *rxdesc, struct 
ieee802_11_hdr *hdr);
+
 #endif /* _ORINOCO_H */



--
"Education is what remains after one has forgotten everything he learned in 
school."
        - Albert Einstein

Attachment: signature.asc
Description: OpenPGP digital signature



Reply via email to