From cb7b04c8c9ddaee2cea881ec1547c61277789802 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 29 Oct 2008 21:48:14 +0200 Subject: [PATCH] Moved ieee802_11_parse_elems() into common code --- hostapd/Makefile | 1 + hostapd/driver_madwifi.c | 1 + hostapd/ieee802_11.c | 204 ------------------------------ hostapd/ieee802_11.h | 51 +------- hostapd/wme.h | 17 --- src/common/ieee802_11_common.c | 220 +++++++++++++++++++++++++++++++++ src/common/ieee802_11_common.h | 68 ++++++++++ src/common/ieee802_11_defs.h | 22 ++++ src/drivers/driver_madwifi.c | 6 + 9 files changed, 319 insertions(+), 271 deletions(-) create mode 100644 src/common/ieee802_11_common.c create mode 100644 src/common/ieee802_11_common.h diff --git a/hostapd/Makefile b/hostapd/Makefile index 2580a442d..7a85368f9 100644 --- a/hostapd/Makefile +++ b/hostapd/Makefile @@ -52,6 +52,7 @@ OBJS += ../src/utils/wpabuf.o OBJS += ../src/utils/os_$(CONFIG_OS).o OBJS += ../src/utils/ip_addr.o +OBJS += ../src/common/ieee802_11_common.o OBJS += ../src/common/wpa_common.o OBJS += ../src/radius/radius.o diff --git a/hostapd/driver_madwifi.c b/hostapd/driver_madwifi.c index 1dd12eaf3..9ddd03322 100644 --- a/hostapd/driver_madwifi.c +++ b/hostapd/driver_madwifi.c @@ -35,6 +35,7 @@ #undef RSN_VERSION #undef WPA_VERSION #undef WPA_OUI_TYPE +#undef WME_OUI_TYPE #ifdef IEEE80211_IOCTL_SETWMMPARAMS diff --git a/hostapd/ieee802_11.c b/hostapd/ieee802_11.c index 81f7bae7a..0e5b08e52 100644 --- a/hostapd/ieee802_11.c +++ b/hostapd/ieee802_11.c @@ -290,86 +290,6 @@ u16 hostapd_own_capab_info(struct hostapd_data *hapd, struct sta_info *sta, } -#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) - * 00:50:F2 */ - -static int ieee802_11_parse_vendor_specific(u8 *pos, size_t elen, - struct ieee802_11_elems *elems, - int show_errors) -{ - unsigned int oui; - - /* first 3 bytes in vendor specific information element are the IEEE - * OUI of the vendor. The following byte is used a vendor specific - * sub-type. */ - if (elen < 4) { - if (show_errors) { - wpa_printf(MSG_MSGDUMP, "short vendor specific " - "information element ignored (len=%lu)", - (unsigned long) elen); - } - return -1; - } - - oui = WPA_GET_BE24(pos); - switch (oui) { - case OUI_MICROSOFT: - /* Microsoft/Wi-Fi information elements are further typed and - * subtyped */ - switch (pos[3]) { - case 1: - /* Microsoft OUI (00:50:F2) with OUI Type 1: - * real WPA information element */ - elems->wpa_ie = pos; - elems->wpa_ie_len = elen; - break; - case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ - if (elen < 5) { - wpa_printf(MSG_MSGDUMP, "short WME " - "information element ignored " - "(len=%lu)", - (unsigned long) elen); - return -1; - } - switch (pos[4]) { - case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: - case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: - elems->wme = pos; - elems->wme_len = elen; - break; - case WME_OUI_SUBTYPE_TSPEC_ELEMENT: - elems->wme_tspec = pos; - elems->wme_tspec_len = elen; - break; - default: - wpa_printf(MSG_MSGDUMP, "unknown WME " - "information element ignored " - "(subtype=%d len=%lu)", - pos[4], (unsigned long) elen); - return -1; - } - break; - default: - wpa_printf(MSG_MSGDUMP, "Unknown Microsoft " - "information element ignored " - "(type=%d len=%lu)\n", - 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)", - pos[0], pos[1], pos[2], (unsigned long) elen); - return -1; - } - - return 0; -} - - #ifdef CONFIG_IEEE80211W static u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd, struct sta_info *sta, u8 *eid) @@ -389,130 +309,6 @@ static u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd, #endif /* CONFIG_IEEE80211W */ -ParseRes ieee802_11_parse_elems(u8 *start, size_t len, - struct ieee802_11_elems *elems, - int show_errors) -{ - size_t left = len; - u8 *pos = start; - int unknown = 0; - - os_memset(elems, 0, sizeof(*elems)); - - while (left >= 2) { - u8 id, elen; - - id = *pos++; - elen = *pos++; - left -= 2; - - if (elen > left) { - if (show_errors) { - wpa_printf(MSG_DEBUG, "IEEE 802.11 element " - "parse failed (id=%d elen=%d " - "left=%lu)", - id, elen, (unsigned long) left); - wpa_hexdump(MSG_MSGDUMP, "IEs", start, len); - } - return ParseFailed; - } - - switch (id) { - case WLAN_EID_SSID: - elems->ssid = pos; - elems->ssid_len = elen; - break; - case WLAN_EID_SUPP_RATES: - elems->supp_rates = pos; - elems->supp_rates_len = elen; - break; - case WLAN_EID_FH_PARAMS: - elems->fh_params = pos; - elems->fh_params_len = elen; - break; - case WLAN_EID_DS_PARAMS: - elems->ds_params = pos; - elems->ds_params_len = elen; - break; - case WLAN_EID_CF_PARAMS: - elems->cf_params = pos; - elems->cf_params_len = elen; - break; - case WLAN_EID_TIM: - elems->tim = pos; - elems->tim_len = elen; - break; - case WLAN_EID_IBSS_PARAMS: - elems->ibss_params = pos; - elems->ibss_params_len = elen; - break; - case WLAN_EID_CHALLENGE: - elems->challenge = pos; - elems->challenge_len = elen; - break; - case WLAN_EID_ERP_INFO: - elems->erp_info = pos; - elems->erp_info_len = elen; - break; - case WLAN_EID_EXT_SUPP_RATES: - elems->ext_supp_rates = pos; - elems->ext_supp_rates_len = elen; - break; - case WLAN_EID_VENDOR_SPECIFIC: - if (ieee802_11_parse_vendor_specific(pos, elen, - elems, - show_errors)) - unknown++; - break; - case WLAN_EID_RSN: - elems->rsn_ie = pos; - elems->rsn_ie_len = elen; - break; - case WLAN_EID_PWR_CAPABILITY: - elems->power_cap = pos; - elems->power_cap_len = elen; - break; - case WLAN_EID_SUPPORTED_CHANNELS: - elems->supp_channels = pos; - elems->supp_channels_len = elen; - break; - case WLAN_EID_MOBILITY_DOMAIN: - elems->mdie = pos; - elems->mdie_len = elen; - break; - case WLAN_EID_FAST_BSS_TRANSITION: - elems->ftie = pos; - elems->ftie_len = elen; - break; - case WLAN_EID_HT_CAP: - elems->ht_capabilities = pos; - elems->ht_capabilities_len = elen; - break; - case WLAN_EID_HT_OPERATION: - elems->ht_operation = pos; - elems->ht_operation_len = elen; - break; - default: - unknown++; - if (!show_errors) - break; - wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse " - "ignored unknown element (id=%d elen=%d)", - id, elen); - break; - } - - left -= elen; - pos += elen; - } - - if (left) - return ParseFailed; - - return unknown ? ParseUnknown : ParseOK; -} - - void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len) { int i; diff --git a/hostapd/ieee802_11.h b/hostapd/ieee802_11.h index 5454812fa..bb88ede78 100644 --- a/hostapd/ieee802_11.h +++ b/hostapd/ieee802_11.h @@ -17,53 +17,7 @@ #define IEEE802_11_H #include "ieee802_11_defs.h" - -/* Parsed Information Elements */ -struct ieee802_11_elems { - u8 *ssid; - u8 ssid_len; - u8 *supp_rates; - u8 supp_rates_len; - u8 *fh_params; - u8 fh_params_len; - u8 *ds_params; - u8 ds_params_len; - u8 *cf_params; - u8 cf_params_len; - u8 *tim; - u8 tim_len; - u8 *ibss_params; - u8 ibss_params_len; - u8 *challenge; - u8 challenge_len; - u8 *erp_info; - u8 erp_info_len; - u8 *ext_supp_rates; - u8 ext_supp_rates_len; - u8 *wpa_ie; - u8 wpa_ie_len; - u8 *rsn_ie; - u8 rsn_ie_len; - u8 *wme; - u8 wme_len; - u8 *wme_tspec; - u8 wme_tspec_len; - u8 *power_cap; - u8 power_cap_len; - u8 *supp_channels; - u8 supp_channels_len; - u8 *mdie; - u8 mdie_len; - u8 *ftie; - u8 ftie_len; - u8 *ht_capabilities; - u8 ht_capabilities_len; - u8 *ht_operation; - u8 ht_operation_len; -}; - -typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; - +#include "ieee802_11_common.h" struct hostapd_frame_info { u32 phytype; @@ -83,9 +37,6 @@ void ieee802_11_mgmt(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype, struct hostapd_frame_info *fi); void ieee802_11_mgmt_cb(struct hostapd_data *hapd, u8 *buf, size_t len, u16 stype, int ok); -ParseRes ieee802_11_parse_elems(u8 *start, size_t len, - struct ieee802_11_elems *elems, - int show_errors); void ieee802_11_print_ssid(char *buf, const u8 *ssid, u8 len); void ieee80211_michael_mic_failure(struct hostapd_data *hapd, const u8 *addr, int local); diff --git a/hostapd/wme.h b/hostapd/wme.h index c524fb34d..4ee281ab7 100644 --- a/hostapd/wme.h +++ b/hostapd/wme.h @@ -26,23 +26,6 @@ #endif /* defined(__FreeBSD__) || defined(__NetBSD__) || * defined(__DragonFly__) */ -#define WME_OUI_TYPE 2 -#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0 -#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1 -#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2 -#define WME_VERSION 1 - -#define WME_ACTION_CODE_SETUP_REQUEST 0 -#define WME_ACTION_CODE_SETUP_RESPONSE 1 -#define WME_ACTION_CODE_TEARDOWN 2 - -#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0 -#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1 -#define WME_SETUP_RESPONSE_STATUS_REFUSED 3 - -#define WME_TSPEC_DIRECTION_UPLINK 0 -#define WME_TSPEC_DIRECTION_DOWNLINK 1 -#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 extern inline u16 tsinfo(int tag1d, int contention_based, int direction) { diff --git a/src/common/ieee802_11_common.c b/src/common/ieee802_11_common.c new file mode 100644 index 000000000..34fc7cd4b --- /dev/null +++ b/src/common/ieee802_11_common.c @@ -0,0 +1,220 @@ +/* + * IEEE 802.11 Common routines + * Copyright (c) 2002-2008, Jouni Malinen + * + * 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. + */ + +#include "includes.h" + +#include "common.h" +#include "ieee802_11_defs.h" +#include "ieee802_11_common.h" + + +static int ieee802_11_parse_vendor_specific(u8 *pos, size_t elen, + struct ieee802_11_elems *elems, + int show_errors) +{ + unsigned int oui; + + /* first 3 bytes in vendor specific information element are the IEEE + * OUI of the vendor. The following byte is used a vendor specific + * sub-type. */ + if (elen < 4) { + if (show_errors) { + wpa_printf(MSG_MSGDUMP, "short vendor specific " + "information element ignored (len=%lu)", + (unsigned long) elen); + } + return -1; + } + + oui = WPA_GET_BE24(pos); + switch (oui) { + case OUI_MICROSOFT: + /* Microsoft/Wi-Fi information elements are further typed and + * subtyped */ + switch (pos[3]) { + case 1: + /* Microsoft OUI (00:50:F2) with OUI Type 1: + * real WPA information element */ + elems->wpa_ie = pos; + elems->wpa_ie_len = elen; + break; + case WME_OUI_TYPE: /* this is a Wi-Fi WME info. element */ + if (elen < 5) { + wpa_printf(MSG_MSGDUMP, "short WME " + "information element ignored " + "(len=%lu)", + (unsigned long) elen); + return -1; + } + switch (pos[4]) { + case WME_OUI_SUBTYPE_INFORMATION_ELEMENT: + case WME_OUI_SUBTYPE_PARAMETER_ELEMENT: + elems->wme = pos; + elems->wme_len = elen; + break; + case WME_OUI_SUBTYPE_TSPEC_ELEMENT: + elems->wme_tspec = pos; + elems->wme_tspec_len = elen; + break; + default: + wpa_printf(MSG_MSGDUMP, "unknown WME " + "information element ignored " + "(subtype=%d len=%lu)", + pos[4], (unsigned long) elen); + return -1; + } + break; + default: + wpa_printf(MSG_MSGDUMP, "Unknown Microsoft " + "information element ignored " + "(type=%d len=%lu)\n", + 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)", + pos[0], pos[1], pos[2], (unsigned long) elen); + return -1; + } + + return 0; +} + + +ParseRes ieee802_11_parse_elems(u8 *start, size_t len, + struct ieee802_11_elems *elems, + int show_errors) +{ + size_t left = len; + u8 *pos = start; + int unknown = 0; + + os_memset(elems, 0, sizeof(*elems)); + + while (left >= 2) { + u8 id, elen; + + id = *pos++; + elen = *pos++; + left -= 2; + + if (elen > left) { + if (show_errors) { + wpa_printf(MSG_DEBUG, "IEEE 802.11 element " + "parse failed (id=%d elen=%d " + "left=%lu)", + id, elen, (unsigned long) left); + wpa_hexdump(MSG_MSGDUMP, "IEs", start, len); + } + return ParseFailed; + } + + switch (id) { + case WLAN_EID_SSID: + elems->ssid = pos; + elems->ssid_len = elen; + break; + case WLAN_EID_SUPP_RATES: + elems->supp_rates = pos; + elems->supp_rates_len = elen; + break; + case WLAN_EID_FH_PARAMS: + elems->fh_params = pos; + elems->fh_params_len = elen; + break; + case WLAN_EID_DS_PARAMS: + elems->ds_params = pos; + elems->ds_params_len = elen; + break; + case WLAN_EID_CF_PARAMS: + elems->cf_params = pos; + elems->cf_params_len = elen; + break; + case WLAN_EID_TIM: + elems->tim = pos; + elems->tim_len = elen; + break; + case WLAN_EID_IBSS_PARAMS: + elems->ibss_params = pos; + elems->ibss_params_len = elen; + break; + case WLAN_EID_CHALLENGE: + elems->challenge = pos; + elems->challenge_len = elen; + break; + case WLAN_EID_ERP_INFO: + elems->erp_info = pos; + elems->erp_info_len = elen; + break; + case WLAN_EID_EXT_SUPP_RATES: + elems->ext_supp_rates = pos; + elems->ext_supp_rates_len = elen; + break; + case WLAN_EID_VENDOR_SPECIFIC: + if (ieee802_11_parse_vendor_specific(pos, elen, + elems, + show_errors)) + unknown++; + break; + case WLAN_EID_RSN: + elems->rsn_ie = pos; + elems->rsn_ie_len = elen; + break; + case WLAN_EID_PWR_CAPABILITY: + elems->power_cap = pos; + elems->power_cap_len = elen; + break; + case WLAN_EID_SUPPORTED_CHANNELS: + elems->supp_channels = pos; + elems->supp_channels_len = elen; + break; + case WLAN_EID_MOBILITY_DOMAIN: + elems->mdie = pos; + elems->mdie_len = elen; + break; + case WLAN_EID_FAST_BSS_TRANSITION: + elems->ftie = pos; + elems->ftie_len = elen; + break; + case WLAN_EID_HT_CAP: + elems->ht_capabilities = pos; + elems->ht_capabilities_len = elen; + break; + case WLAN_EID_HT_OPERATION: + elems->ht_operation = pos; + elems->ht_operation_len = elen; + break; + default: + unknown++; + if (!show_errors) + break; + wpa_printf(MSG_MSGDUMP, "IEEE 802.11 element parse " + "ignored unknown element (id=%d elen=%d)", + id, elen); + break; + } + + left -= elen; + pos += elen; + } + + if (left) + return ParseFailed; + + return unknown ? ParseUnknown : ParseOK; +} diff --git a/src/common/ieee802_11_common.h b/src/common/ieee802_11_common.h new file mode 100644 index 000000000..56bb50249 --- /dev/null +++ b/src/common/ieee802_11_common.h @@ -0,0 +1,68 @@ +/* + * IEEE 802.11 Common routines + * Copyright (c) 2002-2008, Jouni Malinen + * + * 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. + */ + +#ifndef IEEE802_11_COMMON_H +#define IEEE802_11_COMMON_H + +/* Parsed Information Elements */ +struct ieee802_11_elems { + u8 *ssid; + u8 ssid_len; + u8 *supp_rates; + u8 supp_rates_len; + u8 *fh_params; + u8 fh_params_len; + u8 *ds_params; + u8 ds_params_len; + u8 *cf_params; + u8 cf_params_len; + u8 *tim; + u8 tim_len; + u8 *ibss_params; + u8 ibss_params_len; + u8 *challenge; + u8 challenge_len; + u8 *erp_info; + u8 erp_info_len; + u8 *ext_supp_rates; + u8 ext_supp_rates_len; + u8 *wpa_ie; + u8 wpa_ie_len; + u8 *rsn_ie; + u8 rsn_ie_len; + u8 *wme; + u8 wme_len; + u8 *wme_tspec; + u8 wme_tspec_len; + u8 *power_cap; + u8 power_cap_len; + u8 *supp_channels; + u8 supp_channels_len; + u8 *mdie; + u8 mdie_len; + u8 *ftie; + u8 ftie_len; + u8 *ht_capabilities; + u8 ht_capabilities_len; + u8 *ht_operation; + u8 ht_operation_len; +}; + +typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; + +ParseRes ieee802_11_parse_elems(u8 *start, size_t len, + struct ieee802_11_elems *elems, + int show_errors); + +#endif /* IEEE802_11_COMMON_H */ diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 7e2801ed6..9819b0947 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -556,4 +556,26 @@ struct mimo_pwr_save_action { u8 mode; } STRUCT_PACKED; + +#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) + * 00:50:F2 */ + +#define WME_OUI_TYPE 2 +#define WME_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WME_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WME_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WME_VERSION 1 + +#define WME_ACTION_CODE_SETUP_REQUEST 0 +#define WME_ACTION_CODE_SETUP_RESPONSE 1 +#define WME_ACTION_CODE_TEARDOWN 2 + +#define WME_SETUP_RESPONSE_STATUS_ADMISSION_ACCEPTED 0 +#define WME_SETUP_RESPONSE_STATUS_INVALID_PARAMETERS 1 +#define WME_SETUP_RESPONSE_STATUS_REFUSED 3 + +#define WME_TSPEC_DIRECTION_UPLINK 0 +#define WME_TSPEC_DIRECTION_DOWNLINK 1 +#define WME_TSPEC_DIRECTION_BI_DIRECTIONAL 3 + #endif /* IEEE802_11_DEFS_H */ diff --git a/src/drivers/driver_madwifi.c b/src/drivers/driver_madwifi.c index aeabe34c5..c37cc358e 100644 --- a/src/drivers/driver_madwifi.c +++ b/src/drivers/driver_madwifi.c @@ -23,6 +23,11 @@ #include "ieee802_11_defs.h" #include "wireless_copy.h" +/* + * Avoid conflicts with wpa_supplicant definitions by undefining a definition. + */ +#undef WME_OUI_TYPE + #include #include #ifdef WME_NUM_AC @@ -33,6 +38,7 @@ #include #include + #ifdef IEEE80211_IOCTL_SETWMMPARAMS /* Assume this is built against madwifi-ng */ #define MADWIFI_NG