All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx
@ 2007-03-20 10:39 andy
  2007-03-20 10:39 ` [PATCH 1/4] mac80211: Coding style cleanups andy
                   ` (5 more replies)
  0 siblings, 6 replies; 25+ messages in thread
From: andy @ 2007-03-20 10:39 UTC (permalink / raw)
  To: linux-wireless

Hi folks -

This set of patches change the Monitor Mode wireless interfaces to use radiotap
both for monitoring and for packet injection.  The monitoring side is done by a patch
from Michael Wu.  Tcpdump knows how to handle the result.

For injecting packets, the you issue a packet using libpcap or a SOCK_PACKET
socket down an interface to the wireless device that is in Monitor Mode.  The packet
has a normal radiotap header prepended to the IEEE80211 header.  The radiotap header
is variable length depending on what the user wants to specify, currently the
transmit rate, power and antenna can be specified using normal radiotap semantics.
Any other entries are skipped.

A usermode app packetspammer is available from here

http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer

which allows easy injection of these packets from the commandline.  At the moment it
loops issuing packets at a variety of rates which can be seen from another
machine's monitor mode interface on the same channel.  There are instructions for
build and using it on the page above.

Currently it has been tested for both rx and tx using zd1211rw-mac80211.

The patches should be based against wireless-dev.

I also added a documentation file patch which explains how to use the injection
functionality.
-- 

