diff -u -P linux-2.4.18_vanilla/drivers/net/wireless/hermes.h linux/drivers/net/wireless/hermes.h --- linux-2.4.18_vanilla/drivers/net/wireless/hermes.h Tue Feb 26 13:18:32 2002 +++ linux/drivers/net/wireless/hermes.h Tue Feb 26 15:31:39 2002 @@ -230,25 +230,23 @@ u16 RxDiscards_WEPExcluded; } __attribute__ ((packed)); +/* patch file by logan@sandsriver.com */ +/* modified by patrik@cqure.net */ /* Grabbed from wlan-ng - Thanks Mark... - Jean II * This is the result of a scan inquiry command */ /* Structure describing info about an Access Point */ struct hermes_scan_apinfo { u16 channel; /* Channel where the AP sits */ - u16 noise; /* Noise level */ - u16 level; /* Signal level */ + u16 level; /* Signal level */ + u16 noise; /* Noise level */ u8 bssid[ETH_ALEN]; /* MAC address of the Access Point */ - u16 beacon_interv; /* Beacon interval ? */ - u16 capabilities; /* Capabilities ? */ + u16 beacon_interv; /* Beacon Interval ? */ + u16 capabilities; /* Capabilities ? */ + u16 essidlen; /* ESSID length */ u8 essid[32]; /* ESSID of the network */ - u8 rates[10]; /* Bit rate supported */ - u16 proberesp_rate; /* ???? */ } __attribute__ ((packed)); /* Container */ struct hermes_scan_frame { - u16 rsvd; /* ??? */ - u16 scanreason; /* ??? */ - struct hermes_scan_apinfo aps[35]; /* Scan result */ + struct hermes_scan_apinfo aps[35]; /* Scan result */ } __attribute__ ((packed)); #ifdef __KERNEL__ diff -u -P linux-2.4.18_vanilla/drivers/net/wireless/orinoco.c linux/drivers/net/wireless/orinoco.c --- linux-2.4.18_vanilla/drivers/net/wireless/orinoco.c Tue Feb 26 13:00:44 2002 +++ linux/drivers/net/wireless/orinoco.c Tue Feb 26 15:31:39 2002 @@ -300,6 +300,8 @@ #include #include #include +#include +#include #include "hermes.h" #include "hermes_rid.h" @@ -420,6 +422,12 @@ u16 qual, signal, noise; } __attribute__ ((packed)) orinoco_commsqual_t; +/* sniffing stuff added by Patrik Karlsson, patrik@cqure.net 20020201 */ +/* Netlink interface(s) */ +static struct sock *nl_indicate = NULL; +#define APSTATUS_NL_SOCK_IND NETLINK_USERSOCK +#define APSTATUS_NL_MCAST_GRP_SNIFF 0x00000002 + /* * Function prototypes */ @@ -478,6 +486,9 @@ static int orinoco_proc_init(void); static void orinoco_proc_cleanup(void); +/* dummy functions */ +void p80211ind_rx(struct sock *sk, int len); + /* * Inline functions */ @@ -1238,6 +1249,40 @@ } switch (le16_to_cpu(info.type)) { + + /* + * do the actual scanning, 20020201 patrik@cqure.net + */ + case HERMES_INQ_SCAN: { + struct hermes_scan_frame scan; + struct sk_buff *skb; + int len = le16_to_cpu(info.len) - 1; + + /* len seems to be 25 even if its longer */ + if ( len >= 25 ) + len = sizeof(struct hermes_scan_apinfo); + + hermes_read_words(hw, HERMES_DATA1, (void *)&scan, len); + + if ( ( skb = alloc_skb(len, GFP_ATOMIC) ) == NULL ) { + DEBUG(2, "alloc_skb failed trying to allocate %d bytes\n", len); + return; + } + + skb_put(skb, len); + memcpy(skb->data, &scan, len); + + + /* create a netlink socket to listen to */ + nl_indicate = netlink_kernel_create( APSTATUS_NL_SOCK_IND, &p80211ind_rx); + + netlink_broadcast(nl_indicate, skb, 0, APSTATUS_NL_MCAST_GRP_SNIFF, + GFP_ATOMIC); + + sock_release(nl_indicate->socket); + + + } case HERMES_INQ_TALLIES: { struct hermes_tallies_frame tallies; struct iw_statistics *wstats = &priv->wstats; @@ -3811,6 +3856,16 @@ total, buf); } +/* + * Empty dummy function, theres nothing to see here + */ +static int +orinoco_proc_get_hermes_cmds(char *page, char **start, off_t requested_offset, + int requested_len, int *eof, void *data) +{ + return 0; +} + /* initialise the /proc subsystem for the hermes driver, creating the * separate entries */ static int @@ -3833,6 +3888,43 @@ return err; } +/* copy-paste linux-wlan-ng */ +/* userland data not supported */ +void p80211ind_rx(struct sock *sk, int len) +{ + return; +} + + +int +orinoco_send_scan_cmd(struct orinoco_private *priv) { + + hermes_inquire(&priv->hw, HERMES_INQ_SCAN); + + return 0; +} + +int +orinoco_proc_set_hermes_cmds(struct file *file, const char *buffer, + unsigned long count, void *context) +{ + char buf[256]; + + /* copy - paste code from elsewere in kernel */ + if (count > 250) + return -EPERM; + if (copy_from_user(buf, buffer, count)) + return -EFAULT; + + buf[count] = 0; + + if (!strncmp(buf, "apscan", 6)) { + orinoco_send_scan_cmd(context); + } + + return -EL3RST; +} + int orinoco_proc_dev_init(struct orinoco_private *priv) { @@ -3863,6 +3955,17 @@ goto fail; } + priv->dir_cmds = NULL; + priv->dir_cmds = create_proc_read_entry("cmds", S_IFREG | S_IRUGO, + priv->dir_dev, orinoco_proc_get_hermes_cmds, priv); + if (priv->dir_cmds == NULL) { + printk(KERN_ERR "Unable to initialise /proc/hermes/%s/cmds.\n", dev->name); + goto fail; + } + + priv->dir_cmds->write_proc = orinoco_proc_set_hermes_cmds; + + return 0; fail: orinoco_proc_dev_cleanup(priv); diff -u -P linux-2.4.18_vanilla/drivers/net/wireless/orinoco.h linux/drivers/net/wireless/orinoco.h --- linux-2.4.18_vanilla/drivers/net/wireless/orinoco.h Tue Feb 26 13:00:44 2002 +++ linux/drivers/net/wireless/orinoco.h Tue Feb 26 15:31:39 2002 @@ -89,6 +89,7 @@ struct proc_dir_entry *dir_dev; struct proc_dir_entry *dir_regs; struct proc_dir_entry *dir_recs; + struct proc_dir_entry *dir_cmds; }; /*====================================================================*/ diff -u -P linux-2.4.18_vanilla/drivers/net/wireless/orinoco_plx.c linux/drivers/net/wireless/orinoco_plx.c --- linux-2.4.18_vanilla/drivers/net/wireless/orinoco_plx.c Tue Feb 26 13:00:44 2002 +++ linux/drivers/net/wireless/orinoco_plx.c Tue Feb 26 15:31:39 2002 @@ -394,7 +394,7 @@ name:"orinoco_plx", id_table:orinoco_plx_pci_id_table, probe:orinoco_plx_init_one, - remove:__devexit_p(orinoco_plx_remove_one), + remove:orinoco_plx_remove_one, suspend:0, resume:0 };