diff options
Diffstat (limited to 'contrib/wpa/src/common/ieee802_11_common.c')
-rw-r--r-- | contrib/wpa/src/common/ieee802_11_common.c | 194 |
1 files changed, 178 insertions, 16 deletions
diff --git a/contrib/wpa/src/common/ieee802_11_common.c b/contrib/wpa/src/common/ieee802_11_common.c index 96ef5b6..98fadda 100644 --- a/contrib/wpa/src/common/ieee802_11_common.c +++ b/contrib/wpa/src/common/ieee802_11_common.c @@ -1,15 +1,9 @@ /* * IEEE 802.11 Common routines - * Copyright (c) 2002-2009, Jouni Malinen <j@w1.fi> + * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Alternatively, this software may be distributed under the terms of BSD - * license. - * - * See README and COPYING for more details. + * This software may be distributed under the terms of the BSD license. + * See README for more details. */ #include "includes.h" @@ -75,7 +69,7 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, elems->wmm_tspec_len = elen; break; default: - wpa_printf(MSG_MSGDUMP, "unknown WMM " + wpa_printf(MSG_EXCESSIVE, "unknown WMM " "information element ignored " "(subtype=%d len=%lu)", pos[4], (unsigned long) elen); @@ -88,7 +82,33 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, elems->wps_ie_len = elen; break; default: - wpa_printf(MSG_MSGDUMP, "Unknown Microsoft " + wpa_printf(MSG_EXCESSIVE, "Unknown Microsoft " + "information element ignored " + "(type=%d len=%lu)", + pos[3], (unsigned long) elen); + return -1; + } + break; + + case OUI_WFA: + switch (pos[3]) { + case P2P_OUI_TYPE: + /* Wi-Fi Alliance - P2P IE */ + elems->p2p = pos; + elems->p2p_len = elen; + break; + case WFD_OUI_TYPE: + /* Wi-Fi Alliance - WFD IE */ + elems->wfd = pos; + elems->wfd_len = elen; + break; + case HS20_INDICATION_OUI_TYPE: + /* Hotspot 2.0 */ + elems->hs20 = pos; + elems->hs20_len = elen; + break; + default: + wpa_printf(MSG_MSGDUMP, "Unknown WFA " "information element ignored " "(type=%d len=%lu)\n", pos[3], (unsigned long) elen); @@ -103,18 +123,18 @@ static int ieee802_11_parse_vendor_specific(const u8 *pos, size_t elen, elems->vendor_ht_cap_len = elen; break; default: - wpa_printf(MSG_MSGDUMP, "Unknown Broadcom " + wpa_printf(MSG_EXCESSIVE, "Unknown Broadcom " "information element ignored " - "(type=%d len=%lu)\n", + "(type=%d len=%lu)", pos[3], (unsigned long) elen); return -1; } break; default: - wpa_printf(MSG_MSGDUMP, "unknown vendor specific information " - "element ignored (vendor OUI %02x:%02x:%02x " - "len=%lu)", + wpa_printf(MSG_EXCESSIVE, "unknown vendor specific " + "information element ignored (vendor OUI " + "%02x:%02x:%02x len=%lu)", pos[0], pos[1], pos[2], (unsigned long) elen); return -1; } @@ -238,6 +258,36 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len, elems->ht_operation = pos; elems->ht_operation_len = elen; break; + case WLAN_EID_VHT_CAP: + elems->vht_capabilities = pos; + elems->vht_capabilities_len = elen; + break; + case WLAN_EID_VHT_OPERATION: + elems->vht_operation = pos; + elems->vht_operation_len = elen; + break; + case WLAN_EID_LINK_ID: + if (elen < 18) + break; + elems->link_id = pos; + break; + case WLAN_EID_INTERWORKING: + elems->interworking = pos; + elems->interworking_len = elen; + break; + case WLAN_EID_EXT_CAPAB: + elems->ext_capab = pos; + elems->ext_capab_len = elen; + break; + case WLAN_EID_BSS_MAX_IDLE_PERIOD: + if (elen < 3) + break; + elems->bss_max_idle_period = pos; + break; + case WLAN_EID_SSID_LIST: + elems->ssid_list = pos; + elems->ssid_list_len = elen; + break; default: unknown++; if (!show_errors) @@ -324,3 +374,115 @@ struct wpabuf * ieee802_11_vendor_ie_concat(const u8 *ies, size_t ies_len, return buf; } + + +const u8 * get_hdr_bssid(const struct ieee80211_hdr *hdr, size_t len) +{ + u16 fc, type, stype; + + /* + * PS-Poll frames are 16 bytes. All other frames are + * 24 bytes or longer. + */ + if (len < 16) + return NULL; + + fc = le_to_host16(hdr->frame_control); + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + + switch (type) { + case WLAN_FC_TYPE_DATA: + if (len < 24) + return NULL; + switch (fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) { + case WLAN_FC_FROMDS | WLAN_FC_TODS: + case WLAN_FC_TODS: + return hdr->addr1; + case WLAN_FC_FROMDS: + return hdr->addr2; + default: + return NULL; + } + case WLAN_FC_TYPE_CTRL: + if (stype != WLAN_FC_STYPE_PSPOLL) + return NULL; + return hdr->addr1; + case WLAN_FC_TYPE_MGMT: + return hdr->addr3; + default: + return NULL; + } +} + + +int hostapd_config_wmm_ac(struct hostapd_wmm_ac_params wmm_ac_params[], + const char *name, const char *val) +{ + int num, v; + const char *pos; + struct hostapd_wmm_ac_params *ac; + + /* skip 'wme_ac_' or 'wmm_ac_' prefix */ + pos = name + 7; + if (os_strncmp(pos, "be_", 3) == 0) { + num = 0; + pos += 3; + } else if (os_strncmp(pos, "bk_", 3) == 0) { + num = 1; + pos += 3; + } else if (os_strncmp(pos, "vi_", 3) == 0) { + num = 2; + pos += 3; + } else if (os_strncmp(pos, "vo_", 3) == 0) { + num = 3; + pos += 3; + } else { + wpa_printf(MSG_ERROR, "Unknown WMM name '%s'", pos); + return -1; + } + + ac = &wmm_ac_params[num]; + + if (os_strcmp(pos, "aifs") == 0) { + v = atoi(val); + if (v < 1 || v > 255) { + wpa_printf(MSG_ERROR, "Invalid AIFS value %d", v); + return -1; + } + ac->aifs = v; + } else if (os_strcmp(pos, "cwmin") == 0) { + v = atoi(val); + if (v < 0 || v > 12) { + wpa_printf(MSG_ERROR, "Invalid cwMin value %d", v); + return -1; + } + ac->cwmin = v; + } else if (os_strcmp(pos, "cwmax") == 0) { + v = atoi(val); + if (v < 0 || v > 12) { + wpa_printf(MSG_ERROR, "Invalid cwMax value %d", v); + return -1; + } + ac->cwmax = v; + } else if (os_strcmp(pos, "txop_limit") == 0) { + v = atoi(val); + if (v < 0 || v > 0xffff) { + wpa_printf(MSG_ERROR, "Invalid txop value %d", v); + return -1; + } + ac->txop_limit = v; + } else if (os_strcmp(pos, "acm") == 0) { + v = atoi(val); + if (v < 0 || v > 1) { + wpa_printf(MSG_ERROR, "Invalid acm value %d", v); + return -1; + } + ac->admission_control_mandatory = v; + } else { + wpa_printf(MSG_ERROR, "Unknown wmm_ac_ field '%s'", pos); + return -1; + } + + return 0; +} |