aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ChangeLog2
-rw-r--r--Makefile.in11
-rw-r--r--README47
-rw-r--r--README.md53
-rw-r--r--about_scr.c3
-rw-r--r--aclocal.m4173
-rw-r--r--conf.c264
-rw-r--r--conf_scr.c2
-rwxr-xr-xconfigure324
-rw-r--r--configure.ac19
-rw-r--r--ieee80211.h61
-rw-r--r--info_scr.c434
-rw-r--r--iw_if.c367
-rw-r--r--iw_if.h234
-rw-r--r--iw_nl80211.c730
-rw-r--r--iw_nl80211.h271
-rw-r--r--iw_scan.c959
-rw-r--r--lhist_scr.c31
-rw-r--r--nl80211.h4588
-rw-r--r--scan_scr.c78
-rw-r--r--ui.c4
-rw-r--r--utils.c261
-rw-r--r--wavemon.120
-rw-r--r--wavemon.h20
-rw-r--r--wavemonrc.522
25 files changed, 7336 insertions, 1642 deletions
diff --git a/ChangeLog b/ChangeLog
index 5fb83ad..a9a9b12 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
diff --git a/README b/README
deleted file mode 100644
index 77cb21b..0000000
--- a/README
+++ /dev/null
@@ -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
+
diff --git a/conf.c b/conf.c
index 376569e..27c11dc 100644
--- a/conf.c
+++ b/conf.c
@@ -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");
}
diff --git a/conf_scr.c b/conf_scr.c
index ad6462c..eca8e04 100644
--- a/conf_scr.c
+++ b/conf_scr.c
@@ -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);
diff --git a/configure b/configure
index 082dd99..a1b606f 100755
--- a/configure
+++ b/configure
@@ -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 */
diff --git a/info_scr.c b/info_scr.c
index 1251ae0..6a50b43 100644
--- a/info_scr.c
+++ b/info_scr.c
@@ -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);
diff --git a/iw_if.c b/iw_if.c
index 97718c4..77fc5c2 100644
--- a/iw_if.c
+++ b/iw_if.c
@@ -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);
-}
diff --git a/iw_if.h b/iw_if.h
index 494afa0..cc9e886 100644
--- a/iw_if.h
+++ b/iw_if.h
@@ -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;
+}
diff --git a/iw_scan.c b/iw_scan.c
index 740bdff..6426f68 100644
--- a/iw_scan.c
+++ b/iw_scan.c
@@ -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 */
diff --git a/scan_scr.c b/scan_scr.c
index 611a32f..6373b6a 100644
--- a/scan_scr.c
+++ b/scan_scr.c
@@ -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;
diff --git a/ui.c b/ui.c
index 14e47d1..ce5262b 100644
--- a/ui.c
+++ b/ui.c
@@ -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)
diff --git a/utils.c b/utils.c
new file mode 100644
index 0000000..10818ba
--- /dev/null
+++ b/utils.c
@@ -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";
+ }
+}
diff --git a/wavemon.1 b/wavemon.1
index 0300946..ccfba7d 100644
--- a/wavemon.1
+++ b/wavemon.1
@@ -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"
diff --git a/wavemon.h b/wavemon.h
index 3afc2ba..e7584f7 100644
--- a/wavemon.h
+++ b/wavemon.h
@@ -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)