^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 1/4] mac80211: Coding style cleanups
  2007-03-20 10:39 [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx andy
@ 2007-03-20 10:39 ` andy
  2007-03-21 18:58   ` Johannes Berg
  2007-03-20 10:39 ` [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX andy
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 25+ messages in thread
From: andy @ 2007-03-20 10:39 UTC (permalink / raw)
  To: linux-wireless

Stop existing code in ieee80211.c giving me panic attacks that I let my edits
go over 80 cols

From: Andy Green <andy@warmcat.com>

diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 577dbe3..c598c9d 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -275,7 +275,8 @@ EXPORT_SYMBOL(ieee80211_get_hdrlen);
 
 int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
 {
-	const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) skb->data;
+	const struct ieee80211_hdr *hdr =
+		(const struct ieee80211_hdr *) skb->data;
 	int hdrlen;
 
 	if (unlikely(skb->len < 10))
@@ -489,7 +490,8 @@ ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx)
 		fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen);
 		memcpy(fhdr, first->data, hdrlen);
 		if (i == num_fragm - 2)
-			fhdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS);
+			fhdr->frame_control &=
+				cpu_to_le16(~IEEE80211_FCTL_MOREFRAGS);
 		fhdr->seq_ctrl = cpu_to_le16(i + 1);
 		copylen = left > per_fragm ? per_fragm : left;
 		memcpy(skb_put(frag, copylen), pos, copylen);
@@ -545,7 +547,8 @@ void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
 		for (i = 0; i < tx->u.tx.num_extra_frag; i++) {
 			fhdr = (struct ieee80211_hdr *)
 				tx->u.tx.extra_frag[i]->data;
-			fhdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
+			fhdr->frame_control |=
+				cpu_to_le16(IEEE80211_FCTL_PROTECTED);
 		}
 	}
 }
@@ -861,7 +864,8 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
 	if (likely(tx->u.tx.unicast)) {
 		if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
 			     tx->sdata->type != IEEE80211_IF_TYPE_IBSS &&
-			     (tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
+			     (tx->fc & IEEE80211_FCTL_FTYPE)
+==			      IEEE80211_FTYPE_DATA)) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
 			printk(KERN_DEBUG "%s: dropped data frame to not "
 			       "associated station " MAC_FMT "\n",
@@ -871,7 +875,8 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
 			return TXRX_DROP;
 		}
 	} else {
-		if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
+		if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) ==
+		             IEEE80211_FTYPE_DATA &&
 			     tx->local->num_sta == 0 &&
 			     !tx->local->allow_broadcast_always &&
 			     tx->sdata->type != IEEE80211_IF_TYPE_IBSS)) {
@@ -982,7 +987,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
 
 	if (unlikely(!sta ||
 		     ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT &&
-		      (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)))
+		      (tx->fc & IEEE80211_FCTL_STYPE) ==
+		       IEEE80211_STYPE_PROBE_RESP)))
 		return TXRX_CONTINUE;
 
 	if (unlikely((sta->flags & WLAN_STA_PS) && !sta->pspoll)) {
@@ -1012,7 +1018,8 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx)
 				tx->local->ops->set_tim(local_to_hw(tx->local),
 						       sta->aid, 1);
 			if (tx->sdata->bss)
-				bss_tim_set(tx->local, tx->sdata->bss, sta->aid);
+				bss_tim_set(tx->local, tx->sdata->bss,
+				            sta->aid);
 		}
 		pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb;
 		pkt_data->jiffies = jiffies;
@@ -1146,7 +1153,8 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
 	int ret, i;
 
 	if (skb) {
-		ieee80211_dump_frame(local->mdev->name, "TX to low-level driver", skb);
+		ieee80211_dump_frame(local->mdev->name,
+		                     "TX to low-level driver", skb);
 		ret = local->ops->tx(local_to_hw(local), skb, control);
 		if (ret)
 			return IEEE80211_TX_AGAIN;
@@ -1170,7 +1178,8 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
 						IEEE80211_TXCTL_RATE_CTRL_PROBE;
 				else
 					control->flags &=
-						~IEEE80211_TXCTL_RATE_CTRL_PROBE;
+						~IEEE80211_TXCTL_RATE_CTRL_PROBE
+					;
 			}
 
 			ieee80211_dump_frame(local->mdev->name,
@@ -1783,7 +1792,8 @@ struct sk_buff * ieee80211_beacon_get(struct ieee80211_hw *hw, int if_id,
 		rate = rate_control_get_rate(local, local->mdev, skb, &extra);
 		if (!rate) {
 			if (net_ratelimit()) {
-				printk(KERN_DEBUG "%s: ieee80211_beacon_get: no rate "
+				printk(KERN_DEBUG
+				       "%s: ieee80211_beacon_get: no rate "
 				       "found\n", local->mdev->name);
 			}
 			dev_kfree_skb(skb);
@@ -1835,7 +1845,8 @@ EXPORT_SYMBOL(ieee80211_rts_duration);
 
 __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
 				    size_t frame_len,
-				    const struct ieee80211_tx_control *frame_txctl)
+				    const struct ieee80211_tx_control
+					*frame_txctl)
 {
 	struct ieee80211_local *local = hw_to_local(hw);
 	struct ieee80211_rate *rate;
@@ -1885,7 +1896,8 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw,
 
 	fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS;
 	cts->frame_control = cpu_to_le16(fctl);
-	cts->duration = ieee80211_ctstoself_duration(hw, frame_len, frame_txctl);
+	cts->duration = ieee80211_ctstoself_duration(hw, frame_len,
+			                             frame_txctl);
 	memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
 }
 EXPORT_SYMBOL(ieee80211_ctstoself_get);
@@ -2942,10 +2954,12 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx)
 		/* Use MoreData flag to indicate whether there are more
 		 * buffered frames for this STA */
 		if (no_pending_pkts) {
-			hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
+			hdr->frame_control &=
+				cpu_to_le16(~IEEE80211_FCTL_MOREDATA);
 			rx->sta->flags &= ~WLAN_STA_TIM;
 		} else
-			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
+			hdr->frame_control |=
+				cpu_to_le16(IEEE80211_FCTL_MOREDATA);
 
 		dev_queue_xmit(skb);
 
@@ -2954,7 +2968,8 @@ ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx)
 				rx->local->ops->set_tim(local_to_hw(rx->local),
 						       rx->sta->aid, 0);
 			if (rx->sdata->bss)
-				bss_tim_clear(rx->local, rx->sdata->bss, rx->sta->aid);
+				bss_tim_clear(rx->local, rx->sdata->bss,
+					rx->sta->aid);
 		}
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
 	} else if (!rx->u.rx.sent_ps_buffered) {
@@ -3040,7 +3055,8 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata,
 		f_hdr = (struct ieee80211_hdr *) entry->skb_list.next->data;
 		f_fc = le16_to_cpu(f_hdr->frame_control);
 
-		if ((fc & IEEE80211_FCTL_FTYPE) != (f_fc & IEEE80211_FCTL_FTYPE) ||
+		if ((fc & IEEE80211_FCTL_FTYPE) !=
+		    (f_fc & IEEE80211_FCTL_FTYPE) ||
 		    compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 ||
 		    compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0)
 			continue;
@@ -3231,7 +3247,8 @@ ieee80211_rx_h_check(struct ieee80211_txrx_data *rx)
 	 */
 	if (unlikely(((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA ||
 		      ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL &&
-		       (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
+		       (rx->fc & IEEE80211_FCTL_STYPE) ==
+		        IEEE80211_STYPE_PSPOLL)) &&
 		     rx->sdata->type != IEEE80211_IF_TYPE_IBSS &&
 		     (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) {
 		if ((!(rx->fc & IEEE80211_FCTL_FROMDS) &&
@@ -3445,7 +3462,8 @@ ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx)
 
 	if (unlikely(rx->sdata->ieee802_1x &&
 		     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
-		     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
+		     (rx->fc & IEEE80211_FCTL_STYPE) !=
+		      IEEE80211_STYPE_NULLFUNC &&
 		     (!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)) &&
 		     !ieee80211_is_eapol(rx->skb))) {
 #ifdef CONFIG_MAC80211_DEBUG
@@ -3472,7 +3490,8 @@ ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx)
 	/* Drop unencrypted frames if key is set. */
 	if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) &&
 		     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
-		     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
+		     (rx->fc & IEEE80211_FCTL_STYPE) !=
+		      IEEE80211_STYPE_NULLFUNC &&
 		     (rx->key || rx->sdata->drop_unencrypted) &&
 		     (rx->sdata->eapol == 0 ||
 		      !ieee80211_is_eapol(rx->skb)))) {
@@ -3537,7 +3556,8 @@ ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx)
 			local->scan.rx_beacon++;
 			/* Need to trim FCS here because it is normally
 			 * removed only after this passive scan handler. */
-			if ((rx->local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) &&
+			if ((rx->local->hw.flags &
+			     IEEE80211_HW_RX_INCLUDES_FCS) &&
 			    rx->skb->len > FCS_LEN)
 				skb_trim(rx->skb, rx->skb->len - FCS_LEN);
 
@@ -3800,8 +3820,9 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 						continue;
 					rx.u.rx.ra_match = 0;
 				} else if (!multicast &&
-					   compare_ether_addr(sdata->dev->dev_addr,
-							      hdr->addr1) != 0) {
+					   compare_ether_addr(
+						sdata->dev->dev_addr,
+						hdr->addr1) != 0) {
 					if (!sdata->promisc)
 						continue;
 					rx.u.rx.ra_match = 0;
@@ -3816,22 +3837,27 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 						continue;
 					rx.u.rx.ra_match = 0;
 				} else if (!multicast &&
-					   compare_ether_addr(sdata->dev->dev_addr,
-							      hdr->addr1) != 0) {
+					   compare_ether_addr(
+						sdata->dev->dev_addr,
+						hdr->addr1) != 0) {
 					if (!sdata->promisc)
 						continue;
 					rx.u.rx.ra_match = 0;
 				} else if (!sta)
 					sta = rx.sta =
-						ieee80211_ibss_add_sta(local->mdev,
-								       skb, bssid,
-								       hdr->addr2);
-						/* FIXME: call with sdata->dev */
+						ieee80211_ibss_add_sta(
+							local->mdev,
+							skb, bssid,
+							hdr->addr2);
+						/* FIXME: call with
+						 * sdata->dev
+						 */
 				break;
 			case IEEE80211_IF_TYPE_AP:
 				if (!bssid) {
-					if (compare_ether_addr(sdata->dev->dev_addr,
-							       hdr->addr1) != 0)
+					if (compare_ether_addr(
+						sdata->dev->dev_addr,
+						hdr->addr1) != 0)
 						continue;
 				} else if (!ieee80211_bssid_match(bssid,
 							sdata->dev->dev_addr)) {
@@ -3847,7 +3873,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 				break;
 			case IEEE80211_IF_TYPE_WDS:
 				if (bssid ||
-				    (rx.fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)
+				    (rx.fc & IEEE80211_FCTL_FTYPE) !=
+				     IEEE80211_FTYPE_DATA)
 					continue;
 				if (compare_ether_addr(sdata->u.wds.remote_addr,
 						       hdr->addr2) != 0)
@@ -3859,9 +3886,11 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 				skb_new = skb_copy(skb, GFP_ATOMIC);
 				if (!skb_new) {
 					if (net_ratelimit())
-						printk(KERN_DEBUG "%s: failed to copy "
+						printk(KERN_DEBUG
+						       "%s: failed to copy "
 						       "multicast frame for %s",
-						       local->mdev->name, prev->dev->name);
+						       local->mdev->name,
+						       prev->dev->name);
 					continue;
 				}
 				rx.skb = skb_new;
@@ -4149,9 +4178,12 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
 	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
 	pkt_data->ifindex = control->ifindex;
 	pkt_data->mgmt_iface = (control->type == IEEE80211_IF_TYPE_MGMT);
-	pkt_data->req_tx_status = !!(control->flags & IEEE80211_TXCTL_REQ_TX_STATUS);
-	pkt_data->do_not_encrypt = !!(control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT);
-	pkt_data->requeue = !!(control->flags & IEEE80211_TXCTL_REQUEUE);
+	pkt_data->req_tx_status = !!(control->flags &
+				     IEEE80211_TXCTL_REQ_TX_STATUS);
+	pkt_data->do_not_encrypt = !!(control->flags &
+				      IEEE80211_TXCTL_DO_NOT_ENCRYPT);
+	pkt_data->requeue = !!(control->flags &
+			       IEEE80211_TXCTL_REQUEUE);
 	pkt_data->queue = control->queue;
 
 	hdrlen = ieee80211_get_hdrlen_from_skb(skb);
@@ -4223,7 +4255,8 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
 				 * that this TX packet failed because of that.
 				 */
 				status->excessive_retries = 0;
-				status->flags |= IEEE80211_TX_STATUS_TX_FILTERED;
+				status->flags |=
+					IEEE80211_TX_STATUS_TX_FILTERED;
 			}
 			sta_info_put(sta);
 		}
@@ -4254,9 +4287,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb,
 							  &status->control);
 				skb_queue_tail(&sta->tx_filtered, skb);
 			} else if (!(sta->flags & WLAN_STA_PS) &&
-				   !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) {
+				   !(status->control.flags &
+				     IEEE80211_TXCTL_REQUEUE)) {
 				/* Software retry the packet once */
-				status->control.flags |= IEEE80211_TXCTL_REQUEUE;
+				status->control.flags |=
+					IEEE80211_TXCTL_REQUEUE;
 				ieee80211_remove_tx_extra(local, sta->key,
 							  skb,
 							  &status->control);

-- 

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX
  2007-03-20 10:39 [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx andy
  2007-03-20 10:39 ` [PATCH 1/4] mac80211: Coding style cleanups andy
@ 2007-03-20 10:39 ` andy
  2007-03-21 18:51   ` Johannes Berg
  2007-03-20 10:39 ` [PATCH 3/4] mac80211: Monitor mode radiotap injection docs andy
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 25+ messages in thread
From: andy @ 2007-03-20 10:39 UTC (permalink / raw)
  To: linux-wireless

Try #2
 - Fix radiotap bitmap generation (Andy Green)
 - Fix radiotap padding (Michael Wu)

From: Michael Wu <flamingice@sourmilk.net>

---

 include/net/mac80211.h         |    3 ++
 net/mac80211/ieee80211.c       |   67 +++++++++++++++++++++++++++++++++-------
 net/mac80211/ieee80211_iface.c |    2 +
 3 files changed, 59 insertions(+), 13 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 916b21b..27cffdc 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -518,6 +518,9 @@ struct ieee80211_hw {
 	 * normal operation. */
 #define IEEE80211_HW_MONITOR_DURING_OPER (1<<9)
 
+	/* Driver supports radiotap. */
+#define IEEE80211_HW_RADIOTAP_SUPPORTED (1<<10)
+
 	/* please fill this gap when adding new flags */
 
 	/* calculate Michael MIC for an MSDU when doing hwcrypto */
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 0b7cb35..6bffc29 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -8,6 +8,7 @@
  */
 
 #include <net/mac80211.h>
+#include <net/ieee80211_radiotap.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
@@ -286,6 +287,14 @@ int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
 }
 EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
 
+static int ieee80211_get_radiotap_len(struct sk_buff *skb)
+{
+	struct ieee80211_radiotap_header *hdr =
+		(struct ieee80211_radiotap_header *) skb->data;
+
+	return le16_to_cpu(hdr->it_len);
+}
+
 #ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP
 static void ieee80211_dump_frame(const char *ifname, const char *title,
 				 const struct sk_buff *skb)
@@ -2741,26 +2750,48 @@ ieee80211_rx_monitor(struct net_device *dev, struct sk_buff *skb,
 		     struct ieee80211_rx_status *status)
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-	struct ieee80211_frame_info *fi;
 	struct ieee80211_sub_if_data *sdata;
-	const size_t hlen = sizeof(struct ieee80211_frame_info)
-				- sizeof(fi->msg_type);
+	struct ieee80211_rtap_hdr {
+		struct ieee80211_radiotap_header hdr;
+		u8 flags;
+		u8 rate;
+		__le16 chan_freq;
+		__le16 chan_flags;
+		u8 antsignal;
+	} __attribute__ ((packed)) *rthdr;
 
 	skb->dev = dev;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-	if (skb_headroom(skb) < hlen) {
-		I802_DEBUG_INC(local->rx_expand_skb_head);
-		if (pskb_expand_head(skb, hlen, 0, GFP_ATOMIC)) {
-			dev_kfree_skb(skb);
-			return;
+	if (!(local->hw.flags & IEEE80211_HW_RADIOTAP_SUPPORTED)) {
+		if (skb_headroom(skb) < sizeof(*rthdr)) {
+			I802_DEBUG_INC(local->rx_expand_skb_head);
+			if (pskb_expand_head(skb, sizeof(*rthdr), 0, GFP_ATOMIC)) {
+				dev_kfree_skb(skb);
+				return;
+			}
 		}
-	}
 
-	fi = (struct ieee80211_frame_info *) skb_push(skb, hlen);
+		rthdr = (struct ieee80211_rtap_hdr *) skb_push(skb, sizeof(*rthdr));
+		memset(rthdr, 0, sizeof(*rthdr));
+		rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));
+		rthdr->hdr.it_present =
+			cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) |
+				    (1 << IEEE80211_RADIOTAP_RATE) |
+				    (1 << IEEE80211_RADIOTAP_CHANNEL) |
+				    (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL));
+		rthdr->flags = local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS ?
+			       IEEE80211_RADIOTAP_F_FCS : 0;
+		rthdr->rate = status->rate / 5;
+		rthdr->chan_freq = cpu_to_le16(status->freq);
+		rthdr->chan_flags =
+			status->phymode == MODE_IEEE80211A ?
+			cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ) :
+			cpu_to_le16(IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ);
+		rthdr->antsignal = status->ssi;
+	}
 
-	ieee80211_fill_frame_info(local, fi, status);
 	sdata->stats.rx_packets++;
 	sdata->stats.rx_bytes += skb->len;
 
@@ -3164,6 +3195,10 @@ ieee80211_rx_h_monitor(struct ieee80211_txrx_data *rx)
 		return TXRX_QUEUED;
 	}
 
+	if (rx->local->monitors &&
+	    rx->local->hw.flags & IEEE80211_HW_RADIOTAP_SUPPORTED)
+		skb_pull(rx->skb, ieee80211_get_radiotap_len(rx->skb));
+
 	return TXRX_CONTINUE;
 }
 
@@ -3731,6 +3766,13 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	struct ieee80211_txrx_data rx;
 	u16 type;
 	int multicast;
+	int radiotap_len = 0;
+
+	if (local->monitors &&
+	    local->hw.flags & IEEE80211_HW_RADIOTAP_SUPPORTED) {
+		radiotap_len = ieee80211_get_radiotap_len(skb);
+		skb_pull(skb, radiotap_len);
+	}
 
 	hdr = (struct ieee80211_hdr *) skb->data;
 	memset(&rx, 0, sizeof(rx));
@@ -3767,6 +3809,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 		goto end;
 	skb = rx.skb;
 
+	skb_push(skb, radiotap_len);
 	if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) &&
 	    !local->iff_promiscs && !multicast) {
 		rx.u.rx.ra_match = 1;
@@ -3775,7 +3818,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
 	} else {
 		struct ieee80211_sub_if_data *prev = NULL;
 		struct sk_buff *skb_new;
-		u8 *bssid = ieee80211_get_bssid(hdr, skb->len);
+		u8 *bssid = ieee80211_get_bssid(hdr, skb->len - radiotap_len);
 
 		list_for_each_entry(sdata, &local->sub_if_list, list) {
 			rx.u.rx.ra_match = 1;
diff --git a/net/mac80211/ieee80211_iface.c b/net/mac80211/ieee80211_iface.c
index 3e0b4fa..51197b1 100644
--- a/net/mac80211/ieee80211_iface.c
+++ b/net/mac80211/ieee80211_iface.c
@@ -199,7 +199,7 @@ void ieee80211_if_set_type(struct net_device *dev, int type)
 		break;
 	}
 	case IEEE80211_IF_TYPE_MNTR:
-		dev->type = ARPHRD_IEEE80211_PRISM;
+		dev->type = ARPHRD_IEEE80211_RADIOTAP;
 		break;
 	default:
 		printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",

-- 

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 3/4] mac80211: Monitor mode radiotap injection docs
  2007-03-20 10:39 [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx andy
  2007-03-20 10:39 ` [PATCH 1/4] mac80211: Coding style cleanups andy
  2007-03-20 10:39 ` [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX andy
@ 2007-03-20 10:39 ` andy
  2007-03-21 18:15   ` Johannes Berg
  2007-03-20 10:39 ` [PATCH 4/4] mac80211: Monitor mode radiotap-based packet injection andy
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 25+ messages in thread
From: andy @ 2007-03-20 10:39 UTC (permalink / raw)
  To: linux-wireless

From: Andy Green <andy@warmcat.com>


diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt
new file mode 100644
index 0000000..bee8931
--- /dev/null
+++ b/Documentation/networking/mac80211-injection.txt
@@ -0,0 +1,77 @@
+How to use packet injection with mac80211
+=========================================
+
+mac80211 now allows arbitrary packets to be injected down any Monitor Mode
+interface from userland.  The packet you inject needs to be composed in the
+following format:
+
+ [ radiotap header  ]
+ [ ieee80211 header ]
+ [ payload ]
+
+Radiotap headers are variable-length and extensible, you can get most of the
+information you need to know on them from:
+
+./include/net/ieee80211_radiotap.h
+
+But note: all fields in the radiotap header are *little endian*.
+
+There is a fixed portion at the start which contains a u32 bitmap that defines
+if the possible argument is present or not.  At the moment there are only 13
+possible arguments defined, but in case we run out of space in the u32 it is
+defined that b31 set indicates that there is another u32 bitmap following, and
+the start of the arguments is moved forward 4 bytes each time.
+
+After the fixed part of the header, the arguments follow.
+
+ - the arguments are all little-endian!
+
+ - the arguments must be aligned to a boundary of the argument size using
+   padding.  So a u16 argument must start on the next u16 boundary if it isn't
+   already on one, a u32 must start on the next u32 boundary and so on.
+
+Despite 13 radiotap argument types are currently defined, most only make sense
+to appear on received packets.  Currently three kinds of argument are used by
+the injection code, although it knows to skip any other arguments that are
+present (facilitating replay of captured radiotap headers directly):
+
+ - IEEE80211_RADIOTAP_RATE - u8 arg in 500kbps units (0x02 --> 1Mbps)
+
+ - IEEE80211_RADIOTAP_ANTENNA - u8 arg, 0x00 = ant1, 0x01 = ant2
+
+ - IEEE80211_RADIOTAP_DBM_TX_POWER - u8 arg, dBm
+
+Here is an example valid radiotap header defining these three parameters
+
+	0x00, 0x00, // <-- radiotap version
+	0x0b, 0x00, // <- radiotap header length
+	0x04, 0x0c, 0x00, 0x00, // <-- bitmap
+	0x6c, // <-- rate
+	0x0c, //<-- tx power
+	0x01 //<-- antenna
+
+The ieee80211 header follows immediately afterwards, looking for example like
+this:
+
+	0x08, 0x01, 0x00, 0x00,
+	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+	0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
+	0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
+	0x10, 0x86
+
+Then lastly there is the payload.
+
+After composing the packet contents, it is sent by send()-ing it to a logical
+mac80211 interface that is in Monitor mode.  Libpcap can also be used,
+(which is easier than doing the work to bind the socket to the right
+interface), along the following lines:
+
+	ppcap = pcap_open_live(szInterfaceName, 800, 1, 20, szErrbuf);
+...
+	r = pcap_inject(ppcap, u8aSendBuffer, nLength);
+
+You can also find sources for a complete inject test applet here:
+
+http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer
+
+Andy Green <andy@warmcat.com>

-- 

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 4/4] mac80211: Monitor mode radiotap-based packet injection
  2007-03-20 10:39 [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx andy
                   ` (2 preceding siblings ...)
  2007-03-20 10:39 ` [PATCH 3/4] mac80211: Monitor mode radiotap injection docs andy
@ 2007-03-20 10:39 ` andy
  2007-03-21 18:28   ` Johannes Berg
  2007-03-21 18:10 ` [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx Johannes Berg
  2007-03-21 18:46 ` Johannes Berg
  5 siblings, 1 reply; 25+ messages in thread
From: andy @ 2007-03-20 10:39 UTC (permalink / raw)
  To: linux-wireless

From: Andy Green <andy@warmcat.com>

Try #5
 - De-indent last few indented comments

Try #4
 - All from Michael Wu's feedback: further style heresies removed
 - took account of radiotap arg alignment requirement.  n-byte arg must be
   placed on n-byte boundary using padding where necessary

Try #3
 - moved to Michael Wu's method of tracking if we came in on a
   monitor interface by using ifindex
 - removed older proposed monitor interface tracking method and flags
 - style fixes
 - removed duped #include that is present in Michael Wu's patch already

Try #2
 - took Michael Wu's advice about better tools and basing on wireless-dev
 - took Luis Rodriguez's advice about coding style makeover
 - took Pavel Roskin's advice about little-endian radiotap

===================================================

diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index fb33b90..fe15612 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -1054,7 +1054,180 @@ ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
 }
 
 
