diff -aur pcmcia-cs-3.1.31/wireless/hermes.c pcmcia-cs-3.1.31-devel/wireless/hermes.c --- pcmcia-cs-3.1.31/wireless/hermes.c Mon Feb 18 20:13:01 2002 +++ pcmcia-cs-3.1.31-devel/wireless/hermes.c Tue Feb 19 17:03:53 2002 @@ -166,6 +166,9 @@ err = hermes_issue_cmd(hw, HERMES_CMD_INIT, 0); 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; diff -aur pcmcia-cs-3.1.31/wireless/hermes.h pcmcia-cs-3.1.31-devel/wireless/hermes.h --- pcmcia-cs-3.1.31/wireless/hermes.h Mon Feb 18 20:13:01 2002 +++ pcmcia-cs-3.1.31-devel/wireless/hermes.h Tue Feb 19 17:03:53 2002 @@ -32,6 +32,10 @@ #include #include +#define HFA384x_PORTTYPE_IBSS ((uint16_t)3) +#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT (0x10) +#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT (0x80) + /* * Limits and constants */ @@ -206,6 +210,30 @@ #define HERMES_RID_SYMBOL_SECONDARY_VER (0xfd24) #define HERMES_RID_SYMBOL_KEY_LENGTH (0xfc2B) +/*-- 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 */ @@ -240,6 +268,8 @@ uint iobase; uint16_t inten; /* Which interrupts should be enabled? */ + uint8_t port_enabled[HERMES_NUMPORTS_MAX]; + } hermes_t; typedef struct hermes_response { @@ -303,6 +333,8 @@ { hermes_response_t resp; + hw->port_enabled[port] = 1; + return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), 0, &resp); } @@ -311,7 +343,9 @@ { hermes_response_t resp; - return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), + hw->port_enabled[port] = 0; + + return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 0, &resp); } diff -aur pcmcia-cs-3.1.31/wireless/orinoco.c pcmcia-cs-3.1.31-devel/wireless/orinoco.c --- pcmcia-cs-3.1.31/wireless/orinoco.c Mon Feb 18 20:13:01 2002 +++ pcmcia-cs-3.1.31-devel/wireless/orinoco.c Tue Feb 19 17:03:53 2002 @@ -235,8 +235,12 @@ #include #include #include -#include #include +#include +#undef min +#undef max +#include +#include #include #include @@ -399,6 +403,9 @@ static int dldwd_proc_init(void); static void dldwd_proc_cleanup(void); +/* Netlink interface(s) */ +static struct sock *nl_indicate = NULL; + /* * Inline functions */ @@ -515,6 +522,8 @@ TRACE_ENTER(priv->ndev.name); + p80211indicate_shutdown(); + dldwd_lock(priv); __dldwd_stop_irqs(priv); @@ -671,6 +680,7 @@ /* Set promiscuity / multicast*/ priv->promiscuous = 0; + priv->sniffing = 0; priv->allmulti = 0; priv->mc_count = 0; __dldwd_set_multicast_list(dev); @@ -1133,6 +1143,7 @@ show_rx_frame(&hdr); } else if ((status & HERMES_RXSTAT_ERR) == HERMES_RXSTAT_UNDECRYPTABLE) { + if (priv->sniffing) goto sniffing; wstats->discard.code++; printk(KERN_WARNING "%s: Undecryptable frame on Rx. Frame dropped.\n", dev->name); @@ -1144,7 +1155,7 @@ stats->rx_errors++; goto drop; } - +sniffing: length = le16_to_cpu(hdr.p80211.data_len); /* Yes, you heard right, that's le16. 802.2 and 802.3 are big-endian, but 802.11 is little-endian believe it or @@ -1162,6 +1173,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 @@ -1240,6 +1256,22 @@ return; + case 7: + if ( ! HERMES_RXSTATUS_ISFCSERR(status) ) { + /* Copy to wlansnif skb */ + dldwd_int_rxmonitor( priv, rxfid, &hdr); + } 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: if (skb) dev_kfree_skb_irq(skb); @@ -2817,6 +2849,180 @@ return 0; } +/*---------------------------------------------------------------- +* dldwd_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 +----------------------------------------------------------------*/ +int dldwd_wlansniff(struct net_device *wlandev, p80211msg_t *msgp) +{ + dldwd_priv_t *priv = (dldwd_priv_t *)wlandev->priv; + + hermes_t *hw = &(priv->hw); + hermes_response_t resp; + int result = 0; + p80211msg_lnxreq_wlansniff_t *msg = (p80211msg_lnxreq_wlansniff_t *) msgp; + uint16_t word; + + msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; + + switch (msg->enable.data) + { + case P80211ENUM_truth_false: + /* Confirm that we're in monitor mode */ + if ( !priv->sniffing ) { + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + result = 0; + } + /* Disable monitor mode */ + word = HERMES_CMD_MONITOR | (HERMES_MONITOR_DISABLE << 8); + result = hermes_docmd_wait(hw, word, 0, &resp); + + if ( result ) { + goto failed; + } + /* Disable port 0 */ + result = hermes_disable_port(hw, 0); + if ( result ) { + goto failed; + } + /* Clear the driver state */ + priv->sniffing = 0; + + /* 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 ) { + goto failed; + } +*/ + /* 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 ) { + goto failed; + } + /* Enable the port */ + result = hermes_enable_port(hw, 0); + if ( result ) { + goto failed; + } + } + + msg->resultcode.data = P80211ENUM_resultcode_success; + result = 0; + goto exit; + break; + case P80211ENUM_truth_true: + /* 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 ) { + goto failed; + } + /* Save the wepflags state */ + result = hermes_read_wordrec(hw, USER_BAP, + HERMES_RID_CNF_PRISM2_WEP_ON, + &(priv->presniff_wepflags)); + if ( result ) { + goto failed; + } + result = hermes_disable_port(hw, 0); + if ( result ) { + goto failed; + } + } + else { + priv->presniff_port_type = 0; + } + /* Set the channel we wish to sniff */ + word = msg->channel.data; + result = hermes_write_wordrec(hw, USER_BAP, + HERMES_RID_CNF_CHANNEL, word); + if ( result ) { + goto failed; + } + /* Set the port type to pIbss */ + word = HFA384x_PORTTYPE_IBSS; + result = hermes_write_wordrec(hw, USER_BAP, + HERMES_RID_CNF_PORTTYPE, word); + if ( result ) { + goto failed; + } + /* Set the wepflags for no decryption */ //Orinoco doesn't like this +/* + word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | + HFA384x_WEPFLAGS_DISABLE_RXCRYPT; + result = hermes_write_wordrec(hw, USER_BAP, + HERMES_RID_CNF_PRISM2_WEP_ON, word); //won't work with the bits above + if ( result ) { + goto failed; + } +*/ + /* Enable the port */ + result = hermes_enable_port(hw, 0); + if ( result ) { + goto failed; + } + /* Enable monitor mode */ + word = HERMES_CMD_MONITOR | (HERMES_MONITOR_ENABLE << 8); + result = hermes_docmd_wait(hw, word, 0, &resp); + if ( result ) { + goto failed; + } + /* Set the driver state */ + priv->sniffing = 1; + msg->resultcode.data = P80211ENUM_resultcode_success; + result = 0; + goto exit; + break; + default: + msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; + result = 0; + goto exit; + break; + } + +failed: + msg->resultcode.data = P80211ENUM_resultcode_refused; + result = 0; +exit: + return result; +} + +int doWlanIoctl(struct net_device *wlandev, p80211msg_t *msgp) { + int result = 0; +printk("%s: wlan generated ioctl: %02X\n", wlandev->name, msgp->msgcode); + switch (msgp->msgcode) { + case DIDmsg_lnxreq_wlansniff: + result = dldwd_wlansniff(wlandev, msgp); + break; + } + return result; +} + + int dldwd_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { @@ -3093,9 +3299,14 @@ dldwd_reset(priv); break; - case SIOCDEVPRIVATE + 0x1: /* card_reset */ + case SIOCDEVPRIVATE + 0x1: /* card_reset */ //also P80211_IFREQ DEBUG(1, "%s: SIOCDEVPRIVATE + 0x1 (card_reset)\n", dev->name); + if (((p80211ioctl_req_t*)rq)->magic == P80211_IOCTL_MAGIC) { + //this is a wlan generated ioctl + err = doWlanIoctl(dev, (p80211msg_t*)((p80211ioctl_req_t*)rq)->data); + break; + } if (! capable(CAP_NET_ADMIN)) { err = -EPERM; break; @@ -3185,6 +3396,10 @@ break; + case SIOCDEVPRIVATE + 0x8: /* set sniff (monitor) mode */ //DIDmsg_lnxreq_wlansniff : + err = dldwd_wlansniff(dev, (void*)(wrq->u.data.pointer));//msg); + break; + default: err = -EOPNOTSUPP; } @@ -3724,9 +3939,115 @@ netif_stop_queue(dev); + p80211indicate_init(); //setup netlink + return 0; } + +/*---------------------------------------------------------------- +* p80211ind_rx +* +* Called by netlink when a message comes down. We currently don't +* support message from userland via netlink, so this is a empty +* function. +* +* Arguments: +* sk netlink sock +* len msg len +* +* Returns: +* nothing +* +* Call context: +* Any +----------------------------------------------------------------*/ +void p80211ind_rx(struct sock *sk, int len) +{ + return; +} + + +/*---------------------------------------------------------------- +* p80211indicate_init +* +* Called during the p80211 startup to set up the netlink interfaces +* for sniffing and indication messages. +* +* Arguments: +* none +* +* Returns: +* nothing +* +* Call context: +* Any +----------------------------------------------------------------*/ +void p80211indicate_init(void) +{ + nl_indicate = + netlink_kernel_create( P80211_NL_SOCK_IND, &p80211ind_rx); + if ( nl_indicate == NULL ) { + printk("Failed to create indicate netlink i/f.\n"); + } + return; +} + + +/*---------------------------------------------------------------- +* p80211indicate_shutdown +* +* Called during the p80211 unload to get rid of our netlink +* interface. +* +* Arguments: +* none +* +* Returns: +* nothing +* +* Call context: +* Any +----------------------------------------------------------------*/ +void p80211indicate_shutdown(void) +{ + struct sock *nl; + nl = nl_indicate; + nl_indicate = NULL; + if ( nl != NULL && nl->socket != NULL) { + sock_release(nl->socket); + } + return; +} + + +/*---------------------------------------------------------------- +* p80211ind_sniff +* +* Called by the MSD to deliver a sniff type indication message. +* +* Arguments: +* wlandev WLAN device struct +* skb skb containing message to deliver +* +* Returns: +* nothing +* +* Call context: +* Any +----------------------------------------------------------------*/ +void p80211ind_sniff( dldwd_priv_t *wlandev, struct sk_buff *skb) +{ + if ( nl_indicate != NULL ) { + netlink_broadcast(nl_indicate, + skb, 0, P80211_NL_MCAST_GRP_SNIFF, GFP_ATOMIC); + } else { + printk("Can't send indicate msg, no netlink i/f\n"); + } + return; +} + + #ifdef ORINOCO_DEBUG EXPORT_SYMBOL(dldwd_debug); #endif @@ -3761,3 +4082,168 @@ module_init(init_dldwd); module_exit(exit_dldwd); + +/*---------------------------------------------------------------- +* dldwd_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: +* wlandev 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 p80211ind_sniff() +* Call context: +* interrupt +----------------------------------------------------------------*/ +void dldwd_int_rxmonitor( dldwd_priv_t *wlandev, uint16_t rxfid, struct dldwd_frame_hdr *rxdesc) +{ + hermes_t *hw = &(wlandev->hw); + uint32_t hdrlen = 0; + uint32_t datalen = 0; + uint32_t skblen = 0; + p80211msg_lnxind_wlansniffrm_t *msg; + 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(rxdesc->p80211.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 = rxdesc->p80211.data_len; + break; + case WLAN_FTYPE_MGMT: + hdrlen = WLAN_HDR_A3_LEN; + datalen = rxdesc->p80211.data_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 + WLAN_CRC_LEN; + /* 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 = alloc_skb(skblen, GFP_ATOMIC)) == NULL ) { + printk("alloc_skb failed trying to allocate %d bytes\n", skblen); + return; + } + 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, wlandev->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 = *((uint32_t*)&(rxdesc->desc.res1)); //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->desc.q_info & 0xFF; + + msg->noise.did = DIDmsg_lnxind_wlansniffrm_noise; + msg->noise.status = 0; + msg->noise.len = 4; + msg->noise.data = (rxdesc->desc.q_info >> 8) & 0xFF; + + msg->rate.did = DIDmsg_lnxind_wlansniffrm_rate; + msg->rate.status = 0; + msg->rate.len = 4; + msg->rate.data = rxdesc->desc.res3 / 5; /* rate?? 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 + WLAN_CRC_LEN; + + /* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */ + memcpy( datap, &(rxdesc->p80211.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); + } + + /* Set the CRC */ + memset( ((uint8_t *)(skb->data)) + skb->len - WLAN_CRC_LEN, 0xff, WLAN_CRC_LEN); + + /* Pass it up */ + p80211ind_sniff(wlandev, skb); + + return; +} + diff -aur pcmcia-cs-3.1.31/wireless/orinoco.h pcmcia-cs-3.1.31-devel/wireless/orinoco.h --- pcmcia-cs-3.1.31/wireless/orinoco.h Mon Feb 18 20:13:01 2002 +++ pcmcia-cs-3.1.31-devel/wireless/orinoco.h Tue Feb 19 17:06:47 2002 @@ -7,6 +7,8 @@ #ifndef _ORINOCO_H #define _ORINOCO_H +#include "hermes.h" + /* To enable debug messages */ //#define ORINOCO_DEBUG 3 @@ -41,6 +43,188 @@ /*====================================================================*/ +#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; + +//THESE constants reflect the wlan-ng 0.1.13 values +#define DIDmsg_lnxreq_wlansniff 0x0083 +#define DIDmsg_lnxreq_wlansniff_enable 0x1083 +#define DIDmsg_lnxreq_wlansniff_channel 0x2083 +#define DIDmsg_lnxreq_wlansniff_resultcode 0x3083 + +typedef struct p80211msg_lnxreq_wlansniff +{ + uint32_t msgcode __attribute__ ((packed)); + uint32_t msglen __attribute__ ((packed)); + uint8_t devname[WLAN_DEVNAMELEN_MAX] __attribute__ ((packed)); + p80211item_uint32_t enable __attribute__ ((packed)); + p80211item_uint32_t channel __attribute__ ((packed)); + p80211item_uint32_t resultcode __attribute__ ((packed)); +} __attribute__ ((packed)) p80211msg_lnxreq_wlansniff_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) + +/*----------------------------------------------------------------*/ +/* Netlink protocol numbers for the indication interface */ + +#define P80211_NL_SOCK_IND NETLINK_USERSOCK + +/*----------------------------------------------------------------*/ +/* Netlink multicast bits for different types of messages */ + +#define P80211_NL_MCAST_GRP_MLME 0x01 /* Local station messages */ +#define P80211_NL_MCAST_GRP_SNIFF 0x02 /* Sniffer messages */ +#define P80211_NL_MCAST_GRP_DIST 0x04 /* Distribution system messages */ + +/*====================================================================*/ + +/*================================================================*/ +/* 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; typedef struct dldwd_priv { void* card; /* Pointer to card dependant structure */ @@ -90,7 +274,10 @@ uint16_t pm_on, pm_mcast, pm_period, pm_timeout; uint16_t preamble; - int promiscuous, allmulti, mc_count; + uint16_t presniff_port_type; + uint16_t presniff_wepflags; + + int promiscuous, allmulti, mc_count, sniffing; #ifdef WIRELESS_SPY int spy_number; @@ -139,4 +326,15 @@ extern void dldwd_proc_dev_cleanup(dldwd_priv_t *priv); extern void dldwd_interrupt(int irq, void * dev_id, struct pt_regs *regs); +/*================================================================*/ +/* Function Declarations */ + +struct dldwd_frame_hdr; + +void p80211indicate_init(void); +void p80211indicate_shutdown(void); +void p80211ind_sniff( dldwd_priv_t *wlandev, struct sk_buff *skb); +void dldwd_int_rxmonitor( dldwd_priv_t *wlandev, uint16_t rxfid, struct dldwd_frame_hdr *rxdesc); + + #endif