aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-18 10:54:50 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-11-21 16:20:49 -0500
commitdd76986b0e398978ca32dd60c1b7dc50ab4e9ae1 (patch)
treefea61a3dcb75a0c90e772b2beeaf4edb49ae7b50 /net/mac80211/util.c
parent80b998993d97d8a13589f8462e62a60298c72cf2 (diff)
cfg80211/mac80211: Revert "move information element parsing logic to cfg80211"
No other driver ever ended up using this, and the commit forgot to move the prototype so no driver could have used it. Revert it, if any driver shows up and needs it it can be moved again, but until then it's more efficient to have it in mac80211 where the only user is. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 939bf248ec73..e2cb00df8c36 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -19,6 +19,7 @@
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/bitmap.h> 21#include <linux/bitmap.h>
22#include <linux/crc32.h>
22#include <net/net_namespace.h> 23#include <net/net_namespace.h>
23#include <net/cfg80211.h> 24#include <net/cfg80211.h>
24#include <net/rtnetlink.h> 25#include <net/rtnetlink.h>
@@ -563,6 +564,172 @@ void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
563} 564}
564EXPORT_SYMBOL(ieee80211_queue_delayed_work); 565EXPORT_SYMBOL(ieee80211_queue_delayed_work);
565 566
567u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
568 struct ieee802_11_elems *elems,
569 u64 filter, u32 crc)
570{
571 size_t left = len;
572 u8 *pos = start;
573 bool calc_crc = filter != 0;
574
575 memset(elems, 0, sizeof(*elems));
576 elems->ie_start = start;
577 elems->total_len = len;
578
579 while (left >= 2) {
580 u8 id, elen;
581
582 id = *pos++;
583 elen = *pos++;
584 left -= 2;
585
586 if (elen > left)
587 break;
588
589 if (calc_crc && id < 64 && (filter & (1ULL << id)))
590 crc = crc32_be(crc, pos - 2, elen + 2);
591
592 switch (id) {
593 case WLAN_EID_SSID:
594 elems->ssid = pos;
595 elems->ssid_len = elen;
596 break;
597 case WLAN_EID_SUPP_RATES:
598 elems->supp_rates = pos;
599 elems->supp_rates_len = elen;
600 break;
601 case WLAN_EID_FH_PARAMS:
602 elems->fh_params = pos;
603 elems->fh_params_len = elen;
604 break;
605 case WLAN_EID_DS_PARAMS:
606 elems->ds_params = pos;
607 elems->ds_params_len = elen;
608 break;
609 case WLAN_EID_CF_PARAMS:
610 elems->cf_params = pos;
611 elems->cf_params_len = elen;
612 break;
613 case WLAN_EID_TIM:
614 if (elen >= sizeof(struct ieee80211_tim_ie)) {
615 elems->tim = (void *)pos;
616 elems->tim_len = elen;
617 }
618 break;
619 case WLAN_EID_IBSS_PARAMS:
620 elems->ibss_params = pos;
621 elems->ibss_params_len = elen;
622 break;
623 case WLAN_EID_CHALLENGE:
624 elems->challenge = pos;
625 elems->challenge_len = elen;
626 break;
627 case WLAN_EID_VENDOR_SPECIFIC:
628 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
629 pos[2] == 0xf2) {
630 /* Microsoft OUI (00:50:F2) */
631
632 if (calc_crc)
633 crc = crc32_be(crc, pos - 2, elen + 2);
634
635 if (pos[3] == 1) {
636 /* OUI Type 1 - WPA IE */
637 elems->wpa = pos;
638 elems->wpa_len = elen;
639 } else if (elen >= 5 && pos[3] == 2) {
640 /* OUI Type 2 - WMM IE */
641 if (pos[4] == 0) {
642 elems->wmm_info = pos;
643 elems->wmm_info_len = elen;
644 } else if (pos[4] == 1) {
645 elems->wmm_param = pos;
646 elems->wmm_param_len = elen;
647 }
648 }
649 }
650 break;
651 case WLAN_EID_RSN:
652 elems->rsn = pos;
653 elems->rsn_len = elen;
654 break;
655 case WLAN_EID_ERP_INFO:
656 elems->erp_info = pos;
657 elems->erp_info_len = elen;
658 break;
659 case WLAN_EID_EXT_SUPP_RATES:
660 elems->ext_supp_rates = pos;
661 elems->ext_supp_rates_len = elen;
662 break;
663 case WLAN_EID_HT_CAPABILITY:
664 if (elen >= sizeof(struct ieee80211_ht_cap))
665 elems->ht_cap_elem = (void *)pos;
666 break;
667 case WLAN_EID_HT_INFORMATION:
668 if (elen >= sizeof(struct ieee80211_ht_info))
669 elems->ht_info_elem = (void *)pos;
670 break;
671 case WLAN_EID_MESH_ID:
672 elems->mesh_id = pos;
673 elems->mesh_id_len = elen;
674 break;
675 case WLAN_EID_MESH_CONFIG:
676 if (elen >= sizeof(struct ieee80211_meshconf_ie))
677 elems->mesh_config = (void *)pos;
678 break;
679 case WLAN_EID_PEER_MGMT:
680 elems->peering = pos;
681 elems->peering_len = elen;
682 break;
683 case WLAN_EID_PREQ:
684 elems->preq = pos;
685 elems->preq_len = elen;
686 break;
687 case WLAN_EID_PREP:
688 elems->prep = pos;
689 elems->prep_len = elen;
690 break;
691 case WLAN_EID_PERR:
692 elems->perr = pos;
693 elems->perr_len = elen;
694 break;
695 case WLAN_EID_RANN:
696 if (elen >= sizeof(struct ieee80211_rann_ie))
697 elems->rann = (void *)pos;
698 break;
699 case WLAN_EID_CHANNEL_SWITCH:
700 elems->ch_switch_elem = pos;
701 elems->ch_switch_elem_len = elen;
702 break;
703 case WLAN_EID_QUIET:
704 if (!elems->quiet_elem) {
705 elems->quiet_elem = pos;
706 elems->quiet_elem_len = elen;
707 }
708 elems->num_of_quiet_elem++;
709 break;
710 case WLAN_EID_COUNTRY:
711 elems->country_elem = pos;
712 elems->country_elem_len = elen;
713 break;
714 case WLAN_EID_PWR_CONSTRAINT:
715 elems->pwr_constr_elem = pos;
716 elems->pwr_constr_elem_len = elen;
717 break;
718 case WLAN_EID_TIMEOUT_INTERVAL:
719 elems->timeout_int = pos;
720 elems->timeout_int_len = elen;
721 break;
722 default:
723 break;
724 }
725
726 left -= elen;
727 pos += elen;
728 }
729
730 return crc;
731}
732
566void ieee802_11_parse_elems(u8 *start, size_t len, 733void ieee802_11_parse_elems(u8 *start, size_t len,
567 struct ieee802_11_elems *elems) 734 struct ieee802_11_elems *elems)
568{ 735{