-static void inline
+/* deal with packet injection down monitor interface
+ * with Radiotap Header -- only called for monitor mode interface
+ */
+
+static ieee80211_txrx_result
+__ieee80211_convert_radiotap_to_control_and_remove(
+	struct ieee80211_txrx_data *tx,
+	struct sk_buff *skb, struct ieee80211_tx_control *control)
+{
+	/* this is the moment to interpret the radiotap header that
+	 * must be at the start of the packet injected in Monitor
+	 * mode into control and then discard the radiotap header
+	 *
+	 * Need to take some care with endian-ness since radiotap
+	 * is apparently a little-endian struct, including the args
+	 *
+	 * There is also some pervacious arg padding, so that args
+	 * of a given length must begin at a boundary of that length
+	 */
+
+	struct ieee80211_radiotap_header *rthdr =
+		(struct ieee80211_radiotap_header *) skb->data;
+
+	/* small length lookup table for all radiotap types we heard of
+	 * starting from b0 in the bitmap, so we can walk the payload
+	 * area of the radiotap header
+	 */
+
+	static const u8 radiotap_entry_sizes[] = {
+		8, /* IEEE80211_RADIOTAP_TSFT */
+		1, /* IEEE80211_RADIOTAP_FLAGS */
+		1, /* IEEE80211_RADIOTAP_RATE */
+		4, /* IEEE80211_RADIOTAP_CHANNEL */
+		2, /* IEEE80211_RADIOTAP_FHSS */
+		1, /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */
+		1, /* IEEE80211_RADIOTAP_DBM_ANTNOISE */
+		2, /* IEEE80211_RADIOTAP_LOCK_QUALITY */
+		2, /* IEEE80211_RADIOTAP_TX_ATTENUATION */
+		2, /* IEEE80211_RADIOTAP_DB_TX_ATTENUATION */
+		1, /* IEEE80211_RADIOTAP_DBM_TX_POWER */
+		1, /* IEEE80211_RADIOTAP_ANTENNA */
+		1, /* IEEE80211_RADIOTAP_DB_ANTSIGNAL */
+		1  /* IEEE80211_RADIOTAP_DB_ANTNOISE */
+		/* add more here as they are defined */
+	};
+	int tap_index = 0;
+	u8 *tap_arg = skb->data + sizeof(struct ieee80211_radiotap_header);
+	u32 *curr_arg_bitmap = &rthdr->it_present;
+	u32 arg_bitmap = le32_to_cpu(*curr_arg_bitmap);
+
+	if (rthdr->it_version)
+		return TXRX_DROP; /* version byte as magic */
+
+	/* sanity check for skb length and radiotap length field */
+	if (skb->len < (le16_to_cpu(rthdr->it_len) +
+	    sizeof(struct ieee80211_hdr)))
+		return TXRX_DROP;
+
+	/* find payload start allowing for extended bitmap(s) */
+
+	if (le32_to_cpu(rthdr->it_present) & 0x80000000) {
+		while (le32_to_cpu(*((u32 *)tap_arg)) & 0x80000000)
+			tap_arg += sizeof(u32);
+		tap_arg += sizeof(u32);
+	}
+
+	/* default control situation for all injected packets */
+
+	control->retry_limit = 1; /* no retry */
+	control->key_idx = -1; /* no encryption key */
+	control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
+		IEEE80211_TXCTL_USE_CTS_PROTECT);
+	control->flags |= (IEEE80211_TXCTL_DO_NOT_ENCRYPT |
+		IEEE80211_TXCTL_NO_ACK);
+	control->antenna_sel_tx = 0; /* default to default antenna */
+
+	/* for every radiotap entry we can at
+	 * least skip (by knowing the length)...
+	 */
+
+	while (tap_index < sizeof(radiotap_entry_sizes)) {
+		int i, target_rate;
+
+		if (!(arg_bitmap & 1))
+			goto next_entry;
+
+		/* arg is present, account for alignment padding
+		 *  8-bit args can be at any alignment
+		 * 16-bit args must start on 16-bit boundary
+		 * 32-bit args must start on 32-bit boundary
+		 * 64-bit args must start on 64-bit boundary
+		 */
+
+		if (((int)tap_arg) & (radiotap_entry_sizes[tap_index]-1))
+			tap_arg += radiotap_entry_sizes[tap_index]-
+				   (((int)tap_arg) &
+				    (radiotap_entry_sizes[tap_index]-1));
+
+		/* see if this argument is something that interests us */
+
+		switch (tap_index) {
+
+		case IEEE80211_RADIOTAP_RATE:
+			/* radiotap "rate" u8 is in
+			 * 500kbps units, eg, 0x02=1Mbps
+			 * ieee80211 "rate" int is
+			 * in 100kbps units, eg, 0x0a=1Mbps
+			 */
+			target_rate = (*tap_arg) * 5;
+			for (i = 0; i < tx->local->num_curr_rates; i++) {
+				struct ieee80211_rate *r =
+					&tx->local->curr_rates[i];
+
+				if (r->rate <= target_rate) {
+					if (r->flags &
+					   IEEE80211_RATE_PREAMBLE2) {
+						control->tx_rate = r->val2;
+					} else {
+						control->tx_rate = r->val;
+					}
+				
+
+					/* end on exact match */
+					if (r->rate == target_rate)
+						i = tx->local->num_curr_rates;
+				}
+			}
+			break;
+
+		case IEEE80211_RADIOTAP_ANTENNA:
+			/* radiotap uses 0 for 1st ant,
+			 * mac80211 is 1 for 1st ant
+			 * absence of IEEE80211_RADIOTAP_ANTENNA
+			 * gives default/diversity
+			 */
+			control->antenna_sel_tx = (*tap_arg) + 1;
+			break;
+
+		case IEEE80211_RADIOTAP_DBM_TX_POWER:
+			control->power_level = *tap_arg;
+			break;
+
+		default:
+			break;
+		}
+
+		tap_arg += radiotap_entry_sizes[tap_index];
+
+	next_entry:
+
+		tap_index++;
+		if (unlikely((tap_index & 31) == 0)) {
+			/* completed current u32 bitmap */
+			if (arg_bitmap & 1) { /* b31 was set, there is more */
+				/* move to next u32 bitmap */
+				curr_arg_bitmap++;
+				arg_bitmap = le32_to_cpu(*curr_arg_bitmap);
+			} else {
+				/* no more bitmaps: end */
+				tap_index = sizeof(radiotap_entry_sizes);
+			}
+		} else { /* just try the next bit */
+			arg_bitmap >>= 1;
+		}
+	}
+
+	/* remove the radiotap header */
+	skb_pull(skb, le16_to_cpu(rthdr->it_len));
+
+	return TXRX_CONTINUE;
+}
+
+
+static ieee80211_txrx_result inline
 __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
 		       struct sk_buff *skb,
 		       struct net_device *dev,
