Search Linux Wireless

[PATCH 2/2] p54: enable proper frame injection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch enables frame injection in monitor mode for all p54 devices.
As a result, any user can finally use the aircrack-ng suite out of the box.

e.g:
aireplay-ng --test wlan0
Trying broadcast probe requests...
Injection is working!
Found 1 AP

Trying directed probe requests...
XX:XX:XX:XX:XX:XX - channel: i - 'SSID'
Ping (min/avg/max): 1.536ms/3.193ms/4.377ms Power: 193.00
30/30: 100%

Signed-off-by: Christian Lamparter <chunkeey@xxxxxx>
---
diff -Nurp a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
--- a/drivers/net/wireless/p54/p54common.c	2008-12-21 18:05:02.000000000 +0100
+++ b/drivers/net/wireless/p54/p54common.c	2008-12-21 19:52:47.000000000 +0100
@@ -760,9 +760,16 @@ static void p54_rx_frame_sent(struct iee
 		priv->tx_stats[entry_data->hw_queue].len--;
 		priv->stats.dot11ACKFailureCount += payload->tries - 1;
 
-		if (unlikely(entry == priv->cached_beacon)) {
+		/*
+		 * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
+		 * generated by the driver. Therefore tx_status is bogus
+		 * and we don't want to confuse the mac80211 stack.
+		 */
+		if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
+			if (entry_data->hw_queue == P54_QUEUE_BEACON)
+				priv->cached_beacon = NULL;
+
 			kfree_skb(entry);
-			priv->cached_beacon = NULL;
 			goto out;
 		}
 
@@ -1212,33 +1219,26 @@ static int p54_tx_fill(struct ieee80211_
 {
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct p54_common *priv = dev->priv;
-	int ret = 0;
-
-	if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
-		if (ieee80211_is_beacon(hdr->frame_control)) {
-			*aid = 0;
-			*queue = P54_QUEUE_BEACON;
-			*extra_len = IEEE80211_MAX_TIM_LEN;
-			*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
-			return 0;
-		} else if (ieee80211_is_probe_resp(hdr->frame_control)) {
-			*aid = 0;
-			*queue = P54_QUEUE_MGMT;
-			*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
-				 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
-			return 0;
-		} else {
-			*queue = P54_QUEUE_MGMT;
-			ret = 0;
-		}
-	} else {
-		*queue += P54_QUEUE_DATA;
-		ret = 1;
-	}
+	int ret = 1;
 
 	switch (priv->mode) {
+	case NL80211_IFTYPE_MONITOR:
+		/*
+		 * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
+		 * every frame in promiscuous/monitor mode.
+		 * see STSW45x0C LMAC API - page 12.
+		 */
+		*aid = 0;
+		*flags = P54_HDR_FLAG_DATA_OUT_PROMISC;
+		*queue += P54_QUEUE_DATA;
+		break;
 	case NL80211_IFTYPE_STATION:
 		*aid = 1;
+		if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+			*queue = P54_QUEUE_MGMT;
+			ret = 0;
+		} else
+			*queue += P54_QUEUE_DATA;
 		break;
 	case NL80211_IFTYPE_AP:
 	case NL80211_IFTYPE_ADHOC:
@@ -1248,10 +1248,44 @@ static int p54_tx_fill(struct ieee80211_
 			*queue = P54_QUEUE_CAB;
 			return 0;
 		}
+
+		if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
+			if (ieee80211_is_probe_resp(hdr->frame_control)) {
+				*aid = 0;
+				*queue = P54_QUEUE_MGMT;
+				*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
+					 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+				return 0;
+			} else if (ieee80211_is_beacon(hdr->frame_control)) {
+				*aid = 0;
+
+				if (info->flags & IEEE80211_TX_CTL_INJECTED) {
+					/*
+					 * Injecting beacons on top of a AP is
+					 * not a good idea... nevertheless,
+					 * it should be doable.
+					 */
+
+					*queue += P54_QUEUE_DATA;
+					return 1;
+				}
+
+				*flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
+				*queue = P54_QUEUE_BEACON;
+				*extra_len = IEEE80211_MAX_TIM_LEN;
+				return 0;
+			} else {
+				*queue = P54_QUEUE_MGMT;
+				ret = 0;
+			}
+		} else
+			*queue += P54_QUEUE_DATA;
+
 		if (info->control.sta)
 			*aid = info->control.sta->aid;
 		else
 			*flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
+		break;
 	}
 	return ret;
 }
@@ -1469,11 +1503,20 @@ static int p54_setup_mac(struct ieee8021
 		case NL80211_IFTYPE_MESH_POINT:
 			mode = P54_FILTER_TYPE_IBSS;
 			break;
+		case NL80211_IFTYPE_MONITOR:
+			mode = P54_FILTER_TYPE_PROMISCUOUS;
+			break;
 		default:
 			mode = P54_FILTER_TYPE_NONE;
 			break;
 		}
-		if (priv->filter_flags & FIF_PROMISC_IN_BSS)
+
+		/*
+		 * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
+		 * STSW45X0C LMAC API - page 12
+		 */
+		if ((priv->filter_flags & FIF_PROMISC_IN_BSS) &&
+		    (mode != P54_FILTER_TYPE_PROMISCUOUS))
 			mode |= P54_FILTER_TYPE_TRANSPARENT;
 	} else
 		mode = P54_FILTER_TYPE_RX_DISABLED;
@@ -2145,6 +2188,7 @@ struct ieee80211_hw *p54_init_common(siz
 
 	dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
 				      BIT(NL80211_IFTYPE_ADHOC) |
+				      BIT(NL80211_IFTYPE_MONITOR) |
 				      BIT(NL80211_IFTYPE_AP) |
 				      BIT(NL80211_IFTYPE_MESH_POINT);
 
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux