From: Jiri Benc <jbenc@suse.cz>
To: netdev@vger.kernel.org
Cc: "John W. Linville" <linville@tuxdriver.com>
Subject: [PATCH 16/17] d80211: fix monitor interfaces
Date: Fri, 21 Apr 2006 22:11:47 +0200 (CEST) [thread overview]
Message-ID: <20060421201147.D4F76482CF@silver.suse.cz> (raw)
In-Reply-To: <20060421220951.205579000.midnight@suse.cz>
This patch allows monitor interfaces to be set by SIOCSIWMODE and to receive
frames.
Also, "soft" and "hard" monitor modes are introduced.
Signed-off-by: Jiri Benc <jbenc@suse.cz>
---
include/net/d80211.h | 10 ++++++
net/d80211/ieee80211.c | 67 ++++++++++++++++++++++++++++++++++++++++--
net/d80211/ieee80211_i.h | 1 +
net/d80211/ieee80211_iface.c | 7 ++++
4 files changed, 81 insertions(+), 4 deletions(-)
738241025b5e0091237d8c9d809d9affbdfaee29
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 7bc66b5..23bcbfa 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -330,6 +330,8 @@ enum ieee80211_if_types {
* @if_id: internal interface ID. This number has no particular meaning to
* drivers and the only allowed usage is to pass it to
* ieee80211_beacon_get() and ieee80211_get_buffered_bc() functions.
+ * This field is not valid for monitor interfaces
+ * (interfaces of %IEEE80211_IF_TYPE_MNTR type).
* @type: one of &enum ieee80211_if_types constants. Determines the type of
* added/removed interface.
* @mac_addr: pointer to MAC address of the interface. This pointer is valid
@@ -476,6 +478,10 @@ struct ieee80211_hw {
*/
unsigned int device_strips_mic:1;
+ /* Device is capable of performing full monitor mode even during
+ * normal operation. */
+ unsigned int monitor_during_oper:1;
+
/* 1 = low-level driver supports skb fraglist (NETIF_F_FRAGLIST), i.e.,
* more than one skb per frame */
unsigned int fraglist;
@@ -511,7 +517,9 @@ struct ieee80211_hw {
* more exactly, set UP). If the handler returns zero, the interface
* is added. Driver should perform any initialization it needs prior
* to returning zero. By returning non-zero, adding of the interface
- * is not permitted. The open() handler is called after
+ * is not permitted. Unless monitor_during_oper is set, it is
+ * guaranteed that monitor interfaces and normal interfaces are
+ * mutually exclusive. The open() handler is called after
* add_interface() if this is the first device added. At least one
* of open() and add_interface() handler has to be non-NULL. If
* add_interface() is NULL, one STA interface is permitted only. */
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index e2a42af..b199b9e 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1891,7 +1891,9 @@ static struct net_device_stats *ieee8021
static inline int identical_mac_addr_allowed(int type1, int type2)
{
- return ((type1 == IEEE80211_IF_TYPE_AP &&
+ return (type1 == IEEE80211_IF_TYPE_MNTR ||
+ type2 == IEEE80211_IF_TYPE_MNTR ||
+ (type1 == IEEE80211_IF_TYPE_AP &&
type2 == IEEE80211_IF_TYPE_WDS) ||
(type1 == IEEE80211_IF_TYPE_WDS &&
(type2 == IEEE80211_IF_TYPE_WDS ||
@@ -1925,6 +1927,36 @@ static int ieee80211_master_stop(struct
return 0;
}
+/* Check if running monitor interfaces should go to a "soft monitor" mode
+ * and switch them if necessary. */
+static inline void ieee80211_start_soft_monitor(struct ieee80211_local *local)
+{
+ struct ieee80211_if_init_conf conf;
+
+ if (local->open_count && local->open_count == local->monitors &&
+ !local->hw->monitor_during_oper && local->hw->remove_interface) {
+ conf.if_id = -1;
+ conf.type = IEEE80211_IF_TYPE_MNTR;
+ conf.mac_addr = NULL;
+ local->hw->remove_interface(local->mdev, &conf);
+ }
+}
+
+/* Check if running monitor interfaces should go to a "hard monitor" mode
+ * and switch them if necessary. */
+static void ieee80211_start_hard_monitor(struct ieee80211_local *local)
+{
+ struct ieee80211_if_init_conf conf;
+
+ if (local->open_count && local->open_count == local->monitors &&
+ !local->hw->monitor_during_oper && local->hw->add_interface) {
+ conf.if_id = -1;
+ conf.type = IEEE80211_IF_TYPE_MNTR;
+ conf.mac_addr = NULL;
+ local->hw->add_interface(local->mdev, &conf);
+ }
+}
+
static int ieee80211_open(struct net_device *dev)
{
struct ieee80211_sub_if_data *sdata, *nsdata;
@@ -1948,13 +1980,25 @@ static int ieee80211_open(struct net_dev
memcmp(sdata->u.wds.remote_addr, "\0\0\0\0\0\0", ETH_ALEN) == 0)
return -ENOLINK;
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR && local->open_count &&
+ !local->hw->monitor_during_oper) {
+ /* run the interface in a "soft monitor" mode */
+ local->monitors++;
+ local->open_count++;
+ return 0;
+ }
+ ieee80211_start_soft_monitor(local);
+
if (local->hw->add_interface) {
conf.if_id = dev->ifindex;
conf.type = sdata->type;
conf.mac_addr = dev->dev_addr;
res = local->hw->add_interface(sdata->master, &conf);
- if (res)
+ if (res) {
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+ ieee80211_start_hard_monitor(local);
return res;
+ }
} else {
if (sdata->type != IEEE80211_IF_TYPE_STA)
return -EOPNOTSUPP;
@@ -1980,6 +2024,9 @@ static int ieee80211_open(struct net_dev
}
local->open_count++;
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+ local->monitors++;
+
netif_start_queue(dev);
return 0;
}
@@ -1992,8 +2039,19 @@ static int ieee80211_stop(struct net_dev
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR &&
+ local->open_count > 1 && !local->hw->monitor_during_oper) {
+ /* remove "soft monitor" interface */
+ local->open_count--;
+ local->monitors--;
+ return 0;
+ }
+
netif_stop_queue(dev);
+ if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+ local->monitors--;
+
local->open_count--;
if (local->open_count == 0) {
ieee80211_stop_scan(sdata->master);
@@ -2010,6 +2068,8 @@ static int ieee80211_stop(struct net_dev
local->hw->remove_interface(sdata->master, &conf);
}
+ ieee80211_start_hard_monitor(local);
+
return 0;
}
@@ -2242,7 +2302,8 @@ ieee80211_rx_mgmt(struct net_device *dev
size_t hlen;
struct ieee80211_sub_if_data *sdata;
- dev = local->apdev;
+ if (msg_type != ieee80211_msg_monitor)
+ dev = local->apdev;
skb->dev = dev;
sdata = IEEE80211_DEV_TO_SUB_IF(dev);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 37d533d..2dbb132 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -305,6 +305,7 @@ struct ieee80211_local {
struct net_device *wdev; /* wlan# - default Ethernet (data) devide */
struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
int open_count;
+ int monitors;
struct ieee80211_conf conf;
int dev_index;
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 2151bd9..dd809c2 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
+#include <linux/if_arp.h>
#include <linux/netdevice.h>
#include <linux/rtnetlink.h>
#include <net/d80211.h>
@@ -124,6 +125,9 @@ void ieee80211_if_set_type(struct net_de
sdata->bss = &msdata->u.ap;
break;
}
+ case IEEE80211_IF_TYPE_MNTR:
+ dev->type = ARPHRD_IEEE80211_PRISM;
+ break;
default:
printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",
dev->name, __FUNCTION__, type);
@@ -211,6 +215,9 @@ #endif /* CONFIG_D80211_VERBOSE_DEBUG */
}
break;
+ case IEEE80211_IF_TYPE_MNTR:
+ dev->type = ARPHRD_ETHER;
+ break;
}
/* remove all STAs that are bound to this virtual interface */
--
1.3.0
next prev parent reply other threads:[~2006-04-21 20:11 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-04-21 20:11 [PATCH 0/17] d80211 patches Jiri Benc
2006-04-21 20:11 ` [PATCH 1/17] d80211: Replace MODULE_PARM with module_param Jiri Benc
2006-04-21 20:11 ` [PATCH 2/17] d80211: symlinks to wiphy in sysfs Jiri Benc
2006-04-21 20:11 ` [PATCH 3/17] d80211: allow WDS remote to by set by WE Jiri Benc
2006-04-21 20:11 ` [PATCH 4/17] d80211: add IBSS and monitor interface types Jiri Benc
2006-04-21 20:11 ` [PATCH 5/17] d80211: non-shared " Jiri Benc
2006-04-21 20:11 ` [PATCH 6/17] d80211: remove local->bssid variable Jiri Benc
2006-04-21 20:11 ` [PATCH 7/17] d80211: rename IEEE80211_SUB_IF_TYPE_ constants Jiri Benc
2006-04-21 20:11 ` [PATCH 8/17] d80211: ask driver for allowed iface combinations Jiri Benc
2006-04-21 20:11 ` [PATCH 9/17] d80211: remove obsolete stuff Jiri Benc
2006-04-21 20:11 ` [PATCH 10/17] d80211: fix interface configuration Jiri Benc
2006-04-21 20:11 ` [PATCH 11/17] d80211: rename adm_status to radio_enabled Jiri Benc
2006-04-21 20:11 ` [PATCH 12/17] d80211: interface types changeable by SIOCSIWMODE Jiri Benc
2006-04-21 20:11 ` [PATCH 13/17] d80211: master interface auto up/down Jiri Benc
2006-04-21 20:11 ` [PATCH 14/17] d80211: set_multicast_list Jiri Benc
2006-04-21 20:11 ` [PATCH 15/17] d80211: fix handling of received frames Jiri Benc
2006-04-21 20:11 ` Jiri Benc [this message]
2006-04-21 20:29 ` [PATCH 16/17] d80211: fix monitor interfaces Johannes Berg
2006-04-21 20:49 ` Jiri Benc
2006-04-21 20:52 ` Johannes Berg
2006-04-21 20:57 ` Jiri Benc
2006-04-21 21:01 ` Johannes Berg
2006-04-21 21:05 ` Jiri Benc
2006-04-21 21:05 ` Johannes Berg
2006-04-21 20:11 ` [PATCH 17/17] d80211: fix AP interfaces Jiri Benc
2006-04-21 20:52 ` [PATCH 0/17] d80211 patches Michael Buesch
2006-04-21 20:52 ` Jiri Benc
2006-04-26 19:39 ` John W. Linville
2006-04-26 21:27 ` Ivo van Doorn
2006-04-27 12:49 ` Michael Buesch
2006-04-28 15:45 ` [PATCH] bcm43xx_d80211: fix bug in open Jiri Benc
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=20060421201147.D4F76482CF@silver.suse.cz \
--to=jbenc@suse.cz \
--cc=linville@tuxdriver.com \
--cc=netdev@vger.kernel.org \
/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).