@@ -1062,6 +1235,9 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
 {
 	struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_sub_if_data *sdata;
+	ieee80211_txrx_result res = TXRX_CONTINUE;
+
 	int hdrlen;
 
 	memset(tx, 0, sizeof(*tx));
@@ -1071,7 +1247,32 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
 	tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	tx->sta = sta_info_get(local, hdr->addr1);
 	tx->fc = le16_to_cpu(hdr->frame_control);
+
+	/* set defaults for things that can be set by
+	 * injected radiotap headers
+	 */
+
 	control->power_level = local->hw.conf.power_level;
+	control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
+	if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)
+		control->antenna_sel_tx = tx->sta->antenna_sel_tx;
+
+	/* process and remove the injection radiotap header */
+
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {
+		if (__ieee80211_convert_radiotap_to_control_and_remove(
+		    tx, skb, control) == TXRX_DROP) {
+			return TXRX_DROP;
+		}
+		/* we removed the radiotap header after this point,
+		 * we filled control with what we could use
+		 * set to the actual ieee header now
+		 */
+		hdr = (struct ieee80211_hdr *) skb->data;
+		res = TXRX_QUEUED; /* indication it was monitor packet */
+	}
+
 	tx->u.tx.control = control;
 	tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1);
 	if (is_multicast_ether_addr(hdr->addr1))
@@ -1088,9 +1289,6 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
 		control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;
 		tx->sta->clear_dst_mask = 0;
 	}
-	control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
-	if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)
-		control->antenna_sel_tx = tx->sta->antenna_sel_tx;
 	hdrlen = ieee80211_get_hdrlen(tx->fc);
 	if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
 		u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
@@ -1098,6 +1296,7 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
 	}
 	control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT;
 
+	return res;
 }
 
 static int inline is_ieee80211_device(struct net_device *dev,
@@ -1205,7 +1404,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 	struct sta_info *sta;
 	ieee80211_tx_handler *handler;
 	struct ieee80211_txrx_data tx;
-	ieee80211_txrx_result res = TXRX_DROP;
+	ieee80211_txrx_result res = TXRX_DROP, res_prepare;
 	int ret, i;
 
 	WARN_ON(__ieee80211_queue_pending(local, control->queue));
@@ -1215,14 +1414,24 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 		return 0;
 	}
 
-	__ieee80211_tx_prepare(&tx, skb, dev, control);
+	res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control);
+
+	if (res_prepare == TXRX_DROP) {
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
 	sta = tx.sta;
 	tx.u.tx.mgmt_interface = mgmt;
 
-	for (handler = local->tx_handlers; *handler != NULL; handler++) {
-		res = (*handler)(&tx);
-		if (res != TXRX_CONTINUE)
-			break;
+	if (res_prepare == TXRX_QUEUED) { /* if it was an injected packet */
+		res = TXRX_CONTINUE;
+	} else {
+		for (handler = local->tx_handlers; *handler != NULL; handler++) {
+			res = (*handler)(&tx);
+			if (res != TXRX_CONTINUE)
+				break;
+		}
 	}
 
 	skb = tx.skb; /* handlers are allowed to change skb */
@@ -1456,6 +1665,51 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb,
 		goto fail;
 	}
 
+	if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {
+		struct ieee80211_radiotap_header * prthdr =
+			(struct ieee80211_radiotap_header *)skb->data;
+
+		/* there must be a radiotap header at the
+		 * start in this case
+		 */
+
+		if (unlikely(prthdr->it_version)) {
+			/* radiotap version used as magic */
+			ret = 0;
+			goto fail;
+		}
+
+		skb->dev = local->mdev;
+
+		pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
+		memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
+		pkt_data->ifindex = sdata->dev->ifindex;
+		pkt_data->mgmt_iface = 0;
+		pkt_data->do_not_encrypt = 1;
+
+		/* above needed because we set skb device to master */
+
+		/* fix up the pointers accounting for the radiotap
+		 * header still being in there.  We are being given
+		 * a precooked IEEE80211 header so no need for
+		 * normal processing
+		 */
+
+		skb->mac.raw = skb->data+prthdr->it_len;
+		skb->nh.raw = skb->data+prthdr->it_len+
+			sizeof(struct ieee80211_hdr);
+		skb->h.raw = skb->data+prthdr->it_len+
+			sizeof(struct ieee80211_hdr);
+
+		/* pass the radiotap header up to
+		 * the next stage intact
+		 */
+
+		dev_queue_xmit(skb);
+
+		return 0;
+	}
+
 	nh_pos = skb->nh.raw - skb->data;
 	h_pos = skb->h.raw - skb->data;
 

-- 

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx  and tx
  2007-03-20 10:39 [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx andy
                   ` (3 preceding siblings ...)
  2007-03-20 10:39 ` [PATCH 4/4] mac80211: Monitor mode radiotap-based packet injection andy
@ 2007-03-21 18:10 ` Johannes Berg
  2007-03-22 22:58   ` Michael Wu
  2007-03-23  8:57   ` Andy Green
  2007-03-21 18:46 ` Johannes Berg
  5 siblings, 2 replies; 25+ messages in thread
From: Johannes Berg @ 2007-03-21 18:10 UTC (permalink / raw)
  To: andy; +Cc: linux-wireless, Michael Wu, John Linville

[-- Attachment #1: Type: text/plain, Size: 1470 bytes --]

On Tue, 2007-03-20 at 10:39 +0000, andy@warmcat.com wrote:

> For injecting packets, the you issue a packet using libpcap or a SOCK_PACKET
> socket down an interface to the wireless device that is in Monitor Mode.

Ok so people don't want to have this in cfg80211, all the better for me
since it's less work.

I urge you to solve the issues with this injection interface, we've
established that you can use packet filters to grab only management
frames but monitor interfaces definitely still interact very badly with
power management, and when the hardware has a BSS filter then this will
also be disabled with a monitor interface (if monitor during operation
is supported) which again puts more load on the host.

I have previously suggested to use the IFF_PROMISC bit for this, but
this will also need good driver/stack API since currently drivers that
support monitor during operation will just turn off BSS filters and such
when a monitor interface is added. That will have to be changed in
drivers as well.

Also, and I'm going to reply to your patches as well, this is not
something that should be restricted to mac80211 since cfg80211
generically supports virtual interfaces and anybody could in theory use
a userspace MLME even with a full-mac card given a special no-management
firmware mode. Hence, this should be documented for cfg80211 users.

Please work out these issues before adding this interface to the kernel.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 3/4] mac80211: Monitor mode radiotap injection docs
  2007-03-20 10:39 ` [PATCH 3/4] mac80211: Monitor mode radiotap injection docs andy
@ 2007-03-21 18:15   ` Johannes Berg
  2007-03-29 11:18     ` Andy Green
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Berg @ 2007-03-21 18:15 UTC (permalink / raw)
  To: andy; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 2081 bytes --]

On Tue, 2007-03-20 at 10:39 +0000, andy@warmcat.com wrote:

> +++ b/Documentation/networking/mac80211-injection.txt

This needs to be for cfg80211.

> +Radiotap headers are variable-length and extensible, you can get most of the
> +information you need to know on them from:
> +
> +./include/net/ieee80211_radiotap.h
> +
> +But note: all fields in the radiotap header are *little endian*.
> +
> +There is a fixed portion at the start which contains a u32 bitmap that defines
> +if the possible argument is present or not.  At the moment there are only 13
> +possible arguments defined, but in case we run out of space in the u32 it is
> +defined that b31 set indicates that there is another u32 bitmap following, and
> +the start of the arguments is moved forward 4 bytes each time.

Drop all that, it's generic radiotap description. Put it into another
file if you want.

> +After the fixed part of the header, the arguments follow.
> +
> + - the arguments are all little-endian!

duplicated information.

> +The ieee80211 header follows immediately afterwards, looking for example like
> +this:
> +
> +	0x08, 0x01, 0x00, 0x00,
> +	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
> +	0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
> +	0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
> +	0x10, 0x86
> +
> +Then lastly there is the payload.

Scratch that, somebody who doesn't know how a IEEE 802.11 header looks
like has no business reading that file anyway ;)

> Libpcap can also be used,
> +(which is easier than doing the work to bind the socket to the right
> +interface), along the following lines:
> +
> +	ppcap = pcap_open_live(szInterfaceName, 800, 1, 20, szErrbuf);
> +...
> +	r = pcap_inject(ppcap, u8aSendBuffer, nLength);
> +
> +You can also find sources for a complete inject test applet here:
> +
> +http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer

Is it big enough to warrant being elsewhere? I don't see how an example
program can be more than a few lines of code and then it could be
included here as a C file.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 4/4] mac80211: Monitor mode radiotap-based packet  injection
  2007-03-20 10:39 ` [PATCH 4/4] mac80211: Monitor mode radiotap-based packet injection andy
@ 2007-03-21 18:28   ` Johannes Berg
  2007-03-29 11:14     ` Andy Green
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Berg @ 2007-03-21 18:28 UTC (permalink / raw)
  To: andy; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 2371 bytes --]

On Tue, 2007-03-20 at 10:39 +0000, andy@warmcat.com wrote:

> --- a/net/mac80211/ieee80211.c
> +++ b/net/mac80211/ieee80211.c
> @@ -1054,7 +1054,180 @@ ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
>  }
>  
> 
> -static void inline
> +/* deal with packet injection down monitor interface
> + * with Radiotap Header -- only called for monitor mode interface
> + */
> +
> +static ieee80211_txrx_result
> +__ieee80211_convert_radiotap_to_control_and_remove(
> +	struct ieee80211_txrx_data *tx,
> +	struct sk_buff *skb, struct ieee80211_tx_control *control)
> +{

The actual parsing should live in cfg80211 (preferably in a new file) so
that others can use it. If it's a lot of code then add a new invisible
Kconfig symbol for it that drivers/stacks can select.

> +	 * There is also some pervacious arg padding, so that args

perwhat?

> +	static const u8 radiotap_entry_sizes[] = {
> +		8, /* IEEE80211_RADIOTAP_TSFT */
> +		1, /* IEEE80211_RADIOTAP_FLAGS */
[...]

I'd prefer C99 style for this.

> +		return TXRX_DROP; /* version byte as magic */

Bad idea. At least the comment. If you mean "drop the packet if it has a
radiotap version we don't parse" then say so.

> +	if (le32_to_cpu(rthdr->it_present) & 0x80000000) {
> +		while (le32_to_cpu(*((u32 *)tap_arg)) & 0x80000000)

Use a constant for that, introduce one if necessary.

> +	control->key_idx = -1; /* no encryption key */

Is there any way to indicate encryption? I think there might need to be
for 802.11w.

> +	control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
> +		IEEE80211_TXCTL_USE_CTS_PROTECT);

These really should be selectable as well.

> +	control->flags |= (IEEE80211_TXCTL_DO_NOT_ENCRYPT |
> +		IEEE80211_TXCTL_NO_ACK);

And NO_ACK is a really really totally bad idea for a userspace MLME.
Needs to be selectable for sure.

We also need to be able to assign some magic cookie to a packet that we
get back along with the packet so that we know when the injected packet
has been acked by the peer.

> +	/* remove the radiotap header */
> +	skb_pull(skb, le16_to_cpu(rthdr->it_len));

Shouldn't there be some sort of sanity check here so we don't pull too
much if userspace asks us to?

> +			/* radiotap version used as magic */

Same comment as above, there's nothing magic about the radiotap version.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx  and tx
  2007-03-20 10:39 [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx andy
                   ` (4 preceding siblings ...)
  2007-03-21 18:10 ` [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx Johannes Berg
@ 2007-03-21 18:46 ` Johannes Berg
  2007-03-22 23:10   ` Michael Wu
  5 siblings, 1 reply; 25+ messages in thread
From: Johannes Berg @ 2007-03-21 18:46 UTC (permalink / raw)
  To: andy; +Cc: linux-wireless, Michael Wu

[-- Attachment #1: Type: text/plain, Size: 768 bytes --]

Hi,

Here are some more issues using monitor interfaces for management that
will need to be addressed before I'm convinced that doing injection on
monitor interfaces is viable.

If the driver does not support radiotap, ieee80211_rx_monitor needs to
expand the head for each packet. Currently, this is also true, but since
currently no non-management frames are sent down the management
interface, this is not an issue. If each data packet needs to be first
reallocated though, it quickly becomes a problem for low-power embedded
access points running hostapd.

Additionally, the overhead of tacking on radiotap headers to each
received frame is also rather high if you're only interested in
receiving the information for management frames.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX
  2007-03-20 10:39 ` [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX andy
@ 2007-03-21 18:51   ` Johannes Berg
  2007-03-22 23:18     ` Michael Wu
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Berg @ 2007-03-21 18:51 UTC (permalink / raw)
  To: andy; +Cc: linux-wireless, Michael Wu

[-- Attachment #1: Type: text/plain, Size: 694 bytes --]


> +	/* Driver supports radiotap. */
> +#define IEEE80211_HW_RADIOTAP_SUPPORTED (1<<10)

> +	if (local->monitors &&
> +	    local->hw.flags & IEEE80211_HW_RADIOTAP_SUPPORTED) {
> +		radiotap_len = ieee80211_get_radiotap_len(skb);
> +		skb_pull(skb, radiotap_len);
> +	}

I don't think that can work. 

 1) it needs a lot more documentation on what a driver needs to do for
    this (for example that it should only add radiotap headers if a
    monitor interface was added)

 2) afaik local->monitors is increased even for soft monitor interfaces,
    thus this will really fall on its nose when the driver supports
    radiotap but not monitor during operation.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/4] mac80211: Coding style cleanups
  2007-03-20 10:39 ` [PATCH 1/4] mac80211: Coding style cleanups andy
@ 2007-03-21 18:58   ` Johannes Berg
  2007-03-29 11:17     ` Andy Green
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Berg @ 2007-03-21 18:58 UTC (permalink / raw)
  To: andy; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 3744 bytes --]

On Tue, 2007-03-20 at 10:39 +0000, andy@warmcat.com wrote:

I don't really see why this is necessary at all, but anyway.

> -			     (tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
> +			     (tx->fc & IEEE80211_FCTL_FTYPE)
> +==			      IEEE80211_FTYPE_DATA)) {

That's totally borked.

> -		if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
> +		if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) ==
> +		             IEEE80211_FTYPE_DATA &&

Indent that a bit more so it's clear it belongs to the line above and
isn't a condition itself.
 
>  	if (unlikely(!sta ||
>  		     ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT &&
> -		      (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)))
> +		      (tx->fc & IEEE80211_FCTL_STYPE) ==
> +		       IEEE80211_STYPE_PROBE_RESP)))

