Eric Gaumer wrote: [...] | Yes I have patches that enable scanning. I wouldn't be able to function | without kismet ;-) | I have a Titanium PB with an airport card. | | deb ftp://corp.primenetwork.net/debian/ prime contrib | deb-src ftp://corp.primenetwork.net/debian prime contrib | | ]$ apt-get update | ]$ apt-get install kernel-image-2.6.10-powerpc_1.1_powerpc.deb | | Or I can send you the patch if you'd like to build your own kernel. [...] Eric, you are my hero. Please send the patch; I will build that tonight. Has there been any talk of having that be standard with the Debian kernels for ppc? I can't think of a case where someone wouldn't want scanning enabled.
There must be obvious reasons why this isn't the case though I'm not sure of them myself. Perhaps someone can shed some light.
I've used this patch pretty heavily and it's never shown any instability for me.
The patch is from 2.6.9 but applies cleanly to 2.6.10 as well.
-- "Education is what remains after one has forgotten everything he learned in school." - Albert Einstein
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 */
signature.asc
Description: OpenPGP digital signature