#include <linux/bitmap.h>
#include <net/net_namespace.h>
#include <net/cfg80211.h>
+#include <net/rtnetlink.h>
#include "ieee80211_i.h"
#include "ieee80211_rate.h"
const unsigned char bridge_tunnel_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-static const unsigned char eapol_header[] =
- { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
-
static int rate_list_match(const int *rate_list, int rate)
{
if (rate->rate == 10 || rate->rate == 20)
rate->flags |= IEEE80211_RATE_BASIC;
break;
- case MODE_ATHEROS_TURBO:
- if (rate->rate == 120 || rate->rate == 240 ||
- rate->rate == 480)
- rate->flags |= IEEE80211_RATE_BASIC;
- break;
case MODE_IEEE80211G:
if (rate->rate == 10 || rate->rate == 20 ||
rate->rate == 55 || rate->rate == 110)
rate->flags |= IEEE80211_RATE_BASIC;
break;
+ case NUM_IEEE80211_MODES:
+ /* not useful */
+ break;
}
/* Set ERP and MANDATORY flags based on phymode */
if (rate->rate == 10)
rate->flags |= IEEE80211_RATE_MANDATORY;
break;
- case MODE_ATHEROS_TURBO:
- break;
case MODE_IEEE80211G:
if (rate->rate == 10 || rate->rate == 20 ||
rate->rate == 55 || rate->rate == 110 ||
rate->rate == 240)
rate->flags |= IEEE80211_RATE_MANDATORY;
break;
+ case NUM_IEEE80211_MODES:
+ /* not useful */
+ break;
}
if (ieee80211_is_erp_rate(mode->mode, rate->rate))
rate->flags |= IEEE80211_RATE_ERP;
{
u16 fc;
- if (len < 24)
+ /* drop ACK/CTS frames and incorrect hdr len (ctrl) */
+ if (len < 16)
return NULL;
fc = le16_to_cpu(hdr->frame_control);
switch (fc & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_DATA:
+ if (len < 24) /* drop incorrect hdr len (data) */
+ return NULL;
switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
case IEEE80211_FCTL_TODS:
return hdr->addr1;
}
break;
case IEEE80211_FTYPE_MGMT:
+ if (len < 24) /* drop incorrect hdr len (mgmt) */
+ return NULL;
return hdr->addr3;
case IEEE80211_FTYPE_CTL:
if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)
}
EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
-int ieee80211_is_eapol(const struct sk_buff *skb)
-{
- const struct ieee80211_hdr *hdr;
- u16 fc;
- int hdrlen;
-
- if (unlikely(skb->len < 10))
- return 0;
-
- hdr = (const struct ieee80211_hdr *) skb->data;
- fc = le16_to_cpu(hdr->frame_control);
-
- if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
- return 0;
-
- hdrlen = ieee80211_get_hdrlen(fc);
-
- if (unlikely(skb->len >= hdrlen + sizeof(eapol_header) &&
- memcmp(skb->data + hdrlen, eapol_header,
- sizeof(eapol_header)) == 0))
- return 1;
-
- return 0;
-}
-
void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data;
* DIV_ROUND_UP() operations.
*/
- if (local->hw.conf.phymode == MODE_IEEE80211A || erp ||
- local->hw.conf.phymode == MODE_ATHEROS_TURBO) {
+ if (local->hw.conf.phymode == MODE_IEEE80211A || erp) {
/*
* OFDM:
*
* 802.11g - 19.8.4: aSIFSTime = 10 usec +
* signal ext = 6 usec
*/
- /* FIX: Atheros Turbo may have different (shorter) duration? */
dur = 16; /* SIFS + signal ext */
dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */
dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */
ieee80211_wake_queue(hw, i);
}
EXPORT_SYMBOL(ieee80211_wake_queues);
+
+void ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
+ void (*iterator)(void *data, u8 *mac,
+ int if_id),
+ void *data)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata;
+
+ rcu_read_lock();
+
+ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+ switch (sdata->type) {
+ case IEEE80211_IF_TYPE_INVALID:
+ case IEEE80211_IF_TYPE_MNTR:
+ case IEEE80211_IF_TYPE_VLAN:
+ continue;
+ case IEEE80211_IF_TYPE_AP:
+ case IEEE80211_IF_TYPE_STA:
+ case IEEE80211_IF_TYPE_IBSS:
+ case IEEE80211_IF_TYPE_WDS:
+ break;
+ }
+ if (sdata->dev == local->mdev)
+ continue;
+ if (netif_running(sdata->dev))
+ iterator(data, sdata->dev->dev_addr,
+ sdata->dev->ifindex);
+ }
+
+ rcu_read_unlock();
+}
+EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces);