Search Linux Wireless

[PATCH] iwlwifi: Make packet injection work in iwl3945

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

 



We currently forbid injecting packets in monitor mode for iwl3945, but
it's done in an unsafe way, that can result in various issues. This
patch enables injecting packets in monitor mode. The patch is also
available as an attachment in case Gmail decides to corrupt it.

John, please apply to 2.6.27. You might also want to apply it to
2.6.26, but it's not tested there.

Signed-off-by: Gábor Stefanik <netrolller.3d@xxxxxxxxx>

---
diff -ru8p compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c
compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c	2008-06-04
06:10:49.000000000 +0200
+++ compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c	2008-06-04
22:34:32.000000000 +0200
@@ -2532,16 +2532,19 @@ static int iwl3945_get_sta_id(struct iwl
 			return sta_id;

 		IWL_DEBUG_DROP("Station %s not in station map. "
 			       "Defaulting to broadcast...\n",
 			       print_mac(mac, hdr->addr1));
 		iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
 		return priv->hw_setting.bcast_sta_id;
 	}
+	/* If we are in monitor mode, use BCAST */
+	case IEEE80211_IF_TYPE_MNTR:
+		return priv->hw_setting.bcast_sta_id;
 	default:
 		IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
 		return priv->hw_setting.bcast_sta_id;
 	}
 }

 /*
  * start REPLY_TX command process
@@ -2571,21 +2574,16 @@ static int iwl3945_tx_skb(struct iwl3945
 	int rc;

 	spin_lock_irqsave(&priv->lock, flags);
 	if (iwl3945_is_rfkill(priv)) {
 		IWL_DEBUG_DROP("Dropping - RF KILL\n");
 		goto drop_unlock;
 	}

-	if (!priv->vif) {
-		IWL_DEBUG_DROP("Dropping - !priv->vif\n");
-		goto drop_unlock;
-	}
-
 	if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) ==
IWL_INVALID_RATE) {
 		IWL_ERROR("ERROR: No TX rate available.\n");
 		goto drop_unlock;
 	}

 	unicast = !is_multicast_ether_addr(hdr->addr1);
 	id = 0;

@@ -2595,24 +2593,16 @@ static int iwl3945_tx_skb(struct iwl3945
 	if (ieee80211_is_auth(fc))
 		IWL_DEBUG_TX("Sending AUTH frame\n");
 	else if (ieee80211_is_assoc_request(fc))
 		IWL_DEBUG_TX("Sending ASSOC frame\n");
 	else if (ieee80211_is_reassoc_request(fc))
 		IWL_DEBUG_TX("Sending REASSOC frame\n");
 #endif

-	/* drop all data frame if we are not associated */
-	if ((!iwl3945_is_associated(priv) ||
-	     ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
-	    ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
-		IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
-		goto drop_unlock;
-	}
-
 	spin_unlock_irqrestore(&priv->lock, flags);

 	hdr_len = ieee80211_get_hdrlen(fc);

 	/* Find (or create) index into station table for destination station */
 	sta_id = iwl3945_get_sta_id(priv, hdr);
 	if (sta_id == IWL_INVALID_STATION) {
 		DECLARE_MAC_BUF(mac);
@@ -6334,17 +6324,17 @@ static void iwl3945_bg_request_scan(stru
 		IWL_WARNING("Invalid scan band count\n");
 		goto done;
 	}

 	/* select Rx antennas */
 	scan->flags |= iwl3945_get_antenna_flags(priv);

 	if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
-		scan->filter_flags = RXON_FILTER_PROMISC_MSK;
+		scan->filter_flags |= RXON_FILTER_PROMISC_MSK |
RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;

 	if (direct_mask)
 		scan->channel_count =
 			iwl3945_get_channels_for_scan(
 				priv, band, 1, /* active */
 				direct_mask,
 				(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 	else
@@ -6660,38 +6650,33 @@ static void iwl3945_mac_stop(struct ieee
 		 * RXON_FILTER_ASSOC_MSK BIT
 		 */
 		mutex_lock(&priv->mutex);
 		iwl3945_scan_cancel_timeout(priv, 100);
 		cancel_delayed_work(&priv->post_associate);
 		mutex_unlock(&priv->mutex);
 	}

 	iwl3945_down(priv);

 	flush_workqueue(priv->workqueue);
 	free_irq(priv->pci_dev->irq, priv);
 	pci_disable_msi(priv->pci_dev);
 	pci_save_state(priv->pci_dev);
 	pci_disable_device(priv->pci_dev);

 	IWL_DEBUG_MAC80211("leave\n");
 }

 static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct iwl3945_priv *priv = hw->priv;

 	IWL_DEBUG_MAC80211("enter\n");

-	if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-		IWL_DEBUG_MAC80211("leave - monitor\n");
-		return -1;
-	}
-
 	IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
 		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);

 	if (iwl3945_tx_skb(priv, skb))
 		dev_kfree_skb_any(skb);

 	IWL_DEBUG_MAC80211("leave\n");
 	return 0;
diff -ru8p compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c
--- compat-wireless-2008-06-04.orig/drivers/net/wireless/iwlwifi/iwl3945-base.c	2008-06-04 06:10:49.000000000 +0200
+++ compat-wireless-2008-06-04/drivers/net/wireless/iwlwifi/iwl3945-base.c	2008-06-04 22:34:32.000000000 +0200
@@ -2532,16 +2532,19 @@ static int iwl3945_get_sta_id(struct iwl
 			return sta_id;
 
 		IWL_DEBUG_DROP("Station %s not in station map. "
 			       "Defaulting to broadcast...\n",
 			       print_mac(mac, hdr->addr1));
 		iwl3945_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
 		return priv->hw_setting.bcast_sta_id;
 	}
+	/* If we are in monitor mode, use BCAST */
+	case IEEE80211_IF_TYPE_MNTR:
+		return priv->hw_setting.bcast_sta_id;
 	default:
 		IWL_WARNING("Unknown mode of operation: %d", priv->iw_mode);
 		return priv->hw_setting.bcast_sta_id;
 	}
 }
 
 /*
  * start REPLY_TX command process
@@ -2571,21 +2574,16 @@ static int iwl3945_tx_skb(struct iwl3945
 	int rc;
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (iwl3945_is_rfkill(priv)) {
 		IWL_DEBUG_DROP("Dropping - RF KILL\n");
 		goto drop_unlock;
 	}
 
-	if (!priv->vif) {
-		IWL_DEBUG_DROP("Dropping - !priv->vif\n");
-		goto drop_unlock;
-	}
-
 	if ((ieee80211_get_tx_rate(priv->hw, info)->hw_value & 0xFF) == IWL_INVALID_RATE) {
 		IWL_ERROR("ERROR: No TX rate available.\n");
 		goto drop_unlock;
 	}
 
 	unicast = !is_multicast_ether_addr(hdr->addr1);
 	id = 0;
 
@@ -2595,24 +2593,16 @@ static int iwl3945_tx_skb(struct iwl3945
 	if (ieee80211_is_auth(fc))
 		IWL_DEBUG_TX("Sending AUTH frame\n");
 	else if (ieee80211_is_assoc_request(fc))
 		IWL_DEBUG_TX("Sending ASSOC frame\n");
 	else if (ieee80211_is_reassoc_request(fc))
 		IWL_DEBUG_TX("Sending REASSOC frame\n");
 #endif
 
-	/* drop all data frame if we are not associated */
-	if ((!iwl3945_is_associated(priv) ||
-	     ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && !priv->assoc_id)) &&
-	    ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) {
-		IWL_DEBUG_DROP("Dropping - !iwl3945_is_associated\n");
-		goto drop_unlock;
-	}
-
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	hdr_len = ieee80211_get_hdrlen(fc);
 
 	/* Find (or create) index into station table for destination station */
 	sta_id = iwl3945_get_sta_id(priv, hdr);
 	if (sta_id == IWL_INVALID_STATION) {
 		DECLARE_MAC_BUF(mac);
@@ -6334,17 +6324,17 @@ static void iwl3945_bg_request_scan(stru
 		IWL_WARNING("Invalid scan band count\n");
 		goto done;
 	}
 
 	/* select Rx antennas */
 	scan->flags |= iwl3945_get_antenna_flags(priv);
 
 	if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR)
