aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2007-09-26 11:53:18 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:54:18 -0400
commit58d4185e36913d4fc94afa4b4daccb3c9aa01957 (patch)
tree77d2e8e423652f5bbf2e29e8c0b3e0aeb7858b9f
parent628a140ba033ef201706a8c7e767c8a0c0f8326c (diff)
[MAC80211]: improve radiotap injection
This improves radiotap injection by removing the shortcut over TX handlers that led to BUGS when injecting frames without setting a rate and also resulted in various other quirks. Now, TX handlers are run but some information that was present in the radiotap header is used instead of automatic settings. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Cc: Andy Green <andy@warmcat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--Documentation/networking/mac80211-injection.txt32
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/tx.c195
3 files changed, 131 insertions, 97 deletions
diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt
index 53ef7a06f49c..84906ef3ed6e 100644
--- a/Documentation/networking/mac80211-injection.txt
+++ b/Documentation/networking/mac80211-injection.txt
@@ -13,15 +13,35 @@ The radiotap format is discussed in
13./Documentation/networking/radiotap-headers.txt. 13./Documentation/networking/radiotap-headers.txt.
14 14
15Despite 13 radiotap argument types are currently defined, most only make sense 15Despite 13 radiotap argument types are currently defined, most only make sense
16to appear on received packets. Currently three kinds of argument are used by 16to appear on received packets. The following information is parsed from the
17the injection code, although it knows to skip any other arguments that are 17radiotap headers and used to control injection:
18present (facilitating replay of captured radiotap headers directly):
19 18
20 - IEEE80211_RADIOTAP_RATE - u8 arg in 500kbps units (0x02 --> 1Mbps) 19 * IEEE80211_RADIOTAP_RATE
21 20
22 - IEEE80211_RADIOTAP_ANTENNA - u8 arg, 0x00 = ant1, 0x01 = ant2 21 rate in 500kbps units, automatic if invalid or not present
23 22
24 - IEEE80211_RADIOTAP_DBM_TX_POWER - u8 arg, dBm 23
24 * IEEE80211_RADIOTAP_ANTENNA
25
26 antenna to use, automatic if not present
27
28
29 * IEEE80211_RADIOTAP_DBM_TX_POWER
30
31 transmit power in dBm, automatic if not present
32
33
34 * IEEE80211_RADIOTAP_FLAGS
35
36 IEEE80211_RADIOTAP_F_FCS: FCS will be removed and recalculated
37 IEEE80211_RADIOTAP_F_WEP: frame will be encrypted if key available
38 IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
39 current fragmentation threshold. Note that
40 this flag is only reliable when software
41 fragmentation is enabled)
42
43The injection code can also skip all other currently defined radiotap fields
44facilitating replay of captured radiotap headers directly.
25 45
26Here is an example valid radiotap header defining these three parameters 46Here is an example valid radiotap header defining these three parameters
27 47
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d24b0574c436..0fe077747082 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -122,6 +122,7 @@ typedef enum {
122#define IEEE80211_TXRXD_RXIN_SCAN BIT(4) 122#define IEEE80211_TXRXD_RXIN_SCAN BIT(4)
123/* frame is destined to interface currently processed (incl. multicast frames) */ 123/* frame is destined to interface currently processed (incl. multicast frames) */
124#define IEEE80211_TXRXD_RXRA_MATCH BIT(5) 124#define IEEE80211_TXRXD_RXRA_MATCH BIT(5)
125#define IEEE80211_TXRXD_TX_INJECTED BIT(6)
125struct ieee80211_txrx_data { 126struct ieee80211_txrx_data {
126 struct sk_buff *skb; 127 struct sk_buff *skb;
127 struct net_device *dev; 128 struct net_device *dev;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 47416b0645db..1a531543bccb 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -222,6 +222,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx)
222#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 222#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
223 u32 sta_flags; 223 u32 sta_flags;
224 224
225 if (unlikely(tx->flags & IEEE80211_TXRXD_TX_INJECTED))
226 return TXRX_CONTINUE;
227
225 if (unlikely(tx->local->sta_scanning != 0) && 228 if (unlikely(tx->local->sta_scanning != 0) &&
226 ((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || 229 ((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT ||
227 (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ)) 230 (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))
@@ -566,22 +569,27 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx)
566{ 569{
567 struct rate_control_extra extra; 570 struct rate_control_extra extra;
568 571
569 memset(&extra, 0, sizeof(extra)); 572 if (likely(!tx->u.tx.rate)) {
570 extra.mode = tx->u.tx.mode; 573 memset(&extra, 0, sizeof(extra));
571 extra.ethertype = tx->ethertype; 574 extra.mode = tx->u.tx.mode;
572 575 extra.ethertype = tx->ethertype;
573 tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev, tx->skb, 576
574 &extra); 577 tx->u.tx.rate = rate_control_get_rate(tx->local, tx->dev,
575 if (unlikely(extra.probe != NULL)) { 578 tx->skb, &extra);
576 tx->u.tx.control->flags |= IEEE80211_TXCTL_RATE_CTRL_PROBE; 579 if (unlikely(extra.probe != NULL)) {
577 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG; 580 tx->u.tx.control->flags |=
578 tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val; 581 IEEE80211_TXCTL_RATE_CTRL_PROBE;
579 tx->u.tx.rate = extra.probe; 582 tx->flags |= IEEE80211_TXRXD_TXPROBE_LAST_FRAG;
580 } else { 583 tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val;
584 tx->u.tx.rate = extra.probe;
585 } else
586 tx->u.tx.control->alt_retry_rate = -1;
587
588 if (!tx->u.tx.rate)
589 return TXRX_DROP;
590 } else
581 tx->u.tx.control->alt_retry_rate = -1; 591 tx->u.tx.control->alt_retry_rate = -1;
582 } 592
583 if (!tx->u.tx.rate)
584 return TXRX_DROP;
585 if (tx->u.tx.mode->mode == MODE_IEEE80211G && 593 if (tx->u.tx.mode->mode == MODE_IEEE80211G &&
586 (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) && 594 (tx->sdata->flags & IEEE80211_SDATA_USE_PROTECTION) &&
587 (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && extra.nonerp) { 595 (tx->flags & IEEE80211_TXRXD_FRAGMENTED) && extra.nonerp) {
@@ -611,19 +619,24 @@ ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx)
611 struct ieee80211_tx_control *control = tx->u.tx.control; 619 struct ieee80211_tx_control *control = tx->u.tx.control;
612 struct ieee80211_hw_mode *mode = tx->u.tx.mode; 620 struct ieee80211_hw_mode *mode = tx->u.tx.mode;
613 621
614 if (!is_multicast_ether_addr(hdr->addr1)) { 622 if (!control->retry_limit) {
615 if (tx->skb->len + FCS_LEN > tx->local->rts_threshold && 623 if (!is_multicast_ether_addr(hdr->addr1)) {
616 tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD) { 624 if (tx->skb->len + FCS_LEN > tx->local->rts_threshold
617 control->flags |= IEEE80211_TXCTL_USE_RTS_CTS; 625 && tx->local->rts_threshold <
618 control->flags |= IEEE80211_TXCTL_LONG_RETRY_LIMIT; 626 IEEE80211_MAX_RTS_THRESHOLD) {
619 control->retry_limit = 627 control->flags |=
620 tx->local->long_retry_limit; 628 IEEE80211_TXCTL_USE_RTS_CTS;
629 control->flags |=
630 IEEE80211_TXCTL_LONG_RETRY_LIMIT;
631 control->retry_limit =
632 tx->local->long_retry_limit;
633 } else {
634 control->retry_limit =
635 tx->local->short_retry_limit;
636 }
621 } else { 637 } else {
622 control->retry_limit = 638 control->retry_limit = 1;
623 tx->local->short_retry_limit;
624 } 639 }
625 } else {
626 control->retry_limit = 1;
627 } 640 }
628 641
629 if (tx->flags & IEEE80211_TXRXD_FRAGMENTED) { 642 if (tx->flags & IEEE80211_TXRXD_FRAGMENTED) {
@@ -785,9 +798,8 @@ ieee80211_tx_handler ieee80211_tx_handlers[] =
785 * with Radiotap Header -- only called for monitor mode interface 798 * with Radiotap Header -- only called for monitor mode interface
786 */ 799 */
787static ieee80211_txrx_result 800static ieee80211_txrx_result
788__ieee80211_parse_tx_radiotap( 801__ieee80211_parse_tx_radiotap(struct ieee80211_txrx_data *tx,
789 struct ieee80211_txrx_data *tx, 802 struct sk_buff *skb)
790 struct sk_buff *skb, struct ieee80211_tx_control *control)
791{ 803{
792 /* 804 /*
793 * this is the moment to interpret and discard the radiotap header that 805 * this is the moment to interpret and discard the radiotap header that
@@ -802,18 +814,11 @@ __ieee80211_parse_tx_radiotap(
802 (struct ieee80211_radiotap_header *) skb->data; 814 (struct ieee80211_radiotap_header *) skb->data;
803 struct ieee80211_hw_mode *mode = tx->local->hw.conf.mode; 815 struct ieee80211_hw_mode *mode = tx->local->hw.conf.mode;
804 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); 816 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
817 struct ieee80211_tx_control *control = tx->u.tx.control;
805 818
806 /* 819 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT;
807 * default control situation for all injected packets 820 tx->flags |= IEEE80211_TXRXD_TX_INJECTED;
808 * FIXME: this does not suit all usage cases, expand to allow control 821 tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED;
809 */
810
811 control->retry_limit = 1; /* no retry */
812 control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |
813 IEEE80211_TXCTL_USE_CTS_PROTECT);
814 control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT |
815 IEEE80211_TXCTL_NO_ACK;
816 control->antenna_sel_tx = 0; /* default to default antenna */
817 822
818 /* 823 /*
819 * for every radiotap entry that is present 824 * for every radiotap entry that is present
@@ -846,19 +851,10 @@ __ieee80211_parse_tx_radiotap(
846 for (i = 0; i < mode->num_rates; i++) { 851 for (i = 0; i < mode->num_rates; i++) {
847 struct ieee80211_rate *r = &mode->rates[i]; 852 struct ieee80211_rate *r = &mode->rates[i];
848 853
849 if (r->rate > target_rate) 854 if (r->rate == target_rate) {
850 continue; 855 tx->u.tx.rate = r;
851 856 break;
852 control->rate = r; 857 }
853
854 if (r->flags & IEEE80211_RATE_PREAMBLE2)
855 control->tx_rate = r->val2;
856 else
857 control->tx_rate = r->val;
858
859 /* end on exact match */
860 if (r->rate == target_rate)
861 i = mode->num_rates;
862 } 858 }
863 break; 859 break;
864 860
@@ -888,8 +884,19 @@ __ieee80211_parse_tx_radiotap(
888 884
889 skb_trim(skb, skb->len - FCS_LEN); 885 skb_trim(skb, skb->len - FCS_LEN);
890 } 886 }
887 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
888 control->flags &=
889 ~IEEE80211_TXCTL_DO_NOT_ENCRYPT;
890 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
891 tx->flags |= IEEE80211_TXRXD_FRAGMENTED;
891 break; 892 break;
892 893
894 /*
895 * Please update the file
896 * Documentation/networking/mac80211-injection.txt
897 * when parsing new fields here.
898 */
899
893 default: 900 default:
894 break; 901 break;
895 } 902 }
@@ -908,14 +915,17 @@ __ieee80211_parse_tx_radiotap(
908 return TXRX_CONTINUE; 915 return TXRX_CONTINUE;
909} 916}
910 917
911static ieee80211_txrx_result inline 918/*
919 * initialises @tx
920 */
921static ieee80211_txrx_result
912__ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, 922__ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
913 struct sk_buff *skb, 923 struct sk_buff *skb,
914 struct net_device *dev, 924 struct net_device *dev,
915 struct ieee80211_tx_control *control) 925 struct ieee80211_tx_control *control)
916{ 926{
917 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 927 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
918 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 928 struct ieee80211_hdr *hdr;
919 struct ieee80211_sub_if_data *sdata; 929 struct ieee80211_sub_if_data *sdata;
920 ieee80211_txrx_result res = TXRX_CONTINUE; 930 ieee80211_txrx_result res = TXRX_CONTINUE;
921 931
@@ -926,33 +936,31 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
926 tx->dev = dev; /* use original interface */ 936 tx->dev = dev; /* use original interface */
927 tx->local = local; 937 tx->local = local;
928 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); 938 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
929 939 tx->u.tx.control = control;
930 /* 940 /*
931 * set defaults for things that can be set by 941 * Set this flag (used below to indicate "automatic fragmentation"),
932 * injected radiotap headers 942 * it will be cleared/left by radiotap as desired.
933 */ 943 */
934 control->power_level = local->hw.conf.power_level; 944 tx->flags |= IEEE80211_TXRXD_FRAGMENTED;
935 control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
936 945
937 /* process and remove the injection radiotap header */ 946 /* process and remove the injection radiotap header */
938 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 947 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
939 if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) { 948 if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {
940 if (__ieee80211_parse_tx_radiotap(tx, skb, control) == 949 if (__ieee80211_parse_tx_radiotap(tx, skb) == TXRX_DROP)
941 TXRX_DROP) {
942 return TXRX_DROP; 950 return TXRX_DROP;
943 } 951
944 /* 952 /*
945 * we removed the radiotap header after this point, 953 * __ieee80211_parse_tx_radiotap has now removed
946 * we filled control with what we could use 954 * the radiotap header that was present and pre-filled
947 * set to the actual ieee header now 955 * 'tx' with tx control information.
948 */ 956 */
949 hdr = (struct ieee80211_hdr *) skb->data;
950 res = TXRX_QUEUED; /* indication it was monitor packet */
951 } 957 }
952 958
959 hdr = (struct ieee80211_hdr *) skb->data;
960
953 tx->sta = sta_info_get(local, hdr->addr1); 961 tx->sta = sta_info_get(local, hdr->addr1);
954 tx->fc = le16_to_cpu(hdr->frame_control); 962 tx->fc = le16_to_cpu(hdr->frame_control);
955 tx->u.tx.control = control; 963
956 if (is_multicast_ether_addr(hdr->addr1)) { 964 if (is_multicast_ether_addr(hdr->addr1)) {
957 tx->flags &= ~IEEE80211_TXRXD_TXUNICAST; 965 tx->flags &= ~IEEE80211_TXRXD_TXUNICAST;
958 control->flags |= IEEE80211_TXCTL_NO_ACK; 966 control->flags |= IEEE80211_TXCTL_NO_ACK;
@@ -960,19 +968,23 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
960 tx->flags |= IEEE80211_TXRXD_TXUNICAST; 968 tx->flags |= IEEE80211_TXRXD_TXUNICAST;
961 control->flags &= ~IEEE80211_TXCTL_NO_ACK; 969 control->flags &= ~IEEE80211_TXCTL_NO_ACK;
962 } 970 }
963 if (local->fragmentation_threshold < IEEE80211_MAX_FRAG_THRESHOLD && 971
964 (tx->flags & IEEE80211_TXRXD_TXUNICAST) && 972 if (tx->flags & IEEE80211_TXRXD_FRAGMENTED) {
965 skb->len + FCS_LEN > local->fragmentation_threshold && 973 if ((tx->flags & IEEE80211_TXRXD_TXUNICAST) &&
966 !local->ops->set_frag_threshold) 974 skb->len + FCS_LEN > local->fragmentation_threshold &&
967 tx->flags |= IEEE80211_TXRXD_FRAGMENTED; 975 !local->ops->set_frag_threshold)
968 else 976 tx->flags |= IEEE80211_TXRXD_FRAGMENTED;
969 tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED; 977 else
978 tx->flags &= ~IEEE80211_TXRXD_FRAGMENTED;
979 }
980
970 if (!tx->sta) 981 if (!tx->sta)
971 control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; 982 control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;
972 else if (tx->sta->clear_dst_mask) { 983 else if (tx->sta->clear_dst_mask) {
973 control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK; 984 control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;
974 tx->sta->clear_dst_mask = 0; 985 tx->sta->clear_dst_mask = 0;
975 } 986 }
987
976 hdrlen = ieee80211_get_hdrlen(tx->fc); 988 hdrlen = ieee80211_get_hdrlen(tx->fc);
977 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { 989 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
978 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; 990 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
@@ -984,11 +996,14 @@ __ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
984} 996}
985 997
986/* Device in tx->dev has a reference added; use dev_put(tx->dev) when 998/* Device in tx->dev has a reference added; use dev_put(tx->dev) when
987 * finished with it. */ 999 * finished with it.
988static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, 1000 *
989 struct sk_buff *skb, 1001 * NB: @tx is uninitialised when passed in here
990 struct net_device *mdev, 1002 */
991 struct ieee80211_tx_control *control) 1003static int ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
1004 struct sk_buff *skb,
1005 struct net_device *mdev,
1006 struct ieee80211_tx_control *control)
992{ 1007{
993 struct ieee80211_tx_packet_data *pkt_data; 1008 struct ieee80211_tx_packet_data *pkt_data;
994 struct net_device *dev; 1009 struct net_device *dev;
@@ -1001,6 +1016,7 @@ static int inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
1001 } 1016 }
1002 if (unlikely(!dev)) 1017 if (unlikely(!dev))
1003 return -ENODEV; 1018 return -ENODEV;
1019 /* initialises tx with control */
1004 __ieee80211_tx_prepare(tx, skb, dev, control); 1020 __ieee80211_tx_prepare(tx, skb, dev, control);
1005 return 0; 1021 return 0;
1006} 1022}
@@ -1081,6 +1097,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1081 return 0; 1097 return 0;
1082 } 1098 }
1083 1099
1100 /* initialises tx */
1084 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); 1101 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control);
1085 1102
1086 if (res_prepare == TXRX_DROP) { 1103 if (res_prepare == TXRX_DROP) {
@@ -1097,15 +1114,11 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1097 sta = tx.sta; 1114 sta = tx.sta;
1098 tx.u.tx.mode = local->hw.conf.mode; 1115 tx.u.tx.mode = local->hw.conf.mode;
1099 1116
1100 if (res_prepare == TXRX_QUEUED) { /* if it was an injected packet */ 1117 for (handler = local->tx_handlers; *handler != NULL;
1101 res = TXRX_CONTINUE; 1118 handler++) {
1102 } else { 1119 res = (*handler)(&tx);
1103 for (handler = local->tx_handlers; *handler != NULL; 1120 if (res != TXRX_CONTINUE)
1104 handler++) { 1121 break;
1105 res = (*handler)(&tx);
1106 if (res != TXRX_CONTINUE)
1107 break;
1108 }
1109 } 1122 }
1110 1123
1111 skb = tx.skb; /* handlers are allowed to change skb */ 1124 skb = tx.skb; /* handlers are allowed to change skb */
@@ -1857,7 +1870,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,
1857 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1870 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1858 } 1871 }
1859 1872
1860 if (ieee80211_tx_prepare(&tx, skb, local->mdev, control) == 0) 1873 if (!ieee80211_tx_prepare(&tx, skb, local->mdev, control))
1861 break; 1874 break;
1862 dev_kfree_skb_any(skb); 1875 dev_kfree_skb_any(skb);
1863 } 1876 }