ditto.

> @@ -1170,7 +1178,8 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
>  						IEEE80211_TXCTL_RATE_CTRL_PROBE;
>  				else
>  					control->flags &=
> -						~IEEE80211_TXCTL_RATE_CTRL_PROBE;
> +						~IEEE80211_TXCTL_RATE_CTRL_PROBE
> +					;

ahem.

> -				printk(KERN_DEBUG "%s: ieee80211_beacon_get: no rate "
> +				printk(KERN_DEBUG
> +				       "%s: ieee80211_beacon_get: no rate "
>  				       "found\n", local->mdev->name);

Please change that to
	... no "
	"rate found\n", ...

instead.
 
>  __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
>  				    size_t frame_len,
> -				    const struct ieee80211_tx_control *frame_txctl)
> +				    const struct ieee80211_tx_control
> +					*frame_txctl)

That's not how the kernel looks like in that case. I'd prefer this as

__le16 ieee80211_ctstoself_duration(
	struct ieee80211_hw *hw,
	size_t frame_len,
	const struct ieee80211_tx_control *frame_txctl)


>  			if (rx->sdata->bss)
> -				bss_tim_clear(rx->local, rx->sdata->bss, rx->sta->aid);
> +				bss_tim_clear(rx->local, rx->sdata->bss,
> +					rx->sta->aid);

You have lots of space to indent it to the parenthesis.
 
> -		if ((fc & IEEE80211_FCTL_FTYPE) != (f_fc & IEEE80211_FCTL_FTYPE) ||
> +		if ((fc & IEEE80211_FCTL_FTYPE) !=
> +		    (f_fc & IEEE80211_FCTL_FTYPE) ||

same as above.

> -		       (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) &&
> +		       (rx->fc & IEEE80211_FCTL_STYPE) ==
> +		        IEEE80211_STYPE_PSPOLL)) &&

ditto.

>  		     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
> -		     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
> +		     (rx->fc & IEEE80211_FCTL_STYPE) !=
> +		      IEEE80211_STYPE_NULLFUNC &&

ditto.

> -		     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
> +		     (rx->fc & IEEE80211_FCTL_STYPE) !=
> +		      IEEE80211_STYPE_NULLFUNC &&

ditto.
 
> @@ -3800,8 +3820,9 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
>  						continue;
>  					rx.u.rx.ra_match = 0;
>  				} else if (!multicast &&
> -					   compare_ether_addr(sdata->dev->dev_addr,
> -							      hdr->addr1) != 0) {
> +					   compare_ether_addr(
> +						sdata->dev->dev_addr,
> +						hdr->addr1) != 0) {
>  					if (!sdata->promisc)
>  						continue;


Ugh. Somebody really needs to take this code and delete some indent by
moving stuff into new functions.

>  					if (net_ratelimit())
> -						printk(KERN_DEBUG "%s: failed to copy "
> +						printk(KERN_DEBUG
> +						       "%s: failed to copy "
>  						       "multicast frame for %s",
> -						       local->mdev->name, prev->dev->name);
> +						       local->mdev->name,
> +						       prev->dev->name);

Same as I said for that other message.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx
  2007-03-21 18:10 ` [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx Johannes Berg
@ 2007-03-22 22:58   ` Michael Wu
  2007-03-23 14:01     ` Johannes Berg
  2007-03-23  8:57   ` Andy Green
  1 sibling, 1 reply; 25+ messages in thread
From: Michael Wu @ 2007-03-22 22:58 UTC (permalink / raw)
  To: Johannes Berg; +Cc: andy, linux-wireless, John Linville

[-- Attachment #1: Type: text/plain, Size: 2331 bytes --]

On Wednesday 21 March 2007 14:10, Johannes Berg wrote:
> Ok so people don't want to have this in cfg80211, all the better for me
> since it's less work.
>
> I urge you to solve the issues with this injection interface, we've
> established that you can use packet filters to grab only management
> frames but monitor interfaces definitely still interact very badly with
> power management, and when the hardware has a BSS filter then this will
> also be disabled with a monitor interface (if monitor during operation
> is supported) which again puts more load on the host.
>
> I have previously suggested to use the IFF_PROMISC bit for this, but
> this will also need good driver/stack API since currently drivers that
> support monitor during operation will just turn off BSS filters and such
> when a monitor interface is added. That will have to be changed in
> drivers as well.
>
Note that my patch predates the suggestion that IFF_PROMISC be used to turn on 
monitor mode on the hardware. (2006-12-18) I merely updated it so that 
monitor interfaces output radiotap whether or not the driver supports.

This patch series is not meant to replace the management interface. I just 
gave Andy Green the radiotap RX patch so he could do some work in the right 
direction, but that patch isn't complete by itself. (That's why I didn't sign 
off on it) In particular, patches doing these things in addition to what this 
current patch series does will be needed to finally remove the management 
interface:

1. Make it easy to flip monitor mode on and off in drivers and support your 
IFF_PROMISC suggestion.
2. Make the use of radiotap by drivers configurable independently of monitor 
mode.
3. Report the result of a TX through monitor interfaces after 
ieee80211_tx_status is called. This requires new radiotap definitions.
4. Move things like radar detection and the rest of ieee80211_msg_* to 
cfg/nl80211 if they are necessary.
5. Port hostap and wpa_supplicant to the new interface. Will require some fun 
with packet filtering..
6. Kill the mgmt interface once and for all.

We don't need to replace the mgmt interface at once however. Addressing the 
first two issues should be sufficient to merge the radiotap RX/TX patches. 
After that, 3-6 can be done one by one.

-Michael Wu

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx
  2007-03-21 18:46 ` Johannes Berg
@ 2007-03-22 23:10   ` Michael Wu
  0 siblings, 0 replies; 25+ messages in thread
From: Michael Wu @ 2007-03-22 23:10 UTC (permalink / raw)
  To: Johannes Berg; +Cc: andy, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 747 bytes --]

