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