diff options
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | Makefile.in | 11 | ||||
-rw-r--r-- | README | 47 | ||||
-rw-r--r-- | README.md | 53 | ||||
-rw-r--r-- | about_scr.c | 3 | ||||
-rw-r--r-- | aclocal.m4 | 173 | ||||
-rw-r--r-- | conf.c | 264 | ||||
-rw-r--r-- | conf_scr.c | 2 | ||||
-rwxr-xr-x | configure | 324 | ||||
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | ieee80211.h | 61 | ||||
-rw-r--r-- | info_scr.c | 434 | ||||
-rw-r--r-- | iw_if.c | 367 | ||||
-rw-r--r-- | iw_if.h | 234 | ||||
-rw-r--r-- | iw_nl80211.c | 730 | ||||
-rw-r--r-- | iw_nl80211.h | 271 | ||||
-rw-r--r-- | iw_scan.c | 959 | ||||
-rw-r--r-- | lhist_scr.c | 31 | ||||
-rw-r--r-- | nl80211.h | 4588 | ||||
-rw-r--r-- | scan_scr.c | 78 | ||||
-rw-r--r-- | ui.c | 4 | ||||
-rw-r--r-- | utils.c | 261 | ||||
-rw-r--r-- | wavemon.1 | 20 | ||||
-rw-r--r-- | wavemon.h | 20 | ||||
-rw-r--r-- | wavemonrc.5 | 22 |
25 files changed, 7336 insertions, 1642 deletions
@@ -1,4 +1,4 @@ ChangeLog: Since version 0.5, wavemon is maintained as a git tree where all changes can be tracked in detail, found at - http://eden-feed.erg.abdn.ac.uk/wavemon + https://github.com/uoaerg/wavemon diff --git a/Makefile.in b/Makefile.in index 0b27ad7..d2e1c01 100644 --- a/Makefile.in +++ b/Makefile.in @@ -9,23 +9,24 @@ exec_perms = 0755 install-suid-root: exec_perms = 4755 CC ?= @CC@ -CFLAGS ?= @CFLAGS@ +CFLAGS ?= @CFLAGS@ @LIBNL3_CFLAGS@ CPPFLAGS ?= @CPPFLAGS@ LDFLAGS ?= @LDFLAGS@ DEFS ?= @DEFS@ -LDLIBS ?= @LIBS@ +LDLIBS ?= @LIBS@ @LIBNL3_LIBS@ INSTALL = @INSTALL@ RM = rm -vf MAIN = @PACKAGE_NAME@.c -HEADERS = @PACKAGE_NAME@.h llist.h iw_if.h +HEADERS = $(wildcard *.h) PURESRC = $(filter-out $(MAIN),$(wildcard *.c)) OBJS = $(PURESRC:.c=.o) -DOCS = README NEWS THANKS AUTHORS COPYING ChangeLog +DOCS = README.md NEWS THANKS AUTHORS COPYING ChangeLog %.o: %.c $(HEADERS) - $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(DEFS) -c -o $@ $< + @echo ' CC ' $< + @$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(DEFS) -c -o $@ $< all: @PACKAGE_NAME@ @PACKAGE_NAME@: $(MAIN) $(OBJS) @@ -1,47 +0,0 @@ -1) Synopsis ------------ - -wavemon is a wireless device monitoring application that allows you to watch -signal and noise levels, packet statistics, device configuration and network -parameters of your wireless network hardware. It should work (though with -varying features) with all devices supported by the Linux wireless kernel -extensions by Jean Tourrilhes. - -See the man page for an in-depth description of operation and configuration. - - -2) Where to obtain ------------------- -Apart from debian/ubuntu packages (apt-cache search wavemon) and slackbuild -scripts for wavemon on slackbuilds.org, up-to-date sources are available at - - http://www.erg.abdn.ac.uk/ergcms/wavemon/ - -Please check this page for updates and for further information. -wavemon is distributed under the GPLv3, refer to the file COPYING. - - -3) How to build ---------------- -wavemon uses autoconf, so that in most cases you can simply run - - ./configure - make - sudo make install - -to build and install the package. Type 'make uninstall' if not happy. -Refer to the file INSTALL for generic installation instructions. - -To grant users access to restricted networking operations (e.g. reading WEP -keys or performing scan operations), use additionally - - sudo make install-suid-root - -If you have changed some of the autoconf files or use a git version, run - ./config/bootstrap -(requires a recent installation of 'autotools'). - - -3) Bugs? --------- -Send bug reports, comments, and suggestions to <gerrit@erg.abdn.ac.uk>. diff --git a/README.md b/README.md new file mode 100644 index 0000000..637f639 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +![wavemon screenshot](https://cloud.githubusercontent.com/assets/5132989/8640926/1f8436a0-28c6-11e5-9336-a79fd002c324.png) + +## Synopsis + +wavemon is a wireless device monitoring application that allows you to watch +signal and noise levels, packet statistics, device configuration and network +parameters of your wireless network hardware. It should work (though with +varying features) with all devices supported by the Linux kernel. + +See the man page for an in-depth description of operation and configuration. + + +### Where to obtain + +Apart from debian/ubuntu packages (apt-cache search wavemon) and slackbuild +scripts for wavemon on slackbuilds.org, this repository contains the full +source code. + +Please check this page for updates and for further information. +wavemon is distributed under the [GPLv3](http://www.gnu.org/licenses/gpl-3.0.en.html), refer to the file `COPYING`. + + +## How to build + +wavemon uses `autoconf`, so that in most cases you can simply run +``` + ./configure + make + sudo make install +``` +to build and install the package. Type 'make uninstall' if not happy. +Refer to the file `INSTALL` for generic installation instructions. + +**Dependencies**: at least version 3.2 of `libnl`, including the Generic Netlink support (`libnl-genl`). +On Debian/Ubuntu, this can be done using +```bash + apt-get -y install libnl-3-dev libnl-genl-3-dev +``` + +To grant users access to restricted networking operations (scan operations), use additionally +``` + sudo make install-suid-root +``` +If you have changed some of the autoconf files or use a git version, run +``` + ./config/bootstrap +``` +(requires a recent installation of `autotools`). + + +## Bugs? + +Send bug reports, comments, and suggestions by opening an issue on [github](https://github.com/uoaerg/wavemon/issues). diff --git a/about_scr.c b/about_scr.c index 31ac37b..fb4c080 100644 --- a/about_scr.c +++ b/about_scr.c @@ -29,9 +29,6 @@ static char *about_lines[] = { "original by jan morgenstern <jan@jm-music.de>", "distributed under the GNU general public license v3", "", - "wavemon uses the wireless extensions by", - "jean tourrilhes <jt@hpl.hp.com>", - "", "please send suggestions and bug reports to ", PACKAGE_BUGREPORT, "", diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..3ab5298 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,173 @@ +# generated automatically by aclocal 1.11.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 1 (pkg-config-0.24) +# +# Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# PKG_PROG_PKG_CONFIG([MIN-VERSION]) +# ---------------------------------- +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])# PKG_PROG_PKG_CONFIG + +# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# +# Check to see whether a particular set of modules exists. Similar +# to PKG_CHECK_MODULES(), but does not set variables or print errors. +# +# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +# only at the first occurence in configure.ac, so if the first place +# it's called might be skipped (such as if it is within an "if", you +# have to call PKG_CHECK_EXISTS manually +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +# --------------------------------------------- +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])# _PKG_CONFIG + +# _PKG_SHORT_ERRORS_SUPPORTED +# ----------------------------- +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])# _PKG_SHORT_ERRORS_SUPPORTED + + +# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +# [ACTION-IF-NOT-FOUND]) +# +# +# Note that if there is a possibility the first call to +# PKG_CHECK_MODULES might not happen, you should be sure to include an +# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +# +# +# -------------------------------------------------------------- +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])# PKG_CHECK_MODULES + @@ -22,7 +22,8 @@ #include <sys/types.h> /* GLOBALS */ -static char **if_list; /* array of WiFi interface names */ +#define MAX_IFLIST_ENTRIES 64 +static char *if_list[MAX_IFLIST_ENTRIES]; /* array of WiFi interface names */ int conf_items; /* index into array storing menu items */ static char *on_off_names[] = { [false] = "Off", [true] = "On", NULL }; @@ -37,6 +38,7 @@ static char *action_items[] = { static char *sort_order[] = { [SO_CHAN] = "Channel", [SO_SIGNAL] = "Signal", + [SO_MAC] = "MAC", [SO_ESSID] = "Essid", [SO_OPEN] = "Open", [SO_CHAN_SIG] = "Chan/Sig", @@ -62,12 +64,11 @@ struct wavemon_conf conf = { .check_geometry = false, .cisco_mac = false, .override_bounds = false, - .random = false, - .sig_min = -102, - .sig_max = 10, - .noise_min = -102, - .noise_max = 10, + .sig_min = -100, + .sig_max = -10, + .noise_min = -120, + .noise_max = -40, .scan_sort_order = SO_CHAN_SIG, .scan_sort_asc = false, @@ -80,22 +81,20 @@ struct wavemon_conf conf = { }; /** Populate interface list */ -void conf_get_interface_list(bool init) +void conf_get_interface_list(void) { char *old_if = NULL; int idx; - if (if_list) { - for (idx = 0; if_list[idx]; idx++) - if (idx == conf.if_idx) - old_if = if_list[idx]; - else - free(if_list[idx]); - free(if_list); + for (idx = 0; if_list[idx]; idx++) { + if (idx == conf.if_idx) + old_if = if_list[idx]; + else + free(if_list[idx]); } - if_list = iw_get_interface_list(); - if (if_list == NULL && !init) - err_quit("no wireless interfaces found!"); + iw_get_interface_list(if_list, MAX_IFLIST_ENTRIES); + if (!if_list[0]) + err_quit("no supported wireless interfaces found!"); conf.if_idx = 0; if (old_if) { @@ -109,7 +108,7 @@ void conf_get_interface_list(bool init) /** Return currently selected interface name */ const char *conf_ifname(void) { - return if_list ? if_list[conf.if_idx] : "(none)"; + return if_list[0] && if_list[conf.if_idx] ? if_list[conf.if_idx] : "(none)"; } /* Return full path of rcfile. Allocates string which must bee free()-d. */ @@ -130,6 +129,77 @@ static char *get_confname(void) return full_path; } +static void write_cf(void) +{ + char tmp[0x100], rv[0x40]; + struct conf_item *ci = NULL; + char *lp, *cp; + int add, i; + char *cfname = get_confname(); + int cfld = ll_create(); + FILE *fd = fopen(cfname, "w"); + + if (fd == NULL) + err_sys("failed to open configuration file '%s'", cfname); + + for (ll_reset(conf_items); (ci = ll_getall(conf_items)); ) { + if (ci->type != t_sep && ci->type != t_func && + (!ci->dep || (ci->dep && *ci->dep))) { + switch (ci->type) { + case t_int: + sprintf(rv, "%d", *ci->v.i); + break; + case t_list: + if (!argv_count(ci->list)) + continue; + sprintf(rv, "%s", ci->list[*ci->v.i]); + str_tolower(rv); + break; + case t_sep: + case t_func: + break; + } + + add = 1; + + for (i = 0; i < ll_size(cfld); i++) { + lp = ll_get(cfld, i); + cp = lp += strspn(lp, " "); + if (!strncasecmp(cp, ci->cfname, strcspn(cp, " =")) + && strlen(ci->cfname) == strcspn(cp, " =")) { + add = 0; + cp += strcspn(cp, "=") + 1; + cp += strspn(cp, " "); + strncpy(tmp, cp, strcspn(cp, " #\n")); + if (strcasecmp(tmp, rv)) { + strncpy(tmp, lp, strcspn(lp, " =")); + tmp[strcspn(lp, " =")] = '\0'; + strcat(tmp, " = "); + strcat(tmp, rv); + strcat(tmp, "\n"); + ll_replace(cfld, i, "s", tmp); + } + } + } + + if (add) { + strcpy(tmp, ci->cfname); + strcat(tmp, " = "); + strcat(tmp, rv); + strcat(tmp, "\n"); + ll_push(cfld, "s", tmp); + } + } + } + + for (ll_reset(cfld); (lp = ll_getall(cfld)); ) + fputs(lp, fd); + fclose(fd); + + ll_destroy(cfld); + free(cfname); +} + static void read_cf(void) { char tmp[0x100], lv[0x20], rv[0x20]; @@ -138,6 +208,7 @@ static void read_cf(void) size_t len; int lnum, found, v_int; char *lp, *conv_err; + bool file_needs_update = false; char *cfname = get_confname(); if (access(cfname, F_OK) != 0) @@ -148,7 +219,6 @@ static void read_cf(void) err_sys("can not read configuration file '%s'", cfname); for (lnum = 1; fgets(tmp, sizeof(tmp), fd); lnum++) { - lp = tmp + strspn(tmp, " "); if (*lp == '#' || *lp == '\n') continue; @@ -168,6 +238,7 @@ static void read_cf(void) if (!found) { err_msg("%s, line %d: ignoring unknown identifier '%s'", cfname, lnum, lv); + file_needs_update = true; continue; } @@ -192,110 +263,43 @@ static void read_cf(void) err_quit("parse error in %s, line %d: integer value expected, '%s' found instead", cfname, lnum, rv); } else if (v_int > ci->max) { - err_quit("parse error in %s, line %d: value exceeds maximum of %d", + err_msg("%s, line %d: value exceeds maximum of %d - using maximum", cfname, lnum, (int)ci->max); + *ci->v.i = ci->max; + file_needs_update = true; } else if (v_int < ci->min) { - err_quit("parse error in %s, line %d: value is below minimum of %d", + err_msg("%s, line %d: value is below minimum of %d - using minimum", cfname, lnum, (int)ci->min); + *ci->v.i = ci->min; + file_needs_update = true; } else { *ci->v.i = v_int; } break; case t_list: - v_int = ci->list ? argv_find(ci->list, rv) : -1; - if (v_int < 0) + assert(ci->list != NULL); + if (!argv_count(ci->list)) + err_quit("no usable %s candidates available for '%s'", ci->name, rv); + v_int = argv_find(ci->list, rv); + if (v_int < 0) { err_msg("%s, line %d: '%s = %s' is not valid - using defaults", cfname, lnum, lv, rv); - else + file_needs_update = true; + } else { *ci->v.i = v_int; - case t_sep: /* These two cases are missing from the enum, they are not handled */ - case t_func: /* To pacify gcc -Wall, fall through here */ + } + case t_sep: + case t_func: break; } } fclose(fd); done: free(cfname); -} -static void write_cf(void) -{ - char tmp[0x100], rv[0x40]; - struct conf_item *ci = NULL; - char *lp, *cp; - int add, i; - FILE *fd; - char *cfname = get_confname(); - int cfld = ll_create(); - - if (access(cfname, F_OK) == 0) { - fd = fopen(cfname, "r"); - if (fd == NULL) - err_sys("can not read configuration file '%s'", cfname); - while (fgets(tmp, sizeof(tmp), fd)) - ll_push(cfld, "s", tmp); - fclose(fd); + if (file_needs_update) { + write_cf(); } - - for (ll_reset(conf_items); (ci = ll_getall(conf_items)); ) { - if (ci->type != t_sep && ci->type != t_func && - (!ci->dep || (ci->dep && *ci->dep))) { - switch (ci->type) { - case t_int: - sprintf(rv, "%d", *ci->v.i); - break; - case t_list: - sprintf(rv, "%s", ci->list[*ci->v.i]); - str_tolower(rv); - break; - /* Fall through, the rest are dummy statements to pacify gcc -Wall */ - case t_sep: - case t_func: - break; - } - - add = 1; - - for (i = 0; i < ll_size(cfld); i++) { - lp = ll_get(cfld, i); - cp = lp += strspn(lp, " "); - if (!strncasecmp(cp, ci->cfname, strcspn(cp, " =")) - && strlen(ci->cfname) == strcspn(cp, " =")) { - add = 0; - cp += strcspn(cp, "=") + 1; - cp += strspn(cp, " "); - strncpy(tmp, cp, strcspn(cp, " #\n")); - if (strcasecmp(tmp, rv)) { - strncpy(tmp, lp, strcspn(lp, " =")); - tmp[strcspn(lp, " =")] = '\0'; - strcat(tmp, " = "); - strcat(tmp, rv); - strcat(tmp, "\n"); - ll_replace(cfld, i, "s", tmp); - } - } - } - - if (add) { - strcpy(tmp, ci->cfname); - strcat(tmp, " = "); - strcat(tmp, rv); - strcat(tmp, "\n"); - ll_push(cfld, "s", tmp); - } - } - } - - fd = fopen(cfname, "w"); - if (fd == NULL) - err_sys("can not write to configuration file '%s'", cfname); - - for (ll_reset(cfld); (lp = ll_getall(cfld)); ) - fputs(lp, fd); - fclose(fd); - - ll_destroy(cfld); - free(cfname); } static void init_conf_items(void) @@ -407,8 +411,8 @@ static void init_conf_items(void) item->cfname = strdup("min_signal_level"); item->type = t_int; item->v.i = &conf.sig_min; - item->min = -128; - item->max = -60; + item->min = -100; + item->max = -39; item->inc = 1; item->unit = strdup("dBm"); item->dep = &conf.override_bounds; @@ -419,8 +423,8 @@ static void init_conf_items(void) item->cfname = strdup("max_signal_level"); item->type = t_int; item->v.i = &conf.sig_max; - item->min = -59; - item->max = 120; + item->min = -40; + item->max = -10; item->inc = 1; item->unit = strdup("dBm"); item->dep = &conf.override_bounds; @@ -431,8 +435,8 @@ static void init_conf_items(void) item->cfname = strdup("min_noise_level"); item->type = t_int; item->v.i = &conf.noise_min; - item->min = -128; - item->max = -60; + item->min = -120; + item->max = -70; item->inc = 1; item->unit = strdup("dBm"); item->dep = &conf.override_bounds; @@ -443,21 +447,13 @@ static void init_conf_items(void) item->cfname = strdup("max_noise_level"); item->type = t_int; item->v.i = &conf.noise_max; - item->min = -60; - item->max = 120; + item->min = -69; + item->max = -40; item->inc = 1; item->unit = strdup("dBm"); item->dep = &conf.override_bounds; ll_push(conf_items, "*", item); - item = calloc(1, sizeof(*item)); - item->name = strdup("Random signals"); - item->cfname = strdup("random"); - item->type = t_list; - item->v.i = &conf.random; - item->list = on_off_names; - ll_push(conf_items, "*", item); - /* thresholds */ item = calloc(1, sizeof(*item)); item->name = strdup("Low threshold action"); @@ -532,18 +528,14 @@ static void init_conf_items(void) void getconf(int argc, char *argv[]) { - int arg, dump = 0, help = 0, version = 0; + int arg, help = 0, version = 0; - conf_get_interface_list(true); + conf_get_interface_list(); init_conf_items(); read_cf(); - while ((arg = getopt(argc, argv, "dghi:rv")) >= 0) { + while ((arg = getopt(argc, argv, "ghi:v")) >= 0) { switch (arg) { - case 'd': - if (if_list) - dump++; - break; case 'g': conf.check_geometry = true; break; @@ -551,42 +543,32 @@ void getconf(int argc, char *argv[]) help++; break; case 'i': - conf.if_idx = if_list ? argv_find(if_list, optarg) : -1; + conf.if_idx = argv_find(if_list, optarg); if (conf.if_idx < 0) err_quit("no wireless extensions found on '%s'", optarg); break; - case 'r': - conf.random = true; - break; case 'v': version++; break; default: - /* bad argument. bad bad */ exit(EXIT_FAILURE); } } if (version) { printf("wavemon %s", PACKAGE_VERSION); - printf(" with %s and %s.\n", we_version(), curses_version()); + printf(" with %s.\n", curses_version()); printf("Distributed under the terms of the GPLv3.\n%s", help ? "\n" : ""); } if (help) { - printf("usage: wavemon [ -dhlrv ] [ -i ifname ]\n"); - printf(" -d Dump the current device status to stdout and exit\n"); + printf("usage: wavemon [ -hgv ] [ -i ifname ]\n"); printf(" -g Ensure screen is sufficiently dimensioned\n"); printf(" -h This help screen\n"); printf(" -i <ifname> Use specified network interface (default: auto)\n"); - printf(" -r Generate random levels (for testing purposes)\n"); printf(" -v Print version number\n"); - } else if (dump) { - dump_parameters(); } - if (version || help || dump) + if (version || help) exit(EXIT_SUCCESS); - else if (if_list == NULL) - err_quit("no supported wireless interfaces found"); } @@ -159,7 +159,7 @@ static int m_pref(WINDOW *w_conf, int list_offset, int active_item, int num_item void scr_conf_init(void) { struct conf_item *item; - conf_get_interface_list(false); /* may have changed in the meantime */ + conf_get_interface_list(); /* may have changed in the meantime */ num_items = ll_size(conf_items); w_conf = newwin_title(0, WAV_HEIGHT, "Preferences", false); @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for wavemon 0.7.6. +# Generated by GNU Autoconf 2.69 for wavemon 0.8.0. # # Report bugs to <gerrit@erg.abdn.ac.uk>. # @@ -580,10 +580,10 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='wavemon' PACKAGE_TARNAME='wavemon-current' -PACKAGE_VERSION='0.7.6' -PACKAGE_STRING='wavemon 0.7.6' +PACKAGE_VERSION='0.8.0' +PACKAGE_STRING='wavemon 0.8.0' PACKAGE_BUGREPORT='gerrit@erg.abdn.ac.uk' -PACKAGE_URL='http://www.erg.abdn.ac.uk/ergcms/wavemon/' +PACKAGE_URL='https://github.com/uoaerg/wavemon' # Factoring default headers for most tests. ac_includes_default="\ @@ -623,6 +623,13 @@ ac_includes_default="\ ac_subst_vars='LTLIBOBJS LIBOBJS +LIBNL3_GENL_LIBS +LIBNL3_GENL_CFLAGS +LIBNL3_LIBS +LIBNL3_CFLAGS +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG EGREP GREP INSTALL_DATA @@ -694,7 +701,14 @@ CFLAGS LDFLAGS LIBS CPPFLAGS -CPP' +CPP +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +LIBNL3_CFLAGS +LIBNL3_LIBS +LIBNL3_GENL_CFLAGS +LIBNL3_GENL_LIBS' # Initialize some variables set by options. @@ -1235,7 +1249,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures wavemon 0.7.6 to adapt to many kinds of systems. +\`configure' configures wavemon 0.8.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1300,7 +1314,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of wavemon 0.7.6:";; + short | recursive ) echo "Configuration of wavemon 0.8.0:";; esac cat <<\_ACEOF @@ -1313,12 +1327,24 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if you have headers in a nonstandard directory <include dir> CPP C preprocessor + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + LIBNL3_CFLAGS + C compiler flags for LIBNL3, overriding pkg-config + LIBNL3_LIBS linker flags for LIBNL3, overriding pkg-config + LIBNL3_GENL_CFLAGS + C compiler flags for LIBNL3_GENL, overriding pkg-config + LIBNL3_GENL_LIBS + linker flags for LIBNL3_GENL, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to <gerrit@erg.abdn.ac.uk>. -wavemon home page: <http://www.erg.abdn.ac.uk/ergcms/wavemon/>. +wavemon home page: <https://github.com/uoaerg/wavemon>. _ACEOF ac_status=$? fi @@ -1381,7 +1407,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -wavemon configure 0.7.6 +wavemon configure 0.8.0 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1804,7 +1830,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by wavemon $as_me 0.7.6, which was +It was created by wavemon $as_me 0.8.0, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2186,11 +2212,19 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. ac_config_files="$ac_config_files Makefile" +# allow BUILD_DATE to be externally set for build reproducibility +if test "$BUILD_DATE"; then + cat >>confdefs.h <<_ACEOF +#define BUILD_DATE "$BUILD_DATE" +_ACEOF + +else cat >>confdefs.h <<_ACEOF #define BUILD_DATE "`/bin/date`" _ACEOF +fi CFLAGS="-O2 -Wall" @@ -3948,6 +3982,270 @@ fi done +# libnl3 with GeNetlink support - wavemon is tracking changes to iw + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL3" >&5 +$as_echo_n "checking for LIBNL3... " >&6; } + +if test -n "$LIBNL3_CFLAGS"; then + pkg_cv_LIBNL3_CFLAGS="$LIBNL3_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-3.0 >= 3.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-3.0 >= 3.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNL3_CFLAGS=`$PKG_CONFIG --cflags "libnl-3.0 >= 3.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBNL3_LIBS"; then + pkg_cv_LIBNL3_LIBS="$LIBNL3_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-3.0 >= 3.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-3.0 >= 3.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNL3_LIBS=`$PKG_CONFIG --libs "libnl-3.0 >= 3.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBNL3_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnl-3.0 >= 3.2" 2>&1` + else + LIBNL3_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnl-3.0 >= 3.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBNL3_PKG_ERRORS" >&5 + + CFLAGS="$CFLAGS $LIBNL3_CFLAGS" +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + CFLAGS="$CFLAGS $LIBNL3_CFLAGS" +else + LIBNL3_CFLAGS=$pkg_cv_LIBNL3_CFLAGS + LIBNL3_LIBS=$pkg_cv_LIBNL3_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBNL3_GENL" >&5 +$as_echo_n "checking for LIBNL3_GENL... " >&6; } + +if test -n "$LIBNL3_GENL_CFLAGS"; then + pkg_cv_LIBNL3_GENL_CFLAGS="$LIBNL3_GENL_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-genl-3.0 >= 3.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-genl-3.0 >= 3.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNL3_GENL_CFLAGS=`$PKG_CONFIG --cflags "libnl-genl-3.0 >= 3.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$LIBNL3_GENL_LIBS"; then + pkg_cv_LIBNL3_GENL_LIBS="$LIBNL3_GENL_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libnl-genl-3.0 >= 3.2\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libnl-genl-3.0 >= 3.2") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_LIBNL3_GENL_LIBS=`$PKG_CONFIG --libs "libnl-genl-3.0 >= 3.2" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + LIBNL3_GENL_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libnl-genl-3.0 >= 3.2" 2>&1` + else + LIBNL3_GENL_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libnl-genl-3.0 >= 3.2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$LIBNL3_GENL_PKG_ERRORS" >&5 + + as_fn_error $? "need libnl-genl >= 3.2" "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "need libnl-genl >= 3.2" "$LINENO" 5 +else + LIBNL3_GENL_CFLAGS=$pkg_cv_LIBNL3_GENL_CFLAGS + LIBNL3_GENL_LIBS=$pkg_cv_LIBNL3_GENL_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + LIBS="$LIBS $LIBNL3_GENL_LIBS" +fi + # Checks for typedefs, structures, and compiler characteristics. if test $ac_cv_c_compiler_gnu = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC needs -traditional" >&5 @@ -4657,7 +4955,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by wavemon $as_me 0.7.6, which was +This file was extended by wavemon $as_me 0.8.0, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4705,13 +5003,13 @@ Configuration files: $config_files Report bugs to <gerrit@erg.abdn.ac.uk>. -wavemon home page: <http://www.erg.abdn.ac.uk/ergcms/wavemon/>." +wavemon home page: <https://github.com/uoaerg/wavemon>." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -wavemon config.status 0.7.6 +wavemon config.status 0.8.0 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index e50c986..7132dea 100644 --- a/configure.ac +++ b/configure.ac @@ -1,14 +1,19 @@ dnl Process this file with autoconf to produce a configure script. AC_PREREQ(2.64) -AC_INIT([wavemon], [0.7.6], [gerrit@erg.abdn.ac.uk], [wavemon-current], - [http://www.erg.abdn.ac.uk/ergcms/wavemon/]) +AC_INIT([wavemon], [0.8.0], [gerrit@erg.abdn.ac.uk], [wavemon-current], + [https://github.com/uoaerg/wavemon]) # Variables AC_CONFIG_AUX_DIR([config]) AC_CONFIG_FILES([Makefile]) -AC_DEFINE_UNQUOTED([BUILD_DATE], ["`/bin/date`"], +# allow BUILD_DATE to be externally set for build reproducibility +if test "$BUILD_DATE"; then + AC_DEFINE_UNQUOTED(BUILD_DATE, ["$BUILD_DATE"]) +else + AC_DEFINE_UNQUOTED([BUILD_DATE], ["`/bin/date`"], [date wavemon was last configured and built]) +fi CFLAGS="-O2 -Wall" @@ -63,6 +68,14 @@ AC_CHECK_LIB([cap], [cap_get_flag]) AC_CHECK_FUNCS([gettimeofday ether_ntohost], [], [AC_MSG_ERROR(function '$ac_func' not supported)]) +# libnl3 with GeNetlink support - wavemon is tracking changes to iw +PKG_CHECK_MODULES([LIBNL3], [libnl-3.0 >= 3.2], [], + [CFLAGS="$CFLAGS $LIBNL3_CFLAGS"], + [AC_MSG_ERROR(need libnl >= 3.2)]) +PKG_CHECK_MODULES([LIBNL3_GENL], [libnl-genl-3.0 >= 3.2], + [LIBS="$LIBS $LIBNL3_GENL_LIBS"], + [AC_MSG_ERROR(need libnl-genl >= 3.2)]) + # Checks for typedefs, structures, and compiler characteristics. AC_PROG_GCC_TRADITIONAL AC_C_CONST diff --git a/ieee80211.h b/ieee80211.h new file mode 100644 index 0000000..8745608 --- /dev/null +++ b/ieee80211.h @@ -0,0 +1,61 @@ +#ifndef __IEEE80211 +#define __IEEE80211 + +/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ +#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 +#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C + +#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 +#define IEEE80211_HT_CAP_SGI_40 0x0040 +#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 + +#define IEEE80211_HT_MCS_MASK_LEN 10 + +/** + * struct ieee80211_mcs_info - MCS information + * @rx_mask: RX mask + * @rx_highest: highest supported RX rate. If set represents + * the highest supported RX data rate in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_params: TX parameters + */ +struct ieee80211_mcs_info { + __u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; + __u16 rx_highest; + __u8 tx_params; + __u8 reserved[3]; +} __attribute__ ((packed)); + + +/** + * struct ieee80211_ht_cap - HT capabilities + * + * This structure is the "HT capabilities element" as + * described in 802.11n D5.0 7.3.2.57 + */ +struct ieee80211_ht_cap { + __u16 cap_info; + __u8 ampdu_params_info; + + /* 16 bytes MCS information */ + struct ieee80211_mcs_info mcs; + + __u16 extended_ht_cap_info; + __u32 tx_BF_cap_info; + __u8 antenna_selection_info; +} __attribute__ ((packed)); + +struct ieee80211_vht_mcs_info { + __u16 rx_vht_mcs; + __u16 rx_highest; + __u16 tx_vht_mcs; + __u16 tx_highest; +} __attribute__ ((packed)); + +struct ieee80211_vht_cap { + __u32 cap_info; + struct ieee80211_vht_mcs_info mcs; +} __attribute__ ((packed)); + +#endif /* __IEEE80211 */ @@ -18,11 +18,13 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "iw_if.h" +#include "iw_nl80211.h" /* GLOBALS */ static WINDOW *w_levels, *w_stats, *w_if, *w_info, *w_net; static struct timer dyn_updates; -static struct iw_stat cur; +struct iw_range range; +static struct iw_nl80211_linkstat ls; void sampling_init(void (*sampling_handler)(int)) { @@ -30,7 +32,7 @@ void sampling_init(void (*sampling_handler)(int)) div_t d = div(conf.stat_iv, 1000); /* conf.stat_iv in msec */ xsignal(SIGALRM, SIG_IGN); - iw_getinf_range(conf_ifname(), &cur.range); + iw_getinf_range(conf_ifname(), &range); i.it_interval.tv_sec = i.it_value.tv_sec = d.quot; i.it_interval.tv_usec = i.it_value.tv_usec = d.rem * 1000; xsignal(SIGALRM, sampling_handler); @@ -41,23 +43,49 @@ void sampling_init(void (*sampling_handler)(int)) void sampling_do_poll(void) { - iw_getstat(&cur); - iw_cache_update(&cur); + iw_nl80211_get_linkstat(&ls); + iw_cache_update(&ls); } static void display_levels(void) { - char nscale[2] = { cur.dbm.signal - 20, cur.dbm.signal }, - lvlscale[2] = { -40, -20}, - snrscale[2] = { 6, 12 }; - char tmp[0x100]; static float qual, signal, noise, ssnr; + /* + * FIXME: revise the scale implementation. It does not work + * satisfactorily, maybe it is better to have a simple + * solution using 3 levels of different colour. + */ + int8_t nscale[2] = { conf.noise_min, conf.noise_max }, + lvlscale[2] = { -40, -20}; + char tmp[0x100]; int line; + bool noise_data_valid = iw_nl80211_have_survey_data(&ls); + int sig_qual = -1; + int sig_qual_max; + int sig_level = ls.signal_avg ?: ls.signal; + + /* See comments in iw_cache_update */ + if (sig_level == 0) + sig_level = ls.bss_signal; for (line = 1; line <= WH_LEVEL; line++) mvwclrtoborder(w_levels, line, 1); - if ((cur.stat.qual.updated & IW_QUAL_ALL_INVALID) == IW_QUAL_ALL_INVALID) { + if (ls.bss_signal_qual) { + /* BSS_SIGNAL_UNSPEC is scaled 0..100 */ + sig_qual = ls.bss_signal_qual; + sig_qual_max = 100; + } else if (sig_level) { + if (sig_level < -110) + sig_qual = 0; + else if (sig_level > -40) + sig_qual = 70; + else + sig_qual = sig_level + 110; + sig_qual_max = 70; + } + + if (sig_qual == -1 && !sig_level && !noise_data_valid) { wattron(w_levels, A_BOLD); waddstr_center(w_levels, (WH_LEVEL + 1)/2, "NO INTERFACE DATA"); goto done_levels; @@ -66,34 +94,33 @@ static void display_levels(void) line = 1; /* Noise data is rare. Use the space for spreading out. */ - if (cur.stat.qual.updated & IW_QUAL_NOISE_INVALID) + if (!noise_data_valid) line++; - if (cur.stat.qual.updated & IW_QUAL_QUAL_INVALID) { + if (sig_qual == -1) { line++; } else { - qual = ewma(qual, cur.stat.qual.qual, conf.meter_decay / 100.0); + qual = ewma(qual, sig_qual, conf.meter_decay / 100.0); mvwaddstr(w_levels, line++, 1, "link quality: "); - sprintf(tmp, "%0.f%% ", (1e2 * qual)/cur.range.max_qual.qual); + sprintf(tmp, "%0.f%% ", (1e2 * qual)/sig_qual_max); waddstr_b(w_levels, tmp); - sprintf(tmp, "(%0.f/%d) ", qual, cur.range.max_qual.qual); + sprintf(tmp, "(%0.f/%d) ", qual, sig_qual_max); waddstr(w_levels, tmp); - waddbar(w_levels, line++, qual, 0, cur.range.max_qual.qual, - lvlscale, true); + waddbar(w_levels, line++, qual, 0, sig_qual_max, lvlscale, true); } - if (cur.stat.qual.updated & IW_QUAL_NOISE_INVALID) + /* Spacer */ + line++; + if (!noise_data_valid) line++; - if (cur.stat.qual.updated & IW_QUAL_LEVEL_INVALID) { - line++; - } else { - signal = ewma(signal, cur.dbm.signal, conf.meter_decay / 100.0); + if (sig_level != 0) { + signal = ewma(signal, sig_level, conf.meter_decay / 100.0); mvwaddstr(w_levels, line++, 1, "signal level: "); - sprintf(tmp, "%.0f dBm (%s) ", signal, dbm2units(signal)); + sprintf(tmp, "%.0f dBm (%s)", signal, dbm2units(signal)); waddstr_b(w_levels, tmp); waddbar(w_levels, line, signal, conf.sig_min, conf.sig_max, @@ -104,32 +131,28 @@ static void display_levels(void) if (conf.hthreshold_action) waddthreshold(w_levels, line, signal, conf.hthreshold, conf.sig_min, conf.sig_max, lvlscale, '<'); - line++; } - if (! (cur.stat.qual.updated & IW_QUAL_NOISE_INVALID)) { - noise = ewma(noise, cur.dbm.noise, conf.meter_decay / 100.0); + line++; + + if (noise_data_valid) { + noise = ewma(noise, ls.survey.noise, conf.meter_decay / 100.0); mvwaddstr(w_levels, line++, 1, "noise level: "); - sprintf(tmp, "%.0f dBm (%s) ", noise, dbm2units(noise)); + sprintf(tmp, "%.0f dBm (%s)", noise, dbm2units(noise)); waddstr_b(w_levels, tmp); waddbar(w_levels, line++, noise, conf.noise_min, conf.noise_max, nscale, false); - /* - * Since we make sure (in iw_if.c) that invalid signal levels always - * imply invalid noise levels, we can display a valid SNR here. - */ - ssnr = ewma(ssnr, cur.dbm.signal - cur.dbm.noise, + } + + if (noise_data_valid && sig_level) { + ssnr = ewma(ssnr, sig_level - ls.survey.noise, conf.meter_decay / 100.0); - mvwaddstr(w_levels, line++, 1, "signal-to-noise ratio: "); - if (ssnr > 0) - waddstr_b(w_levels, "+"); - sprintf(tmp, "%.0f dB ", ssnr); + mvwaddstr(w_levels, line++, 1, "SNR: "); + sprintf(tmp, "%.0f dB", ssnr); waddstr_b(w_levels, tmp); - - waddbar(w_levels, line, ssnr, 0, 110, snrscale, true); } done_levels: @@ -148,27 +171,34 @@ static void display_stats(void) */ mvwaddstr(w_stats, 1, 1, "RX: "); - sprintf(tmp, "%'llu (%s)", nstat.rx_packets, - byte_units(nstat.rx_bytes)); - waddstr_b(w_stats, tmp); - - waddstr(w_stats, ", invalid: "); - sprintf(tmp, "%u", cur.stat.discard.nwid); - - waddstr_b(w_stats, tmp); - waddstr(w_stats, " nwid, "); + if (ls.rx_packets) { + sprintf(tmp, "%'u (%s)", ls.rx_packets, + byte_units(ls.rx_bytes)); + waddstr_b(w_stats, tmp); + } else { + waddstr(w_stats, "n/a"); + } - sprintf(tmp, "%u", cur.stat.discard.code); - waddstr_b(w_stats, tmp); - waddstr(w_stats, " crypt, "); + if (iw_nl80211_have_survey_data(&ls)) { + if (ls.rx_bitrate[0]) { + waddstr(w_stats, ", rate: "); + waddstr_b(w_stats, ls.rx_bitrate); + } - sprintf(tmp, "%u", cur.stat.discard.fragment); - waddstr_b(w_stats, tmp); - waddstr(w_stats, " frag, "); + if (ls.expected_thru) { + if (ls.expected_thru >= 1024) + sprintf(tmp, " (exp: %.1f MB/s)", ls.expected_thru/1024.0); + else + sprintf(tmp, " (exp: %u kB/s)", ls.expected_thru); + waddstr(w_stats, tmp); + } + } - sprintf(tmp, "%u", cur.stat.discard.misc); - waddstr_b(w_stats, tmp); - waddstr(w_stats, " misc"); + if (ls.rx_drop_misc) { + waddstr(w_stats, ", drop: "); + sprintf(tmp, "%'llu", (unsigned long long)ls.rx_drop_misc); + waddstr_b(w_stats, tmp); + } wclrtoborder(w_stats); @@ -177,18 +207,30 @@ static void display_stats(void) */ mvwaddstr(w_stats, 2, 1, "TX: "); - sprintf(tmp, "%'llu (%s)", nstat.tx_packets, - byte_units(nstat.tx_bytes)); - waddstr_b(w_stats, tmp); + if (ls.tx_packets) { + sprintf(tmp, "%'u (%s)", ls.tx_packets, + byte_units(ls.tx_bytes)); + waddstr_b(w_stats, tmp); + } else { + waddstr(w_stats, "n/a"); + } - waddstr(w_stats, ", mac retries: "); - sprintf(tmp, "%u", cur.stat.discard.retries); - waddstr_b(w_stats, tmp); + if (iw_nl80211_have_survey_data(&ls) && ls.tx_bitrate[0]) { + waddstr(w_stats, ", rate: "); + waddstr_b(w_stats, ls.tx_bitrate); + } - waddstr(w_stats, ", missed beacons: "); - sprintf(tmp, "%u", cur.stat.miss.beacon); - waddstr_b(w_stats, tmp); + if (ls.tx_retries) { + waddstr(w_stats, ", retries: "); + sprintf(tmp, "%'u", ls.tx_retries); + waddstr_b(w_stats, tmp); + } + if (ls.tx_failed) { + waddstr(w_stats, ", failed: "); + sprintf(tmp, "%'u", ls.tx_failed); + waddstr_b(w_stats, tmp); + } wclrtoborder(w_stats); wrefresh(w_stats); } @@ -196,112 +238,234 @@ static void display_stats(void) static void display_info(WINDOW *w_if, WINDOW *w_info) { struct iw_dyn_info info; + struct iw_nl80211_ifstat ifs; + struct iw_nl80211_reg ir; char tmp[0x100]; int i; - dyn_info_get(&info, conf_ifname(), &cur.range); + dyn_info_get(&info, conf_ifname(), &range); + iw_nl80211_getifstat(&ifs); + iw_nl80211_getreg(&ir); + /* + * Interface Part + */ wmove(w_if, 1, 1); waddstr_b(w_if, conf_ifname()); - if (cur.range.enc_capa & IW_WPA_MASK) - sprintf(tmp, " (%s, %s)", info.name, format_wpa(&cur.range)); + if (range.enc_capa & IW_WPA_MASK) + sprintf(tmp, " (%s, %s)", info.name, format_wpa(&range)); else sprintf(tmp, " (%s)", info.name); waddstr(w_if, tmp); - if (info.cap_essid) { - waddstr_b(w_if, ","); - waddstr(w_if, " ESSID: "); - if (info.essid_ct > 1) - sprintf(tmp, "\"%s\" [%d]", info.essid, - info.essid_ct); - else if (info.essid_ct) - sprintf(tmp, "\"%s\"", info.essid); - else - sprintf(tmp, "off/any"); - waddstr_b(w_if, tmp); + /* PHY */ + waddstr(w_if, ", phy "); + sprintf(tmp, "%d", ifs.phy); + waddstr_b(w_if, tmp); + + /* Regulatory domain */ + waddstr(w_if, ", reg: "); + if (ir.region > 0) { + waddstr_b(w_if, ir.country); + sprintf(tmp, " (%s)", dfs_domain_name(ir.region)); + waddstr(w_if, tmp); + } else { + waddstr_b(w_if, "n/a"); } - if (info.cap_nickname) { - waddstr(w_if, ", nick: "); - sprintf(tmp, "\"%s\"", info.nickname); - waddstr_b(w_if, tmp); + if (ifs.ssid[0]) { + waddstr(w_if, ", SSID: "); + waddstr_b(w_if, ifs.ssid); } - if (info.cap_nwid) { - waddstr(w_if, ", nwid: "); - if (info.nwid.disabled) - sprintf(tmp, "off/any"); - else - sprintf(tmp, "%X", info.nwid.value); - waddstr_b(w_if, tmp); - } wclrtoborder(w_if); wrefresh(w_if); + /* + * Info window: + */ wmove(w_info, 1, 1); waddstr(w_info, "mode: "); - if (info.cap_mode) - waddstr_b(w_info, iw_opmode(info.mode)); - else - waddstr(w_info, "n/a"); + waddstr_b(w_info, iftype_name(ifs.iftype)); + + if (!ether_addr_is_zero(&ls.bssid)) { + waddstr_b(w_info, ", "); + + switch (ls.status) { + case NL80211_BSS_STATUS_ASSOCIATED: + waddstr(w_info, "connected to: "); + break; + case NL80211_BSS_STATUS_AUTHENTICATED: + waddstr(w_info, "authenticated with: "); + break; + case NL80211_BSS_STATUS_IBSS_JOINED: + waddstr(w_info, "joined IBSS: "); + break; + default: + waddstr(w_info, "station: "); + } + waddstr_b(w_info, ether_lookup(&ls.bssid)); - if (info.mode != IW_MODE_MASTER && - info.mode != IW_MODE_SECOND && info.mode != IW_MODE_MONITOR) { - if (info.mode == IW_MODE_ADHOC) - waddstr(w_info, ", cell: "); - else - waddstr(w_info, ", access point: "); + if (ls.status == NL80211_BSS_STATUS_ASSOCIATED) { + waddstr_b(w_info, ","); + waddstr(w_info, " time: "); + waddstr_b(w_info, pretty_time(ls.connected_time)); - if (info.cap_ap) - waddstr_b(w_info, format_bssid(&info.ap_addr)); - else - waddstr(w_info, "n/a"); - } - - if (info.cap_sens) { - waddstr(w_info, ", sensitivity: "); - if (info.sens < 0) - sprintf(tmp, "%d dBm", info.sens); - else - sprintf(tmp, "%d/%d", info.sens, - cur.range.sensitivity); - waddstr_b(w_info, tmp); + waddstr(w_info, ", inactive: "); + sprintf(tmp, "%.1fs", (float)ls.inactive_time/1e3); + waddstr_b(w_info, tmp); + } } wclrtoborder(w_info); wmove(w_info, 2, 1); - if (info.cap_freq && info.freq < 256) - info.freq = channel_to_freq(info.freq, &cur.range); - if (info.cap_freq && info.freq > 1e3) { + /* Frequency / channel */ + if (ifs.freq) { waddstr(w_info, "freq: "); - sprintf(tmp, "%g GHz", info.freq / 1.0e9); + sprintf(tmp, "%d MHz", ifs.freq); waddstr_b(w_info, tmp); - i = freq_to_channel(info.freq, &cur.range); - if (i >= 0) { - waddstr(w_info, ", channel: "); - sprintf(tmp, "%d", i); + /* The following condition should in theory never happen */ + if (ls.survey.freq && ls.survey.freq != ifs.freq) { + sprintf(tmp, " [survey freq: %d MHz]", ls.survey.freq); + waddstr(w_info, tmp); + } + + if (ifs.freq_ctr1 && ifs.freq_ctr1 != ifs.freq) { + waddstr(w_info, ", ctr1: "); + sprintf(tmp, "%d MHz", ifs.freq_ctr1); waddstr_b(w_info, tmp); } + if (ifs.freq_ctr2 && ifs.freq_ctr2 != ifs.freq_ctr1 && ifs.freq_ctr2 != ifs.freq) { + waddstr(w_info, ", ctr2: "); + sprintf(tmp, "%d MHz", ifs.freq_ctr2); + waddstr_b(w_info, tmp); + } + + waddstr(w_info, ", channel: "); + sprintf(tmp, "%d", ieee80211_frequency_to_channel(ifs.freq)); + waddstr_b(w_info, tmp); + + if (ifs.chan_width >= 0) { + sprintf(tmp, " (width: %s)", channel_width_name(ifs.chan_width)); + waddstr(w_info, tmp); + } else if (ifs.chan_type >= 0) { + sprintf(tmp, " (%s)", channel_type_name(ifs.chan_type)); + waddstr(w_info, tmp); + } + } else if (iw_nl80211_have_survey_data(&ls)) { + waddstr(w_info, "freq: "); + sprintf(tmp, "%d MHz", ls.survey.freq); + waddstr_b(w_info, tmp); } else { waddstr(w_info, "frequency/channel: n/a"); } + wclrtoborder(w_info); + + /* Channel data */ + wmove(w_info, 3, 1); + if (iw_nl80211_have_survey_data(&ls)) { + waddstr(w_info, "channel "); + waddstr(w_info, "active: "); + waddstr_b(w_info, pretty_time_ms(ls.survey.time.active)); + + waddstr(w_info, ", busy: "); + waddstr_b(w_info, pretty_time_ms(ls.survey.time.busy)); + + if (ls.survey.time.ext_busy) { + waddstr(w_info, ", ext-busy: "); + waddstr_b(w_info, pretty_time_ms(ls.survey.time.ext_busy)); + } + + waddstr(w_info, ", rx: "); + waddstr_b(w_info, pretty_time_ms(ls.survey.time.rx)); + + waddstr(w_info, ", tx: "); + waddstr_b(w_info, pretty_time_ms(ls.survey.time.tx)); + + if (ls.survey.time.scan) { + waddstr(w_info, ", scan: "); + waddstr_b(w_info, pretty_time_ms(ls.survey.time.scan)); + } + } else if (ls.tx_bitrate[0] && ls.rx_bitrate[0]) { + waddstr(w_info, "rx rate: "); + waddstr_b(w_info, ls.rx_bitrate); + + if (ls.expected_thru) { + if (ls.expected_thru >= 1024) + sprintf(tmp, " (exp: %.1f MB/s)", ls.expected_thru/1024.0); + else + sprintf(tmp, " (exp: %u kB/s)", ls.expected_thru); + waddstr(w_info, tmp); + } + waddstr(w_info, ", tx rate: "); + waddstr_b(w_info, ls.tx_bitrate); + } - if (! (info.mode >= IW_MODE_MASTER && info.mode <= IW_MODE_MONITOR)) { - waddstr(w_info, ", bitrate: "); - if (info.bitrate) { - sprintf(tmp, "%g Mbit/s", info.bitrate / 1.0e6); + /* Beacons */ + wmove(w_info, 4, 1); + + if (ls.beacons) { + waddstr(w_info, "beacons: "); + sprintf(tmp, "%'llu", (unsigned long long)ls.beacons); + waddstr_b(w_info, tmp); + + if (ls.beacon_loss) { + waddstr(w_info, ", lost: "); + sprintf(tmp, "%'u", ls.beacon_loss); waddstr_b(w_info, tmp); - } else - waddstr(w_info, "n/a"); + } + waddstr(w_info, ", avg sig: "); + sprintf(tmp, "%d dBm", (int8_t)ls.beacon_avg_sig); + waddstr_b(w_info, tmp); + + waddstr(w_info, ", interval: "); + sprintf(tmp, "%.1fs", (ls.beacon_int * 1024.0)/1e6); + waddstr_b(w_info, tmp); + + waddstr(w_info, ", DTIM: "); + sprintf(tmp, "%u", ls.dtim_period); + waddstr_b(w_info, tmp); + } else { + waddstr(w_info, "station flags:"); + if (ls.cts_protection) + waddstr_b(w_info, " CTS"); + if (ls.wme) + waddstr_b(w_info, " WME"); + if (ls.tdls) + waddstr_b(w_info, " TDLS"); + if (ls.mfp) + waddstr_b(w_info, " MFP"); + if (!(ls.cts_protection | ls.wme | ls.tdls | ls.mfp)) + waddstr_b(w_info, " (none)"); + waddstr(w_info, ", preamble:"); + if (ls.long_preamble) + waddstr_b(w_info, " long"); + else + waddstr_b(w_info, " short"); + waddstr(w_info, ", slot:"); + if (ls.short_slot_time) + waddstr_b(w_info, " short"); + else + waddstr_b(w_info, " long"); + } + + if (info.cap_sens) { + waddstr(w_info, ", sensitivity: "); + if (info.sens < 0) + sprintf(tmp, "%d dBm", info.sens); + else + sprintf(tmp, "%d/%d", info.sens, + range.sensitivity); + waddstr_b(w_info, tmp); } + wclrtoborder(w_info); - wmove(w_info, 3, 1); + wmove(w_info, 5, 1); waddstr(w_info, "power mgt: "); if (info.cap_power) - waddstr_b(w_info, format_power(&info.power, &cur.range)); + waddstr_b(w_info, format_power(&info.power, &range)); else waddstr(w_info, "n/a"); @@ -320,10 +484,10 @@ static void display_info(WINDOW *w_if, WINDOW *w_info) } wclrtoborder(w_info); - wmove(w_info, 4, 1); + wmove(w_info, 6, 1); waddstr(w_info, "retry: "); if (info.cap_retry) - waddstr_b(w_info, format_retry(&info.retry, &cur.range)); + waddstr_b(w_info, format_retry(&info.retry, &range)); else waddstr(w_info, "n/a"); @@ -352,7 +516,7 @@ static void display_info(WINDOW *w_if, WINDOW *w_info) } wclrtoborder(w_info); - wmove(w_info, 5, 1); + wmove(w_info, 7, 1); waddstr(w_info, "encryption: "); if (info.keys) { int cnt = dyn_info_active_keys(&info); @@ -480,7 +644,7 @@ static void display_netinfo(WINDOW *w_net) waddstr(w_net, "ip: "); if (!info.addr.s_addr) { - waddstr_b(w_net, "n/a"); + waddstr(w_net, "n/a"); } else { sprintf(tmp, "%s/%u", inet_ntoa(info.addr), prefix_len(&info.netmask)); @@ -526,7 +690,7 @@ void scr_info_init(void) if (LINES >= WH_INFO_SCR_MIN + (WH_NET_MAX - WH_NET_MIN)) w_net = newwin_title(line, WH_NET_MAX, "Network", false); else - w_net = newwin_title(line, WH_NET_MIN, "Network", false); + w_net = newwin_title(line, WH_NET_MAX, "Network", false); display_info(w_if, w_info); display_netinfo(w_net); @@ -40,9 +40,15 @@ static int if_get_flags(int skfd, const char *ifname) } /* Return true if @ifname is known to be up. */ -bool if_is_up(int skfd, const char *ifname) +bool if_is_up(const char *ifname) { - return if_get_flags(skfd, ifname) & IFF_UP; + int ret, skfd = socket(AF_INET, SOCK_DGRAM, 0); + + if (skfd < 0) + err_sys("%s: can not open socket", __func__); + ret = if_get_flags(skfd, ifname) & IFF_UP; + close(skfd); + return ret; } /** Bring @ifname up if not already up. Return 0 if ok, < 0 on error. */ @@ -101,14 +107,15 @@ void if_getinf(const char *ifname, struct if_info *info) } /** - * iw_get_interface_list - Return NULL-terminated array of WiFi interfaces. + * iw_get_interface_list - fill if_list with NULL-terminated array of WiFi + * interfaces. * Use the safe route of checking /proc/net/dev/ for wireless interfaces: * - SIOCGIFCONF only returns running interfaces that have an IP address; * - /proc/net/wireless may exist, but may not list all wireless interfaces. */ -char **iw_get_interface_list(void) +void iw_get_interface_list(char** if_list, size_t max_entries) { - char **if_list = NULL, *p, tmp[BUFSIZ]; + char *p, tmp[BUFSIZ]; int nifs = 1; /* if_list[nifs-1] = NULL */ struct iwreq wrq; FILE *fp; @@ -129,27 +136,24 @@ char **iw_get_interface_list(void) * Use SIOCGIWNAME as indicator: if interface does not * support this ioctl, it has no wireless extensions. */ - strncpy(wrq.ifr_name, p, IFNAMSIZ); + snprintf(wrq.ifr_name, IFNAMSIZ, "%s", p); if (ioctl(skfd, SIOCGIWNAME, &wrq) < 0) continue; - - if_list = realloc(if_list, sizeof(char *) * (nifs + 1)); - if (if_list == NULL) - err_sys("can not reallocate interface list"); + if(nifs >= max_entries) break; if_list[nifs-1] = strdup(p); if_list[nifs++] = NULL; } } close(skfd); fclose(fp); - return if_list; } void if_getstat(const char *ifname, struct if_stat *stat) { char line[0x100]; - unsigned long d; + unsigned long long d; char *lp; + size_t l = strlen(ifname); const char path[] = "/proc/net/dev"; FILE *fp = fopen(path, "r"); @@ -161,11 +165,11 @@ void if_getstat(const char *ifname, struct if_stat *stat) */ while (fgets(line, sizeof(line), fp)) { lp = line + strspn(line, " "); - if (!strncmp(lp, ifname, strlen(ifname))) { - lp += strlen(ifname) + 1; + if (!strncmp(lp, ifname, l) && lp[l] == ':') { + lp += l + 1; lp += strspn(lp, " "); - sscanf(lp, "%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu", + sscanf(lp, "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", &stat->rx_bytes, &stat->rx_packets, &d, &d, &d, &d, &d, &d, &stat->tx_bytes, &stat->tx_packets); } @@ -205,11 +209,6 @@ void dyn_info_get(struct iw_dyn_info *info, info->essid[iwr.u.essid.length] = '\0'; } - if (ioctl(skfd, SIOCGIWNWID, &iwr) >= 0) { - info->cap_nwid = 1; - memcpy(&info->nwid, &iwr.u.nwid, sizeof(info->nwid)); - } - iwr.u.essid.pointer = (caddr_t) info->nickname; iwr.u.essid.length = sizeof(info->nickname); iwr.u.essid.flags = 0; @@ -334,331 +333,3 @@ void iw_getinf_range(const char *ifname, struct iw_range *range) err_sys("can not get range information"); close(skfd); } - -/* - * Obtain periodic IW statistics - */ -static int rand_wave(float *rlvl, float *step, float *rlvl_next, float range) -{ - int i; - - for (i = 0; i < WAVE_RAND_SPREAD; i++) - if (*rlvl < *rlvl_next) { - if (*rlvl_next - *rlvl < *step) - *step /= 2.0; - *rlvl += *step; - } else if (*rlvl > *rlvl_next) { - if (*rlvl - *rlvl_next < *step) - *step /= 2.0; - *rlvl -= *step; - } - *step += (random() / (float)RAND_MAX) - 0.5; - if (*rlvl == *rlvl_next || *step < 0.05) { - *rlvl_next = (range * random()) / RAND_MAX; - *step = random() / (float)RAND_MAX; - } - return *rlvl; -} - -/* Random signal/noise/quality levels */ -static void iw_getstat_random(struct iw_stat *iw) -{ - static float rnd_sig, snext, sstep = 1.0, rnd_noise, nnext, nstep = 1.0; - - rand_wave(&rnd_sig, &sstep, &snext, conf.sig_max - conf.sig_min); - rand_wave(&rnd_noise, &nstep, &nnext, conf.noise_max - conf.noise_min); - - if (iw->range.max_qual.qual == 0) - iw->range.max_qual.qual = WAVE_RAND_QUAL_MAX; - - iw->stat.qual.level = dbm_to_u8(conf.sig_min + rnd_sig); - iw->stat.qual.noise = dbm_to_u8(conf.noise_min + rnd_noise); - iw->stat.qual.updated = IW_QUAL_DBM; - iw->stat.qual.qual = map_range(conf.sig_min + rnd_sig, - conf.sig_min, conf.sig_max, - 0, iw->range.max_qual.qual); -} - -static void iw_getstat_real(struct iw_statistics *stat) -{ - struct iwreq wrq; - int skfd = socket(AF_INET, SOCK_DGRAM, 0); - - if (skfd < 0) - err_sys("%s: can not open socket", __func__); - - wrq.u.data.pointer = (caddr_t) stat; - wrq.u.data.length = sizeof(*stat); - wrq.u.data.flags = 0; - strncpy(wrq.ifr_name, conf_ifname(), IFNAMSIZ); - - if (ioctl(skfd, SIOCGIWSTATS, &wrq) < 0) { - /* - * iw_handler_get_iwstats() returns EOPNOTSUPP if - * there are no statistics. Bail out in this case. - */ - if (errno != EOPNOTSUPP) - err_sys("can not obtain iw statistics"); - errno = 0; - memset(&wrq, 0, sizeof(wrq)); - } - close(skfd); -} - -/* - * Generate dBm values and perform sanity checks on values. - * Code in part taken from wireless extensions #30 - * @range: range information, read-only - * @qual: wireless statistics, read-write - * @dbm: dBm level information, write-only - */ -void iw_sanitize(struct iw_range *range, struct iw_quality *qual, - struct iw_levelstat *dbm) -{ - memset(dbm, 0, sizeof(*dbm)); - - if (qual->level != 0 || (qual->updated & (IW_QUAL_DBM | IW_QUAL_RCPI))) { - /* - * RCPI (IEEE 802.11k) statistics: - * RCPI = int{(Power in dBm +110)*2} - * for 0 dBm > Power > -110 dBm - */ - if (qual->updated & IW_QUAL_RCPI) { - if (!(qual->updated & IW_QUAL_LEVEL_INVALID)) - dbm->signal = (double)(qual->level / 2.0) - 110.0; - if (!(qual->updated & IW_QUAL_NOISE_INVALID)) - dbm->noise = (double)(qual->noise / 2.0) - 110.0; - - } else if ((qual->updated & IW_QUAL_DBM) || - qual->level > range->max_qual.level) { - if (!(qual->updated & IW_QUAL_LEVEL_INVALID)) - dbm->signal = u8_to_dbm(qual->level); - if (!(qual->updated & IW_QUAL_NOISE_INVALID)) - dbm->noise = u8_to_dbm(qual->noise); - } else { - /* - * Relative values (0 -> max) - */ - if (!(qual->updated & IW_QUAL_LEVEL_INVALID)) - dbm->signal = mw2dbm(qual->level); - if (!(qual->updated & IW_QUAL_NOISE_INVALID)) - dbm->noise = mw2dbm(qual->noise); - } - } else { - qual->updated |= IW_QUAL_ALL_INVALID; - } - - /* - * Value sanity checks - * - * These rules serve to avoid "insensible" level displays. Please do send - * comments and/or bug reports if you encounter room for improvement. - * - * 1) if noise level is valid, but signal level is not, displaying just - * the noise level does not reveal very much - can be omitted; - * 2) if the noise level is below an "invalid" magic value (see iw_if.h), - * declare the noise value to be invalid; - * 3) SNR is only displayed if both signal and noise values are valid. - */ - if (qual->updated & IW_QUAL_LEVEL_INVALID) - qual->updated |= IW_QUAL_NOISE_INVALID; - if (dbm->noise <= NOISE_DBM_SANE_MIN) - qual->updated |= IW_QUAL_NOISE_INVALID; -} - -void iw_getstat(struct iw_stat *iw) -{ - memset(&iw->stat, 0, sizeof(iw->stat)); - - if (conf.random) - iw_getstat_random(iw); - else - iw_getstat_real(&iw->stat); - - iw_sanitize(&iw->range, &iw->stat.qual, &iw->dbm); -} - -const char *we_version(void) -{ - static char buf[BUFSIZ]; - struct iw_stat iw; - - iw_getinf_range(conf_ifname(), &iw.range); - sprintf(buf, "wireless extensions v%d (source v%d)", - iw.range.we_version_compiled, iw.range.we_version_source); - return buf; -} - -void dump_parameters(void) -{ - struct iw_dyn_info info; - struct iw_stat iw; - struct if_stat nstat; - int i; - - iw_getinf_range(conf_ifname(), &iw.range); - dyn_info_get(&info, conf_ifname(), &iw.range); - iw_getstat(&iw); - if_getstat(conf_ifname(), &nstat); - - printf("\n"); - printf("Configured device: %s (%s)\n", conf_ifname(), info.name); - printf(" Security: %s\n", iw.range.enc_capa ? - format_enc_capab(iw.range.enc_capa, ", ") : "WEP"); - if (iw.range.num_encoding_sizes && - iw.range.num_encoding_sizes < IW_MAX_ENCODING_SIZES) { - - printf(" Key sizes: "); - for (i = 0; i < iw.range.num_encoding_sizes; i++) { - if (i) - printf(", "); - if (iw.range.encoding_size[i] == 5) - printf("WEP-40"); - else if (iw.range.encoding_size[i] == 13) - printf("WEP-104"); - else - printf("%u bits", - iw.range.encoding_size[i] * 8); - } - printf("\n"); - } - printf("\n"); - - if (info.cap_essid) { - if (info.essid_ct > 1) - printf(" essid: \"%s\" [%d]\n", - info.essid, info.essid_ct); - else if (info.essid_ct) - printf(" essid: \"%s\"\n", info.essid); - else - printf(" essid: off/any\n"); - } - - if (info.cap_nickname) - printf(" nick: \"%s\"\n", info.nickname); - - if (info.cap_nwid) { - if (info.nwid.disabled) - printf(" nwid: off/any\n"); - else - printf(" nwid: %X\n", info.nwid.value); - } - - /* Some drivers only return the channel (e.g. ipw2100) */ - if (info.cap_freq && info.freq < 256) - info.freq = channel_to_freq(info.freq, &iw.range); - if (info.cap_freq && info.freq > 1e3) { - i = freq_to_channel(info.freq, &iw.range); - if (i >= 0) - printf(" channel: %d\n", i); - printf(" frequency: %g GHz\n", info.freq / 1.0e9); - } else - printf(" frequency: n/a\n"); - - if (info.cap_sens) { - if (info.sens < 0) - printf(" sensitivity: %d dBm\n", info.sens); - else - printf(" sensitivity: %d/%d\n", info.sens, - iw.range.sensitivity); - } - - if (info.cap_txpower && info.txpower.disabled) - printf(" tx-power: off\n"); - else if (info.cap_txpower && info.txpower.fixed) - printf(" tx-power: %s\n", format_txpower(&info.txpower)); - else if (info.cap_txpower) - printf(" TX-power: %s\n", format_txpower(&info.txpower)); - - printf(" mode: %s\n", iw_opmode(info.mode)); - - if (info.mode != 1 && info.cap_ap) - printf(" access point: %s\n", format_bssid(&info.ap_addr)); - - if (info.bitrate) - printf(" bitrate: %g Mbit/s\n", info.bitrate / 1.0e6); - else - printf(" bitrate: n/a\n"); - - printf(" retry: "); - if (info.cap_retry) - printf("%s\n", format_retry(&info.retry, &iw.range)); - else - printf("n/a\n"); - - printf(" rts thr: "); - if (info.cap_rts) { - if (info.rts.disabled) - printf("off\n"); - else - printf("%d B %s\n", info.rts.value, - info.rts.fixed ? "" : "(auto-select)"); - } else - printf("n/a\n"); - - printf(" frag thr: "); - if (info.cap_frag) { - if (info.frag.disabled) - printf("off\n"); - else - printf("%d B %s\n", info.frag.value, - info.frag.fixed ? "" : "(auto-select)"); - } else { - printf("n/a\n"); - } - - printf(" encryption: "); - if (!info.nkeys && has_net_admin_capability()) - printf("no information available\n"); - else if (!info.nkeys) - printf("n/a (requires CAP_NET_ADMIN permissions)\n"); - for (i = 0; i < info.nkeys; i++) { - if (i) - printf(" "); - /* Current key is marked by `=' sign */ - printf("[%u]%s ", i + 1, i + 1 == info.active_key ? "=" : ":"); - - if (info.keys[i].flags & IW_ENCODE_DISABLED || !info.keys[i].size) { - printf("off\n"); - } else { - printf("%s", format_key(info.keys + i)); - if (info.keys[i].flags & IW_ENCODE_RESTRICTED) - printf(", restricted"); - if (info.keys[i].flags & IW_ENCODE_OPEN) - printf(", open"); - printf("\n"); - } - } - - printf(" power management: "); - if (info.cap_power) - printf("%s\n", format_power(&info.power, &iw.range)); - else - printf("n/a\n"); - - printf("\n"); - printf(" link quality: %d/%d\n", iw.stat.qual.qual, - iw.range.max_qual.qual); - printf(" signal level: %.0f dBm (%s)\n", iw.dbm.signal, - dbm2units(iw.dbm.signal)); - printf(" noise level: %.0f dBm (%s)\n", iw.dbm.noise, - dbm2units(iw.dbm.noise)); - printf(" SNR: %.0f dB\n", iw.dbm.signal - iw.dbm.noise); - - /* RX stats */ - printf(" RX total: %'llu packets (%s)\n", nstat.rx_packets, - byte_units(nstat.rx_bytes)); - printf(" invalid nwid: %'u\n", iw.stat.discard.nwid); - printf(" invalid key: %'u\n", iw.stat.discard.code); - printf(" invalid fragm.: %'u\n", iw.stat.discard.fragment); - printf(" missed beacons: %'u\n", iw.stat.miss.beacon); - printf(" misc errors: %'u\n", iw.stat.discard.misc); - - /* TX stats */ - printf(" TX total: %'llu packets (%s)\n", nstat.tx_packets, - byte_units(nstat.tx_bytes)); - printf(" exc. MAC retries: %'u\n", iw.stat.discard.retries); - - printf("\n"); - dyn_info_cleanup(&info); -} @@ -18,7 +18,9 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "wavemon.h" +#include "nl80211.h" #include <netdb.h> +#include <stdbool.h> #include <pthread.h> #include <arpa/inet.h> #include <netinet/in.h> @@ -33,22 +35,24 @@ #ifndef IW_POWER_SAVING #define IW_POWER_SAVING 0x4000 /* version 20 -> 21 */ #endif -#ifndef IW_MODE_MESH -#define IW_MODE_MESH 7 /* introduced in 2.6.26-rc1 */ -#endif -/* Maximum length of a MAC address: 2 * 6 hex digits, 6 - 1 colons, plus '\0' */ -#define MAC_ADDR_MAX 18 +/* Definitions from linux/ieee80211.h (not necessarily part of distro headers) */ +#define WLAN_CAPABILITY_ESS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_IS_STA_BSS(cap) \ + (!((cap) & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS))) +#define WLAN_CAPABILITY_PRIVACY (1<<4) + +/* 802.11h */ +#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) +#define WLAN_CAPABILITY_QOS (1<<9) +#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) +#define WLAN_CAPABILITY_APSD (1<<11) +#define WLAN_CAPABILITY_RADIO_MEASURE (1<<12) +#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) +#define WLAN_CAPABILITY_DEL_BACK (1<<14) +#define WLAN_CAPABILITY_IMM_BACK (1<<15) -/* - * Threshold for 'sane' noise levels. - * - * Some drivers simply set an arbitrary minimum noise level to mean 'invalid', - * but do not set IW_QUAL_NOISE_INVALID so that the display gets stuck at a - * "house number". The value below is suggested by and taken from the iwl3945 - * driver (constant IWL_NOISE_MEAS_NOT_AVAILABLE in iwl-3945.h). - */ -#define NOISE_DBM_SANE_MIN -127 /** * struct if_info - wireless interface network information @@ -70,6 +74,7 @@ struct if_info { uint16_t txqlen; uint16_t flags; }; +extern bool if_is_up(const char *ifname); extern int if_set_up(const char *ifname); extern void if_getinf(const char *ifname, struct if_info *info); @@ -95,7 +100,6 @@ struct iw_key { * @essid: Extended Service Set ID (network name) * @essid_ct: index number of the @essid (starts at 1, 0 = off) * @nickname: optional station nickname - * @nwid: Network ID (pre-802.11 hardware only) * @ap_addr: BSSID or IBSSID * * @retry: MAC-retransmission retry behaviour @@ -118,7 +122,6 @@ struct iw_dyn_info { uint8_t mode; bool cap_essid:1, - cap_nwid:1, cap_nickname:1, cap_freq:1, cap_sens:1, @@ -134,7 +137,6 @@ struct iw_dyn_info { char essid[IW_ESSID_MAX_SIZE+2]; uint8_t essid_ct; char nickname[IW_ESSID_MAX_SIZE+2]; - struct iw_param nwid; struct sockaddr ap_addr; struct iw_param retry; @@ -202,28 +204,10 @@ struct iw_levelstat { #define IW_LSTAT_INIT { 0, 0, IW_QUAL_LEVEL_INVALID | IW_QUAL_NOISE_INVALID } extern void iw_getinf_range(const char *ifname, struct iw_range *range); -extern void iw_sanitize(struct iw_range *range, - struct iw_quality *qual, - struct iw_levelstat *dbm); - -/** - * struct iw_stat - record current WiFi state - * @range: current range information - * @stats: current signal level statistics - * @dbm: the noise/signal of @stats in dBm - */ -struct iw_stat { - struct iw_range range; - struct iw_statistics stat; - struct iw_levelstat dbm; -}; /* * Periodic sampling of wireless statistics via timer alarm */ -extern void iw_getstat(struct iw_stat *stat); -extern void iw_cache_update(struct iw_stat *stat); - extern void sampling_init(void (*sampling_handler)(int)); extern void sampling_do_poll(void); static inline void sampling_stop(void) { alarm(0); } @@ -233,27 +217,35 @@ static inline void sampling_stop(void) { alarm(0); } */ /** * struct scan_entry - Representation of a single scan result. - * @ap_addr: MAC address - * @essid: station SSID (may be empty) - * @mode: operation mode (type of station) - * @freq: frequency/channel information - * @chan: channel corresponding to @freq (where applicable) - * @qual: signal quality information - * @has_key: whether using encryption or not - * @flags: properties gathered from Information Elements - * @next: next entry in list + * @ap_addr: MAC address + * @essid: station SSID (may be empty) + * @freq: frequency in MHz + * @chan: channel corresponding to @freq (where applicable) + * @has_key: whether using encryption or not + * @last_seen: time station was last seen in seconds + * @tsf: value of the Timing Synchronisation Function counter + * @bss_signal: signal strength of BSS probe in dBm (or 0) + * @bss_signal_qual: unitless signal strength of BSS probe, 0..100 + * @bss_capa: BSS capability flags + * @bss_sta_count: BSS station count + * @bss_chan_usage: BSS channel utilisation + * @next: next entry in list */ struct scan_entry { struct ether_addr ap_addr; char essid[IW_ESSID_MAX_SIZE + 2]; - int mode; - double freq; + uint32_t freq; int chan; - struct iw_quality qual; - struct iw_levelstat dbm; + uint8_t has_key:1; - int has_key:1; - uint32_t flags; + uint32_t last_seen; + uint64_t tsf; + + int8_t bss_signal; + uint8_t bss_signal_qual; + uint16_t bss_capa; + uint8_t bss_sta_count, + bss_chan_usage; struct scan_entry *next; }; @@ -280,7 +272,6 @@ struct cnt { * @num.two_gig: number of 2.4GHz stations among @num.total * @num.five_gig: number of 5 GHz stations among @num.total * @num.ch_stats: length of @channel_stats array - * @range: range data associated with scan interface * @mutex: protects against concurrent consumer/producer access */ struct scan_result { @@ -297,7 +288,6 @@ struct scan_result { #define MAX_CH_STATS 3 size_t ch_stats; } num; - struct iw_range range; pthread_mutex_t mutex; }; @@ -306,125 +296,31 @@ extern void scan_result_fini(struct scan_result *sr); extern void *do_scan(void *sr_ptr); /* - * General helper routines + * utils.c */ -static inline const char *iw_opmode(const uint8_t mode) -{ - static char *modes[] = { - [IW_MODE_AUTO] = "Auto", - [IW_MODE_ADHOC] = "Ad-Hoc", - [IW_MODE_INFRA] = "Managed", - [IW_MODE_MASTER] = "Master", - [IW_MODE_REPEAT] = "Repeater", - [IW_MODE_SECOND] = "Secondary", - [IW_MODE_MONITOR] = "Monitor", - [IW_MODE_MESH] = "Mesh" - }; - - return mode < ARRAY_SIZE(modes) ? modes[mode] : "Unknown/bug"; -} - -/* Print a mac-address, include leading zeroes (unlike ether_ntoa(3)) */ -static inline char *ether_addr(const struct ether_addr *ea) -{ - static char mac[MAC_ADDR_MAX]; - char *d = mac, *a = ether_ntoa(ea); -next_chunk: - if (a[0] == '\0' || a[1] == '\0' || a[1] == ':') - *d++ = '0'; - while ((*d++ = conf.cisco_mac ? (*a == ':' ? '.' : *a) : toupper(*a))) - if (*a++ == ':') - goto next_chunk; - return mac; -} - -/* Print mac-address translation from /etc/ethers if available */ -static inline char *ether_lookup(const struct ether_addr *ea) -{ - static char hostname[BUFSIZ]; - - if (ether_ntohost(hostname, ea) == 0) - return hostname; - return ether_addr(ea); -} - -/* Format an Ethernet mac address */ -static inline char *mac_addr(const struct sockaddr *sa) -{ - if (sa->sa_family != ARPHRD_ETHER) - return "00:00:00:00:00:00"; - return ether_lookup((const struct ether_addr *)sa->sa_data); -} - -/* Format a (I)BSSID */ -static inline char *format_bssid(const struct sockaddr *ap) -{ - uint8_t bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - uint8_t zero_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - if (memcmp(ap->sa_data, zero_addr, ETH_ALEN) == 0) - return "Not-Associated"; - if (memcmp(ap->sa_data, bcast_addr, ETH_ALEN) == 0) - return "Invalid"; - return mac_addr(ap); -} - -/* count bits set in @mask the Brian Kernighan way */ -static inline uint8_t bit_count(uint32_t mask) -{ - uint8_t bits_set; - - for (bits_set = 0; mask; bits_set++) - mask &= mask - 1; - - return bits_set; -} - -/* netmask = contiguous 1's followed by contiguous 0's */ -static inline uint8_t prefix_len(const struct in_addr *netmask) -{ - return bit_count(netmask->s_addr); -} - -/* Absolute power measurement in dBm (IW_QUAL_DBM): map into -192 .. 63 range */ -static inline int u8_to_dbm(const int power) -{ - return power > 63 ? power - 0x100 : power; -} -static inline uint8_t dbm_to_u8(const int dbm) -{ - return dbm < 0 ? dbm + 0x100 : dbm; -} - -/* Convert log dBm values to linear mW */ -static inline double dbm2mw(const double in) -{ - return pow(10.0, in / 10.0); -} - -static inline char *dbm2units(const double in) -{ - static char with_units[0x100]; - double val = dbm2mw(in); - - if (val < 0.00000001) { - sprintf(with_units, "%.2f pW", val * 1e9); - } else if (val < 0.00001) { - sprintf(with_units, "%.2f nW", val * 1e6); - } else if (val < 0.01) { - sprintf(with_units, "%.2f uW", val * 1e3); - } else { - sprintf(with_units, "%.2f mW", val); - } - return with_units; -} - -/* Convert linear mW values to log dBm */ -static inline double mw2dbm(const double in) -{ - return 10.0 * log10(in); -} +extern char *ether_addr(const struct ether_addr *ea); +extern char *ether_lookup(const struct ether_addr *ea); +extern char *mac_addr(const struct sockaddr *sa); +extern char *format_bssid(const struct sockaddr *ap); +extern uint8_t bit_count(uint32_t mask); +extern uint8_t prefix_len(const struct in_addr *netmask); +extern const char *pretty_time(const unsigned sec); +extern const char *pretty_time_ms(const unsigned msec); +extern int u8_to_dbm(const int power); +extern uint8_t dbm_to_u8(const int dbm); +extern double dbm2mw(const double in); +extern char *dbm2units(const double in); +extern double mw2dbm(const double in); + +extern const char *dfs_domain_name(enum nl80211_dfs_regions region); +extern int ieee80211_frequency_to_channel(int freq); +extern const char *channel_width_name(enum nl80211_chan_width width); +extern const char *channel_type_name(enum nl80211_channel_type channel_type); +extern const char *iftype_name(enum nl80211_iftype iftype); +/* + * WEXT helper routines + */ /* Format driver TX power information */ static inline char *format_txpower(const struct iw_param *txpwr) { diff --git a/iw_nl80211.c b/iw_nl80211.c new file mode 100644 index 0000000..5b9c562 --- /dev/null +++ b/iw_nl80211.c @@ -0,0 +1,730 @@ +/* + * FIXME: + * PROTOTYPE: add nl80211 calls to iw_if. Mostly copied/stolen from iw + */ +#include "wavemon.h" +#include <net/if.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> + +#include "iw_nl80211.h" + +/** + * handle_cmd: process @cmd + * Returns 0 if ok, -errno < 0 on failure + * stolen/modified from iw:iw.c + */ +int handle_cmd(struct cmd *cmd) +{ + struct nl_cb *cb; + struct nl_msg *msg; + static int nl80211_id = -1; + int ret; + uint32_t ifindex, idx; + + /* + * Initialization of static components: + * - per-cmd socket + * - global nl80211 ID + * - per-cmd interface index (in case conf_ifname() changes) + */ + if (!cmd->sk) { + cmd->sk = nl_socket_alloc(); + if (!cmd->sk) + err_sys("failed to allocate netlink socket"); + + /* NB: not setting sk buffer size, using default 32Kb */ + if (genl_connect(cmd->sk)) + err_sys("failed to connect to GeNetlink"); + } + + if (nl80211_id < 0) { + nl80211_id = genl_ctrl_resolve(cmd->sk, "nl80211"); + if (nl80211_id < 0) + err_sys("nl80211 not found"); + } + + ifindex = if_nametoindex(conf_ifname()); + if (ifindex == 0 && errno) + err_sys("failed to look up interface %s", conf_ifname()); + + /* + * Message Preparation + */ + msg = nlmsg_alloc(); + if (!msg) + err_sys("failed to allocate netlink message"); + + cb = nl_cb_alloc(IW_NL_CB_DEBUG ? NL_CB_DEBUG : NL_CB_DEFAULT); + if (!cb) + err_sys("failed to allocate netlink callback"); + + genlmsg_put(msg, 0, 0, nl80211_id, 0, cmd->flags, cmd->cmd, 0); + + /* netdev identifier: interface index */ + NLA_PUT(msg, NL80211_ATTR_IFINDEX, sizeof(ifindex), &ifindex); + + /* Additional attributes */ + if (cmd->msg_args) { + for (idx = 0; idx < cmd->msg_args_len; idx++) + NLA_PUT(msg, cmd->msg_args[idx].type, + cmd->msg_args[idx].len, + cmd->msg_args[idx].data); + } + + ret = nl_send_auto_complete(cmd->sk, msg); + if (ret < 0) + err_sys("failed to send netlink message"); + + /*------------------------------------------------------------------------- + * Receive loop + *-------------------------------------------------------------------------*/ + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &ret); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &ret); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &ret); + if (cmd->handler) + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, cmd->handler, cmd->handler_arg); + + while (ret > 0) + nl_recvmsgs(cmd->sk, cb); + + nl_cb_put(cb); + nlmsg_free(msg); + goto out; + +nla_put_failure: + err_quit("failed to add attribute to netlink message"); +out: + return ret; +} + +/* + * STATION COMMANDS + */ +/* stolen from iw:station.c */ +void parse_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen) +{ + int rate = 0; + char *pos = buf; + struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; + static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { + [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 }, + [NL80211_RATE_INFO_BITRATE32] = { .type = NLA_U32 }, + [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 }, + [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG }, + [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, + }; + + if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, + bitrate_attr, rate_policy)) { + snprintf(buf, buflen, "failed to parse nested rate attributes!"); + return; + } + + if (rinfo[NL80211_RATE_INFO_BITRATE32]) + rate = nla_get_u32(rinfo[NL80211_RATE_INFO_BITRATE32]); + else if (rinfo[NL80211_RATE_INFO_BITRATE]) + rate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); + if (rate > 0) + pos += snprintf(pos, buflen - (pos - buf), + "%d.%d MBit/s", rate / 10, rate % 10); + + if (rinfo[NL80211_RATE_INFO_MCS]) + pos += snprintf(pos, buflen - (pos - buf), + " MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_MCS])); + if (rinfo[NL80211_RATE_INFO_VHT_MCS]) + pos += snprintf(pos, buflen - (pos - buf), + " VHT-MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_MCS])); + if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) + pos += snprintf(pos, buflen - (pos - buf), " 40MHz"); + if (rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH]) + pos += snprintf(pos, buflen - (pos - buf), " 80MHz"); + if (rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH]) + pos += snprintf(pos, buflen - (pos - buf), " 80P80MHz"); + if (rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH]) + pos += snprintf(pos, buflen - (pos - buf), " 160MHz"); + if (rinfo[NL80211_RATE_INFO_SHORT_GI]) + pos += snprintf(pos, buflen - (pos - buf), " short GI"); + if (rinfo[NL80211_RATE_INFO_VHT_NSS]) + pos += snprintf(pos, buflen - (pos - buf), + " VHT-NSS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS])); +} + +/* + * INTERFACE COMMANDS + */ +void print_ssid_escaped(char *buf, const size_t buflen, + const uint8_t *data, const size_t datalen) +{ + int i, l; + + memset(buf, '\0', buflen); + /* Treat zeroed-out SSIDs separately */ + for (i = 0; i < datalen && data[i] == '\0'; i++) + ; + if (i == datalen) + return; + + for (i = l= 0; i < datalen; i++) { + if (l + 4 >= buflen) + return; + else if (isprint(data[i]) && data[i] != ' ' && data[i] != '\\') + l += sprintf(buf + l, "%c", data[i]); + else if (data[i] == ' ' && i != 0 && i != datalen -1) + l += sprintf(buf + l, " "); + else + l += sprintf(buf + l, "\\x%.2x", data[i]); + } +} + +/* stolen from iw:interface.c */ +static int iface_handler(struct nl_msg *msg, void *arg) +{ + struct iw_nl80211_ifstat *ifs = (struct iw_nl80211_ifstat *)arg; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + + assert(ifs != NULL); + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (tb_msg[NL80211_ATTR_WIPHY]) + ifs->phy = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]); + + if (tb_msg[NL80211_ATTR_IFINDEX]) + ifs->ifindex = nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX]); + + if (tb_msg[NL80211_ATTR_WDEV]) + ifs->wdev = nla_get_u64(tb_msg[NL80211_ATTR_WDEV]); + if (tb_msg[NL80211_ATTR_SSID]) + print_ssid_escaped(ifs->ssid, sizeof(ifs->ssid), + nla_data(tb_msg[NL80211_ATTR_SSID]), + nla_len(tb_msg[NL80211_ATTR_SSID])); + + if (tb_msg[NL80211_ATTR_IFTYPE]) + ifs->iftype = nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]); + + ifs->chan_width = -1; + ifs->chan_type = -1; + if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) { + ifs->freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]); + + if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) { + ifs->chan_width = nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH]); + + if (tb_msg[NL80211_ATTR_CENTER_FREQ1]) + ifs->freq_ctr1 = nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1]); + if (tb_msg[NL80211_ATTR_CENTER_FREQ2]) + ifs->freq_ctr2 = nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2]); + + } + if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) + ifs->chan_type = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); + } + + return NL_SKIP; +} + +/** + * survey_handler - channel survey data + * This handler will be called multiple times, for each channel. + * stolen from iw:survey.c + */ +static int survey_handler(struct nl_msg *msg, void *arg) +{ + struct iw_nl80211_survey *sd = (struct iw_nl80211_survey *)arg; + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; + + static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = { + [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 }, + [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 }, + [NL80211_SURVEY_INFO_IN_USE] = { .type = NLA_FLAG }, + [NL80211_SURVEY_INFO_TIME] = { .type = NLA_U64 }, + [NL80211_SURVEY_INFO_TIME_BUSY] = { .type = NLA_U64 }, + [NL80211_SURVEY_INFO_TIME_EXT_BUSY] = { .type = NLA_U64 }, + [NL80211_SURVEY_INFO_TIME_RX] = { .type = NLA_U64 }, + [NL80211_SURVEY_INFO_TIME_TX] = { .type = NLA_U64 }, + [NL80211_SURVEY_INFO_TIME_SCAN] = { .type = NLA_U64 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_SURVEY_INFO]) + return NL_SKIP; + + if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX, + tb[NL80211_ATTR_SURVEY_INFO], survey_policy)) + return NL_SKIP; + + /* The frequency is needed to match up with the associated station */ + if (!sinfo[NL80211_SURVEY_INFO_FREQUENCY]) + return NL_SKIP; + + /* We are only interested in the data of the operating channel */ + if (!sinfo[NL80211_SURVEY_INFO_IN_USE]) + return NL_SKIP; + + sd->freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]); + + if (sinfo[NL80211_SURVEY_INFO_NOISE]) + sd->noise = (int8_t)nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]); + + if (sinfo[NL80211_SURVEY_INFO_TIME]) + sd->time.active = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]); + + if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY]) + sd->time.busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]); + + if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]) + sd->time.ext_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]); + + if (sinfo[NL80211_SURVEY_INFO_TIME_RX]) + sd->time.rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]); + + if (sinfo[NL80211_SURVEY_INFO_TIME_TX]) + sd->time.tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]); + + if (sinfo[NL80211_SURVEY_INFO_TIME_SCAN]) + sd->time.scan = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_SCAN]); + + return NL_SKIP; +} + +/* Regulatory domain, stolen from iw:reg.c */ +static int reg_handler(struct nl_msg *msg, void *arg) +{ + struct iw_nl80211_reg *ir = (struct iw_nl80211_reg *)arg; + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + char *alpha2; + + ir->region = -1; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) + return NL_SKIP; + + if (!tb_msg[NL80211_ATTR_REG_RULES]) + return NL_SKIP; + + if (tb_msg[NL80211_ATTR_DFS_REGION]) + ir->region = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]); + else + ir->region = NL80211_DFS_UNSET; + + alpha2 = nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]); + ir->country[0] = alpha2[0]; + ir->country[1] = alpha2[1]; + + return NL_SKIP; +} + +static int link_handler(struct nl_msg *msg, void *arg) +{ + struct iw_nl80211_linkstat *ls = arg; + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *bss[NL80211_BSS_MAX + 1]; + static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { + [NL80211_BSS_TSF] = { .type = NLA_U64 }, + [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, + [NL80211_BSS_BSSID] = { }, + [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 }, + [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 }, + [NL80211_BSS_INFORMATION_ELEMENTS] = { }, + [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 }, + [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 }, + [NL80211_BSS_STATUS] = { .type = NLA_U32 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_BSS]) + return NL_SKIP; + + if (nla_parse_nested(bss, NL80211_BSS_MAX, tb[NL80211_ATTR_BSS], bss_policy)) + return NL_SKIP; + + if (!bss[NL80211_BSS_BSSID]) + return NL_SKIP; + + if (!bss[NL80211_BSS_STATUS]) + return NL_SKIP; + + if (bss[NL80211_BSS_SIGNAL_UNSPEC]) + ls->bss_signal_qual = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); + + if (bss[NL80211_BSS_SIGNAL_MBM]) { + int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]); + ls->bss_signal = s / 100; + } + + ls->status = nla_get_u32(bss[NL80211_BSS_STATUS]); + switch (ls->status) { + case NL80211_BSS_STATUS_ASSOCIATED: /* apparently no longer used */ + case NL80211_BSS_STATUS_AUTHENTICATED: + case NL80211_BSS_STATUS_IBSS_JOINED: + memcpy(&ls->bssid, nla_data(bss[NL80211_BSS_BSSID]), ETH_ALEN); + } + + return NL_SKIP; +} + +static int link_sta_handler(struct nl_msg *msg, void *arg) +{ + struct iw_nl80211_linkstat *ls = arg; + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; + struct nlattr *binfo[NL80211_STA_BSS_PARAM_MAX + 1]; + struct nl80211_sta_flag_update *sta_flags; + static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { + [NL80211_STA_INFO_CONNECTED_TIME] = { .type = NLA_U32 }, + [NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 }, + [NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 }, + [NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 }, + [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 }, + [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 }, + [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 }, + [NL80211_STA_INFO_SIGNAL_AVG] = { .type = NLA_U8 }, + [NL80211_STA_INFO_T_OFFSET] = { .type = NLA_U64 }, + [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED }, + [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED }, + [NL80211_STA_INFO_RX_DROP_MISC] = { .type = NLA_U64 }, + [NL80211_STA_INFO_BEACON_RX] = { .type = NLA_U64 }, + [NL80211_STA_INFO_BEACON_LOSS] = { .type = NLA_U32 }, + [NL80211_STA_INFO_BEACON_SIGNAL_AVG] = { .type = NLA_U8 }, + [NL80211_STA_INFO_LLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 }, + [NL80211_STA_INFO_TX_RETRIES] = { .type = NLA_U32 }, + [NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 }, + [NL80211_STA_INFO_STA_FLAGS] = + { .minlen = sizeof(struct nl80211_sta_flag_update) }, + [NL80211_STA_INFO_LOCAL_PM] = { .type = NLA_U32}, + [NL80211_STA_INFO_PEER_PM] = { .type = NLA_U32}, + [NL80211_STA_INFO_NONPEER_PM] = { .type = NLA_U32}, + [NL80211_STA_INFO_CHAIN_SIGNAL] = { .type = NLA_NESTED }, + [NL80211_STA_INFO_CHAIN_SIGNAL_AVG] = { .type = NLA_NESTED }, + }; + static struct nla_policy bss_policy[NL80211_STA_BSS_PARAM_MAX + 1] = { + [NL80211_STA_BSS_PARAM_CTS_PROT] = { .type = NLA_FLAG }, + [NL80211_STA_BSS_PARAM_SHORT_PREAMBLE] = { .type = NLA_FLAG }, + [NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME] = { .type = NLA_FLAG }, + [NL80211_STA_BSS_PARAM_DTIM_PERIOD] = { .type = NLA_U8 }, + [NL80211_STA_BSS_PARAM_BEACON_INTERVAL] = { .type = NLA_U16 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_STA_INFO]) + return NL_SKIP; + + if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, + tb[NL80211_ATTR_STA_INFO], + stats_policy)) + return NL_SKIP; + + if (sinfo[NL80211_STA_INFO_TX_RETRIES]) + ls->tx_retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]); + if (sinfo[NL80211_STA_INFO_TX_FAILED]) + ls->tx_failed = nla_get_u32(sinfo[NL80211_STA_INFO_TX_FAILED]); + + + if (sinfo[NL80211_STA_INFO_EXPECTED_THROUGHPUT]) { + ls->expected_thru = nla_get_u32(sinfo[NL80211_STA_INFO_EXPECTED_THROUGHPUT]); + /* convert in Mbps but scale by 1000 to save kbps units */ + ls->expected_thru = ls->expected_thru * 1000 / 1024; + } + if (sinfo[NL80211_STA_INFO_INACTIVE_TIME]) + ls->inactive_time = nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME]); + if (sinfo[NL80211_STA_INFO_CONNECTED_TIME]) + ls->connected_time = nla_get_u32(sinfo[NL80211_STA_INFO_CONNECTED_TIME]); + + if (sinfo[NL80211_STA_INFO_RX_BYTES]) + ls->rx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]); + if (sinfo[NL80211_STA_INFO_RX_PACKETS]) + ls->rx_packets = nla_get_u32(sinfo[NL80211_STA_INFO_RX_PACKETS]); + if (sinfo[NL80211_STA_INFO_RX_DROP_MISC]) + ls->rx_drop_misc = nla_get_u64(sinfo[NL80211_STA_INFO_RX_DROP_MISC]); + + if (sinfo[NL80211_STA_INFO_TX_BYTES]) + ls->tx_bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]); + if (sinfo[NL80211_STA_INFO_TX_PACKETS]) + ls->tx_packets = nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS]); + + if (sinfo[NL80211_STA_INFO_SIGNAL]) + ls->signal = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]); + if (sinfo[NL80211_STA_INFO_SIGNAL_AVG]) + ls->signal_avg = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]); + + + if (sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]) + ls->beacon_avg_sig = nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]); + if (sinfo[NL80211_STA_INFO_BEACON_RX]) + ls->beacons = nla_get_u64(sinfo[NL80211_STA_INFO_BEACON_RX]); + if (sinfo[NL80211_STA_INFO_BEACON_LOSS]) + ls->beacon_loss = nla_get_u32(sinfo[NL80211_STA_INFO_BEACON_LOSS]); + + if (sinfo[NL80211_STA_INFO_TX_BITRATE]) + parse_bitrate(sinfo[NL80211_STA_INFO_TX_BITRATE], ls->tx_bitrate, sizeof(ls->tx_bitrate)); + + if (sinfo[NL80211_STA_INFO_RX_BITRATE]) + parse_bitrate(sinfo[NL80211_STA_INFO_RX_BITRATE], ls->rx_bitrate, sizeof(ls->rx_bitrate)); + + if (sinfo[NL80211_STA_INFO_STA_FLAGS]) { + sta_flags = (struct nl80211_sta_flag_update *) + nla_data(sinfo[NL80211_STA_INFO_STA_FLAGS]); + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) && + sta_flags->set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) + ls->long_preamble = true; + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_WME) && + sta_flags->set & BIT(NL80211_STA_FLAG_WME)) + ls->wme = true; + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_MFP) && + sta_flags->set & BIT(NL80211_STA_FLAG_MFP)) + ls->mfp = true; + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_TDLS_PEER) && + sta_flags->set & BIT(NL80211_STA_FLAG_TDLS_PEER)) + ls->tdls = true; + } + + /* BSS Flags */ + if (sinfo[NL80211_STA_INFO_BSS_PARAM]) { + if (nla_parse_nested(binfo, NL80211_STA_BSS_PARAM_MAX, + sinfo[NL80211_STA_INFO_BSS_PARAM], + bss_policy) == 0) { + if (binfo[NL80211_STA_BSS_PARAM_CTS_PROT]) { + ls->cts_protection = true; + } + if (binfo[NL80211_STA_BSS_PARAM_SHORT_PREAMBLE]) + ls->long_preamble = false; + if (binfo[NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME]) + ls->short_slot_time = true; + + ls->beacon_int = nla_get_u16(binfo[NL80211_STA_BSS_PARAM_BEACON_INTERVAL]); + ls->dtim_period = nla_get_u8(binfo[NL80211_STA_BSS_PARAM_DTIM_PERIOD]); + } + } + + return NL_SKIP; +} + +/* + * COMMAND HANDLERS + */ +void iw_nl80211_get_linkstat(struct iw_nl80211_linkstat *ls) +{ + static struct cmd cmd_linkstat = { + .cmd = NL80211_CMD_GET_SCAN, + .flags = NLM_F_DUMP, + .handler = link_handler + }; + static struct cmd cmd_getstation = { + .cmd = NL80211_CMD_GET_STATION, + .flags = 0, + .handler = link_sta_handler + }; + + struct msg_attribute station_addr = { + .type = NL80211_ATTR_MAC, + .len = sizeof(ls->bssid), + .data = &ls->bssid + }; + + cmd_linkstat.handler_arg = ls; + memset(ls, 0, sizeof(*ls)); + handle_cmd(&cmd_linkstat); + + /* If not associated to another station, the bssid is zeroed out */ + if (ether_addr_is_zero(&ls->bssid)) + return; + /* + * Details of the associated station + */ + cmd_getstation.handler_arg = ls; + cmd_getstation.msg_args = &station_addr; + cmd_getstation.msg_args_len = 1; + + handle_cmd(&cmd_getstation); + + /* Channel survey data */ + iw_nl80211_get_survey(&ls->survey); +} + +void iw_nl80211_getreg(struct iw_nl80211_reg *ir) +{ + static struct cmd cmd_reg = { + .cmd = NL80211_CMD_GET_REG, + .flags = 0, + .handler = reg_handler + }; + + cmd_reg.handler_arg = ir; + memset(ir, 0, sizeof(*ir)); + handle_cmd(&cmd_reg); +} + +void iw_nl80211_getifstat(struct iw_nl80211_ifstat *ifs) +{ + static struct cmd cmd_ifstat = { + .cmd = NL80211_CMD_GET_INTERFACE, + .flags = 0, + .handler = iface_handler + }; + + cmd_ifstat.handler_arg = ifs; + memset(ifs, 0, sizeof(*ifs)); + handle_cmd(&cmd_ifstat); +} + +void iw_nl80211_get_survey(struct iw_nl80211_survey *sd) +{ + static struct cmd cmd_survey = { + .cmd = NL80211_CMD_GET_SURVEY, + .flags = NLM_F_DUMP, + .handler = survey_handler + }; + + cmd_survey.handler_arg = sd; + memset(sd, 0, sizeof(*sd)); + handle_cmd(&cmd_survey); +} + +/* + * Multicast Handling + */ +/** + * struct handler_args - arguments to resolve multicast group + * @group: group name to resolve + * @id: ID it resolves into + */ +struct handler_args { + const char *group; + int id; +}; + +/* stolen from iw:genl.c */ +static int family_handler(struct nl_msg *msg, void *arg) +{ + struct handler_args *grp = arg; + struct nlattr *tb[CTRL_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *mcgrp; + int rem_mcgrp; + + nla_parse(tb, CTRL_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[CTRL_ATTR_MCAST_GROUPS]) + return NL_SKIP; + + nla_for_each_nested(mcgrp, tb[CTRL_ATTR_MCAST_GROUPS], rem_mcgrp) { + struct nlattr *tb_mcgrp[CTRL_ATTR_MCAST_GRP_MAX + 1]; + + nla_parse(tb_mcgrp, CTRL_ATTR_MCAST_GRP_MAX, + nla_data(mcgrp), nla_len(mcgrp), NULL); + + if (!tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME] || + !tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]) + continue; + if (strncmp(nla_data(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]), + grp->group, nla_len(tb_mcgrp[CTRL_ATTR_MCAST_GRP_NAME]))) + continue; + grp->id = nla_get_u32(tb_mcgrp[CTRL_ATTR_MCAST_GRP_ID]); + break; + } + + return NL_SKIP; +} + +/* stolen from iw:genl.c */ +int nl_get_multicast_id(struct nl_sock *sock, const char *family, const char *group) +{ + struct nl_msg *msg; + struct nl_cb *cb; + int ret, ctrlid; + struct handler_args grp = { + .group = group, + .id = -ENOENT, + }; + + msg = nlmsg_alloc(); + if (!msg) + return -ENOMEM; + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + ret = -ENOMEM; + goto out_fail_cb; + } + + ctrlid = genl_ctrl_resolve(sock, "nlctrl"); + + genlmsg_put(msg, 0, 0, ctrlid, 0, + 0, CTRL_CMD_GETFAMILY, 0); + + ret = -ENOBUFS; + NLA_PUT_STRING(msg, CTRL_ATTR_FAMILY_NAME, family); + + ret = nl_send_auto_complete(sock, msg); + if (ret < 0) + goto out; + + ret = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &ret); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &ret); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, family_handler, &grp); + + while (ret > 0) + nl_recvmsgs(sock, cb); + + if (ret == 0) + ret = grp.id; +nla_put_failure: +out: + nl_cb_put(cb); +out_fail_cb: + nlmsg_free(msg); + return ret; +} + +/** + * Allocate a GeNetlink socket ready to listen for nl80211 multicast group @grp + * @grp: identifier of an nl80211 multicast group (e.g. "scan") + */ +struct nl_sock *alloc_nl_mcast_sk(const char *grp) +{ + int mcid, ret; + struct nl_sock *sk = nl_socket_alloc(); + + if (!sk) + err_sys("failed to allocate netlink multicast socket"); + + if (genl_connect(sk)) + err_sys("failed to connect multicast socket to GeNetlink"); + + mcid = nl_get_multicast_id(sk, "nl80211", grp); + if (mcid < 0) + err_quit("failed to resolve nl80211 '%s' multicast group", grp); + + ret = nl_socket_add_membership(sk, mcid); + if (ret) + err_sys("failed to join nl80211 multicast group %s", grp); + + return sk; +} diff --git a/iw_nl80211.h b/iw_nl80211.h new file mode 100644 index 0000000..b1c295f --- /dev/null +++ b/iw_nl80211.h @@ -0,0 +1,271 @@ +/* + * Definitions and functions for nl80211 based routines. + */ +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> + +#include <netinet/ether.h> +#include <stdbool.h> + +/* + * Use local copy of nl80211.h rather than the one shipped with the distro in + * /usr/include/linux. There are different versions, local one may be out of date. + */ +#include "nl80211.h" + +#define BIT(x) (1ULL<<(x)) /* from iw:iw.h */ + +/* Set to 1 to enable callback debugging */ +#define IW_NL_CB_DEBUG 0 + + +/** + * struct msg_attribute - attributes to nla_put into the message + * @type: type of the attribute + * @len: attribute length + * @data: pointer to data area of length @len + */ +struct msg_attribute { + int type, + len; + const void *data; +}; + +/** + * struct cmd - stolen and modified from iw:iw.h + * @cmd: nl80211 command to send via GeNetlink + * @sk: netlink socket to be used for this command + * @flags: flags to set in the GeNetlink message + * @handler: netlink callback handler + * @handler_arg: argument for @handler + * @msg_args: additional attributes to pass into message + * @msg_args_len: number of elements in @msg_args + */ +struct cmd { + enum nl80211_commands cmd; + struct nl_sock *sk; + int flags; + int (*handler)(struct nl_msg *msg, void *arg); + void *handler_arg; + + struct msg_attribute *msg_args; + uint8_t msg_args_len; +}; +extern int handle_cmd(struct cmd *cmd); + +/** + * iw_nl80211_ifstat - interface statistics + * @phy: PHY index + * @ifindex: ifindex of receiving interface + * @wdev: wireless device index + * @iftype: interface mode (access point ...) + * + * @freq: frequency in MHz + * @chan_width: channel width + * @chan_type: channel type + * @freq_ctr1: center frequency #1 + * @freq_ctr2: center frequency #2 + */ +struct iw_nl80211_ifstat { + uint32_t phy, + ifindex, + wdev, + iftype; + + char ssid[64]; + + uint32_t freq; + int chan_width, + chan_type, + freq_ctr1, + freq_ctr2; +}; +extern void iw_nl80211_getifstat(struct iw_nl80211_ifstat *is); + +/** + * struct iw_nl80211_survey_data - channel survey data + * @freq: channel frequency (only filled in if it is in use) + * @noise: channel noise in dBm (0 means invalid data) + * + * @active: amount of time that the radio was on + * @busy: amount of the time the primary channel was sensed busy + * @ext_busy: amount of time the extension channel was sensed busy + * @rx: amount of time the radio spent receiving data + * @tx: amount of time the radio spent transmitting data + * @scan: time the radio spent for scan + */ +struct iw_nl80211_survey { + uint32_t freq; + int8_t noise; + + struct time_data_in_milliseconds { + uint64_t active, + busy, + ext_busy, + rx, + tx, + scan; + } time; +}; +extern void iw_nl80211_get_survey(struct iw_nl80211_survey *sd); + +/* struct iw_nl80211_linkstat - aggregate link statistics + * @status: association status (%nl80211_bss_status) + * @bssid: station MAC address + * @inactive_time: inactivity in msec + * @connected_time: time since last connecting in sec + * @beacon_loss: count of time beacon loss was detected + * @rx_bytes/packets: byte/packet counter for RX direction + * @rx_drop_misc: packets dropped for unspecified reasons + * @tx_bytes/packets: byte/packet counter for TX direction + * @tx_retries: TX retry counter + * @tx_failed: TX failure counter + * @expected_thru: expected throughput in kB/s + * @beacon_int: beacon interval in Time Units of 1024usec + * @dtim_period: DTIM period for beaconing + * @beacon_avg_sig: average beacon signal (in dBm) + * @beacons: number of beacons received + * @beacon_loss: count of times beacon loss was detected + * @signal: signal strength in dBm (0 if not present) + * @signal_avg: average signal strength in dBm + * @bss_signal: signal strength of BSS probe in dBm (or 0) + * @bss_signal_qual: unitless signal strength of BSS probe, 0..100 + * @tx_bitrate: string describing current TX bitrate + * @rx_bitrate: string describing current RX bitrate + * @cts_protection: whether CTS protection is set + * @long_preamble: whether using long or short preamble + * @short_slot_time: whether short slots are enabled + * @wme: Wireless Multimedia Extensions / Wi-Fi Multimedia + * @mfp: Management Frame Protection + * @tdls: Tunneled Direct Link Setup + * @survey: channel survey data (where present) + */ +struct iw_nl80211_linkstat { + uint32_t status; + struct ether_addr bssid; + /* + * Station details (not always filled in): + */ + uint32_t inactive_time, + connected_time, + rx_bytes, + rx_packets; + uint64_t rx_drop_misc; + + uint16_t beacon_int; + uint8_t dtim_period, + beacon_avg_sig; + uint64_t beacons; + uint32_t beacon_loss; + + uint32_t tx_bytes, + tx_packets, + tx_retries, + tx_failed; + + uint32_t expected_thru; + int8_t signal, + signal_avg; + + int8_t bss_signal; + uint8_t bss_signal_qual; + + char tx_bitrate[100], + rx_bitrate[100]; + + bool cts_protection:1, + long_preamble:1, + short_slot_time:1, + wme:1, + mfp:1, + tdls:1; + /* + * Channel survey data (requires suitable card, e.g. ath9k). + */ + struct iw_nl80211_survey survey; +}; +extern void iw_nl80211_get_linkstat(struct iw_nl80211_linkstat *ls); +extern void iw_cache_update(struct iw_nl80211_linkstat *ls); + +/* Indicate whether @ls contains usable channel survey data */ +static inline bool iw_nl80211_have_survey_data(struct iw_nl80211_linkstat *ls) +{ + return ls->survey.freq != 0 && ls->survey.noise != 0; +} + +/** + * struct iw_nl80211_reg - regulatory domain information + * @region: regulatory DFS region (%nl80211_dfs_regions or -1) + * @country: two-character country code + */ +struct iw_nl80211_reg { + int region; + char country[3]; +}; +extern void iw_nl80211_getreg(struct iw_nl80211_reg *ir); +extern void print_ssid_escaped(char *buf, const size_t buflen, + const uint8_t *data, const size_t datalen); + +/* + * Multicast event handling (taken from iw:event.c and iw:scan.c) + */ +/** + * struct wait_event - wait for arrival of a specified message + * @cmds: array of GeNetlink commands (>0) to match + * @n_cmds: length of @cmds + * @cmd: matched element of @cmds (if message arrived), else 0 + */ +struct wait_event { + const uint32_t *cmds; + uint8_t n_cmds; + uint32_t cmd; +}; +extern struct nl_sock *alloc_nl_mcast_sk(const char *grp); + +/* + * utils.c + */ +extern bool ether_addr_is_zero(const struct ether_addr *ea); + +/* + * (Ge)Netlink and nl80211 Internals + */ +// stolen from iw:station.c +enum plink_state { + LISTEN, + OPN_SNT, + OPN_RCVD, + CNF_RCVD, + ESTAB, + HOLDING, + BLOCKED +}; + +/* Predefined handlers, stolen from iw:iw.c */ +static inline int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = arg; + *ret = err->error; + return NL_STOP; +} + +static inline int finish_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_SKIP; +} + +static inline int ack_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_STOP; +} + +static inline int no_seq_check(struct nl_msg *msg, void *arg) +{ + return NL_OK; +} @@ -6,547 +6,14 @@ */ #include "iw_if.h" #include <search.h> /* lsearch(3) */ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include "iw_nl80211.h" -#define MAX_SCAN_WAIT 10000 /* maximum milliseconds spent waiting */ +/* GLOBAL VARIABLES */ +static struct nl_sock *scan_wait_sk; -/* - * Meta-data about all the additional standard Wireless Extension events - * we know about. - */ -/* Type of headers we know about (basically union iwreq_data) */ -#define IW_HEADER_TYPE_NULL 0 /* Not available */ -#define IW_HEADER_TYPE_CHAR 2 /* char [IFNAMSIZ] */ -#define IW_HEADER_TYPE_UINT 4 /* __u32 */ -#define IW_HEADER_TYPE_FREQ 5 /* struct iw_freq */ -#define IW_HEADER_TYPE_ADDR 6 /* struct sockaddr */ -#define IW_HEADER_TYPE_POINT 8 /* struct iw_point */ -#define IW_HEADER_TYPE_PARAM 9 /* struct iw_param */ -#define IW_HEADER_TYPE_QUAL 10 /* struct iw_quality */ - -/* Size (in bytes) of various events */ -static const int event_type_size[] = { - [IW_HEADER_TYPE_NULL] = IW_EV_LCP_PK_LEN, - [IW_HEADER_TYPE_CHAR] = IW_EV_CHAR_PK_LEN, - [IW_HEADER_TYPE_UINT] = IW_EV_UINT_PK_LEN, - [IW_HEADER_TYPE_FREQ] = IW_EV_FREQ_PK_LEN, - [IW_HEADER_TYPE_ADDR] = IW_EV_ADDR_PK_LEN, - /* - * Fix IW_EV_POINT_PK_LEN: some wireless.h versions define this - * erroneously as IW_EV_LCP_LEN + 4 (e.g. ESSID will disappear). - * The value below is from wireless tools 30. - */ - [IW_HEADER_TYPE_POINT] = IW_EV_LCP_PK_LEN + 4, - [IW_HEADER_TYPE_PARAM] = IW_EV_PARAM_PK_LEN, - [IW_HEADER_TYPE_QUAL] = IW_EV_QUAL_PK_LEN -}; - -/* Handling flags */ -#define IW_DESCR_FLAG_NONE 0x0000 /* Obvious */ -/* Wrapper level flags */ -#define IW_DESCR_FLAG_DUMP 0x0001 /* Not part of the dump command */ -#define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */ -#define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */ - /* SET : Omit payload from generated iwevent */ -#define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */ -/* Driver level flags */ -#define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */ - -struct iw_ioctl_description { - __u8 header_type; /* NULL, iw_point or other */ - __u8 token_type; /* Future */ - __u16 token_size; /* Granularity of payload */ - __u16 min_tokens; /* Min acceptable token number */ - __u16 max_tokens; /* Max acceptable token number */ - __u32 flags; /* Special handling of the request */ -}; - -/* - * Meta-data about all the standard Wireless Extension request we - * know about. - */ -static const struct iw_ioctl_description standard_ioctl_descr[] = { - [SIOCSIWCOMMIT - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_NULL, - }, - [SIOCGIWNAME - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_CHAR, - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWNWID - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - .flags = IW_DESCR_FLAG_EVENT, - }, - [SIOCGIWNWID - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWFREQ - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_FREQ, - .flags = IW_DESCR_FLAG_EVENT, - }, - [SIOCGIWFREQ - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_FREQ, - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWMODE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_UINT, - .flags = IW_DESCR_FLAG_EVENT, - }, - [SIOCGIWMODE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_UINT, - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWSENS - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWSENS - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCSIWRANGE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_NULL, - }, - [SIOCGIWRANGE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = sizeof(struct iw_range), - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWPRIV - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_NULL, - }, - [SIOCGIWPRIV - SIOCIWFIRST] = { /* (handled directly by us) */ - .header_type = IW_HEADER_TYPE_NULL, - }, - [SIOCSIWSTATS - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_NULL, - }, - [SIOCGIWSTATS - SIOCIWFIRST] = { /* (handled directly by us) */ - .header_type = IW_HEADER_TYPE_NULL, - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWSPY - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = sizeof(struct sockaddr), - .max_tokens = IW_MAX_SPY, - }, - [SIOCGIWSPY - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = sizeof(struct sockaddr) + - sizeof(struct iw_quality), - .max_tokens = IW_MAX_SPY, - }, - [SIOCSIWTHRSPY - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = sizeof(struct iw_thrspy), - .min_tokens = 1, - .max_tokens = 1, - }, - [SIOCGIWTHRSPY - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = sizeof(struct iw_thrspy), - .min_tokens = 1, - .max_tokens = 1, - }, - [SIOCSIWAP - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_ADDR, - }, - [SIOCGIWAP - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_ADDR, - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWMLME - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .min_tokens = sizeof(struct iw_mlme), - .max_tokens = sizeof(struct iw_mlme), - }, - [SIOCGIWAPLIST - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = sizeof(struct sockaddr) + - sizeof(struct iw_quality), - .max_tokens = IW_MAX_AP, - .flags = IW_DESCR_FLAG_NOMAX, - }, - [SIOCSIWSCAN - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .min_tokens = 0, - .max_tokens = sizeof(struct iw_scan_req), - }, - [SIOCGIWSCAN - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_SCAN_MAX_DATA, - .flags = IW_DESCR_FLAG_NOMAX, - }, - [SIOCSIWESSID - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_ESSID_MAX_SIZE + 1, - .flags = IW_DESCR_FLAG_EVENT, - }, - [SIOCGIWESSID - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_ESSID_MAX_SIZE + 1, - .flags = IW_DESCR_FLAG_DUMP, - }, - [SIOCSIWNICKN - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_ESSID_MAX_SIZE + 1, - }, - [SIOCGIWNICKN - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_ESSID_MAX_SIZE + 1, - }, - [SIOCSIWRATE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWRATE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCSIWRTS - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWRTS - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCSIWFRAG - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWFRAG - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCSIWTXPOW - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWTXPOW - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCSIWRETRY - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWRETRY - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCSIWENCODE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_ENCODING_TOKEN_MAX, - .flags = IW_DESCR_FLAG_EVENT | IW_DESCR_FLAG_RESTRICT, - }, - [SIOCGIWENCODE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_ENCODING_TOKEN_MAX, - .flags = IW_DESCR_FLAG_DUMP | IW_DESCR_FLAG_RESTRICT, - }, - [SIOCSIWPOWER - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWPOWER - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, -#ifdef SIOCSIWMODUL - [SIOCSIWMODUL - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, -#endif -#ifdef SIOCGIWMODUL - [SIOCGIWMODUL - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, -#endif - [SIOCSIWGENIE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_GENERIC_IE_MAX, - }, - [SIOCGIWGENIE - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_GENERIC_IE_MAX, - }, - [SIOCSIWAUTH - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCGIWAUTH - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_PARAM, - }, - [SIOCSIWENCODEEXT - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .min_tokens = sizeof(struct iw_encode_ext), - .max_tokens = sizeof(struct iw_encode_ext) + - IW_ENCODING_TOKEN_MAX, - }, - [SIOCGIWENCODEEXT - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .min_tokens = sizeof(struct iw_encode_ext), - .max_tokens = sizeof(struct iw_encode_ext) + - IW_ENCODING_TOKEN_MAX, - }, - [SIOCSIWPMKSA - SIOCIWFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .min_tokens = sizeof(struct iw_pmksa), - .max_tokens = sizeof(struct iw_pmksa), - }, -}; - -static const struct iw_ioctl_description standard_event_descr[] = { - [IWEVTXDROP - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_ADDR, - }, - [IWEVQUAL - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_QUAL, - }, - [IWEVCUSTOM - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_CUSTOM_MAX, - }, - [IWEVREGISTERED - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_ADDR, - }, - [IWEVEXPIRED - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_ADDR, - }, - [IWEVGENIE - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_GENERIC_IE_MAX, - }, - [IWEVMICHAELMICFAILURE - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = sizeof(struct iw_michaelmicfailure), - }, - [IWEVASSOCREQIE - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_GENERIC_IE_MAX, - }, - [IWEVASSOCRESPIE - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = IW_GENERIC_IE_MAX, - }, - [IWEVPMKIDCAND - IWEVFIRST] = { - .header_type = IW_HEADER_TYPE_POINT, - .token_size = 1, - .max_tokens = sizeof(struct iw_pmkid_cand), - }, -}; - -struct stream_descr { - char *current; /* Current event in stream of events */ - char *value; /* Current value in event */ - char *end; /* End of the stream */ -}; - -/* - * Extract the next event from the event stream. - */ -static int iw_extract_event_stream(struct stream_descr *stream, - struct iw_event *iwe, int we_version) -{ - const struct iw_ioctl_description *descr = NULL; - int event_type; - unsigned int event_len = 1; /* Invalid */ - unsigned cmd_index; /* *MUST* be unsigned */ - char *pointer; - - if (stream->current + IW_EV_LCP_PK_LEN > stream->end) - return 0; - - /* Extract the event header to get the event id. - * Note : the event may be unaligned, therefore copy... */ - memcpy((char *)iwe, stream->current, IW_EV_LCP_PK_LEN); - - if (iwe->len <= IW_EV_LCP_PK_LEN) - return -1; - - /* Get the type and length of that event */ - if (iwe->cmd <= SIOCIWLAST) { - cmd_index = iwe->cmd - SIOCIWFIRST; - if (cmd_index < ARRAY_SIZE(standard_ioctl_descr)) - descr = standard_ioctl_descr + cmd_index; - } else { - cmd_index = iwe->cmd - IWEVFIRST; - if (cmd_index < ARRAY_SIZE(standard_event_descr)) - descr = standard_event_descr + cmd_index; - } - - /* Unknown events -> event_type = 0 => IW_EV_LCP_PK_LEN */ - event_type = descr ? descr->header_type : 0; - event_len = event_type_size[event_type]; - - /* Check if we know about this event */ - if (event_len <= IW_EV_LCP_PK_LEN) { - stream->current += iwe->len; /* Skip to next event */ - return 2; - } - event_len -= IW_EV_LCP_PK_LEN; - - /* Fixup for earlier version of WE */ - if (we_version <= 18 && event_type == IW_HEADER_TYPE_POINT) - event_len += IW_EV_POINT_OFF; - - if (stream->value != NULL) - pointer = stream->value; /* Next value in event */ - else - pointer = stream->current + IW_EV_LCP_PK_LEN; /* First value in event */ - - /* Copy the rest of the event (at least, fixed part) */ - if (pointer + event_len > stream->end) { - stream->current += iwe->len; /* Skip to next event */ - return -2; - } - - /* Fixup for WE-19 and later: pointer no longer in the stream */ - /* Beware of alignment. Dest has local alignment, not packed */ - if (we_version > 18 && event_type == IW_HEADER_TYPE_POINT) - memcpy((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pointer, event_len); - else - memcpy((char *)iwe + IW_EV_LCP_LEN, pointer, event_len); - - /* Skip event in the stream */ - pointer += event_len; - - /* Special processing for iw_point events */ - if (event_type == IW_HEADER_TYPE_POINT) { - unsigned int extra_len = iwe->len - (event_len + IW_EV_LCP_PK_LEN); - - if (extra_len > 0) { - /* Set pointer on variable part (warning : non aligned) */ - iwe->u.data.pointer = pointer; - - /* Check that we have a descriptor for the command */ - if (descr == NULL) { - /* Can't check payload -> unsafe... */ - iwe->u.data.pointer = NULL; /* Discard paylod */ - } else { - unsigned int token_len = iwe->u.data.length * descr->token_size; - /* - * Ugly fixup for alignment issues. - * If the kernel is 64 bits and userspace 32 bits, we have an extra 4 + 4 - * bytes. Fixing that in the kernel would break 64 bits userspace. - */ - if (token_len != extra_len && extra_len >= 4) { - union iw_align_u16 { - __u16 value; - unsigned char byte[2]; - } alt_dlen; - unsigned int alt_token_len; - - /* Userspace seems to not always like unaligned access, - * so be careful and make sure to align value. - * I hope gcc won't play any of its aliasing tricks... */ - alt_dlen.byte[0] = *(pointer); - alt_dlen.byte[1] = *(pointer + 1); - alt_token_len = alt_dlen.value * descr->token_size; - - /* Verify that data is consistent if assuming 64 bit alignment... */ - if (alt_token_len + 8 == extra_len) { - - /* Ok, let's redo everything */ - pointer -= event_len; - pointer += 4; - - /* Dest has local alignment, not packed */ - memcpy((char *)iwe + IW_EV_LCP_LEN + IW_EV_POINT_OFF, pointer, event_len); - pointer += event_len + 4; - token_len = alt_token_len; - - /* We may have no payload */ - if (alt_token_len) - iwe->u.data.pointer = pointer; - else - iwe->u.data.pointer = NULL; - } - } - - /* Discard bogus events which advertise more tokens than they carry ... */ - if (token_len > extra_len) - iwe->u.data.pointer = NULL; /* Discard paylod */ - - /* Check that the advertised token size is not going to - * produce buffer overflow to our caller... */ - if (iwe->u.data.length > descr->max_tokens - && !(descr->flags & IW_DESCR_FLAG_NOMAX)) - iwe->u.data.pointer = NULL; /* Discard payload */ - - /* Same for underflows... */ - if (iwe->u.data.length < descr->min_tokens) - iwe->u.data.pointer = NULL; /* Discard paylod */ - } - } else { - /* No data */ - iwe->u.data.pointer = NULL; - } - - stream->current += iwe->len; /* Go to next event */ - } else { - /* - * Ugly fixup for alignment issues. - * If the kernel is 64 bits and userspace 32 bits, we have an extra 4 bytes. - * Fixing that in the kernel would break 64 bits userspace. - */ - if (stream->value == NULL && - ((iwe->len - IW_EV_LCP_PK_LEN) % event_len == 4 || - (iwe->len == 12 && (event_type == IW_HEADER_TYPE_UINT || - event_type == IW_HEADER_TYPE_QUAL)))) { - - pointer -= event_len; - pointer += 4; - - /* Beware of alignment. Dest has local alignment, not packed */ - memcpy((char *)iwe + IW_EV_LCP_LEN, pointer, event_len); - pointer += event_len; - } - - if (pointer + event_len <= stream->current + iwe->len) { - stream->value = pointer; /* Go to next value */ - } else { - stream->value = NULL; - stream->current += iwe->len; /* Go to next event */ - } - } - return 1; -} - -static void iw_extract_ie(struct iw_event *iwe, struct scan_entry *sr) -{ - const uint8_t wpa1_oui[3] = { 0x00, 0x50, 0xf2 }; - uint8_t *buffer = iwe->u.data.pointer; - int ielen = 0, ietype, i; - - /* Loop on each IE, each is min. 2 bytes TLV: IE-ID - Length - Value */ - for (i = 0; i <= iwe->u.data.length - 2; i += ielen + 2) { - ietype = buffer[i]; - ielen = buffer[i + 1]; - - switch (ietype) { - case 0x30: - if (ielen < 4) /* make sure we have enough data */ - continue; - sr->flags |= IW_ENC_CAPA_WPA2; - break; - case 0xdd: - /* Not all IEs that start with 0xdd are WPA1 */ - if (ielen < 8 || memcmp(buffer + i + 2, wpa1_oui, 3) || - buffer[i + 5] != 1) - continue; - sr->flags |= IW_ENC_CAPA_WPA; - break; - } - } -} -/*----------------- End of code copied from iwlib -----------------------*/ /* * Ordering functions for scan results: all return true for a < b. @@ -561,7 +28,9 @@ static bool cmp_freq(const struct scan_entry *a, const struct scan_entry *b) /* Order by signal strength. */ static bool cmp_sig(const struct scan_entry *a, const struct scan_entry *b) { - return a->qual.level < b->qual.level; + if (!a->bss_signal && !b->bss_signal) + return a->bss_signal_qual < b->bss_signal_qual; + return a->bss_signal < b->bss_signal; } /* Order by ESSID, organize entries with same ESSID by frequency and signal. */ @@ -573,6 +42,12 @@ static bool cmp_essid(const struct scan_entry *a, const struct scan_entry *b) : res < 0; } +/* Order by MAC address */ +static bool cmp_mac(const struct scan_entry *a, const struct scan_entry *b) +{ + return memcmp(&a->ap_addr, &b->ap_addr, sizeof(a->ap_addr)) < 0; +} + /* Order by frequency, grouping channels by ESSID. */ static bool cmp_chan(const struct scan_entry *a, const struct scan_entry *b) { @@ -600,116 +75,202 @@ static bool cmp_open_sig(const struct scan_entry *a, const struct scan_entry *b) static bool (*scan_cmp[])(const struct scan_entry *, const struct scan_entry *) = { [SO_CHAN] = cmp_chan, [SO_SIGNAL] = cmp_sig, + [SO_MAC] = cmp_mac, [SO_ESSID] = cmp_essid, [SO_OPEN] = cmp_open, [SO_CHAN_SIG] = cmp_chan_sig, [SO_OPEN_SIG] = cmp_open_sig }; +/* + * Scan event handling + */ + +/* Callback event handler */ +static int wait_event(struct nl_msg *msg, void *arg) +{ + struct wait_event *wait = arg; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + int i; + + for (i = 0; i < wait->n_cmds; i++) { + if (gnlh->cmd == wait->cmds[i]) + wait->cmd = gnlh->cmd; + } + return NL_SKIP; +} + /** - * Produce ranked list of scan results. - * @ifname: interface name to run scan on - * @we_version: version of the WE extensions (needed internally) + * Wait for scan result notification sent by the kernel + * Returns true if scan results are available, false if scan was aborted. + * Taken from iw:event.c:__do_listen_events */ -static struct scan_entry *get_scan_list(const char *ifname, int we_version) +static bool wait_for_scan_events(struct scan_result *sr) { - struct scan_entry *head = NULL, **tailp = &head; - struct iwreq wrq; - int wait, waited = 0; - int skfd = socket(AF_INET, SOCK_DGRAM, 0); - - if (skfd < 0) - err_sys("%s: can not open socket", __func__); - /* - * Some drivers may return very large scan results, either because there - * are many cells, or there are many large elements. Do not bother to - * guess buffer size, use maximum u16 wrq.u.data.length size. - */ - char scan_buf[0xffff]; - - /* We are checking errno when returning NULL, so reset it here */ - errno = 0; - - memset(&wrq, 0, sizeof(wrq)); - strncpy(wrq.ifr_ifrn.ifrn_name, ifname, IFNAMSIZ); - if (ioctl(skfd, SIOCSIWSCAN, &wrq) < 0) - goto done; - - /* Larger initial timeout of 250ms between set and first get */ - for (wait = 250; (waited += wait) < MAX_SCAN_WAIT; wait = 100) { - struct timeval tv = { 0, wait * 1000 }; - - while (select(0, NULL, NULL, NULL, &tv) < 0) - if (errno != EINTR && errno != EAGAIN) - return NULL; - - wrq.u.data.pointer = scan_buf; - wrq.u.data.length = sizeof(scan_buf); - wrq.u.data.flags = 0; - - if (ioctl(skfd, SIOCGIWSCAN, &wrq) == 0) - break; + static const uint32_t cmds[] = { + NL80211_CMD_NEW_SCAN_RESULTS, + NL80211_CMD_SCAN_ABORTED, + }; + struct wait_event wait_ev = { + .cmds = cmds, + .n_cmds = ARRAY_SIZE(cmds), + .cmd = 0 + }; + struct nl_cb *cb; + + if (!scan_wait_sk) + scan_wait_sk = alloc_nl_mcast_sk("scan"); + + cb = nl_cb_alloc(IW_NL_CB_DEBUG ? NL_CB_DEBUG : NL_CB_DEFAULT); + if (!cb) + err_sys("failed to allocate netlink callbacks"); + + /* no sequence checking for multicast messages */ + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, wait_event, &wait_ev); + + while (!wait_ev.cmd) + nl_recvmsgs(scan_wait_sk, cb); + nl_cb_put(cb); + + return wait_ev.cmd == NL80211_CMD_NEW_SCAN_RESULTS; +} + +/** + * Scan result handler. Stolen from iw:scan.c + * This also updates the scan-result statistics. + */ +int scan_dump_handler(struct nl_msg *msg, void *arg) +{ + struct scan_result *sr = (struct scan_result *)arg; + struct scan_entry *new = calloc(1, sizeof(*new)); + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct nlattr *bss[NL80211_BSS_MAX + 1]; + static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { + [NL80211_BSS_TSF] = { .type = NLA_U64 }, + [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, + [NL80211_BSS_BSSID] = { }, + [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 }, + [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 }, + [NL80211_BSS_INFORMATION_ELEMENTS] = { }, + [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 }, + [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 }, + [NL80211_BSS_STATUS] = { .type = NLA_U32 }, + [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 }, + [NL80211_BSS_BEACON_IES] = { }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_BSS]) + return NL_SKIP; + + if (nla_parse_nested(bss, NL80211_BSS_MAX, + tb[NL80211_ATTR_BSS], + bss_policy)) + return NL_SKIP; + + if (!bss[NL80211_BSS_BSSID]) + return NL_SKIP; + + new = calloc(1, sizeof(*new)); + if (!new) + err_sys("failed to allocate scan entry"); + + memcpy(&new->ap_addr, nla_data(bss[NL80211_BSS_BSSID]), sizeof(new->ap_addr)); + + if (bss[NL80211_BSS_FREQUENCY]) { + new->freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]); + new->chan = ieee80211_frequency_to_channel(new->freq); } - if (wrq.u.data.length) { - struct iw_event iwe; - struct stream_descr stream; - struct scan_entry *new = NULL; - int f = 0; /* Idea taken from waproamd */ + if (bss[NL80211_BSS_SIGNAL_UNSPEC]) + new->bss_signal_qual = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); - memset(&stream, 0, sizeof(stream)); - stream.current = scan_buf; - stream.end = scan_buf + wrq.u.data.length; - while (iw_extract_event_stream(&stream, &iwe, we_version) > 0) { - if (!new) - new = calloc(1, sizeof(*new)); + if (bss[NL80211_BSS_SIGNAL_MBM]) { + int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]); + new->bss_signal = s / 100; + } - switch (iwe.cmd) { - case SIOCGIWAP: - f = 1; - memcpy(&new->ap_addr, &iwe.u.ap_addr.sa_data, sizeof(new->ap_addr)); - break; - case SIOCGIWESSID: - f |= 2; - memset(new->essid, 0, sizeof(new->essid)); + if (bss[NL80211_BSS_CAPABILITY]) { + new->bss_capa = nla_get_u16(bss[NL80211_BSS_CAPABILITY]); + new->has_key = (new->bss_capa & WLAN_CAPABILITY_PRIVACY) != 0; + } - if (iwe.u.essid.flags && iwe.u.essid.pointer && iwe.u.essid.length) - memcpy(new->essid, iwe.u.essid.pointer, iwe.u.essid.length); - break; - case SIOCGIWMODE: - new->mode = iwe.u.mode; - f |= 4; - break; - case SIOCGIWFREQ: - f |= 8; - new->freq = freq_to_hz(&iwe.u.freq); - break; - case SIOCGIWENCODE: - f |= 16; - new->has_key = !(iwe.u.data.flags & IW_ENCODE_DISABLED); - break; - case IWEVQUAL: - f |= 32; - memcpy(&new->qual, &iwe.u.qual, sizeof(struct iw_quality)); + if (bss[NL80211_BSS_SEEN_MS_AGO]) + new->last_seen = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]); + + if (bss[NL80211_BSS_TSF]) + new->tsf = nla_get_u64(bss[NL80211_BSS_TSF]); + + if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) { + uint8_t *ie = nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]); + int ielen = nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]); + uint8_t len = ie[1]; + + while (ielen >= 2 && ielen >= ie[1]) { + switch (ie[0]) { + case 0: /* SSID */ + if (len > 0 && len <= 32) + print_ssid_escaped(new->essid, sizeof(new->essid), + ie+2, len); break; - case IWEVGENIE: - f |= 64; - iw_extract_ie(&iwe, new); + case 11: /* BSS Load */ + if (len >= 5) { + new->bss_sta_count = ie[3] << 8 | ie[2]; + new->bss_chan_usage = ie[4]; + } break; } - if (f == 127) { - f = 0; - *tailp = new; - tailp = &new->next; - new = NULL; - } - } - free(new); /* may have been allocated, but not filled in */ + ielen -= ie[1] + 2; + ie += ie[1] + 2; + } } -done: - close(skfd); - return head; + + /* Update stats */ + new->next = sr->head; + sr->head = new; + if (str_is_ascii(new->essid)) + sr->max_essid_len = clamp(strlen(new->essid), + sr->max_essid_len, + IW_ESSID_MAX_SIZE); + + if (new->freq > 45000) /* 802.11ad 60GHz spectrum */ + err_quit("FIXME: can not handle %d MHz spectrum yet", new->freq); + else if (new->freq >= 5000) + sr->num.five_gig++; + else if (new->freq >= 2000) + sr->num.two_gig++; + sr->num.entries += 1; + sr->num.open += !new->has_key; + + return NL_SKIP; +} + +static int iw_nl80211_scan_trigger(void) +{ + static struct cmd cmd_trigger_scan = { + .cmd = NL80211_CMD_TRIGGER_SCAN, + }; + + return handle_cmd(&cmd_trigger_scan); +} + +static int iw_nl80211_get_scan_data(struct scan_result *sr) +{ + static struct cmd cmd_scan_dump = { + .cmd = NL80211_CMD_GET_SCAN, + .flags = NLM_F_DUMP, + .handler = scan_dump_handler + }; + + memset(sr, 0, sizeof(*sr)); + cmd_scan_dump.handler_arg = sr; + + return handle_cmd(&cmd_scan_dump); } /* @@ -740,6 +301,19 @@ static void free_scan_list(struct scan_entry *head) } } +static void clear_scan_list(struct scan_result *sr) +{ + pthread_mutex_lock(&sr->mutex); + free_scan_list(sr->head); + free(sr->channel_stats); + sr->head = NULL; + sr->channel_stats = NULL; + sr->msg[0] = '\0'; + sr->max_essid_len = MAX_ESSID_LEN; + memset(&(sr->num), 0, sizeof(sr->num)); + pthread_mutex_unlock(&sr->mutex); +} + /* * Channel statistics shown at the bottom of scan screen. */ @@ -797,13 +371,18 @@ static void compute_channel_stats(struct scan_result *sr) */ void scan_result_init(struct scan_result *sr) { + pthread_mutexattr_t ma; + memset(sr, 0, sizeof(*sr)); - iw_getinf_range(conf_ifname(), &sr->range); - pthread_mutex_init(&sr->mutex, NULL); + pthread_mutexattr_init(&ma); + if (pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) < 0) + err_sys("Failed to set the mutex robust attribute"); + pthread_mutex_init(&sr->mutex, &ma); } void scan_result_fini(struct scan_result *sr) { + /* FIXME: this may have a bug on resource de-allocation, if the main thread still holds the lock */ free_scan_list(sr->head); free(sr->channel_stats); pthread_mutex_destroy(&sr->mutex); @@ -812,83 +391,63 @@ void scan_result_fini(struct scan_result *sr) /** The actual scan thread. */ void *do_scan(void *sr_ptr) { - struct scan_result *sr = (struct scan_result *)sr_ptr; - struct scan_entry *cur; + struct scan_result *sr = sr_ptr; + sigset_t blockmask; + int ret = 0; - pthread_detach(pthread_self()); + /* SIGWINCH is supposed to be handled in the main thread. */ + sigemptyset(&blockmask); + sigaddset(&blockmask, SIGWINCH); + pthread_sigmask(SIG_BLOCK, &blockmask, NULL); + pthread_detach(pthread_self()); do { - pthread_mutex_lock(&sr->mutex); - - free_scan_list(sr->head); - free(sr->channel_stats); - - sr->head = NULL; - sr->channel_stats = NULL; - sr->msg[0] = '\0'; - sr->max_essid_len = MAX_ESSID_LEN; - memset(&(sr->num), 0, sizeof(sr->num)); - - sr->head = get_scan_list(conf_ifname(), sr->range.we_version_compiled); - if (!sr->head) { - switch(errno) { - case EPERM: - /* Don't try to read leftover results, it does not work reliably. */ - if (!has_net_admin_capability()) + clear_scan_list(sr); + + ret = iw_nl80211_scan_trigger(); + switch(-ret) { + case 0: + case EBUSY: + /* Trigger returns -EBUSY if a scan request is pending or ready. */ + if (!wait_for_scan_events(sr)) { + snprintf(sr->msg, sizeof(sr->msg), "Waiting for scan data..."); + } else { + pthread_mutex_lock(&sr->mutex); + ret = iw_nl80211_get_scan_data(sr); + if (ret < 0) { snprintf(sr->msg, sizeof(sr->msg), - "This screen requires CAP_NET_ADMIN permissions"); - break; - case EFAULT: - /* - * EFAULT can occur after a window resizing event and is temporary. - * It may also occur when the interface is down, hence defer handling. - */ - break; - case EINTR: - case EBUSY: - case EAGAIN: - /* Temporary errors. */ - snprintf(sr->msg, sizeof(sr->msg), "Waiting for scan data on %s ...", conf_ifname()); - break; - case ENETDOWN: + "Scan failed on %s: %s", conf_ifname(), strerror(-ret)); + } else if (!sr->head) { + snprintf(sr->msg, sizeof(sr->msg), "Empty scan results on %s", conf_ifname()); + } + compute_channel_stats(sr); + pthread_mutex_unlock(&sr->mutex); + } + break; + case EPERM: + if (!has_net_admin_capability()) + snprintf(sr->msg, sizeof(sr->msg), + "This screen requires CAP_NET_ADMIN permissions"); + return NULL; + case EFAULT: + /* EFAULT can occur after a window resizing event: temporary, fall through. */ + case EINTR: + case EAGAIN: + /* Temporary errors. */ + snprintf(sr->msg, sizeof(sr->msg), "Waiting for device to become ready ..."); + break; + case ENETDOWN: + if (!if_is_up(conf_ifname())) { snprintf(sr->msg, sizeof(sr->msg), "Interface %s is down - setting it up ...", conf_ifname()); if (if_set_up(conf_ifname()) < 0) err_sys("Can not bring up interface '%s'", conf_ifname()); break; - case E2BIG: - /* - * This is a driver issue, since already using the largest possible - * scan buffer. See comments in iwlist.c of wireless tools. - */ - snprintf(sr->msg, sizeof(sr->msg), - "No scan on %s: Driver returned too much data", conf_ifname()); - break; - case 0: - snprintf(sr->msg, sizeof(sr->msg), "Empty scan results on %s", conf_ifname()); - break; - default: - snprintf(sr->msg, sizeof(sr->msg), - "Scan failed on %s: %s", conf_ifname(), strerror(errno)); } + /* fall through */ + default: + snprintf(sr->msg, sizeof(sr->msg), + "Scan trigger failed on %s: %s", conf_ifname(), strerror(-ret)); } - - for (cur = sr->head; cur; cur = cur->next) { - if (str_is_ascii(cur->essid)) - sr->max_essid_len = clamp(strlen(cur->essid), - sr->max_essid_len, - IW_ESSID_MAX_SIZE); - iw_sanitize(&sr->range, &cur->qual, &cur->dbm); - cur->chan = freq_to_channel(cur->freq, &sr->range); - if (cur->freq >= 5e9) - sr->num.five_gig++; - else if (cur->freq >= 2e9) - sr->num.two_gig++; - sr->num.entries += 1; - sr->num.open += !cur->has_key; - } - compute_channel_stats(sr); - - pthread_mutex_unlock(&sr->mutex); } while (usleep(conf.stat_iv * 1000) == 0); return NULL; diff --git a/lhist_scr.c b/lhist_scr.c index 84b6925..2595b45 100644 --- a/lhist_scr.c +++ b/lhist_scr.c @@ -18,6 +18,7 @@ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "iw_if.h" +#include "iw_nl80211.h" /* Number of lines in the key window at the bottom */ #define KEY_WIN_HEIGHT 3 @@ -117,22 +118,34 @@ static struct iw_levelstat iw_cache_get(const uint32_t index) return iw_stats_cache[(count - index) % IW_STACKSIZE]; } -void iw_cache_update(struct iw_stat *iw) +void iw_cache_update(struct iw_nl80211_linkstat *ls) { static struct iw_levelstat prev, avg = IW_LSTAT_INIT; static int slot; + int sig_level = ls->signal_avg ?: ls->signal; - if (! (iw->stat.qual.updated & IW_QUAL_LEVEL_INVALID)) { + /* + * If hardware does not support dBm signal level, it will not + * be filled in, and show up as 0. Try to fall back to the BSS + * probe where again a 0 dBm value reflects 'not initialized'. + */ + if (sig_level == 0) + sig_level = ls->bss_signal; + + if (sig_level == 0) { + avg.flags |= IW_QUAL_LEVEL_INVALID; + } else { avg.flags &= ~IW_QUAL_LEVEL_INVALID; - avg.signal += iw->dbm.signal / conf.slotsize; - track_extrema(iw->dbm.signal, &e_signal); + avg.signal += (float)sig_level / conf.slotsize; + track_extrema(sig_level, &e_signal); } - if (! (iw->stat.qual.updated & IW_QUAL_NOISE_INVALID)) { - avg.flags &= ~IW_QUAL_NOISE_INVALID; - avg.noise += iw->dbm.noise / conf.slotsize; - track_extrema(iw->dbm.noise, &e_noise); - track_extrema(iw->dbm.signal - iw->dbm.noise, &e_snr); + if (iw_nl80211_have_survey_data(ls)) { + avg.flags &= ~IW_QUAL_NOISE_INVALID; + avg.noise += (float)ls->survey.noise / conf.slotsize; + track_extrema(ls->survey.noise, &e_noise); + if (! (avg.flags & IW_QUAL_LEVEL_INVALID)) + track_extrema(sig_level - ls->survey.noise, &e_snr); } if (++slot >= conf.slotsize) { diff --git a/nl80211.h b/nl80211.h new file mode 100644 index 0000000..241220c --- /dev/null +++ b/nl80211.h @@ -0,0 +1,4588 @@ +#ifndef __LINUX_NL80211_H +#define __LINUX_NL80211_H +/* + * 802.11 netlink interface public header + * + * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> + * Copyright 2008 Michael Wu <flamingice@sourmilk.net> + * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com> + * Copyright 2008 Michael Buesch <m@bues.ch> + * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com> + * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> + * Copyright 2008 Colin McCabe <colin@cozybit.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +/* + * This header file defines the userspace API to the wireless stack. Please + * be careful not to break things - i.e. don't move anything around or so + * unless you can demonstrate that it breaks neither API nor ABI. + * + * Additions to the API should be accompanied by actual implementations in + * an upstream driver, so that example implementations exist in case there + * are ever concerns about the precise semantics of the API or changes are + * needed, and to ensure that code for dead (no longer implemented) API + * can actually be identified and removed. + * Nonetheless, semantics should also be documented carefully in this file. + */ + +#include <linux/types.h> + +#define NL80211_GENL_NAME "nl80211" + +#define NL80211_MULTICAST_GROUP_CONFIG "config" +#define NL80211_MULTICAST_GROUP_SCAN "scan" +#define NL80211_MULTICAST_GROUP_REG "regulatory" +#define NL80211_MULTICAST_GROUP_MLME "mlme" +#define NL80211_MULTICAST_GROUP_VENDOR "vendor" +#define NL80211_MULTICAST_GROUP_TESTMODE "testmode" + +/** + * DOC: Station handling + * + * Stations are added per interface, but a special case exists with VLAN + * interfaces. When a station is bound to an AP interface, it may be moved + * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN). + * The station is still assumed to belong to the AP interface it was added + * to. + * + * Station handling varies per interface type and depending on the driver's + * capabilities. + * + * For drivers supporting TDLS with external setup (WIPHY_FLAG_SUPPORTS_TDLS + * and WIPHY_FLAG_TDLS_EXTERNAL_SETUP), the station lifetime is as follows: + * - a setup station entry is added, not yet authorized, without any rate + * or capability information, this just exists to avoid race conditions + * - when the TDLS setup is done, a single NL80211_CMD_SET_STATION is valid + * to add rate and capability information to the station and at the same + * time mark it authorized. + * - %NL80211_TDLS_ENABLE_LINK is then used + * - after this, the only valid operation is to remove it by tearing down + * the TDLS link (%NL80211_TDLS_DISABLE_LINK) + * + * TODO: need more info for other interface types + */ + +/** + * DOC: Frame transmission/registration support + * + * Frame transmission and registration support exists to allow userspace + * management entities such as wpa_supplicant react to management frames + * that are not being handled by the kernel. This includes, for example, + * certain classes of action frames that cannot be handled in the kernel + * for various reasons. + * + * Frame registration is done on a per-interface basis and registrations + * cannot be removed other than by closing the socket. It is possible to + * specify a registration filter to register, for example, only for a + * certain type of action frame. In particular with action frames, those + * that userspace registers for will not be returned as unhandled by the + * driver, so that the registered application has to take responsibility + * for doing that. + * + * The type of frame that can be registered for is also dependent on the + * driver and interface type. The frame types are advertised in wiphy + * attributes so applications know what to expect. + * + * NOTE: When an interface changes type while registrations are active, + * these registrations are ignored until the interface type is + * changed again. This means that changing the interface type can + * lead to a situation that couldn't otherwise be produced, but + * any such registrations will be dormant in the sense that they + * will not be serviced, i.e. they will not receive any frames. + * + * Frame transmission allows userspace to send for example the required + * responses to action frames. It is subject to some sanity checking, + * but many frames can be transmitted. When a frame was transmitted, its + * status is indicated to the sending socket. + * + * For more technical details, see the corresponding command descriptions + * below. + */ + +/** + * DOC: Virtual interface / concurrency capabilities + * + * Some devices are able to operate with virtual MACs, they can have + * more than one virtual interface. The capability handling for this + * is a bit complex though, as there may be a number of restrictions + * on the types of concurrency that are supported. + * + * To start with, each device supports the interface types listed in + * the %NL80211_ATTR_SUPPORTED_IFTYPES attribute, but by listing the + * types there no concurrency is implied. + * + * Once concurrency is desired, more attributes must be observed: + * To start with, since some interface types are purely managed in + * software, like the AP-VLAN type in mac80211 for example, there's + * an additional list of these, they can be added at any time and + * are only restricted by some semantic restrictions (e.g. AP-VLAN + * cannot be added without a corresponding AP interface). This list + * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute. + * + * Further, the list of supported combinations is exported. This is + * in the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute. Basically, + * it exports a list of "groups", and at any point in time the + * interfaces that are currently active must fall into any one of + * the advertised groups. Within each group, there are restrictions + * on the number of interfaces of different types that are supported + * and also the number of different channels, along with potentially + * some other restrictions. See &enum nl80211_if_combination_attrs. + * + * All together, these attributes define the concurrency of virtual + * interfaces that a given device supports. + */ + +/** + * DOC: packet coalesce support + * + * In most cases, host that receives IPv4 and IPv6 multicast/broadcast + * packets does not do anything with these packets. Therefore the + * reception of these unwanted packets causes unnecessary processing + * and power consumption. + * + * Packet coalesce feature helps to reduce number of received interrupts + * to host by buffering these packets in firmware/hardware for some + * predefined time. Received interrupt will be generated when one of the + * following events occur. + * a) Expiration of hardware timer whose expiration time is set to maximum + * coalescing delay of matching coalesce rule. + * b) Coalescing buffer in hardware reaches it's limit. + * c) Packet doesn't match any of the configured coalesce rules. + * + * User needs to configure following parameters for creating a coalesce + * rule. + * a) Maximum coalescing delay + * b) List of packet patterns which needs to be matched + * c) Condition for coalescence. pattern 'match' or 'no match' + * Multiple such rules can be created. + */ + +/** + * enum nl80211_commands - supported nl80211 commands + * + * @NL80211_CMD_UNSPEC: unspecified command to catch errors + * + * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request + * to get a list of all present wiphys. + * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or + * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, + * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the + * attributes determining the channel width; this is used for setting + * monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT, + * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, + * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. + * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL + * instead, the support here is for backward compatibility only. + * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request + * or rename notification. Has attributes %NL80211_ATTR_WIPHY and + * %NL80211_ATTR_WIPHY_NAME. + * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes + * %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME. + * + * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration; + * either a dump request for all interfaces or a specific get with a + * single %NL80211_ATTR_IFINDEX is supported. + * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. + * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response + * to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX, + * %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also + * be sent from userspace to request creation of a new virtual interface, + * then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and + * %NL80211_ATTR_IFNAME. + * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from + * userspace to request deletion of a virtual interface, then requires + * attribute %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified + * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. + * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT, + * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD. + * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA, + * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER, + * and %NL80211_ATTR_KEY_SEQ attributes. + * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX + * or %NL80211_ATTR_MAC. + * + * @NL80211_CMD_GET_BEACON: (not used) + * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface + * using the %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL + * attributes. For drivers that generate the beacon and probe responses + * internally, the following attributes must be provided: %NL80211_ATTR_IE, + * %NL80211_ATTR_IE_PROBE_RESP and %NL80211_ATTR_IE_ASSOC_RESP. + * @NL80211_CMD_START_AP: Start AP operation on an AP interface, parameters + * are like for %NL80211_CMD_SET_BEACON, and additionally parameters that + * do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL, + * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, + * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, + * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, + * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, + * %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_INACTIVITY_TIMEOUT, + * %NL80211_ATTR_ACL_POLICY and %NL80211_ATTR_MAC_ADDRS. + * The channel to use can be set on the interface or be given using the + * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width. + * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP + * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface + * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP + * + * @NL80211_CMD_GET_STATION: Get station attributes for station identified by + * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_SET_STATION: Set station attributes for station identified by + * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the + * the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC + * or, if no MAC address given, all stations, on the interface identified + * by %NL80211_ATTR_IFINDEX. %NL80211_ATTR_MGMT_SUBTYPE and + * %NL80211_ATTR_REASON_CODE can optionally be used to specify which type + * of disconnection indication should be sent to the station + * (Deauthentication or Disassociation frame and reason code for that + * frame). + * + * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by + * %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP. + * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by + * %NL80211_ATTR_MAC. + * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the + * the interface identified by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC + * or, if no MAC address given, all mesh paths, on the interface identified + * by %NL80211_ATTR_IFINDEX. + * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by + * %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set + * regulatory domain. If %NL80211_ATTR_WIPHY is specified and the device + * has a private regulatory domain, it will be returned. Otherwise, the + * global regdomain will be returned. + * A device will have a private regulatory domain if it uses the + * regulatory_hint() API. Even when a private regdomain is used the channel + * information will still be mended according to further hints from + * the regulatory core to help with compliance. A dump version of this API + * is now available which will returns the global regdomain as well as + * all private regdomains of present wiphys (for those that have it). + * If a wiphy is self-managed (%NL80211_ATTR_WIPHY_SELF_MANAGED_REG), then + * its private regdomain is the only valid one for it. The regulatory + * core is not used to help with compliance in this case. + * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command + * after being queried by the kernel. CRDA replies by sending a regulatory + * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our + * current alpha2 if it found a match. It also provides + * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each + * regulatory rule is a nested set of attributes given by + * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and + * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by + * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and + * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP. + * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain + * to the specified ISO/IEC 3166-1 alpha2 country code. The core will + * store this as a valid request and then query userspace for it. + * + * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the + * interface identified by %NL80211_ATTR_IFINDEX + * + * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the + * interface identified by %NL80211_ATTR_IFINDEX + * + * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The + * interface is identified with %NL80211_ATTR_IFINDEX and the management + * frame subtype with %NL80211_ATTR_MGMT_SUBTYPE. The extra IE data to be + * added to the end of the specified management frame is specified with + * %NL80211_ATTR_IE. If the command succeeds, the requested data will be + * added to all specified management frames generated by + * kernel/firmware/driver. + * Note: This command has been removed and it is only reserved at this + * point to avoid re-using existing command number. The functionality this + * command was planned for has been provided with cleaner design with the + * option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN, + * NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE, + * NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE. + * + * @NL80211_CMD_GET_SCAN: get scan results + * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters + * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the + * probe requests at CCK rate or not. + * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to + * NL80211_CMD_GET_SCAN and on the "scan" multicast group) + * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, + * partial scan results may be available + * + * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain + * intervals, as specified by %NL80211_ATTR_SCHED_SCAN_INTERVAL. + * Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS) + * are passed, they are used in the probe requests. For + * broadcast, a broadcast SSID must be passed (ie. an empty + * string). If no SSID is passed, no probe requests are sent and + * a passive scan is performed. %NL80211_ATTR_SCAN_FREQUENCIES, + * if passed, define which channels should be scanned; if not + * passed, all channels allowed for the current regulatory domain + * are used. Extra IEs can also be passed from the userspace by + * using the %NL80211_ATTR_IE attribute. The first cycle of the + * scheduled scan can be delayed by %NL80211_ATTR_SCHED_SCAN_DELAY + * is supplied. + * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if + * scheduled scan is not running. The caller may assume that as soon + * as the call returns, it is safe to start a new scheduled scan again. + * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan + * results available. + * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has + * stopped. The driver may issue this event at any time during a + * scheduled scan. One reason for stopping the scan is if the hardware + * does not support starting an association or a normal scan while running + * a scheduled scan. This event is also sent when the + * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface + * is brought down while a scheduled scan was running. + * + * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation + * or noise level + * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to + * NL80211_CMD_GET_SURVEY and on the "scan" multicast group) + * + * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC + * (for the BSSID) and %NL80211_ATTR_PMKID. + * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC + * (for the BSSID) and %NL80211_ATTR_PMKID. + * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. + * + * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain + * has been changed and provides details of the request information + * that caused the change such as who initiated the regulatory request + * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx + * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if + * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or + * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain + * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is + * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on + * to (%NL80211_ATTR_REG_ALPHA2). + * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon + * has been found while world roaming thus enabling active scan or + * any mode of operation that initiates TX (beacons) on a channel + * where we would not have been able to do either before. As an example + * if you are world roaming (regulatory domain set to world or if your + * driver is using a custom world roaming regulatory domain) and while + * doing a passive scan on the 5 GHz band you find an AP there (if not + * on a DFS channel) you will now be able to actively scan for that AP + * or use AP mode on your card on that same channel. Note that this will + * never be used for channels 1-11 on the 2 GHz band as they are always + * enabled world wide. This beacon hint is only sent if your device had + * either disabled active scanning or beaconing on a channel. We send to + * userspace the wiphy on which we removed a restriction from + * (%NL80211_ATTR_WIPHY) and the channel on which this occurred + * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER) + * the beacon hint was processed. + * + * @NL80211_CMD_AUTHENTICATE: authentication request and notification. + * This command is used both as a command (request to authenticate) and + * as an event on the "mlme" multicast group indicating completion of the + * authentication process. + * When used as a command, %NL80211_ATTR_IFINDEX is used to identify the + * interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and + * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify + * the SSID (mainly for association, but is included in authentication + * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used + * to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE + * is used to specify the authentication type. %NL80211_ATTR_IE is used to + * define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs) + * to be added to the frame. + * When used as an event, this reports reception of an Authentication + * frame in station and IBSS modes when the local MLME processed the + * frame, i.e., it was for the local STA and was received in correct + * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the + * MLME SAP interface (kernel providing MLME, userspace SME). The + * included %NL80211_ATTR_FRAME attribute contains the management frame + * (including both the header and frame body, but not FCS). This event is + * also used to indicate if the authentication attempt timed out. In that + * case the %NL80211_ATTR_FRAME attribute is replaced with a + * %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which + * pending authentication timed out). + * @NL80211_CMD_ASSOCIATE: association request and notification; like + * NL80211_CMD_AUTHENTICATE but for Association and Reassociation + * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request, + * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). + * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like + * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to + * MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication + * primitives). + * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like + * NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to + * MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives). + * + * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael + * MIC (part of TKIP) failure; sent on the "mlme" multicast group; the + * event includes %NL80211_ATTR_MAC to describe the source MAC address of + * the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key + * type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and + * %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this + * event matches with MLME-MICHAELMICFAILURE.indication() primitive + * + * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a + * FREQ attribute (for the initial frequency if no peer can be found) + * and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those + * should be fixed rather than automatically determined. Can only be + * executed on a network interface that is UP, and fixed BSSID/FREQ + * may be rejected. Another optional parameter is the beacon interval, + * given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not + * given defaults to 100 TU (102.4ms). + * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is + * determined by the network interface. + * + * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute + * to identify the device, and the TESTDATA blob attribute to pass through + * to the driver. + * + * @NL80211_CMD_CONNECT: connection request and notification; this command + * requests to connect to a specified network but without separating + * auth and assoc steps. For this, you need to specify the SSID in a + * %NL80211_ATTR_SSID attribute, and can optionally specify the association + * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_USE_MFP, + * %NL80211_ATTR_MAC, %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, %NL80211_ATTR_MAC_HINT, and + * %NL80211_ATTR_WIPHY_FREQ_HINT. + * If included, %NL80211_ATTR_MAC and %NL80211_ATTR_WIPHY_FREQ are + * restrictions on BSS selection, i.e., they effectively prevent roaming + * within the ESS. %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT + * can be included to provide a recommendation of the initial BSS while + * allowing the driver to roam to other BSSes within the ESS and also to + * ignore this recommendation if the indicated BSS is not ideal. Only one + * set of BSSID,frequency parameters is used (i.e., either the enforcing + * %NL80211_ATTR_MAC,%NL80211_ATTR_WIPHY_FREQ or the less strict + * %NL80211_ATTR_MAC_HINT and %NL80211_ATTR_WIPHY_FREQ_HINT). + * Background scan period can optionally be + * specified in %NL80211_ATTR_BG_SCAN_PERIOD, + * if not specified default background scan configuration + * in driver is used and if period value is 0, bg scan will be disabled. + * This attribute is ignored if driver does not support roam scan. + * It is also sent as an event, with the BSSID and response IEs when the + * connection is established or failed to be established. This can be + * determined by the STATUS_CODE attribute. + * @NL80211_CMD_ROAM: request that the card roam (currently not implemented), + * sent as an event when the card/driver roamed by itself. + * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify + * userspace that a connection was dropped by the AP or due to other + * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and + * %NL80211_ATTR_REASON_CODE attributes are used. + * + * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices + * associated with this wiphy must be down and will follow. + * + * @NL80211_CMD_REMAIN_ON_CHANNEL: Request to remain awake on the specified + * channel for the specified amount of time. This can be used to do + * off-channel operations like transmit a Public Action frame and wait for + * a response while being associated to an AP on another channel. + * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus + * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the + * frequency for the operation. + * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds + * to remain on the channel. This command is also used as an event to + * notify when the requested duration starts (it may take a while for the + * driver to schedule this time due to other concurrent needs for the + * radio). + * When called, this operation returns a cookie (%NL80211_ATTR_COOKIE) + * that will be included with any events pertaining to this request; + * the cookie is also used to cancel the request. + * @NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: This command can be used to cancel a + * pending remain-on-channel duration if the desired operation has been + * completed prior to expiration of the originally requested duration. + * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify the + * radio. The %NL80211_ATTR_COOKIE attribute must be given as well to + * uniquely identify the request. + * This command is also used as an event to notify when a requested + * remain-on-channel duration has expired. + * + * @NL80211_CMD_SET_TX_BITRATE_MASK: Set the mask of rates to be used in TX + * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface + * and @NL80211_ATTR_TX_RATES the set of allowed rates. + * + * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames + * (via @NL80211_CMD_FRAME) for processing in userspace. This command + * requires an interface index, a frame type attribute (optional for + * backward compatibility reasons, if not given assumes action frames) + * and a match attribute containing the first few bytes of the frame + * that should match, e.g. a single byte for only a category match or + * four bytes for vendor frames including the OUI. The registration + * cannot be dropped, but is removed automatically when the netlink + * socket is closed. Multiple registrations can be made. + * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for + * backward compatibility + * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This + * command is used both as a request to transmit a management frame and + * as an event indicating reception of a frame that was not processed in + * kernel code, but is for us (i.e., which may need to be processed in a + * user space application). %NL80211_ATTR_FRAME is used to specify the + * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ is used + * to indicate on which channel the frame is to be transmitted or was + * received. If this channel is not the current channel (remain-on-channel + * or the operational channel) the device will switch to the given channel + * and transmit the frame, optionally waiting for a response for the time + * specified using %NL80211_ATTR_DURATION. When called, this operation + * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the + * TX status event pertaining to the TX request. + * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the + * management frames at CCK rate or not in 2GHz band. + * %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA + * counters which will be updated to the current value. This attribute + * is used during CSA period. + * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this + * command may be used with the corresponding cookie to cancel the wait + * time if it is known that it is no longer necessary. + * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. + * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame + * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies + * the TX command and %NL80211_ATTR_FRAME includes the contents of the + * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged + * the frame. + * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for + * backward compatibility. + * + * @NL80211_CMD_SET_POWER_SAVE: Set powersave, using %NL80211_ATTR_PS_STATE + * @NL80211_CMD_GET_POWER_SAVE: Get powersave status in %NL80211_ATTR_PS_STATE + * + * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command + * is used to configure connection quality monitoring notification trigger + * levels. + * @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This + * command is used as an event to indicate the that a trigger level was + * reached. + * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ + * and the attributes determining channel width) the given interface + * (identifed by %NL80211_ATTR_IFINDEX) shall operate on. + * In case multiple channels are supported by the device, the mechanism + * with which it switches channels is implementation-defined. + * When a monitor interface is given, it can only switch channel while + * no other interfaces are operating to avoid disturbing the operation + * of any other interfaces, and other interfaces will again take + * precedence when they are used. + * + * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. + * + * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial + * mesh config parameters may be given. + * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the + * network is determined by the network interface. + * + * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame + * notification. This event is used to indicate that an unprotected + * deauthentication frame was dropped when MFP is in use. + * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame + * notification. This event is used to indicate that an unprotected + * disassociation frame was dropped when MFP is in use. + * + * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a + * beacon or probe response from a compatible mesh peer. This is only + * sent while no station information (sta_info) exists for the new peer + * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH, + * @NL80211_MESH_SETUP_USERSPACE_AMPE, or + * @NL80211_MESH_SETUP_USERSPACE_MPM is set. On reception of this + * notification, userspace may decide to create a new station + * (@NL80211_CMD_NEW_STATION). To stop this notification from + * reoccurring, the userspace authentication daemon may want to create the + * new station with the AUTHENTICATED flag unset and maybe change it later + * depending on the authentication result. + * + * @NL80211_CMD_GET_WOWLAN: get Wake-on-Wireless-LAN (WoWLAN) settings. + * @NL80211_CMD_SET_WOWLAN: set Wake-on-Wireless-LAN (WoWLAN) settings. + * Since wireless is more complex than wired ethernet, it supports + * various triggers. These triggers can be configured through this + * command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For + * more background information, see + * http://wireless.kernel.org/en/users/Documentation/WoWLAN. + * The @NL80211_CMD_SET_WOWLAN command can also be used as a notification + * from the driver reporting the wakeup reason. In this case, the + * @NL80211_ATTR_WOWLAN_TRIGGERS attribute will contain the reason + * for the wakeup, if it was caused by wireless. If it is not present + * in the wakeup notification, the wireless device didn't cause the + * wakeup but reports that it was woken up. + * + * @NL80211_CMD_SET_REKEY_OFFLOAD: This command is used give the driver + * the necessary information for supporting GTK rekey offload. This + * feature is typically used during WoWLAN. The configuration data + * is contained in %NL80211_ATTR_REKEY_DATA (which is nested and + * contains the data in sub-attributes). After rekeying happened, + * this command may also be sent by the driver as an MLME event to + * inform userspace of the new replay counter. + * + * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace + * of PMKSA caching dandidates. + * + * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). + * In addition, this can be used as an event to request userspace to take + * actions on TDLS links (set up a new link or tear down an existing one). + * In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested + * operation, %NL80211_ATTR_MAC contains the peer MAC address, and + * %NL80211_ATTR_REASON_CODE the reason code to be used (only with + * %NL80211_TDLS_TEARDOWN). + * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. The + * %NL80211_ATTR_TDLS_ACTION attribute determines the type of frame to be + * sent. Public Action codes (802.11-2012 8.1.5.1) will be sent as + * 802.11 management frames, while TDLS action codes (802.11-2012 + * 8.5.13.1) will be encapsulated and sent as data frames. The currently + * supported Public Action code is %WLAN_PUB_ACTION_TDLS_DISCOVER_RES + * and the currently supported TDLS actions codes are given in + * &enum ieee80211_tdls_actioncode. + * + * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP + * (or GO) interface (i.e. hostapd) to ask for unexpected frames to + * implement sending deauth to stations that send unexpected class 3 + * frames. Also used as the event sent by the kernel when such a frame + * is received. + * For the event, the %NL80211_ATTR_MAC attribute carries the TA and + * other attributes like the interface index are present. + * If used as the command it must have an interface index and you can + * only unsubscribe from the event by closing the socket. Subscription + * is also for %NL80211_CMD_UNEXPECTED_4ADDR_FRAME events. + * + * @NL80211_CMD_UNEXPECTED_4ADDR_FRAME: Sent as an event indicating that the + * associated station identified by %NL80211_ATTR_MAC sent a 4addr frame + * and wasn't already in a 4-addr VLAN. The event will be sent similarly + * to the %NL80211_CMD_UNEXPECTED_FRAME event, to the same listener. + * + * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface + * by sending a null data frame to it and reporting when the frame is + * acknowleged. This is used to allow timing out inactive clients. Uses + * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a + * direct reply with an %NL80211_ATTR_COOKIE that is later used to match + * up the event with the request. The event includes the same data and + * has %NL80211_ATTR_ACK set if the frame was ACKed. + * + * @NL80211_CMD_REGISTER_BEACONS: Register this socket to receive beacons from + * other BSSes when any interfaces are in AP mode. This helps implement + * OLBC handling in hostapd. Beacons are reported in %NL80211_CMD_FRAME + * messages. Note that per PHY only one application may register. + * + * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether + * No Acknowledgement Policy should be applied. + * + * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels + * independently of the userspace SME, send this event indicating + * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the + * attributes determining channel width. This indication may also be + * sent when a remotely-initiated switch (e.g., when a STA receives a CSA + * from the remote AP) is completed; + * + * @NL80211_CMD_CH_SWITCH_STARTED_NOTIFY: Notify that a channel switch + * has been started on an interface, regardless of the initiator + * (ie. whether it was requested from a remote device or + * initiated on our own). It indicates that + * %NL80211_ATTR_IFINDEX will be on %NL80211_ATTR_WIPHY_FREQ + * after %NL80211_ATTR_CH_SWITCH_COUNT TBTT's. The userspace may + * decide to react to this indication by requesting other + * interfaces to change channel as well. + * + * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by + * its %NL80211_ATTR_WDEV identifier. It must have been created with + * %NL80211_CMD_NEW_INTERFACE previously. After it has been started, the + * P2P Device can be used for P2P operations, e.g. remain-on-channel and + * public action frame TX. + * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by + * its %NL80211_ATTR_WDEV identifier. + * + * @NL80211_CMD_CONN_FAILED: connection request to an AP failed; used to + * notify userspace that AP has rejected the connection request from a + * station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON + * is used for this. + * + * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames + * for IBSS or MESH vif. + * + * @NL80211_CMD_SET_MAC_ACL: sets ACL for MAC address based access control. + * This is to be used with the drivers advertising the support of MAC + * address based access control. List of MAC addresses is passed in + * %NL80211_ATTR_MAC_ADDRS and ACL policy is passed in + * %NL80211_ATTR_ACL_POLICY. Driver will enable ACL with this list, if it + * is not already done. The new list will replace any existing list. Driver + * will clear its ACL when the list of MAC addresses passed is empty. This + * command is used in AP/P2P GO mode. Driver has to make sure to clear its + * ACL list during %NL80211_CMD_STOP_AP. + * + * @NL80211_CMD_RADAR_DETECT: Start a Channel availability check (CAC). Once + * a radar is detected or the channel availability scan (CAC) has finished + * or was aborted, or a radar was detected, usermode will be notified with + * this event. This command is also used to notify userspace about radars + * while operating on this channel. + * %NL80211_ATTR_RADAR_EVENT is used to inform about the type of the + * event. + * + * @NL80211_CMD_GET_PROTOCOL_FEATURES: Get global nl80211 protocol features, + * i.e. features for the nl80211 protocol rather than device features. + * Returns the features in the %NL80211_ATTR_PROTOCOL_FEATURES bitmap. + * + * @NL80211_CMD_UPDATE_FT_IES: Pass down the most up-to-date Fast Transition + * Information Element to the WLAN driver + * + * @NL80211_CMD_FT_EVENT: Send a Fast transition event from the WLAN driver + * to the supplicant. This will carry the target AP's MAC address along + * with the relevant Information Elements. This event is used to report + * received FT IEs (MDIE, FTIE, RSN IE, TIE, RICIE). + * + * @NL80211_CMD_CRIT_PROTOCOL_START: Indicates user-space will start running + * a critical protocol that needs more reliability in the connection to + * complete. + * + * @NL80211_CMD_CRIT_PROTOCOL_STOP: Indicates the connection reliability can + * return back to normal. + * + * @NL80211_CMD_GET_COALESCE: Get currently supported coalesce rules. + * @NL80211_CMD_SET_COALESCE: Configure coalesce rules or clear existing rules. + * + * @NL80211_CMD_CHANNEL_SWITCH: Perform a channel switch by announcing the + * the new channel information (Channel Switch Announcement - CSA) + * in the beacon for some time (as defined in the + * %NL80211_ATTR_CH_SWITCH_COUNT parameter) and then change to the + * new channel. Userspace provides the new channel information (using + * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel + * width). %NL80211_ATTR_CH_SWITCH_BLOCK_TX may be supplied to inform + * other station that transmission must be blocked until the channel + * switch is complete. + * + * @NL80211_CMD_VENDOR: Vendor-specified command/event. The command is specified + * by the %NL80211_ATTR_VENDOR_ID attribute and a sub-command in + * %NL80211_ATTR_VENDOR_SUBCMD. Parameter(s) can be transported in + * %NL80211_ATTR_VENDOR_DATA. + * For feature advertisement, the %NL80211_ATTR_VENDOR_DATA attribute is + * used in the wiphy data as a nested attribute containing descriptions + * (&struct nl80211_vendor_cmd_info) of the supported vendor commands. + * This may also be sent as an event with the same attributes. + * + * @NL80211_CMD_SET_QOS_MAP: Set Interworking QoS mapping for IP DSCP values. + * The QoS mapping information is included in %NL80211_ATTR_QOS_MAP. If + * that attribute is not included, QoS mapping is disabled. Since this + * QoS mapping is relevant for IP packets, it is only valid during an + * association. This is cleared on disassociation and AP restart. + * + * @NL80211_CMD_ADD_TX_TS: Ask the kernel to add a traffic stream for the given + * %NL80211_ATTR_TSID and %NL80211_ATTR_MAC with %NL80211_ATTR_USER_PRIO + * and %NL80211_ATTR_ADMITTED_TIME parameters. + * Note that the action frame handshake with the AP shall be handled by + * userspace via the normal management RX/TX framework, this only sets + * up the TX TS in the driver/device. + * If the admitted time attribute is not added then the request just checks + * if a subsequent setup could be successful, the intent is to use this to + * avoid setting up a session with the AP when local restrictions would + * make that impossible. However, the subsequent "real" setup may still + * fail even if the check was successful. + * @NL80211_CMD_DEL_TX_TS: Remove an existing TS with the %NL80211_ATTR_TSID + * and %NL80211_ATTR_MAC parameters. It isn't necessary to call this + * before removing a station entry entirely, or before disassociating + * or similar, cleanup will happen in the driver/device in this case. + * + * @NL80211_CMD_GET_MPP: Get mesh path attributes for mesh proxy path to + * destination %NL80211_ATTR_MAC on the interface identified by + * %NL80211_ATTR_IFINDEX. + * + * @NL80211_CMD_JOIN_OCB: Join the OCB network. The center frequency and + * bandwidth of a channel must be given. + * @NL80211_CMD_LEAVE_OCB: Leave the OCB network -- no special arguments, the + * network is determined by the network interface. + * + * @NL80211_CMD_TDLS_CHANNEL_SWITCH: Start channel-switching with a TDLS peer, + * identified by the %NL80211_ATTR_MAC parameter. A target channel is + * provided via %NL80211_ATTR_WIPHY_FREQ and other attributes determining + * channel width/type. The target operating class is given via + * %NL80211_ATTR_OPER_CLASS. + * The driver is responsible for continually initiating channel-switching + * operations and returning to the base channel for communication with the + * AP. + * @NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH: Stop channel-switching with a TDLS + * peer given by %NL80211_ATTR_MAC. Both peers must be on the base channel + * when this command completes. + * + * @NL80211_CMD_WIPHY_REG_CHANGE: Similar to %NL80211_CMD_REG_CHANGE, but used + * as an event to indicate changes for devices with wiphy-specific regdom + * management. + * + * @NL80211_CMD_MAX: highest used command number + * @__NL80211_CMD_AFTER_LAST: internal use + */ +enum nl80211_commands { +/* don't change the order or add anything between, this is ABI! */ + NL80211_CMD_UNSPEC, + + NL80211_CMD_GET_WIPHY, /* can dump */ + NL80211_CMD_SET_WIPHY, + NL80211_CMD_NEW_WIPHY, + NL80211_CMD_DEL_WIPHY, + + NL80211_CMD_GET_INTERFACE, /* can dump */ + NL80211_CMD_SET_INTERFACE, + NL80211_CMD_NEW_INTERFACE, + NL80211_CMD_DEL_INTERFACE, + + NL80211_CMD_GET_KEY, + NL80211_CMD_SET_KEY, + NL80211_CMD_NEW_KEY, + NL80211_CMD_DEL_KEY, + + NL80211_CMD_GET_BEACON, + NL80211_CMD_SET_BEACON, + NL80211_CMD_START_AP, + NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP, + NL80211_CMD_STOP_AP, + NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP, + + NL80211_CMD_GET_STATION, + NL80211_CMD_SET_STATION, + NL80211_CMD_NEW_STATION, + NL80211_CMD_DEL_STATION, + + NL80211_CMD_GET_MPATH, + NL80211_CMD_SET_MPATH, + NL80211_CMD_NEW_MPATH, + NL80211_CMD_DEL_MPATH, + + NL80211_CMD_SET_BSS, + + NL80211_CMD_SET_REG, + NL80211_CMD_REQ_SET_REG, + + NL80211_CMD_GET_MESH_CONFIG, + NL80211_CMD_SET_MESH_CONFIG, + + NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */, + + NL80211_CMD_GET_REG, + + NL80211_CMD_GET_SCAN, + NL80211_CMD_TRIGGER_SCAN, + NL80211_CMD_NEW_SCAN_RESULTS, + NL80211_CMD_SCAN_ABORTED, + + NL80211_CMD_REG_CHANGE, + + NL80211_CMD_AUTHENTICATE, + NL80211_CMD_ASSOCIATE, + NL80211_CMD_DEAUTHENTICATE, + NL80211_CMD_DISASSOCIATE, + + NL80211_CMD_MICHAEL_MIC_FAILURE, + + NL80211_CMD_REG_BEACON_HINT, + + NL80211_CMD_JOIN_IBSS, + NL80211_CMD_LEAVE_IBSS, + + NL80211_CMD_TESTMODE, + + NL80211_CMD_CONNECT, + NL80211_CMD_ROAM, + NL80211_CMD_DISCONNECT, + + NL80211_CMD_SET_WIPHY_NETNS, + + NL80211_CMD_GET_SURVEY, + NL80211_CMD_NEW_SURVEY_RESULTS, + + NL80211_CMD_SET_PMKSA, + NL80211_CMD_DEL_PMKSA, + NL80211_CMD_FLUSH_PMKSA, + + NL80211_CMD_REMAIN_ON_CHANNEL, + NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, + + NL80211_CMD_SET_TX_BITRATE_MASK, + + NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME, + NL80211_CMD_FRAME, + NL80211_CMD_ACTION = NL80211_CMD_FRAME, + NL80211_CMD_FRAME_TX_STATUS, + NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS, + + NL80211_CMD_SET_POWER_SAVE, + NL80211_CMD_GET_POWER_SAVE, + + NL80211_CMD_SET_CQM, + NL80211_CMD_NOTIFY_CQM, + + NL80211_CMD_SET_CHANNEL, + NL80211_CMD_SET_WDS_PEER, + + NL80211_CMD_FRAME_WAIT_CANCEL, + + NL80211_CMD_JOIN_MESH, + NL80211_CMD_LEAVE_MESH, + + NL80211_CMD_UNPROT_DEAUTHENTICATE, + NL80211_CMD_UNPROT_DISASSOCIATE, + + NL80211_CMD_NEW_PEER_CANDIDATE, + + NL80211_CMD_GET_WOWLAN, + NL80211_CMD_SET_WOWLAN, + + NL80211_CMD_START_SCHED_SCAN, + NL80211_CMD_STOP_SCHED_SCAN, + NL80211_CMD_SCHED_SCAN_RESULTS, + NL80211_CMD_SCHED_SCAN_STOPPED, + + NL80211_CMD_SET_REKEY_OFFLOAD, + + NL80211_CMD_PMKSA_CANDIDATE, + + NL80211_CMD_TDLS_OPER, + NL80211_CMD_TDLS_MGMT, + + NL80211_CMD_UNEXPECTED_FRAME, + + NL80211_CMD_PROBE_CLIENT, + + NL80211_CMD_REGISTER_BEACONS, + + NL80211_CMD_UNEXPECTED_4ADDR_FRAME, + + NL80211_CMD_SET_NOACK_MAP, + + NL80211_CMD_CH_SWITCH_NOTIFY, + + NL80211_CMD_START_P2P_DEVICE, + NL80211_CMD_STOP_P2P_DEVICE, + + NL80211_CMD_CONN_FAILED, + + NL80211_CMD_SET_MCAST_RATE, + + NL80211_CMD_SET_MAC_ACL, + + NL80211_CMD_RADAR_DETECT, + + NL80211_CMD_GET_PROTOCOL_FEATURES, + + NL80211_CMD_UPDATE_FT_IES, + NL80211_CMD_FT_EVENT, + + NL80211_CMD_CRIT_PROTOCOL_START, + NL80211_CMD_CRIT_PROTOCOL_STOP, + + NL80211_CMD_GET_COALESCE, + NL80211_CMD_SET_COALESCE, + + NL80211_CMD_CHANNEL_SWITCH, + + NL80211_CMD_VENDOR, + + NL80211_CMD_SET_QOS_MAP, + + NL80211_CMD_ADD_TX_TS, + NL80211_CMD_DEL_TX_TS, + + NL80211_CMD_GET_MPP, + + NL80211_CMD_JOIN_OCB, + NL80211_CMD_LEAVE_OCB, + + NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, + + NL80211_CMD_TDLS_CHANNEL_SWITCH, + NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, + + NL80211_CMD_WIPHY_REG_CHANGE, + + /* add new commands above here */ + + /* used to define NL80211_CMD_MAX below */ + __NL80211_CMD_AFTER_LAST, + NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 +}; + +/* + * Allow user space programs to use #ifdef on new commands by defining them + * here + */ +#define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS +#define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE +#define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE +#define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE +#define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE +#define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE +#define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE +#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT + +#define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS + +/* source-level API compatibility */ +#define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG +#define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG +#define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE + +/** + * enum nl80211_attrs - nl80211 netlink attributes + * + * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors + * + * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf. + * /sys/class/ieee80211/<phyname>/index + * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) + * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters + * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz, + * defines the channel together with the (deprecated) + * %NL80211_ATTR_WIPHY_CHANNEL_TYPE attribute or the attributes + * %NL80211_ATTR_CHANNEL_WIDTH and if needed %NL80211_ATTR_CENTER_FREQ1 + * and %NL80211_ATTR_CENTER_FREQ2 + * @NL80211_ATTR_CHANNEL_WIDTH: u32 attribute containing one of the values + * of &enum nl80211_chan_width, describing the channel width. See the + * documentation of the enum for more information. + * @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the + * channel, used for anything but 20 MHz bandwidth + * @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the + * channel, used only for 80+80 MHz bandwidth + * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ + * if HT20 or HT40 are to be used (i.e., HT disabled if not included): + * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including + * this attribute) + * NL80211_CHAN_HT20 = HT20 only + * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel + * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel + * This attribute is now deprecated. + * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is + * less than or equal to the RTS threshold; allowed range: 1..255; + * dot11ShortRetryLimit; u8 + * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is + * greater than the RTS threshold; allowed range: 1..255; + * dot11ShortLongLimit; u8 + * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum + * length in octets for frames; allowed range: 256..8000, disable + * fragmentation with (u32)-1; dot11FragmentationThreshold; u32 + * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length + * larger than or equal to this use RTS/CTS handshake); allowed range: + * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32 + * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11 + * section 7.3.2.9; dot11CoverageClass; u8 + * + * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on + * @NL80211_ATTR_IFNAME: network interface name + * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype + * + * @NL80211_ATTR_WDEV: wireless device identifier, used for pseudo-devices + * that don't have a netdev (u64) + * + * @NL80211_ATTR_MAC: MAC address (various uses) + * + * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of + * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC + * keys + * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3) + * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 + * section 7.3.2.25.1, e.g. 0x000FAC04) + * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and + * CCMP keys, each six bytes in little endian + * @NL80211_ATTR_KEY_DEFAULT: Flag attribute indicating the key is default key + * @NL80211_ATTR_KEY_DEFAULT_MGMT: Flag attribute indicating the key is the + * default management key + * @NL80211_ATTR_CIPHER_SUITES_PAIRWISE: For crypto settings for connect or + * other commands, indicates which pairwise cipher suites are used + * @NL80211_ATTR_CIPHER_SUITE_GROUP: For crypto settings for connect or + * other commands, indicates which group cipher suite is used + * + * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU + * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing + * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE + * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE + * + * @NL80211_ATTR_STA_AID: Association ID for the station (u16) + * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of + * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2) + * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by + * IEEE 802.11 7.3.1.6 (u16). + * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported + * rates as defined by IEEE 802.11 7.3.2.2 but without the length + * restriction (at most %NL80211_MAX_SUPP_RATES). + * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station + * to, or the AP interface the station was originally added to to. + * @NL80211_ATTR_STA_INFO: information about a station, part of station info + * given for %NL80211_CMD_GET_STATION, nested attribute containing + * info as possible, see &enum nl80211_sta_info. + * + * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands, + * consisting of a nested array. + * + * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). + * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link + * (see &enum nl80211_plink_action). + * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. + * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path + * info given for %NL80211_CMD_GET_MPATH, nested attribute described at + * &enum nl80211_mpath_info. + * + * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of + * &enum nl80211_mntr_flags. + * + * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the + * current regulatory domain should be set to or is already set to. + * For example, 'CR', for Costa Rica. This attribute is used by the kernel + * to query the CRDA to retrieve one regulatory domain. This attribute can + * also be used by userspace to query the kernel for the currently set + * regulatory domain. We chose an alpha2 as that is also used by the + * IEEE-802.11 country information element to identify a country. + * Users can also simply ask the wireless core to set regulatory domain + * to a specific alpha2. + * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory + * rules. + * + * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1) + * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled + * (u8, 0 or 1) + * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled + * (u8, 0 or 1) + * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic + * rates in format defined by IEEE 802.11 7.3.2.2 but without the length + * restriction (at most %NL80211_MAX_SUPP_RATES). + * + * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from + * association request when used with NL80211_CMD_NEW_STATION) + * + * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all + * supported interface types, each a flag attribute with the number + * of the interface mode. + * + * @NL80211_ATTR_MGMT_SUBTYPE: Management frame subtype for + * %NL80211_CMD_SET_MGMT_EXTRA_IE. + * + * @NL80211_ATTR_IE: Information element(s) data (used, e.g., with + * %NL80211_CMD_SET_MGMT_EXTRA_IE). + * + * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with + * a single scan request, a wiphy attribute. + * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS: number of SSIDs you can + * scan with a single scheduled scan request, a wiphy attribute. + * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements + * that can be added to a scan request + * @NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: maximum length of information + * elements that can be added to a scheduled scan request + * @NL80211_ATTR_MAX_MATCH_SETS: maximum number of sets that can be + * used with @NL80211_ATTR_SCHED_SCAN_MATCH, a wiphy attribute. + * + * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz) + * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive + * scanning and include a zero-length SSID (wildcard) for wildcard scan + * @NL80211_ATTR_BSS: scan result BSS + * + * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain + * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_* + * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently + * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*) + * + * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies + * an array of command numbers (i.e. a mapping index to command number) + * that the driver for the given wiphy supports. + * + * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header + * and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and + * NL80211_CMD_ASSOCIATE events + * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets) + * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type, + * represented as a u32 + * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and + * %NL80211_CMD_DISASSOCIATE, u16 + * + * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as + * a u32 + * + * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change + * due to considerations from a beacon hint. This attribute reflects + * the state of the channel _before_ the beacon hint processing. This + * attributes consists of a nested attribute containing + * NL80211_FREQUENCY_ATTR_* + * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change + * due to considerations from a beacon hint. This attribute reflects + * the state of the channel _after_ the beacon hint processing. This + * attributes consists of a nested attribute containing + * NL80211_FREQUENCY_ATTR_* + * + * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported + * cipher suites + * + * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look + * for other networks on different channels + * + * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this + * is used, e.g., with %NL80211_CMD_AUTHENTICATE event + * + * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is + * used for the association (&enum nl80211_mfp, represented as a u32); + * this attribute can be used + * with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests + * + * @NL80211_ATTR_STA_FLAGS2: Attribute containing a + * &struct nl80211_sta_flag_update. + * + * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls + * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in + * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE + * request, the driver will assume that the port is unauthorized until + * authorized by user space. Otherwise, port is marked authorized by + * default in station mode. + * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the + * ethertype that will be used for key negotiation. It can be + * specified with the associate and connect commands. If it is not + * specified, the value defaults to 0x888E (PAE, 802.1X). This + * attribute is also used as a flag in the wiphy information to + * indicate that protocols other than PAE are supported. + * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom + * ethertype frames used for key negotiation must not be encrypted. + * + * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. + * We recommend using nested, driver-specific attributes within this. + * + * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT + * event was due to the AP disconnecting the station, and not due to + * a local disconnect request. + * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT + * event (u16) + * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating + * that protected APs should be used. This is also used with NEW_BEACON to + * indicate that the BSS is to use protection. + * + * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON + * to indicate which unicast key ciphers will be used with the connection + * (an array of u32). + * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to + * indicate which group key cipher will be used with the connection (a + * u32). + * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to + * indicate which WPA version(s) the AP we want to associate with is using + * (a u32 with flags from &enum nl80211_wpa_versions). + * @NL80211_ATTR_AKM_SUITES: Used with CONNECT, ASSOCIATE, and NEW_BEACON to + * indicate which key management algorithm(s) to use (an array of u32). + * + * @NL80211_ATTR_REQ_IE: (Re)association request information elements as + * sent out by the card, for ROAM and successful CONNECT events. + * @NL80211_ATTR_RESP_IE: (Re)association response information elements as + * sent by peer, for ROAM and successful CONNECT events. + * + * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE + * commands to specify using a reassociate frame + * + * @NL80211_ATTR_KEY: key information in a nested attribute with + * %NL80211_KEY_* sub-attributes + * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect() + * and join_ibss(), key information is in a nested attribute each + * with %NL80211_KEY_* sub-attributes + * + * @NL80211_ATTR_PID: Process ID of a network namespace. + * + * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for + * dumps. This number increases whenever the object list being + * dumped changes, and as such userspace can verify that it has + * obtained a complete and consistent snapshot by verifying that + * all dump messages contain the same generation number. If it + * changed then the list changed and the dump should be repeated + * completely from scratch. + * + * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface + * + * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of + * the survey response for %NL80211_CMD_GET_SURVEY, nested attribute + * containing info as possible, see &enum survey_info. + * + * @NL80211_ATTR_PMKID: PMK material for PMKSA caching. + * @NL80211_ATTR_MAX_NUM_PMKIDS: maximum number of PMKIDs a firmware can + * cache, a wiphy attribute. + * + * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32. + * @NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: Device attribute that + * specifies the maximum duration that can be requested with the + * remain-on-channel operation, in milliseconds, u32. + * + * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects. + * + * @NL80211_ATTR_TX_RATES: Nested set of attributes + * (enum nl80211_tx_rate_attributes) describing TX rates per band. The + * enum nl80211_band value is used as the index (nla_type() of the nested + * data. If a band is not included, it will be configured to allow all + * rates based on negotiated supported rates information. This attribute + * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. + * + * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain + * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. + * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the + * @NL80211_CMD_REGISTER_FRAME command. + * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be transmitted with + * %NL80211_CMD_FRAME. + * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a + * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing + * information about which frame types can be registered for RX. + * + * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was + * acknowledged by the recipient. + * + * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values. + * + * @NL80211_ATTR_CQM: connection quality monitor configuration in a + * nested attribute with %NL80211_ATTR_CQM_* sub-attributes. + * + * @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command + * is requesting a local authentication/association state change without + * invoking actual management frame exchange. This can be used with + * NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE, + * NL80211_CMD_DISASSOCIATE. + * + * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations + * connected to this BSS. + * + * @NL80211_ATTR_WIPHY_TX_POWER_SETTING: Transmit power setting type. See + * &enum nl80211_tx_power_setting for possible values. + * @NL80211_ATTR_WIPHY_TX_POWER_LEVEL: Transmit power level in signed mBm units. + * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING + * for non-automatic settings. + * + * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly + * means support for per-station GTKs. + * + * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting. + * This can be used to mask out antennas which are not attached or should + * not be used for transmitting. If an antenna is not selected in this + * bitmap the hardware is not allowed to transmit on this antenna. + * + * Each bit represents one antenna, starting with antenna 1 at the first + * bit. Depending on which antennas are selected in the bitmap, 802.11n + * drivers can derive which chainmasks to use (if all antennas belonging to + * a particular chain are disabled this chain should be disabled) and if + * a chain has diversity antennas wether diversity should be used or not. + * HT capabilities (STBC, TX Beamforming, Antenna selection) can be + * derived from the available chains after applying the antenna mask. + * Non-802.11n drivers can derive wether to use diversity or not. + * Drivers may reject configurations or RX/TX mask combinations they cannot + * support by returning -EINVAL. + * + * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving. + * This can be used to mask out antennas which are not attached or should + * not be used for receiving. If an antenna is not selected in this bitmap + * the hardware should not be configured to receive on this antenna. + * For a more detailed description see @NL80211_ATTR_WIPHY_ANTENNA_TX. + * + * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available + * for configuration as TX antennas via the above parameters. + * + * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available + * for configuration as RX antennas via the above parameters. + * + * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS + * + * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be + * transmitted on another channel when the channel given doesn't match + * the current channel. If the current channel doesn't match and this + * flag isn't set, the frame will be rejected. This is also used as an + * nl80211 capability flag. + * + * @NL80211_ATTR_BSS_HT_OPMODE: HT operation mode (u16) + * + * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags + * attributes, specifying what a key should be set as default as. + * See &enum nl80211_key_default_types. + * + * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be + * changed once the mesh is active. + * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute + * containing attributes from &enum nl80211_meshconf_params. + * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver + * allows auth frames in a mesh to be passed to userspace for processing via + * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. + * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as defined in + * &enum nl80211_plink_state. Used when userspace is driving the peer link + * management state machine. @NL80211_MESH_SETUP_USERSPACE_AMPE or + * @NL80211_MESH_SETUP_USERSPACE_MPM must be enabled. + * + * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy + * capabilities, the supported WoWLAN triggers + * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to + * indicate which WoW triggers should be enabled. This is also + * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN + * triggers. + * + * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan + * cycles, in msecs. + * + * @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more + * sets of attributes to match during scheduled scans. Only BSSs + * that match any of the sets will be reported. These are + * pass-thru filter rules. + * For a match to succeed, the BSS must match all attributes of a + * set. Since not every hardware supports matching all types of + * attributes, there is no guarantee that the reported BSSs are + * fully complying with the match sets and userspace needs to be + * able to ignore them by itself. + * Thus, the implementation is somewhat hardware-dependent, but + * this is only an optimization and the userspace application + * needs to handle all the non-filtered results anyway. + * If the match attributes don't make sense when combined with + * the values passed in @NL80211_ATTR_SCAN_SSIDS (eg. if an SSID + * is included in the probe request, but the match attributes + * will never let it go through), -EINVAL may be returned. + * If ommited, no filtering is done. + * + * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported + * interface combinations. In each nested item, it contains attributes + * defined in &enum nl80211_if_combination_attrs. + * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like + * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that + * are managed in software: interfaces of these types aren't subject to + * any restrictions in their number or combinations. + * + * @NL80211_ATTR_REKEY_DATA: nested attribute containing the information + * necessary for GTK rekeying in the device, see &enum nl80211_rekey_data. + * + * @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan, + * nested array attribute containing an entry for each band, with the entry + * being a list of supported rates as defined by IEEE 802.11 7.3.2.2 but + * without the length restriction (at most %NL80211_MAX_SUPP_RATES). + * + * @NL80211_ATTR_HIDDEN_SSID: indicates whether SSID is to be hidden from Beacon + * and Probe Response (when response to wildcard Probe Request); see + * &enum nl80211_hidden_ssid, represented as a u32 + * + * @NL80211_ATTR_IE_PROBE_RESP: Information element(s) for Probe Response frame. + * This is used with %NL80211_CMD_NEW_BEACON and %NL80211_CMD_SET_BEACON to + * provide extra IEs (e.g., WPS/P2P IE) into Probe Response frames when the + * driver (or firmware) replies to Probe Request frames. + * @NL80211_ATTR_IE_ASSOC_RESP: Information element(s) for (Re)Association + * Response frames. This is used with %NL80211_CMD_NEW_BEACON and + * %NL80211_CMD_SET_BEACON to provide extra IEs (e.g., WPS/P2P IE) into + * (Re)Association Response frames when the driver (or firmware) replies to + * (Re)Association Request frames. + * + * @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration + * of the station, see &enum nl80211_sta_wme_attr. + * @NL80211_ATTR_SUPPORT_AP_UAPSD: the device supports uapsd when working + * as AP. + * + * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of + * roaming to another AP in the same ESS if the signal lever is low. + * + * @NL80211_ATTR_PMKSA_CANDIDATE: Nested attribute containing the PMKSA caching + * candidate information, see &enum nl80211_pmksa_candidate_attr. + * + * @NL80211_ATTR_TX_NO_CCK_RATE: Indicates whether to use CCK rate or not + * for management frames transmission. In order to avoid p2p probe/action + * frames are being transmitted at CCK rate in 2GHz band, the user space + * applications use this attribute. + * This attribute is used with %NL80211_CMD_TRIGGER_SCAN and + * %NL80211_CMD_FRAME commands. + * + * @NL80211_ATTR_TDLS_ACTION: Low level TDLS action code (e.g. link setup + * request, link setup confirm, link teardown, etc.). Values are + * described in the TDLS (802.11z) specification. + * @NL80211_ATTR_TDLS_DIALOG_TOKEN: Non-zero token for uniquely identifying a + * TDLS conversation between two devices. + * @NL80211_ATTR_TDLS_OPERATION: High level TDLS operation; see + * &enum nl80211_tdls_operation, represented as a u8. + * @NL80211_ATTR_TDLS_SUPPORT: A flag indicating the device can operate + * as a TDLS peer sta. + * @NL80211_ATTR_TDLS_EXTERNAL_SETUP: The TDLS discovery/setup and teardown + * procedures should be performed by sending TDLS packets via + * %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be + * used for asking the driver to perform a TDLS operation. + * + * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices + * that have AP support to indicate that they have the AP SME integrated + * with support for the features listed in this attribute, see + * &enum nl80211_ap_sme_features. + * + * @NL80211_ATTR_DONT_WAIT_FOR_ACK: Used with %NL80211_CMD_FRAME, this tells + * the driver to not wait for an acknowledgement. Note that due to this, + * it will also not give a status callback nor return a cookie. This is + * mostly useful for probe responses to save airtime. + * + * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from + * &enum nl80211_feature_flags and is advertised in wiphy information. + * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe + * requests while operating in AP-mode. + * This attribute holds a bitmap of the supported protocols for + * offloading (see &enum nl80211_probe_resp_offload_support_attr). + * + * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire + * probe-response frame. The DA field in the 802.11 header is zero-ed out, + * to be filled by the FW. + * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable + * this feature. Currently, only supported in mac80211 drivers. + * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the + * ATTR_HT_CAPABILITY to which attention should be paid. + * Currently, only mac80211 NICs support this feature. + * The values that may be configured are: + * MCS rates, MAX-AMSDU, HT-20-40 and HT_CAP_SGI_40 + * AMPDU density and AMPDU factor. + * All values are treated as suggestions and may be ignored + * by the driver as required. The actual values may be seen in + * the station debugfs ht_caps file. + * + * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country + * abides to when initiating radiation on DFS channels. A country maps + * to one DFS region. + * + * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of + * up to 16 TIDs. + * + * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be + * used by the drivers which has MLME in firmware and does not have support + * to report per station tx/rx activity to free up the staion entry from + * the list. This needs to be used when the driver advertises the + * capability to timeout the stations. + * + * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int); + * this attribute is (depending on the driver capabilities) added to + * received frames indicated with %NL80211_CMD_FRAME. + * + * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds + * or 0 to disable background scan. + * + * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from + * userspace. If unset it is assumed the hint comes directly from + * a user. If set code could specify exactly what type of source + * was used to provide the hint. For the different types of + * allowed user regulatory hints see nl80211_user_reg_hint_type. + * + * @NL80211_ATTR_CONN_FAILED_REASON: The reason for which AP has rejected + * the connection request from a station. nl80211_connect_failed_reason + * enum has different reasons of connection failure. + * + * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts + * with the Authentication transaction sequence number field. + * + * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from + * association request when used with NL80211_CMD_NEW_STATION) + * + * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32) + * + * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with + * the START_AP and SET_BSS commands + * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the + * START_AP and SET_BSS commands. This can have the values 0 or 1; + * if not given in START_AP 0 is assumed, if not given in SET_BSS + * no change is made. + * + * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode + * defined in &enum nl80211_mesh_power_mode. + * + * @NL80211_ATTR_ACL_POLICY: ACL policy, see &enum nl80211_acl_policy, + * carried in a u32 attribute + * + * @NL80211_ATTR_MAC_ADDRS: Array of nested MAC addresses, used for + * MAC ACL. + * + * @NL80211_ATTR_MAC_ACL_MAX: u32 attribute to advertise the maximum + * number of MAC addresses that a device can support for MAC + * ACL. + * + * @NL80211_ATTR_RADAR_EVENT: Type of radar event for notification to userspace, + * contains a value of enum nl80211_radar_event (u32). + * + * @NL80211_ATTR_EXT_CAPA: 802.11 extended capabilities that the kernel driver + * has and handles. The format is the same as the IE contents. See + * 802.11-2012 8.4.2.29 for more information. + * @NL80211_ATTR_EXT_CAPA_MASK: Extended capabilities that the kernel driver + * has set in the %NL80211_ATTR_EXT_CAPA value, for multibit fields. + * + * @NL80211_ATTR_STA_CAPABILITY: Station capabilities (u16) are advertised to + * the driver, e.g., to enable TDLS power save (PU-APSD). + * + * @NL80211_ATTR_STA_EXT_CAPABILITY: Station extended capabilities are + * advertised to the driver, e.g., to enable TDLS off channel operations + * and PU-APSD. + * + * @NL80211_ATTR_PROTOCOL_FEATURES: global nl80211 feature flags, see + * &enum nl80211_protocol_features, the attribute is a u32. + * + * @NL80211_ATTR_SPLIT_WIPHY_DUMP: flag attribute, userspace supports + * receiving the data for a single wiphy split across multiple + * messages, given with wiphy dump message + * + * @NL80211_ATTR_MDID: Mobility Domain Identifier + * + * @NL80211_ATTR_IE_RIC: Resource Information Container Information + * Element + * + * @NL80211_ATTR_CRIT_PROT_ID: critical protocol identifier requiring increased + * reliability, see &enum nl80211_crit_proto_id (u16). + * @NL80211_ATTR_MAX_CRIT_PROT_DURATION: duration in milliseconds in which + * the connection should have increased reliability (u16). + * + * @NL80211_ATTR_PEER_AID: Association ID for the peer TDLS station (u16). + * This is similar to @NL80211_ATTR_STA_AID but with a difference of being + * allowed to be used with the first @NL80211_CMD_SET_STATION command to + * update a TDLS peer STA entry. + * + * @NL80211_ATTR_COALESCE_RULE: Coalesce rule information. + * + * @NL80211_ATTR_CH_SWITCH_COUNT: u32 attribute specifying the number of TBTT's + * until the channel switch event. + * @NL80211_ATTR_CH_SWITCH_BLOCK_TX: flag attribute specifying that transmission + * must be blocked on the current channel (before the channel switch + * operation). + * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information + * for the time while performing a channel switch. + * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel + * switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL). + * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel + * switch counters in the probe response (%NL80211_ATTR_PROBE_RESP). + * + * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32. + * As specified in the &enum nl80211_rxmgmt_flags. + * + * @NL80211_ATTR_STA_SUPPORTED_CHANNELS: array of supported channels. + * + * @NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES: array of supported + * supported operating classes. + * + * @NL80211_ATTR_HANDLE_DFS: A flag indicating whether user space + * controls DFS operation in IBSS mode. If the flag is included in + * %NL80211_CMD_JOIN_IBSS request, the driver will allow use of DFS + * channels and reports radar events to userspace. Userspace is required + * to react to radar events, e.g. initiate a channel switch or leave the + * IBSS network. + * + * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports + * 5 MHz channel bandwidth. + * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports + * 10 MHz channel bandwidth. + * + * @NL80211_ATTR_OPMODE_NOTIF: Operating mode field from Operating Mode + * Notification Element based on association request when used with + * %NL80211_CMD_NEW_STATION; u8 attribute. + * + * @NL80211_ATTR_VENDOR_ID: The vendor ID, either a 24-bit OUI or, if + * %NL80211_VENDOR_ID_IS_LINUX is set, a special Linux ID (not used yet) + * @NL80211_ATTR_VENDOR_SUBCMD: vendor sub-command + * @NL80211_ATTR_VENDOR_DATA: data for the vendor command, if any; this + * attribute is also used for vendor command feature advertisement + * @NL80211_ATTR_VENDOR_EVENTS: used for event list advertising in the wiphy + * info, containing a nested array of possible events + * + * @NL80211_ATTR_QOS_MAP: IP DSCP mapping for Interworking QoS mapping. This + * data is in the format defined for the payload of the QoS Map Set element + * in IEEE Std 802.11-2012, 8.4.2.97. + * + * @NL80211_ATTR_MAC_HINT: MAC address recommendation as initial BSS + * @NL80211_ATTR_WIPHY_FREQ_HINT: frequency of the recommended initial BSS + * + * @NL80211_ATTR_MAX_AP_ASSOC_STA: Device attribute that indicates how many + * associated stations are supported in AP mode (including P2P GO); u32. + * Since drivers may not have a fixed limit on the maximum number (e.g., + * other concurrent operations may affect this), drivers are allowed to + * advertise values that cannot always be met. In such cases, an attempt + * to add a new station entry with @NL80211_CMD_NEW_STATION may fail. + * + * @NL80211_ATTR_CSA_C_OFFSETS_TX: An array of csa counter offsets (u16) which + * should be updated when the frame is transmitted. + * @NL80211_ATTR_MAX_CSA_COUNTERS: U8 attribute used to advertise the maximum + * supported number of csa counters. + * + * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32. + * As specified in the &enum nl80211_tdls_peer_capability. + * + * @NL80211_ATTR_SOCKET_OWNER: Flag attribute, if set during interface + * creation then the new interface will be owned by the netlink socket + * that created it and will be destroyed when the socket is closed. + * If set during scheduled scan start then the new scan req will be + * owned by the netlink socket that created it and the scheduled scan will + * be stopped when the socket is closed. + * If set during configuration of regulatory indoor operation then the + * regulatory indoor configuration would be owned by the netlink socket + * that configured the indoor setting, and the indoor operation would be + * cleared when the socket is closed. + * + * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is + * the TDLS link initiator. + * + * @NL80211_ATTR_USE_RRM: flag for indicating whether the current connection + * shall support Radio Resource Measurements (11k). This attribute can be + * used with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests. + * User space applications are expected to use this flag only if the + * underlying device supports these minimal RRM features: + * %NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES, + * %NL80211_FEATURE_QUIET, + * If this flag is used, driver must add the Power Capabilities IE to the + * association request. In addition, it must also set the RRM capability + * flag in the association request's Capability Info field. + * + * @NL80211_ATTR_WIPHY_DYN_ACK: flag attribute used to enable ACK timeout + * estimation algorithm (dynack). In order to activate dynack + * %NL80211_FEATURE_ACKTO_ESTIMATION feature flag must be set by lower + * drivers to indicate dynack capability. Dynack is automatically disabled + * setting valid value for coverage class. + * + * @NL80211_ATTR_TSID: a TSID value (u8 attribute) + * @NL80211_ATTR_USER_PRIO: user priority value (u8 attribute) + * @NL80211_ATTR_ADMITTED_TIME: admitted time in units of 32 microseconds + * (per second) (u16 attribute) + * + * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see + * &enum nl80211_smps_mode. + * + * @NL80211_ATTR_OPER_CLASS: operating class + * + * @NL80211_ATTR_MAC_MASK: MAC address mask + * + * @NL80211_ATTR_WIPHY_SELF_MANAGED_REG: flag attribute indicating this device + * is self-managing its regulatory information and any regulatory domain + * obtained from it is coming from the device's wiphy and not the global + * cfg80211 regdomain. + * + * @NL80211_ATTR_EXT_FEATURES: extended feature flags contained in a byte + * array. The feature flags are identified by their bit index (see &enum + * nl80211_ext_feature_index). The bit index is ordered starting at the + * least-significant bit of the first byte in the array, ie. bit index 0 + * is located at bit 0 of byte 0. bit index 25 would be located at bit 1 + * of byte 3 (u8 array). + * + * @NL80211_ATTR_SURVEY_RADIO_STATS: Request overall radio statistics to be + * returned along with other survey data. If set, @NL80211_CMD_GET_SURVEY + * may return a survey entry without a channel indicating global radio + * statistics (only some values are valid and make sense.) + * For devices that don't return such an entry even then, the information + * should be contained in the result as the sum of the respective counters + * over all channels. + * + * @NL80211_ATTR_SCHED_SCAN_DELAY: delay before the first cycle of a + * scheduled scan (or a WoWLAN net-detect scan) is started, u32 + * in seconds. + + * @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device + * is operating in an indoor environment. + * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use + */ +enum nl80211_attrs { +/* don't change the order or add anything between, this is ABI! */ + NL80211_ATTR_UNSPEC, + + NL80211_ATTR_WIPHY, + NL80211_ATTR_WIPHY_NAME, + + NL80211_ATTR_IFINDEX, + NL80211_ATTR_IFNAME, + NL80211_ATTR_IFTYPE, + + NL80211_ATTR_MAC, + + NL80211_ATTR_KEY_DATA, + NL80211_ATTR_KEY_IDX, + NL80211_ATTR_KEY_CIPHER, + NL80211_ATTR_KEY_SEQ, + NL80211_ATTR_KEY_DEFAULT, + + NL80211_ATTR_BEACON_INTERVAL, + NL80211_ATTR_DTIM_PERIOD, + NL80211_ATTR_BEACON_HEAD, + NL80211_ATTR_BEACON_TAIL, + + NL80211_ATTR_STA_AID, + NL80211_ATTR_STA_FLAGS, + NL80211_ATTR_STA_LISTEN_INTERVAL, + NL80211_ATTR_STA_SUPPORTED_RATES, + NL80211_ATTR_STA_VLAN, + NL80211_ATTR_STA_INFO, + + NL80211_ATTR_WIPHY_BANDS, + + NL80211_ATTR_MNTR_FLAGS, + + NL80211_ATTR_MESH_ID, + NL80211_ATTR_STA_PLINK_ACTION, + NL80211_ATTR_MPATH_NEXT_HOP, + NL80211_ATTR_MPATH_INFO, + + NL80211_ATTR_BSS_CTS_PROT, + NL80211_ATTR_BSS_SHORT_PREAMBLE, + NL80211_ATTR_BSS_SHORT_SLOT_TIME, + + NL80211_ATTR_HT_CAPABILITY, + + NL80211_ATTR_SUPPORTED_IFTYPES, + + NL80211_ATTR_REG_ALPHA2, + NL80211_ATTR_REG_RULES, + + NL80211_ATTR_MESH_CONFIG, + + NL80211_ATTR_BSS_BASIC_RATES, + + NL80211_ATTR_WIPHY_TXQ_PARAMS, + NL80211_ATTR_WIPHY_FREQ, + NL80211_ATTR_WIPHY_CHANNEL_TYPE, + + NL80211_ATTR_KEY_DEFAULT_MGMT, + + NL80211_ATTR_MGMT_SUBTYPE, + NL80211_ATTR_IE, + + NL80211_ATTR_MAX_NUM_SCAN_SSIDS, + + NL80211_ATTR_SCAN_FREQUENCIES, + NL80211_ATTR_SCAN_SSIDS, + NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */ + NL80211_ATTR_BSS, + + NL80211_ATTR_REG_INITIATOR, + NL80211_ATTR_REG_TYPE, + + NL80211_ATTR_SUPPORTED_COMMANDS, + + NL80211_ATTR_FRAME, + NL80211_ATTR_SSID, + NL80211_ATTR_AUTH_TYPE, + NL80211_ATTR_REASON_CODE, + + NL80211_ATTR_KEY_TYPE, + + NL80211_ATTR_MAX_SCAN_IE_LEN, + NL80211_ATTR_CIPHER_SUITES, + + NL80211_ATTR_FREQ_BEFORE, + NL80211_ATTR_FREQ_AFTER, + + NL80211_ATTR_FREQ_FIXED, + + + NL80211_ATTR_WIPHY_RETRY_SHORT, + NL80211_ATTR_WIPHY_RETRY_LONG, + NL80211_ATTR_WIPHY_FRAG_THRESHOLD, + NL80211_ATTR_WIPHY_RTS_THRESHOLD, + + NL80211_ATTR_TIMED_OUT, + + NL80211_ATTR_USE_MFP, + + NL80211_ATTR_STA_FLAGS2, + + NL80211_ATTR_CONTROL_PORT, + + NL80211_ATTR_TESTDATA, + + NL80211_ATTR_PRIVACY, + + NL80211_ATTR_DISCONNECTED_BY_AP, + NL80211_ATTR_STATUS_CODE, + + NL80211_ATTR_CIPHER_SUITES_PAIRWISE, + NL80211_ATTR_CIPHER_SUITE_GROUP, + NL80211_ATTR_WPA_VERSIONS, + NL80211_ATTR_AKM_SUITES, + + NL80211_ATTR_REQ_IE, + NL80211_ATTR_RESP_IE, + + NL80211_ATTR_PREV_BSSID, + + NL80211_ATTR_KEY, + NL80211_ATTR_KEYS, + + NL80211_ATTR_PID, + + NL80211_ATTR_4ADDR, + + NL80211_ATTR_SURVEY_INFO, + + NL80211_ATTR_PMKID, + NL80211_ATTR_MAX_NUM_PMKIDS, + + NL80211_ATTR_DURATION, + + NL80211_ATTR_COOKIE, + + NL80211_ATTR_WIPHY_COVERAGE_CLASS, + + NL80211_ATTR_TX_RATES, + + NL80211_ATTR_FRAME_MATCH, + + NL80211_ATTR_ACK, + + NL80211_ATTR_PS_STATE, + + NL80211_ATTR_CQM, + + NL80211_ATTR_LOCAL_STATE_CHANGE, + + NL80211_ATTR_AP_ISOLATE, + + NL80211_ATTR_WIPHY_TX_POWER_SETTING, + NL80211_ATTR_WIPHY_TX_POWER_LEVEL, + + NL80211_ATTR_TX_FRAME_TYPES, + NL80211_ATTR_RX_FRAME_TYPES, + NL80211_ATTR_FRAME_TYPE, + + NL80211_ATTR_CONTROL_PORT_ETHERTYPE, + NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, + + NL80211_ATTR_SUPPORT_IBSS_RSN, + + NL80211_ATTR_WIPHY_ANTENNA_TX, + NL80211_ATTR_WIPHY_ANTENNA_RX, + + NL80211_ATTR_MCAST_RATE, + + NL80211_ATTR_OFFCHANNEL_TX_OK, + + NL80211_ATTR_BSS_HT_OPMODE, + + NL80211_ATTR_KEY_DEFAULT_TYPES, + + NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, + + NL80211_ATTR_MESH_SETUP, + + NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, + NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, + + NL80211_ATTR_SUPPORT_MESH_AUTH, + NL80211_ATTR_STA_PLINK_STATE, + + NL80211_ATTR_WOWLAN_TRIGGERS, + NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, + + NL80211_ATTR_SCHED_SCAN_INTERVAL, + + NL80211_ATTR_INTERFACE_COMBINATIONS, + NL80211_ATTR_SOFTWARE_IFTYPES, + + NL80211_ATTR_REKEY_DATA, + + NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, + NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, + + NL80211_ATTR_SCAN_SUPP_RATES, + + NL80211_ATTR_HIDDEN_SSID, + + NL80211_ATTR_IE_PROBE_RESP, + NL80211_ATTR_IE_ASSOC_RESP, + + NL80211_ATTR_STA_WME, + NL80211_ATTR_SUPPORT_AP_UAPSD, + + NL80211_ATTR_ROAM_SUPPORT, + + NL80211_ATTR_SCHED_SCAN_MATCH, + NL80211_ATTR_MAX_MATCH_SETS, + + NL80211_ATTR_PMKSA_CANDIDATE, + + NL80211_ATTR_TX_NO_CCK_RATE, + + NL80211_ATTR_TDLS_ACTION, + NL80211_ATTR_TDLS_DIALOG_TOKEN, + NL80211_ATTR_TDLS_OPERATION, + NL80211_ATTR_TDLS_SUPPORT, + NL80211_ATTR_TDLS_EXTERNAL_SETUP, + + NL80211_ATTR_DEVICE_AP_SME, + + NL80211_ATTR_DONT_WAIT_FOR_ACK, + + NL80211_ATTR_FEATURE_FLAGS, + + NL80211_ATTR_PROBE_RESP_OFFLOAD, + + NL80211_ATTR_PROBE_RESP, + + NL80211_ATTR_DFS_REGION, + + NL80211_ATTR_DISABLE_HT, + NL80211_ATTR_HT_CAPABILITY_MASK, + + NL80211_ATTR_NOACK_MAP, + + NL80211_ATTR_INACTIVITY_TIMEOUT, + + NL80211_ATTR_RX_SIGNAL_DBM, + + NL80211_ATTR_BG_SCAN_PERIOD, + + NL80211_ATTR_WDEV, + + NL80211_ATTR_USER_REG_HINT_TYPE, + + NL80211_ATTR_CONN_FAILED_REASON, + + NL80211_ATTR_SAE_DATA, + + NL80211_ATTR_VHT_CAPABILITY, + + NL80211_ATTR_SCAN_FLAGS, + + NL80211_ATTR_CHANNEL_WIDTH, + NL80211_ATTR_CENTER_FREQ1, + NL80211_ATTR_CENTER_FREQ2, + + NL80211_ATTR_P2P_CTWINDOW, + NL80211_ATTR_P2P_OPPPS, + + NL80211_ATTR_LOCAL_MESH_POWER_MODE, + + NL80211_ATTR_ACL_POLICY, + + NL80211_ATTR_MAC_ADDRS, + + NL80211_ATTR_MAC_ACL_MAX, + + NL80211_ATTR_RADAR_EVENT, + + NL80211_ATTR_EXT_CAPA, + NL80211_ATTR_EXT_CAPA_MASK, + + NL80211_ATTR_STA_CAPABILITY, + NL80211_ATTR_STA_EXT_CAPABILITY, + + NL80211_ATTR_PROTOCOL_FEATURES, + NL80211_ATTR_SPLIT_WIPHY_DUMP, + + NL80211_ATTR_DISABLE_VHT, + NL80211_ATTR_VHT_CAPABILITY_MASK, + + NL80211_ATTR_MDID, + NL80211_ATTR_IE_RIC, + + NL80211_ATTR_CRIT_PROT_ID, + NL80211_ATTR_MAX_CRIT_PROT_DURATION, + + NL80211_ATTR_PEER_AID, + + NL80211_ATTR_COALESCE_RULE, + + NL80211_ATTR_CH_SWITCH_COUNT, + NL80211_ATTR_CH_SWITCH_BLOCK_TX, + NL80211_ATTR_CSA_IES, + NL80211_ATTR_CSA_C_OFF_BEACON, + NL80211_ATTR_CSA_C_OFF_PRESP, + + NL80211_ATTR_RXMGMT_FLAGS, + + NL80211_ATTR_STA_SUPPORTED_CHANNELS, + + NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES, + + NL80211_ATTR_HANDLE_DFS, + + NL80211_ATTR_SUPPORT_5_MHZ, + NL80211_ATTR_SUPPORT_10_MHZ, + + NL80211_ATTR_OPMODE_NOTIF, + + NL80211_ATTR_VENDOR_ID, + NL80211_ATTR_VENDOR_SUBCMD, + NL80211_ATTR_VENDOR_DATA, + NL80211_ATTR_VENDOR_EVENTS, + + NL80211_ATTR_QOS_MAP, + + NL80211_ATTR_MAC_HINT, + NL80211_ATTR_WIPHY_FREQ_HINT, + + NL80211_ATTR_MAX_AP_ASSOC_STA, + + NL80211_ATTR_TDLS_PEER_CAPABILITY, + + NL80211_ATTR_SOCKET_OWNER, + + NL80211_ATTR_CSA_C_OFFSETS_TX, + NL80211_ATTR_MAX_CSA_COUNTERS, + + NL80211_ATTR_TDLS_INITIATOR, + + NL80211_ATTR_USE_RRM, + + NL80211_ATTR_WIPHY_DYN_ACK, + + NL80211_ATTR_TSID, + NL80211_ATTR_USER_PRIO, + NL80211_ATTR_ADMITTED_TIME, + + NL80211_ATTR_SMPS_MODE, + + NL80211_ATTR_OPER_CLASS, + + NL80211_ATTR_MAC_MASK, + + NL80211_ATTR_WIPHY_SELF_MANAGED_REG, + + NL80211_ATTR_EXT_FEATURES, + + NL80211_ATTR_SURVEY_RADIO_STATS, + + NL80211_ATTR_NETNS_FD, + + NL80211_ATTR_SCHED_SCAN_DELAY, + + NL80211_ATTR_REG_INDOOR, + + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, + NUM_NL80211_ATTR = __NL80211_ATTR_AFTER_LAST, + NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 +}; + +/* source-level API compatibility */ +#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION +#define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG +#define NL80211_ATTR_IFACE_SOCKET_OWNER NL80211_ATTR_SOCKET_OWNER + +/* + * Allow user space programs to use #ifdef on new attributes by defining them + * here + */ +#define NL80211_CMD_CONNECT NL80211_CMD_CONNECT +#define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY +#define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES +#define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS +#define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ +#define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE +#define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE +#define NL80211_ATTR_IE NL80211_ATTR_IE +#define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR +#define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE +#define NL80211_ATTR_FRAME NL80211_ATTR_FRAME +#define NL80211_ATTR_SSID NL80211_ATTR_SSID +#define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE +#define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE +#define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE +#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP +#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS +#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES +#define NL80211_ATTR_KEY NL80211_ATTR_KEY +#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS +#define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS + +#define NL80211_MAX_SUPP_RATES 32 +#define NL80211_MAX_SUPP_HT_RATES 77 +#define NL80211_MAX_SUPP_REG_RULES 64 +#define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 +#define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 +#define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 +#define NL80211_HT_CAPABILITY_LEN 26 +#define NL80211_VHT_CAPABILITY_LEN 12 + +#define NL80211_MAX_NR_CIPHER_SUITES 5 +#define NL80211_MAX_NR_AKM_SUITES 2 + +#define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10 + +/* default RSSI threshold for scan results if none specified. */ +#define NL80211_SCAN_RSSI_THOLD_OFF -300 + +#define NL80211_CQM_TXE_MAX_INTVL 1800 + +/** + * enum nl80211_iftype - (virtual) interface types + * + * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides + * @NL80211_IFTYPE_ADHOC: independent BSS member + * @NL80211_IFTYPE_STATION: managed BSS member + * @NL80211_IFTYPE_AP: access point + * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces + * are a bit special in that they must always be tied to a pre-existing + * AP type interface. + * @NL80211_IFTYPE_WDS: wireless distribution interface + * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames + * @NL80211_IFTYPE_MESH_POINT: mesh point + * @NL80211_IFTYPE_P2P_CLIENT: P2P client + * @NL80211_IFTYPE_P2P_GO: P2P group owner + * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev + * and therefore can't be created in the normal ways, use the + * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE + * commands to create and destroy one + * @NL80211_IF_TYPE_OCB: Outside Context of a BSS + * This mode corresponds to the MIB variable dot11OCBActivated=true + * @NL80211_IFTYPE_MAX: highest interface type number currently defined + * @NUM_NL80211_IFTYPES: number of defined interface types + * + * These values are used with the %NL80211_ATTR_IFTYPE + * to set the type of an interface. + * + */ +enum nl80211_iftype { + NL80211_IFTYPE_UNSPECIFIED, + NL80211_IFTYPE_ADHOC, + NL80211_IFTYPE_STATION, + NL80211_IFTYPE_AP, + NL80211_IFTYPE_AP_VLAN, + NL80211_IFTYPE_WDS, + NL80211_IFTYPE_MONITOR, + NL80211_IFTYPE_MESH_POINT, + NL80211_IFTYPE_P2P_CLIENT, + NL80211_IFTYPE_P2P_GO, + NL80211_IFTYPE_P2P_DEVICE, + NL80211_IFTYPE_OCB, + + /* keep last */ + NUM_NL80211_IFTYPES, + NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 +}; + +/** + * enum nl80211_sta_flags - station flags + * + * Station flags. When a station is added to an AP interface, it is + * assumed to be already associated (and hence authenticated.) + * + * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved + * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) + * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames + * with short barker preamble + * @NL80211_STA_FLAG_WME: station is WME/QoS capable + * @NL80211_STA_FLAG_MFP: station uses management frame protection + * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated + * @NL80211_STA_FLAG_TDLS_PEER: station is a TDLS peer -- this flag should + * only be used in managed mode (even in the flags mask). Note that the + * flag can't be changed, it is only valid while adding a station, and + * attempts to change it will silently be ignored (rather than rejected + * as errors.) + * @NL80211_STA_FLAG_ASSOCIATED: station is associated; used with drivers + * that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a + * previously added station into associated state + * @NL80211_STA_FLAG_MAX: highest station flag number currently defined + * @__NL80211_STA_FLAG_AFTER_LAST: internal use + */ +enum nl80211_sta_flags { + __NL80211_STA_FLAG_INVALID, + NL80211_STA_FLAG_AUTHORIZED, + NL80211_STA_FLAG_SHORT_PREAMBLE, + NL80211_STA_FLAG_WME, + NL80211_STA_FLAG_MFP, + NL80211_STA_FLAG_AUTHENTICATED, + NL80211_STA_FLAG_TDLS_PEER, + NL80211_STA_FLAG_ASSOCIATED, + + /* keep last */ + __NL80211_STA_FLAG_AFTER_LAST, + NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 +}; + +#define NL80211_STA_FLAG_MAX_OLD_API NL80211_STA_FLAG_TDLS_PEER + +/** + * struct nl80211_sta_flag_update - station flags mask/set + * @mask: mask of station flags to set + * @set: which values to set them to + * + * Both mask and set contain bits as per &enum nl80211_sta_flags. + */ +struct nl80211_sta_flag_update { + __u32 mask; + __u32 set; +} __attribute__((packed)); + +/** + * enum nl80211_rate_info - bitrate information + * + * These attribute types are used with %NL80211_STA_INFO_TXRATE + * when getting information about the bitrate of a station. + * There are 2 attributes for bitrate, a legacy one that represents + * a 16-bit value, and new one that represents a 32-bit value. + * If the rate value fits into 16 bit, both attributes are reported + * with the same value. If the rate is too high to fit into 16 bits + * (>6.5535Gbps) only 32-bit attribute is included. + * User space tools encouraged to use the 32-bit attribute and fall + * back to the 16-bit one for compatibility with older kernels. + * + * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved + * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) + * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) + * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate + * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval + * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s) + * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined + * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8) + * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8) + * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate + * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: unused - 80+80 is treated the + * same as 160 for purposes of the bitrates + * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate + * @NL80211_RATE_INFO_10_MHZ_WIDTH: 10 MHz width - note that this is + * a legacy rate and will be reported as the actual bitrate, i.e. + * half the base (20 MHz) rate + * @NL80211_RATE_INFO_5_MHZ_WIDTH: 5 MHz width - note that this is + * a legacy rate and will be reported as the actual bitrate, i.e. + * a quarter of the base (20 MHz) rate + * @__NL80211_RATE_INFO_AFTER_LAST: internal use + */ +enum nl80211_rate_info { + __NL80211_RATE_INFO_INVALID, + NL80211_RATE_INFO_BITRATE, + NL80211_RATE_INFO_MCS, + NL80211_RATE_INFO_40_MHZ_WIDTH, + NL80211_RATE_INFO_SHORT_GI, + NL80211_RATE_INFO_BITRATE32, + NL80211_RATE_INFO_VHT_MCS, + NL80211_RATE_INFO_VHT_NSS, + NL80211_RATE_INFO_80_MHZ_WIDTH, + NL80211_RATE_INFO_80P80_MHZ_WIDTH, + NL80211_RATE_INFO_160_MHZ_WIDTH, + NL80211_RATE_INFO_10_MHZ_WIDTH, + NL80211_RATE_INFO_5_MHZ_WIDTH, + + /* keep last */ + __NL80211_RATE_INFO_AFTER_LAST, + NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 +}; + +/** + * enum nl80211_sta_bss_param - BSS information collected by STA + * + * These attribute types are used with %NL80211_STA_INFO_BSS_PARAM + * when getting information about the bitrate of a station. + * + * @__NL80211_STA_BSS_PARAM_INVALID: attribute number 0 is reserved + * @NL80211_STA_BSS_PARAM_CTS_PROT: whether CTS protection is enabled (flag) + * @NL80211_STA_BSS_PARAM_SHORT_PREAMBLE: whether short preamble is enabled + * (flag) + * @NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME: whether short slot time is enabled + * (flag) + * @NL80211_STA_BSS_PARAM_DTIM_PERIOD: DTIM period for beaconing (u8) + * @NL80211_STA_BSS_PARAM_BEACON_INTERVAL: Beacon interval (u16) + * @NL80211_STA_BSS_PARAM_MAX: highest sta_bss_param number currently defined + * @__NL80211_STA_BSS_PARAM_AFTER_LAST: internal use + */ +enum nl80211_sta_bss_param { + __NL80211_STA_BSS_PARAM_INVALID, + NL80211_STA_BSS_PARAM_CTS_PROT, + NL80211_STA_BSS_PARAM_SHORT_PREAMBLE, + NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME, + NL80211_STA_BSS_PARAM_DTIM_PERIOD, + NL80211_STA_BSS_PARAM_BEACON_INTERVAL, + + /* keep last */ + __NL80211_STA_BSS_PARAM_AFTER_LAST, + NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1 +}; + +/** + * enum nl80211_sta_info - station information + * + * These attribute types are used with %NL80211_ATTR_STA_INFO + * when getting information about a station. + * + * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved + * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) + * @NL80211_STA_INFO_RX_BYTES: total received bytes (MPDU length) + * (u32, from this station) + * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (MPDU length) + * (u32, to this station) + * @NL80211_STA_INFO_RX_BYTES64: total received bytes (MPDU length) + * (u64, from this station) + * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (MPDU length) + * (u64, to this station) + * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) + * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute + * containing info as possible, see &enum nl80211_rate_info + * @NL80211_STA_INFO_RX_PACKETS: total received packet (MSDUs and MMPDUs) + * (u32, from this station) + * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (MSDUs and MMPDUs) + * (u32, to this station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (MPDUs) (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (MPDUs) + * (u32, to this station) + * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) + * @NL80211_STA_INFO_LLID: the station's mesh LLID + * @NL80211_STA_INFO_PLID: the station's mesh PLID + * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station + * (see %enum nl80211_plink_state) + * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested + * attribute, like NL80211_STA_INFO_TX_BITRATE. + * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute + * containing info as possible, see &enum nl80211_sta_bss_param + * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected + * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. + * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32) + * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64) + * @NL80211_STA_INFO_LOCAL_PM: local mesh STA link-specific power mode + * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode + * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards + * non-peer STA + * @NL80211_STA_INFO_CHAIN_SIGNAL: per-chain signal strength of last PPDU + * Contains a nested array of signal strength attributes (u8, dBm) + * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average + * Same format as NL80211_STA_INFO_CHAIN_SIGNAL. + * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the + * 802.11 header (u32, kbps) + * @NL80211_STA_INFO_RX_DROP_MISC: RX packets dropped for unspecified reasons + * (u64) + * @NL80211_STA_INFO_BEACON_RX: number of beacons received from this peer (u64) + * @NL80211_STA_INFO_BEACON_SIGNAL_AVG: signal strength average + * for beacons only (u8, dBm) + * @NL80211_STA_INFO_TID_STATS: per-TID statistics (see &enum nl80211_tid_stats) + * This is a nested attribute where each the inner attribute number is the + * TID+1 and the special TID 16 (i.e. value 17) is used for non-QoS frames; + * each one of those is again nested with &enum nl80211_tid_stats + * attributes carrying the actual values. + * @__NL80211_STA_INFO_AFTER_LAST: internal + * @NL80211_STA_INFO_MAX: highest possible station info attribute + */ +enum nl80211_sta_info { + __NL80211_STA_INFO_INVALID, + NL80211_STA_INFO_INACTIVE_TIME, + NL80211_STA_INFO_RX_BYTES, + NL80211_STA_INFO_TX_BYTES, + NL80211_STA_INFO_LLID, + NL80211_STA_INFO_PLID, + NL80211_STA_INFO_PLINK_STATE, + NL80211_STA_INFO_SIGNAL, + NL80211_STA_INFO_TX_BITRATE, + NL80211_STA_INFO_RX_PACKETS, + NL80211_STA_INFO_TX_PACKETS, + NL80211_STA_INFO_TX_RETRIES, + NL80211_STA_INFO_TX_FAILED, + NL80211_STA_INFO_SIGNAL_AVG, + NL80211_STA_INFO_RX_BITRATE, + NL80211_STA_INFO_BSS_PARAM, + NL80211_STA_INFO_CONNECTED_TIME, + NL80211_STA_INFO_STA_FLAGS, + NL80211_STA_INFO_BEACON_LOSS, + NL80211_STA_INFO_T_OFFSET, + NL80211_STA_INFO_LOCAL_PM, + NL80211_STA_INFO_PEER_PM, + NL80211_STA_INFO_NONPEER_PM, + NL80211_STA_INFO_RX_BYTES64, + NL80211_STA_INFO_TX_BYTES64, + NL80211_STA_INFO_CHAIN_SIGNAL, + NL80211_STA_INFO_CHAIN_SIGNAL_AVG, + NL80211_STA_INFO_EXPECTED_THROUGHPUT, + NL80211_STA_INFO_RX_DROP_MISC, + NL80211_STA_INFO_BEACON_RX, + NL80211_STA_INFO_BEACON_SIGNAL_AVG, + NL80211_STA_INFO_TID_STATS, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, + NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 +}; + +/** + * enum nl80211_tid_stats - per TID statistics attributes + * @__NL80211_TID_STATS_INVALID: attribute number 0 is reserved + * @NL80211_TID_STATS_RX_MSDU: number of MSDUs received (u64) + * @NL80211_TID_STATS_TX_MSDU: number of MSDUs transmitted (or + * attempted to transmit; u64) + * @NL80211_TID_STATS_TX_MSDU_RETRIES: number of retries for + * transmitted MSDUs (not counting the first attempt; u64) + * @NL80211_TID_STATS_TX_MSDU_FAILED: number of failed transmitted + * MSDUs (u64) + * @NUM_NL80211_TID_STATS: number of attributes here + * @NL80211_TID_STATS_MAX: highest numbered attribute here + */ +enum nl80211_tid_stats { + __NL80211_TID_STATS_INVALID, + NL80211_TID_STATS_RX_MSDU, + NL80211_TID_STATS_TX_MSDU, + NL80211_TID_STATS_TX_MSDU_RETRIES, + NL80211_TID_STATS_TX_MSDU_FAILED, + + /* keep last */ + NUM_NL80211_TID_STATS, + NL80211_TID_STATS_MAX = NUM_NL80211_TID_STATS - 1 +}; + +/** + * enum nl80211_mpath_flags - nl80211 mesh path flags + * + * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active + * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running + * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN + * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set + * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded + */ +enum nl80211_mpath_flags { + NL80211_MPATH_FLAG_ACTIVE = 1<<0, + NL80211_MPATH_FLAG_RESOLVING = 1<<1, + NL80211_MPATH_FLAG_SN_VALID = 1<<2, + NL80211_MPATH_FLAG_FIXED = 1<<3, + NL80211_MPATH_FLAG_RESOLVED = 1<<4, +}; + +/** + * enum nl80211_mpath_info - mesh path information + * + * These attribute types are used with %NL80211_ATTR_MPATH_INFO when getting + * information about a mesh path. + * + * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved + * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination + * @NL80211_MPATH_INFO_SN: destination sequence number + * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path + * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now + * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in + * &enum nl80211_mpath_flags; + * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec + * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries + * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number + * currently defind + * @__NL80211_MPATH_INFO_AFTER_LAST: internal use + */ +enum nl80211_mpath_info { + __NL80211_MPATH_INFO_INVALID, + NL80211_MPATH_INFO_FRAME_QLEN, + NL80211_MPATH_INFO_SN, + NL80211_MPATH_INFO_METRIC, + NL80211_MPATH_INFO_EXPTIME, + NL80211_MPATH_INFO_FLAGS, + NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, + NL80211_MPATH_INFO_DISCOVERY_RETRIES, + + /* keep last */ + __NL80211_MPATH_INFO_AFTER_LAST, + NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1 +}; + +/** + * enum nl80211_band_attr - band attributes + * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band, + * an array of nested frequency attributes + * @NL80211_BAND_ATTR_RATES: supported bitrates in this band, + * an array of nested bitrate attributes + * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as + * defined in 802.11n + * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE + * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n + * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n + * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as + * defined in 802.11ac + * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE + * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined + * @__NL80211_BAND_ATTR_AFTER_LAST: internal use + */ +enum nl80211_band_attr { + __NL80211_BAND_ATTR_INVALID, + NL80211_BAND_ATTR_FREQS, + NL80211_BAND_ATTR_RATES, + + NL80211_BAND_ATTR_HT_MCS_SET, + NL80211_BAND_ATTR_HT_CAPA, + NL80211_BAND_ATTR_HT_AMPDU_FACTOR, + NL80211_BAND_ATTR_HT_AMPDU_DENSITY, + + NL80211_BAND_ATTR_VHT_MCS_SET, + NL80211_BAND_ATTR_VHT_CAPA, + + /* keep last */ + __NL80211_BAND_ATTR_AFTER_LAST, + NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 +}; + +#define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA + +/** + * enum nl80211_frequency_attr - frequency attributes + * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz + * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current + * regulatory domain. + * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation + * are permitted on this channel, this includes sending probe + * requests, or modes of operation that require beaconing. + * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm + * (100 * dBm). + * @NL80211_FREQUENCY_ATTR_DFS_STATE: current state for DFS + * (enum nl80211_dfs_state) + * @NL80211_FREQUENCY_ATTR_DFS_TIME: time in miliseconds for how long + * this channel is in this DFS state. + * @NL80211_FREQUENCY_ATTR_NO_HT40_MINUS: HT40- isn't possible with this + * channel as the control channel + * @NL80211_FREQUENCY_ATTR_NO_HT40_PLUS: HT40+ isn't possible with this + * channel as the control channel + * @NL80211_FREQUENCY_ATTR_NO_80MHZ: any 80 MHz channel using this channel + * as the primary or any of the secondary channels isn't possible, + * this includes 80+80 channels + * @NL80211_FREQUENCY_ATTR_NO_160MHZ: any 160 MHz (but not 80+80) channel + * using this channel as the primary or any of the secondary channels + * isn't possible + * @NL80211_FREQUENCY_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. + * @NL80211_FREQUENCY_ATTR_INDOOR_ONLY: Only indoor use is permitted on this + * channel. A channel that has the INDOOR_ONLY attribute can only be + * used when there is a clear assessment that the device is operating in + * an indoor surroundings, i.e., it is connected to AC power (and not + * through portable DC inverters) or is under the control of a master + * that is acting as an AP and is connected to AC power. + * @NL80211_FREQUENCY_ATTR_GO_CONCURRENT: GO operation is allowed on this + * channel if it's connected concurrently to a BSS on the same channel on + * the 2 GHz band or to a channel in the same UNII band (on the 5 GHz + * band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO on a + * channel that has the GO_CONCURRENT attribute set can be done when there + * is a clear assessment that the device is operating under the guidance of + * an authorized master, i.e., setting up a GO while the device is also + * connected to an AP with DFS and radar detection on the UNII band (it is + * up to user-space, i.e., wpa_supplicant to perform the required + * verifications) + * @NL80211_FREQUENCY_ATTR_NO_20MHZ: 20 MHz operation is not allowed + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_NO_10MHZ: 10 MHz operation is not allowed + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + * + * See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122 + * for more information on the FCC description of the relaxations allowed + * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and + * NL80211_FREQUENCY_ATTR_GO_CONCURRENT. + */ +enum nl80211_frequency_attr { + __NL80211_FREQUENCY_ATTR_INVALID, + NL80211_FREQUENCY_ATTR_FREQ, + NL80211_FREQUENCY_ATTR_DISABLED, + NL80211_FREQUENCY_ATTR_NO_IR, + __NL80211_FREQUENCY_ATTR_NO_IBSS, + NL80211_FREQUENCY_ATTR_RADAR, + NL80211_FREQUENCY_ATTR_MAX_TX_POWER, + NL80211_FREQUENCY_ATTR_DFS_STATE, + NL80211_FREQUENCY_ATTR_DFS_TIME, + NL80211_FREQUENCY_ATTR_NO_HT40_MINUS, + NL80211_FREQUENCY_ATTR_NO_HT40_PLUS, + NL80211_FREQUENCY_ATTR_NO_80MHZ, + NL80211_FREQUENCY_ATTR_NO_160MHZ, + NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, + NL80211_FREQUENCY_ATTR_INDOOR_ONLY, + NL80211_FREQUENCY_ATTR_GO_CONCURRENT, + NL80211_FREQUENCY_ATTR_NO_20MHZ, + NL80211_FREQUENCY_ATTR_NO_10MHZ, + + /* keep last */ + __NL80211_FREQUENCY_ATTR_AFTER_LAST, + NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1 +}; + +#define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER +#define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR +#define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR +#define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR + +/** + * enum nl80211_bitrate_attr - bitrate attributes + * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps + * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported + * in 2.4 GHz band. + * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number + * currently defined + * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use + */ +enum nl80211_bitrate_attr { + __NL80211_BITRATE_ATTR_INVALID, + NL80211_BITRATE_ATTR_RATE, + NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE, + + /* keep last */ + __NL80211_BITRATE_ATTR_AFTER_LAST, + NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_initiator - Indicates the initiator of a reg domain request + * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world + * regulatory domain. + * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the + * regulatory domain. + * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the + * wireless core it thinks its knows the regulatory domain we should be in. + * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an + * 802.11 country information element with regulatory information it + * thinks we should consider. cfg80211 only processes the country + * code from the IE, and relies on the regulatory domain information + * structure passed by userspace (CRDA) from our wireless-regdb. + * If a channel is enabled but the country code indicates it should + * be disabled we disable the channel and re-enable it upon disassociation. + */ +enum nl80211_reg_initiator { + NL80211_REGDOM_SET_BY_CORE, + NL80211_REGDOM_SET_BY_USER, + NL80211_REGDOM_SET_BY_DRIVER, + NL80211_REGDOM_SET_BY_COUNTRY_IE, +}; + +/** + * enum nl80211_reg_type - specifies the type of regulatory domain + * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains + * to a specific country. When this is set you can count on the + * ISO / IEC 3166 alpha2 country code being valid. + * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory + * domain. + * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom + * driver specific world regulatory domain. These do not apply system-wide + * and are only applicable to the individual devices which have requested + * them to be applied. + * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product + * of an intersection between two regulatory domains -- the previously + * set regulatory domain on the system and the last accepted regulatory + * domain request to be processed. + */ +enum nl80211_reg_type { + NL80211_REGDOM_TYPE_COUNTRY, + NL80211_REGDOM_TYPE_WORLD, + NL80211_REGDOM_TYPE_CUSTOM_WORLD, + NL80211_REGDOM_TYPE_INTERSECTION, +}; + +/** + * enum nl80211_reg_rule_attr - regulatory rule attributes + * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional + * considerations for a given frequency range. These are the + * &enum nl80211_reg_rule_flags. + * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory + * rule in KHz. This is not a center of frequency but an actual regulatory + * band edge. + * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule + * in KHz. This is not a center a frequency but an actual regulatory + * band edge. + * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this + * frequency range, in KHz. + * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain + * for a given frequency range. The value is in mBi (100 * dBi). + * If you don't have one then don't send this. + * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for + * a given frequency range. The value is in mBm (100 * dBm). + * @NL80211_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds. + * If not present or 0 default CAC time will be used. + * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number + * currently defined + * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use + */ +enum nl80211_reg_rule_attr { + __NL80211_REG_RULE_ATTR_INVALID, + NL80211_ATTR_REG_RULE_FLAGS, + + NL80211_ATTR_FREQ_RANGE_START, + NL80211_ATTR_FREQ_RANGE_END, + NL80211_ATTR_FREQ_RANGE_MAX_BW, + + NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, + NL80211_ATTR_POWER_RULE_MAX_EIRP, + + NL80211_ATTR_DFS_CAC_TIME, + + /* keep last */ + __NL80211_REG_RULE_ATTR_AFTER_LAST, + NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_sched_scan_match_attr - scheduled scan match attributes + * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved + * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, + * only report BSS with matching SSID. + * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a + * BSS in scan results. Filtering is turned off if not specified. Note that + * if this attribute is in a match set of its own, then it is treated as + * the default value for all matchsets with an SSID, rather than being a + * matchset of its own without an RSSI filter. This is due to problems with + * how this API was implemented in the past. Also, due to the same problem, + * the only way to create a matchset with only an RSSI filter (with this + * attribute) is if there's only a single matchset with the RSSI attribute. + * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter + * attribute number currently defined + * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use + */ +enum nl80211_sched_scan_match_attr { + __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID, + + NL80211_SCHED_SCAN_MATCH_ATTR_SSID, + NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, + + /* keep last */ + __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, + NL80211_SCHED_SCAN_MATCH_ATTR_MAX = + __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 +}; + +/* only for backward compatibility */ +#define NL80211_ATTR_SCHED_SCAN_MATCH_SSID NL80211_SCHED_SCAN_MATCH_ATTR_SSID + +/** + * enum nl80211_reg_rule_flags - regulatory rule flags + * + * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed + * @NL80211_RRF_NO_CCK: CCK modulation not allowed + * @NL80211_RRF_NO_INDOOR: indoor operation not allowed + * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed + * @NL80211_RRF_DFS: DFS support is required to be used + * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links + * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links + * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, + * this includes probe requests or modes of operation that require + * beaconing. + * @NL80211_RRF_AUTO_BW: maximum available bandwidth should be calculated + * base on contiguous rules and wider channels will be allowed to cross + * multiple contiguous/overlapping frequency ranges. + * @NL80211_RRF_GO_CONCURRENT: See &NL80211_FREQUENCY_ATTR_GO_CONCURRENT + * @NL80211_RRF_NO_HT40MINUS: channels can't be used in HT40- operation + * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation + * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed + * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed + */ +enum nl80211_reg_rule_flags { + NL80211_RRF_NO_OFDM = 1<<0, + NL80211_RRF_NO_CCK = 1<<1, + NL80211_RRF_NO_INDOOR = 1<<2, + NL80211_RRF_NO_OUTDOOR = 1<<3, + NL80211_RRF_DFS = 1<<4, + NL80211_RRF_PTP_ONLY = 1<<5, + NL80211_RRF_PTMP_ONLY = 1<<6, + NL80211_RRF_NO_IR = 1<<7, + __NL80211_RRF_NO_IBSS = 1<<8, + NL80211_RRF_AUTO_BW = 1<<11, + NL80211_RRF_GO_CONCURRENT = 1<<12, + NL80211_RRF_NO_HT40MINUS = 1<<13, + NL80211_RRF_NO_HT40PLUS = 1<<14, + NL80211_RRF_NO_80MHZ = 1<<15, + NL80211_RRF_NO_160MHZ = 1<<16, +}; + +#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR +#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR +#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR +#define NL80211_RRF_NO_HT40 (NL80211_RRF_NO_HT40MINUS |\ + NL80211_RRF_NO_HT40PLUS) + +/* For backport compatibility with older userspace */ +#define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) + +/** + * enum nl80211_dfs_regions - regulatory DFS regions + * + * @NL80211_DFS_UNSET: Country has no DFS master region specified + * @NL80211_DFS_FCC: Country follows DFS master rules from FCC + * @NL80211_DFS_ETSI: Country follows DFS master rules from ETSI + * @NL80211_DFS_JP: Country follows DFS master rules from JP/MKK/Telec + */ +enum nl80211_dfs_regions { + NL80211_DFS_UNSET = 0, + NL80211_DFS_FCC = 1, + NL80211_DFS_ETSI = 2, + NL80211_DFS_JP = 3, +}; + +/** + * enum nl80211_user_reg_hint_type - type of user regulatory hint + * + * @NL80211_USER_REG_HINT_USER: a user sent the hint. This is always + * assumed if the attribute is not set. + * @NL80211_USER_REG_HINT_CELL_BASE: the hint comes from a cellular + * base station. Device drivers that have been tested to work + * properly to support this type of hint can enable these hints + * by setting the NL80211_FEATURE_CELL_BASE_REG_HINTS feature + * capability on the struct wiphy. The wireless core will + * ignore all cell base station hints until at least one device + * present has been registered with the wireless core that + * has listed NL80211_FEATURE_CELL_BASE_REG_HINTS as a + * supported feature. + * @NL80211_USER_REG_HINT_INDOOR: a user sent an hint indicating that the + * platform is operating in an indoor environment. + */ +enum nl80211_user_reg_hint_type { + NL80211_USER_REG_HINT_USER = 0, + NL80211_USER_REG_HINT_CELL_BASE = 1, + NL80211_USER_REG_HINT_INDOOR = 2, +}; + +/** + * enum nl80211_survey_info - survey information + * + * These attribute types are used with %NL80211_ATTR_SURVEY_INFO + * when getting information about a survey. + * + * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved + * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel + * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) + * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used + * @NL80211_SURVEY_INFO_TIME: amount of time (in ms) that the radio + * was turned on (on channel or globally) + * @NL80211_SURVEY_INFO_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_TIME_RX: amount of time the radio spent + * receiving data (on channel or globally) + * @NL80211_SURVEY_INFO_TIME_TX: amount of time the radio spent + * transmitting data (on channel or globally) + * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan + * (on this channel or globally) + * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number + * currently defined + * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use + */ +enum nl80211_survey_info { + __NL80211_SURVEY_INFO_INVALID, + NL80211_SURVEY_INFO_FREQUENCY, + NL80211_SURVEY_INFO_NOISE, + NL80211_SURVEY_INFO_IN_USE, + NL80211_SURVEY_INFO_TIME, + NL80211_SURVEY_INFO_TIME_BUSY, + NL80211_SURVEY_INFO_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_TIME_RX, + NL80211_SURVEY_INFO_TIME_TX, + NL80211_SURVEY_INFO_TIME_SCAN, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, + NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 +}; + +/* keep old names for compatibility */ +#define NL80211_SURVEY_INFO_CHANNEL_TIME NL80211_SURVEY_INFO_TIME +#define NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY NL80211_SURVEY_INFO_TIME_BUSY +#define NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY NL80211_SURVEY_INFO_TIME_EXT_BUSY +#define NL80211_SURVEY_INFO_CHANNEL_TIME_RX NL80211_SURVEY_INFO_TIME_RX +#define NL80211_SURVEY_INFO_CHANNEL_TIME_TX NL80211_SURVEY_INFO_TIME_TX + +/** + * enum nl80211_mntr_flags - monitor configuration flags + * + * Monitor configuration flags. + * + * @__NL80211_MNTR_FLAG_INVALID: reserved + * + * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS + * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP + * @NL80211_MNTR_FLAG_CONTROL: pass control frames + * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering + * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing. + * overrides all other flags. + * @NL80211_MNTR_FLAG_ACTIVE: use the configured MAC address + * and ACK incoming unicast packets. + * + * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use + * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag + */ +enum nl80211_mntr_flags { + __NL80211_MNTR_FLAG_INVALID, + NL80211_MNTR_FLAG_FCSFAIL, + NL80211_MNTR_FLAG_PLCPFAIL, + NL80211_MNTR_FLAG_CONTROL, + NL80211_MNTR_FLAG_OTHER_BSS, + NL80211_MNTR_FLAG_COOK_FRAMES, + NL80211_MNTR_FLAG_ACTIVE, + + /* keep last */ + __NL80211_MNTR_FLAG_AFTER_LAST, + NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1 +}; + +/** + * enum nl80211_mesh_power_mode - mesh power save modes + * + * @NL80211_MESH_POWER_UNKNOWN: The mesh power mode of the mesh STA is + * not known or has not been set yet. + * @NL80211_MESH_POWER_ACTIVE: Active mesh power mode. The mesh STA is + * in Awake state all the time. + * @NL80211_MESH_POWER_LIGHT_SLEEP: Light sleep mode. The mesh STA will + * alternate between Active and Doze states, but will wake up for + * neighbor's beacons. + * @NL80211_MESH_POWER_DEEP_SLEEP: Deep sleep mode. The mesh STA will + * alternate between Active and Doze states, but may not wake up + * for neighbor's beacons. + * + * @__NL80211_MESH_POWER_AFTER_LAST - internal use + * @NL80211_MESH_POWER_MAX - highest possible power save level + */ + +enum nl80211_mesh_power_mode { + NL80211_MESH_POWER_UNKNOWN, + NL80211_MESH_POWER_ACTIVE, + NL80211_MESH_POWER_LIGHT_SLEEP, + NL80211_MESH_POWER_DEEP_SLEEP, + + __NL80211_MESH_POWER_AFTER_LAST, + NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1 +}; + +/** + * enum nl80211_meshconf_params - mesh configuration parameters + * + * Mesh configuration parameters. These can be changed while the mesh is + * active. + * + * @__NL80211_MESHCONF_INVALID: internal use + * + * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in + * millisecond units, used by the Peer Link Open message + * + * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in + * millisecond units, used by the peer link management to close a peer link + * + * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in + * millisecond units + * + * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed + * on this mesh interface + * + * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link + * open retries that can be sent to establish a new peer link instance in a + * mesh + * + * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh + * point. + * + * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically open + * peer links when we detect compatible mesh peers. Disabled if + * @NL80211_MESH_SETUP_USERSPACE_MPM or @NL80211_MESH_SETUP_USERSPACE_AMPE are + * set. + * + * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames + * containing a PREQ that an MP can send to a particular destination (path + * target) + * + * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths + * (in milliseconds) + * + * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait + * until giving up on a path discovery (in milliseconds) + * + * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh + * points receiving a PREQ shall consider the forwarding information from + * the root to be valid. (TU = time unit) + * + * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in + * TUs) during which an MP can send only one action frame containing a PREQ + * reference element + * + * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) + * that it takes for an HWMP information element to propagate across the + * mesh + * + * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not + * + * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a + * source mesh point for path selection elements. + * + * @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between + * root announcements are transmitted. + * + * @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has + * access to a broader network beyond the MBSS. This is done via Root + * Announcement frames. + * + * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in + * TUs) during which a mesh STA can send only one Action frame containing a + * PERR element. + * + * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding + * or forwarding entity (default is TRUE - forwarding entity) + * + * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the + * threshold for average signal strength of candidate station to establish + * a peer link. + * + * @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors + * to synchronize to for 11s default synchronization method + * (see 11C.12.2.2) + * + * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode. + * + * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute + * + * @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for + * which mesh STAs receiving a proactive PREQ shall consider the forwarding + * information to the root mesh STA to be valid. + * + * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between + * proactive PREQs are transmitted. + * + * @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time + * (in TUs) during which a mesh STA can send only one Action frame + * containing a PREQ element for root path confirmation. + * + * @NL80211_MESHCONF_POWER_MODE: Default mesh power mode for new peer links. + * type &enum nl80211_mesh_power_mode (u32) + * + * @NL80211_MESHCONF_AWAKE_WINDOW: awake window duration (in TUs) + * + * @NL80211_MESHCONF_PLINK_TIMEOUT: If no tx activity is seen from a STA we've + * established peering with for longer than this time (in seconds), then + * remove it from the STA's list of peers. You may set this to 0 to disable + * the removal of the STA. Default is 30 minutes. + * + * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use + */ +enum nl80211_meshconf_params { + __NL80211_MESHCONF_INVALID, + NL80211_MESHCONF_RETRY_TIMEOUT, + NL80211_MESHCONF_CONFIRM_TIMEOUT, + NL80211_MESHCONF_HOLDING_TIMEOUT, + NL80211_MESHCONF_MAX_PEER_LINKS, + NL80211_MESHCONF_MAX_RETRIES, + NL80211_MESHCONF_TTL, + NL80211_MESHCONF_AUTO_OPEN_PLINKS, + NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, + NL80211_MESHCONF_PATH_REFRESH_TIME, + NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, + NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, + NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, + NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, + NL80211_MESHCONF_HWMP_ROOTMODE, + NL80211_MESHCONF_ELEMENT_TTL, + NL80211_MESHCONF_HWMP_RANN_INTERVAL, + NL80211_MESHCONF_GATE_ANNOUNCEMENTS, + NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, + NL80211_MESHCONF_FORWARDING, + NL80211_MESHCONF_RSSI_THRESHOLD, + NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, + NL80211_MESHCONF_HT_OPMODE, + NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, + NL80211_MESHCONF_HWMP_ROOT_INTERVAL, + NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, + NL80211_MESHCONF_POWER_MODE, + NL80211_MESHCONF_AWAKE_WINDOW, + NL80211_MESHCONF_PLINK_TIMEOUT, + + /* keep last */ + __NL80211_MESHCONF_ATTR_AFTER_LAST, + NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_mesh_setup_params - mesh setup parameters + * + * Mesh setup parameters. These are used to start/join a mesh and cannot be + * changed while the mesh is active. + * + * @__NL80211_MESH_SETUP_INVALID: Internal use + * + * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a + * vendor specific path selection algorithm or disable it to use the + * default HWMP. + * + * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a + * vendor specific path metric or disable it to use the default Airtime + * metric. + * + * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a + * robust security network ie, or a vendor specific information element + * that vendors will use to identify the path selection methods and + * metrics in use. + * + * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication + * daemon will be authenticating mesh candidates. + * + * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication + * daemon will be securing peer link frames. AMPE is a secured version of + * Mesh Peering Management (MPM) and is implemented with the assistance of + * a userspace daemon. When this flag is set, the kernel will send peer + * management frames to a userspace daemon that will implement AMPE + * functionality (security capabilities selection, key confirmation, and + * key management). When the flag is unset (default), the kernel can + * autonomously complete (unsecured) mesh peering without the need of a + * userspace daemon. + * + * @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a + * vendor specific synchronization method or disable it to use the default + * neighbor offset synchronization + * + * @NL80211_MESH_SETUP_USERSPACE_MPM: Enable this option if userspace will + * implement an MPM which handles peer allocation and state. + * + * @NL80211_MESH_SETUP_AUTH_PROTOCOL: Inform the kernel of the authentication + * method (u8, as defined in IEEE 8.4.2.100.6, e.g. 0x1 for SAE). + * Default is no authentication method required. + * + * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number + * + * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use + */ +enum nl80211_mesh_setup_params { + __NL80211_MESH_SETUP_INVALID, + NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, + NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, + NL80211_MESH_SETUP_IE, + NL80211_MESH_SETUP_USERSPACE_AUTH, + NL80211_MESH_SETUP_USERSPACE_AMPE, + NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC, + NL80211_MESH_SETUP_USERSPACE_MPM, + NL80211_MESH_SETUP_AUTH_PROTOCOL, + + /* keep last */ + __NL80211_MESH_SETUP_ATTR_AFTER_LAST, + NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1 +}; + +/** + * enum nl80211_txq_attr - TX queue parameter attributes + * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved + * @NL80211_TXQ_ATTR_AC: AC identifier (NL80211_AC_*) + * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning + * disabled + * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form + * 2^n-1 in the range 1..32767] + * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form + * 2^n-1 in the range 1..32767] + * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255] + * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal + * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number + */ +enum nl80211_txq_attr { + __NL80211_TXQ_ATTR_INVALID, + NL80211_TXQ_ATTR_AC, + NL80211_TXQ_ATTR_TXOP, + NL80211_TXQ_ATTR_CWMIN, + NL80211_TXQ_ATTR_CWMAX, + NL80211_TXQ_ATTR_AIFS, + + /* keep last */ + __NL80211_TXQ_ATTR_AFTER_LAST, + NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1 +}; + +enum nl80211_ac { + NL80211_AC_VO, + NL80211_AC_VI, + NL80211_AC_BE, + NL80211_AC_BK, + NL80211_NUM_ACS +}; + +/* backward compat */ +#define NL80211_TXQ_ATTR_QUEUE NL80211_TXQ_ATTR_AC +#define NL80211_TXQ_Q_VO NL80211_AC_VO +#define NL80211_TXQ_Q_VI NL80211_AC_VI +#define NL80211_TXQ_Q_BE NL80211_AC_BE +#define NL80211_TXQ_Q_BK NL80211_AC_BK + +/** + * enum nl80211_channel_type - channel type + * @NL80211_CHAN_NO_HT: 20 MHz, non-HT channel + * @NL80211_CHAN_HT20: 20 MHz HT channel + * @NL80211_CHAN_HT40MINUS: HT40 channel, secondary channel + * below the control channel + * @NL80211_CHAN_HT40PLUS: HT40 channel, secondary channel + * above the control channel + */ +enum nl80211_channel_type { + NL80211_CHAN_NO_HT, + NL80211_CHAN_HT20, + NL80211_CHAN_HT40MINUS, + NL80211_CHAN_HT40PLUS +}; + +/** + * enum nl80211_chan_width - channel width definitions + * + * These values are used with the %NL80211_ATTR_CHANNEL_WIDTH + * attribute. + * + * @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel + * @NL80211_CHAN_WIDTH_20: 20 MHz HT channel + * @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * attribute must be provided as well + * @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * attribute must be provided as well + * @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well + * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 + * attribute must be provided as well + * @NL80211_CHAN_WIDTH_5: 5 MHz OFDM channel + * @NL80211_CHAN_WIDTH_10: 10 MHz OFDM channel + */ +enum nl80211_chan_width { + NL80211_CHAN_WIDTH_20_NOHT, + NL80211_CHAN_WIDTH_20, + NL80211_CHAN_WIDTH_40, + NL80211_CHAN_WIDTH_80, + NL80211_CHAN_WIDTH_80P80, + NL80211_CHAN_WIDTH_160, + NL80211_CHAN_WIDTH_5, + NL80211_CHAN_WIDTH_10, +}; + +/** + * enum nl80211_bss_scan_width - control channel width for a BSS + * + * These values are used with the %NL80211_BSS_CHAN_WIDTH attribute. + * + * @NL80211_BSS_CHAN_WIDTH_20: control channel is 20 MHz wide or compatible + * @NL80211_BSS_CHAN_WIDTH_10: control channel is 10 MHz wide + * @NL80211_BSS_CHAN_WIDTH_5: control channel is 5 MHz wide + */ +enum nl80211_bss_scan_width { + NL80211_BSS_CHAN_WIDTH_20, + NL80211_BSS_CHAN_WIDTH_10, + NL80211_BSS_CHAN_WIDTH_5, +}; + +/** + * enum nl80211_bss - netlink attributes for a BSS + * + * @__NL80211_BSS_INVALID: invalid + * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) + * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) + * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) + * (if @NL80211_BSS_PRESP_DATA is present then this is known to be + * from a probe response, otherwise it may be from the same beacon + * that the NL80211_BSS_BEACON_TSF will be from) + * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) + * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16) + * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the + * raw information elements from the probe response/beacon (bin); + * if the %NL80211_BSS_BEACON_IES attribute is present and the data is + * different then the IEs here are from a Probe Response frame; otherwise + * they are from a Beacon frame. + * However, if the driver does not indicate the source of the IEs, these + * IEs may be from either frame subtype. + * If present, the @NL80211_BSS_PRESP_DATA attribute indicates that the + * data here is known to be from a probe response, without any heuristics. + * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon + * in mBm (100 * dBm) (s32) + * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon + * in unspecified units, scaled to 0..100 (u8) + * @NL80211_BSS_STATUS: status, if this BSS is "used" + * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms + * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information + * elements from a Beacon frame (bin); not present if no Beacon frame has + * yet been received + * @NL80211_BSS_CHAN_WIDTH: channel width of the control channel + * (u32, enum nl80211_bss_scan_width) + * @NL80211_BSS_BEACON_TSF: TSF of the last received beacon (u64) + * (not present if no beacon frame has been received yet) + * @NL80211_BSS_PRESP_DATA: the data in @NL80211_BSS_INFORMATION_ELEMENTS and + * @NL80211_BSS_TSF is known to be from a probe response (flag attribute) + * @__NL80211_BSS_AFTER_LAST: internal + * @NL80211_BSS_MAX: highest BSS attribute + */ +enum nl80211_bss { + __NL80211_BSS_INVALID, + NL80211_BSS_BSSID, + NL80211_BSS_FREQUENCY, + NL80211_BSS_TSF, + NL80211_BSS_BEACON_INTERVAL, + NL80211_BSS_CAPABILITY, + NL80211_BSS_INFORMATION_ELEMENTS, + NL80211_BSS_SIGNAL_MBM, + NL80211_BSS_SIGNAL_UNSPEC, + NL80211_BSS_STATUS, + NL80211_BSS_SEEN_MS_AGO, + NL80211_BSS_BEACON_IES, + NL80211_BSS_CHAN_WIDTH, + NL80211_BSS_BEACON_TSF, + NL80211_BSS_PRESP_DATA, + + /* keep last */ + __NL80211_BSS_AFTER_LAST, + NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1 +}; + +/** + * enum nl80211_bss_status - BSS "status" + * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. + * Note that this is no longer used since cfg80211 no longer + * keeps track of whether or not authentication was done with + * a given BSS. + * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. + * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. + * + * The BSS status is a BSS attribute in scan dumps, which + * indicates the status the interface has wrt. this BSS. + */ +enum nl80211_bss_status { + NL80211_BSS_STATUS_AUTHENTICATED, + NL80211_BSS_STATUS_ASSOCIATED, + NL80211_BSS_STATUS_IBSS_JOINED, +}; + +/** + * enum nl80211_auth_type - AuthenticationType + * + * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication + * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) + * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) + * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) + * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals + * @__NL80211_AUTHTYPE_NUM: internal + * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm + * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by + * trying multiple times); this is invalid in netlink -- leave out + * the attribute for this on CONNECT commands. + */ +enum nl80211_auth_type { + NL80211_AUTHTYPE_OPEN_SYSTEM, + NL80211_AUTHTYPE_SHARED_KEY, + NL80211_AUTHTYPE_FT, + NL80211_AUTHTYPE_NETWORK_EAP, + NL80211_AUTHTYPE_SAE, + + /* keep last */ + __NL80211_AUTHTYPE_NUM, + NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1, + NL80211_AUTHTYPE_AUTOMATIC +}; + +/** + * enum nl80211_key_type - Key Type + * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key + * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key + * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) + * @NUM_NL80211_KEYTYPES: number of defined key types + */ +enum nl80211_key_type { + NL80211_KEYTYPE_GROUP, + NL80211_KEYTYPE_PAIRWISE, + NL80211_KEYTYPE_PEERKEY, + + NUM_NL80211_KEYTYPES +}; + +/** + * enum nl80211_mfp - Management frame protection state + * @NL80211_MFP_NO: Management frame protection not used + * @NL80211_MFP_REQUIRED: Management frame protection required + */ +enum nl80211_mfp { + NL80211_MFP_NO, + NL80211_MFP_REQUIRED, +}; + +enum nl80211_wpa_versions { + NL80211_WPA_VERSION_1 = 1 << 0, + NL80211_WPA_VERSION_2 = 1 << 1, +}; + +/** + * enum nl80211_key_default_types - key default types + * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid + * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default + * unicast key + * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default + * multicast key + * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types + */ +enum nl80211_key_default_types { + __NL80211_KEY_DEFAULT_TYPE_INVALID, + NL80211_KEY_DEFAULT_TYPE_UNICAST, + NL80211_KEY_DEFAULT_TYPE_MULTICAST, + + NUM_NL80211_KEY_DEFAULT_TYPES +}; + +/** + * enum nl80211_key_attributes - key attributes + * @__NL80211_KEY_INVALID: invalid + * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of + * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC + * keys + * @NL80211_KEY_IDX: key ID (u8, 0-3) + * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 + * section 7.3.2.25.1, e.g. 0x000FAC04) + * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and + * CCMP keys, each six bytes in little endian + * @NL80211_KEY_DEFAULT: flag indicating default key + * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key + * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not + * specified the default depends on whether a MAC address was + * given with the command using the key or not (u32) + * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags + * attributes, specifying what a key should be set as default as. + * See &enum nl80211_key_default_types. + * @__NL80211_KEY_AFTER_LAST: internal + * @NL80211_KEY_MAX: highest key attribute + */ +enum nl80211_key_attributes { + __NL80211_KEY_INVALID, + NL80211_KEY_DATA, + NL80211_KEY_IDX, + NL80211_KEY_CIPHER, + NL80211_KEY_SEQ, + NL80211_KEY_DEFAULT, + NL80211_KEY_DEFAULT_MGMT, + NL80211_KEY_TYPE, + NL80211_KEY_DEFAULT_TYPES, + + /* keep last */ + __NL80211_KEY_AFTER_LAST, + NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1 +}; + +/** + * enum nl80211_tx_rate_attributes - TX rate set attributes + * @__NL80211_TXRATE_INVALID: invalid + * @NL80211_TXRATE_LEGACY: Legacy (non-MCS) rates allowed for TX rate selection + * in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with + * 1 = 500 kbps) but without the IE length restriction (at most + * %NL80211_MAX_SUPP_RATES in a single array). + * @NL80211_TXRATE_HT: HT (MCS) rates allowed for TX rate selection + * in an array of MCS numbers. + * @NL80211_TXRATE_VHT: VHT rates allowed for TX rate selection, + * see &struct nl80211_txrate_vht + * @NL80211_TXRATE_GI: configure GI, see &enum nl80211_txrate_gi + * @__NL80211_TXRATE_AFTER_LAST: internal + * @NL80211_TXRATE_MAX: highest TX rate attribute + */ +enum nl80211_tx_rate_attributes { + __NL80211_TXRATE_INVALID, + NL80211_TXRATE_LEGACY, + NL80211_TXRATE_HT, + NL80211_TXRATE_VHT, + NL80211_TXRATE_GI, + + /* keep last */ + __NL80211_TXRATE_AFTER_LAST, + NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 +}; + +#define NL80211_TXRATE_MCS NL80211_TXRATE_HT +#define NL80211_VHT_NSS_MAX 8 + +/** + * struct nl80211_txrate_vht - VHT MCS/NSS txrate bitmap + * @mcs: MCS bitmap table for each NSS (array index 0 for 1 stream, etc.) + */ +struct nl80211_txrate_vht { + __u16 mcs[NL80211_VHT_NSS_MAX]; +}; + +enum nl80211_txrate_gi { + NL80211_TXRATE_DEFAULT_GI, + NL80211_TXRATE_FORCE_SGI, + NL80211_TXRATE_FORCE_LGI, +}; + +/** + * enum nl80211_band - Frequency band + * @NL80211_BAND_2GHZ: 2.4 GHz ISM band + * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) + * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, + NL80211_BAND_60GHZ, +}; + +/** + * enum nl80211_ps_state - powersave state + * @NL80211_PS_DISABLED: powersave is disabled + * @NL80211_PS_ENABLED: powersave is enabled + */ +enum nl80211_ps_state { + NL80211_PS_DISABLED, + NL80211_PS_ENABLED, +}; + +/** + * enum nl80211_attr_cqm - connection quality monitor attributes + * @__NL80211_ATTR_CQM_INVALID: invalid + * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies + * the threshold for the RSSI level at which an event will be sent. Zero + * to disable. + * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies + * the minimum amount the RSSI level must change after an event before a + * new event may be issued (to reduce effects of RSSI oscillation). + * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event + * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many + * consecutive packets were not acknowledged by the peer + * @NL80211_ATTR_CQM_TXE_RATE: TX error rate in %. Minimum % of TX failures + * during the given %NL80211_ATTR_CQM_TXE_INTVL before an + * %NL80211_CMD_NOTIFY_CQM with reported %NL80211_ATTR_CQM_TXE_RATE and + * %NL80211_ATTR_CQM_TXE_PKTS is generated. + * @NL80211_ATTR_CQM_TXE_PKTS: number of attempted packets in a given + * %NL80211_ATTR_CQM_TXE_INTVL before %NL80211_ATTR_CQM_TXE_RATE is + * checked. + * @NL80211_ATTR_CQM_TXE_INTVL: interval in seconds. Specifies the periodic + * interval in which %NL80211_ATTR_CQM_TXE_PKTS and + * %NL80211_ATTR_CQM_TXE_RATE must be satisfied before generating an + * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. + * @NL80211_ATTR_CQM_BEACON_LOSS_EVENT: flag attribute that's set in a beacon + * loss event + * @__NL80211_ATTR_CQM_AFTER_LAST: internal + * @NL80211_ATTR_CQM_MAX: highest key attribute + */ +enum nl80211_attr_cqm { + __NL80211_ATTR_CQM_INVALID, + NL80211_ATTR_CQM_RSSI_THOLD, + NL80211_ATTR_CQM_RSSI_HYST, + NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, + NL80211_ATTR_CQM_PKT_LOSS_EVENT, + NL80211_ATTR_CQM_TXE_RATE, + NL80211_ATTR_CQM_TXE_PKTS, + NL80211_ATTR_CQM_TXE_INTVL, + NL80211_ATTR_CQM_BEACON_LOSS_EVENT, + + /* keep last */ + __NL80211_ATTR_CQM_AFTER_LAST, + NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1 +}; + +/** + * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the + * configured threshold + * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the + * configured threshold + * @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: (reserved, never sent) + */ +enum nl80211_cqm_rssi_threshold_event { + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, + NL80211_CQM_RSSI_BEACON_LOSS_EVENT, +}; + + +/** + * enum nl80211_tx_power_setting - TX power adjustment + * @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power + * @NL80211_TX_POWER_LIMITED: limit TX power by the mBm parameter + * @NL80211_TX_POWER_FIXED: fix TX power to the mBm parameter + */ +enum nl80211_tx_power_setting { + NL80211_TX_POWER_AUTOMATIC, + NL80211_TX_POWER_LIMITED, + NL80211_TX_POWER_FIXED, +}; + +/** + * enum nl80211_packet_pattern_attr - packet pattern attribute + * @__NL80211_PKTPAT_INVALID: invalid number for nested attribute + * @NL80211_PKTPAT_PATTERN: the pattern, values where the mask has + * a zero bit are ignored + * @NL80211_PKTPAT_MASK: pattern mask, must be long enough to have + * a bit for each byte in the pattern. The lowest-order bit corresponds + * to the first byte of the pattern, but the bytes of the pattern are + * in a little-endian-like format, i.e. the 9th byte of the pattern + * corresponds to the lowest-order bit in the second byte of the mask. + * For example: The match 00:xx:00:00:xx:00:00:00:00:xx:xx:xx (where + * xx indicates "don't care") would be represented by a pattern of + * twelve zero bytes, and a mask of "0xed,0x01". + * Note that the pattern matching is done as though frames were not + * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked + * first (including SNAP header unpacking) and then matched. + * @NL80211_PKTPAT_OFFSET: packet offset, pattern is matched after + * these fixed number of bytes of received packet + * @NUM_NL80211_PKTPAT: number of attributes + * @MAX_NL80211_PKTPAT: max attribute number + */ +enum nl80211_packet_pattern_attr { + __NL80211_PKTPAT_INVALID, + NL80211_PKTPAT_MASK, + NL80211_PKTPAT_PATTERN, + NL80211_PKTPAT_OFFSET, + + NUM_NL80211_PKTPAT, + MAX_NL80211_PKTPAT = NUM_NL80211_PKTPAT - 1, +}; + +/** + * struct nl80211_pattern_support - packet pattern support information + * @max_patterns: maximum number of patterns supported + * @min_pattern_len: minimum length of each pattern + * @max_pattern_len: maximum length of each pattern + * @max_pkt_offset: maximum Rx packet offset + * + * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when + * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED or in + * %NL80211_ATTR_COALESCE_RULE_PKT_PATTERN when that is part of + * %NL80211_ATTR_COALESCE_RULE in the capability information given + * by the kernel to userspace. + */ +struct nl80211_pattern_support { + __u32 max_patterns; + __u32 min_pattern_len; + __u32 max_pattern_len; + __u32 max_pkt_offset; +} __attribute__((packed)); + +/* only for backward compatibility */ +#define __NL80211_WOWLAN_PKTPAT_INVALID __NL80211_PKTPAT_INVALID +#define NL80211_WOWLAN_PKTPAT_MASK NL80211_PKTPAT_MASK +#define NL80211_WOWLAN_PKTPAT_PATTERN NL80211_PKTPAT_PATTERN +#define NL80211_WOWLAN_PKTPAT_OFFSET NL80211_PKTPAT_OFFSET +#define NUM_NL80211_WOWLAN_PKTPAT NUM_NL80211_PKTPAT +#define MAX_NL80211_WOWLAN_PKTPAT MAX_NL80211_PKTPAT +#define nl80211_wowlan_pattern_support nl80211_pattern_support + +/** + * enum nl80211_wowlan_triggers - WoWLAN trigger definitions + * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes + * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put + * the chip into a special state -- works best with chips that have + * support for low-power operation already (flag) + * Note that this mode is incompatible with all of the others, if + * any others are even supported by the device. + * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect + * is detected is implementation-specific (flag) + * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed + * by 16 repetitions of MAC addr, anywhere in payload) (flag) + * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns + * which are passed in an array of nested attributes, each nested attribute + * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern. + * Each pattern defines a wakeup packet. Packet offset is associated with + * each pattern which is used while matching the pattern. The matching is + * done on the MSDU, i.e. as though the packet was an 802.3 packet, so the + * pattern matching is done after the packet is converted to the MSDU. + * + * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute + * carrying a &struct nl80211_pattern_support. + * + * When reporting wakeup. it is a u32 attribute containing the 0-based + * index of the pattern that caused the wakeup, in the patterns passed + * to the kernel when configuring. + * @NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: Not a real trigger, and cannot be + * used when setting, used only to indicate that GTK rekeying is supported + * by the device (flag) + * @NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: wake up on GTK rekey failure (if + * done by the device) (flag) + * @NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: wake up on EAP Identity Request + * packet (flag) + * @NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: wake up on 4-way handshake (flag) + * @NL80211_WOWLAN_TRIG_RFKILL_RELEASE: wake up when rfkill is released + * (on devices that have rfkill in the device) (flag) + * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211: For wakeup reporting only, contains + * the 802.11 packet that caused the wakeup, e.g. a deauth frame. The frame + * may be truncated, the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN + * attribute contains the original length. + * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN: Original length of the 802.11 + * packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211 + * attribute if the packet was truncated somewhere. + * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023: For wakeup reporting only, contains the + * 802.11 packet that caused the wakeup, e.g. a magic packet. The frame may + * be truncated, the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN attribute + * contains the original length. + * @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN: Original length of the 802.3 + * packet, may be bigger than the @NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023 + * attribute if the packet was truncated somewhere. + * @NL80211_WOWLAN_TRIG_TCP_CONNECTION: TCP connection wake, see DOC section + * "TCP connection wakeup" for more details. This is a nested attribute + * containing the exact information for establishing and keeping alive + * the TCP connection. + * @NL80211_WOWLAN_TRIG_TCP_WAKEUP_MATCH: For wakeup reporting only, the + * wakeup packet was received on the TCP connection + * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST: For wakeup reporting only, the + * TCP connection was lost or failed to be established + * @NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS: For wakeup reporting only, + * the TCP connection ran out of tokens to use for data to send to the + * service + * @NL80211_WOWLAN_TRIG_NET_DETECT: wake up when a configured network + * is detected. This is a nested attribute that contains the + * same attributes used with @NL80211_CMD_START_SCHED_SCAN. It + * specifies how the scan is performed (e.g. the interval, the + * channels to scan and the initial delay) as well as the scan + * results that will trigger a wake (i.e. the matchsets). This + * attribute is also sent in a response to + * @NL80211_CMD_GET_WIPHY, indicating the number of match sets + * supported by the driver (u32). + * @NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS: nested attribute + * containing an array with information about what triggered the + * wake up. If no elements are present in the array, it means + * that the information is not available. If more than one + * element is present, it means that more than one match + * occurred. + * Each element in the array is a nested attribute that contains + * one optional %NL80211_ATTR_SSID attribute and one optional + * %NL80211_ATTR_SCAN_FREQUENCIES attribute. At least one of + * these attributes must be present. If + * %NL80211_ATTR_SCAN_FREQUENCIES contains more than one + * frequency, it means that the match occurred in more than one + * channel. + * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers + * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number + * + * These nested attributes are used to configure the wakeup triggers and + * to report the wakeup reason(s). + */ +enum nl80211_wowlan_triggers { + __NL80211_WOWLAN_TRIG_INVALID, + NL80211_WOWLAN_TRIG_ANY, + NL80211_WOWLAN_TRIG_DISCONNECT, + NL80211_WOWLAN_TRIG_MAGIC_PKT, + NL80211_WOWLAN_TRIG_PKT_PATTERN, + NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED, + NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE, + NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST, + NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE, + NL80211_WOWLAN_TRIG_RFKILL_RELEASE, + NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211, + NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN, + NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023, + NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN, + NL80211_WOWLAN_TRIG_TCP_CONNECTION, + NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH, + NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST, + NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS, + NL80211_WOWLAN_TRIG_NET_DETECT, + NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS, + + /* keep last */ + NUM_NL80211_WOWLAN_TRIG, + MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 +}; + +/** + * DOC: TCP connection wakeup + * + * Some devices can establish a TCP connection in order to be woken up by a + * packet coming in from outside their network segment, or behind NAT. If + * configured, the device will establish a TCP connection to the given + * service, and periodically send data to that service. The first data + * packet is usually transmitted after SYN/ACK, also ACKing the SYN/ACK. + * The data packets can optionally include a (little endian) sequence + * number (in the TCP payload!) that is generated by the device, and, also + * optionally, a token from a list of tokens. This serves as a keep-alive + * with the service, and for NATed connections, etc. + * + * During this keep-alive period, the server doesn't send any data to the + * client. When receiving data, it is compared against the wakeup pattern + * (and mask) and if it matches, the host is woken up. Similarly, if the + * connection breaks or cannot be established to start with, the host is + * also woken up. + * + * Developer's note: ARP offload is required for this, otherwise TCP + * response packets might not go through correctly. + */ + +/** + * struct nl80211_wowlan_tcp_data_seq - WoWLAN TCP data sequence + * @start: starting value + * @offset: offset of sequence number in packet + * @len: length of the sequence value to write, 1 through 4 + * + * Note: don't confuse with the TCP sequence number(s), this is for the + * keepalive packet payload. The actual value is written into the packet + * in little endian. + */ +struct nl80211_wowlan_tcp_data_seq { + __u32 start, offset, len; +}; + +/** + * struct nl80211_wowlan_tcp_data_token - WoWLAN TCP data token config + * @offset: offset of token in packet + * @len: length of each token + * @token_stream: stream of data to be used for the tokens, the length must + * be a multiple of @len for this to make sense + */ +struct nl80211_wowlan_tcp_data_token { + __u32 offset, len; + __u8 token_stream[]; +}; + +/** + * struct nl80211_wowlan_tcp_data_token_feature - data token features + * @min_len: minimum token length + * @max_len: maximum token length + * @bufsize: total available token buffer size (max size of @token_stream) + */ +struct nl80211_wowlan_tcp_data_token_feature { + __u32 min_len, max_len, bufsize; +}; + +/** + * enum nl80211_wowlan_tcp_attrs - WoWLAN TCP connection parameters + * @__NL80211_WOWLAN_TCP_INVALID: invalid number for nested attributes + * @NL80211_WOWLAN_TCP_SRC_IPV4: source IPv4 address (in network byte order) + * @NL80211_WOWLAN_TCP_DST_IPV4: destination IPv4 address + * (in network byte order) + * @NL80211_WOWLAN_TCP_DST_MAC: destination MAC address, this is given because + * route lookup when configured might be invalid by the time we suspend, + * and doing a route lookup when suspending is no longer possible as it + * might require ARP querying. + * @NL80211_WOWLAN_TCP_SRC_PORT: source port (u16); optional, if not given a + * socket and port will be allocated + * @NL80211_WOWLAN_TCP_DST_PORT: destination port (u16) + * @NL80211_WOWLAN_TCP_DATA_PAYLOAD: data packet payload, at least one byte. + * For feature advertising, a u32 attribute holding the maximum length + * of the data payload. + * @NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ: data packet sequence configuration + * (if desired), a &struct nl80211_wowlan_tcp_data_seq. For feature + * advertising it is just a flag + * @NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN: data packet token configuration, + * see &struct nl80211_wowlan_tcp_data_token and for advertising see + * &struct nl80211_wowlan_tcp_data_token_feature. + * @NL80211_WOWLAN_TCP_DATA_INTERVAL: data interval in seconds, maximum + * interval in feature advertising (u32) + * @NL80211_WOWLAN_TCP_WAKE_PAYLOAD: wake packet payload, for advertising a + * u32 attribute holding the maximum length + * @NL80211_WOWLAN_TCP_WAKE_MASK: Wake packet payload mask, not used for + * feature advertising. The mask works like @NL80211_PKTPAT_MASK + * but on the TCP payload only. + * @NUM_NL80211_WOWLAN_TCP: number of TCP attributes + * @MAX_NL80211_WOWLAN_TCP: highest attribute number + */ +enum nl80211_wowlan_tcp_attrs { + __NL80211_WOWLAN_TCP_INVALID, + NL80211_WOWLAN_TCP_SRC_IPV4, + NL80211_WOWLAN_TCP_DST_IPV4, + NL80211_WOWLAN_TCP_DST_MAC, + NL80211_WOWLAN_TCP_SRC_PORT, + NL80211_WOWLAN_TCP_DST_PORT, + NL80211_WOWLAN_TCP_DATA_PAYLOAD, + NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ, + NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, + NL80211_WOWLAN_TCP_DATA_INTERVAL, + NL80211_WOWLAN_TCP_WAKE_PAYLOAD, + NL80211_WOWLAN_TCP_WAKE_MASK, + + /* keep last */ + NUM_NL80211_WOWLAN_TCP, + MAX_NL80211_WOWLAN_TCP = NUM_NL80211_WOWLAN_TCP - 1 +}; + +/** + * struct nl80211_coalesce_rule_support - coalesce rule support information + * @max_rules: maximum number of rules supported + * @pat: packet pattern support information + * @max_delay: maximum supported coalescing delay in msecs + * + * This struct is carried in %NL80211_ATTR_COALESCE_RULE in the + * capability information given by the kernel to userspace. + */ +struct nl80211_coalesce_rule_support { + __u32 max_rules; + struct nl80211_pattern_support pat; + __u32 max_delay; +} __attribute__((packed)); + +/** + * enum nl80211_attr_coalesce_rule - coalesce rule attribute + * @__NL80211_COALESCE_RULE_INVALID: invalid number for nested attribute + * @NL80211_ATTR_COALESCE_RULE_DELAY: delay in msecs used for packet coalescing + * @NL80211_ATTR_COALESCE_RULE_CONDITION: condition for packet coalescence, + * see &enum nl80211_coalesce_condition. + * @NL80211_ATTR_COALESCE_RULE_PKT_PATTERN: packet offset, pattern is matched + * after these fixed number of bytes of received packet + * @NUM_NL80211_ATTR_COALESCE_RULE: number of attributes + * @NL80211_ATTR_COALESCE_RULE_MAX: max attribute number + */ +enum nl80211_attr_coalesce_rule { + __NL80211_COALESCE_RULE_INVALID, + NL80211_ATTR_COALESCE_RULE_DELAY, + NL80211_ATTR_COALESCE_RULE_CONDITION, + NL80211_ATTR_COALESCE_RULE_PKT_PATTERN, + + /* keep last */ + NUM_NL80211_ATTR_COALESCE_RULE, + NL80211_ATTR_COALESCE_RULE_MAX = NUM_NL80211_ATTR_COALESCE_RULE - 1 +}; + +/** + * enum nl80211_coalesce_condition - coalesce rule conditions + * @NL80211_COALESCE_CONDITION_MATCH: coalaesce Rx packets when patterns + * in a rule are matched. + * @NL80211_COALESCE_CONDITION_NO_MATCH: coalesce Rx packets when patterns + * in a rule are not matched. + */ +enum nl80211_coalesce_condition { + NL80211_COALESCE_CONDITION_MATCH, + NL80211_COALESCE_CONDITION_NO_MATCH +}; + +/** + * enum nl80211_iface_limit_attrs - limit attributes + * @NL80211_IFACE_LIMIT_UNSPEC: (reserved) + * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that + * can be chosen from this set of interface types (u32) + * @NL80211_IFACE_LIMIT_TYPES: nested attribute containing a + * flag attribute for each interface type in this set + * @NUM_NL80211_IFACE_LIMIT: number of attributes + * @MAX_NL80211_IFACE_LIMIT: highest attribute number + */ +enum nl80211_iface_limit_attrs { + NL80211_IFACE_LIMIT_UNSPEC, + NL80211_IFACE_LIMIT_MAX, + NL80211_IFACE_LIMIT_TYPES, + + /* keep last */ + NUM_NL80211_IFACE_LIMIT, + MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1 +}; + +/** + * enum nl80211_if_combination_attrs -- interface combination attributes + * + * @NL80211_IFACE_COMB_UNSPEC: (reserved) + * @NL80211_IFACE_COMB_LIMITS: Nested attributes containing the limits + * for given interface types, see &enum nl80211_iface_limit_attrs. + * @NL80211_IFACE_COMB_MAXNUM: u32 attribute giving the total number of + * interfaces that can be created in this group. This number doesn't + * apply to interfaces purely managed in software, which are listed + * in a separate attribute %NL80211_ATTR_INTERFACES_SOFTWARE. + * @NL80211_IFACE_COMB_STA_AP_BI_MATCH: flag attribute specifying that + * beacon intervals within this group must be all the same even for + * infrastructure and AP/GO combinations, i.e. the GO(s) must adopt + * the infrastructure network's beacon interval. + * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many + * different channels may be used within this group. + * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap + * of supported channel widths for radar detection. + * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap + * of supported regulatory regions for radar detection. + * @NUM_NL80211_IFACE_COMB: number of attributes + * @MAX_NL80211_IFACE_COMB: highest attribute number + * + * Examples: + * limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2 + * => allows an AP and a STA that must match BIs + * + * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8 + * => allows 8 of AP/GO + * + * numbers = [ #{STA} <= 2 ], channels = 2, max = 2 + * => allows two STAs on different channels + * + * numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4 + * => allows a STA plus three P2P interfaces + * + * The list of these four possiblities could completely be contained + * within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate + * that any of these groups must match. + * + * "Combinations" of just a single interface will not be listed here, + * a single interface of any valid interface type is assumed to always + * be possible by itself. This means that implicitly, for each valid + * interface type, the following group always exists: + * numbers = [ #{<type>} <= 1 ], channels = 1, max = 1 + */ +enum nl80211_if_combination_attrs { + NL80211_IFACE_COMB_UNSPEC, + NL80211_IFACE_COMB_LIMITS, + NL80211_IFACE_COMB_MAXNUM, + NL80211_IFACE_COMB_STA_AP_BI_MATCH, + NL80211_IFACE_COMB_NUM_CHANNELS, + NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, + NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, + + /* keep last */ + NUM_NL80211_IFACE_COMB, + MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1 +}; + + +/** + * enum nl80211_plink_state - state of a mesh peer link finite state machine + * + * @NL80211_PLINK_LISTEN: initial state, considered the implicit + * state of non existant mesh peer links + * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to + * this mesh peer + * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received + * from this mesh peer + * @NL80211_PLINK_CNF_RCVD: mesh plink confirm frame has been + * received from this mesh peer + * @NL80211_PLINK_ESTAB: mesh peer link is established + * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled + * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh + * plink are discarded + * @NUM_NL80211_PLINK_STATES: number of peer link states + * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states + */ +enum nl80211_plink_state { + NL80211_PLINK_LISTEN, + NL80211_PLINK_OPN_SNT, + NL80211_PLINK_OPN_RCVD, + NL80211_PLINK_CNF_RCVD, + NL80211_PLINK_ESTAB, + NL80211_PLINK_HOLDING, + NL80211_PLINK_BLOCKED, + + /* keep last */ + NUM_NL80211_PLINK_STATES, + MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 +}; + +/** + * enum nl80211_plink_action - actions to perform in mesh peers + * + * @NL80211_PLINK_ACTION_NO_ACTION: perform no action + * @NL80211_PLINK_ACTION_OPEN: start mesh peer link establishment + * @NL80211_PLINK_ACTION_BLOCK: block traffic from this mesh peer + * @NUM_NL80211_PLINK_ACTIONS: number of possible actions + */ +enum plink_actions { + NL80211_PLINK_ACTION_NO_ACTION, + NL80211_PLINK_ACTION_OPEN, + NL80211_PLINK_ACTION_BLOCK, + + NUM_NL80211_PLINK_ACTIONS, +}; + + +#define NL80211_KCK_LEN 16 +#define NL80211_KEK_LEN 16 +#define NL80211_REPLAY_CTR_LEN 8 + +/** + * enum nl80211_rekey_data - attributes for GTK rekey offload + * @__NL80211_REKEY_DATA_INVALID: invalid number for nested attributes + * @NL80211_REKEY_DATA_KEK: key encryption key (binary) + * @NL80211_REKEY_DATA_KCK: key confirmation key (binary) + * @NL80211_REKEY_DATA_REPLAY_CTR: replay counter (binary) + * @NUM_NL80211_REKEY_DATA: number of rekey attributes (internal) + * @MAX_NL80211_REKEY_DATA: highest rekey attribute (internal) + */ +enum nl80211_rekey_data { + __NL80211_REKEY_DATA_INVALID, + NL80211_REKEY_DATA_KEK, + NL80211_REKEY_DATA_KCK, + NL80211_REKEY_DATA_REPLAY_CTR, + + /* keep last */ + NUM_NL80211_REKEY_DATA, + MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1 +}; + +/** + * enum nl80211_hidden_ssid - values for %NL80211_ATTR_HIDDEN_SSID + * @NL80211_HIDDEN_SSID_NOT_IN_USE: do not hide SSID (i.e., broadcast it in + * Beacon frames) + * @NL80211_HIDDEN_SSID_ZERO_LEN: hide SSID by using zero-length SSID element + * in Beacon frames + * @NL80211_HIDDEN_SSID_ZERO_CONTENTS: hide SSID by using correct length of SSID + * element in Beacon frames but zero out each byte in the SSID + */ +enum nl80211_hidden_ssid { + NL80211_HIDDEN_SSID_NOT_IN_USE, + NL80211_HIDDEN_SSID_ZERO_LEN, + NL80211_HIDDEN_SSID_ZERO_CONTENTS +}; + +/** + * enum nl80211_sta_wme_attr - station WME attributes + * @__NL80211_STA_WME_INVALID: invalid number for nested attribute + * @NL80211_STA_WME_UAPSD_QUEUES: bitmap of uapsd queues. the format + * is the same as the AC bitmap in the QoS info field. + * @NL80211_STA_WME_MAX_SP: max service period. the format is the same + * as the MAX_SP field in the QoS info field (but already shifted down). + * @__NL80211_STA_WME_AFTER_LAST: internal + * @NL80211_STA_WME_MAX: highest station WME attribute + */ +enum nl80211_sta_wme_attr { + __NL80211_STA_WME_INVALID, + NL80211_STA_WME_UAPSD_QUEUES, + NL80211_STA_WME_MAX_SP, + + /* keep last */ + __NL80211_STA_WME_AFTER_LAST, + NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1 +}; + +/** + * enum nl80211_pmksa_candidate_attr - attributes for PMKSA caching candidates + * @__NL80211_PMKSA_CANDIDATE_INVALID: invalid number for nested attributes + * @NL80211_PMKSA_CANDIDATE_INDEX: candidate index (u32; the smaller, the higher + * priority) + * @NL80211_PMKSA_CANDIDATE_BSSID: candidate BSSID (6 octets) + * @NL80211_PMKSA_CANDIDATE_PREAUTH: RSN pre-authentication supported (flag) + * @NUM_NL80211_PMKSA_CANDIDATE: number of PMKSA caching candidate attributes + * (internal) + * @MAX_NL80211_PMKSA_CANDIDATE: highest PMKSA caching candidate attribute + * (internal) + */ +enum nl80211_pmksa_candidate_attr { + __NL80211_PMKSA_CANDIDATE_INVALID, + NL80211_PMKSA_CANDIDATE_INDEX, + NL80211_PMKSA_CANDIDATE_BSSID, + NL80211_PMKSA_CANDIDATE_PREAUTH, + + /* keep last */ + NUM_NL80211_PMKSA_CANDIDATE, + MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1 +}; + +/** + * enum nl80211_tdls_operation - values for %NL80211_ATTR_TDLS_OPERATION + * @NL80211_TDLS_DISCOVERY_REQ: Send a TDLS discovery request + * @NL80211_TDLS_SETUP: Setup TDLS link + * @NL80211_TDLS_TEARDOWN: Teardown a TDLS link which is already established + * @NL80211_TDLS_ENABLE_LINK: Enable TDLS link + * @NL80211_TDLS_DISABLE_LINK: Disable TDLS link + */ +enum nl80211_tdls_operation { + NL80211_TDLS_DISCOVERY_REQ, + NL80211_TDLS_SETUP, + NL80211_TDLS_TEARDOWN, + NL80211_TDLS_ENABLE_LINK, + NL80211_TDLS_DISABLE_LINK, +}; + +/* + * enum nl80211_ap_sme_features - device-integrated AP features + * Reserved for future use, no bits are defined in + * NL80211_ATTR_DEVICE_AP_SME yet. +enum nl80211_ap_sme_features { +}; + */ + +/** + * enum nl80211_feature_flags - device/driver features + * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back + * TX status to the socket error queue when requested with the + * socket option. + * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. + * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up + * the connected inactive stations in AP mode. + * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested + * to work properly to suppport receiving regulatory hints from + * cellular base stations. + * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only + * here to reserve the value for API/ABI compatibility) + * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of + * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station + * mode + * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan + * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported + * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif + * @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting + * @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform + * OBSS scans and generate 20/40 BSS coex reports. This flag is used only + * for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied. + * @NL80211_FEATURE_P2P_GO_CTWIN: P2P GO implementation supports CT Window + * setting + * @NL80211_FEATURE_P2P_GO_OPPPS: P2P GO implementation supports opportunistic + * powersave + * @NL80211_FEATURE_FULL_AP_CLIENT_STATE: The driver supports full state + * transitions for AP clients. Without this flag (and if the driver + * doesn't have the AP SME in the device) the driver supports adding + * stations only when they're associated and adds them in associated + * state (to later be transitioned into authorized), with this flag + * they should be added before even sending the authentication reply + * and then transitioned into authenticated, associated and authorized + * states using station flags. + * Note that even for drivers that support this, the default is to add + * stations in authenticated/associated state, so to add unauthenticated + * stations the authenticated/associated bits have to be set in the mask. + * @NL80211_FEATURE_ADVERTISE_CHAN_LIMITS: cfg80211 advertises channel limits + * (HT40, VHT 80/160 MHz) if this flag is set + * @NL80211_FEATURE_USERSPACE_MPM: This driver supports a userspace Mesh + * Peering Management entity which may be implemented by registering for + * beacons or NL80211_CMD_NEW_PEER_CANDIDATE events. The mesh beacon is + * still generated by the driver. + * @NL80211_FEATURE_ACTIVE_MONITOR: This driver supports an active monitor + * interface. An active monitor interface behaves like a normal monitor + * interface, but gets added to the driver. It ensures that incoming + * unicast packets directed at the configured interface address get ACKed. + * @NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE: This driver supports dynamic + * channel bandwidth change (e.g., HT 20 <-> 40 MHz channel) during the + * lifetime of a BSS. + * @NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES: This device adds a DS Parameter + * Set IE to probe requests. + * @NL80211_FEATURE_WFA_TPC_IE_IN_PROBES: This device adds a WFA TPC Report IE + * to probe requests. + * @NL80211_FEATURE_QUIET: This device, in client mode, supports Quiet Period + * requests sent to it by an AP. + * @NL80211_FEATURE_TX_POWER_INSERTION: This device is capable of inserting the + * current tx power value into the TPC Report IE in the spectrum + * management TPC Report action frame, and in the Radio Measurement Link + * Measurement Report action frame. + * @NL80211_FEATURE_ACKTO_ESTIMATION: This driver supports dynamic ACK timeout + * estimation (dynack). %NL80211_ATTR_WIPHY_DYN_ACK flag attribute is used + * to enable dynack. + * @NL80211_FEATURE_STATIC_SMPS: Device supports static spatial + * multiplexing powersave, ie. can turn off all but one chain + * even on HT connections that should be using more chains. + * @NL80211_FEATURE_DYNAMIC_SMPS: Device supports dynamic spatial + * multiplexing powersave, ie. can turn off all but one chain + * and then wake the rest up as required after, for example, + * rts/cts handshake. + * @NL80211_FEATURE_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM + * TSPEC sessions (TID aka TSID 0-7) with the %NL80211_CMD_ADD_TX_TS + * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it + * needs to be able to handle Block-Ack agreements and other things. + * @NL80211_FEATURE_MAC_ON_CREATE: Device supports configuring + * the vif's MAC address upon creation. + * See 'macaddr' field in the vif_params (cfg80211.h). + * @NL80211_FEATURE_TDLS_CHANNEL_SWITCH: Driver supports channel switching when + * operating as a TDLS peer. + * @NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR: This device/driver supports using a + * random MAC address during scan (if the device is unassociated); the + * %NL80211_SCAN_FLAG_RANDOM_ADDR flag may be set for scans and the MAC + * address mask/value will be used. + * @NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR: This device/driver supports + * using a random MAC address for every scan iteration during scheduled + * scan (while not associated), the %NL80211_SCAN_FLAG_RANDOM_ADDR may + * be set for scheduled scan and the MAC address mask/value will be used. + * @NL80211_FEATURE_ND_RANDOM_MAC_ADDR: This device/driver supports using a + * random MAC address for every scan iteration during "net detect", i.e. + * scan in unassociated WoWLAN, the %NL80211_SCAN_FLAG_RANDOM_ADDR may + * be set for scheduled scan and the MAC address mask/value will be used. + */ +enum nl80211_feature_flags { + NL80211_FEATURE_SK_TX_STATUS = 1 << 0, + NL80211_FEATURE_HT_IBSS = 1 << 1, + NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, + NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, + NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, + NL80211_FEATURE_SAE = 1 << 5, + NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, + NL80211_FEATURE_SCAN_FLUSH = 1 << 7, + NL80211_FEATURE_AP_SCAN = 1 << 8, + NL80211_FEATURE_VIF_TXPOWER = 1 << 9, + NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10, + NL80211_FEATURE_P2P_GO_CTWIN = 1 << 11, + NL80211_FEATURE_P2P_GO_OPPPS = 1 << 12, + /* bit 13 is reserved */ + NL80211_FEATURE_ADVERTISE_CHAN_LIMITS = 1 << 14, + NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 15, + NL80211_FEATURE_USERSPACE_MPM = 1 << 16, + NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17, + NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE = 1 << 18, + NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES = 1 << 19, + NL80211_FEATURE_WFA_TPC_IE_IN_PROBES = 1 << 20, + NL80211_FEATURE_QUIET = 1 << 21, + NL80211_FEATURE_TX_POWER_INSERTION = 1 << 22, + NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23, + NL80211_FEATURE_STATIC_SMPS = 1 << 24, + NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, + NL80211_FEATURE_SUPPORTS_WMM_ADMISSION = 1 << 26, + NL80211_FEATURE_MAC_ON_CREATE = 1 << 27, + NL80211_FEATURE_TDLS_CHANNEL_SWITCH = 1 << 28, + NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR = 1 << 29, + NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR = 1 << 30, + NL80211_FEATURE_ND_RANDOM_MAC_ADDR = 1 << 31, +}; + +/** + * enum nl80211_ext_feature_index - bit index of extended features. + * @NL80211_EXT_FEATURE_VHT_IBSS: This driver supports IBSS with VHT datarates. + * + * @NUM_NL80211_EXT_FEATURES: number of extended features. + * @MAX_NL80211_EXT_FEATURES: highest extended feature index. + */ +enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_VHT_IBSS, + + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, + MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1 +}; + +/** + * enum nl80211_probe_resp_offload_support_attr - optional supported + * protocols for probe-response offloading by the driver/FW. + * To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute. + * Each enum value represents a bit in the bitmap of supported + * protocols. Typically a subset of probe-requests belonging to a + * supported protocol will be excluded from offload and uploaded + * to the host. + * + * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: Support for WPS ver. 1 + * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: Support for WPS ver. 2 + * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P + * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: Support for 802.11u + */ +enum nl80211_probe_resp_offload_support_attr { + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS = 1<<0, + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 = 1<<1, + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P = 1<<2, + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U = 1<<3, +}; + +/** + * enum nl80211_connect_failed_reason - connection request failed reasons + * @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be + * handled by the AP is reached. + * @NL80211_CONN_FAIL_BLOCKED_CLIENT: Connection request is rejected due to ACL. + */ +enum nl80211_connect_failed_reason { + NL80211_CONN_FAIL_MAX_CLIENTS, + NL80211_CONN_FAIL_BLOCKED_CLIENT, +}; + +/** + * enum nl80211_scan_flags - scan request control flags + * + * Scan request control flags are used to control the handling + * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN + * requests. + * + * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority + * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning + * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured + * as AP and the beaconing has already been configured. This attribute is + * dangerous because will destroy stations performance as a lot of frames + * will be lost while scanning off-channel, therefore it must be used only + * when really needed + * @NL80211_SCAN_FLAG_RANDOM_ADDR: use a random MAC address for this scan (or + * for scheduled scan: a different one for every scan iteration). When the + * flag is set, depending on device capabilities the @NL80211_ATTR_MAC and + * @NL80211_ATTR_MAC_MASK attributes may also be given in which case only + * the masked bits will be preserved from the MAC address and the remainder + * randomised. If the attributes are not given full randomisation (46 bits, + * locally administered 1, multicast 0) is assumed. + * This flag must not be requested when the feature isn't supported, check + * the nl80211 feature flags for the device. + */ +enum nl80211_scan_flags { + NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, + NL80211_SCAN_FLAG_FLUSH = 1<<1, + NL80211_SCAN_FLAG_AP = 1<<2, + NL80211_SCAN_FLAG_RANDOM_ADDR = 1<<3, +}; + +/** + * enum nl80211_acl_policy - access control policy + * + * Access control policy is applied on a MAC list set by + * %NL80211_CMD_START_AP and %NL80211_CMD_SET_MAC_ACL, to + * be used with %NL80211_ATTR_ACL_POLICY. + * + * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are + * listed in ACL, i.e. allow all the stations which are not listed + * in ACL to authenticate. + * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow the stations which are listed + * in ACL, i.e. deny all the stations which are not listed in ACL. + */ +enum nl80211_acl_policy { + NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED, + NL80211_ACL_POLICY_DENY_UNLESS_LISTED, +}; + +/** + * enum nl80211_smps_mode - SMPS mode + * + * Requested SMPS mode (for AP mode) + * + * @NL80211_SMPS_OFF: SMPS off (use all antennas). + * @NL80211_SMPS_STATIC: static SMPS (use a single antenna) + * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and + * turn on other antennas after CTS/RTS). + */ +enum nl80211_smps_mode { + NL80211_SMPS_OFF, + NL80211_SMPS_STATIC, + NL80211_SMPS_DYNAMIC, + + __NL80211_SMPS_AFTER_LAST, + NL80211_SMPS_MAX = __NL80211_SMPS_AFTER_LAST - 1 +}; + +/** + * enum nl80211_radar_event - type of radar event for DFS operation + * + * Type of event to be used with NL80211_ATTR_RADAR_EVENT to inform userspace + * about detected radars or success of the channel available check (CAC) + * + * @NL80211_RADAR_DETECTED: A radar pattern has been detected. The channel is + * now unusable. + * @NL80211_RADAR_CAC_FINISHED: Channel Availability Check has been finished, + * the channel is now available. + * @NL80211_RADAR_CAC_ABORTED: Channel Availability Check has been aborted, no + * change to the channel status. + * @NL80211_RADAR_NOP_FINISHED: The Non-Occupancy Period for this channel is + * over, channel becomes usable. + */ +enum nl80211_radar_event { + NL80211_RADAR_DETECTED, + NL80211_RADAR_CAC_FINISHED, + NL80211_RADAR_CAC_ABORTED, + NL80211_RADAR_NOP_FINISHED, +}; + +/** + * enum nl80211_dfs_state - DFS states for channels + * + * Channel states used by the DFS code. + * + * @NL80211_DFS_USABLE: The channel can be used, but channel availability + * check (CAC) must be performed before using it for AP or IBSS. + * @NL80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it + * is therefore marked as not available. + * @NL80211_DFS_AVAILABLE: The channel has been CAC checked and is available. + */ +enum nl80211_dfs_state { + NL80211_DFS_USABLE, + NL80211_DFS_UNAVAILABLE, + NL80211_DFS_AVAILABLE, +}; + +/** + * enum enum nl80211_protocol_features - nl80211 protocol features + * @NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP: nl80211 supports splitting + * wiphy dumps (if requested by the application with the attribute + * %NL80211_ATTR_SPLIT_WIPHY_DUMP. Also supported is filtering the + * wiphy dump by %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFINDEX or + * %NL80211_ATTR_WDEV. + */ +enum nl80211_protocol_features { + NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP = 1 << 0, +}; + +/** + * enum nl80211_crit_proto_id - nl80211 critical protocol identifiers + * + * @NL80211_CRIT_PROTO_UNSPEC: protocol unspecified. + * @NL80211_CRIT_PROTO_DHCP: BOOTP or DHCPv6 protocol. + * @NL80211_CRIT_PROTO_EAPOL: EAPOL protocol. + * @NL80211_CRIT_PROTO_APIPA: APIPA protocol. + * @NUM_NL80211_CRIT_PROTO: must be kept last. + */ +enum nl80211_crit_proto_id { + NL80211_CRIT_PROTO_UNSPEC, + NL80211_CRIT_PROTO_DHCP, + NL80211_CRIT_PROTO_EAPOL, + NL80211_CRIT_PROTO_APIPA, + /* add other protocols before this one */ + NUM_NL80211_CRIT_PROTO +}; + +/* maximum duration for critical protocol measures */ +#define NL80211_CRIT_PROTO_MAX_DURATION 5000 /* msec */ + +/** + * enum nl80211_rxmgmt_flags - flags for received management frame. + * + * Used by cfg80211_rx_mgmt() + * + * @NL80211_RXMGMT_FLAG_ANSWERED: frame was answered by device/driver. + */ +enum nl80211_rxmgmt_flags { + NL80211_RXMGMT_FLAG_ANSWERED = 1 << 0, +}; + +/* + * If this flag is unset, the lower 24 bits are an OUI, if set + * a Linux nl80211 vendor ID is used (no such IDs are allocated + * yet, so that's not valid so far) + */ +#define NL80211_VENDOR_ID_IS_LINUX 0x80000000 + +/** + * struct nl80211_vendor_cmd_info - vendor command data + * @vendor_id: If the %NL80211_VENDOR_ID_IS_LINUX flag is clear, then the + * value is a 24-bit OUI; if it is set then a separately allocated ID + * may be used, but no such IDs are allocated yet. New IDs should be + * added to this file when needed. + * @subcmd: sub-command ID for the command + */ +struct nl80211_vendor_cmd_info { + __u32 vendor_id; + __u32 subcmd; +}; + +/** + * enum nl80211_tdls_peer_capability - TDLS peer flags. + * + * Used by tdls_mgmt() to determine which conditional elements need + * to be added to TDLS Setup frames. + * + * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable. + * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable. + * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable. + */ +enum nl80211_tdls_peer_capability { + NL80211_TDLS_PEER_HT = 1<<0, + NL80211_TDLS_PEER_VHT = 1<<1, + NL80211_TDLS_PEER_WMM = 1<<2, +}; + +#endif /* __LINUX_NL80211_H */ @@ -36,37 +36,56 @@ static void fmt_scan_entry(struct scan_entry *cur, char buf[], size_t buflen) { size_t len = 0; - if (!(cur->qual.updated & (IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID))) - len += snprintf(buf + len, buflen - len, "%3.0f%%, %.0f dBm", - 1E2 * cur->qual.qual / sr.range.max_qual.qual, - cur->dbm.signal); - else if (!(cur->qual.updated & IW_QUAL_QUAL_INVALID)) + if (cur->bss_signal) { + float sig_qual, sig_qual_max; + + if (cur->bss_signal_qual) { + /* BSS_SIGNAL_UNSPEC is scaled 0..100 */ + sig_qual = cur->bss_signal_qual; + sig_qual_max = 100; + } else { + if (cur->bss_signal < -110) + sig_qual = 0; + else if (cur->bss_signal > -40) + sig_qual = 70; + else + sig_qual = cur->bss_signal + 110; + sig_qual_max = 70; + } + len += snprintf(buf + len, buflen - len, "%3.0f%%, %d dBm", + (1E2 * sig_qual)/ sig_qual_max, cur->bss_signal); + } else if (cur->bss_signal_qual) { len += snprintf(buf + len, buflen - len, "%2d/%d", - cur->qual.qual, sr.range.max_qual.qual); - else if (!(cur->qual.updated & IW_QUAL_LEVEL_INVALID)) - len += snprintf(buf + len, buflen - len, "%.0f dBm", - cur->dbm.signal); - else + cur->bss_signal_qual, 100); + } else { len += snprintf(buf + len, buflen - len, "? dBm"); + } - if (cur->freq < 1e3) - len += snprintf(buf + len, buflen - len, ", Chan %2.0f", - cur->freq); - else if (cur->chan >= 0) - len += snprintf(buf + len, buflen - len, ", %s %3d, %g MHz", - cur->freq < 5e9 ? "ch" : "CH", - cur->chan, cur->freq / 1e6); + if (cur->chan >= 0) + len += snprintf(buf + len, buflen - len, ", %s %3d, %d MHz", + cur->freq < 5e6 ? "ch" : "CH", + cur->chan, cur->freq); else len += snprintf(buf + len, buflen - len, ", %g GHz", - cur->freq / 1e9); - - /* Access Points are marked by CP_SCAN_CRYPT/CP_SCAN_UNENC already */ - if (cur->mode != IW_MODE_MASTER) - len += snprintf(buf + len, buflen - len, " %s", - iw_opmode(cur->mode)); - if (cur->flags) - len += snprintf(buf + len, buflen - len, ", %s", - format_enc_capab(cur->flags, "/")); + cur->freq / 1e3); + + if (cur->bss_capa & WLAN_CAPABILITY_ESS) { + if (cur->bss_sta_count || cur->bss_chan_usage > 2) { + if (cur->bss_sta_count) + len += snprintf(buf + len, buflen - len, " %u sta", cur->bss_sta_count); + if (cur->bss_chan_usage > 2) /* 1% is 2.55 */ + len += snprintf(buf + len, buflen - len, "%s %.0f%% chan", + cur->bss_sta_count? "," : "", (1e2 * cur->bss_chan_usage)/2.55e2); + } else { + len += snprintf(buf + len, buflen - len, " ESS"); + } + if (cur->bss_capa & WLAN_CAPABILITY_RADIO_MEASURE) + len += snprintf(buf + len, buflen - len, ", Radio Measure"); + if (cur->bss_capa & WLAN_CAPABILITY_SPECTRUM_MGMT) + len += snprintf(buf + len, buflen - len, ", Spectrum Mgmt"); + } else if (cur->bss_capa & WLAN_CAPABILITY_IBSS) { + len += snprintf(buf + len, buflen - len, " IBSS"); + } } static void display_aplist(WINDOW *w_aplst) @@ -75,6 +94,7 @@ static void display_aplist(WINDOW *w_aplst) const char *sort_type[] = { [SO_CHAN] = "Chan", [SO_SIGNAL] = "Sig", + [SO_MAC] = "Mac", [SO_ESSID] = "Essid", [SO_OPEN] = "Open", [SO_CHAN_SIG] = "Ch/Sg", @@ -100,8 +120,9 @@ static void display_aplist(WINDOW *w_aplst) for (cur = sr.head; cur && line < MAXYLEN; line++, cur = cur->next) { col = CP_SCAN_NON_AP; - if (cur->mode == IW_MODE_MASTER) + if (!WLAN_CAPABILITY_IS_STA_BSS(cur->bss_capa) && (cur->bss_capa & WLAN_CAPABILITY_ESS)) { col = cur->has_key ? CP_SCAN_CRYPT : CP_SCAN_UNENC; + } wmove(w_aplst, line, 1); if (!*cur->essid) { @@ -209,6 +230,9 @@ int scr_aplst_loop(WINDOW *w_menu) case 'e': /* ESSID */ conf.scan_sort_order = SO_ESSID; return -1; + case 'm': /* MAC address */ + conf.scan_sort_order = SO_MAC; + return -1; case 'o': /* open (descending is default) */ conf.scan_sort_order = SO_OPEN; conf.scan_sort_asc = false; @@ -117,7 +117,7 @@ static double interpolate(const double val, const double min, const double max) } void waddbar(WINDOW *win, int y, float v, float min, float max, - char *cscale, bool rev) + int8_t *cscale, bool rev) { chtype ch = '=' | A_BOLD | cp_from_scale(v, cscale, rev); int len = MAXXLEN * interpolate(v, min, max); @@ -127,7 +127,7 @@ void waddbar(WINDOW *win, int y, float v, float min, float max, } void waddthreshold(WINDOW *win, int y, float v, float tv, - float minv, float maxv, char *cscale, chtype tch) + float minv, float maxv, int8_t *cscale, chtype tch) { if (tv > minv && tv < maxv) { if (v > tv) @@ -0,0 +1,261 @@ +/* + * General-purpose utilities used by multiple files. + */ +#include "wavemon.h" +#include "nl80211.h" +#include <arpa/inet.h> +#include <netinet/in.h> +#include <netinet/ether.h> +#include <net/if_arp.h> +#include <net/ethernet.h> +#include <sys/socket.h> +#include <linux/if.h> + +/* Maximum length of a MAC address: 2 * 6 hex digits, 6 - 1 colons, plus '\0' */ +#define MAC_ADDR_MAX 18 + +/* Return true if all ethernet octets are zero. */ +bool ether_addr_is_zero(const struct ether_addr *ea) +{ + static const struct ether_addr zero = {{0}}; + + return memcmp(ea, &zero, sizeof(zero)) == 0; +} + +/* Print a mac-address, include leading zeroes (unlike ether_ntoa(3)) */ +char *ether_addr(const struct ether_addr *ea) +{ + static char mac[MAC_ADDR_MAX]; + char *d = mac, *a = ether_ntoa(ea); +next_chunk: + if (a[0] == '\0' || a[1] == '\0' || a[1] == ':') + *d++ = '0'; + while ((*d++ = conf.cisco_mac ? (*a == ':' ? '.' : *a) : toupper(*a))) + if (*a++ == ':') + goto next_chunk; + return mac; +} + +/* Print mac-address translation from /etc/ethers if available */ +char *ether_lookup(const struct ether_addr *ea) +{ + static char hostname[BUFSIZ]; + + if (ether_ntohost(hostname, ea) == 0) + return hostname; + return ether_addr(ea); +} + +/* Format an Ethernet mac address */ +char *mac_addr(const struct sockaddr *sa) +{ + if (sa->sa_family != ARPHRD_ETHER) + return "00:00:00:00:00:00"; + return ether_lookup((const struct ether_addr *)sa->sa_data); +} + +/* Format a (I)BSSID */ +char *format_bssid(const struct sockaddr *ap) +{ + uint8_t bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + uint8_t zero_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + if (memcmp(ap->sa_data, zero_addr, ETH_ALEN) == 0) + return "Not-Associated"; + if (memcmp(ap->sa_data, bcast_addr, ETH_ALEN) == 0) + return "Invalid"; + return mac_addr(ap); +} + +/* count bits set in @mask the Brian Kernighan way */ +uint8_t bit_count(uint32_t mask) +{ + uint8_t bits_set; + + for (bits_set = 0; mask; bits_set++) + mask &= mask - 1; + + return bits_set; +} + +/* netmask = contiguous 1's followed by contiguous 0's */ +uint8_t prefix_len(const struct in_addr *netmask) +{ + return bit_count(netmask->s_addr); +} + +/* Pretty-print @sec into a string of up to 6 characters. */ +const char *pretty_time(const unsigned sec) +{ + static char buf[12]; + unsigned d = sec / 86400, + h = sec % 86400 / 3600, + m = sec % 3600 / 60; + + if (d > 9) { + sprintf(buf, "%u days", d); + } else if (d) { + if (h) { + sprintf(buf, "%ud %uh", d, h); + } else if (m) { + sprintf(buf, "%ud %dm", d, m); + } else { + sprintf(buf, "%u day%s", d, d == 1 ? "" : "s"); + } + } else if (h) { + sprintf(buf, "%u:%02uh", h, m); + } else if (m) { + sprintf(buf, "%u:%02um", m, sec % 60); + } else { + sprintf(buf, "%u sec", sec); + } + return buf; +} + +/* Like pretty_time, but allow milliseconds */ +const char *pretty_time_ms(const unsigned msec) +{ + static char buf[12]; + + if (msec < 1000) { + sprintf(buf, "%u ms", msec); + return buf; + } + return pretty_time(msec/1000); +} + +/* Absolute power measurement in dBm (IW_QUAL_DBM): map into -192 .. 63 range */ +int u8_to_dbm(const int power) +{ + return power > 63 ? power - 0x100 : power; +} +uint8_t dbm_to_u8(const int dbm) +{ + return dbm < 0 ? dbm + 0x100 : dbm; +} + +/* Convert log dBm values to linear mW */ +double dbm2mw(const double in) +{ + return pow(10.0, in / 10.0); +} + +char *dbm2units(const double in) +{ + static char with_units[0x100]; + double val = dbm2mw(in); + + if (val < 0.00000001) { + sprintf(with_units, "%.2f pW", val * 1e9); + } else if (val < 0.00001) { + sprintf(with_units, "%.2f nW", val * 1e6); + } else if (val < 0.01) { + sprintf(with_units, "%.2f uW", val * 1e3); + } else { + sprintf(with_units, "%.2f mW", val); + } + return with_units; +} + +/* Convert linear mW values to log dBm */ +double mw2dbm(const double in) +{ + return 10.0 * log10(in); +} + +/* Stolen from iw:util.c */ +int ieee80211_frequency_to_channel(int freq) +{ + /* see 802.11-2007 17.3.8.3.2 and Annex J */ + if (freq == 2484) + return 14; + else if (freq < 2484) + return (freq - 2407) / 5; + else if (freq >= 4910 && freq <= 4980) + return (freq - 4000) / 5; + else if (freq <= 45000) /* DMG band lower limit */ + return (freq - 5000) / 5; + else if (freq >= 58320 && freq <= 64800) + return (freq - 56160) / 2160; + else + return 0; +} + +const char *channel_width_name(enum nl80211_chan_width width) +{ + switch (width) { + case NL80211_CHAN_WIDTH_20_NOHT: + return "20 MHz (no HT)"; + case NL80211_CHAN_WIDTH_20: + return "20 MHz"; + case NL80211_CHAN_WIDTH_40: + return "40 MHz"; + case NL80211_CHAN_WIDTH_80: + return "80 MHz"; + case NL80211_CHAN_WIDTH_80P80: + return "80+80 MHz"; + case NL80211_CHAN_WIDTH_160: + return "160 MHz"; + default: + return "unknown"; + } +} + +/* stolen from iw:interface.c */ +const char *channel_type_name(enum nl80211_channel_type channel_type) +{ + switch (channel_type) { + case NL80211_CHAN_NO_HT: + return "NO HT"; + case NL80211_CHAN_HT20: + return "HT20"; + case NL80211_CHAN_HT40MINUS: + return "HT40-"; + case NL80211_CHAN_HT40PLUS: + return "HT40+"; + default: + return "unknown"; + } +} + +/* stolen from iw:util.c */ +const char *iftype_name(enum nl80211_iftype iftype) +{ + static char modebuf[100]; + static const char *ifmodes[NL80211_IFTYPE_MAX + 1] = { + "Unspecified", + "IBSS", + "Managed", + "AP", + "AP/VLAN", + "WDS", + "Monitor", + "Mesh Point", + "P2P-Client", + "P2P-GO", + "P2P-Device", + "Outside of a BSS", + }; + + if (iftype <= NL80211_IFTYPE_MAX && ifmodes[iftype]) + return ifmodes[iftype]; + sprintf(modebuf, "Unknown mode (%d)", iftype); + return modebuf; +} + +/* stolen from iw:reg.c */ +const char *dfs_domain_name(enum nl80211_dfs_regions region) +{ + switch (region) { + case NL80211_DFS_UNSET: + return "DFS-UNSET"; + case NL80211_DFS_FCC: + return "DFS-FCC"; + case NL80211_DFS_ETSI: + return "DFS-ETSI"; + case NL80211_DFS_JP: + return "DFS-JP"; + default: + return "DFS-invalid"; + } +} @@ -1,15 +1,14 @@ -.TH wavemon 1 "March 2012" Linux "User Manuals" +.TH wavemon 1 "January 2015" Linux "User Manuals" .SH NAME wavemon \- a wireless network monitor .SH SYNOPSIS .B wavemon [-h] [-i .I ifname -.B ] [-l] [-r] [-v] +.B ] [-g] [-v] .SH DESCRIPTION \fIwavemon\fR is a ncurses-based monitoring application for wireless network devices. It plots levels in real-time as well as showing wireless and network -related device information. Currently, wavemon is still based on the wireless -extensions by Jean Tourrilhes <jt@hpl.hp.com>. +related device information. The \fIwavemon\fR interface splits into different "screens". Each screen presents information in a specific manner. For example, the @@ -79,17 +78,18 @@ address and the signal/channel information. A green/red MAC address indicates an (un-)encrypted access point, the colour changes to yellow for non-access points (in this case the mode is shown at the end of the line). The uncoloured information following the MAC address lists relative and -absolute signal strengths, channel, frequency, and the mode if the node -is not an access point. +absolute signal strengths, channel, frequency, and station-specific information. +The station-specific information includes the station type (ESS for Access Point, +IBSS for Ad-Hoc network), station count and channel utilisation. + A status line at the bottom informs about the current sort order and a few statistics, such as most (least) crowded channels (least crowded channels are listed when sorting by descending channel). The \fIsort_order\fR can also directly be changed via these keyboard shortcuts: \fIa\fRscending, \fId\fRescending; by \fIe\fRssid, \fIs\fRignal, \fIc\fRhannel (\fIC\fR also with signal), -or by \fIo\fRpen access (\fIO\fR also with signal). +\fIm\fRac address, or by \fIo\fRpen access (\fIO\fR also with signal). -Please note that gathering meaningful scan data can take several seconds. .TP .B Preferences (F7 or 'p') This screen allows you to change all program options such as interface and @@ -113,14 +113,10 @@ enabled by installing \fIwavemon\fR setuid-root. .SH "OPTIONS" .IP "\fB\-i \fIinterface\fR\fR" override autodetection and use the specified \fIinterface\fR. -.IP "\fB\-d\fR" -dump interface parameters to stdout and exit. .IP "\fB\-g\fR" check screen \fIgeometry\fR: a minimum size is required for proper display; this flag adds a check to ensure it is sufficiently large. Enable this if window does not display properly. -.IP "\fB\-r\fR" -generate random levels (for testing purposes). .IP "\fB\-h\fR" print help and exit. .IP "\fB\-v\fR" @@ -48,9 +48,9 @@ */ enum info_screen_geometry { WH_IFACE = 2, /* 'Interface' area at the top */ - WH_LEVEL = 9, /* Level meters (signal/noise/SNR) */ + WH_LEVEL = 9, /* Level meters */ WH_STATS = 3, /* WiFi statistics area */ - WH_INFO_MIN = 6, /* WiFi information area */ + WH_INFO_MIN = 8, /* WiFi information area */ WH_NET_MIN = 3, /* Network interface information area */ WH_NET_MAX = 5, /* Network interface information area */ WH_MENU = 1 /* Menu bar at the bottom */ @@ -78,7 +78,7 @@ enum info_screen_geometry { #define MAXYLEN (WAV_HEIGHT - 2) /* Number of seconds to display a warning message outside ncurses mode */ -#define WARN_DISPLAY_DELAY 3 +#define WARN_DISPLAY_DELAY 1 /* Minimum SSID length */ #define MAX_ESSID_LEN 16 @@ -108,6 +108,7 @@ static inline void threshold_action(enum threshold_action action) enum scan_sort_order { SO_CHAN, SO_SIGNAL, + SO_MAC, SO_ESSID, SO_OPEN, SO_CHAN_SIG, @@ -135,7 +136,6 @@ extern struct wavemon_conf { /* Boolean values */ int check_geometry, /* ensure window is large enough */ cisco_mac, /* Cisco-style MAC addresses */ - random, /* random signals */ override_bounds, /* override autodetection */ scan_sort_asc; /* direction of @scan_sort_order */ @@ -237,9 +237,9 @@ extern void waddstr_center(WINDOW * win, int y, const char *s); extern const char *curtail(const char *str, const char *sep, int len); extern void waddbar(WINDOW *win, int y, float v, float min, float max, - char *cscale, bool rev); + int8_t *cscale, bool rev); extern void waddthreshold(WINDOW *win, int y, float v, float tv, - float minv, float maxv, char *cscale, chtype tch); + float minv, float maxv, int8_t *cscale, chtype tch); enum colour_pair { CP_STANDARD = 1, CP_SCALEHI, @@ -262,7 +262,7 @@ enum colour_pair { CP_SCAN_NON_AP }; -static inline int cp_from_scale(float value, const char *cscale, bool reverse) +static inline int cp_from_scale(float value, int8_t const *cscale, bool reverse) { enum colour_pair cp; @@ -279,11 +279,9 @@ static inline int cp_from_scale(float value, const char *cscale, bool reverse) /* * Wireless interfaces */ -extern const char *we_version(void); extern const char *conf_ifname(void); -extern void conf_get_interface_list(bool init); -extern char **iw_get_interface_list(void); -extern void dump_parameters(void); +extern void conf_get_interface_list(void); +extern void iw_get_interface_list(char** if_list, size_t max_entries); /* * Timers diff --git a/wavemonrc.5 b/wavemonrc.5 index 0353194..07356e4 100644 --- a/wavemonrc.5 +++ b/wavemonrc.5 @@ -1,4 +1,4 @@ -.TH wavemonrc 5 "March 2012" Linux "User Manuals" +.TH wavemonrc 5 "January 2015" Linux "User Manuals" .SH NAME $HOME/.wavemonrc \- wavemon configuration file .SH DESCRIPTION @@ -24,14 +24,14 @@ If enabled, display MAC addresses using lower-case hex digits separated by dots rather than colons. .P .RE -.B sort_order = (channel|essid|signal|open|chan/sig|open/sig) +.B sort_order = (channel|essid|mac|signal|open|chan/sig|open/sig) .RS .RE (Scan sort type) .RS Determines the ordering used in the scan window: \fIchannel\fR sorts by channel number, \fIessid\fR by -access point name, \fIsignal\fR by signal strength, and \fIopen\fR by openness. The combined variants -\fIchan/sig\fR and \fIopen/sig\fR sort first by channel/openness and then by signal strength. +access point name, \fImac\fR by MAC address, \fIsignal\fR by signal strength, and \fIopen\fR by openness. +The combined variants \fIchan/sig\fR and \fIopen/sig\fR sort first by channel/openness and then by signal strength. It also affects the status line at the bottom: normally the most crowded channels are listed, sorting by \fIchannel\fR in descending order switches to least crowded ones instead. .P @@ -95,7 +95,7 @@ Override the auto-scaling of the bar graphs and histogram, allowing you to set y .RE (Minimum signal level, Maximum signal level) .RS -Set the left and right boundaries of the signal level scales. Ranges: \-128..\-60dBm (minimum) and \-59..120dBm (maximum). +Set the left and right boundaries of the signal level scales. Ranges: \-100..\-39 (minimum) and \-40..\-10dBm (maximum). .P .RE .B min_noise_level, max_noise_level = <n> @@ -103,16 +103,8 @@ Set the left and right boundaries of the signal level scales. Ranges: \-128..\-6 .RE (Minimum noise level, Maximum noise level) .RS -These work similar to the signal boundary settings. Ranges: \-128..\-60dBm -(minimum) and \-60..120dBm (maximum). -.P -.RE -.B random = (on|off) -.RS -.RE -(Random signals) -.RS -Switches on a fancy random generator for testing. +These work similar to the signal boundary settings. Ranges: \-120..\-70dBm +(minimum) and \-69..\-40dBm (maximum). .P .RE .B lo_threshold_action = (disabled|beep|flash|beep+flash) |