* for Intersil Prism2/2.5/3 - hostap.o module, common routines
*
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
+ * <j@w1.fi>
+ * Copyright (c) 2002-2003, Jouni Malinen <j@w1.fi>
* Copyright (c) 2004-2005, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
*/
#include <linux/compiler.h>
-#include <linux/config.h>
#include <linux/errno.h>
#include <linux/if_arp.h>
#include <linux/in6.h>
u16 fc = le16_to_cpu(hdr->frame_ctl);
skb->dev = ieee->dev;
- skb->mac.raw = skb->data;
+ skb_reset_mac_header(skb);
skb_pull(skb, ieee80211_get_hdrlen(fc));
skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_80211_RAW);
+ skb->protocol = htons(ETH_P_80211_RAW);
memset(skb->cb, 0, sizeof(skb->cb));
netif_rx(skb);
}
{
struct ieee80211_hdr_3addr *hdr;
int res, hdrlen;
+ DECLARE_MAC_BUF(mac);
if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
return 0;
res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
atomic_dec(&crypt->refcnt);
if (res < 0) {
- IEEE80211_DEBUG_DROP("decryption failed (SA=" MAC_FMT
- ") res=%d\n", MAC_ARG(hdr->addr2), res);
+ IEEE80211_DEBUG_DROP("decryption failed (SA=%s"
+ ") res=%d\n", print_mac(mac, hdr->addr2), res);
if (res == -2)
IEEE80211_DEBUG_DROP("Decryption failed ICV "
"mismatch (key %d)\n",
{
struct ieee80211_hdr_3addr *hdr;
int res, hdrlen;
+ DECLARE_MAC_BUF(mac);
if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
return 0;
atomic_dec(&crypt->refcnt);
if (res < 0) {
printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
- " (SA=" MAC_FMT " keyidx=%d)\n",
- ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
+ " (SA=%s keyidx=%d)\n",
+ ieee->dev->name, print_mac(mac, hdr->addr2), keyidx);
return -1;
}
struct ieee80211_crypt_data *crypt = NULL;
int keyidx = 0;
int can_be_decrypted = 0;
+ DECLARE_MAC_BUF(mac);
hdr = (struct ieee80211_hdr_4addr *)skb->data;
stats = &ieee->stats;
frag = WLAN_GET_SEQ_FRAG(sc);
hdrlen = ieee80211_get_hdrlen(fc);
+ if (skb->len < hdrlen) {
+ printk(KERN_INFO "%s: invalid SKB length %d\n",
+ dev->name, skb->len);
+ goto rx_dropped;
+ }
+
/* Put this code here so that we avoid duplicating it in all
* Rx paths. - Jean II */
+#ifdef CONFIG_WIRELESS_EXT
#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
-#ifdef CONFIG_NET_RADIO
/* If spy monitoring on */
if (ieee->spy_data.spy_number > 0) {
struct iw_quality wstats;
/* Update spy records */
wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
}
-#endif /* CONFIG_NET_RADIO */
#endif /* IW_WIRELESS_SPY */
+#endif /* CONFIG_WIRELESS_EXT */
#ifdef NOT_YET
hostap_update_rx_stats(local->ap, hdr, rx_stats);
#endif
if (ieee->iw_mode == IW_MODE_MONITOR) {
- ieee80211_monitor_rx(ieee, skb, rx_stats);
stats->rx_packets++;
stats->rx_bytes += skb->len;
+ ieee80211_monitor_rx(ieee, skb, rx_stats);
return 1;
}
ieee->host_mc_decrypt : ieee->host_decrypt;
if (can_be_decrypted) {
- int idx = 0;
if (skb->len >= hdrlen + 3) {
/* Top two-bits of byte 3 are the key index */
- idx = skb->data[hdrlen + 3] >> 6;
+ keyidx = skb->data[hdrlen + 3] >> 6;
}
- /* ieee->crypt[] is WEP_KEY (4) in length. Given that idx
- * is only allowed 2-bits of storage, no value of idx can
- * be provided via above code that would result in idx
+ /* ieee->crypt[] is WEP_KEY (4) in length. Given that keyidx
+ * is only allowed 2-bits of storage, no value of keyidx can
+ * be provided via above code that would result in keyidx
* being out of range */
- crypt = ieee->crypt[idx];
+ crypt = ieee->crypt[keyidx];
#ifdef NOT_YET
sta = NULL;
* frames silently instead of filling system log with
* these reports. */
IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=" MAC_FMT ")\n",
- MAC_ARG(hdr->addr2));
+ " (SA=%s)\n",
+ print_mac(mac, hdr->addr2));
ieee->ieee_stats.rx_discards_undecryptable++;
goto rx_dropped;
}
fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
(keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
- "from " MAC_FMT "\n", dev->name,
- MAC_ARG(hdr->addr2));
+ "from %s\n", dev->name,
+ print_mac(mac, hdr->addr2));
/* TODO: could inform hostapd about this so that it
* could send auth failure report */
goto rx_dropped;
goto rx_exit;
}
#endif
+ /* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */
+ if (sc == ieee->prev_seq_ctl)
+ goto rx_dropped;
+ else
+ ieee->prev_seq_ctl = sc;
/* Data frame - extract src/dst addresses */
if (skb->len < IEEE80211_3ADDR_LEN)
/* skb: hdr + (possibly fragmented) plaintext payload */
// PR: FIXME: hostap has additional conditions in the "if" below:
// ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
- if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
+ if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
int flen;
struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
if (frag == 0) {
/* copy first fragment (including full headers) into
* beginning of the fragment cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data, flen);
+ skb_copy_from_linear_data(skb, skb_put(frag_skb, flen), flen);
} else {
/* append frame payload to the end of the fragment
* cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
- flen);
+ skb_copy_from_linear_data_offset(skb, hdrlen,
+ skb_put(frag_skb, flen), flen);
}
dev_kfree_skb_any(skb);
skb = NULL;
* configured */
} else {
IEEE80211_DEBUG_DROP("encryption configured, but RX "
- "frame not encrypted (SA=" MAC_FMT
- ")\n", MAC_ARG(hdr->addr2));
+ "frame not encrypted (SA=%s"
+ ")\n", print_mac(mac, hdr->addr2));
goto rx_dropped;
}
}
if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
!ieee80211_is_eapol_frame(ieee, skb)) {
IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
- "frame from " MAC_FMT
+ "frame from %s"
" (drop_unencrypted=1)\n",
- MAC_ARG(hdr->addr2));
+ print_mac(mac, hdr->addr2));
goto rx_dropped;
}
+ /* If the frame was decrypted in hardware, we may need to strip off
+ * any security data (IV, ICV, etc) that was left behind */
+ if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
+ ieee->host_strip_iv_icv) {
+ int trimlen = 0;
+
+ /* Top two-bits of byte 3 are the key index */
+ if (skb->len >= hdrlen + 3)
+ keyidx = skb->data[hdrlen + 3] >> 6;
+
+ /* To strip off any security data which appears before the
+ * payload, we simply increase hdrlen (as the header gets
+ * chopped off immediately below). For the security data which
+ * appears after the payload, we use skb_trim. */
+
+ switch (ieee->sec.encode_alg[keyidx]) {
+ case SEC_ALG_WEP:
+ /* 4 byte IV */
+ hdrlen += 4;
+ /* 4 byte ICV */
+ trimlen = 4;
+ break;
+ case SEC_ALG_TKIP:
+ /* 4 byte IV, 4 byte ExtIV */
+ hdrlen += 8;
+ /* 8 byte MIC, 4 byte ICV */
+ trimlen = 12;
+ break;
+ case SEC_ALG_CCMP:
+ /* 8 byte CCMP header */
+ hdrlen += 8;
+ /* 8 byte MIC */
+ trimlen = 8;
+ break;
+ }
+
+ if (skb->len < trimlen)
+ goto rx_dropped;
+
+ __skb_trim(skb, skb->len - trimlen);
+
+ if (skb->len < hdrlen)
+ goto rx_dropped;
+ }
+
/* skb: hdr + (possible reassembled) full plaintext payload */
payload = skb->data + hdrlen;
memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
} else {
- u16 len;
+ __be16 len;
/* Leave Ethernet header part of hdr and full payload */
skb_pull(skb, hdrlen);
len = htons(skb->len);
IEEE80211_FCTL_TODS) && skb->len >= ETH_HLEN + ETH_ALEN) {
/* Non-standard frame: get addr4 from its bogus location after
* the payload */
- memcpy(skb->data + ETH_ALEN,
- skb->data + skb->len - ETH_ALEN, ETH_ALEN);
+ skb_copy_to_linear_data_offset(skb, ETH_ALEN,
+ skb->data + skb->len - ETH_ALEN,
+ ETH_ALEN);
skb_trim(skb, skb->len - ETH_ALEN);
}
#endif
if (skb2 != NULL) {
/* send to wireless media */
- skb2->protocol = __constant_htons(ETH_P_802_3);
- skb2->mac.raw = skb2->nh.raw = skb2->data;
- /* skb2->nh.raw = skb2->data + ETH_HLEN; */
skb2->dev = dev;
+ skb2->protocol = htons(ETH_P_802_3);
+ skb_reset_mac_header(skb2);
+ skb_reset_network_header(skb2);
+ /* skb2->network_header += ETH_HLEN; */
dev_queue_xmit(skb2);
}
#endif
if (skb) {
skb->protocol = eth_type_trans(skb, dev);
memset(skb->cb, 0, sizeof(skb->cb));
- skb->dev = dev;
skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
if (netif_rx(skb) == NET_RX_DROP) {
/* netif_rx always succeeds, but it might drop
return 0;
}
+/* Filter out unrelated packets, call ieee80211_rx[_mgt]
+ * This function takes over the skb, it should not be used again after calling
+ * this function. */
+void ieee80211_rx_any(struct ieee80211_device *ieee,
+ struct sk_buff *skb, struct ieee80211_rx_stats *stats)
+{
+ struct ieee80211_hdr_4addr *hdr;
+ int is_packet_for_us;
+ u16 fc;
+
+ if (ieee->iw_mode == IW_MODE_MONITOR) {
+ if (!ieee80211_rx(ieee, skb, stats))
+ dev_kfree_skb_irq(skb);
+ return;
+ }
+
+ if (skb->len < sizeof(struct ieee80211_hdr))
+ goto drop_free;
+
+ hdr = (struct ieee80211_hdr_4addr *)skb->data;
+ fc = le16_to_cpu(hdr->frame_ctl);
+
+ if ((fc & IEEE80211_FCTL_VERS) != 0)
+ goto drop_free;
+
+ switch (fc & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_MGMT:
+ if (skb->len < sizeof(struct ieee80211_hdr_3addr))
+ goto drop_free;
+ ieee80211_rx_mgt(ieee, hdr, stats);
+ dev_kfree_skb_irq(skb);
+ return;
+ case IEEE80211_FTYPE_DATA:
+ break;
+ case IEEE80211_FTYPE_CTL:
+ return;
+ default:
+ return;
+ }
+
+ is_packet_for_us = 0;
+ switch (ieee->iw_mode) {
+ case IW_MODE_ADHOC:
+ /* our BSS and not from/to DS */
+ if (memcmp(hdr->addr3, ieee->bssid, ETH_ALEN) == 0)
+ if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == 0) {
+ /* promisc: get all */
+ if (ieee->dev->flags & IFF_PROMISC)
+ is_packet_for_us = 1;
+ /* to us */
+ else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0)
+ is_packet_for_us = 1;
+ /* mcast */
+ else if (is_multicast_ether_addr(hdr->addr1))
+ is_packet_for_us = 1;
+ }
+ break;
+ case IW_MODE_INFRA:
+ /* our BSS (== from our AP) and from DS */
+ if (memcmp(hdr->addr2, ieee->bssid, ETH_ALEN) == 0)
+ if ((fc & (IEEE80211_FCTL_TODS+IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS) {
+ /* promisc: get all */
+ if (ieee->dev->flags & IFF_PROMISC)
+ is_packet_for_us = 1;
+ /* to us */
+ else if (memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN) == 0)
+ is_packet_for_us = 1;
+ /* mcast */
+ else if (is_multicast_ether_addr(hdr->addr1)) {
+ /* not our own packet bcasted from AP */
+ if (memcmp(hdr->addr3, ieee->dev->dev_addr, ETH_ALEN))
+ is_packet_for_us = 1;
+ }
+ }
+ break;
+ default:
+ /* ? */
+ break;
+ }
+
+ if (is_packet_for_us)
+ if (!ieee80211_rx(ieee, skb, stats))
+ dev_kfree_skb_irq(skb);
+ return;
+
+drop_free:
+ dev_kfree_skb_irq(skb);
+ ieee->stats.rx_dropped++;
+ return;
+}
+
#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
qos_param->aifs[i] -= (qos_param->aifs[i] < 2) ? 0 : 2;
cw_min = ac_params->ecw_min_max & 0x0F;
- qos_param->cw_min[i] = (u16) ((1 << cw_min) - 1);
+ qos_param->cw_min[i] = cpu_to_le16((1 << cw_min) - 1);
cw_max = (ac_params->ecw_min_max & 0xF0) >> 4;
- qos_param->cw_max[i] = (u16) ((1 << cw_max) - 1);
+ qos_param->cw_max[i] = cpu_to_le16((1 << cw_max) - 1);
qos_param->flag[i] =
(ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00;
txop = le16_to_cpu(ac_params->tx_op_limit) * 32;
- qos_param->tx_op_limit[i] = (u16) txop;
+ qos_param->tx_op_limit[i] = cpu_to_le16(txop);
}
return rc;
}
info_element->len +
sizeof(*info_element),
length, info_element->id);
- return 1;
+ /* We stop processing but don't return an error here
+ * because some misbehaviour APs break this rule. ie.
+ * Orinoco AP1000. */
+ break;
}
switch (info_element->id) {
case MFIE_TYPE_ERP_INFO:
network->erp_value = info_element->data[0];
+ network->flags |= NETWORK_HAS_ERP_VALUE;
IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n",
network->erp_value);
break;
case MFIE_TYPE_IBSS_DFS:
if (network->ibss_dfs)
break;
- network->ibss_dfs =
- kmalloc(info_element->len, GFP_ATOMIC);
+ network->ibss_dfs = kmemdup(info_element->data,
+ info_element->len,
+ GFP_ATOMIC);
if (!network->ibss_dfs)
return 1;
- memcpy(network->ibss_dfs, info_element->data,
- info_element->len);
network->flags |= NETWORK_HAS_IBSS_DFS;
break;
struct ieee80211_network *network,
struct ieee80211_rx_stats *stats)
{
+ DECLARE_MAC_BUF(mac);
+
network->qos_data.active = 0;
network->qos_data.supported = 0;
network->qos_data.param_count = 0;
}
if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
+ IEEE80211_DEBUG_SCAN("Filtered out '%s (%s)' "
"network.\n",
escape_essid(network->ssid,
network->ssid_len),
- MAC_ARG(network->bssid));
+ print_mac(mac, network->bssid));
return 1;
}
{
int qos_active;
u8 old_param;
+ DECLARE_MAC_BUF(mac);
ieee80211_network_reset(dst);
dst->ibss_dfs = src->ibss_dfs;
- memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
+ /* We only update the statistics if they were created by receiving
+ * the network information on the actual channel the network is on.
+ *
+ * This keeps beacons received on neighbor channels from bringing
+ * down the signal level of an AP. */
+ if (dst->channel == src->stats.received_channel)
+ memcpy(&dst->stats, &src->stats,
+ sizeof(struct ieee80211_rx_stats));
+ else
+ IEEE80211_DEBUG_SCAN("Network %s info received "
+ "off channel (%d vs. %d)\n", print_mac(mac, src->bssid),
+ dst->channel, src->stats.received_channel);
+
dst->capability = src->capability;
memcpy(dst->rates, src->rates, src->rates_len);
dst->rates_len = src->rates_len;
/* dst->last_associate is not overwritten */
}
-static inline int is_beacon(int fc)
+static inline int is_beacon(__le16 fc)
{
return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON);
}
struct ieee80211_info_element *info_element = beacon->info_element;
#endif
unsigned long flags;
-
- IEEE80211_DEBUG_SCAN("'%s' (" MAC_FMT
- "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- escape_essid(info_element->data,
- info_element->len),
- MAC_ARG(beacon->header.addr3),
- (beacon->capability & (1 << 0xf)) ? '1' : '0',
- (beacon->capability & (1 << 0xe)) ? '1' : '0',
- (beacon->capability & (1 << 0xd)) ? '1' : '0',
- (beacon->capability & (1 << 0xc)) ? '1' : '0',
- (beacon->capability & (1 << 0xb)) ? '1' : '0',
- (beacon->capability & (1 << 0xa)) ? '1' : '0',
- (beacon->capability & (1 << 0x9)) ? '1' : '0',
- (beacon->capability & (1 << 0x8)) ? '1' : '0',
- (beacon->capability & (1 << 0x7)) ? '1' : '0',
- (beacon->capability & (1 << 0x6)) ? '1' : '0',
- (beacon->capability & (1 << 0x5)) ? '1' : '0',
- (beacon->capability & (1 << 0x4)) ? '1' : '0',
- (beacon->capability & (1 << 0x3)) ? '1' : '0',
- (beacon->capability & (1 << 0x2)) ? '1' : '0',
- (beacon->capability & (1 << 0x1)) ? '1' : '0',
- (beacon->capability & (1 << 0x0)) ? '1' : '0');
+ DECLARE_MAC_BUF(mac);
+
+ IEEE80211_DEBUG_SCAN("'%s' (%s"
+ "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
+ escape_essid(info_element->data, info_element->len),
+ print_mac(mac, beacon->header.addr3),
+ (beacon->capability & cpu_to_le16(1 << 0xf)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0xe)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0xd)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0xc)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0xb)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0xa)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x9)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x8)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x7)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x6)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x5)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x4)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x3)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x2)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x1)) ? '1' : '0',
+ (beacon->capability & cpu_to_le16(1 << 0x0)) ? '1' : '0');
if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Dropped '%s' (%s) via %s.\n",
escape_essid(info_element->data,
info_element->len),
- MAC_ARG(beacon->header.addr3),
- is_beacon(le16_to_cpu
- (beacon->header.
- frame_ctl)) ?
+ print_mac(mac, beacon->header.addr3),
+ is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
return;
}
/* If there are no more slots, expire the oldest */
list_del(&oldest->list);
target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
+ IEEE80211_DEBUG_SCAN("Expired '%s' (%s) from "
"network list.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid));
+ print_mac(mac, target->bssid));
ieee80211_network_reset(target);
} else {
/* Otherwise just pull from the free list */
}
#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Adding '%s' (%s) via %s.\n",
escape_essid(network.ssid,
network.ssid_len),
- MAC_ARG(network.bssid),
- is_beacon(le16_to_cpu
- (beacon->header.
- frame_ctl)) ?
+ print_mac(mac, network.bssid),
+ is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
#endif
memcpy(target, &network, sizeof(*target));
network.ibss_dfs = NULL;
list_add_tail(&target->list, &ieee->network_list);
} else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
+ IEEE80211_DEBUG_SCAN("Updating '%s' (%s) via %s.\n",
escape_essid(target->ssid,
target->ssid_len),
- MAC_ARG(target->bssid),
- is_beacon(le16_to_cpu
- (beacon->header.
- frame_ctl)) ?
+ print_mac(mac, target->bssid),
+ is_beacon(beacon->header.frame_ctl) ?
"BEACON" : "PROBE RESPONSE");
update_network(target, &network);
network.ibss_dfs = NULL;
spin_unlock_irqrestore(&ieee->lock, flags);
- if (is_beacon(le16_to_cpu(beacon->header.frame_ctl))) {
+ if (is_beacon(beacon->header.frame_ctl)) {
if (ieee->handle_beacon != NULL)
- ieee->handle_beacon(dev, beacon, &network);
+ ieee->handle_beacon(dev, beacon, target);
} else {
if (ieee->handle_probe_response != NULL)
- ieee->handle_probe_response(dev, beacon, &network);
+ ieee->handle_probe_response(dev, beacon, target);
}
}
header, stats);
break;
+ case IEEE80211_STYPE_REASSOC_REQ:
+ IEEE80211_DEBUG_MGMT("received reassoc (%d)\n",
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+
+ IEEE80211_DEBUG_MGMT("%s: IEEE80211_REASSOC_REQ received\n",
+ ieee->dev->name);
+ if (ieee->handle_reassoc_request != NULL)
+ ieee->handle_reassoc_request(ieee->dev,
+ (struct ieee80211_reassoc_request *)
+ header);
+ break;
+
+ case IEEE80211_STYPE_ASSOC_REQ:
+ IEEE80211_DEBUG_MGMT("received assoc (%d)\n",
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
+
+ IEEE80211_DEBUG_MGMT("%s: IEEE80211_ASSOC_REQ received\n",
+ ieee->dev->name);
+ if (ieee->handle_assoc_request != NULL)
+ ieee->handle_assoc_request(ieee->dev);
+ break;
+
case IEEE80211_STYPE_DEAUTH:
IEEE80211_DEBUG_MGMT("DEAUTH\n");
if (ieee->handle_deauth != NULL)
IEEE80211_DEBUG_MGMT("received UNKNOWN (%d)\n",
WLAN_FC_GET_STYPE(le16_to_cpu
(header->frame_ctl)));
- IEEE80211_WARNING("%s: Unknown management packet: %d\n",
- ieee->dev->name,
- WLAN_FC_GET_STYPE(le16_to_cpu
- (header->frame_ctl)));
+ IEEE80211_DEBUG_MGMT("%s: Unknown management packet: %d\n",
+ ieee->dev->name,
+ WLAN_FC_GET_STYPE(le16_to_cpu
+ (header->frame_ctl)));
break;
}
}
+EXPORT_SYMBOL_GPL(ieee80211_rx_any);
EXPORT_SYMBOL(ieee80211_rx_mgt);
EXPORT_SYMBOL(ieee80211_rx);