|
Subject: [PATCH] live monitoring Newsgroups: gmane.linux.drivers.madwifi.devel Date: 2004-09-03 07:40:07 GMT (4 years, 43 weeks, 4 days and 14 hours ago)
Greetings!
Attached is a small patch which adds a "live monitoring" facility
to the madwifi driver. The patch is against the CVS trunk as of
Fri Sep 3 5:48 GMT.
With this patch, you can sniff 802.11 frames with prism2 header
without putting the interface in monitor mode. This is achieved by
creating an auxiliary device ath0mon which always has the type
ARPHRD_IEEE80211_PRISM. Then the ath0mon device is UP, ath_rx_tasklet
copies all packets received by the card to this device.
The patch also adds ability to control packet filter via sysctl
interface, so you can adjust what kind of packets you see. Of course,
you must be careful not to reset filter bits which are essential for
the current mode of operation.
Usage:
# ifup ath0
# ifconfig ath0mon up
# cat /proc/sys/dev/ath0/rxfilt
# grep HAL_RX_FILTER_ /usr/src/madwifi/hal/ah.h
# echo 0x2ff > /proc/sys/dev/ath0/rxfilt
# tethereal -lni ath0mon
Note: only received packets are shown. Packets transmitted by the
card do not appear in the dump.
I am not an expert in network driver hacking, so please take a look at
the code before applying the patch.
Thanks,
-- sizif
Index: ath/if_ath.c
===================================================================
RCS file: /cvsroot/madwifi/madwifi/ath/if_ath.c,v
retrieving revision 1.5
diff -u -u -r1.5 if_ath.c
--- ath/if_ath.c 20 Aug 2004 21:28:46 -0000 1.5
+++ ath/if_ath.c 3 Sep 2004 07:18:46 -0000
@@ -2389,7 +2389,6 @@
skb->protocol = ETH_P_CONTROL;
skb->pkt_type = PACKET_OTHERHOST;
- skb_put(skb, len);
/* Check to see if we need to remove pad bytes */
if (ic->ic_flags & IEEE80211_F_DATAPAD) {
@@ -2629,6 +2628,7 @@
bus_unmap_single(sc->sc_bdev, bf->bf_skbaddr,
sc->sc_rxbufsize, BUS_DMA_FROMDEVICE);
bf->bf_skb = NULL;
+ skb_put(skb, len);
if (sc->sc_softled)
ath_update_led(sc);
@@ -2651,6 +2651,16 @@
goto rx_next;
}
+ if (sc->sc_mondev.flags & IFF_UP) {
+ struct sk_buff *skb2;
+ skb2 = skb_copy_expand(skb,
+ skb_headroom(skb) +
+ sizeof(wlan_ng_prism2_header),
+ skb_tailroom(skb),
+ GFP_ATOMIC);
+ ath_rx_capture(&sc->sc_mondev, ds, skb2);
+ }
+
/*
* From this point on we assume the frame is at least
* as large as ieee80211_frame_min; verify that.
@@ -2666,7 +2676,6 @@
/*
* Normal receive.
*/
- skb_put(skb, len);
skb->protocol = ETH_P_CONTROL; /* XXX */
if (IFF_DUMPPKTS(ic, ATH_DEBUG_RECV)) {
@@ -4634,6 +4643,7 @@
ATH_CTSTIMEOUT = 3,
ATH_SOFTLED = 4,
ATH_LEDPIN = 5,
+ ATH_RXFILT = 6,
};
static int
@@ -4675,6 +4685,9 @@
case ATH_LEDPIN:
sc->sc_ledpin = val;
break;
+ case ATH_RXFILT:
+ ath_hal_setrxfilter(sc->sc_ah, val);
+ break;
default:
return -EINVAL;
}
@@ -4696,6 +4709,9 @@
case ATH_LEDPIN:
val = sc->sc_ledpin;
break;
+ case ATH_RXFILT:
+ val = ath_hal_getrxfilter (sc->sc_ah);
+ break;
default:
return -EINVAL;
}
@@ -4739,6 +4755,11 @@
.mode = 0644,
.proc_handler = ath_sysctl_halparam
},
+ { .ctl_name = ATH_RXFILT,
+ .procname = "rxfilt",
+ .mode = 0644,
+ .proc_handler = ath_sysctl_halparam
+ },
{ 0 }
};
Index: ath/if_ath_pci.c
===================================================================
RCS file: /cvsroot/madwifi/madwifi/ath/if_ath_pci.c,v
retrieving revision 1.3
diff -u -u -r1.3 if_ath_pci.c
--- ath/if_ath_pci.c 20 Aug 2004 21:28:46 -0000 1.3
+++ ath/if_ath_pci.c 3 Sep 2004 07:18:46 -0000
@@ -49,6 +49,7 @@
#include <linux/if.h>
#include <linux/netdevice.h>
#include <linux/cache.h>
+#include <linux/if_arp.h>
#include <linux/pci.h>
@@ -89,6 +90,46 @@
{ 0 }
};
+static void
+athmon_stop (struct net_device *mondev)
+{
+ struct ath_softc *sc = mondev->priv;
+ struct net_device *dev = &sc->sc_dev;
+
+ /* restore rx filter as approptiate for current operation mode,
+ in case the user changed it with /proc/sys/dev/athX/rxfilt. */
+ dev->set_multicast_list(dev);
+}
+
+/* blackhole any outgoing traffic on ath0mon device (none expected) */
+
+static int
+athmon_hard_start_xmit(struct sk_buff *skb, struct net_device *mondev)
+{
+ dev_kfree_skb(skb);
+ return 0;
+}
+
+/* Monitoring device doesn't keep any statistics for now, but simply
+ not implementing get_stats method is not good as it breaks format
+ of /proc/net/dev. So return zero statistics (sc_mondevstats is
+ zeroed along with whole ath_softc upon initialization). */
+
+static struct net_device_stats *
+athmon_get_stats(struct net_device *dev)
+{
+ struct ath_softc *sc = dev->priv;
+ return &sc->sc_mondevstats;
+}
+
+/* not sure if we really need it. Mimic drivers/net/dummy.c */
+
+static void
+athmon_set_multicast_list(struct net_device *mondev)
+{
+}
+
+
static int
ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
@@ -96,6 +137,7 @@
unsigned long mem;
struct ath_pci_softc *sc;
struct net_device *dev;
+ struct net_device *mondev;
const char *athname;
u_int8_t csz;
u32 val;
@@ -196,10 +238,37 @@
printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
dev->name, athname ? athname : "Atheros ???", phymem, dev->irq);
+ /*
+ * Create additional device ath0mon for live monitoring.
+ * When ath0mon is UP, all packets received by ath0 are copied
+ * to ath0mon for sniffers' pleasure, with prism2 header.
+ */
+
+ mondev = &sc->aps_sc.sc_mondev;
+ strcpy(mondev->name, dev->name);
+ strcat(mondev->name, "mon");
+ mondev->priv = sc;
+ ether_setup(mondev);
+ mondev->stop = athmon_stop;
+ mondev->hard_start_xmit = athmon_hard_start_xmit;
+ mondev->set_multicast_list = athmon_set_multicast_list;
+ mondev->get_stats = athmon_get_stats;
+ mondev->type = ARPHRD_IEEE80211_PRISM;
+ mondev->tx_queue_len = 0;
+ mondev->flags |= IFF_NOARP;
+ mondev->flags &= ~IFF_MULTICAST;
+
+ if (register_netdev(mondev)) {
+ printk(KERN_ERR "%s: unable to register device\n", mondev->name);
+ goto bad5;
+ }
+
/* ready to process interrupts */
sc->aps_sc.sc_invalid = 0;
return 0;
+bad5:
+ ath_detach(dev);
bad4:
free_irq(dev->irq, dev);
bad3:
@@ -217,8 +286,10 @@
ath_pci_remove(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
+ struct ath_softc *sc = dev->priv;
ath_detach(dev);
+ unregister_netdev(&sc->sc_mondev);
if (dev->irq)
free_irq(dev->irq, dev);
iounmap((void *) dev->mem_start);
Index: ath/if_athvar.h
===================================================================
RCS file: /cvsroot/madwifi/madwifi/ath/if_athvar.h,v
retrieving revision 1.4
diff -u -u -r1.4 if_athvar.h
--- ath/if_athvar.h 20 Aug 2004 21:28:46 -0000 1.4
+++ ath/if_athvar.h 3 Sep 2004 07:18:46 -0000
@@ -190,8 +190,10 @@
struct ath_softc {
struct net_device sc_dev; /* NB: must be first */
+ struct net_device sc_mondev; /* parallel monitoring device */
struct semaphore sc_lock; /* dev-level lock */
struct net_device_stats sc_devstats; /* device statistics */
+ struct net_device_stats sc_mondevstats; /* mon device statistics */
struct ath_stats sc_stats; /* private statistics */
struct ieee80211com sc_ic; /* IEEE 802.11 common */
int (*sc_newstate)(struct ieee80211com *,
-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=5047&alloc_id=10808&op=click
|
|
|