On Wednesday 21 March 2007 14:46, Johannes Berg wrote:
> If the driver does not support radiotap, ieee80211_rx_monitor needs to
> expand the head for each packet. Currently, this is also true, but since
> currently no non-management frames are sent down the management
> interface, this is not an issue. If each data packet needs to be first
> reallocated though, it quickly becomes a problem for low-power embedded
> access points running hostapd.
>
That's why drivers should be modified to support radiotap.

> Additionally, the overhead of tacking on radiotap headers to each
> received frame is also rather high if you're only interested in
> receiving the information for management frames.
>
It's really not that much overhead.

-Michael Wu

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX
  2007-03-21 18:51   ` Johannes Berg
@ 2007-03-22 23:18     ` Michael Wu
  2007-03-23 13:44       ` Johannes Berg
  0 siblings, 1 reply; 25+ messages in thread
From: Michael Wu @ 2007-03-22 23:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: andy, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 1062 bytes --]

On Wednesday 21 March 2007 14:51, Johannes Berg wrote:
> > +	/* Driver supports radiotap. */
> > +#define IEEE80211_HW_RADIOTAP_SUPPORTED (1<<10)
> >
> > +	if (local->monitors &&
> > +	    local->hw.flags & IEEE80211_HW_RADIOTAP_SUPPORTED) {
> > +		radiotap_len = ieee80211_get_radiotap_len(skb);
> > +		skb_pull(skb, radiotap_len);
> > +	}
>
> I don't think that can work.
>
>  1) it needs a lot more documentation on what a driver needs to do for
>     this (for example that it should only add radiotap headers if a
>     monitor interface was added)
>
Lack of documentation makes code not work?

>  2) afaik local->monitors is increased even for soft monitor interfaces,
>     thus this will really fall on its nose when the driver supports
>     radiotap but not monitor during operation.
>
Yes. I noted that in December when the patch was first posted. This will be 
fixed when I post a radiotap RX patch that's actually signed off. No sign off 
from me means it's not done and probably not tested enough if at all.

-Michael Wu

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx  and tx
  2007-03-21 18:10 ` [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx Johannes Berg
  2007-03-22 22:58   ` Michael Wu
@ 2007-03-23  8:57   ` Andy Green
  2007-03-23 13:57     ` Johannes Berg
  1 sibling, 1 reply; 25+ messages in thread
From: Andy Green @ 2007-03-23  8:57 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Michael Wu, John Linville

Johannes Berg wrote:
> On Tue, 2007-03-20 at 10:39 +0000, andy@warmcat.com wrote:
> 
>> For injecting packets, the you issue a packet using libpcap or a SOCK_PACKET
>> socket down an interface to the wireless device that is in Monitor Mode.
> 
> Ok so people don't want to have this in cfg80211, all the better for me
> since it's less work.

$ cd wireless-dev
$ grep cfg80211 Documentation/* -R

As a Johnny-come-lately noob, how should I find out that cfg80211 either 
exists or how it works?  Far from some kind of turf war initiating 
gauntlet throwing, I was unaware cfg80211 was an option.

My interest is being able to inject broadcast packets from userspace 
with fine control over how it goes out.  I have now tried several ways 
to get that to happen with varying success, patching drivers in the old 
stack (worked but impractical for wide uptake), using the management 
interface in the new stack (works but it is heading towards deprecation 
and did not allow rate control) and finally the Monitor mode injection 
(works perfectly but requires to convince you guys to include it).

send()ing packets back up a Monitor Mode interface with the same 
radiotap semantics as the came out of it with is the most natural and 
portable (libpcap pcap_inject() just works with it on the same network 
interface as it can capture on) way to do injection from a usermode and 
architectural standpoint.

I wouldn't say it is the "best" way to push the weirdo wext/prism Ioctls 
out of the stack, I don't know enough about the details of it, but I 
don't think this and the cfg80211 methods need to be in conflict.  In a 
real sense you can look at this patchset as intending to max out the 
promise of libpcap to usermode.  Sine they then have enough tools, if 
someone wants to implement a userspace MLME or other unthinkable hacks 
in userspace their way is open without any more kernelside cooperation 
needed.

> I urge you to solve the issues with this injection interface, we've
> established that you can use packet filters to grab only management
> frames but monitor interfaces definitely still interact very badly with
> power management, and when the hardware has a BSS filter then this will
> also be disabled with a monitor interface (if monitor during operation
> is supported) which again puts more load on the host.

Those aren't issues with "this injection interface" but in optimizing 
the receive action for the existing Monitor mode.

> I have previously suggested to use the IFF_PROMISC bit for this, but
> this will also need good driver/stack API since currently drivers that
> support monitor during operation will just turn off BSS filters and such
> when a monitor interface is added. That will have to be changed in
> drivers as well.

Sure.  Monitor mode can deliver sensible default results with 
IFF_PROMISC off: it will just show traffic that was flying about inside 
the associated connection with the client anyway.  Just making the only 
way to enable hardware promisc being via IFF_PROMISC ioctl handler will 
allow control over whether you want to see everything with the power hit 
(the power hit doesn't matter for a box wired to the mains) or you just 
want to see things aimed at you.  So it sounds like a good enhancement 
exploiting an existing traditional attribute whatever way you look at it.

> Also, and I'm going to reply to your patches as well, this is not
> something that should be restricted to mac80211 since cfg80211
> generically supports virtual interfaces and anybody could in theory use
> a userspace MLME even with a full-mac card given a special no-management
> firmware mode. Hence, this should be documented for cfg80211 users.

I don't understand why Monitor Mode injection needs to fly under the 
cfg80211 flag.  It seems to belong to mac80211 code and would continue 
to work if cfg80211 was disabled.  Can you explain a bit more why it 
logically belongs in that category?

-Andy

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX
  2007-03-22 23:18     ` Michael Wu
@ 2007-03-23 13:44       ` Johannes Berg
  0 siblings, 0 replies; 25+ messages in thread
From: Johannes Berg @ 2007-03-23 13:44 UTC (permalink / raw)
  To: Michael Wu; +Cc: andy, linux-wireless

[-- Attachment #1: Type: text/plain, Size: 804 bytes --]

On Thu, 2007-03-22 at 19:18 -0400, Michael Wu wrote:

> >  1) it needs a lot more documentation on what a driver needs to do for
> >     this (for example that it should only add radiotap headers if a
> >     monitor interface was added)
> >
> Lack of documentation makes code not work?

Heh, no, but it adds new driver API.

> >  2) afaik local->monitors is increased even for soft monitor interfaces,
> >     thus this will really fall on its nose when the driver supports
> >     radiotap but not monitor during operation.
> >
> Yes. I noted that in December when the patch was first posted. This will be 
> fixed when I post a radiotap RX patch that's actually signed off. No sign off 
> from me means it's not done and probably not tested enough if at all.

Ok, good.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx  and tx
  2007-03-23  8:57   ` Andy Green
@ 2007-03-23 13:57     ` Johannes Berg
  0 siblings, 0 replies; 25+ messages in thread
From: Johannes Berg @ 2007-03-23 13:57 UTC (permalink / raw)
  To: Andy Green; +Cc: linux-wireless, Michael Wu, John Linville

[-- Attachment #1: Type: text/plain, Size: 2303 bytes --]

On Fri, 2007-03-23 at 08:57 +0000, Andy Green wrote:

> $ cd wireless-dev
> $ grep cfg80211 Documentation/* -R
> 
> As a Johnny-come-lately noob, how should I find out that cfg80211 either 
> exists or how it works?  Far from some kind of turf war initiating 
> gauntlet throwing, I was unaware cfg80211 was an option.

Yep, my mistake. I blame lack of time and cooperation, nobody but me
seems to be actually interested in working on cfg80211.

> My interest is being able to inject broadcast packets from userspace 
> with fine control over how it goes out.  I have now tried several ways 
> to get that to happen with varying success, patching drivers in the old 
> stack (worked but impractical for wide uptake), using the management 
> interface in the new stack (works but it is heading towards deprecation 
> and did not allow rate control) and finally the Monitor mode injection 
> (works perfectly but requires to convince you guys to include it).

Yep, I know.

> send()ing packets back up a Monitor Mode interface with the same 
> radiotap semantics as the came out of it with is the most natural and 
> portable (libpcap pcap_inject() just works with it on the same network 
> interface as it can capture on) way to do injection from a usermode and 
> architectural standpoint.

Right, and I'm not saying it doesn't make sense. I'm just trying to say
that before we add this interface we really need to figure out whether
it's feasible that this interface replaces all the wext/prism ioctl foo.

> I don't understand why Monitor Mode injection needs to fly under the 
> cfg80211 flag.  It seems to belong to mac80211 code and would continue 
> to work if cfg80211 was disabled.  Can you explain a bit more why it 
> logically belongs in that category?

Because of the userspace MLME that cfg80211 needs to support. At the
second wireless summit in London we have decided that the userspace MLME
should be transparent to users in that they still simply use nl80211 and
the kernel forwards the requests to the userspace MLME and also forwards
the responses. Therefore, most of the userspace MLME handling needs to
live in cfg80211, which makes cfg80211 also the logical point to define
injection at since the userspace MLME requires it.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx  and tx
  2007-03-22 22:58   ` Michael Wu
@ 2007-03-23 14:01     ` Johannes Berg
  0 siblings, 0 replies; 25+ messages in thread
From: Johannes Berg @ 2007-03-23 14:01 UTC (permalink / raw)
  To: Michael Wu; +Cc: andy, linux-wireless, John Linville

[-- Attachment #1: Type: text/plain, Size: 1972 bytes --]

On Thu, 2007-03-22 at 18:58 -0400, Michael Wu wrote:

> Note that my patch predates the suggestion that IFF_PROMISC be used to turn on 
> monitor mode on the hardware. (2006-12-18) I merely updated it so that 
> monitor interfaces output radiotap whether or not the driver supports.

Right.

> This patch series is not meant to replace the management interface. 

I know. However, ultimately something that will grow out of this patch
series will replace the management interface, otherwise this just adds
redundant API.

> 1. Make it easy to flip monitor mode on and off in drivers and support your 
> IFF_PROMISC suggestion.
> 2. Make the use of radiotap by drivers configurable independently of monitor 
> mode.
> 3. Report the result of a TX through monitor interfaces after 
> ieee80211_tx_status is called. This requires new radiotap definitions.
> 4. Move things like radar detection and the rest of ieee80211_msg_* to 
> cfg/nl80211 if they are necessary.
> 5. Port hostap and wpa_supplicant to the new interface. Will require some fun 
> with packet filtering..
> 6. Kill the mgmt interface once and for all.
> 
> We don't need to replace the mgmt interface at once however. Addressing the 
> first two issues should be sufficient to merge the radiotap RX/TX patches. 
> After that, 3-6 can be done one by one.

Those are all good points, and 1 isn't even required for just this
injection stuff that Andy is after, but I don't like adding this API
without having a clear plan of how it can replace the management
interface. One of the things you haven't convinced me of is that you
will be able to convince the BSD people to add new radiotap definitions
that we need. Also, if we can't have a good way to know exactly and
easily which frame we have when we see one on ACK (the cookie thing
about mapping injected frames to status updates) then I don't see how
this can possibly replace the management interface.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 4/4] mac80211: Monitor mode radiotap-based packet injection
  2007-03-21 18:28   ` Johannes Berg
@ 2007-03-29 11:14     ` Andy Green
  2007-03-29 11:19       ` Johannes Berg
  0 siblings, 1 reply; 25+ messages in thread
From: Andy Green @ 2007-03-29 11:14 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Johannes Berg wrote:

Hi Johannes -

I am going to issue a new patch set for the injection stuff shortly, so 
I can reply to your comments with what has happened about them.

> The actual parsing should live in cfg80211 (preferably in a new file) so
> that others can use it. If it's a lot of code then add a new invisible
> Kconfig symbol for it that drivers/stacks can select.

I did this -- it's pretty small so I just added it to the Makefile.

>> +	 * There is also some pervacious arg padding, so that args
> 
> perwhat?

http://www.urbandictionary.com/define.php?term=pervacious

Rephrased to something less exciting.

>> +	static const u8 radiotap_entry_sizes[] = {
>> +		8, /* IEEE80211_RADIOTAP_TSFT */
>> +		1, /* IEEE80211_RADIOTAP_FLAGS */
> [...]
> 
> I'd prefer C99 style for this.

Shocked that stuff from as late as 1999 is allowed.  I normally use // 
myself, I was making a special effort.

>> +		return TXRX_DROP; /* version byte as magic */
> 
> Bad idea. At least the comment. If you mean "drop the packet if it has a
> radiotap version we don't parse" then say so.

the PRISM format stuff that this replaces (on rx anyway) has an explicit 
magic at the start.  Hence the thought to treat the version byte as a 
"magic".  But changed.

>> +	if (le32_to_cpu(rthdr->it_present) & 0x80000000) {
>> +		while (le32_to_cpu(*((u32 *)tap_arg)) & 0x80000000)
> 
> Use a constant for that, introduce one if necessary.

Done.

>> +	control->key_idx = -1; /* no encryption key */
> 
> Is there any way to indicate encryption? I think there might need to be
> for 802.11w.
> 
>> +	control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
>> +		IEEE80211_TXCTL_USE_CTS_PROTECT);
> 
> These really should be selectable as well.
> 
>> +	control->flags |= (IEEE80211_TXCTL_DO_NOT_ENCRYPT |
>> +		IEEE80211_TXCTL_NO_ACK);
> 
> And NO_ACK is a really really totally bad idea for a userspace MLME.
> Needs to be selectable for sure.

Yes to cover more usage cases setting more things is needed.  The game 
seems to be to set the elements of the control struct from the radiotap 
header.  For clear discussion here is the list of things that can be set 
in control, first the ones we allow control of with this patch

	int tx_rate; /* Transmit rate, given as the hw specific value for the
		      * rate (from struct ieee80211_rate) */
	u8 power_level;		/* per-packet transmit power level, in dBm */
	u8 antenna_sel_tx; 	/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */


and the ones we might possibly want to fiddle with

	int rts_cts_rate; /* Transmit rate for RTS/CTS frame, given as the hw
			   * specific value for the rate (from
			   * struct ieee80211_rate) */
	u32 flags;			       /* tx control flags defined
						* above */
	u8 retry_limit;		/* 1 = only first attempt, 2 = one retry, .. */
	s8 key_idx;		/* -1 = do not encrypt, >= 0 keyidx from
				 * hw->set_key() */
	u8 icv_len;		/* length of the ICV/MIC field in octets */
	u8 iv_len;		/* length of the IV field in octets */
	u8 tkip_key[16];	/* generated phase2/phase1 key for hw TKIP */
	u8 queue;		/* hardware queue to use for this frame;
				 * 0 = highest, hw->queues-1 = lowest */
	u8 sw_retry_attempt;	/* number of times hw has tried to
				 * transmit frame (not incl. hw retries) */
	int alt_retry_rate; /* retry rate for the last retries, given as the
			     * hw specific value for the rate (from
			     * struct ieee80211_rate). To be used to limit
			     * packet dropping when probing higher rates, if hw
			     * supports multiple retry rates. -1 = not used */

the flags are these

#define IEEE80211_TXCTL_REQ_TX_STATUS	(1<<0)/* request TX status 
callback for
						* this frame */
#define IEEE80211_TXCTL_DO_NOT_ENCRYPT	(1<<1) /* send this frame without
						* encryption; e.g., for EAPOL
						* frames */
#define IEEE80211_TXCTL_USE_RTS_CTS	(1<<2) /* use RTS-CTS before sending
						* frame */
#define IEEE80211_TXCTL_USE_CTS_PROTECT	(1<<3) /* use CTS protection for the
						* frame (e.g., for combined
						* 802.11g / 802.11b networks) */
#define IEEE80211_TXCTL_NO_ACK		(1<<4) /* tell the low level not to
						* wait for an ack */
#define IEEE80211_TXCTL_RATE_CTRL_PROBE	(1<<5)
#define IEEE80211_TXCTL_CLEAR_DST_MASK	(1<<6)
#define IEEE80211_TXCTL_REQUEUE		(1<<7)
#define IEEE80211_TXCTL_FIRST_FRAGMENT	(1<<8) /* this is a first fragment of
						* the frame */
#define IEEE80211_TXCTL_TKIP_NEW_PHASE1_KEY (1<<9)

I guess the method is to work out what is useful to control and to 
define a minimal set of new radiotap arg indexes to cover them, and 
propose it to the radiotap folks.

> We also need to be able to assign some magic cookie to a packet that we
> get back along with the packet so that we know when the injected packet
> has been acked by the peer.

The idea here is to synthesize an rx packet later after the tx has 
happened, reflecting the tx status back to userspace that way (if he 
elects to listen out for them)?

>> +	/* remove the radiotap header */
>> +	skb_pull(skb, le16_to_cpu(rthdr->it_len));
> 
> Shouldn't there be some sort of sanity check here so we don't pull too
> much if userspace asks us to?

The sanity check for length of the radiotap header vs length of the 
packet is done right after the mag-^H^H^H version test.  It is moved 
into the radiotap iteration init function in cfg80211 in the new patches.

-Andy


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 1/4] mac80211: Coding style cleanups
  2007-03-21 18:58   ` Johannes Berg
@ 2007-03-29 11:17     ` Andy Green
  0 siblings, 0 replies; 25+ messages in thread
From: Andy Green @ 2007-03-29 11:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Johannes Berg wrote:
> On Tue, 2007-03-20 at 10:39 +0000, andy@warmcat.com wrote:
> 
> I don't really see why this is necessary at all, but anyway.

Yeah I cam to the same view -- I changed the file to match your 
suggestions here and realized that the (many) existing function defs do 
not follow your style recommendation.  So I mass-changed them and it 
came to me I will only annoy the original author by this attempt at 
consistency.  I started breaking out code into other functions and I 
realized I wasn't taking enough care, because it wasn't what I was 
trying to achieve, and would have to test it, might introduce bugs and 
would be run out of town by a mob with pitchforks.

I deleted the patch and learned to stop getting a tic in my eye every 
time a line > 80 cols flys by.

-Andy

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 3/4] mac80211: Monitor mode radiotap injection docs
  2007-03-21 18:15   ` Johannes Berg
@ 2007-03-29 11:18     ` Andy Green
  2007-03-29 11:26       ` Johannes Berg
  0 siblings, 1 reply; 25+ messages in thread
From: Andy Green @ 2007-03-29 11:18 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Johannes Berg wrote:
> On Tue, 2007-03-20 at 10:39 +0000, andy@warmcat.com wrote:
> 
>> +++ b/Documentation/networking/mac80211-injection.txt
> 
> This needs to be for cfg80211.

Well, the actual injection action is happening in mac80211.  I think 
you're looking at it as a cfg80211 wext-replacing type thing and I am 
looking at it as completely generic mac80211 packet injection from 
userspace.

>> +Radiotap headers are variable-length and extensible, you can get most of the
>> +information you need to know on them from:
>> +
>> +./include/net/ieee80211_radiotap.h
>> +
>> +But note: all fields in the radiotap header are *little endian*.
>> +
>> +There is a fixed portion at the start which contains a u32 bitmap that defines
>> +if the possible argument is present or not.  At the moment there are only 13
>> +possible arguments defined, but in case we run out of space in the u32 it is
>> +defined that b31 set indicates that there is another u32 bitmap following, and
>> +the start of the arguments is moved forward 4 bytes each time.
> 
> Drop all that, it's generic radiotap description. Put it into another
> file if you want.

This kind of description makes documentation useful to the reader, who 
may never have heard of radiotap (it is not very visible in Google right 
now in a useful way).

>> +After the fixed part of the header, the arguments follow.
>> +
>> + - the arguments are all little-endian!
> 
> duplicated information.

Yes when documenting something, you duplicate critical information, it 
is not an error but a static Forward Error Correction technology for 
lossy readers.

>> +The ieee80211 header follows immediately afterwards, looking for example like
>> +this:
>> +
>> +	0x08, 0x01, 0x00, 0x00,
>> +	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
>> +	0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
>> +	0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
>> +	0x10, 0x86
>> +
>> +Then lastly there is the payload.
> 
> Scratch that, somebody who doesn't know how a IEEE 802.11 header looks
> like has no business reading that file anyway ;)

Everybody has to learn from nothing!

>> Libpcap can also be used,
>> +(which is easier than doing the work to bind the socket to the right
>> +interface), along the following lines:
>> +
>> +	ppcap = pcap_open_live(szInterfaceName, 800, 1, 20, szErrbuf);
>> +...
>> +	r = pcap_inject(ppcap, u8aSendBuffer, nLength);
>> +
>> +You can also find sources for a complete inject test applet here:
>> +
>> +http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer
> 
> Is it big enough to warrant being elsewhere? I don't see how an example
> program can be more than a few lines of code and then it could be
> included here as a C file.

It's ~380 lines.  It also knows how to conjure up management interfaces. 
  I can chop it down and put it in here if you feel it is important.

I appreciate the comments, but I am 100% sure that some correct 
documentation that may be over-chatty is better than no documentation at 
all.  After hesitating and starting to change it I left it as it is, if 
you still feel these things are important comment in that direction 
again on the new patch and I will grit my teeth and change it.

-Andy

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 4/4] mac80211: Monitor mode radiotap-based packet  injection
  2007-03-29 11:14     ` Andy Green
