|
# --- ROCK-COPYRIGHT-NOTE-BEGIN ---
|
|
#
|
|
# This copyright note is auto-generated by ./scripts/Create-CopyPatch.
|
|
# Please add additional copyright information _after_ the line containing
|
|
# the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
|
|
# the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
|
|
#
|
|
# ROCK Linux: rock-src/package/powerpc/linux24benh/port-orinoco-monitor-0.13e.patch
|
|
# ROCK Linux is Copyright (C) 1998 - 2004 Clifford Wolf
|
|
#
|
|
# This patch file is dual-licensed. It is available under the license the
|
|
# patched project is licensed under, as long as it is an OpenSource license
|
|
# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms
|
|
# of the GNU General Public License as published by the Free Software
|
|
# Foundation; either version 2 of the License, or (at your option) any later
|
|
# version.
|
|
#
|
|
# --- ROCK-COPYRIGHT-NOTE-END ---
|
|
|
|
--- orinoco-0.13e/drivers/net/wireless/hermes.c 2003-05-11 23:22:27.000000000 -0700
|
|
+++ orinoco-0.13e-patched/drivers/net/wireless/hermes.c 2003-08-07 04:16:04.000000000 -0700
|
|
@@ -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 -aur orinoco-0.13e/hermes.h orinoco-0.13e-patched/hermes.h
|
|
--- orinoco-0.13e/drivers/net/wireless/hermes.h 2003-05-11 23:22:27.000000000 -0700
|
|
+++ orinoco-0.13e-patched/drivers/net/wireless/hermes.h 2003-08-07 04:16:04.000000000 -0700
|
|
@@ -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
|
|
*/
|
|
@@ -149,6 +153,38 @@
|
|
#define HERMES_MONITOR_DISABLE (0x000f)
|
|
|
|
/*
|
|
+ * 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
|
|
*/
|
|
|
|
@@ -286,6 +322,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];
|
|
@@ -339,12 +376,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 -aur orinoco-0.13e/orinoco.c orinoco-0.13e-patched/orinoco.c
|
|
--- orinoco-0.13e/drivers/net/wireless/orinoco.c 2003-05-11 23:22:27.000000000 -0700
|
|
+++ orinoco-0.13e-patched/drivers/net/wireless/orinoco.c 2003-08-07 04:16:04.000000000 -0700
|
|
@@ -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,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);
|
|
@@ -1699,7 +1701,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 */
|
|
|
|
@@ -1730,6 +1732,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
|
|
@@ -1804,6 +1811,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++;
|
|
|
|
@@ -2446,6 +2473,24 @@
|
|
return err;
|
|
}
|
|
|
|
+//#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)
|
|
{
|
|
@@ -3598,6 +3643,173 @@
|
|
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);
|
|
+ hermes_response_t resp;
|
|
+ int result = 0;
|
|
+ uint16_t word;
|
|
+
|
|
+ int *parms = (int *) wrq->u.name;
|
|
+ int enable = parms[0] > 0;
|
|
+ unsigned long flags;
|
|
+
|
|
+ orinoco_lock(priv, &flags);
|
|
+
|
|
+ switch (enable)
|
|
+ {
|
|
+ case P80211ENUM_truth_false:
|
|
+ /* Confirm that we're in monitor mode */
|
|
+ if ( dev->type == ARPHRD_ETHER ) {
|
|
+ result = -EFAULT;
|
|
+ }
|
|
+ /* Disable monitor mode */
|
|
+ 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:
|
|
+ /* 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);
|
|
+/*
|
|
+ __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;
|
|
+ result = hermes_disable_port(hw, 0);
|
|
+ if ( result ) break;
|
|
+ }
|
|
+ else {
|
|
+ priv->presniff_port_type = 0;
|
|
+ }
|
|
+
|
|
+ /* 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;
|
|
+
|
|
+ /* 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;
|
|
+
|
|
+/*
|
|
+ if ( (msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) &&
|
|
+ (msg->keepwepflags.data != P80211ENUM_truth_true)) {
|
|
+ // 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 ) break;
|
|
+
|
|
+*/
|
|
+ /* Enable the port */
|
|
+ result = hermes_enable_port(hw, 0);
|
|
+ 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;
|
|
+
|
|
+ /* 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)
|
|
{
|
|
@@ -3830,6 +4042,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 +4139,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)
|
|
@@ -4146,6 +4371,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;
|
|
@@ -4171,6 +4399,197 @@
|
|
|
|
}
|
|
|
|
+/*----------------------------------------------------------------
|
|
+* 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 */
|
|
/********************************************************************/
|
|
diff -aur orinoco-0.13e/orinoco.h orinoco-0.13e-patched/orinoco.h
|
|
--- orinoco-0.13e/drivers/net/wireless/orinoco.h 2003-05-11 23:22:27.000000000 -0700
|
|
+++ orinoco-0.13e-patched/drivers/net/wireless/orinoco.h 2003-08-07 04:16:04.000000000 -0700
|
|
@@ -37,6 +37,20 @@
|
|
/* 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
|
|
+
|
|
#if (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10)
|
|
#error "orinoco driver requires Wireless extensions v10 or later."
|
|
#endif /* (! defined (WIRELESS_EXT)) || (WIRELESS_EXT < 10) */
|
|
@@ -54,6 +68,158 @@
|
|
HERMES_EV_TXEXC | HERMES_EV_WTERR | HERMES_EV_INFO | \
|
|
HERMES_EV_INFDROP )
|
|
|
|
+#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 */
|
|
@@ -116,6 +282,9 @@
|
|
/* Configuration dependent variables */
|
|
int port_type, createibss;
|
|
int promiscuous, mc_count;
|
|
+
|
|
+ uint16_t presniff_port_type;
|
|
+ uint16_t presniff_wepflags;
|
|
};
|
|
|
|
#ifdef ORINOCO_DEBUG
|
|
@@ -163,4 +332,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 */
|