···11+How to use packet injection with mac8021122+=========================================33+44+mac80211 now allows arbitrary packets to be injected down any Monitor Mode55+interface from userland. The packet you inject needs to be composed in the66+following format:77+88+ [ radiotap header ]99+ [ ieee80211 header ]1010+ [ payload ]1111+1212+The radiotap format is discussed in1313+./Documentation/networking/radiotap-headers.txt.1414+1515+Despite 13 radiotap argument types are currently defined, most only make sense1616+to appear on received packets. Currently three kinds of argument are used by1717+the injection code, although it knows to skip any other arguments that are1818+present (facilitating replay of captured radiotap headers directly):1919+2020+ - IEEE80211_RADIOTAP_RATE - u8 arg in 500kbps units (0x02 --> 1Mbps)2121+2222+ - IEEE80211_RADIOTAP_ANTENNA - u8 arg, 0x00 = ant1, 0x01 = ant22323+2424+ - IEEE80211_RADIOTAP_DBM_TX_POWER - u8 arg, dBm2525+2626+Here is an example valid radiotap header defining these three parameters2727+2828+ 0x00, 0x00, // <-- radiotap version2929+ 0x0b, 0x00, // <- radiotap header length3030+ 0x04, 0x0c, 0x00, 0x00, // <-- bitmap3131+ 0x6c, // <-- rate3232+ 0x0c, //<-- tx power3333+ 0x01 //<-- antenna3434+3535+The ieee80211 header follows immediately afterwards, looking for example like3636+this:3737+3838+ 0x08, 0x01, 0x00, 0x00,3939+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,4040+ 0x13, 0x22, 0x33, 0x44, 0x55, 0x66,4141+ 0x13, 0x22, 0x33, 0x44, 0x55, 0x66,4242+ 0x10, 0x864343+4444+Then lastly there is the payload.4545+4646+After composing the packet contents, it is sent by send()-ing it to a logical4747+mac80211 interface that is in Monitor mode. Libpcap can also be used,4848+(which is easier than doing the work to bind the socket to the right4949+interface), along the following lines:5050+5151+ ppcap = pcap_open_live(szInterfaceName, 800, 1, 20, szErrbuf);5252+...5353+ r = pcap_inject(ppcap, u8aSendBuffer, nLength);5454+5555+You can also find sources for a complete inject test applet here:5656+5757+http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer5858+5959+Andy Green <andy@warmcat.com>
+152
Documentation/networking/radiotap-headers.txt
···11+How to use radiotap headers22+===========================33+44+Pointer to the radiotap include file55+------------------------------------66+77+Radiotap headers are variable-length and extensible, you can get most of the88+information you need to know on them from:99+1010+./include/net/ieee80211_radiotap.h1111+1212+This document gives an overview and warns on some corner cases.1313+1414+1515+Structure of the header1616+-----------------------1717+1818+There is a fixed portion at the start which contains a u32 bitmap that defines1919+if the possible argument associated with that bit is present or not. So if b02020+of the it_present member of ieee80211_radiotap_header is set, it means that2121+the header for argument index 0 (IEEE80211_RADIOTAP_TSFT) is present in the2222+argument area.2323+2424+ < 8-byte ieee80211_radiotap_header >2525+ [ <possible argument bitmap extensions ... > ]2626+ [ <argument> ... ]2727+2828+At the moment there are only 13 possible argument indexes defined, but in case2929+we run out of space in the u32 it_present member, it is defined that b31 set3030+indicates that there is another u32 bitmap following (shown as "possible3131+argument bitmap extensions..." above), and the start of the arguments is moved3232+forward 4 bytes each time.3333+3434+Note also that the it_len member __le16 is set to the total number of bytes3535+covered by the ieee80211_radiotap_header and any arguments following.3636+3737+3838+Requirements for arguments3939+--------------------------4040+4141+After the fixed part of the header, the arguments follow for each argument4242+index whose matching bit is set in the it_present member of4343+ieee80211_radiotap_header.4444+4545+ - the arguments are all stored little-endian!4646+4747+ - the argument payload for a given argument index has a fixed size. So4848+ IEEE80211_RADIOTAP_TSFT being present always indicates an 8-byte argument is4949+ present. See the comments in ./include/net/ieee80211_radiotap.h for a nice5050+ breakdown of all the argument sizes5151+5252+ - the arguments must be aligned to a boundary of the argument size using5353+ padding. So a u16 argument must start on the next u16 boundary if it isn't5454+ already on one, a u32 must start on the next u32 boundary and so on.5555+5656+ - "alignment" is relative to the start of the ieee80211_radiotap_header, ie,5757+ the first byte of the radiotap header. The absolute alignment of that first5858+ byte isn't defined. So even if the whole radiotap header is starting at, eg,5959+ address 0x00000003, still the first byte of the radiotap header is treated as6060+ 0 for alignment purposes.6161+6262+ - the above point that there may be no absolute alignment for multibyte6363+ entities in the fixed radiotap header or the argument region means that you6464+ have to take special evasive action when trying to access these multibyte6565+ entities. Some arches like Blackfin cannot deal with an attempt to6666+ dereference, eg, a u16 pointer that is pointing to an odd address. Instead6767+ you have to use a kernel API get_unaligned() to dereference the pointer,6868+ which will do it bytewise on the arches that require that.6969+7070+ - The arguments for a given argument index can be a compound of multiple types7171+ together. For example IEEE80211_RADIOTAP_CHANNEL has an argument payload7272+ consisting of two u16s of total length 4. When this happens, the padding7373+ rule is applied dealing with a u16, NOT dealing with a 4-byte single entity.7474+7575+7676+Example valid radiotap header7777+-----------------------------7878+7979+ 0x00, 0x00, // <-- radiotap version + pad byte8080+ 0x0b, 0x00, // <- radiotap header length8181+ 0x04, 0x0c, 0x00, 0x00, // <-- bitmap8282+ 0x6c, // <-- rate (in 500kHz units)8383+ 0x0c, //<-- tx power8484+ 0x01 //<-- antenna8585+8686+8787+Using the Radiotap Parser8888+-------------------------8989+9090+If you are having to parse a radiotap struct, you can radically simplify the9191+job by using the radiotap parser that lives in net/wireless/radiotap.c and has9292+its prototypes available in include/net/cfg80211.h. You use it like this:9393+9494+#include <net/cfg80211.h>9595+9696+/* buf points to the start of the radiotap header part */9797+9898+int MyFunction(u8 * buf, int buflen)9999+{100100+ int pkt_rate_100kHz = 0, antenna = 0, pwr = 0;101101+ struct ieee80211_radiotap_iterator iterator;102102+ int ret = ieee80211_radiotap_iterator_init(&iterator, buf, buflen);103103+104104+ while (!ret) {105105+106106+ ret = ieee80211_radiotap_iterator_next(&iterator);107107+108108+ if (ret)109109+ continue;110110+111111+ /* see if this argument is something we can use */112112+113113+ switch (iterator.this_arg_index) {114114+ /*115115+ * You must take care when dereferencing iterator.this_arg116116+ * for multibyte types... the pointer is not aligned. Use117117+ * get_unaligned((type *)iterator.this_arg) to dereference118118+ * iterator.this_arg for type "type" safely on all arches.119119+ */120120+ case IEEE80211_RADIOTAP_RATE:121121+ /* radiotap "rate" u8 is in122122+ * 500kbps units, eg, 0x02=1Mbps123123+ */124124+ pkt_rate_100kHz = (*iterator.this_arg) * 5;125125+ break;126126+127127+ case IEEE80211_RADIOTAP_ANTENNA:128128+ /* radiotap uses 0 for 1st ant */129129+ antenna = *iterator.this_arg);130130+ break;131131+132132+ case IEEE80211_RADIOTAP_DBM_TX_POWER:133133+ pwr = *iterator.this_arg;134134+ break;135135+136136+ default:137137+ break;138138+ }139139+ } /* while more rt headers */140140+141141+ if (ret != -ENOENT)142142+ return TXRX_DROP;143143+144144+ /* discard the radiotap header part */145145+ buf += iterator.max_length;146146+ buflen -= iterator.max_length;147147+148148+ ...149149+150150+}151151+152152+Andy Green <andy@warmcat.com>
···1111 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>1212 */13131414+1515+/* Radiotap header iteration1616+ * implemented in net/wireless/radiotap.c1717+ * docs in Documentation/networking/radiotap-headers.txt1818+ */1919+/**2020+ * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args2121+ * @rtheader: pointer to the radiotap header we are walking through2222+ * @max_length: length of radiotap header in cpu byte ordering2323+ * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg2424+ * @this_arg: pointer to current radiotap arg2525+ * @arg_index: internal next argument index2626+ * @arg: internal next argument pointer2727+ * @next_bitmap: internal pointer to next present u322828+ * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present2929+ */3030+3131+struct ieee80211_radiotap_iterator {3232+ struct ieee80211_radiotap_header *rtheader;3333+ int max_length;3434+ int this_arg_index;3535+ u8 *this_arg;3636+3737+ int arg_index;3838+ u8 *arg;3939+ __le32 *next_bitmap;4040+ u32 bitmap_shifter;4141+};4242+4343+extern int ieee80211_radiotap_iterator_init(4444+ struct ieee80211_radiotap_iterator *iterator,4545+ struct ieee80211_radiotap_header *radiotap_header,4646+ int max_length);4747+4848+extern int ieee80211_radiotap_iterator_next(4949+ struct ieee80211_radiotap_iterator *iterator);5050+5151+1452/* from net/wireless.h */1553struct wiphy;1654
+12-10
include/net/mac80211.h
···347347 * @mac_addr: pointer to MAC address of the interface. This pointer is valid348348 * until the interface is removed (i.e. it cannot be used after349349 * remove_interface() callback was called for this interface).350350+ * This pointer will be %NULL for monitor interfaces, be careful.350351 *351352 * This structure is used in add_interface() and remove_interface()352353 * callbacks of &struct ieee80211_hw.354354+ *355355+ * When you allow multiple interfaces to be added to your PHY, take care356356+ * that the hardware can actually handle multiple MAC addresses. However,357357+ * also take care that when there's no interface left with mac_addr != %NULL358358+ * you remove the MAC address from the device to avoid acknowledging packets359359+ * in pure monitor mode.353360 */354361struct ieee80211_if_init_conf {355362 int if_id;···581574 * to returning zero. By returning non-zero addition of the interface582575 * is inhibited. Unless monitor_during_oper is set, it is guaranteed583576 * that monitor interfaces and normal interfaces are mutually584584- * exclusive. The open() handler is called after add_interface()585585- * if this is the first device added. At least one of the open()586586- * open() and add_interface() callbacks has to be assigned. If587587- * add_interface() is NULL, one STA interface is permitted only. */577577+ * exclusive. If assigned, the open() handler is called after578578+ * add_interface() if this is the first device added. The579579+ * add_interface() callback has to be assigned because it is the only580580+ * way to obtain the requested MAC address for any interface.581581+ */588582 int (*add_interface)(struct ieee80211_hw *hw,589583 struct ieee80211_if_init_conf *conf);590584···928920struct sk_buff *929921ieee80211_get_buffered_bc(struct ieee80211_hw *hw, int if_id,930922 struct ieee80211_tx_control *control);931931-932932-/* Low level drivers that have their own MLME and MAC indicate933933- * the aid for an associating station with this call */934934-int ieee80211_set_aid_for_sta(struct ieee80211_hw *hw,935935- u8 *peer_address, u16 aid);936936-937923938924/* Given an sk_buff with a raw 802.11 header at the data pointer this function939925 * returns the 802.11 header length in bytes (not including encryption
···2424#include <linux/compiler.h>2525#include <linux/bitmap.h>2626#include <net/cfg80211.h>2727+#include <asm/unaligned.h>27282829#include "ieee80211_common.h"2930#include "ieee80211_i.h"···5554/* No encapsulation header if EtherType < 0x600 (=length) */5655static const unsigned char eapol_header[] =5756 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };5757+5858+5959+/*6060+ * For seeing transmitted packets on monitor interfaces6161+ * we have a radiotap header too.6262+ */6363+struct ieee80211_tx_status_rtap_hdr {6464+ struct ieee80211_radiotap_header hdr;6565+ __le16 tx_flags;6666+ u8 data_retries;6767+} __attribute__ ((packed));586859696070static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdata,···442430 if (!tx->u.tx.rate)443431 return TXRX_DROP;444432 if (tx->u.tx.mode->mode == MODE_IEEE80211G &&445445- tx->local->cts_protect_erp_frames && tx->fragmented &&433433+ tx->sdata->use_protection && tx->fragmented &&446434 extra.nonerp) {447435 tx->u.tx.last_frag_rate = tx->u.tx.rate;448436 tx->u.tx.probe_last_frag = extra.probe ? 1 : 0;···540528 /* reserve enough extra head and tail room for possible541529 * encryption */542530 frag = frags[i] =543543- dev_alloc_skb(tx->local->hw.extra_tx_headroom +531531+ dev_alloc_skb(tx->local->tx_headroom +544532 frag_threshold +545533 IEEE80211_ENCRYPT_HEADROOM +546534 IEEE80211_ENCRYPT_TAILROOM);···549537 /* Make sure that all fragments use the same priority so550538 * that they end up using the same TX queue */551539 frag->priority = first->priority;552552- skb_reserve(frag, tx->local->hw.extra_tx_headroom +553553- IEEE80211_ENCRYPT_HEADROOM);540540+ skb_reserve(frag, tx->local->tx_headroom +541541+ IEEE80211_ENCRYPT_HEADROOM);554542 fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen);555543 memcpy(fhdr, first->data, hdrlen);556544 if (i == num_fragm - 2)···868856 * for the frame. */869857 if (mode->mode == MODE_IEEE80211G &&870858 (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) &&871871- tx->u.tx.unicast &&872872- tx->local->cts_protect_erp_frames &&859859+ tx->u.tx.unicast && tx->sdata->use_protection &&873860 !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS))874861 control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT;875862···11291118}113011191131112011321132-static void inline11211121+/*11221122+ * deal with packet injection down monitor interface11231123+ * with Radiotap Header -- only called for monitor mode interface11241124+ */11251125+11261126+static ieee80211_txrx_result11271127+__ieee80211_parse_tx_radiotap(11281128+ struct ieee80211_txrx_data *tx,11291129+ struct sk_buff *skb, struct ieee80211_tx_control *control)11301130+{11311131+ /*11321132+ * this is the moment to interpret and discard the radiotap header that11331133+ * must be at the start of the packet injected in Monitor mode11341134+ *11351135+ * Need to take some care with endian-ness since radiotap11361136+ * args are little-endian11371137+ */11381138+11391139+ struct ieee80211_radiotap_iterator iterator;11401140+ struct ieee80211_radiotap_header *rthdr =11411141+ (struct ieee80211_radiotap_header *) skb->data;11421142+ struct ieee80211_hw_mode *mode = tx->local->hw.conf.mode;11431143+ int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);11441144+11451145+ /*11461146+ * default control situation for all injected packets11471147+ * FIXME: this does not suit all usage cases, expand to allow control11481148+ */11491149+11501150+ control->retry_limit = 1; /* no retry */11511151+ control->key_idx = -1; /* no encryption key */11521152+ control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS |11531153+ IEEE80211_TXCTL_USE_CTS_PROTECT);11541154+ control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT |11551155+ IEEE80211_TXCTL_NO_ACK;11561156+ control->antenna_sel_tx = 0; /* default to default antenna */11571157+11581158+ /*11591159+ * for every radiotap entry that is present11601160+ * (ieee80211_radiotap_iterator_next returns -ENOENT when no more11611161+ * entries present, or -EINVAL on error)11621162+ */11631163+11641164+ while (!ret) {11651165+ int i, target_rate;11661166+11671167+ ret = ieee80211_radiotap_iterator_next(&iterator);11681168+11691169+ if (ret)11701170+ continue;11711171+11721172+ /* see if this argument is something we can use */11731173+ switch (iterator.this_arg_index) {11741174+ /*11751175+ * You must take care when dereferencing iterator.this_arg11761176+ * for multibyte types... the pointer is not aligned. Use11771177+ * get_unaligned((type *)iterator.this_arg) to dereference11781178+ * iterator.this_arg for type "type" safely on all arches.11791179+ */11801180+ case IEEE80211_RADIOTAP_RATE:11811181+ /*11821182+ * radiotap rate u8 is in 500kbps units eg, 0x02=1Mbps11831183+ * ieee80211 rate int is in 100kbps units eg, 0x0a=1Mbps11841184+ */11851185+ target_rate = (*iterator.this_arg) * 5;11861186+ for (i = 0; i < mode->num_rates; i++) {11871187+ struct ieee80211_rate *r = &mode->rates[i];11881188+11891189+ if (r->rate > target_rate)11901190+ continue;11911191+11921192+ control->rate = r;11931193+11941194+ if (r->flags & IEEE80211_RATE_PREAMBLE2)11951195+ control->tx_rate = r->val2;11961196+ else11971197+ control->tx_rate = r->val;11981198+11991199+ /* end on exact match */12001200+ if (r->rate == target_rate)12011201+ i = mode->num_rates;12021202+ }12031203+ break;12041204+12051205+ case IEEE80211_RADIOTAP_ANTENNA:12061206+ /*12071207+ * radiotap uses 0 for 1st ant, mac80211 is 1 for12081208+ * 1st ant12091209+ */12101210+ control->antenna_sel_tx = (*iterator.this_arg) + 1;12111211+ break;12121212+12131213+ case IEEE80211_RADIOTAP_DBM_TX_POWER:12141214+ control->power_level = *iterator.this_arg;12151215+ break;12161216+12171217+ case IEEE80211_RADIOTAP_FLAGS:12181218+ if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FCS) {12191219+ /*12201220+ * this indicates that the skb we have been12211221+ * handed has the 32-bit FCS CRC at the end...12221222+ * we should react to that by snipping it off12231223+ * because it will be recomputed and added12241224+ * on transmission12251225+ */12261226+ if (skb->len < (iterator.max_length + FCS_LEN))12271227+ return TXRX_DROP;12281228+12291229+ skb_trim(skb, skb->len - FCS_LEN);12301230+ }12311231+ break;12321232+12331233+ default:12341234+ break;12351235+ }12361236+ }12371237+12381238+ if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */12391239+ return TXRX_DROP;12401240+12411241+ /*12421242+ * remove the radiotap header12431243+ * iterator->max_length was sanity-checked against12441244+ * skb->len by iterator init12451245+ */12461246+ skb_pull(skb, iterator.max_length);12471247+12481248+ return TXRX_CONTINUE;12491249+}12501250+12511251+12521252+static ieee80211_txrx_result inline11331253__ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,11341254 struct sk_buff *skb,11351255 struct net_device *dev,···12681126{12691127 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);12701128 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;11291129+ struct ieee80211_sub_if_data *sdata;11301130+ ieee80211_txrx_result res = TXRX_CONTINUE;11311131+12711132 int hdrlen;1272113312731134 memset(tx, 0, sizeof(*tx));···12801135 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);12811136 tx->sta = sta_info_get(local, hdr->addr1);12821137 tx->fc = le16_to_cpu(hdr->frame_control);11381138+11391139+ /*11401140+ * set defaults for things that can be set by11411141+ * injected radiotap headers11421142+ */12831143 control->power_level = local->hw.conf.power_level;11441144+ control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;11451145+ if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)11461146+ control->antenna_sel_tx = tx->sta->antenna_sel_tx;11471147+11481148+ /* process and remove the injection radiotap header */11491149+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);11501150+ if (unlikely(sdata->type == IEEE80211_IF_TYPE_MNTR)) {11511151+ if (__ieee80211_parse_tx_radiotap(tx, skb, control) ==11521152+ TXRX_DROP) {11531153+ return TXRX_DROP;11541154+ }11551155+ /*11561156+ * we removed the radiotap header after this point,11571157+ * we filled control with what we could use11581158+ * set to the actual ieee header now11591159+ */11601160+ hdr = (struct ieee80211_hdr *) skb->data;11611161+ res = TXRX_QUEUED; /* indication it was monitor packet */11621162+ }11631163+12841164 tx->u.tx.control = control;12851165 tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1);12861166 if (is_multicast_ether_addr(hdr->addr1))···13221152 control->flags |= IEEE80211_TXCTL_CLEAR_DST_MASK;13231153 tx->sta->clear_dst_mask = 0;13241154 }13251325- control->antenna_sel_tx = local->hw.conf.antenna_sel_tx;13261326- if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta)13271327- control->antenna_sel_tx = tx->sta->antenna_sel_tx;13281155 hdrlen = ieee80211_get_hdrlen(tx->fc);13291156 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {13301157 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];···13291162 }13301163 control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT;1331116411651165+ return res;13321166}1333116713341168static int inline is_ieee80211_device(struct net_device *dev,···14421274 struct sta_info *sta;14431275 ieee80211_tx_handler *handler;14441276 struct ieee80211_txrx_data tx;14451445- ieee80211_txrx_result res = TXRX_DROP;12771277+ ieee80211_txrx_result res = TXRX_DROP, res_prepare;14461278 int ret, i;1447127914481280 WARN_ON(__ieee80211_queue_pending(local, control->queue));···14521284 return 0;14531285 }1454128614551455- __ieee80211_tx_prepare(&tx, skb, dev, control);12871287+ res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control);12881288+12891289+ if (res_prepare == TXRX_DROP) {12901290+ dev_kfree_skb(skb);12911291+ return 0;12921292+ }12931293+14561294 sta = tx.sta;14571295 tx.u.tx.mgmt_interface = mgmt;14581296 tx.u.tx.mode = local->hw.conf.mode;1459129714601460- for (handler = local->tx_handlers; *handler != NULL; handler++) {14611461- res = (*handler)(&tx);14621462- if (res != TXRX_CONTINUE)14631463- break;12981298+ if (res_prepare == TXRX_QUEUED) { /* if it was an injected packet */12991299+ res = TXRX_CONTINUE;13001300+ } else {13011301+ for (handler = local->tx_handlers; *handler != NULL;13021302+ handler++) {13031303+ res = (*handler)(&tx);13041304+ if (res != TXRX_CONTINUE)13051305+ break;13061306+ }14641307 }1465130814661309 skb = tx.skb; /* handlers are allowed to change skb */···16461467 }16471468 osdata = IEEE80211_DEV_TO_SUB_IF(odev);1648146916491649- headroom = osdata->local->hw.extra_tx_headroom +16501650- IEEE80211_ENCRYPT_HEADROOM;14701470+ headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM;16511471 if (skb_headroom(skb) < headroom) {16521472 if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) {16531473 dev_kfree_skb(skb);···16721494}167314951674149614971497+int ieee80211_monitor_start_xmit(struct sk_buff *skb,14981498+ struct net_device *dev)14991499+{15001500+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);15011501+ struct ieee80211_tx_packet_data *pkt_data;15021502+ struct ieee80211_radiotap_header *prthdr =15031503+ (struct ieee80211_radiotap_header *)skb->data;15041504+ u16 len;15051505+15061506+ /*15071507+ * there must be a radiotap header at the15081508+ * start in this case15091509+ */15101510+ if (unlikely(prthdr->it_version)) {15111511+ /* only version 0 is supported */15121512+ dev_kfree_skb(skb);15131513+ return NETDEV_TX_OK;15141514+ }15151515+15161516+ skb->dev = local->mdev;15171517+15181518+ pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;15191519+ memset(pkt_data, 0, sizeof(*pkt_data));15201520+ pkt_data->ifindex = dev->ifindex;15211521+ pkt_data->mgmt_iface = 0;15221522+ pkt_data->do_not_encrypt = 1;15231523+15241524+ /* above needed because we set skb device to master */15251525+15261526+ /*15271527+ * fix up the pointers accounting for the radiotap15281528+ * header still being in there. We are being given15291529+ * a precooked IEEE80211 header so no need for15301530+ * normal processing15311531+ */15321532+ len = le16_to_cpu(get_unaligned(&prthdr->it_len));15331533+ skb_set_mac_header(skb, len);15341534+ skb_set_network_header(skb, len + sizeof(struct ieee80211_hdr));15351535+ skb_set_transport_header(skb, len + sizeof(struct ieee80211_hdr));15361536+15371537+ /*15381538+ * pass the radiotap header up to15391539+ * the next stage intact15401540+ */15411541+ dev_queue_xmit(skb);15421542+15431543+ return NETDEV_TX_OK;15441544+}15451545+15461546+16751547/**16761548 * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type16771549 * subinterfaces (wlan#, WDS, and VLAN interfaces)···17371509 * encapsulated packet will then be passed to master interface, wlan#.11, for17381510 * transmission (through low-level driver).17391511 */17401740-static int ieee80211_subif_start_xmit(struct sk_buff *skb,17411741- struct net_device *dev)15121512+int ieee80211_subif_start_xmit(struct sk_buff *skb,15131513+ struct net_device *dev)17421514{17431515 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);17441516 struct ieee80211_tx_packet_data *pkt_data;···18471619 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and18481620 * alloc_skb() (net/core/skbuff.c)18491621 */18501850- head_need = hdrlen + encaps_len + local->hw.extra_tx_headroom;16221622+ head_need = hdrlen + encaps_len + local->tx_headroom;18511623 head_need -= skb_headroom(skb);1852162418531625 /* We are going to modify skb data, so make a copy of it if happens to···1886165818871659 pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;18881660 memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));18891889- pkt_data->ifindex = sdata->dev->ifindex;16611661+ pkt_data->ifindex = dev->ifindex;18901662 pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);18911663 pkt_data->do_not_encrypt = no_encrypt;18921664···19341706 return 0;19351707 }1936170819371937- if (skb_headroom(skb) < sdata->local->hw.extra_tx_headroom) {19381938- if (pskb_expand_head(skb,19391939- sdata->local->hw.extra_tx_headroom, 0, GFP_ATOMIC)) {17091709+ if (skb_headroom(skb) < sdata->local->tx_headroom) {17101710+ if (pskb_expand_head(skb, sdata->local->tx_headroom,17111711+ 0, GFP_ATOMIC)) {19401712 dev_kfree_skb(skb);19411713 return 0;19421714 }···20751847 bh_len = ap->beacon_head_len;20761848 bt_len = ap->beacon_tail_len;2077184920782078- skb = dev_alloc_skb(local->hw.extra_tx_headroom +18501850+ skb = dev_alloc_skb(local->tx_headroom +20791851 bh_len + bt_len + 256 /* maximum TIM len */);20801852 if (!skb)20811853 return NULL;2082185420832083- skb_reserve(skb, local->hw.extra_tx_headroom);18551855+ skb_reserve(skb, local->tx_headroom);20841856 memcpy(skb_put(skb, bh_len), b_head, bh_len);2085185720861858 ieee80211_include_sequence(sdata, (struct ieee80211_hdr *)skb->data);···26042376 struct ieee80211_if_init_conf conf;2605237726062378 if (local->open_count && local->open_count == local->monitors &&26072607- !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER) &&26082608- local->ops->add_interface) {23792379+ !(local->hw.flags & IEEE80211_HW_MONITOR_DURING_OPER)) {26092380 conf.if_id = -1;26102381 conf.type = IEEE80211_IF_TYPE_MNTR;26112382 conf.mac_addr = NULL;···26472420 }26482421 ieee80211_start_soft_monitor(local);2649242226502650- if (local->ops->add_interface) {26512651- conf.if_id = dev->ifindex;26522652- conf.type = sdata->type;26532653- conf.mac_addr = dev->dev_addr;26542654- res = local->ops->add_interface(local_to_hw(local), &conf);26552655- if (res) {26562656- if (sdata->type == IEEE80211_IF_TYPE_MNTR)26572657- ieee80211_start_hard_monitor(local);26582658- return res;26592659- }26602660- } else {26612661- if (sdata->type != IEEE80211_IF_TYPE_STA)26622662- return -EOPNOTSUPP;26632663- if (local->open_count > 0)26642664- return -ENOBUFS;24232423+ conf.if_id = dev->ifindex;24242424+ conf.type = sdata->type;24252425+ conf.mac_addr = dev->dev_addr;24262426+ res = local->ops->add_interface(local_to_hw(local), &conf);24272427+ if (res) {24282428+ if (sdata->type == IEEE80211_IF_TYPE_MNTR)24292429+ ieee80211_start_hard_monitor(local);24302430+ return res;26652431 }2666243226672433 if (local->open_count == 0) {···31612941}31622942EXPORT_SYMBOL(ieee80211_radar_status);3163294331643164-int ieee80211_set_aid_for_sta(struct ieee80211_hw *hw, u8 *peer_address,31653165- u16 aid)31663166-{31673167- struct sk_buff *skb;31683168- struct ieee80211_msg_set_aid_for_sta *msg;31693169- struct ieee80211_local *local = hw_to_local(hw);31703170-31713171- /* unlikely because if this event only happens for APs,31723172- * which require an open ap device. */31733173- if (unlikely(!local->apdev))31743174- return 0;31753175-31763176- skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) +31773177- sizeof(struct ieee80211_msg_set_aid_for_sta));31783178-31793179- if (!skb)31803180- return -ENOMEM;31813181- skb_reserve(skb, sizeof(struct ieee80211_frame_info));31823182-31833183- msg = (struct ieee80211_msg_set_aid_for_sta *)31843184- skb_put(skb, sizeof(struct ieee80211_msg_set_aid_for_sta));31853185- memcpy(msg->sta_address, peer_address, ETH_ALEN);31863186- msg->aid = aid;31873187-31883188- ieee80211_rx_mgmt(local, skb, NULL, ieee80211_msg_set_aid_for_sta);31893189- return 0;31903190-}31913191-EXPORT_SYMBOL(ieee80211_set_aid_for_sta);3192294431932945static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta)31942946{···44764284 struct ieee80211_local *local = hw_to_local(hw);44774285 u16 frag, type;44784286 u32 msg_type;42874287+ struct ieee80211_tx_status_rtap_hdr *rthdr;42884288+ struct ieee80211_sub_if_data *sdata;42894289+ int monitors;4479429044804291 if (!status) {44814292 printk(KERN_ERR···45904395 local->dot11FailedCount++;45914396 }4592439745934593- if (!(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS)45944594- || unlikely(!local->apdev)) {45954595- dev_kfree_skb(skb);45964596- return;45974597- }45984598-45994398 msg_type = (status->flags & IEEE80211_TX_STATUS_ACK) ?46004399 ieee80211_msg_tx_callback_ack : ieee80211_msg_tx_callback_fail;4601440046024602- /* skb was the original skb used for TX. Clone it and give the clone46034603- * to netif_rx(). Free original skb. */46044604- skb2 = skb_copy(skb, GFP_ATOMIC);46054605- if (!skb2) {44014401+ /* this was a transmitted frame, but now we want to reuse it */44024402+ skb_orphan(skb);44034403+44044404+ if ((status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) &&44054405+ local->apdev) {44064406+ if (local->monitors) {44074407+ skb2 = skb_clone(skb, GFP_ATOMIC);44084408+ } else {44094409+ skb2 = skb;44104410+ skb = NULL;44114411+ }44124412+44134413+ if (skb2)44144414+ /* Send frame to hostapd */44154415+ ieee80211_rx_mgmt(local, skb2, NULL, msg_type);44164416+44174417+ if (!skb)44184418+ return;44194419+ }44204420+44214421+ if (!local->monitors) {46064422 dev_kfree_skb(skb);46074423 return;46084424 }46094609- dev_kfree_skb(skb);46104610- skb = skb2;4611442546124612- /* Send frame to hostapd */46134613- ieee80211_rx_mgmt(local, skb, NULL, msg_type);44264426+ /* send frame to monitor interfaces now */44274427+44284428+ if (skb_headroom(skb) < sizeof(*rthdr)) {44294429+ printk(KERN_ERR "ieee80211_tx_status: headroom too small\n");44304430+ dev_kfree_skb(skb);44314431+ return;44324432+ }44334433+44344434+ rthdr = (struct ieee80211_tx_status_rtap_hdr*)44354435+ skb_push(skb, sizeof(*rthdr));44364436+44374437+ memset(rthdr, 0, sizeof(*rthdr));44384438+ rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr));44394439+ rthdr->hdr.it_present =44404440+ cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) |44414441+ (1 << IEEE80211_RADIOTAP_DATA_RETRIES));44424442+44434443+ if (!(status->flags & IEEE80211_TX_STATUS_ACK) &&44444444+ !is_multicast_ether_addr(hdr->addr1))44454445+ rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);44464446+44474447+ if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) &&44484448+ (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT))44494449+ rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);44504450+ else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS)44514451+ rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);44524452+44534453+ rthdr->data_retries = status->retry_count;44544454+44554455+ read_lock(&local->sub_if_lock);44564456+ monitors = local->monitors;44574457+ list_for_each_entry(sdata, &local->sub_if_list, list) {44584458+ /*44594459+ * Using the monitors counter is possibly racy, but44604460+ * if the value is wrong we simply either clone the skb44614461+ * once too much or forget sending it to one monitor iface44624462+ * The latter case isn't nice but fixing the race is much44634463+ * more complicated.44644464+ */44654465+ if (!monitors || !skb)44664466+ goto out;44674467+44684468+ if (sdata->type == IEEE80211_IF_TYPE_MNTR) {44694469+ if (!netif_running(sdata->dev))44704470+ continue;44714471+ monitors--;44724472+ if (monitors)44734473+ skb2 = skb_clone(skb, GFP_KERNEL);44744474+ else44754475+ skb2 = NULL;44764476+ skb->dev = sdata->dev;44774477+ /* XXX: is this sufficient for BPF? */44784478+ skb_set_mac_header(skb, 0);44794479+ skb->ip_summed = CHECKSUM_UNNECESSARY;44804480+ skb->pkt_type = PACKET_OTHERHOST;44814481+ skb->protocol = htons(ETH_P_802_2);44824482+ memset(skb->cb, 0, sizeof(skb->cb));44834483+ netif_rx(skb);44844484+ skb = skb2;44854485+ break;44864486+ }44874487+ }44884488+ out:44894489+ read_unlock(&local->sub_if_lock);44904490+ if (skb)44914491+ dev_kfree_skb(skb);46144492}46154493EXPORT_SYMBOL(ieee80211_tx_status);46164494···48874619 ((sizeof(struct ieee80211_local) +48884620 NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);4889462146224622+ BUG_ON(!ops->tx);46234623+ BUG_ON(!ops->config);46244624+ BUG_ON(!ops->add_interface);48904625 local->ops = ops;4891462648924627 /* for now, mdev needs sub_if_data :/ */···49184647 local->short_retry_limit = 7;49194648 local->long_retry_limit = 4;49204649 local->hw.conf.radio_enabled = 1;49214921- local->rate_ctrl_num_up = RATE_CONTROL_NUM_UP;49224922- local->rate_ctrl_num_down = RATE_CONTROL_NUM_DOWN;4923465049244651 local->enabled_modes = (unsigned int) -1;49254652···49804711 result = -ENOMEM;49814712 goto fail_workqueue;49824713 }47144714+47154715+ /*47164716+ * The hardware needs headroom for sending the frame,47174717+ * and we need some headroom for passing the frame to monitor47184718+ * interfaces, but never both at the same time.47194719+ */47204720+ local->tx_headroom = max(local->hw.extra_tx_headroom,47214721+ sizeof(struct ieee80211_tx_status_rtap_hdr));4983472249844723 debugfs_hw_add(local);49854724
+2-7
net/mac80211/ieee80211_common.h
···4747 ieee80211_msg_normal = 0,4848 ieee80211_msg_tx_callback_ack = 1,4949 ieee80211_msg_tx_callback_fail = 2,5050- ieee80211_msg_passive_scan = 3,5050+ /* hole at 3, was ieee80211_msg_passive_scan but unused */5151 ieee80211_msg_wep_frame_unknown_key = 4,5252 ieee80211_msg_michael_mic_failure = 5,5353 /* hole at 6, was monitor but never sent to userspace */5454 ieee80211_msg_sta_not_assoc = 7,5555- ieee80211_msg_set_aid_for_sta = 8 /* used by Intersil MVC driver */,5555+ /* 8 was ieee80211_msg_set_aid_for_sta */5656 ieee80211_msg_key_threshold_notification = 9,5757 ieee80211_msg_radar = 11,5858-};5959-6060-struct ieee80211_msg_set_aid_for_sta {6161- char sta_address[ETH_ALEN];6262- u16 aid;6358};64596560struct ieee80211_msg_key_notification {
+10-4
net/mac80211/ieee80211_i.h
···9999 int probe_resp;100100 unsigned long last_update;101101102102+ /* during assocation, we save an ERP value from a probe response so103103+ * that we can feed ERP info to the driver when handling the104104+ * association completes. these fields probably won't be up-to-date105105+ * otherwise, you probably don't want to use them. */106106+ int has_erp_value;107107+ u8 erp_value;102108};103109104110···241235 unsigned int authenticated:1;242236 unsigned int associated:1;243237 unsigned int probereq_poll:1;244244- unsigned int use_protection:1;245238 unsigned int create_ibss:1;246239 unsigned int mixed_cell:1;247240 unsigned int wmm_enabled:1;···283278 int mc_count;284279 unsigned int allmulti:1;285280 unsigned int promisc:1;281281+ unsigned int use_protection:1; /* CTS protect ERP frames */286282287283 struct net_device_stats stats;288284 int drop_unencrypted;···398392 int monitors;399393 struct iw_statistics wstats;400394 u8 wstats_flags;395395+ int tx_headroom; /* required headroom for hardware/radiotap */401396402397 enum {403398 IEEE80211_DEV_UNINITIALIZED = 0,···444437 int *basic_rates[NUM_IEEE80211_MODES];445438446439 int rts_threshold;447447- int cts_protect_erp_frames;448440 int fragmentation_threshold;449441 int short_retry_limit; /* dot11ShortRetryLimit */450442 int long_retry_limit; /* dot11LongRetryLimit */···518512 STA_ANTENNA_SEL_SW_CTRL = 1,519513 STA_ANTENNA_SEL_SW_CTRL_DEBUG = 2520514 } sta_antenna_sel;521521-522522- int rate_ctrl_num_up, rate_ctrl_num_down;523515524516#ifdef CONFIG_MAC80211_DEBUG_COUNTERS525517 /* TX/RX handler statistics */···723719 struct ieee80211_hw_mode *mode);724720void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);725721int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);722722+int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);723723+int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);726724void ieee80211_if_setup(struct net_device *dev);727725void ieee80211_if_mgmt_setup(struct net_device *dev);728726int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
+3
net/mac80211/ieee80211_iface.c
···157157 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);158158 int oldtype = sdata->type;159159160160+ dev->hard_start_xmit = ieee80211_subif_start_xmit;161161+160162 sdata->type = type;161163 switch (type) {162164 case IEEE80211_IF_TYPE_WDS:···198196 }199197 case IEEE80211_IF_TYPE_MNTR:200198 dev->type = ARPHRD_IEEE80211_RADIOTAP;199199+ dev->hard_start_xmit = ieee80211_monitor_start_xmit;201200 break;202201 default:203202 printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",
+69-171
net/mac80211/ieee80211_ioctl.c
···345345{346346 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);347347 struct iw_range *range = (struct iw_range *) extra;348348+ struct ieee80211_hw_mode *mode = NULL;349349+ int c = 0;348350349351 data->length = sizeof(struct iw_range);350352 memset(range, 0, sizeof(struct iw_range));···379377380378 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |381379 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;380380+381381+ list_for_each_entry(mode, &local->modes_list, list) {382382+ int i = 0;383383+384384+ if (!(local->enabled_modes & (1 << mode->mode)) ||385385+ (local->hw_modes & local->enabled_modes &386386+ (1 << MODE_IEEE80211G) && mode->mode == MODE_IEEE80211B))387387+ continue;388388+389389+ while (i < mode->num_channels && c < IW_MAX_FREQUENCIES) {390390+ struct ieee80211_channel *chan = &mode->channels[i];391391+392392+ if (chan->flag & IEEE80211_CHAN_W_SCAN) {393393+ range->freq[c].i = chan->chan;394394+ range->freq[c].m = chan->freq * 100000;395395+ range->freq[c].e = 1;396396+ c++;397397+ }398398+ i++;399399+ }400400+ }401401+ range->num_channels = c;402402+ range->num_frequency = c;382403383404 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);384405 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);···863838}864839865840841841+static int ieee80211_ioctl_siwrate(struct net_device *dev,842842+ struct iw_request_info *info,843843+ struct iw_param *rate, char *extra)844844+{845845+ struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);846846+ struct ieee80211_hw_mode *mode;847847+ int i;848848+ u32 target_rate = rate->value / 100000;849849+ struct ieee80211_sub_if_data *sdata;850850+851851+ sdata = IEEE80211_DEV_TO_SUB_IF(dev);852852+ if (!sdata->bss)853853+ return -ENODEV;854854+ mode = local->oper_hw_mode;855855+ /* target_rate = -1, rate->fixed = 0 means auto only, so use all rates856856+ * target_rate = X, rate->fixed = 1 means only rate X857857+ * target_rate = X, rate->fixed = 0 means all rates <= X */858858+ sdata->bss->max_ratectrl_rateidx = -1;859859+ sdata->bss->force_unicast_rateidx = -1;860860+ if (rate->value < 0)861861+ return 0;862862+ for (i=0; i< mode->num_rates; i++) {863863+ struct ieee80211_rate *rates = &mode->rates[i];864864+ int this_rate = rates->rate;865865+866866+ if (mode->mode == MODE_ATHEROS_TURBO ||867867+ mode->mode == MODE_ATHEROS_TURBOG)868868+ this_rate *= 2;869869+ if (target_rate == this_rate) {870870+ sdata->bss->max_ratectrl_rateidx = i;871871+ if (rate->fixed)872872+ sdata->bss->force_unicast_rateidx = i;873873+ break;874874+ }875875+ }876876+ return 0;877877+}878878+866879static int ieee80211_ioctl_giwrate(struct net_device *dev,867880 struct iw_request_info *info,868881 struct iw_param *rate, char *extra)···1056993 return 0;1057994}105899510591059-static int ieee80211_ioctl_clear_keys(struct net_device *dev)10601060-{10611061- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);10621062- struct ieee80211_key_conf key;10631063- int i;10641064- u8 addr[ETH_ALEN];10651065- struct ieee80211_key_conf *keyconf;10661066- struct ieee80211_sub_if_data *sdata;10671067- struct sta_info *sta;10681068-10691069- memset(addr, 0xff, ETH_ALEN);10701070- read_lock(&local->sub_if_lock);10711071- list_for_each_entry(sdata, &local->sub_if_list, list) {10721072- for (i = 0; i < NUM_DEFAULT_KEYS; i++) {10731073- keyconf = NULL;10741074- if (sdata->keys[i] &&10751075- !sdata->keys[i]->force_sw_encrypt &&10761076- local->ops->set_key &&10771077- (keyconf = ieee80211_key_data2conf(local,10781078- sdata->keys[i])))10791079- local->ops->set_key(local_to_hw(local),10801080- DISABLE_KEY, addr,10811081- keyconf, 0);10821082- kfree(keyconf);10831083- ieee80211_key_free(sdata->keys[i]);10841084- sdata->keys[i] = NULL;10851085- }10861086- sdata->default_key = NULL;10871087- }10881088- read_unlock(&local->sub_if_lock);10891089-10901090- spin_lock_bh(&local->sta_lock);10911091- list_for_each_entry(sta, &local->sta_list, list) {10921092- keyconf = NULL;10931093- if (sta->key && !sta->key->force_sw_encrypt &&10941094- local->ops->set_key &&10951095- (keyconf = ieee80211_key_data2conf(local, sta->key)))10961096- local->ops->set_key(local_to_hw(local), DISABLE_KEY,10971097- sta->addr, keyconf, sta->aid);10981098- kfree(keyconf);10991099- ieee80211_key_free(sta->key);11001100- sta->key = NULL;11011101- }11021102- spin_unlock_bh(&local->sta_lock);11031103-11041104- memset(&key, 0, sizeof(key));11051105- if (local->ops->set_key &&11061106- local->ops->set_key(local_to_hw(local), REMOVE_ALL_KEYS,11071107- NULL, &key, 0))11081108- printk(KERN_DEBUG "%s: failed to remove hwaccel keys\n",11091109- dev->name);11101110-11111111- return 0;11121112-}11131113-11141114-11151115-static int11161116-ieee80211_ioctl_force_unicast_rate(struct net_device *dev,11171117- struct ieee80211_sub_if_data *sdata,11181118- int rate)11191119-{11201120- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);11211121- struct ieee80211_hw_mode *mode;11221122- int i;11231123-11241124- if (sdata->type != IEEE80211_IF_TYPE_AP)11251125- return -ENOENT;11261126-11271127- if (rate == 0) {11281128- sdata->u.ap.force_unicast_rateidx = -1;11291129- return 0;11301130- }11311131-11321132- mode = local->oper_hw_mode;11331133- for (i = 0; i < mode->num_rates; i++) {11341134- if (mode->rates[i].rate == rate) {11351135- sdata->u.ap.force_unicast_rateidx = i;11361136- return 0;11371137- }11381138- }11391139- return -EINVAL;11401140-}11411141-11421142-11431143-static int11441144-ieee80211_ioctl_max_ratectrl_rate(struct net_device *dev,11451145- struct ieee80211_sub_if_data *sdata,11461146- int rate)11471147-{11481148- struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);11491149- struct ieee80211_hw_mode *mode;11501150- int i;11511151-11521152- if (sdata->type != IEEE80211_IF_TYPE_AP)11531153- return -ENOENT;11541154-11551155- if (rate == 0) {11561156- sdata->u.ap.max_ratectrl_rateidx = -1;11571157- return 0;11581158- }11591159-11601160- mode = local->oper_hw_mode;11611161- for (i = 0; i < mode->num_rates; i++) {11621162- if (mode->rates[i].rate == rate) {11631163- sdata->u.ap.max_ratectrl_rateidx = i;11641164- return 0;11651165- }11661166- }11671167- return -EINVAL;11681168-}11691169-11701170-1171996static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local,1172997 struct ieee80211_key *key)1173998{···11791228 sdata->ieee802_1x = value;11801229 break;1181123011821182- case PRISM2_PARAM_ANTSEL_TX:11831183- local->hw.conf.antenna_sel_tx = value;11841184- if (ieee80211_hw_config(local))11851185- ret = -EINVAL;11861186- break;11871187-11881188- case PRISM2_PARAM_ANTSEL_RX:11891189- local->hw.conf.antenna_sel_rx = value;11901190- if (ieee80211_hw_config(local))11911191- ret = -EINVAL;11921192- break;11931193-11941231 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:11951195- local->cts_protect_erp_frames = value;11961196- break;11971197-11981198- case PRISM2_PARAM_DROP_UNENCRYPTED:11991199- sdata->drop_unencrypted = value;12321232+ if (sdata->type != IEEE80211_IF_TYPE_AP)12331233+ ret = -ENOENT;12341234+ else12351235+ sdata->use_protection = value;12001236 break;1201123712021238 case PRISM2_PARAM_PREAMBLE:···12121274 local->next_mode = value;12131275 break;1214127612151215- case PRISM2_PARAM_CLEAR_KEYS:12161216- ret = ieee80211_ioctl_clear_keys(dev);12171217- break;12181218-12191277 case PRISM2_PARAM_RADIO_ENABLED:12201278 ret = ieee80211_ioctl_set_radio_enabled(dev, value);12211279 break;···1224129012251291 case PRISM2_PARAM_STA_ANTENNA_SEL:12261292 local->sta_antenna_sel = value;12271227- break;12281228-12291229- case PRISM2_PARAM_FORCE_UNICAST_RATE:12301230- ret = ieee80211_ioctl_force_unicast_rate(dev, sdata, value);12311231- break;12321232-12331233- case PRISM2_PARAM_MAX_RATECTRL_RATE:12341234- ret = ieee80211_ioctl_max_ratectrl_rate(dev, sdata, value);12351235- break;12361236-12371237- case PRISM2_PARAM_RATE_CTRL_NUM_UP:12381238- local->rate_ctrl_num_up = value;12391239- break;12401240-12411241- case PRISM2_PARAM_RATE_CTRL_NUM_DOWN:12421242- local->rate_ctrl_num_down = value;12431293 break;1244129412451295 case PRISM2_PARAM_TX_POWER_REDUCTION:···13051387 *param = sdata->ieee802_1x;13061388 break;1307138913081308- case PRISM2_PARAM_ANTSEL_TX:13091309- *param = local->hw.conf.antenna_sel_tx;13101310- break;13111311-13121312- case PRISM2_PARAM_ANTSEL_RX:13131313- *param = local->hw.conf.antenna_sel_rx;13141314- break;13151315-13161390 case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES:13171317- *param = local->cts_protect_erp_frames;13181318- break;13191319-13201320- case PRISM2_PARAM_DROP_UNENCRYPTED:13211321- *param = sdata->drop_unencrypted;13911391+ *param = sdata->use_protection;13221392 break;1323139313241394 case PRISM2_PARAM_PREAMBLE:···1330142413311425 case PRISM2_PARAM_STA_ANTENNA_SEL:13321426 *param = local->sta_antenna_sel;13331333- break;13341334-13351335- case PRISM2_PARAM_RATE_CTRL_NUM_UP:13361336- *param = local->rate_ctrl_num_up;13371337- break;13381338-13391339- case PRISM2_PARAM_RATE_CTRL_NUM_DOWN:13401340- *param = local->rate_ctrl_num_down;13411427 break;1342142813431429 case PRISM2_PARAM_TX_POWER_REDUCTION:···16991801 (iw_handler) NULL, /* SIOCGIWNICKN */17001802 (iw_handler) NULL, /* -- hole -- */17011803 (iw_handler) NULL, /* -- hole -- */17021702- (iw_handler) NULL, /* SIOCSIWRATE */18041804+ (iw_handler) ieee80211_ioctl_siwrate, /* SIOCSIWRATE */17031805 (iw_handler) ieee80211_ioctl_giwrate, /* SIOCGIWRATE */17041806 (iw_handler) ieee80211_ioctl_siwrts, /* SIOCSIWRTS */17051807 (iw_handler) ieee80211_ioctl_giwrts, /* SIOCGIWRTS */
···187187 }188188#endif189189190190- if (per_failed > local->rate_ctrl_num_down) {190190+ /*191191+ * XXX: Make these configurable once we have an192192+ * interface to the rate control algorithms193193+ */194194+ if (per_failed > RATE_CONTROL_NUM_DOWN) {191195 rate_control_rate_dec(local, sta);192192- } else if (per_failed < local->rate_ctrl_num_up) {196196+ } else if (per_failed < RATE_CONTROL_NUM_UP) {193197 rate_control_rate_inc(local, sta);194198 }195199 srctrl->tx_avg_rate_sum += status->control.rate->rate;
···11+/*22+ * Radiotap parser33+ *44+ * Copyright 2007 Andy Green <andy@warmcat.com>55+ */66+77+#include <net/cfg80211.h>88+#include <net/ieee80211_radiotap.h>99+#include <asm/unaligned.h>1010+1111+/* function prototypes and related defs are in include/net/cfg80211.h */1212+1313+/**1414+ * ieee80211_radiotap_iterator_init - radiotap parser iterator initialization1515+ * @iterator: radiotap_iterator to initialize1616+ * @radiotap_header: radiotap header to parse1717+ * @max_length: total length we can parse into (eg, whole packet length)1818+ *1919+ * Returns: 0 or a negative error code if there is a problem.2020+ *2121+ * This function initializes an opaque iterator struct which can then2222+ * be passed to ieee80211_radiotap_iterator_next() to visit every radiotap2323+ * argument which is present in the header. It knows about extended2424+ * present headers and handles them.2525+ *2626+ * How to use:2727+ * call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator2828+ * struct ieee80211_radiotap_iterator (no need to init the struct beforehand)2929+ * checking for a good 0 return code. Then loop calling3030+ * __ieee80211_radiotap_iterator_next()... it returns either 0,3131+ * -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.3232+ * The iterator's @this_arg member points to the start of the argument3333+ * associated with the current argument index that is present, which can be3434+ * found in the iterator's @this_arg_index member. This arg index corresponds3535+ * to the IEEE80211_RADIOTAP_... defines.3636+ *3737+ * Radiotap header length:3838+ * You can find the CPU-endian total radiotap header length in3939+ * iterator->max_length after executing ieee80211_radiotap_iterator_init()4040+ * successfully.4141+ *4242+ * Alignment Gotcha:4343+ * You must take care when dereferencing iterator.this_arg4444+ * for multibyte types... the pointer is not aligned. Use4545+ * get_unaligned((type *)iterator.this_arg) to dereference4646+ * iterator.this_arg for type "type" safely on all arches.4747+ *4848+ * Example code:4949+ * See Documentation/networking/radiotap-headers.txt5050+ */5151+5252+int ieee80211_radiotap_iterator_init(5353+ struct ieee80211_radiotap_iterator *iterator,5454+ struct ieee80211_radiotap_header *radiotap_header,5555+ int max_length)5656+{5757+ /* Linux only supports version 0 radiotap format */5858+ if (radiotap_header->it_version)5959+ return -EINVAL;6060+6161+ /* sanity check for allowed length and radiotap length field */6262+ if (max_length < le16_to_cpu(get_unaligned(&radiotap_header->it_len)))6363+ return -EINVAL;6464+6565+ iterator->rtheader = radiotap_header;6666+ iterator->max_length = le16_to_cpu(get_unaligned(6767+ &radiotap_header->it_len));6868+ iterator->arg_index = 0;6969+ iterator->bitmap_shifter = le32_to_cpu(get_unaligned(7070+ &radiotap_header->it_present));7171+ iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);7272+ iterator->this_arg = NULL;7373+7474+ /* find payload start allowing for extended bitmap(s) */7575+7676+ if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {7777+ while (le32_to_cpu(get_unaligned((__le32 *)iterator->arg)) &7878+ (1<<IEEE80211_RADIOTAP_EXT)) {7979+ iterator->arg += sizeof(u32);8080+8181+ /*8282+ * check for insanity where the present bitmaps8383+ * keep claiming to extend up to or even beyond the8484+ * stated radiotap header length8585+ */8686+8787+ if (((ulong)iterator->arg -8888+ (ulong)iterator->rtheader) > iterator->max_length)8989+ return -EINVAL;9090+ }9191+9292+ iterator->arg += sizeof(u32);9393+9494+ /*9595+ * no need to check again for blowing past stated radiotap9696+ * header length, because ieee80211_radiotap_iterator_next9797+ * checks it before it is dereferenced9898+ */9999+ }100100+101101+ /* we are all initialized happily */102102+103103+ return 0;104104+}105105+EXPORT_SYMBOL(ieee80211_radiotap_iterator_init);106106+107107+108108+/**109109+ * ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg110110+ * @iterator: radiotap_iterator to move to next arg (if any)111111+ *112112+ * Returns: 0 if there is an argument to handle,113113+ * -ENOENT if there are no more args or -EINVAL114114+ * if there is something else wrong.115115+ *116116+ * This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)117117+ * in @this_arg_index and sets @this_arg to point to the118118+ * payload for the field. It takes care of alignment handling and extended119119+ * present fields. @this_arg can be changed by the caller (eg,120120+ * incremented to move inside a compound argument like121121+ * IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in122122+ * little-endian format whatever the endianess of your CPU.123123+ *124124+ * Alignment Gotcha:125125+ * You must take care when dereferencing iterator.this_arg126126+ * for multibyte types... the pointer is not aligned. Use127127+ * get_unaligned((type *)iterator.this_arg) to dereference128128+ * iterator.this_arg for type "type" safely on all arches.129129+ */130130+131131+int ieee80211_radiotap_iterator_next(132132+ struct ieee80211_radiotap_iterator *iterator)133133+{134134+135135+ /*136136+ * small length lookup table for all radiotap types we heard of137137+ * starting from b0 in the bitmap, so we can walk the payload138138+ * area of the radiotap header139139+ *140140+ * There is a requirement to pad args, so that args141141+ * of a given length must begin at a boundary of that length142142+ * -- but note that compound args are allowed (eg, 2 x u16143143+ * for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not144144+ * a reliable indicator of alignment requirement.145145+ *146146+ * upper nybble: content alignment for arg147147+ * lower nybble: content length for arg148148+ */149149+150150+ static const u8 rt_sizes[] = {151151+ [IEEE80211_RADIOTAP_TSFT] = 0x88,152152+ [IEEE80211_RADIOTAP_FLAGS] = 0x11,153153+ [IEEE80211_RADIOTAP_RATE] = 0x11,154154+ [IEEE80211_RADIOTAP_CHANNEL] = 0x24,155155+ [IEEE80211_RADIOTAP_FHSS] = 0x22,156156+ [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,157157+ [IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,158158+ [IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,159159+ [IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,160160+ [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,161161+ [IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,162162+ [IEEE80211_RADIOTAP_ANTENNA] = 0x11,163163+ [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,164164+ [IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11165165+ /*166166+ * add more here as they are defined in167167+ * include/net/ieee80211_radiotap.h168168+ */169169+ };170170+171171+ /*172172+ * for every radiotap entry we can at173173+ * least skip (by knowing the length)...174174+ */175175+176176+ while (iterator->arg_index < sizeof(rt_sizes)) {177177+ int hit = 0;178178+ int pad;179179+180180+ if (!(iterator->bitmap_shifter & 1))181181+ goto next_entry; /* arg not present */182182+183183+ /*184184+ * arg is present, account for alignment padding185185+ * 8-bit args can be at any alignment186186+ * 16-bit args must start on 16-bit boundary187187+ * 32-bit args must start on 32-bit boundary188188+ * 64-bit args must start on 64-bit boundary189189+ *190190+ * note that total arg size can differ from alignment of191191+ * elements inside arg, so we use upper nybble of length192192+ * table to base alignment on193193+ *194194+ * also note: these alignments are ** relative to the195195+ * start of the radiotap header **. There is no guarantee196196+ * that the radiotap header itself is aligned on any197197+ * kind of boundary.198198+ *199199+ * the above is why get_unaligned() is used to dereference200200+ * multibyte elements from the radiotap area201201+ */202202+203203+ pad = (((ulong)iterator->arg) -204204+ ((ulong)iterator->rtheader)) &205205+ ((rt_sizes[iterator->arg_index] >> 4) - 1);206206+207207+ if (pad)208208+ iterator->arg +=209209+ (rt_sizes[iterator->arg_index] >> 4) - pad;210210+211211+ /*212212+ * this is what we will return to user, but we need to213213+ * move on first so next call has something fresh to test214214+ */215215+ iterator->this_arg_index = iterator->arg_index;216216+ iterator->this_arg = iterator->arg;217217+ hit = 1;218218+219219+ /* internally move on the size of this arg */220220+ iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;221221+222222+ /*223223+ * check for insanity where we are given a bitmap that224224+ * claims to have more arg content than the length of the225225+ * radiotap section. We will normally end up equalling this226226+ * max_length on the last arg, never exceeding it.227227+ */228228+229229+ if (((ulong)iterator->arg - (ulong)iterator->rtheader) >230230+ iterator->max_length)231231+ return -EINVAL;232232+233233+ next_entry:234234+ iterator->arg_index++;235235+ if (unlikely((iterator->arg_index & 31) == 0)) {236236+ /* completed current u32 bitmap */237237+ if (iterator->bitmap_shifter & 1) {238238+ /* b31 was set, there is more */239239+ /* move to next u32 bitmap */240240+ iterator->bitmap_shifter = le32_to_cpu(241241+ get_unaligned(iterator->next_bitmap));242242+ iterator->next_bitmap++;243243+ } else244244+ /* no more bitmaps: end */245245+ iterator->arg_index = sizeof(rt_sizes);246246+ } else /* just try the next bit */247247+ iterator->bitmap_shifter >>= 1;248248+249249+ /* if we found a valid arg earlier, return it now */250250+ if (hit)251251+ return 0;252252+ }253253+254254+ /* we don't know how to handle any more args, we're done */255255+ return -ENOENT;256256+}257257+EXPORT_SYMBOL(ieee80211_radiotap_iterator_next);