@ 2007-03-29 11:19       ` Johannes Berg
  2007-03-29 11:33         ` Andy Green
  0 siblings, 1 reply; 25+ messages in thread
From: Johannes Berg @ 2007-03-29 11:19 UTC (permalink / raw)
  To: Andy Green; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 3688 bytes --]

On Thu, 2007-03-29 at 12:14 +0100, Andy Green wrote:

> >> +	static const u8 radiotap_entry_sizes[] = {
> >> +		8, /* IEEE80211_RADIOTAP_TSFT */
> >> +		1, /* IEEE80211_RADIOTAP_FLAGS */
> > [...]
> > 
> > I'd prefer C99 style for this.
> 
> Shocked that stuff from as late as 1999 is allowed.  I normally use // 
> myself, I was making a special effort.

Oh, dang, that was ambiguous. I was thinking
static const u8 radiotap_entry_sizes[] = {
	[IEEE80211_RADIOTAP_TSFT] = 8,
	...

> Yes to cover more usage cases setting more things is needed.  The game 
> seems to be to set the elements of the control struct from the radiotap 
> header.  For clear discussion here is the list of things that can be set 
> in control, first the ones we allow control of with this patch
> 
> 	int tx_rate; /* Transmit rate, given as the hw specific value for the
> 		      * rate (from struct ieee80211_rate) */
> 	u8 power_level;		/* per-packet transmit power level, in dBm */
> 	u8 antenna_sel_tx; 	/* 0 = default/diversity, 1 = Ant0, 2 = Ant1 */
> 
> 
> and the ones we might possibly want to fiddle with
> 
> 	int rts_cts_rate; /* Transmit rate for RTS/CTS frame, given as the hw
> 			   * specific value for the rate (from
> 			   * struct ieee80211_rate) */
> 	u32 flags;			       /* tx control flags defined
> 						* above */
> 	u8 retry_limit;		/* 1 = only first attempt, 2 = one retry, .. */
> 	s8 key_idx;		/* -1 = do not encrypt, >= 0 keyidx from
> 				 * hw->set_key() */
> 	u8 icv_len;		/* length of the ICV/MIC field in octets */
> 	u8 iv_len;		/* length of the IV field in octets */
> 	u8 tkip_key[16];	/* generated phase2/phase1 key for hw TKIP */
> 	u8 queue;		/* hardware queue to use for this frame;
> 				 * 0 = highest, hw->queues-1 = lowest */
> 	u8 sw_retry_attempt;	/* number of times hw has tried to
> 				 * transmit frame (not incl. hw retries) */
> 	int alt_retry_rate; /* retry rate for the last retries, given as the
> 			     * hw specific value for the rate (from
> 			     * struct ieee80211_rate). To be used to limit
> 			     * packet dropping when probing higher rates, if hw
> 			     * supports multiple retry rates. -1 = not used */
> 
> the flags are these
> 
> #define IEEE80211_TXCTL_REQ_TX_STATUS	(1<<0)/* request TX status 
> callback for
> 						* this frame */
> #define IEEE80211_TXCTL_DO_NOT_ENCRYPT	(1<<1) /* send this frame without
> 						* encryption; e.g., for EAPOL
> 						* frames */
> #define IEEE80211_TXCTL_USE_RTS_CTS	(1<<2) /* use RTS-CTS before sending
> 						* frame */
> #define IEEE80211_TXCTL_USE_CTS_PROTECT	(1<<3) /* use CTS protection for the
> 						* frame (e.g., for combined
> 						* 802.11g / 802.11b networks) */
> #define IEEE80211_TXCTL_NO_ACK		(1<<4) /* tell the low level not to
> 						* wait for an ack */
> #define IEEE80211_TXCTL_RATE_CTRL_PROBE	(1<<5)
> #define IEEE80211_TXCTL_CLEAR_DST_MASK	(1<<6)
> #define IEEE80211_TXCTL_REQUEUE		(1<<7)
> #define IEEE80211_TXCTL_FIRST_FRAGMENT	(1<<8) /* this is a first fragment of
> 						* the frame */
> #define IEEE80211_TXCTL_TKIP_NEW_PHASE1_KEY (1<<9)
> 
> I guess the method is to work out what is useful to control and to 
> define a minimal set of new radiotap arg indexes to cover them, and 
> propose it to the radiotap folks.

Yeah, not really necessary right from the start anyway. It's doable
which is/was my biggest concern.

> The idea here is to synthesize an rx packet later after the tx has 
> happened, reflecting the tx status back to userspace that way (if he 
> elects to listen out for them)?

Yeah. Michael Wu says we don't need the magic cookie though.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 3/4] mac80211: Monitor mode radiotap injection docs
  2007-03-29 11:18     ` Andy Green
@ 2007-03-29 11:26       ` Johannes Berg
  0 siblings, 0 replies; 25+ messages in thread
From: Johannes Berg @ 2007-03-29 11:26 UTC (permalink / raw)
  To: Andy Green; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 1763 bytes --]

On Thu, 2007-03-29 at 12:18 +0100, Andy Green wrote:

> Well, the actual injection action is happening in mac80211.  I think 
> you're looking at it as a cfg80211 wext-replacing type thing and I am 
> looking at it as completely generic mac80211 packet injection from 
> userspace.

Yeah. Don't worry about it. We can move it later and define it for
cfg80211 when we introduce the userspace mlme stuff.

> > Drop all that, it's generic radiotap description. Put it into another
> > file if you want.
> 
> This kind of description makes documentation useful to the reader, who 
> may never have heard of radiotap (it is not very visible in Google right 
> now in a useful way).

Maybe just stick it into a radiotap file and refer to that? I'm just a
bit worried that it'll get outdated because somebody looking for
radiotap stuff won't find it here when updating. Not sure it can even
get outdated though.

> It's ~380 lines.  It also knows how to conjure up management interfaces. 
>   I can chop it down and put it in here if you feel it is important.

It's probably easy enough to write from the docs so probably not really
necessary. I think when I wrote this I was offline so couldn't actually
check out the demo program ;)

