aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/ieee80211_rx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211/ieee80211_rx.c')
-rw-r--r--net/ieee80211/ieee80211_rx.c153
1 files changed, 142 insertions, 11 deletions
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 960aa78cdb97..fcf4382ef7d7 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -369,8 +369,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
369 369
370 /* Put this code here so that we avoid duplicating it in all 370 /* Put this code here so that we avoid duplicating it in all
371 * Rx paths. - Jean II */ 371 * Rx paths. - Jean II */
372#ifdef CONFIG_WIRELESS_EXT
372#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ 373#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
373#ifdef CONFIG_NET_RADIO
374 /* If spy monitoring on */ 374 /* If spy monitoring on */
375 if (ieee->spy_data.spy_number > 0) { 375 if (ieee->spy_data.spy_number > 0) {
376 struct iw_quality wstats; 376 struct iw_quality wstats;
@@ -397,8 +397,8 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
397 /* Update spy records */ 397 /* Update spy records */
398 wireless_spy_update(ieee->dev, hdr->addr2, &wstats); 398 wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
399 } 399 }
400#endif /* CONFIG_NET_RADIO */
401#endif /* IW_WIRELESS_SPY */ 400#endif /* IW_WIRELESS_SPY */
401#endif /* CONFIG_WIRELESS_EXT */
402 402
403#ifdef NOT_YET 403#ifdef NOT_YET
404 hostap_update_rx_stats(local->ap, hdr, rx_stats); 404 hostap_update_rx_stats(local->ap, hdr, rx_stats);
@@ -574,7 +574,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
574 /* skb: hdr + (possibly fragmented) plaintext payload */ 574 /* skb: hdr + (possibly fragmented) plaintext payload */
575 // PR: FIXME: hostap has additional conditions in the "if" below: 575 // PR: FIXME: hostap has additional conditions in the "if" below:
576 // ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) && 576 // ieee->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
577 if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { 577 if ((frag != 0) || (fc & IEEE80211_FCTL_MOREFRAGS)) {
578 int flen; 578 int flen;
579 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr); 579 struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
580 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); 580 IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
@@ -754,7 +754,14 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
754 memset(skb->cb, 0, sizeof(skb->cb)); 754 memset(skb->cb, 0, sizeof(skb->cb));
755 skb->dev = dev; 755 skb->dev = dev;
756 skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ 756 skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
757 netif_rx(skb); 757 if (netif_rx(skb) == NET_RX_DROP) {
758 /* netif_rx always succeeds, but it might drop
759 * the packet. If it drops the packet, we log that
760 * in our stats. */
761 IEEE80211_DEBUG_DROP
762 ("RX: netif_rx dropped the packet\n");
763 stats->rx_dropped++;
764 }
758 } 765 }
759 766
760 rx_exit: 767 rx_exit:
@@ -930,6 +937,45 @@ static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element
930 return rc; 937 return rc;
931} 938}
932 939
940#ifdef CONFIG_IEEE80211_DEBUG
941#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x
942
943static const char *get_info_element_string(u16 id)
944{
945 switch (id) {
946 MFIE_STRING(SSID);
947 MFIE_STRING(RATES);
948 MFIE_STRING(FH_SET);
949 MFIE_STRING(DS_SET);
950 MFIE_STRING(CF_SET);
951 MFIE_STRING(TIM);
952 MFIE_STRING(IBSS_SET);
953 MFIE_STRING(COUNTRY);
954 MFIE_STRING(HOP_PARAMS);
955 MFIE_STRING(HOP_TABLE);
956 MFIE_STRING(REQUEST);
957 MFIE_STRING(CHALLENGE);
958 MFIE_STRING(POWER_CONSTRAINT);
959 MFIE_STRING(POWER_CAPABILITY);
960 MFIE_STRING(TPC_REQUEST);
961 MFIE_STRING(TPC_REPORT);
962 MFIE_STRING(SUPP_CHANNELS);
963 MFIE_STRING(CSA);
964 MFIE_STRING(MEASURE_REQUEST);
965 MFIE_STRING(MEASURE_REPORT);
966 MFIE_STRING(QUIET);
967 MFIE_STRING(IBSS_DFS);
968 MFIE_STRING(ERP_INFO);
969 MFIE_STRING(RSN);
970 MFIE_STRING(RATES_EX);
971 MFIE_STRING(GENERIC);
972 MFIE_STRING(QOS_PARAMETER);
973 default:
974 return "UNKNOWN";
975 }
976}
977#endif
978
933static int ieee80211_parse_info_param(struct ieee80211_info_element 979static int ieee80211_parse_info_param(struct ieee80211_info_element
934 *info_element, u16 length, 980 *info_element, u16 length,
935 struct ieee80211_network *network) 981 struct ieee80211_network *network)
@@ -1040,7 +1086,9 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1040 break; 1086 break;
1041 1087
1042 case MFIE_TYPE_TIM: 1088 case MFIE_TYPE_TIM:
1043 IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: ignored\n"); 1089 network->tim.tim_count = info_element->data[0];
1090 network->tim.tim_period = info_element->data[1];
1091 IEEE80211_DEBUG_MGMT("MFIE_TYPE_TIM: partially ignored\n");
1044 break; 1092 break;
1045 1093
1046 case MFIE_TYPE_ERP_INFO: 1094 case MFIE_TYPE_ERP_INFO:
@@ -1091,10 +1139,49 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1091 printk(KERN_ERR 1139 printk(KERN_ERR
1092 "QoS Error need to parse QOS_PARAMETER IE\n"); 1140 "QoS Error need to parse QOS_PARAMETER IE\n");
1093 break; 1141 break;
1142 /* 802.11h */
1143 case MFIE_TYPE_POWER_CONSTRAINT:
1144 network->power_constraint = info_element->data[0];
1145 network->flags |= NETWORK_HAS_POWER_CONSTRAINT;
1146 break;
1147
1148 case MFIE_TYPE_CSA:
1149 network->power_constraint = info_element->data[0];
1150 network->flags |= NETWORK_HAS_CSA;
1151 break;
1152
1153 case MFIE_TYPE_QUIET:
1154 network->quiet.count = info_element->data[0];
1155 network->quiet.period = info_element->data[1];
1156 network->quiet.duration = info_element->data[2];
1157 network->quiet.offset = info_element->data[3];
1158 network->flags |= NETWORK_HAS_QUIET;
1159 break;
1160
1161 case MFIE_TYPE_IBSS_DFS:
1162 if (network->ibss_dfs)
1163 break;
1164 network->ibss_dfs =
1165 kmalloc(info_element->len, GFP_ATOMIC);
1166 if (!network->ibss_dfs)
1167 return 1;
1168 memcpy(network->ibss_dfs, info_element->data,
1169 info_element->len);
1170 network->flags |= NETWORK_HAS_IBSS_DFS;
1171 break;
1172
1173 case MFIE_TYPE_TPC_REPORT:
1174 network->tpc_report.transmit_power =
1175 info_element->data[0];
1176 network->tpc_report.link_margin = info_element->data[1];
1177 network->flags |= NETWORK_HAS_TPC_REPORT;
1178 break;
1094 1179
1095 default: 1180 default:
1096 IEEE80211_DEBUG_MGMT("unsupported IE %d\n", 1181 IEEE80211_DEBUG_MGMT
1097 info_element->id); 1182 ("Unsupported info element: %s (%d)\n",
1183 get_info_element_string(info_element->id),
1184 info_element->id);
1098 break; 1185 break;
1099 } 1186 }
1100 1187
@@ -1110,7 +1197,9 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1110static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response 1197static int ieee80211_handle_assoc_resp(struct ieee80211_device *ieee, struct ieee80211_assoc_response
1111 *frame, struct ieee80211_rx_stats *stats) 1198 *frame, struct ieee80211_rx_stats *stats)
1112{ 1199{
1113 struct ieee80211_network network_resp; 1200 struct ieee80211_network network_resp = {
1201 .ibss_dfs = NULL,
1202 };
1114 struct ieee80211_network *network = &network_resp; 1203 struct ieee80211_network *network = &network_resp;
1115 struct net_device *dev = ieee->dev; 1204 struct net_device *dev = ieee->dev;
1116 1205
@@ -1253,6 +1342,9 @@ static void update_network(struct ieee80211_network *dst,
1253 int qos_active; 1342 int qos_active;
1254 u8 old_param; 1343 u8 old_param;
1255 1344
1345 ieee80211_network_reset(dst);
1346 dst->ibss_dfs = src->ibss_dfs;
1347
1256 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); 1348 memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
1257 dst->capability = src->capability; 1349 dst->capability = src->capability;
1258 memcpy(dst->rates, src->rates, src->rates_len); 1350 memcpy(dst->rates, src->rates, src->rates_len);
@@ -1269,6 +1361,7 @@ static void update_network(struct ieee80211_network *dst,
1269 dst->listen_interval = src->listen_interval; 1361 dst->listen_interval = src->listen_interval;
1270 dst->atim_window = src->atim_window; 1362 dst->atim_window = src->atim_window;
1271 dst->erp_value = src->erp_value; 1363 dst->erp_value = src->erp_value;
1364 dst->tim = src->tim;
1272 1365
1273 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); 1366 memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
1274 dst->wpa_ie_len = src->wpa_ie_len; 1367 dst->wpa_ie_len = src->wpa_ie_len;
@@ -1313,7 +1406,9 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1313 *stats) 1406 *stats)
1314{ 1407{
1315 struct net_device *dev = ieee->dev; 1408 struct net_device *dev = ieee->dev;
1316 struct ieee80211_network network; 1409 struct ieee80211_network network = {
1410 .ibss_dfs = NULL,
1411 };
1317 struct ieee80211_network *target; 1412 struct ieee80211_network *target;
1318 struct ieee80211_network *oldest = NULL; 1413 struct ieee80211_network *oldest = NULL;
1319#ifdef CONFIG_IEEE80211_DEBUG 1414#ifdef CONFIG_IEEE80211_DEBUG
@@ -1388,6 +1483,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1388 escape_essid(target->ssid, 1483 escape_essid(target->ssid,
1389 target->ssid_len), 1484 target->ssid_len),
1390 MAC_ARG(target->bssid)); 1485 MAC_ARG(target->bssid));
1486 ieee80211_network_reset(target);
1391 } else { 1487 } else {
1392 /* Otherwise just pull from the free list */ 1488 /* Otherwise just pull from the free list */
1393 target = list_entry(ieee->network_free_list.next, 1489 target = list_entry(ieee->network_free_list.next,
@@ -1406,6 +1502,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1406 "BEACON" : "PROBE RESPONSE"); 1502 "BEACON" : "PROBE RESPONSE");
1407#endif 1503#endif
1408 memcpy(target, &network, sizeof(*target)); 1504 memcpy(target, &network, sizeof(*target));
1505 network.ibss_dfs = NULL;
1409 list_add_tail(&target->list, &ieee->network_list); 1506 list_add_tail(&target->list, &ieee->network_list);
1410 } else { 1507 } else {
1411 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n", 1508 IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
@@ -1417,6 +1514,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1417 frame_ctl)) ? 1514 frame_ctl)) ?
1418 "BEACON" : "PROBE RESPONSE"); 1515 "BEACON" : "PROBE RESPONSE");
1419 update_network(target, &network); 1516 update_network(target, &network);
1517 network.ibss_dfs = NULL;
1420 } 1518 }
1421 1519
1422 spin_unlock_irqrestore(&ieee->lock, flags); 1520 spin_unlock_irqrestore(&ieee->lock, flags);
@@ -1501,10 +1599,43 @@ void ieee80211_rx_mgt(struct ieee80211_device *ieee,
1501 header); 1599 header);
1502 break; 1600 break;
1503 1601
1602 case IEEE80211_STYPE_ACTION:
1603 IEEE80211_DEBUG_MGMT("ACTION\n");
1604 if (ieee->handle_action)
1605 ieee->handle_action(ieee->dev,
1606 (struct ieee80211_action *)
1607 header, stats);
1608 break;
1609
1610 case IEEE80211_STYPE_REASSOC_REQ:
1611 IEEE80211_DEBUG_MGMT("received reassoc (%d)\n",
1612 WLAN_FC_GET_STYPE(le16_to_cpu
1613 (header->frame_ctl)));
1614
1615 IEEE80211_WARNING("%s: IEEE80211_REASSOC_REQ received\n",
1616 ieee->dev->name);
1617 if (ieee->handle_reassoc_request != NULL)
1618 ieee->handle_reassoc_request(ieee->dev,
1619 (struct ieee80211_reassoc_request *)
1620 header);
1621 break;
1622
1623 case IEEE80211_STYPE_ASSOC_REQ:
1624 IEEE80211_DEBUG_MGMT("received assoc (%d)\n",
1625 WLAN_FC_GET_STYPE(le16_to_cpu
1626 (header->frame_ctl)));
1627
1628 IEEE80211_WARNING("%s: IEEE80211_ASSOC_REQ received\n",
1629 ieee->dev->name);
1630 if (ieee->handle_assoc_request != NULL)
1631 ieee->handle_assoc_request(ieee->dev);
1632 break;
1633
1504 case IEEE80211_STYPE_DEAUTH: 1634 case IEEE80211_STYPE_DEAUTH:
1505 printk("DEAUTH from AP\n"); 1635 IEEE80211_DEBUG_MGMT("DEAUTH\n");
1506 if (ieee->handle_deauth != NULL) 1636 if (ieee->handle_deauth != NULL)
1507 ieee->handle_deauth(ieee->dev, (struct ieee80211_auth *) 1637 ieee->handle_deauth(ieee->dev,
1638 (struct ieee80211_deauth *)
1508 header); 1639 header);
1509 break; 1640 break;
1510 default: 1641 default: