diff --git a/wireless/wifictld/Makefile b/wireless/wifictld/Makefile index 109d4f0..f614d8a 100644 --- a/wireless/wifictld/Makefile +++ b/wireless/wifictld/Makefile @@ -9,6 +9,8 @@ PKG_LICENSE:=APGL include $(INCLUDE_DIR)/package.mk +TARGET_CFLAGS += -DDEBUG + define Package/wifictld/Default SECTION:=net CATEGORY:=Network @@ -21,7 +23,6 @@ define Package/wifictld $(call Package/wifictld/Default) TITLE+= (full) VARIANT:=full - TARGET_CFLAGS += -DDEBUG endef define Package/wifictld-mini @@ -42,7 +43,7 @@ endef define Build/Prepare mkdir -p $(PKG_BUILD_DIR) - cp ./src/* $(PKG_BUILD_DIR) + cp -r ./src/* $(PKG_BUILD_DIR) $(Build/Patch) endef diff --git a/wireless/wifictld/src/Makefile b/wireless/wifictld/src/Makefile index 8ffd9fc..9219088 100644 --- a/wireless/wifictld/src/Makefile +++ b/wireless/wifictld/src/Makefile @@ -1,5 +1,5 @@ -all: wifictld +all: hostapd wifictld CC = gcc CFLAGS = -Wall @@ -9,7 +9,10 @@ DEPS = $(wildcard *.h) SRC = $(wildcard *.c) -OBJ = $(patsubst %.c, %.o, $(SRC)) +OBJ = $(patsubst %.c, %.o, $(SRC)) hostapd/common.o + +hostapd: + $(MAKE) -C hostapd %.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) @@ -20,4 +23,5 @@ wifictld: $(OBJ) .PHONY: clean clean: + $(MAKE) -C hostapd clean rm -f wifictld *.o diff --git a/wireless/wifictld/src/hostapd/Makefile b/wireless/wifictld/src/hostapd/Makefile new file mode 100644 index 0000000..9436a88 --- /dev/null +++ b/wireless/wifictld/src/hostapd/Makefile @@ -0,0 +1,20 @@ + +all: common.o + +CC = gcc +CFLAGS = -Wall +LDFLAGS = + +DEPS = $(wildcard *.h) + +SRC = $(wildcard *.c) + +OBJ = $(patsubst %.c, %.o, $(SRC)) + +%.o: %.c $(DEPS) + $(CC) -c -o $@ $< $(CFLAGS) + +.PHONY: clean + +clean: + rm -f *.o diff --git a/wireless/wifictld/src/hostapd/common.c b/wireless/wifictld/src/hostapd/common.c new file mode 100644 index 0000000..1eb3370 --- /dev/null +++ b/wireless/wifictld/src/hostapd/common.c @@ -0,0 +1,1223 @@ +/* + * wpa_supplicant/hostapd / common helper functions, etc. + * Copyright (c) 2002-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include "includes.h" + +#include "common/ieee802_11_defs.h" +#include "common.h" + + +static int hex2num(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + + +int hex2byte(const char *hex) +{ + int a, b; + a = hex2num(*hex++); + if (a < 0) + return -1; + b = hex2num(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + + +static const char * hwaddr_parse(const char *txt, u8 *addr) +{ + size_t i; + + for (i = 0; i < ETH_ALEN; i++) { + int a; + + a = hex2byte(txt); + if (a < 0) + return NULL; + txt += 2; + addr[i] = a; + if (i < ETH_ALEN - 1 && *txt++ != ':') + return NULL; + } + return txt; +} + + +/** + * hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format) + * @txt: MAC address as a string (e.g., "00:11:22:33:44:55") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +int hwaddr_aton(const char *txt, u8 *addr) +{ + return hwaddr_parse(txt, addr) ? 0 : -1; +} + + +/** + * hwaddr_masked_aton - Convert ASCII string with optional mask to MAC address (colon-delimited format) + * @txt: MAC address with optional mask as a string (e.g., "00:11:22:33:44:55/ff:ff:ff:ff:00:00") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * @mask: Buffer for the MAC address mask (ETH_ALEN = 6 bytes) + * @maskable: Flag to indicate whether a mask is allowed + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable) +{ + const char *r; + + /* parse address part */ + r = hwaddr_parse(txt, addr); + if (!r) + return -1; + + /* check for optional mask */ + if (*r == '\0' || isspace((unsigned char) *r)) { + /* no mask specified, assume default */ + os_memset(mask, 0xff, ETH_ALEN); + } else if (maskable && *r == '/') { + /* mask specified and allowed */ + r = hwaddr_parse(r + 1, mask); + /* parser error? */ + if (!r) + return -1; + } else { + /* mask specified but not allowed or trailing garbage */ + return -1; + } + + return 0; +} + + +/** + * hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format) + * @txt: MAC address as a string (e.g., "001122334455") + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: 0 on success, -1 on failure (e.g., string not a MAC address) + */ +int hwaddr_compact_aton(const char *txt, u8 *addr) +{ + int i; + + for (i = 0; i < 6; i++) { + int a, b; + + a = hex2num(*txt++); + if (a < 0) + return -1; + b = hex2num(*txt++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + } + + return 0; +} + +/** + * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format) + * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455) + * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) + * Returns: Characters used (> 0) on success, -1 on failure + */ +int hwaddr_aton2(const char *txt, u8 *addr) +{ + int i; + const char *pos = txt; + + for (i = 0; i < 6; i++) { + int a, b; + + while (*pos == ':' || *pos == '.' || *pos == '-') + pos++; + + a = hex2num(*pos++); + if (a < 0) + return -1; + b = hex2num(*pos++); + if (b < 0) + return -1; + *addr++ = (a << 4) | b; + } + + return pos - txt; +} + + +/** + * hexstr2bin - Convert ASCII hex string into binary data + * @hex: ASCII hex string (e.g., "01ab") + * @buf: Buffer for the binary data + * @len: Length of the text to convert in bytes (of buf); hex will be double + * this size + * Returns: 0 on success, -1 on failure (invalid hex string) + */ +int hexstr2bin(const char *hex, u8 *buf, size_t len) +{ + size_t i; + int a; + const char *ipos = hex; + u8 *opos = buf; + + for (i = 0; i < len; i++) { + a = hex2byte(ipos); + if (a < 0) + return -1; + *opos++ = a; + ipos += 2; + } + return 0; +} + + +int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask) +{ + size_t i; + int print_mask = 0; + int res; + + for (i = 0; i < ETH_ALEN; i++) { + if (mask[i] != 0xff) { + print_mask = 1; + break; + } + } + + if (print_mask) + res = os_snprintf(buf, len, MACSTR "/" MACSTR, + MAC2STR(addr), MAC2STR(mask)); + else + res = os_snprintf(buf, len, MACSTR, MAC2STR(addr)); + if (os_snprintf_error(len, res)) + return -1; + return res; +} + + +/** + * inc_byte_array - Increment arbitrary length byte array by one + * @counter: Pointer to byte array + * @len: Length of the counter in bytes + * + * This function increments the last byte of the counter by one and continues + * rolling over to more significant bytes if the byte was incremented from + * 0xff to 0x00. + */ +void inc_byte_array(u8 *counter, size_t len) +{ + int pos = len - 1; + while (pos >= 0) { + counter[pos]++; + if (counter[pos] != 0) + break; + pos--; + } +} + + +void wpa_get_ntp_timestamp(u8 *buf) +{ + struct os_time now; + u32 sec, usec; + be32 tmp; + + /* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */ + os_get_time(&now); + sec = now.sec + 2208988800U; /* Epoch to 1900 */ + /* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */ + usec = now.usec; + usec = 4295 * usec - (usec >> 5) - (usec >> 9); + tmp = host_to_be32(sec); + os_memcpy(buf, (u8 *) &tmp, 4); + tmp = host_to_be32(usec); + os_memcpy(buf + 4, (u8 *) &tmp, 4); +} + +/** + * wpa_scnprintf - Simpler-to-use snprintf function + * @buf: Output buffer + * @size: Buffer size + * @fmt: format + * + * Simpler snprintf version that doesn't require further error checks - the + * return value only indicates how many bytes were actually written, excluding + * the NULL byte (i.e., 0 on error, size-1 if buffer is not big enough). + */ +int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...) +{ + va_list ap; + int ret; + + if (!size) + return 0; + + va_start(ap, fmt); + ret = vsnprintf(buf, size, fmt, ap); + va_end(ap); + + if (ret < 0) + return 0; + if ((size_t) ret >= size) + return size - 1; + + return ret; +} + + +int wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len, + char sep) +{ + size_t i; + char *pos = buf, *end = buf + buf_size; + int ret; + + if (buf_size == 0) + return 0; + + for (i = 0; i < len; i++) { + ret = os_snprintf(pos, end - pos, "%02x%c", + data[i], sep); + if (os_snprintf_error(end - pos, ret)) { + end[-1] = '\0'; + return pos - buf; + } + pos += ret; + } + pos[-1] = '\0'; + return pos - buf; +} + + +static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, + size_t len, int uppercase) +{ + size_t i; + char *pos = buf, *end = buf + buf_size; + int ret; + if (buf_size == 0) + return 0; + for (i = 0; i < len; i++) { + ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x", + data[i]); + if (os_snprintf_error(end - pos, ret)) { + end[-1] = '\0'; + return pos - buf; + } + pos += ret; + } + end[-1] = '\0'; + return pos - buf; +} + +/** + * wpa_snprintf_hex - Print data as a hex string into a buffer + * @buf: Memory area to use as the output buffer + * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) + * @data: Data to be printed + * @len: Length of data in bytes + * Returns: Number of bytes written + */ +int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len) +{ + return _wpa_snprintf_hex(buf, buf_size, data, len, 0); +} + + +/** + * wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf + * @buf: Memory area to use as the output buffer + * @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1) + * @data: Data to be printed + * @len: Length of data in bytes + * Returns: Number of bytes written + */ +int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, + size_t len) +{ + return _wpa_snprintf_hex(buf, buf_size, data, len, 1); +} + + +#ifdef CONFIG_ANSI_C_EXTRA + +#ifdef _WIN32_WCE +void perror(const char *s) +{ + wpa_printf(MSG_ERROR, "%s: GetLastError: %d", + s, (int) GetLastError()); +} +#endif /* _WIN32_WCE */ + + +int optind = 1; +int optopt; +char *optarg; + +int getopt(int argc, char *const argv[], const char *optstring) +{ + static int optchr = 1; + char *cp; + + if (optchr == 1) { + if (optind >= argc) { + /* all arguments processed */ + return EOF; + } + + if (argv[optind][0] != '-' || argv[optind][1] == '\0') { + /* no option characters */ + return EOF; + } + } + + if (os_strcmp(argv[optind], "--") == 0) { + /* no more options */ + optind++; + return EOF; + } + + optopt = argv[optind][optchr]; + cp = os_strchr(optstring, optopt); + if (cp == NULL || optopt == ':') { + if (argv[optind][++optchr] == '\0') { + optchr = 1; + optind++; + } + return '?'; + } + + if (cp[1] == ':') { + /* Argument required */ + optchr = 1; + if (argv[optind][optchr + 1]) { + /* No space between option and argument */ + optarg = &argv[optind++][optchr + 1]; + } else if (++optind >= argc) { + /* option requires an argument */ + return '?'; + } else { + /* Argument in the next argv */ + optarg = argv[optind++]; + } + } else { + /* No argument */ + if (argv[optind][++optchr] == '\0') { + optchr = 1; + optind++; + } + optarg = NULL; + } + return *cp; +} +#endif /* CONFIG_ANSI_C_EXTRA */ + + +#ifdef CONFIG_NATIVE_WINDOWS +/** + * wpa_unicode2ascii_inplace - Convert unicode string into ASCII + * @str: Pointer to string to convert + * + * This function converts a unicode string to ASCII using the same + * buffer for output. If UNICODE is not set, the buffer is not + * modified. + */ +void wpa_unicode2ascii_inplace(TCHAR *str) +{ +#ifdef UNICODE + char *dst = (char *) str; + while (*str) + *dst++ = (char) *str++; + *dst = '\0'; +#endif /* UNICODE */ +} + + +TCHAR * wpa_strdup_tchar(const char *str) +{ +#ifdef UNICODE + TCHAR *buf; + buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR)); + if (buf == NULL) + return NULL; + wsprintf(buf, L"%S", str); + return buf; +#else /* UNICODE */ + return os_strdup(str); +#endif /* UNICODE */ +} +#endif /* CONFIG_NATIVE_WINDOWS */ + + +void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len) +{ + char *end = txt + maxlen; + size_t i; + + for (i = 0; i < len; i++) { + if (txt + 4 >= end) + break; + + switch (data[i]) { + case '\"': + *txt++ = '\\'; + *txt++ = '\"'; + break; + case '\\': + *txt++ = '\\'; + *txt++ = '\\'; + break; + case '\033': + *txt++ = '\\'; + *txt++ = 'e'; + break; + case '\n': + *txt++ = '\\'; + *txt++ = 'n'; + break; + case '\r': + *txt++ = '\\'; + *txt++ = 'r'; + break; + case '\t': + *txt++ = '\\'; + *txt++ = 't'; + break; + default: + if (data[i] >= 32 && data[i] <= 126) { + *txt++ = data[i]; + } else { + txt += os_snprintf(txt, end - txt, "\\x%02x", + data[i]); + } + break; + } + } + + *txt = '\0'; +} + + +size_t printf_decode(u8 *buf, size_t maxlen, const char *str) +{ + const char *pos = str; + size_t len = 0; + int val; + + while (*pos) { + if (len + 1 >= maxlen) + break; + switch (*pos) { + case '\\': + pos++; + switch (*pos) { + case '\\': + buf[len++] = '\\'; + pos++; + break; + case '"': + buf[len++] = '"'; + pos++; + break; + case 'n': + buf[len++] = '\n'; + pos++; + break; + case 'r': + buf[len++] = '\r'; + pos++; + break; + case 't': + buf[len++] = '\t'; + pos++; + break; + case 'e': + buf[len++] = '\033'; + pos++; + break; + case 'x': + pos++; + val = hex2byte(pos); + if (val < 0) { + val = hex2num(*pos); + if (val < 0) + break; + buf[len++] = val; + pos++; + } else { + buf[len++] = val; + pos += 2; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + val = *pos++ - '0'; + if (*pos >= '0' && *pos <= '7') + val = val * 8 + (*pos++ - '0'); + if (*pos >= '0' && *pos <= '7') + val = val * 8 + (*pos++ - '0'); + buf[len++] = val; + break; + default: + break; + } + break; + default: + buf[len++] = *pos++; + break; + } + } + if (maxlen > len) + buf[len] = '\0'; + + return len; +} + + +/** + * wpa_ssid_txt - Convert SSID to a printable string + * @ssid: SSID (32-octet string) + * @ssid_len: Length of ssid in octets + * Returns: Pointer to a printable string + * + * This function can be used to convert SSIDs into printable form. In most + * cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard + * does not limit the used character set, so anything could be used in an SSID. + * + * This function uses a static buffer, so only one call can be used at the + * time, i.e., this is not re-entrant and the returned buffer must be used + * before calling this again. + */ +const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len) +{ + static char ssid_txt[SSID_MAX_LEN * 4 + 1]; + + if (ssid == NULL) { + ssid_txt[0] = '\0'; + return ssid_txt; + } + + printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len); + return ssid_txt; +} + + +void * __hide_aliasing_typecast(void *foo) +{ + return foo; +} + + +char * wpa_config_parse_string(const char *value, size_t *len) +{ + if (*value == '"') { + const char *pos; + char *str; + value++; + pos = os_strrchr(value, '"'); + if (pos == NULL || pos[1] != '\0') + return NULL; + *len = pos - value; + str = dup_binstr(value, *len); + if (str == NULL) + return NULL; + return str; + } else if (*value == 'P' && value[1] == '"') { + const char *pos; + char *tstr, *str; + size_t tlen; + value += 2; + pos = os_strrchr(value, '"'); + if (pos == NULL || pos[1] != '\0') + return NULL; + tlen = pos - value; + tstr = dup_binstr(value, tlen); + if (tstr == NULL) + return NULL; + + str = os_malloc(tlen + 1); + if (str == NULL) { + os_free(tstr); + return NULL; + } + + *len = printf_decode((u8 *) str, tlen + 1, tstr); + os_free(tstr); + + return str; + } else { + u8 *str; + size_t tlen, hlen = os_strlen(value); + if (hlen & 1) + return NULL; + tlen = hlen / 2; + str = os_malloc(tlen + 1); + if (str == NULL) + return NULL; + if (hexstr2bin(value, str, tlen)) { + os_free(str); + return NULL; + } + str[tlen] = '\0'; + *len = tlen; + return (char *) str; + } +} + + +int is_hex(const u8 *data, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + if (data[i] < 32 || data[i] >= 127) + return 1; + } + return 0; +} + + +int has_ctrl_char(const u8 *data, size_t len) +{ + size_t i; + + for (i = 0; i < len; i++) { + if (data[i] < 32 || data[i] == 127) + return 1; + } + return 0; +} + + +int has_newline(const char *str) +{ + while (*str) { + if (*str == '\n' || *str == '\r') + return 1; + str++; + } + return 0; +} + + +size_t merge_byte_arrays(u8 *res, size_t res_len, + const u8 *src1, size_t src1_len, + const u8 *src2, size_t src2_len) +{ + size_t len = 0; + + os_memset(res, 0, res_len); + + if (src1) { + if (src1_len >= res_len) { + os_memcpy(res, src1, res_len); + return res_len; + } + + os_memcpy(res, src1, src1_len); + len += src1_len; + } + + if (src2) { + if (len + src2_len >= res_len) { + os_memcpy(res + len, src2, res_len - len); + return res_len; + } + + os_memcpy(res + len, src2, src2_len); + len += src2_len; + } + + return len; +} + + +char * dup_binstr(const void *src, size_t len) +{ + char *res; + + if (src == NULL) + return NULL; + res = os_malloc(len + 1); + if (res == NULL) + return NULL; + os_memcpy(res, src, len); + res[len] = '\0'; + + return res; +} + + +int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value) +{ + struct wpa_freq_range *freq = NULL, *n; + unsigned int count = 0; + const char *pos, *pos2, *pos3; + + /* + * Comma separated list of frequency ranges. + * For example: 2412-2432,2462,5000-6000 + */ + pos = value; + while (pos && pos[0]) { + n = os_realloc_array(freq, count + 1, + sizeof(struct wpa_freq_range)); + if (n == NULL) { + os_free(freq); + return -1; + } + freq = n; + freq[count].min = atoi(pos); + pos2 = os_strchr(pos, '-'); + pos3 = os_strchr(pos, ','); + if (pos2 && (!pos3 || pos2 < pos3)) { + pos2++; + freq[count].max = atoi(pos2); + } else + freq[count].max = freq[count].min; + pos = pos3; + if (pos) + pos++; + count++; + } + + os_free(res->range); + res->range = freq; + res->num = count; + + return 0; +} + + +int freq_range_list_includes(const struct wpa_freq_range_list *list, + unsigned int freq) +{ + unsigned int i; + + if (list == NULL) + return 0; + + for (i = 0; i < list->num; i++) { + if (freq >= list->range[i].min && freq <= list->range[i].max) + return 1; + } + + return 0; +} + + +char * freq_range_list_str(const struct wpa_freq_range_list *list) +{ + char *buf, *pos, *end; + size_t maxlen; + unsigned int i; + int res; + + if (list->num == 0) + return NULL; + + maxlen = list->num * 30; + buf = os_malloc(maxlen); + if (buf == NULL) + return NULL; + pos = buf; + end = buf + maxlen; + + for (i = 0; i < list->num; i++) { + struct wpa_freq_range *range = &list->range[i]; + + if (range->min == range->max) + res = os_snprintf(pos, end - pos, "%s%u", + i == 0 ? "" : ",", range->min); + else + res = os_snprintf(pos, end - pos, "%s%u-%u", + i == 0 ? "" : ",", + range->min, range->max); + if (os_snprintf_error(end - pos, res)) { + os_free(buf); + return NULL; + } + pos += res; + } + + return buf; +} + + +int int_array_len(const int *a) +{ + int i; + for (i = 0; a && a[i]; i++) + ; + return i; +} + + +void int_array_concat(int **res, const int *a) +{ + int reslen, alen, i; + int *n; + + reslen = int_array_len(*res); + alen = int_array_len(a); + + n = os_realloc_array(*res, reslen + alen + 1, sizeof(int)); + if (n == NULL) { + os_free(*res); + *res = NULL; + return; + } + for (i = 0; i <= alen; i++) + n[reslen + i] = a[i]; + *res = n; +} + + +static int freq_cmp(const void *a, const void *b) +{ + int _a = *(int *) a; + int _b = *(int *) b; + + if (_a == 0) + return 1; + if (_b == 0) + return -1; + return _a - _b; +} + + +void int_array_sort_unique(int *a) +{ + int alen; + int i, j; + + if (a == NULL) + return; + + alen = int_array_len(a); + qsort(a, alen, sizeof(int), freq_cmp); + + i = 0; + j = 1; + while (a[i] && a[j]) { + if (a[i] == a[j]) { + j++; + continue; + } + a[++i] = a[j++]; + } + if (a[i]) + i++; + a[i] = 0; +} + + +void int_array_add_unique(int **res, int a) +{ + int reslen; + int *n; + + for (reslen = 0; *res && (*res)[reslen]; reslen++) { + if ((*res)[reslen] == a) + return; /* already in the list */ + } + + n = os_realloc_array(*res, reslen + 2, sizeof(int)); + if (n == NULL) { + os_free(*res); + *res = NULL; + return; + } + + n[reslen] = a; + n[reslen + 1] = 0; + + *res = n; +} + + +void str_clear_free(char *str) +{ + if (str) { + size_t len = os_strlen(str); + os_memset(str, 0, len); + os_free(str); + } +} + + +void bin_clear_free(void *bin, size_t len) +{ + if (bin) { + os_memset(bin, 0, len); + os_free(bin); + } +} + + +int random_mac_addr(u8 *addr) +{ + if (os_get_random(addr, ETH_ALEN) < 0) + return -1; + addr[0] &= 0xfe; /* unicast */ + addr[0] |= 0x02; /* locally administered */ + return 0; +} + + +int random_mac_addr_keep_oui(u8 *addr) +{ + if (os_get_random(addr + 3, 3) < 0) + return -1; + addr[0] &= 0xfe; /* unicast */ + addr[0] |= 0x02; /* locally administered */ + return 0; +} + + +/** + * cstr_token - Get next token from const char string + * @str: a constant string to tokenize + * @delim: a string of delimiters + * @last: a pointer to a character following the returned token + * It has to be set to NULL for the first call and passed for any + * further call. + * Returns: a pointer to token position in str or NULL + * + * This function is similar to str_token, but it can be used with both + * char and const char strings. Differences: + * - The str buffer remains unmodified + * - The returned token is not a NULL terminated string, but a token + * position in str buffer. If a return value is not NULL a size + * of the returned token could be calculated as (last - token). + */ +const char * cstr_token(const char *str, const char *delim, const char **last) +{ + const char *end, *token = str; + + if (!str || !delim || !last) + return NULL; + + if (*last) + token = *last; + + while (*token && os_strchr(delim, *token)) + token++; + + if (!*token) + return NULL; + + end = token + 1; + + while (*end && !os_strchr(delim, *end)) + end++; + + *last = end; + return token; +} + + +/** + * str_token - Get next token from a string + * @buf: String to tokenize. Note that the string might be modified. + * @delim: String of delimiters + * @context: Pointer to save our context. Should be initialized with + * NULL on the first call, and passed for any further call. + * Returns: The next token, NULL if there are no more valid tokens. + */ +char * str_token(char *str, const char *delim, char **context) +{ + char *token = (char *) cstr_token(str, delim, (const char **) context); + + if (token && **context) + *(*context)++ = '\0'; + + return token; +} + + +size_t utf8_unescape(const char *inp, size_t in_size, + char *outp, size_t out_size) +{ + size_t res_size = 0; + + if (!inp || !outp) + return 0; + + if (!in_size) + in_size = os_strlen(inp); + + /* Advance past leading single quote */ + if (*inp == '\'' && in_size) { + inp++; + in_size--; + } + + while (in_size--) { + if (res_size >= out_size) + return 0; + + switch (*inp) { + case '\'': + /* Terminate on bare single quote */ + *outp = '\0'; + return res_size; + + case '\\': + if (!in_size--) + return 0; + inp++; + /* fall through */ + + default: + *outp++ = *inp++; + res_size++; + } + } + + /* NUL terminate if space allows */ + if (res_size < out_size) + *outp = '\0'; + + return res_size; +} + + +size_t utf8_escape(const char *inp, size_t in_size, + char *outp, size_t out_size) +{ + size_t res_size = 0; + + if (!inp || !outp) + return 0; + + /* inp may or may not be NUL terminated, but must be if 0 size + * is specified */ + if (!in_size) + in_size = os_strlen(inp); + + while (in_size--) { + if (res_size++ >= out_size) + return 0; + + switch (*inp) { + case '\\': + case '\'': + if (res_size++ >= out_size) + return 0; + *outp++ = '\\'; + /* fall through */ + + default: + *outp++ = *inp++; + break; + } + } + + /* NUL terminate if space allows */ + if (res_size < out_size) + *outp = '\0'; + + return res_size; +} + + +int is_ctrl_char(char c) +{ + return c > 0 && c < 32; +} + + +/** + * ssid_parse - Parse a string that contains SSID in hex or text format + * @buf: Input NULL terminated string that contains the SSID + * @ssid: Output SSID + * Returns: 0 on success, -1 otherwise + * + * The SSID has to be enclosed in double quotes for the text format or space + * or NULL terminated string of hex digits for the hex format. buf can include + * additional arguments after the SSID. + */ +int ssid_parse(const char *buf, struct wpa_ssid_value *ssid) +{ + char *tmp, *res, *end; + size_t len; + + ssid->ssid_len = 0; + + tmp = os_strdup(buf); + if (!tmp) + return -1; + + if (*tmp != '"') { + end = os_strchr(tmp, ' '); + if (end) + *end = '\0'; + } else { + end = os_strchr(tmp + 1, '"'); + if (!end) { + os_free(tmp); + return -1; + } + + end[1] = '\0'; + } + + res = wpa_config_parse_string(tmp, &len); + if (res && len <= SSID_MAX_LEN) { + ssid->ssid_len = len; + os_memcpy(ssid->ssid, res, len); + } + + os_free(tmp); + os_free(res); + + return ssid->ssid_len ? 0 : -1; +} + + +int str_starts(const char *str, const char *start) +{ + return os_strncmp(str, start, os_strlen(start)) == 0; +} + + +/** + * rssi_to_rcpi - Convert RSSI to RCPI + * @rssi: RSSI to convert + * Returns: RCPI corresponding to the given RSSI value, or 255 if not available. + * + * It's possible to estimate RCPI based on RSSI in dBm. This calculation will + * not reflect the correct value for high rates, but it's good enough for Action + * frames which are transmitted with up to 24 Mbps rates. + */ +u8 rssi_to_rcpi(int rssi) +{ + if (!rssi) + return 255; /* not available */ + if (rssi < -110) + return 0; + if (rssi > 0) + return 220; + return (rssi + 110) * 2; +} diff --git a/wireless/wifictld/src/hostapd/common.h b/wireless/wifictld/src/hostapd/common.h new file mode 100644 index 0000000..f824d00 --- /dev/null +++ b/wireless/wifictld/src/hostapd/common.h @@ -0,0 +1,590 @@ +/* + * wpa_supplicant/hostapd / common helper functions, etc. + * Copyright (c) 2002-2007, Jouni Malinen + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef COMMON_H +#define COMMON_H + +#include "os.h" + +#if defined(__linux__) || defined(__GLIBC__) +#include +#include +#endif /* __linux__ */ + +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ + defined(__OpenBSD__) +#include +#include +#define __BYTE_ORDER _BYTE_ORDER +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN +#ifdef __OpenBSD__ +#define bswap_16 swap16 +#define bswap_32 swap32 +#define bswap_64 swap64 +#else /* __OpenBSD__ */ +#define bswap_16 bswap16 +#define bswap_32 bswap32 +#define bswap_64 bswap64 +#endif /* __OpenBSD__ */ +#endif /* defined(__FreeBSD__) || defined(__NetBSD__) || + * defined(__DragonFly__) || defined(__OpenBSD__) */ + +#ifdef __APPLE__ +#include +#include +#define __BYTE_ORDER _BYTE_ORDER +#define __LITTLE_ENDIAN _LITTLE_ENDIAN +#define __BIG_ENDIAN _BIG_ENDIAN +static inline unsigned short bswap_16(unsigned short v) +{ + return ((v & 0xff) << 8) | (v >> 8); +} + +static inline unsigned int bswap_32(unsigned int v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | + ((v & 0xff0000) >> 8) | (v >> 24); +} +#endif /* __APPLE__ */ + +#ifdef __rtems__ +#include +#define __BYTE_ORDER BYTE_ORDER +#define __LITTLE_ENDIAN LITTLE_ENDIAN +#define __BIG_ENDIAN BIG_ENDIAN +#define bswap_16 CPU_swap_u16 +#define bswap_32 CPU_swap_u32 +#endif /* __rtems__ */ + +#ifdef CONFIG_NATIVE_WINDOWS +#include + +typedef int socklen_t; + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 /* not supported */ +#endif + +#endif /* CONFIG_NATIVE_WINDOWS */ + +#ifdef _MSC_VER +#define inline __inline + +#undef vsnprintf +#define vsnprintf _vsnprintf +#undef close +#define close closesocket +#endif /* _MSC_VER */ + + +/* Define platform specific integer types */ + +#ifdef _MSC_VER +typedef UINT64 u64; +typedef UINT32 u32; +typedef UINT16 u16; +typedef UINT8 u8; +typedef INT64 s64; +typedef INT32 s32; +typedef INT16 s16; +typedef INT8 s8; +#define WPA_TYPES_DEFINED +#endif /* _MSC_VER */ + +#ifdef __vxworks +typedef unsigned long long u64; +typedef UINT32 u32; +typedef UINT16 u16; +typedef UINT8 u8; +typedef long long s64; +typedef INT32 s32; +typedef INT16 s16; +typedef INT8 s8; +#define WPA_TYPES_DEFINED +#endif /* __vxworks */ + +#ifndef WPA_TYPES_DEFINED +#ifdef CONFIG_USE_INTTYPES_H +#include +#else +#include +#endif +typedef uint64_t u64; +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; +typedef int64_t s64; +typedef int32_t s32; +typedef int16_t s16; +typedef int8_t s8; +#define WPA_TYPES_DEFINED +#endif /* !WPA_TYPES_DEFINED */ + + +/* Define platform specific byte swapping macros */ + +#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS) + +static inline unsigned short wpa_swap_16(unsigned short v) +{ + return ((v & 0xff) << 8) | (v >> 8); +} + +static inline unsigned int wpa_swap_32(unsigned int v) +{ + return ((v & 0xff) << 24) | ((v & 0xff00) << 8) | + ((v & 0xff0000) >> 8) | (v >> 24); +} + +#define le_to_host16(n) (n) +#define host_to_le16(n) (n) +#define be_to_host16(n) wpa_swap_16(n) +#define host_to_be16(n) wpa_swap_16(n) +#define le_to_host32(n) (n) +#define host_to_le32(n) (n) +#define be_to_host32(n) wpa_swap_32(n) +#define host_to_be32(n) wpa_swap_32(n) +#define host_to_le64(n) (n) + +#define WPA_BYTE_SWAP_DEFINED + +#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */ + + +#ifndef WPA_BYTE_SWAP_DEFINED + +#ifndef __BYTE_ORDER +#ifndef __LITTLE_ENDIAN +#ifndef __BIG_ENDIAN +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#if defined(sparc) +#define __BYTE_ORDER __BIG_ENDIAN +#endif +#endif /* __BIG_ENDIAN */ +#endif /* __LITTLE_ENDIAN */ +#endif /* __BYTE_ORDER */ + +#if __BYTE_ORDER == __LITTLE_ENDIAN +#define le_to_host16(n) ((__force u16) (le16) (n)) +#define host_to_le16(n) ((__force le16) (u16) (n)) +#define be_to_host16(n) bswap_16((__force u16) (be16) (n)) +#define host_to_be16(n) ((__force be16) bswap_16((n))) +#define le_to_host32(n) ((__force u32) (le32) (n)) +#define host_to_le32(n) ((__force le32) (u32) (n)) +#define be_to_host32(n) bswap_32((__force u32) (be32) (n)) +#define host_to_be32(n) ((__force be32) bswap_32((n))) +#define le_to_host64(n) ((__force u64) (le64) (n)) +#define host_to_le64(n) ((__force le64) (u64) (n)) +#define be_to_host64(n) bswap_64((__force u64) (be64) (n)) +#define host_to_be64(n) ((__force be64) bswap_64((n))) +#elif __BYTE_ORDER == __BIG_ENDIAN +#define le_to_host16(n) bswap_16(n) +#define host_to_le16(n) bswap_16(n) +#define be_to_host16(n) (n) +#define host_to_be16(n) (n) +#define le_to_host32(n) bswap_32(n) +#define host_to_le32(n) bswap_32(n) +#define be_to_host32(n) (n) +#define host_to_be32(n) (n) +#define le_to_host64(n) bswap_64(n) +#define host_to_le64(n) bswap_64(n) +#define be_to_host64(n) (n) +#define host_to_be64(n) (n) +#ifndef WORDS_BIGENDIAN +#define WORDS_BIGENDIAN +#endif +#else +#error Could not determine CPU byte order +#endif + +#define WPA_BYTE_SWAP_DEFINED +#endif /* !WPA_BYTE_SWAP_DEFINED */ + + +/* Macros for handling unaligned memory accesses */ + +static inline u16 WPA_GET_BE16(const u8 *a) +{ + return (a[0] << 8) | a[1]; +} + +static inline void WPA_PUT_BE16(u8 *a, u16 val) +{ + a[0] = val >> 8; + a[1] = val & 0xff; +} + +static inline u16 WPA_GET_LE16(const u8 *a) +{ + return (a[1] << 8) | a[0]; +} + +static inline void WPA_PUT_LE16(u8 *a, u16 val) +{ + a[1] = val >> 8; + a[0] = val & 0xff; +} + +static inline u32 WPA_GET_BE24(const u8 *a) +{ + return (a[0] << 16) | (a[1] << 8) | a[2]; +} + +static inline void WPA_PUT_BE24(u8 *a, u32 val) +{ + a[0] = (val >> 16) & 0xff; + a[1] = (val >> 8) & 0xff; + a[2] = val & 0xff; +} + +static inline u32 WPA_GET_BE32(const u8 *a) +{ + return ((u32) a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]; +} + +static inline void WPA_PUT_BE32(u8 *a, u32 val) +{ + a[0] = (val >> 24) & 0xff; + a[1] = (val >> 16) & 0xff; + a[2] = (val >> 8) & 0xff; + a[3] = val & 0xff; +} + +static inline u32 WPA_GET_LE32(const u8 *a) +{ + return ((u32) a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]; +} + +static inline void WPA_PUT_LE32(u8 *a, u32 val) +{ + a[3] = (val >> 24) & 0xff; + a[2] = (val >> 16) & 0xff; + a[1] = (val >> 8) & 0xff; + a[0] = val & 0xff; +} + +static inline u64 WPA_GET_BE64(const u8 *a) +{ + return (((u64) a[0]) << 56) | (((u64) a[1]) << 48) | + (((u64) a[2]) << 40) | (((u64) a[3]) << 32) | + (((u64) a[4]) << 24) | (((u64) a[5]) << 16) | + (((u64) a[6]) << 8) | ((u64) a[7]); +} + +static inline void WPA_PUT_BE64(u8 *a, u64 val) +{ + a[0] = val >> 56; + a[1] = val >> 48; + a[2] = val >> 40; + a[3] = val >> 32; + a[4] = val >> 24; + a[5] = val >> 16; + a[6] = val >> 8; + a[7] = val & 0xff; +} + +static inline u64 WPA_GET_LE64(const u8 *a) +{ + return (((u64) a[7]) << 56) | (((u64) a[6]) << 48) | + (((u64) a[5]) << 40) | (((u64) a[4]) << 32) | + (((u64) a[3]) << 24) | (((u64) a[2]) << 16) | + (((u64) a[1]) << 8) | ((u64) a[0]); +} + +static inline void WPA_PUT_LE64(u8 *a, u64 val) +{ + a[7] = val >> 56; + a[6] = val >> 48; + a[5] = val >> 40; + a[4] = val >> 32; + a[3] = val >> 24; + a[2] = val >> 16; + a[1] = val >> 8; + a[0] = val & 0xff; +} + + +#ifndef ETH_ALEN +#define ETH_ALEN 6 +#endif +#ifndef ETH_HLEN +#define ETH_HLEN 14 +#endif +#ifndef IFNAMSIZ +#define IFNAMSIZ 16 +#endif +#ifndef ETH_P_ALL +#define ETH_P_ALL 0x0003 +#endif +#ifndef ETH_P_IP +#define ETH_P_IP 0x0800 +#endif +#ifndef ETH_P_80211_ENCAP +#define ETH_P_80211_ENCAP 0x890d /* TDLS comes under this category */ +#endif +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif /* ETH_P_PAE */ +#ifndef ETH_P_EAPOL +#define ETH_P_EAPOL ETH_P_PAE +#endif /* ETH_P_EAPOL */ +#ifndef ETH_P_RSN_PREAUTH +#define ETH_P_RSN_PREAUTH 0x88c7 +#endif /* ETH_P_RSN_PREAUTH */ +#ifndef ETH_P_RRB +#define ETH_P_RRB 0x890D +#endif /* ETH_P_RRB */ +#ifndef ETH_P_OUI +#define ETH_P_OUI 0x88B7 +#endif /* ETH_P_OUI */ + + +#ifdef __GNUC__ +#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b)))) +#define STRUCT_PACKED __attribute__ ((packed)) +#else +#define PRINTF_FORMAT(a,b) +#define STRUCT_PACKED +#endif + + +#ifdef CONFIG_ANSI_C_EXTRA + +#if !defined(_MSC_VER) || _MSC_VER < 1400 +/* snprintf - used in number of places; sprintf() is _not_ a good replacement + * due to possible buffer overflow; see, e.g., + * http://www.ijs.si/software/snprintf/ for portable implementation of + * snprintf. */ +int snprintf(char *str, size_t size, const char *format, ...); + +/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */ +int vsnprintf(char *str, size_t size, const char *format, va_list ap); +#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */ + +/* getopt - only used in main.c */ +int getopt(int argc, char *const argv[], const char *optstring); +extern char *optarg; +extern int optind; + +#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF +#ifndef __socklen_t_defined +typedef int socklen_t; +#endif +#endif + +/* inline - define as __inline or just define it to be empty, if needed */ +#ifdef CONFIG_NO_INLINE +#define inline +#else +#define inline __inline +#endif + +#ifndef __func__ +#define __func__ "__func__ not defined" +#endif + +#ifndef bswap_16 +#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff)) +#endif + +#ifndef bswap_32 +#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \ + (((u32) (a) << 8) & 0xff0000) | \ + (((u32) (a) >> 8) & 0xff00) | \ + (((u32) (a) >> 24) & 0xff)) +#endif + +#ifndef MSG_DONTWAIT +#define MSG_DONTWAIT 0 +#endif + +#ifdef _WIN32_WCE +void perror(const char *s); +#endif /* _WIN32_WCE */ + +#endif /* CONFIG_ANSI_C_EXTRA */ + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" + +/* + * Compact form for string representation of MAC address + * To be used, e.g., for constructing dbus paths for P2P Devices + */ +#define COMPACT_MACSTR "%02x%02x%02x%02x%02x%02x" +#endif + +#ifndef BIT +#define BIT(x) (1U << (x)) +#endif + +/* + * Definitions for sparse validation + * (http://kernel.org/pub/linux/kernel/people/josh/sparse/) + */ +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#undef __bitwise +#define __bitwise __attribute__((bitwise)) +#else +#define __force +#undef __bitwise +#define __bitwise +#endif + +typedef u16 __bitwise be16; +typedef u16 __bitwise le16; +typedef u32 __bitwise be32; +typedef u32 __bitwise le32; +typedef u64 __bitwise be64; +typedef u64 __bitwise le64; + +#ifndef __must_check +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define __must_check __attribute__((__warn_unused_result__)) +#else +#define __must_check +#endif /* __GNUC__ */ +#endif /* __must_check */ + +#ifndef __maybe_unused +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define __maybe_unused __attribute__((unused)) +#else +#define __maybe_unused +#endif /* __GNUC__ */ +#endif /* __must_check */ + +#define SSID_MAX_LEN 32 + +struct wpa_ssid_value { + u8 ssid[SSID_MAX_LEN]; + size_t ssid_len; +}; + +int hwaddr_aton(const char *txt, u8 *addr); +int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable); +int hwaddr_compact_aton(const char *txt, u8 *addr); +int hwaddr_aton2(const char *txt, u8 *addr); +int hex2byte(const char *hex); +int hexstr2bin(const char *hex, u8 *buf, size_t len); +void inc_byte_array(u8 *counter, size_t len); +void wpa_get_ntp_timestamp(u8 *buf); +int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...); +int wpa_snprintf_hex_sep(char *buf, size_t buf_size, const u8 *data, size_t len, + char sep); +int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len); +int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data, + size_t len); + +int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask); +int ssid_parse(const char *buf, struct wpa_ssid_value *ssid); + +#ifdef CONFIG_NATIVE_WINDOWS +void wpa_unicode2ascii_inplace(TCHAR *str); +TCHAR * wpa_strdup_tchar(const char *str); +#else /* CONFIG_NATIVE_WINDOWS */ +#define wpa_unicode2ascii_inplace(s) do { } while (0) +#define wpa_strdup_tchar(s) strdup((s)) +#endif /* CONFIG_NATIVE_WINDOWS */ + +void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len); +size_t printf_decode(u8 *buf, size_t maxlen, const char *str); + +const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len); + +char * wpa_config_parse_string(const char *value, size_t *len); +int is_hex(const u8 *data, size_t len); +int has_ctrl_char(const u8 *data, size_t len); +int has_newline(const char *str); +size_t merge_byte_arrays(u8 *res, size_t res_len, + const u8 *src1, size_t src1_len, + const u8 *src2, size_t src2_len); +char * dup_binstr(const void *src, size_t len); + +static inline int is_zero_ether_addr(const u8 *a) +{ + return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]); +} + +static inline int is_broadcast_ether_addr(const u8 *a) +{ + return (a[0] & a[1] & a[2] & a[3] & a[4] & a[5]) == 0xff; +} + +static inline int is_multicast_ether_addr(const u8 *a) +{ + return a[0] & 0x01; +} + +#define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff" + +#include "wpa_debug.h" + + +struct wpa_freq_range_list { + struct wpa_freq_range { + unsigned int min; + unsigned int max; + } *range; + unsigned int num; +}; + +int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value); +int freq_range_list_includes(const struct wpa_freq_range_list *list, + unsigned int freq); +char * freq_range_list_str(const struct wpa_freq_range_list *list); + +int int_array_len(const int *a); +void int_array_concat(int **res, const int *a); +void int_array_sort_unique(int *a); +void int_array_add_unique(int **res, int a); + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +void str_clear_free(char *str); +void bin_clear_free(void *bin, size_t len); + +int random_mac_addr(u8 *addr); +int random_mac_addr_keep_oui(u8 *addr); + +const char * cstr_token(const char *str, const char *delim, const char **last); +char * str_token(char *str, const char *delim, char **context); +size_t utf8_escape(const char *inp, size_t in_size, + char *outp, size_t out_size); +size_t utf8_unescape(const char *inp, size_t in_size, + char *outp, size_t out_size); +int is_ctrl_char(char c); + +int str_starts(const char *str, const char *start); + +u8 rssi_to_rcpi(int rssi); + +/* + * gcc 4.4 ends up generating strict-aliasing warnings about some very common + * networking socket uses that do not really result in a real problem and + * cannot be easily avoided with union-based type-punning due to struct + * definitions including another struct in system header files. To avoid having + * to fully disable strict-aliasing warnings, provide a mechanism to hide the + * typecast from aliasing for now. A cleaner solution will hopefully be found + * in the future to handle these cases. + */ +void * __hide_aliasing_typecast(void *foo); +#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a)) + +#ifdef CONFIG_VALGRIND +#include +#define WPA_MEM_DEFINED(ptr, len) VALGRIND_MAKE_MEM_DEFINED((ptr), (len)) +#else /* CONFIG_VALGRIND */ +#define WPA_MEM_DEFINED(ptr, len) do { } while (0) +#endif /* CONFIG_VALGRIND */ + +#endif /* COMMON_H */ diff --git a/wireless/wifictld/src/hostapd/ieee802_11_defs.h b/wireless/wifictld/src/hostapd/ieee802_11_defs.h new file mode 100644 index 0000000..b7fa563 --- /dev/null +++ b/wireless/wifictld/src/hostapd/ieee802_11_defs.h @@ -0,0 +1,2035 @@ +/* + * IEEE 802.11 Frame type definitions + * Copyright (c) 2002-2015, Jouni Malinen + * Copyright (c) 2007-2008 Intel Corporation + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#ifndef IEEE802_11_DEFS_H +#define IEEE802_11_DEFS_H + +#include + +/* IEEE 802.11 defines */ + +#define WLAN_FC_PVER 0x0003 +#define WLAN_FC_TODS 0x0100 +#define WLAN_FC_FROMDS 0x0200 +#define WLAN_FC_MOREFRAG 0x0400 +#define WLAN_FC_RETRY 0x0800 +#define WLAN_FC_PWRMGT 0x1000 +#define WLAN_FC_MOREDATA 0x2000 +#define WLAN_FC_ISWEP 0x4000 +#define WLAN_FC_ORDER 0x8000 + +#define WLAN_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2) +#define WLAN_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4) + +#define WLAN_INVALID_MGMT_SEQ 0xFFFF + +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & (BIT(3) | BIT(2) | BIT(1) | BIT(0))) +#define WLAN_GET_SEQ_SEQ(seq) \ + (((seq) & (~(BIT(3) | BIT(2) | BIT(1) | BIT(0)))) >> 4) + +#define WLAN_FC_TYPE_MGMT 0 +#define WLAN_FC_TYPE_CTRL 1 +#define WLAN_FC_TYPE_DATA 2 + +/* management */ +#define WLAN_FC_STYPE_ASSOC_REQ 0 +#define WLAN_FC_STYPE_ASSOC_RESP 1 +#define WLAN_FC_STYPE_REASSOC_REQ 2 +#define WLAN_FC_STYPE_REASSOC_RESP 3 +#define WLAN_FC_STYPE_PROBE_REQ 4 +#define WLAN_FC_STYPE_PROBE_RESP 5 +#define WLAN_FC_STYPE_BEACON 8 +#define WLAN_FC_STYPE_ATIM 9 +#define WLAN_FC_STYPE_DISASSOC 10 +#define WLAN_FC_STYPE_AUTH 11 +#define WLAN_FC_STYPE_DEAUTH 12 +#define WLAN_FC_STYPE_ACTION 13 + +/* control */ +#define WLAN_FC_STYPE_PSPOLL 10 +#define WLAN_FC_STYPE_RTS 11 +#define WLAN_FC_STYPE_CTS 12 +#define WLAN_FC_STYPE_ACK 13 +#define WLAN_FC_STYPE_CFEND 14 +#define WLAN_FC_STYPE_CFENDACK 15 + +/* data */ +#define WLAN_FC_STYPE_DATA 0 +#define WLAN_FC_STYPE_DATA_CFACK 1 +#define WLAN_FC_STYPE_DATA_CFPOLL 2 +#define WLAN_FC_STYPE_DATA_CFACKPOLL 3 +#define WLAN_FC_STYPE_NULLFUNC 4 +#define WLAN_FC_STYPE_CFACK 5 +#define WLAN_FC_STYPE_CFPOLL 6 +#define WLAN_FC_STYPE_CFACKPOLL 7 +#define WLAN_FC_STYPE_QOS_DATA 8 +#define WLAN_FC_STYPE_QOS_DATA_CFACK 9 +#define WLAN_FC_STYPE_QOS_DATA_CFPOLL 10 +#define WLAN_FC_STYPE_QOS_DATA_CFACKPOLL 11 +#define WLAN_FC_STYPE_QOS_NULL 12 +#define WLAN_FC_STYPE_QOS_CFPOLL 14 +#define WLAN_FC_STYPE_QOS_CFACKPOLL 15 + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 +#define WLAN_AUTH_FT 2 +#define WLAN_AUTH_SAE 3 +#define WLAN_AUTH_FILS_SK 4 +#define WLAN_AUTH_FILS_SK_PFS 5 +#define WLAN_AUTH_FILS_PK 6 +#define WLAN_AUTH_LEAP 128 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_ESS BIT(0) +#define WLAN_CAPABILITY_IBSS BIT(1) +#define WLAN_CAPABILITY_CF_POLLABLE BIT(2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3) +#define WLAN_CAPABILITY_PRIVACY BIT(4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE BIT(5) +#define WLAN_CAPABILITY_PBCC BIT(6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY BIT(7) +#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8) +#define WLAN_CAPABILITY_QOS BIT(9) +#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10) +#define WLAN_CAPABILITY_APSD BIT(11) +#define WLAN_CAPABILITY_RADIO_MEASUREMENT BIT(12) +#define WLAN_CAPABILITY_DSSS_OFDM BIT(13) +#define WLAN_CAPABILITY_DELAYED_BLOCK_ACK BIT(14) +#define WLAN_CAPABILITY_IMM_BLOCK_ACK BIT(15) + +/* Status codes (IEEE Std 802.11-2016, 9.4.1.9, Table 9-46) */ +#define WLAN_STATUS_SUCCESS 0 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 +#define WLAN_STATUS_TDLS_WAKEUP_ALTERNATE 2 +#define WLAN_STATUS_TDLS_WAKEUP_REJECT 3 +#define WLAN_STATUS_SECURITY_DISABLED 5 +#define WLAN_STATUS_UNACCEPTABLE_LIFETIME 6 +#define WLAN_STATUS_NOT_IN_SAME_BSS 7 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 +#define WLAN_STATUS_CHALLENGE_FAIL 15 +#define WLAN_STATUS_AUTH_TIMEOUT 16 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18 +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 +#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 +#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 +#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 +#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 +#define WLAN_STATUS_ASSOC_DENIED_NO_HT 27 +#define WLAN_STATUS_R0KH_UNREACHABLE 28 +#define WLAN_STATUS_ASSOC_DENIED_NO_PCO 29 +#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 +#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 +#define WLAN_STATUS_UNSPECIFIED_QOS_FAILURE 32 +#define WLAN_STATUS_DENIED_INSUFFICIENT_BANDWIDTH 33 +#define WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS 34 +#define WLAN_STATUS_DENIED_QOS_NOT_SUPPORTED 35 +#define WLAN_STATUS_REQUEST_DECLINED 37 +#define WLAN_STATUS_INVALID_PARAMETERS 38 +#define WLAN_STATUS_REJECTED_WITH_SUGGESTED_CHANGES 39 +#define WLAN_STATUS_INVALID_IE 40 +#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 +#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 +#define WLAN_STATUS_AKMP_NOT_VALID 43 +#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 +#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 +#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 +#define WLAN_STATUS_TS_NOT_CREATED 47 +#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 +#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 +#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 +#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 +#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 +#define WLAN_STATUS_INVALID_PMKID 53 +#define WLAN_STATUS_INVALID_MDIE 54 +#define WLAN_STATUS_INVALID_FTIE 55 +#define WLAN_STATUS_REQUESTED_TCLAS_NOT_SUPPORTED 56 +#define WLAN_STATUS_INSUFFICIENT_TCLAS_PROCESSING_RESOURCES 57 +#define WLAN_STATUS_TRY_ANOTHER_BSS 58 +#define WLAN_STATUS_GAS_ADV_PROTO_NOT_SUPPORTED 59 +#define WLAN_STATUS_NO_OUTSTANDING_GAS_REQ 60 +#define WLAN_STATUS_GAS_RESP_NOT_RECEIVED 61 +#define WLAN_STATUS_STA_TIMED_OUT_WAITING_FOR_GAS_RESP 62 +#define WLAN_STATUS_GAS_RESP_LARGER_THAN_LIMIT 63 +#define WLAN_STATUS_REQ_REFUSED_HOME 64 +#define WLAN_STATUS_ADV_SRV_UNREACHABLE 65 +#define WLAN_STATUS_REQ_REFUSED_SSPN 67 +#define WLAN_STATUS_REQ_REFUSED_UNAUTH_ACCESS 68 +#define WLAN_STATUS_INVALID_RSNIE 72 +#define WLAN_STATUS_U_APSD_COEX_NOT_SUPPORTED 73 +#define WLAN_STATUS_U_APSD_COEX_MODE_NOT_SUPPORTED 74 +#define WLAN_STATUS_BAD_INTERVAL_WITH_U_APSD_COEX 75 +#define WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ 76 +#define WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED 77 +#define WLAN_STATUS_CANNOT_FIND_ALT_TBTT 78 +#define WLAN_STATUS_TRANSMISSION_FAILURE 79 +#define WLAN_STATUS_REQ_TCLAS_NOT_SUPPORTED 80 +#define WLAN_STATUS_TCLAS_RESOURCES_EXCHAUSTED 81 +#define WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION 82 +#define WLAN_STATUS_REJECT_WITH_SCHEDULE 83 +#define WLAN_STATUS_REJECT_NO_WAKEUP_SPECIFIED 84 +#define WLAN_STATUS_SUCCESS_POWER_SAVE_MODE 85 +#define WLAN_STATUS_PENDING_ADMITTING_FST_SESSION 86 +#define WLAN_STATUS_PERFORMING_FST_NOW 87 +#define WLAN_STATUS_PENDING_GAP_IN_BA_WINDOW 88 +#define WLAN_STATUS_REJECT_U_PID_SETTING 89 +#define WLAN_STATUS_REFUSED_EXTERNAL_REASON 92 +#define WLAN_STATUS_REFUSED_AP_OUT_OF_MEMORY 93 +#define WLAN_STATUS_REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED 94 +#define WLAN_STATUS_QUERY_RESP_OUTSTANDING 95 +#define WLAN_STATUS_REJECT_DSE_BAND 96 +#define WLAN_STATUS_TCLAS_PROCESSING_TERMINATED 97 +#define WLAN_STATUS_TS_SCHEDULE_CONFLICT 98 +#define WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL 99 +#define WLAN_STATUS_MCCAOP_RESERVATION_CONFLICT 100 +#define WLAN_STATUS_MAF_LIMIT_EXCEEDED 101 +#define WLAN_STATUS_MCCA_TRACK_LIMIT_EXCEEDED 102 +#define WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT 103 +#define WLAN_STATUS_ASSOC_DENIED_NO_VHT 104 +#define WLAN_STATUS_ENABLEMENT_DENIED 105 +#define WLAN_STATUS_RESTRICTION_FROM_AUTHORIZED_GDB 106 +#define WLAN_STATUS_AUTHORIZATION_DEENABLED 107 +#define WLAN_STATUS_FILS_AUTHENTICATION_FAILURE 112 +#define WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER 113 + +/* Reason codes (IEEE Std 802.11-2016, 9.4.1.7, Table 9-45) */ +#define WLAN_REASON_UNSPECIFIED 1 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 +#define WLAN_REASON_DEAUTH_LEAVING 3 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 +#define WLAN_REASON_DISASSOC_AP_BUSY 5 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 +#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 +#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 +#define WLAN_REASON_BSS_TRANSITION_DISASSOC 12 +#define WLAN_REASON_INVALID_IE 13 +#define WLAN_REASON_MICHAEL_MIC_FAILURE 14 +#define WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT 15 +#define WLAN_REASON_GROUP_KEY_UPDATE_TIMEOUT 16 +#define WLAN_REASON_IE_IN_4WAY_DIFFERS 17 +#define WLAN_REASON_GROUP_CIPHER_NOT_VALID 18 +#define WLAN_REASON_PAIRWISE_CIPHER_NOT_VALID 19 +#define WLAN_REASON_AKMP_NOT_VALID 20 +#define WLAN_REASON_UNSUPPORTED_RSN_IE_VERSION 21 +#define WLAN_REASON_INVALID_RSN_IE_CAPAB 22 +#define WLAN_REASON_IEEE_802_1X_AUTH_FAILED 23 +#define WLAN_REASON_CIPHER_SUITE_REJECTED 24 +#define WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE 25 +#define WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED 26 +#define WLAN_REASON_SSP_REQUESTED_DISASSOC 27 +#define WLAN_REASON_NO_SSP_ROAMING_AGREEMENT 28 +#define WLAN_REASON_BAD_CIPHER_OR_AKM 29 +#define WLAN_REASON_NOT_AUTHORIZED_THIS_LOCATION 30 +#define WLAN_REASON_SERVICE_CHANGE_PRECLUDES_TS 31 +#define WLAN_REASON_UNSPECIFIED_QOS_REASON 32 +#define WLAN_REASON_NOT_ENOUGH_BANDWIDTH 33 +#define WLAN_REASON_DISASSOC_LOW_ACK 34 +#define WLAN_REASON_EXCEEDED_TXOP 35 +#define WLAN_REASON_STA_LEAVING 36 +#define WLAN_REASON_END_TS_BA_DLS 37 +#define WLAN_REASON_UNKNOWN_TS_BA 38 +#define WLAN_REASON_TIMEOUT 39 +#define WLAN_REASON_PEERKEY_MISMATCH 45 +#define WLAN_REASON_AUTHORIZED_ACCESS_LIMIT_REACHED 46 +#define WLAN_REASON_EXTERNAL_SERVICE_REQUIREMENTS 47 +#define WLAN_REASON_INVALID_FT_ACTION_FRAME_COUNT 48 +#define WLAN_REASON_INVALID_PMKID 49 +#define WLAN_REASON_INVALID_MDE 50 +#define WLAN_REASON_INVALID_FTE 51 +#define WLAN_REASON_MESH_PEERING_CANCELLED 52 +#define WLAN_REASON_MESH_MAX_PEERS 53 +#define WLAN_REASON_MESH_CONFIG_POLICY_VIOLATION 54 +#define WLAN_REASON_MESH_CLOSE_RCVD 55 +#define WLAN_REASON_MESH_MAX_RETRIES 56 +#define WLAN_REASON_MESH_CONFIRM_TIMEOUT 57 +#define WLAN_REASON_MESH_INVALID_GTK 58 +#define WLAN_REASON_MESH_INCONSISTENT_PARAMS 59 +#define WLAN_REASON_MESH_INVALID_SECURITY_CAP 60 +#define WLAN_REASON_MESH_PATH_ERROR_NO_PROXY_INFO 61 +#define WLAN_REASON_MESH_PATH_ERROR_NO_FORWARDING_INFO 62 +#define WLAN_REASON_MESH_PATH_ERROR_DEST_UNREACHABLE 63 +#define WLAN_REASON_MAC_ADDRESS_ALREADY_EXISTS_IN_MBSS 64 +#define WLAN_REASON_MESH_CHANNEL_SWITCH_REGULATORY_REQ 65 +#define WLAN_REASON_MESH_CHANNEL_SWITCH_UNSPECIFIED 66 + + +/* Information Element IDs (IEEE Std 802.11-2016, 9.4.2.1, Table 9-77) */ +#define WLAN_EID_SSID 0 +#define WLAN_EID_SUPP_RATES 1 +#define WLAN_EID_DS_PARAMS 3 +#define WLAN_EID_CF_PARAMS 4 +#define WLAN_EID_TIM 5 +#define WLAN_EID_IBSS_PARAMS 6 +#define WLAN_EID_COUNTRY 7 +#define WLAN_EID_REQUEST 10 +#define WLAN_EID_BSS_LOAD 11 +#define WLAN_EID_EDCA_PARAM_SET 12 +#define WLAN_EID_TSPEC 13 +#define WLAN_EID_TCLAS 14 +#define WLAN_EID_SCHEDULE 15 +#define WLAN_EID_CHALLENGE 16 +#define WLAN_EID_PWR_CONSTRAINT 32 +#define WLAN_EID_PWR_CAPABILITY 33 +#define WLAN_EID_TPC_REQUEST 34 +#define WLAN_EID_TPC_REPORT 35 +#define WLAN_EID_SUPPORTED_CHANNELS 36 +#define WLAN_EID_CHANNEL_SWITCH 37 +#define WLAN_EID_MEASURE_REQUEST 38 +#define WLAN_EID_MEASURE_REPORT 39 +#define WLAN_EID_QUIET 40 +#define WLAN_EID_IBSS_DFS 41 +#define WLAN_EID_ERP_INFO 42 +#define WLAN_EID_TS_DELAY 43 +#define WLAN_EID_TCLAS_PROCESSING 44 +#define WLAN_EID_HT_CAP 45 +#define WLAN_EID_QOS 46 +#define WLAN_EID_RSN 48 +#define WLAN_EID_EXT_SUPP_RATES 50 +#define WLAN_EID_AP_CHANNEL_REPORT 51 +#define WLAN_EID_NEIGHBOR_REPORT 52 +#define WLAN_EID_RCPI 53 +#define WLAN_EID_MOBILITY_DOMAIN 54 +#define WLAN_EID_FAST_BSS_TRANSITION 55 +#define WLAN_EID_TIMEOUT_INTERVAL 56 +#define WLAN_EID_RIC_DATA 57 +#define WLAN_EID_DSE_REGISTERED_LOCATION 58 +#define WLAN_EID_SUPPORTED_OPERATING_CLASSES 59 +#define WLAN_EID_EXT_CHANSWITCH_ANN 60 +#define WLAN_EID_HT_OPERATION 61 +#define WLAN_EID_SECONDARY_CHANNEL_OFFSET 62 +#define WLAN_EID_BSS_AVERAGE_ACCESS_DELAY 63 +#define WLAN_EID_ANTENNA 64 +#define WLAN_EID_RSNI 65 +#define WLAN_EID_MEASUREMENT_PILOT_TRANSMISSION 66 +#define WLAN_EID_BSS_AVAILABLE_ADM_CAPA 67 +#define WLAN_EID_BSS_AC_ACCESS_DELAY 68 /* note: also used by WAPI */ +#define WLAN_EID_TIME_ADVERTISEMENT 69 +#define WLAN_EID_RRM_ENABLED_CAPABILITIES 70 +#define WLAN_EID_MULTIPLE_BSSID 71 +#define WLAN_EID_20_40_BSS_COEXISTENCE 72 +#define WLAN_EID_20_40_BSS_INTOLERANT 73 +#define WLAN_EID_OVERLAPPING_BSS_SCAN_PARAMS 74 +#define WLAN_EID_RIC_DESCRIPTOR 75 +#define WLAN_EID_MMIE 76 +#define WLAN_EID_EVENT_REQUEST 78 +#define WLAN_EID_EVENT_REPORT 79 +#define WLAN_EID_DIAGNOSTIC_REQUEST 80 +#define WLAN_EID_DIAGNOSTIC_REPORT 81 +#define WLAN_EID_LOCATION_PARAMETERS 82 +#define WLAN_EID_NONTRANSMITTED_BSSID_CAPA 83 +#define WLAN_EID_SSID_LIST 84 +#define WLAN_EID_MLTIPLE_BSSID_INDEX 85 +#define WLAN_EID_FMS_DESCRIPTOR 86 +#define WLAN_EID_FMS_REQUEST 87 +#define WLAN_EID_FMS_RESPONSE 88 +#define WLAN_EID_QOS_TRAFFIC_CAPABILITY 89 +#define WLAN_EID_BSS_MAX_IDLE_PERIOD 90 +#define WLAN_EID_TFS_REQ 91 +#define WLAN_EID_TFS_RESP 92 +#define WLAN_EID_WNMSLEEP 93 +#define WLAN_EID_TIM_BROADCAST_REQUEST 94 +#define WLAN_EID_TIM_BROADCAST_RESPONSE 95 +#define WLAN_EID_COLLOCATED_INTERFERENCE_REPORT 96 +#define WLAN_EID_CHANNEL_USAGE 97 +#define WLAN_EID_TIME_ZONE 98 +#define WLAN_EID_DMS_REQUEST 99 +#define WLAN_EID_DMS_RESPONSE 100 +#define WLAN_EID_LINK_ID 101 +#define WLAN_EID_WAKEUP_SCHEDULE 102 +#define WLAN_EID_CHANNEL_SWITCH_TIMING 104 +#define WLAN_EID_PTI_CONTROL 105 +#define WLAN_EID_TPU_BUFFER_STATUS 106 +#define WLAN_EID_INTERWORKING 107 +#define WLAN_EID_ADV_PROTO 108 +#define WLAN_EID_EXPEDITED_BANDWIDTH_REQ 109 +#define WLAN_EID_QOS_MAP_SET 110 +#define WLAN_EID_ROAMING_CONSORTIUM 111 +#define WLAN_EID_EMERGENCY_ALERT_ID 112 +#define WLAN_EID_MESH_CONFIG 113 +#define WLAN_EID_MESH_ID 114 +#define WLAN_EID_MESH_LINK_METRIC_REPORT 115 +#define WLAN_EID_CONGESTION_NOTIFICATION 116 +#define WLAN_EID_PEER_MGMT 117 +#define WLAN_EID_MESH_CHANNEL_SWITCH_PARAMETERS 118 +#define WLAN_EID_MESH_AWAKE_WINDOW 119 +#define WLAN_EID_BEACON_TIMING 120 +#define WLAN_EID_MCCAOP_SETUP_REQUEST 121 +#define WLAN_EID_MCCAOP_SETUP_REPLY 122 +#define WLAN_EID_MCCAOP_ADVERTISEMENT 123 +#define WLAN_EID_MCCAOP_TEARDOWN 124 +#define WLAN_EID_GANN 125 +#define WLAN_EID_RANN 126 +#define WLAN_EID_EXT_CAPAB 127 +#define WLAN_EID_PREQ 130 +#define WLAN_EID_PREP 131 +#define WLAN_EID_PERR 132 +#define WLAN_EID_PXU 137 +#define WLAN_EID_PXUC 138 +#define WLAN_EID_AMPE 139 +#define WLAN_EID_MIC 140 +#define WLAN_EID_DESTINATION_URI 141 +#define WLAN_EID_U_APSD_COEX 142 +#define WLAN_EID_DMG_WAKEUP_SCHEDULE 143 +#define WLAN_EID_EXTENDED_SCHEDULE 144 +#define WLAN_EID_STA_AVAILABILITY 145 +#define WLAN_EID_DMG_TSPEC 146 +#define WLAN_EID_NEXT_DMG_ATI 147 +#define WLAN_EID_DMG_CAPABILITIES 148 +#define WLAN_EID_DMG_OPERATION 151 +#define WLAN_EID_DMG_BSS_PARAMETER_CHANGE 152 +#define WLAN_EID_DMG_BEAM_REFINEMENT 153 +#define WLAN_EID_CHANNEL_MEASUREMENT_FEEDBACK 154 +#define WLAN_EID_CCKM 156 +#define WLAN_EID_AWAKE_WINDOW 157 +#define WLAN_EID_MULTI_BAND 158 +#define WLAN_EID_ADDBA_EXTENSION 159 +#define WLAN_EID_NEXTPCP_LIST 160 +#define WLAN_EID_PCP_HANDOVER 161 +#define WLAN_EID_DMG_LINK_MARGIN 162 +#define WLAN_EID_SWITCHING_STREAM 163 +#define WLAN_EID_SESSION_TRANSITION 164 +#define WLAN_EID_DYNAMIC_TONE_PAIRING_REPORT 165 +#define WLAN_EID_CLUSTER_REPORT 166 +#define WLAN_EID_REPLAY_CAPABILITIES 167 +#define WLAN_EID_RELAY_TRANSFER_PARAM_SET 168 +#define WLAN_EID_BEAMLINK_MAINTENANCE 169 +#define WLAN_EID_MULTIPLE_MAC_SUBLAYERS 170 +#define WLAN_EID_U_PID 171 +#define WLAN_EID_DMG_LINK_ADAPTATION_ACK 172 +#define WLAN_EID_MCCAOP_ADVERTISEMENT_OVERVIEW 174 +#define WLAN_EID_QUIET_PERIOD_REQUEST 175 +#define WLAN_EID_QUIET_PERIOD_RESPONSE 177 +#define WLAN_EID_QMF_POLICY 181 +#define WLAN_EID_ECAPC_POLICY 182 +#define WLAN_EID_CLUSTER_TIME_OFFSET 183 +#define WLAN_EID_INTRA_ACCESS_CATEGORY_PRIORITY 184 +#define WLAN_EID_SCS_DESCRIPTOR 185 +#define WLAN_EID_QLOAD_REPORT 186 +#define WLAN_EID_HCCA_TXOP_UPDATE_COUNT 187 +#define WLAN_EID_HIGHER_LAYER_STREAM_ID 188 +#define WLAN_EID_GCR_GROUP_ADDRESS 189 +#define WLAN_EID_ANTENNA_SECTOR_ID_PATTERN 190 +#define WLAN_EID_VHT_CAP 191 +#define WLAN_EID_VHT_OPERATION 192 +#define WLAN_EID_VHT_EXTENDED_BSS_LOAD 193 +#define WLAN_EID_VHT_WIDE_BW_CHSWITCH 194 +#define WLAN_EID_VHT_TRANSMIT_POWER_ENVELOPE 195 +#define WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER 196 +#define WLAN_EID_VHT_AID 197 +#define WLAN_EID_VHT_QUIET_CHANNEL 198 +#define WLAN_EID_VHT_OPERATING_MODE_NOTIFICATION 199 +#define WLAN_EID_UPSIM 200 +#define WLAN_EID_REDUCED_NEIGHBOR_REPORT 201 +#define WLAN_EID_TVHT_OPERATION 202 +#define WLAN_EID_DEVICE_LOCATION 204 +#define WLAN_EID_WHITE_SPACE_MAP 205 +#define WLAN_EID_FTM_PARAMETERS 206 +#define WLAN_EID_VENDOR_SPECIFIC 221 +#define WLAN_EID_CAG_NUMBER 237 +#define WLAN_EID_AP_CSN 239 +#define WLAN_EID_FILS_INDICATION 240 +#define WLAN_EID_DILS 241 +#define WLAN_EID_FRAGMENT 242 +#define WLAN_EID_EXTENSION 255 + +/* Element ID Extension (EID 255) values */ +#define WLAN_EID_EXT_ASSOC_DELAY_INFO 1 +#define WLAN_EID_EXT_FILS_REQ_PARAMS 2 +#define WLAN_EID_EXT_FILS_KEY_CONFIRM 3 +#define WLAN_EID_EXT_FILS_SESSION 4 +#define WLAN_EID_EXT_FILS_HLP_CONTAINER 5 +#define WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN 6 +#define WLAN_EID_EXT_KEY_DELIVERY 7 +#define WLAN_EID_EXT_FILS_WRAPPED_DATA 8 +#define WLAN_EID_EXT_FTM_SYNC_INFO 9 +#define WLAN_EID_EXT_EXTENDED_REQUEST 10 +#define WLAN_EID_EXT_ESTIMATED_SERVICE_PARAMS 11 +#define WLAN_EID_EXT_FILS_PUBLIC_KEY 12 +#define WLAN_EID_EXT_FILS_NONCE 13 +#define WLAN_EID_EXT_FUTURE_CHANNEL_GUIDANCE 14 +#define WLAN_EID_EXT_OWE_DH_PARAM 32 +#define WLAN_EID_EXT_HE_CAPABILITIES 35 +#define WLAN_EID_EXT_HE_OPERATION 36 + + +/* Action frame categories (IEEE Std 802.11-2016, 9.4.1.11, Table 9-76) */ +#define WLAN_ACTION_SPECTRUM_MGMT 0 +#define WLAN_ACTION_QOS 1 +#define WLAN_ACTION_DLS 2 +#define WLAN_ACTION_BLOCK_ACK 3 +#define WLAN_ACTION_PUBLIC 4 +#define WLAN_ACTION_RADIO_MEASUREMENT 5 +#define WLAN_ACTION_FT 6 +#define WLAN_ACTION_HT 7 +#define WLAN_ACTION_SA_QUERY 8 +#define WLAN_ACTION_PROTECTED_DUAL 9 +#define WLAN_ACTION_WNM 10 +#define WLAN_ACTION_UNPROTECTED_WNM 11 +#define WLAN_ACTION_TDLS 12 +#define WLAN_ACTION_MESH 13 +#define WLAN_ACTION_MULTIHOP 14 +#define WLAN_ACTION_SELF_PROTECTED 15 +#define WLAN_ACTION_DMG 16 +#define WLAN_ACTION_WMM 17 /* WMM Specification 1.1 */ +#define WLAN_ACTION_FST 18 +#define WLAN_ACTION_ROBUST_AV_STREAMING 19 +#define WLAN_ACTION_UNPROTECTED_DMG 20 +#define WLAN_ACTION_VHT 21 +#define WLAN_ACTION_FILS 26 +#define WLAN_ACTION_VENDOR_SPECIFIC_PROTECTED 126 +#define WLAN_ACTION_VENDOR_SPECIFIC 127 +/* Note: 128-255 used to report errors by setting category | 0x80 */ + +/* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */ +#define WLAN_PA_20_40_BSS_COEX 0 +#define WLAN_PA_DSE_ENABLEMENT 1 +#define WLAN_PA_DSE_DEENABLEMENT 2 +#define WLAN_PA_DSE_REG_LOCATION_ANNOUNCE 3 +#define WLAN_PA_EXT_CHANNEL_SWITCH_ANNOUNCE 4 +#define WLAN_PA_DSE_MEASUREMENT_REQ 5 +#define WLAN_PA_DSE_MEASUREMENT_RESP 6 +#define WLAN_PA_MEASUREMENT_PILOT 7 +#define WLAN_PA_DSE_POWER_CONSTRAINT 8 +#define WLAN_PA_VENDOR_SPECIFIC 9 +#define WLAN_PA_GAS_INITIAL_REQ 10 +#define WLAN_PA_GAS_INITIAL_RESP 11 +#define WLAN_PA_GAS_COMEBACK_REQ 12 +#define WLAN_PA_GAS_COMEBACK_RESP 13 +#define WLAN_TDLS_DISCOVERY_RESPONSE 14 +#define WLAN_PA_LOCATION_TRACK_NOTIFICATION 15 +#define WLAN_PA_QAB_REQUEST_FRAME 16 +#define WLAN_PA_QAB_RESPONSE_FRAME 17 +#define WLAN_PA_QMF_POLICY 18 +#define WLAN_PA_QMF_POLICY_CHANGE 19 +#define WLAN_PA_QLOAD_REQUEST 20 +#define WLAN_PA_QLOAD_REPORT 21 +#define WLAN_PA_HCCA_TXOP_ADVERTISEMENT 22 +#define WLAN_PA_HCCA_TXOP_RESPONSE 23 +#define WLAN_PA_PUBLIC_KEY 24 +#define WLAN_PA_CHANNEL_AVAILABILITY_QUERY 25 +#define WLAN_PA_CHANNEL_SCHEDULE_MANAGEMENT 26 +#define WLAN_PA_CONTACT_VERIFICATION_SIGNAL 27 +#define WLAN_PA_GDD_ENABLEMENT_REQ 28 +#define WLAN_PA_GDD_ENABLEMENT_RESP 29 +#define WLAN_PA_NETWORK_CHANNEL_CONTROL 30 +#define WLAN_PA_WHITE_SPACE_MAP_ANNOUNCEMENT 31 +#define WLAN_PA_FTM_REQUEST 32 +#define WLAN_PA_FTM 33 +#define WLAN_PA_FILS_DISCOVERY 34 + +/* Protected Dual of Public Action frames (IEEE Std 802.11-2016, 9.6.11, + * Table 9-332) */ +#define WLAN_PROT_DSE_ENABLEMENT 1 +#define WLAN_PROT_DSE_DEENABLEMENT 2 +#define WLAN_PROT_EXT_CSA 4 +#define WLAN_PROT_MEASUREMENT_REQ 5 +#define WLAN_PROT_MEASUREMENT_REPORT 6 +#define WLAN_PROT_DSE_POWER_CONSTRAINT 8 +#define WLAN_PROT_VENDOR_SPECIFIC 9 +#define WLAN_PROT_GAS_INITIAL_REQ 10 +#define WLAN_PROT_GAS_INITIAL_RESP 11 +#define WLAN_PROT_GAS_COMEBACK_REQ 12 +#define WLAN_PROT_GAS_COMEBACK_RESP 13 +#define WLAN_PROT_QAB_REQUEST_FRAME 16 +#define WLAN_PROT_QAB_RESPONSE_FRAME 17 +#define WLAN_PROT_QMF_POLICY 18 +#define WLAN_PROT_QMF_POLICY_CHANGE 19 +#define WLAN_PROT_QLOAD_REQUEST 20 +#define WLAN_PROT_QLOAD_REPORT 21 +#define WLAN_PROT_HCCA_TXOP_ADVERTISEMENT 22 +#define WLAN_PROT_HCCA_TXOP_RESPONSE 23 +#define WLAN_PROT_CHANNEL_AVAILABILITY_QUERY 25 +#define WLAN_PROT_CHANNEL_SCHEDULE_MANAGEMENT 26 +#define WLAN_PROT_CONTACT_VERIFICATION_SIGNAL 27 +#define WLAN_PROT_GDD_ENABLEMENT_REQ 28 +#define WLAN_PROT_GDD_ENABLEMENT_RESP 29 +#define WLAN_PROT_NETWORK_CHANNEL_CONTROL 30 +#define WLAN_PROT_WHITE_SPACE_MAP_ANNOUNCEMENT 31 + +/* SA Query Action frame (IEEE 802.11w/D8.0, 7.4.9) */ +#define WLAN_SA_QUERY_REQUEST 0 +#define WLAN_SA_QUERY_RESPONSE 1 + +#define WLAN_SA_QUERY_TR_ID_LEN 2 + +/* TDLS action codes */ +#define WLAN_TDLS_SETUP_REQUEST 0 +#define WLAN_TDLS_SETUP_RESPONSE 1 +#define WLAN_TDLS_SETUP_CONFIRM 2 +#define WLAN_TDLS_TEARDOWN 3 +#define WLAN_TDLS_PEER_TRAFFIC_INDICATION 4 +#define WLAN_TDLS_CHANNEL_SWITCH_REQUEST 5 +#define WLAN_TDLS_CHANNEL_SWITCH_RESPONSE 6 +#define WLAN_TDLS_PEER_PSM_REQUEST 7 +#define WLAN_TDLS_PEER_PSM_RESPONSE 8 +#define WLAN_TDLS_PEER_TRAFFIC_RESPONSE 9 +#define WLAN_TDLS_DISCOVERY_REQUEST 10 + +/* Radio Measurement Action codes */ +#define WLAN_RRM_RADIO_MEASUREMENT_REQUEST 0 +#define WLAN_RRM_RADIO_MEASUREMENT_REPORT 1 +#define WLAN_RRM_LINK_MEASUREMENT_REQUEST 2 +#define WLAN_RRM_LINK_MEASUREMENT_REPORT 3 +#define WLAN_RRM_NEIGHBOR_REPORT_REQUEST 4 +#define WLAN_RRM_NEIGHBOR_REPORT_RESPONSE 5 + +/* Radio Measurement capabilities (from RM Enabled Capabilities element) + * IEEE Std 802.11-2016, 9.4.2.45, Table 9-157 */ +/* byte 1 (out of 5) */ +#define WLAN_RRM_CAPS_LINK_MEASUREMENT BIT(0) +#define WLAN_RRM_CAPS_NEIGHBOR_REPORT BIT(1) +#define WLAN_RRM_CAPS_BEACON_REPORT_PASSIVE BIT(4) +#define WLAN_RRM_CAPS_BEACON_REPORT_ACTIVE BIT(5) +#define WLAN_RRM_CAPS_BEACON_REPORT_TABLE BIT(6) +/* byte 2 (out of 5) */ +#define WLAN_RRM_CAPS_LCI_MEASUREMENT BIT(4) +/* byte 5 (out of 5) */ +#define WLAN_RRM_CAPS_FTM_RANGE_REPORT BIT(2) + +/* + * IEEE P802.11-REVmc/D5.0, 9.4.2.21.19 (Fine Timing Measurement Range + * request) - Minimum AP count + */ +#define WLAN_RRM_RANGE_REQ_MAX_MIN_AP 15 + +/* Timeout Interval Type */ +#define WLAN_TIMEOUT_REASSOC_DEADLINE 1 +#define WLAN_TIMEOUT_KEY_LIFETIME 2 +#define WLAN_TIMEOUT_ASSOC_COMEBACK 3 + +/* Interworking element (IEEE 802.11u) - Access Network Options */ +#define INTERWORKING_ANO_ACCESS_NETWORK_MASK 0x0f +#define INTERWORKING_ANO_INTERNET 0x10 +#define INTERWORKING_ANO_ASRA 0x20 +#define INTERWORKING_ANO_ESR 0x40 +#define INTERWORKING_ANO_UESA 0x80 + +#define INTERWORKING_ANT_PRIVATE 0 +#define INTERWORKING_ANT_PRIVATE_WITH_GUEST 1 +#define INTERWORKING_ANT_CHARGEABLE_PUBLIC 2 +#define INTERWORKING_ANT_FREE_PUBLIC 3 +#define INTERWORKING_ANT_PERSONAL_DEVICE 4 +#define INTERWORKING_ANT_EMERGENCY_SERVICES 5 +#define INTERWORKING_ANT_TEST 6 +#define INTERWORKING_ANT_WILDCARD 15 + +/* Advertisement Protocol ID definitions (IEEE Std 802.11-2016, Table 9-215) */ +enum adv_proto_id { + ACCESS_NETWORK_QUERY_PROTOCOL = 0, + MIH_INFO_SERVICE = 1, + MIH_CMD_AND_EVENT_DISCOVERY = 2, + EMERGENCY_ALERT_SYSTEM = 3, + REGISTERED_LOCATION_QUERY_PROTO = 4, + ADV_PROTO_VENDOR_SPECIFIC = 221 +}; + +/* Access Network Query Protocol info ID definitions (IEEE Std 802.11-2016, + * Table 9-271; P802.11ai) */ +enum anqp_info_id { + ANQP_QUERY_LIST = 256, + ANQP_CAPABILITY_LIST = 257, + ANQP_VENUE_NAME = 258, + ANQP_EMERGENCY_CALL_NUMBER = 259, + ANQP_NETWORK_AUTH_TYPE = 260, + ANQP_ROAMING_CONSORTIUM = 261, + ANQP_IP_ADDR_TYPE_AVAILABILITY = 262, + ANQP_NAI_REALM = 263, + ANQP_3GPP_CELLULAR_NETWORK = 264, + ANQP_AP_GEOSPATIAL_LOCATION = 265, + ANQP_AP_CIVIC_LOCATION = 266, + ANQP_AP_LOCATION_PUBLIC_URI = 267, + ANQP_DOMAIN_NAME = 268, + ANQP_EMERGENCY_ALERT_URI = 269, + ANQP_TDLS_CAPABILITY = 270, + ANQP_EMERGENCY_NAI = 271, + ANQP_NEIGHBOR_REPORT = 272, + ANQP_QUERY_AP_LIST = 273, + ANQP_AP_LIST_RESPONSE = 274, + ANQP_FILS_REALM_INFO = 275, + ANQP_CAG = 276, + ANQP_VENUE_URL = 277, + ANQP_ADVICE_OF_CHARGE = 278, + ANQP_LOCAL_CONTENT = 279, + ANQP_NETWORK_AUTH_TYPE_TIMESTAMP = 280, + ANQP_VENDOR_SPECIFIC = 56797 +}; + +/* NAI Realm list - EAP Method subfield - Authentication Parameter ID */ +enum nai_realm_eap_auth_param { + NAI_REALM_EAP_AUTH_EXPANDED_EAP_METHOD = 1, + NAI_REALM_EAP_AUTH_NON_EAP_INNER_AUTH = 2, + NAI_REALM_EAP_AUTH_INNER_AUTH_EAP_METHOD = 3, + NAI_REALM_EAP_AUTH_EXPANDED_INNER_EAP_METHOD = 4, + NAI_REALM_EAP_AUTH_CRED_TYPE = 5, + NAI_REALM_EAP_AUTH_TUNNELED_CRED_TYPE = 6, + NAI_REALM_EAP_AUTH_VENDOR_SPECIFIC = 221 +}; + +enum nai_realm_eap_auth_inner_non_eap { + NAI_REALM_INNER_NON_EAP_PAP = 1, + NAI_REALM_INNER_NON_EAP_CHAP = 2, + NAI_REALM_INNER_NON_EAP_MSCHAP = 3, + NAI_REALM_INNER_NON_EAP_MSCHAPV2 = 4 +}; + +enum nai_realm_eap_cred_type { + NAI_REALM_CRED_TYPE_SIM = 1, + NAI_REALM_CRED_TYPE_USIM = 2, + NAI_REALM_CRED_TYPE_NFC_SECURE_ELEMENT = 3, + NAI_REALM_CRED_TYPE_HARDWARE_TOKEN = 4, + NAI_REALM_CRED_TYPE_SOFTOKEN = 5, + NAI_REALM_CRED_TYPE_CERTIFICATE = 6, + NAI_REALM_CRED_TYPE_USERNAME_PASSWORD = 7, + NAI_REALM_CRED_TYPE_NONE = 8, + NAI_REALM_CRED_TYPE_ANONYMOUS = 9, + NAI_REALM_CRED_TYPE_VENDOR_SPECIFIC = 10 +}; + +/* + * IEEE P802.11-REVmc/D5.0 Table 9-81 - Measurement type definitions for + * measurement requests + */ +enum measure_type { + MEASURE_TYPE_BASIC = 0, + MEASURE_TYPE_CCA = 1, + MEASURE_TYPE_RPI_HIST = 2, + MEASURE_TYPE_CHANNEL_LOAD = 3, + MEASURE_TYPE_NOISE_HIST = 4, + MEASURE_TYPE_BEACON = 5, + MEASURE_TYPE_FRAME = 6, + MEASURE_TYPE_STA_STATISTICS = 7, + MEASURE_TYPE_LCI = 8, + MEASURE_TYPE_TRANSMIT_STREAM = 9, + MEASURE_TYPE_MULTICAST_DIAG = 10, + MEASURE_TYPE_LOCATION_CIVIC = 11, + MEASURE_TYPE_LOCATION_ID = 12, + MEASURE_TYPE_DIRECTIONAL_CHAN_QUALITY = 13, + MEASURE_TYPE_DIRECTIONAL_MEASURE = 14, + MEASURE_TYPE_DIRECTIONAL_STATS = 15, + MEASURE_TYPE_FTM_RANGE = 16, + MEASURE_TYPE_MEASURE_PAUSE = 255, +}; + +/* IEEE Std 802.11-2012 Table 8-71 - Location subject definition */ +enum location_subject { + LOCATION_SUBJECT_LOCAL = 0, + LOCATION_SUBJECT_REMOTE = 1, + LOCATION_SUBJECT_3RD_PARTY = 2, +}; + +/* + * IEEE P802.11-REVmc/D5.0 Table 9-94 - Optional subelement IDs for LCI request + */ +enum lci_req_subelem { + LCI_REQ_SUBELEM_AZIMUTH_REQ = 1, + LCI_REQ_SUBELEM_ORIGINATOR_MAC_ADDR = 2, + LCI_REQ_SUBELEM_TARGET_MAC_ADDR = 3, + LCI_REQ_SUBELEM_MAX_AGE = 4, +}; + +#define FILS_NONCE_LEN 16 +#define FILS_SESSION_LEN 8 +#define FILS_CACHE_ID_LEN 2 +#define FILS_MAX_KEY_AUTH_LEN 48 + +#ifdef _MSC_VER +#pragma pack(push, 1) +#endif /* _MSC_VER */ + +struct ieee80211_hdr { + le16 frame_control; + le16 duration_id; + u8 addr1[6]; + u8 addr2[6]; + u8 addr3[6]; + le16 seq_ctrl; + /* followed by 'u8 addr4[6];' if ToDS and FromDS is set in data frame + */ +} STRUCT_PACKED; + +#define IEEE80211_DA_FROMDS addr1 +#define IEEE80211_BSSID_FROMDS addr2 +#define IEEE80211_SA_FROMDS addr3 + +#define IEEE80211_HDRLEN (sizeof(struct ieee80211_hdr)) + +#define IEEE80211_FC(type, stype) host_to_le16((type << 2) | (stype << 4)) + +struct ieee80211_mgmt { + le16 frame_control; + le16 duration; + u8 da[6]; + u8 sa[6]; + u8 bssid[6]; + le16 seq_ctrl; + union { + struct { + le16 auth_alg; + le16 auth_transaction; + le16 status_code; + /* possibly followed by Challenge text */ + u8 variable[]; + } STRUCT_PACKED auth; + struct { + le16 reason_code; + u8 variable[]; + } STRUCT_PACKED deauth; + struct { + le16 capab_info; + le16 listen_interval; + /* followed by SSID and Supported rates */ + u8 variable[]; + } STRUCT_PACKED assoc_req; + struct { + le16 capab_info; + le16 status_code; + le16 aid; + /* followed by Supported rates */ + u8 variable[]; + } STRUCT_PACKED assoc_resp, reassoc_resp; + struct { + le16 capab_info; + le16 listen_interval; + u8 current_ap[6]; + /* followed by SSID and Supported rates */ + u8 variable[]; + } STRUCT_PACKED reassoc_req; + struct { + le16 reason_code; + u8 variable[]; + } STRUCT_PACKED disassoc; + struct { + u8 timestamp[8]; + le16 beacon_int; + le16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params, TIM */ + u8 variable[]; + } STRUCT_PACKED beacon; + /* probe_req: only variable items: SSID, Supported rates */ + struct { + u8 timestamp[8]; + le16 beacon_int; + le16 capab_info; + /* followed by some of SSID, Supported rates, + * FH Params, DS Params, CF Params, IBSS Params */ + u8 variable[]; + } STRUCT_PACKED probe_resp; + struct { + u8 category; + union { + struct { + u8 action_code; + u8 dialog_token; + u8 status_code; + u8 variable[]; + } STRUCT_PACKED wmm_action; + struct{ + u8 action_code; + u8 element_id; + u8 length; + u8 switch_mode; + u8 new_chan; + u8 switch_count; + } STRUCT_PACKED chan_switch; + struct { + u8 action; + u8 sta_addr[ETH_ALEN]; + u8 target_ap_addr[ETH_ALEN]; + u8 variable[]; /* FT Request */ + } STRUCT_PACKED ft_action_req; + struct { + u8 action; + u8 sta_addr[ETH_ALEN]; + u8 target_ap_addr[ETH_ALEN]; + le16 status_code; + u8 variable[]; /* FT Request */ + } STRUCT_PACKED ft_action_resp; + struct { + u8 action; + u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; + } STRUCT_PACKED sa_query_req; + struct { + u8 action; /* */ + u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; + } STRUCT_PACKED sa_query_resp; + struct { + u8 action; + u8 dialogtoken; + u8 variable[]; + } STRUCT_PACKED wnm_sleep_req; + struct { + u8 action; + u8 dialogtoken; + le16 keydata_len; + u8 variable[]; + } STRUCT_PACKED wnm_sleep_resp; + struct { + u8 action; + u8 variable[]; + } STRUCT_PACKED public_action; + struct { + u8 action; /* 9 */ + u8 oui[3]; + /* Vendor-specific content */ + u8 variable[]; + } STRUCT_PACKED vs_public_action; + struct { + u8 action; /* 7 */ + u8 dialog_token; + u8 req_mode; + le16 disassoc_timer; + u8 validity_interval; + /* BSS Termination Duration (optional), + * Session Information URL (optional), + * BSS Transition Candidate List + * Entries */ + u8 variable[]; + } STRUCT_PACKED bss_tm_req; + struct { + u8 action; /* 8 */ + u8 dialog_token; + u8 status_code; + u8 bss_termination_delay; + /* Target BSSID (optional), + * BSS Transition Candidate List + * Entries (optional) */ + u8 variable[]; + } STRUCT_PACKED bss_tm_resp; + struct { + u8 action; /* 6 */ + u8 dialog_token; + u8 query_reason; + /* BSS Transition Candidate List + * Entries (optional) */ + u8 variable[]; + } STRUCT_PACKED bss_tm_query; + struct { + u8 action; /* 15 */ + u8 variable[]; + } STRUCT_PACKED slf_prot_action; + struct { + u8 action; + u8 variable[]; + } STRUCT_PACKED fst_action; + struct { + u8 action; + u8 dialog_token; + u8 variable[]; + } STRUCT_PACKED rrm; + } u; + } STRUCT_PACKED action; + } u; +} STRUCT_PACKED; + + +#define IEEE80211_MAX_MMPDU_SIZE 2304 + +/* Rx MCS bitmask is in the first 77 bits of supported_mcs_set */ +#define IEEE80211_HT_MCS_MASK_LEN 10 + +/* HT Capabilities element */ +struct ieee80211_ht_capabilities { + le16 ht_capabilities_info; + u8 a_mpdu_params; /* Maximum A-MPDU Length Exponent B0..B1 + * Minimum MPDU Start Spacing B2..B4 + * Reserved B5..B7 */ + u8 supported_mcs_set[16]; + le16 ht_extended_capabilities; + le32 tx_bf_capability_info; + u8 asel_capabilities; +} STRUCT_PACKED; + + +/* HT Operation element */ +struct ieee80211_ht_operation { + u8 primary_chan; + /* Five octets of HT Operation Information */ + u8 ht_param; /* B0..B7 */ + le16 operation_mode; /* B8..B23 */ + le16 param; /* B24..B39 */ + u8 basic_mcs_set[16]; +} STRUCT_PACKED; + + +struct ieee80211_obss_scan_parameters { + le16 scan_passive_dwell; + le16 scan_active_dwell; + le16 width_trigger_scan_interval; + le16 scan_passive_total_per_channel; + le16 scan_active_total_per_channel; + le16 channel_transition_delay_factor; + le16 scan_activity_threshold; +} STRUCT_PACKED; + + +struct ieee80211_vht_capabilities { + le32 vht_capabilities_info; + struct { + le16 rx_map; + le16 rx_highest; + le16 tx_map; + le16 tx_highest; + } vht_supported_mcs_set; +} STRUCT_PACKED; + +struct ieee80211_vht_operation { + u8 vht_op_info_chwidth; + u8 vht_op_info_chan_center_freq_seg0_idx; + u8 vht_op_info_chan_center_freq_seg1_idx; + le16 vht_basic_mcs_set; +} STRUCT_PACKED; + +struct ieee80211_ampe_ie { + u8 selected_pairwise_suite[4]; + u8 local_nonce[32]; + u8 peer_nonce[32]; + /* Followed by + * Key Replay Counter[8] (optional) + * (only in Mesh Group Key Inform/Acknowledge frames) + * GTKdata[variable] (optional) + * (MGTK[variable] || Key RSC[8] || GTKExpirationTime[4]) + * IGTKdata[variable] (optional) + * (Key ID[2], IPN[6], IGTK[variable] in IGTK KDE format) + */ +} STRUCT_PACKED; + +#ifdef _MSC_VER +#pragma pack(pop) +#endif /* _MSC_VER */ + +#define ERP_INFO_NON_ERP_PRESENT BIT(0) +#define ERP_INFO_USE_PROTECTION BIT(1) +#define ERP_INFO_BARKER_PREAMBLE_MODE BIT(2) + +#define OVERLAPPING_BSS_TRANS_DELAY_FACTOR 5 + +/* HT Capabilities Info field within HT Capabilities element */ +#define HT_CAP_INFO_LDPC_CODING_CAP ((u16) BIT(0)) +#define HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET ((u16) BIT(1)) +#define HT_CAP_INFO_SMPS_MASK ((u16) (BIT(2) | BIT(3))) +#define HT_CAP_INFO_SMPS_STATIC ((u16) 0) +#define HT_CAP_INFO_SMPS_DYNAMIC ((u16) BIT(2)) +#define HT_CAP_INFO_SMPS_DISABLED ((u16) (BIT(2) | BIT(3))) +#define HT_CAP_INFO_GREEN_FIELD ((u16) BIT(4)) +#define HT_CAP_INFO_SHORT_GI20MHZ ((u16) BIT(5)) +#define HT_CAP_INFO_SHORT_GI40MHZ ((u16) BIT(6)) +#define HT_CAP_INFO_TX_STBC ((u16) BIT(7)) +#define HT_CAP_INFO_RX_STBC_MASK ((u16) (BIT(8) | BIT(9))) +#define HT_CAP_INFO_RX_STBC_1 ((u16) BIT(8)) +#define HT_CAP_INFO_RX_STBC_12 ((u16) BIT(9)) +#define HT_CAP_INFO_RX_STBC_123 ((u16) (BIT(8) | BIT(9))) +#define HT_CAP_INFO_DELAYED_BA ((u16) BIT(10)) +#define HT_CAP_INFO_MAX_AMSDU_SIZE ((u16) BIT(11)) +#define HT_CAP_INFO_DSSS_CCK40MHZ ((u16) BIT(12)) +/* B13 - Reserved (was PSMP support during P802.11n development) */ +#define HT_CAP_INFO_40MHZ_INTOLERANT ((u16) BIT(14)) +#define HT_CAP_INFO_LSIG_TXOP_PROTECT_SUPPORT ((u16) BIT(15)) + +/* HT Extended Capabilities field within HT Capabilities element */ +#define EXT_HT_CAP_INFO_PCO ((u16) BIT(0)) +#define EXT_HT_CAP_INFO_PCO_TRANS_TIME_MASK ((u16) (BIT(1) | BIT(2))) +#define EXT_HT_CAP_INFO_TRANS_TIME_OFFSET 1 +/* B3..B7 - Reserved */ +#define EXT_HT_CAP_INFO_MCS_FEEDBACK_MASK ((u16) (BIT(8) | BIT(9))) +#define EXT_HT_CAP_INFO_MCS_FEEDBACK_OFFSET 8 +#define EXT_HT_CAP_INFO_HTC_SUPPORT ((u16) BIT(10)) +#define EXT_HT_CAP_INFO_RD_RESPONDER ((u16) BIT(11)) +/* B12..B15 - Reserved */ + +/* Transmit Beanforming Capabilities within HT Capabilities element */ +#define TX_BF_CAP_IMPLICIT_TXBF_RX_CAP ((u32) BIT(0)) +#define TX_BF_CAP_RX_STAGGERED_SOUNDING_CAP ((u32) BIT(1)) +#define TX_BF_CAP_TX_STAGGERED_SOUNDING_CAP ((u32) BIT(2)) +#define TX_BF_CAP_RX_NDP_CAP ((u32) BIT(3)) +#define TX_BF_CAP_TX_NDP_CAP ((u32) BIT(4)) +#define TX_BF_CAP_IMPLICIT_TX_BF_CAP ((u32) BIT(5)) +#define TX_BF_CAP_CALIBRATION_MASK ((u32) (BIT(6) | BIT(7)) +#define TX_BF_CAP_CALIB_OFFSET 6 +#define TX_BF_CAP_EXPLICIT_CSI_TXBF_CAP ((u32) BIT(8)) +#define TX_BF_CAP_EXPLICIT_NONCOMPR_STEERING_CAP ((u32) BIT(9)) +#define TX_BF_CAP_EXPLICIT_COMPR_STEERING_CAP ((u32) BIT(10)) +#define TX_BF_CAP_EXPLICIT_TX_BF_CSI_FEEDBACK_MASK ((u32) (BIT(10) | BIT(11))) +#define TX_BF_CAP_EXPLICIT_BF_CSI_FEEDBACK_OFFSET 11 +#define TX_BF_CAP_EXPLICIT_UNCOMPR_STEERING_MATRIX_FEEDBACK_OFFSET 13 +#define TX_BF_CAP_EXPLICIT_COMPRESSED_STEERING_MATRIX_FEEDBACK_OFFSET 15 +#define TX_BF_CAP_MINIMAL_GROUPING_OFFSET 17 +#define TX_BF_CAP_CSI_NUM_BEAMFORMER_ANT_OFFSET 19 +#define TX_BF_CAP_UNCOMPRESSED_STEERING_MATRIX_BEAMFORMER_ANT_OFFSET 21 +#define TX_BF_CAP_COMPRESSED_STEERING_MATRIX_BEAMFORMER_ANT_OFFSET 23 +#define TX_BF_CAP_SCI_MAX_OF_ROWS_BEANFORMER_SUPPORTED_OFFSET 25 +#define TX_BF_CAP_CHANNEL_ESTIMATION_CAP_MASK ((u32) (BIT(27) | BIT(28))) +#define TX_BF_CAP_CHANNEL_ESTIMATION_CAP_OFFSET 27 +/* B29..B31 - Reserved */ + +/* ASEL Capability field within HT Capabilities element */ +#define ASEL_CAP_ASEL_CAPABLE ((u8) BIT(0)) +#define ASEL_CAP_EXPLICIT_CSI_FEEDBACK_BASED_TX_AS_CAP ((u8) BIT(1)) +#define ASEL_CAP_ANT_INDICES_FEEDBACK_BASED_TX_AS_CAP ((u8) BIT(2)) +#define ASEL_CAP_EXPLICIT_CSI_FEEDBACK_CAP ((u8) BIT(3)) +#define ASEL_CAP_ANT_INDICES_FEEDBACK_CAP ((u8) BIT(4)) +#define ASEL_CAP_RX_AS_CAP ((u8) BIT(5)) +#define ASEL_CAP_TX_SOUNDING_PPDUS_CAP ((u8) BIT(6)) +/* B7 - Reserved */ + +/* First octet of HT Operation Information within HT Operation element */ +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_ABOVE ((u8) BIT(0)) +#define HT_INFO_HT_PARAM_SECONDARY_CHNL_BELOW ((u8) BIT(0) | BIT(1)) +#define HT_INFO_HT_PARAM_STA_CHNL_WIDTH ((u8) BIT(2)) +#define HT_INFO_HT_PARAM_RIFS_MODE ((u8) BIT(3)) +/* B4..B7 - Reserved */ + +/* HT Protection (B8..B9 of HT Operation Information) */ +#define HT_PROT_NO_PROTECTION 0 +#define HT_PROT_NONMEMBER_PROTECTION 1 +#define HT_PROT_20MHZ_PROTECTION 2 +#define HT_PROT_NON_HT_MIXED 3 +/* Bits within ieee80211_ht_operation::operation_mode (BIT(0) maps to B8 in + * HT Operation Information) */ +#define HT_OPER_OP_MODE_HT_PROT_MASK ((u16) (BIT(0) | BIT(1))) /* B8..B9 */ +#define HT_OPER_OP_MODE_NON_GF_HT_STAS_PRESENT ((u16) BIT(2)) /* B10 */ +/* BIT(3), i.e., B11 in HT Operation Information field - Reserved */ +#define HT_OPER_OP_MODE_OBSS_NON_HT_STAS_PRESENT ((u16) BIT(4)) /* B12 */ +/* BIT(5)..BIT(15), i.e., B13..B23 - Reserved */ + +/* Last two octets of HT Operation Information (BIT(0) = B24) */ +/* B24..B29 - Reserved */ +#define HT_OPER_PARAM_DUAL_BEACON ((u16) BIT(6)) +#define HT_OPER_PARAM_DUAL_CTS_PROTECTION ((u16) BIT(7)) +#define HT_OPER_PARAM_STBC_BEACON ((u16) BIT(8)) +#define HT_OPER_PARAM_LSIG_TXOP_PROT_FULL_SUPP ((u16) BIT(9)) +#define HT_OPER_PARAM_PCO_ACTIVE ((u16) BIT(10)) +#define HT_OPER_PARAM_PCO_PHASE ((u16) BIT(11)) +/* B36..B39 - Reserved */ + +#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126 +#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 + +/* VHT Defines */ +#define VHT_CAP_MAX_MPDU_LENGTH_7991 ((u32) BIT(0)) +#define VHT_CAP_MAX_MPDU_LENGTH_11454 ((u32) BIT(1)) +#define VHT_CAP_MAX_MPDU_LENGTH_MASK ((u32) BIT(0) | BIT(1)) +#define VHT_CAP_MAX_MPDU_LENGTH_MASK_SHIFT 0 +#define VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ((u32) BIT(2)) +#define VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ ((u32) BIT(3)) +#define VHT_CAP_SUPP_CHAN_WIDTH_MASK ((u32) BIT(2) | BIT(3)) +#define VHT_CAP_SUPP_CHAN_WIDTH_MASK_SHIFT 2 +#define VHT_CAP_RXLDPC ((u32) BIT(4)) +#define VHT_CAP_SHORT_GI_80 ((u32) BIT(5)) +#define VHT_CAP_SHORT_GI_160 ((u32) BIT(6)) +#define VHT_CAP_TXSTBC ((u32) BIT(7)) +#define VHT_CAP_RXSTBC_1 ((u32) BIT(8)) +#define VHT_CAP_RXSTBC_2 ((u32) BIT(9)) +#define VHT_CAP_RXSTBC_3 ((u32) BIT(8) | BIT(9)) +#define VHT_CAP_RXSTBC_4 ((u32) BIT(10)) +#define VHT_CAP_RXSTBC_MASK ((u32) BIT(8) | BIT(9) | \ + BIT(10)) +#define VHT_CAP_RXSTBC_MASK_SHIFT 8 +#define VHT_CAP_SU_BEAMFORMER_CAPABLE ((u32) BIT(11)) +#define VHT_CAP_SU_BEAMFORMEE_CAPABLE ((u32) BIT(12)) +#define VHT_CAP_BEAMFORMEE_STS_MAX ((u32) BIT(13) | \ + BIT(14) | BIT(15)) +#define VHT_CAP_BEAMFORMEE_STS_MAX_SHIFT 13 +#define VHT_CAP_BEAMFORMEE_STS_OFFSET 13 +#define VHT_CAP_SOUNDING_DIMENSION_MAX ((u32) BIT(16) | \ + BIT(17) | BIT(18)) +#define VHT_CAP_SOUNDING_DIMENSION_MAX_SHIFT 16 +#define VHT_CAP_SOUNDING_DIMENSION_OFFSET 16 +#define VHT_CAP_MU_BEAMFORMER_CAPABLE ((u32) BIT(19)) +#define VHT_CAP_MU_BEAMFORMEE_CAPABLE ((u32) BIT(20)) +#define VHT_CAP_VHT_TXOP_PS ((u32) BIT(21)) +#define VHT_CAP_HTC_VHT ((u32) BIT(22)) + +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_1 ((u32) BIT(23)) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_2 ((u32) BIT(24)) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_3 ((u32) BIT(23) | BIT(24)) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_4 ((u32) BIT(25)) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_5 ((u32) BIT(23) | BIT(25)) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_6 ((u32) BIT(24) | BIT(25)) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX ((u32) BIT(23) | \ + BIT(24) | BIT(25)) +#define VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MAX_SHIFT 23 +#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_UNSOL_MFB ((u32) BIT(27)) +#define VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB ((u32) BIT(26) | BIT(27)) +#define VHT_CAP_RX_ANTENNA_PATTERN ((u32) BIT(28)) +#define VHT_CAP_TX_ANTENNA_PATTERN ((u32) BIT(29)) + +#define VHT_OPMODE_CHANNEL_WIDTH_MASK ((u8) BIT(0) | BIT(1)) +#define VHT_OPMODE_CHANNEL_RxNSS_MASK ((u8) BIT(4) | BIT(5) | \ + BIT(6)) +#define VHT_OPMODE_NOTIF_RX_NSS_SHIFT 4 + +#define VHT_RX_NSS_MAX_STREAMS 8 + +/* VHT channel widths */ +#define VHT_CHANWIDTH_USE_HT 0 +#define VHT_CHANWIDTH_80MHZ 1 +#define VHT_CHANWIDTH_160MHZ 2 +#define VHT_CHANWIDTH_80P80MHZ 3 + +#define OUI_MICROSOFT 0x0050f2 /* Microsoft (also used in Wi-Fi specs) + * 00:50:F2 */ +#define WPA_IE_VENDOR_TYPE 0x0050f201 +#define WMM_IE_VENDOR_TYPE 0x0050f202 +#define WPS_IE_VENDOR_TYPE 0x0050f204 +#define OUI_WFA 0x506f9a +#define P2P_IE_VENDOR_TYPE 0x506f9a09 +#define WFD_IE_VENDOR_TYPE 0x506f9a0a +#define WFD_OUI_TYPE 10 +#define HS20_IE_VENDOR_TYPE 0x506f9a10 +#define OSEN_IE_VENDOR_TYPE 0x506f9a12 +#define MBO_IE_VENDOR_TYPE 0x506f9a16 +#define MBO_OUI_TYPE 22 +#define OWE_IE_VENDOR_TYPE 0x506f9a1c +#define OWE_OUI_TYPE 28 + +#define WMM_OUI_TYPE 2 +#define WMM_OUI_SUBTYPE_INFORMATION_ELEMENT 0 +#define WMM_OUI_SUBTYPE_PARAMETER_ELEMENT 1 +#define WMM_OUI_SUBTYPE_TSPEC_ELEMENT 2 +#define WMM_VERSION 1 + +#define WMM_ACTION_CODE_ADDTS_REQ 0 +#define WMM_ACTION_CODE_ADDTS_RESP 1 +#define WMM_ACTION_CODE_DELTS 2 + +#define WMM_ADDTS_STATUS_ADMISSION_ACCEPTED 0 +#define WMM_ADDTS_STATUS_INVALID_PARAMETERS 1 +/* 2 - Reserved */ +#define WMM_ADDTS_STATUS_REFUSED 3 +/* 4-255 - Reserved */ + +/* WMM TSPEC Direction Field Values */ +#define WMM_TSPEC_DIRECTION_UPLINK 0 +#define WMM_TSPEC_DIRECTION_DOWNLINK 1 +/* 2 - Reserved */ +#define WMM_TSPEC_DIRECTION_BI_DIRECTIONAL 3 + +/* + * WMM Information Element (used in (Re)Association Request frames; may also be + * used in Beacon frames) + */ +struct wmm_information_element { + /* Element ID: 221 (0xdd); Length: 7 */ + /* required fields for WMM version 1 */ + u8 oui[3]; /* 00:50:f2 */ + u8 oui_type; /* 2 */ + u8 oui_subtype; /* 0 */ + u8 version; /* 1 for WMM version 1.0 */ + u8 qos_info; /* AP/STA specific QoS info */ + +} STRUCT_PACKED; + +#define WMM_QOSINFO_AP_UAPSD 0x80 + +#define WMM_QOSINFO_STA_AC_MASK 0x0f +#define WMM_QOSINFO_STA_SP_MASK 0x03 +#define WMM_QOSINFO_STA_SP_SHIFT 5 + +#define WMM_AC_AIFSN_MASK 0x0f +#define WMM_AC_AIFNS_SHIFT 0 +#define WMM_AC_ACM 0x10 +#define WMM_AC_ACI_MASK 0x60 +#define WMM_AC_ACI_SHIFT 5 + +#define WMM_AC_ECWMIN_MASK 0x0f +#define WMM_AC_ECWMIN_SHIFT 0 +#define WMM_AC_ECWMAX_MASK 0xf0 +#define WMM_AC_ECWMAX_SHIFT 4 + +struct wmm_ac_parameter { + u8 aci_aifsn; /* AIFSN, ACM, ACI */ + u8 cw; /* ECWmin, ECWmax (CW = 2^ECW - 1) */ + le16 txop_limit; +} STRUCT_PACKED; + +/* + * WMM Parameter Element (used in Beacon, Probe Response, and (Re)Association + * Response frmaes) + */ +struct wmm_parameter_element { + /* Element ID: 221 (0xdd); Length: 24 */ + /* required fields for WMM version 1 */ + u8 oui[3]; /* 00:50:f2 */ + u8 oui_type; /* 2 */ + u8 oui_subtype; /* 1 */ + u8 version; /* 1 for WMM version 1.0 */ + u8 qos_info; /* AP/STA specific QoS info */ + u8 reserved; /* 0 */ + struct wmm_ac_parameter ac[4]; /* AC_BE, AC_BK, AC_VI, AC_VO */ + +} STRUCT_PACKED; + +/* WMM TSPEC Element */ +struct wmm_tspec_element { + u8 eid; /* 221 = 0xdd */ + u8 length; /* 6 + 55 = 61 */ + u8 oui[3]; /* 00:50:f2 */ + u8 oui_type; /* 2 */ + u8 oui_subtype; /* 2 */ + u8 version; /* 1 */ + /* WMM TSPEC body (55 octets): */ + u8 ts_info[3]; + le16 nominal_msdu_size; + le16 maximum_msdu_size; + le32 minimum_service_interval; + le32 maximum_service_interval; + le32 inactivity_interval; + le32 suspension_interval; + le32 service_start_time; + le32 minimum_data_rate; + le32 mean_data_rate; + le32 peak_data_rate; + le32 maximum_burst_size; + le32 delay_bound; + le32 minimum_phy_rate; + le16 surplus_bandwidth_allowance; + le16 medium_time; +} STRUCT_PACKED; + + +/* Access Categories / ACI to AC coding */ +enum wmm_ac { + WMM_AC_BE = 0 /* Best Effort */, + WMM_AC_BK = 1 /* Background */, + WMM_AC_VI = 2 /* Video */, + WMM_AC_VO = 3 /* Voice */, + WMM_AC_NUM = 4 +}; + + +#define HS20_INDICATION_OUI_TYPE 16 +#define HS20_ANQP_OUI_TYPE 17 +#define HS20_OSEN_OUI_TYPE 18 +#define HS20_STYPE_QUERY_LIST 1 +#define HS20_STYPE_CAPABILITY_LIST 2 +#define HS20_STYPE_OPERATOR_FRIENDLY_NAME 3 +#define HS20_STYPE_WAN_METRICS 4 +#define HS20_STYPE_CONNECTION_CAPABILITY 5 +#define HS20_STYPE_NAI_HOME_REALM_QUERY 6 +#define HS20_STYPE_OPERATING_CLASS 7 +#define HS20_STYPE_OSU_PROVIDERS_LIST 8 +#define HS20_STYPE_ICON_REQUEST 10 +#define HS20_STYPE_ICON_BINARY_FILE 11 + +#define HS20_DGAF_DISABLED 0x01 +#define HS20_PPS_MO_ID_PRESENT 0x02 +#define HS20_ANQP_DOMAIN_ID_PRESENT 0x04 +#define HS20_VERSION 0x10 /* Release 2 */ + +/* WNM-Notification WFA vendors specific subtypes */ +#define HS20_WNM_SUB_REM_NEEDED 0 +#define HS20_WNM_DEAUTH_IMMINENT_NOTICE 1 + +#define HS20_DEAUTH_REASON_CODE_BSS 0 +#define HS20_DEAUTH_REASON_CODE_ESS 1 + +/* MBO v0.0_r19, 4.2: MBO Attributes */ +/* Table 4-5: MBO Attributes */ +/* OCE v0.0.10, Table 4-3: OCE Attributes */ +enum mbo_attr_id { + MBO_ATTR_ID_AP_CAPA_IND = 1, + MBO_ATTR_ID_NON_PREF_CHAN_REPORT = 2, + MBO_ATTR_ID_CELL_DATA_CAPA = 3, + MBO_ATTR_ID_ASSOC_DISALLOW = 4, + MBO_ATTR_ID_CELL_DATA_PREF = 5, + MBO_ATTR_ID_TRANSITION_REASON = 6, + MBO_ATTR_ID_TRANSITION_REJECT_REASON = 7, + MBO_ATTR_ID_ASSOC_RETRY_DELAY = 8, + OCE_ATTR_ID_CAPA_IND = 101, + OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT = 102, + OCE_ATTR_ID_REDUCED_WAN_METRICS = 103, + OCE_ATTR_ID_RNR_COMPLETENESS = 104, +}; + +/* MBO v0.0_r19, 4.2.1: MBO AP Capability Indication Attribute */ +/* Table 4-7: MBO AP Capability Indication Field Values */ +#define MBO_AP_CAPA_CELL_AWARE BIT(6) + +/* MBO v0.0_r19, 4.2.2: Non-preferred Channel Report Attribute */ +/* Table 4-10: Reason Code Field Values */ +enum mbo_non_pref_chan_reason { + MBO_NON_PREF_CHAN_REASON_UNSPECIFIED = 0, + MBO_NON_PREF_CHAN_REASON_RSSI = 1, + MBO_NON_PREF_CHAN_REASON_EXT_INTERFERENCE = 2, + MBO_NON_PREF_CHAN_REASON_INT_INTERFERENCE = 3, +}; + +/* MBO v0.0_r19, 4.2.3: Cellular Data Capabilities Attribute */ +/* Table 4-13: Cellular Data Connectivity Field */ +enum mbo_cellular_capa { + MBO_CELL_CAPA_AVAILABLE = 1, + MBO_CELL_CAPA_NOT_AVAILABLE = 2, + MBO_CELL_CAPA_NOT_SUPPORTED = 3, +}; + +/* MBO v0.0_r19, 4.2.4: Association Disallowed Attribute */ +/* Table 4-15: Reason Code Field Values */ +enum mbo_assoc_disallow_reason { + MBO_ASSOC_DISALLOW_REASON_UNSPECIFIED = 1, + MBO_ASSOC_DISALLOW_REASON_MAX_STA = 2, + MBO_ASSOC_DISALLOW_REASON_AIR_INTERFERENCE = 3, + MBO_ASSOC_DISALLOW_REASON_AUTH_SERVER_OVERLOAD = 4, + MBO_ASSOC_DISALLOW_REASON_LOW_RSSI = 5, +}; + +/* MBO v0.0_r19, 4.2.5: Cellular Data Connection Preference Attribute */ +/* Table 4-17: Cellular Preference Field Values */ +enum mbo_cell_pref { + MBO_CELL_PREF_EXCLUDED = 0, + MBO_CELL_PREF_NO_USE = 1, + MBO_CELL_PREF_USE = 255 +}; + +/* MBO v0.0_r19, 4.2.6: Transition Reason Code Attribute */ +/* Table 4-19: Transition Reason Code Field Values */ +enum mbo_transition_reason { + MBO_TRANSITION_REASON_UNSPECIFIED = 0, + MBO_TRANSITION_REASON_FRAME_LOSS = 1, + MBO_TRANSITION_REASON_DELAY = 2, + MBO_TRANSITION_REASON_BANDWIDTH = 3, + MBO_TRANSITION_REASON_LOAD_BALANCE = 4, + MBO_TRANSITION_REASON_RSSI = 5, + MBO_TRANSITION_REASON_RETRANSMISSIONS = 6, + MBO_TRANSITION_REASON_INTERFERENCE = 7, + MBO_TRANSITION_REASON_GRAY_ZONE = 8, + MBO_TRANSITION_REASON_PREMIUM_AP = 9, +}; + +/* MBO v0.0_r19, 4.2.7: Transition Rejection Reason Code Attribute */ +/* Table 4-21: Transition Rejection Reason Code Field Values */ +enum mbo_transition_reject_reason { + MBO_TRANSITION_REJECT_REASON_UNSPECIFIED = 0, + MBO_TRANSITION_REJECT_REASON_FRAME_LOSS = 1, + MBO_TRANSITION_REJECT_REASON_DELAY = 2, + MBO_TRANSITION_REJECT_REASON_QOS_CAPACITY = 3, + MBO_TRANSITION_REJECT_REASON_RSSI = 4, + MBO_TRANSITION_REJECT_REASON_INTERFERENCE = 5, + MBO_TRANSITION_REJECT_REASON_SERVICES = 6, +}; + +/* MBO v0.0_r19, 4.4: WNM-Notification vendor subelements */ +enum wfa_wnm_notif_subelem_id { + WFA_WNM_NOTIF_SUBELEM_NON_PREF_CHAN_REPORT = 2, + WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3, +}; + +/* MBO v0.0_r27, 4.3: MBO ANQP-elements */ +#define MBO_ANQP_OUI_TYPE 0x12 +#define MBO_ANQP_SUBTYPE_QUERY_LIST 1 +#define MBO_ANQP_SUBTYPE_CELL_CONN_PREF 2 +#define MAX_MBO_ANQP_SUBTYPE MBO_ANQP_SUBTYPE_CELL_CONN_PREF + +/* OCE v0.0.10, 4.2.1: OCE Capability Indication Attribute */ +#define OCE_RELEASE 1 +#define OCE_RELEASE_MASK (BIT(0) | BIT(1) | BIT(2)) +#define OCE_IS_STA_CFON BIT(3) +#define OCE_IS_NON_OCE_AP_PRESENT BIT(4) + +/* Wi-Fi Direct (P2P) */ + +#define P2P_OUI_TYPE 9 + +enum p2p_attr_id { + P2P_ATTR_STATUS = 0, + P2P_ATTR_MINOR_REASON_CODE = 1, + P2P_ATTR_CAPABILITY = 2, + P2P_ATTR_DEVICE_ID = 3, + P2P_ATTR_GROUP_OWNER_INTENT = 4, + P2P_ATTR_CONFIGURATION_TIMEOUT = 5, + P2P_ATTR_LISTEN_CHANNEL = 6, + P2P_ATTR_GROUP_BSSID = 7, + P2P_ATTR_EXT_LISTEN_TIMING = 8, + P2P_ATTR_INTENDED_INTERFACE_ADDR = 9, + P2P_ATTR_MANAGEABILITY = 10, + P2P_ATTR_CHANNEL_LIST = 11, + P2P_ATTR_NOTICE_OF_ABSENCE = 12, + P2P_ATTR_DEVICE_INFO = 13, + P2P_ATTR_GROUP_INFO = 14, + P2P_ATTR_GROUP_ID = 15, + P2P_ATTR_INTERFACE = 16, + P2P_ATTR_OPERATING_CHANNEL = 17, + P2P_ATTR_INVITATION_FLAGS = 18, + P2P_ATTR_OOB_GO_NEG_CHANNEL = 19, + P2P_ATTR_SERVICE_HASH = 21, + P2P_ATTR_SESSION_INFORMATION_DATA = 22, + P2P_ATTR_CONNECTION_CAPABILITY = 23, + P2P_ATTR_ADVERTISEMENT_ID = 24, + P2P_ATTR_ADVERTISED_SERVICE = 25, + P2P_ATTR_SESSION_ID = 26, + P2P_ATTR_FEATURE_CAPABILITY = 27, + P2P_ATTR_PERSISTENT_GROUP = 28, + P2P_ATTR_VENDOR_SPECIFIC = 221 +}; + +#define P2P_MAX_GO_INTENT 15 + +/* P2P Capability - Device Capability bitmap */ +#define P2P_DEV_CAPAB_SERVICE_DISCOVERY BIT(0) +#define P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY BIT(1) +#define P2P_DEV_CAPAB_CONCURRENT_OPER BIT(2) +#define P2P_DEV_CAPAB_INFRA_MANAGED BIT(3) +#define P2P_DEV_CAPAB_DEVICE_LIMIT BIT(4) +#define P2P_DEV_CAPAB_INVITATION_PROCEDURE BIT(5) + +/* P2P Capability - Group Capability bitmap */ +#define P2P_GROUP_CAPAB_GROUP_OWNER BIT(0) +#define P2P_GROUP_CAPAB_PERSISTENT_GROUP BIT(1) +#define P2P_GROUP_CAPAB_GROUP_LIMIT BIT(2) +#define P2P_GROUP_CAPAB_INTRA_BSS_DIST BIT(3) +#define P2P_GROUP_CAPAB_CROSS_CONN BIT(4) +#define P2P_GROUP_CAPAB_PERSISTENT_RECONN BIT(5) +#define P2P_GROUP_CAPAB_GROUP_FORMATION BIT(6) +#define P2P_GROUP_CAPAB_IP_ADDR_ALLOCATION BIT(7) + +/* P2PS Coordination Protocol Transport Bitmap */ +#define P2PS_FEATURE_CAPAB_UDP_TRANSPORT BIT(0) +#define P2PS_FEATURE_CAPAB_MAC_TRANSPORT BIT(1) + +struct p2ps_feature_capab { + u8 cpt; + u8 reserved; +} STRUCT_PACKED; + +/* Invitation Flags */ +#define P2P_INVITATION_FLAGS_TYPE BIT(0) + +/* P2P Manageability */ +#define P2P_MAN_DEVICE_MANAGEMENT BIT(0) +#define P2P_MAN_CROSS_CONNECTION_PERMITTED BIT(1) +#define P2P_MAN_COEXISTENCE_OPTIONAL BIT(2) + +enum p2p_status_code { + P2P_SC_SUCCESS = 0, + P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE = 1, + P2P_SC_FAIL_INCOMPATIBLE_PARAMS = 2, + P2P_SC_FAIL_LIMIT_REACHED = 3, + P2P_SC_FAIL_INVALID_PARAMS = 4, + P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE = 5, + P2P_SC_FAIL_PREV_PROTOCOL_ERROR = 6, + P2P_SC_FAIL_NO_COMMON_CHANNELS = 7, + P2P_SC_FAIL_UNKNOWN_GROUP = 8, + P2P_SC_FAIL_BOTH_GO_INTENT_15 = 9, + P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD = 10, + P2P_SC_FAIL_REJECTED_BY_USER = 11, + P2P_SC_SUCCESS_DEFERRED = 12, +}; + +enum p2p_role_indication { + P2P_DEVICE_NOT_IN_GROUP = 0x00, + P2P_CLIENT_IN_A_GROUP = 0x01, + P2P_GO_IN_A_GROUP = 0x02, +}; + +#define P2P_WILDCARD_SSID "DIRECT-" +#define P2P_WILDCARD_SSID_LEN 7 + +/* P2P action frames */ +enum p2p_act_frame_type { + P2P_NOA = 0, + P2P_PRESENCE_REQ = 1, + P2P_PRESENCE_RESP = 2, + P2P_GO_DISC_REQ = 3 +}; + +/* P2P public action frames */ +enum p2p_action_frame_type { + P2P_GO_NEG_REQ = 0, + P2P_GO_NEG_RESP = 1, + P2P_GO_NEG_CONF = 2, + P2P_INVITATION_REQ = 3, + P2P_INVITATION_RESP = 4, + P2P_DEV_DISC_REQ = 5, + P2P_DEV_DISC_RESP = 6, + P2P_PROV_DISC_REQ = 7, + P2P_PROV_DISC_RESP = 8 +}; + +enum p2p_service_protocol_type { + P2P_SERV_ALL_SERVICES = 0, + P2P_SERV_BONJOUR = 1, + P2P_SERV_UPNP = 2, + P2P_SERV_WS_DISCOVERY = 3, + P2P_SERV_WIFI_DISPLAY = 4, + P2P_SERV_P2PS = 11, + P2P_SERV_VENDOR_SPECIFIC = 255 +}; + +enum p2p_sd_status { + P2P_SD_SUCCESS = 0, + P2P_SD_PROTO_NOT_AVAILABLE = 1, + P2P_SD_REQUESTED_INFO_NOT_AVAILABLE = 2, + P2P_SD_BAD_REQUEST = 3 +}; + + +enum wifi_display_subelem { + WFD_SUBELEM_DEVICE_INFO = 0, + WFD_SUBELEM_ASSOCIATED_BSSID = 1, + WFD_SUBELEM_AUDIO_FORMATS = 2, + WFD_SUBELEM_VIDEO_FORMATS = 3, + WFD_SUBELEM_3D_VIDEO_FORMATS = 4, + WFD_SUBELEM_CONTENT_PROTECTION = 5, + WFD_SUBELEM_COUPLED_SINK = 6, + WFD_SUBELEM_EXT_CAPAB = 7, + WFD_SUBELEM_LOCAL_IP_ADDRESS = 8, + WFD_SUBELEM_SESSION_INFO = 9, + WFD_SUBELEM_MAC_INFO = 10, + WFD_SUBELEM_R2_DEVICE_INFO = 11, +}; + +/* 802.11s */ +#define MESH_SYNC_METHOD_NEIGHBOR_OFFSET 1 +#define MESH_SYNC_METHOD_VENDOR 255 +#define MESH_PATH_PROTOCOL_HWMP 1 +#define MESH_PATH_PROTOCOL_VENDOR 255 +#define MESH_PATH_METRIC_AIRTIME 1 +#define MESH_PATH_METRIC_VENDOR 255 +/* IEEE 802.11s - Mesh Capability */ +#define MESH_CAP_ACCEPT_ADDITIONAL_PEER BIT(0) +#define MESH_CAP_MCCA_SUPPORTED BIT(1) +#define MESH_CAP_MCCA_ENABLED BIT(2) +#define MESH_CAP_FORWARDING BIT(3) +#define MESH_CAP_MBCA_ENABLED BIT(4) +#define MESH_CAP_TBTT_ADJUSTING BIT(5) +#define MESH_CAP_MESH_PS_LEVEL BIT(6) + +enum plink_action_field { + PLINK_OPEN = 1, + PLINK_CONFIRM, + PLINK_CLOSE +}; + +#define OUI_BROADCOM 0x00904c /* Broadcom (Epigram) */ +#define VENDOR_VHT_TYPE 0x04 +#define VENDOR_VHT_SUBTYPE 0x08 +#define VENDOR_VHT_SUBTYPE2 0x00 + +#define VENDOR_HT_CAPAB_OUI_TYPE 0x33 /* 00-90-4c:0x33 */ + + +/* IEEE 802.11v - WNM Action field values */ +enum wnm_action { + WNM_EVENT_REQ = 0, + WNM_EVENT_REPORT = 1, + WNM_DIAGNOSTIC_REQ = 2, + WNM_DIAGNOSTIC_REPORT = 3, + WNM_LOCATION_CFG_REQ = 4, + WNM_LOCATION_CFG_RESP = 5, + WNM_BSS_TRANS_MGMT_QUERY = 6, + WNM_BSS_TRANS_MGMT_REQ = 7, + WNM_BSS_TRANS_MGMT_RESP = 8, + WNM_FMS_REQ = 9, + WNM_FMS_RESP = 10, + WNM_COLLOCATED_INTERFERENCE_REQ = 11, + WNM_COLLOCATED_INTERFERENCE_REPORT = 12, + WNM_TFS_REQ = 13, + WNM_TFS_RESP = 14, + WNM_TFS_NOTIFY = 15, + WNM_SLEEP_MODE_REQ = 16, + WNM_SLEEP_MODE_RESP = 17, + WNM_TIM_BROADCAST_REQ = 18, + WNM_TIM_BROADCAST_RESP = 19, + WNM_QOS_TRAFFIC_CAPAB_UPDATE = 20, + WNM_CHANNEL_USAGE_REQ = 21, + WNM_CHANNEL_USAGE_RESP = 22, + WNM_DMS_REQ = 23, + WNM_DMS_RESP = 24, + WNM_TIMING_MEASUREMENT_REQ = 25, + WNM_NOTIFICATION_REQ = 26, + WNM_NOTIFICATION_RESP = 27 +}; + +/* IEEE 802.11v - BSS Transition Management Request - Request Mode */ +#define WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED BIT(0) +#define WNM_BSS_TM_REQ_ABRIDGED BIT(1) +#define WNM_BSS_TM_REQ_DISASSOC_IMMINENT BIT(2) +#define WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED BIT(3) +#define WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT BIT(4) + +/* IEEE Std 802.11-2012 - Table 8-253 */ +enum bss_trans_mgmt_status_code { + WNM_BSS_TM_ACCEPT = 0, + WNM_BSS_TM_REJECT_UNSPECIFIED = 1, + WNM_BSS_TM_REJECT_INSUFFICIENT_BEACON = 2, + WNM_BSS_TM_REJECT_INSUFFICIENT_CAPABITY = 3, + WNM_BSS_TM_REJECT_UNDESIRED = 4, + WNM_BSS_TM_REJECT_DELAY_REQUEST = 5, + WNM_BSS_TM_REJECT_STA_CANDIDATE_LIST_PROVIDED = 6, + WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES = 7, + WNM_BSS_TM_REJECT_LEAVING_ESS = 8 +}; + +/* + * IEEE P802.11-REVmc/D5.0 Table 9-150 - Optional subelement IDs for + * neighbor report + */ +#define WNM_NEIGHBOR_TSF 1 +#define WNM_NEIGHBOR_CONDENSED_COUNTRY_STRING 2 +#define WNM_NEIGHBOR_BSS_TRANSITION_CANDIDATE 3 +#define WNM_NEIGHBOR_BSS_TERMINATION_DURATION 4 +#define WNM_NEIGHBOR_BEARING 5 +#define WNM_NEIGHBOR_WIDE_BW_CHAN 6 +#define WNM_NEIGHBOR_MEASUREMENT_REPORT 39 +#define WNM_NEIGHBOR_HT_CAPAB 45 +#define WNM_NEIGHBOR_HT_OPER 61 +#define WNM_NEIGHBOR_SEC_CHAN_OFFSET 62 +#define WNM_NEIGHBOR_MEASUREMENT_PILOT 66 +#define WNM_NEIGHBOR_RRM_ENABLED_CAPABILITIES 70 +#define WNM_NEIGHBOR_MULTIPLE_BSSID 71 +#define WNM_NEIGHBOR_VHT_CAPAB 191 +#define WNM_NEIGHBOR_VHT_OPER 192 + +/* QoS action */ +enum qos_action { + QOS_ADDTS_REQ = 0, + QOS_ADDTS_RESP = 1, + QOS_DELTS = 2, + QOS_SCHEDULE = 3, + QOS_QOS_MAP_CONFIG = 4, +}; + +/* IEEE Std 802.11-2012, 8.4.2.62 20/40 BSS Coexistence element */ +#define WLAN_20_40_BSS_COEX_INFO_REQ BIT(0) +#define WLAN_20_40_BSS_COEX_40MHZ_INTOL BIT(1) +#define WLAN_20_40_BSS_COEX_20MHZ_WIDTH_REQ BIT(2) +#define WLAN_20_40_BSS_COEX_OBSS_EXEMPT_REQ BIT(3) +#define WLAN_20_40_BSS_COEX_OBSS_EXEMPT_GRNT BIT(4) + +struct ieee80211_2040_bss_coex_ie { + u8 element_id; + u8 length; + u8 coex_param; +} STRUCT_PACKED; + +struct ieee80211_2040_intol_chan_report { + u8 element_id; + u8 length; + u8 op_class; + u8 variable[0]; /* Channel List */ +} STRUCT_PACKED; + +/* IEEE 802.11v - WNM-Sleep Mode element */ +struct wnm_sleep_element { + u8 eid; /* WLAN_EID_WNMSLEEP */ + u8 len; + u8 action_type; /* WNM_SLEEP_ENTER/WNM_SLEEP_MODE_EXIT */ + u8 status; + le16 intval; +} STRUCT_PACKED; + +#define WNM_SLEEP_MODE_ENTER 0 +#define WNM_SLEEP_MODE_EXIT 1 + +enum wnm_sleep_mode_response_status { + WNM_STATUS_SLEEP_ACCEPT = 0, + WNM_STATUS_SLEEP_EXIT_ACCEPT_GTK_UPDATE = 1, + WNM_STATUS_DENIED_ACTION = 2, + WNM_STATUS_DENIED_TMP = 3, + WNM_STATUS_DENIED_KEY = 4, + WNM_STATUS_DENIED_OTHER_WNM_SERVICE = 5 +}; + +/* WNM-Sleep Mode subelement IDs */ +enum wnm_sleep_mode_subelement_id { + WNM_SLEEP_SUBELEM_GTK = 0, + WNM_SLEEP_SUBELEM_IGTK = 1 +}; + +/* Channel Switch modes (802.11h) */ +#define CHAN_SWITCH_MODE_ALLOW_TX 0 +#define CHAN_SWITCH_MODE_BLOCK_TX 1 + +struct tpc_report { + u8 eid; + u8 len; + u8 tx_power; + u8 link_margin; +} STRUCT_PACKED; + +#define RRM_CAPABILITIES_IE_LEN 5 + +/* IEEE Std 802.11-2012, 8.5.7.4 - Link Measurement Request frame format */ +struct rrm_link_measurement_request { + u8 dialog_token; + s8 tx_power; + s8 max_tp; + u8 variable[0]; +} STRUCT_PACKED; + +/* IEEE Std 802.11-2012, 8.5.7.5 - Link Measurement Report frame format */ +struct rrm_link_measurement_report { + u8 dialog_token; + struct tpc_report tpc; + u8 rx_ant_id; + u8 tx_ant_id; + u8 rcpi; + u8 rsni; + u8 variable[0]; +} STRUCT_PACKED; + +/* IEEE Std 802.11-2016, 9.4.2.21 - Measurement Request element */ +struct rrm_measurement_request_element { + u8 eid; /* Element ID */ + u8 len; /* Length */ + u8 token; /* Measurement Token */ + u8 mode; /* Measurement Request Mode */ + u8 type; /* Measurement Type */ + u8 variable[0]; /* Measurement Request */ +} STRUCT_PACKED; + +/* IEEE Std 802.11-2016, Figure 9-148 - Measurement Request Mode field */ +#define MEASUREMENT_REQUEST_MODE_PARALLEL BIT(0) +#define MEASUREMENT_REQUEST_MODE_ENABLE BIT(1) +#define MEASUREMENT_REQUEST_MODE_REQUEST BIT(2) +#define MEASUREMENT_REQUEST_MODE_REPORT BIT(3) +#define MEASUREMENT_REQUEST_MODE_DURATION_MANDATORY BIT(4) + +/* IEEE Std 802.11-2016, 9.4.2.21.7 - Beacon request */ +struct rrm_measurement_beacon_request { + u8 oper_class; /* Operating Class */ + u8 channel; /* Channel Number */ + le16 rand_interval; /* Randomization Interval (in TUs) */ + le16 duration; /* Measurement Duration (in TUs) */ + u8 mode; /* Measurement Mode */ + u8 bssid[ETH_ALEN]; /* BSSID */ + u8 variable[0]; /* Optional Subelements */ +} STRUCT_PACKED; + +/* + * IEEE Std 802.11-2016, Table 9-87 - Measurement Mode definitions for Beacon + * request + */ +enum beacon_report_mode { + BEACON_REPORT_MODE_PASSIVE = 0, + BEACON_REPORT_MODE_ACTIVE = 1, + BEACON_REPORT_MODE_TABLE = 2, +}; + +/* IEEE Std 802.11-2016, Table 9-88 - Beacon Request subelement IDs */ +#define WLAN_BEACON_REQUEST_SUBELEM_SSID 0 +#define WLAN_BEACON_REQUEST_SUBELEM_INFO 1 /* Beacon Reporting */ +#define WLAN_BEACON_REQUEST_SUBELEM_DETAIL 2 /* Reporting Detail */ +#define WLAN_BEACON_REQUEST_SUBELEM_REQUEST 10 +#define WLAN_BEACON_REQUEST_SUBELEM_AP_CHANNEL 51 /* AP Channel Report */ +#define WLAN_BEACON_REQUEST_SUBELEM_VENDOR 221 + +/* + * IEEE Std 802.11-2016, Table 9-90 - Reporting Detail values + */ +enum beacon_report_detail { + /* No fixed-length fields or elements */ + BEACON_REPORT_DETAIL_NONE = 0, + /* All fixed-length fields and any requested elements in the Request + * element if present */ + BEACON_REPORT_DETAIL_REQUESTED_ONLY = 1, + /* All fixed-length fields and elements (default, used when Reporting + * Detail subelement is not included in a Beacon request) */ + BEACON_REPORT_DETAIL_ALL_FIELDS_AND_ELEMENTS = 2, +}; + +/* IEEE Std 802.11-2016, 9.4.2.22 - Measurement Report element */ +struct rrm_measurement_report_element { + u8 eid; /* Element ID */ + u8 len; /* Length */ + u8 token; /* Measurement Token */ + u8 mode; /* Measurement Report Mode */ + u8 type; /* Measurement Type */ + u8 variable[0]; /* Measurement Report */ +} STRUCT_PACKED; + +/* IEEE Std 802.11-2016, Figure 9-192 - Measurement Report Mode field */ +#define MEASUREMENT_REPORT_MODE_ACCEPT 0 +#define MEASUREMENT_REPORT_MODE_REJECT_LATE BIT(0) +#define MEASUREMENT_REPORT_MODE_REJECT_INCAPABLE BIT(1) +#define MEASUREMENT_REPORT_MODE_REJECT_REFUSED BIT(2) + +/* IEEE Std 802.11-2016, 9.4.2.22.7 - Beacon report */ +struct rrm_measurement_beacon_report { + u8 op_class; /* Operating Class */ + u8 channel; /* Channel Number */ + le64 start_time; /* Actual Measurement Start Time + * (in TSF of the BSS requesting the measurement) */ + le16 duration; /* in TUs */ + u8 report_info; /* Reported Frame Information */ + u8 rcpi; /* RCPI */ + u8 rsni; /* RSNI */ + u8 bssid[ETH_ALEN]; /* BSSID */ + u8 antenna_id; /* Antenna ID */ + le32 parent_tsf; /* Parent TSF */ + u8 variable[0]; /* Optional Subelements */ +} STRUCT_PACKED; + +/* IEEE Std 802.11-2016, Table 9-112 - Beacon report Subelement IDs */ +#define WLAN_BEACON_REPORT_SUBELEM_FRAME_BODY 1 +#define WLAN_BEACON_REPORT_SUBELEM_VENDOR 221 + +/* IEEE Std 802.11ad-2012 - Multi-band element */ +struct multi_band_ie { + u8 eid; /* WLAN_EID_MULTI_BAND */ + u8 len; + u8 mb_ctrl; + u8 band_id; + u8 op_class; + u8 chan; + u8 bssid[ETH_ALEN]; + le16 beacon_int; + u8 tsf_offs[8]; + u8 mb_connection_capability; + u8 fst_session_tmout; + /* Optional: + * STA MAC Address + * Pairwise Cipher Suite Count + * Pairwise Cipher Suite List + */ + u8 variable[0]; +} STRUCT_PACKED; + +enum mb_ctrl_sta_role { + MB_STA_ROLE_AP = 0, + MB_STA_ROLE_TDLS_STA = 1, + MB_STA_ROLE_IBSS_STA = 2, + MB_STA_ROLE_PCP = 3, + MB_STA_ROLE_NON_PCP_NON_AP = 4 +}; + +#define MB_CTRL_ROLE_MASK (BIT(0) | BIT(1) | BIT(2)) +#define MB_CTRL_ROLE(ctrl) ((u8) ((ctrl) & MB_CTRL_ROLE_MASK)) +#define MB_CTRL_STA_MAC_PRESENT ((u8) (BIT(3))) +#define MB_CTRL_PAIRWISE_CIPHER_SUITE_PRESENT ((u8) (BIT(4))) + +enum mb_band_id { + MB_BAND_ID_WIFI_2_4GHZ = 2, /* 2.4 GHz */ + MB_BAND_ID_WIFI_5GHZ = 4, /* 4.9 and 5 GHz */ + MB_BAND_ID_WIFI_60GHZ = 5, /* 60 GHz */ +}; + +#define MB_CONNECTION_CAPABILITY_AP ((u8) (BIT(0))) +#define MB_CONNECTION_CAPABILITY_PCP ((u8) (BIT(1))) +#define MB_CONNECTION_CAPABILITY_DLS ((u8) (BIT(2))) +#define MB_CONNECTION_CAPABILITY_TDLS ((u8) (BIT(3))) +#define MB_CONNECTION_CAPABILITY_IBSS ((u8) (BIT(4))) + +/* IEEE Std 802.11ad-2014 - FST Action field */ +enum fst_action { + FST_ACTION_SETUP_REQUEST = 0, + FST_ACTION_SETUP_RESPONSE = 1, + FST_ACTION_TEAR_DOWN = 2, + FST_ACTION_ACK_REQUEST = 3, + FST_ACTION_ACK_RESPONSE = 4, + FST_ACTION_ON_CHANNEL_TUNNEL = 5, +}; + +/* IEEE Std 802.11ac-2013, Annex C - dot11PHYType */ +enum phy_type { + PHY_TYPE_UNSPECIFIED = 0, + PHY_TYPE_FHSS = 1, + PHY_TYPE_DSSS = 2, + PHY_TYPE_IRBASEBAND = 3, + PHY_TYPE_OFDM = 4, + PHY_TYPE_HRDSSS = 5, + PHY_TYPE_ERP = 6, + PHY_TYPE_HT = 7, + PHY_TYPE_DMG = 8, + PHY_TYPE_VHT = 9, +}; + +/* IEEE P802.11-REVmc/D5.0, 9.4.2.37 - Neighbor Report element */ +/* BSSID Information Field */ +#define NEI_REP_BSSID_INFO_AP_NOT_REACH BIT(0) +#define NEI_REP_BSSID_INFO_AP_UNKNOWN_REACH BIT(1) +#define NEI_REP_BSSID_INFO_AP_REACHABLE (BIT(0) | BIT(1)) +#define NEI_REP_BSSID_INFO_SECURITY BIT(2) +#define NEI_REP_BSSID_INFO_KEY_SCOPE BIT(3) +#define NEI_REP_BSSID_INFO_SPECTRUM_MGMT BIT(4) +#define NEI_REP_BSSID_INFO_QOS BIT(5) +#define NEI_REP_BSSID_INFO_APSD BIT(6) +#define NEI_REP_BSSID_INFO_RM BIT(7) +#define NEI_REP_BSSID_INFO_DELAYED_BA BIT(8) +#define NEI_REP_BSSID_INFO_IMM_BA BIT(9) +#define NEI_REP_BSSID_INFO_MOBILITY_DOMAIN BIT(10) +#define NEI_REP_BSSID_INFO_HT BIT(11) +#define NEI_REP_BSSID_INFO_VHT BIT(12) +#define NEI_REP_BSSID_INFO_FTM BIT(13) + +/* + * IEEE P802.11-REVmc/D5.0 Table 9-152 - HT/VHT Operation Information + * subfields. + * Note: These definitions are not the same as other VHT_CHANWIDTH_*. + */ +enum nr_chan_width { + NR_CHAN_WIDTH_20 = 0, + NR_CHAN_WIDTH_40 = 1, + NR_CHAN_WIDTH_80 = 2, + NR_CHAN_WIDTH_160 = 3, + NR_CHAN_WIDTH_80P80 = 4, +}; + +struct ieee80211_he_capabilities { + u8 he_mac_capab_info[5]; + u8 he_phy_capab_info[9]; + u8 he_txrx_mcs_support[12]; /* TODO: 4, 8, or 12 octets */ + /* PPE Thresholds (optional) */ +} STRUCT_PACKED; + +struct ieee80211_he_operation { + u32 he_oper_params; + u8 he_mcs_nss_set[2]; + u8 vht_op_info_chwidth; + u8 vht_op_info_chan_center_freq_seg0_idx; + u8 vht_op_info_chan_center_freq_seg1_idx; + /* Followed by conditional MaxBSSID Indicator subfield (u8) */ +} STRUCT_PACKED; + +/* HE Capabilities Information defines */ +#define HE_PHYCAP_SU_BEAMFORMER_CAPAB_IDX 3 +#define HE_PHYCAP_SU_BEAMFORMER_CAPAB ((u8) BIT(7)) +#define HE_PHYCAP_SU_BEAMFORMEE_CAPAB_IDX 4 +#define HE_PHYCAP_SU_BEAMFORMEE_CAPAB ((u8) BIT(0)) +#define HE_PHYCAP_MU_BEAMFORMER_CAPAB_IDX 4 +#define HE_PHYCAP_MU_BEAMFORMER_CAPAB ((u8) BIT(1)) + +/* HE Operation defines */ +#define HE_OPERATION_BSS_COLOR_MASK ((u32) (BIT(0) | BIT(1) | \ + BIT(2) | BIT(3) | \ + BIT(4) | BIT(5))) +#define HE_OPERATION_DFLT_PE_DURATION_MASK ((u32) (BIT(6) | BIT(7) | \ + BIT(8))) +#define HE_OPERATION_DFLT_PE_DURATION_OFFSET 6 +#define HE_OPERATION_TWT_REQUIRED ((u32) BIT(9)) +#define HE_OPERATION_RTS_THRESHOLD_MASK ((u32) (BIT(10) | BIT(11) | \ + BIT(12) | BIT(13) | \ + BIT(14) | BIT(15) | \ + BIT(16) | BIT(17) | \ + BIT(18) | BIT(19))) +#define HE_OPERATION_RTS_THRESHOLD_OFFSET 10 +#define HE_OPERATION_PARTIAL_BSS_COLOR ((u32) BIT(20)) +#define HE_OPERATION_MAX_BSSID_INDICATOR_MASK ((u32) (BIT(21) | BIT(22) | \ + BIT(23) | BIT(24) | \ + BIT(25) | BIT(26) | \ + BIT(27) | BIT(28))) +#define HE_OPERATION_MAX_BSSID_INDICATOR_OFFSET 21 +#define HE_OPERATION_TX_BSSID_INDICATOR ((u32) BIT(29)) +#define HE_OPERATION_BSS_COLOR_DISABLED ((u32) BIT(30)) +#define HE_OPERATION_BSS_DUAL_BEACON ((u32) BIT(31)) + +/* DPP Public Action frame identifiers - OUI_WFA */ +#define DPP_OUI_TYPE 0x1A + +#endif /* IEEE802_11_DEFS_H */ diff --git a/wireless/wifictld/src/log.c b/wireless/wifictld/src/log.c new file mode 100644 index 0000000..0968734 --- /dev/null +++ b/wireless/wifictld/src/log.c @@ -0,0 +1,39 @@ +#include +#include +#include "log.h" + +#ifdef DEBUG +void log_debug(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} +#else + void log_debug(const char *format, ...) { + } +#endif + + +void log_verbose(const char *format, ...) { + if (!verbose) + return; + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +void log_info(const char *format, ...) { + va_list args; + va_start(args, format); + vprintf(format, args); + va_end(args); +} + +void log_error(const char *format, ...) { + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} diff --git a/wireless/wifictld/src/log.h b/wireless/wifictld/src/log.h index f1f7434..9e5846f 100644 --- a/wireless/wifictld/src/log.h +++ b/wireless/wifictld/src/log.h @@ -1,14 +1,11 @@ #ifndef __WIFICTLD_LOG_H #define __WIFICTLD_LOG_H -#ifdef DEBUG - #define DEBUG_COMPILE 1 -#else - #define DEBUG_COMPILE 0 -#endif +static int verbose = 0; -#define debug_print(fmt) \ - do { if (DEBUG_COMPILE) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ - __LINE__, __func__); } while (0) +void log_info(const char *format, ...); +void log_verbose(const char *format, ...); +void log_debug(const char *format, ...); +void log_error(const char *format, ...); #endif diff --git a/wireless/wifictld/src/temp_defs.h b/wireless/wifictld/src/temp_defs.h deleted file mode 100644 index 420b26c..0000000 --- a/wireless/wifictld/src/temp_defs.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef IEEE802_11_DEFS_H -#define IEEE802_11_DEFS_H - -//TODO showd use hostapd/../src/common/ieee802_11_defs.h - -/* Status codes (IEEE Std 802.11-2016, 9.4.1.9, Table 9-46) */ -#define WLAN_STATUS_SUCCESS 0 -#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 -#define WLAN_STATUS_TDLS_WAKEUP_ALTERNATE 2 -#define WLAN_STATUS_TDLS_WAKEUP_REJECT 3 -#define WLAN_STATUS_SECURITY_DISABLED 5 -#define WLAN_STATUS_UNACCEPTABLE_LIFETIME 6 -#define WLAN_STATUS_NOT_IN_SAME_BSS 7 -#define WLAN_STATUS_CAPS_UNSUPPORTED 10 -#define WLAN_STATUS_REASSOC_NO_ASSOC 11 -#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 -#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 -#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 -#define WLAN_STATUS_CHALLENGE_FAIL 15 -#define WLAN_STATUS_AUTH_TIMEOUT 16 -#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 -#define WLAN_STATUS_ASSOC_DENIED_RATES 18 -#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 -#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 -#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 -#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 -#define WLAN_STATUS_ASSOC_DENIED_NO_SHORT_SLOT_TIME 25 -#define WLAN_STATUS_ASSOC_DENIED_NO_HT 27 -#define WLAN_STATUS_R0KH_UNREACHABLE 28 -#define WLAN_STATUS_ASSOC_DENIED_NO_PCO 29 -#define WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY 30 -#define WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION 31 -#define WLAN_STATUS_UNSPECIFIED_QOS_FAILURE 32 -#define WLAN_STATUS_DENIED_INSUFFICIENT_BANDWIDTH 33 -#define WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS 34 -#define WLAN_STATUS_DENIED_QOS_NOT_SUPPORTED 35 -#define WLAN_STATUS_REQUEST_DECLINED 37 -#define WLAN_STATUS_INVALID_PARAMETERS 38 -#define WLAN_STATUS_REJECTED_WITH_SUGGESTED_CHANGES 39 -#define WLAN_STATUS_INVALID_IE 40 -#define WLAN_STATUS_GROUP_CIPHER_NOT_VALID 41 -#define WLAN_STATUS_PAIRWISE_CIPHER_NOT_VALID 42 -#define WLAN_STATUS_AKMP_NOT_VALID 43 -#define WLAN_STATUS_UNSUPPORTED_RSN_IE_VERSION 44 -#define WLAN_STATUS_INVALID_RSN_IE_CAPAB 45 -#define WLAN_STATUS_CIPHER_REJECTED_PER_POLICY 46 -#define WLAN_STATUS_TS_NOT_CREATED 47 -#define WLAN_STATUS_DIRECT_LINK_NOT_ALLOWED 48 -#define WLAN_STATUS_DEST_STA_NOT_PRESENT 49 -#define WLAN_STATUS_DEST_STA_NOT_QOS_STA 50 -#define WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE 51 -#define WLAN_STATUS_INVALID_FT_ACTION_FRAME_COUNT 52 -#define WLAN_STATUS_INVALID_PMKID 53 -#define WLAN_STATUS_INVALID_MDIE 54 -#define WLAN_STATUS_INVALID_FTIE 55 -#define WLAN_STATUS_REQUESTED_TCLAS_NOT_SUPPORTED 56 -#define WLAN_STATUS_INSUFFICIENT_TCLAS_PROCESSING_RESOURCES 57 -#define WLAN_STATUS_TRY_ANOTHER_BSS 58 -#define WLAN_STATUS_GAS_ADV_PROTO_NOT_SUPPORTED 59 -#define WLAN_STATUS_NO_OUTSTANDING_GAS_REQ 60 -#define WLAN_STATUS_GAS_RESP_NOT_RECEIVED 61 -#define WLAN_STATUS_STA_TIMED_OUT_WAITING_FOR_GAS_RESP 62 -#define WLAN_STATUS_GAS_RESP_LARGER_THAN_LIMIT 63 -#define WLAN_STATUS_REQ_REFUSED_HOME 64 -#define WLAN_STATUS_ADV_SRV_UNREACHABLE 65 -#define WLAN_STATUS_REQ_REFUSED_SSPN 67 -#define WLAN_STATUS_REQ_REFUSED_UNAUTH_ACCESS 68 -#define WLAN_STATUS_INVALID_RSNIE 72 -#define WLAN_STATUS_U_APSD_COEX_NOT_SUPPORTED 73 -#define WLAN_STATUS_U_APSD_COEX_MODE_NOT_SUPPORTED 74 -#define WLAN_STATUS_BAD_INTERVAL_WITH_U_APSD_COEX 75 -#define WLAN_STATUS_ANTI_CLOGGING_TOKEN_REQ 76 -#define WLAN_STATUS_FINITE_CYCLIC_GROUP_NOT_SUPPORTED 77 -#define WLAN_STATUS_CANNOT_FIND_ALT_TBTT 78 -#define WLAN_STATUS_TRANSMISSION_FAILURE 79 -#define WLAN_STATUS_REQ_TCLAS_NOT_SUPPORTED 80 -#define WLAN_STATUS_TCLAS_RESOURCES_EXCHAUSTED 81 -#define WLAN_STATUS_REJECTED_WITH_SUGGESTED_BSS_TRANSITION 82 -#define WLAN_STATUS_REJECT_WITH_SCHEDULE 83 -#define WLAN_STATUS_REJECT_NO_WAKEUP_SPECIFIED 84 -#define WLAN_STATUS_SUCCESS_POWER_SAVE_MODE 85 -#define WLAN_STATUS_PENDING_ADMITTING_FST_SESSION 86 -#define WLAN_STATUS_PERFORMING_FST_NOW 87 -#define WLAN_STATUS_PENDING_GAP_IN_BA_WINDOW 88 -#define WLAN_STATUS_REJECT_U_PID_SETTING 89 -#define WLAN_STATUS_REFUSED_EXTERNAL_REASON 92 -#define WLAN_STATUS_REFUSED_AP_OUT_OF_MEMORY 93 -#define WLAN_STATUS_REJECTED_EMERGENCY_SERVICE_NOT_SUPPORTED 94 -#define WLAN_STATUS_QUERY_RESP_OUTSTANDING 95 -#define WLAN_STATUS_REJECT_DSE_BAND 96 -#define WLAN_STATUS_TCLAS_PROCESSING_TERMINATED 97 -#define WLAN_STATUS_TS_SCHEDULE_CONFLICT 98 -#define WLAN_STATUS_DENIED_WITH_SUGGESTED_BAND_AND_CHANNEL 99 -#define WLAN_STATUS_MCCAOP_RESERVATION_CONFLICT 100 -#define WLAN_STATUS_MAF_LIMIT_EXCEEDED 101 -#define WLAN_STATUS_MCCA_TRACK_LIMIT_EXCEEDED 102 -#define WLAN_STATUS_DENIED_DUE_TO_SPECTRUM_MANAGEMENT 103 -#define WLAN_STATUS_ASSOC_DENIED_NO_VHT 104 -#define WLAN_STATUS_ENABLEMENT_DENIED 105 -#define WLAN_STATUS_RESTRICTION_FROM_AUTHORIZED_GDB 106 -#define WLAN_STATUS_AUTHORIZATION_DEENABLED 107 -#define WLAN_STATUS_FILS_AUTHENTICATION_FAILURE 112 -#define WLAN_STATUS_UNKNOWN_AUTHENTICATION_SERVER 113 - -#endif diff --git a/wireless/wifictld/src/ubus_events.c b/wireless/wifictld/src/ubus_events.c index 9ff4100..b8c72f6 100644 --- a/wireless/wifictld/src/ubus_events.c +++ b/wireless/wifictld/src/ubus_events.c @@ -1,69 +1,71 @@ #include #include #include -#include #include -#include "temp_defs.h" +#include "hostapd/ieee802_11_defs.h" // ETH_ALEN + hwaddr_aton +#include "hostapd/common.h" #include "log.h" +#include "wifi_clients.h" +#include "ubus_events.h" static struct blob_buf b; -struct ubus_context *ctx_main; - - - -static int receive_request(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) -{ - const char *attr_name, *addr; - uint16_t freq, ssi_signal = -1; - struct blob_attr *pos; - int rem = blobmsg_data_len(msg); - - // read msg - blobmsg_for_each_attr(pos, msg, rem) { - attr_name = blobmsg_name(pos); - - if (!strcmp(attr_name, "address")){ - addr = blobmsg_get_string(pos); - } else if(!strcmp(attr_name, "signal")){ - ssi_signal = blobmsg_get_u32(pos); - } else if(!strcmp(attr_name, "freq")){ - freq = blobmsg_get_u32(pos); - } - } - - /* - blob_buf_init(&b, 0); - blob_put_u32(&b, 0, WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA); - ubus_send_reply(ctx, req, b.head); - */ - - if (!strcmp(method, "probe")) { - ULOG_NOTE("probe\n"); - return WLAN_STATUS_SUCCESS; - } - if (!strcmp(method, "auth")) { - if (freq <= 5000) { - ULOG_WARN("auth [drop]-> %s\n", addr); - return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; - } - ULOG_WARN("auth [accept]-> %s\n", addr); - } - - // learn by freq and address - - ULOG_INFO("%s\n", method); - return WLAN_STATUS_SUCCESS; -} +static struct ubus_context *ctx_main; +// bind on every hostapd by receive all ubus registered services +static void recieve_interfaces(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv); +/** + * handle every notify sended by hostapd + * (and allow or deny client auth) + */ +static int receive_notify(struct ubus_context *ctx, struct ubus_object *obj, + struct ubus_request_data *req, const char *method, struct blob_attr *msg); +// subscriber handler with callback to handle notifies from hostapd struct ubus_subscriber sub = { - .cb = receive_request, + .cb = receive_notify, }; +/** + * init ubus connection and request for all registered hostapd instances + * (start everthing need and add themselve to uloop) + */ +int wifictld_ubus_init() +{ + int ret = 0; -void wifictld_ubus_interfaces(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv) + // connect to ubus + ctx_main = ubus_connect(NULL); + if (!ctx_main) { + log_error("Failed to connect to ubus"); + return 1; + } + + // register subscriber on ubus + ret = ubus_register_subscriber(ctx_main, &sub); + if (ret) { + log_error("Error while registering subscriber: %s", ubus_strerror(ret)); + ubus_free(ctx_main); + return 2; + } + + // request for all ubus services + ubus_lookup(ctx_main, NULL, recieve_interfaces, NULL); + + // add to uloop + ubus_add_uloop(ctx_main); + + return 0; +} + +// close ubus connection +void wifictld_ubus_close() +{ + ubus_free(ctx_main); +} + +static void recieve_interfaces(struct ubus_context *ctx, struct ubus_object_data *obj, void *priv) { int ret = 0; const char *str = "notify_response"; @@ -72,49 +74,63 @@ void wifictld_ubus_interfaces(struct ubus_context *ctx, struct ubus_object_data return; } - //switch to notify + //change hostapd to wait for response blob_buf_init(&b, 0); blobmsg_add_u32(&b, str, 1); ret = ubus_invoke(ctx, obj->id, str, b.head, NULL, NULL, 100); if (ret) { - ULOG_ERR("Error while register response for event '%s': %s\n", obj->path, ubus_strerror(ret)); + log_error("Error while register response for event '%s': %s\n", obj->path, ubus_strerror(ret)); } - //subscribe + //subscribe hostapd with THIS interface ret = ubus_subscribe(ctx, &sub, obj->id); if (ret) { - ULOG_ERR("Error while register subscribe for event '%s': %s\n", obj->path, ubus_strerror(ret)); + log_error("Error while register subscribe for event '%s': %s\n", obj->path, ubus_strerror(ret)); } - printf("sub %s: %d:%d\n", obj->path, obj->id, obj->type_id); + log_info("sub %s: %d:%d\n", obj->path, obj->id, obj->type_id); } -int wifictld_ubus_init() + +static int receive_notify(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg) { - int ret = 0; + const char *attr_name, *str; + u8 addr[ETH_ALEN]; + uint32_t freq, ssi_signal = -1; + struct blob_attr *pos; + int rem = blobmsg_data_len(msg); - ctx_main = ubus_connect(NULL); - if (!ctx_main) { - ULOG_ERR("Failed to connect to ubus"); - return 1; + // read msg + blobmsg_for_each_attr(pos, msg, rem) { + attr_name = blobmsg_name(pos); + + if (!strcmp(attr_name, "address")){ + str = blobmsg_get_string(pos); + hwaddr_aton(str, addr); + } else if(!strcmp(attr_name, "signal")){ + ssi_signal = blobmsg_get_u32(pos); + } else if(!strcmp(attr_name, "freq")){ + freq = blobmsg_get_u32(pos); + } } - ret = ubus_register_subscriber(ctx_main, &sub); - if (ret) { - ULOG_ERR("Error while registering subscriber: %s", ubus_strerror(ret)); - ubus_free(ctx_main); - return 2; + // handle + + if (!strcmp(method, "probe")) { + log_verbose("probe\n"); + if (client_probe_learning) + wifi_clients_learn(addr, freq); + return WLAN_STATUS_SUCCESS; + } + if (!strcmp(method, "auth")) { + if (!wifi_clients_try(addr, freq)) { + log_info("auth [drop]-> %s\n", addr); + return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; + } + log_info("auth [accept]-> %s\n", addr); + } else { + log_verbose("%s\n", method); } - ubus_lookup(ctx_main, NULL, wifictld_ubus_interfaces, NULL); - - ubus_add_uloop(ctx_main); - - return 0; -} - - -void wifictld_ubus_close() -{ - ubus_free(ctx_main); + return WLAN_STATUS_SUCCESS; } diff --git a/wireless/wifictld/src/ubus_events.h b/wireless/wifictld/src/ubus_events.h index 9a31206..8fbc4d9 100644 --- a/wireless/wifictld/src/ubus_events.h +++ b/wireless/wifictld/src/ubus_events.h @@ -1,7 +1,7 @@ #ifndef __WIFICTLD_UBUS_EVENT_H #define __WIFICTLD_UBUS_EVENT_H -#include +static int client_probe_learning = 0; int wifictld_ubus_init(); void wifictld_ubus_close(); diff --git a/wireless/wifictld/src/wifi_clients.c b/wireless/wifictld/src/wifi_clients.c new file mode 100644 index 0000000..346958d --- /dev/null +++ b/wireless/wifictld/src/wifi_clients.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include "hostapd/ieee802_11_defs.h" // ETH_ALEN +#include "wifi_clients.h" + +static void wifi_clients_del(const u8 *addr); + +static struct avl_tree clients_by_addr; + +struct wifi_client { + struct avl_node avl; + u8 addr[ETH_ALEN]; + int time; + int try; + uint32_t highfreq; +}; + +int wifi_clients_init() { + return 0; +} + +void wifi_clients_close() { + +} + +struct wifi_client *__get_client(const u8 *addr){ + struct wifi_client *client; + + client = avl_find_element(&clients_by_addr, addr, client, avl); + if (client) + return client; + client = malloc(sizeof(*client)); + memcpy(client->addr, addr, sizeof(client->addr)); + client->highfreq = 0; + client->try = 0; + client->time = 0; + client->avl.key = client->addr; + avl_insert(&clients_by_addr, &client->avl); + return client; +} + +void __client_learn(struct wifi_client *client, uint32_t freq) { + if (client->highfreq < freq) { + client->highfreq = freq; + } + //TODO time set and reset clean +} + +void wifi_clients_learn(const u8 *address, uint32_t freq) { + struct wifi_client *client; + client = __get_client(address); + __client_learn(client, freq); +} + +int wifi_clients_try(const u8 *address, uint32_t freq) { + struct wifi_client *client; + client = __get_client(address); + __client_learn(client, freq); + + if (freq > 5000) { + client->try = 0; + } else { + if(client->try > client_freq_try_threashold) { + return 0; + } + client->try++; + } + + return client->try; +} + + +static void wifi_clients_del(const u8 *addr) { + struct wifi_client *client; + + client = avl_find_element(&clients_by_addr, addr, client, avl); + if (!client) + return; + + avl_delete(&clients_by_addr, &client->avl); + free(client); +} diff --git a/wireless/wifictld/src/wifi_clients.h b/wireless/wifictld/src/wifi_clients.h new file mode 100644 index 0000000..9801e26 --- /dev/null +++ b/wireless/wifictld/src/wifi_clients.h @@ -0,0 +1,14 @@ +#ifndef __WIFICTLD_WIFI_CLIENTS_H +#define __WIFICTLD_WIFI_CLIENTS_H + +#include + +static int client_freq_try_threashold = 3; + +int wifi_clients_init(); +void wifi_clients_close(); + +void wifi_clients_learn(const uint8_t *address, uint32_t freq); +int wifi_clients_try(const uint8_t *address, uint32_t freq); + +#endif diff --git a/wireless/wifictld/src/wifictld.c b/wireless/wifictld/src/wifictld.c index a64b114..b51d658 100644 --- a/wireless/wifictld/src/wifictld.c +++ b/wireless/wifictld/src/wifictld.c @@ -1,31 +1,40 @@ -#include -#include -#include +#include +#include "log.h" +#include "wifi_clients.h" #include "ubus_events.h" int main(void) { + verbose = 1; + client_probe_learning = 1; int ret = 0; #ifdef MINI - ULOG_NOTE("start wifictld (mini)\n"); + log_error("start wifictld (mini)\n"); #else - ULOG_NOTE("start wifictld (full)\n"); + log_error("start wifictld (full)\n"); #endif uloop_init(); - //bind to loop - ret = wifictld_ubus_init(); - + // define wifi clients memory + ret = wifi_clients_init(); if (ret) { return ret; } + // bind to loop + ret = wifictld_ubus_init(); + if (ret) + { + wifi_clients_close(); + return ret; + } uloop_run(); uloop_done(); wifictld_ubus_close(); + wifi_clients_close(); return 0; }