aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorAndy Green <andy@warmcat.com>2007-07-10 13:32:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2007-07-12 16:07:24 -0400
commite4c967c6d88ca94365dd8e2a7bbd22eedb8d7ae7 (patch)
treeae6e1d6335018c2540b5fd58c679e4bdd5c05dfd /net/mac80211
parent179f831bc33104d14deb54a52b7a8b43433f8ccc (diff)
[PATCH] mac80211: Monitor mode radiotap-based packet injection
Signed-off-by: Andy Green <andy@warmcat.com> Signed-off-by: Jiri Benc <jbenc@suse.cz> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/ieee80211.c234
1 files changed, 224 insertions, 10 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c
index 4e84f24fd439..8b57eaa2a271 100644
--- a/net/mac80211/ieee80211.c
+++ b/net/mac80211/ieee80211.c
@@ -24,6 +24,7 @@
24#include <linux/compiler.h> 24#include <linux/compiler.h>
25#include <linux/bitmap.h> 25#include <linux/bitmap.h>
26#include <net/cfg80211.h> 26#include <net/cfg80211.h>
27#include <asm/unaligned.h>
27 28
28#include "ieee80211_common.h" 29#include "ieee80211_common.h"
29#include "ieee80211_i.h" 30#include "ieee80211_i.h"
@@ -1118,7 +1119,138 @@ ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx)
1118} 1119}
1119 1120
1120 1121
1121static void inline 1122/*
1123 * deal with packet injection down monitor interface
1124 * with Radiotap Header -- only called for monitor mode interface
1125 */
1126
1127static ieee80211_txrx_result
1128__ieee80211_parse_tx_radiotap(
1129 struct ieee80211_txrx_data *tx,
1130 struct sk_buff *skb, struct ieee80211_tx_control *control)
1131{
1132 /*
1133 * this is the moment to interpret and discard the radiotap header that
1134 * must be at the start of the packet injected in Monitor mode
1135 *
1136 * Need to take some care with endian-ness since radiotap
1137 * args are little-endian
1138 */
1139
1140 struct ieee80211_radiotap_iterator iterator;
1141 struct ieee80211_radiotap_header *rthdr =
1142 (struct ieee80211_radiotap_header *) skb->data;
1143 struct ieee80211_hw_mode *mode = tx->local->hw.conf.mode;
1144 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
1145
1146 /*
1147 * default control situation for all injected packets
1148 * FIXME: this does not suit all usage cases, expand to allow control
1149 */
1150
1151 control->retry_limit = 1; /* no retry */
1152 control->key_idx = -1; /* no encryption key */
1153 control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
1154 IEEE80211_TXCTL_USE_CTS_PROTECT);
1155 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT |
1156 IEEE80211_TXCTL_NO_ACK;
1157 control->antenna_sel_tx = 0; /* default to default antenna */
1158
1159 /*
1160 * for every radiotap entry that is present
1161 * (ieee80211_radiotap_iterator_next returns -ENOENT when no more
1162 * entries present, or -EINVAL on error)
1163 */
1164
1165 while (!ret) {
1166 int i, target_rate;
1167
1168 ret = ieee80211_radiotap_iterator_next(&iterator);
1169
1170 if (ret)
1171 continue;
1172
1173 /* see if this argument is something we can use */
1174 switch (iterator.this_arg_index) {
1175 /*
1176 * You must take care when dereferencing iterator.this_arg
1177 * for multibyte types... the pointer is not aligned. Use
1178 * get_unaligned((type *)iterator.this_arg) to dereference
1179 * iterator.this_arg for type "type" safely on all arches.
1180 */
1181 case IEEE80211_RADIOTAP_RATE:
1182 /*
1183 * radiotap rate u8 is in 500kbps units eg, 0x02=1Mbps
1184 * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps
1185 */
1186 target_rate = (*iterator.this_arg) * 5;
1187 for (i = 0; i < mode->num_rates; i++) {
1188 struct ieee80211_rate *r = &mode->rates[i];
1189
1190 if (r->rate > target_rate)
1191 continue;
1192
1193 control->rate = r;
1194
1195 if (r->flags & IEEE80211_RATE_PREAMBLE2)
1196 control->tx_rate = r->val2;
1197 else
1198 control->tx_rate = r->val;
1199
1200 /* end on exact match */
1201 if (r->rate == target_rate)
1202 i = mode->num_rates;
1203 }
1204 break;
1205
1206 case IEEE80211_RADIOTAP_ANTENNA:
1207 /*
1208 * radiotap uses 0 for 1st ant, mac80211 is 1 for
1209 * 1st ant
1210 */
1211 control->antenna_sel_tx = (*iterator.this_arg) + 1;
1212 break;
1213
1214 case IEEE80211_RADIOTAP_DBM_TX_POWER:
1215 control->power_level = *iterator.this_arg;
1216 break;
1217
1218 case IEEE80211_RADIOTAP_FLAGS:
1219 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {
1220 /*
1221 * this indicates that the skb we have been
1222 * handed has the 32-bit FCS CRC at the end...
1223 * we should react to that by snipping it off
1224 * because it will be recomputed and added
1225 * on transmission
1226 */
1227 if (skb->len < (iterator.max_length + FCS_LEN))
1228 return TXRX_DROP;
1229
1230 skb_trim(skb, skb->len - FCS_LEN);
1231 }
1232 break;
1233
1234 default:
1235 break;
1236 }
1237 }
1238
1239 if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
1240 return TXRX_DROP;
1241
1242 /*
1243 * remove the radiotap header
1244 * iterator->max_length was sanity-checked against
1245 * skb->len by iterator init
1246 */
1247 skb_pull(skb, iterator.max_length);
1248
1249 return TXRX_CONTINUE;
1250}
1251
1252
1253static ieee80211_txrx_result inline
1122__ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, 1254__ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
1123 struct sk_buff *skb, 1255 struct sk_buff *skb,
1124 struct net_device *dev, 1256 struct net_device *dev,
@@ -1126,6 +1258,9 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
1126{ 1258{
1127 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1259 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1128 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1260 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1261 struct ieee80211_sub_if_data *sdata;
1262 ieee80211_txrx_result res = TXRX_CONTINUE;
1263
1129 int hdrlen; 1264 int hdrlen;
1130 1265
1131 memset(tx, 0, sizeof(*tx)); 1266 memset(tx, 0, sizeof(*tx));
@@ -1135,7 +1270,32 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
1135 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1270 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1136 tx->sta = sta_info_get(local, hdr->addr1); 1271 tx->sta = sta_info_get(local, hdr->addr1);
1137 tx->fc = le16_to_cpu(hdr->frame_control); 1272 tx->fc = le16_to_cpu(hdr->frame_control);
1273
1274 /*
1275 * set defaults for things that can be set by
1276 * injected radiotap headers
1277 */
1138 control->power_level = local->hw.conf.power_level; 1278 control->power_level = local->hw.conf.power_level;
1279 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1280 if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)
1281 control->antenna_sel_tx = tx->sta->antenna_sel_tx;
1282
1283 /* process and remove the injection radiotap header */
1284 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1285 if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {
1286 if (__ieee80211_parse_tx_radiotap(tx, skb, control) ==
1287 TXRX_DROP) {
1288 return TXRX_DROP;
1289 }
1290 /*
1291 * we removed the radiotap header after this point,
1292 * we filled control with what we could use
1293 * set to the actual ieee header now
1294 */
1295 hdr = (struct ieee80211_hdr *) skb->data;
1296 res = TXRX_QUEUED; /* indication it was monitor packet */
1297 }
1298
1139 tx->u.tx.control = control; 1299 tx->u.tx.control = control;
1140 tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1); 1300 tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1);
1141 if (is_multicast_ether_addr(hdr->addr1)) 1301 if (is_multicast_ether_addr(hdr->addr1))
@@ -1152,9 +1312,6 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
1152 control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; 1312 control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;
1153 tx->sta->clear_dst_mask = 0; 1313 tx->sta->clear_dst_mask = 0;
1154 } 1314 }
1155 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1156 if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)
1157 control->antenna_sel_tx = tx->sta->antenna_sel_tx;
1158 hdrlen = ieee80211_get_hdrlen(tx->fc); 1315 hdrlen = ieee80211_get_hdrlen(tx->fc);
1159 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { 1316 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
1160 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; 1317 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
@@ -1162,6 +1319,7 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
1162 } 1319 }
1163 control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; 1320 control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT;
1164 1321
1322 return res;
1165} 1323}
1166 1324
1167static int inline is_ieee80211_device(struct net_device *dev, 1325static int inline is_ieee80211_device(struct net_device *dev,
@@ -1274,7 +1432,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1274 struct sta_info *sta; 1432 struct sta_info *sta;
1275 ieee80211_tx_handler *handler; 1433 ieee80211_tx_handler *handler;
1276 struct ieee80211_txrx_data tx; 1434 struct ieee80211_txrx_data tx;
1277 ieee80211_txrx_result res = TXRX_DROP; 1435 ieee80211_txrx_result res = TXRX_DROP, res_prepare;
1278 int ret, i; 1436 int ret, i;
1279 1437
1280 WARN_ON(__ieee80211_queue_pending(local, control->queue)); 1438 WARN_ON(__ieee80211_queue_pending(local, control->queue));
@@ -1284,15 +1442,26 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1284 return 0; 1442 return 0;
1285 } 1443 }
1286 1444
1287 __ieee80211_tx_prepare(&tx, skb, dev, control); 1445 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control);
1446
1447 if (res_prepare == TXRX_DROP) {
1448 dev_kfree_skb(skb);
1449 return 0;
1450 }
1451
1288 sta = tx.sta; 1452 sta = tx.sta;
1289 tx.u.tx.mgmt_interface = mgmt; 1453 tx.u.tx.mgmt_interface = mgmt;
1290 tx.u.tx.mode = local->hw.conf.mode; 1454 tx.u.tx.mode = local->hw.conf.mode;
1291 1455
1292 for (handler = local->tx_handlers; *handler != NULL; handler++) { 1456 if (res_prepare == TXRX_QUEUED) { /* if it was an injected packet */
1293 res = (*handler)(&tx); 1457 res = TXRX_CONTINUE;
1294 if (res != TXRX_CONTINUE) 1458 } else {
1295 break; 1459 for (handler = local->tx_handlers; *handler != NULL;
1460 handler++) {
1461 res = (*handler)(&tx);
1462 if (res != TXRX_CONTINUE)
1463 break;
1464 }
1296 } 1465 }
1297 1466
1298 skb = tx.skb; /* handlers are allowed to change skb */ 1467 skb = tx.skb; /* handlers are allowed to change skb */
@@ -1531,6 +1700,51 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb,
1531 goto fail; 1700 goto fail;
1532 } 1701 }
1533 1702
1703 if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {
1704 struct ieee80211_radiotap_header *prthdr =
1705 (struct ieee80211_radiotap_header *)skb->data;
1706 u16 len;
1707
1708 /*
1709 * there must be a radiotap header at the
1710 * start in this case
1711 */
1712 if (unlikely(prthdr->it_version)) {
1713 /* only version 0 is supported */
1714 ret = 0;
1715 goto fail;
1716 }
1717
1718 skb->dev = local->mdev;
1719
1720 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
1721 memset(pkt_data, 0, sizeof(*pkt_data));
1722 pkt_data->ifindex = sdata->dev->ifindex;
1723 pkt_data->mgmt_iface = 0;
1724 pkt_data->do_not_encrypt = 1;
1725
1726 /* above needed because we set skb device to master */
1727
1728 /*
1729 * fix up the pointers accounting for the radiotap
1730 * header still being in there. We are being given
1731 * a precooked IEEE80211 header so no need for
1732 * normal processing
1733 */
1734 len = le16_to_cpu(get_unaligned(&prthdr->it_len));
1735 skb_set_mac_header(skb, len);
1736 skb_set_network_header(skb, len + sizeof(hdr));
1737 skb_set_transport_header(skb, len + sizeof(hdr));
1738
1739 /*
1740 * pass the radiotap header up to
1741 * the next stage intact
1742 */
1743 dev_queue_xmit(skb);
1744
1745 return 0;
1746 }
1747
1534 nh_pos = skb_network_header(skb) - skb->data; 1748 nh_pos = skb_network_header(skb) - skb->data;
1535 h_pos = skb_transport_header(skb) - skb->data; 1749 h_pos = skb_transport_header(skb) - skb->data;
1536 1750