-		scan->filter_flags = RXON_FILTER_PROMISC_MSK;
+		scan->filter_flags |= RXON_FILTER_PROMISC_MSK | RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
 
 	if (direct_mask)
 		scan->channel_count =
 			iwl3945_get_channels_for_scan(
 				priv, band, 1, /* active */
 				direct_mask,
 				(void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 	else
@@ -6660,38 +6650,33 @@ static void iwl3945_mac_stop(struct ieee
 		 * RXON_FILTER_ASSOC_MSK BIT
 		 */
 		mutex_lock(&priv->mutex);
 		iwl3945_scan_cancel_timeout(priv, 100);
 		cancel_delayed_work(&priv->post_associate);
 		mutex_unlock(&priv->mutex);
 	}
 
 	iwl3945_down(priv);
 
 	flush_workqueue(priv->workqueue);
 	free_irq(priv->pci_dev->irq, priv);
 	pci_disable_msi(priv->pci_dev);
 	pci_save_state(priv->pci_dev);
 	pci_disable_device(priv->pci_dev);
 
 	IWL_DEBUG_MAC80211("leave\n");
 }
 
 static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct iwl3945_priv *priv = hw->priv;
 
 	IWL_DEBUG_MAC80211("enter\n");
 
-	if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
-		IWL_DEBUG_MAC80211("leave - monitor\n");
-		return -1;
-	}
-
 	IWL_DEBUG_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
 		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
 
 	if (iwl3945_tx_skb(priv, skb))
 		dev_kfree_skb_any(skb);
 
 	IWL_DEBUG_MAC80211("leave\n");
 	return 0;

[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