> I appreciate the comments, but I am 100% sure that some correct 
> documentation that may be over-chatty is better than no documentation at 
> all.  After hesitating and starting to change it I left it as it is, if 
> you still feel these things are important comment in that direction 
> again on the new patch and I will grit my teeth and change it.

No, don't take me too seriously. I appreciate documentation I may not
agree with in all points much more than the lack thereof :)

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 4/4] mac80211: Monitor mode radiotap-based packet injection
  2007-03-29 11:19       ` Johannes Berg
@ 2007-03-29 11:33         ` Andy Green
  2007-03-29 11:48           ` Johannes Berg
  0 siblings, 1 reply; 25+ messages in thread
From: Andy Green @ 2007-03-29 11:33 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

Johannes Berg wrote:
> On Thu, 2007-03-29 at 12:14 +0100, Andy Green wrote:
> 
>>>> +	static const u8 radiotap_entry_sizes[] = {
>>>> +		8, /* IEEE80211_RADIOTAP_TSFT */
>>>> +		1, /* IEEE80211_RADIOTAP_FLAGS */
>>> [...]
>>>
>>> I'd prefer C99 style for this.
>> Shocked that stuff from as late as 1999 is allowed.  I normally use // 
>> myself, I was making a special effort.
> 
> Oh, dang, that was ambiguous. I was thinking
> static const u8 radiotap_entry_sizes[] = {
> 	[IEEE80211_RADIOTAP_TSFT] = 8,
> 	...

Ha, well I will fix that up then.  I couldn't really understand how the 
coding style that insists to turn code into 80-col Bonsai Kittens can 
also allow //.

>> The idea here is to synthesize an rx packet later after the tx has 
>> happened, reflecting the tx status back to userspace that way (if he 
>> elects to listen out for them)?
> 
> Yeah. Michael Wu says we don't need the magic cookie though.

I missed this conversation evidently, didn't find it just now either. 
In case the plan is to block the thread doing the injection until the 
packet has gone out and is retired and can return an "acknowledged" 
status direct to the send()er, throughput is an issue.

-Andy

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 4/4] mac80211: Monitor mode radiotap-based  packet injection
  2007-03-29 11:33         ` Andy Green
@ 2007-03-29 11:48           ` Johannes Berg
  0 siblings, 0 replies; 25+ messages in thread
From: Johannes Berg @ 2007-03-29 11:48 UTC (permalink / raw)
  To: Andy Green; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 769 bytes --]

On Thu, 2007-03-29 at 12:33 +0100, Andy Green wrote:

> I missed this conversation evidently, didn't find it just now either. 

Sorry. It was on IRC.

> In case the plan is to block the thread doing the injection until the 
> packet has gone out and is retired and can return an "acknowledged" 
> status direct to the send()er, throughput is an issue.

I don't think that's the plan. But apparently the current interface
doesn't allow userspace to exactly map the sent packet to the tx status
it gets in the monitor interface (when the sent packet shows up there).
I'm a bit worried that it would need such an exact mapping especially
when others may be injecting frames at the same time, but I suppose that
can be solved when we get to it.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2007-03-29 11:49 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-20 10:39 [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx andy
2007-03-20 10:39 ` [PATCH 1/4] mac80211: Coding style cleanups andy
2007-03-21 18:58   ` Johannes Berg
2007-03-29 11:17     ` Andy Green
2007-03-20 10:39 ` [PATCH 2/4] mac80211: Add radiotap support for Monitor mode RX andy
2007-03-21 18:51   ` Johannes Berg
2007-03-22 23:18     ` Michael Wu
2007-03-23 13:44       ` Johannes Berg
2007-03-20 10:39 ` [PATCH 3/4] mac80211: Monitor mode radiotap injection docs andy
2007-03-21 18:15   ` Johannes Berg
2007-03-29 11:18     ` Andy Green
2007-03-29 11:26       ` Johannes Berg
2007-03-20 10:39 ` [PATCH 4/4] mac80211: Monitor mode radiotap-based packet injection andy
2007-03-21 18:28   ` Johannes Berg
2007-03-29 11:14     ` Andy Green
2007-03-29 11:19       ` Johannes Berg
2007-03-29 11:33         ` Andy Green
2007-03-29 11:48           ` Johannes Berg
2007-03-21 18:10 ` [PATCH 0/4] Try #5: Radiotap on Monitor Mode interfaces for rx and tx Johannes Berg
2007-03-22 22:58   ` Michael Wu
2007-03-23 14:01     ` Johannes Berg
2007-03-23  8:57   ` Andy Green
2007-03-23 13:57     ` Johannes Berg
2007-03-21 18:46 ` Johannes Berg
2007-03-22 23:10   ` Michael Wu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.