Re: Orinoco promiscuous mode?

From: Jerry McBride (mcbrides9_at_comcast.net)
Date: 05/13/04

  • Next message: Madhusudan Singh: "USB powered drives with laptops"
    Date: Wed, 12 May 2004 22:56:18 -0400
    
    

    theanswriz42 wrote:

    > Hello,
    > I have recently come into ownership of an Orinoco Gold card and have
    > done some reading suggesting I need a patch to enable promiscuous mode
    > ie. to use airsnort or other similar tools. Does anyone happen to know
    > where I can find this patch? I greatly appreciate the help
    >
    > cheers

    I'll assume you are using a 2.6.x kernel... here's the patch I use...

    beware word wrap...

    diff -urN linux/drivers/net/wireless/hermes.c orinoco-monitor/hermes.c
    --- linux/drivers/net/wireless/hermes.c 2003-05-12 16:22:27.000000000 +1000
    +++ orinoco-monitor/hermes.c 2003-05-13 13:26:02.000000000 +1000
    @@ -183,6 +183,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 -urN linux/drivers/net/wireless/hermes.h orinoco-monitor/hermes.h
    --- linux/drivers/net/wireless/hermes.h 2003-05-12 16:22:27.000000000 +1000
    +++ orinoco-monitor/hermes.h 2003-05-07 16:54:45.000000000 +1000
    @@ -33,6 +33,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
      */
    @@ -148,6 +152,14 @@
     #define HERMES_MONITOR_ENABLE (0x000b)
     #define HERMES_MONITOR_DISABLE (0x000f)
     
    +/*--------------------------------------------------------------------
    +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
      */
    @@ -171,6 +183,7 @@
     #define HERMES_RXSTAT_BADCRC (0x0001)
     #define HERMES_RXSTAT_UNDECRYPTABLE (0x0002)
     #define HERMES_RXSTAT_MACPORT (0x0700)
    +#define HERMES_RXSTAT_GET_MACPORT(s) (((s) & HERMES_RXSTAT_MACPORT) >> 8)
     #define HERMES_RXSTAT_PCF (0x1000) /* Frame was received in CF period */
     #define HERMES_RXSTAT_MSGTYPE (0xE000)
     #define HERMES_RXSTAT_1042 (0x2000) /* RFC-1042 frame */
    @@ -286,6 +299,7 @@
     #define HERMES_32BIT_REGSPACING 1
     
            u16 inten; /* Which interrupts should be enabled? */
    + u8 port_enabled[HERMES_NUMPORTS_MAX];
     
     #ifdef HERMES_DEBUG_BUFFER
            struct hermes_debug_entry dbuf[HERMES_DEBUG_BUFSIZE];
    @@ -339,12 +353,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 -urN linux/drivers/net/wireless/orinoco.c orinoco-monitor/orinoco.c
    --- linux/drivers/net/wireless/orinoco.c 2003-05-12 16:22:27.000000000 +1000
    +++ orinoco-monitor/orinoco.c 2003-05-13 13:27:31.000000000 +1000
    @@ -1673,6 +1673,7 @@
            struct header_struct hdr;
            struct ethhdr *eh;
            int err;
    + struct ieee802_11_hdr hdr80211;
     
            rxfid = hermes_read_regn(hw, RXFID);
     
    @@ -1689,6 +1690,8 @@
            
            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);
    @@ -1699,7 +1702,7 @@
                    stats->rx_errors++;
                    goto drop;
            }
    -
    +sniffing:
            /* For now we ignore the 802.11 header completely, assuming
                that the card's firmware has handled anything vital */
     
    @@ -1729,81 +1732,111 @@
                    stats->rx_errors++;
                    goto drop;
            }
    + /* Now handle frame based on port# */
    + switch (HERMES_RXSTAT_GET_MACPORT(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 packets from the card, which
    + * has an IO granularity of 16 bits */
    + skb = dev_alloc_skb(length+ETH_HLEN+2+1);
    + if (!skb) {
    + printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
    + dev->name);
    + goto drop;
    + }
     
    - /* 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
    - packets from the card, which has an IO granularity of 16
    - bits */
    - skb = dev_alloc_skb(length+ETH_HLEN+2+1);
    - if (!skb) {
    - printk(KERN_WARNING "%s: Can't allocate skb for Rx\n",
    - dev->name);
    - goto drop;
    - }
    -
    - skb_reserve(skb, 2); /* This way the IP header is aligned */
    -
    - /* Handle decapsulation
    - * In most cases, the firmware tell us about SNAP frames.
    - * For some reason, the SNAP frames sent by LinkSys APs
    - * are not properly recognised by most firmwares.
    - * So, check ourselves */
    - if(((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
    - ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
    - is_ethersnap(&hdr)) {
    - /* These indicate a SNAP within 802.2 LLC within
    - 802.11 frame which we'll need to de-encapsulate to
    - the original EthernetII frame. */
    + skb_reserve(skb, 2); /* This way the IP header is aligned */
     
    - if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
    - stats->rx_length_errors++;
    + /* Handle decapsulation In most cases, the firmware
    + * tell us about SNAP frames. For some reason, the
    + * SNAP frames sent by LinkSys APs are not properly
    + * recognised by most firmwares. So, check ourselves
    + * */
    + if (((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_1042) ||
    + ((status & HERMES_RXSTAT_MSGTYPE) == HERMES_RXSTAT_TUNNEL) ||
    + is_ethersnap(&hdr)) {
    + /* These indicate a SNAP within 802.2 LLC
    + * within 802.11 frame which we'll need to
    + * de-encapsulate to the original EthernetII
    + * frame. */
    +
    + if (length < ENCAPS_OVERHEAD) { /* No room for full LLC+SNAP */
    + stats->rx_length_errors++;
    + goto drop;
    + }
    +
    + /* Remove SNAP header, reconstruct EthernetII frame */
    + data_len = length - ENCAPS_OVERHEAD;
    + data_off = HERMES_802_3_OFFSET + sizeof(hdr);
    +
    + eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
    +
    + memcpy(eh, &hdr, 2 * ETH_ALEN);
    + eh->h_proto = hdr.ethertype;
    + } else {
    + /* All other cases indicate a genuine 802.3 frame. No
    + decapsulation needed. We just throw the whole
    + thing in, and hope the protocol layer can deal with
    + it as 802.3 */
    + data_len = length;
    + data_off = HERMES_802_3_OFFSET;
    + /* FIXME: we re-read from the card data we already read here */
    + }
    +
    + p = skb_put(skb, data_len);
    + err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
    + rxfid, data_off);
    + if (err) {
    + printk(KERN_ERR "%s: error %d reading frame. "
    + "Frame dropped.\n", dev->name, err);
    + stats->rx_errors++;
    + goto drop;
    + }
    +
    + dev->last_rx = jiffies;
    + skb->dev = dev;
    + skb->protocol = eth_type_trans(skb, dev);
    + skb->ip_summed = CHECKSUM_NONE;
    +
    + /* Process the wireless stats if needed */
    + orinoco_stat_gather(dev, skb, &desc);
    +
    + /* Pass the packet to the networking stack */
    + netif_rx(skb);
    + stats->rx_packets++;
    + stats->rx_bytes += length;
    +
    + return;
    +
    + case 7:
    + if (status & HERMES_RXSTAT_BADCRC) {
    + printk(KERN_DEBUG "%s: Received monitor frame: "
    + "BADCRC set\n", dev->name);
                            goto drop;
                    }
     
    - /* Remove SNAP header, reconstruct EthernetII frame */
    - data_len = length - ENCAPS_OVERHEAD;
    - data_off = HERMES_802_3_OFFSET + sizeof(hdr);
    + err = hermes_bap_pread(hw, IRQ_BAP, &hdr80211,
    + sizeof(hdr80211),
    + rxfid, HERMES_RX_80211HDR_OFF);
     
    - eh = (struct ethhdr *)skb_put(skb, ETH_HLEN);
    + if (err) {
    + printk(KERN_ERR "%s: error %d reading monitor frame. "
    + "Frame dropped.\n", dev->name, err);
    + stats->rx_errors++;
    + goto drop;
    + }
     
    - memcpy(eh, &hdr, 2 * ETH_ALEN);
    - eh->h_proto = hdr.ethertype;
    - } else {
    - /* All other cases indicate a genuine 802.3 frame. No
    - decapsulation needed. We just throw the whole
    - thing in, and hope the protocol layer can deal with
    - it as 802.3 */
    - data_len = length;
    - data_off = HERMES_802_3_OFFSET;
    - /* FIXME: we re-read from the card data we already read here */
    - }
    + orinoco_int_rxmonitor(dev, rxfid, length,
    + &desc, &hdr80211);
    + break;
     
    - p = skb_put(skb, data_len);
    - err = hermes_bap_pread(hw, IRQ_BAP, p, RUP_EVEN(data_len),
    - rxfid, data_off);
    - if (err) {
    - printk(KERN_ERR "%s: error %d reading frame. "
    - "Frame dropped.\n", dev->name, err);
    - stats->rx_errors++;
    - goto drop;
    + default:
    + printk("Received frame on unsupported port=%d\n",
    + HERMES_RXSTAT_GET_MACPORT(status));
    + break;
            }
    -
    - dev->last_rx = jiffies;
    - skb->dev = dev;
    - skb->protocol = eth_type_trans(skb, dev);
    - skb->ip_summed = CHECKSUM_NONE;
    -
    - /* Process the wireless stats if needed */
    - orinoco_stat_gather(dev, skb, &desc);
    -
    - /* Pass the packet to the networking stack */
    - netif_rx(skb);
    - stats->rx_packets++;
    - stats->rx_bytes += length;
    -
    - return;
    -
      drop:
            stats->rx_dropped++;
     
    @@ -3598,6 +3631,159 @@
            return 0;
     }
     
    +static int orinoco_wlansniff(struct net_device *dev, struct iwreq *wrq)
    +{
    + struct orinoco_private *priv = dev->priv;
    + hermes_t *hw = &priv->hw;
    + int err = 0;
    + u16 word;
    + int *parms = (int *) wrq->u.name;
    + int enable = parms[0] > 0;
    + unsigned long flags;
    +
    + err = orinoco_lock(priv, &flags);
    + if (err)
    + return err;
    +
    + switch (enable) {
    + case 0:
    + /* Confirm that we're in monitor mode */
    + if (dev->type == ARPHRD_ETHER)
    + err = -EFAULT;
    +
    + /* Disable monitor mode */
    + word = HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8);
    + err = hermes_docmd_wait(hw, word, 0, NULL);
    + if (err)
    + break;
    +
    + /* Disable port 0 */
    + err = hermes_disable_port(hw, 0);
    + if (err)
    + break;
    +
    + /* Clear the driver state */
    + dev->type = ARPHRD_ETHER;
    +
    + /* Restore the wepflags */ /*Orinoco doesn't like this*/
    +#if 0
    + err = hermes_write_wordrec(hw, USER_BAP,
    + HERMES_RID_CNFWEPFLAGS_INTERSIL,
    + priv->presniff_wepflags);
    + if (err)
    + break;
    +#endif /* 0 */
    +
    + /* Set the port to its prior type and enable (if necessary) */
    + if (priv->presniff_port_type != 0) {
    + word = priv->presniff_port_type;
    + err = hermes_write_wordrec(hw, USER_BAP,
    + HERMES_RID_CNFPORTTYPE,
    + word);
    + if (err)
    + break;
    +
    + /* Enable the port */
    + err = hermes_enable_port(hw, 0);
    + if (err)
    + break;
    + }
    +
    + break;
    +
    + case 1:
    + /* 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);
    + /* Disable the port (if enabled), only check Port 0 */
    + if (hw->port_enabled[0]) {
    + /* Save macport 0 state */
    + err = hermes_read_wordrec(hw, USER_BAP,
    + HERMES_RID_CNFPORTTYPE,
    + &(priv->presniff_port_type));
    + if (err)
    + break;
    +
    + /* Save the wepflags state */
    + err = hermes_read_wordrec(hw, USER_BAP,
    + HERMES_RID_CNFWEPFLAGS_INTERSIL,
    + &(priv->presniff_wepflags));
    + if (err)
    + break;
    + err = hermes_disable_port(hw, 0);
    + if (err)
    + break;
    + } else {
    + priv->presniff_port_type = 0;
    + }
    +
    + /* Set the channel we wish to sniff */
    + if ((parms[1] > 0) && (parms[1] < 15)) {
    + word = parms[1];
    + err = hermes_write_wordrec(hw, USER_BAP,
    + HERMES_RID_CNFOWNCHANNEL,
    + word);
    + } else {
    + err = -EFAULT;
    + }
    +
    + if (err)
    + break;
    +
    + /* Set the port type to pIbss */
    + word = HFA384x_PORTTYPE_IBSS;
    + err = hermes_write_wordrec(hw, USER_BAP,
    + HERMES_RID_CNFPORTTYPE, word);
    + if (err)
    + break;
    +
    +#if 0
    + if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) &&
    + (msg->keepwepflags.data != 1)) {
    + /* Set the wepflags for no decryption */
    + /* Orinoco doesn't like this */
    + word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
    + HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
    + err = hermes_write_wordrec(hw, USER_BAP,
    + HERMES_RID_CNFWEPFLAGS_INTERSIL,
    + word); /*won't work with the bits above */
    + }
    + if (err)
    + break;
    +#endif /* 0 */
    + /* Enable the port */
    + err = hermes_enable_port(hw, 0);
    + if (err)
    + break;
    +
    + /* Enable monitor mode */
    + word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8);
    + err = hermes_docmd_wait(hw, word, 0, NULL);
    + if (err)
    + 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:
    + BUG();
    + break;
    + }
    +
    + orinoco_unlock(priv, &flags);
    + return err;
    +}
    +
     static int
     orinoco_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
     {
    @@ -3830,6 +4016,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" },
                            };
     
    @@ -3924,6 +4113,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)
    @@ -4171,6 +4370,191 @@
     
     }
     
    +/*----------------------------------------------------------------
    +* orinoco_int_rxmonitor
    +*
    +* 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
    +*
    +* Side effects:
    +* Allocates an skb and passes it up via the PF_PACKET interface.
    +* Call context:
    +* interrupt
    +----------------------------------------------------------------*/
    +void orinoco_int_rxmonitor(struct net_device *dev, u16 rxfid,
    + int len, struct hermes_rx_descriptor *rxdesc,
    + struct ieee802_11_hdr *hdr)
    +{
    + struct orinoco_private *priv = dev->priv;
    + hermes_t *hw = &priv->hw;
    + u32 hdrlen = 0;
    + u32 datalen = 0;
    + u32 skblen = 0;
    + p80211msg_lnxind_wlansniffrm_t *msg;
    + struct net_device_stats *stats = &priv->stats;
    + u8 *datap;
    + u16 fc;
    + struct sk_buff *skb;
    +
    + /* Don't forget the status, time, and data_len fields are in
    + * little-endian order */
    + /* Figure out how big the frame is */
    + fc = le16_to_cpu(hdr->frame_ctl);
    + switch (fc & IEEE802_11_FCTL_FTYPE) {
    + case IEEE802_11_FTYPE_DATA:
    + if ((fc & IEEE802_11_FCTL_TODS)
    + && (fc & IEEE802_11_FCTL_FROMDS))
    + hdrlen = WLAN_HDR_A4_LEN;
    + else
    + hdrlen = WLAN_HDR_A3_LEN;
    + datalen = len;
    + break;
    + case IEEE802_11_FTYPE_MGMT:
    + hdrlen = WLAN_HDR_A3_LEN;
    + datalen = len;
    + break;
    + case IEEE802_11_FTYPE_CTL:
    + switch (fc & IEEE802_11_FCTL_STYPE) {
    + case IEEE802_11_STYPE_PSPOLL:
    + case IEEE802_11_STYPE_RTS:
    + case IEEE802_11_STYPE_CFEND:
    + case IEEE802_11_STYPE_CFENDACK:
    + hdrlen = 16;
    + break;
    + case IEEE802_11_STYPE_CTS:
    + case IEEE802_11_STYPE_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->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->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 = 0;
    +
    + 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;
    + 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 */
     /********************************************************************/
    diff -urN linux/drivers/net/wireless/orinoco.h orinoco-monitor/orinoco.h
    --- linux/drivers/net/wireless/orinoco.h 2003-05-12 16:22:27.000000000 +1000
    +++ orinoco-monitor/orinoco.h 2003-05-13 13:27:02.000000000 +1000
    @@ -37,6 +37,16 @@
     /* To enable debug messages */
     //#define ORINOCO_DEBUG 3
     
    +#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
    +
     #if (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10)
     #error "orinoco driver requires Wireless extensions v10 or later."
     #endif /* (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10) */
    @@ -55,6 +65,67 @@
                                    HERMES_EV_INFDROP )
     
     
    +#define WLAN_DEVNAMELEN_MAX 16
    +
    +/* message data item for INT, BOUNDEDINT, ENUMINT */
    +typedef struct p80211item_uint32 {
    + u32 did;
    + u16 status;
    + u16 len;
    + u32 data;
    +} __attribute__ ((packed)) p80211item_uint32_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 {
    + u32 msgcode;
    + u32 msglen;
    + u8 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_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
    +
    +/*--- Sizes -----------------------------------------------*/
    +#define WLAN_CRC_LEN 4
    +#define WLAN_HDR_A3_LEN 24
    +#define WLAN_HDR_A4_LEN 30
    +#define WLAN_DATA_MAXLEN 2312
    +
     struct orinoco_private {
            void *card; /* Pointer to card dependent structure */
            int (*hard_reset)(struct orinoco_private *);
    @@ -116,6 +187,9 @@
            /* Configuration dependent variables */
            int port_type, createibss;
            int promiscuous, mc_count;
    +
    + u16 presniff_port_type;
    + u16 presniff_wepflags;
     };
     
     #ifdef ORINOCO_DEBUG

    -- 
    ******************************************************************************
                         Registered Linux User Number 185956
              http://groups.google.com/groups?hl=en&safe=off&group=linux
                 Join me in chat at #linux-users on irc.freenode.net
        Buy an Xbox for $149.00, run linux on it and Microsoft loses $150.00!
        10:16pm  up 23 days,  1:37,  5 users,  load average: 1.94, 2.28, 2.40
    

  • Next message: Madhusudan Singh: "USB powered drives with laptops"

    Relevant Pages