From: Pavel Roskin <proski@gnu.org>
To: linux-wireless@vger.kernel.org,
John W Linville <linville@tuxdriver.com>, Jouni Malinen <j@w1.fi>
Subject: [PATCH 5/5] hostap: add radiotap support, always use it in monitor mode
Date: Thu, 22 May 2008 21:55:05 -0400 [thread overview]
Message-ID: <20080523015505.16636.58672.stgit@dv.roinet.com> (raw)
In-Reply-To: <20080523015442.16636.92254.stgit@dv.roinet.com>
Provide MAC time, rate, channel, signal and noise. Remove
"monitor_type" and "getmonitor_type" ioctl. Never add bogus CRC at the
end, as radiotap aware software would never need it.
Keep support for "no header" for the master and AP devices. Simplify
hostap_80211_header_parse(), as it's never used on interfaces in monitor
mode.
Signed-off-by: Pavel Roskin <proski@gnu.org>
---
drivers/net/wireless/hostap/hostap_80211_rx.c | 126 ++++++++-----------------
drivers/net/wireless/hostap/hostap_common.h | 2
drivers/net/wireless/hostap/hostap_ioctl.c | 27 -----
drivers/net/wireless/hostap/hostap_main.c | 21 +---
drivers/net/wireless/hostap/hostap_wlan.h | 44 ++-------
5 files changed, 53 insertions(+), 167 deletions(-)
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 47884c3..832579f 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -54,35 +54,22 @@ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
}
-/* Send RX frame to netif with 802.11 (and possible prism) header.
+/* Send RX frame to netif with 802.11 and possibly radiotap header.
* Called from hardware or software IRQ context. */
int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats, int type)
{
struct hostap_interface *iface;
local_info_t *local;
- int hdrlen, phdrlen, head_need, tail_need;
+ int hdrlen, rt_hdrlen;
u16 fc;
- int prism_header, ret;
+ int ret;
struct ieee80211_hdr_4addr *hdr;
iface = netdev_priv(dev);
local = iface->local;
dev->last_rx = jiffies;
- if (dev->type == ARPHRD_IEEE80211_PRISM) {
- if (local->monitor_type == PRISM2_MONITOR_PRISM) {
- prism_header = 1;
- phdrlen = sizeof(struct linux_wlan_ng_prism_hdr);
- } else { /* local->monitor_type == PRISM2_MONITOR_CAPHDR */
- prism_header = 2;
- phdrlen = sizeof(struct linux_wlan_ng_cap_hdr);
- }
- } else {
- prism_header = 0;
- phdrlen = 0;
- }
-
hdr = (struct ieee80211_hdr_4addr *) skb->data;
fc = le16_to_cpu(hdr->frame_ctl);
@@ -95,84 +82,47 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb,
hdrlen = hostap_80211_get_hdrlen(fc);
- /* check if there is enough room for extra data; if not, expand skb
- * buffer to be large enough for the changes */
- head_need = phdrlen;
- tail_need = 0;
-#ifdef PRISM2_ADD_BOGUS_CRC
- tail_need += 4;
-#endif /* PRISM2_ADD_BOGUS_CRC */
-
- head_need -= skb_headroom(skb);
- tail_need -= skb_tailroom(skb);
-
- if (head_need > 0 || tail_need > 0) {
- if (pskb_expand_head(skb, head_need > 0 ? head_need : 0,
- tail_need > 0 ? tail_need : 0,
- GFP_ATOMIC)) {
- printk(KERN_DEBUG "%s: prism2_rx_80211 failed to "
- "reallocate skb buffer\n", dev->name);
- dev_kfree_skb_any(skb);
- return 0;
+ if (dev->type == ARPHRD_IEEE80211_RADIOTAP) {
+ int head_need;
+ struct hostap_radiotap_rx *rt_hdr;
+
+ /* if needed, expand skb buffer to accomodate radiotap header */
+ rt_hdrlen = sizeof(struct hostap_radiotap_rx);
+ head_need = rt_hdrlen - skb_headroom(skb);
+
+ if (head_need > 0) {
+ if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) {
+ printk(KERN_DEBUG "%s: prism2_rx_80211 failed "
+ "to reallocate skb buffer\n", dev->name);
+ dev_kfree_skb_any(skb);
+ return 0;
+ }
}
- }
- /* We now have an skb with enough head and tail room, so just insert
- * the extra data */
-
-#ifdef PRISM2_ADD_BOGUS_CRC
- memset(skb_put(skb, 4), 0xff, 4); /* Prism2 strips CRC */
-#endif /* PRISM2_ADD_BOGUS_CRC */
-
- if (prism_header == 1) {
- struct linux_wlan_ng_prism_hdr *hdr;
- hdr = (struct linux_wlan_ng_prism_hdr *)
- skb_push(skb, phdrlen);
- memset(hdr, 0, phdrlen);
- hdr->msgcode = LWNG_CAP_DID_BASE;
- hdr->msglen = sizeof(*hdr);
- memcpy(hdr->devname, dev->name, sizeof(hdr->devname));
-#define LWNG_SETVAL(f,i,s,l,d) \
-hdr->f.did = LWNG_CAP_DID_BASE | (i << 12); \
-hdr->f.status = s; hdr->f.len = l; hdr->f.data = d
- LWNG_SETVAL(hosttime, 1, 0, 4, jiffies);
- LWNG_SETVAL(mactime, 2, 0, 4, rx_stats->mac_time);
- LWNG_SETVAL(channel, 3, 1 /* no value */, 4, 0);
- LWNG_SETVAL(rssi, 4, 1 /* no value */, 4, 0);
- LWNG_SETVAL(sq, 5, 1 /* no value */, 4, 0);
- LWNG_SETVAL(signal, 6, 0, 4, rx_stats->signal);
- LWNG_SETVAL(noise, 7, 0, 4, rx_stats->noise);
- LWNG_SETVAL(rate, 8, 0, 4, rx_stats->rate / 5);
- LWNG_SETVAL(istx, 9, 0, 4, 0);
- LWNG_SETVAL(frmlen, 10, 0, 4, skb->len - phdrlen);
-#undef LWNG_SETVAL
- } else if (prism_header == 2) {
- struct linux_wlan_ng_cap_hdr *hdr;
- hdr = (struct linux_wlan_ng_cap_hdr *)
- skb_push(skb, phdrlen);
- memset(hdr, 0, phdrlen);
- hdr->version = htonl(LWNG_CAPHDR_VERSION);
- hdr->length = htonl(phdrlen);
- hdr->mactime = __cpu_to_be64(rx_stats->mac_time);
- hdr->hosttime = __cpu_to_be64(jiffies);
- hdr->phytype = htonl(4); /* dss_dot11_b */
- hdr->channel = htonl(local->channel);
- hdr->datarate = htonl(rx_stats->rate);
- hdr->antenna = htonl(0); /* unknown */
- hdr->priority = htonl(0); /* unknown */
- hdr->ssi_type = htonl(3); /* raw */
- hdr->ssi_signal = htonl(rx_stats->signal);
- hdr->ssi_noise = htonl(rx_stats->noise);
- hdr->preamble = htonl(0); /* unknown */
- hdr->encoding = htonl(1); /* cck */
+ rt_hdr = (struct hostap_radiotap_rx *)skb_push(skb, rt_hdrlen);
+ memset(rt_hdr, 0, rt_hdrlen);
+ rt_hdr->hdr.it_len = cpu_to_le16(rt_hdrlen);
+ rt_hdr->hdr.it_present =
+ cpu_to_le32((1 << IEEE80211_RADIOTAP_TSFT) |
+ (1 << IEEE80211_RADIOTAP_CHANNEL) |
+ (1 << IEEE80211_RADIOTAP_RATE) |
+ (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+ (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE));
+ rt_hdr->tsft = cpu_to_le64(rx_stats->mac_time);
+ rt_hdr->chan_freq = cpu_to_le16(freq_list[local->channel - 1]);
+ rt_hdr->chan_flags = cpu_to_le16(IEEE80211_CHAN_CCK |
+ IEEE80211_CHAN_2GHZ);
+ rt_hdr->rate = rx_stats->rate / 5;
+ rt_hdr->dbm_antsignal = rx_stats->signal;
+ rt_hdr->dbm_antnoise = rx_stats->noise;
+ } else {
+ rt_hdrlen = 0;
}
- ret = skb->len - phdrlen;
+ ret = skb->len - rt_hdrlen;
skb->dev = dev;
skb_reset_mac_header(skb);
- skb_pull(skb, hdrlen);
- if (prism_header)
- skb_pull(skb, phdrlen);
+ skb_pull(skb, rt_hdrlen + hdrlen);
skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = __constant_htons(ETH_P_802_2);
memset(skb->cb, 0, sizeof(skb->cb));
diff --git a/drivers/net/wireless/hostap/hostap_common.h b/drivers/net/wireless/hostap/hostap_common.h
index 2f92ecd..ba6725f 100644
--- a/drivers/net/wireless/hostap/hostap_common.h
+++ b/drivers/net/wireless/hostap/hostap_common.h
@@ -283,7 +283,7 @@ enum {
PRISM2_PARAM_IEEE_802_1X = 23,
PRISM2_PARAM_ANTSEL_TX = 24,
PRISM2_PARAM_ANTSEL_RX = 25,
- PRISM2_PARAM_MONITOR_TYPE = 26,
+ /* PRISM2_PARAM_MONITOR_TYPE = 26, */
PRISM2_PARAM_WDS_TYPE = 27,
PRISM2_PARAM_HOSTSCAN = 28,
PRISM2_PARAM_AP_SCAN = 29,
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 7dc8392..5386831 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -894,12 +894,7 @@ static void hostap_monitor_set_type(local_info_t *local)
if (dev == NULL)
return;
- if (local->monitor_type == PRISM2_MONITOR_PRISM ||
- local->monitor_type == PRISM2_MONITOR_CAPHDR) {
- dev->type = ARPHRD_IEEE80211_PRISM;
- } else {
- dev->type = ARPHRD_IEEE80211;
- }
+ dev->type = ARPHRD_IEEE80211_RADIOTAP;
}
@@ -2247,10 +2242,6 @@ static const struct iw_priv_args prism2_priv[] = {
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "antsel_rx" },
{ PRISM2_PARAM_ANTSEL_RX,
0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getantsel_rx" },
- { PRISM2_PARAM_MONITOR_TYPE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "monitor_type" },
- { PRISM2_PARAM_MONITOR_TYPE,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getmonitor_type" },
{ PRISM2_PARAM_WDS_TYPE,
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wds_type" },
{ PRISM2_PARAM_WDS_TYPE,
@@ -2511,18 +2502,6 @@ static int prism2_ioctl_priv_prism2_param(struct net_device *dev,
hostap_set_antsel(local);
break;
- case PRISM2_PARAM_MONITOR_TYPE:
- if (value != PRISM2_MONITOR_80211 &&
- value != PRISM2_MONITOR_CAPHDR &&
- value != PRISM2_MONITOR_PRISM) {
- ret = -EINVAL;
- break;
- }
- local->monitor_type = value;
- if (local->iw_mode == IW_MODE_MONITOR)
- hostap_monitor_set_type(local);
- break;
-
case PRISM2_PARAM_WDS_TYPE:
local->wds_type = value;
break;
@@ -2789,10 +2768,6 @@ static int prism2_ioctl_priv_get_prism2_param(struct net_device *dev,
*param = local->antsel_rx;
break;
- case PRISM2_PARAM_MONITOR_TYPE:
- *param = local->monitor_type;
- break;
-
case PRISM2_PARAM_WDS_TYPE:
*param = local->wds_type;
break;
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c
index c8f41da..5de6123 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -597,25 +597,10 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx)
static int hostap_80211_header_parse(const struct sk_buff *skb,
unsigned char *haddr)
{
- struct hostap_interface *iface = netdev_priv(skb->dev);
- local_info_t *local = iface->local;
-
- if (local->monitor_type == PRISM2_MONITOR_PRISM ||
- local->monitor_type == PRISM2_MONITOR_CAPHDR) {
- const unsigned char *mac = skb_mac_header(skb);
-
- if (*(u32 *)mac == LWNG_CAP_DID_BASE) {
- memcpy(haddr,
- mac + sizeof(struct linux_wlan_ng_prism_hdr) + 10,
- ETH_ALEN); /* addr2 */
- } else { /* (*(u32 *)mac == htonl(LWNG_CAPHDR_VERSION)) */
- memcpy(haddr,
- mac + sizeof(struct linux_wlan_ng_cap_hdr) + 10,
- ETH_ALEN); /* addr2 */
- }
- } else
- memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
+ struct ieee80211_hdr_4addr *hdr =
+ (struct ieee80211_hdr_4addr *)skb_mac_header(skb);
+ memcpy(haddr, hdr->addr2, ETH_ALEN);
return ETH_ALEN;
}
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index 15445bc..6e047cf 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -5,6 +5,7 @@
#include <linux/netdevice.h>
#include <linux/mutex.h>
#include <net/iw_handler.h>
+#include <net/ieee80211_radiotap.h>
#include "hostap_config.h"
#include "hostap_common.h"
@@ -23,36 +24,15 @@
* prism2_send_mgmt() sends these with dev_queue_xmit() to prism2_tx(). */
#define ETH_P_HOSTAP ETH_P_CONTROL
-/* ARPHRD_IEEE80211_PRISM uses a bloated version of Prism2 RX frame header
- * (from linux-wlan-ng) */
-struct linux_wlan_ng_val {
- u32 did;
- u16 status, len;
- u32 data;
-} __attribute__ ((packed));
-
-struct linux_wlan_ng_prism_hdr {
- u32 msgcode, msglen;
- char devname[16];
- struct linux_wlan_ng_val hosttime, mactime, channel, rssi, sq, signal,
- noise, rate, istx, frmlen;
-} __attribute__ ((packed));
-
-struct linux_wlan_ng_cap_hdr {
- __be32 version;
- __be32 length;
- __be64 mactime;
- __be64 hosttime;
- __be32 phytype;
- __be32 channel;
- __be32 datarate;
- __be32 antenna;
- __be32 priority;
- __be32 ssi_type;
- __be32 ssi_signal;
- __be32 ssi_noise;
- __be32 preamble;
- __be32 encoding;
+struct hostap_radiotap_rx {
+ struct ieee80211_radiotap_header hdr;
+ __le64 tsft;
+ u8 rate;
+ u8 padding;
+ __le16 chan_freq;
+ __le16 chan_flags;
+ s8 dbm_antsignal;
+ s8 dbm_antnoise;
} __attribute__ ((packed));
#define LWNG_CAP_DID_BASE (4 | (1 << 6)) /* section 4, group 1 */
@@ -732,10 +712,6 @@ struct local_info {
struct iw_statistics wstats;
unsigned long scan_timestamp; /* Time started to scan */
- enum {
- PRISM2_MONITOR_80211 = 0, PRISM2_MONITOR_PRISM = 1,
- PRISM2_MONITOR_CAPHDR = 2
- } monitor_type;
int monitor_allow_fcserr;
int hostapd; /* whether user space daemon, hostapd, is used for AP
prev parent reply other threads:[~2008-05-23 1:55 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-05-23 1:54 [PATCH 1/5] hostap: fix sparse warnings Pavel Roskin
2008-05-23 1:54 ` [PATCH 2/5] hostap: fix references to 8802.11 Pavel Roskin
2008-05-26 9:38 ` Jouni Malinen
2008-05-23 1:54 ` [PATCH 3/5] hostap: remove private "monitor" ioctl Pavel Roskin
2008-05-26 9:44 ` Jouni Malinen
2008-05-28 13:30 ` Pavel Roskin
2008-05-28 14:48 ` Jouni Malinen
2008-05-23 1:55 ` [PATCH 4/5] hostap: don't report useless WDS frames by default Pavel Roskin
2008-05-23 1:55 ` Pavel Roskin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080523015505.16636.58672.stgit@dv.roinet.com \
--to=proski@gnu.org \
--cc=j@w1.fi \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).