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 <linux/delay.h>
 #include <linux/if_ether.h>
 
+#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 <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
-#include <linux/wireless.h>
 #include <linux/list.h>
+#include <linux/netlink.h>
+#undef min
+#undef max
+#include <net/sock.h>
+#include <linux/wireless.h>
 
 #include <pcmcia/version.h>
 #include <pcmcia/cs_types.h>
@@ -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
