24 #include <linux/compiler.h>
26 #include <linux/errno.h>
27 #include <linux/if_arp.h>
28 #include <linux/in6.h>
31 #include <linux/kernel.h>
32 #include <linux/module.h>
33 #include <linux/netdevice.h>
34 #include <linux/pci.h>
37 #include <linux/slab.h>
38 #include <linux/tcp.h>
39 #include <linux/types.h>
40 #include <linux/wireless.h>
42 #include <asm/uaccess.h>
43 #include <linux/ctype.h>
56 skb_reset_mac_header(skb);
60 memset(skb->cb, 0,
sizeof(skb->cb));
78 "expiring fragment cache entry "
79 "seq=%u last_frag=%u\n",
86 (entry->
last_frag + 1 == frag || frag == -1) &&
126 skb = dev_alloc_skb(ieee->
dev->mtu +
153 entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->
addr2,
191 entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->
addr2,
196 "could not invalidate fragment cache "
197 "entry (seq=%u)\n", seq);
247 static unsigned char rfc1042_header[] =
248 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
250 static unsigned char bridge_tunnel_header[] =
251 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
282 if (skb->
len < 24 + 8)
288 ethertype = (pos[6] << 8) | pos[7];
303 if (crypt ==
NULL || crypt->
ops->decrypt_mpdu ==
NULL)
309 #ifdef CONFIG_IEEE80211_CRYPT_TKIP
314 "received packet from %pM\n",
322 res = crypt->
ops->decrypt_mpdu(skb, hdrlen, crypt->
priv);
326 "decryption failed (SA=%pM"
327 ") res=%d\n", hdr->
addr2, res);
330 "mismatch (key %d)\n",
331 skb->
data[hdrlen + 3] >> 6);
348 if (crypt ==
NULL || crypt->
ops->decrypt_msdu ==
NULL)
355 res = crypt->
ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->
priv);
359 " (SA=%pM keyidx=%d)\n",
360 ieee->
dev->name, hdr->
addr2, keyidx);
369 #define IEEE_PACKET_RETRY_TIME (5*HZ)
377 u16 *last_seq, *last_frag;
424 last_seq = &entry->
seq_num[tid];
443 if ((*last_seq == seq) &&
445 if (*last_frag == frag){
450 if (*last_frag + 1 != frag)
493 stats = &ieee->
stats;
529 ieee80211_monitor_rx(ieee, skb, rx_stats);
537 if (skb->
len >= hdrlen + 3)
538 idx = skb->
data[hdrlen + 3] >> 6;
543 if (crypt && (crypt->
ops ==
NULL ||
544 crypt->
ops->decrypt_mpdu ==
NULL))
564 if (is_duplicate_packet(ieee, hdr))
569 if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
582 case IEEE80211_FCTL_TODS:
615 "RX: dropped data frame "
616 "with no data (type=0x%02x, "
617 "subtype=0x%02x, len=%d)\n",
618 type, stype, skb->
len);
630 (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
640 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
645 "Rx cannot get skb from fragment "
646 "cache (morefrag=%d seq=%u frag=%u)\n",
647 (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
655 if (frag_skb->
tail + flen > frag_skb->
end) {
657 "reassembled frame did not fit skb\n",
659 ieee80211_frag_cache_invalidate(ieee, hdr);
676 if (fc & IEEE80211_FCTL_MOREFRAGS) {
687 ieee80211_frag_cache_invalidate(ieee, hdr);
693 ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
697 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->
open_wep) {
699 ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
701 #ifdef CONFIG_IEEE80211_DEBUG
707 eap_get_type(eap->
type));
711 "encryption configured, but RX "
712 "frame not encrypted (SA=%pM)\n",
718 #ifdef CONFIG_IEEE80211_DEBUG
719 if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
720 ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
724 eap_get_type(eap->
type));
728 if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->
open_wep &&
729 !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
731 "dropped unencrypted RX data "
733 " (drop_unencrypted=1)\n",
744 ethertype = (payload[6] << 8) | payload[7];
748 if (skb->
len - hdrlen >= 8 &&
773 memset(skb->cb, 0,
sizeof(skb->cb));
792 #define MGMT_FRAME_FIXED_PART_LENGTH 0x24
794 static inline int ieee80211_is_ofdm_rate(
u8 rate)
810 static inline int ieee80211_SignalStrengthTranslate(
817 if(CurrSS >= 71 && CurrSS <= 100)
819 RetSS = 90 + ((CurrSS - 70) / 3);
821 else if(CurrSS >= 41 && CurrSS <= 70)
823 RetSS = 78 + ((CurrSS - 40) / 3);
825 else if(CurrSS >= 31 && CurrSS <= 40)
827 RetSS = 66 + (CurrSS - 30);
829 else if(CurrSS >= 21 && CurrSS <= 30)
831 RetSS = 54 + (CurrSS - 20);
833 else if(CurrSS >= 5 && CurrSS <= 20)
835 RetSS = 42 + (((CurrSS - 5) * 2) / 3);
866 static inline void ieee80211_extract_country_ie(
875 if(info_element->
len!= 0)
901 unsigned char SignalStrengthIndex
904 unsigned char SignalPower;
907 SignalPower = (
int)SignalStrengthIndex * 7 / 10;
918 #ifdef CONFIG_IEEE80211_DEBUG
926 u8 curRate = 0,hOpRate = 0,curRate_ex = 0;
960 left = stats->
len - ((
void *)info_element - (
void *)beacon);
963 IEEE80211_DEBUG_SCAN(
"SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
969 switch (info_element->
id) {
972 info_element->
len)) {
980 if (network->
ssid_len < IW_ESSID_MAX_SIZE)
982 IW_ESSID_MAX_SIZE - network->
ssid_len);
989 #ifdef CONFIG_IEEE80211_DEBUG
993 for (i = 0; i < network->
rates_len; i++) {
995 curRate = network->
rates[
i] & 0x7f;
996 if( hOpRate < curRate )
998 #ifdef CONFIG_IEEE80211_DEBUG
999 p +=
snprintf(p,
sizeof(rates_str) - (p - rates_str),
"%02X ", network->
rates[i]);
1001 if (ieee80211_is_ofdm_rate(info_element->
data[i])) {
1003 if (info_element->
data[i] &
1015 #ifdef CONFIG_IEEE80211_DEBUG
1021 curRate_ex = network->
rates_ex[
i] & 0x7f;
1022 if( hOpRate < curRate_ex )
1023 hOpRate = curRate_ex;
1024 #ifdef CONFIG_IEEE80211_DEBUG
1025 p +=
snprintf(p,
sizeof(rates_str) - (p - rates_str),
"%02X ", network->
rates[i]);
1027 if (ieee80211_is_ofdm_rate(info_element->
data[i])) {
1029 if (info_element->
data[i] &
1042 info_element->
data[0]);
1057 if(info_element->
len < 4)
1070 if(info_element->
data[0] != 0)
1073 if(info_element->
data[2] & 1)
1076 offset = (info_element->
data[2] >> 1)*2;
1082 ieee->
assoc_id > 8*(offset + info_element->
len -3)) {
1086 offset = (ieee->
assoc_id/8) - offset;
1092 if(info_element->
data[3+offset] & (1<<(ieee->
assoc_id%8))) {
1109 if (info_element->
len >= 4 &&
1110 info_element->
data[0] == 0x00 &&
1111 info_element->
data[1] == 0x50 &&
1112 info_element->
data[2] == 0xf2 &&
1113 info_element->
data[3] == 0x01) {
1120 if (info_element->
len == 7 &&
1121 info_element->
data[0] == 0x00 &&
1122 info_element->
data[1] == 0xe0 &&
1123 info_element->
data[2] == 0x4c &&
1124 info_element->
data[3] == 0x01 &&
1125 info_element->
data[4] == 0x02) {
1132 if (info_element->
len >= 5 &&
1133 info_element->
data[0] == 0x00 &&
1134 info_element->
data[1] == 0x50 &&
1135 info_element->
data[2] == 0xf2 &&
1136 info_element->
data[3] == 0x02 &&
1137 info_element->
data[4] == 0x00) {
1144 if (info_element->
len >= 8 &&
1145 info_element->
data[0] == 0x00 &&
1146 info_element->
data[1] == 0x50 &&
1147 info_element->
data[2] == 0xf2 &&
1148 info_element->
data[3] == 0x02 &&
1149 info_element->
data[4] == 0x01) {
1172 ieee80211_extract_country_ie(ieee, info_element, network, beacon->
header.addr2);
1183 &info_element->data[info_element->len];
1198 if (network->
mode == 0) {
1201 escape_essid(network->
ssid,
1241 unsigned char quality = src->
stats.signalstrength;
1242 unsigned char signal = 0;
1243 unsigned char noise = 0;
1244 if(dst->
stats.signalstrength > 0) {
1245 quality = (dst->
stats.signalstrength * 5 + src->
stats.signalstrength + 5)/6;
1249 if(dst->
stats.noise > 0)
1250 noise = (dst->
stats.noise * 5 + src->
stats.noise)/6;
1254 dst->
stats.signalstrength = quality;
1255 dst->
stats.signal = signal;
1257 dst->
stats.noise = noise;
1308 if(src->
wmm_param[0].ac_aci_acm_aifsn|| \
1333 #ifdef CONFIG_IEEE80211_DEBUG
1336 unsigned long flags;
1344 "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
1345 escape_essid(info_element->
data, info_element->
len),
1362 (beacon->
capability & (1<<0x0)) ?
'1' :
'0');
1366 escape_essid(info_element->
data,
1371 "PROBE RESPONSE" :
"BEACON");
1390 printk(
"GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.
channel);
1400 printk(
"GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.
channel);
1412 printk(
"GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.
channel);
1422 printk(
"GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.
channel);
1453 if (is_same_network(target, &network, ieee))
1455 if ((oldest ==
NULL) ||
1469 escape_essid(target->
ssid,
1480 #ifdef CONFIG_IEEE80211_DEBUG
1482 escape_essid(network.
ssid,
1487 "PROBE RESPONSE" :
"BEACON");
1490 memcpy(target, &network,
sizeof(*target));
1494 escape_essid(target->
ssid,
1499 "PROBE RESPONSE" :
"BEACON");
1519 spin_unlock_irqrestore(&ieee->
lock, flags);