aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorZhu Yi <yi.zhu@intel.com>2006-04-13 05:20:27 -0400
committerJohn W. Linville <linville@tuxdriver.com>2006-04-24 16:15:56 -0400
commitd685b8c226727bf5db907c7241f55461e7f1f008 (patch)
tree698e2194daef4c065ccbfd22802e7214caf6ea93 /drivers
parentc6c33a779dfe7aa8254be4da08c217914f1390a0 (diff)
[PATCH] ipw2200: Enable rtap interface for RF promiscuous mode while associated
With this patch, a new promiscuous mode is enabled. If the module is loaded with the rtap_iface=1 module parameter, two interfaces will be created (instead of just one). The second interface is prefixed 'rtap' and provides received 802.11 frames on the current channel to user space in a radiotap header format. Example usage: % modprobe ipw2200 rtap_iface=1 % iwconfig eth1 essid MyNetwork % dhcpcd eth1 % tcpdump -i rtap0 If you do not specify 'rtap_iface=1' then the rtap interface will not be created and you will need to turn it on via: % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface You can filter out what type of information is passed to user space via the rtap_filter sysfs entry. Currently you can tell the driver to transmit just the headers (which will provide the RADIOTAP and IEEE 802.11 header but not the payload), to filter based on frame control type (Management, Control, or Data), and whether to report transmitted frames, received frames, or both. The transmit frame reporting is based on a patch by Stefan Rompf. Filters can be get and set via a sysfs interface. For example, set the filter to only send headers (0x7), don't report Tx'd frames (0x10), and don't report data frames (0x100): % echo 0x117 > /sys/bus/pci/drivers/ipw2200/*/rtap_filter All your packets are belong to us: % tethereal -n -i rtap0 Signed-off-by: James Ketrenos <jketreno@linux.intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/Kconfig24
-rw-r--r--drivers/net/wireless/ipw2200.c599
-rw-r--r--drivers/net/wireless/ipw2200.h77
3 files changed, 673 insertions, 27 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index e0874cbfefea..c04971a8e4a8 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -263,6 +263,30 @@ config IPW2200_DEBUG
263 If you are not trying to debug or develop the IPW2200 driver, you 263 If you are not trying to debug or develop the IPW2200 driver, you
264 most likely want to say N here. 264 most likely want to say N here.
265 265
266config IPW2200_PROMISCUOUS
267 bool "Enable creation of a RF radiotap promiscuous interface."
268 depends on IPW2200
269 select IEEE80211_RADIOTAP
270 ---help---
271 Enables the creation of a second interface prefixed 'rtap'.
272 This second interface will provide every received in radiotap
273 format.
274
275 This is useful for performing wireless network analysis while
276 maintaining an active association.
277
278 Example usage:
279
280 % modprobe ipw2200 rtap_iface=1
281 % ifconfig rtap0 up
282 % tethereal -i rtap0
283
284 If you do not specify 'rtap_iface=1' as a module parameter then
285 the rtap interface will not be created and you will need to turn
286 it on via sysfs:
287
288 % echo 1 > /sys/bus/pci/drivers/ipw2200/*/rtap_iface
289
266config AIRO 290config AIRO
267 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" 291 tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
268 depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN) 292 depends on NET_RADIO && ISA_DMA_API && (PCI || BROKEN)
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 11730448a821..94172558cd03 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -65,6 +65,11 @@ static const char ipw_modes[] = {
65}; 65};
66static int antenna = CFG_SYS_ANTENNA_BOTH; 66static int antenna = CFG_SYS_ANTENNA_BOTH;
67 67
68#ifdef CONFIG_IPW2200_PROMISCUOUS
69static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */
70#endif
71
72
68#ifdef CONFIG_IPW_QOS 73#ifdef CONFIG_IPW_QOS
69static int qos_enable = 0; 74static int qos_enable = 0;
70static int qos_burst_enable = 0; 75static int qos_burst_enable = 0;
@@ -1272,6 +1277,105 @@ static ssize_t show_cmd_log(struct device *d,
1272 1277
1273static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL); 1278static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
1274 1279
1280#ifdef CONFIG_IPW2200_PROMISCUOUS
1281static void ipw_prom_free(struct ipw_priv *priv);
1282static int ipw_prom_alloc(struct ipw_priv *priv);
1283static ssize_t store_rtap_iface(struct device *d,
1284 struct device_attribute *attr,
1285 const char *buf, size_t count)
1286{
1287 struct ipw_priv *priv = dev_get_drvdata(d);
1288 int rc = 0;
1289
1290 if (count < 1)
1291 return -EINVAL;
1292
1293 switch (buf[0]) {
1294 case '0':
1295 if (!rtap_iface)
1296 return count;
1297
1298 if (netif_running(priv->prom_net_dev)) {
1299 IPW_WARNING("Interface is up. Cannot unregister.\n");
1300 return count;
1301 }
1302
1303 ipw_prom_free(priv);
1304 rtap_iface = 0;
1305 break;
1306
1307 case '1':
1308 if (rtap_iface)
1309 return count;
1310
1311 rc = ipw_prom_alloc(priv);
1312 if (!rc)
1313 rtap_iface = 1;
1314 break;
1315
1316 default:
1317 return -EINVAL;
1318 }
1319
1320 if (rc) {
1321 IPW_ERROR("Failed to register promiscuous network "
1322 "device (error %d).\n", rc);
1323 }
1324
1325 return count;
1326}
1327
1328static ssize_t show_rtap_iface(struct device *d,
1329 struct device_attribute *attr,
1330 char *buf)
1331{
1332 struct ipw_priv *priv = dev_get_drvdata(d);
1333 if (rtap_iface)
1334 return sprintf(buf, "%s", priv->prom_net_dev->name);
1335 else {
1336 buf[0] = '-';
1337 buf[1] = '1';
1338 buf[2] = '\0';
1339 return 3;
1340 }
1341}
1342
1343static DEVICE_ATTR(rtap_iface, S_IWUSR | S_IRUSR, show_rtap_iface,
1344 store_rtap_iface);
1345
1346static ssize_t store_rtap_filter(struct device *d,
1347 struct device_attribute *attr,
1348 const char *buf, size_t count)
1349{
1350 struct ipw_priv *priv = dev_get_drvdata(d);
1351
1352 if (!priv->prom_priv) {
1353 IPW_ERROR("Attempting to set filter without "
1354 "rtap_iface enabled.\n");
1355 return -EPERM;
1356 }
1357
1358 priv->prom_priv->filter = simple_strtol(buf, NULL, 0);
1359
1360 IPW_DEBUG_INFO("Setting rtap filter to " BIT_FMT16 "\n",
1361 BIT_ARG16(priv->prom_priv->filter));
1362
1363 return count;
1364}
1365
1366static ssize_t show_rtap_filter(struct device *d,
1367 struct device_attribute *attr,
1368 char *buf)
1369{
1370 struct ipw_priv *priv = dev_get_drvdata(d);
1371 return sprintf(buf, "0x%04X",
1372 priv->prom_priv ? priv->prom_priv->filter : 0);
1373}
1374
1375static DEVICE_ATTR(rtap_filter, S_IWUSR | S_IRUSR, show_rtap_filter,
1376 store_rtap_filter);
1377#endif
1378
1275static ssize_t show_scan_age(struct device *d, struct device_attribute *attr, 1379static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
1276 char *buf) 1380 char *buf)
1277{ 1381{
@@ -2028,16 +2132,11 @@ static int ipw_send_host_complete(struct ipw_priv *priv)
2028 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE); 2132 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);
2029} 2133}
2030 2134
2031static int ipw_send_system_config(struct ipw_priv *priv, 2135static int ipw_send_system_config(struct ipw_priv *priv)
2032 struct ipw_sys_config *config)
2033{ 2136{
2034 if (!priv || !config) { 2137 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG,
2035 IPW_ERROR("Invalid args\n"); 2138 sizeof(priv->sys_config),
2036 return -1; 2139 &priv->sys_config);
2037 }
2038
2039 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG, sizeof(*config),
2040 config);
2041} 2140}
2042 2141
2043static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len) 2142static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -3704,7 +3803,17 @@ static void ipw_bg_disassociate(void *data)
3704static void ipw_system_config(void *data) 3803static void ipw_system_config(void *data)
3705{ 3804{
3706 struct ipw_priv *priv = data; 3805 struct ipw_priv *priv = data;
3707 ipw_send_system_config(priv, &priv->sys_config); 3806
3807#ifdef CONFIG_IPW2200_PROMISCUOUS
3808 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
3809 priv->sys_config.accept_all_data_frames = 1;
3810 priv->sys_config.accept_non_directed_frames = 1;
3811 priv->sys_config.accept_all_mgmt_bcpr = 1;
3812 priv->sys_config.accept_all_mgmt_frames = 1;
3813 }
3814#endif
3815
3816 ipw_send_system_config(priv);
3708} 3817}
3709 3818
3710struct ipw_status_code { 3819struct ipw_status_code {
@@ -7138,7 +7247,7 @@ static int ipw_associate_network(struct ipw_priv *priv,
7138 else 7247 else
7139 priv->sys_config.answer_broadcast_ssid_probe = 0; 7248 priv->sys_config.answer_broadcast_ssid_probe = 0;
7140 7249
7141 err = ipw_send_system_config(priv, &priv->sys_config); 7250 err = ipw_send_system_config(priv);
7142 if (err) { 7251 if (err) {
7143 IPW_DEBUG_HC("Attempt to send sys config command failed.\n"); 7252 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
7144 return err; 7253 return err;
@@ -7454,15 +7563,7 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7454 /* Magic struct that slots into the radiotap header -- no reason 7563 /* Magic struct that slots into the radiotap header -- no reason
7455 * to build this manually element by element, we can write it much 7564 * to build this manually element by element, we can write it much
7456 * more efficiently than we can parse it. ORDER MATTERS HERE */ 7565 * more efficiently than we can parse it. ORDER MATTERS HERE */
7457 struct ipw_rt_hdr { 7566 struct ipw_rt_hdr *ipw_rt;
7458 struct ieee80211_radiotap_header rt_hdr;
7459 u8 rt_flags; /* radiotap packet flags */
7460 u8 rt_rate; /* rate in 500kb/s */
7461 u16 rt_channel; /* channel in mhz */
7462 u16 rt_chbitmask; /* channel bitfield */
7463 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
7464 u8 rt_antenna; /* antenna number */
7465 } *ipw_rt;
7466 7567
7467 short len = le16_to_cpu(pkt->u.frame.length); 7568 short len = le16_to_cpu(pkt->u.frame.length);
7468 7569
@@ -7516,9 +7617,11 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7516 /* Big bitfield of all the fields we provide in radiotap */ 7617 /* Big bitfield of all the fields we provide in radiotap */
7517 ipw_rt->rt_hdr.it_present = 7618 ipw_rt->rt_hdr.it_present =
7518 ((1 << IEEE80211_RADIOTAP_FLAGS) | 7619 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7620 (1 << IEEE80211_RADIOTAP_TSFT) |
7519 (1 << IEEE80211_RADIOTAP_RATE) | 7621 (1 << IEEE80211_RADIOTAP_RATE) |
7520 (1 << IEEE80211_RADIOTAP_CHANNEL) | 7622 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7521 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | 7623 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7624 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
7522 (1 << IEEE80211_RADIOTAP_ANTENNA)); 7625 (1 << IEEE80211_RADIOTAP_ANTENNA));
7523 7626
7524 /* Zero the flags, we'll add to them as we go */ 7627 /* Zero the flags, we'll add to them as we go */
@@ -7604,6 +7707,220 @@ static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
7604} 7707}
7605#endif 7708#endif
7606 7709
7710#ifdef CONFIG_IPW2200_PROMISCUOUS
7711#define ieee80211_is_probe_response(fc) \
7712 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && \
7713 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP )
7714
7715#define ieee80211_is_management(fc) \
7716 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)
7717
7718#define ieee80211_is_control(fc) \
7719 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)
7720
7721#define ieee80211_is_data(fc) \
7722 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
7723
7724#define ieee80211_is_assoc_request(fc) \
7725 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ)
7726
7727#define ieee80211_is_reassoc_request(fc) \
7728 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)
7729
7730static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,
7731 struct ipw_rx_mem_buffer *rxb,
7732 struct ieee80211_rx_stats *stats)
7733{
7734 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
7735 struct ipw_rx_frame *frame = &pkt->u.frame;
7736 struct ipw_rt_hdr *ipw_rt;
7737
7738 /* First cache any information we need before we overwrite
7739 * the information provided in the skb from the hardware */
7740 struct ieee80211_hdr *hdr;
7741 u16 channel = frame->received_channel;
7742 u8 phy_flags = frame->antennaAndPhy;
7743 s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;
7744 s8 noise = frame->noise;
7745 u8 rate = frame->rate;
7746 short len = le16_to_cpu(pkt->u.frame.length);
7747 u64 tsf = 0;
7748 struct sk_buff *skb;
7749 int hdr_only = 0;
7750 u16 filter = priv->prom_priv->filter;
7751
7752 /* If the filter is set to not include Rx frames then return */
7753 if (filter & IPW_PROM_NO_RX)
7754 return;
7755
7756 if (!noise)
7757 noise = priv->last_noise;
7758
7759 /* We received data from the HW, so stop the watchdog */
7760 priv->prom_net_dev->trans_start = jiffies;
7761
7762 if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
7763 priv->prom_priv->ieee->stats.rx_errors++;
7764 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
7765 return;
7766 }
7767
7768 /* We only process data packets if the interface is open */
7769 if (unlikely(!netif_running(priv->prom_net_dev))) {
7770 priv->prom_priv->ieee->stats.rx_dropped++;
7771 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
7772 return;
7773 }
7774
7775 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
7776 * that now */
7777 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
7778 /* FIXME: Should alloc bigger skb instead */
7779 priv->prom_priv->ieee->stats.rx_dropped++;
7780 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
7781 return;
7782 }
7783
7784 hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;
7785 if (ieee80211_is_management(hdr->frame_ctl)) {
7786 if (filter & IPW_PROM_NO_MGMT)
7787 return;
7788 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
7789 hdr_only = 1;
7790 } else if (ieee80211_is_control(hdr->frame_ctl)) {
7791 if (filter & IPW_PROM_NO_CTL)
7792 return;
7793 if (filter & IPW_PROM_CTL_HEADER_ONLY)
7794 hdr_only = 1;
7795 } else if (ieee80211_is_data(hdr->frame_ctl)) {
7796 if (filter & IPW_PROM_NO_DATA)
7797 return;
7798 if (filter & IPW_PROM_DATA_HEADER_ONLY)
7799 hdr_only = 1;
7800 }
7801
7802 /* Copy the SKB since this is for the promiscuous side */
7803 skb = skb_copy(rxb->skb, GFP_ATOMIC);
7804 if (skb == NULL) {
7805 IPW_ERROR("skb_clone failed for promiscuous copy.\n");
7806 return;
7807 }
7808
7809 /* copy the frame data to write after where the radiotap header goes */
7810 ipw_rt = (void *)skb->data;
7811
7812 if (hdr_only)
7813 len = ieee80211_get_hdrlen(hdr->frame_ctl);
7814
7815 memcpy(ipw_rt->payload, hdr, len);
7816
7817 /* Zero the radiotap static buffer ... We only need to zero the bytes
7818 * NOT part of our real header, saves a little time.
7819 *
7820 * No longer necessary since we fill in all our data. Purge before
7821 * merging patch officially.
7822 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
7823 * IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
7824 */
7825
7826 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
7827 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */
7828 ipw_rt->rt_hdr.it_len = sizeof(*ipw_rt); /* total header+data */
7829
7830 /* Set the size of the skb to the size of the frame */
7831 skb_put(skb, ipw_rt->rt_hdr.it_len + len);
7832
7833 /* Big bitfield of all the fields we provide in radiotap */
7834 ipw_rt->rt_hdr.it_present =
7835 ((1 << IEEE80211_RADIOTAP_FLAGS) |
7836 (1 << IEEE80211_RADIOTAP_TSFT) |
7837 (1 << IEEE80211_RADIOTAP_RATE) |
7838 (1 << IEEE80211_RADIOTAP_CHANNEL) |
7839 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
7840 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |
7841 (1 << IEEE80211_RADIOTAP_ANTENNA));
7842
7843 /* Zero the flags, we'll add to them as we go */
7844 ipw_rt->rt_flags = 0;
7845
7846 ipw_rt->rt_tsf = tsf;
7847
7848 /* Convert to DBM */
7849 ipw_rt->rt_dbmsignal = signal;
7850 ipw_rt->rt_dbmnoise = noise;
7851
7852 /* Convert the channel data and set the flags */
7853 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(channel));
7854 if (channel > 14) { /* 802.11a */
7855 ipw_rt->rt_chbitmask =
7856 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
7857 } else if (phy_flags & (1 << 5)) { /* 802.11b */
7858 ipw_rt->rt_chbitmask =
7859 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
7860 } else { /* 802.11g */
7861 ipw_rt->rt_chbitmask =
7862 (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
7863 }
7864
7865 /* set the rate in multiples of 500k/s */
7866 switch (rate) {
7867 case IPW_TX_RATE_1MB:
7868 ipw_rt->rt_rate = 2;
7869 break;
7870 case IPW_TX_RATE_2MB:
7871 ipw_rt->rt_rate = 4;
7872 break;
7873 case IPW_TX_RATE_5MB:
7874 ipw_rt->rt_rate = 10;
7875 break;
7876 case IPW_TX_RATE_6MB:
7877 ipw_rt->rt_rate = 12;
7878 break;
7879 case IPW_TX_RATE_9MB:
7880 ipw_rt->rt_rate = 18;
7881 break;
7882 case IPW_TX_RATE_11MB:
7883 ipw_rt->rt_rate = 22;
7884 break;
7885 case IPW_TX_RATE_12MB:
7886 ipw_rt->rt_rate = 24;
7887 break;
7888 case IPW_TX_RATE_18MB:
7889 ipw_rt->rt_rate = 36;
7890 break;
7891 case IPW_TX_RATE_24MB:
7892 ipw_rt->rt_rate = 48;
7893 break;
7894 case IPW_TX_RATE_36MB:
7895 ipw_rt->rt_rate = 72;
7896 break;
7897 case IPW_TX_RATE_48MB:
7898 ipw_rt->rt_rate = 96;
7899 break;
7900 case IPW_TX_RATE_54MB:
7901 ipw_rt->rt_rate = 108;
7902 break;
7903 default:
7904 ipw_rt->rt_rate = 0;
7905 break;
7906 }
7907
7908 /* antenna number */
7909 ipw_rt->rt_antenna = (phy_flags & 3);
7910
7911 /* set the preamble flag if we have it */
7912 if (phy_flags & (1 << 6))
7913 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
7914
7915 IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);
7916
7917 if (!ieee80211_rx(priv->prom_priv->ieee, skb, stats)) {
7918 priv->prom_priv->ieee->stats.rx_errors++;
7919 dev_kfree_skb_any(skb);
7920 }
7921}
7922#endif
7923
7607static int is_network_packet(struct ipw_priv *priv, 7924static int is_network_packet(struct ipw_priv *priv,
7608 struct ieee80211_hdr_4addr *header) 7925 struct ieee80211_hdr_4addr *header)
7609{ 7926{
@@ -7830,15 +8147,21 @@ static void ipw_rx(struct ipw_priv *priv)
7830 8147
7831 priv->rx_packets++; 8148 priv->rx_packets++;
7832 8149
8150#ifdef CONFIG_IPW2200_PROMISCUOUS
8151 if (priv->prom_net_dev && netif_running(priv->prom_net_dev))
8152 ipw_handle_promiscuous_rx(priv, rxb, &stats);
8153#endif
8154
7833#ifdef CONFIG_IPW2200_MONITOR 8155#ifdef CONFIG_IPW2200_MONITOR
7834 if (priv->ieee->iw_mode == IW_MODE_MONITOR) { 8156 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7835#ifdef CONFIG_IEEE80211_RADIOTAP 8157#ifdef CONFIG_IEEE80211_RADIOTAP
7836 ipw_handle_data_packet_monitor(priv, 8158
7837 rxb, 8159 ipw_handle_data_packet_monitor(priv,
7838 &stats); 8160 rxb,
8161 &stats);
7839#else 8162#else
7840 ipw_handle_data_packet(priv, rxb, 8163 ipw_handle_data_packet(priv, rxb,
7841 &stats); 8164 &stats);
7842#endif 8165#endif
7843 break; 8166 break;
7844 } 8167 }
@@ -9880,6 +10203,88 @@ static int ipw_net_is_queue_full(struct net_device *dev, int pri)
9880 return 0; 10203 return 0;
9881} 10204}
9882 10205
10206#ifdef CONFIG_IPW2200_PROMISCUOUS
10207static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,
10208 struct ieee80211_txb *txb)
10209{
10210 struct ieee80211_rx_stats dummystats;
10211 struct ieee80211_hdr *hdr;
10212 u8 n;
10213 u16 filter = priv->prom_priv->filter;
10214 int hdr_only = 0;
10215
10216 if (filter & IPW_PROM_NO_TX)
10217 return;
10218
10219 memset(&dummystats, 0, sizeof(dummystats));
10220
10221 /* Filtering of fragment chains is done agains the first fragment */
10222 hdr = (void *)txb->fragments[0]->data;
10223 if (ieee80211_is_management(hdr->frame_ctl)) {
10224 if (filter & IPW_PROM_NO_MGMT)
10225 return;
10226 if (filter & IPW_PROM_MGMT_HEADER_ONLY)
10227 hdr_only = 1;
10228 } else if (ieee80211_is_control(hdr->frame_ctl)) {
10229 if (filter & IPW_PROM_NO_CTL)
10230 return;
10231 if (filter & IPW_PROM_CTL_HEADER_ONLY)
10232 hdr_only = 1;
10233 } else if (ieee80211_is_data(hdr->frame_ctl)) {
10234 if (filter & IPW_PROM_NO_DATA)
10235 return;
10236 if (filter & IPW_PROM_DATA_HEADER_ONLY)
10237 hdr_only = 1;
10238 }
10239
10240 for(n=0; n<txb->nr_frags; ++n) {
10241 struct sk_buff *src = txb->fragments[n];
10242 struct sk_buff *dst;
10243 struct ieee80211_radiotap_header *rt_hdr;
10244 int len;
10245
10246 if (hdr_only) {
10247 hdr = (void *)src->data;
10248 len = ieee80211_get_hdrlen(hdr->frame_ctl);
10249 } else
10250 len = src->len;
10251
10252 dst = alloc_skb(
10253 len + IEEE80211_RADIOTAP_HDRLEN, GFP_ATOMIC);
10254 if (!dst) continue;
10255
10256 rt_hdr = (void *)skb_put(dst, sizeof(*rt_hdr));
10257
10258 rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
10259 rt_hdr->it_pad = 0;
10260 rt_hdr->it_present = 0; /* after all, it's just an idea */
10261 rt_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
10262
10263 *(u16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(
10264 ieee80211chan2mhz(priv->channel));
10265 if (priv->channel > 14) /* 802.11a */
10266 *(u16*)skb_put(dst, sizeof(u16)) =
10267 cpu_to_le16(IEEE80211_CHAN_OFDM |
10268 IEEE80211_CHAN_5GHZ);
10269 else if (priv->ieee->mode == IEEE_B) /* 802.11b */
10270 *(u16*)skb_put(dst, sizeof(u16)) =
10271 cpu_to_le16(IEEE80211_CHAN_CCK |
10272 IEEE80211_CHAN_2GHZ);
10273 else /* 802.11g */
10274 *(u16*)skb_put(dst, sizeof(u16)) =
10275 cpu_to_le16(IEEE80211_CHAN_OFDM |
10276 IEEE80211_CHAN_2GHZ);
10277
10278 rt_hdr->it_len = dst->len;
10279
10280 memcpy(skb_put(dst, len), src->data, len);
10281
10282 if (!ieee80211_rx(priv->prom_priv->ieee, dst, &dummystats))
10283 dev_kfree_skb_any(dst);
10284 }
10285}
10286#endif
10287
9883static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, 10288static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
9884 struct net_device *dev, int pri) 10289 struct net_device *dev, int pri)
9885{ 10290{
@@ -9897,6 +10302,11 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
9897 goto fail_unlock; 10302 goto fail_unlock;
9898 } 10303 }
9899 10304
10305#ifdef CONFIG_IPW2200_PROMISCUOUS
10306 if (rtap_iface && netif_running(priv->prom_net_dev))
10307 ipw_handle_promiscuous_tx(priv, txb);
10308#endif
10309
9900 ret = ipw_tx_skb(priv, txb, pri); 10310 ret = ipw_tx_skb(priv, txb, pri);
9901 if (ret == NETDEV_TX_OK) 10311 if (ret == NETDEV_TX_OK)
9902 __ipw_led_activity_on(priv); 10312 __ipw_led_activity_on(priv);
@@ -10344,12 +10754,21 @@ static int ipw_config(struct ipw_priv *priv)
10344 |= CFG_BT_COEXISTENCE_OOB; 10754 |= CFG_BT_COEXISTENCE_OOB;
10345 } 10755 }
10346 10756
10757#ifdef CONFIG_IPW2200_PROMISCUOUS
10758 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {
10759 priv->sys_config.accept_all_data_frames = 1;
10760 priv->sys_config.accept_non_directed_frames = 1;
10761 priv->sys_config.accept_all_mgmt_bcpr = 1;
10762 priv->sys_config.accept_all_mgmt_frames = 1;
10763 }
10764#endif
10765
10347 if (priv->ieee->iw_mode == IW_MODE_ADHOC) 10766 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
10348 priv->sys_config.answer_broadcast_ssid_probe = 1; 10767 priv->sys_config.answer_broadcast_ssid_probe = 1;
10349 else 10768 else
10350 priv->sys_config.answer_broadcast_ssid_probe = 0; 10769 priv->sys_config.answer_broadcast_ssid_probe = 0;
10351 10770
10352 if (ipw_send_system_config(priv, &priv->sys_config)) 10771 if (ipw_send_system_config(priv))
10353 goto error; 10772 goto error;
10354 10773
10355 init_supported_rates(priv, &priv->rates); 10774 init_supported_rates(priv, &priv->rates);
@@ -10887,6 +11306,10 @@ static struct attribute *ipw_sysfs_entries[] = {
10887 &dev_attr_led.attr, 11306 &dev_attr_led.attr,
10888 &dev_attr_speed_scan.attr, 11307 &dev_attr_speed_scan.attr,
10889 &dev_attr_net_stats.attr, 11308 &dev_attr_net_stats.attr,
11309#ifdef CONFIG_IPW2200_PROMISCUOUS
11310 &dev_attr_rtap_iface.attr,
11311 &dev_attr_rtap_filter.attr,
11312#endif
10890 NULL 11313 NULL
10891}; 11314};
10892 11315
@@ -10895,6 +11318,109 @@ static struct attribute_group ipw_attribute_group = {
10895 .attrs = ipw_sysfs_entries, 11318 .attrs = ipw_sysfs_entries,
10896}; 11319};
10897 11320
11321#ifdef CONFIG_IPW2200_PROMISCUOUS
11322static int ipw_prom_open(struct net_device *dev)
11323{
11324 struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
11325 struct ipw_priv *priv = prom_priv->priv;
11326
11327 IPW_DEBUG_INFO("prom dev->open\n");
11328 netif_carrier_off(dev);
11329 netif_stop_queue(dev);
11330
11331 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11332 priv->sys_config.accept_all_data_frames = 1;
11333 priv->sys_config.accept_non_directed_frames = 1;
11334 priv->sys_config.accept_all_mgmt_bcpr = 1;
11335 priv->sys_config.accept_all_mgmt_frames = 1;
11336
11337 ipw_send_system_config(priv);
11338 }
11339
11340 return 0;
11341}
11342
11343static int ipw_prom_stop(struct net_device *dev)
11344{
11345 struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
11346 struct ipw_priv *priv = prom_priv->priv;
11347
11348 IPW_DEBUG_INFO("prom dev->stop\n");
11349
11350 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
11351 priv->sys_config.accept_all_data_frames = 0;
11352 priv->sys_config.accept_non_directed_frames = 0;
11353 priv->sys_config.accept_all_mgmt_bcpr = 0;
11354 priv->sys_config.accept_all_mgmt_frames = 0;
11355
11356 ipw_send_system_config(priv);
11357 }
11358
11359 return 0;
11360}
11361
11362static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
11363{
11364 IPW_DEBUG_INFO("prom dev->xmit\n");
11365 netif_stop_queue(dev);
11366 return -EOPNOTSUPP;
11367}
11368
11369static struct net_device_stats *ipw_prom_get_stats(struct net_device *dev)
11370{
11371 struct ipw_prom_priv *prom_priv = ieee80211_priv(dev);
11372 return &prom_priv->ieee->stats;
11373}
11374
11375static int ipw_prom_alloc(struct ipw_priv *priv)
11376{
11377 int rc = 0;
11378
11379 if (priv->prom_net_dev)
11380 return -EPERM;
11381
11382 priv->prom_net_dev = alloc_ieee80211(sizeof(struct ipw_prom_priv));
11383 if (priv->prom_net_dev == NULL)
11384 return -ENOMEM;
11385
11386 priv->prom_priv = ieee80211_priv(priv->prom_net_dev);
11387 priv->prom_priv->ieee = netdev_priv(priv->prom_net_dev);
11388 priv->prom_priv->priv = priv;
11389
11390 strcpy(priv->prom_net_dev->name, "rtap%d");
11391
11392 priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
11393 priv->prom_net_dev->open = ipw_prom_open;
11394 priv->prom_net_dev->stop = ipw_prom_stop;
11395 priv->prom_net_dev->get_stats = ipw_prom_get_stats;
11396 priv->prom_net_dev->hard_start_xmit = ipw_prom_hard_start_xmit;
11397
11398 priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;
11399
11400 rc = register_netdev(priv->prom_net_dev);
11401 if (rc) {
11402 free_ieee80211(priv->prom_net_dev);
11403 priv->prom_net_dev = NULL;
11404 return rc;
11405 }
11406
11407 return 0;
11408}
11409
11410static void ipw_prom_free(struct ipw_priv *priv)
11411{
11412 if (!priv->prom_net_dev)
11413 return;
11414
11415 unregister_netdev(priv->prom_net_dev);
11416 free_ieee80211(priv->prom_net_dev);
11417
11418 priv->prom_net_dev = NULL;
11419}
11420
11421#endif
11422
11423
10898static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 11424static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
10899{ 11425{
10900 int err = 0; 11426 int err = 0;
@@ -11025,6 +11551,18 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
11025 goto out_remove_sysfs; 11551 goto out_remove_sysfs;
11026 } 11552 }
11027 11553
11554#ifdef CONFIG_IPW2200_PROMISCUOUS
11555 if (rtap_iface) {
11556 err = ipw_prom_alloc(priv);
11557 if (err) {
11558 IPW_ERROR("Failed to register promiscuous network "
11559 "device (error %d).\n", err);
11560 unregister_netdev(priv->net_dev);
11561 goto out_remove_sysfs;
11562 }
11563 }
11564#endif
11565
11028 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg " 11566 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "
11029 "channels, %d 802.11a channels)\n", 11567 "channels, %d 802.11a channels)\n",
11030 priv->ieee->geo.name, priv->ieee->geo.bg_channels, 11568 priv->ieee->geo.name, priv->ieee->geo.bg_channels,
@@ -11104,6 +11642,10 @@ static void ipw_pci_remove(struct pci_dev *pdev)
11104 priv->error = NULL; 11642 priv->error = NULL;
11105 } 11643 }
11106 11644
11645#ifdef CONFIG_IPW2200_PROMISCUOUS
11646 ipw_prom_free(priv);
11647#endif
11648
11107 free_irq(pdev->irq, priv); 11649 free_irq(pdev->irq, priv);
11108 iounmap(priv->hw_base); 11650 iounmap(priv->hw_base);
11109 pci_release_regions(pdev); 11651 pci_release_regions(pdev);
@@ -11228,6 +11770,11 @@ MODULE_PARM_DESC(debug, "debug output mask");
11228module_param(channel, int, 0444); 11770module_param(channel, int, 0444);
11229MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])"); 11771MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
11230 11772
11773#ifdef CONFIG_IPW2200_PROMISCUOUS
11774module_param(rtap_iface, int, 0444);
11775MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)");
11776#endif
11777
11231#ifdef CONFIG_IPW_QOS 11778#ifdef CONFIG_IPW_QOS
11232module_param(qos_enable, int, 0444); 11779module_param(qos_enable, int, 0444);
11233MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis"); 11780MODULE_PARM_DESC(qos_enable, "enable all QoS functionalitis");
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 1f2cab3f9944..14fe79abca67 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -789,7 +789,7 @@ struct ipw_sys_config {
789 u8 bt_coexist_collision_thr; 789 u8 bt_coexist_collision_thr;
790 u8 silence_threshold; 790 u8 silence_threshold;
791 u8 accept_all_mgmt_bcpr; 791 u8 accept_all_mgmt_bcpr;
792 u8 accept_all_mgtm_frames; 792 u8 accept_all_mgmt_frames;
793 u8 pass_noise_stats_to_host; 793 u8 pass_noise_stats_to_host;
794 u8 reserved3; 794 u8 reserved3;
795} __attribute__ ((packed)); 795} __attribute__ ((packed));
@@ -1122,6 +1122,52 @@ struct ipw_fw_error {
1122 u8 payload[0]; 1122 u8 payload[0];
1123} __attribute__ ((packed)); 1123} __attribute__ ((packed));
1124 1124
1125#ifdef CONFIG_IPW2200_PROMISCUOUS
1126
1127enum ipw_prom_filter {
1128 IPW_PROM_CTL_HEADER_ONLY = (1 << 0),
1129 IPW_PROM_MGMT_HEADER_ONLY = (1 << 1),
1130 IPW_PROM_DATA_HEADER_ONLY = (1 << 2),
1131 IPW_PROM_ALL_HEADER_ONLY = 0xf, /* bits 0..3 */
1132 IPW_PROM_NO_TX = (1 << 4),
1133 IPW_PROM_NO_RX = (1 << 5),
1134 IPW_PROM_NO_CTL = (1 << 6),
1135 IPW_PROM_NO_MGMT = (1 << 7),
1136 IPW_PROM_NO_DATA = (1 << 8),
1137};
1138
1139struct ipw_priv;
1140struct ipw_prom_priv {
1141 struct ipw_priv *priv;
1142 struct ieee80211_device *ieee;
1143 enum ipw_prom_filter filter;
1144 int tx_packets;
1145 int rx_packets;
1146};
1147#endif
1148
1149#if defined(CONFIG_IEEE80211_RADIOTAP) || defined(CONFIG_IPW2200_PROMISCUOUS)
1150/* Magic struct that slots into the radiotap header -- no reason
1151 * to build this manually element by element, we can write it much
1152 * more efficiently than we can parse it. ORDER MATTERS HERE
1153 *
1154 * When sent to us via the simulated Rx interface in sysfs, the entire
1155 * structure is provided regardless of any bits unset.
1156 */
1157struct ipw_rt_hdr {
1158 struct ieee80211_radiotap_header rt_hdr;
1159 u64 rt_tsf; /* TSF */
1160 u8 rt_flags; /* radiotap packet flags */
1161 u8 rt_rate; /* rate in 500kb/s */
1162 u16 rt_channel; /* channel in mhz */
1163 u16 rt_chbitmask; /* channel bitfield */
1164 s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
1165 s8 rt_dbmnoise;
1166 u8 rt_antenna; /* antenna number */
1167 u8 payload[0]; /* payload... */
1168} __attribute__ ((packed));
1169#endif
1170
1125struct ipw_priv { 1171struct ipw_priv {
1126 /* ieee device used by generic ieee processing code */ 1172 /* ieee device used by generic ieee processing code */
1127 struct ieee80211_device *ieee; 1173 struct ieee80211_device *ieee;
@@ -1133,6 +1179,12 @@ struct ipw_priv {
1133 struct pci_dev *pci_dev; 1179 struct pci_dev *pci_dev;
1134 struct net_device *net_dev; 1180 struct net_device *net_dev;
1135 1181
1182#ifdef CONFIG_IPW2200_PROMISCUOUS
1183 /* Promiscuous mode */
1184 struct ipw_prom_priv *prom_priv;
1185 struct net_device *prom_net_dev;
1186#endif
1187
1136 /* pci hardware address support */ 1188 /* pci hardware address support */
1137 void __iomem *hw_base; 1189 void __iomem *hw_base;
1138 unsigned long hw_len; 1190 unsigned long hw_len;
@@ -1306,6 +1358,29 @@ struct ipw_priv {
1306 1358
1307/* debug macros */ 1359/* debug macros */
1308 1360
1361/* Debug and printf string expansion helpers for printing bitfields */
1362#define BIT_FMT8 "%c%c%c%c-%c%c%c%c"
1363#define BIT_FMT16 BIT_FMT8 ":" BIT_FMT8
1364#define BIT_FMT32 BIT_FMT16 " " BIT_FMT16
1365
1366#define BITC(x,y) (((x>>y)&1)?'1':'0')
1367#define BIT_ARG8(x) \
1368BITC(x,7),BITC(x,6),BITC(x,5),BITC(x,4),\
1369BITC(x,3),BITC(x,2),BITC(x,1),BITC(x,0)
1370
1371#define BIT_ARG16(x) \
1372BITC(x,15),BITC(x,14),BITC(x,13),BITC(x,12),\
1373BITC(x,11),BITC(x,10),BITC(x,9),BITC(x,8),\
1374BIT_ARG8(x)
1375
1376#define BIT_ARG32(x) \
1377BITC(x,31),BITC(x,30),BITC(x,29),BITC(x,28),\
1378BITC(x,27),BITC(x,26),BITC(x,25),BITC(x,24),\
1379BITC(x,23),BITC(x,22),BITC(x,21),BITC(x,20),\
1380BITC(x,19),BITC(x,18),BITC(x,17),BITC(x,16),\
1381BIT_ARG16(x)
1382
1383
1309#ifdef CONFIG_IPW2200_DEBUG 1384#ifdef CONFIG_IPW2200_DEBUG
1310#define IPW_DEBUG(level, fmt, args...) \ 1385#define IPW_DEBUG(level, fmt, args...) \
1311do { if (ipw_debug_level & (level)) \ 1386do { if (ipw_debug_level & (level)) \