18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEEE 802.11 Common routines 34b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt * Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 124b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt#include "defs.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_defs.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "ieee802_11_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems *elems, 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int show_errors) 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int oui; 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* first 3 bytes in vendor specific information element are the IEEE 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * OUI of the vendor. The following byte is used a vendor specific 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * sub-type. */ 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elen < 4) { 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (show_errors) { 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "short vendor specific " 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information element ignored (len=%lu)", 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) elen); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt oui = WPA_GET_BE24(pos); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (oui) { 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case OUI_MICROSOFT: 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Microsoft/Wi-Fi information elements are further typed and 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * subtyped */ 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (pos[3]) { 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 1: 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Microsoft OUI (00:50:F2) with OUI Type 1: 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * real WPA information element */ 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wpa_ie = pos; 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wpa_ie_len = elen; 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WMM_OUI_TYPE: 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* WMM information element */ 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elen < 5) { 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "short WMM " 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information element ignored " 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(len=%lu)", 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) elen); 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (pos[4]) { 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WMM_OUI_SUBTYPE_INFORMATION_ELEMENT: 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WMM_OUI_SUBTYPE_PARAMETER_ELEMENT: 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Share same pointer since only one of these 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is used and they start with same data. 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Length field can be used to distinguish the 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * IEs. 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wmm = pos; 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wmm_len = elen; 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WMM_OUI_SUBTYPE_TSPEC_ELEMENT: 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wmm_tspec = pos; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wmm_tspec_len = elen; 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_EXCESSIVE, "unknown WMM " 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information element ignored " 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(subtype=%d len=%lu)", 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[4], (unsigned long) elen); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case 4: 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wi-Fi Protected Setup (WPS) IE */ 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wps_ie = pos; 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->wps_ie_len = elen; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft " 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information element ignored " 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(type=%d len=%lu)", 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[3], (unsigned long) elen); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case OUI_WFA: 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (pos[3]) { 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case P2P_OUI_TYPE: 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wi-Fi Alliance - P2P IE */ 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->p2p = pos; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->p2p_len = elen; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case WFD_OUI_TYPE: 10261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* Wi-Fi Alliance - WFD IE */ 10361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->wfd = pos; 10461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->wfd_len = elen; 10561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 10604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case HS20_INDICATION_OUI_TYPE: 10704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt /* Hotspot 2.0 */ 10804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt elems->hs20 = pos; 10904949598a23f501be6eec21697465fd46a28840aDmitry Shmidt elems->hs20_len = elen; 11004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 111f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt case HS20_OSEN_OUI_TYPE: 112f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt /* Hotspot 2.0 OSEN */ 113f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt elems->osen = pos; 114f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt elems->osen_len = elen; 115f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt break; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "Unknown WFA " 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information element ignored " 119717574375e969e8272c6d1a26137286eac158abbDmitry Shmidt "(type=%d len=%lu)", 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[3], (unsigned long) elen); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case OUI_BROADCOM: 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (pos[3]) { 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case VENDOR_HT_CAPAB_OUI_TYPE: 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->vendor_ht_cap = pos; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->vendor_ht_cap_len = elen; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom " 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information element ignored " 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(type=%d len=%lu)", 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[3], (unsigned long) elen); 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_EXCESSIVE, "unknown vendor specific " 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "information element ignored (vendor OUI " 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%02x:%02x:%02x len=%lu)", 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos[0], pos[1], pos[2], (unsigned long) elen); 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ieee802_11_parse_elems - Parse information elements in management frames 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @start: Pointer to the start of IEs 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of IE buffer in octets 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @elems: Data structure for parsed elements 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @show_errors: Whether to show parsing errors in debug log 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Parsing result 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry ShmidtParseRes ieee802_11_parse_elems(const u8 *start, size_t len, 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct ieee802_11_elems *elems, 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int show_errors) 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left = len; 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos = start; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int unknown = 0; 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(elems, 0, sizeof(*elems)); 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (left >= 2) { 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 id, elen; 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id = *pos++; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elen = *pos++; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 2; 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elen > left) { 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (show_errors) { 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "IEEE 802.11 element " 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "parse failed (id=%d elen=%d " 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "left=%lu)", 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id, elen, (unsigned long) left); 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_MSGDUMP, "IEs", start, len); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ParseFailed; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt switch (id) { 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_SSID: 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ssid = pos; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ssid_len = elen; 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_SUPP_RATES: 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->supp_rates = pos; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->supp_rates_len = elen; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_DS_PARAMS: 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ds_params = pos; 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ds_params_len = elen; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_CF_PARAMS: 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_TIM: 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_CHALLENGE: 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->challenge = pos; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->challenge_len = elen; 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_ERP_INFO: 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->erp_info = pos; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->erp_info_len = elen; 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_EXT_SUPP_RATES: 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ext_supp_rates = pos; 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ext_supp_rates_len = elen; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_VENDOR_SPECIFIC: 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ieee802_11_parse_vendor_specific(pos, elen, 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems, 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt show_errors)) 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unknown++; 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_RSN: 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->rsn_ie = pos; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->rsn_ie_len = elen; 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_PWR_CAPABILITY: 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_SUPPORTED_CHANNELS: 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->supp_channels = pos; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->supp_channels_len = elen; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_MOBILITY_DOMAIN: 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->mdie = pos; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->mdie_len = elen; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_FAST_BSS_TRANSITION: 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ftie = pos; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ftie_len = elen; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_TIMEOUT_INTERVAL: 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->timeout_int = pos; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->timeout_int_len = elen; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_HT_CAP: 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ht_capabilities = pos; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ht_capabilities_len = elen; 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_HT_OPERATION: 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ht_operation = pos; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->ht_operation_len = elen; 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 25261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case WLAN_EID_VHT_CAP: 25361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->vht_capabilities = pos; 25461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->vht_capabilities_len = elen; 25561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 25661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt case WLAN_EID_VHT_OPERATION: 25761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->vht_operation = pos; 25861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt elems->vht_operation_len = elen; 25961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt break; 260bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt case WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION: 261bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt if (elen != 1) 262bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt break; 263bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt elems->vht_opmode_notif = pos; 264bd14a57187b024f49f5b9ace55ef457d8d04650aDmitry Shmidt break; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt case WLAN_EID_LINK_ID: 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (elen < 18) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt elems->link_id = pos; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2701f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_EID_INTERWORKING: 2711f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt elems->interworking = pos; 2721f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt elems->interworking_len = elen; 2731f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt break; 274051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt case WLAN_EID_QOS_MAP_SET: 275051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt if (elen < 16) 276051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 277051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt elems->qos_map_set = pos; 278051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt elems->qos_map_set_len = elen; 279051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt break; 28004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case WLAN_EID_EXT_CAPAB: 28104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt elems->ext_capab = pos; 28204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt elems->ext_capab_len = elen; 28304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 28404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt case WLAN_EID_BSS_MAX_IDLE_PERIOD: 28504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (elen < 3) 28604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 28704949598a23f501be6eec21697465fd46a28840aDmitry Shmidt elems->bss_max_idle_period = pos; 28804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt break; 289a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt case WLAN_EID_SSID_LIST: 290a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt elems->ssid_list = pos; 291a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt elems->ssid_list_len = elen; 292a54fa5fb807eaeff45464139b5a7759f060cec68Dmitry Shmidt break; 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt default: 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unknown++; 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!show_errors) 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse " 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "ignored unknown element (id=%d elen=%d)", 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id, elen); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= elen; 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += elen; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left) 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ParseFailed; 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return unknown ? ParseUnknown : ParseOK; 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint ieee802_11_ie_count(const u8 *ies, size_t ies_len) 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int count = 0; 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos, *end; 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ies == NULL) 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = ies; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = ies + ies_len; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 2 <= end) { 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt count++; 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return count; 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len, 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u32 oui_type) 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end, *pos, *ie; 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = ies; 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt end = ies + ies_len; 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = NULL; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&pos[2]) == oui_type) { 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ie = pos; 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ie == NULL) 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; /* No specified vendor IE found */ 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = wpabuf_alloc(ies_len); 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * There may be multiple vendor IEs in the message, so need to 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * concatenate their data fields. 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (pos + 1 < end) { 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos + 2 + pos[1] > end) 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 && 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_GET_BE32(&pos[2]) == oui_type) 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(buf, pos + 6, pos[1] - 4); 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 2 + pos[1]; 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3791f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3801f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3811f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidtconst u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) 3821f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt{ 3831f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt u16 fc, type, stype; 3841f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3851f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt /* 3861f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * PS-Poll frames are 16 bytes. All other frames are 3871f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt * 24 bytes or longer. 3881f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt */ 3891f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (len < 16) 3901f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 3911f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3921f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt fc = le_to_host16(hdr->frame_control); 3931f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt type = WLAN_FC_GET_TYPE(fc); 3941f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt stype = WLAN_FC_GET_STYPE(fc); 3951f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt 3961f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (type) { 3971f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_TYPE_DATA: 3981f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (len < 24) 3991f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 4001f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { 4011f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_FROMDS | WLAN_FC_TODS: 4021f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_TODS: 4031f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return hdr->addr1; 4041f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_FROMDS: 4051f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return hdr->addr2; 4061f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt default: 4071f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 4081f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4091f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_TYPE_CTRL: 4101f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (stype != WLAN_FC_STYPE_PSPOLL) 4111f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 4121f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return hdr->addr1; 4131f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt case WLAN_FC_TYPE_MGMT: 4141f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return hdr->addr3; 4151f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt default: 4161f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt return NULL; 4171f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt } 4181f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt} 41961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 42061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 42161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtint hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[], 42261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *name, const char *val) 42361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 42461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt int num, v; 42561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt const char *pos; 42661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct hostapd_wmm_ac_params *ac; 42761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 42861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* skip 'wme_ac_' or 'wmm_ac_' prefix */ 42961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = name + 7; 43061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strncmp(pos, "be_", 3) == 0) { 43161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt num = 0; 43261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += 3; 43361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (os_strncmp(pos, "bk_", 3) == 0) { 43461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt num = 1; 43561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += 3; 43661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (os_strncmp(pos, "vi_", 3) == 0) { 43761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt num = 2; 43861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += 3; 43961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (os_strncmp(pos, "vo_", 3) == 0) { 44061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt num = 3; 44161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos += 3; 44261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 44361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos); 44461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 44561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 44661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 44761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ac = &wmm_ac_params[num]; 44861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 44961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strcmp(pos, "aifs") == 0) { 45061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt v = atoi(val); 45161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (v < 1 || v > 255) { 45261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v); 45361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 45461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 45561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ac->aifs = v; 45661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (os_strcmp(pos, "cwmin") == 0) { 45761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt v = atoi(val); 45861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (v < 0 || v > 12) { 45961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v); 46061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 46161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 46261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ac->cwmin = v; 46361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (os_strcmp(pos, "cwmax") == 0) { 46461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt v = atoi(val); 46561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (v < 0 || v > 12) { 46661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v); 46761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 46861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 46961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ac->cwmax = v; 47061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (os_strcmp(pos, "txop_limit") == 0) { 47161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt v = atoi(val); 47261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (v < 0 || v > 0xffff) { 47361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid txop value %d", v); 47461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 47561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 47661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ac->txop_limit = v; 47761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else if (os_strcmp(pos, "acm") == 0) { 47861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt v = atoi(val); 47961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (v < 0 || v > 1) { 48061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Invalid acm value %d", v); 48161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 48261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 48361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt ac->admission_control_mandatory = v; 48461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } else { 48561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos); 48661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return -1; 48761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 48861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 48961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return 0; 49061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 4914b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 4924b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 4934b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidtenum hostapd_hw_mode ieee80211_freq_to_chan(int freq, u8 *channel) 4944b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt{ 4954b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt enum hostapd_hw_mode mode = NUM_HOSTAPD_MODES; 4964b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 4974b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt if (freq >= 2412 && freq <= 2472) { 4984b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode = HOSTAPD_MODE_IEEE80211G; 4994b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *channel = (freq - 2407) / 5; 5004b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else if (freq == 2484) { 5014b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode = HOSTAPD_MODE_IEEE80211B; 5024b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *channel = 14; 5034b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else if (freq >= 4900 && freq < 5000) { 5044b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode = HOSTAPD_MODE_IEEE80211A; 5054b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *channel = (freq - 4000) / 5; 5064b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else if (freq >= 5000 && freq < 5900) { 5074b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode = HOSTAPD_MODE_IEEE80211A; 5084b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *channel = (freq - 5000) / 5; 5094b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } else if (freq >= 56160 + 2160 * 1 && freq <= 56160 + 2160 * 4) { 5104b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt mode = HOSTAPD_MODE_IEEE80211AD; 5114b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt *channel = (freq - 56160) / 2160; 5124b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt } 5134b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt 5144b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt return mode; 5154b06059785b935dd1f4f09314e4e12c417d2c6a4Dmitry Shmidt} 51634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 51734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 51834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtstatic int is_11b(u8 rate) 51934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 52034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return rate == 0x02 || rate == 0x04 || rate == 0x0b || rate == 0x16; 52134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 52234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 52334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 52434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidtint supp_rates_11b_only(struct ieee802_11_elems *elems) 52534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt{ 52634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int num_11b = 0, num_others = 0; 52734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt int i; 52834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 52934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (elems->supp_rates == NULL && elems->ext_supp_rates == NULL) 53034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return 0; 53134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 53234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt for (i = 0; elems->supp_rates && i < elems->supp_rates_len; i++) { 53334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (is_11b(elems->supp_rates[i])) 53434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt num_11b++; 53534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else 53634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt num_others++; 53734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 53834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 53934af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt for (i = 0; elems->ext_supp_rates && i < elems->ext_supp_rates_len; 54034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt i++) { 54134af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (is_11b(elems->ext_supp_rates[i])) 54234af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt num_11b++; 54334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt else 54434af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt num_others++; 54534af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt } 54634af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt 54734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt return num_11b > 0 && num_others == 0; 54834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt} 5492271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 5502271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 5512271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidtconst char * fc2str(u16 fc) 5522271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt{ 5532271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt u16 stype = WLAN_FC_GET_STYPE(fc); 5542271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt#define C2S(x) case x: return #x; 5552271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt 5562271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt switch (WLAN_FC_GET_TYPE(fc)) { 5572271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt case WLAN_FC_TYPE_MGMT: 5582271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt switch (stype) { 5592271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_ASSOC_REQ) 5602271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_ASSOC_RESP) 5612271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_REASSOC_REQ) 5622271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_REASSOC_RESP) 5632271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_PROBE_REQ) 5642271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_PROBE_RESP) 5652271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_BEACON) 5662271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_ATIM) 5672271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_DISASSOC) 5682271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_AUTH) 5692271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_DEAUTH) 5702271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_ACTION) 5712271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt } 5722271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt break; 5732271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt case WLAN_FC_TYPE_CTRL: 5742271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt switch (stype) { 5752271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_PSPOLL) 5762271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_RTS) 5772271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_CTS) 5782271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_ACK) 5792271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_CFEND) 5802271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_CFENDACK) 5812271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt } 5822271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt break; 5832271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt case WLAN_FC_TYPE_DATA: 5842271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt switch (stype) { 5852271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_DATA) 5862271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_DATA_CFACK) 5872271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_DATA_CFPOLL) 5882271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_DATA_CFACKPOLL) 5892271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_NULLFUNC) 5902271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_CFACK) 5912271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_CFPOLL) 5922271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_CFACKPOLL) 5932271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_QOS_DATA) 5942271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_QOS_DATA_CFACK) 5952271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_QOS_DATA_CFPOLL) 5962271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_QOS_DATA_CFACKPOLL) 5972271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_QOS_NULL) 5982271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_QOS_CFPOLL) 5992271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt C2S(WLAN_FC_STYPE_QOS_CFACKPOLL) 6002271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt } 6012271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt break; 6022271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt } 6032271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt return "WLAN_FC_TYPE_UNKNOWN"; 6042271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt#undef C2S 6052271d3fdd5982d0e5e81cf9999a861bba933eacbDmitry Shmidt} 606