diff options
author | Christian Lamparter <chunkeey@web.de> | 2008-12-21 16:52:10 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 15:58:44 -0500 |
commit | 29701e5abf155d76fc8ab785a172c4ccf6cf47ee (patch) | |
tree | bdf9e9d5582a7754b124439b7674d56302918a6e /drivers/net/wireless/p54 | |
parent | a15bd00543a859a72546e4b09342b70e79e9ef1e (diff) |
p54: enable proper frame injection
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@web.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54')
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 95 |
1 files changed, 69 insertions, 26 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index 3298cb464f7..28d98338957 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c | |||
@@ -775,9 +775,16 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
775 | priv->tx_stats[entry_data->hw_queue].len--; | 775 | priv->tx_stats[entry_data->hw_queue].len--; |
776 | priv->stats.dot11ACKFailureCount += payload->tries - 1; | 776 | priv->stats.dot11ACKFailureCount += payload->tries - 1; |
777 | 777 | ||
778 | if (unlikely(entry == priv->cached_beacon)) { | 778 | /* |
779 | * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are | ||
780 | * generated by the driver. Therefore tx_status is bogus | ||
781 | * and we don't want to confuse the mac80211 stack. | ||
782 | */ | ||
783 | if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) { | ||
784 | if (entry_data->hw_queue == P54_QUEUE_BEACON) | ||
785 | priv->cached_beacon = NULL; | ||
786 | |||
779 | kfree_skb(entry); | 787 | kfree_skb(entry); |
780 | priv->cached_beacon = NULL; | ||
781 | goto out; | 788 | goto out; |
782 | } | 789 | } |
783 | 790 | ||
@@ -1240,33 +1247,26 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1240 | { | 1247 | { |
1241 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1248 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1242 | struct p54_common *priv = dev->priv; | 1249 | struct p54_common *priv = dev->priv; |
1243 | int ret = 0; | 1250 | int ret = 1; |
1244 | |||
1245 | if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) { | ||
1246 | if (ieee80211_is_beacon(hdr->frame_control)) { | ||
1247 | *aid = 0; | ||
1248 | *queue = P54_QUEUE_BEACON; | ||
1249 | *extra_len = IEEE80211_MAX_TIM_LEN; | ||
1250 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP; | ||
1251 | return 0; | ||
1252 | } else if (ieee80211_is_probe_resp(hdr->frame_control)) { | ||
1253 | *aid = 0; | ||
1254 | *queue = P54_QUEUE_MGMT; | ||
1255 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP | | ||
1256 | P54_HDR_FLAG_DATA_OUT_NOCANCEL; | ||
1257 | return 0; | ||
1258 | } else { | ||
1259 | *queue = P54_QUEUE_MGMT; | ||
1260 | ret = 0; | ||
1261 | } | ||
1262 | } else { | ||
1263 | *queue += P54_QUEUE_DATA; | ||
1264 | ret = 1; | ||
1265 | } | ||
1266 | 1251 | ||
1267 | switch (priv->mode) { | 1252 | switch (priv->mode) { |
1253 | case NL80211_IFTYPE_MONITOR: | ||
1254 | /* | ||
1255 | * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for | ||
1256 | * every frame in promiscuous/monitor mode. | ||
1257 | * see STSW45x0C LMAC API - page 12. | ||
1258 | */ | ||
1259 | *aid = 0; | ||
1260 | *flags = P54_HDR_FLAG_DATA_OUT_PROMISC; | ||
1261 | *queue += P54_QUEUE_DATA; | ||
1262 | break; | ||
1268 | case NL80211_IFTYPE_STATION: | 1263 | case NL80211_IFTYPE_STATION: |
1269 | *aid = 1; | 1264 | *aid = 1; |
1265 | if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) { | ||
1266 | *queue = P54_QUEUE_MGMT; | ||
1267 | ret = 0; | ||
1268 | } else | ||
1269 | *queue += P54_QUEUE_DATA; | ||
1270 | break; | 1270 | break; |
1271 | case NL80211_IFTYPE_AP: | 1271 | case NL80211_IFTYPE_AP: |
1272 | case NL80211_IFTYPE_ADHOC: | 1272 | case NL80211_IFTYPE_ADHOC: |
@@ -1276,10 +1276,44 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1276 | *queue = P54_QUEUE_CAB; | 1276 | *queue = P54_QUEUE_CAB; |
1277 | return 0; | 1277 | return 0; |
1278 | } | 1278 | } |
1279 | |||
1280 | if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) { | ||
1281 | if (ieee80211_is_probe_resp(hdr->frame_control)) { | ||
1282 | *aid = 0; | ||
1283 | *queue = P54_QUEUE_MGMT; | ||
1284 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP | | ||
1285 | P54_HDR_FLAG_DATA_OUT_NOCANCEL; | ||
1286 | return 0; | ||
1287 | } else if (ieee80211_is_beacon(hdr->frame_control)) { | ||
1288 | *aid = 0; | ||
1289 | |||
1290 | if (info->flags & IEEE80211_TX_CTL_INJECTED) { | ||
1291 | /* | ||
1292 | * Injecting beacons on top of a AP is | ||
1293 | * not a good idea... nevertheless, | ||
1294 | * it should be doable. | ||
1295 | */ | ||
1296 | |||
1297 | *queue += P54_QUEUE_DATA; | ||
1298 | return 1; | ||
1299 | } | ||
1300 | |||
1301 | *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP; | ||
1302 | *queue = P54_QUEUE_BEACON; | ||
1303 | *extra_len = IEEE80211_MAX_TIM_LEN; | ||
1304 | return 0; | ||
1305 | } else { | ||
1306 | *queue = P54_QUEUE_MGMT; | ||
1307 | ret = 0; | ||
1308 | } | ||
1309 | } else | ||
1310 | *queue += P54_QUEUE_DATA; | ||
1311 | |||
1279 | if (info->control.sta) | 1312 | if (info->control.sta) |
1280 | *aid = info->control.sta->aid; | 1313 | *aid = info->control.sta->aid; |
1281 | else | 1314 | else |
1282 | *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; | 1315 | *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; |
1316 | break; | ||
1283 | } | 1317 | } |
1284 | return ret; | 1318 | return ret; |
1285 | } | 1319 | } |
@@ -1497,11 +1531,20 @@ static int p54_setup_mac(struct ieee80211_hw *dev) | |||
1497 | case NL80211_IFTYPE_MESH_POINT: | 1531 | case NL80211_IFTYPE_MESH_POINT: |
1498 | mode = P54_FILTER_TYPE_IBSS; | 1532 | mode = P54_FILTER_TYPE_IBSS; |
1499 | break; | 1533 | break; |
1534 | case NL80211_IFTYPE_MONITOR: | ||
1535 | mode = P54_FILTER_TYPE_PROMISCUOUS; | ||
1536 | break; | ||
1500 | default: | 1537 | default: |
1501 | mode = P54_FILTER_TYPE_NONE; | 1538 | mode = P54_FILTER_TYPE_NONE; |
1502 | break; | 1539 | break; |
1503 | } | 1540 | } |
1504 | if (priv->filter_flags & FIF_PROMISC_IN_BSS) | 1541 | |
1542 | /* | ||
1543 | * "TRANSPARENT and PROMISCUOUS are mutually exclusive" | ||
1544 | * STSW45X0C LMAC API - page 12 | ||
1545 | */ | ||
1546 | if ((priv->filter_flags & FIF_PROMISC_IN_BSS) && | ||
1547 | (mode != P54_FILTER_TYPE_PROMISCUOUS)) | ||
1505 | mode |= P54_FILTER_TYPE_TRANSPARENT; | 1548 | mode |= P54_FILTER_TYPE_TRANSPARENT; |
1506 | } else | 1549 | } else |
1507 | mode = P54_FILTER_TYPE_RX_DISABLED; | 1550 | mode = P54_FILTER_TYPE_RX_DISABLED; |