Project import
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..876bd85 --- /dev/null +++ b/Makefile
@@ -0,0 +1,123 @@ +# +# Copyright (c) 2010-2011 Nest, Inc. +# All rights reserved. +# +# This document is the property of Nest. It is considered +# confidential and proprietary information. +# +# This document may not be reproduced or transmitted in any form, +# in whole or in part, without the express written permission of +# Nest. +# +# Description: +# This file is for iw, a library and set of utilities for +# manipulating Linux nl80211-based wireless network interfaces. +# + +BuildConfigSpecialized := No +BuildProductSpecialized := Yes + +include pre.mak + +PackageRoot := ./$(IwPackageName) +PackageExtension := tar.bz2 +PackageSeparator := +PackageVersion := + +PackagePatchArgs := -p1 + +PackageArchive := $(IwPackageName)/$(IwPackageName).$(PackageExtension) +PackageSourceDir := $(IwPackageName)/$(IwPackageName)$(PackageSeparator)$(PackageVersion) +PackagePatchDir := $(IwPackageName)/$(IwPackageName).patches + +PackageBuildMakefile = $(call GenerateBuildPaths,Makefile) + +LicenseSourceFile := COPYING +LicenseSourcePath := $(addprefix $(PackageSourceDir)/,$(LicenseSourceFile)) + +CleanPaths += $(PackageLicenseFile) + +NetlinkDir := sw/tps/libnl +NetlinkIncDir := $(call GenerateResultPaths,$(NetlinkDir),usr/include) +NetlinkLibDir := $(call GenerateResultPaths,$(NetlinkDir),usr/lib) + +all: $(PackageDefaultGoal) + +# Generate the package license contents. + +$(LicenseSourcePath): source + +$(PackageLicenseFile): $(LicenseSourcePath) + $(copy-result) + +# Extract the source from the archive and apply patches, if any. + +$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths) + $(call expand-archive,$(PackageArchive),$(PackageRoot)) + $(Verbose)touch $@ + $(call patch-directory,$(PackageSourceDir),$(PackagePatchArgs),$(PackagePatchPaths)) + +# Prepare the sources. + +.PHONY: source +source: | $(PackageSourceDir) + +# Patch the sources, if necessary. + +.PHONY: patch +patch: source + +# Generate the package build makefile. + +$(PackageBuildMakefile): | $(PackageSourceDir) $(BuildDirectory) + $(call create-links,$(CURDIR)/$(PackageSourceDir),$(BuildDirectory)) + +# Configure the source for building. + +.PHONY: configure +configure: source $(PackageBuildMakefile) + +# Build the source. +# +# We have to unset MAKEFLAGS since they confuse the package build otherwise. + +.PHONY: build +build: configure | $(BuildDirectory) + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(BuildDirectory) \ + CC="$(CC)" CXX="$(CXX)" AR=$(AR) NM=$(NM) RANLIB=$(RANLIB) STRIP=$(STRIP) \ + INSTALL="$(INSTALL) $(INSTALLFLAGS)" \ + NLLIBNAME="libnl-2.0" \ + NLCFLAGS="$(call ToolGenerateIncludeArgument,$(NetlinkIncDir))" \ + NLLDFLAGS="-L$(NetlinkLibDir)" \ + all + +# Stage the build to a temporary installation area. +# +# We have to unset MAKEFLAGS since they confuse the package build otherwise. + +.PHONY: stage stage-default stage-headers +stage: stage-default stage-headers + +stage-default: build | $(ResultDirectory) + $(Verbose)unset MAKEFLAGS && \ + $(MAKE) $(JOBSFLAG) -C $(BuildDirectory) \ + NLLIBNAME="libnl-2.0" \ + DESTDIR=$(ResultDirectory) \ + install + +ResultHeaderDir = $(ResultDirectory)/usr/include +SourceHeaderPaths = $(wildcard $(BuildDirectory)/*.h) + +$(ResultHeaderDir): + $(create-directory) + +stage-headers: build | $(ResultHeaderDir) + install --mode=0664 $(SourceHeaderPaths) $(ResultHeaderDir) + +clean: + $(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir) + $(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory) + $(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory) + +include post.mak
diff --git a/iw.url b/iw.url new file mode 100644 index 0000000..a3891cc --- /dev/null +++ b/iw.url
@@ -0,0 +1 @@ +git://git.sipsolutions.net/iw.git
diff --git a/iw.version b/iw.version new file mode 100644 index 0000000..ea3f0d7 --- /dev/null +++ b/iw.version
@@ -0,0 +1 @@ +0.9.22
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-50.description b/iw_0.9.22/iw_0.9.22.patches/iw-50.description new file mode 100644 index 0000000..ec9fb0f --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-50.description
@@ -0,0 +1,3 @@ +This patch synchronizes the version script with the like script from the rfkill package and eliminates the GIT repository label version +checking because it will invariably fail when the package is included as a subtree or submodule of a larger GIT repository. +
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-50.patch b/iw_0.9.22/iw_0.9.22.patches/iw-50.patch new file mode 100644 index 0000000..fa623cc --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-50.patch
@@ -0,0 +1,33 @@ +diff -aruN a/version.sh b/version.sh +--- a/version.sh 2011-11-04 03:53:29.000000000 -0700 ++++ b/version.sh 2011-12-15 14:17:51.000000000 -0800 +@@ -1,20 +1,17 @@ + #!/bin/sh + + VERSION="0.9.22" +-OUT="$1" +- +-if head=`git rev-parse --verify HEAD 2>/dev/null`; then +- git update-index --refresh --unmerged > /dev/null +- descr=$(git describe) + +- # on git builds check that the version number above +- # is correct... +- [ "${descr%%-*}" = "v$VERSION" ] || exit 2 ++SUFFIX= ++if test "x$1" = x--suffix; then ++ shift ++ SUFFIX="-$1" ++ shift ++fi ++OUT="$1" + +- v="${descr#v}" +- if git diff-index --name-only HEAD | read dummy ; then +- v="$v"-dirty +- fi ++if test "x$SUFFIX" != 'x'; then ++ v="$VERSION$SUFFIX" + else + v="$VERSION" + fi
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-51.description b/iw_0.9.22/iw_0.9.22.patches/iw-51.description new file mode 100644 index 0000000..7edbcbe --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-51.description
@@ -0,0 +1 @@ +This patch allows the package builder to specify the libnl version being built against externally to pkg-config.
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-51.patch b/iw_0.9.22/iw_0.9.22.patches/iw-51.patch new file mode 100644 index 0000000..05d300f --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-51.patch
@@ -0,0 +1,57 @@ +diff -aruN iw-0.9.22/Makefile iw-0.9.22.N/Makefile +--- iw-0.9.22/Makefile 2013-06-07 18:36:50.000000000 -0700 ++++ iw-0.9.22.N/Makefile 2013-06-10 12:09:36.006767045 -0700 +@@ -22,6 +22,31 @@ + OBJS += sections.o + ALL = iw + ++ifdef NLLIBNAME ++ ++NLLIBS = -lnl ++ ++ifeq ($(NLLIBNAME),libnl-1) ++NL1FOUND := Y ++endif ++ ++ifeq ($(NLLIBNAME),libnl-2.0) ++NL2FOUND := Y ++endif ++ ++ifdef NLCFLAGS ++CFLAGS += $(NLCFLAGS) ++endif ++ ++ifdef NLLDFLAGS ++LDFLAGS += $(NLLDFLAGS) ++endif ++ ++ifdef NLLIBS ++LIBS += $(NLLIBS) ++endif ++ ++else + NL1FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-1 && echo Y) + NL2FOUND := $(shell $(PKG_CONFIG) --atleast-version=2 libnl-2.0 && echo Y) + +@@ -30,8 +55,6 @@ + endif + + ifeq ($(NL2FOUND),Y) +-CFLAGS += -DCONFIG_LIBNL20 +-LIBS += -lnl-genl + NLLIBNAME = libnl-2.0 + endif + +@@ -41,6 +64,12 @@ + + LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME)) + CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME)) ++endif ++ ++ifeq ($(NL2FOUND),Y) ++CFLAGS += -DCONFIG_LIBNL20 ++LIBS += -lnl-genl ++endif + + ifeq ($(V),1) + Q=
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-52.description b/iw_0.9.22/iw_0.9.22.patches/iw-52.description new file mode 100644 index 0000000..7157b47 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-52.description
@@ -0,0 +1 @@ +This patch adds the ability to add/delete/start/stop device side tcp keep alives using iw
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-52.patch b/iw_0.9.22/iw_0.9.22.patches/iw-52.patch new file mode 100644 index 0000000..6a4e7dd --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-52.patch
@@ -0,0 +1,397 @@ +diff -aruN iw_0.9.22/keepalive.c iw_0.9.22.N/keepalive.c +--- iw_0.9.22/keepalive.c 1969-12-31 16:00:00.000000000 -0800 ++++ iw_0.9.22.N/keepalive.c 2015-03-27 17:02:09.738162006 -0700 +@@ -0,0 +1,287 @@ ++#include <net/if.h> ++#include <errno.h> ++#include <string.h> ++#include <stdlib.h> ++ ++#include <netlink/genl/genl.h> ++#include <netlink/genl/family.h> ++#include <netlink/genl/ctrl.h> ++#include <netlink/msg.h> ++#include <netlink/attr.h> ++ ++#include "nl80211.h" ++#include "iw.h" ++ ++typedef uint8_t u8; ++typedef uint16_t u16; ++typedef uint32_t u32; ++ ++#define CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH 64 ++ ++struct cfg80211_keepalive_request { ++ u32 interval; ++ u8 cmd; /* 0: ADD; 1: DEL: 2: START; 3: STOP */ ++ u8 index; ++ u8 trig; ++ u8 dst_macaddr[ETH_ALEN]; ++ u8 payload_len; ++ u8 payload[CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH]; ++}; ++ ++struct cfg80211_keepalive_request keepalive_req; ++ ++SECTION(keepalive); ++ ++static void keepalive_hex_dump(char *title, u8 *buf, size_t len) ++{ ++ int i; ++ ++ printf("%s - hexdump(len=%lu):", title, (unsigned long) len); ++ ++ for (i = 0; i < len; i++) ++ printf(" %02x", buf[i]); ++ printf("\n"); ++} ++ ++static int nl80211_parse_klv_req(const char *s) ++{ ++ long i; ++ char *endp; ++ ++ i = strtol(s, &endp, 10); ++ ++ if(endp == s) ++ return -1; ++ return i; ++} ++ ++static int nl80211_str2hex(u8 *src, u8 *dst, int src_len) ++{ ++ int i, bytecount=0; ++ ++ if (src_len & 0x01) ++ return -2; ++ ++ for (i=0; i<src_len; i++, src++) { ++ if (i != 0 && i%2 == 0) { ++ dst++; ++ bytecount++; ++ } else { ++ *dst <<= 4; ++ } ++ ++ if ((*src >= '0') && (*src <= '9')) ++ *dst += *src - '0'; ++ else if ((*src >= 'A') && (*src <= 'F')) ++ *dst += *src - 'A' + 10; ++ else if ((*src >= 'a') && (*src <= 'f')) ++ *dst += *src - 'a' + 10; ++ else { ++ return -1; ++ } ++ } ++ ++ bytecount++; ++ ++ return bytecount; ++} ++ ++static int build_klv_req(struct nl_msg *msg, int klv_cmd, u8 index, int interval, u8 trig, u8 *dst_macaddr, u8 payload_len, u8 *payload) ++{ ++ int ret = -1; ++ ++ if (!msg) ++ return -1; ++ ++ NLA_PUT_U32(msg, NL80211_ATTR_KLV_TYPE, klv_cmd); ++ NLA_PUT_U32(msg, NL80211_ATTR_KLV_INDEX, index); ++ ++ if (klv_cmd == 0 || klv_cmd == 1) { ++ ++ NLA_PUT_U32(msg, NL80211_ATTR_KLV_INTVL, interval); ++ NLA_PUT_U32 (msg, NL80211_ATTR_KLV_TRIG, trig); ++ ++ if (payload != NULL) { ++ if (dst_macaddr) { ++ keepalive_hex_dump("nl80211 klv_dstmac: ", dst_macaddr, ETH_ALEN); ++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst_macaddr); ++ } ++ ++ keepalive_hex_dump("nl80211 klv_payload: ", payload, payload_len); ++ NLA_PUT(msg, NL80211_ATTR_KLV_PAYLOAD, payload_len, payload); ++ } ++ } ++ ++ ret = 0; ++ ++ nla_put_failure: ++ return ret; ++} ++ ++static int nl80211_change_klv_req(char **cmdptr, int cmdtype, struct nl_msg *msg) ++{ ++ u8 index = 1, trig_type = 1, payload_len = 0; ++ u8 dst_macaddr[ETH_ALEN]; ++ u32 interval_ms = 10; ++ u8 *payload=NULL; ++ int val; ++ u8 dst_payload[64]; ++ ++ switch(cmdtype) { ++ case 0: /* KLV-ADD */ ++ val = nl80211_parse_klv_req(*cmdptr++); ++ /* valid index # is [1, 3]. Index #0 is reserved for driver internal use */ ++ if (val <= 0 || val > 3) { ++ printf("invalid index (%d)\n", val); ++ return -1; ++ } ++ index = val; ++ ++ val = nl80211_parse_klv_req(*cmdptr++); ++ /* limit klv interval to [10 ms, 50000 ms] */ ++ if (val < 1000 || val > 55000) { ++ printf("Keeplalive interval is out of range.\n"); ++ return -1; ++ } ++ interval_ms = val; ++ ++ val = nl80211_parse_klv_req(*cmdptr++); ++ /* valid trig type is limited to 0 or 1 */ ++ if (val < 0 || val > 1) { ++ printf("Invalid keepalive trigger type.\n"); ++ return -1; ++ } ++ trig_type = val; ++ ++ memset(dst_macaddr, 0, ETH_ALEN); ++ if (nl80211_str2hex((u8 *)(*cmdptr++), dst_macaddr, 2*ETH_ALEN) <= 0) { ++ printf("Invalid mac address\n"); ++ return -1; ++ } ++ ++ val = strlen(*cmdptr); /* klv payload length must be <= 64 bytes */ ++ if (val > 128) { ++ printf("Payload is too long\n"); ++ return -1; ++ } ++ ++ memset(dst_payload, 0, 64); ++ if ((payload_len=nl80211_str2hex((u8 *)(*cmdptr), dst_payload, val)) < 0) { ++ printf("Keepalive payload is invalid\n"); ++ return -1; ++ } ++ ++ break; ++ ++ case 1: /* KLV-DEL */ ++ index = nl80211_parse_klv_req(cmdptr[0]); ++ printf("index = %d\n", index); ++ /* index #0 is reserved for driver internal klv type */ ++ if (index <= 0 || index > 3) { ++ return -1; ++ } ++ ++ interval_ms = 10000; ++ break; ++ ++ case 2: /* KLV-START */ ++ case 3: /* KLV-STOP */ ++ break; ++ ++ case 4: /* KLV-SHOW */ ++ printf("Not supported\n"); ++ val = 0; ++ return val; ++ ++ default: ++ return -1; ++ } ++ ++ val = build_klv_req(msg, cmdtype, index, interval_ms, trig_type, &dst_macaddr[0], payload_len, dst_payload); ++ ++ return val; ++} ++ ++static int handle_keepalive_add(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv) ++{ ++ int ret; ++ ++ if (argc != 5) { ++ printf("Command parameters incorrect.\n"); ++ return -1; ++ } ++ ++ ret = nl80211_change_klv_req(argv, 0, msg); ++ printf("ret is %d\n", ret); ++ return ret; ++} ++ ++static int handle_keepalive_delete(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv) ++{ ++ int ret; ++ ++ if (argc != 1) { ++ printf("Command parameters incorrect.\n"); ++ return -1; ++ } ++ ++ ret = nl80211_change_klv_req(argv, 1, msg); ++ return ret; ++} ++ ++static int handle_keepalive_start(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv) ++{ ++ int ret; ++ ret = nl80211_change_klv_req(argv, 2, msg); ++ return ret; ++} ++ ++static int handle_keepalive_stop(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv) ++{ ++ int ret; ++ ret = nl80211_change_klv_req(argv, 3, msg); ++ return ret; ++} ++ ++static int print_keepalive_handler(struct nl_msg *msg, void *arg) ++{ ++ int *ret = arg; ++ if (arg != NULL) ++ *ret = 0; ++ return 0; ++} ++ ++static int handle_keepalive_show(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv) ++{ ++ int ret; ++ ++ printf("handle_keepalive_show\n"); ++ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, ++ print_keepalive_handler, &ret); ++ ++ return 0; ++} ++ ++COMMAND(keepalive, add, "<index> <interval> <trigger_type> <dst_macaddr> <payload>", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_add, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, del, "<index>", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_delete, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, start, "", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_start, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, stop, "", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_stop, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, show, "", NL80211_CMD_GET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_show, ++ "Show keepalive status."); +diff -aruN iw_0.9.22/Makefile iw_0.9.22.N/Makefile +--- iw_0.9.22/Makefile 2015-03-27 17:09:36.094185681 -0700 ++++ iw_0.9.22.N/Makefile 2015-03-27 17:02:09.738162006 -0700 +@@ -18,7 +18,7 @@ + interface.o ibss.o station.o survey.o util.o \ + mesh.o mpath.o scan.o reg.o version.o \ + reason.o status.o connect.o link.o offch.o ps.o cqm.o \ +- bitrate.o wowlan.o roc.o ++ bitrate.o wowlan.o roc.o keepalive.o + OBJS += sections.o + ALL = iw + +diff -aruN iw_0.9.22/nl80211.h iw_0.9.22.N/nl80211.h +--- iw_0.9.22/nl80211.h 2013-06-07 18:36:50.000000000 -0700 ++++ iw_0.9.22.N/nl80211.h 2015-03-27 17:06:38.766176275 -0700 +@@ -616,6 +616,8 @@ + + NL80211_CMD_SET_REKEY_OFFLOAD, + ++ NL80211_CMD_GET_KEEPALIVE, ++ NL80211_CMD_SET_KEEPALIVE, + /* add new commands above here */ + + /* used to define NL80211_CMD_MAX below */ +@@ -1217,6 +1219,81 @@ + 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, ++ ++ /* leave some room for new attributes in nl80211 updates */ ++ NL80211_ATTR_IM_SCAN_RESULT = NL80211_ATTR_BG_SCAN_PERIOD + 10, ++ NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI, ++ ++ NL80211_ATTR_SCAN_MIN_DWELL, ++ NL80211_ATTR_SCAN_MAX_DWELL, ++ NL80211_ATTR_SCAN_NUM_PROBE, ++ ++ NL80211_ATTR_SCHED_SCAN_SHORT_INTERVAL, ++ NL80211_ATTR_SCHED_SCAN_NUM_SHORT_INTERVALS, ++ ++ NL80211_ATTR_ROAMING_DISABLED, ++ NL80211_ATTR_CH_SWITCH_COUNT, ++ NL80211_ATTR_CH_SWITCH_BLOCK_TX, ++ NL80211_ATTR_CH_SWITCH_POST_BLOCK_TX, ++ ++ NL80211_ATTR_KLVDATA, ++ NL80211_ATTR_KLV_TYPE, ++ NL80211_ATTR_KLV_INTVL, ++ NL80211_ATTR_KLV_INDEX, ++ NL80211_ATTR_KLV_TRIG, ++ NL80211_ATTR_KLV_PAYLOAD, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST,
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-54.description b/iw_0.9.22/iw_0.9.22.patches/iw-54.description new file mode 100644 index 0000000..3a401f0 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-54.description
@@ -0,0 +1 @@ +Add the enums for drop action for wow filters. iw latest version still does not define these enumerations. These defines are taken from nl80211.h sitting in compat-wireless directory.
diff --git a/iw_0.9.22/iw_0.9.22.patches/iw-54.patch b/iw_0.9.22/iw_0.9.22.patches/iw-54.patch new file mode 100644 index 0000000..451e280 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.patches/iw-54.patch
@@ -0,0 +1,35 @@ +diff --git a/nl80211.h b/nl80211.h +index 7ba71e4..3ef44f1 100644 +--- a/nl80211.h ++++ b/nl80211.h +@@ -2222,12 +2222,30 @@ enum nl80211_wowlan_packet_pattern_attr { + __NL80211_WOWLAN_PKTPAT_INVALID, + NL80211_WOWLAN_PKTPAT_MASK, + NL80211_WOWLAN_PKTPAT_PATTERN, ++ NL80211_WOWLAN_PKTPAT_ACTION = NL80211_WOWLAN_PKTPAT_PATTERN + 10, + + NUM_NL80211_WOWLAN_PKTPAT, + MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, + }; + + /** ++ * enum nl80211_wowlan_action - WoWLAN packet pattern action ++ * @NL80211_WOWLAN_ACTION_ALLOW: this pattern should wake up the host ++ * and the packet should be forwarded to the host unless this packet ++ * matches a DROP rule. ++ * @NL80211_WOWLAN_ACTION_DROP: a packet containing this pattern shouldn't ++ * wake up the host. ++ */ ++enum nl80211_wowlan_action { ++ NL80211_WOWLAN_ACTION_ALLOW, ++ NL80211_WOWLAN_ACTION_DROP, ++ ++ /* keep last */ ++ NUM_NL80211_WOWLAN_ACTION, ++ MAX_NL80211_WOWLAN_ACTION = NUM_NL80211_WOWLAN_ACTION - 1, ++}; ++ ++/** + * struct nl80211_wowlan_pattern_support - pattern support information + * @max_patterns: maximum number of patterns supported + * @min_pattern_len: minimum length of each pattern
diff --git a/iw_0.9.22/iw_0.9.22.tar.bz2 b/iw_0.9.22/iw_0.9.22.tar.bz2 new file mode 100644 index 0000000..dcb1533 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22.tar.bz2 Binary files differ
diff --git a/iw_0.9.22/iw_0.9.22/COPYING b/iw_0.9.22/iw_0.9.22/COPYING new file mode 100644 index 0000000..73e19ac --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/COPYING
@@ -0,0 +1,16 @@ +Copyright (c) 2007, 2008 Johannes Berg +Copyright (c) 2007 Andy Lutomirski +Copyright (c) 2007 Mike Kershaw +Copyright (c) 2008-2009 Luis R. Rodriguez + +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.
diff --git a/iw_0.9.22/iw_0.9.22/Makefile b/iw_0.9.22/iw_0.9.22/Makefile new file mode 100644 index 0000000..0e7e4e6 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/Makefile
@@ -0,0 +1,125 @@ +-include .config + +MAKEFLAGS += --no-print-directory + +PREFIX ?= /usr +SBINDIR ?= $(PREFIX)/sbin +MANDIR ?= $(PREFIX)/share/man +PKG_CONFIG ?= pkg-config + +MKDIR ?= mkdir -p +INSTALL ?= install +CC ?= "gcc" + +CFLAGS ?= -O2 -g +CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration + +OBJS = iw.o genl.o event.o info.o phy.o \ + interface.o ibss.o station.o survey.o util.o \ + mesh.o mpath.o scan.o reg.o version.o \ + reason.o status.o connect.o link.o offch.o ps.o cqm.o \ + bitrate.o wowlan.o roc.o keepalive.o +OBJS += sections.o +ALL = iw + +ifdef NLLIBNAME + +NLLIBS = -lnl + +ifeq ($(NLLIBNAME),libnl-1) +NL1FOUND := Y +endif + +ifeq ($(NLLIBNAME),libnl-2.0) +NL2FOUND := Y +endif + +ifdef NLCFLAGS +CFLAGS += $(NLCFLAGS) +endif + +ifdef NLLDFLAGS +LDFLAGS += $(NLLDFLAGS) +endif + +ifdef NLLIBS +LIBS += $(NLLIBS) +endif + +else +NL1FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-1 && echo Y) +NL2FOUND := $(shell $(PKG_CONFIG) --atleast-version=2 libnl-2.0 && echo Y) + +ifeq ($(NL1FOUND),Y) +NLLIBNAME = libnl-1 +endif + +ifeq ($(NL2FOUND),Y) +NLLIBNAME = libnl-2.0 +endif + +ifeq ($(NLLIBNAME),) +$(error Cannot find development files for any supported version of libnl) +endif + +LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME)) +CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME)) +endif + +ifeq ($(NL2FOUND),Y) +CFLAGS += -DCONFIG_LIBNL20 +LIBS += -lnl-genl +endif + +ifeq ($(V),1) +Q= +NQ=true +else +Q=@ +NQ=echo +endif + +all: version_check $(ALL) + +version_check: +ifeq ($(NL2FOUND),Y) +else +ifeq ($(NL1FOUND),Y) +else + $(error No libnl found) +endif +endif + + +VERSION_OBJS := $(filter-out version.o, $(OBJS)) + +version.c: version.sh $(patsubst %.o,%.c,$(VERSION_OBJS)) nl80211.h iw.h Makefile \ + $(wildcard .git/index .git/refs/tags) + @$(NQ) ' GEN ' $@ + $(Q)./version.sh $@ + +%.o: %.c iw.h nl80211.h + @$(NQ) ' CC ' $@ + $(Q)$(CC) $(CFLAGS) -c -o $@ $< + +iw: $(OBJS) + @$(NQ) ' CC ' iw + $(Q)$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o iw + +check: + $(Q)$(MAKE) all CC="REAL_CC=$(CC) CHECK=\"sparse -Wall\" cgcc" + +%.gz: % + @$(NQ) ' GZIP' $< + $(Q)gzip < $< > $@ + +install: iw iw.8.gz + @$(NQ) ' INST iw' + $(Q)$(MKDIR) $(DESTDIR)$(SBINDIR) + $(Q)$(INSTALL) -m 755 iw $(DESTDIR)$(SBINDIR) + @$(NQ) ' INST iw.8' + $(Q)$(MKDIR) $(DESTDIR)$(MANDIR)/man8/ + $(Q)$(INSTALL) -m 644 iw.8.gz $(DESTDIR)$(MANDIR)/man8/ + +clean: + $(Q)rm -f iw *.o *~ *.gz version.c *-stamp
diff --git a/iw_0.9.22/iw_0.9.22/README b/iw_0.9.22/iw_0.9.22/README new file mode 100644 index 0000000..1d0eaae --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/README
@@ -0,0 +1,15 @@ + +This is 'iw', a tool to use nl80211. + + +To build iw, just enter 'make'. If that fails, set the +PKG_CONFIG_PATH environment variable to allow the Makefile +to find libnl. + + +'iw' is currently maintained at http://git.sipsolutions.net/iw.git/, +some more documentation is available at +http://wireless.kernel.org/en/users/Documentation/iw. + +Please send all patches to Johannes Berg <johannes@sipsolutions.net> +and CC linux-wireless@vger.kernel.org for community review.
diff --git a/iw_0.9.22/iw_0.9.22/bitrate.c b/iw_0.9.22/iw_0.9.22/bitrate.c new file mode 100644 index 0000000..cefd150 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/bitrate.c
@@ -0,0 +1,142 @@ +#include <errno.h> + +#include "nl80211.h" +#include "iw.h" + + +static int handle_bitrates(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + struct nlattr *nl_rates, *nl_band; + int i; + bool have_legacy_24 = false, have_legacy_5 = false; + uint8_t legacy_24[32], legacy_5[32]; + int n_legacy_24 = 0, n_legacy_5 = 0; + uint8_t *legacy = NULL; + int *n_legacy = NULL; + bool have_mcs_24 = false, have_mcs_5 = false; +#ifdef NL80211_TXRATE_MCS + uint8_t mcs_24[77], mcs_5[77]; + int n_mcs_24 = 0, n_mcs_5 = 0; + uint8_t *mcs = NULL; + int *n_mcs = NULL; +#endif + enum { + S_NONE, + S_LEGACY, + S_MCS, + } parser_state = S_NONE; + + for (i = 0; i < argc; i++) { + char *end; + double tmpd; +#ifdef NL80211_TXRATE_MCS + long tmpl; +#endif + + if (strcmp(argv[i], "legacy-2.4") == 0) { + if (have_legacy_24) + return 1; + parser_state = S_LEGACY; + legacy = legacy_24; + n_legacy = &n_legacy_24; + have_legacy_24 = true; + } else if (strcmp(argv[i], "legacy-5") == 0) { + if (have_legacy_5) + return 1; + parser_state = S_LEGACY; + legacy = legacy_5; + n_legacy = &n_legacy_5; + have_legacy_5 = true; + } +#ifdef NL80211_TXRATE_MCS + else if (strcmp(argv[i], "mcs-2.4") == 0) { + if (have_mcs_24) + return 1; + parser_state = S_MCS; + mcs = mcs_24; + n_mcs = &n_mcs_24; + have_mcs_24 = true; + } else if (strcmp(argv[i], "mcs-5") == 0) { + if (have_mcs_5) + return 1; + parser_state = S_MCS; + mcs = mcs_5; + n_mcs = &n_mcs_5; + have_mcs_5 = true; + } +#endif + else switch (parser_state) { + case S_LEGACY: + tmpd = strtod(argv[i], &end); + if (*end != '\0') + return 1; + if (tmpd < 1 || tmpd > 255 * 2) + return 1; + legacy[(*n_legacy)++] = tmpd * 2; + break; + case S_MCS: +#ifdef NL80211_TXRATE_MCS + tmpl = strtol(argv[i], &end, 0); + if (*end != '\0') + return 1; + if (tmpl < 0 || tmpl > 255) + return 1; + mcs[(*n_mcs)++] = tmpl; + break; +#endif + default: + return 1; + } + } + + nl_rates = nla_nest_start(msg, NL80211_ATTR_TX_RATES); + if (!nl_rates) + goto nla_put_failure; + + if (have_legacy_24 || have_mcs_24) { + nl_band = nla_nest_start(msg, NL80211_BAND_2GHZ); + if (!nl_band) + goto nla_put_failure; + if (have_legacy_24) + nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_24, legacy_24); +#ifdef NL80211_TXRATE_MCS + if (have_mcs_24) + nla_put(msg, NL80211_TXRATE_MCS, n_mcs_24, mcs_24); +#endif + nla_nest_end(msg, nl_band); + } + + if (have_legacy_5 || have_mcs_5) { + nl_band = nla_nest_start(msg, NL80211_BAND_5GHZ); + if (!nl_band) + goto nla_put_failure; + if (have_legacy_5) + nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_5, legacy_5); +#ifdef NL80211_TXRATE_MCS + if (have_mcs_5) + nla_put(msg, NL80211_TXRATE_MCS, n_mcs_5, mcs_5); +#endif + nla_nest_end(msg, nl_band); + } + + nla_nest_end(msg, nl_rates); + + return 0; + nla_put_failure: + return -ENOBUFS; +} + +#define DESCR_LEGACY "[legacy-<2.4|5> <legacy rate in Mbps>*]" +#ifdef NL80211_TXRATE_MCS +#define DESCR DESCR_LEGACY " [mcs-<2.4|5> <MCS index>*]" +#else +#define DESCR DESCR_LEGACY +#endif + +COMMAND(set, bitrates, DESCR, NL80211_CMD_SET_TX_BITRATE_MASK, 0, CIB_NETDEV, + handle_bitrates, + "Sets up the specified rate masks.\n" + "Not passing any arguments would clear the existing mask (if any).");
diff --git a/iw_0.9.22/iw_0.9.22/connect.c b/iw_0.9.22/iw_0.9.22/connect.c new file mode 100644 index 0000000..1af4e0d --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/connect.c
@@ -0,0 +1,144 @@ +#include <errno.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int iw_conn(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *end; + unsigned char bssid[6]; + int freq; + + if (argc < 1) + return 1; + + /* SSID */ + NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]); + argv++; + argc--; + + /* freq */ + if (argc) { + freq = strtoul(argv[0], &end, 10); + if (*end == '\0') { + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + argv++; + argc--; + } + } + + /* bssid */ + if (argc) { + if (mac_addr_a2n(bssid, argv[0]) == 0) { + NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid); + argv++; + argc--; + } + } + + if (!argc) + return 0; + + if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0) + return 1; + + argv++; + argc--; + + return parse_keys(msg, argv, argc); + nla_put_failure: + return -ENOSPC; +} + +static int disconnect(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + return 0; +} +TOPLEVEL(disconnect, NULL, + NL80211_CMD_DISCONNECT, 0, CIB_NETDEV, disconnect, + "Disconnect from the current network."); + +static int iw_connect(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char **conn_argv, *dev = argv[0]; + static const __u32 cmds[] = { + NL80211_CMD_CONNECT, + }; + struct print_event_args printargs = { }; + int conn_argc, err; + bool wait = false; + int i; + + /* strip "wlan0 connect" */ + argc -= 2; + argv += 2; + + /* check -w */ + if (argc && strcmp(argv[0], "-w") == 0) { + wait = true; + argc--; + argv++; + } + + conn_argc = 3 + argc; + conn_argv = calloc(conn_argc, sizeof(*conn_argv)); + if (!conn_argv) + return -ENOMEM; + + err = __prepare_listen_events(state); + if (err) + return err; + + conn_argv[0] = dev; + conn_argv[1] = "connect"; + conn_argv[2] = "establish"; + for (i = 0; i < argc; i++) + conn_argv[i + 3] = argv[i]; + err = handle_cmd(state, II_NETDEV, conn_argc, conn_argv); + free(conn_argv); + if (err) + return err; + + if (!wait) + return 0; + + /* + * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION + * + * This code has a bug: + * + * It is possible for a connect result message from another + * connect attempt to be processed here first, because we + * start listening to the multicast group before starting + * our own connect request, which may succeed but we get a + * fail message from a previous attempt that raced with us, + * or similar. + * + * The only proper way to fix this would be to listen to events + * before sending the command, and for the kernel to send the + * connect request or a cookie along with the event, so that you + * can match up whether the connect _you_ requested was finished + * or aborted. + * + * Alas, the kernel doesn't do that (yet). + */ + + __do_listen_events(state, ARRAY_SIZE(cmds), cmds, &printargs); + return 0; +} +TOPLEVEL(connect, "[-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:6162636465]", + 0, 0, CIB_NETDEV, iw_connect, + "Join the network with the given SSID (and frequency, BSSID).\n" + "With -w, wait for the connect to finish or fail."); +HIDDEN(connect, establish, "", NL80211_CMD_CONNECT, 0, CIB_NETDEV, iw_conn);
diff --git a/iw_0.9.22/iw_0.9.22/cqm.c b/iw_0.9.22/iw_0.9.22/cqm.c new file mode 100644 index 0000000..3da2b54 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/cqm.c
@@ -0,0 +1,54 @@ +#include <errno.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int iw_cqm_rssi(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nl_msg *cqm = NULL; + int thold = 0; + int hyst = 0; + int ret = -ENOSPC; + + /* get the required args */ + if (argc < 1 || argc > 2) + return 1; + + if (strcmp(argv[0], "off")) { + thold = atoi(argv[0]); + + if (thold == 0) + return -EINVAL; + + if (argc == 2) + hyst = atoi(argv[1]); + } + + /* connection quality monitor attributes */ + cqm = nlmsg_alloc(); + + NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, thold); + NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hyst); + + nla_put_nested(msg, NL80211_ATTR_CQM, cqm); + ret = 0; + + nla_put_failure: + nlmsg_free(cqm); + return ret; +} + +TOPLEVEL(cqm, "", + 0, 0, CIB_NETDEV, NULL, + "Configure the WLAN connection quality monitor.\n"); + +COMMAND(cqm, rssi, "<threshold|off> [<hysteresis>]", + NL80211_CMD_SET_CQM, 0, CIB_NETDEV, iw_cqm_rssi, + "Set connection quality monitor RSSI threshold.\n");
diff --git a/iw_0.9.22/iw_0.9.22/event.c b/iw_0.9.22/iw_0.9.22/event.c new file mode 100644 index 0000000..cdd5036 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/event.c
@@ -0,0 +1,587 @@ +#include <stdint.h> +#include <stdbool.h> +#include <net/if.h> +#include <errno.h> +#include "iw.h" + +static int no_seq_check(struct nl_msg *msg, void *arg) +{ + return NL_OK; +} + +struct ieee80211_beacon_channel { + __u16 center_freq; + bool passive_scan; + bool no_ibss; +}; + +static int parse_beacon_hint_chan(struct nlattr *tb, + struct ieee80211_beacon_channel *chan) +{ + struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; + static struct nla_policy beacon_freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, + [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, + }; + + if (nla_parse_nested(tb_freq, + NL80211_FREQUENCY_ATTR_MAX, + tb, + beacon_freq_policy)) + return -EINVAL; + + chan->center_freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + + if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) + chan->passive_scan = true; + if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS]) + chan->no_ibss = true; + + return 0; +} + +static void print_frame(struct print_event_args *args, struct nlattr *attr) +{ + uint8_t *frame; + size_t len; + int i; + char macbuf[6*3]; + uint16_t tmp; + + if (!attr) + printf(" [no frame]"); + + frame = nla_data(attr); + len = nla_len(attr); + + if (len < 26) { + printf(" [invalid frame: "); + goto print_frame; + } + + mac_addr_n2a(macbuf, frame + 10); + printf(" %s -> ", macbuf); + mac_addr_n2a(macbuf, frame + 4); + printf("%s", macbuf); + + switch (frame[0] & 0xfc) { + case 0x10: /* assoc resp */ + case 0x30: /* reassoc resp */ + /* status */ + tmp = (frame[27] << 8) + frame[26]; + printf(" status: %d: %s", tmp, get_status_str(tmp)); + break; + case 0x00: /* assoc req */ + case 0x20: /* reassoc req */ + break; + case 0xb0: /* auth */ + /* status */ + tmp = (frame[29] << 8) + frame[28]; + printf(" status: %d: %s", tmp, get_status_str(tmp)); + break; + break; + case 0xa0: /* disassoc */ + case 0xc0: /* deauth */ + /* reason */ + tmp = (frame[25] << 8) + frame[24]; + printf(" reason %d: %s", tmp, get_reason_str(tmp)); + break; + } + + if (!args->frame) + return; + + printf(" [frame:"); + + print_frame: + for (i = 0; i < len; i++) + printf(" %.02x", frame[i]); + printf("]"); +} + +static void parse_cqm_event(struct nlattr **attrs) +{ + static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = { + [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 }, + [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 }, + [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 }, + }; + struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1]; + struct nlattr *cqm_attr = attrs[NL80211_ATTR_CQM]; + + printf("connection quality monitor event: "); + + if (!cqm_attr || + nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, cqm_attr, cqm_policy)) { + printf("missing data!\n"); + return; + } + + if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]) { + enum nl80211_cqm_rssi_threshold_event rssi_event; + rssi_event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]); + if (rssi_event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) + printf("RSSI went above threshold\n"); + else + printf("RSSI went below threshold\n"); + } else if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT] && + attrs[NL80211_ATTR_MAC]) { + uint32_t frames; + char buf[3*6]; + + frames = nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]); + mac_addr_n2a(buf, nla_data(attrs[NL80211_ATTR_MAC])); + printf("peer %s didn't ACK %d packets\n", buf, frames); + } else + printf("unknown event\n"); +} + +static const char * key_type_str(enum nl80211_key_type key_type) +{ + static char buf[30]; + switch (key_type) { + case NL80211_KEYTYPE_GROUP: + return "Group"; + case NL80211_KEYTYPE_PAIRWISE: + return "Pairwise"; + case NL80211_KEYTYPE_PEERKEY: + return "PeerKey"; + default: + snprintf(buf, sizeof(buf), "unknown(%d)", key_type); + return buf; + } +} + +static void parse_mic_failure(struct nlattr **attrs) +{ + printf("Michael MIC failure event:"); + + if (attrs[NL80211_ATTR_MAC]) { + char addr[3 * ETH_ALEN]; + mac_addr_n2a(addr, nla_data(attrs[NL80211_ATTR_MAC])); + printf(" source MAC address %s", addr); + } + + if (attrs[NL80211_ATTR_KEY_SEQ] && + nla_len(attrs[NL80211_ATTR_KEY_SEQ]) == 6) { + unsigned char *seq = nla_data(attrs[NL80211_ATTR_KEY_SEQ]); + printf(" seq=%02x%02x%02x%02x%02x%02x", + seq[0], seq[1], seq[2], seq[3], seq[4], seq[5]); + } + if (attrs[NL80211_ATTR_KEY_TYPE]) { + enum nl80211_key_type key_type = + nla_get_u32(attrs[NL80211_ATTR_KEY_TYPE]); + printf(" Key Type %s", key_type_str(key_type)); + } + + if (attrs[NL80211_ATTR_KEY_IDX]) { + __u8 key_id = nla_get_u8(attrs[NL80211_ATTR_KEY_IDX]); + printf(" Key Id %d", key_id); + } + + printf("\n"); +} + +static int print_event(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1], *nst; + struct print_event_args *args = arg; + char ifname[100]; + char macbuf[6*3]; + __u8 reg_type; + struct ieee80211_beacon_channel chan_before_beacon, chan_after_beacon; + __u32 wiphy_idx = 0; + int rem_nst; + __u16 status; + + if (args->time || args->reltime) { + unsigned long long usecs, previous; + + previous = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec; + gettimeofday(&args->ts, NULL); + usecs = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec; + if (args->reltime) { + if (!args->have_ts) { + usecs = 0; + args->have_ts = true; + } else + usecs -= previous; + } + printf("%llu.%06llu: ", usecs/1000000, usecs % 1000000); + } + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (tb[NL80211_ATTR_IFINDEX] && tb[NL80211_ATTR_WIPHY]) { + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), ifname); + printf("%s (phy #%d): ", ifname, nla_get_u32(tb[NL80211_ATTR_WIPHY])); + } else if (tb[NL80211_ATTR_IFINDEX]) { + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), ifname); + printf("%s: ", ifname); + } else if (tb[NL80211_ATTR_WIPHY]) { + printf("phy #%d: ", nla_get_u32(tb[NL80211_ATTR_WIPHY])); + } + + switch (gnlh->cmd) { + case NL80211_CMD_NEW_WIPHY: + printf("renamed to %s\n", nla_get_string(tb[NL80211_ATTR_WIPHY_NAME])); + break; + case NL80211_CMD_TRIGGER_SCAN: + printf("scan started\n"); + break; + case NL80211_CMD_NEW_SCAN_RESULTS: + printf("scan finished:"); + case NL80211_CMD_SCAN_ABORTED: + if (gnlh->cmd == NL80211_CMD_SCAN_ABORTED) + printf("scan aborted:"); + if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) { + nla_for_each_nested(nst, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem_nst) + printf(" %d", nla_get_u32(nst)); + printf(","); + } + if (tb[NL80211_ATTR_SCAN_SSIDS]) { + nla_for_each_nested(nst, tb[NL80211_ATTR_SCAN_SSIDS], rem_nst) { + printf(" \""); + print_ssid_escaped(nla_len(nst), nla_data(nst)); + printf("\""); + } + } + printf("\n"); + break; + case NL80211_CMD_REG_CHANGE: + printf("regulatory domain change: "); + + reg_type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]); + + switch (reg_type) { + case NL80211_REGDOM_TYPE_COUNTRY: + printf("set to %s by %s request", + nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]), + reg_initiator_to_string(nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]))); + if (tb[NL80211_ATTR_WIPHY]) + printf(" on phy%d", nla_get_u32(tb[NL80211_ATTR_WIPHY])); + break; + case NL80211_REGDOM_TYPE_WORLD: + printf("set to world roaming by %s request", + reg_initiator_to_string(nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]))); + break; + case NL80211_REGDOM_TYPE_CUSTOM_WORLD: + printf("custom world roaming rules in place on phy%d by %s request", + nla_get_u32(tb[NL80211_ATTR_WIPHY]), + reg_initiator_to_string(nla_get_u32(tb[NL80211_ATTR_REG_INITIATOR]))); + break; + case NL80211_REGDOM_TYPE_INTERSECTION: + printf("intersection used due to a request made by %s", + reg_initiator_to_string(nla_get_u32(tb[NL80211_ATTR_REG_INITIATOR]))); + if (tb[NL80211_ATTR_WIPHY]) + printf(" on phy%d", nla_get_u32(tb[NL80211_ATTR_WIPHY])); + break; + default: + printf("unknown source (upgrade this utility)"); + break; + } + + printf("\n"); + break; + case NL80211_CMD_REG_BEACON_HINT: + + wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]); + + memset(&chan_before_beacon, 0, sizeof(chan_before_beacon)); + memset(&chan_after_beacon, 0, sizeof(chan_after_beacon)); + + if (parse_beacon_hint_chan(tb[NL80211_ATTR_FREQ_BEFORE], + &chan_before_beacon)) + break; + if (parse_beacon_hint_chan(tb[NL80211_ATTR_FREQ_AFTER], + &chan_after_beacon)) + break; + + if (chan_before_beacon.center_freq != chan_after_beacon.center_freq) + break; + + /* A beacon hint is sent _only_ if something _did_ change */ + printf("beacon hint:\n"); + + printf("phy%d %d MHz [%d]:\n", + wiphy_idx, + chan_before_beacon.center_freq, + ieee80211_frequency_to_channel(chan_before_beacon.center_freq)); + + if (chan_before_beacon.passive_scan && !chan_after_beacon.passive_scan) + printf("\to active scanning enabled\n"); + if (chan_before_beacon.no_ibss && !chan_after_beacon.no_ibss) + printf("\to beaconing enabled\n"); + + break; + case NL80211_CMD_NEW_STATION: + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf("new station %s\n", macbuf); + break; + case NL80211_CMD_JOIN_IBSS: + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf("IBSS %s joined\n", macbuf); + break; + case NL80211_CMD_AUTHENTICATE: + printf("auth"); + if (tb[NL80211_ATTR_FRAME]) + print_frame(args, tb[NL80211_ATTR_FRAME]); + else if (tb[NL80211_ATTR_TIMED_OUT]) + printf(": timed out"); + else + printf(": unknown event"); + printf("\n"); + break; + case NL80211_CMD_ASSOCIATE: + printf("assoc"); + if (tb[NL80211_ATTR_FRAME]) + print_frame(args, tb[NL80211_ATTR_FRAME]); + else if (tb[NL80211_ATTR_TIMED_OUT]) + printf(": timed out"); + else + printf(": unknown event"); + printf("\n"); + break; + case NL80211_CMD_DEAUTHENTICATE: + printf("deauth"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_DISASSOCIATE: + printf("disassoc"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_UNPROT_DEAUTHENTICATE: + printf("unprotected deauth"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_UNPROT_DISASSOCIATE: + printf("unprotected disassoc"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_CONNECT: + status = 0; + if (!tb[NL80211_ATTR_STATUS_CODE]) + printf("unknown connect status"); + else if (nla_get_u16(tb[NL80211_ATTR_STATUS_CODE]) == 0) + printf("connected"); + else { + status = nla_get_u16(tb[NL80211_ATTR_STATUS_CODE]); + printf("failed to connect"); + } + if (tb[NL80211_ATTR_MAC]) { + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf(" to %s", macbuf); + } + if (status) + printf(", status: %d: %s", status, get_status_str(status)); + printf("\n"); + break; + case NL80211_CMD_ROAM: + printf("roamed"); + if (tb[NL80211_ATTR_MAC]) { + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf(" to %s", macbuf); + } + printf("\n"); + break; + case NL80211_CMD_DISCONNECT: + printf("disconnected"); + if (tb[NL80211_ATTR_DISCONNECTED_BY_AP]) + printf(" (by AP)"); + else + printf(" (local request)"); + if (tb[NL80211_ATTR_REASON_CODE]) + printf(" reason: %d: %s", nla_get_u16(tb[NL80211_ATTR_REASON_CODE]), + get_reason_str(nla_get_u16(tb[NL80211_ATTR_REASON_CODE]))); + printf("\n"); + break; + case NL80211_CMD_REMAIN_ON_CHANNEL: + printf("remain on freq %d (%dms, cookie %llx)\n", + nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]), + nla_get_u32(tb[NL80211_ATTR_DURATION]), + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE])); + break; + case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: + printf("done with remain on freq %d (cookie %llx)\n", + nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]), + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE])); + break; + case NL80211_CMD_NOTIFY_CQM: + parse_cqm_event(tb); + break; + case NL80211_CMD_MICHAEL_MIC_FAILURE: + parse_mic_failure(tb); + break; + case NL80211_CMD_FRAME_TX_STATUS: + printf("mgmt TX status (cookie %llx): %s\n", + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE]), + tb[NL80211_ATTR_ACK] ? "acked" : "no ack"); + break; + default: + printf("unknown event %d\n", gnlh->cmd); + break; + } + + fflush(stdout); + return NL_SKIP; +} + +struct wait_event { + int n_cmds; + const __u32 *cmds; + __u32 cmd; + struct print_event_args *pargs; +}; + +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; + if (wait->pargs) + print_event(msg, wait->pargs); + } + } + + return NL_SKIP; +} + +int __prepare_listen_events(struct nl80211_state *state) +{ + int mcid, ret; + + /* Configuration multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "config"); + if (mcid < 0) + return mcid; + + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + + /* Scan multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "scan"); + if (mcid >= 0) { + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + } + + /* Regulatory multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "regulatory"); + if (mcid >= 0) { + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + } + + /* MLME multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "mlme"); + if (mcid >= 0) { + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + } + + return 0; +} + +__u32 __do_listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits, + struct print_event_args *args) +{ + struct nl_cb *cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); + struct wait_event wait_ev; + + if (!cb) { + fprintf(stderr, "failed to allocate netlink callbacks\n"); + return -ENOMEM; + } + + /* no sequence checking for multicast messages */ + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + + if (n_waits && waits) { + wait_ev.cmds = waits; + wait_ev.n_cmds = n_waits; + wait_ev.pargs = args; + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, wait_event, &wait_ev); + } else + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, args); + + wait_ev.cmd = 0; + + while (!wait_ev.cmd) + nl_recvmsgs(state->nl_sock, cb); + + nl_cb_put(cb); + + return wait_ev.cmd; +} + +__u32 listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits) +{ + int ret; + + ret = __prepare_listen_events(state); + if (ret) + return ret; + + return __do_listen_events(state, n_waits, waits, NULL); +} + +static int print_events(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + struct print_event_args args; + int ret; + + memset(&args, 0, sizeof(args)); + + argc--; + argv++; + + while (argc > 0) { + if (strcmp(argv[0], "-f") == 0) + args.frame = true; + else if (strcmp(argv[0], "-t") == 0) + args.time = true; + else if (strcmp(argv[0], "-r") == 0) + args.reltime = true; + else + return 1; + argc--; + argv++; + } + + if (args.time && args.reltime) + return 1; + + if (argc) + return 1; + + ret = __prepare_listen_events(state); + if (ret) + return ret; + + return __do_listen_events(state, 0, NULL, &args); +} +TOPLEVEL(event, "[-t] [-r] [-f]", 0, 0, CIB_NONE, print_events, + "Monitor events from the kernel.\n" + "-t - print timestamp\n" + "-r - print relative timstamp\n" + "-f - print full frame for auth/assoc etc.");
diff --git a/iw_0.9.22/iw_0.9.22/genl.c b/iw_0.9.22/iw_0.9.22/genl.c new file mode 100644 index 0000000..af08676 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/genl.c
@@ -0,0 +1,117 @@ +/* + * This ought to be provided by libnl + */ + +#include <asm/errno.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> +#include <linux/genetlink.h> + +#include "iw.h" + +static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = arg; + *ret = err->error; + return NL_STOP; +} + +static int ack_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_STOP; +} + +struct handler_args { + const char *group; + int id; +}; + +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; +} + +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; +}
diff --git a/iw_0.9.22/iw_0.9.22/ibss.c b/iw_0.9.22/iw_0.9.22/ibss.c new file mode 100644 index 0000000..b70dee3 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/ibss.c
@@ -0,0 +1,146 @@ +#ifndef _POSIX_SOURCE +#define _POSIX_SOURCE +#endif +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(ibss); + +static int join_ibss(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *end; + unsigned char abssid[6]; + unsigned char rates[NL80211_MAX_SUPP_RATES]; + int n_rates = 0; + char *value = NULL, *sptr = NULL; + float rate; + int bintval; + + if (argc < 2) + return 1; + + /* SSID */ + NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]); + argv++; + argc--; + + /* freq */ + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, + strtoul(argv[0], &end, 10)); + if (*end != '\0') + return 1; + argv++; + argc--; + + if (argc && strcmp(argv[0], "fixed-freq") == 0) { + NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED); + argv++; + argc--; + } + + if (argc) { + if (mac_addr_a2n(abssid, argv[0]) == 0) { + NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid); + argv++; + argc--; + } + } + + if (argc > 1 && strcmp(argv[0], "beacon-interval") == 0) { + argv++; + argc--; + bintval = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, bintval); + argv++; + argc--; + } + + /* basic rates */ + if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) { + argv++; + argc--; + + value = strtok_r(argv[0], ",", &sptr); + + while (value && n_rates < NL80211_MAX_SUPP_RATES) { + rate = strtod(value, &end); + rates[n_rates] = rate * 2; + + /* filter out suspicious values */ + if (*end != '\0' || !rates[n_rates] || + rate*2 != rates[n_rates]) + return 1; + + n_rates++; + value = strtok_r(NULL, ",", &sptr); + } + + NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates); + + argv++; + argc--; + } + + /* multicast rate */ + if (argc > 1 && strcmp(argv[0], "mcast-rate") == 0) { + argv++; + argc--; + + rate = strtod(argv[0], &end); + if (*end != '\0') + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10)); + argv++; + argc--; + } + + if (!argc) + return 0; + + if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0) + return 1; + + argv++; + argc--; + + return parse_keys(msg, argv, argc); + nla_put_failure: + return -ENOSPC; +} + +static int leave_ibss(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + return 0; +} +COMMAND(ibss, leave, NULL, + NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss, + "Leave the current IBSS cell."); +COMMAND(ibss, join, + "<SSID> <freq in MHz> [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]" + " [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] " + "[key d:0:abcde]", + NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss, + "Join the IBSS cell with the given SSID, if it doesn't exist create\n" + "it on the given frequency. When fixed frequency is requested, don't\n" + "join/create a cell on a different frequency. When a fixed BSSID is\n" + "requested use that BSSID and do not adopt another cell's BSSID even\n" + "if it has higher TSF and the same SSID. If an IBSS is created, create\n" + "it with the specified basic-rates, multicast-rate and beacon-interval.");
diff --git a/iw_0.9.22/iw_0.9.22/info.c b/iw_0.9.22/iw_0.9.22/info.c new file mode 100644 index 0000000..559fd2a --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/info.c
@@ -0,0 +1,375 @@ +#include <stdbool.h> +#include <errno.h> +#include <net/if.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static void print_flag(const char *name, int *open) +{ + if (!*open) + printf(" ("); + else + printf(", "); + printf("%s", name); + *open = 1; +} + +static int print_phy_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; + + struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; + static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, + [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 }, + }; + + struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1]; + static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = { + [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 }, + [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG }, + }; + + struct nlattr *nl_band; + struct nlattr *nl_freq; + struct nlattr *nl_rate; + struct nlattr *nl_mode; + struct nlattr *nl_cmd; + struct nlattr *nl_if, *nl_ftype; + int bandidx = 1; + int rem_band, rem_freq, rem_rate, rem_mode, rem_cmd, rem_ftype, rem_if; + int open; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb_msg[NL80211_ATTR_WIPHY_BANDS]) + return NL_SKIP; + + if (tb_msg[NL80211_ATTR_WIPHY_NAME]) + printf("Wiphy %s\n", nla_get_string(tb_msg[NL80211_ATTR_WIPHY_NAME])); + + nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) { + printf("\tBand %d:\n", bandidx); + bandidx++; + + nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band), + nla_len(nl_band), NULL); + +#ifdef NL80211_BAND_ATTR_HT_CAPA + if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) { + __u16 cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]); + print_ht_capability(cap); + } + if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) { + __u8 exponent = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]); + print_ampdu_length(exponent); + } + if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) { + __u8 spacing = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]); + print_ampdu_spacing(spacing); + } + if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] && + nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]) == 16) + print_ht_mcs(nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET])); +#endif + + printf("\t\tFrequencies:\n"); + + nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) { + uint32_t freq; + nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq), + nla_len(nl_freq), freq_policy); + if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) + continue; + freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + printf("\t\t\t* %d MHz [%d]", freq, ieee80211_frequency_to_channel(freq)); + + if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] && + !tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) + printf(" (%.1f dBm)", 0.01 * nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])); + + open = 0; + if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) { + print_flag("disabled", &open); + goto next; + } + if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) + print_flag("passive scanning", &open); + if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS]) + print_flag("no IBSS", &open); + if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR]) + print_flag("radar detection", &open); + next: + if (open) + printf(")"); + printf("\n"); + } + + printf("\t\tBitrates (non-HT):\n"); + + nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) { + nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate), + nla_len(nl_rate), rate_policy); + if (!tb_rate[NL80211_BITRATE_ATTR_RATE]) + continue; + printf("\t\t\t* %2.1f Mbps", 0.1 * nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE])); + open = 0; + if (tb_rate[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE]) + print_flag("short preamble supported", &open); + if (open) + printf(")"); + printf("\n"); + } + } + + if (tb_msg[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) + printf("\tmax # scan SSIDs: %d\n", + nla_get_u8(tb_msg[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])); + if (tb_msg[NL80211_ATTR_MAX_SCAN_IE_LEN]) + printf("\tmax scan IEs length: %d bytes\n", + nla_get_u16(tb_msg[NL80211_ATTR_MAX_SCAN_IE_LEN])); + + if (tb_msg[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) { + unsigned int frag; + + frag = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]); + if (frag != (unsigned int)-1) + printf("\tFragmentation threshold: %d\n", frag); + } + + if (tb_msg[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) { + unsigned int rts; + + rts = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_RTS_THRESHOLD]); + if (rts != (unsigned int)-1) + printf("\tRTS threshold: %d\n", rts); + } + + if (tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { + unsigned char coverage; + + coverage = nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); + /* See handle_distance() for an explanation where the '450' comes from */ + printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage); + } + + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX] && + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX]) + printf("\tAvailable Antennas: TX %#x RX %#x\n", + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX]), + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX])); + + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] && + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) + printf("\tConfigured Antennas: TX %#x RX %#x\n", + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]), + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX])); + + if (tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES]) { + printf("\tSupported interface modes:\n"); + nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], rem_mode) + printf("\t\t * %s\n", iftype_name(nla_type(nl_mode))); + } + + if (tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES]) { + printf("\tsoftware interface modes (can always be added):\n"); + nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES], rem_mode) + printf("\t\t * %s\n", iftype_name(nla_type(nl_mode))); + } + + if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS]) { + struct nlattr *nl_combi; + int rem_combi; + bool have_combinations = false; + + nla_for_each_nested(nl_combi, tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], rem_combi) { + static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = { + [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED }, + [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 }, + [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG }, + [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 }, + }; + struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB]; + static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = { + [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED }, + [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 }, + }; + struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT]; + struct nlattr *nl_limit; + int err, rem_limit; + bool comma = false; + + if (!have_combinations) { + printf("\tvalid interface combinations:\n"); + have_combinations = true; + } + + printf("\t\t * "); + + err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB, + nl_combi, iface_combination_policy); + if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] || + !tb_comb[NL80211_IFACE_COMB_MAXNUM] || + !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) { + printf(" <failed to parse>\n"); + goto broken_combination; + } + + nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) { + bool ift_comma = false; + + err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT, + nl_limit, iface_limit_policy); + if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) { + printf("<failed to parse>\n"); + goto broken_combination; + } + + if (comma) + printf(", "); + comma = true; + printf("#{"); + + nla_for_each_nested(nl_mode, tb_limit[NL80211_IFACE_LIMIT_TYPES], rem_mode) { + printf("%s %s", ift_comma ? "," : "", + iftype_name(nla_type(nl_mode))); + ift_comma = true; + } + printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX])); + } + printf(",\n\t\t "); + + printf("total <= %d, #channels <= %d%s\n", + nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]), + nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]), + tb_comb[NL80211_IFACE_COMB_STA_AP_BI_MATCH] ? + ", STA/AP BI must match" : ""); +broken_combination: + ; + } + + if (!have_combinations) + printf("\tinterface combinations are not supported\n"); + } + + if (tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS]) { + printf("\tSupported commands:\n"); + nla_for_each_nested(nl_cmd, tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS], rem_cmd) + printf("\t\t * %s\n", command_name(nla_get_u32(nl_cmd))); + } + + if (tb_msg[NL80211_ATTR_TX_FRAME_TYPES]) { + printf("\tSupported TX frame types:\n"); + nla_for_each_nested(nl_if, tb_msg[NL80211_ATTR_TX_FRAME_TYPES], rem_if) { + bool printed = false; + nla_for_each_nested(nl_ftype, nl_if, rem_ftype) { + if (!printed) + printf("\t\t * %s:", iftype_name(nla_type(nl_if))); + printed = true; + printf(" 0x%.4x", nla_get_u16(nl_ftype)); + } + if (printed) + printf("\n"); + } + } + + if (tb_msg[NL80211_ATTR_RX_FRAME_TYPES]) { + printf("\tSupported RX frame types:\n"); + nla_for_each_nested(nl_if, tb_msg[NL80211_ATTR_RX_FRAME_TYPES], rem_if) { + bool printed = false; + nla_for_each_nested(nl_ftype, nl_if, rem_ftype) { + if (!printed) + printf("\t\t * %s:", iftype_name(nla_type(nl_if))); + printed = true; + printf(" 0x%.4x", nla_get_u16(nl_ftype)); + } + if (printed) + printf("\n"); + } + } + + if (tb_msg[NL80211_ATTR_SUPPORT_IBSS_RSN]) + printf("\tDevice supports RSN-IBSS.\n"); + + if (tb_msg[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]) { + struct nlattr *tb_wowlan[NUM_NL80211_WOWLAN_TRIG]; + static struct nla_policy wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { + [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { + .minlen = sizeof(struct nl80211_wowlan_pattern_support), + }, + [NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, + }; + struct nl80211_wowlan_pattern_support *pat; + int err; + + err = nla_parse_nested(tb_wowlan, MAX_NL80211_WOWLAN_TRIG, + tb_msg[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED], + wowlan_policy); + printf("\tWoWLAN support:"); + if (err) { + printf(" <failed to parse>\n"); + } else { + printf("\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_ANY]) + printf("\t\t * wake up on anything (device continues operating normally)\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_DISCONNECT]) + printf("\t\t * wake up on disconnect\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_MAGIC_PKT]) + printf("\t\t * wake up on magic packet\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { + pat = nla_data(tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]); + printf("\t\t * wake up on pattern match, up to %u patterns of %u-%u bytes\n", + pat->max_patterns, pat->min_pattern_len, pat->max_pattern_len); + } + if (tb_wowlan[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) + printf("\t\t * can do GTK rekeying\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) + printf("\t\t * wake up on GTK rekey failure\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) + printf("\t\t * wake up on EAP identity request\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) + printf("\t\t * wake up on 4-way handshake\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) + printf("\t\t * wake up on rfkill release\n"); + } + } + + return NL_SKIP; +} + +static int handle_info(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_phy_handler, NULL); + + return 0; +} +__COMMAND(NULL, info, "info", NULL, NL80211_CMD_GET_WIPHY, 0, 0, CIB_PHY, handle_info, + "Show capabilities for the specified wireless device.", NULL); +TOPLEVEL(list, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, + "List all wireless devices and their capabilities."); +TOPLEVEL(phy, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, NULL);
diff --git a/iw_0.9.22/iw_0.9.22/interface.c b/iw_0.9.22/iw_0.9.22/interface.c new file mode 100644 index 0000000..9ee39c8 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/interface.c
@@ -0,0 +1,416 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +#define VALID_FLAGS "none: no special flags\n"\ + "fcsfail: show frames with FCS errors\n"\ + "control: show control frames\n"\ + "otherbss: show frames from other BSSes\n"\ + "cook: use cooked mode" + +SECTION(interface); + +static char *mntr_flags[NL80211_MNTR_FLAG_MAX + 1] = { + "none", + "fcsfail", + "plcpfail", + "control", + "otherbss", + "cook", +}; + +static int parse_mntr_flags(int *_argc, char ***_argv, + struct nl_msg *msg) +{ + struct nl_msg *flags; + int err = -ENOBUFS; + enum nl80211_mntr_flags flag; + int argc = *_argc; + char **argv = *_argv; + + flags = nlmsg_alloc(); + if (!flags) + return -ENOMEM; + + while (argc) { + int ok = 0; + for (flag = __NL80211_MNTR_FLAG_INVALID; + flag <= NL80211_MNTR_FLAG_MAX; flag++) { + if (strcmp(*argv, mntr_flags[flag]) == 0) { + ok = 1; + /* + * This shouldn't be adding "flag" if that is + * zero, but due to a problem in the kernel's + * nl80211 code (using NLA_NESTED policy) it + * will reject an empty nested attribute but + * not one that contains an invalid attribute + */ + NLA_PUT_FLAG(flags, flag); + break; + } + } + if (!ok) { + err = -EINVAL; + goto out; + } + argc--; + argv++; + } + + nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags); + err = 0; + nla_put_failure: + out: + nlmsg_free(flags); + + *_argc = argc; + *_argv = argv; + + return err; +} + +/* for help */ +#define IFACE_TYPES "Valid interface types are: managed, ibss, monitor, mesh, wds." + +/* return 0 if ok, internal error otherwise */ +static int get_if_type(int *argc, char ***argv, enum nl80211_iftype *type, + bool need_type) +{ + char *tpstr; + + if (*argc < 1 + !!need_type) + return 1; + + if (need_type && strcmp((*argv)[0], "type")) + return 1; + + tpstr = (*argv)[!!need_type]; + *argc -= 1 + !!need_type; + *argv += 1 + !!need_type; + + if (strcmp(tpstr, "adhoc") == 0 || + strcmp(tpstr, "ibss") == 0) { + *type = NL80211_IFTYPE_ADHOC; + return 0; + } else if (strcmp(tpstr, "monitor") == 0) { + *type = NL80211_IFTYPE_MONITOR; + return 0; + } else if (strcmp(tpstr, "master") == 0 || + strcmp(tpstr, "ap") == 0) { + *type = NL80211_IFTYPE_UNSPECIFIED; + fprintf(stderr, "You need to run a management daemon, e.g. hostapd,\n"); + fprintf(stderr, "see http://wireless.kernel.org/en/users/Documentation/hostapd\n"); + fprintf(stderr, "for more information on how to do that.\n"); + return 2; + } else if (strcmp(tpstr, "__ap") == 0) { + *type = NL80211_IFTYPE_AP; + return 0; + } else if (strcmp(tpstr, "__ap_vlan") == 0) { + *type = NL80211_IFTYPE_AP_VLAN; + return 0; + } else if (strcmp(tpstr, "wds") == 0) { + *type = NL80211_IFTYPE_WDS; + return 0; + } else if (strcmp(tpstr, "managed") == 0 || + strcmp(tpstr, "mgd") == 0 || + strcmp(tpstr, "station") == 0) { + *type = NL80211_IFTYPE_STATION; + return 0; + } else if (strcmp(tpstr, "mp") == 0 || + strcmp(tpstr, "mesh") == 0) { + *type = NL80211_IFTYPE_MESH_POINT; + return 0; + } else if (strcmp(tpstr, "__p2pcl") == 0) { + *type = NL80211_IFTYPE_P2P_CLIENT; + return 0; + } else if (strcmp(tpstr, "__p2pgo") == 0) { + *type = NL80211_IFTYPE_P2P_GO; + return 0; + } + + fprintf(stderr, "invalid interface type %s\n", tpstr); + return 2; +} + +static int parse_4addr_flag(const char *value, struct nl_msg *msg) +{ + if (strcmp(value, "on") == 0) + NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, 1); + else if (strcmp(value, "off") == 0) + NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, 0); + else + return 1; + return 0; + +nla_put_failure: + return 1; +} + +static int handle_interface_add(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *name; + char *mesh_id = NULL; + enum nl80211_iftype type; + int tpset; + + if (argc < 1) + return 1; + + name = argv[0]; + argc--; + argv++; + + tpset = get_if_type(&argc, &argv, &type, true); + if (tpset) + return tpset; + + if (argc) { + if (strcmp(argv[0], "mesh_id") == 0) { + argc--; + argv++; + + if (!argc) + return 1; + mesh_id = argv[0]; + argc--; + argv++; + } else if (strcmp(argv[0], "4addr") == 0) { + argc--; + argv++; + if (parse_4addr_flag(argv[0], msg)) { + fprintf(stderr, "4addr error\n"); + return 2; + } + argc--; + argv++; + } else if (strcmp(argv[0], "flags") == 0) { + argc--; + argv++; + if (parse_mntr_flags(&argc, &argv, msg)) { + fprintf(stderr, "flags error\n"); + return 2; + } + } else { + return 1; + } + } + + if (argc) + return 1; + + NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, name); + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type); + if (mesh_id) + NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*]", + NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add, + "Add a new virtual interface with the given configuration.\n" + IFACE_TYPES "\n\n" + "The flags are only used for monitor interfaces, valid flags are:\n" + VALID_FLAGS "\n\n" + "The mesh_id is used only for mesh mode."); +COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*]", + NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add, NULL); + +static int handle_interface_del(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + return 0; +} +TOPLEVEL(del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del, + "Remove this virtual interface"); +HIDDEN(interface, del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del); + +static int print_iface_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + unsigned int *wiphy = arg; + const char *indent = ""; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (wiphy && tb_msg[NL80211_ATTR_WIPHY]) { + unsigned int thiswiphy = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]); + indent = "\t"; + if (*wiphy != thiswiphy) + printf("phy#%d\n", thiswiphy); + *wiphy = thiswiphy; + } + + if (tb_msg[NL80211_ATTR_IFNAME]) + printf("%sInterface %s\n", indent, nla_get_string(tb_msg[NL80211_ATTR_IFNAME])); + if (tb_msg[NL80211_ATTR_IFINDEX]) + printf("%s\tifindex %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX])); + if (tb_msg[NL80211_ATTR_IFTYPE]) + printf("%s\ttype %s\n", indent, iftype_name(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]))); + + return NL_SKIP; +} + +static int handle_interface_info(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, NULL); + return 0; +} +TOPLEVEL(info, NULL, NL80211_CMD_GET_INTERFACE, 0, CIB_NETDEV, handle_interface_info, + "Show information for this interface."); + +static int handle_interface_set(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + if (!argc) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR); + + switch (parse_mntr_flags(&argc, &argv, msg)) { + case 0: + return 0; + case -ENOMEM: + fprintf(stderr, "failed to allocate flags\n"); + return 2; + case -EINVAL: + fprintf(stderr, "unknown flag %s\n", *argv); + return 2; + default: + return 2; + } + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, monitor, "<flag>*", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_set, + "Set monitor flags. Valid flags are:\n" + VALID_FLAGS); + +static int handle_interface_meshid(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *mesh_id = NULL; + + if (argc != 1) + return 1; + + mesh_id = argv[0]; + + NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, meshid, "<meshid>", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_meshid, NULL); + +static unsigned int dev_dump_wiphy; + +static int handle_dev_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + dev_dump_wiphy = -1; + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, &dev_dump_wiphy); + return 0; +} +TOPLEVEL(dev, NULL, NL80211_CMD_GET_INTERFACE, NLM_F_DUMP, CIB_NONE, handle_dev_dump, + "List all network interfaces for wireless hardware."); + +static int handle_interface_type(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + enum nl80211_iftype type; + int tpset; + + tpset = get_if_type(&argc, &argv, &type, false); + if (tpset) + return tpset; + + if (argc) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, type, "<type>", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_type, + "Set interface type/mode.\n" + IFACE_TYPES); + +static int handle_interface_4addr(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + if (argc != 1) + return 1; + return parse_4addr_flag(argv[0], msg); +} +COMMAND(set, 4addr, "<on|off>", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_4addr, + "Set interface 4addr (WDS) mode."); + +static int handle_interface_wds_peer(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "Invalid MAC address\n"); + return 2; + } + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, peer, "<MAC address>", + NL80211_CMD_SET_WDS_PEER, 0, CIB_NETDEV, handle_interface_wds_peer, + "Set interface WDS peer.");
diff --git a/iw_0.9.22/iw_0.9.22/iw.8 b/iw_0.9.22/iw_0.9.22/iw.8 new file mode 100644 index 0000000..866260f --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/iw.8
@@ -0,0 +1,67 @@ +.TH IW 8 "16 September 2008" "iw" "Linux" +.SH NAME +iw \- show / manipulate wireless devices and their configuration +.SH SYNOPSIS + +.ad l +.in +8 +.ti -8 +.B iw +.RI [ " OPTIONS " ] " " { " +.BR help " |" +.RI ""OBJECT " " COMMAND " }" +.sp + +.ti -8 +.IR OBJECT " := { " +.BR dev " | " phy " | " reg " }" +.sp + +.ti -8 +.IR OPTIONS " := { --version | --debug }" + +.SH OPTIONS + +.TP +.BR " --version" +print version information and exit. + +.TP +.BR " --debug" +enable netlink message debugging. + +.SH IW - COMMAND SYNTAX + +.SS +.I OBJECT + +.TP +.B dev <interface name> +- network interface. + +.TP +.B phy <phy name> +- wireless hardware device (by name). +.TP +.B phy#<phy index> +- wireless hardware device (by index). + +.TP +.B reg +- regulatory agent. + +.SS +.I COMMAND + +Specifies the action to perform on the object. +The set of possible actions depends on the object type. +.B iw help +will print all supported commands. + +.SH SEE ALSO +.BR ip (8), +.BR crda (8), +.BR regdbdump (8), +.BR regulatory.bin (5) + +.BR http://wireless.kernel.org/en/users/Documentation/iw
diff --git a/iw_0.9.22/iw_0.9.22/iw.c b/iw_0.9.22/iw_0.9.22/iw.c new file mode 100644 index 0000000..50c3a42 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/iw.c
@@ -0,0 +1,507 @@ +/* + * nl80211 userspace tool + * + * Copyright 2007, 2008 Johannes Berg <johannes@sipsolutions.net> + */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <net/if.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +#ifndef CONFIG_LIBNL20 +/* libnl 2.0 compatibility code */ + +static inline struct nl_handle *nl_socket_alloc(void) +{ + return nl_handle_alloc(); +} + +static inline void nl_socket_free(struct nl_sock *h) +{ + nl_handle_destroy(h); +} + +static inline int __genl_ctrl_alloc_cache(struct nl_sock *h, struct nl_cache **cache) +{ + struct nl_cache *tmp = genl_ctrl_alloc_cache(h); + if (!tmp) + return -ENOMEM; + *cache = tmp; + return 0; +} +#define genl_ctrl_alloc_cache __genl_ctrl_alloc_cache +#endif /* CONFIG_LIBNL20 */ + +int iw_debug = 0; + +static int nl80211_init(struct nl80211_state *state) +{ + int err; + + state->nl_sock = nl_socket_alloc(); + if (!state->nl_sock) { + fprintf(stderr, "Failed to allocate netlink socket.\n"); + return -ENOMEM; + } + + if (genl_connect(state->nl_sock)) { + fprintf(stderr, "Failed to connect to generic netlink.\n"); + err = -ENOLINK; + goto out_handle_destroy; + } + + if (genl_ctrl_alloc_cache(state->nl_sock, &state->nl_cache)) { + fprintf(stderr, "Failed to allocate generic netlink cache.\n"); + err = -ENOMEM; + goto out_handle_destroy; + } + + state->nl80211 = genl_ctrl_search_by_name(state->nl_cache, "nl80211"); + if (!state->nl80211) { + fprintf(stderr, "nl80211 not found.\n"); + err = -ENOENT; + goto out_cache_free; + } + + return 0; + + out_cache_free: + nl_cache_free(state->nl_cache); + out_handle_destroy: + nl_socket_free(state->nl_sock); + return err; +} + +static void nl80211_cleanup(struct nl80211_state *state) +{ + genl_family_put(state->nl80211); + nl_cache_free(state->nl_cache); + nl_socket_free(state->nl_sock); +} + +static int cmd_size; + +extern struct cmd __start___cmd; +extern struct cmd __stop___cmd; + +#define for_each_cmd(_cmd) \ + for (_cmd = &__start___cmd; _cmd < &__stop___cmd; \ + _cmd = (const struct cmd *)((char *)_cmd + cmd_size)) + + +static void __usage_cmd(const struct cmd *cmd, char *indent, bool full) +{ + const char *start, *lend, *end; + + printf("%s", indent); + + switch (cmd->idby) { + case CIB_NONE: + break; + case CIB_PHY: + printf("phy <phyname> "); + break; + case CIB_NETDEV: + printf("dev <devname> "); + break; + } + if (cmd->parent && cmd->parent->name) + printf("%s ", cmd->parent->name); + printf("%s", cmd->name); + if (cmd->args) + printf(" %s", cmd->args); + printf("\n"); + + if (!full || !cmd->help) + return; + + /* hack */ + if (strlen(indent)) + indent = "\t\t"; + else + printf("\n"); + + /* print line by line */ + start = cmd->help; + end = strchr(start, '\0'); + do { + lend = strchr(start, '\n'); + if (!lend) + lend = end; + printf("%s", indent); + printf("%.*s\n", (int)(lend - start), start); + start = lend + 1; + } while (end != lend); + + printf("\n"); +} + +static void usage_options(void) +{ + printf("Options:\n"); + printf("\t--debug\t\tenable netlink debugging\n"); +} + +static const char *argv0; + +static void usage(bool full) +{ + const struct cmd *section, *cmd; + + printf("Usage:\t%s [options] command\n", argv0); + usage_options(); + printf("\t--version\tshow version (%s)\n", iw_version); + printf("Commands:\n"); + for_each_cmd(section) { + if (section->parent) + continue; + + if (section->handler && !section->hidden) + __usage_cmd(section, "\t", full); + + for_each_cmd(cmd) { + if (section != cmd->parent) + continue; + if (!cmd->handler || cmd->hidden) + continue; + __usage_cmd(cmd, "\t", full); + } + } + printf("\nYou can omit the 'phy' or 'dev' if " + "the identification is unique,\n" + "e.g. \"iw wlan0 info\" or \"iw phy0 info\". " + "(Don't when scripting.)\n\n" + "Do NOT screenscrape this tool, we don't " + "consider its output stable.\n\n"); +} + +static int print_help(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + exit(3); +} +TOPLEVEL(help, NULL, 0, 0, CIB_NONE, print_help, + "Print usage for each command."); + +static void usage_cmd(const struct cmd *cmd) +{ + printf("Usage:\t%s [options] ", argv0); + __usage_cmd(cmd, "", true); + usage_options(); +} + +static void version(void) +{ + printf("iw version %s\n", iw_version); +} + +static int phy_lookup(char *name) +{ + char buf[200]; + int fd, pos; + + snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", name); + + fd = open(buf, O_RDONLY); + if (fd < 0) + return -1; + pos = read(fd, buf, sizeof(buf) - 1); + if (pos < 0) { + close(fd); + return -1; + } + buf[pos] = '\0'; + close(fd); + return atoi(buf); +} + +static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = arg; + *ret = err->error; + return NL_STOP; +} + +static int finish_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_SKIP; +} + +static int ack_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_STOP; +} + +static int __handle_cmd(struct nl80211_state *state, enum id_input idby, + int argc, char **argv, const struct cmd **cmdout) +{ + const struct cmd *cmd, *match = NULL, *sectcmd; + struct nl_cb *cb; + struct nl_cb *s_cb; + struct nl_msg *msg; + int devidx = 0; + int err, o_argc; + const char *command, *section; + char *tmp, **o_argv; + enum command_identify_by command_idby = CIB_NONE; + + if (argc <= 1 && idby != II_NONE) + return 1; + + o_argc = argc; + o_argv = argv; + + switch (idby) { + case II_PHY_IDX: + command_idby = CIB_PHY; + devidx = strtoul(*argv + 4, &tmp, 0); + if (*tmp != '\0') + return 1; + argc--; + argv++; + break; + case II_PHY_NAME: + command_idby = CIB_PHY; + devidx = phy_lookup(*argv); + argc--; + argv++; + break; + case II_NETDEV: + command_idby = CIB_NETDEV; + devidx = if_nametoindex(*argv); + if (devidx == 0) + devidx = -1; + argc--; + argv++; + break; + default: + break; + } + + if (devidx < 0) + return -errno; + + section = *argv; + argc--; + argv++; + + for_each_cmd(sectcmd) { + if (sectcmd->parent) + continue; + /* ok ... bit of a hack for the dupe 'info' section */ + if (match && sectcmd->idby != command_idby) + continue; + if (strcmp(sectcmd->name, section) == 0) + match = sectcmd; + } + + sectcmd = match; + match = NULL; + if (!sectcmd) + return 1; + + if (argc > 0) { + command = *argv; + + for_each_cmd(cmd) { + if (!cmd->handler) + continue; + if (cmd->parent != sectcmd) + continue; + if (cmd->idby != command_idby) + continue; + if (strcmp(cmd->name, command)) + continue; + if (argc > 1 && !cmd->args) + continue; + match = cmd; + break; + } + + if (match) { + argc--; + argv++; + } + } + + if (match) + cmd = match; + else { + /* Use the section itself, if possible. */ + cmd = sectcmd; + if (argc && !cmd->args) + return 1; + if (cmd->idby != command_idby) + return 1; + if (!cmd->handler) + return 1; + } + + if (cmd->selector) { + cmd = cmd->selector(argc, argv); + if (!cmd) + return 1; + } + + if (cmdout) + *cmdout = cmd; + + if (!cmd->cmd) { + argc = o_argc; + argv = o_argv; + return cmd->handler(state, NULL, NULL, argc, argv); + } + + msg = nlmsg_alloc(); + if (!msg) { + fprintf(stderr, "failed to allocate netlink message\n"); + return 2; + } + + cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); + s_cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); + if (!cb || !s_cb) { + fprintf(stderr, "failed to allocate netlink callbacks\n"); + err = 2; + goto out_free_msg; + } + + genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0, + cmd->nl_msg_flags, cmd->cmd, 0); + + switch (command_idby) { + case CIB_PHY: + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx); + break; + case CIB_NETDEV: + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); + break; + default: + break; + } + + err = cmd->handler(state, cb, msg, argc, argv); + if (err) + goto out; + + nl_socket_set_cb(state->nl_sock, s_cb); + + err = nl_send_auto_complete(state->nl_sock, msg); + if (err < 0) + goto out; + + err = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); + + while (err > 0) + nl_recvmsgs(state->nl_sock, cb); + out: + nl_cb_put(cb); + out_free_msg: + nlmsg_free(msg); + return err; + nla_put_failure: + fprintf(stderr, "building message failed\n"); + return 2; +} + +int handle_cmd(struct nl80211_state *state, enum id_input idby, + int argc, char **argv) +{ + return __handle_cmd(state, idby, argc, argv, NULL); +} + +int main(int argc, char **argv) +{ + struct nl80211_state nlstate; + int err; + const struct cmd *cmd = NULL; + + /* calculate command size including padding */ + cmd_size = abs((long)&__section_set - (long)&__section_get); + /* strip off self */ + argc--; + argv0 = *argv++; + + if (argc > 0 && strcmp(*argv, "--debug") == 0) { + iw_debug = 1; + argc--; + argv++; + } + + if (argc > 0 && strcmp(*argv, "--version") == 0) { + version(); + return 0; + } + + /* need to treat "help" command specially so it works w/o nl80211 */ + if (argc == 0 || strcmp(*argv, "help") == 0) { + usage(argc != 0); + return 0; + } + + err = nl80211_init(&nlstate); + if (err) + return 1; + + if (strcmp(*argv, "dev") == 0 && argc > 1) { + argc--; + argv++; + err = __handle_cmd(&nlstate, II_NETDEV, argc, argv, &cmd); + } else if (strncmp(*argv, "phy", 3) == 0 && argc > 1) { + if (strlen(*argv) == 3) { + argc--; + argv++; + err = __handle_cmd(&nlstate, II_PHY_NAME, argc, argv, &cmd); + } else if (*(*argv + 3) == '#') + err = __handle_cmd(&nlstate, II_PHY_IDX, argc, argv, &cmd); + else + goto detect; + } else { + int idx; + enum id_input idby = II_NONE; + detect: + if ((idx = if_nametoindex(argv[0])) != 0) + idby = II_NETDEV; + else if ((idx = phy_lookup(argv[0])) >= 0) + idby = II_PHY_NAME; + err = __handle_cmd(&nlstate, idby, argc, argv, &cmd); + } + + if (err == 1) { + if (cmd) + usage_cmd(cmd); + else + usage(false); + } else if (err < 0) + fprintf(stderr, "command failed: %s (%d)\n", strerror(-err), err); + + nl80211_cleanup(&nlstate); + + return err; +}
diff --git a/iw_0.9.22/iw_0.9.22/iw.h b/iw_0.9.22/iw_0.9.22/iw.h new file mode 100644 index 0000000..616fa04 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/iw.h
@@ -0,0 +1,170 @@ +#ifndef __IW_H +#define __IW_H + +#include <stdbool.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> + +#include "nl80211.h" + +#define ETH_ALEN 6 + +#ifndef CONFIG_LIBNL20 +# define nl_sock nl_handle +#endif + +struct nl80211_state { + struct nl_sock *nl_sock; + struct nl_cache *nl_cache; + struct genl_family *nl80211; +}; + +enum command_identify_by { + CIB_NONE, + CIB_PHY, + CIB_NETDEV, +}; + +enum id_input { + II_NONE, + II_NETDEV, + II_PHY_NAME, + II_PHY_IDX, +}; + +struct cmd { + const char *name; + const char *args; + const char *help; + const enum nl80211_commands cmd; + int nl_msg_flags; + int hidden; + const enum command_identify_by idby; + /* + * The handler should return a negative error code, + * zero on success, 1 if the arguments were wrong + * and the usage message should and 2 otherwise. + */ + int (*handler)(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv); + const struct cmd *(*selector)(int argc, char **argv); + const struct cmd *parent; +}; + +#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof(ar[0])) +#define DIV_ROUND_UP(x, y) (((x) + (y - 1)) / (y)) + +#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel)\ + static struct cmd \ + __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\ + __attribute__((used)) __attribute__((section("__cmd"))) = { \ + .name = (_name), \ + .args = (_args), \ + .cmd = (_nlcmd), \ + .nl_msg_flags = (_flags), \ + .hidden = (_hidden), \ + .idby = (_idby), \ + .handler = (_handler), \ + .help = (_help), \ + .parent = _section, \ + .selector = (_sel), \ + } +#define __ACMD(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel, _alias)\ + __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel);\ + static const struct cmd *_alias = &__cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden +#define COMMAND(section, name, args, cmd, flags, idby, handler, help) \ + __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help, NULL) +#define COMMAND_ALIAS(section, name, args, cmd, flags, idby, handler, help, selector, alias)\ + __ACMD(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help, selector, alias) +#define HIDDEN(section, name, args, cmd, flags, idby, handler) \ + __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 1, idby, handler, NULL, NULL) + +#define TOPLEVEL(_name, _args, _nlcmd, _flags, _idby, _handler, _help) \ + struct cmd \ + __section ## _ ## _name \ + __attribute__((used)) __attribute__((section("__cmd"))) = { \ + .name = (#_name), \ + .args = (_args), \ + .cmd = (_nlcmd), \ + .nl_msg_flags = (_flags), \ + .idby = (_idby), \ + .handler = (_handler), \ + .help = (_help), \ + } +#define SECTION(_name) \ + struct cmd __section ## _ ## _name \ + __attribute__((used)) __attribute__((section("__cmd"))) = { \ + .name = (#_name), \ + .hidden = 1, \ + } + +#define DECLARE_SECTION(_name) \ + extern struct cmd __section ## _ ## _name; + +extern const char iw_version[]; + +extern int iw_debug; + +int handle_cmd(struct nl80211_state *state, enum id_input idby, + int argc, char **argv); + +struct print_event_args { + struct timeval ts; /* internal */ + bool have_ts; /* must be set false */ + bool frame, time, reltime; +}; + +__u32 listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits); +int __prepare_listen_events(struct nl80211_state *state); +__u32 __do_listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits, + struct print_event_args *args); + + +int mac_addr_a2n(unsigned char *mac_addr, char *arg); +void mac_addr_n2a(char *mac_addr, unsigned char *arg); +int parse_hex_mask(char *hexmask, unsigned char **result, size_t *result_len, + unsigned char **mask); +unsigned char *parse_hex(char *hex, size_t *outlen); + +int parse_keys(struct nl_msg *msg, char **argv, int argc); + +void print_ht_mcs(const __u8 *mcs); +void print_ampdu_length(__u8 exponent); +void print_ampdu_spacing(__u8 spacing); +void print_ht_capability(__u16 cap); + +const char *iftype_name(enum nl80211_iftype iftype); +const char *command_name(enum nl80211_commands cmd); +int ieee80211_channel_to_frequency(int chan); +int ieee80211_frequency_to_channel(int freq); + +void print_ssid_escaped(const uint8_t len, const uint8_t *data); + +int nl_get_multicast_id(struct nl_sock *sock, const char *family, const char *group); + +char *reg_initiator_to_string(__u8 initiator); + +const char *get_reason_str(uint16_t reason); +const char *get_status_str(uint16_t status); + +enum print_ie_type { + PRINT_SCAN, + PRINT_LINK, +}; + +#define BIT(x) (1ULL<<(x)) + +void print_ies(unsigned char *ie, int ielen, bool unknown, + enum print_ie_type ptype); + + +DECLARE_SECTION(set); +DECLARE_SECTION(get); + +#endif /* __IW_H */
diff --git a/iw_0.9.22/iw_0.9.22/keepalive.c b/iw_0.9.22/iw_0.9.22/keepalive.c new file mode 100644 index 0000000..9b0d73c --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/keepalive.c
@@ -0,0 +1,287 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; + +#define CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH 64 + +struct cfg80211_keepalive_request { + u32 interval; + u8 cmd; /* 0: ADD; 1: DEL: 2: START; 3: STOP */ + u8 index; + u8 trig; + u8 dst_macaddr[ETH_ALEN]; + u8 payload_len; + u8 payload[CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH]; +}; + +struct cfg80211_keepalive_request keepalive_req; + +SECTION(keepalive); + +static void keepalive_hex_dump(char *title, u8 *buf, size_t len) +{ + int i; + + printf("%s - hexdump(len=%lu):", title, (unsigned long) len); + + for (i = 0; i < len; i++) + printf(" %02x", buf[i]); + printf("\n"); +} + +static int nl80211_parse_klv_req(const char *s) +{ + long i; + char *endp; + + i = strtol(s, &endp, 10); + + if(endp == s) + return -1; + return i; +} + +static int nl80211_str2hex(u8 *src, u8 *dst, int src_len) +{ + int i, bytecount=0; + + if (src_len & 0x01) + return -2; + + for (i=0; i<src_len; i++, src++) { + if (i != 0 && i%2 == 0) { + dst++; + bytecount++; + } else { + *dst <<= 4; + } + + if ((*src >= '0') && (*src <= '9')) + *dst += *src - '0'; + else if ((*src >= 'A') && (*src <= 'F')) + *dst += *src - 'A' + 10; + else if ((*src >= 'a') && (*src <= 'f')) + *dst += *src - 'a' + 10; + else { + return -1; + } + } + + bytecount++; + + return bytecount; +} + +static int build_klv_req(struct nl_msg *msg, int klv_cmd, u8 index, int interval, u8 trig, u8 *dst_macaddr, u8 payload_len, u8 *payload) +{ + int ret = -1; + + if (!msg) + return -1; + + NLA_PUT_U32(msg, NL80211_ATTR_KLV_TYPE, klv_cmd); + NLA_PUT_U32(msg, NL80211_ATTR_KLV_INDEX, index); + + if (klv_cmd == 0 || klv_cmd == 1) { + + NLA_PUT_U32(msg, NL80211_ATTR_KLV_INTVL, interval); + NLA_PUT_U32 (msg, NL80211_ATTR_KLV_TRIG, trig); + + if (payload != NULL) { + if (dst_macaddr) { + keepalive_hex_dump("nl80211 klv_dstmac: ", dst_macaddr, ETH_ALEN); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst_macaddr); + } + + keepalive_hex_dump("nl80211 klv_payload: ", payload, payload_len); + NLA_PUT(msg, NL80211_ATTR_KLV_PAYLOAD, payload_len, payload); + } + } + + ret = 0; + + nla_put_failure: + return ret; +} + +static int nl80211_change_klv_req(char **cmdptr, int cmdtype, struct nl_msg *msg) +{ + u8 index = 1, trig_type = 1, payload_len = 0; + u8 dst_macaddr[ETH_ALEN]; + u32 interval_ms = 10; + u8 *payload=NULL; + int val; + u8 dst_payload[64]; + + switch(cmdtype) { + case 0: /* KLV-ADD */ + val = nl80211_parse_klv_req(*cmdptr++); + /* valid index # is [1, 3]. Index #0 is reserved for driver internal use */ + if (val <= 0 || val > 3) { + printf("invalid index (%d)\n", val); + return -1; + } + index = val; + + val = nl80211_parse_klv_req(*cmdptr++); + /* limit klv interval to [10 ms, 50000 ms] */ + if (val < 1000 || val > 55000) { + printf("Keeplalive interval is out of range.\n"); + return -1; + } + interval_ms = val; + + val = nl80211_parse_klv_req(*cmdptr++); + /* valid trig type is limited to 0 or 1 */ + if (val < 0 || val > 1) { + printf("Invalid keepalive trigger type.\n"); + return -1; + } + trig_type = val; + + memset(dst_macaddr, 0, ETH_ALEN); + if (nl80211_str2hex((u8 *)(*cmdptr++), dst_macaddr, 2*ETH_ALEN) <= 0) { + printf("Invalid mac address\n"); + return -1; + } + + val = strlen(*cmdptr); /* klv payload length must be <= 64 bytes */ + if (val > 128) { + printf("Payload is too long\n"); + return -1; + } + + memset(dst_payload, 0, 64); + if ((payload_len=nl80211_str2hex((u8 *)(*cmdptr), dst_payload, val)) < 0) { + printf("Keepalive payload is invalid\n"); + return -1; + } + + break; + + case 1: /* KLV-DEL */ + index = nl80211_parse_klv_req(cmdptr[0]); + printf("index = %d\n", index); + /* index #0 is reserved for driver internal klv type */ + if (index <= 0 || index > 3) { + return -1; + } + + interval_ms = 10000; + break; + + case 2: /* KLV-START */ + case 3: /* KLV-STOP */ + break; + + case 4: /* KLV-SHOW */ + printf("Not supported\n"); + val = 0; + return val; + + default: + return -1; + } + + val = build_klv_req(msg, cmdtype, index, interval_ms, trig_type, &dst_macaddr[0], payload_len, dst_payload); + + return val; +} + +static int handle_keepalive_add(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + int ret; + + if (argc != 5) { + printf("Command parameters incorrect.\n"); + return -1; + } + + ret = nl80211_change_klv_req(argv, 0, msg); + printf("ret is %d\n", ret); + return ret; +} + +static int handle_keepalive_delete(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + int ret; + + if (argc != 1) { + printf("Command parameters incorrect.\n"); + return -1; + } + + ret = nl80211_change_klv_req(argv, 1, msg); + return ret; +} + +static int handle_keepalive_start(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + int ret; + ret = nl80211_change_klv_req(argv, 2, msg); + return ret; +} + +static int handle_keepalive_stop(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + int ret; + ret = nl80211_change_klv_req(argv, 3, msg); + return ret; +} + +static int print_keepalive_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + if (arg != NULL) + *ret = 0; + return 0; +} + +static int handle_keepalive_show(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + int ret; + + printf("handle_keepalive_show\n"); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_keepalive_handler, &ret); + + return 0; +} + +COMMAND(keepalive, add, "<index> <interval> <trigger_type> <dst_macaddr> <payload>", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_add, + "Configure keep alive feature"); + +COMMAND(keepalive, del, "<index>", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_delete, + "Configure keep alive feature"); + +COMMAND(keepalive, start, "", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_start, + "Configure keep alive feature"); + +COMMAND(keepalive, stop, "", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_stop, + "Configure keep alive feature"); + +COMMAND(keepalive, show, "", NL80211_CMD_GET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_show, + "Show keepalive status.");
diff --git a/iw_0.9.22/iw_0.9.22/link.c b/iw_0.9.22/iw_0.9.22/link.c new file mode 100644 index 0000000..11ee0aa --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/link.c
@@ -0,0 +1,294 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +struct link_result { + uint8_t bssid[8]; + bool link_found; + bool anything_found; +}; + +static struct link_result lr = { .link_found = false }; + +static int link_bss_handler(struct nl_msg *msg, void *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 }, + }; + struct link_result *result = arg; + char mac_addr[20], dev[20]; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_BSS]) { + fprintf(stderr, "bss info missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(bss, NL80211_BSS_MAX, + tb[NL80211_ATTR_BSS], + bss_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (!bss[NL80211_BSS_BSSID]) + return NL_SKIP; + + if (!bss[NL80211_BSS_STATUS]) + return NL_SKIP; + + mac_addr_n2a(mac_addr, nla_data(bss[NL80211_BSS_BSSID])); + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + + switch (nla_get_u32(bss[NL80211_BSS_STATUS])) { + case NL80211_BSS_STATUS_ASSOCIATED: + printf("Connected to %s (on %s)\n", mac_addr, dev); + break; + case NL80211_BSS_STATUS_AUTHENTICATED: + printf("Authenticated with %s (on %s)\n", mac_addr, dev); + return NL_SKIP; + case NL80211_BSS_STATUS_IBSS_JOINED: + printf("Joined IBSS %s (on %s)\n", mac_addr, dev); + break; + default: + return NL_SKIP; + } + + result->anything_found = true; + + if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) + print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + false, PRINT_LINK); + + if (bss[NL80211_BSS_FREQUENCY]) + printf("\tfreq: %d\n", + nla_get_u32(bss[NL80211_BSS_FREQUENCY])); + + if (nla_get_u32(bss[NL80211_BSS_STATUS]) != NL80211_BSS_STATUS_ASSOCIATED) + return NL_SKIP; + + /* only in the assoc case do we want more info from station get */ + result->link_found = true; + memcpy(result->bssid, nla_data(bss[NL80211_BSS_BSSID]), 6); + return NL_SKIP; +} + +static int handle_scan_for_link(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + if (argc > 0) + return 1; + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, link_bss_handler, &lr); + return 0; +} + +static int print_link_sta(struct nl_msg *msg, void *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 *rinfo[NL80211_RATE_INFO_MAX + 1]; + struct nlattr *binfo[NL80211_STA_BSS_PARAM_MAX + 1]; + static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { + [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_TX_BITRATE] = { .type = NLA_NESTED }, + [NL80211_STA_INFO_LLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 }, + }; + + static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { + [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 }, + [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 }, + [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG }, + [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, + }; + 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]) { + fprintf(stderr, "sta stats missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, + tb[NL80211_ATTR_STA_INFO], + stats_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (sinfo[NL80211_STA_INFO_RX_BYTES] && sinfo[NL80211_STA_INFO_RX_PACKETS]) + printf("\tRX: %u bytes (%u packets)\n", + nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]), + nla_get_u32(sinfo[NL80211_STA_INFO_RX_PACKETS])); + if (sinfo[NL80211_STA_INFO_TX_BYTES] && sinfo[NL80211_STA_INFO_TX_PACKETS]) + printf("\tTX: %u bytes (%u packets)\n", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]), + nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS])); + if (sinfo[NL80211_STA_INFO_SIGNAL]) + printf("\tsignal: %d dBm\n", + (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL])); + + if (sinfo[NL80211_STA_INFO_TX_BITRATE]) { + if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, + sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) { + fprintf(stderr, "failed to parse nested rate attributes!\n"); + } else { + printf("\ttx bitrate: "); + if (rinfo[NL80211_RATE_INFO_BITRATE]) { + int rate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); + printf("%d.%d MBit/s", rate / 10, rate % 10); + } + + if (rinfo[NL80211_RATE_INFO_MCS]) + printf(" MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_MCS])); + if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) + printf(" 40Mhz"); + if (rinfo[NL80211_RATE_INFO_SHORT_GI]) + printf(" short GI"); + printf("\n"); + } + } + + 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)) { + fprintf(stderr, "failed to parse nested bss parameters!\n"); + } else { + char *delim = ""; + printf("\n\tbss flags:\t"); + if (binfo[NL80211_STA_BSS_PARAM_CTS_PROT]) { + printf("CTS-protection"); + delim = " "; + } + if (binfo[NL80211_STA_BSS_PARAM_SHORT_PREAMBLE]) { + printf("%sshort-preamble", delim); + delim = " "; + } + if (binfo[NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME]) + printf("%sshort-slot-time", delim); + printf("\n\tdtim period:\t%d", + nla_get_u8(binfo[NL80211_STA_BSS_PARAM_DTIM_PERIOD])); + printf("\n\tbeacon int:\t%d", + nla_get_u16(binfo[NL80211_STA_BSS_PARAM_BEACON_INTERVAL])); + printf("\n"); + } + } + + return NL_SKIP; +} + +static int handle_link_sta(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_link_sta, NULL); + + return 0; + nla_put_failure: + return -ENOBUFS; +} + +static int handle_link(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *link_argv[] = { + NULL, + "link", + "get_bss", + NULL, + }; + char *station_argv[] = { + NULL, + "link", + "get_sta", + NULL, + NULL, + }; + char bssid_buf[3*6]; + int err; + + link_argv[0] = argv[0]; + err = handle_cmd(state, II_NETDEV, 3, link_argv); + if (err) + return err; + + if (!lr.link_found) { + if (!lr.anything_found) + printf("Not connected.\n"); + return 0; + } + + mac_addr_n2a(bssid_buf, lr.bssid); + bssid_buf[17] = '\0'; + + station_argv[0] = argv[0]; + station_argv[3] = bssid_buf; + return handle_cmd(state, II_NETDEV, 4, station_argv); +} +TOPLEVEL(link, NULL, 0, 0, CIB_NETDEV, handle_link, + "Print information about the current link, if any."); +HIDDEN(link, get_sta, "", NL80211_CMD_GET_STATION, 0, + CIB_NETDEV, handle_link_sta); +HIDDEN(link, get_bss, NULL, NL80211_CMD_GET_SCAN, NLM_F_DUMP, + CIB_NETDEV, handle_scan_for_link);
diff --git a/iw_0.9.22/iw_0.9.22/mesh.c b/iw_0.9.22/iw_0.9.22/mesh.c new file mode 100644 index 0000000..7c6ab3d --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/mesh.c
@@ -0,0 +1,367 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(mesh); + + +typedef struct _any_t { + union { + uint32_t as_32; + uint16_t as_16; + uint8_t as_8; + } u; +} _any; + +/* describes a mesh parameter */ +struct mesh_param_descr { + const char *name; + enum nl80211_meshconf_params mesh_param_num; + int (*nla_put_fn)(struct nl_msg*, int, _any*); + uint32_t (*parse_fn)(const char*, _any*); + void (*nla_print_fn)(struct nlattr *); +}; + +/* utility functions for manipulating and printing u8/u16/u32 values and + * timesouts. */ +static int _my_nla_put_u8(struct nl_msg *n, int mesh_param_num, _any *value) +{ + return nla_put(n, mesh_param_num, sizeof(uint8_t), &value->u.as_8); +} + +static int _my_nla_put_u16(struct nl_msg *n, int mesh_param_num, _any *value) +{ + return nla_put(n, mesh_param_num, sizeof(uint16_t), &value->u.as_16); +} + +static int _my_nla_put_u32(struct nl_msg *n, int mesh_param_num, _any *value) +{ + return nla_put(n, mesh_param_num, sizeof(uint32_t), &value->u.as_32); +} + +static uint32_t _parse_u8(const char *str, _any *ret) +{ + char *endptr = NULL; + unsigned long int v = strtoul(str, &endptr, 10); + if (*endptr != '\0') + return 0xff; + if (v > 0xff) + return 0xff; + ret->u.as_8 = (uint8_t)v; + return 0; +} + +static uint32_t _parse_u8_as_bool(const char *str, _any *ret) +{ + char *endptr = NULL; + unsigned long int v = strtoul(str, &endptr, 10); + if (*endptr != '\0') + return 0x1; + if (v > 0x1) + return 0x1; + ret->u.as_8 = (uint8_t)v; + return 0; +} + +static uint32_t _parse_u16(const char *str, _any *ret) +{ + char *endptr = NULL; + long int v = strtol(str, &endptr, 10); + if (*endptr != '\0') + return 0xffff; + if ((v < 0) || (v > 0xffff)) + return 0xffff; + ret->u.as_16 = (uint16_t)v; + return 0; +} + +static uint32_t _parse_u32(const char *str, _any *ret) +{ + char *endptr = NULL; + long long int v = strtoll(str, &endptr, 10); + if (*endptr != '\0') + return 0xffffffff; + if ((v < 0) || (v > 0xffffffff)) + return 0xffffffff; + ret->u.as_32 = (uint32_t)v; + return 0; +} + +static void _print_u8(struct nlattr *a) +{ + printf("%d", nla_get_u8(a)); +} + +static void _print_u16(struct nlattr *a) +{ + printf("%d", nla_get_u16(a)); +} + +static void _print_u16_timeout(struct nlattr *a) +{ + printf("%d milliseconds", nla_get_u16(a)); +} + +static void _print_u16_in_TUs(struct nlattr *a) +{ + printf("%d TUs", nla_get_u16(a)); +} + +static void _print_u32_timeout(struct nlattr *a) +{ + printf("%u milliseconds", nla_get_u32(a)); +} + +static void _print_u32_in_TUs(struct nlattr *a) +{ + printf("%d TUs", nla_get_u32(a)); +} + +/* The current mesh parameters */ +const static struct mesh_param_descr _mesh_param_descrs[] = +{ + {"mesh_retry_timeout", + NL80211_MESHCONF_RETRY_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_confirm_timeout", + NL80211_MESHCONF_CONFIRM_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_holding_timeout", + NL80211_MESHCONF_HOLDING_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_max_peer_links", + NL80211_MESHCONF_MAX_PEER_LINKS, + _my_nla_put_u16, _parse_u16, _print_u16}, + {"mesh_max_retries", + NL80211_MESHCONF_MAX_RETRIES, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_ttl", + NL80211_MESHCONF_TTL, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_element_ttl", + NL80211_MESHCONF_ELEMENT_TTL, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_auto_open_plinks", + NL80211_MESHCONF_AUTO_OPEN_PLINKS, + _my_nla_put_u8, _parse_u8_as_bool, _print_u8}, + {"mesh_hwmp_max_preq_retries", + NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_path_refresh_time", + NL80211_MESHCONF_PATH_REFRESH_TIME, + _my_nla_put_u32, _parse_u32, _print_u32_timeout}, + {"mesh_min_discovery_timeout", + NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_hwmp_active_path_timeout", + NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, + _my_nla_put_u32, _parse_u32, _print_u32_in_TUs}, + {"mesh_hwmp_preq_min_interval", + NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, + {"mesh_hwmp_net_diameter_traversal_time", + NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, + {"mesh_hwmp_rootmode", NL80211_MESHCONF_HWMP_ROOTMODE, + _my_nla_put_u8, _parse_u8, _print_u8}, +}; + +static void print_all_mesh_param_descr(void) +{ + int i; + + printf("Possible mesh parameters are:\n"); + + for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) + printf(" - %s\n", _mesh_param_descrs[i].name); +} + +static const struct mesh_param_descr *find_mesh_param(const char *name) +{ + int i; + const struct mesh_param_descr *mdescr = NULL; + + /* Find out what mesh parameter we want to change. */ + for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) { + if (!strcmp(_mesh_param_descrs[i].name, name)) + return _mesh_param_descrs + i; + } + + if (!mdescr) { + print_all_mesh_param_descr(); + return NULL; + } + return mdescr; +} + +/* Setter */ +static int set_interface_meshparam(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + const struct mesh_param_descr *mdescr; + struct nlattr *container; + uint32_t ret; + int err; + + container = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); + if (!container) + return -ENOBUFS; + + if (!argc) + return 1; + + while (argc) { + const char *name; + char *value; + _any any; + + memset(&any, 0, sizeof(_any)); + + name = argv[0]; + value = strchr(name, '='); + if (value) { + *value = '\0'; + value++; + argc--; + argv++; + } else { + /* backward compat -- accept w/o '=' */ + if (argc < 2) { + printf("Must specify a value for %s.\n", name); + return 2; + } + value = argv[1]; + argc -= 2; + argv += 2; + } + + mdescr = find_mesh_param(name); + if (!mdescr) + return 2; + + /* Parse the new value */ + ret = mdescr->parse_fn(value, &any); + if (ret != 0) { + printf("%s must be set to a number " + "between 0 and %u\n", mdescr->name, ret); + return 2; + } + + err = mdescr->nla_put_fn(msg, mdescr->mesh_param_num, &any); + if (err) + return err; + } + nla_nest_end(msg, container); + + return err; +} + +COMMAND(set, mesh_param, "<param>=<value> [<param>=<value>]*", + NL80211_CMD_SET_MESH_PARAMS, 0, CIB_NETDEV, set_interface_meshparam, + "Set mesh parameter (run command without any to see available ones)."); + +/* Getter */ +static int print_mesh_param_handler(struct nl_msg *msg, void *arg) +{ + const struct mesh_param_descr *mdescr = arg; + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct nlattr *parent_attr; + struct nlattr *mesh_params[NL80211_MESHCONF_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + /* locate NL80211_ATTR_MESH_PARAMS */ + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + parent_attr = attrs[NL80211_ATTR_MESH_PARAMS]; + if (!parent_attr) + return -EINVAL; + + /* unpack the mesh parameters */ + if (nla_parse_nested(mesh_params, NL80211_MESHCONF_ATTR_MAX, + parent_attr, NULL)) + return -EINVAL; + + if (!mdescr) { + int i; + + for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) { + mdescr = &_mesh_param_descrs[i]; + printf("%s = ", mdescr->name); + mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]); + printf("\n"); + } + return NL_SKIP; + } + + /* print out the mesh parameter */ + mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]); + printf("\n"); + return NL_SKIP; +} + +static int get_interface_meshparam(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + const struct mesh_param_descr *mdescr = NULL; + + if (argc > 1) + return 1; + + if (argc == 1) { + mdescr = find_mesh_param(argv[0]); + if (!mdescr) + return 2; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_mesh_param_handler, (void *)mdescr); + return 0; +} + +COMMAND(get, mesh_param, "[<param>]", + NL80211_CMD_GET_MESH_PARAMS, 0, CIB_NETDEV, get_interface_meshparam, + "Retrieve mesh parameter (run command without any to see available ones)."); + +static int join_mesh(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + if (argc < 1) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(argv[0]), argv[0]); + argc--; + argv++; + + if (!argc) + return 0; + return set_interface_meshparam(state, cb, msg, argc, argv); + nla_put_failure: + return -ENOBUFS; +} +COMMAND(mesh, join, "<mesh ID> [<param>=<value>]*", + NL80211_CMD_JOIN_MESH, 0, CIB_NETDEV, join_mesh, + "Join a mesh with the given mesh ID and mesh parameters."); + +static int leave_mesh(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + if (argc) + return 1; + + return 0; +} +COMMAND(mesh, leave, NULL, NL80211_CMD_LEAVE_MESH, 0, CIB_NETDEV, leave_mesh, + "Leave a mesh.");
diff --git a/iw_0.9.22/iw_0.9.22/mpath.c b/iw_0.9.22/iw_0.9.22/mpath.c new file mode 100644 index 0000000..3afe7b7 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/mpath.c
@@ -0,0 +1,194 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(mpath); + +enum plink_state { + LISTEN, + OPN_SNT, + OPN_RCVD, + CNF_RCVD, + ESTAB, + HOLDING, + BLOCKED +}; + +enum plink_actions { + PLINK_ACTION_UNDEFINED, + PLINK_ACTION_OPEN, + PLINK_ACTION_BLOCK, +}; + + +static int print_mpath_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *pinfo[NL80211_MPATH_INFO_MAX + 1]; + char dst[20], next_hop[20], dev[20]; + static struct nla_policy mpath_policy[NL80211_MPATH_INFO_MAX + 1] = { + [NL80211_MPATH_INFO_FRAME_QLEN] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_SN] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_METRIC] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_EXPTIME] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_DISCOVERY_TIMEOUT] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_DISCOVERY_RETRIES] = { .type = NLA_U8 }, + [NL80211_MPATH_INFO_FLAGS] = { .type = NLA_U8 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + /* + * TODO: validate the interface and mac address! + * Otherwise, there's a race condition as soon as + * the kernel starts sending mpath notifications. + */ + + if (!tb[NL80211_ATTR_MPATH_INFO]) { + fprintf(stderr, "mpath info missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(pinfo, NL80211_MPATH_INFO_MAX, + tb[NL80211_ATTR_MPATH_INFO], + mpath_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + mac_addr_n2a(dst, nla_data(tb[NL80211_ATTR_MAC])); + mac_addr_n2a(next_hop, nla_data(tb[NL80211_ATTR_MPATH_NEXT_HOP])); + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("%s %s %s", dst, next_hop, dev); + if (pinfo[NL80211_MPATH_INFO_SN]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_SN])); + if (pinfo[NL80211_MPATH_INFO_METRIC]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_METRIC])); + if (pinfo[NL80211_MPATH_INFO_FRAME_QLEN]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_FRAME_QLEN])); + if (pinfo[NL80211_MPATH_INFO_EXPTIME]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_EXPTIME])); + if (pinfo[NL80211_MPATH_INFO_DISCOVERY_TIMEOUT]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_DISCOVERY_TIMEOUT])); + if (pinfo[NL80211_MPATH_INFO_DISCOVERY_RETRIES]) + printf("\t%u", + nla_get_u8(pinfo[NL80211_MPATH_INFO_DISCOVERY_RETRIES])); + if (pinfo[NL80211_MPATH_INFO_FLAGS]) + printf("\t0x%x", + nla_get_u8(pinfo[NL80211_MPATH_INFO_FLAGS])); + + printf("\n"); + return NL_SKIP; +} + +static int handle_mpath_get(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + unsigned char dst[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(dst, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(mpath, get, "<MAC address>", + NL80211_CMD_GET_MPATH, 0, CIB_NETDEV, handle_mpath_get, + "Get information on mesh path to the given node."); +COMMAND(mpath, del, "<MAC address>", + NL80211_CMD_DEL_MPATH, 0, CIB_NETDEV, handle_mpath_get, + "Remove the mesh path to the given node."); + +static int handle_mpath_set(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + unsigned char dst[ETH_ALEN]; + unsigned char next_hop[ETH_ALEN]; + + if (argc < 3) + return 1; + + if (mac_addr_a2n(dst, argv[0])) { + fprintf(stderr, "invalid destination mac address\n"); + return 2; + } + argc--; + argv++; + + if (strcmp("next_hop", argv[0]) != 0) + return 1; + argc--; + argv++; + + if (mac_addr_a2n(next_hop, argv[0])) { + fprintf(stderr, "invalid next hop mac address\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst); + NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL); + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(mpath, new, "<destination MAC address> next_hop <next hop MAC address>", + NL80211_CMD_NEW_MPATH, 0, CIB_NETDEV, handle_mpath_set, + "Create a new mesh path (instead of relying on automatic discovery)."); +COMMAND(mpath, set, "<destination MAC address> next_hop <next hop MAC address>", + NL80211_CMD_SET_MPATH, 0, CIB_NETDEV, handle_mpath_set, + "Set an existing mesh path's next hop."); + +static int handle_mpath_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + printf("DEST ADDR NEXT HOP IFACE\tSN\tMETRIC\tQLEN\t" + "EXPTIME\t\tDTIM\tDRET\tFLAGS\n"); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL); + return 0; +} +COMMAND(mpath, dump, NULL, + NL80211_CMD_GET_MPATH, NLM_F_DUMP, CIB_NETDEV, handle_mpath_dump, + "List known mesh paths.");
diff --git a/iw_0.9.22/iw_0.9.22/nl80211.h b/iw_0.9.22/iw_0.9.22/nl80211.h new file mode 100644 index 0000000..2460f30 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/nl80211.h
@@ -0,0 +1,2521 @@ +#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 <mb@bu3sch.de> + * 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. + * + */ + +#include <linux/types.h> + +/** + * 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. + * + * TODO: need more info? + */ + +/** + * 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. + */ + +/** + * 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, + * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %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 on a %NL80211_ATTR_WIPHY or a specific get + * on an %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: retrieve beacon information (returned in a + * %NL80222_CMD_NEW_BEACON message) + * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface + * using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD, + * %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes. + * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface, + * parameters are like for %NL80211_CMD_SET_BEACON. + * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it + * + * @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_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. + * @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_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. + * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT + * if scheduled scan is not running. + * @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_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_MAC, + * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. + * 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 and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be + * optionally used to specify additional channel parameters. + * %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 (and + * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) 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_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_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 %NL80211_ATTR_WIPHY_CHANNEL_TYPE) 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 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. + * + * @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_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_NEW_BEACON, + NL80211_CMD_DEL_BEACON, + + 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_GET_KEEPALIVE, + NL80211_CMD_SET_KEEPALIVE, + /* 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 + +/* 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 + * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ + * if HT20 or HT40 are allowed (i.e., 802.11n 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 + * @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_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_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. + * @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.11d 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_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 request + * + * @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. + * + * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to + * indicate which unicast key ciphers will be used with the connection + * (an array of u32). + * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate + * which group key cipher will be used with the connection (a u32). + * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE 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 and ASSOCIATE 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_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_HTOPMODE: 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 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_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_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, + + /* leave some room for new attributes in nl80211 updates */ + NL80211_ATTR_IM_SCAN_RESULT = NL80211_ATTR_BG_SCAN_PERIOD + 10, + NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI, + + NL80211_ATTR_SCAN_MIN_DWELL, + NL80211_ATTR_SCAN_MAX_DWELL, + NL80211_ATTR_SCAN_NUM_PROBE, + + NL80211_ATTR_SCHED_SCAN_SHORT_INTERVAL, + NL80211_ATTR_SCHED_SCAN_NUM_SHORT_INTERVALS, + + NL80211_ATTR_ROAMING_DISABLED, + NL80211_ATTR_CH_SWITCH_COUNT, + NL80211_ATTR_CH_SWITCH_BLOCK_TX, + NL80211_ATTR_CH_SWITCH_POST_BLOCK_TX, + + NL80211_ATTR_KLVDATA, + NL80211_ATTR_KLV_TYPE, + NL80211_ATTR_KLV_INTVL, + NL80211_ATTR_KLV_INDEX, + NL80211_ATTR_KLV_TRIG, + NL80211_ATTR_KLV_PAYLOAD, + + /* add attributes here, update the policy in nl80211.c */ + + __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 + +/* + * 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_MAX_SUPP_RATES 32 +#define NL80211_MAX_SUPP_REG_RULES 32 +#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_MAX_NR_CIPHER_SUITES 5 +#define NL80211_MAX_NR_AKM_SUITES 2 + +/** + * 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_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, + + /* 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_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, + + /* keep last */ + __NL80211_STA_FLAG_AFTER_LAST, + NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 +}; + +/** + * 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. + * + * @__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_MAX: highest rate_info number currently defined + * @__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, + + /* 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 (u32, from this station) + * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, 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 (u32, from this station) + * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this + * station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (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_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, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, + NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 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_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, + + /* 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_PASSIVE_SCAN: Only passive scanning is + * permitted on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted + * on this channel in current regulatory domain. + * @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_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + */ +enum nl80211_frequency_attr { + __NL80211_FREQUENCY_ATTR_INVALID, + NL80211_FREQUENCY_ATTR_FREQ, + NL80211_FREQUENCY_ATTR_DISABLED, + NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, + NL80211_FREQUENCY_ATTR_NO_IBSS, + NL80211_FREQUENCY_ATTR_RADAR, + NL80211_FREQUENCY_ATTR_MAX_TX_POWER, + + /* 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 + +/** + * 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_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, + + /* keep last */ + __NL80211_REG_RULE_ATTR_AFTER_LAST, + NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 +}; + +/** + * 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_PASSIVE_SCAN: passive scan is required + * @NL80211_RRF_NO_IBSS: no IBSS is 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_PASSIVE_SCAN = 1<<7, + NL80211_RRF_NO_IBSS = 1<<8, +}; + +/** + * 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_CHANNEL_TIME: amount of time (in ms) that the radio + * spent on this channel + * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent + * receiving data + * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent + * transmitting data + * @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_CHANNEL_TIME, + NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, + NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 +}; + +/** + * 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_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, + + /* keep last */ + __NL80211_MNTR_FLAG_AFTER_LAST, + NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_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. + * + * @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_ATTR_MAX: highest possible mesh configuration attribute + * + * @__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, + + /* 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_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, + + /* 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_QUEUE: TX queue identifier (NL80211_TXQ_Q_*) + * @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_QUEUE, + 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_txq_q { + NL80211_TXQ_Q_VO, + NL80211_TXQ_Q_VI, + NL80211_TXQ_Q_BE, + NL80211_TXQ_Q_BK +}; + +enum nl80211_channel_type { + NL80211_CHAN_NO_HT, + NL80211_CHAN_HT20, + NL80211_CHAN_HT40MINUS, + NL80211_CHAN_HT40PLUS +}; + +/** + * 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) + * @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, 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. + * @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_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, + + /* 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. + * @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_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, + + /* 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_AFTER_LAST: internal + * @NL80211_TXRATE_MAX: highest TX rate attribute + */ +enum nl80211_tx_rate_attributes { + __NL80211_TXRATE_INVALID, + NL80211_TXRATE_LEGACY, + + /* keep last */ + __NL80211_TXRATE_AFTER_LAST, + NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 +}; + +/** + * 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) + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, +}; + +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_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, + + /* 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 + */ +enum nl80211_cqm_rssi_threshold_event { + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, +}; + + +/** + * 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_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute + * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute + * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has + * a zero bit are ignored + * @NL80211_WOWLAN_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,0x07". + * 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. + * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes + * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number + */ +enum nl80211_wowlan_packet_pattern_attr { + __NL80211_WOWLAN_PKTPAT_INVALID, + NL80211_WOWLAN_PKTPAT_MASK, + NL80211_WOWLAN_PKTPAT_PATTERN, + NL80211_WOWLAN_PKTPAT_ACTION = NL80211_WOWLAN_PKTPAT_PATTERN + 10, + + NUM_NL80211_WOWLAN_PKTPAT, + MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, +}; + +/** + * enum nl80211_wowlan_action - WoWLAN packet pattern action + * @NL80211_WOWLAN_ACTION_ALLOW: this pattern should wake up the host + * and the packet should be forwarded to the host unless this packet + * matches a DROP rule. + * @NL80211_WOWLAN_ACTION_DROP: a packet containing this pattern shouldn't + * wake up the host. + */ +enum nl80211_wowlan_action { + NL80211_WOWLAN_ACTION_ALLOW, + NL80211_WOWLAN_ACTION_DROP, + + /* keep last */ + NUM_NL80211_WOWLAN_ACTION, + MAX_NL80211_WOWLAN_ACTION = NUM_NL80211_WOWLAN_ACTION - 1, +}; + +/** + * struct nl80211_wowlan_pattern_support - 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 + * + * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when + * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the + * capability information given by the kernel to userspace. + */ +struct nl80211_wowlan_pattern_support { + __u32 max_patterns; + __u32 min_pattern_len; + __u32 max_pattern_len; +} __attribute__((packed)); + +/** + * 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) + * @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. 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_wowlan_pattern_support. + * @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) + * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers + * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number + */ +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, + + /* keep last */ + NUM_NL80211_WOWLAN_TRIG, + MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 +}; + +/** + * 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. + * @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, + + /* 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 +}; + +#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 +}; + +#endif /* __LINUX_NL80211_H */
diff --git a/iw_0.9.22/iw_0.9.22/nl80211.h.orig b/iw_0.9.22/iw_0.9.22/nl80211.h.orig new file mode 100644 index 0000000..5cd5f8f --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/nl80211.h.orig
@@ -0,0 +1,2503 @@ +#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 <mb@bu3sch.de> + * 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. + * + */ + +#include <linux/types.h> + +/** + * 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. + * + * TODO: need more info? + */ + +/** + * 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. + */ + +/** + * 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, + * %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %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 on a %NL80211_ATTR_WIPHY or a specific get + * on an %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: retrieve beacon information (returned in a + * %NL80222_CMD_NEW_BEACON message) + * @NL80211_CMD_SET_BEACON: set the beacon on an access point interface + * using the %NL80211_ATTR_BEACON_INTERVAL, %NL80211_ATTR_DTIM_PERIOD, + * %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL attributes. + * @NL80211_CMD_NEW_BEACON: add a new beacon to an access point interface, + * parameters are like for %NL80211_CMD_SET_BEACON. + * @NL80211_CMD_DEL_BEACON: remove the beacon, stop sending it + * + * @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_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. + * @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_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. + * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT + * if scheduled scan is not running. + * @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_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_MAC, + * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, + * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. + * 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 and %NL80211_ATTR_WIPHY_CHANNEL_TYPE may be + * optionally used to specify additional channel parameters. + * %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 (and + * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) 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_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_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 %NL80211_ATTR_WIPHY_CHANNEL_TYPE) 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 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. + * + * @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_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_NEW_BEACON, + NL80211_CMD_DEL_BEACON, + + 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_GET_KEEPALIVE, + NL80211_CMD_SET_KEEPALIVE, + /* 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 + +/* 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 + * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ + * if HT20 or HT40 are allowed (i.e., 802.11n 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 + * @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_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_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. + * @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.11d 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_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 request + * + * @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. + * + * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT and ASSOCIATE to + * indicate which unicast key ciphers will be used with the connection + * (an array of u32). + * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT and ASSOCIATE to indicate + * which group key cipher will be used with the connection (a u32). + * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT and ASSOCIATE 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 and ASSOCIATE 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_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_HTOPMODE: 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 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_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_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, + + /* leave some room for new attributes in nl80211 updates */ + NL80211_ATTR_IM_SCAN_RESULT = NL80211_ATTR_BG_SCAN_PERIOD + 10, + NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI, + + NL80211_ATTR_SCAN_MIN_DWELL, + NL80211_ATTR_SCAN_MAX_DWELL, + NL80211_ATTR_SCAN_NUM_PROBE, + + NL80211_ATTR_SCHED_SCAN_SHORT_INTERVAL, + NL80211_ATTR_SCHED_SCAN_NUM_SHORT_INTERVALS, + + NL80211_ATTR_ROAMING_DISABLED, + NL80211_ATTR_CH_SWITCH_COUNT, + NL80211_ATTR_CH_SWITCH_BLOCK_TX, + NL80211_ATTR_CH_SWITCH_POST_BLOCK_TX, + + NL80211_ATTR_KLVDATA, + NL80211_ATTR_KLV_TYPE, + NL80211_ATTR_KLV_INTVL, + NL80211_ATTR_KLV_INDEX, + NL80211_ATTR_KLV_TRIG, + NL80211_ATTR_KLV_PAYLOAD, + + /* add attributes here, update the policy in nl80211.c */ + + __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 + +/* + * 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_MAX_SUPP_RATES 32 +#define NL80211_MAX_SUPP_REG_RULES 32 +#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_MAX_NR_CIPHER_SUITES 5 +#define NL80211_MAX_NR_AKM_SUITES 2 + +/** + * 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_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, + + /* 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_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, + + /* keep last */ + __NL80211_STA_FLAG_AFTER_LAST, + NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 +}; + +/** + * 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. + * + * @__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_MAX: highest rate_info number currently defined + * @__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, + + /* 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 (u32, from this station) + * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, 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 (u32, from this station) + * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this + * station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (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_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, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, + NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 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_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, + + /* 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_PASSIVE_SCAN: Only passive scanning is + * permitted on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted + * on this channel in current regulatory domain. + * @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_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + */ +enum nl80211_frequency_attr { + __NL80211_FREQUENCY_ATTR_INVALID, + NL80211_FREQUENCY_ATTR_FREQ, + NL80211_FREQUENCY_ATTR_DISABLED, + NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, + NL80211_FREQUENCY_ATTR_NO_IBSS, + NL80211_FREQUENCY_ATTR_RADAR, + NL80211_FREQUENCY_ATTR_MAX_TX_POWER, + + /* 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 + +/** + * 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_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, + + /* keep last */ + __NL80211_REG_RULE_ATTR_AFTER_LAST, + NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 +}; + +/** + * 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_PASSIVE_SCAN: passive scan is required + * @NL80211_RRF_NO_IBSS: no IBSS is 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_PASSIVE_SCAN = 1<<7, + NL80211_RRF_NO_IBSS = 1<<8, +}; + +/** + * 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_CHANNEL_TIME: amount of time (in ms) that the radio + * spent on this channel + * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent + * receiving data + * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent + * transmitting data + * @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_CHANNEL_TIME, + NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, + NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 +}; + +/** + * 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_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, + + /* keep last */ + __NL80211_MNTR_FLAG_AFTER_LAST, + NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_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. + * + * @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_ATTR_MAX: highest possible mesh configuration attribute + * + * @__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, + + /* 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_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, + + /* 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_QUEUE: TX queue identifier (NL80211_TXQ_Q_*) + * @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_QUEUE, + 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_txq_q { + NL80211_TXQ_Q_VO, + NL80211_TXQ_Q_VI, + NL80211_TXQ_Q_BE, + NL80211_TXQ_Q_BK +}; + +enum nl80211_channel_type { + NL80211_CHAN_NO_HT, + NL80211_CHAN_HT20, + NL80211_CHAN_HT40MINUS, + NL80211_CHAN_HT40PLUS +}; + +/** + * 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) + * @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, 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. + * @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_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, + + /* 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. + * @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_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, + + /* 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_AFTER_LAST: internal + * @NL80211_TXRATE_MAX: highest TX rate attribute + */ +enum nl80211_tx_rate_attributes { + __NL80211_TXRATE_INVALID, + NL80211_TXRATE_LEGACY, + + /* keep last */ + __NL80211_TXRATE_AFTER_LAST, + NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 +}; + +/** + * 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) + */ +enum nl80211_band { + NL80211_BAND_2GHZ, + NL80211_BAND_5GHZ, +}; + +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_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, + + /* 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 + */ +enum nl80211_cqm_rssi_threshold_event { + NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, + NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, +}; + + +/** + * 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_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute + * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute + * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has + * a zero bit are ignored + * @NL80211_WOWLAN_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,0x07". + * 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. + * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes + * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number + */ +enum nl80211_wowlan_packet_pattern_attr { + __NL80211_WOWLAN_PKTPAT_INVALID, + NL80211_WOWLAN_PKTPAT_MASK, + NL80211_WOWLAN_PKTPAT_PATTERN, + + NUM_NL80211_WOWLAN_PKTPAT, + MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, +}; + +/** + * struct nl80211_wowlan_pattern_support - 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 + * + * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when + * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the + * capability information given by the kernel to userspace. + */ +struct nl80211_wowlan_pattern_support { + __u32 max_patterns; + __u32 min_pattern_len; + __u32 max_pattern_len; +} __attribute__((packed)); + +/** + * 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) + * @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. 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_wowlan_pattern_support. + * @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) + * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers + * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number + */ +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, + + /* keep last */ + NUM_NL80211_WOWLAN_TRIG, + MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 +}; + +/** + * 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. + * @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, + + /* 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 +}; + +#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 +}; + +#endif /* __LINUX_NL80211_H */
diff --git a/iw_0.9.22/iw_0.9.22/offch.c b/iw_0.9.22/iw_0.9.22/offch.c new file mode 100644 index 0000000..b40a523 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/offch.c
@@ -0,0 +1,43 @@ +#include <errno.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int offchannel(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *end; + + /* freq */ + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, + strtoul(argv[0], &end, 10)); + if (*end != '\0') + return 1; + argv++; + argc--; + + /* duration */ + NLA_PUT_U32(msg, NL80211_ATTR_DURATION, + strtoul(argv[0], &end, 10)); + if (*end != '\0') + return 1; + argv++; + argc--; + + if (argc) + return 1; + + return 0; + nla_put_failure: + return -ENOSPC; +} + +TOPLEVEL(offchannel, "<freq> <duration>", NL80211_CMD_REMAIN_ON_CHANNEL, 0, + CIB_NETDEV, offchannel, + "Leave operating channel and go to the given channel for a while.");
diff --git a/iw_0.9.22/iw_0.9.22/phy.c b/iw_0.9.22/iw_0.9.22/phy.c new file mode 100644 index 0000000..91042b4 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/phy.c
@@ -0,0 +1,351 @@ +#include <stdbool.h> +#include <errno.h> +#include <net/if.h> +#include <strings.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int handle_name(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + if (argc != 1) + return 1; + + NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, *argv); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name, + "Rename this wireless device."); + +static int handle_freqchan(struct nl_msg *msg, bool chan, + int argc, char **argv) +{ + char *end; + static const struct { + const char *name; + unsigned int val; + } htmap[] = { + { .name = "HT20", .val = NL80211_CHAN_HT20, }, + { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, }, + { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, }, + }; + unsigned int htval = NL80211_CHAN_NO_HT; + unsigned int freq; + int i; + + if (!argc || argc > 2) + return 1; + + if (argc == 2) { + for (i = 0; i < ARRAY_SIZE(htmap); i++) { + if (strcasecmp(htmap[i].name, argv[1]) == 0) { + htval = htmap[i].val; + break; + } + } + if (htval == NL80211_CHAN_NO_HT) + return 1; + } + + if (!*argv[0]) + return 1; + freq = strtoul(argv[0], &end, 10); + if (*end) + return 1; + + if (chan) + freq = ieee80211_channel_to_frequency(freq); + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, htval); + + return 0; + nla_put_failure: + return -ENOBUFS; +} + +static int handle_freq(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv) +{ + return handle_freqchan(msg, false, argc, argv); +} +COMMAND(set, freq, "<freq> [HT20|HT40+|HT40-]", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_freq, + "Set frequency/channel the hardware is using, including HT\n" + "configuration."); +COMMAND(set, freq, "<freq> [HT20|HT40+|HT40-]", + NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_freq, NULL); + +static int handle_chan(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv) +{ + return handle_freqchan(msg, true, argc, argv); +} +COMMAND(set, channel, "<channel> [HT20|HT40+|HT40-]", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_chan, NULL); +COMMAND(set, channel, "<channel> [HT20|HT40+|HT40-]", + NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_chan, NULL); + +static int handle_fragmentation(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv) +{ + unsigned int frag; + + if (argc != 1) + return 1; + + if (strcmp("off", argv[0]) == 0) + frag = -1; + else { + char *end; + + if (!*argv[0]) + return 1; + frag = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, frag); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, frag, "<fragmentation threshold|off>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_fragmentation, + "Set fragmentation threshold."); + +static int handle_rts(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv) +{ + unsigned int rts; + + if (argc != 1) + return 1; + + if (strcmp("off", argv[0]) == 0) + rts = -1; + else { + char *end; + + if (!*argv[0]) + return 1; + rts = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, rts); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, rts, "<rts threshold|off>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_rts, + "Set rts threshold."); + +static int handle_netns(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *end; + + if (argc != 1) + return 1; + + if (!*argv[0]) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_PID, + strtoul(argv[0], &end, 10)); + + if (*end != '\0') + return 1; + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, netns, "<pid>", + NL80211_CMD_SET_WIPHY_NETNS, 0, CIB_PHY, handle_netns, + "Put this wireless device into a different network namespace"); + +static int handle_coverage(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *end; + unsigned int coverage; + + if (argc != 1) + return 1; + + if (!*argv[0]) + return 1; + coverage = strtoul(argv[0], &end, 10); + if (coverage > 255) + return 1; + + if (*end) + return 1; + + NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, coverage, "<coverage class>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_coverage, + "Set coverage class (1 for every 3 usec of air propagation time).\n" + "Valid values: 0 - 255."); + +static int handle_distance(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *end; + unsigned int distance, coverage; + + if (argc != 1) + return 1; + + if (!*argv[0]) + return 1; + + distance = strtoul(argv[0], &end, 10); + + if (*end) + return 1; + + /* + * Divide double the distance by the speed of light in m/usec (300) to + * get round-trip time in microseconds and then divide the result by + * three to get coverage class as specified in IEEE 802.11-2007 table + * 7-27. Values are rounded upwards. + */ + coverage = (distance + 449) / 450; + if (coverage > 255) + return 1; + + NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, distance, "<distance>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_distance, + "Set appropriate coverage class for given link distance in meters.\n" + "Valid values: 0 - 114750"); + +static int handle_txpower(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + enum nl80211_tx_power_setting type; + int mbm; + + /* get the required args */ + if (argc != 1 && argc != 2) + return 1; + + if (!strcmp(argv[0], "auto")) + type = NL80211_TX_POWER_AUTOMATIC; + else if (!strcmp(argv[0], "fixed")) + type = NL80211_TX_POWER_FIXED; + else if (!strcmp(argv[0], "limit")) + type = NL80211_TX_POWER_LIMITED; + else { + printf("Invalid parameter: %s\n", argv[0]); + return 2; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, type); + + if (type != NL80211_TX_POWER_AUTOMATIC) { + char *endptr; + if (argc != 2) { + printf("Missing TX power level argument.\n"); + return 2; + } + + mbm = strtol(argv[1], &endptr, 10); + if (!*endptr) + return 2; + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, mbm); + } else if (argc != 1) + return 1; + + return 0; + + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_txpower, + "Specify transmit power level and setting type."); +COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]", + NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_txpower, + "Specify transmit power level and setting type."); + +static int handle_antenna(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char *end; + uint32_t tx_ant = 0, rx_ant = 0; + + if (argc == 1 && strcmp(argv[0], "all") == 0) { + tx_ant = 0xffffffff; + rx_ant = 0xffffffff; + } else if (argc == 1) { + tx_ant = rx_ant = strtoul(argv[0], &end, 0); + if (*end) + return 1; + } + else if (argc == 2) { + tx_ant = strtoul(argv[0], &end, 0); + if (*end) + return 1; + rx_ant = strtoul(argv[1], &end, 0); + if (*end) + return 1; + } else + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant); + + return 0; + + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, antenna, "<bitmap> | all | <tx bitmap> <rx bitmap>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna, + "Set a bitmap of allowed antennas to use for TX and RX.\n" + "The driver may reject antenna configurations it cannot support.");
diff --git a/iw_0.9.22/iw_0.9.22/ps.c b/iw_0.9.22/iw_0.9.22/ps.c new file mode 100644 index 0000000..6feeeb9 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/ps.c
@@ -0,0 +1,83 @@ +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int set_power_save(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + enum nl80211_ps_state ps_state; + + if (argc != 1) { + printf("Invalid parameters!\n"); + return 2; + } + + if (strcmp(argv[0], "on") == 0) + ps_state = NL80211_PS_ENABLED; + else if (strcmp(argv[0], "off") == 0) + ps_state = NL80211_PS_DISABLED; + else { + printf("Invalid parameter: %s\n", argv[0]); + return 2; + } + + NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); + + return 0; + + nla_put_failure: + return -ENOBUFS; +} + +COMMAND(set, power_save, "<on|off>", + NL80211_CMD_SET_POWER_SAVE, 0, CIB_NETDEV, set_power_save, + "Set power save state to on or off."); + +static int print_power_save_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + const char *s; + + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_PS_STATE]) + return NL_SKIP; + + switch (nla_get_u32(attrs[NL80211_ATTR_PS_STATE])) { + case NL80211_PS_ENABLED: + s = "on"; + break; + case NL80211_PS_DISABLED: + default: + s = "off"; + break; + } + + printf("Power save: %s\n", s); + + return NL_SKIP; +} + +static int get_power_save(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_power_save_handler, NULL); + return 0; +} + +COMMAND(get, power_save, "<param>", + NL80211_CMD_GET_POWER_SAVE, 0, CIB_NETDEV, get_power_save, + "Retrieve power save state.");
diff --git a/iw_0.9.22/iw_0.9.22/reason.c b/iw_0.9.22/iw_0.9.22/reason.c new file mode 100644 index 0000000..f91c681 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/reason.c
@@ -0,0 +1,50 @@ +#include <stdint.h> +#include "iw.h" + +static const char *reason_table[] = { + [1] = "Unspecified", + [2] = "Previous authentication no longer valid", + [3] = "Deauthenticated because sending station is leaving (or has left) the IBSS or ESS", + [4] = "Disassociated due to inactivity", + [5] = "Disassociated because AP is unable to handle all currently associated STA", + [6] = "Class 2 frame received from non-authenticated station", + [7] = "Class 3 frame received from non-authenticated station", + [8] = "Disassociated because sending station is leaving (or has left) the BSS", + [9] = "Station requesting (re)association is not authenticated with responding station", + [10] = "Disassociated because the information in the Power Capability element is unacceptable", + [11] = "Disassociated because the information in the Supported Channels element is unacceptable", + [13] = "Invalid information element", + [14] = "MIC failure", + [15] = "4-way handshake timeout", + [16] = "Group key update timeout", + [17] = "Information element in 4-way handshake different from (Re-)associate request/Probe response/Beacon", + [18] = "Multicast cipher is not valid", + [19] = "Unicast cipher is not valid", + [20] = "AKMP is not valid", + [21] = "Unsupported RSNE version", + [22] = "Invalid RSNE capabilities", + [23] = "IEEE 802.1X authentication failed", + [24] = "Cipher Suite rejected per security policy", + [31] = "TS deleted because QoS AP lacks sufficient bandwidth for this QoS STA due to a change in BSS service characteristics or operational mode", + [32] = "Disassociated for unspecified QoS-related reason", + [33] = "Disassociated because QAP lacks sufficient bandwidth for this STA", + [34] = "Disassociated because of excessive frame losses and/or poor channel conditions", + [35] = "Disassociated because QSTA is transmitting outside the limits of its polled TXOPs", + [36] = "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)", + [37] = "Requested from peer QSTA as it does not want to use Traffic Stream", + [38] = "Requested from peer QSTA as the QSTA received frames indicated Traffic Stream for which it has not set up", + [39] = "Requested from peer QSTA due to time out", + [40] = "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)", + [41] = "Requested from peer QSTA as it does not want to receive frames directly from the QSTA", + [42] = "Requested from peer QSTA as the QSTA received DLP frames for which it has not set up", + [43] = "Requested from peer QSTA as it does not want to use Block Ack", + [44] = "Requested from peer QSTA as the QSTA received frames indicated Block Acknowledgement policy for which it has not set up", + [45] = "Peer QSTA does not support the requested cipher suite", +}; + +const char *get_reason_str(uint16_t reason) +{ + if (reason < ARRAY_SIZE(reason_table) && reason_table[reason]) + return reason_table[reason]; + return "<unknown>"; +}
diff --git a/iw_0.9.22/iw_0.9.22/reg.c b/iw_0.9.22/iw_0.9.22/reg.c new file mode 100644 index 0000000..c4ee1c4 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/reg.c
@@ -0,0 +1,191 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(reg); + +#define MHZ_TO_KHZ(freq) ((freq) * 1000) +#define KHZ_TO_MHZ(freq) ((freq) / 1000) +#define DBI_TO_MBI(gain) ((gain) * 100) +#define MBI_TO_DBI(gain) ((gain) / 100) +#define DBM_TO_MBM(gain) ((gain) * 100) +#define MBM_TO_DBM(gain) ((gain) / 100) + +static bool isalpha_upper(char letter) +{ + if (letter >= 65 && letter <= 90) + return true; + return false; +} + +static bool is_alpha2(char *alpha2) +{ + if (isalpha_upper(alpha2[0]) && isalpha_upper(alpha2[1])) + return true; + return false; +} + +static bool is_world_regdom(char *alpha2) +{ + /* ASCII 0 */ + if (alpha2[0] == 48 && alpha2[1] == 48) + return true; + return false; +} + +char *reg_initiator_to_string(__u8 initiator) +{ + switch (initiator) { + case NL80211_REGDOM_SET_BY_CORE: + return "the wireless core upon initialization"; + case NL80211_REGDOM_SET_BY_USER: + return "a user"; + case NL80211_REGDOM_SET_BY_DRIVER: + return "a driver"; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + return "a country IE"; + default: + return "BUG"; + } +} + +static int handle_reg_set(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char alpha2[3]; + + if (argc < 1) + return 1; + + if (!is_alpha2(argv[0]) && !is_world_regdom(argv[0])) { + fprintf(stderr, "not a valid ISO/IEC 3166-1 alpha2\n"); + fprintf(stderr, "Special non-alpha2 usable entries:\n"); + fprintf(stderr, "\t00\tWorld Regulatory domain\n"); + return 2; + } + + alpha2[0] = argv[0][0]; + alpha2[1] = argv[0][1]; + alpha2[2] = '\0'; + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(reg, set, "<ISO/IEC 3166-1 alpha2>", + NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set, + "Notify the kernel about the current regulatory domain."); + +static int print_reg_handler(struct nl_msg *msg, void *arg) + +{ +#define PARSE_FLAG(nl_flag, string_value) do { \ + if ((flags & nl_flag)) { \ + printf(", %s", string_value); \ + } \ + } while (0) + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + char *alpha2; + struct nlattr *nl_rule; + int rem_rule; + static struct nla_policy reg_rule_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 }, + [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 }, + [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 }, + [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 }, + [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 }, + [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, + }; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) { + printf("No alpha2\n"); + return NL_SKIP; + } + + if (!tb_msg[NL80211_ATTR_REG_RULES]) { + printf("No reg rules\n"); + return NL_SKIP; + } + + alpha2 = nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]); + printf("country %c%c:\n", alpha2[0], alpha2[1]); + + nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule) { + struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1]; + __u32 flags, start_freq_khz, end_freq_khz, max_bw_khz, max_ant_gain_mbi, max_eirp_mbm; + + nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_rule), nla_len(nl_rule), reg_rule_policy); + + flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]); + start_freq_khz = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]); + end_freq_khz = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]); + max_bw_khz = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]); + max_ant_gain_mbi = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]); + max_eirp_mbm = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]); + + + printf("\t(%d - %d @ %d), (", + KHZ_TO_MHZ(start_freq_khz), KHZ_TO_MHZ(end_freq_khz), KHZ_TO_MHZ(max_bw_khz)); + + if (MBI_TO_DBI(max_ant_gain_mbi)) + printf("%d", MBI_TO_DBI(max_ant_gain_mbi)); + else + printf("N/A"); + + printf(", %d)", MBM_TO_DBM(max_eirp_mbm)); + + if (!flags) { + printf("\n"); + continue; + } + + /* Sync this output format to match that of dbparse.py from wireless-regdb.git */ + PARSE_FLAG(NL80211_RRF_NO_OFDM, "NO-OFDM"); + PARSE_FLAG(NL80211_RRF_NO_CCK, "NO-CCK"); + PARSE_FLAG(NL80211_RRF_NO_INDOOR, "NO-INDOOR"); + PARSE_FLAG(NL80211_RRF_NO_OUTDOOR, "NO-OUTDOOR"); + PARSE_FLAG(NL80211_RRF_DFS, "DFS"); + PARSE_FLAG(NL80211_RRF_PTP_ONLY, "PTP-ONLY"); + PARSE_FLAG(NL80211_RRF_PASSIVE_SCAN, "PASSIVE-SCAN"); + PARSE_FLAG(NL80211_RRF_NO_IBSS, "NO-IBSS"); + + printf("\n"); + } + return NL_OK; +#undef PARSE_FLAG +} + +static int handle_reg_get(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_reg_handler, NULL); + return 0; +} +COMMAND(reg, get, NULL, NL80211_CMD_GET_REG, 0, CIB_NONE, handle_reg_get, + "Print out the kernel's current regulatory domain information.");
diff --git a/iw_0.9.22/iw_0.9.22/roc.c b/iw_0.9.22/iw_0.9.22/roc.c new file mode 100644 index 0000000..1b29e6a --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/roc.c
@@ -0,0 +1,40 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(roc); + +static int handle_roc_start(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + char *end; + int freq, time; + + if (argc != 2) + return 1; + + freq = strtol(argv[0], &end, 0); + if (!end || *end) + return 1; + + time = strtol(argv[1], &end, 0); + if (!end || *end) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + NLA_PUT_U32(msg, NL80211_ATTR_DURATION, time); + return 0; + nla_put_failure: + return -ENOBUFS; +} + +COMMAND(roc, start, "<freq> <time>", NL80211_CMD_REMAIN_ON_CHANNEL, 0, CIB_NETDEV, handle_roc_start, "");
diff --git a/iw_0.9.22/iw_0.9.22/scan.c b/iw_0.9.22/iw_0.9.22/scan.c new file mode 100644 index 0000000..d083591 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/scan.c
@@ -0,0 +1,1345 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +#define WLAN_CAPABILITY_ESS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#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_DSSS_OFDM (1<<13) + +static unsigned char ms_oui[3] = { 0x00, 0x50, 0xf2 }; +static unsigned char ieee80211_oui[3] = { 0x00, 0x0f, 0xac }; +static unsigned char wfa_oui[3] = { 0x50, 0x6f, 0x9a }; + +struct scan_params { + bool unknown; + enum print_ie_type type; + bool show_both_ie_sets; +}; + +#define IEEE80211_COUNTRY_EXTENSION_ID 201 + +union ieee80211_country_ie_triplet { + struct { + __u8 first_channel; + __u8 num_channels; + __s8 max_power; + } __attribute__ ((packed)) chans; + struct { + __u8 reg_extension_id; + __u8 reg_class; + __u8 coverage_class; + } __attribute__ ((packed)) ext; +} __attribute__ ((packed)); + +static int handle_scan(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + struct nl_msg *ssids = NULL, *freqs = NULL; + char *eptr; + int err = -ENOBUFS; + int i; + enum { + NONE, + FREQ, + IES, + SSID, + DONE, + } parse = NONE; + int freq; + bool passive = false, have_ssids = false, have_freqs = false; + size_t tmp; + unsigned char *ies; + + ssids = nlmsg_alloc(); + if (!ssids) + return -ENOMEM; + + freqs = nlmsg_alloc(); + if (!freqs) { + nlmsg_free(ssids); + return -ENOMEM; + } + + for (i = 0; i < argc; i++) { + switch (parse) { + case NONE: + if (strcmp(argv[i], "freq") == 0) { + parse = FREQ; + have_freqs = true; + break; + } else if (strcmp(argv[i], "ies") == 0) { + parse = IES; + break; + } else if (strcmp(argv[i], "ssid") == 0) { + parse = SSID; + have_ssids = true; + break; + } else if (strcmp(argv[i], "passive") == 0) { + parse = DONE; + passive = true; + break; + } + case DONE: + return 1; + case FREQ: + freq = strtoul(argv[i], &eptr, 10); + if (eptr != argv[i] + strlen(argv[i])) { + /* failed to parse as number -- maybe a tag? */ + i--; + parse = NONE; + continue; + } + NLA_PUT_U32(freqs, i, freq); + break; + case IES: + ies = parse_hex(argv[i], &tmp); + if (!ies) + goto nla_put_failure; + NLA_PUT(msg, NL80211_ATTR_IE, tmp, ies); + free(ies); + parse = NONE; + break; + case SSID: + NLA_PUT(ssids, i, strlen(argv[i]), argv[i]); + break; + } + } + + if (!have_ssids) + NLA_PUT(ssids, 1, 0, ""); + if (!passive) + nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids); + + if (have_freqs) + nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); + + err = 0; + nla_put_failure: + nlmsg_free(ssids); + nlmsg_free(freqs); + return err; +} + +static void tab_on_first(bool *first) +{ + if (!*first) + printf("\t"); + else + *first = false; +} + +static void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" "); + print_ssid_escaped(len, data); + printf("\n"); +} + +static void print_supprates(const uint8_t type, uint8_t len, const uint8_t *data) +{ + int i; + + printf(" "); + + for (i = 0; i < len; i++) { + int r = data[i] & 0x7f; + printf("%d.%d%s ", r/2, 5*(r&1), data[i] & 0x80 ? "*":""); + } + printf("\n"); +} + +static void print_ds(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" channel %d\n", data[0]); +} + +static const char *country_env_str(char environment) +{ + switch (environment) { + case 'I': + return "Indoor only"; + case 'O': + return "Outdoor only"; + case ' ': + return "Indoor/Outdoor"; + default: + return "bogus"; + } +} + +static void print_country(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" %.*s", 2, data); + + printf("\tEnvironment: %s\n", country_env_str(data[2])); + + data += 3; + len -= 3; + + if (len < 3) { + printf("\t\tNo country IE triplets present\n"); + return; + } + + while (len >= 3) { + int end_channel; + union ieee80211_country_ie_triplet *triplet = (void *) data; + + if (triplet->ext.reg_extension_id >= IEEE80211_COUNTRY_EXTENSION_ID) { + printf("\t\tExtension ID: %d Regulatory Class: %d Coverage class: %d (up to %dm)\n", + triplet->ext.reg_extension_id, + triplet->ext.reg_class, + triplet->ext.coverage_class, + triplet->ext.coverage_class * 450); + + data += 3; + len -= 3; + continue; + } + + /* 2 GHz */ + if (triplet->chans.first_channel <= 14) + end_channel = triplet->chans.first_channel + (triplet->chans.num_channels - 1); + else + end_channel = triplet->chans.first_channel + (4 * (triplet->chans.num_channels - 1)); + + printf("\t\tChannels [%d - %d] @ %d dBm\n", triplet->chans.first_channel, end_channel, triplet->chans.max_power); + + data += 3; + len -= 3; + } + + return; +} + +static void print_powerconstraint(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" %d dB\n", data[0]); +} + +static void print_erp(const uint8_t type, uint8_t len, const uint8_t *data) +{ + if (data[0] == 0x00) + printf(" <no flags>"); + if (data[0] & 0x01) + printf(" NonERP_Present"); + if (data[0] & 0x02) + printf(" Use_Protection"); + if (data[0] & 0x04) + printf(" Barker_Preamble_Mode"); + printf("\n"); +} + +static void print_cipher(const uint8_t *data) +{ + if (memcmp(data, ms_oui, 3) == 0) { + switch (data[3]) { + case 0: + printf("Use group cipher suite"); + break; + case 1: + printf("WEP-40"); + break; + case 2: + printf("TKIP"); + break; + case 4: + printf("CCMP"); + break; + case 5: + printf("WEP-104"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else if (memcmp(data, ieee80211_oui, 3) == 0) { + switch (data[3]) { + case 0: + printf("Use group cipher suite"); + break; + case 1: + printf("WEP-40"); + break; + case 2: + printf("TKIP"); + break; + case 4: + printf("CCMP"); + break; + case 5: + printf("WEP-104"); + break; + case 6: + printf("AES-128-CMAC"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); +} + +static void print_auth(const uint8_t *data) +{ + if (memcmp(data, ms_oui, 3) == 0) { + switch (data[3]) { + case 1: + printf("IEEE 802.1X"); + break; + case 2: + printf("PSK"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else if (memcmp(data, ieee80211_oui, 3) == 0) { + switch (data[3]) { + case 1: + printf("IEEE 802.1X"); + break; + case 2: + printf("PSK"); + break; + case 3: + printf("FT/IEEE 802.1X"); + break; + case 4: + printf("FT/PSK"); + break; + case 5: + printf("IEEE 802.1X/SHA-256"); + break; + case 6: + printf("PSK/SHA-256"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); +} + +static void print_rsn_ie(const char *defcipher, const char *defauth, + uint8_t len, const uint8_t *data) +{ + bool first = true; + __u16 version, count, capa; + int i; + + version = data[0] + (data[1] << 8); + tab_on_first(&first); + printf("\t * Version: %d\n", version); + + data += 2; + len -= 2; + + if (len < 4) { + tab_on_first(&first); + printf("\t * Group cipher: %s\n", defcipher); + printf("\t * Pairwise ciphers: %s\n", defcipher); + return; + } + + tab_on_first(&first); + printf("\t * Group cipher: "); + print_cipher(data); + printf("\n"); + + data += 4; + len -= 4; + + if (len < 2) { + tab_on_first(&first); + printf("\t * Pairwise ciphers: %s\n", defcipher); + return; + } + + count = data[0] | (data[1] << 8); + if (2 + (count * 4) > len) + goto invalid; + + tab_on_first(&first); + printf("\t * Pairwise ciphers:"); + for (i = 0; i < count; i++) { + printf(" "); + print_cipher(data + 2 + (i * 4)); + } + printf("\n"); + + data += 2 + (count * 4); + len -= 2 + (count * 4); + + if (len < 2) { + tab_on_first(&first); + printf("\t * Authentication suites: %s\n", defauth); + return; + } + + count = data[0] | (data[1] << 8); + if (2 + (count * 4) > len) + goto invalid; + + tab_on_first(&first); + printf("\t * Authentication suites:"); + for (i = 0; i < count; i++) { + printf(" "); + print_auth(data + 2 + (i * 4)); + } + printf("\n"); + + data += 2 + (count * 4); + len -= 2 + (count * 4); + + if (len >= 2) { + capa = data[0] | (data[1] << 8); + tab_on_first(&first); + printf("\t * Capabilities:"); + if (capa & 0x0001) + printf(" PreAuth"); + if (capa & 0x0002) + printf(" NoPairwise"); + switch ((capa & 0x000c) >> 2) { + case 0: + break; + case 1: + printf(" 2-PTKSA-RC"); + break; + case 2: + printf(" 4-PTKSA-RC"); + break; + case 3: + printf(" 16-PTKSA-RC"); + break; + } + switch ((capa & 0x0030) >> 4) { + case 0: + break; + case 1: + printf(" 2-GTKSA-RC"); + break; + case 2: + printf(" 4-GTKSA-RC"); + break; + case 3: + printf(" 16-GTKSA-RC"); + break; + } + if (capa & 0x0040) + printf(" MFP-required"); + if (capa & 0x0080) + printf(" MFP-capable"); + if (capa & 0x0200) + printf(" Peerkey-enabled"); + if (capa & 0x0400) + printf(" SPP-AMSDU-capable"); + if (capa & 0x0800) + printf(" SPP-AMSDU-required"); + printf(" (0x%.4x)\n", capa); + data += 2; + len -= 2; + } + + if (len >= 2) { + int pmkid_count = data[0] | (data[1] << 8); + + if (len >= 2 + 16 * pmkid_count) { + tab_on_first(&first); + printf("\t * %d PMKIDs\n", pmkid_count); + /* not printing PMKID values */ + data += 2 + 16 * pmkid_count; + len -= 2 + 16 * pmkid_count; + } else + goto invalid; + } + + if (len >= 4) { + tab_on_first(&first); + printf("\t * Group mgmt cipher suite: "); + print_cipher(data); + printf("\n"); + data += 4; + len -= 4; + } + + invalid: + if (len != 0) { + printf("\t\t * bogus tail data (%d):", len); + while (len) { + printf(" %.2x", *data); + data++; + len--; + } + printf("\n"); + } +} + +static void print_rsn(const uint8_t type, uint8_t len, const uint8_t *data) +{ + print_rsn_ie("CCMP", "IEEE 802.1X", len, data); +} + +static void print_ht_capa(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf("\n"); + print_ht_capability(data[0] | (data[1] << 8)); + print_ampdu_length(data[2] & 3); + print_ampdu_spacing((data[2] >> 2) & 7); + print_ht_mcs(data + 3); +} + +static void print_ht_op(const uint8_t type, uint8_t len, const uint8_t *data) +{ + static const char *offset[4] = { + "no secondary", + "above", + "[reserved!]", + "below", + }; + static const char *protection[4] = { + "no", + "nonmember", + "20 MHz", + "non-HT mixed", + }; + static const char *sta_chan_width[2] = { + "20 MHz", + "any", + }; + + printf("\n"); + printf("\t\t * primary channel: %d\n", data[0]); + printf("\t\t * secondary channel offset: %s\n", + offset[data[1] & 0x3]); + printf("\t\t * STA channel width: %s\n", sta_chan_width[(data[1] & 0x4)>>2]); + printf("\t\t * RIFS: %d\n", (data[1] & 0x8)>>3); + printf("\t\t * HT protection: %s\n", protection[data[2] & 0x3]); + printf("\t\t * non-GF present: %d\n", (data[2] & 0x4) >> 2); + printf("\t\t * OBSS non-GF present: %d\n", (data[2] & 0x10) >> 4); + printf("\t\t * dual beacon: %d\n", (data[4] & 0x40) >> 6); + printf("\t\t * dual CTS protection: %d\n", (data[4] & 0x80) >> 7); + printf("\t\t * STBC beacon: %d\n", data[5] & 0x1); + printf("\t\t * L-SIG TXOP Prot: %d\n", (data[5] & 0x2) >> 1); + printf("\t\t * PCO active: %d\n", (data[5] & 0x4) >> 2); + printf("\t\t * PCO phase: %d\n", (data[5] & 0x8) >> 3); +} + +static void print_capabilities(const uint8_t type, uint8_t len, const uint8_t *data) +{ + int i, base, bit; + bool first = true; + + + for (i = 0; i < len; i++) { + base = i * 8; + + for (bit = 0; bit < 8; bit++) { + if (!(data[i] & (1 << bit))) + continue; + + if (!first) + printf(","); + else + first = false; + + switch (bit + base) { + case 0: + printf(" HT Information Exchange Supported"); + break; + case 1: + printf(" On-demand Beacon"); + break; + case 2: + printf(" Extended Channel Switching"); + break; + case 3: + printf(" Wave Indication"); + break; + case 4: + printf(" PSMP Capability"); + break; + case 5: + printf(" Service Interval Granularity"); + break; + case 6: + printf(" S-PSMP Capability"); + break; + default: + printf(" %d", bit); + break; + } + } + } + + printf("\n"); +} + +static void print_tim(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" DTIM Count %u DTIM Period %u Bitmap Control 0x%x " + "Bitmap[0] 0x%x", + data[0], data[1], data[2], data[3]); + if (len - 4) + printf(" (+ %u octet%s)", len - 4, len - 4 == 1 ? "" : "s"); + printf("\n"); +} + +struct ie_print { + const char *name; + void (*print)(const uint8_t type, uint8_t len, const uint8_t *data); + uint8_t minlen, maxlen; + uint8_t flags; +}; + +static void print_ie(const struct ie_print *p, const uint8_t type, + uint8_t len, const uint8_t *data) +{ + int i; + + if (!p->print) + return; + + printf("\t%s:", p->name); + if (len < p->minlen || len > p->maxlen) { + if (len > 1) { + printf(" <invalid: %d bytes:", len); + for (i = 0; i < len; i++) + printf(" %.02x", data[i]); + printf(">\n"); + } else if (len) + printf(" <invalid: 1 byte: %.02x>\n", data[0]); + else + printf(" <invalid: no data>\n"); + return; + } + + p->print(type, len, data); +} + +#define PRINT_IGN { \ + .name = "IGNORE", \ + .print = NULL, \ + .minlen = 0, \ + .maxlen = 255, \ +} + +static const struct ie_print ieprinters[] = { + [0] = { "SSID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), }, + [1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, + [3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), }, + [5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), }, + [7] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), }, + [32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), }, + [42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), }, + [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), }, + [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), }, + [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), }, + [50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, + [127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), }, +}; + +static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data) +{ + print_rsn_ie("TKIP", "IEEE 802.1X", len, data); +} + +static bool print_wifi_wmm_param(const uint8_t *data, uint8_t len) +{ + int i; + static const char *aci_tbl[] = { "BE", "BK", "VI", "VO" }; + + if (len < 19) + goto invalid; + + if (data[0] != 1) { + printf("Parameter: not version 1: "); + return false; + } + + printf("\t * Parameter version 1"); + + data++; + + if (data[0] & 0x80) + printf("\n\t\t * u-APSD"); + + data += 2; + + for (i = 0; i < 4; i++) { + printf("\n\t\t * %s:", aci_tbl[(data[0] >> 5) & 3]); + if (data[4] & 0x10) + printf(" acm"); + printf(" CW %d-%d", (1 << (data[1] & 0xf)) - 1, + (1 << (data[1] >> 4)) - 1); + printf(", AIFSN %d", data[0] & 0xf); + if (data[2] | data[3]) + printf(", TXOP %d usec", (data[2] + (data[3] << 8)) * 32); + data += 4; + } + + printf("\n"); + return true; + + invalid: + printf("invalid: "); + return false; +} + +static void print_wifi_wmm(const uint8_t type, uint8_t len, const uint8_t *data) +{ + int i; + + switch (data[0]) { + case 0x00: + printf(" information:"); + break; + case 0x01: + if (print_wifi_wmm_param(data + 1, len - 1)) + return; + break; + default: + printf(" type %d:", data[0]); + break; + } + + for(i = 1; i < len; i++) + printf(" %.02x", data[i]); + printf("\n"); +} + +static const char * wifi_wps_dev_passwd_id(uint16_t id) +{ + switch (id) { + case 0: + return "Default (PIN)"; + case 1: + return "User-specified"; + case 2: + return "Machine-specified"; + case 3: + return "Rekey"; + case 4: + return "PushButton"; + case 5: + return "Registrar-specified"; + default: + return "??"; + } +} + +static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data) +{ + bool first = true; + __u16 subtype, sublen; + + while (len >= 4) { + subtype = (data[0] << 8) + data[1]; + sublen = (data[2] << 8) + data[3]; + if (sublen > len) + break; + + switch (subtype) { + case 0x104a: + tab_on_first(&first); + printf("\t * Version: %d.%d\n", data[4] >> 4, data[4] & 0xF); + break; + case 0x1011: + tab_on_first(&first); + printf("\t * Device name: %.*s\n", sublen, data + 4); + break; + case 0x1012: { + uint16_t id; + tab_on_first(&first); + if (sublen != 2) { + printf("\t * Device Password ID: (invalid " + "length %d)\n", sublen); + break; + } + id = data[4] << 8 | data[5]; + printf("\t * Device Password ID: %u (%s)\n", + id, wifi_wps_dev_passwd_id(id)); + break; + } + case 0x1021: + tab_on_first(&first); + printf("\t * Manufacturer: %.*s\n", sublen, data + 4); + break; + case 0x1023: + tab_on_first(&first); + printf("\t * Model: %.*s\n", sublen, data + 4); + break; + case 0x1024: + tab_on_first(&first); + printf("\t * Model Number: %.*s\n", sublen, data + 4); + break; + case 0x103b: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * Response Type: %d%s\n", + val, val == 3 ? " (AP)" : ""); + break; + } + case 0x103c: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * RF Bands: 0x%x\n", val); + break; + } + case 0x1041: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * Selected Registrar: 0x%x\n", val); + break; + } + case 0x1042: + tab_on_first(&first); + printf("\t * Serial Number: %.*s\n", sublen, data + 4); + break; + case 0x1044: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * Wi-Fi Protected Setup State: %d%s%s\n", + val, + val == 1 ? " (Unconfigured)" : "", + val == 2 ? " (Configured)" : ""); + break; + } + case 0x1047: + tab_on_first(&first); + printf("\t * UUID: "); + if (sublen != 16) { + printf("(invalid, length=%d)\n", sublen); + break; + } + printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x-%02x%02x%02x%02x%02x%02x\n", + data[4], data[5], data[6], data[7], + data[8], data[9], data[10], data[11], + data[12], data[13], data[14], data[15], + data[16], data[17], data[18], data[19]); + break; + case 0x1054: { + tab_on_first(&first); + if (sublen != 8) { + printf("\t * Primary Device Type: (invalid " + "length %d)\n", sublen); + break; + } + printf("\t * Primary Device Type: " + "%u-%02x%02x%02x%02x-%u\n", + data[4] << 8 | data[5], + data[6], data[7], data[8], data[9], + data[10] << 8 | data[11]); + break; + } + case 0x1057: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * AP setup locked: 0x%.2x\n", val); + break; + } + case 0x1008: + case 0x1053: { + __u16 meth = (data[4] << 8) + data[5]; + bool comma = false; + tab_on_first(&first); + printf("\t * %sConfig methods:", + subtype == 0x1053 ? "Selected Registrar ": ""); +#define T(bit, name) do { \ + if (meth & (1<<bit)) { \ + if (comma) \ + printf(","); \ + comma = true; \ + printf(" " name); \ + } } while (0) + T(0, "USB"); + T(1, "Ethernet"); + T(2, "Label"); + T(3, "Display"); + T(4, "Ext. NFC"); + T(5, "Int. NFC"); + T(6, "NFC Intf."); + T(7, "PBC"); + T(8, "Keypad"); + printf("\n"); + break; +#undef T + } + default: { + const __u8 *subdata = data + 4; + __u16 tmplen = sublen; + + tab_on_first(&first); + printf("\t * Unknown TLV (%#.4x, %d bytes):", + subtype, tmplen); + while (tmplen) { + printf(" %.2x", *subdata); + subdata++; + tmplen--; + } + printf("\n"); + break; + } + } + + data += sublen + 4; + len -= sublen + 4; + } + + if (len != 0) { + printf("\t\t * bogus tail data (%d):", len); + while (len) { + printf(" %.2x", *data); + data++; + len--; + } + printf("\n"); + } +} + +static const struct ie_print wifiprinters[] = { + [1] = { "WPA", print_wifi_wpa, 2, 255, BIT(PRINT_SCAN), }, + [2] = { "WMM", print_wifi_wmm, 1, 255, BIT(PRINT_SCAN), }, + [4] = { "WPS", print_wifi_wps, 0, 255, BIT(PRINT_SCAN), }, +}; + +static inline void print_p2p(const uint8_t type, uint8_t len, const uint8_t *data) +{ + bool first = true; + __u8 subtype; + __u16 sublen; + + while (len >= 3) { + subtype = data[0]; + sublen = (data[2] << 8) + data[1]; + + if (sublen > len - 3) + break; + + switch (subtype) { + case 0x02: /* capability */ + tab_on_first(&first); + if (sublen < 2) { + printf("\t * malformed capability\n"); + break; + } + printf("\t * Group capa: 0x%.2x, Device capa: 0x%.2x\n", + data[3], data[4]); + break; + case 0x0d: /* device info */ + if (sublen < 6 + 2 + 8 + 1) { + printf("\t * malformed device info\n"); + break; + } + /* fall through for now */ + case 0x00: /* status */ + case 0x01: /* minor reason */ + case 0x03: /* device ID */ + case 0x04: /* GO intent */ + case 0x05: /* configuration timeout */ + case 0x06: /* listen channel */ + case 0x07: /* group BSSID */ + case 0x08: /* ext listen timing */ + case 0x09: /* intended interface address */ + case 0x0a: /* manageability */ + case 0x0b: /* channel list */ + case 0x0c: /* NoA */ + case 0x0e: /* group info */ + case 0x0f: /* group ID */ + case 0x10: /* interface */ + case 0x11: /* operating channel */ + case 0x12: /* invitation flags */ + case 0xdd: /* vendor specific */ + default: { + const __u8 *subdata = data + 4; + __u16 tmplen = sublen; + + tab_on_first(&first); + printf("\t * Unknown TLV (%#.2x, %d bytes):", + subtype, tmplen); + while (tmplen) { + printf(" %.2x", *subdata); + subdata++; + tmplen--; + } + printf("\n"); + break; + } + } + + data += sublen + 3; + len -= sublen + 3; + } + + if (len != 0) { + tab_on_first(&first); + printf("\t * bogus tail data (%d):", len); + while (len) { + printf(" %.2x", *data); + data++; + len--; + } + printf("\n"); + } +} + +static const struct ie_print wfa_printers[] = { + [9] = { "P2P", print_p2p, 2, 255, BIT(PRINT_SCAN), }, +}; + +static void print_vendor(unsigned char len, unsigned char *data, + bool unknown, enum print_ie_type ptype) +{ + int i; + + if (len < 3) { + printf("\tVendor specific: <too short> data:"); + for(i = 0; i < len; i++) + printf(" %.02x", data[i]); + printf("\n"); + return; + } + + if (len >= 4 && memcmp(data, ms_oui, 3) == 0) { + if (data[3] < ARRAY_SIZE(wifiprinters) && + wifiprinters[data[3]].name && + wifiprinters[data[3]].flags & BIT(ptype)) { + print_ie(&wifiprinters[data[3]], data[3], len - 4, data + 4); + return; + } + if (!unknown) + return; + printf("\tMS/WiFi %#.2x, data:", data[3]); + for(i = 0; i < len - 4; i++) + printf(" %.02x", data[i + 4]); + printf("\n"); + return; + } + + if (len >= 4 && memcmp(data, wfa_oui, 3) == 0) { + if (data[3] < ARRAY_SIZE(wfa_printers) && + wfa_printers[data[3]].name && + wfa_printers[data[3]].flags & BIT(ptype)) { + print_ie(&wfa_printers[data[3]], data[3], len - 4, data + 4); + return; + } + if (!unknown) + return; + printf("\tWFA %#.2x, data:", data[3]); + for(i = 0; i < len - 4; i++) + printf(" %.02x", data[i + 4]); + printf("\n"); + return; + } + + if (!unknown) + return; + + printf("\tVendor specific: OUI %.2x:%.2x:%.2x, data:", + data[0], data[1], data[2]); + for (i = 3; i < len; i++) + printf(" %.2x", data[i]); + printf("\n"); +} + +void print_ies(unsigned char *ie, int ielen, bool unknown, + enum print_ie_type ptype) +{ + while (ielen >= 2 && ielen >= ie[1]) { + if (ie[0] < ARRAY_SIZE(ieprinters) && + ieprinters[ie[0]].name && + ieprinters[ie[0]].flags & BIT(ptype)) { + print_ie(&ieprinters[ie[0]], ie[0], ie[1], ie + 2); + } else if (ie[0] == 221 /* vendor */) { + print_vendor(ie[1], ie + 2, unknown, ptype); + } else if (unknown) { + int i; + + printf("\tUnknown IE (%d):", ie[0]); + for (i=0; i<ie[1]; i++) + printf(" %.2x", ie[2+i]); + printf("\n"); + } + ielen -= ie[1] + 2; + ie += ie[1] + 2; + } +} + +static int print_bss_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *bss[NL80211_BSS_MAX + 1]; + char mac_addr[20], dev[20]; + 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] = { }, + }; + struct scan_params *params = arg; + int show = params->show_both_ie_sets ? 2 : 1; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_BSS]) { + fprintf(stderr, "bss info missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(bss, NL80211_BSS_MAX, + tb[NL80211_ATTR_BSS], + bss_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (!bss[NL80211_BSS_BSSID]) + return NL_SKIP; + + mac_addr_n2a(mac_addr, nla_data(bss[NL80211_BSS_BSSID])); + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("BSS %s (on %s)", mac_addr, dev); + + if (bss[NL80211_BSS_STATUS]) { + switch (nla_get_u32(bss[NL80211_BSS_STATUS])) { + case NL80211_BSS_STATUS_AUTHENTICATED: + printf(" -- authenticated"); + break; + case NL80211_BSS_STATUS_ASSOCIATED: + printf(" -- associated"); + break; + case NL80211_BSS_STATUS_IBSS_JOINED: + printf(" -- joined"); + break; + default: + printf(" -- unknown status: %d", + nla_get_u32(bss[NL80211_BSS_STATUS])); + break; + } + } + printf("\n"); + + if (bss[NL80211_BSS_TSF]) { + unsigned long long tsf; + tsf = (unsigned long long)nla_get_u64(bss[NL80211_BSS_TSF]); + printf("\tTSF: %llu usec (%llud, %.2lld:%.2llu:%.2llu)\n", + tsf, tsf/1000/1000/60/60/24, (tsf/1000/1000/60/60) % 24, + (tsf/1000/1000/60) % 60, (tsf/1000/1000) % 60); + } + if (bss[NL80211_BSS_FREQUENCY]) + printf("\tfreq: %d\n", + nla_get_u32(bss[NL80211_BSS_FREQUENCY])); + if (bss[NL80211_BSS_BEACON_INTERVAL]) + printf("\tbeacon interval: %d\n", + nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL])); + if (bss[NL80211_BSS_CAPABILITY]) { + __u16 capa = nla_get_u16(bss[NL80211_BSS_CAPABILITY]); + printf("\tcapability:"); + if (capa & WLAN_CAPABILITY_ESS) + printf(" ESS"); + if (capa & WLAN_CAPABILITY_IBSS) + printf(" IBSS"); + if (capa & WLAN_CAPABILITY_PRIVACY) + printf(" Privacy"); + if (capa & WLAN_CAPABILITY_SHORT_PREAMBLE) + printf(" ShortPreamble"); + if (capa & WLAN_CAPABILITY_PBCC) + printf(" PBCC"); + if (capa & WLAN_CAPABILITY_CHANNEL_AGILITY) + printf(" ChannelAgility"); + if (capa & WLAN_CAPABILITY_SPECTRUM_MGMT) + printf(" SpectrumMgmt"); + if (capa & WLAN_CAPABILITY_QOS) + printf(" QoS"); + if (capa & WLAN_CAPABILITY_SHORT_SLOT_TIME) + printf(" ShortSlotTime"); + if (capa & WLAN_CAPABILITY_APSD) + printf(" APSD"); + if (capa & WLAN_CAPABILITY_DSSS_OFDM) + printf(" DSSS-OFDM"); + printf(" (0x%.4x)\n", capa); + } + if (bss[NL80211_BSS_SIGNAL_MBM]) { + int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]); + printf("\tsignal: %d.%.2d dBm\n", s/100, s%100); + } + if (bss[NL80211_BSS_SIGNAL_UNSPEC]) { + unsigned char s = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); + printf("\tsignal: %d/100\n", s); + } + if (bss[NL80211_BSS_SEEN_MS_AGO]) { + int age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]); + printf("\tlast seen: %d ms ago\n", age); + } + + if (bss[NL80211_BSS_INFORMATION_ELEMENTS] && show--) { + if (bss[NL80211_BSS_BEACON_IES]) + printf("\tInformation elements from Probe Response " + "frame:\n"); + print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + params->unknown, params->type); + } + if (bss[NL80211_BSS_BEACON_IES] && show--) { + printf("\tInformation elements from Beacon frame:\n"); + print_ies(nla_data(bss[NL80211_BSS_BEACON_IES]), + nla_len(bss[NL80211_BSS_BEACON_IES]), + params->unknown, params->type); + } + + return NL_SKIP; +} + +static struct scan_params scan_params; + +static int handle_scan_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + if (argc > 1) + return 1; + + memset(&scan_params, 0, sizeof(scan_params)); + + if (argc == 1 && !strcmp(argv[0], "-u")) + scan_params.unknown = true; + else if (argc == 1 && !strcmp(argv[0], "-b")) + scan_params.show_both_ie_sets = true; + + scan_params.type = PRINT_SCAN; + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_bss_handler, + &scan_params); + return 0; +} + +static int handle_scan_combined(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + char **trig_argv; + static char *dump_argv[] = { + NULL, + "scan", + "dump", + NULL, + }; + static const __u32 cmds[] = { + NL80211_CMD_NEW_SCAN_RESULTS, + NL80211_CMD_SCAN_ABORTED, + }; + int trig_argc, dump_argc, err; + + if (argc >= 3 && !strcmp(argv[2], "-u")) { + dump_argc = 4; + dump_argv[3] = "-u"; + } else if (argc >= 3 && !strcmp(argv[2], "-b")) { + dump_argc = 4; + dump_argv[3] = "-b"; + } else + dump_argc = 3; + + trig_argc = 3 + (argc - 2) + (3 - dump_argc); + trig_argv = calloc(trig_argc, sizeof(*trig_argv)); + if (!trig_argv) + return -ENOMEM; + trig_argv[0] = argv[0]; + trig_argv[1] = "scan"; + trig_argv[2] = "trigger"; + int i; + for (i = 0; i < argc - 2 - (dump_argc - 3); i++) + trig_argv[i + 3] = argv[i + 2 + (dump_argc - 3)]; + err = handle_cmd(state, II_NETDEV, trig_argc, trig_argv); + free(trig_argv); + if (err) + return err; + + /* + * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION + * + * This code has a bug, which requires creating a separate + * nl80211 socket to fix: + * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or + * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel + * before (!) we listen to it, because we only start listening + * after we send our scan request. + * + * Doing it the other way around has a race condition as well, + * if you first open the events socket you may get a notification + * for a previous scan. + * + * The only proper way to fix this would be to listen to events + * before sending the command, and for the kernel to send the + * scan request along with the event, so that you can match up + * whether the scan you requested was finished or aborted (this + * may result in processing a scan that another application + * requested, but that doesn't seem to be a problem). + * + * Alas, the kernel doesn't do that (yet). + */ + + if (listen_events(state, ARRAY_SIZE(cmds), cmds) == + NL80211_CMD_SCAN_ABORTED) { + printf("scan aborted!\n"); + return 0; + } + + dump_argv[0] = argv[0]; + return handle_cmd(state, II_NETDEV, dump_argc, dump_argv); +} +TOPLEVEL(scan, "[-u] [freq <freq>*] [ies <hex as 00:11:..>] [ssid <ssid>*|passive]", 0, 0, + CIB_NETDEV, handle_scan_combined, + "Scan on the given frequencies and probe for the given SSIDs\n" + "(or wildcard if not given) unless passive scanning is requested.\n" + "If -u is specified print unknown data in the scan results.\n" + "Specified (vendor) IEs must be well-formed."); +COMMAND(scan, dump, "[-u]", + NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump, + "Dump the current scan results. If -u is specified, print unknown\n" + "data in scan results."); +COMMAND(scan, trigger, "[freq <freq>*] [ies <hex as 00:11:..>] [ssid <ssid>*|passive]", + NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan, + "Trigger a scan on the given frequencies with probing for the given\n" + "SSIDs (or wildcard if not given) unless passive scanning is requested.");
diff --git a/iw_0.9.22/iw_0.9.22/sections.c b/iw_0.9.22/iw_0.9.22/sections.c new file mode 100644 index 0000000..38095f6 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/sections.c
@@ -0,0 +1,4 @@ +#include "iw.h" + +SECTION(get); +SECTION(set);
diff --git a/iw_0.9.22/iw_0.9.22/station.c b/iw_0.9.22/iw_0.9.22/station.c new file mode 100644 index 0000000..6581d50 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/station.c
@@ -0,0 +1,331 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(station); + +enum plink_state { + LISTEN, + OPN_SNT, + OPN_RCVD, + CNF_RCVD, + ESTAB, + HOLDING, + BLOCKED +}; + +enum plink_actions { + PLINK_ACTION_UNDEFINED, + PLINK_ACTION_OPEN, + PLINK_ACTION_BLOCK, +}; + + +static int print_sta_handler(struct nl_msg *msg, void *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 *rinfo[NL80211_RATE_INFO_MAX + 1]; + char mac_addr[20], state_name[10], dev[20]; + static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { + [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_TX_BITRATE] = { .type = NLA_NESTED }, + [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 }, + }; + + static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { + [NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 }, + [NL80211_RATE_INFO_MCS] = { .type = NLA_U8 }, + [NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG }, + [NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + /* + * TODO: validate the interface and mac address! + * Otherwise, there's a race condition as soon as + * the kernel starts sending station notifications. + */ + + if (!tb[NL80211_ATTR_STA_INFO]) { + fprintf(stderr, "sta stats missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, + tb[NL80211_ATTR_STA_INFO], + stats_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + mac_addr_n2a(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("Station %s (on %s)", mac_addr, dev); + + if (sinfo[NL80211_STA_INFO_INACTIVE_TIME]) + printf("\n\tinactive time:\t%u ms", + nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME])); + if (sinfo[NL80211_STA_INFO_RX_BYTES]) + printf("\n\trx bytes:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES])); + if (sinfo[NL80211_STA_INFO_RX_PACKETS]) + printf("\n\trx packets:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_RX_PACKETS])); + if (sinfo[NL80211_STA_INFO_TX_BYTES]) + printf("\n\ttx bytes:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES])); + if (sinfo[NL80211_STA_INFO_TX_PACKETS]) + printf("\n\ttx packets:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS])); + if (sinfo[NL80211_STA_INFO_TX_RETRIES]) + printf("\n\ttx retries:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES])); + if (sinfo[NL80211_STA_INFO_TX_FAILED]) + printf("\n\ttx failed:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_FAILED])); + if (sinfo[NL80211_STA_INFO_SIGNAL]) + printf("\n\tsignal: \t%d dBm", + (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL])); + if (sinfo[NL80211_STA_INFO_SIGNAL_AVG]) + printf("\n\tsignal avg:\t%d dBm", + (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG])); + + if (sinfo[NL80211_STA_INFO_TX_BITRATE]) { + if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, + sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) { + fprintf(stderr, "failed to parse nested rate attributes!\n"); + } else { + printf("\n\ttx bitrate:\t"); + if (rinfo[NL80211_RATE_INFO_BITRATE]) { + int rate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); + printf("%d.%d MBit/s", rate / 10, rate % 10); + } + + if (rinfo[NL80211_RATE_INFO_MCS]) + printf(" MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_MCS])); + if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) + printf(" 40Mhz"); + if (rinfo[NL80211_RATE_INFO_SHORT_GI]) + printf(" short GI"); + } + } + + if (sinfo[NL80211_STA_INFO_LLID]) + printf("\n\tmesh llid:\t%d", + nla_get_u16(sinfo[NL80211_STA_INFO_LLID])); + if (sinfo[NL80211_STA_INFO_PLID]) + printf("\n\tmesh plid:\t%d", + nla_get_u16(sinfo[NL80211_STA_INFO_PLID])); + if (sinfo[NL80211_STA_INFO_PLINK_STATE]) { + switch (nla_get_u8(sinfo[NL80211_STA_INFO_PLINK_STATE])) { + case LISTEN: + strcpy(state_name, "LISTEN"); + break; + case OPN_SNT: + strcpy(state_name, "OPN_SNT"); + break; + case OPN_RCVD: + strcpy(state_name, "OPN_RCVD"); + break; + case CNF_RCVD: + strcpy(state_name, "CNF_RCVD"); + break; + case ESTAB: + strcpy(state_name, "ESTAB"); + break; + case HOLDING: + strcpy(state_name, "HOLDING"); + break; + case BLOCKED: + strcpy(state_name, "BLOCKED"); + break; + default: + strcpy(state_name, "UNKNOWN"); + break; + } + printf("\n\tmesh plink:\t%s", state_name); + } + + printf("\n"); + return NL_SKIP; +} + +static int handle_station_get(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(station, get, "<MAC address>", + NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get, + "Get information for a specific station."); +COMMAND(station, del, "<MAC address>", + NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get, + "Remove the given station entry (use with caution!)"); + +static const struct cmd *station_set_plink; +static const struct cmd *station_set_vlan; + +static const struct cmd *select_station_cmd(int argc, char **argv) +{ + if (argc < 2) + return NULL; + if (strcmp(argv[1], "plink_action") == 0) + return station_set_plink; + if (strcmp(argv[1], "vlan") == 0) + return station_set_vlan; + return NULL; +} + +static int handle_station_set_plink(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + unsigned char plink_action; + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 3) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + argc--; + argv++; + + if (strcmp("plink_action", argv[0]) != 0) + return 1; + argc--; + argv++; + + if (strcmp("open", argv[0]) == 0) + plink_action = PLINK_ACTION_OPEN; + else if (strcmp("block", argv[0]) == 0) + plink_action = PLINK_ACTION_BLOCK; + else { + fprintf(stderr, "plink action not supported\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + NLA_PUT_U8(msg, NL80211_ATTR_STA_PLINK_ACTION, plink_action); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND_ALIAS(station, set, "<MAC address> plink_action <open|block>", + NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set_plink, + "Set mesh peer link action for this station (peer).", + select_station_cmd, station_set_plink); + +static int handle_station_set_vlan(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + unsigned char mac_addr[ETH_ALEN]; + unsigned long sta_vlan = 0; + char *err = NULL; + + if (argc < 3) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + argc--; + argv++; + + if (strcmp("vlan", argv[0]) != 0) + return 1; + argc--; + argv++; + + sta_vlan = strtoul(argv[0], &err, 0); + if (err && *err) { + fprintf(stderr, "invalid vlan id\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN, sta_vlan); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND_ALIAS(station, set, "<MAC address> vlan <ifindex>", + NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set_vlan, + "Set an AP VLAN for this station.", + select_station_cmd, station_set_vlan); + + +static int handle_station_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL); + return 0; +} +COMMAND(station, dump, NULL, + NL80211_CMD_GET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump, + "List all stations known, e.g. the AP on managed interfaces");
diff --git a/iw_0.9.22/iw_0.9.22/status.c b/iw_0.9.22/iw_0.9.22/status.c new file mode 100644 index 0000000..731727d --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/status.c
@@ -0,0 +1,59 @@ +#include <stdint.h> +#include "iw.h" + +static const char *status_table[] = { + [0] = "Successful", + [1] = "Unspecified failure", + [10] = "Cannot support all requested capabilities in the capability information field", + [11] = "Reassociation denied due to inability to confirm that association exists", + [12] = "Association denied due to reason outside the scope of this standard", + [13] = "Responding station does not support the specified authentication algorithm", + [14] = "Received an authentication frame with authentication transaction sequence number out of expected sequence", + [15] = "Authentication rejected because of challenge failure", + [16] = "Authentication rejected due to timeout waiting for next frame in sequence", + [17] = "Association denied because AP is unable to handle additional associated STA", + [18] = "Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter", + [19] = "Association denied due to requesting station not supporting the short preamble option", + [20] = "Association denied due to requesting station not supporting the PBCC modulation option", + [21] = "Association denied due to requesting station not supporting the channel agility option", + [22] = "Association request rejected because Spectrum Management capability is required", + [23] = "Association request rejected because the information in the Power Capability element is unacceptable", + [24] = "Association request rejected because the information in the Supported Channels element is unacceptable", + [25] = "Association request rejected due to requesting station not supporting the short slot time option", + [26] = "Association request rejected due to requesting station not supporting the ER-PBCC modulation option", + [27] = "Association denied due to requesting STA not supporting HT features", + [28] = "R0KH Unreachable", + [29] = "Association denied because the requesting STA does not support the PCO transition required by the AP", + [30] = "Association request rejected temporarily; try again later", + [31] = "Robust Management frame policy violation", + [32] = "Unspecified, QoS related failure", + [33] = "Association denied due to QAP having insufficient bandwidth to handle another QSTA", + [34] = "Association denied due to poor channel conditions", + [35] = "Association (with QBSS) denied due to requesting station not supporting the QoS facility", + [37] = "The request has been declined", + [38] = "The request has not been successful as one or more parameters have invalid values", + [39] = "The TS has not been created because the request cannot be honored. However, a suggested Tspec is provided so that the initiating QSTA may attempt to send another TS with the suggested changes to the TSpec", + [40] = "Invalid Information Element", + [41] = "Group Cipher is not valid", + [42] = "Pairwise Cipher is not valid", + [43] = "AKMP is not valid", + [44] = "Unsupported RSN IE version", + [45] = "Invalid RSN IE Capabilities", + [46] = "Cipher suite is rejected per security policy", + [47] = "The TS has not been created. However, the HC may be capable of creating a TS, in response to a request, after the time indicated in the TS Delay element", + [48] = "Direct link is not allowed in the BSS by policy", + [49] = "Destination STA is not present within this QBSS", + [50] = "The destination STA is not a QSTA", + [51] = "Association denied because Listen Interval is too large", + [52] = "Invalid Fast BSS Transition Action Frame Count", + [53] = "Invalid PMKID", + [54] = "Invalid MDIE", + [55] = "Invalid FTIE", +}; + +const char *get_status_str(uint16_t status) +{ + if (status < ARRAY_SIZE(status_table) && status_table[status]) + return status_table[status]; + return "<unknown>"; +}
diff --git a/iw_0.9.22/iw_0.9.22/survey.c b/iw_0.9.22/iw_0.9.22/survey.c new file mode 100644 index 0000000..0810d0c --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/survey.c
@@ -0,0 +1,82 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(survey); + +static int print_survey_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; + char dev[20]; + + 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 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("Survey data from %s\n", dev); + + if (!tb[NL80211_ATTR_SURVEY_INFO]) { + fprintf(stderr, "survey data missing!\n"); + return NL_SKIP; + } + + if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX, + tb[NL80211_ATTR_SURVEY_INFO], + survey_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (sinfo[NL80211_SURVEY_INFO_FREQUENCY]) + printf("\tfrequency:\t\t\t%u MHz%s\n", + nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]), + sinfo[NL80211_SURVEY_INFO_IN_USE] ? " [in use]" : ""); + if (sinfo[NL80211_SURVEY_INFO_NOISE]) + printf("\tnoise:\t\t\t\t%d dBm\n", + (int8_t)nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) + printf("\tchannel active time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) + printf("\tchannel busy time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY]) + printf("\textension channel busy time:\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) + printf("\tchannel receive time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) + printf("\tchannel transmit time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX])); + return NL_SKIP; +} + +static int handle_survey_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_survey_handler, NULL); + return 0; +} +COMMAND(survey, dump, NULL, + NL80211_CMD_GET_SURVEY, NLM_F_DUMP, CIB_NETDEV, handle_survey_dump, + "List all gathered channel survey data"); +
diff --git a/iw_0.9.22/iw_0.9.22/util.c b/iw_0.9.22/iw_0.9.22/util.c new file mode 100644 index 0000000..afffeb6 --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/util.c
@@ -0,0 +1,562 @@ +#include <ctype.h> +#include <netlink/attr.h> +#include <errno.h> +#include <stdbool.h> +#include "iw.h" +#include "nl80211.h" + +void mac_addr_n2a(char *mac_addr, unsigned char *arg) +{ + int i, l; + + l = 0; + for (i = 0; i < ETH_ALEN ; i++) { + if (i == 0) { + sprintf(mac_addr+l, "%02x", arg[i]); + l += 2; + } else { + sprintf(mac_addr+l, ":%02x", arg[i]); + l += 3; + } + } +} + +int mac_addr_a2n(unsigned char *mac_addr, char *arg) +{ + int i; + + for (i = 0; i < ETH_ALEN ; i++) { + int temp; + char *cp = strchr(arg, ':'); + if (cp) { + *cp = 0; + cp++; + } + if (sscanf(arg, "%x", &temp) != 1) + return -1; + if (temp < 0 || temp > 255) + return -1; + + mac_addr[i] = temp; + if (!cp) + break; + arg = cp; + } + if (i < ETH_ALEN - 1) + return -1; + + return 0; +} + +int parse_hex_mask(char *hexmask, unsigned char **result, size_t *result_len, + unsigned char **mask) +{ + size_t len = strlen(hexmask) / 2; + unsigned char *result_val; + unsigned char *result_mask = NULL; + + int pos = 0; + + *result_len = 0; + + result_val = calloc(len + 2, 1); + if (!result_val) + goto error; + *result = result_val; + if (mask) { + result_mask = calloc(DIV_ROUND_UP(len, 8) + 2, 1); + if (!result_mask) + goto error; + *mask = result_mask; + } + + while (1) { + char *cp = strchr(hexmask, ':'); + if (cp) { + *cp = 0; + cp++; + } + + if (result_mask && (strcmp(hexmask, "-") == 0 || + strcmp(hexmask, "xx") == 0 || + strcmp(hexmask, "--") == 0)) { + /* skip this byte and leave mask bit unset */ + } else { + int temp, mask_pos; + char *end; + + temp = strtoul(hexmask, &end, 16); + if (*end) + goto error; + if (temp < 0 || temp > 255) + goto error; + result_val[pos] = temp; + + mask_pos = pos / 8; + if (result_mask) + result_mask[mask_pos] |= 1 << (pos % 8); + } + + (*result_len)++; + pos++; + + if (!cp) + break; + hexmask = cp; + } + + return 0; + error: + free(result_val); + free(result_mask); + return -1; +} + +unsigned char *parse_hex(char *hex, size_t *outlen) +{ + unsigned char *result; + + if (parse_hex_mask(hex, &result, outlen, NULL)) + return NULL; + return result; +} + +static const char *ifmodes[NL80211_IFTYPE_MAX + 1] = { + "unspecified", + "IBSS", + "managed", + "AP", + "AP/VLAN", + "WDS", + "monitor", + "mesh point", + "P2P-client", + "P2P-GO", +}; + +static char modebuf[100]; + +const char *iftype_name(enum nl80211_iftype iftype) +{ + if (iftype <= NL80211_IFTYPE_MAX) + return ifmodes[iftype]; + sprintf(modebuf, "Unknown mode (%d)", iftype); + return modebuf; +} + +static const char *commands[NL80211_CMD_MAX + 1] = { + [NL80211_CMD_GET_WIPHY] = "get_wiphy", + [NL80211_CMD_SET_WIPHY] = "set_wiphy", + [NL80211_CMD_NEW_WIPHY] = "new_wiphy", + [NL80211_CMD_DEL_WIPHY] = "del_wiphy", + [NL80211_CMD_GET_INTERFACE] = "get_interface", + [NL80211_CMD_SET_INTERFACE] = "set_interface", + [NL80211_CMD_NEW_INTERFACE] = "new_interface", + [NL80211_CMD_DEL_INTERFACE] = "del_interface", + [NL80211_CMD_GET_KEY] = "get_key", + [NL80211_CMD_SET_KEY] = "set_key", + [NL80211_CMD_NEW_KEY] = "new_key", + [NL80211_CMD_DEL_KEY] = "del_key", + [NL80211_CMD_GET_BEACON] = "get_beacon", + [NL80211_CMD_SET_BEACON] = "set_beacon", + [NL80211_CMD_NEW_BEACON] = "new_beacon", + [NL80211_CMD_DEL_BEACON] = "del_beacon", + [NL80211_CMD_GET_STATION] = "get_station", + [NL80211_CMD_SET_STATION] = "set_station", + [NL80211_CMD_NEW_STATION] = "new_station", + [NL80211_CMD_DEL_STATION] = "del_station", + [NL80211_CMD_GET_MPATH] = "get_mpath", + [NL80211_CMD_SET_MPATH] = "set_mpath", + [NL80211_CMD_NEW_MPATH] = "new_mpath", + [NL80211_CMD_DEL_MPATH] = "del_mpath", + [NL80211_CMD_SET_BSS] = "set_bss", + [NL80211_CMD_SET_REG] = "set_reg", + [NL80211_CMD_REQ_SET_REG] = "reg_set_reg", + [NL80211_CMD_GET_MESH_PARAMS] = "get_mesh_params", + [NL80211_CMD_SET_MESH_PARAMS] = "set_mesh_params", + [NL80211_CMD_SET_MGMT_EXTRA_IE] = "set_mgmt_extra_ie", + [NL80211_CMD_GET_REG] = "get_reg", + [NL80211_CMD_GET_SCAN] = "get_scan", + [NL80211_CMD_TRIGGER_SCAN] = "trigger_scan", + [NL80211_CMD_NEW_SCAN_RESULTS] = "new_scan_results", + [NL80211_CMD_SCAN_ABORTED] = "scan_aborted", + [NL80211_CMD_REG_CHANGE] = "reg_change", + [NL80211_CMD_AUTHENTICATE] = "authenticate", + [NL80211_CMD_ASSOCIATE] = "associate", + [NL80211_CMD_DEAUTHENTICATE] = "deauthenticate", + [NL80211_CMD_DISASSOCIATE] = "disassociate", + [NL80211_CMD_MICHAEL_MIC_FAILURE] = "michael_mic_failure", + [NL80211_CMD_REG_BEACON_HINT] = "reg_beacon_hint", + [NL80211_CMD_JOIN_IBSS] = "join_ibss", + [NL80211_CMD_LEAVE_IBSS] = "leave_ibss", + [NL80211_CMD_TESTMODE] = "testmode", + [NL80211_CMD_CONNECT] = "connect", + [NL80211_CMD_ROAM] = "roam", + [NL80211_CMD_DISCONNECT] = "disconnect", + [NL80211_CMD_SET_WIPHY_NETNS] = "set_wiphy_netns", + [NL80211_CMD_GET_SURVEY] = "get_survey", + [NL80211_CMD_SET_PMKSA] = "set_pmksa", + [NL80211_CMD_DEL_PMKSA] = "del_pmksa", + [NL80211_CMD_FLUSH_PMKSA] = "flush_pmksa", + [NL80211_CMD_REMAIN_ON_CHANNEL] = "remain_on_channel", + [NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL] = "cancel_remain_on_channel", + [NL80211_CMD_SET_TX_BITRATE_MASK] = "set_tx_bitrate_mask", + [NL80211_CMD_REGISTER_ACTION] = "register_action", + [NL80211_CMD_ACTION] = "action", + [NL80211_CMD_SET_CHANNEL] = "set_channel", + [NL80211_CMD_SET_WDS_PEER] = "set_wds_peer", + [NL80211_CMD_FRAME_WAIT_CANCEL] = "frame_wait_cancel", + [NL80211_CMD_JOIN_MESH] = "join_mesh", + [NL80211_CMD_LEAVE_MESH] = "leave_mesh", + [NL80211_CMD_SET_REKEY_OFFLOAD] = "set_rekey_offload", +}; + +static char cmdbuf[100]; + +const char *command_name(enum nl80211_commands cmd) +{ + if (cmd <= NL80211_CMD_MAX && commands[cmd]) + return commands[cmd]; + sprintf(cmdbuf, "Unknown command (%d)", cmd); + return cmdbuf; +} + +int ieee80211_channel_to_frequency(int chan) +{ + if (chan < 14) + return 2407 + chan * 5; + + if (chan == 14) + return 2484; + + /* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */ + return (chan + 1000) * 5; +} + +int ieee80211_frequency_to_channel(int freq) +{ + if (freq == 2484) + return 14; + + if (freq < 2484) + return (freq - 2407) / 5; + + /* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */ + return freq/5 - 1000; +} + +void print_ssid_escaped(const uint8_t len, const uint8_t *data) +{ + int i; + + for (i = 0; i < len; i++) { + if (isprint(data[i])) + printf("%c", data[i]); + else + printf("\\x%.2x", data[i]); + } +} + +static int hex2num(char digit) +{ + if (!isxdigit(digit)) + return -1; + if (isdigit(digit)) + return digit - '0'; + return tolower(digit) - 'a' + 10; +} + +static int hex2byte(char *hex) +{ + int d1, d2; + + d1 = hex2num(hex[0]); + if (d1 < 0) + return -1; + d2 = hex2num(hex[1]); + if (d2 < 0) + return -1; + return (d1 << 4) | d2; +} + +static char *hex2bin(char *hex, char *buf) +{ + char *result = buf; + int d; + + while (hex[0]) { + d = hex2byte(hex); + if (d < 0) + return NULL; + buf[0] = d; + buf++; + hex += 2; + } + + return result; +} + +int parse_keys(struct nl_msg *msg, char **argv, int argc) +{ + struct nlattr *keys; + int i = 0; + bool have_default = false; + char keybuf[13]; + + if (!argc) + return 1; + + NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY); + + keys = nla_nest_start(msg, NL80211_ATTR_KEYS); + if (!keys) + return -ENOBUFS; + + do { + char *arg = *argv; + int pos = 0, keylen; + struct nlattr *key = nla_nest_start(msg, ++i); + char *keydata; + + if (!key) + return -ENOBUFS; + + if (arg[pos] == 'd') { + NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT); + pos++; + if (arg[pos] == ':') + pos++; + have_default = true; + } + + if (!isdigit(arg[pos])) + goto explain; + NLA_PUT_U8(msg, NL80211_KEY_IDX, arg[pos++] - '0'); + if (arg[pos++] != ':') + goto explain; + keydata = arg + pos; + switch (strlen(keydata)) { + case 10: + keydata = hex2bin(keydata, keybuf); + case 5: + NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC01); + keylen = 5; + break; + case 26: + keydata = hex2bin(keydata, keybuf); + case 13: + NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC05); + keylen = 13; + break; + default: + goto explain; + } + + if (!keydata) + goto explain; + + NLA_PUT(msg, NL80211_KEY_DATA, keylen, keydata); + + argv++; + argc--; + + /* one key should be TX key */ + if (!have_default && !argc) + NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT); + + nla_nest_end(msg, key); + } while (argc); + + nla_nest_end(msg, keys); + + return 0; + nla_put_failure: + return -ENOBUFS; + explain: + fprintf(stderr, "key must be [d:]index:data where\n" + " 'd:' means default (transmit) key\n" + " 'index:' is a single digit (0-3)\n" + " 'data' must be 5 or 13 ascii chars\n" + " or 10 or 26 hex digits\n" + "for example: d:2:6162636465 is the same as d:2:abcde\n"); + return 2; +} + +static void print_mcs_index(const __u8 *mcs) +{ + unsigned int mcs_bit, prev_bit = -2, prev_cont = 0; + + for (mcs_bit = 0; mcs_bit <= 76; mcs_bit++) { + unsigned int mcs_octet = mcs_bit/8; + unsigned int MCS_RATE_BIT = 1 << mcs_bit % 8; + bool mcs_rate_idx_set; + + mcs_rate_idx_set = !!(mcs[mcs_octet] & MCS_RATE_BIT); + + if (!mcs_rate_idx_set) + continue; + + if (prev_bit != mcs_bit - 1) { + if (prev_bit != -2) + printf("%d, ", prev_bit); + else + printf(" "); + printf("%d", mcs_bit); + prev_cont = 0; + } else if (!prev_cont) { + printf("-"); + prev_cont = 1; + } + + prev_bit = mcs_bit; + } + + if (prev_cont) + printf("%d", prev_bit); + printf("\n"); +} + +/* + * There are only 4 possible values, we just use a case instead of computing it, + * but technically this can also be computed through the formula: + * + * Max AMPDU length = (2 ^ (13 + exponent)) - 1 bytes + */ +static __u32 compute_ampdu_length(__u8 exponent) +{ + switch (exponent) { + case 0: return 8191; /* (2 ^(13 + 0)) -1 */ + case 1: return 16383; /* (2 ^(13 + 1)) -1 */ + case 2: return 32767; /* (2 ^(13 + 2)) -1 */ + case 3: return 65535; /* (2 ^(13 + 3)) -1 */ + default: return 0; + } +} + +static const char *print_ampdu_space(__u8 space) +{ + switch (space) { + case 0: return "No restriction"; + case 1: return "1/4 usec"; + case 2: return "1/2 usec"; + case 3: return "1 usec"; + case 4: return "2 usec"; + case 5: return "4 usec"; + case 6: return "8 usec"; + case 7: return "16 usec"; + default: + return "BUG (spacing more than 3 bits!)"; + } +} + +void print_ampdu_length(__u8 exponent) +{ + __u32 max_ampdu_length; + + max_ampdu_length = compute_ampdu_length(exponent); + + if (max_ampdu_length) { + printf("\t\tMaximum RX AMPDU length %d bytes (exponent: 0x0%02x)\n", + max_ampdu_length, exponent); + } else { + printf("\t\tMaximum RX AMPDU length: unrecognized bytes " + "(exponent: %d)\n", exponent); + } +} + +void print_ampdu_spacing(__u8 spacing) +{ + printf("\t\tMinimum RX AMPDU time spacing: %s (0x%02x)\n", + print_ampdu_space(spacing), spacing); +} + +void print_ht_capability(__u16 cap) +{ +#define PRINT_HT_CAP(_cond, _str) \ + do { \ + if (_cond) \ + printf("\t\t\t" _str "\n"); \ + } while (0) + + printf("\t\tCapabilities: 0x%02x\n", cap); + + PRINT_HT_CAP((cap & BIT(0)), "RX LDPC"); + PRINT_HT_CAP((cap & BIT(1)), "HT20/HT40"); + PRINT_HT_CAP(!(cap & BIT(1)), "HT20"); + + PRINT_HT_CAP(((cap >> 2) & 0x3) == 0, "Static SM Power Save"); + PRINT_HT_CAP(((cap >> 2) & 0x3) == 1, "Dynamic SM Power Save"); + PRINT_HT_CAP(((cap >> 2) & 0x3) == 3, "SM Power Save disabled"); + + PRINT_HT_CAP((cap & BIT(4)), "RX Greenfield"); + PRINT_HT_CAP((cap & BIT(5)), "RX HT20 SGI"); + PRINT_HT_CAP((cap & BIT(6)), "RX HT40 SGI"); + PRINT_HT_CAP((cap & BIT(7)), "TX STBC"); + + PRINT_HT_CAP(((cap >> 8) & 0x3) == 0, "No RX STBC"); + PRINT_HT_CAP(((cap >> 8) & 0x3) == 1, "RX STBC 1-stream"); + PRINT_HT_CAP(((cap >> 8) & 0x3) == 2, "RX STBC 2-streams"); + PRINT_HT_CAP(((cap >> 8) & 0x3) == 3, "RX STBC 3-streams"); + + PRINT_HT_CAP((cap & BIT(10)), "HT Delayed Block Ack"); + + PRINT_HT_CAP(!(cap & BIT(11)), "Max AMSDU length: 3839 bytes"); + PRINT_HT_CAP((cap & BIT(11)), "Max AMSDU length: 7935 bytes"); + + /* + * For beacons and probe response this would mean the BSS + * does or does not allow the usage of DSSS/CCK HT40. + * Otherwise it means the STA does or does not use + * DSSS/CCK HT40. + */ + PRINT_HT_CAP((cap & BIT(12)), "DSSS/CCK HT40"); + PRINT_HT_CAP(!(cap & BIT(12)), "No DSSS/CCK HT40"); + + /* BIT(13) is reserved */ + + PRINT_HT_CAP((cap & BIT(14)), "40 MHz Intolerant"); + + PRINT_HT_CAP((cap & BIT(15)), "L-SIG TXOP protection"); +#undef PRINT_HT_CAP +} + +void print_ht_mcs(const __u8 *mcs) +{ + /* As defined in 7.3.2.57.4 Supported MCS Set field */ + unsigned int tx_max_num_spatial_streams, max_rx_supp_data_rate; + bool tx_mcs_set_defined, tx_mcs_set_equal, tx_unequal_modulation; + + max_rx_supp_data_rate = ((mcs[10] >> 8) & ((mcs[11] & 0x3) << 8)); + tx_mcs_set_defined = !!(mcs[12] & (1 << 0)); + tx_mcs_set_equal = !(mcs[12] & (1 << 1)); + tx_max_num_spatial_streams = ((mcs[12] >> 2) & 3) + 1; + tx_unequal_modulation = !!(mcs[12] & (1 << 4)); + + if (max_rx_supp_data_rate) + printf("\t\tHT Max RX data rate: %d Mbps\n", max_rx_supp_data_rate); + /* XXX: else see 9.6.0e.5.3 how to get this I think */ + + if (tx_mcs_set_defined) { + if (tx_mcs_set_equal) { + printf("\t\tHT TX/RX MCS rate indexes supported:"); + print_mcs_index(mcs); + } else { + printf("\t\tHT RX MCS rate indexes supported:"); + print_mcs_index(mcs); + + if (tx_unequal_modulation) + printf("\t\tTX unequal modulation supported\n"); + else + printf("\t\tTX unequal modulation not supported\n"); + + printf("\t\tHT TX Max spatial streams: %d\n", + tx_max_num_spatial_streams); + + printf("\t\tHT TX MCS rate indexes supported may differ\n"); + } + } else { + printf("\t\tHT RX MCS rate indexes supported:"); + print_mcs_index(mcs); + printf("\t\tHT TX MCS rate indexes are undefined\n"); + } +}
diff --git a/iw_0.9.22/iw_0.9.22/version.sh b/iw_0.9.22/iw_0.9.22/version.sh new file mode 100755 index 0000000..b6f929a --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/version.sh
@@ -0,0 +1,20 @@ +#!/bin/sh + +VERSION="0.9.22" + +SUFFIX= +if test "x$1" = x--suffix; then + shift + SUFFIX="-$1" + shift +fi +OUT="$1" + +if test "x$SUFFIX" != 'x'; then + v="$VERSION$SUFFIX" +else + v="$VERSION" +fi + +echo '#include "iw.h"' > "$OUT" +echo "const char iw_version[] = \"$v\";" >> "$OUT"
diff --git a/iw_0.9.22/iw_0.9.22/wowlan.c b/iw_0.9.22/iw_0.9.22/wowlan.c new file mode 100644 index 0000000..fa33c1f --- /dev/null +++ b/iw_0.9.22/iw_0.9.22/wowlan.c
@@ -0,0 +1,196 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(wowlan); + +static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + struct nlattr *wowlan, *pattern; + struct nl_msg *patterns = NULL; + enum { + PS_REG, + PS_PAT, + } parse_state = PS_REG; + int err = -ENOBUFS; + unsigned char *pat, *mask; + size_t patlen; + int patnum = 0; + + wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); + if (!wowlan) + return -ENOBUFS; + + while (argc) { + switch (parse_state) { + case PS_REG: + if (strcmp(argv[0], "any") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); + else if (strcmp(argv[0], "disconnect") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); + else if (strcmp(argv[0], "magic-packet") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); + else if (strcmp(argv[0], "gtk-rekey-failure") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); + else if (strcmp(argv[0], "eap-identity-request") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); + else if (strcmp(argv[0], "4way-handshake") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); + else if (strcmp(argv[0], "rfkill-release") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); + else if (strcmp(argv[0], "patterns") == 0) { + parse_state = PS_PAT; + patterns = nlmsg_alloc(); + if (!patterns) { + err = -ENOMEM; + goto nla_put_failure; + } + } else { + err = 1; + goto nla_put_failure; + } + break; + case PS_PAT: + if (parse_hex_mask(argv[0], &pat, &patlen, &mask)) { + err = 1; + goto nla_put_failure; + } + pattern = nla_nest_start(patterns, ++patnum); + NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_MASK, + DIV_ROUND_UP(patlen, 8), mask); + NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_PATTERN, + patlen, pat); + nla_nest_end(patterns, pattern); + free(mask); + free(pat); + break; + } + argv++; + argc--; + } + + if (patterns) + nla_put_nested(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, + patterns); + + nla_nest_end(msg, wowlan); + err = 0; + nla_put_failure: + nlmsg_free(patterns); + return err; +} +COMMAND(wowlan, enable, "[any] [disconnect] [magic-packet] [gtk-rekey-failure] [eap-identity-request]" + " [4way-handshake] [rfkill-release] [patterns <pattern>*]", + NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_enable, + "Enable WoWLAN with the given triggers.\n" + "Each pattern is given as a bytestring with '-' in places where any byte\n" + "may be present, e.g. 00:11:22:-:44 will match 00:11:22:33:44 and\n" + "00:11:22:33:ff:44 etc."); + + +static int handle_wowlan_disable(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + /* just a set w/o wowlan attribute */ + return 0; +} +COMMAND(wowlan, disable, "", NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_disable, + "Disable WoWLAN."); + + +static int print_wowlan_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *pattern; + int rem_pattern; + + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { + printf("WoWLAN is disabled.\n"); + return NL_SKIP; + } + + /* XXX: use policy */ + nla_parse(trig, MAX_NL80211_WOWLAN_TRIG, + nla_data(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + nla_len(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + NULL); + + printf("WoWLAN is enabled:\n"); + if (trig[NL80211_WOWLAN_TRIG_ANY]) + printf(" * wake up on special any trigger\n"); + if (trig[NL80211_WOWLAN_TRIG_DISCONNECT]) + printf(" * wake up on disconnect\n"); + if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT]) + printf(" * wake up on magic packet\n"); + if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) + printf(" * wake up on GTK rekeying failure\n"); + if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) + printf(" * wake up on EAP identity request\n"); + if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) + printf(" * wake up on 4-way handshake\n"); + if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) + printf(" * wake up on RF-kill release\n"); + if (trig[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { + nla_for_each_nested(pattern, + trig[NL80211_WOWLAN_TRIG_PKT_PATTERN], + rem_pattern) { + struct nlattr *patattr[NUM_NL80211_WOWLAN_PKTPAT]; + int i, patlen, masklen; + uint8_t *mask, *pat; + nla_parse(patattr, MAX_NL80211_WOWLAN_PKTPAT, + nla_data(pattern), nla_len(pattern), + NULL); + if (!patattr[NL80211_WOWLAN_PKTPAT_MASK] || + !patattr[NL80211_WOWLAN_PKTPAT_PATTERN]) { + printf(" * (invalid pattern specification)\n"); + continue; + } + masklen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_MASK]); + patlen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]); + if (DIV_ROUND_UP(patlen, 8) != masklen) { + printf(" * (invalid pattern specification)\n"); + continue; + } + printf(" * wake up on pattern: "); + pat = nla_data(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]); + mask = nla_data(patattr[NL80211_WOWLAN_PKTPAT_MASK]); + for (i = 0; i < patlen; i++) { + if (mask[i / 8] & (1 << (i % 8))) + printf("%.2x", pat[i]); + else + printf("--"); + if (i != patlen - 1) + printf(":"); + } + printf("\n"); + } + } + + return NL_SKIP; +} + +static int handle_wowlan_show(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_wowlan_handler, NULL); + + return 0; +} +COMMAND(wowlan, show, "", NL80211_CMD_GET_WOWLAN, 0, CIB_PHY, handle_wowlan_show, + "Show WoWLAN status.");
diff --git a/iw_3.10/iw_3.10.patches/iw-50.description b/iw_3.10/iw_3.10.patches/iw-50.description new file mode 100644 index 0000000..ec9fb0f --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-50.description
@@ -0,0 +1,3 @@ +This patch synchronizes the version script with the like script from the rfkill package and eliminates the GIT repository label version +checking because it will invariably fail when the package is included as a subtree or submodule of a larger GIT repository. +
diff --git a/iw_3.10/iw_3.10.patches/iw-50.patch b/iw_3.10/iw_3.10.patches/iw-50.patch new file mode 100644 index 0000000..364439b --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-50.patch
@@ -0,0 +1,33 @@ +diff -aruN iw-3.10/version.sh iw-3.10.n/version.sh +--- iw-3.10/version.sh 2013-05-02 00:29:10.000000000 -0700 ++++ iw-3.10.n/version.sh 2015-03-24 12:24:03.355548918 -0700 +@@ -1,20 +1,17 @@ + #!/bin/sh + + VERSION="3.10" +-OUT="$1" +- +-if head=`git rev-parse --verify HEAD 2>/dev/null`; then +- git update-index --refresh --unmerged > /dev/null +- descr=$(git describe) + +- # on git builds check that the version number above +- # is correct... +- [ "${descr%%-*}" = "v$VERSION" ] || exit 2 ++SUFFIX= ++if test "x$1" = x--suffix; then ++ shift ++ SUFFIX="-$1" ++ shift ++fi ++OUT="$1" + +- v="${descr#v}" +- if git diff-index --name-only HEAD | read dummy ; then +- v="$v"-dirty +- fi ++if test "x$SUFFIX" != 'x'; then ++ v="$VERSION$SUFFIX" + else + v="$VERSION" + fi
diff --git a/iw_3.10/iw_3.10.patches/iw-51.description b/iw_3.10/iw_3.10.patches/iw-51.description new file mode 100644 index 0000000..7edbcbe --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-51.description
@@ -0,0 +1 @@ +This patch allows the package builder to specify the libnl version being built against externally to pkg-config.
diff --git a/iw_3.10/iw_3.10.patches/iw-51.patch b/iw_3.10/iw_3.10.patches/iw-51.patch new file mode 100644 index 0000000..471d120 --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-51.patch
@@ -0,0 +1,82 @@ +diff -aruN iw-3.10/Makefile iw-3.10.n/Makefile +--- iw-3.10/Makefile 2013-05-02 00:29:10.000000000 -0700 ++++ iw-3.10.n/Makefile 2015-03-24 12:35:45.731563338 -0700 +@@ -25,6 +25,31 @@ + + ALL = iw + ++ifdef NLLIBNAME ++ ++NLLIBS = -lnl ++ ++ifeq ($(NLLIBNAME),libnl-1) ++NL1FOUND := Y ++endif ++ ++ifeq ($(NLLIBNAME),libnl-2.0) ++NL2FOUND := Y ++endif ++ ++ifdef NLCFLAGS ++CFLAGS += $(NLCFLAGS) ++endif ++ ++ifdef NLLDFLAGS ++LDFLAGS += $(NLLDFLAGS) ++endif ++ ++ifdef NLLIBS ++LIBS += $(NLLIBS) ++endif ++ ++else + ifeq ($(NO_PKG_CONFIG),) + NL3xFOUND := $(shell $(PKG_CONFIG) --atleast-version=3.2 libnl-3.0 && echo Y) + ifneq ($(NL3xFOUND),Y) +@@ -39,14 +64,13 @@ + endif + endif + endif ++endif + + ifeq ($(NL1FOUND),Y) + NLLIBNAME = libnl-1 + endif + + ifeq ($(NL2FOUND),Y) +-CFLAGS += -DCONFIG_LIBNL20 +-LIBS += -lnl-genl + NLLIBNAME = libnl-2.0 + endif + +@@ -80,6 +104,11 @@ + CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME)) + endif # NO_PKG_CONFIG + ++ifeq ($(NL2FOUND),Y) ++CFLAGS += -DCONFIG_LIBNL20 ++LIBS += -lnl-genl ++endif ++ + ifeq ($(V),1) + Q= + NQ=true +@@ -88,7 +117,17 @@ + NQ=echo + endif + +-all: $(ALL) ++all: version_check $(ALL) ++ ++version_check: ++ifeq ($(NL2FOUND),Y) ++else ++ifeq ($(NL1FOUND),Y) ++else ++ $(error No libnl found) ++endif ++endif ++ + + VERSION_OBJS := $(filter-out version.o, $(OBJS)) +
diff --git a/iw_3.10/iw_3.10.patches/iw-52.description b/iw_3.10/iw_3.10.patches/iw-52.description new file mode 100644 index 0000000..7157b47 --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-52.description
@@ -0,0 +1 @@ +This patch adds the ability to add/delete/start/stop device side tcp keep alives using iw
diff --git a/iw_3.10/iw_3.10.patches/iw-52.patch b/iw_3.10/iw_3.10.patches/iw-52.patch new file mode 100644 index 0000000..dc07013 --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-52.patch
@@ -0,0 +1,329 @@ +diff -aruN iw-3.10/keepalive.c iw-3.10.n/keepalive.c +--- iw-3.10/keepalive.c 1969-12-31 16:00:00.000000000 -0800 ++++ iw-3.10.n/keepalive.c 2015-03-24 12:39:02.019567368 -0700 +@@ -0,0 +1,286 @@ ++#include <net/if.h> ++#include <errno.h> ++#include <string.h> ++#include <stdlib.h> ++ ++#include <netlink/genl/genl.h> ++#include <netlink/genl/family.h> ++#include <netlink/genl/ctrl.h> ++#include <netlink/msg.h> ++#include <netlink/attr.h> ++ ++#include "nl80211.h" ++#include "iw.h" ++ ++typedef uint8_t u8; ++typedef uint16_t u16; ++typedef uint32_t u32; ++ ++#define CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH 64 ++ ++struct cfg80211_keepalive_request { ++ u32 interval; ++ u8 cmd; /* 0: ADD; 1: DEL: 2: START; 3: STOP */ ++ u8 index; ++ u8 trig; ++ u8 dst_macaddr[ETH_ALEN]; ++ u8 payload_len; ++ u8 payload[CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH]; ++}; ++ ++struct cfg80211_keepalive_request keepalive_req; ++ ++SECTION(keepalive); ++ ++static void keepalive_hex_dump(char *title, u8 *buf, size_t len) ++{ ++ int i; ++ ++ printf("%s - hexdump(len=%lu):", title, (unsigned long) len); ++ ++ for (i = 0; i < len; i++) ++ printf(" %02x", buf[i]); ++ printf("\n"); ++} ++ ++static int nl80211_parse_klv_req(const char *s) ++{ ++ long i; ++ char *endp; ++ ++ i = strtol(s, &endp, 10); ++ ++ if(endp == s) ++ return -1; ++ return i; ++} ++ ++static int nl80211_str2hex(u8 *src, u8 *dst, int src_len) ++{ ++ int i, bytecount=0; ++ ++ if (src_len & 0x01) ++ return -2; ++ ++ for (i=0; i<src_len; i++, src++) { ++ if (i != 0 && i%2 == 0) { ++ dst++; ++ bytecount++; ++ } else { ++ *dst <<= 4; ++ } ++ ++ if ((*src >= '0') && (*src <= '9')) ++ *dst += *src - '0'; ++ else if ((*src >= 'A') && (*src <= 'F')) ++ *dst += *src - 'A' + 10; ++ else if ((*src >= 'a') && (*src <= 'f')) ++ *dst += *src - 'a' + 10; ++ else { ++ return -1; ++ } ++ } ++ ++ bytecount++; ++ ++ return bytecount; ++} ++ ++static int build_klv_req(struct nl_msg *msg, int klv_cmd, u8 index, int interval, u8 trig, u8 *dst_macaddr, u8 payload_len, u8 *payload) ++{ ++ int ret = -1; ++ ++ if (!msg) ++ return -1; ++ ++ NLA_PUT_U32(msg, NL80211_ATTR_KLV_TYPE, klv_cmd); ++ NLA_PUT_U32(msg, NL80211_ATTR_KLV_INDEX, index); ++ ++ if (klv_cmd == 0 || klv_cmd == 1) { ++ ++ NLA_PUT_U32(msg, NL80211_ATTR_KLV_INTVL, interval); ++ NLA_PUT_U32 (msg, NL80211_ATTR_KLV_TRIG, trig); ++ ++ if (payload != NULL) { ++ if (dst_macaddr) { ++ keepalive_hex_dump("nl80211 klv_dstmac: ", dst_macaddr, ETH_ALEN); ++ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst_macaddr); ++ } ++ ++ keepalive_hex_dump("nl80211 klv_payload: ", payload, payload_len); ++ NLA_PUT(msg, NL80211_ATTR_KLV_PAYLOAD, payload_len, payload); ++ } ++ } ++ ++ ret = 0; ++ ++ nla_put_failure: ++ return ret; ++} ++ ++static int nl80211_change_klv_req(char **cmdptr, int cmdtype, struct nl_msg *msg) ++{ ++ u8 index = 1, trig_type = 1, payload_len = 0; ++ u8 dst_macaddr[ETH_ALEN]; ++ u32 interval_ms = 10; ++ int val; ++ u8 dst_payload[64]; ++ ++ switch(cmdtype) { ++ case 0: /* KLV-ADD */ ++ val = nl80211_parse_klv_req(*cmdptr++); ++ /* valid index # is [1, 3]. Index #0 is reserved for driver internal use */ ++ if (val <= 0 || val > 3) { ++ printf("invalid index (%d)\n", val); ++ return -1; ++ } ++ index = val; ++ ++ val = nl80211_parse_klv_req(*cmdptr++); ++ /* limit klv interval to [10 ms, 50000 ms] */ ++ if (val < 1000 || val > 55000) { ++ printf("Keeplalive interval is out of range.\n"); ++ return -1; ++ } ++ interval_ms = val; ++ ++ val = nl80211_parse_klv_req(*cmdptr++); ++ /* valid trig type is limited to 0 or 1 */ ++ if (val < 0 || val > 1) { ++ printf("Invalid keepalive trigger type.\n"); ++ return -1; ++ } ++ trig_type = val; ++ ++ memset(dst_macaddr, 0, ETH_ALEN); ++ if (nl80211_str2hex((u8 *)(*cmdptr++), dst_macaddr, 2*ETH_ALEN) <= 0) { ++ printf("Invalid mac address\n"); ++ return -1; ++ } ++ ++ val = strlen(*cmdptr); /* klv payload length must be <= 64 bytes */ ++ if (val > 128) { ++ printf("Payload is too long\n"); ++ return -1; ++ } ++ ++ memset(dst_payload, 0, 64); ++ if ((payload_len=nl80211_str2hex((u8 *)(*cmdptr), dst_payload, val)) < 0) { ++ printf("Keepalive payload is invalid\n"); ++ return -1; ++ } ++ ++ break; ++ ++ case 1: /* KLV-DEL */ ++ index = nl80211_parse_klv_req(cmdptr[0]); ++ printf("index = %d\n", index); ++ /* index #0 is reserved for driver internal klv type */ ++ if (index <= 0 || index > 3) { ++ return -1; ++ } ++ ++ interval_ms = 10000; ++ break; ++ ++ case 2: /* KLV-START */ ++ case 3: /* KLV-STOP */ ++ break; ++ ++ case 4: /* KLV-SHOW */ ++ printf("Not supported\n"); ++ val = 0; ++ return val; ++ ++ default: ++ return -1; ++ } ++ ++ val = build_klv_req(msg, cmdtype, index, interval_ms, trig_type, &dst_macaddr[0], payload_len, dst_payload); ++ ++ return val; ++} ++ ++static int handle_keepalive_add(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv, enum id_input id) ++{ ++ int ret; ++ ++ if (argc != 5) { ++ printf("Command parameters incorrect.\n"); ++ return -1; ++ } ++ ++ ret = nl80211_change_klv_req(argv, 0, msg); ++ printf("ret is %d\n", ret); ++ return ret; ++} ++ ++static int handle_keepalive_delete(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv, enum id_input id) ++{ ++ int ret; ++ ++ if (argc != 1) { ++ printf("Command parameters incorrect.\n"); ++ return -1; ++ } ++ ++ ret = nl80211_change_klv_req(argv, 1, msg); ++ return ret; ++} ++ ++static int handle_keepalive_start(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv, enum id_input id) ++{ ++ int ret; ++ ret = nl80211_change_klv_req(argv, 2, msg); ++ return ret; ++} ++ ++static int handle_keepalive_stop(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv, enum id_input id) ++{ ++ int ret; ++ ret = nl80211_change_klv_req(argv, 3, msg); ++ return ret; ++} ++ ++static int print_keepalive_handler(struct nl_msg *msg, void *arg) ++{ ++ int *ret = arg; ++ if (arg != NULL) ++ *ret = 0; ++ return 0; ++} ++ ++static int handle_keepalive_show(struct nl80211_state *state, struct nl_cb *cb, ++ struct nl_msg *msg, int argc, char **argv, enum id_input id) ++{ ++ int ret; ++ ++ printf("handle_keepalive_show\n"); ++ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, ++ print_keepalive_handler, &ret); ++ ++ return 0; ++} ++ ++COMMAND(keepalive, add, "<index> <interval> <trigger_type> <dst_macaddr> <payload>", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_add, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, del, "<index>", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_delete, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, start, "", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_start, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, stop, "", ++ NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_stop, ++ "Configure keep alive feature"); ++ ++COMMAND(keepalive, show, "", NL80211_CMD_GET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_show, ++ "Show keepalive status."); +diff -aruN iw-3.10/Makefile iw-3.10.n/Makefile +--- iw-3.10/Makefile 2015-03-24 12:38:14.411566390 -0700 ++++ iw-3.10.n/Makefile 2015-03-24 12:39:23.491567809 -0700 +@@ -16,7 +16,7 @@ + interface.o ibss.o station.o survey.o util.o \ + mesh.o mpath.o scan.o reg.o version.o \ + reason.o status.o connect.o link.o offch.o ps.o cqm.o \ +- bitrate.o wowlan.o roc.o p2p.o ++ bitrate.o wowlan.o roc.o p2p.o keepalive.o + OBJS += sections.o + + OBJS-$(HWSIM) += hwsim.o +diff -aruN iw-3.10/nl80211.h iw-3.10.n/nl80211.h +--- iw-3.10/nl80211.h 2013-05-02 00:29:10.000000000 -0700 ++++ iw-3.10.n/nl80211.h 2015-03-24 12:43:33.115572934 -0700 +@@ -772,6 +772,9 @@ + + NL80211_CMD_SET_REKEY_OFFLOAD, + ++ NL80211_CMD_GET_KEEPALIVE, ++ NL80211_CMD_SET_KEEPALIVE, ++ + NL80211_CMD_PMKSA_CANDIDATE, + + NL80211_CMD_TDLS_OPER, +@@ -1727,6 +1730,13 @@ + NL80211_ATTR_CRIT_PROT_ID, + NL80211_ATTR_MAX_CRIT_PROT_DURATION, + ++ NL80211_ATTR_KLVDATA, ++ NL80211_ATTR_KLV_TYPE, ++ NL80211_ATTR_KLV_INTVL, ++ NL80211_ATTR_KLV_INDEX, ++ NL80211_ATTR_KLV_TRIG, ++ NL80211_ATTR_KLV_PAYLOAD, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST,
diff --git a/iw_3.10/iw_3.10.patches/iw-53.description b/iw_3.10/iw_3.10.patches/iw-53.description new file mode 100644 index 0000000..3a401f0 --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-53.description
@@ -0,0 +1 @@ +Add the enums for drop action for wow filters. iw latest version still does not define these enumerations. These defines are taken from nl80211.h sitting in compat-wireless directory.
diff --git a/iw_3.10/iw_3.10.patches/iw-53.patch b/iw_3.10/iw_3.10.patches/iw-53.patch new file mode 100644 index 0000000..c1009bf --- /dev/null +++ b/iw_3.10/iw_3.10.patches/iw-53.patch
@@ -0,0 +1,36 @@ +diff --git a/nl80211.h b/nl80211.h +index 7ba71e4..3ef44f1 100644 +--- a/nl80211.h ++++ b/nl80211.h +@@ -2222,12 +2222,30 @@ enum nl80211_wowlan_packet_pattern_attr { + __NL80211_WOWLAN_PKTPAT_INVALID, + NL80211_WOWLAN_PKTPAT_MASK, + NL80211_WOWLAN_PKTPAT_PATTERN, + NL80211_WOWLAN_PKTPAT_OFFSET, ++ NL80211_WOWLAN_PKTPAT_ACTION = NL80211_WOWLAN_PKTPAT_OFFSET + 10, + + NUM_NL80211_WOWLAN_PKTPAT, + MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, + }; + + /** ++ * enum nl80211_wowlan_action - WoWLAN packet pattern action ++ * @NL80211_WOWLAN_ACTION_ALLOW: this pattern should wake up the host ++ * and the packet should be forwarded to the host unless this packet ++ * matches a DROP rule. ++ * @NL80211_WOWLAN_ACTION_DROP: a packet containing this pattern shouldn't ++ * wake up the host. ++ */ ++enum nl80211_wowlan_action { ++ NL80211_WOWLAN_ACTION_ALLOW, ++ NL80211_WOWLAN_ACTION_DROP, ++ ++ /* keep last */ ++ NUM_NL80211_WOWLAN_ACTION, ++ MAX_NL80211_WOWLAN_ACTION = NUM_NL80211_WOWLAN_ACTION - 1, ++}; ++ ++/** + * struct nl80211_wowlan_pattern_support - pattern support information + * @max_patterns: maximum number of patterns supported + * @min_pattern_len: minimum length of each pattern
diff --git a/iw_3.10/iw_3.10.tar.bz2 b/iw_3.10/iw_3.10.tar.bz2 new file mode 100644 index 0000000..686eea5 --- /dev/null +++ b/iw_3.10/iw_3.10.tar.bz2 Binary files differ
diff --git a/iw_3.10/iw_3.10.version b/iw_3.10/iw_3.10.version new file mode 100644 index 0000000..14ab818 --- /dev/null +++ b/iw_3.10/iw_3.10.version
@@ -0,0 +1 @@ +fe424b2465118eca166b2e901b5a378bf9582fb0
diff --git a/iw_3.10/iw_3.10/Android.mk b/iw_3.10/iw_3.10/Android.mk new file mode 100644 index 0000000..8afda1d --- /dev/null +++ b/iw_3.10/iw_3.10/Android.mk
@@ -0,0 +1,25 @@ +LOCAL_PATH := $(call my-dir) +IW_SOURCE_DIR := $(LOCAL_PATH) + +include $(CLEAR_VARS) + +NO_PKG_CONFIG=y +include $(LOCAL_PATH)/Makefile + +LOCAL_SRC_FILES := $(patsubst %.o,%.c,$(OBJS)) android-nl.c + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH) \ + external/libnl-headers/ + +LOCAL_CFLAGS += -DCONFIG_LIBNL20 +LOCAL_LDFLAGS := -Wl,--no-gc-sections +#LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_TAGS := eng +LOCAL_SHARED_LIBRARIES := libnl_2 +LOCAL_MODULE := iw + +$(IW_SOURCE_DIR)/version.c: + $(IW_SOURCE_DIR)/version.sh $(IW_SOURCE_DIR)/version.c + +include $(BUILD_EXECUTABLE)
diff --git a/iw_3.10/iw_3.10/COPYING b/iw_3.10/iw_3.10/COPYING new file mode 100644 index 0000000..73e19ac --- /dev/null +++ b/iw_3.10/iw_3.10/COPYING
@@ -0,0 +1,16 @@ +Copyright (c) 2007, 2008 Johannes Berg +Copyright (c) 2007 Andy Lutomirski +Copyright (c) 2007 Mike Kershaw +Copyright (c) 2008-2009 Luis R. Rodriguez + +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.
diff --git a/iw_3.10/iw_3.10/Makefile b/iw_3.10/iw_3.10/Makefile new file mode 100644 index 0000000..ba8d848 --- /dev/null +++ b/iw_3.10/iw_3.10/Makefile
@@ -0,0 +1,163 @@ +MAKEFLAGS += --no-print-directory + +PREFIX ?= /usr +SBINDIR ?= $(PREFIX)/sbin +MANDIR ?= $(PREFIX)/share/man +PKG_CONFIG ?= pkg-config + +MKDIR ?= mkdir -p +INSTALL ?= install +CC ?= "gcc" + +CFLAGS ?= -O2 -g +CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration + +OBJS = iw.o genl.o event.o info.o phy.o \ + interface.o ibss.o station.o survey.o util.o \ + mesh.o mpath.o scan.o reg.o version.o \ + reason.o status.o connect.o link.o offch.o ps.o cqm.o \ + bitrate.o wowlan.o roc.o p2p.o keepalive.o +OBJS += sections.o + +OBJS-$(HWSIM) += hwsim.o + +OBJS += $(OBJS-y) $(OBJS-Y) + +ALL = iw + +ifdef NLLIBNAME + +NLLIBS = -lnl + +ifeq ($(NLLIBNAME),libnl-1) +NL1FOUND := Y +endif + +ifeq ($(NLLIBNAME),libnl-2.0) +NL2FOUND := Y +endif + +ifdef NLCFLAGS +CFLAGS += $(NLCFLAGS) +endif + +ifdef NLLDFLAGS +LDFLAGS += $(NLLDFLAGS) +endif + +ifdef NLLIBS +LIBS += $(NLLIBS) +endif + +else +ifeq ($(NO_PKG_CONFIG),) +NL3xFOUND := $(shell $(PKG_CONFIG) --atleast-version=3.2 libnl-3.0 && echo Y) +ifneq ($(NL3xFOUND),Y) +NL31FOUND := $(shell $(PKG_CONFIG) --exact-version=3.1 libnl-3.1 && echo Y) +ifneq ($(NL31FOUND),Y) +NL3FOUND := $(shell $(PKG_CONFIG) --atleast-version=3 libnl-3.0 && echo Y) +ifneq ($(NL3FOUND),Y) +NL2FOUND := $(shell $(PKG_CONFIG) --atleast-version=2 libnl-2.0 && echo Y) +ifneq ($(NL2FOUND),Y) +NL1FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libnl-1 && echo Y) +endif +endif +endif +endif +endif + +ifeq ($(NL1FOUND),Y) +NLLIBNAME = libnl-1 +endif + +ifeq ($(NL2FOUND),Y) +NLLIBNAME = libnl-2.0 +endif + +ifeq ($(NL3xFOUND),Y) +# libnl 3.2 might be found as 3.2 and 3.0 +NL3FOUND = N +CFLAGS += -DCONFIG_LIBNL30 +LIBS += -lnl-genl-3 +NLLIBNAME = libnl-3.0 +endif + +ifeq ($(NL3FOUND),Y) +CFLAGS += -DCONFIG_LIBNL30 +LIBS += -lnl-genl +NLLIBNAME = libnl-3.0 +endif + +# nl-3.1 has a broken libnl-gnl-3.1.pc file +# as show by pkg-config --debug --libs --cflags --exact-version=3.1 libnl-genl-3.1;echo $? +ifeq ($(NL31FOUND),Y) +CFLAGS += -DCONFIG_LIBNL30 +LIBS += -lnl-genl +NLLIBNAME = libnl-3.1 +endif + +ifeq ($(NLLIBNAME),) +$(error Cannot find development files for any supported version of libnl) +endif + +LIBS += $(shell $(PKG_CONFIG) --libs $(NLLIBNAME)) +CFLAGS += $(shell $(PKG_CONFIG) --cflags $(NLLIBNAME)) +endif # NO_PKG_CONFIG + +ifeq ($(NL2FOUND),Y) +CFLAGS += -DCONFIG_LIBNL20 +LIBS += -lnl-genl +endif + +ifeq ($(V),1) +Q= +NQ=true +else +Q=@ +NQ=echo +endif + +all: version_check $(ALL) + +version_check: +ifeq ($(NL2FOUND),Y) +else +ifeq ($(NL1FOUND),Y) +else + $(error No libnl found) +endif +endif + + +VERSION_OBJS := $(filter-out version.o, $(OBJS)) + +version.c: version.sh $(patsubst %.o,%.c,$(VERSION_OBJS)) nl80211.h iw.h Makefile \ + $(wildcard .git/index .git/refs/tags) + @$(NQ) ' GEN ' $@ + $(Q)./version.sh $@ + +%.o: %.c iw.h nl80211.h + @$(NQ) ' CC ' $@ + $(Q)$(CC) $(CFLAGS) -c -o $@ $< + +iw: $(OBJS) + @$(NQ) ' CC ' iw + $(Q)$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o iw + +check: + $(Q)$(MAKE) all CC="REAL_CC=$(CC) CHECK=\"sparse -Wall\" cgcc" + +%.gz: % + @$(NQ) ' GZIP' $< + $(Q)gzip < $< > $@ + +install: iw iw.8.gz + @$(NQ) ' INST iw' + $(Q)$(MKDIR) $(DESTDIR)$(SBINDIR) + $(Q)$(INSTALL) -m 755 iw $(DESTDIR)$(SBINDIR) + @$(NQ) ' INST iw.8' + $(Q)$(MKDIR) $(DESTDIR)$(MANDIR)/man8/ + $(Q)$(INSTALL) -m 644 iw.8.gz $(DESTDIR)$(MANDIR)/man8/ + +clean: + $(Q)rm -f iw *.o *~ *.gz version.c *-stamp
diff --git a/iw_3.10/iw_3.10/README b/iw_3.10/iw_3.10/README new file mode 100644 index 0000000..1d0eaae --- /dev/null +++ b/iw_3.10/iw_3.10/README
@@ -0,0 +1,15 @@ + +This is 'iw', a tool to use nl80211. + + +To build iw, just enter 'make'. If that fails, set the +PKG_CONFIG_PATH environment variable to allow the Makefile +to find libnl. + + +'iw' is currently maintained at http://git.sipsolutions.net/iw.git/, +some more documentation is available at +http://wireless.kernel.org/en/users/Documentation/iw. + +Please send all patches to Johannes Berg <johannes@sipsolutions.net> +and CC linux-wireless@vger.kernel.org for community review.
diff --git a/iw_3.10/iw_3.10/android-nl.c b/iw_3.10/iw_3.10/android-nl.c new file mode 100644 index 0000000..d216f5f --- /dev/null +++ b/iw_3.10/iw_3.10/android-nl.c
@@ -0,0 +1,6 @@ +#include <netlink/attr.h> + +int nla_put_flag(struct nl_msg *msg, int flag) +{ + return nla_put(msg, flag, 0, NULL); +}
diff --git a/iw_3.10/iw_3.10/bitrate.c b/iw_3.10/iw_3.10/bitrate.c new file mode 100644 index 0000000..4da246f --- /dev/null +++ b/iw_3.10/iw_3.10/bitrate.c
@@ -0,0 +1,127 @@ +#include <errno.h> + +#include "nl80211.h" +#include "iw.h" + + +static int handle_bitrates(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + struct nlattr *nl_rates, *nl_band; + int i; + bool have_legacy_24 = false, have_legacy_5 = false; + uint8_t legacy_24[32], legacy_5[32]; + int n_legacy_24 = 0, n_legacy_5 = 0; + uint8_t *legacy = NULL; + int *n_legacy = NULL; + bool have_mcs_24 = false, have_mcs_5 = false; + uint8_t mcs_24[77], mcs_5[77]; + int n_mcs_24 = 0, n_mcs_5 = 0; + uint8_t *mcs = NULL; + int *n_mcs = NULL; + enum { + S_NONE, + S_LEGACY, + S_MCS, + } parser_state = S_NONE; + + for (i = 0; i < argc; i++) { + char *end; + double tmpd; + long tmpl; + + if (strcmp(argv[i], "legacy-2.4") == 0) { + if (have_legacy_24) + return 1; + parser_state = S_LEGACY; + legacy = legacy_24; + n_legacy = &n_legacy_24; + have_legacy_24 = true; + } else if (strcmp(argv[i], "legacy-5") == 0) { + if (have_legacy_5) + return 1; + parser_state = S_LEGACY; + legacy = legacy_5; + n_legacy = &n_legacy_5; + have_legacy_5 = true; + } + else if (strcmp(argv[i], "mcs-2.4") == 0) { + if (have_mcs_24) + return 1; + parser_state = S_MCS; + mcs = mcs_24; + n_mcs = &n_mcs_24; + have_mcs_24 = true; + } else if (strcmp(argv[i], "mcs-5") == 0) { + if (have_mcs_5) + return 1; + parser_state = S_MCS; + mcs = mcs_5; + n_mcs = &n_mcs_5; + have_mcs_5 = true; + } + else switch (parser_state) { + case S_LEGACY: + tmpd = strtod(argv[i], &end); + if (*end != '\0') + return 1; + if (tmpd < 1 || tmpd > 255 * 2) + return 1; + legacy[(*n_legacy)++] = tmpd * 2; + break; + case S_MCS: + tmpl = strtol(argv[i], &end, 0); + if (*end != '\0') + return 1; + if (tmpl < 0 || tmpl > 255) + return 1; + mcs[(*n_mcs)++] = tmpl; + break; + default: + return 1; + } + } + + nl_rates = nla_nest_start(msg, NL80211_ATTR_TX_RATES); + if (!nl_rates) + goto nla_put_failure; + + if (have_legacy_24 || have_mcs_24) { + nl_band = nla_nest_start(msg, NL80211_BAND_2GHZ); + if (!nl_band) + goto nla_put_failure; + if (have_legacy_24) + nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_24, legacy_24); + if (have_mcs_24) + nla_put(msg, NL80211_TXRATE_MCS, n_mcs_24, mcs_24); + nla_nest_end(msg, nl_band); + } + + if (have_legacy_5 || have_mcs_5) { + nl_band = nla_nest_start(msg, NL80211_BAND_5GHZ); + if (!nl_band) + goto nla_put_failure; + if (have_legacy_5) + nla_put(msg, NL80211_TXRATE_LEGACY, n_legacy_5, legacy_5); + if (have_mcs_5) + nla_put(msg, NL80211_TXRATE_MCS, n_mcs_5, mcs_5); + nla_nest_end(msg, nl_band); + } + + nla_nest_end(msg, nl_rates); + + return 0; + nla_put_failure: + return -ENOBUFS; +} + +#define DESCR_LEGACY "[legacy-<2.4|5> <legacy rate in Mbps>*]" +#define DESCR DESCR_LEGACY " [mcs-<2.4|5> <MCS index>*]" + +COMMAND(set, bitrates, "[legacy-<2.4|5> <legacy rate in Mbps>*] [mcs-<2.4|5> <MCS index>*]", + NL80211_CMD_SET_TX_BITRATE_MASK, 0, CIB_NETDEV, handle_bitrates, + "Sets up the specified rate masks.\n" + "Not passing any arguments would clear the existing mask (if any).");
diff --git a/iw_3.10/iw_3.10/connect.c b/iw_3.10/iw_3.10/connect.c new file mode 100644 index 0000000..74e4578 --- /dev/null +++ b/iw_3.10/iw_3.10/connect.c
@@ -0,0 +1,218 @@ +#include <errno.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int iw_conn(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + char *end; + unsigned char bssid[6]; + int freq; + + if (argc < 1) + return 1; + + /* SSID */ + NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]); + argv++; + argc--; + + /* freq */ + if (argc) { + freq = strtoul(argv[0], &end, 10); + if (*end == '\0') { + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + argv++; + argc--; + } + } + + /* bssid */ + if (argc) { + if (mac_addr_a2n(bssid, argv[0]) == 0) { + NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid); + argv++; + argc--; + } + } + + if (!argc) + return 0; + + if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0) + return 1; + + argv++; + argc--; + + return parse_keys(msg, argv, argc); + nla_put_failure: + return -ENOSPC; +} + +static int disconnect(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + return 0; +} +TOPLEVEL(disconnect, NULL, + NL80211_CMD_DISCONNECT, 0, CIB_NETDEV, disconnect, + "Disconnect from the current network."); + +static int iw_connect(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + char **conn_argv, *dev = argv[0]; + static const __u32 cmds[] = { + NL80211_CMD_CONNECT, + }; + struct print_event_args printargs = { }; + int conn_argc, err; + bool wait = false; + int i; + + /* strip "wlan0 connect" */ + argc -= 2; + argv += 2; + + /* check -w */ + if (argc && strcmp(argv[0], "-w") == 0) { + wait = true; + argc--; + argv++; + } + + conn_argc = 3 + argc; + conn_argv = calloc(conn_argc, sizeof(*conn_argv)); + if (!conn_argv) + return -ENOMEM; + + err = __prepare_listen_events(state); + if (err) + return err; + + conn_argv[0] = dev; + conn_argv[1] = "connect"; + conn_argv[2] = "establish"; + for (i = 0; i < argc; i++) + conn_argv[i + 3] = argv[i]; + err = handle_cmd(state, id, conn_argc, conn_argv); + free(conn_argv); + if (err) + return err; + + if (!wait) + return 0; + + /* + * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION + * + * This code has a bug: + * + * It is possible for a connect result message from another + * connect attempt to be processed here first, because we + * start listening to the multicast group before starting + * our own connect request, which may succeed but we get a + * fail message from a previous attempt that raced with us, + * or similar. + * + * The only proper way to fix this would be to listen to events + * before sending the command, and for the kernel to send the + * connect request or a cookie along with the event, so that you + * can match up whether the connect _you_ requested was finished + * or aborted. + * + * Alas, the kernel doesn't do that (yet). + */ + + __do_listen_events(state, ARRAY_SIZE(cmds), cmds, &printargs); + return 0; +} +TOPLEVEL(connect, "[-w] <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1:6162636465]", + 0, 0, CIB_NETDEV, iw_connect, + "Join the network with the given SSID (and frequency, BSSID).\n" + "With -w, wait for the connect to finish or fail."); +HIDDEN(connect, establish, "", NL80211_CMD_CONNECT, 0, CIB_NETDEV, iw_conn); + +static int iw_auth(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + char *end; + unsigned char bssid[6]; + int freq; + bool need_key = false; + + if (argc < 4) + return 1; + + /* SSID */ + NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]); + argv++; + argc--; + + /* bssid */ + if (mac_addr_a2n(bssid, argv[0]) == 0) { + NLA_PUT(msg, NL80211_ATTR_MAC, 6, bssid); + argv++; + argc--; + } else { + return 1; + } + + /* FIXME */ + if (strcmp(argv[0], "open") == 0) { + NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, + NL80211_AUTHTYPE_OPEN_SYSTEM); + } else if (strcmp(argv[0], "shared") == 0) { + NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE, + NL80211_AUTHTYPE_SHARED_KEY); + need_key = true; + } else { + return 1; + } + argv++; + argc--; + + freq = strtoul(argv[0], &end, 10); + if (*end == '\0') { + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + argv++; + argc--; + } else { + return 1; + } + + if (!argc && need_key) + return 1; + if (argc && !need_key) + return 1; + if (!argc) + return 0; + + if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0) + return 1; + + argv++; + argc--; + + return parse_keys(msg, argv, argc); + nla_put_failure: + return -ENOSPC; +} + +TOPLEVEL(auth, "<SSID> <bssid> <type:open|shared> <freq in MHz> [key 0:abcde d:1:6162636465]", + NL80211_CMD_AUTHENTICATE, 0, CIB_NETDEV, iw_auth, + "Authenticate with the given network.\n");
diff --git a/iw_3.10/iw_3.10/cqm.c b/iw_3.10/iw_3.10/cqm.c new file mode 100644 index 0000000..65876af --- /dev/null +++ b/iw_3.10/iw_3.10/cqm.c
@@ -0,0 +1,55 @@ +#include <errno.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int iw_cqm_rssi(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + struct nl_msg *cqm = NULL; + int thold = 0; + int hyst = 0; + int ret = -ENOSPC; + + /* get the required args */ + if (argc < 1 || argc > 2) + return 1; + + if (strcmp(argv[0], "off")) { + thold = atoi(argv[0]); + + if (thold == 0) + return -EINVAL; + + if (argc == 2) + hyst = atoi(argv[1]); + } + + /* connection quality monitor attributes */ + cqm = nlmsg_alloc(); + + NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_THOLD, thold); + NLA_PUT_U32(cqm, NL80211_ATTR_CQM_RSSI_HYST, hyst); + + nla_put_nested(msg, NL80211_ATTR_CQM, cqm); + ret = 0; + + nla_put_failure: + nlmsg_free(cqm); + return ret; +} + +TOPLEVEL(cqm, "", + 0, 0, CIB_NETDEV, NULL, + "Configure the WLAN connection quality monitor.\n"); + +COMMAND(cqm, rssi, "<threshold|off> [<hysteresis>]", + NL80211_CMD_SET_CQM, 0, CIB_NETDEV, iw_cqm_rssi, + "Set connection quality monitor RSSI threshold.\n");
diff --git a/iw_3.10/iw_3.10/event.c b/iw_3.10/iw_3.10/event.c new file mode 100644 index 0000000..603b072 --- /dev/null +++ b/iw_3.10/iw_3.10/event.c
@@ -0,0 +1,691 @@ +#include <stdint.h> +#include <stdbool.h> +#include <net/if.h> +#include <errno.h> +#include "iw.h" + +static int no_seq_check(struct nl_msg *msg, void *arg) +{ + return NL_OK; +} + +struct ieee80211_beacon_channel { + __u16 center_freq; + bool passive_scan; + bool no_ibss; +}; + +static int parse_beacon_hint_chan(struct nlattr *tb, + struct ieee80211_beacon_channel *chan) +{ + struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; + static struct nla_policy beacon_freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, + [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, + }; + + if (nla_parse_nested(tb_freq, + NL80211_FREQUENCY_ATTR_MAX, + tb, + beacon_freq_policy)) + return -EINVAL; + + chan->center_freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + + if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) + chan->passive_scan = true; + if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS]) + chan->no_ibss = true; + + return 0; +} + +static void print_frame(struct print_event_args *args, struct nlattr *attr) +{ + uint8_t *frame; + size_t len; + int i; + char macbuf[6*3]; + uint16_t tmp; + + if (!attr) + printf(" [no frame]"); + + frame = nla_data(attr); + len = nla_len(attr); + + if (len < 26) { + printf(" [invalid frame: "); + goto print_frame; + } + + mac_addr_n2a(macbuf, frame + 10); + printf(" %s -> ", macbuf); + mac_addr_n2a(macbuf, frame + 4); + printf("%s", macbuf); + + switch (frame[0] & 0xfc) { + case 0x10: /* assoc resp */ + case 0x30: /* reassoc resp */ + /* status */ + tmp = (frame[27] << 8) + frame[26]; + printf(" status: %d: %s", tmp, get_status_str(tmp)); + break; + case 0x00: /* assoc req */ + case 0x20: /* reassoc req */ + break; + case 0xb0: /* auth */ + /* status */ + tmp = (frame[29] << 8) + frame[28]; + printf(" status: %d: %s", tmp, get_status_str(tmp)); + break; + break; + case 0xa0: /* disassoc */ + case 0xc0: /* deauth */ + /* reason */ + tmp = (frame[25] << 8) + frame[24]; + printf(" reason %d: %s", tmp, get_reason_str(tmp)); + break; + } + + if (!args->frame) + return; + + printf(" [frame:"); + + print_frame: + for (i = 0; i < len; i++) + printf(" %.02x", frame[i]); + printf("]"); +} + +static void parse_cqm_event(struct nlattr **attrs) +{ + static struct nla_policy cqm_policy[NL80211_ATTR_CQM_MAX + 1] = { + [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 }, + [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 }, + [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 }, + }; + struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1]; + struct nlattr *cqm_attr = attrs[NL80211_ATTR_CQM]; + + printf("CQM event: "); + + if (!cqm_attr || + nla_parse_nested(cqm, NL80211_ATTR_CQM_MAX, cqm_attr, cqm_policy)) { + printf("missing data!\n"); + return; + } + + if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]) { + enum nl80211_cqm_rssi_threshold_event rssi_event; + bool found_one = false; + + rssi_event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]); + + switch (rssi_event) { + case NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: + printf("RSSI went above threshold\n"); + found_one = true; + break; + case NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: + printf("RSSI went below threshold\n"); + found_one = true; + break; + case NL80211_CQM_RSSI_BEACON_LOSS_EVENT: + printf("Beacon loss detected\n"); + found_one = true; + break; + } + + if (!found_one) + printf("Unknown event type: %i\n", rssi_event); + } else if (cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT] && + attrs[NL80211_ATTR_MAC]) { + uint32_t frames; + char buf[3*6]; + + frames = nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]); + mac_addr_n2a(buf, nla_data(attrs[NL80211_ATTR_MAC])); + printf("peer %s didn't ACK %d packets\n", buf, frames); + } else + printf("unknown event\n"); +} + +static const char * key_type_str(enum nl80211_key_type key_type) +{ + static char buf[30]; + switch (key_type) { + case NL80211_KEYTYPE_GROUP: + return "Group"; + case NL80211_KEYTYPE_PAIRWISE: + return "Pairwise"; + case NL80211_KEYTYPE_PEERKEY: + return "PeerKey"; + default: + snprintf(buf, sizeof(buf), "unknown(%d)", key_type); + return buf; + } +} + +static void parse_mic_failure(struct nlattr **attrs) +{ + printf("Michael MIC failure event:"); + + if (attrs[NL80211_ATTR_MAC]) { + char addr[3 * ETH_ALEN]; + mac_addr_n2a(addr, nla_data(attrs[NL80211_ATTR_MAC])); + printf(" source MAC address %s", addr); + } + + if (attrs[NL80211_ATTR_KEY_SEQ] && + nla_len(attrs[NL80211_ATTR_KEY_SEQ]) == 6) { + unsigned char *seq = nla_data(attrs[NL80211_ATTR_KEY_SEQ]); + printf(" seq=%02x%02x%02x%02x%02x%02x", + seq[0], seq[1], seq[2], seq[3], seq[4], seq[5]); + } + if (attrs[NL80211_ATTR_KEY_TYPE]) { + enum nl80211_key_type key_type = + nla_get_u32(attrs[NL80211_ATTR_KEY_TYPE]); + printf(" Key Type %s", key_type_str(key_type)); + } + + if (attrs[NL80211_ATTR_KEY_IDX]) { + __u8 key_id = nla_get_u8(attrs[NL80211_ATTR_KEY_IDX]); + printf(" Key Id %d", key_id); + } + + printf("\n"); +} + +static void parse_wowlan_wake_event(struct nlattr **attrs) +{ + struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; + + printf("WoWLAN wakeup\n"); + if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { + printf("\twakeup not due to WoWLAN\n"); + return; + } + + nla_parse(tb, MAX_NL80211_WOWLAN_TRIG, + nla_data(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + nla_len(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), NULL); + + if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) + printf("\t* was disconnected\n"); + if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) + printf("\t* magic packet received\n"); + if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) + printf("\t* pattern index: %u\n", + nla_get_u32(tb[NL80211_WOWLAN_TRIG_PKT_PATTERN])); + if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) + printf("\t* GTK rekey failure\n"); + if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) + printf("\t* EAP identity request\n"); + if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) + printf("\t* 4-way handshake\n"); + if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) + printf("\t* RF-kill released\n"); + if (tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211]) { + uint8_t *d = nla_data(tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211]); + int l = nla_len(tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211]); + int i; + printf("\t* packet (might be truncated): "); + for (i = 0; i < l; i++) { + if (i > 0) + printf(":"); + printf("%.2x", d[i]); + } + printf("\n"); + } + if (tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023]) { + uint8_t *d = nla_data(tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023]); + int l = nla_len(tb[NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023]); + int i; + printf("\t* packet (might be truncated): "); + for (i = 0; i < l; i++) { + if (i > 0) + printf(":"); + printf("%.2x", d[i]); + } + printf("\n"); + } + if (tb[NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH]) + printf("\t* TCP connection wakeup received\n"); + if (tb[NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST]) + printf("\t* TCP connection lost\n"); + if (tb[NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS]) + printf("\t* TCP connection ran out of tokens\n"); +} + +static int print_event(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb[NL80211_ATTR_MAX + 1], *nst; + struct print_event_args *args = arg; + char ifname[100]; + char macbuf[6*3]; + __u8 reg_type; + struct ieee80211_beacon_channel chan_before_beacon, chan_after_beacon; + __u32 wiphy_idx = 0; + int rem_nst; + __u16 status; + + if (args->time || args->reltime) { + unsigned long long usecs, previous; + + previous = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec; + gettimeofday(&args->ts, NULL); + usecs = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec; + if (args->reltime) { + if (!args->have_ts) { + usecs = 0; + args->have_ts = true; + } else + usecs -= previous; + } + printf("%llu.%06llu: ", usecs/1000000, usecs % 1000000); + } + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (tb[NL80211_ATTR_IFINDEX] && tb[NL80211_ATTR_WIPHY]) { + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), ifname); + printf("%s (phy #%d): ", ifname, nla_get_u32(tb[NL80211_ATTR_WIPHY])); + } else if (tb[NL80211_ATTR_WDEV] && tb[NL80211_ATTR_WIPHY]) { + printf("wdev 0x%llx (phy #%d): ", + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_WDEV]), + nla_get_u32(tb[NL80211_ATTR_WIPHY])); + } else if (tb[NL80211_ATTR_IFINDEX]) { + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), ifname); + printf("%s: ", ifname); + } else if (tb[NL80211_ATTR_WDEV]) { + printf("wdev 0x%llx: ", (unsigned long long)nla_get_u64(tb[NL80211_ATTR_WDEV])); + } else if (tb[NL80211_ATTR_WIPHY]) { + printf("phy #%d: ", nla_get_u32(tb[NL80211_ATTR_WIPHY])); + } + + switch (gnlh->cmd) { + case NL80211_CMD_NEW_WIPHY: + printf("renamed to %s\n", nla_get_string(tb[NL80211_ATTR_WIPHY_NAME])); + break; + case NL80211_CMD_TRIGGER_SCAN: + printf("scan started\n"); + break; + case NL80211_CMD_NEW_SCAN_RESULTS: + printf("scan finished:"); + case NL80211_CMD_SCAN_ABORTED: + if (gnlh->cmd == NL80211_CMD_SCAN_ABORTED) + printf("scan aborted:"); + if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) { + nla_for_each_nested(nst, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem_nst) + printf(" %d", nla_get_u32(nst)); + printf(","); + } + if (tb[NL80211_ATTR_SCAN_SSIDS]) { + nla_for_each_nested(nst, tb[NL80211_ATTR_SCAN_SSIDS], rem_nst) { + printf(" \""); + print_ssid_escaped(nla_len(nst), nla_data(nst)); + printf("\""); + } + } + printf("\n"); + break; + case NL80211_CMD_REG_CHANGE: + printf("regulatory domain change: "); + + reg_type = nla_get_u8(tb[NL80211_ATTR_REG_TYPE]); + + switch (reg_type) { + case NL80211_REGDOM_TYPE_COUNTRY: + printf("set to %s by %s request", + nla_get_string(tb[NL80211_ATTR_REG_ALPHA2]), + reg_initiator_to_string(nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]))); + if (tb[NL80211_ATTR_WIPHY]) + printf(" on phy%d", nla_get_u32(tb[NL80211_ATTR_WIPHY])); + break; + case NL80211_REGDOM_TYPE_WORLD: + printf("set to world roaming by %s request", + reg_initiator_to_string(nla_get_u8(tb[NL80211_ATTR_REG_INITIATOR]))); + break; + case NL80211_REGDOM_TYPE_CUSTOM_WORLD: + printf("custom world roaming rules in place on phy%d by %s request", + nla_get_u32(tb[NL80211_ATTR_WIPHY]), + reg_initiator_to_string(nla_get_u32(tb[NL80211_ATTR_REG_INITIATOR]))); + break; + case NL80211_REGDOM_TYPE_INTERSECTION: + printf("intersection used due to a request made by %s", + reg_initiator_to_string(nla_get_u32(tb[NL80211_ATTR_REG_INITIATOR]))); + if (tb[NL80211_ATTR_WIPHY]) + printf(" on phy%d", nla_get_u32(tb[NL80211_ATTR_WIPHY])); + break; + default: + printf("unknown source (upgrade this utility)"); + break; + } + + printf("\n"); + break; + case NL80211_CMD_REG_BEACON_HINT: + + wiphy_idx = nla_get_u32(tb[NL80211_ATTR_WIPHY]); + + memset(&chan_before_beacon, 0, sizeof(chan_before_beacon)); + memset(&chan_after_beacon, 0, sizeof(chan_after_beacon)); + + if (parse_beacon_hint_chan(tb[NL80211_ATTR_FREQ_BEFORE], + &chan_before_beacon)) + break; + if (parse_beacon_hint_chan(tb[NL80211_ATTR_FREQ_AFTER], + &chan_after_beacon)) + break; + + if (chan_before_beacon.center_freq != chan_after_beacon.center_freq) + break; + + /* A beacon hint is sent _only_ if something _did_ change */ + printf("beacon hint:\n"); + + printf("phy%d %d MHz [%d]:\n", + wiphy_idx, + chan_before_beacon.center_freq, + ieee80211_frequency_to_channel(chan_before_beacon.center_freq)); + + if (chan_before_beacon.passive_scan && !chan_after_beacon.passive_scan) + printf("\to active scanning enabled\n"); + if (chan_before_beacon.no_ibss && !chan_after_beacon.no_ibss) + printf("\to beaconing enabled\n"); + + break; + case NL80211_CMD_NEW_STATION: + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf("new station %s\n", macbuf); + break; + case NL80211_CMD_DEL_STATION: + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf("del station %s\n", macbuf); + break; + case NL80211_CMD_JOIN_IBSS: + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf("IBSS %s joined\n", macbuf); + break; + case NL80211_CMD_AUTHENTICATE: + printf("auth"); + if (tb[NL80211_ATTR_FRAME]) + print_frame(args, tb[NL80211_ATTR_FRAME]); + else if (tb[NL80211_ATTR_TIMED_OUT]) + printf(": timed out"); + else + printf(": unknown event"); + printf("\n"); + break; + case NL80211_CMD_ASSOCIATE: + printf("assoc"); + if (tb[NL80211_ATTR_FRAME]) + print_frame(args, tb[NL80211_ATTR_FRAME]); + else if (tb[NL80211_ATTR_TIMED_OUT]) + printf(": timed out"); + else + printf(": unknown event"); + printf("\n"); + break; + case NL80211_CMD_DEAUTHENTICATE: + printf("deauth"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_DISASSOCIATE: + printf("disassoc"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_UNPROT_DEAUTHENTICATE: + printf("unprotected deauth"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_UNPROT_DISASSOCIATE: + printf("unprotected disassoc"); + print_frame(args, tb[NL80211_ATTR_FRAME]); + printf("\n"); + break; + case NL80211_CMD_CONNECT: + status = 0; + if (!tb[NL80211_ATTR_STATUS_CODE]) + printf("unknown connect status"); + else if (nla_get_u16(tb[NL80211_ATTR_STATUS_CODE]) == 0) + printf("connected"); + else { + status = nla_get_u16(tb[NL80211_ATTR_STATUS_CODE]); + printf("failed to connect"); + } + if (tb[NL80211_ATTR_MAC]) { + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf(" to %s", macbuf); + } + if (status) + printf(", status: %d: %s", status, get_status_str(status)); + printf("\n"); + break; + case NL80211_CMD_ROAM: + printf("roamed"); + if (tb[NL80211_ATTR_MAC]) { + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + printf(" to %s", macbuf); + } + printf("\n"); + break; + case NL80211_CMD_DISCONNECT: + printf("disconnected"); + if (tb[NL80211_ATTR_DISCONNECTED_BY_AP]) + printf(" (by AP)"); + else + printf(" (local request)"); + if (tb[NL80211_ATTR_REASON_CODE]) + printf(" reason: %d: %s", nla_get_u16(tb[NL80211_ATTR_REASON_CODE]), + get_reason_str(nla_get_u16(tb[NL80211_ATTR_REASON_CODE]))); + printf("\n"); + break; + case NL80211_CMD_REMAIN_ON_CHANNEL: + printf("remain on freq %d (%dms, cookie %llx)\n", + nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]), + nla_get_u32(tb[NL80211_ATTR_DURATION]), + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE])); + break; + case NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: + printf("done with remain on freq %d (cookie %llx)\n", + nla_get_u32(tb[NL80211_ATTR_WIPHY_FREQ]), + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE])); + break; + case NL80211_CMD_NOTIFY_CQM: + parse_cqm_event(tb); + break; + case NL80211_CMD_MICHAEL_MIC_FAILURE: + parse_mic_failure(tb); + break; + case NL80211_CMD_FRAME_TX_STATUS: + printf("mgmt TX status (cookie %llx): %s\n", + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE]), + tb[NL80211_ATTR_ACK] ? "acked" : "no ack"); + break; + case NL80211_CMD_PMKSA_CANDIDATE: + printf("PMKSA candidate found\n"); + break; + case NL80211_CMD_SET_WOWLAN: + parse_wowlan_wake_event(tb); + break; + case NL80211_CMD_PROBE_CLIENT: + if (tb[NL80211_ATTR_MAC]) + mac_addr_n2a(macbuf, nla_data(tb[NL80211_ATTR_MAC])); + else + strcpy(macbuf, "??"); + printf("probe client %s (cookie %llx): %s\n", + macbuf, + (unsigned long long)nla_get_u64(tb[NL80211_ATTR_COOKIE]), + tb[NL80211_ATTR_ACK] ? "acked" : "no ack"); + break; + default: + printf("unknown event %d\n", gnlh->cmd); + break; + } + + fflush(stdout); + return NL_SKIP; +} + +struct wait_event { + int n_cmds; + const __u32 *cmds; + __u32 cmd; + struct print_event_args *pargs; +}; + +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; + if (wait->pargs) + print_event(msg, wait->pargs); + } + } + + return NL_SKIP; +} + +int __prepare_listen_events(struct nl80211_state *state) +{ + int mcid, ret; + + /* Configuration multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "config"); + if (mcid < 0) + return mcid; + + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + + /* Scan multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "scan"); + if (mcid >= 0) { + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + } + + /* Regulatory multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "regulatory"); + if (mcid >= 0) { + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + } + + /* MLME multicast group */ + mcid = nl_get_multicast_id(state->nl_sock, "nl80211", "mlme"); + if (mcid >= 0) { + ret = nl_socket_add_membership(state->nl_sock, mcid); + if (ret) + return ret; + } + + return 0; +} + +__u32 __do_listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits, + struct print_event_args *args) +{ + struct nl_cb *cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); + struct wait_event wait_ev; + + if (!cb) { + fprintf(stderr, "failed to allocate netlink callbacks\n"); + return -ENOMEM; + } + + /* no sequence checking for multicast messages */ + nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + + if (n_waits && waits) { + wait_ev.cmds = waits; + wait_ev.n_cmds = n_waits; + wait_ev.pargs = args; + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, wait_event, &wait_ev); + } else + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, args); + + wait_ev.cmd = 0; + + while (!wait_ev.cmd) + nl_recvmsgs(state->nl_sock, cb); + + nl_cb_put(cb); + + return wait_ev.cmd; +} + +__u32 listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits) +{ + int ret; + + ret = __prepare_listen_events(state); + if (ret) + return ret; + + return __do_listen_events(state, n_waits, waits, NULL); +} + +static int print_events(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + struct print_event_args args; + int ret; + + memset(&args, 0, sizeof(args)); + + argc--; + argv++; + + while (argc > 0) { + if (strcmp(argv[0], "-f") == 0) + args.frame = true; + else if (strcmp(argv[0], "-t") == 0) + args.time = true; + else if (strcmp(argv[0], "-r") == 0) + args.reltime = true; + else + return 1; + argc--; + argv++; + } + + if (args.time && args.reltime) + return 1; + + if (argc) + return 1; + + ret = __prepare_listen_events(state); + if (ret) + return ret; + + return __do_listen_events(state, 0, NULL, &args); +} +TOPLEVEL(event, "[-t] [-r] [-f]", 0, 0, CIB_NONE, print_events, + "Monitor events from the kernel.\n" + "-t - print timestamp\n" + "-r - print relative timstamp\n" + "-f - print full frame for auth/assoc etc.");
diff --git a/iw_3.10/iw_3.10/genl.c b/iw_3.10/iw_3.10/genl.c new file mode 100644 index 0000000..7dc27f7 --- /dev/null +++ b/iw_3.10/iw_3.10/genl.c
@@ -0,0 +1,117 @@ +/* + * This ought to be provided by libnl + */ + +#include <asm/errno.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> +#include <linux/genetlink.h> + +#include "iw.h" + +static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = arg; + *ret = err->error; + return NL_STOP; +} + +static int ack_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_STOP; +} + +struct handler_args { + const char *group; + int id; +}; + +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; +} + +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; +}
diff --git a/iw_3.10/iw_3.10/hwsim.c b/iw_3.10/iw_3.10/hwsim.c new file mode 100644 index 0000000..08c9c2e --- /dev/null +++ b/iw_3.10/iw_3.10/hwsim.c
@@ -0,0 +1,151 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +/* These enums need to be kept in sync with the kernel */ +enum hwsim_testmode_attr { + __HWSIM_TM_ATTR_INVALID = 0, + HWSIM_TM_ATTR_CMD = 1, + HWSIM_TM_ATTR_PS = 2, + + /* keep last */ + __HWSIM_TM_ATTR_AFTER_LAST, + HWSIM_TM_ATTR_MAX = __HWSIM_TM_ATTR_AFTER_LAST - 1 +}; + +enum hwsim_testmode_cmd { + HWSIM_TM_CMD_SET_PS = 0, + HWSIM_TM_CMD_GET_PS = 1, + HWSIM_TM_CMD_STOP_QUEUES = 2, + HWSIM_TM_CMD_WAKE_QUEUES = 3, +}; + + +SECTION(hwsim); + +static int print_hwsim_ps_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct nlattr *tb[HWSIM_TM_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_TESTDATA]) + return NL_SKIP; + + nla_parse(tb, HWSIM_TM_ATTR_MAX, nla_data(attrs[NL80211_ATTR_TESTDATA]), + nla_len(attrs[NL80211_ATTR_TESTDATA]), NULL); + + printf("HWSIM PS: %d\n", nla_get_u32(tb[HWSIM_TM_ATTR_PS])); + + return NL_SKIP; +} + +static int handle_hwsim_getps(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + struct nlattr *tmdata; + + tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!tmdata) + goto nla_put_failure; + + NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_GET_PS); + + nla_nest_end(msg, tmdata); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_hwsim_ps_handler, NULL); + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(hwsim, getps, "", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_getps, ""); + +static int handle_hwsim_setps(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + struct nlattr *tmdata; + __u32 ps; + char *end; + + if (argc != 1) + return 1; + + ps = strtoul(argv[0], &end, 0); + if (*end) + return 1; + + tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!tmdata) + goto nla_put_failure; + + NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_SET_PS); + NLA_PUT_U32(msg, HWSIM_TM_ATTR_PS, ps); + + nla_nest_end(msg, tmdata); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_hwsim_ps_handler, NULL); + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(hwsim, setps, "<value>", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_setps, ""); + +static int handle_hwsim_stop_queues(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + struct nlattr *tmdata; + + if (argc != 0) + return 1; + + tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!tmdata) + goto nla_put_failure; + + NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_STOP_QUEUES); + + nla_nest_end(msg, tmdata); + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(hwsim, stopqueues, "", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_stop_queues, ""); + +static int handle_hwsim_wake_queues(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + struct nlattr *tmdata; + + if (argc != 0) + return 1; + + tmdata = nla_nest_start(msg, NL80211_ATTR_TESTDATA); + if (!tmdata) + goto nla_put_failure; + + NLA_PUT_U32(msg, HWSIM_TM_ATTR_CMD, HWSIM_TM_CMD_WAKE_QUEUES); + + nla_nest_end(msg, tmdata); + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(hwsim, wakequeues, "", NL80211_CMD_TESTMODE, 0, CIB_PHY, handle_hwsim_wake_queues, "");
diff --git a/iw_3.10/iw_3.10/ibss.c b/iw_3.10/iw_3.10/ibss.c new file mode 100644 index 0000000..955446e --- /dev/null +++ b/iw_3.10/iw_3.10/ibss.c
@@ -0,0 +1,176 @@ +#ifndef _POSIX_SOURCE +#define _POSIX_SOURCE +#endif +#include <errno.h> +#include <string.h> +#include <strings.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(ibss); + +static int join_ibss(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *end; + unsigned char abssid[6]; + unsigned char rates[NL80211_MAX_SUPP_RATES]; + int n_rates = 0; + char *value = NULL, *sptr = NULL; + float rate; + int bintval; + int i; + static const struct { + const char *name; + unsigned int val; + } htmap[] = { + { .name = "HT20", .val = NL80211_CHAN_HT20, }, + { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, }, + { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, }, + { .name = "NOHT", .val = NL80211_CHAN_NO_HT, }, + }; + unsigned int htval; + + if (argc < 2) + return 1; + + /* SSID */ + NLA_PUT(msg, NL80211_ATTR_SSID, strlen(argv[0]), argv[0]); + argv++; + argc--; + + /* freq */ + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, + strtoul(argv[0], &end, 10)); + if (*end != '\0') + return 1; + argv++; + argc--; + + if (argc) { + for (i = 0; i < ARRAY_SIZE(htmap); i++) { + if (strcasecmp(htmap[i].name, argv[0]) == 0) { + htval = htmap[i].val; + break; + } + } + if (i != ARRAY_SIZE(htmap)) { + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, + htval); + argv++; + argc--; + } + + } + + if (argc && strcmp(argv[0], "fixed-freq") == 0) { + NLA_PUT_FLAG(msg, NL80211_ATTR_FREQ_FIXED); + argv++; + argc--; + } + + if (argc) { + if (mac_addr_a2n(abssid, argv[0]) == 0) { + NLA_PUT(msg, NL80211_ATTR_MAC, 6, abssid); + argv++; + argc--; + } + } + + if (argc > 1 && strcmp(argv[0], "beacon-interval") == 0) { + argv++; + argc--; + bintval = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, bintval); + argv++; + argc--; + } + + /* basic rates */ + if (argc > 1 && strcmp(argv[0], "basic-rates") == 0) { + argv++; + argc--; + + value = strtok_r(argv[0], ",", &sptr); + + while (value && n_rates < NL80211_MAX_SUPP_RATES) { + rate = strtod(value, &end); + rates[n_rates] = rate * 2; + + /* filter out suspicious values */ + if (*end != '\0' || !rates[n_rates] || + rate*2 != rates[n_rates]) + return 1; + + n_rates++; + value = strtok_r(NULL, ",", &sptr); + } + + NLA_PUT(msg, NL80211_ATTR_BSS_BASIC_RATES, n_rates, rates); + + argv++; + argc--; + } + + /* multicast rate */ + if (argc > 1 && strcmp(argv[0], "mcast-rate") == 0) { + argv++; + argc--; + + rate = strtod(argv[0], &end); + if (*end != '\0') + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10)); + argv++; + argc--; + } + + if (!argc) + return 0; + + if (strcmp(*argv, "key") != 0 && strcmp(*argv, "keys") != 0) + return 1; + + argv++; + argc--; + + return parse_keys(msg, argv, argc); + nla_put_failure: + return -ENOSPC; +} + +static int leave_ibss(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + return 0; +} +COMMAND(ibss, leave, NULL, + NL80211_CMD_LEAVE_IBSS, 0, CIB_NETDEV, leave_ibss, + "Leave the current IBSS cell."); +COMMAND(ibss, join, + "<SSID> <freq in MHz> [HT20|HT40+|HT40-|NOHT] [fixed-freq] [<fixed bssid>] [beacon-interval <TU>]" + " [basic-rates <rate in Mbps,rate2,...>] [mcast-rate <rate in Mbps>] " + "[key d:0:abcde]", + NL80211_CMD_JOIN_IBSS, 0, CIB_NETDEV, join_ibss, + "Join the IBSS cell with the given SSID, if it doesn't exist create\n" + "it on the given frequency. When fixed frequency is requested, don't\n" + "join/create a cell on a different frequency. When a fixed BSSID is\n" + "requested use that BSSID and do not adopt another cell's BSSID even\n" + "if it has higher TSF and the same SSID. If an IBSS is created, create\n" + "it with the specified basic-rates, multicast-rate and beacon-interval.");
diff --git a/iw_3.10/iw_3.10/ieee80211.h b/iw_3.10/iw_3.10/ieee80211.h new file mode 100644 index 0000000..8745608 --- /dev/null +++ b/iw_3.10/iw_3.10/ieee80211.h
@@ -0,0 +1,61 @@ +#ifndef __IEEE80211 +#define __IEEE80211 + +/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ +#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 +#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C + +#define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 +#define IEEE80211_HT_CAP_SGI_40 0x0040 +#define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 + +#define IEEE80211_HT_MCS_MASK_LEN 10 + +/** + * struct ieee80211_mcs_info - MCS information + * @rx_mask: RX mask + * @rx_highest: highest supported RX rate. If set represents + * the highest supported RX data rate in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + * @tx_params: TX parameters + */ +struct ieee80211_mcs_info { + __u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; + __u16 rx_highest; + __u8 tx_params; + __u8 reserved[3]; +} __attribute__ ((packed)); + + +/** + * struct ieee80211_ht_cap - HT capabilities + * + * This structure is the "HT capabilities element" as + * described in 802.11n D5.0 7.3.2.57 + */ +struct ieee80211_ht_cap { + __u16 cap_info; + __u8 ampdu_params_info; + + /* 16 bytes MCS information */ + struct ieee80211_mcs_info mcs; + + __u16 extended_ht_cap_info; + __u32 tx_BF_cap_info; + __u8 antenna_selection_info; +} __attribute__ ((packed)); + +struct ieee80211_vht_mcs_info { + __u16 rx_vht_mcs; + __u16 rx_highest; + __u16 tx_vht_mcs; + __u16 tx_highest; +} __attribute__ ((packed)); + +struct ieee80211_vht_cap { + __u32 cap_info; + struct ieee80211_vht_mcs_info mcs; +} __attribute__ ((packed)); + +#endif /* __IEEE80211 */
diff --git a/iw_3.10/iw_3.10/info.c b/iw_3.10/iw_3.10/info.c new file mode 100644 index 0000000..54d9a8d --- /dev/null +++ b/iw_3.10/iw_3.10/info.c
@@ -0,0 +1,607 @@ +#include <stdbool.h> +#include <errno.h> +#include <net/if.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static void print_flag(const char *name, int *open) +{ + if (!*open) + printf(" ("); + else + printf(", "); + printf("%s", name); + *open = 1; +} + +static char *cipher_name(__u32 c) +{ + static char buf[20]; + + switch (c) { + case 0x000fac01: + return "WEP40 (00-0f-ac:1)"; + case 0x000fac05: + return "WEP104 (00-0f-ac:5)"; + case 0x000fac02: + return "TKIP (00-0f-ac:2)"; + case 0x000fac04: + return "CCMP (00-0f-ac:4)"; + case 0x000fac06: + return "CMAC (00-0f-ac:6)"; + case 0x000fac08: + return "GCMP (00-0f-ac:8)"; + case 0x00147201: + return "WPI-SMS4 (00-14-72:1)"; + default: + sprintf(buf, "%.2x-%.2x-%.2x:%d", + c >> 24, (c >> 16) & 0xff, + (c >> 8) & 0xff, c & 0xff); + + return buf; + } +} + +static char *dfs_state_name(enum nl80211_dfs_state state) +{ + switch (state) { + case NL80211_DFS_USABLE: + return "usable"; + case NL80211_DFS_AVAILABLE: + return "available"; + case NL80211_DFS_UNAVAILABLE: + return "unavailable"; + default: + return "unknown"; + } +} + +static int print_phy_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1]; + + struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1]; + static struct nla_policy freq_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_FREQUENCY_ATTR_FREQ] = { .type = NLA_U32 }, + [NL80211_FREQUENCY_ATTR_DISABLED] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_NO_IBSS] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_RADAR] = { .type = NLA_FLAG }, + [NL80211_FREQUENCY_ATTR_MAX_TX_POWER] = { .type = NLA_U32 }, + }; + + struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1]; + static struct nla_policy rate_policy[NL80211_BITRATE_ATTR_MAX + 1] = { + [NL80211_BITRATE_ATTR_RATE] = { .type = NLA_U32 }, + [NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = { .type = NLA_FLAG }, + }; + + struct nlattr *nl_band; + struct nlattr *nl_freq; + struct nlattr *nl_rate; + struct nlattr *nl_mode; + struct nlattr *nl_cmd; + struct nlattr *nl_if, *nl_ftype; + int rem_band, rem_freq, rem_rate, rem_mode, rem_cmd, rem_ftype, rem_if; + int open; + /* + * static variables only work here, other applications need to use the + * callback pointer and store them there so they can be multithreaded + * and/or have multiple netlink sockets, etc. + */ + static int64_t phy_id = -1; + static int last_band = -1; + static bool band_had_freq = false; + bool print_name = true; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (tb_msg[NL80211_ATTR_WIPHY]) { + if (nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]) == phy_id) + print_name = false; + else + last_band = -1; + phy_id = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]); + } + if (print_name && tb_msg[NL80211_ATTR_WIPHY_NAME]) + printf("Wiphy %s\n", nla_get_string(tb_msg[NL80211_ATTR_WIPHY_NAME])); + + /* needed for split dump */ + if (tb_msg[NL80211_ATTR_WIPHY_BANDS]) { + nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band) { + if (last_band != nl_band->nla_type) { + printf("\tBand %d:\n", nl_band->nla_type + 1); + band_had_freq = false; + } + last_band = nl_band->nla_type; + + nla_parse(tb_band, NL80211_BAND_ATTR_MAX, nla_data(nl_band), + nla_len(nl_band), NULL); + + if (tb_band[NL80211_BAND_ATTR_HT_CAPA]) { + __u16 cap = nla_get_u16(tb_band[NL80211_BAND_ATTR_HT_CAPA]); + print_ht_capability(cap); + } + if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]) { + __u8 exponent = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_FACTOR]); + print_ampdu_length(exponent); + } + if (tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]) { + __u8 spacing = nla_get_u8(tb_band[NL80211_BAND_ATTR_HT_AMPDU_DENSITY]); + print_ampdu_spacing(spacing); + } + if (tb_band[NL80211_BAND_ATTR_HT_MCS_SET] && + nla_len(tb_band[NL80211_BAND_ATTR_HT_MCS_SET]) == 16) + print_ht_mcs(nla_data(tb_band[NL80211_BAND_ATTR_HT_MCS_SET])); + if (tb_band[NL80211_BAND_ATTR_VHT_CAPA] && + tb_band[NL80211_BAND_ATTR_VHT_MCS_SET]) + print_vht_info(nla_get_u32(tb_band[NL80211_BAND_ATTR_VHT_CAPA]), + nla_data(tb_band[NL80211_BAND_ATTR_VHT_MCS_SET])); + + if (tb_band[NL80211_BAND_ATTR_FREQS]) { + if (!band_had_freq) { + printf("\t\tFrequencies:\n"); + band_had_freq = true; + } + nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq) { + uint32_t freq; + nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_freq), + nla_len(nl_freq), freq_policy); + if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ]) + continue; + freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]); + printf("\t\t\t* %d MHz [%d]", freq, ieee80211_frequency_to_channel(freq)); + + if (tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER] && + !tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) + printf(" (%.1f dBm)", 0.01 * nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_MAX_TX_POWER])); + + open = 0; + if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED]) { + print_flag("disabled", &open); + goto next; + } + if (tb_freq[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN]) + print_flag("passive scanning", &open); + if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IBSS]) + print_flag("no IBSS", &open); + if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR]) + print_flag("radar detection", &open); +next: + if (open) + printf(")"); + printf("\n"); + + if (!tb_freq[NL80211_FREQUENCY_ATTR_DISABLED] && tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]) { + enum nl80211_dfs_state state = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_STATE]); + unsigned long time; + + printf("\t\t\t DFS state: %s", dfs_state_name(state)); + if (tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]) { + time = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_DFS_TIME]); + printf(" (for %lu sec)", time/1000); + } + printf("\n"); + } + + } + } + + if (tb_band[NL80211_BAND_ATTR_RATES]) { + printf("\t\tBitrates (non-HT):\n"); + nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate) { + nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, nla_data(nl_rate), + nla_len(nl_rate), rate_policy); + if (!tb_rate[NL80211_BITRATE_ATTR_RATE]) + continue; + printf("\t\t\t* %2.1f Mbps", 0.1 * nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE])); + open = 0; + if (tb_rate[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE]) + print_flag("short preamble supported", &open); + if (open) + printf(")"); + printf("\n"); + } + } + } + } + + if (tb_msg[NL80211_ATTR_MAX_NUM_SCAN_SSIDS]) + printf("\tmax # scan SSIDs: %d\n", + nla_get_u8(tb_msg[NL80211_ATTR_MAX_NUM_SCAN_SSIDS])); + if (tb_msg[NL80211_ATTR_MAX_SCAN_IE_LEN]) + printf("\tmax scan IEs length: %d bytes\n", + nla_get_u16(tb_msg[NL80211_ATTR_MAX_SCAN_IE_LEN])); + + if (tb_msg[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) { + unsigned int frag; + + frag = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]); + if (frag != (unsigned int)-1) + printf("\tFragmentation threshold: %d\n", frag); + } + + if (tb_msg[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) { + unsigned int rts; + + rts = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_RTS_THRESHOLD]); + if (rts != (unsigned int)-1) + printf("\tRTS threshold: %d\n", rts); + } + + if (tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { + unsigned char coverage; + + coverage = nla_get_u8(tb_msg[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); + /* See handle_distance() for an explanation where the '450' comes from */ + printf("\tCoverage class: %d (up to %dm)\n", coverage, 450 * coverage); + } + + if (tb_msg[NL80211_ATTR_CIPHER_SUITES]) { + int num = nla_len(tb_msg[NL80211_ATTR_CIPHER_SUITES]) / sizeof(__u32); + int i; + __u32 *ciphers = nla_data(tb_msg[NL80211_ATTR_CIPHER_SUITES]); + if (num > 0) { + printf("\tSupported Ciphers:\n"); + for (i = 0; i < num; i++) + printf("\t\t* %s\n", + cipher_name(ciphers[i])); + } + } + + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX] && + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX]) + printf("\tAvailable Antennas: TX %#x RX %#x\n", + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX]), + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX])); + + if (tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX] && + tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX]) + printf("\tConfigured Antennas: TX %#x RX %#x\n", + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_TX]), + nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_ANTENNA_RX])); + + if (tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES]) { + printf("\tSupported interface modes:\n"); + nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], rem_mode) + printf("\t\t * %s\n", iftype_name(nla_type(nl_mode))); + } + + if (tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES]) { + printf("\tsoftware interface modes (can always be added):\n"); + nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SOFTWARE_IFTYPES], rem_mode) + printf("\t\t * %s\n", iftype_name(nla_type(nl_mode))); + } + + if (tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS]) { + struct nlattr *nl_combi; + int rem_combi; + bool have_combinations = false; + + nla_for_each_nested(nl_combi, tb_msg[NL80211_ATTR_INTERFACE_COMBINATIONS], rem_combi) { + static struct nla_policy iface_combination_policy[NUM_NL80211_IFACE_COMB] = { + [NL80211_IFACE_COMB_LIMITS] = { .type = NLA_NESTED }, + [NL80211_IFACE_COMB_MAXNUM] = { .type = NLA_U32 }, + [NL80211_IFACE_COMB_STA_AP_BI_MATCH] = { .type = NLA_FLAG }, + [NL80211_IFACE_COMB_NUM_CHANNELS] = { .type = NLA_U32 }, + [NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS] = { .type = NLA_U32 }, + }; + struct nlattr *tb_comb[NUM_NL80211_IFACE_COMB]; + static struct nla_policy iface_limit_policy[NUM_NL80211_IFACE_LIMIT] = { + [NL80211_IFACE_LIMIT_TYPES] = { .type = NLA_NESTED }, + [NL80211_IFACE_LIMIT_MAX] = { .type = NLA_U32 }, + }; + struct nlattr *tb_limit[NUM_NL80211_IFACE_LIMIT]; + struct nlattr *nl_limit; + int err, rem_limit; + bool comma = false; + + if (!have_combinations) { + printf("\tvalid interface combinations:\n"); + have_combinations = true; + } + + printf("\t\t * "); + + err = nla_parse_nested(tb_comb, MAX_NL80211_IFACE_COMB, + nl_combi, iface_combination_policy); + if (err || !tb_comb[NL80211_IFACE_COMB_LIMITS] || + !tb_comb[NL80211_IFACE_COMB_MAXNUM] || + !tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]) { + printf(" <failed to parse>\n"); + goto broken_combination; + } + + nla_for_each_nested(nl_limit, tb_comb[NL80211_IFACE_COMB_LIMITS], rem_limit) { + bool ift_comma = false; + + err = nla_parse_nested(tb_limit, MAX_NL80211_IFACE_LIMIT, + nl_limit, iface_limit_policy); + if (err || !tb_limit[NL80211_IFACE_LIMIT_TYPES]) { + printf("<failed to parse>\n"); + goto broken_combination; + } + + if (comma) + printf(", "); + comma = true; + printf("#{"); + + nla_for_each_nested(nl_mode, tb_limit[NL80211_IFACE_LIMIT_TYPES], rem_mode) { + printf("%s %s", ift_comma ? "," : "", + iftype_name(nla_type(nl_mode))); + ift_comma = true; + } + printf(" } <= %u", nla_get_u32(tb_limit[NL80211_IFACE_LIMIT_MAX])); + } + printf(",\n\t\t "); + + printf("total <= %d, #channels <= %d%s", + nla_get_u32(tb_comb[NL80211_IFACE_COMB_MAXNUM]), + nla_get_u32(tb_comb[NL80211_IFACE_COMB_NUM_CHANNELS]), + tb_comb[NL80211_IFACE_COMB_STA_AP_BI_MATCH] ? + ", STA/AP BI must match" : ""); + if (tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]) { + unsigned long widths = nla_get_u32(tb_comb[NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS]); + + if (widths) { + int width; + bool first = true; + + printf(", radar detect widths: {"); + for (width = 0; width < 32; width++) + if (widths & (1 << width)) { + printf("%s %s", + first ? "":",", + channel_width_name(width)); + first = false; + } + printf(" }\n"); + } + } + printf("\n"); +broken_combination: + ; + } + + if (!have_combinations) + printf("\tinterface combinations are not supported\n"); + } + + if (tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS]) { + printf("\tSupported commands:\n"); + nla_for_each_nested(nl_cmd, tb_msg[NL80211_ATTR_SUPPORTED_COMMANDS], rem_cmd) + printf("\t\t * %s\n", command_name(nla_get_u32(nl_cmd))); + } + + if (tb_msg[NL80211_ATTR_TX_FRAME_TYPES]) { + printf("\tSupported TX frame types:\n"); + nla_for_each_nested(nl_if, tb_msg[NL80211_ATTR_TX_FRAME_TYPES], rem_if) { + bool printed = false; + nla_for_each_nested(nl_ftype, nl_if, rem_ftype) { + if (!printed) + printf("\t\t * %s:", iftype_name(nla_type(nl_if))); + printed = true; + printf(" 0x%.2x", nla_get_u16(nl_ftype)); + } + if (printed) + printf("\n"); + } + } + + if (tb_msg[NL80211_ATTR_RX_FRAME_TYPES]) { + printf("\tSupported RX frame types:\n"); + nla_for_each_nested(nl_if, tb_msg[NL80211_ATTR_RX_FRAME_TYPES], rem_if) { + bool printed = false; + nla_for_each_nested(nl_ftype, nl_if, rem_ftype) { + if (!printed) + printf("\t\t * %s:", iftype_name(nla_type(nl_if))); + printed = true; + printf(" 0x%.2x", nla_get_u16(nl_ftype)); + } + if (printed) + printf("\n"); + } + } + + if (tb_msg[NL80211_ATTR_SUPPORT_IBSS_RSN]) + printf("\tDevice supports RSN-IBSS.\n"); + + if (tb_msg[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED]) { + struct nlattr *tb_wowlan[NUM_NL80211_WOWLAN_TRIG]; + static struct nla_policy wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { + [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .minlen = 12 }, + [NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, + [NL80211_WOWLAN_TRIG_TCP_CONNECTION] = { .type = NLA_NESTED }, + }; + struct nl80211_wowlan_pattern_support *pat; + int err; + + err = nla_parse_nested(tb_wowlan, MAX_NL80211_WOWLAN_TRIG, + tb_msg[NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED], + wowlan_policy); + printf("\tWoWLAN support:"); + if (err) { + printf(" <failed to parse>\n"); + } else { + printf("\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_ANY]) + printf("\t\t * wake up on anything (device continues operating normally)\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_DISCONNECT]) + printf("\t\t * wake up on disconnect\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_MAGIC_PKT]) + printf("\t\t * wake up on magic packet\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { + pat = nla_data(tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]); + printf("\t\t * wake up on pattern match, up to %u patterns of %u-%u bytes,\n" + "\t\t maximum packet offset %u bytes\n", + pat->max_patterns, pat->min_pattern_len, pat->max_pattern_len, + (nla_len(tb_wowlan[NL80211_WOWLAN_TRIG_PKT_PATTERN]) < + sizeof(*pat)) ? 0 : pat->max_pkt_offset); + } + if (tb_wowlan[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) + printf("\t\t * can do GTK rekeying\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) + printf("\t\t * wake up on GTK rekey failure\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) + printf("\t\t * wake up on EAP identity request\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) + printf("\t\t * wake up on 4-way handshake\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) + printf("\t\t * wake up on rfkill release\n"); + if (tb_wowlan[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) + printf("\t\t * wake up on TCP connection\n"); + } + } + + if (tb_msg[NL80211_ATTR_ROAM_SUPPORT]) + printf("\tDevice supports roaming.\n"); + + if (tb_msg[NL80211_ATTR_SUPPORT_AP_UAPSD]) + printf("\tDevice supports AP-side u-APSD.\n"); + + if (tb_msg[NL80211_ATTR_HT_CAPABILITY_MASK]) { + struct ieee80211_ht_cap *cm; + printf("\tHT Capability overrides:\n"); + if (nla_len(tb_msg[NL80211_ATTR_HT_CAPABILITY_MASK]) >= sizeof(*cm)) { + cm = nla_data(tb_msg[NL80211_ATTR_HT_CAPABILITY_MASK]); + printf("\t\t * MCS: %02hhx %02hhx %02hhx %02hhx %02hhx %02hhx" + " %02hhx %02hhx %02hhx %02hhx\n", + cm->mcs.rx_mask[0], cm->mcs.rx_mask[1], + cm->mcs.rx_mask[2], cm->mcs.rx_mask[3], + cm->mcs.rx_mask[4], cm->mcs.rx_mask[5], + cm->mcs.rx_mask[6], cm->mcs.rx_mask[7], + cm->mcs.rx_mask[8], cm->mcs.rx_mask[9]); + if (cm->cap_info & htole16(IEEE80211_HT_CAP_MAX_AMSDU)) + printf("\t\t * maximum A-MSDU length\n"); + if (cm->cap_info & htole16(IEEE80211_HT_CAP_SUP_WIDTH_20_40)) + printf("\t\t * supported channel width\n"); + if (cm->cap_info & htole16(IEEE80211_HT_CAP_SGI_40)) + printf("\t\t * short GI for 40 MHz\n"); + if (cm->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_FACTOR) + printf("\t\t * max A-MPDU length exponent\n"); + if (cm->ampdu_params_info & IEEE80211_HT_AMPDU_PARM_DENSITY) + printf("\t\t * min MPDU start spacing\n"); + } else { + printf("\tERROR: capabilities mask is too short, expected: %d, received: %d\n", + (int)(sizeof(*cm)), + (int)(nla_len(tb_msg[NL80211_ATTR_HT_CAPABILITY_MASK]))); + } + } + + if (tb_msg[NL80211_ATTR_FEATURE_FLAGS]) { + unsigned int features = nla_get_u32(tb_msg[NL80211_ATTR_FEATURE_FLAGS]); + + if (features & NL80211_FEATURE_SK_TX_STATUS) + printf("\tDevice supports TX status socket option.\n"); + if (features & NL80211_FEATURE_HT_IBSS) + printf("\tDevice supports HT-IBSS.\n"); + if (features & NL80211_FEATURE_INACTIVITY_TIMER) + printf("\tDevice has client inactivity timer.\n"); + if (features & NL80211_FEATURE_CELL_BASE_REG_HINTS) + printf("\tDevice accepts cell base station regulatory hints.\n"); + if (features & NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL) + printf("\tP2P Device uses a channel (of the concurrent ones)\n"); + if (features & NL80211_FEATURE_LOW_PRIORITY_SCAN) + printf("\tDevice supports low priority scan.\n"); + if (features & NL80211_FEATURE_SCAN_FLUSH) + printf("\tDevice supports scan flush.\n"); + if (features & NL80211_FEATURE_AP_SCAN) + printf("\tDevice supports AP scan.\n"); + } + + return NL_SKIP; +} + +static bool nl80211_has_split_wiphy = false; + +static int handle_info(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *feat_args[] = { "features", "-q" }; + int err; + + err = handle_cmd(state, CIB_NONE, 2, feat_args); + if (!err && nl80211_has_split_wiphy) { + nla_put_flag(msg, NL80211_ATTR_SPLIT_WIPHY_DUMP); + nlmsg_hdr(msg)->nlmsg_flags |= NLM_F_DUMP; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_phy_handler, NULL); + + return 0; +} +__COMMAND(NULL, info, "info", NULL, NL80211_CMD_GET_WIPHY, 0, 0, CIB_PHY, handle_info, + "Show capabilities for the specified wireless device.", NULL); +TOPLEVEL(list, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, + "List all wireless devices and their capabilities."); +TOPLEVEL(phy, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info, NULL); + +static int handle_commands(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv, enum id_input id) +{ + int i; + for (i = 1; i < NL80211_CMD_MAX; i++) + printf("%d (0x%x): %s\n", i, i, command_name(i)); + /* don't send netlink messages */ + return 2; +} +TOPLEVEL(commands, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_NONE, handle_commands, + "list all known commands and their decimal & hex value"); + +static int print_feature_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + bool print = (unsigned long)arg; +#define maybe_printf(...) do { if (print) printf(__VA_ARGS__); } while (0) + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]) { + uint32_t feat = nla_get_u32(tb_msg[NL80211_ATTR_PROTOCOL_FEATURES]); + + maybe_printf("nl80211 features: 0x%x\n", feat); + if (feat & NL80211_PROTOCOL_FEATURE_SPLIT_WIPHY_DUMP) { + maybe_printf("\t* split wiphy dump\n"); + nl80211_has_split_wiphy = true; + } + } + + return NL_SKIP; +} + +static int handle_features(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv, enum id_input id) +{ + unsigned long print = argc == 0 || strcmp(argv[0], "-q"); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_feature_handler, (void *)print); + return 0; +} + +TOPLEVEL(features, "", NL80211_CMD_GET_PROTOCOL_FEATURES, 0, CIB_NONE, + handle_features, "");
diff --git a/iw_3.10/iw_3.10/interface.c b/iw_3.10/iw_3.10/interface.c new file mode 100644 index 0000000..b52c8dd --- /dev/null +++ b/iw_3.10/iw_3.10/interface.c
@@ -0,0 +1,563 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +#define VALID_FLAGS "none: no special flags\n"\ + "fcsfail: show frames with FCS errors\n"\ + "control: show control frames\n"\ + "otherbss: show frames from other BSSes\n"\ + "cook: use cooked mode" + +SECTION(interface); + +static char *mntr_flags[NL80211_MNTR_FLAG_MAX + 1] = { + "none", + "fcsfail", + "plcpfail", + "control", + "otherbss", + "cook", +}; + +static int parse_mntr_flags(int *_argc, char ***_argv, + struct nl_msg *msg) +{ + struct nl_msg *flags; + int err = -ENOBUFS; + enum nl80211_mntr_flags flag; + int argc = *_argc; + char **argv = *_argv; + + flags = nlmsg_alloc(); + if (!flags) + return -ENOMEM; + + while (argc) { + int ok = 0; + for (flag = __NL80211_MNTR_FLAG_INVALID; + flag <= NL80211_MNTR_FLAG_MAX; flag++) { + if (strcmp(*argv, mntr_flags[flag]) == 0) { + ok = 1; + /* + * This shouldn't be adding "flag" if that is + * zero, but due to a problem in the kernel's + * nl80211 code (using NLA_NESTED policy) it + * will reject an empty nested attribute but + * not one that contains an invalid attribute + */ + NLA_PUT_FLAG(flags, flag); + break; + } + } + if (!ok) { + err = -EINVAL; + goto out; + } + argc--; + argv++; + } + + nla_put_nested(msg, NL80211_ATTR_MNTR_FLAGS, flags); + err = 0; + nla_put_failure: + out: + nlmsg_free(flags); + + *_argc = argc; + *_argv = argv; + + return err; +} + +/* for help */ +#define IFACE_TYPES "Valid interface types are: managed, ibss, monitor, mesh, wds." + +/* return 0 if ok, internal error otherwise */ +static int get_if_type(int *argc, char ***argv, enum nl80211_iftype *type, + bool need_type) +{ + char *tpstr; + + if (*argc < 1 + !!need_type) + return 1; + + if (need_type && strcmp((*argv)[0], "type")) + return 1; + + tpstr = (*argv)[!!need_type]; + *argc -= 1 + !!need_type; + *argv += 1 + !!need_type; + + if (strcmp(tpstr, "adhoc") == 0 || + strcmp(tpstr, "ibss") == 0) { + *type = NL80211_IFTYPE_ADHOC; + return 0; + } else if (strcmp(tpstr, "monitor") == 0) { + *type = NL80211_IFTYPE_MONITOR; + return 0; + } else if (strcmp(tpstr, "master") == 0 || + strcmp(tpstr, "ap") == 0) { + *type = NL80211_IFTYPE_UNSPECIFIED; + fprintf(stderr, "You need to run a management daemon, e.g. hostapd,\n"); + fprintf(stderr, "see http://wireless.kernel.org/en/users/Documentation/hostapd\n"); + fprintf(stderr, "for more information on how to do that.\n"); + return 2; + } else if (strcmp(tpstr, "__ap") == 0) { + *type = NL80211_IFTYPE_AP; + return 0; + } else if (strcmp(tpstr, "__ap_vlan") == 0) { + *type = NL80211_IFTYPE_AP_VLAN; + return 0; + } else if (strcmp(tpstr, "wds") == 0) { + *type = NL80211_IFTYPE_WDS; + return 0; + } else if (strcmp(tpstr, "managed") == 0 || + strcmp(tpstr, "mgd") == 0 || + strcmp(tpstr, "station") == 0) { + *type = NL80211_IFTYPE_STATION; + return 0; + } else if (strcmp(tpstr, "mp") == 0 || + strcmp(tpstr, "mesh") == 0) { + *type = NL80211_IFTYPE_MESH_POINT; + return 0; + } else if (strcmp(tpstr, "__p2pcl") == 0) { + *type = NL80211_IFTYPE_P2P_CLIENT; + return 0; + } else if (strcmp(tpstr, "__p2pdev") == 0) { + *type = NL80211_IFTYPE_P2P_DEVICE; + return 0; + } else if (strcmp(tpstr, "__p2pgo") == 0) { + *type = NL80211_IFTYPE_P2P_GO; + return 0; + } + + fprintf(stderr, "invalid interface type %s\n", tpstr); + return 2; +} + +static int parse_4addr_flag(const char *value, struct nl_msg *msg) +{ + if (strcmp(value, "on") == 0) + NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, 1); + else if (strcmp(value, "off") == 0) + NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, 0); + else + return 1; + return 0; + +nla_put_failure: + return 1; +} + +static int handle_interface_add(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *name; + char *mesh_id = NULL; + enum nl80211_iftype type; + int tpset; + + if (argc < 1) + return 1; + + name = argv[0]; + argc--; + argv++; + + tpset = get_if_type(&argc, &argv, &type, true); + if (tpset) + return tpset; + + if (argc) { + if (strcmp(argv[0], "mesh_id") == 0) { + argc--; + argv++; + + if (!argc) + return 1; + mesh_id = argv[0]; + argc--; + argv++; + } else if (strcmp(argv[0], "4addr") == 0) { + argc--; + argv++; + if (parse_4addr_flag(argv[0], msg)) { + fprintf(stderr, "4addr error\n"); + return 2; + } + argc--; + argv++; + } else if (strcmp(argv[0], "flags") == 0) { + argc--; + argv++; + if (parse_mntr_flags(&argc, &argv, msg)) { + fprintf(stderr, "flags error\n"); + return 2; + } + } else { + return 1; + } + } + + if (argc) + return 1; + + NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, name); + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type); + if (mesh_id) + NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*]", + NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add, + "Add a new virtual interface with the given configuration.\n" + IFACE_TYPES "\n\n" + "The flags are only used for monitor interfaces, valid flags are:\n" + VALID_FLAGS "\n\n" + "The mesh_id is used only for mesh mode."); +COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [4addr on|off] [flags <flag>*]", + NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add, NULL); + +static int handle_interface_del(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + return 0; +} +TOPLEVEL(del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del, + "Remove this virtual interface"); +HIDDEN(interface, del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del); + +static 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"; + } +} + +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"; + } +} + +static int print_iface_handler(struct nl_msg *msg, void *arg) +{ + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + unsigned int *wiphy = arg; + const char *indent = ""; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (wiphy && tb_msg[NL80211_ATTR_WIPHY]) { + unsigned int thiswiphy = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY]); + indent = "\t"; + if (*wiphy != thiswiphy) + printf("phy#%d\n", thiswiphy); + *wiphy = thiswiphy; + } + + if (tb_msg[NL80211_ATTR_IFNAME]) + printf("%sInterface %s\n", indent, nla_get_string(tb_msg[NL80211_ATTR_IFNAME])); + else + printf("%sUnnamed/non-netdev interface\n", indent); + if (tb_msg[NL80211_ATTR_IFINDEX]) + printf("%s\tifindex %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_IFINDEX])); + if (tb_msg[NL80211_ATTR_WDEV]) + printf("%s\twdev 0x%llx\n", indent, + (unsigned long long)nla_get_u64(tb_msg[NL80211_ATTR_WDEV])); + if (tb_msg[NL80211_ATTR_MAC]) { + char mac_addr[20]; + mac_addr_n2a(mac_addr, nla_data(tb_msg[NL80211_ATTR_MAC])); + printf("%s\taddr %s\n", indent, mac_addr); + } + if (tb_msg[NL80211_ATTR_SSID]) { + printf("%s\tssid ", indent); + print_ssid_escaped(nla_len(tb_msg[NL80211_ATTR_SSID]), + nla_data(tb_msg[NL80211_ATTR_SSID])); + printf("\n"); + } + if (tb_msg[NL80211_ATTR_IFTYPE]) + printf("%s\ttype %s\n", indent, iftype_name(nla_get_u32(tb_msg[NL80211_ATTR_IFTYPE]))); + if (!wiphy && tb_msg[NL80211_ATTR_WIPHY]) + printf("%s\twiphy %d\n", indent, nla_get_u32(tb_msg[NL80211_ATTR_WIPHY])); + if (tb_msg[NL80211_ATTR_WIPHY_FREQ]) { + uint32_t freq = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_FREQ]); + + printf("%s\tchannel %d (%d MHz)", indent, + ieee80211_frequency_to_channel(freq), freq); + + if (tb_msg[NL80211_ATTR_CHANNEL_WIDTH]) { + printf(", width: %s", + channel_width_name(nla_get_u32(tb_msg[NL80211_ATTR_CHANNEL_WIDTH]))); + if (tb_msg[NL80211_ATTR_CENTER_FREQ1]) + printf(", center1: %d MHz", + nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ1])); + if (tb_msg[NL80211_ATTR_CENTER_FREQ2]) + printf(", center2: %d MHz", + nla_get_u32(tb_msg[NL80211_ATTR_CENTER_FREQ2])); + } else if (tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { + enum nl80211_channel_type channel_type; + + channel_type = nla_get_u32(tb_msg[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); + printf(" %s", channel_type_name(channel_type)); + } + + printf("\n"); + } + + return NL_SKIP; +} + +static int handle_interface_info(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, NULL); + return 0; +} +TOPLEVEL(info, NULL, NL80211_CMD_GET_INTERFACE, 0, CIB_NETDEV, handle_interface_info, + "Show information for this interface."); + +static int handle_interface_set(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + if (!argc) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, NL80211_IFTYPE_MONITOR); + + switch (parse_mntr_flags(&argc, &argv, msg)) { + case 0: + return 0; + case -ENOMEM: + fprintf(stderr, "failed to allocate flags\n"); + return 2; + case -EINVAL: + fprintf(stderr, "unknown flag %s\n", *argv); + return 2; + default: + return 2; + } + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, monitor, "<flag>*", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_set, + "Set monitor flags. Valid flags are:\n" + VALID_FLAGS); + +static int handle_interface_meshid(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *mesh_id = NULL; + + if (argc != 1) + return 1; + + mesh_id = argv[0]; + + NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, meshid, "<meshid>", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_meshid, NULL); + +static unsigned int dev_dump_wiphy; + +static int handle_dev_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + dev_dump_wiphy = -1; + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, &dev_dump_wiphy); + return 0; +} +TOPLEVEL(dev, NULL, NL80211_CMD_GET_INTERFACE, NLM_F_DUMP, CIB_NONE, handle_dev_dump, + "List all network interfaces for wireless hardware."); + +static int handle_interface_type(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + enum nl80211_iftype type; + int tpset; + + tpset = get_if_type(&argc, &argv, &type, false); + if (tpset) + return tpset; + + if (argc) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, type); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, type, "<type>", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_type, + "Set interface type/mode.\n" + IFACE_TYPES); + +static int handle_interface_4addr(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + if (argc != 1) + return 1; + return parse_4addr_flag(argv[0], msg); +} +COMMAND(set, 4addr, "<on|off>", + NL80211_CMD_SET_INTERFACE, 0, CIB_NETDEV, handle_interface_4addr, + "Set interface 4addr (WDS) mode."); + +static int handle_interface_noack_map(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + uint16_t noack_map; + char *end; + + if (argc != 1) + return 1; + + noack_map = strtoul(argv[0], &end, 16); + if (*end) + return 1; + + NLA_PUT_U16(msg, NL80211_ATTR_NOACK_MAP, noack_map); + + return 0; + nla_put_failure: + return -ENOBUFS; + +} +COMMAND(set, noack_map, "<map>", + NL80211_CMD_SET_NOACK_MAP, 0, CIB_NETDEV, handle_interface_noack_map, + "Set the NoAck map for the TIDs. (0x0009 = BE, 0x0006 = BK, 0x0030 = VI, 0x00C0 = VO)"); + + +static int handle_interface_wds_peer(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "Invalid MAC address\n"); + return 2; + } + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, peer, "<MAC address>", + NL80211_CMD_SET_WDS_PEER, 0, CIB_NETDEV, handle_interface_wds_peer, + "Set interface WDS peer."); + +static int set_mcast_rate(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + float rate; + char *end; + + if (argc != 1) { + printf("Invalid parameters!\n"); + return 2; + } + + rate = strtod(argv[0], &end); + if (*end != '\0') + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10)); + + return 0; +nla_put_failure: + return -ENOBUFS; +} + +COMMAND(set, mcast_rate, "<rate in Mbps>", + NL80211_CMD_SET_MCAST_RATE, 0, CIB_NETDEV, set_mcast_rate, + "Set the multicast bitrate.");
diff --git a/iw_3.10/iw_3.10/iw.8 b/iw_3.10/iw_3.10/iw.8 new file mode 100644 index 0000000..d0fcb61 --- /dev/null +++ b/iw_3.10/iw_3.10/iw.8
@@ -0,0 +1,71 @@ +.TH IW 8 "7 June 2012" "iw" "Linux" +.SH NAME +iw \- show / manipulate wireless devices and their configuration +.SH SYNOPSIS + +.ad l +.in +8 +.ti -8 +.B iw +.RI [ " OPTIONS " ] " " { " +.BR help " [ " +.RI ""command " ]" +.BR "|" +.RI ""OBJECT " " COMMAND " }" +.sp + +.ti -8 +.IR OBJECT " := { " +.BR dev " | " phy " | " reg " }" +.sp + +.ti -8 +.IR OPTIONS " := { --version | --debug }" + +.SH OPTIONS + +.TP +.BR " --version" +print version information and exit. + +.TP +.BR " --debug" +enable netlink message debugging. + +.SH IW - COMMAND SYNTAX + +.SS +.I OBJECT + +.TP +.B dev <interface name> +- network interface. + +.TP +.B phy <phy name> +- wireless hardware device (by name). +.TP +.B phy#<phy index> +- wireless hardware device (by index). + +.TP +.B reg +- regulatory agent. + +.SS +.I COMMAND + +Specifies the action to perform on the object. +The set of possible actions depends on the object type. +.B iw help +will print all supported commands, while +.B iw help command +will print the help for all matching commands. + +.SH SEE ALSO +.BR ip (8), +.BR crda (8), +.BR regdbdump (8), +.BR regulatory.bin (5) + +.BR http://wireless.kernel.org/en/users/Documentation/iw
diff --git a/iw_3.10/iw_3.10/iw.c b/iw_3.10/iw_3.10/iw.c new file mode 100644 index 0000000..dc99566 --- /dev/null +++ b/iw_3.10/iw_3.10/iw.c
@@ -0,0 +1,567 @@ +/* + * nl80211 userspace tool + * + * Copyright 2007, 2008 Johannes Berg <johannes@sipsolutions.net> + */ + +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <net/if.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +/* libnl 1.x compatibility code */ +#if !defined(CONFIG_LIBNL20) && !defined(CONFIG_LIBNL30) +static inline struct nl_handle *nl_socket_alloc(void) +{ + return nl_handle_alloc(); +} + +static inline void nl_socket_free(struct nl_sock *h) +{ + nl_handle_destroy(h); +} + +static inline int nl_socket_set_buffer_size(struct nl_sock *sk, + int rxbuf, int txbuf) +{ + return nl_set_buffer_size(sk, rxbuf, txbuf); +} +#endif /* CONFIG_LIBNL20 && CONFIG_LIBNL30 */ + +int iw_debug = 0; + +static int nl80211_init(struct nl80211_state *state) +{ + int err; + + state->nl_sock = nl_socket_alloc(); + if (!state->nl_sock) { + fprintf(stderr, "Failed to allocate netlink socket.\n"); + return -ENOMEM; + } + + nl_socket_set_buffer_size(state->nl_sock, 8192, 8192); + + if (genl_connect(state->nl_sock)) { + fprintf(stderr, "Failed to connect to generic netlink.\n"); + err = -ENOLINK; + goto out_handle_destroy; + } + + state->nl80211_id = genl_ctrl_resolve(state->nl_sock, "nl80211"); + if (state->nl80211_id < 0) { + fprintf(stderr, "nl80211 not found.\n"); + err = -ENOENT; + goto out_handle_destroy; + } + + return 0; + + out_handle_destroy: + nl_socket_free(state->nl_sock); + return err; +} + +static void nl80211_cleanup(struct nl80211_state *state) +{ + nl_socket_free(state->nl_sock); +} + +static int cmd_size; + +extern struct cmd __start___cmd; +extern struct cmd __stop___cmd; + +#define for_each_cmd(_cmd) \ + for (_cmd = &__start___cmd; _cmd < &__stop___cmd; \ + _cmd = (const struct cmd *)((char *)_cmd + cmd_size)) + + +static void __usage_cmd(const struct cmd *cmd, char *indent, bool full) +{ + const char *start, *lend, *end; + + printf("%s", indent); + + switch (cmd->idby) { + case CIB_NONE: + break; + case CIB_PHY: + printf("phy <phyname> "); + break; + case CIB_NETDEV: + printf("dev <devname> "); + break; + case CIB_WDEV: + printf("wdev <idx> "); + break; + } + if (cmd->parent && cmd->parent->name) + printf("%s ", cmd->parent->name); + printf("%s", cmd->name); + + if (cmd->args) { + /* print line by line */ + start = cmd->args; + end = strchr(start, '\0'); + printf(" "); + do { + lend = strchr(start, '\n'); + if (!lend) + lend = end; + if (start != cmd->args) { + printf("\t"); + switch (cmd->idby) { + case CIB_NONE: + break; + case CIB_PHY: + printf("phy <phyname> "); + break; + case CIB_NETDEV: + printf("dev <devname> "); + break; + case CIB_WDEV: + printf("wdev <idx> "); + break; + } + if (cmd->parent && cmd->parent->name) + printf("%s ", cmd->parent->name); + printf("%s ", cmd->name); + } + printf("%.*s\n", (int)(lend - start), start); + start = lend + 1; + } while (end != lend); + } else + printf("\n"); + + if (!full || !cmd->help) + return; + + /* hack */ + if (strlen(indent)) + indent = "\t\t"; + else + printf("\n"); + + /* print line by line */ + start = cmd->help; + end = strchr(start, '\0'); + do { + lend = strchr(start, '\n'); + if (!lend) + lend = end; + printf("%s", indent); + printf("%.*s\n", (int)(lend - start), start); + start = lend + 1; + } while (end != lend); + + printf("\n"); +} + +static void usage_options(void) +{ + printf("Options:\n"); + printf("\t--debug\t\tenable netlink debugging\n"); +} + +static const char *argv0; + +static void usage(int argc, char **argv) +{ + const struct cmd *section, *cmd; + bool full = argc >= 0; + const char *sect_filt = NULL; + const char *cmd_filt = NULL; + + if (argc > 0) + sect_filt = argv[0]; + + if (argc > 1) + cmd_filt = argv[1]; + + printf("Usage:\t%s [options] command\n", argv0); + usage_options(); + printf("\t--version\tshow version (%s)\n", iw_version); + printf("Commands:\n"); + for_each_cmd(section) { + if (section->parent) + continue; + + if (sect_filt && strcmp(section->name, sect_filt)) + continue; + + if (section->handler && !section->hidden) + __usage_cmd(section, "\t", full); + + for_each_cmd(cmd) { + if (section != cmd->parent) + continue; + if (!cmd->handler || cmd->hidden) + continue; + if (cmd_filt && strcmp(cmd->name, cmd_filt)) + continue; + __usage_cmd(cmd, "\t", full); + } + } + printf("\nCommands that use the netdev ('dev') can also be given the\n" + "'wdev' instead to identify the device.\n"); + printf("\nYou can omit the 'phy' or 'dev' if " + "the identification is unique,\n" + "e.g. \"iw wlan0 info\" or \"iw phy0 info\". " + "(Don't when scripting.)\n\n" + "Do NOT screenscrape this tool, we don't " + "consider its output stable.\n\n"); +} + +static int print_help(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + exit(3); +} +TOPLEVEL(help, "[command]", 0, 0, CIB_NONE, print_help, + "Print usage for all or a specific command, e.g.\n" + "\"help wowlan\" or \"help wowlan enable\"."); + +static void usage_cmd(const struct cmd *cmd) +{ + printf("Usage:\t%s [options] ", argv0); + __usage_cmd(cmd, "", true); + usage_options(); +} + +static void version(void) +{ + printf("iw version %s\n", iw_version); +} + +static int phy_lookup(char *name) +{ + char buf[200]; + int fd, pos; + + snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", name); + + fd = open(buf, O_RDONLY); + if (fd < 0) + return -1; + pos = read(fd, buf, sizeof(buf) - 1); + if (pos < 0) { + close(fd); + return -1; + } + buf[pos] = '\0'; + close(fd); + return atoi(buf); +} + +static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) +{ + int *ret = arg; + *ret = err->error; + return NL_STOP; +} + +static int finish_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_SKIP; +} + +static int ack_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + *ret = 0; + return NL_STOP; +} + +static int __handle_cmd(struct nl80211_state *state, enum id_input idby, + int argc, char **argv, const struct cmd **cmdout) +{ + const struct cmd *cmd, *match = NULL, *sectcmd; + struct nl_cb *cb; + struct nl_cb *s_cb; + struct nl_msg *msg; + signed long long devidx = 0; + int err, o_argc; + const char *command, *section; + char *tmp, **o_argv; + enum command_identify_by command_idby = CIB_NONE; + + if (argc <= 1 && idby != II_NONE) + return 1; + + o_argc = argc; + o_argv = argv; + + switch (idby) { + case II_PHY_IDX: + command_idby = CIB_PHY; + devidx = strtoul(*argv + 4, &tmp, 0); + if (*tmp != '\0') + return 1; + argc--; + argv++; + break; + case II_PHY_NAME: + command_idby = CIB_PHY; + devidx = phy_lookup(*argv); + argc--; + argv++; + break; + case II_NETDEV: + command_idby = CIB_NETDEV; + devidx = if_nametoindex(*argv); + if (devidx == 0) + devidx = -1; + argc--; + argv++; + break; + case II_WDEV: + command_idby = CIB_WDEV; + devidx = strtoll(*argv, &tmp, 0); + if (*tmp != '\0') + return 1; + argc--; + argv++; + default: + break; + } + + if (devidx < 0) + return -errno; + + section = *argv; + argc--; + argv++; + + for_each_cmd(sectcmd) { + if (sectcmd->parent) + continue; + /* ok ... bit of a hack for the dupe 'info' section */ + if (match && sectcmd->idby != command_idby) + continue; + if (strcmp(sectcmd->name, section) == 0) + match = sectcmd; + } + + sectcmd = match; + match = NULL; + if (!sectcmd) + return 1; + + if (argc > 0) { + command = *argv; + + for_each_cmd(cmd) { + if (!cmd->handler) + continue; + if (cmd->parent != sectcmd) + continue; + /* + * ignore mismatch id by, but allow WDEV + * in place of NETDEV + */ + if (cmd->idby != command_idby && + !(cmd->idby == CIB_NETDEV && + command_idby == CIB_WDEV)) + continue; + if (strcmp(cmd->name, command)) + continue; + if (argc > 1 && !cmd->args) + continue; + match = cmd; + break; + } + + if (match) { + argc--; + argv++; + } + } + + if (match) + cmd = match; + else { + /* Use the section itself, if possible. */ + cmd = sectcmd; + if (argc && !cmd->args) + return 1; + if (cmd->idby != command_idby && + !(cmd->idby == CIB_NETDEV && command_idby == CIB_WDEV)) + return 1; + if (!cmd->handler) + return 1; + } + + if (cmd->selector) { + cmd = cmd->selector(argc, argv); + if (!cmd) + return 1; + } + + if (cmdout) + *cmdout = cmd; + + if (!cmd->cmd) { + argc = o_argc; + argv = o_argv; + return cmd->handler(state, NULL, NULL, argc, argv, idby); + } + + msg = nlmsg_alloc(); + if (!msg) { + fprintf(stderr, "failed to allocate netlink message\n"); + return 2; + } + + cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); + s_cb = nl_cb_alloc(iw_debug ? NL_CB_DEBUG : NL_CB_DEFAULT); + if (!cb || !s_cb) { + fprintf(stderr, "failed to allocate netlink callbacks\n"); + err = 2; + goto out_free_msg; + } + + genlmsg_put(msg, 0, 0, state->nl80211_id, 0, + cmd->nl_msg_flags, cmd->cmd, 0); + + switch (command_idby) { + case CIB_PHY: + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx); + break; + case CIB_NETDEV: + NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, devidx); + break; + case CIB_WDEV: + NLA_PUT_U64(msg, NL80211_ATTR_WDEV, devidx); + break; + default: + break; + } + + err = cmd->handler(state, cb, msg, argc, argv, idby); + if (err) + goto out; + + nl_socket_set_cb(state->nl_sock, s_cb); + + err = nl_send_auto_complete(state->nl_sock, msg); + if (err < 0) + goto out; + + err = 1; + + nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err); + nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err); + + while (err > 0) + nl_recvmsgs(state->nl_sock, cb); + out: + nl_cb_put(cb); + out_free_msg: + nlmsg_free(msg); + return err; + nla_put_failure: + fprintf(stderr, "building message failed\n"); + return 2; +} + +int handle_cmd(struct nl80211_state *state, enum id_input idby, + int argc, char **argv) +{ + return __handle_cmd(state, idby, argc, argv, NULL); +} + +int main(int argc, char **argv) +{ + struct nl80211_state nlstate; + int err; + const struct cmd *cmd = NULL; + + /* calculate command size including padding */ + cmd_size = abs((long)&__section_set - (long)&__section_get); + /* strip off self */ + argc--; + argv0 = *argv++; + + if (argc > 0 && strcmp(*argv, "--debug") == 0) { + iw_debug = 1; + argc--; + argv++; + } + + if (argc > 0 && strcmp(*argv, "--version") == 0) { + version(); + return 0; + } + + /* need to treat "help" command specially so it works w/o nl80211 */ + if (argc == 0 || strcmp(*argv, "help") == 0) { + usage(argc - 1, argv + 1); + return 0; + } + + err = nl80211_init(&nlstate); + if (err) + return 1; + + if (strcmp(*argv, "dev") == 0 && argc > 1) { + argc--; + argv++; + err = __handle_cmd(&nlstate, II_NETDEV, argc, argv, &cmd); + } else if (strncmp(*argv, "phy", 3) == 0 && argc > 1) { + if (strlen(*argv) == 3) { + argc--; + argv++; + err = __handle_cmd(&nlstate, II_PHY_NAME, argc, argv, &cmd); + } else if (*(*argv + 3) == '#') + err = __handle_cmd(&nlstate, II_PHY_IDX, argc, argv, &cmd); + else + goto detect; + } else if (strcmp(*argv, "wdev") == 0 && argc > 1) { + argc--; + argv++; + err = __handle_cmd(&nlstate, II_WDEV, argc, argv, &cmd); + } else { + int idx; + enum id_input idby = II_NONE; + detect: + if ((idx = if_nametoindex(argv[0])) != 0) + idby = II_NETDEV; + else if ((idx = phy_lookup(argv[0])) >= 0) + idby = II_PHY_NAME; + err = __handle_cmd(&nlstate, idby, argc, argv, &cmd); + } + + if (err == 1) { + if (cmd) + usage_cmd(cmd); + else + usage(0, NULL); + } else if (err < 0) + fprintf(stderr, "command failed: %s (%d)\n", strerror(-err), err); + + nl80211_cleanup(&nlstate); + + return err; +}
diff --git a/iw_3.10/iw_3.10/iw.h b/iw_3.10/iw_3.10/iw.h new file mode 100644 index 0000000..8816e88 --- /dev/null +++ b/iw_3.10/iw_3.10/iw.h
@@ -0,0 +1,178 @@ +#ifndef __IW_H +#define __IW_H + +#include <stdbool.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <endian.h> + +#include "nl80211.h" +#include "ieee80211.h" + +#define ETH_ALEN 6 + +/* libnl 1.x compatibility code */ +#if !defined(CONFIG_LIBNL20) && !defined(CONFIG_LIBNL30) +# define nl_sock nl_handle +#endif + +struct nl80211_state { + struct nl_sock *nl_sock; + int nl80211_id; +}; + +enum command_identify_by { + CIB_NONE, + CIB_PHY, + CIB_NETDEV, + CIB_WDEV, +}; + +enum id_input { + II_NONE, + II_NETDEV, + II_PHY_NAME, + II_PHY_IDX, + II_WDEV, +}; + +struct cmd { + const char *name; + const char *args; + const char *help; + const enum nl80211_commands cmd; + int nl_msg_flags; + int hidden; + const enum command_identify_by idby; + /* + * The handler should return a negative error code, + * zero on success, 1 if the arguments were wrong + * and the usage message should and 2 otherwise. + */ + int (*handler)(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id); + const struct cmd *(*selector)(int argc, char **argv); + const struct cmd *parent; +}; + +#define ARRAY_SIZE(ar) (sizeof(ar)/sizeof(ar[0])) +#define DIV_ROUND_UP(x, y) (((x) + (y - 1)) / (y)) + +#define __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel)\ + static struct cmd \ + __cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden\ + __attribute__((used)) __attribute__((section("__cmd"))) = { \ + .name = (_name), \ + .args = (_args), \ + .cmd = (_nlcmd), \ + .nl_msg_flags = (_flags), \ + .hidden = (_hidden), \ + .idby = (_idby), \ + .handler = (_handler), \ + .help = (_help), \ + .parent = _section, \ + .selector = (_sel), \ + } +#define __ACMD(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel, _alias)\ + __COMMAND(_section, _symname, _name, _args, _nlcmd, _flags, _hidden, _idby, _handler, _help, _sel);\ + static const struct cmd *_alias = &__cmd ## _ ## _symname ## _ ## _handler ## _ ## _nlcmd ## _ ## _idby ## _ ## _hidden +#define COMMAND(section, name, args, cmd, flags, idby, handler, help) \ + __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help, NULL) +#define COMMAND_ALIAS(section, name, args, cmd, flags, idby, handler, help, selector, alias)\ + __ACMD(&(__section ## _ ## section), name, #name, args, cmd, flags, 0, idby, handler, help, selector, alias) +#define HIDDEN(section, name, args, cmd, flags, idby, handler) \ + __COMMAND(&(__section ## _ ## section), name, #name, args, cmd, flags, 1, idby, handler, NULL, NULL) + +#define TOPLEVEL(_name, _args, _nlcmd, _flags, _idby, _handler, _help) \ + struct cmd \ + __section ## _ ## _name \ + __attribute__((used)) __attribute__((section("__cmd"))) = { \ + .name = (#_name), \ + .args = (_args), \ + .cmd = (_nlcmd), \ + .nl_msg_flags = (_flags), \ + .idby = (_idby), \ + .handler = (_handler), \ + .help = (_help), \ + } +#define SECTION(_name) \ + struct cmd __section ## _ ## _name \ + __attribute__((used)) __attribute__((section("__cmd"))) = { \ + .name = (#_name), \ + .hidden = 1, \ + } + +#define DECLARE_SECTION(_name) \ + extern struct cmd __section ## _ ## _name; + +extern const char iw_version[]; + +extern int iw_debug; + +int handle_cmd(struct nl80211_state *state, enum id_input idby, + int argc, char **argv); + +struct print_event_args { + struct timeval ts; /* internal */ + bool have_ts; /* must be set false */ + bool frame, time, reltime; +}; + +__u32 listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits); +int __prepare_listen_events(struct nl80211_state *state); +__u32 __do_listen_events(struct nl80211_state *state, + const int n_waits, const __u32 *waits, + struct print_event_args *args); + + +int mac_addr_a2n(unsigned char *mac_addr, char *arg); +void mac_addr_n2a(char *mac_addr, unsigned char *arg); +int parse_hex_mask(char *hexmask, unsigned char **result, size_t *result_len, + unsigned char **mask); +unsigned char *parse_hex(char *hex, size_t *outlen); + +int parse_keys(struct nl_msg *msg, char **argv, int argc); + +void print_ht_mcs(const __u8 *mcs); +void print_ampdu_length(__u8 exponent); +void print_ampdu_spacing(__u8 spacing); +void print_ht_capability(__u16 cap); +void print_vht_info(__u32 capa, const __u8 *mcs); + +char *channel_width_name(enum nl80211_chan_width width); +const char *iftype_name(enum nl80211_iftype iftype); +const char *command_name(enum nl80211_commands cmd); +int ieee80211_channel_to_frequency(int chan); +int ieee80211_frequency_to_channel(int freq); + +void print_ssid_escaped(const uint8_t len, const uint8_t *data); + +int nl_get_multicast_id(struct nl_sock *sock, const char *family, const char *group); + +char *reg_initiator_to_string(__u8 initiator); + +const char *get_reason_str(uint16_t reason); +const char *get_status_str(uint16_t status); + +enum print_ie_type { + PRINT_SCAN, + PRINT_LINK, +}; + +#define BIT(x) (1ULL<<(x)) + +void print_ies(unsigned char *ie, int ielen, bool unknown, + enum print_ie_type ptype); + +void parse_tx_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen); + +DECLARE_SECTION(set); +DECLARE_SECTION(get); + +#endif /* __IW_H */
diff --git a/iw_3.10/iw_3.10/keepalive.c b/iw_3.10/iw_3.10/keepalive.c new file mode 100644 index 0000000..b97bd1a --- /dev/null +++ b/iw_3.10/iw_3.10/keepalive.c
@@ -0,0 +1,286 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; + +#define CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH 64 + +struct cfg80211_keepalive_request { + u32 interval; + u8 cmd; /* 0: ADD; 1: DEL: 2: START; 3: STOP */ + u8 index; + u8 trig; + u8 dst_macaddr[ETH_ALEN]; + u8 payload_len; + u8 payload[CFG80211_KEEP_ALIVE_PAYLOAD_MAX_LENGTH]; +}; + +struct cfg80211_keepalive_request keepalive_req; + +SECTION(keepalive); + +static void keepalive_hex_dump(char *title, u8 *buf, size_t len) +{ + int i; + + printf("%s - hexdump(len=%lu):", title, (unsigned long) len); + + for (i = 0; i < len; i++) + printf(" %02x", buf[i]); + printf("\n"); +} + +static int nl80211_parse_klv_req(const char *s) +{ + long i; + char *endp; + + i = strtol(s, &endp, 10); + + if(endp == s) + return -1; + return i; +} + +static int nl80211_str2hex(u8 *src, u8 *dst, int src_len) +{ + int i, bytecount=0; + + if (src_len & 0x01) + return -2; + + for (i=0; i<src_len; i++, src++) { + if (i != 0 && i%2 == 0) { + dst++; + bytecount++; + } else { + *dst <<= 4; + } + + if ((*src >= '0') && (*src <= '9')) + *dst += *src - '0'; + else if ((*src >= 'A') && (*src <= 'F')) + *dst += *src - 'A' + 10; + else if ((*src >= 'a') && (*src <= 'f')) + *dst += *src - 'a' + 10; + else { + return -1; + } + } + + bytecount++; + + return bytecount; +} + +static int build_klv_req(struct nl_msg *msg, int klv_cmd, u8 index, int interval, u8 trig, u8 *dst_macaddr, u8 payload_len, u8 *payload) +{ + int ret = -1; + + if (!msg) + return -1; + + NLA_PUT_U32(msg, NL80211_ATTR_KLV_TYPE, klv_cmd); + NLA_PUT_U32(msg, NL80211_ATTR_KLV_INDEX, index); + + if (klv_cmd == 0 || klv_cmd == 1) { + + NLA_PUT_U32(msg, NL80211_ATTR_KLV_INTVL, interval); + NLA_PUT_U32 (msg, NL80211_ATTR_KLV_TRIG, trig); + + if (payload != NULL) { + if (dst_macaddr) { + keepalive_hex_dump("nl80211 klv_dstmac: ", dst_macaddr, ETH_ALEN); + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst_macaddr); + } + + keepalive_hex_dump("nl80211 klv_payload: ", payload, payload_len); + NLA_PUT(msg, NL80211_ATTR_KLV_PAYLOAD, payload_len, payload); + } + } + + ret = 0; + + nla_put_failure: + return ret; +} + +static int nl80211_change_klv_req(char **cmdptr, int cmdtype, struct nl_msg *msg) +{ + u8 index = 1, trig_type = 1, payload_len = 0; + u8 dst_macaddr[ETH_ALEN]; + u32 interval_ms = 10; + int val; + u8 dst_payload[64]; + + switch(cmdtype) { + case 0: /* KLV-ADD */ + val = nl80211_parse_klv_req(*cmdptr++); + /* valid index # is [1, 3]. Index #0 is reserved for driver internal use */ + if (val <= 0 || val > 3) { + printf("invalid index (%d)\n", val); + return -1; + } + index = val; + + val = nl80211_parse_klv_req(*cmdptr++); + /* limit klv interval to [10 ms, 50000 ms] */ + if (val < 1000 || val > 55000) { + printf("Keeplalive interval is out of range.\n"); + return -1; + } + interval_ms = val; + + val = nl80211_parse_klv_req(*cmdptr++); + /* valid trig type is limited to 0 or 1 */ + if (val < 0 || val > 1) { + printf("Invalid keepalive trigger type.\n"); + return -1; + } + trig_type = val; + + memset(dst_macaddr, 0, ETH_ALEN); + if (nl80211_str2hex((u8 *)(*cmdptr++), dst_macaddr, 2*ETH_ALEN) <= 0) { + printf("Invalid mac address\n"); + return -1; + } + + val = strlen(*cmdptr); /* klv payload length must be <= 64 bytes */ + if (val > 128) { + printf("Payload is too long\n"); + return -1; + } + + memset(dst_payload, 0, 64); + if ((payload_len=nl80211_str2hex((u8 *)(*cmdptr), dst_payload, val)) < 0) { + printf("Keepalive payload is invalid\n"); + return -1; + } + + break; + + case 1: /* KLV-DEL */ + index = nl80211_parse_klv_req(cmdptr[0]); + printf("index = %d\n", index); + /* index #0 is reserved for driver internal klv type */ + if (index <= 0 || index > 3) { + return -1; + } + + interval_ms = 10000; + break; + + case 2: /* KLV-START */ + case 3: /* KLV-STOP */ + break; + + case 4: /* KLV-SHOW */ + printf("Not supported\n"); + val = 0; + return val; + + default: + return -1; + } + + val = build_klv_req(msg, cmdtype, index, interval_ms, trig_type, &dst_macaddr[0], payload_len, dst_payload); + + return val; +} + +static int handle_keepalive_add(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, enum id_input id) +{ + int ret; + + if (argc != 5) { + printf("Command parameters incorrect.\n"); + return -1; + } + + ret = nl80211_change_klv_req(argv, 0, msg); + printf("ret is %d\n", ret); + return ret; +} + +static int handle_keepalive_delete(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, enum id_input id) +{ + int ret; + + if (argc != 1) { + printf("Command parameters incorrect.\n"); + return -1; + } + + ret = nl80211_change_klv_req(argv, 1, msg); + return ret; +} + +static int handle_keepalive_start(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, enum id_input id) +{ + int ret; + ret = nl80211_change_klv_req(argv, 2, msg); + return ret; +} + +static int handle_keepalive_stop(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, enum id_input id) +{ + int ret; + ret = nl80211_change_klv_req(argv, 3, msg); + return ret; +} + +static int print_keepalive_handler(struct nl_msg *msg, void *arg) +{ + int *ret = arg; + if (arg != NULL) + *ret = 0; + return 0; +} + +static int handle_keepalive_show(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, enum id_input id) +{ + int ret; + + printf("handle_keepalive_show\n"); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_keepalive_handler, &ret); + + return 0; +} + +COMMAND(keepalive, add, "<index> <interval> <trigger_type> <dst_macaddr> <payload>", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_add, + "Configure keep alive feature"); + +COMMAND(keepalive, del, "<index>", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_delete, + "Configure keep alive feature"); + +COMMAND(keepalive, start, "", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_start, + "Configure keep alive feature"); + +COMMAND(keepalive, stop, "", + NL80211_CMD_SET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_stop, + "Configure keep alive feature"); + +COMMAND(keepalive, show, "", NL80211_CMD_GET_KEEPALIVE, 0, CIB_NETDEV, handle_keepalive_show, + "Show keepalive status.");
diff --git a/iw_3.10/iw_3.10/link.c b/iw_3.10/iw_3.10/link.c new file mode 100644 index 0000000..b8acd5c --- /dev/null +++ b/iw_3.10/iw_3.10/link.c
@@ -0,0 +1,275 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +struct link_result { + uint8_t bssid[8]; + bool link_found; + bool anything_found; +}; + +static struct link_result lr = { .link_found = false }; + +static int link_bss_handler(struct nl_msg *msg, void *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 }, + }; + struct link_result *result = arg; + char mac_addr[20], dev[20]; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_BSS]) { + fprintf(stderr, "bss info missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(bss, NL80211_BSS_MAX, + tb[NL80211_ATTR_BSS], + bss_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (!bss[NL80211_BSS_BSSID]) + return NL_SKIP; + + if (!bss[NL80211_BSS_STATUS]) + return NL_SKIP; + + mac_addr_n2a(mac_addr, nla_data(bss[NL80211_BSS_BSSID])); + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + + switch (nla_get_u32(bss[NL80211_BSS_STATUS])) { + case NL80211_BSS_STATUS_ASSOCIATED: + printf("Connected to %s (on %s)\n", mac_addr, dev); + break; + case NL80211_BSS_STATUS_AUTHENTICATED: + printf("Authenticated with %s (on %s)\n", mac_addr, dev); + return NL_SKIP; + case NL80211_BSS_STATUS_IBSS_JOINED: + printf("Joined IBSS %s (on %s)\n", mac_addr, dev); + break; + default: + return NL_SKIP; + } + + result->anything_found = true; + + if (bss[NL80211_BSS_INFORMATION_ELEMENTS]) + print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + false, PRINT_LINK); + + if (bss[NL80211_BSS_FREQUENCY]) + printf("\tfreq: %d\n", + nla_get_u32(bss[NL80211_BSS_FREQUENCY])); + + if (nla_get_u32(bss[NL80211_BSS_STATUS]) != NL80211_BSS_STATUS_ASSOCIATED) + return NL_SKIP; + + /* only in the assoc case do we want more info from station get */ + result->link_found = true; + memcpy(result->bssid, nla_data(bss[NL80211_BSS_BSSID]), 6); + return NL_SKIP; +} + +static int handle_scan_for_link(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + if (argc > 0) + return 1; + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, link_bss_handler, &lr); + return 0; +} + +static int print_link_sta(struct nl_msg *msg, void *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]; + static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { + [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_TX_BITRATE] = { .type = NLA_NESTED }, + [NL80211_STA_INFO_LLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLID] = { .type = NLA_U16 }, + [NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 }, + }; + 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]) { + fprintf(stderr, "sta stats missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, + tb[NL80211_ATTR_STA_INFO], + stats_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (sinfo[NL80211_STA_INFO_RX_BYTES] && sinfo[NL80211_STA_INFO_RX_PACKETS]) + printf("\tRX: %u bytes (%u packets)\n", + nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]), + nla_get_u32(sinfo[NL80211_STA_INFO_RX_PACKETS])); + if (sinfo[NL80211_STA_INFO_TX_BYTES] && sinfo[NL80211_STA_INFO_TX_PACKETS]) + printf("\tTX: %u bytes (%u packets)\n", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]), + nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS])); + if (sinfo[NL80211_STA_INFO_SIGNAL]) + printf("\tsignal: %d dBm\n", + (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL])); + + if (sinfo[NL80211_STA_INFO_TX_BITRATE]) { + char buf[100]; + + parse_tx_bitrate(sinfo[NL80211_STA_INFO_TX_BITRATE], buf, sizeof(buf)); + printf("\ttx bitrate: %s\n", buf); + } + + 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)) { + fprintf(stderr, "failed to parse nested bss parameters!\n"); + } else { + char *delim = ""; + printf("\n\tbss flags:\t"); + if (binfo[NL80211_STA_BSS_PARAM_CTS_PROT]) { + printf("CTS-protection"); + delim = " "; + } + if (binfo[NL80211_STA_BSS_PARAM_SHORT_PREAMBLE]) { + printf("%sshort-preamble", delim); + delim = " "; + } + if (binfo[NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME]) + printf("%sshort-slot-time", delim); + printf("\n\tdtim period:\t%d", + nla_get_u8(binfo[NL80211_STA_BSS_PARAM_DTIM_PERIOD])); + printf("\n\tbeacon int:\t%d", + nla_get_u16(binfo[NL80211_STA_BSS_PARAM_BEACON_INTERVAL])); + printf("\n"); + } + } + + return NL_SKIP; +} + +static int handle_link_sta(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_link_sta, NULL); + + return 0; + nla_put_failure: + return -ENOBUFS; +} + +static int handle_link(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + char *link_argv[] = { + NULL, + "link", + "get_bss", + NULL, + }; + char *station_argv[] = { + NULL, + "link", + "get_sta", + NULL, + NULL, + }; + char bssid_buf[3*6]; + int err; + + link_argv[0] = argv[0]; + err = handle_cmd(state, id, 3, link_argv); + if (err) + return err; + + if (!lr.link_found) { + if (!lr.anything_found) + printf("Not connected.\n"); + return 0; + } + + mac_addr_n2a(bssid_buf, lr.bssid); + bssid_buf[17] = '\0'; + + station_argv[0] = argv[0]; + station_argv[3] = bssid_buf; + return handle_cmd(state, id, 4, station_argv); +} +TOPLEVEL(link, NULL, 0, 0, CIB_NETDEV, handle_link, + "Print information about the current link, if any."); +HIDDEN(link, get_sta, "", NL80211_CMD_GET_STATION, 0, + CIB_NETDEV, handle_link_sta); +HIDDEN(link, get_bss, NULL, NL80211_CMD_GET_SCAN, NLM_F_DUMP, + CIB_NETDEV, handle_scan_for_link);
diff --git a/iw_3.10/iw_3.10/mesh.c b/iw_3.10/iw_3.10/mesh.c new file mode 100644 index 0000000..5a09b62 --- /dev/null +++ b/iw_3.10/iw_3.10/mesh.c
@@ -0,0 +1,525 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(mesh); + + +typedef struct _any_t { + union { + uint32_t as_32; + int32_t as_s32; + uint16_t as_16; + uint8_t as_8; + } u; +} _any; + +/* describes a mesh parameter */ +struct mesh_param_descr { + const char *name; + enum nl80211_meshconf_params mesh_param_num; + int (*nla_put_fn)(struct nl_msg*, int, _any*); + uint32_t (*parse_fn)(const char*, _any*); + void (*nla_print_fn)(struct nlattr *); +}; + +/* utility functions for manipulating and printing u8/u16/u32 values and + * timesouts. */ +static int _my_nla_put_u8(struct nl_msg *n, int mesh_param_num, _any *value) +{ + return nla_put(n, mesh_param_num, sizeof(uint8_t), &value->u.as_8); +} + +static int _my_nla_put_u16(struct nl_msg *n, int mesh_param_num, _any *value) +{ + return nla_put(n, mesh_param_num, sizeof(uint16_t), &value->u.as_16); +} + +static int _my_nla_put_u32(struct nl_msg *n, int mesh_param_num, _any *value) +{ + return nla_put(n, mesh_param_num, sizeof(uint32_t), &value->u.as_32); +} + +static uint32_t _parse_u8(const char *str, _any *ret) +{ + char *endptr = NULL; + unsigned long int v = strtoul(str, &endptr, 10); + if (*endptr != '\0') + return 0xff; + if (v > 0xff) + return 0xff; + ret->u.as_8 = (uint8_t)v; + return 0; +} + +static uint32_t _parse_u8_as_bool(const char *str, _any *ret) +{ + char *endptr = NULL; + unsigned long int v = strtoul(str, &endptr, 10); + if (*endptr != '\0') + return 0x1; + if (v > 0x1) + return 0x1; + ret->u.as_8 = (uint8_t)v; + return 0; +} + +static uint32_t _parse_u16(const char *str, _any *ret) +{ + char *endptr = NULL; + long int v = strtol(str, &endptr, 10); + if (*endptr != '\0') + return 0xffff; + if ((v < 0) || (v > 0xffff)) + return 0xffff; + ret->u.as_16 = (uint16_t)v; + return 0; +} + +static uint32_t _parse_u32(const char *str, _any *ret) +{ + char *endptr = NULL; + long long int v = strtoll(str, &endptr, 10); + if (*endptr != '\0') + return 0xffffffff; + if ((v < 0) || (v > 0xffffffff)) + return 0xffffffff; + ret->u.as_32 = (uint32_t)v; + return 0; +} + +static uint32_t _parse_s32(const char *str, _any *ret) +{ + char *endptr = NULL; + long int v = strtol(str, &endptr, 10); + if (*endptr != '\0') + return 0xffffffff; + if (v > 0xff) + return 0xffffffff; + ret->u.as_s32 = (int32_t)v; + return 0; +} + +static uint32_t _parse_u32_power_mode(const char *str, _any *ret) +{ + unsigned long int v; + + /* Parse attribute for the name of power mode */ + if (!strcmp(str, "active")) + v = NL80211_MESH_POWER_ACTIVE; + else if (!strcmp(str, "light")) + v = NL80211_MESH_POWER_LIGHT_SLEEP; + else if (!strcmp(str, "deep")) + v = NL80211_MESH_POWER_DEEP_SLEEP; + else + return 0xff; + + ret->u.as_32 = (uint32_t)v; + return 0; +} + +static void _print_u8(struct nlattr *a) +{ + printf("%d", nla_get_u8(a)); +} + +static void _print_u16(struct nlattr *a) +{ + printf("%d", nla_get_u16(a)); +} + +static void _print_u16_timeout(struct nlattr *a) +{ + printf("%d milliseconds", nla_get_u16(a)); +} + +static void _print_u16_in_TUs(struct nlattr *a) +{ + printf("%d TUs", nla_get_u16(a)); +} + +static void _print_u32(struct nlattr *a) +{ + printf("%d", nla_get_u32(a)); +} + +static void _print_u32_timeout(struct nlattr *a) +{ + printf("%u milliseconds", nla_get_u32(a)); +} + +static void _print_u32_in_TUs(struct nlattr *a) +{ + printf("%d TUs", nla_get_u32(a)); +} + +static void _print_u32_power_mode(struct nlattr *a) +{ + unsigned long v = nla_get_u32(a); + + switch (v) { + case NL80211_MESH_POWER_ACTIVE: + printf("active"); + break; + case NL80211_MESH_POWER_LIGHT_SLEEP: + printf("light"); + break; + case NL80211_MESH_POWER_DEEP_SLEEP: + printf("deep"); + break; + default: + printf("undefined"); + break; + } +} + +static void _print_s32_in_dBm(struct nlattr *a) +{ + printf("%d dBm", (int32_t) nla_get_u32(a)); +} + + +/* The current mesh parameters */ +const static struct mesh_param_descr _mesh_param_descrs[] = +{ + {"mesh_retry_timeout", + NL80211_MESHCONF_RETRY_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_confirm_timeout", + NL80211_MESHCONF_CONFIRM_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_holding_timeout", + NL80211_MESHCONF_HOLDING_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_max_peer_links", + NL80211_MESHCONF_MAX_PEER_LINKS, + _my_nla_put_u16, _parse_u16, _print_u16}, + {"mesh_max_retries", + NL80211_MESHCONF_MAX_RETRIES, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_ttl", + NL80211_MESHCONF_TTL, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_element_ttl", + NL80211_MESHCONF_ELEMENT_TTL, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_auto_open_plinks", + NL80211_MESHCONF_AUTO_OPEN_PLINKS, + _my_nla_put_u8, _parse_u8_as_bool, _print_u8}, + {"mesh_hwmp_max_preq_retries", + NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_path_refresh_time", + NL80211_MESHCONF_PATH_REFRESH_TIME, + _my_nla_put_u32, _parse_u32, _print_u32_timeout}, + {"mesh_min_discovery_timeout", + NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, + _my_nla_put_u16, _parse_u16, _print_u16_timeout}, + {"mesh_hwmp_active_path_timeout", + NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, + _my_nla_put_u32, _parse_u32, _print_u32_in_TUs}, + {"mesh_hwmp_preq_min_interval", + NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, + {"mesh_hwmp_net_diameter_traversal_time", + NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, + {"mesh_hwmp_rootmode", NL80211_MESHCONF_HWMP_ROOTMODE, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_hwmp_rann_interval", NL80211_MESHCONF_HWMP_RANN_INTERVAL, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, + {"mesh_gate_announcements", NL80211_MESHCONF_GATE_ANNOUNCEMENTS, + _my_nla_put_u8, _parse_u8, _print_u8}, + {"mesh_fwding", NL80211_MESHCONF_FORWARDING, + _my_nla_put_u8, _parse_u8_as_bool, _print_u8}, + {"mesh_sync_offset_max_neighor", + NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, + _my_nla_put_u32, _parse_u32, _print_u32}, + {"mesh_rssi_threshold", NL80211_MESHCONF_RSSI_THRESHOLD, + _my_nla_put_u32, _parse_s32, _print_s32_in_dBm}, + {"mesh_hwmp_active_path_to_root_timeout", + NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, + _my_nla_put_u32, _parse_u32, _print_u32_in_TUs}, + {"mesh_hwmp_root_interval", NL80211_MESHCONF_HWMP_ROOT_INTERVAL, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, + {"mesh_hwmp_confirmation_interval", + NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, + {"mesh_power_mode", NL80211_MESHCONF_POWER_MODE, + _my_nla_put_u32, _parse_u32_power_mode, _print_u32_power_mode}, + {"mesh_awake_window", NL80211_MESHCONF_AWAKE_WINDOW, + _my_nla_put_u16, _parse_u16, _print_u16_in_TUs}, +}; + +static void print_all_mesh_param_descr(void) +{ + int i; + + printf("Possible mesh parameters are:\n"); + + for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) + printf(" - %s\n", _mesh_param_descrs[i].name); +} + +static const struct mesh_param_descr *find_mesh_param(const char *name) +{ + int i; + + /* Find out what mesh parameter we want to change. */ + for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) { + if (strcmp(_mesh_param_descrs[i].name, name) == 0) + return _mesh_param_descrs + i; + } + + print_all_mesh_param_descr(); + return NULL; +} + +/* Setter */ +static int set_interface_meshparam(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + const struct mesh_param_descr *mdescr; + struct nlattr *container; + uint32_t ret; + int err; + + container = nla_nest_start(msg, NL80211_ATTR_MESH_PARAMS); + if (!container) + return -ENOBUFS; + + if (!argc) + return 1; + + while (argc) { + const char *name; + char *value; + _any any; + + memset(&any, 0, sizeof(_any)); + + name = argv[0]; + value = strchr(name, '='); + if (value) { + *value = '\0'; + value++; + argc--; + argv++; + } else { + /* backward compat -- accept w/o '=' */ + if (argc < 2) { + printf("Must specify a value for %s.\n", name); + return 2; + } + value = argv[1]; + argc -= 2; + argv += 2; + } + + mdescr = find_mesh_param(name); + if (!mdescr) + return 2; + + /* Parse the new value */ + ret = mdescr->parse_fn(value, &any); + if (ret != 0) { + if (mdescr->mesh_param_num + == NL80211_MESHCONF_POWER_MODE) + printf("%s must be set to active, light or " + "deep.\n", mdescr->name); + else + printf("%s must be set to a number " + "between 0 and %u\n", + mdescr->name, ret); + + return 2; + } + + err = mdescr->nla_put_fn(msg, mdescr->mesh_param_num, &any); + if (err) + return err; + } + nla_nest_end(msg, container); + + return err; +} + +COMMAND(set, mesh_param, "<param>=<value> [<param>=<value>]*", + NL80211_CMD_SET_MESH_PARAMS, 0, CIB_NETDEV, set_interface_meshparam, + "Set mesh parameter (run command without any to see available ones)."); + +/* Getter */ +static int print_mesh_param_handler(struct nl_msg *msg, void *arg) +{ + const struct mesh_param_descr *mdescr = arg; + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct nlattr *parent_attr; + struct nlattr *mesh_params[NL80211_MESHCONF_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + + /* locate NL80211_ATTR_MESH_PARAMS */ + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + parent_attr = attrs[NL80211_ATTR_MESH_PARAMS]; + if (!parent_attr) + return -EINVAL; + + /* unpack the mesh parameters */ + if (nla_parse_nested(mesh_params, NL80211_MESHCONF_ATTR_MAX, + parent_attr, NULL)) + return -EINVAL; + + if (!mdescr) { + int i; + + for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) { + mdescr = &_mesh_param_descrs[i]; + printf("%s = ", mdescr->name); + mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]); + printf("\n"); + } + return NL_SKIP; + } + + /* print out the mesh parameter */ + mdescr->nla_print_fn(mesh_params[mdescr->mesh_param_num]); + printf("\n"); + return NL_SKIP; +} + +static int get_interface_meshparam(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + const struct mesh_param_descr *mdescr = NULL; + + if (argc > 1) + return 1; + + if (argc == 1) { + mdescr = find_mesh_param(argv[0]); + if (!mdescr) + return 2; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_mesh_param_handler, (void *)mdescr); + return 0; +} + +COMMAND(get, mesh_param, "[<param>]", + NL80211_CMD_GET_MESH_PARAMS, 0, CIB_NETDEV, get_interface_meshparam, + "Retrieve mesh parameter (run command without any to see available ones)."); + +static int join_mesh(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + struct nlattr *container; + float rate; + int bintval, dtim_period; + char *end; + + if (argc < 1) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(argv[0]), argv[0]); + argc--; + argv++; + + if (argc > 1 && strcmp(argv[0], "mcast-rate") == 0) { + argv++; + argc--; + + rate = strtod(argv[0], &end); + if (*end != '\0') + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_MCAST_RATE, (int)(rate * 10)); + argv++; + argc--; + } + + if (argc > 1 && strcmp(argv[0], "beacon-interval") == 0) { + argc--; + argv++; + + bintval = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, bintval); + argv++; + argc--; + } + + if (argc > 1 && strcmp(argv[0], "dtim-period") == 0) { + argc--; + argv++; + + dtim_period = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, dtim_period); + argv++; + argc--; + } + + container = nla_nest_start(msg, NL80211_ATTR_MESH_SETUP); + if (!container) + return -ENOBUFS; + + if (argc > 1 && strcmp(argv[0], "vendor_sync") == 0) { + argv++; + argc--; + if (strcmp(argv[0], "on") == 0) + NLA_PUT_U8(msg, + NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC, 1); + else + NLA_PUT_U8(msg, + NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC, 0); + argv++; + argc--; + } + /* parse and put other NL80211_ATTR_MESH_SETUP elements here */ + + nla_nest_end(msg, container); + + if (!argc) + return 0; + return set_interface_meshparam(state, cb, msg, argc, argv, id); + nla_put_failure: + return -ENOBUFS; +} +COMMAND(mesh, join, "<mesh ID> [mcast-rate <rate in Mbps>]" + " [beacon-interval <time in TUs>] [dtim-period <value>]" + " [vendor_sync on|off] [<param>=<value>]*", + NL80211_CMD_JOIN_MESH, 0, CIB_NETDEV, join_mesh, + "Join a mesh with the given mesh ID with mcast-rate and mesh parameters."); + +static int leave_mesh(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + if (argc) + return 1; + + return 0; +} +COMMAND(mesh, leave, NULL, NL80211_CMD_LEAVE_MESH, 0, CIB_NETDEV, leave_mesh, + "Leave a mesh.");
diff --git a/iw_3.10/iw_3.10/mpath.c b/iw_3.10/iw_3.10/mpath.c new file mode 100644 index 0000000..25c538a --- /dev/null +++ b/iw_3.10/iw_3.10/mpath.c
@@ -0,0 +1,191 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(mpath); + +enum plink_state { + LISTEN, + OPN_SNT, + OPN_RCVD, + CNF_RCVD, + ESTAB, + HOLDING, + BLOCKED +}; + + +static int print_mpath_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *pinfo[NL80211_MPATH_INFO_MAX + 1]; + char dst[20], next_hop[20], dev[20]; + static struct nla_policy mpath_policy[NL80211_MPATH_INFO_MAX + 1] = { + [NL80211_MPATH_INFO_FRAME_QLEN] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_SN] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_METRIC] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_EXPTIME] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_DISCOVERY_TIMEOUT] = { .type = NLA_U32 }, + [NL80211_MPATH_INFO_DISCOVERY_RETRIES] = { .type = NLA_U8 }, + [NL80211_MPATH_INFO_FLAGS] = { .type = NLA_U8 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + /* + * TODO: validate the interface and mac address! + * Otherwise, there's a race condition as soon as + * the kernel starts sending mpath notifications. + */ + + if (!tb[NL80211_ATTR_MPATH_INFO]) { + fprintf(stderr, "mpath info missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(pinfo, NL80211_MPATH_INFO_MAX, + tb[NL80211_ATTR_MPATH_INFO], + mpath_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + mac_addr_n2a(dst, nla_data(tb[NL80211_ATTR_MAC])); + mac_addr_n2a(next_hop, nla_data(tb[NL80211_ATTR_MPATH_NEXT_HOP])); + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("%s %s %s", dst, next_hop, dev); + if (pinfo[NL80211_MPATH_INFO_SN]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_SN])); + if (pinfo[NL80211_MPATH_INFO_METRIC]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_METRIC])); + if (pinfo[NL80211_MPATH_INFO_FRAME_QLEN]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_FRAME_QLEN])); + if (pinfo[NL80211_MPATH_INFO_EXPTIME]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_EXPTIME])); + if (pinfo[NL80211_MPATH_INFO_DISCOVERY_TIMEOUT]) + printf("\t%u", + nla_get_u32(pinfo[NL80211_MPATH_INFO_DISCOVERY_TIMEOUT])); + if (pinfo[NL80211_MPATH_INFO_DISCOVERY_RETRIES]) + printf("\t%u", + nla_get_u8(pinfo[NL80211_MPATH_INFO_DISCOVERY_RETRIES])); + if (pinfo[NL80211_MPATH_INFO_FLAGS]) + printf("\t0x%x", + nla_get_u8(pinfo[NL80211_MPATH_INFO_FLAGS])); + + printf("\n"); + return NL_SKIP; +} + +static int handle_mpath_get(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char dst[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(dst, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(mpath, get, "<MAC address>", + NL80211_CMD_GET_MPATH, 0, CIB_NETDEV, handle_mpath_get, + "Get information on mesh path to the given node."); +COMMAND(mpath, del, "<MAC address>", + NL80211_CMD_DEL_MPATH, 0, CIB_NETDEV, handle_mpath_get, + "Remove the mesh path to the given node."); + +static int handle_mpath_set(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char dst[ETH_ALEN]; + unsigned char next_hop[ETH_ALEN]; + + if (argc < 3) + return 1; + + if (mac_addr_a2n(dst, argv[0])) { + fprintf(stderr, "invalid destination mac address\n"); + return 2; + } + argc--; + argv++; + + if (strcmp("next_hop", argv[0]) != 0) + return 1; + argc--; + argv++; + + if (mac_addr_a2n(next_hop, argv[0])) { + fprintf(stderr, "invalid next hop mac address\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst); + NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL); + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(mpath, new, "<destination MAC address> next_hop <next hop MAC address>", + NL80211_CMD_NEW_MPATH, 0, CIB_NETDEV, handle_mpath_set, + "Create a new mesh path (instead of relying on automatic discovery)."); +COMMAND(mpath, set, "<destination MAC address> next_hop <next hop MAC address>", + NL80211_CMD_SET_MPATH, 0, CIB_NETDEV, handle_mpath_set, + "Set an existing mesh path's next hop."); + +static int handle_mpath_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + printf("DEST ADDR NEXT HOP IFACE\tSN\tMETRIC\tQLEN\t" + "EXPTIME\t\tDTIM\tDRET\tFLAGS\n"); + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL); + return 0; +} +COMMAND(mpath, dump, NULL, + NL80211_CMD_GET_MPATH, NLM_F_DUMP, CIB_NETDEV, handle_mpath_dump, + "List known mesh paths.");
diff --git a/iw_3.10/iw_3.10/nl80211.h b/iw_3.10/iw_3.10/nl80211.h new file mode 100644 index 0000000..37785df --- /dev/null +++ b/iw_3.10/iw_3.10/nl80211.h
@@ -0,0 +1,3752 @@ +#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. + * + */ + +#include <linux/types.h> + +/** + * 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. + */ + +/** + * 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 on a %NL80211_ATTR_WIPHY or a specific get + * on an %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_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. + * @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. + * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT + * if scheduled scan is not running. + * @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 and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. + * 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_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. + * + * @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. + * + * @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_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_GET_KEEPALIVE, + NL80211_CMD_SET_KEEPALIVE, + + 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, + + /* 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.11d 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_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_KLVDATA, + NL80211_ATTR_KLV_TYPE, + NL80211_ATTR_KLV_INTVL, + NL80211_ATTR_KLV_INDEX, + NL80211_ATTR_KLV_TRIG, + NL80211_ATTR_KLV_PAYLOAD, + + /* add attributes here, update the policy in nl80211.c */ + + __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 + +/* + * 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 32 +#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_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, + + /* 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: 80+80 MHz VHT rate + * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT 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, + + /* 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 (u32, from this station) + * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) + * @NL80211_STA_INFO_RX_BYTES64: total received bytes (u64, from this station) + * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (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 (u32, from this station) + * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this + * station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (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_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, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, + NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 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_PASSIVE_SCAN: Only passive scanning is + * permitted on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted + * on this channel in current regulatory domain. + * @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_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + */ +enum nl80211_frequency_attr { + __NL80211_FREQUENCY_ATTR_INVALID, + NL80211_FREQUENCY_ATTR_FREQ, + NL80211_FREQUENCY_ATTR_DISABLED, + NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, + 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, + + /* 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 + +/** + * 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_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, + + /* 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. + * @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_PASSIVE_SCAN: passive scan is required + * @NL80211_RRF_NO_IBSS: no IBSS is 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_PASSIVE_SCAN = 1<<7, + NL80211_RRF_NO_IBSS = 1<<8, +}; + +/** + * 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. + */ +enum nl80211_user_reg_hint_type { + NL80211_USER_REG_HINT_USER = 0, + NL80211_USER_REG_HINT_CELL_BASE = 1, +}; + +/** + * 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_CHANNEL_TIME: amount of time (in ms) that the radio + * spent on this channel + * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent + * receiving data + * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent + * transmitting data + * @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_CHANNEL_TIME, + NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, + NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 +}; + +/** + * 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_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, + + /* 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_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, + + /* 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_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, + + /* 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 + */ +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, +}; + +/** + * 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) + * @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, 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. + * @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_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, + + /* 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. + * @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_MCS: HT (MCS) rates allowed for TX rate selection + * in an array of MCS numbers. + * @__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_MCS, + + /* keep last */ + __NL80211_TXRATE_AFTER_LAST, + NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 +}; + +/** + * 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_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, + + /* 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: The device experienced beacon loss. + * (Note that deauth/disassoc will still follow if the AP is not + * available. This event might get used as roaming event, etc.) + */ +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_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute + * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute + * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has + * a zero bit are ignored + * @NL80211_WOWLAN_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_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after + * these fixed number of bytes of received packet + * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes + * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number + */ +enum nl80211_wowlan_packet_pattern_attr { + __NL80211_WOWLAN_PKTPAT_INVALID, + NL80211_WOWLAN_PKTPAT_MASK, + NL80211_WOWLAN_PKTPAT_PATTERN, + NL80211_WOWLAN_PKTPAT_OFFSET, + NL80211_WOWLAN_PKTPAT_ACTION = NL80211_WOWLAN_PKTPAT_OFFSET + 10, + + NUM_NL80211_WOWLAN_PKTPAT, + MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, +}; + +/** + * enum nl80211_wowlan_action - WoWLAN packet pattern action + * @NL80211_WOWLAN_ACTION_ALLOW: this pattern should wake up the host + * and the packet should be forwarded to the host unless this packet + * matches a DROP rule. + * @NL80211_WOWLAN_ACTION_DROP: a packet containing this pattern shouldn't + * wake up the host. + */ +enum nl80211_wowlan_action { + NL80211_WOWLAN_ACTION_ALLOW, + NL80211_WOWLAN_ACTION_DROP, + + /* keep last */ + NUM_NL80211_WOWLAN_ACTION, + MAX_NL80211_WOWLAN_ACTION = NUM_NL80211_WOWLAN_ACTION - 1, +}; + +/** + * struct nl80211_wowlan_pattern_support - 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 in the + * capability information given by the kernel to userspace. + */ +struct nl80211_wowlan_pattern_support { + __u32 max_patterns; + __u32 min_pattern_len; + __u32 max_pattern_len; + __u32 max_pkt_offset; +} __attribute__((packed)); + +/** + * 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) + * @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_wowlan_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 + * @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, + + /* 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_WOWLAN_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 +}; + +/** + * 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. + * @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, + + /* 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: If this is set, an active + * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel + * in the interface combinations, even when it's only used for scan + * and remain-on-channel. This could be due to, for example, the + * remain-on-channel implementation requiring a channel context. + * @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. + */ +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, +}; + +/** + * 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 + */ +enum nl80211_scan_flags { + NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, + NL80211_SCAN_FLAG_FLUSH = 1<<1, + NL80211_SCAN_FLAG_AP = 1<<2, +}; + +/** + * 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_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. + * + * @IEEE80211_DFS_USABLE: The channel can be used, but channel availability + * check (CAC) must be performed before using it for AP or IBSS. + * @IEEE80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it + * is therefore marked as not available. + * @IEEE80211_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 */ + +#endif /* __LINUX_NL80211_H */
diff --git a/iw_3.10/iw_3.10/nl80211.h.orig b/iw_3.10/iw_3.10/nl80211.h.orig new file mode 100644 index 0000000..e5c78f8 --- /dev/null +++ b/iw_3.10/iw_3.10/nl80211.h.orig
@@ -0,0 +1,3734 @@ +#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. + * + */ + +#include <linux/types.h> + +/** + * 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. + */ + +/** + * 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 on a %NL80211_ATTR_WIPHY or a specific get + * on an %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_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. + * @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. + * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT + * if scheduled scan is not running. + * @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 and + * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. + * 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_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. + * + * @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. + * + * @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_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_GET_KEEPALIVE, + NL80211_CMD_SET_KEEPALIVE, + + 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, + + /* 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.11d 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_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_KLVDATA, + NL80211_ATTR_KLV_TYPE, + NL80211_ATTR_KLV_INTVL, + NL80211_ATTR_KLV_INDEX, + NL80211_ATTR_KLV_TRIG, + NL80211_ATTR_KLV_PAYLOAD, + + /* add attributes here, update the policy in nl80211.c */ + + __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 + +/* + * 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 32 +#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_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, + + /* 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: 80+80 MHz VHT rate + * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT 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, + + /* 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 (u32, from this station) + * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) + * @NL80211_STA_INFO_RX_BYTES64: total received bytes (u64, from this station) + * @NL80211_STA_INFO_TX_BYTES64: total transmitted bytes (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 (u32, from this station) + * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this + * station) + * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) + * @NL80211_STA_INFO_TX_FAILED: total failed packets (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_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, + + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, + NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 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_PASSIVE_SCAN: Only passive scanning is + * permitted on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted + * on this channel in current regulatory domain. + * @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_MAX: highest frequency attribute number + * currently defined + * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use + */ +enum nl80211_frequency_attr { + __NL80211_FREQUENCY_ATTR_INVALID, + NL80211_FREQUENCY_ATTR_FREQ, + NL80211_FREQUENCY_ATTR_DISABLED, + NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, + 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, + + /* 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 + +/** + * 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_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, + + /* 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. + * @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_PASSIVE_SCAN: passive scan is required + * @NL80211_RRF_NO_IBSS: no IBSS is 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_PASSIVE_SCAN = 1<<7, + NL80211_RRF_NO_IBSS = 1<<8, +}; + +/** + * 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. + */ +enum nl80211_user_reg_hint_type { + NL80211_USER_REG_HINT_USER = 0, + NL80211_USER_REG_HINT_CELL_BASE = 1, +}; + +/** + * 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_CHANNEL_TIME: amount of time (in ms) that the radio + * spent on this channel + * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary + * channel was sensed busy (either due to activity or energy detect) + * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension + * channel was sensed busy + * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent + * receiving data + * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent + * transmitting data + * @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_CHANNEL_TIME, + NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, + NL80211_SURVEY_INFO_CHANNEL_TIME_RX, + NL80211_SURVEY_INFO_CHANNEL_TIME_TX, + + /* keep last */ + __NL80211_SURVEY_INFO_AFTER_LAST, + NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 +}; + +/** + * 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_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, + + /* 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_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, + + /* 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_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, + + /* 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 + */ +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, +}; + +/** + * 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) + * @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, 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. + * @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_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, + + /* 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. + * @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_MCS: HT (MCS) rates allowed for TX rate selection + * in an array of MCS numbers. + * @__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_MCS, + + /* keep last */ + __NL80211_TXRATE_AFTER_LAST, + NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 +}; + +/** + * 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_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, + + /* 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: The device experienced beacon loss. + * (Note that deauth/disassoc will still follow if the AP is not + * available. This event might get used as roaming event, etc.) + */ +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_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute + * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute + * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has + * a zero bit are ignored + * @NL80211_WOWLAN_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_WOWLAN_PKTPAT_OFFSET: packet offset, pattern is matched after + * these fixed number of bytes of received packet + * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes + * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number + */ +enum nl80211_wowlan_packet_pattern_attr { + __NL80211_WOWLAN_PKTPAT_INVALID, + NL80211_WOWLAN_PKTPAT_MASK, + NL80211_WOWLAN_PKTPAT_PATTERN, + NL80211_WOWLAN_PKTPAT_OFFSET, + + NUM_NL80211_WOWLAN_PKTPAT, + MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, +}; + +/** + * struct nl80211_wowlan_pattern_support - 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 in the + * capability information given by the kernel to userspace. + */ +struct nl80211_wowlan_pattern_support { + __u32 max_patterns; + __u32 min_pattern_len; + __u32 max_pattern_len; + __u32 max_pkt_offset; +} __attribute__((packed)); + +/** + * 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) + * @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_wowlan_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 + * @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, + + /* 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_WOWLAN_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 +}; + +/** + * 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. + * @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, + + /* 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: If this is set, an active + * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel + * in the interface combinations, even when it's only used for scan + * and remain-on-channel. This could be due to, for example, the + * remain-on-channel implementation requiring a channel context. + * @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. + */ +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, +}; + +/** + * 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 + */ +enum nl80211_scan_flags { + NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, + NL80211_SCAN_FLAG_FLUSH = 1<<1, + NL80211_SCAN_FLAG_AP = 1<<2, +}; + +/** + * 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_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. + * + * @IEEE80211_DFS_USABLE: The channel can be used, but channel availability + * check (CAC) must be performed before using it for AP or IBSS. + * @IEEE80211_DFS_UNAVAILABLE: A radar has been detected on this channel, it + * is therefore marked as not available. + * @IEEE80211_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 */ + +#endif /* __LINUX_NL80211_H */
diff --git a/iw_3.10/iw_3.10/offch.c b/iw_3.10/iw_3.10/offch.c new file mode 100644 index 0000000..d8c67c0 --- /dev/null +++ b/iw_3.10/iw_3.10/offch.c
@@ -0,0 +1,44 @@ +#include <errno.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int offchannel(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + char *end; + + /* freq */ + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, + strtoul(argv[0], &end, 10)); + if (*end != '\0') + return 1; + argv++; + argc--; + + /* duration */ + NLA_PUT_U32(msg, NL80211_ATTR_DURATION, + strtoul(argv[0], &end, 10)); + if (*end != '\0') + return 1; + argv++; + argc--; + + if (argc) + return 1; + + return 0; + nla_put_failure: + return -ENOSPC; +} + +TOPLEVEL(offchannel, "<freq> <duration>", NL80211_CMD_REMAIN_ON_CHANNEL, 0, + CIB_NETDEV, offchannel, + "Leave operating channel and go to the given channel for a while.");
diff --git a/iw_3.10/iw_3.10/p2p.c b/iw_3.10/iw_3.10/p2p.c new file mode 100644 index 0000000..addb740 --- /dev/null +++ b/iw_3.10/iw_3.10/p2p.c
@@ -0,0 +1,30 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(p2p); + +static int handle_p2p_start(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + return 0; +} +COMMAND(p2p, start, "", NL80211_CMD_START_P2P_DEVICE, 0, CIB_WDEV, handle_p2p_start, ""); + +static int handle_p2p_stop(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + return 0; +} +COMMAND(p2p, stop, "", NL80211_CMD_STOP_P2P_DEVICE, 0, CIB_WDEV, handle_p2p_stop, "");
diff --git a/iw_3.10/iw_3.10/phy.c b/iw_3.10/iw_3.10/phy.c new file mode 100644 index 0000000..7f8ce26 --- /dev/null +++ b/iw_3.10/iw_3.10/phy.c
@@ -0,0 +1,423 @@ +#include <stdbool.h> +#include <errno.h> +#include <net/if.h> +#include <strings.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int handle_name(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + if (argc != 1) + return 1; + + NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, *argv); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name, + "Rename this wireless device."); + +static int handle_freqs(struct nl_msg *msg, int argc, char **argv) +{ + static const struct { + const char *name; + unsigned int val; + } bwmap[] = { + { .name = "20", .val = NL80211_CHAN_WIDTH_20, }, + { .name = "40", .val = NL80211_CHAN_WIDTH_40, }, + { .name = "80", .val = NL80211_CHAN_WIDTH_80, }, + { .name = "80+80", .val = NL80211_CHAN_WIDTH_80P80, }, + { .name = "160", .val = NL80211_CHAN_WIDTH_160, }, + }; + uint32_t freq; + int i, bwval = NL80211_CHAN_WIDTH_20_NOHT; + char *end; + + if (argc < 1) + return 1; + + for (i = 0; i < ARRAY_SIZE(bwmap); i++) { + if (strcasecmp(bwmap[i].name, argv[0]) == 0) { + bwval = bwmap[i].val; + break; + } + } + + if (bwval == NL80211_CHAN_WIDTH_20_NOHT) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_CHANNEL_WIDTH, bwval); + + if (argc == 1) + return 0; + + /* center freq 1 */ + if (!*argv[1]) + return 1; + freq = strtoul(argv[1], &end, 10); + if (*end) + return 1; + NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ1, freq); + + if (argc == 2) + return 0; + + /* center freq 2 */ + if (!*argv[2]) + return 1; + freq = strtoul(argv[2], &end, 10); + if (*end) + return 1; + NLA_PUT_U32(msg, NL80211_ATTR_CENTER_FREQ2, freq); + + return 0; + nla_put_failure: + return -ENOBUFS; +} + +static int handle_freqchan(struct nl_msg *msg, bool chan, + int argc, char **argv) +{ + char *end; + static const struct { + const char *name; + unsigned int val; + } htmap[] = { + { .name = "HT20", .val = NL80211_CHAN_HT20, }, + { .name = "HT40+", .val = NL80211_CHAN_HT40PLUS, }, + { .name = "HT40-", .val = NL80211_CHAN_HT40MINUS, }, + }; + unsigned int htval = NL80211_CHAN_NO_HT; + unsigned int freq; + int i; + + if (!argc || argc > 4) + return 1; + + if (!*argv[0]) + return 1; + freq = strtoul(argv[0], &end, 10); + if (*end) + return 1; + + if (chan) + freq = ieee80211_channel_to_frequency(freq); + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + + if (argc > 2) { + return handle_freqs(msg, argc - 1, argv + 1); + } else if (argc == 2) { + for (i = 0; i < ARRAY_SIZE(htmap); i++) { + if (strcasecmp(htmap[i].name, argv[1]) == 0) { + htval = htmap[i].val; + break; + } + } + if (htval == NL80211_CHAN_NO_HT) + return handle_freqs(msg, argc - 1, argv + 1); + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, htval); + + return 0; + nla_put_failure: + return -ENOBUFS; +} + +static int handle_freq(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + return handle_freqchan(msg, false, argc, argv); +} +COMMAND(set, freq, "<freq> [HT20|HT40+|HT40-]", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_freq, + "Set frequency/channel the hardware is using, including HT\n" + "configuration."); +COMMAND(set, freq, "<freq> [HT20|HT40+|HT40-]\n" + "<control freq> [20|40|80|80+80|160] [<center freq 1>] [<center freq 2>]", + NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_freq, NULL); + +static int handle_chan(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + return handle_freqchan(msg, true, argc, argv); +} +COMMAND(set, channel, "<channel> [HT20|HT40+|HT40-]", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_chan, NULL); +COMMAND(set, channel, "<channel> [HT20|HT40+|HT40-]", + NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_chan, NULL); + +static int handle_fragmentation(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned int frag; + + if (argc != 1) + return 1; + + if (strcmp("off", argv[0]) == 0) + frag = -1; + else { + char *end; + + if (!*argv[0]) + return 1; + frag = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, frag); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, frag, "<fragmentation threshold|off>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_fragmentation, + "Set fragmentation threshold."); + +static int handle_rts(struct nl80211_state *state, + struct nl_cb *cb, struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned int rts; + + if (argc != 1) + return 1; + + if (strcmp("off", argv[0]) == 0) + rts = -1; + else { + char *end; + + if (!*argv[0]) + return 1; + rts = strtoul(argv[0], &end, 10); + if (*end != '\0') + return 1; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, rts); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, rts, "<rts threshold|off>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_rts, + "Set rts threshold."); + +static int handle_netns(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *end; + + if (argc != 1) + return 1; + + if (!*argv[0]) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_PID, + strtoul(argv[0], &end, 10)); + + if (*end != '\0') + return 1; + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, netns, "<pid>", + NL80211_CMD_SET_WIPHY_NETNS, 0, CIB_PHY, handle_netns, + "Put this wireless device into a different network namespace"); + +static int handle_coverage(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *end; + unsigned int coverage; + + if (argc != 1) + return 1; + + if (!*argv[0]) + return 1; + coverage = strtoul(argv[0], &end, 10); + if (coverage > 255) + return 1; + + if (*end) + return 1; + + NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, coverage, "<coverage class>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_coverage, + "Set coverage class (1 for every 3 usec of air propagation time).\n" + "Valid values: 0 - 255."); + +static int handle_distance(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *end; + unsigned int distance, coverage; + + if (argc != 1) + return 1; + + if (!*argv[0]) + return 1; + + distance = strtoul(argv[0], &end, 10); + + if (*end) + return 1; + + /* + * Divide double the distance by the speed of light in m/usec (300) to + * get round-trip time in microseconds and then divide the result by + * three to get coverage class as specified in IEEE 802.11-2007 table + * 7-27. Values are rounded upwards. + */ + coverage = (distance + 449) / 450; + if (coverage > 255) + return 1; + + NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, coverage); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, distance, "<distance>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_distance, + "Set appropriate coverage class for given link distance in meters.\n" + "Valid values: 0 - 114750"); + +static int handle_txpower(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + enum nl80211_tx_power_setting type; + int mbm; + + /* get the required args */ + if (argc != 1 && argc != 2) + return 1; + + if (!strcmp(argv[0], "auto")) + type = NL80211_TX_POWER_AUTOMATIC; + else if (!strcmp(argv[0], "fixed")) + type = NL80211_TX_POWER_FIXED; + else if (!strcmp(argv[0], "limit")) + type = NL80211_TX_POWER_LIMITED; + else { + printf("Invalid parameter: %s\n", argv[0]); + return 2; + } + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_SETTING, type); + + if (type != NL80211_TX_POWER_AUTOMATIC) { + char *endptr; + if (argc != 2) { + printf("Missing TX power level argument.\n"); + return 2; + } + + mbm = strtol(argv[1], &endptr, 10); + if (*endptr) + return 2; + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL, mbm); + } else if (argc != 1) + return 1; + + return 0; + + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_txpower, + "Specify transmit power level and setting type."); +COMMAND(set, txpower, "<auto|fixed|limit> [<tx power in mBm>]", + NL80211_CMD_SET_WIPHY, 0, CIB_NETDEV, handle_txpower, + "Specify transmit power level and setting type."); + +static int handle_antenna(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char *end; + uint32_t tx_ant = 0, rx_ant = 0; + + if (argc == 1 && strcmp(argv[0], "all") == 0) { + tx_ant = 0xffffffff; + rx_ant = 0xffffffff; + } else if (argc == 1) { + tx_ant = rx_ant = strtoul(argv[0], &end, 0); + if (*end) + return 1; + } + else if (argc == 2) { + tx_ant = strtoul(argv[0], &end, 0); + if (*end) + return 1; + rx_ant = strtoul(argv[1], &end, 0); + if (*end) + return 1; + } else + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, tx_ant); + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, rx_ant); + + return 0; + + nla_put_failure: + return -ENOBUFS; +} +COMMAND(set, antenna, "<bitmap> | all | <tx bitmap> <rx bitmap>", + NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_antenna, + "Set a bitmap of allowed antennas to use for TX and RX.\n" + "The driver may reject antenna configurations it cannot support.");
diff --git a/iw_3.10/iw_3.10/ps.c b/iw_3.10/iw_3.10/ps.c new file mode 100644 index 0000000..4c8e2d1 --- /dev/null +++ b/iw_3.10/iw_3.10/ps.c
@@ -0,0 +1,85 @@ +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +static int set_power_save(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + enum nl80211_ps_state ps_state; + + if (argc != 1) { + printf("Invalid parameters!\n"); + return 2; + } + + if (strcmp(argv[0], "on") == 0) + ps_state = NL80211_PS_ENABLED; + else if (strcmp(argv[0], "off") == 0) + ps_state = NL80211_PS_DISABLED; + else { + printf("Invalid parameter: %s\n", argv[0]); + return 2; + } + + NLA_PUT_U32(msg, NL80211_ATTR_PS_STATE, ps_state); + + return 0; + + nla_put_failure: + return -ENOBUFS; +} + +COMMAND(set, power_save, "<on|off>", + NL80211_CMD_SET_POWER_SAVE, 0, CIB_NETDEV, set_power_save, + "Set power save state to on or off."); + +static int print_power_save_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + const char *s; + + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_PS_STATE]) + return NL_SKIP; + + switch (nla_get_u32(attrs[NL80211_ATTR_PS_STATE])) { + case NL80211_PS_ENABLED: + s = "on"; + break; + case NL80211_PS_DISABLED: + default: + s = "off"; + break; + } + + printf("Power save: %s\n", s); + + return NL_SKIP; +} + +static int get_power_save(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_power_save_handler, NULL); + return 0; +} + +COMMAND(get, power_save, "<param>", + NL80211_CMD_GET_POWER_SAVE, 0, CIB_NETDEV, get_power_save, + "Retrieve power save state.");
diff --git a/iw_3.10/iw_3.10/reason.c b/iw_3.10/iw_3.10/reason.c new file mode 100644 index 0000000..f91c681 --- /dev/null +++ b/iw_3.10/iw_3.10/reason.c
@@ -0,0 +1,50 @@ +#include <stdint.h> +#include "iw.h" + +static const char *reason_table[] = { + [1] = "Unspecified", + [2] = "Previous authentication no longer valid", + [3] = "Deauthenticated because sending station is leaving (or has left) the IBSS or ESS", + [4] = "Disassociated due to inactivity", + [5] = "Disassociated because AP is unable to handle all currently associated STA", + [6] = "Class 2 frame received from non-authenticated station", + [7] = "Class 3 frame received from non-authenticated station", + [8] = "Disassociated because sending station is leaving (or has left) the BSS", + [9] = "Station requesting (re)association is not authenticated with responding station", + [10] = "Disassociated because the information in the Power Capability element is unacceptable", + [11] = "Disassociated because the information in the Supported Channels element is unacceptable", + [13] = "Invalid information element", + [14] = "MIC failure", + [15] = "4-way handshake timeout", + [16] = "Group key update timeout", + [17] = "Information element in 4-way handshake different from (Re-)associate request/Probe response/Beacon", + [18] = "Multicast cipher is not valid", + [19] = "Unicast cipher is not valid", + [20] = "AKMP is not valid", + [21] = "Unsupported RSNE version", + [22] = "Invalid RSNE capabilities", + [23] = "IEEE 802.1X authentication failed", + [24] = "Cipher Suite rejected per security policy", + [31] = "TS deleted because QoS AP lacks sufficient bandwidth for this QoS STA due to a change in BSS service characteristics or operational mode", + [32] = "Disassociated for unspecified QoS-related reason", + [33] = "Disassociated because QAP lacks sufficient bandwidth for this STA", + [34] = "Disassociated because of excessive frame losses and/or poor channel conditions", + [35] = "Disassociated because QSTA is transmitting outside the limits of its polled TXOPs", + [36] = "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)", + [37] = "Requested from peer QSTA as it does not want to use Traffic Stream", + [38] = "Requested from peer QSTA as the QSTA received frames indicated Traffic Stream for which it has not set up", + [39] = "Requested from peer QSTA due to time out", + [40] = "Requested from peer QSTA as the QSTA is leaving the QBSS (or resetting)", + [41] = "Requested from peer QSTA as it does not want to receive frames directly from the QSTA", + [42] = "Requested from peer QSTA as the QSTA received DLP frames for which it has not set up", + [43] = "Requested from peer QSTA as it does not want to use Block Ack", + [44] = "Requested from peer QSTA as the QSTA received frames indicated Block Acknowledgement policy for which it has not set up", + [45] = "Peer QSTA does not support the requested cipher suite", +}; + +const char *get_reason_str(uint16_t reason) +{ + if (reason < ARRAY_SIZE(reason_table) && reason_table[reason]) + return reason_table[reason]; + return "<unknown>"; +}
diff --git a/iw_3.10/iw_3.10/reg.c b/iw_3.10/iw_3.10/reg.c new file mode 100644 index 0000000..9a60cec --- /dev/null +++ b/iw_3.10/iw_3.10/reg.c
@@ -0,0 +1,215 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(reg); + +#define MHZ_TO_KHZ(freq) ((freq) * 1000) +#define KHZ_TO_MHZ(freq) ((freq) / 1000) +#define DBI_TO_MBI(gain) ((gain) * 100) +#define MBI_TO_DBI(gain) ((gain) / 100) +#define DBM_TO_MBM(gain) ((gain) * 100) +#define MBM_TO_DBM(gain) ((gain) / 100) + +static bool isalpha_upper(char letter) +{ + if (letter >= 65 && letter <= 90) + return true; + return false; +} + +static bool is_alpha2(char *alpha2) +{ + if (isalpha_upper(alpha2[0]) && isalpha_upper(alpha2[1])) + return true; + return false; +} + +static bool is_world_regdom(char *alpha2) +{ + /* ASCII 0 */ + if (alpha2[0] == 48 && alpha2[1] == 48) + return true; + return false; +} + +char *reg_initiator_to_string(__u8 initiator) +{ + switch (initiator) { + case NL80211_REGDOM_SET_BY_CORE: + return "the wireless core upon initialization"; + case NL80211_REGDOM_SET_BY_USER: + return "a user"; + case NL80211_REGDOM_SET_BY_DRIVER: + return "a driver"; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + return "a country IE"; + default: + return "BUG"; + } +} + +static 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"; + } +} + +static int handle_reg_set(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char alpha2[3]; + + if (argc < 1) + return 1; + + if (!is_alpha2(argv[0]) && !is_world_regdom(argv[0])) { + fprintf(stderr, "not a valid ISO/IEC 3166-1 alpha2\n"); + fprintf(stderr, "Special non-alpha2 usable entries:\n"); + fprintf(stderr, "\t00\tWorld Regulatory domain\n"); + return 2; + } + + alpha2[0] = argv[0][0]; + alpha2[1] = argv[0][1]; + alpha2[2] = '\0'; + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(reg, set, "<ISO/IEC 3166-1 alpha2>", + NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set, + "Notify the kernel about the current regulatory domain."); + +static int print_reg_handler(struct nl_msg *msg, void *arg) + +{ +#define PARSE_FLAG(nl_flag, string_value) do { \ + if ((flags & nl_flag)) { \ + printf(", %s", string_value); \ + } \ + } while (0) + struct nlattr *tb_msg[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + char *alpha2; + struct nlattr *nl_rule; + int rem_rule; + enum nl80211_dfs_regions dfs_domain; + static struct nla_policy reg_rule_policy[NL80211_FREQUENCY_ATTR_MAX + 1] = { + [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 }, + [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 }, + [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 }, + [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 }, + [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 }, + [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, + }; + + nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb_msg[NL80211_ATTR_REG_ALPHA2]) { + printf("No alpha2\n"); + return NL_SKIP; + } + + if (!tb_msg[NL80211_ATTR_REG_RULES]) { + printf("No reg rules\n"); + return NL_SKIP; + } + + if (tb_msg[NL80211_ATTR_DFS_REGION]) + dfs_domain = nla_get_u8(tb_msg[NL80211_ATTR_DFS_REGION]); + else + dfs_domain = NL80211_DFS_UNSET; + + alpha2 = nla_data(tb_msg[NL80211_ATTR_REG_ALPHA2]); + printf("country %c%c: %s\n", alpha2[0], alpha2[1], dfs_domain_name(dfs_domain)); + + nla_for_each_nested(nl_rule, tb_msg[NL80211_ATTR_REG_RULES], rem_rule) { + struct nlattr *tb_rule[NL80211_FREQUENCY_ATTR_MAX + 1]; + __u32 flags, start_freq_khz, end_freq_khz, max_bw_khz, max_ant_gain_mbi, max_eirp_mbm; + + nla_parse(tb_rule, NL80211_FREQUENCY_ATTR_MAX, nla_data(nl_rule), nla_len(nl_rule), reg_rule_policy); + + flags = nla_get_u32(tb_rule[NL80211_ATTR_REG_RULE_FLAGS]); + start_freq_khz = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_START]); + end_freq_khz = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_END]); + max_bw_khz = nla_get_u32(tb_rule[NL80211_ATTR_FREQ_RANGE_MAX_BW]); + max_ant_gain_mbi = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]); + max_eirp_mbm = nla_get_u32(tb_rule[NL80211_ATTR_POWER_RULE_MAX_EIRP]); + + + printf("\t(%d - %d @ %d), (", + KHZ_TO_MHZ(start_freq_khz), KHZ_TO_MHZ(end_freq_khz), KHZ_TO_MHZ(max_bw_khz)); + + if (MBI_TO_DBI(max_ant_gain_mbi)) + printf("%d", MBI_TO_DBI(max_ant_gain_mbi)); + else + printf("N/A"); + + printf(", %d)", MBM_TO_DBM(max_eirp_mbm)); + + if (!flags) { + printf("\n"); + continue; + } + + /* Sync this output format to match that of dbparse.py from wireless-regdb.git */ + PARSE_FLAG(NL80211_RRF_NO_OFDM, "NO-OFDM"); + PARSE_FLAG(NL80211_RRF_NO_CCK, "NO-CCK"); + PARSE_FLAG(NL80211_RRF_NO_INDOOR, "NO-INDOOR"); + PARSE_FLAG(NL80211_RRF_NO_OUTDOOR, "NO-OUTDOOR"); + PARSE_FLAG(NL80211_RRF_DFS, "DFS"); + PARSE_FLAG(NL80211_RRF_PTP_ONLY, "PTP-ONLY"); + PARSE_FLAG(NL80211_RRF_PASSIVE_SCAN, "PASSIVE-SCAN"); + PARSE_FLAG(NL80211_RRF_NO_IBSS, "NO-IBSS"); + + printf("\n"); + } + return NL_OK; +#undef PARSE_FLAG +} + +static int handle_reg_get(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_reg_handler, NULL); + return 0; +} +COMMAND(reg, get, NULL, NL80211_CMD_GET_REG, 0, CIB_NONE, handle_reg_get, + "Print out the kernel's current regulatory domain information.");
diff --git a/iw_3.10/iw_3.10/roc.c b/iw_3.10/iw_3.10/roc.c new file mode 100644 index 0000000..c2beb96 --- /dev/null +++ b/iw_3.10/iw_3.10/roc.c
@@ -0,0 +1,41 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(roc); + +static int handle_roc_start(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + char *end; + int freq, time; + + if (argc != 2) + return 1; + + freq = strtol(argv[0], &end, 0); + if (!end || *end) + return 1; + + time = strtol(argv[1], &end, 0); + if (!end || *end) + return 1; + + NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq); + NLA_PUT_U32(msg, NL80211_ATTR_DURATION, time); + return 0; + nla_put_failure: + return -ENOBUFS; +} + +COMMAND(roc, start, "<freq> <time in ms>", NL80211_CMD_REMAIN_ON_CHANNEL, 0, CIB_NETDEV, handle_roc_start, "");
diff --git a/iw_3.10/iw_3.10/scan.c b/iw_3.10/iw_3.10/scan.c new file mode 100644 index 0000000..1842655 --- /dev/null +++ b/iw_3.10/iw_3.10/scan.c
@@ -0,0 +1,1551 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <ctype.h> +#include <stdbool.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +#define WLAN_CAPABILITY_ESS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#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) +/* DMG (60gHz) 802.11ad */ +/* type - bits 0..1 */ +#define WLAN_CAPABILITY_DMG_TYPE_MASK (3<<0) + +#define WLAN_CAPABILITY_DMG_TYPE_IBSS (1<<0) /* Tx by: STA */ +#define WLAN_CAPABILITY_DMG_TYPE_PBSS (2<<0) /* Tx by: PCP */ +#define WLAN_CAPABILITY_DMG_TYPE_AP (3<<0) /* Tx by: AP */ + +#define WLAN_CAPABILITY_DMG_CBAP_ONLY (1<<2) +#define WLAN_CAPABILITY_DMG_CBAP_SOURCE (1<<3) +#define WLAN_CAPABILITY_DMG_PRIVACY (1<<4) +#define WLAN_CAPABILITY_DMG_ECPAC (1<<5) + +#define WLAN_CAPABILITY_DMG_SPECTRUM_MGMT (1<<8) +#define WLAN_CAPABILITY_DMG_RADIO_MEASURE (1<<12) + +static unsigned char ms_oui[3] = { 0x00, 0x50, 0xf2 }; +static unsigned char ieee80211_oui[3] = { 0x00, 0x0f, 0xac }; +static unsigned char wfa_oui[3] = { 0x50, 0x6f, 0x9a }; + +struct scan_params { + bool unknown; + enum print_ie_type type; + bool show_both_ie_sets; +}; + +#define IEEE80211_COUNTRY_EXTENSION_ID 201 + +union ieee80211_country_ie_triplet { + struct { + __u8 first_channel; + __u8 num_channels; + __s8 max_power; + } __attribute__ ((packed)) chans; + struct { + __u8 reg_extension_id; + __u8 reg_class; + __u8 coverage_class; + } __attribute__ ((packed)) ext; +} __attribute__ ((packed)); + +static int handle_scan(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + struct nl_msg *ssids = NULL, *freqs = NULL; + char *eptr; + int err = -ENOBUFS; + int i; + enum { + NONE, + FREQ, + IES, + SSID, + DONE, + } parse = NONE; + int freq; + bool passive = false, have_ssids = false, have_freqs = false; + size_t tmp; + unsigned char *ies; + int flags = 0; + + ssids = nlmsg_alloc(); + if (!ssids) + return -ENOMEM; + + freqs = nlmsg_alloc(); + if (!freqs) { + nlmsg_free(ssids); + return -ENOMEM; + } + + for (i = 0; i < argc; i++) { + switch (parse) { + case NONE: + if (strcmp(argv[i], "freq") == 0) { + parse = FREQ; + have_freqs = true; + break; + } else if (strcmp(argv[i], "ies") == 0) { + parse = IES; + break; + } else if (strcmp(argv[i], "lowpri") == 0) { + parse = NONE; + flags |= NL80211_SCAN_FLAG_LOW_PRIORITY; + break; + } else if (strcmp(argv[i], "flush") == 0) { + parse = NONE; + flags |= NL80211_SCAN_FLAG_FLUSH; + break; + } else if (strcmp(argv[i], "ap-force") == 0) { + parse = NONE; + flags |= NL80211_SCAN_FLAG_AP; + break; + } else if (strcmp(argv[i], "ssid") == 0) { + parse = SSID; + have_ssids = true; + break; + } else if (strcmp(argv[i], "passive") == 0) { + parse = DONE; + passive = true; + break; + } + case DONE: + return 1; + case FREQ: + freq = strtoul(argv[i], &eptr, 10); + if (eptr != argv[i] + strlen(argv[i])) { + /* failed to parse as number -- maybe a tag? */ + i--; + parse = NONE; + continue; + } + NLA_PUT_U32(freqs, i, freq); + break; + case IES: + ies = parse_hex(argv[i], &tmp); + if (!ies) + goto nla_put_failure; + NLA_PUT(msg, NL80211_ATTR_IE, tmp, ies); + free(ies); + parse = NONE; + break; + case SSID: + NLA_PUT(ssids, i, strlen(argv[i]), argv[i]); + break; + } + } + + if (!have_ssids) + NLA_PUT(ssids, 1, 0, ""); + if (!passive) + nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids); + + if (have_freqs) + nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); + if (flags) + NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags); + + err = 0; + nla_put_failure: + nlmsg_free(ssids); + nlmsg_free(freqs); + return err; +} + +static void tab_on_first(bool *first) +{ + if (!*first) + printf("\t"); + else + *first = false; +} + +static void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" "); + print_ssid_escaped(len, data); + printf("\n"); +} + +#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126 +#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 + +static void print_supprates(const uint8_t type, uint8_t len, const uint8_t *data) +{ + int i; + + printf(" "); + + for (i = 0; i < len; i++) { + int r = data[i] & 0x7f; + + if (r == BSS_MEMBERSHIP_SELECTOR_VHT_PHY && data[i] & 0x80) + printf("VHT"); + else if (r == BSS_MEMBERSHIP_SELECTOR_HT_PHY && data[i] & 0x80) + printf("HT"); + else + printf("%d.%d", r/2, 5*(r&1)); + + printf("%s ", data[i] & 0x80 ? "*" : ""); + } + printf("\n"); +} + +static void print_ds(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" channel %d\n", data[0]); +} + +static const char *country_env_str(char environment) +{ + switch (environment) { + case 'I': + return "Indoor only"; + case 'O': + return "Outdoor only"; + case ' ': + return "Indoor/Outdoor"; + default: + return "bogus"; + } +} + +static void print_country(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" %.*s", 2, data); + + printf("\tEnvironment: %s\n", country_env_str(data[2])); + + data += 3; + len -= 3; + + if (len < 3) { + printf("\t\tNo country IE triplets present\n"); + return; + } + + while (len >= 3) { + int end_channel; + union ieee80211_country_ie_triplet *triplet = (void *) data; + + if (triplet->ext.reg_extension_id >= IEEE80211_COUNTRY_EXTENSION_ID) { + printf("\t\tExtension ID: %d Regulatory Class: %d Coverage class: %d (up to %dm)\n", + triplet->ext.reg_extension_id, + triplet->ext.reg_class, + triplet->ext.coverage_class, + triplet->ext.coverage_class * 450); + + data += 3; + len -= 3; + continue; + } + + /* 2 GHz */ + if (triplet->chans.first_channel <= 14) + end_channel = triplet->chans.first_channel + (triplet->chans.num_channels - 1); + else + end_channel = triplet->chans.first_channel + (4 * (triplet->chans.num_channels - 1)); + + printf("\t\tChannels [%d - %d] @ %d dBm\n", triplet->chans.first_channel, end_channel, triplet->chans.max_power); + + data += 3; + len -= 3; + } + + return; +} + +static void print_powerconstraint(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" %d dB\n", data[0]); +} + +static void print_tpcreport(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" TX power: %d dBm\n", data[0]); + /* printf(" Link Margin (%d dB) is reserved in Beacons\n", data[1]); */ +} + +static void print_erp(const uint8_t type, uint8_t len, const uint8_t *data) +{ + if (data[0] == 0x00) + printf(" <no flags>"); + if (data[0] & 0x01) + printf(" NonERP_Present"); + if (data[0] & 0x02) + printf(" Use_Protection"); + if (data[0] & 0x04) + printf(" Barker_Preamble_Mode"); + printf("\n"); +} + +static void print_cipher(const uint8_t *data) +{ + if (memcmp(data, ms_oui, 3) == 0) { + switch (data[3]) { + case 0: + printf("Use group cipher suite"); + break; + case 1: + printf("WEP-40"); + break; + case 2: + printf("TKIP"); + break; + case 4: + printf("CCMP"); + break; + case 5: + printf("WEP-104"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else if (memcmp(data, ieee80211_oui, 3) == 0) { + switch (data[3]) { + case 0: + printf("Use group cipher suite"); + break; + case 1: + printf("WEP-40"); + break; + case 2: + printf("TKIP"); + break; + case 4: + printf("CCMP"); + break; + case 5: + printf("WEP-104"); + break; + case 6: + printf("AES-128-CMAC"); + break; + case 8: + printf("GCMP"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); +} + +static void print_auth(const uint8_t *data) +{ + if (memcmp(data, ms_oui, 3) == 0) { + switch (data[3]) { + case 1: + printf("IEEE 802.1X"); + break; + case 2: + printf("PSK"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else if (memcmp(data, ieee80211_oui, 3) == 0) { + switch (data[3]) { + case 1: + printf("IEEE 802.1X"); + break; + case 2: + printf("PSK"); + break; + case 3: + printf("FT/IEEE 802.1X"); + break; + case 4: + printf("FT/PSK"); + break; + case 5: + printf("IEEE 802.1X/SHA-256"); + break; + case 6: + printf("PSK/SHA-256"); + break; + default: + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); + break; + } + } else + printf("%.02x-%.02x-%.02x:%d", + data[0], data[1] ,data[2], data[3]); +} + +static void print_rsn_ie(const char *defcipher, const char *defauth, + uint8_t len, const uint8_t *data) +{ + bool first = true; + __u16 version, count, capa; + int i; + + version = data[0] + (data[1] << 8); + tab_on_first(&first); + printf("\t * Version: %d\n", version); + + data += 2; + len -= 2; + + if (len < 4) { + tab_on_first(&first); + printf("\t * Group cipher: %s\n", defcipher); + printf("\t * Pairwise ciphers: %s\n", defcipher); + return; + } + + tab_on_first(&first); + printf("\t * Group cipher: "); + print_cipher(data); + printf("\n"); + + data += 4; + len -= 4; + + if (len < 2) { + tab_on_first(&first); + printf("\t * Pairwise ciphers: %s\n", defcipher); + return; + } + + count = data[0] | (data[1] << 8); + if (2 + (count * 4) > len) + goto invalid; + + tab_on_first(&first); + printf("\t * Pairwise ciphers:"); + for (i = 0; i < count; i++) { + printf(" "); + print_cipher(data + 2 + (i * 4)); + } + printf("\n"); + + data += 2 + (count * 4); + len -= 2 + (count * 4); + + if (len < 2) { + tab_on_first(&first); + printf("\t * Authentication suites: %s\n", defauth); + return; + } + + count = data[0] | (data[1] << 8); + if (2 + (count * 4) > len) + goto invalid; + + tab_on_first(&first); + printf("\t * Authentication suites:"); + for (i = 0; i < count; i++) { + printf(" "); + print_auth(data + 2 + (i * 4)); + } + printf("\n"); + + data += 2 + (count * 4); + len -= 2 + (count * 4); + + if (len >= 2) { + capa = data[0] | (data[1] << 8); + tab_on_first(&first); + printf("\t * Capabilities:"); + if (capa & 0x0001) + printf(" PreAuth"); + if (capa & 0x0002) + printf(" NoPairwise"); + switch ((capa & 0x000c) >> 2) { + case 0: + break; + case 1: + printf(" 2-PTKSA-RC"); + break; + case 2: + printf(" 4-PTKSA-RC"); + break; + case 3: + printf(" 16-PTKSA-RC"); + break; + } + switch ((capa & 0x0030) >> 4) { + case 0: + break; + case 1: + printf(" 2-GTKSA-RC"); + break; + case 2: + printf(" 4-GTKSA-RC"); + break; + case 3: + printf(" 16-GTKSA-RC"); + break; + } + if (capa & 0x0040) + printf(" MFP-required"); + if (capa & 0x0080) + printf(" MFP-capable"); + if (capa & 0x0200) + printf(" Peerkey-enabled"); + if (capa & 0x0400) + printf(" SPP-AMSDU-capable"); + if (capa & 0x0800) + printf(" SPP-AMSDU-required"); + printf(" (0x%.4x)\n", capa); + data += 2; + len -= 2; + } + + if (len >= 2) { + int pmkid_count = data[0] | (data[1] << 8); + + if (len >= 2 + 16 * pmkid_count) { + tab_on_first(&first); + printf("\t * %d PMKIDs\n", pmkid_count); + /* not printing PMKID values */ + data += 2 + 16 * pmkid_count; + len -= 2 + 16 * pmkid_count; + } else + goto invalid; + } + + if (len >= 4) { + tab_on_first(&first); + printf("\t * Group mgmt cipher suite: "); + print_cipher(data); + printf("\n"); + data += 4; + len -= 4; + } + + invalid: + if (len != 0) { + printf("\t\t * bogus tail data (%d):", len); + while (len) { + printf(" %.2x", *data); + data++; + len--; + } + printf("\n"); + } +} + +static void print_rsn(const uint8_t type, uint8_t len, const uint8_t *data) +{ + print_rsn_ie("CCMP", "IEEE 802.1X", len, data); +} + +static void print_ht_capa(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf("\n"); + print_ht_capability(data[0] | (data[1] << 8)); + print_ampdu_length(data[2] & 3); + print_ampdu_spacing((data[2] >> 2) & 7); + print_ht_mcs(data + 3); +} + +static const char *ht_secondary_offset[4] = { + "no secondary", + "above", + "[reserved!]", + "below", +}; + +static void print_ht_op(const uint8_t type, uint8_t len, const uint8_t *data) +{ + static const char *protection[4] = { + "no", + "nonmember", + "20 MHz", + "non-HT mixed", + }; + static const char *sta_chan_width[2] = { + "20 MHz", + "any", + }; + + printf("\n"); + printf("\t\t * primary channel: %d\n", data[0]); + printf("\t\t * secondary channel offset: %s\n", + ht_secondary_offset[data[1] & 0x3]); + printf("\t\t * STA channel width: %s\n", sta_chan_width[(data[1] & 0x4)>>2]); + printf("\t\t * RIFS: %d\n", (data[1] & 0x8)>>3); + printf("\t\t * HT protection: %s\n", protection[data[2] & 0x3]); + printf("\t\t * non-GF present: %d\n", (data[2] & 0x4) >> 2); + printf("\t\t * OBSS non-GF present: %d\n", (data[2] & 0x10) >> 4); + printf("\t\t * dual beacon: %d\n", (data[4] & 0x40) >> 6); + printf("\t\t * dual CTS protection: %d\n", (data[4] & 0x80) >> 7); + printf("\t\t * STBC beacon: %d\n", data[5] & 0x1); + printf("\t\t * L-SIG TXOP Prot: %d\n", (data[5] & 0x2) >> 1); + printf("\t\t * PCO active: %d\n", (data[5] & 0x4) >> 2); + printf("\t\t * PCO phase: %d\n", (data[5] & 0x8) >> 3); +} + +static void print_capabilities(const uint8_t type, uint8_t len, const uint8_t *data) +{ + int i, base, bit; + bool first = true; + + + for (i = 0; i < len; i++) { + base = i * 8; + + for (bit = 0; bit < 8; bit++) { + if (!(data[i] & (1 << bit))) + continue; + + if (!first) + printf(","); + else + first = false; + +#define CAPA(bit, name) case bit: printf(" " name); break + + switch (bit + base) { + CAPA(0, "HT Information Exchange Supported"); + CAPA(1, "reserved (On-demand Beacon)"); + CAPA(2, "Extended Channel Switching"); + CAPA(3, "reserved (Wave Indication)"); + CAPA(4, "PSMP Capability"); + CAPA(5, "reserved (Service Interval Granularity)"); + CAPA(6, "S-PSMP Capability"); + CAPA(7, "Event"); + CAPA(8, "Diagnostics"); + CAPA(9, "Multicast Diagnostics"); + CAPA(10, "Location Tracking"); + CAPA(11, "FMS"); + CAPA(12, "Proxy ARP Service"); + CAPA(13, "Collocated Interference Reporting"); + CAPA(14, "Civic Location"); + CAPA(15, "Geospatial Location"); + CAPA(16, "TFS"); + CAPA(17, "WNM-Sleep Mode"); + CAPA(18, "TIM Broadcast"); + CAPA(19, "BSS Transition"); + CAPA(20, "QoS Traffic Capability"); + CAPA(21, "AC Station Count"); + CAPA(22, "Multiple BSSID"); + CAPA(23, "Timing Measurement"); + CAPA(24, "Channel Usage"); + CAPA(25, "SSID List"); + CAPA(26, "DMS"); + CAPA(27, "UTC TSF Offset"); + CAPA(28, "TDLS Peer U-APSD Buffer STA Support"); + CAPA(29, "TDLS Peer PSM Support"); + CAPA(30, "TDLS channel switching"); + CAPA(31, "Interworking"); + CAPA(32, "QoS Map"); + CAPA(33, "EBR"); + CAPA(34, "SSPN Interface"); + CAPA(35, "Reserved"); + CAPA(36, "MSGCF Capability"); + CAPA(37, "TDLS Support"); + CAPA(38, "TDLS Prohibited"); + CAPA(39, "TDLS Channel Switching Prohibited"); + CAPA(40, "Reject Unadmitted Frame"); + CAPA(44, "Identifier Location"); + CAPA(45, "U-APSD Coexistence"); + CAPA(46, "WNM-Notification"); + CAPA(47, "Reserved"); + CAPA(48, "UTF-8 SSID"); + default: + printf(" %d", bit); + break; + } +#undef CAPA + } + } + + printf("\n"); +} + +static void print_tim(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" DTIM Count %u DTIM Period %u Bitmap Control 0x%x " + "Bitmap[0] 0x%x", + data[0], data[1], data[2], data[3]); + if (len - 4) + printf(" (+ %u octet%s)", len - 4, len - 4 == 1 ? "" : "s"); + printf("\n"); +} + +static void print_ibssatim(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf(" %d TUs", (data[1] << 8) + data[0]); +} + +static void print_vht_capa(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf("\n"); + print_vht_info(data[0] | (data[1] << 8) | + (data[2] << 16) | (data[3] << 24), + data + 4); +} + +static void print_vht_oper(const uint8_t type, uint8_t len, const uint8_t *data) +{ + const char *chandwidths[] = { + [0] = "20 or 40 MHz", + [1] = "80 MHz", + [3] = "80+80 MHz", + [2] = "160 MHz", + }; + + printf("\n"); + printf("\t\t * channel width: %d (%s)\n", data[0], + data[0] < ARRAY_SIZE(chandwidths) ? chandwidths[data[0]] : "unknown"); + printf("\t\t * center freq segment 1: %d\n", data[1]); + printf("\t\t * center freq segment 2: %d\n", data[2]); + printf("\t\t * VHT basic MCS set: 0x%.2x%.2x\n", data[4], data[3]); +} + +static void print_obss_scan_params(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf("\n"); + printf("\t\t * passive dwell: %d TUs\n", (data[1] << 8) | data[0]); + printf("\t\t * active dwell: %d TUs\n", (data[3] << 8) | data[2]); + printf("\t\t * channel width trigger scan interval: %d s\n", (data[5] << 8) | data[4]); + printf("\t\t * scan passive total per channel: %d TUs\n", (data[7] << 8) | data[6]); + printf("\t\t * scan active total per channel: %d TUs\n", (data[9] << 8) | data[8]); + printf("\t\t * BSS width channel transition delay factor: %d\n", (data[11] << 8) | data[10]); + printf("\t\t * OBSS Scan Activity Threshold: %d.%02d %%\n", + ((data[13] << 8) | data[12]) / 100, ((data[13] << 8) | data[12]) % 100); +} + +static void print_secchan_offs(const uint8_t type, uint8_t len, const uint8_t *data) +{ + if (data[0] < ARRAY_SIZE(ht_secondary_offset)) + printf(" %s (%d)\n", ht_secondary_offset[data[0]], data[0]); + else + printf(" %d\n", data[0]); +} + +static void print_bss_load(const uint8_t type, uint8_t len, const uint8_t *data) +{ + printf("\n"); + printf("\t\t * station count: %d\n", (data[1] << 8) | data[0]); + printf("\t\t * channel utilisation: %d/255\n", data[2]); + printf("\t\t * available admission capacity: %d [*32us]\n", (data[4] << 8) | data[3]); +} + +struct ie_print { + const char *name; + void (*print)(const uint8_t type, uint8_t len, const uint8_t *data); + uint8_t minlen, maxlen; + uint8_t flags; +}; + +static void print_ie(const struct ie_print *p, const uint8_t type, + uint8_t len, const uint8_t *data) +{ + int i; + + if (!p->print) + return; + + printf("\t%s:", p->name); + if (len < p->minlen || len > p->maxlen) { + if (len > 1) { + printf(" <invalid: %d bytes:", len); + for (i = 0; i < len; i++) + printf(" %.02x", data[i]); + printf(">\n"); + } else if (len) + printf(" <invalid: 1 byte: %.02x>\n", data[0]); + else + printf(" <invalid: no data>\n"); + return; + } + + p->print(type, len, data); +} + +#define PRINT_IGN { \ + .name = "IGNORE", \ + .print = NULL, \ + .minlen = 0, \ + .maxlen = 255, \ +} + +static const struct ie_print ieprinters[] = { + [0] = { "SSID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), }, + [1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, + [3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), }, + [5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), }, + [6] = { "IBSS ATIM window", print_ibssatim, 2, 2, BIT(PRINT_SCAN), }, + [7] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), }, + [11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), }, + [32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), }, + [35] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), }, + [42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), }, + [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), }, + [47] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), }, + [74] = { "Overlapping BSS scan params", print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), }, + [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), }, + [62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), }, + [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), }, + [192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), }, + [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), }, + [50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, + [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), }, + [127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), }, +}; + +static void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data) +{ + print_rsn_ie("TKIP", "IEEE 802.1X", len, data); +} + +static bool print_wifi_wmm_param(const uint8_t *data, uint8_t len) +{ + int i; + static const char *aci_tbl[] = { "BE", "BK", "VI", "VO" }; + + if (len < 19) + goto invalid; + + if (data[0] != 1) { + printf("Parameter: not version 1: "); + return false; + } + + printf("\t * Parameter version 1"); + + data++; + + if (data[0] & 0x80) + printf("\n\t\t * u-APSD"); + + data += 2; + + for (i = 0; i < 4; i++) { + printf("\n\t\t * %s:", aci_tbl[(data[0] >> 5) & 3]); + if (data[0] & 0x10) + printf(" acm"); + printf(" CW %d-%d", (1 << (data[1] & 0xf)) - 1, + (1 << (data[1] >> 4)) - 1); + printf(", AIFSN %d", data[0] & 0xf); + if (data[2] | data[3]) + printf(", TXOP %d usec", (data[2] + (data[3] << 8)) * 32); + data += 4; + } + + printf("\n"); + return true; + + invalid: + printf("invalid: "); + return false; +} + +static void print_wifi_wmm(const uint8_t type, uint8_t len, const uint8_t *data) +{ + int i; + + switch (data[0]) { + case 0x00: + printf(" information:"); + break; + case 0x01: + if (print_wifi_wmm_param(data + 1, len - 1)) + return; + break; + default: + printf(" type %d:", data[0]); + break; + } + + for(i = 1; i < len; i++) + printf(" %.02x", data[i]); + printf("\n"); +} + +static const char * wifi_wps_dev_passwd_id(uint16_t id) +{ + switch (id) { + case 0: + return "Default (PIN)"; + case 1: + return "User-specified"; + case 2: + return "Machine-specified"; + case 3: + return "Rekey"; + case 4: + return "PushButton"; + case 5: + return "Registrar-specified"; + default: + return "??"; + } +} + +static void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data) +{ + bool first = true; + __u16 subtype, sublen; + + while (len >= 4) { + subtype = (data[0] << 8) + data[1]; + sublen = (data[2] << 8) + data[3]; + if (sublen > len) + break; + + switch (subtype) { + case 0x104a: + tab_on_first(&first); + printf("\t * Version: %d.%d\n", data[4] >> 4, data[4] & 0xF); + break; + case 0x1011: + tab_on_first(&first); + printf("\t * Device name: %.*s\n", sublen, data + 4); + break; + case 0x1012: { + uint16_t id; + tab_on_first(&first); + if (sublen != 2) { + printf("\t * Device Password ID: (invalid " + "length %d)\n", sublen); + break; + } + id = data[4] << 8 | data[5]; + printf("\t * Device Password ID: %u (%s)\n", + id, wifi_wps_dev_passwd_id(id)); + break; + } + case 0x1021: + tab_on_first(&first); + printf("\t * Manufacturer: %.*s\n", sublen, data + 4); + break; + case 0x1023: + tab_on_first(&first); + printf("\t * Model: %.*s\n", sublen, data + 4); + break; + case 0x1024: + tab_on_first(&first); + printf("\t * Model Number: %.*s\n", sublen, data + 4); + break; + case 0x103b: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * Response Type: %d%s\n", + val, val == 3 ? " (AP)" : ""); + break; + } + case 0x103c: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * RF Bands: 0x%x\n", val); + break; + } + case 0x1041: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * Selected Registrar: 0x%x\n", val); + break; + } + case 0x1042: + tab_on_first(&first); + printf("\t * Serial Number: %.*s\n", sublen, data + 4); + break; + case 0x1044: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * Wi-Fi Protected Setup State: %d%s%s\n", + val, + val == 1 ? " (Unconfigured)" : "", + val == 2 ? " (Configured)" : ""); + break; + } + case 0x1047: + tab_on_first(&first); + printf("\t * UUID: "); + if (sublen != 16) { + printf("(invalid, length=%d)\n", sublen); + break; + } + printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-" + "%02x%02x-%02x%02x%02x%02x%02x%02x\n", + data[4], data[5], data[6], data[7], + data[8], data[9], data[10], data[11], + data[12], data[13], data[14], data[15], + data[16], data[17], data[18], data[19]); + break; + case 0x1054: { + tab_on_first(&first); + if (sublen != 8) { + printf("\t * Primary Device Type: (invalid " + "length %d)\n", sublen); + break; + } + printf("\t * Primary Device Type: " + "%u-%02x%02x%02x%02x-%u\n", + data[4] << 8 | data[5], + data[6], data[7], data[8], data[9], + data[10] << 8 | data[11]); + break; + } + case 0x1057: { + __u8 val = data[4]; + tab_on_first(&first); + printf("\t * AP setup locked: 0x%.2x\n", val); + break; + } + case 0x1008: + case 0x1053: { + __u16 meth = (data[4] << 8) + data[5]; + bool comma = false; + tab_on_first(&first); + printf("\t * %sConfig methods:", + subtype == 0x1053 ? "Selected Registrar ": ""); +#define T(bit, name) do { \ + if (meth & (1<<bit)) { \ + if (comma) \ + printf(","); \ + comma = true; \ + printf(" " name); \ + } } while (0) + T(0, "USB"); + T(1, "Ethernet"); + T(2, "Label"); + T(3, "Display"); + T(4, "Ext. NFC"); + T(5, "Int. NFC"); + T(6, "NFC Intf."); + T(7, "PBC"); + T(8, "Keypad"); + printf("\n"); + break; +#undef T + } + default: { + const __u8 *subdata = data + 4; + __u16 tmplen = sublen; + + tab_on_first(&first); + printf("\t * Unknown TLV (%#.4x, %d bytes):", + subtype, tmplen); + while (tmplen) { + printf(" %.2x", *subdata); + subdata++; + tmplen--; + } + printf("\n"); + break; + } + } + + data += sublen + 4; + len -= sublen + 4; + } + + if (len != 0) { + printf("\t\t * bogus tail data (%d):", len); + while (len) { + printf(" %.2x", *data); + data++; + len--; + } + printf("\n"); + } +} + +static const struct ie_print wifiprinters[] = { + [1] = { "WPA", print_wifi_wpa, 2, 255, BIT(PRINT_SCAN), }, + [2] = { "WMM", print_wifi_wmm, 1, 255, BIT(PRINT_SCAN), }, + [4] = { "WPS", print_wifi_wps, 0, 255, BIT(PRINT_SCAN), }, +}; + +static inline void print_p2p(const uint8_t type, uint8_t len, const uint8_t *data) +{ + bool first = true; + __u8 subtype; + __u16 sublen; + + while (len >= 3) { + subtype = data[0]; + sublen = (data[2] << 8) + data[1]; + + if (sublen > len - 3) + break; + + switch (subtype) { + case 0x02: /* capability */ + tab_on_first(&first); + if (sublen < 2) { + printf("\t * malformed capability\n"); + break; + } + printf("\t * Group capa: 0x%.2x, Device capa: 0x%.2x\n", + data[3], data[4]); + break; + case 0x0d: /* device info */ + if (sublen < 6 + 2 + 8 + 1) { + printf("\t * malformed device info\n"); + break; + } + /* fall through for now */ + case 0x00: /* status */ + case 0x01: /* minor reason */ + case 0x03: /* device ID */ + case 0x04: /* GO intent */ + case 0x05: /* configuration timeout */ + case 0x06: /* listen channel */ + case 0x07: /* group BSSID */ + case 0x08: /* ext listen timing */ + case 0x09: /* intended interface address */ + case 0x0a: /* manageability */ + case 0x0b: /* channel list */ + case 0x0c: /* NoA */ + case 0x0e: /* group info */ + case 0x0f: /* group ID */ + case 0x10: /* interface */ + case 0x11: /* operating channel */ + case 0x12: /* invitation flags */ + case 0xdd: /* vendor specific */ + default: { + const __u8 *subdata = data + 4; + __u16 tmplen = sublen; + + tab_on_first(&first); + printf("\t * Unknown TLV (%#.2x, %d bytes):", + subtype, tmplen); + while (tmplen) { + printf(" %.2x", *subdata); + subdata++; + tmplen--; + } + printf("\n"); + break; + } + } + + data += sublen + 3; + len -= sublen + 3; + } + + if (len != 0) { + tab_on_first(&first); + printf("\t * bogus tail data (%d):", len); + while (len) { + printf(" %.2x", *data); + data++; + len--; + } + printf("\n"); + } +} + +static const struct ie_print wfa_printers[] = { + [9] = { "P2P", print_p2p, 2, 255, BIT(PRINT_SCAN), }, +}; + +static void print_vendor(unsigned char len, unsigned char *data, + bool unknown, enum print_ie_type ptype) +{ + int i; + + if (len < 3) { + printf("\tVendor specific: <too short> data:"); + for(i = 0; i < len; i++) + printf(" %.02x", data[i]); + printf("\n"); + return; + } + + if (len >= 4 && memcmp(data, ms_oui, 3) == 0) { + if (data[3] < ARRAY_SIZE(wifiprinters) && + wifiprinters[data[3]].name && + wifiprinters[data[3]].flags & BIT(ptype)) { + print_ie(&wifiprinters[data[3]], data[3], len - 4, data + 4); + return; + } + if (!unknown) + return; + printf("\tMS/WiFi %#.2x, data:", data[3]); + for(i = 0; i < len - 4; i++) + printf(" %.02x", data[i + 4]); + printf("\n"); + return; + } + + if (len >= 4 && memcmp(data, wfa_oui, 3) == 0) { + if (data[3] < ARRAY_SIZE(wfa_printers) && + wfa_printers[data[3]].name && + wfa_printers[data[3]].flags & BIT(ptype)) { + print_ie(&wfa_printers[data[3]], data[3], len - 4, data + 4); + return; + } + if (!unknown) + return; + printf("\tWFA %#.2x, data:", data[3]); + for(i = 0; i < len - 4; i++) + printf(" %.02x", data[i + 4]); + printf("\n"); + return; + } + + if (!unknown) + return; + + printf("\tVendor specific: OUI %.2x:%.2x:%.2x, data:", + data[0], data[1], data[2]); + for (i = 3; i < len; i++) + printf(" %.2x", data[i]); + printf("\n"); +} + +void print_ies(unsigned char *ie, int ielen, bool unknown, + enum print_ie_type ptype) +{ + while (ielen >= 2 && ielen >= ie[1]) { + if (ie[0] < ARRAY_SIZE(ieprinters) && + ieprinters[ie[0]].name && + ieprinters[ie[0]].flags & BIT(ptype)) { + print_ie(&ieprinters[ie[0]], ie[0], ie[1], ie + 2); + } else if (ie[0] == 221 /* vendor */) { + print_vendor(ie[1], ie + 2, unknown, ptype); + } else if (unknown) { + int i; + + printf("\tUnknown IE (%d):", ie[0]); + for (i=0; i<ie[1]; i++) + printf(" %.2x", ie[2+i]); + printf("\n"); + } + ielen -= ie[1] + 2; + ie += ie[1] + 2; + } +} + +static void print_capa_dmg(__u16 capa) +{ + switch (capa & WLAN_CAPABILITY_DMG_TYPE_MASK) { + case WLAN_CAPABILITY_DMG_TYPE_AP: + printf(" DMG_ESS"); + break; + case WLAN_CAPABILITY_DMG_TYPE_PBSS: + printf(" DMG_PCP"); + break; + case WLAN_CAPABILITY_DMG_TYPE_IBSS: + printf(" DMG_IBSS"); + break; + } + + if (capa & WLAN_CAPABILITY_DMG_CBAP_ONLY) + printf(" CBAP_Only"); + if (capa & WLAN_CAPABILITY_DMG_CBAP_SOURCE) + printf(" CBAP_Src"); + if (capa & WLAN_CAPABILITY_DMG_PRIVACY) + printf(" Privacy"); + if (capa & WLAN_CAPABILITY_DMG_ECPAC) + printf(" ECPAC"); + if (capa & WLAN_CAPABILITY_DMG_SPECTRUM_MGMT) + printf(" SpectrumMgmt"); + if (capa & WLAN_CAPABILITY_DMG_RADIO_MEASURE) + printf(" RadioMeasure"); +} + +static void print_capa_non_dmg(__u16 capa) +{ + if (capa & WLAN_CAPABILITY_ESS) + printf(" ESS"); + if (capa & WLAN_CAPABILITY_IBSS) + printf(" IBSS"); + if (capa & WLAN_CAPABILITY_CF_POLLABLE) + printf(" CfPollable"); + if (capa & WLAN_CAPABILITY_CF_POLL_REQUEST) + printf(" CfPollReq"); + if (capa & WLAN_CAPABILITY_PRIVACY) + printf(" Privacy"); + if (capa & WLAN_CAPABILITY_SHORT_PREAMBLE) + printf(" ShortPreamble"); + if (capa & WLAN_CAPABILITY_PBCC) + printf(" PBCC"); + if (capa & WLAN_CAPABILITY_CHANNEL_AGILITY) + printf(" ChannelAgility"); + if (capa & WLAN_CAPABILITY_SPECTRUM_MGMT) + printf(" SpectrumMgmt"); + if (capa & WLAN_CAPABILITY_QOS) + printf(" QoS"); + if (capa & WLAN_CAPABILITY_SHORT_SLOT_TIME) + printf(" ShortSlotTime"); + if (capa & WLAN_CAPABILITY_APSD) + printf(" APSD"); + if (capa & WLAN_CAPABILITY_RADIO_MEASURE) + printf(" RadioMeasure"); + if (capa & WLAN_CAPABILITY_DSSS_OFDM) + printf(" DSSS-OFDM"); + if (capa & WLAN_CAPABILITY_DEL_BACK) + printf(" DelayedBACK"); + if (capa & WLAN_CAPABILITY_IMM_BACK) + printf(" ImmediateBACK"); +} + +static int print_bss_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *bss[NL80211_BSS_MAX + 1]; + char mac_addr[20], dev[20]; + 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] = { }, + }; + struct scan_params *params = arg; + int show = params->show_both_ie_sets ? 2 : 1; + bool is_dmg = false; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!tb[NL80211_ATTR_BSS]) { + fprintf(stderr, "bss info missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(bss, NL80211_BSS_MAX, + tb[NL80211_ATTR_BSS], + bss_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (!bss[NL80211_BSS_BSSID]) + return NL_SKIP; + + mac_addr_n2a(mac_addr, nla_data(bss[NL80211_BSS_BSSID])); + printf("BSS %s", mac_addr); + if (tb[NL80211_ATTR_IFINDEX]) { + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("(on %s)", dev); + } + + if (bss[NL80211_BSS_STATUS]) { + switch (nla_get_u32(bss[NL80211_BSS_STATUS])) { + case NL80211_BSS_STATUS_AUTHENTICATED: + printf(" -- authenticated"); + break; + case NL80211_BSS_STATUS_ASSOCIATED: + printf(" -- associated"); + break; + case NL80211_BSS_STATUS_IBSS_JOINED: + printf(" -- joined"); + break; + default: + printf(" -- unknown status: %d", + nla_get_u32(bss[NL80211_BSS_STATUS])); + break; + } + } + printf("\n"); + + if (bss[NL80211_BSS_TSF]) { + unsigned long long tsf; + tsf = (unsigned long long)nla_get_u64(bss[NL80211_BSS_TSF]); + printf("\tTSF: %llu usec (%llud, %.2lld:%.2llu:%.2llu)\n", + tsf, tsf/1000/1000/60/60/24, (tsf/1000/1000/60/60) % 24, + (tsf/1000/1000/60) % 60, (tsf/1000/1000) % 60); + } + if (bss[NL80211_BSS_FREQUENCY]) { + int freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]); + printf("\tfreq: %d\n", freq); + if (freq > 45000) + is_dmg = true; + } + if (bss[NL80211_BSS_BEACON_INTERVAL]) + printf("\tbeacon interval: %d TUs\n", + nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL])); + if (bss[NL80211_BSS_CAPABILITY]) { + __u16 capa = nla_get_u16(bss[NL80211_BSS_CAPABILITY]); + printf("\tcapability:"); + if (is_dmg) + print_capa_dmg(capa); + else + print_capa_non_dmg(capa); + printf(" (0x%.4x)\n", capa); + } + if (bss[NL80211_BSS_SIGNAL_MBM]) { + int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]); + printf("\tsignal: %d.%.2d dBm\n", s/100, s%100); + } + if (bss[NL80211_BSS_SIGNAL_UNSPEC]) { + unsigned char s = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); + printf("\tsignal: %d/100\n", s); + } + if (bss[NL80211_BSS_SEEN_MS_AGO]) { + int age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]); + printf("\tlast seen: %d ms ago\n", age); + } + + if (bss[NL80211_BSS_INFORMATION_ELEMENTS] && show--) { + if (bss[NL80211_BSS_BEACON_IES]) + printf("\tInformation elements from Probe Response " + "frame:\n"); + print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), + params->unknown, params->type); + } + if (bss[NL80211_BSS_BEACON_IES] && show--) { + printf("\tInformation elements from Beacon frame:\n"); + print_ies(nla_data(bss[NL80211_BSS_BEACON_IES]), + nla_len(bss[NL80211_BSS_BEACON_IES]), + params->unknown, params->type); + } + + return NL_SKIP; +} + +static struct scan_params scan_params; + +static int handle_scan_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + if (argc > 1) + return 1; + + memset(&scan_params, 0, sizeof(scan_params)); + + if (argc == 1 && !strcmp(argv[0], "-u")) + scan_params.unknown = true; + else if (argc == 1 && !strcmp(argv[0], "-b")) + scan_params.show_both_ie_sets = true; + + scan_params.type = PRINT_SCAN; + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_bss_handler, + &scan_params); + return 0; +} + +static int handle_scan_combined(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + char **trig_argv; + static char *dump_argv[] = { + NULL, + "scan", + "dump", + NULL, + }; + static const __u32 cmds[] = { + NL80211_CMD_NEW_SCAN_RESULTS, + NL80211_CMD_SCAN_ABORTED, + }; + int trig_argc, dump_argc, err; + + if (argc >= 3 && !strcmp(argv[2], "-u")) { + dump_argc = 4; + dump_argv[3] = "-u"; + } else if (argc >= 3 && !strcmp(argv[2], "-b")) { + dump_argc = 4; + dump_argv[3] = "-b"; + } else + dump_argc = 3; + + trig_argc = 3 + (argc - 2) + (3 - dump_argc); + trig_argv = calloc(trig_argc, sizeof(*trig_argv)); + if (!trig_argv) + return -ENOMEM; + trig_argv[0] = argv[0]; + trig_argv[1] = "scan"; + trig_argv[2] = "trigger"; + int i; + for (i = 0; i < argc - 2 - (dump_argc - 3); i++) + trig_argv[i + 3] = argv[i + 2 + (dump_argc - 3)]; + err = handle_cmd(state, id, trig_argc, trig_argv); + free(trig_argv); + if (err) + return err; + + /* + * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION + * + * This code has a bug, which requires creating a separate + * nl80211 socket to fix: + * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or + * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel + * before (!) we listen to it, because we only start listening + * after we send our scan request. + * + * Doing it the other way around has a race condition as well, + * if you first open the events socket you may get a notification + * for a previous scan. + * + * The only proper way to fix this would be to listen to events + * before sending the command, and for the kernel to send the + * scan request along with the event, so that you can match up + * whether the scan you requested was finished or aborted (this + * may result in processing a scan that another application + * requested, but that doesn't seem to be a problem). + * + * Alas, the kernel doesn't do that (yet). + */ + + if (listen_events(state, ARRAY_SIZE(cmds), cmds) == + NL80211_CMD_SCAN_ABORTED) { + printf("scan aborted!\n"); + return 0; + } + + dump_argv[0] = argv[0]; + return handle_cmd(state, id, dump_argc, dump_argv); +} +TOPLEVEL(scan, "[-u] [freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force] [ssid <ssid>*|passive]", 0, 0, + CIB_NETDEV, handle_scan_combined, + "Scan on the given frequencies and probe for the given SSIDs\n" + "(or wildcard if not given) unless passive scanning is requested.\n" + "If -u is specified print unknown data in the scan results.\n" + "Specified (vendor) IEs must be well-formed."); +COMMAND(scan, dump, "[-u]", + NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump, + "Dump the current scan results. If -u is specified, print unknown\n" + "data in scan results."); +COMMAND(scan, trigger, "[freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force] [ssid <ssid>*|passive]", + NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan, + "Trigger a scan on the given frequencies with probing for the given\n" + "SSIDs (or wildcard if not given) unless passive scanning is requested.");
diff --git a/iw_3.10/iw_3.10/sections.c b/iw_3.10/iw_3.10/sections.c new file mode 100644 index 0000000..38095f6 --- /dev/null +++ b/iw_3.10/iw_3.10/sections.c
@@ -0,0 +1,4 @@ +#include "iw.h" + +SECTION(get); +SECTION(set);
diff --git a/iw_3.10/iw_3.10/station.c b/iw_3.10/iw_3.10/station.c new file mode 100644 index 0000000..dde552f --- /dev/null +++ b/iw_3.10/iw_3.10/station.c
@@ -0,0 +1,505 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(station); + +enum plink_state { + LISTEN, + OPN_SNT, + OPN_RCVD, + CNF_RCVD, + ESTAB, + HOLDING, + BLOCKED +}; + +static void print_power_mode(struct nlattr *a) +{ + enum nl80211_mesh_power_mode pm = nla_get_u32(a); + + switch (pm) { + case NL80211_MESH_POWER_ACTIVE: + printf("ACTIVE"); + break; + case NL80211_MESH_POWER_LIGHT_SLEEP: + printf("LIGHT SLEEP"); + break; + case NL80211_MESH_POWER_DEEP_SLEEP: + printf("DEEP SLEEP"); + break; + default: + printf("UNKNOWN"); + break; + } +} + +void parse_tx_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])); +} + +static int print_sta_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; + char mac_addr[20], state_name[10], dev[20]; + struct nl80211_sta_flag_update *sta_flags; + static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { + [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_T_OFFSET] = { .type = NLA_U64 }, + [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED }, + [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}, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + /* + * TODO: validate the interface and mac address! + * Otherwise, there's a race condition as soon as + * the kernel starts sending station notifications. + */ + + if (!tb[NL80211_ATTR_STA_INFO]) { + fprintf(stderr, "sta stats missing!\n"); + return NL_SKIP; + } + if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, + tb[NL80211_ATTR_STA_INFO], + stats_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + mac_addr_n2a(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("Station %s (on %s)", mac_addr, dev); + + if (sinfo[NL80211_STA_INFO_INACTIVE_TIME]) + printf("\n\tinactive time:\t%u ms", + nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME])); + if (sinfo[NL80211_STA_INFO_RX_BYTES]) + printf("\n\trx bytes:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES])); + if (sinfo[NL80211_STA_INFO_RX_PACKETS]) + printf("\n\trx packets:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_RX_PACKETS])); + if (sinfo[NL80211_STA_INFO_TX_BYTES]) + printf("\n\ttx bytes:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES])); + if (sinfo[NL80211_STA_INFO_TX_PACKETS]) + printf("\n\ttx packets:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS])); + if (sinfo[NL80211_STA_INFO_TX_RETRIES]) + printf("\n\ttx retries:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES])); + if (sinfo[NL80211_STA_INFO_TX_FAILED]) + printf("\n\ttx failed:\t%u", + nla_get_u32(sinfo[NL80211_STA_INFO_TX_FAILED])); + if (sinfo[NL80211_STA_INFO_SIGNAL]) + printf("\n\tsignal: \t%d dBm", + (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL])); + if (sinfo[NL80211_STA_INFO_SIGNAL_AVG]) + printf("\n\tsignal avg:\t%d dBm", + (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG])); + if (sinfo[NL80211_STA_INFO_T_OFFSET]) + printf("\n\tToffset:\t%lld us", + (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_T_OFFSET])); + + if (sinfo[NL80211_STA_INFO_TX_BITRATE]) { + char buf[100]; + + parse_tx_bitrate(sinfo[NL80211_STA_INFO_TX_BITRATE], buf, sizeof(buf)); + printf("\n\ttx bitrate:\t%s", buf); + } + + if (sinfo[NL80211_STA_INFO_LLID]) + printf("\n\tmesh llid:\t%d", + nla_get_u16(sinfo[NL80211_STA_INFO_LLID])); + if (sinfo[NL80211_STA_INFO_PLID]) + printf("\n\tmesh plid:\t%d", + nla_get_u16(sinfo[NL80211_STA_INFO_PLID])); + if (sinfo[NL80211_STA_INFO_PLINK_STATE]) { + switch (nla_get_u8(sinfo[NL80211_STA_INFO_PLINK_STATE])) { + case LISTEN: + strcpy(state_name, "LISTEN"); + break; + case OPN_SNT: + strcpy(state_name, "OPN_SNT"); + break; + case OPN_RCVD: + strcpy(state_name, "OPN_RCVD"); + break; + case CNF_RCVD: + strcpy(state_name, "CNF_RCVD"); + break; + case ESTAB: + strcpy(state_name, "ESTAB"); + break; + case HOLDING: + strcpy(state_name, "HOLDING"); + break; + case BLOCKED: + strcpy(state_name, "BLOCKED"); + break; + default: + strcpy(state_name, "UNKNOWN"); + break; + } + printf("\n\tmesh plink:\t%s", state_name); + } + if (sinfo[NL80211_STA_INFO_LOCAL_PM]) { + printf("\n\tmesh local PS mode:\t"); + print_power_mode(sinfo[NL80211_STA_INFO_LOCAL_PM]); + } + if (sinfo[NL80211_STA_INFO_PEER_PM]) { + printf("\n\tmesh peer PS mode:\t"); + print_power_mode(sinfo[NL80211_STA_INFO_PEER_PM]); + } + if (sinfo[NL80211_STA_INFO_NONPEER_PM]) { + printf("\n\tmesh non-peer PS mode:\t"); + print_power_mode(sinfo[NL80211_STA_INFO_NONPEER_PM]); + } + + 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_AUTHORIZED)) { + printf("\n\tauthorized:\t"); + if (sta_flags->set & BIT(NL80211_STA_FLAG_AUTHORIZED)) + printf("yes"); + else + printf("no"); + } + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) { + printf("\n\tauthenticated:\t"); + if (sta_flags->set & BIT(NL80211_STA_FLAG_AUTHENTICATED)) + printf("yes"); + else + printf("no"); + } + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) { + printf("\n\tpreamble:\t"); + if (sta_flags->set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) + printf("short"); + else + printf("long"); + } + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_WME)) { + printf("\n\tWMM/WME:\t"); + if (sta_flags->set & BIT(NL80211_STA_FLAG_WME)) + printf("yes"); + else + printf("no"); + } + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_MFP)) { + printf("\n\tMFP:\t\t"); + if (sta_flags->set & BIT(NL80211_STA_FLAG_MFP)) + printf("yes"); + else + printf("no"); + } + + if (sta_flags->mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) { + printf("\n\tTDLS peer:\t"); + if (sta_flags->set & BIT(NL80211_STA_FLAG_TDLS_PEER)) + printf("yes"); + else + printf("no"); + } + } + + printf("\n"); + return NL_SKIP; +} + +static int handle_station_get(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 1) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND(station, get, "<MAC address>", + NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get, + "Get information for a specific station."); +COMMAND(station, del, "<MAC address>", + NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get, + "Remove the given station entry (use with caution!)"); + +static const struct cmd *station_set_plink; +static const struct cmd *station_set_vlan; +static const struct cmd *station_set_mesh_power_mode; + +static const struct cmd *select_station_cmd(int argc, char **argv) +{ + if (argc < 2) + return NULL; + if (strcmp(argv[1], "plink_action") == 0) + return station_set_plink; + if (strcmp(argv[1], "vlan") == 0) + return station_set_vlan; + if (strcmp(argv[1], "mesh_power_mode") == 0) + return station_set_mesh_power_mode; + return NULL; +} + +static int handle_station_set_plink(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char plink_action; + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 3) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + argc--; + argv++; + + if (strcmp("plink_action", argv[0]) != 0) + return 1; + argc--; + argv++; + + if (strcmp("open", argv[0]) == 0) + plink_action = NL80211_PLINK_ACTION_OPEN; + else if (strcmp("block", argv[0]) == 0) + plink_action = NL80211_PLINK_ACTION_BLOCK; + else { + fprintf(stderr, "plink action not supported\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + NLA_PUT_U8(msg, NL80211_ATTR_STA_PLINK_ACTION, plink_action); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND_ALIAS(station, set, "<MAC address> plink_action <open|block>", + NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set_plink, + "Set mesh peer link action for this station (peer).", + select_station_cmd, station_set_plink); + +static int handle_station_set_vlan(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char mac_addr[ETH_ALEN]; + unsigned long sta_vlan = 0; + char *err = NULL; + + if (argc < 3) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + argc--; + argv++; + + if (strcmp("vlan", argv[0]) != 0) + return 1; + argc--; + argv++; + + sta_vlan = strtoul(argv[0], &err, 0); + if (err && *err) { + fprintf(stderr, "invalid vlan id\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN, sta_vlan); + + return 0; + nla_put_failure: + return -ENOBUFS; +} +COMMAND_ALIAS(station, set, "<MAC address> vlan <ifindex>", + NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set_vlan, + "Set an AP VLAN for this station.", + select_station_cmd, station_set_vlan); + +static int handle_station_set_mesh_power_mode(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + unsigned char mesh_power_mode; + unsigned char mac_addr[ETH_ALEN]; + + if (argc < 3) + return 1; + + if (mac_addr_a2n(mac_addr, argv[0])) { + fprintf(stderr, "invalid mac address\n"); + return 2; + } + argc--; + argv++; + + if (strcmp("mesh_power_mode", argv[0]) != 0) + return 1; + argc--; + argv++; + + if (strcmp("active", argv[0]) == 0) + mesh_power_mode = NL80211_MESH_POWER_ACTIVE; + else if (strcmp("light", argv[0]) == 0) + mesh_power_mode = NL80211_MESH_POWER_LIGHT_SLEEP; + else if (strcmp("deep", argv[0]) == 0) + mesh_power_mode = NL80211_MESH_POWER_DEEP_SLEEP; + else { + fprintf(stderr, "unknown mesh power mode\n"); + return 2; + } + argc--; + argv++; + + if (argc) + return 1; + + NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr); + NLA_PUT_U32(msg, NL80211_ATTR_LOCAL_MESH_POWER_MODE, mesh_power_mode); + + return 0; +nla_put_failure: + return -ENOBUFS; +} +COMMAND_ALIAS(station, set, "<MAC address> mesh_power_mode " + "<active|light|deep>", NL80211_CMD_SET_STATION, 0, CIB_NETDEV, + handle_station_set_mesh_power_mode, + "Set link-specific mesh power mode for this station", + select_station_cmd, station_set_mesh_power_mode); + +static int handle_station_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL); + return 0; +} +COMMAND(station, dump, NULL, + NL80211_CMD_GET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump, + "List all stations known, e.g. the AP on managed interfaces");
diff --git a/iw_3.10/iw_3.10/status.c b/iw_3.10/iw_3.10/status.c new file mode 100644 index 0000000..731727d --- /dev/null +++ b/iw_3.10/iw_3.10/status.c
@@ -0,0 +1,59 @@ +#include <stdint.h> +#include "iw.h" + +static const char *status_table[] = { + [0] = "Successful", + [1] = "Unspecified failure", + [10] = "Cannot support all requested capabilities in the capability information field", + [11] = "Reassociation denied due to inability to confirm that association exists", + [12] = "Association denied due to reason outside the scope of this standard", + [13] = "Responding station does not support the specified authentication algorithm", + [14] = "Received an authentication frame with authentication transaction sequence number out of expected sequence", + [15] = "Authentication rejected because of challenge failure", + [16] = "Authentication rejected due to timeout waiting for next frame in sequence", + [17] = "Association denied because AP is unable to handle additional associated STA", + [18] = "Association denied due to requesting station not supporting all of the data rates in the BSSBasicRateSet parameter", + [19] = "Association denied due to requesting station not supporting the short preamble option", + [20] = "Association denied due to requesting station not supporting the PBCC modulation option", + [21] = "Association denied due to requesting station not supporting the channel agility option", + [22] = "Association request rejected because Spectrum Management capability is required", + [23] = "Association request rejected because the information in the Power Capability element is unacceptable", + [24] = "Association request rejected because the information in the Supported Channels element is unacceptable", + [25] = "Association request rejected due to requesting station not supporting the short slot time option", + [26] = "Association request rejected due to requesting station not supporting the ER-PBCC modulation option", + [27] = "Association denied due to requesting STA not supporting HT features", + [28] = "R0KH Unreachable", + [29] = "Association denied because the requesting STA does not support the PCO transition required by the AP", + [30] = "Association request rejected temporarily; try again later", + [31] = "Robust Management frame policy violation", + [32] = "Unspecified, QoS related failure", + [33] = "Association denied due to QAP having insufficient bandwidth to handle another QSTA", + [34] = "Association denied due to poor channel conditions", + [35] = "Association (with QBSS) denied due to requesting station not supporting the QoS facility", + [37] = "The request has been declined", + [38] = "The request has not been successful as one or more parameters have invalid values", + [39] = "The TS has not been created because the request cannot be honored. However, a suggested Tspec is provided so that the initiating QSTA may attempt to send another TS with the suggested changes to the TSpec", + [40] = "Invalid Information Element", + [41] = "Group Cipher is not valid", + [42] = "Pairwise Cipher is not valid", + [43] = "AKMP is not valid", + [44] = "Unsupported RSN IE version", + [45] = "Invalid RSN IE Capabilities", + [46] = "Cipher suite is rejected per security policy", + [47] = "The TS has not been created. However, the HC may be capable of creating a TS, in response to a request, after the time indicated in the TS Delay element", + [48] = "Direct link is not allowed in the BSS by policy", + [49] = "Destination STA is not present within this QBSS", + [50] = "The destination STA is not a QSTA", + [51] = "Association denied because Listen Interval is too large", + [52] = "Invalid Fast BSS Transition Action Frame Count", + [53] = "Invalid PMKID", + [54] = "Invalid MDIE", + [55] = "Invalid FTIE", +}; + +const char *get_status_str(uint16_t status) +{ + if (status < ARRAY_SIZE(status_table) && status_table[status]) + return status_table[status]; + return "<unknown>"; +}
diff --git a/iw_3.10/iw_3.10/survey.c b/iw_3.10/iw_3.10/survey.c new file mode 100644 index 0000000..39cd7b8 --- /dev/null +++ b/iw_3.10/iw_3.10/survey.c
@@ -0,0 +1,83 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(survey); + +static int print_survey_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; + char dev[20]; + + 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 }, + }; + + nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); + printf("Survey data from %s\n", dev); + + if (!tb[NL80211_ATTR_SURVEY_INFO]) { + fprintf(stderr, "survey data missing!\n"); + return NL_SKIP; + } + + if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX, + tb[NL80211_ATTR_SURVEY_INFO], + survey_policy)) { + fprintf(stderr, "failed to parse nested attributes!\n"); + return NL_SKIP; + } + + if (sinfo[NL80211_SURVEY_INFO_FREQUENCY]) + printf("\tfrequency:\t\t\t%u MHz%s\n", + nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]), + sinfo[NL80211_SURVEY_INFO_IN_USE] ? " [in use]" : ""); + if (sinfo[NL80211_SURVEY_INFO_NOISE]) + printf("\tnoise:\t\t\t\t%d dBm\n", + (int8_t)nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME]) + printf("\tchannel active time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY]) + printf("\tchannel busy time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY]) + printf("\textension channel busy time:\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX]) + printf("\tchannel receive time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_RX])); + if (sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX]) + printf("\tchannel transmit time:\t\t%llu ms\n", + (unsigned long long)nla_get_u64(sinfo[NL80211_SURVEY_INFO_CHANNEL_TIME_TX])); + return NL_SKIP; +} + +static int handle_survey_dump(struct nl80211_state *state, + struct nl_cb *cb, + struct nl_msg *msg, + int argc, char **argv, + enum id_input id) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_survey_handler, NULL); + return 0; +} +COMMAND(survey, dump, NULL, + NL80211_CMD_GET_SURVEY, NLM_F_DUMP, CIB_NETDEV, handle_survey_dump, + "List all gathered channel survey data"); +
diff --git a/iw_3.10/iw_3.10/util.c b/iw_3.10/iw_3.10/util.c new file mode 100644 index 0000000..c272c1d --- /dev/null +++ b/iw_3.10/iw_3.10/util.c
@@ -0,0 +1,676 @@ +#include <ctype.h> +#include <netlink/attr.h> +#include <errno.h> +#include <stdbool.h> +#include "iw.h" +#include "nl80211.h" + +void mac_addr_n2a(char *mac_addr, unsigned char *arg) +{ + int i, l; + + l = 0; + for (i = 0; i < ETH_ALEN ; i++) { + if (i == 0) { + sprintf(mac_addr+l, "%02x", arg[i]); + l += 2; + } else { + sprintf(mac_addr+l, ":%02x", arg[i]); + l += 3; + } + } +} + +int mac_addr_a2n(unsigned char *mac_addr, char *arg) +{ + int i; + + for (i = 0; i < ETH_ALEN ; i++) { + int temp; + char *cp = strchr(arg, ':'); + if (cp) { + *cp = 0; + cp++; + } + if (sscanf(arg, "%x", &temp) != 1) + return -1; + if (temp < 0 || temp > 255) + return -1; + + mac_addr[i] = temp; + if (!cp) + break; + arg = cp; + } + if (i < ETH_ALEN - 1) + return -1; + + return 0; +} + +int parse_hex_mask(char *hexmask, unsigned char **result, size_t *result_len, + unsigned char **mask) +{ + size_t len = strlen(hexmask) / 2; + unsigned char *result_val; + unsigned char *result_mask = NULL; + + int pos = 0; + + *result_len = 0; + + result_val = calloc(len + 2, 1); + if (!result_val) + goto error; + *result = result_val; + if (mask) { + result_mask = calloc(DIV_ROUND_UP(len, 8) + 2, 1); + if (!result_mask) + goto error; + *mask = result_mask; + } + + while (1) { + char *cp = strchr(hexmask, ':'); + if (cp) { + *cp = 0; + cp++; + } + + if (result_mask && (strcmp(hexmask, "-") == 0 || + strcmp(hexmask, "xx") == 0 || + strcmp(hexmask, "--") == 0)) { + /* skip this byte and leave mask bit unset */ + } else { + int temp, mask_pos; + char *end; + + temp = strtoul(hexmask, &end, 16); + if (*end) + goto error; + if (temp < 0 || temp > 255) + goto error; + result_val[pos] = temp; + + mask_pos = pos / 8; + if (result_mask) + result_mask[mask_pos] |= 1 << (pos % 8); + } + + (*result_len)++; + pos++; + + if (!cp) + break; + hexmask = cp; + } + + return 0; + error: + free(result_val); + free(result_mask); + return -1; +} + +unsigned char *parse_hex(char *hex, size_t *outlen) +{ + unsigned char *result; + + if (parse_hex_mask(hex, &result, outlen, NULL)) + return NULL; + return result; +} + +static const char *ifmodes[NL80211_IFTYPE_MAX + 1] = { + "unspecified", + "IBSS", + "managed", + "AP", + "AP/VLAN", + "WDS", + "monitor", + "mesh point", + "P2P-client", + "P2P-GO", + "P2P-device", +}; + +static char modebuf[100]; + +const char *iftype_name(enum nl80211_iftype iftype) +{ + if (iftype <= NL80211_IFTYPE_MAX && ifmodes[iftype]) + return ifmodes[iftype]; + sprintf(modebuf, "Unknown mode (%d)", iftype); + return modebuf; +} + +static const char *commands[NL80211_CMD_MAX + 1] = { +/* + * sed 's/^\tNL80211_CMD_//;t n;d;:n s%^\([^=]*\),.*%\t[NL80211_CMD_\1] = \"\L\1\",%;t;d' nl80211.h + */ + [NL80211_CMD_UNSPEC] = "unspec", + [NL80211_CMD_GET_WIPHY] = "get_wiphy", + [NL80211_CMD_SET_WIPHY] = "set_wiphy", + [NL80211_CMD_NEW_WIPHY] = "new_wiphy", + [NL80211_CMD_DEL_WIPHY] = "del_wiphy", + [NL80211_CMD_GET_INTERFACE] = "get_interface", + [NL80211_CMD_SET_INTERFACE] = "set_interface", + [NL80211_CMD_NEW_INTERFACE] = "new_interface", + [NL80211_CMD_DEL_INTERFACE] = "del_interface", + [NL80211_CMD_GET_KEY] = "get_key", + [NL80211_CMD_SET_KEY] = "set_key", + [NL80211_CMD_NEW_KEY] = "new_key", + [NL80211_CMD_DEL_KEY] = "del_key", + [NL80211_CMD_GET_BEACON] = "get_beacon", + [NL80211_CMD_SET_BEACON] = "set_beacon", + [NL80211_CMD_START_AP] = "start_ap", + [NL80211_CMD_STOP_AP] = "stop_ap", + [NL80211_CMD_GET_STATION] = "get_station", + [NL80211_CMD_SET_STATION] = "set_station", + [NL80211_CMD_NEW_STATION] = "new_station", + [NL80211_CMD_DEL_STATION] = "del_station", + [NL80211_CMD_GET_MPATH] = "get_mpath", + [NL80211_CMD_SET_MPATH] = "set_mpath", + [NL80211_CMD_NEW_MPATH] = "new_mpath", + [NL80211_CMD_DEL_MPATH] = "del_mpath", + [NL80211_CMD_SET_BSS] = "set_bss", + [NL80211_CMD_SET_REG] = "set_reg", + [NL80211_CMD_REQ_SET_REG] = "req_set_reg", + [NL80211_CMD_GET_MESH_CONFIG] = "get_mesh_config", + [NL80211_CMD_SET_MESH_CONFIG] = "set_mesh_config", + [NL80211_CMD_GET_REG] = "get_reg", + [NL80211_CMD_GET_SCAN] = "get_scan", + [NL80211_CMD_TRIGGER_SCAN] = "trigger_scan", + [NL80211_CMD_NEW_SCAN_RESULTS] = "new_scan_results", + [NL80211_CMD_SCAN_ABORTED] = "scan_aborted", + [NL80211_CMD_REG_CHANGE] = "reg_change", + [NL80211_CMD_AUTHENTICATE] = "authenticate", + [NL80211_CMD_ASSOCIATE] = "associate", + [NL80211_CMD_DEAUTHENTICATE] = "deauthenticate", + [NL80211_CMD_DISASSOCIATE] = "disassociate", + [NL80211_CMD_MICHAEL_MIC_FAILURE] = "michael_mic_failure", + [NL80211_CMD_REG_BEACON_HINT] = "reg_beacon_hint", + [NL80211_CMD_JOIN_IBSS] = "join_ibss", + [NL80211_CMD_LEAVE_IBSS] = "leave_ibss", + [NL80211_CMD_TESTMODE] = "testmode", + [NL80211_CMD_CONNECT] = "connect", + [NL80211_CMD_ROAM] = "roam", + [NL80211_CMD_DISCONNECT] = "disconnect", + [NL80211_CMD_SET_WIPHY_NETNS] = "set_wiphy_netns", + [NL80211_CMD_GET_SURVEY] = "get_survey", + [NL80211_CMD_NEW_SURVEY_RESULTS] = "new_survey_results", + [NL80211_CMD_SET_PMKSA] = "set_pmksa", + [NL80211_CMD_DEL_PMKSA] = "del_pmksa", + [NL80211_CMD_FLUSH_PMKSA] = "flush_pmksa", + [NL80211_CMD_REMAIN_ON_CHANNEL] = "remain_on_channel", + [NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL] = "cancel_remain_on_channel", + [NL80211_CMD_SET_TX_BITRATE_MASK] = "set_tx_bitrate_mask", + [NL80211_CMD_REGISTER_FRAME] = "register_frame", + [NL80211_CMD_FRAME] = "frame", + [NL80211_CMD_FRAME_TX_STATUS] = "frame_tx_status", + [NL80211_CMD_SET_POWER_SAVE] = "set_power_save", + [NL80211_CMD_GET_POWER_SAVE] = "get_power_save", + [NL80211_CMD_SET_CQM] = "set_cqm", + [NL80211_CMD_NOTIFY_CQM] = "notify_cqm", + [NL80211_CMD_SET_CHANNEL] = "set_channel", + [NL80211_CMD_SET_WDS_PEER] = "set_wds_peer", + [NL80211_CMD_FRAME_WAIT_CANCEL] = "frame_wait_cancel", + [NL80211_CMD_JOIN_MESH] = "join_mesh", + [NL80211_CMD_LEAVE_MESH] = "leave_mesh", + [NL80211_CMD_UNPROT_DEAUTHENTICATE] = "unprot_deauthenticate", + [NL80211_CMD_UNPROT_DISASSOCIATE] = "unprot_disassociate", + [NL80211_CMD_NEW_PEER_CANDIDATE] = "new_peer_candidate", + [NL80211_CMD_GET_WOWLAN] = "get_wowlan", + [NL80211_CMD_SET_WOWLAN] = "set_wowlan", + [NL80211_CMD_START_SCHED_SCAN] = "start_sched_scan", + [NL80211_CMD_STOP_SCHED_SCAN] = "stop_sched_scan", + [NL80211_CMD_SCHED_SCAN_RESULTS] = "sched_scan_results", + [NL80211_CMD_SCHED_SCAN_STOPPED] = "sched_scan_stopped", + [NL80211_CMD_SET_REKEY_OFFLOAD] = "set_rekey_offload", + [NL80211_CMD_PMKSA_CANDIDATE] = "pmksa_candidate", + [NL80211_CMD_TDLS_OPER] = "tdls_oper", + [NL80211_CMD_TDLS_MGMT] = "tdls_mgmt", + [NL80211_CMD_UNEXPECTED_FRAME] = "unexpected_frame", + [NL80211_CMD_PROBE_CLIENT] = "probe_client", + [NL80211_CMD_REGISTER_BEACONS] = "register_beacons", + [NL80211_CMD_UNEXPECTED_4ADDR_FRAME] = "unexpected_4addr_frame", + [NL80211_CMD_SET_NOACK_MAP] = "set_noack_map", + [NL80211_CMD_CH_SWITCH_NOTIFY] = "ch_switch_notify", + [NL80211_CMD_START_P2P_DEVICE] = "start_p2p_device", + [NL80211_CMD_STOP_P2P_DEVICE] = "stop_p2p_device", + [NL80211_CMD_CONN_FAILED] = "conn_failed", +}; + +static char cmdbuf[100]; + +const char *command_name(enum nl80211_commands cmd) +{ + if (cmd <= NL80211_CMD_MAX && commands[cmd]) + return commands[cmd]; + sprintf(cmdbuf, "Unknown command (%d)", cmd); + return cmdbuf; +} + +int ieee80211_channel_to_frequency(int chan) +{ + if (chan < 14) + return 2407 + chan * 5; + + if (chan == 14) + return 2484; + + /* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */ + return (chan + 1000) * 5; +} + +int ieee80211_frequency_to_channel(int freq) +{ + if (freq == 2484) + return 14; + + if (freq < 2484) + return (freq - 2407) / 5; + + /* FIXME: dot11ChannelStartingFactor (802.11-2007 17.3.8.3.2) */ + if (freq < 45000) + return freq/5 - 1000; + + if (freq >= 58320 && freq <= 64800) + return (freq - 56160) / 2160; + + return 0; +} + +void print_ssid_escaped(const uint8_t len, const uint8_t *data) +{ + int i; + + for (i = 0; i < len; i++) { + if (isprint(data[i]) && data[i] != ' ' && data[i] != '\\') + printf("%c", data[i]); + else if (data[i] == ' ' && + (i != 0 && i != len -1)) + printf(" "); + else + printf("\\x%.2x", data[i]); + } +} + +static int hex2num(char digit) +{ + if (!isxdigit(digit)) + return -1; + if (isdigit(digit)) + return digit - '0'; + return tolower(digit) - 'a' + 10; +} + +static int hex2byte(char *hex) +{ + int d1, d2; + + d1 = hex2num(hex[0]); + if (d1 < 0) + return -1; + d2 = hex2num(hex[1]); + if (d2 < 0) + return -1; + return (d1 << 4) | d2; +} + +static char *hex2bin(char *hex, char *buf) +{ + char *result = buf; + int d; + + while (hex[0]) { + d = hex2byte(hex); + if (d < 0) + return NULL; + buf[0] = d; + buf++; + hex += 2; + } + + return result; +} + +int parse_keys(struct nl_msg *msg, char **argv, int argc) +{ + struct nlattr *keys; + int i = 0; + bool have_default = false; + char keybuf[13]; + + if (!argc) + return 1; + + NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY); + + keys = nla_nest_start(msg, NL80211_ATTR_KEYS); + if (!keys) + return -ENOBUFS; + + do { + char *arg = *argv; + int pos = 0, keylen; + struct nlattr *key = nla_nest_start(msg, ++i); + char *keydata; + + if (!key) + return -ENOBUFS; + + if (arg[pos] == 'd') { + NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT); + pos++; + if (arg[pos] == ':') + pos++; + have_default = true; + } + + if (!isdigit(arg[pos])) + goto explain; + NLA_PUT_U8(msg, NL80211_KEY_IDX, arg[pos++] - '0'); + if (arg[pos++] != ':') + goto explain; + keydata = arg + pos; + switch (strlen(keydata)) { + case 10: + keydata = hex2bin(keydata, keybuf); + case 5: + NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC01); + keylen = 5; + break; + case 26: + keydata = hex2bin(keydata, keybuf); + case 13: + NLA_PUT_U32(msg, NL80211_KEY_CIPHER, 0x000FAC05); + keylen = 13; + break; + default: + goto explain; + } + + if (!keydata) + goto explain; + + NLA_PUT(msg, NL80211_KEY_DATA, keylen, keydata); + + argv++; + argc--; + + /* one key should be TX key */ + if (!have_default && !argc) + NLA_PUT_FLAG(msg, NL80211_KEY_DEFAULT); + + nla_nest_end(msg, key); + } while (argc); + + nla_nest_end(msg, keys); + + return 0; + nla_put_failure: + return -ENOBUFS; + explain: + fprintf(stderr, "key must be [d:]index:data where\n" + " 'd:' means default (transmit) key\n" + " 'index:' is a single digit (0-3)\n" + " 'data' must be 5 or 13 ascii chars\n" + " or 10 or 26 hex digits\n" + "for example: d:2:6162636465 is the same as d:2:abcde\n"); + return 2; +} + +static void print_mcs_index(const __u8 *mcs) +{ + int mcs_bit, prev_bit = -2, prev_cont = 0; + + for (mcs_bit = 0; mcs_bit <= 76; mcs_bit++) { + unsigned int mcs_octet = mcs_bit/8; + unsigned int MCS_RATE_BIT = 1 << mcs_bit % 8; + bool mcs_rate_idx_set; + + mcs_rate_idx_set = !!(mcs[mcs_octet] & MCS_RATE_BIT); + + if (!mcs_rate_idx_set) + continue; + + if (prev_bit != mcs_bit - 1) { + if (prev_bit != -2) + printf("%d, ", prev_bit); + else + printf(" "); + printf("%d", mcs_bit); + prev_cont = 0; + } else if (!prev_cont) { + printf("-"); + prev_cont = 1; + } + + prev_bit = mcs_bit; + } + + if (prev_cont) + printf("%d", prev_bit); + printf("\n"); +} + +/* + * There are only 4 possible values, we just use a case instead of computing it, + * but technically this can also be computed through the formula: + * + * Max AMPDU length = (2 ^ (13 + exponent)) - 1 bytes + */ +static __u32 compute_ampdu_length(__u8 exponent) +{ + switch (exponent) { + case 0: return 8191; /* (2 ^(13 + 0)) -1 */ + case 1: return 16383; /* (2 ^(13 + 1)) -1 */ + case 2: return 32767; /* (2 ^(13 + 2)) -1 */ + case 3: return 65535; /* (2 ^(13 + 3)) -1 */ + default: return 0; + } +} + +static const char *print_ampdu_space(__u8 space) +{ + switch (space) { + case 0: return "No restriction"; + case 1: return "1/4 usec"; + case 2: return "1/2 usec"; + case 3: return "1 usec"; + case 4: return "2 usec"; + case 5: return "4 usec"; + case 6: return "8 usec"; + case 7: return "16 usec"; + default: + return "BUG (spacing more than 3 bits!)"; + } +} + +void print_ampdu_length(__u8 exponent) +{ + __u32 max_ampdu_length; + + max_ampdu_length = compute_ampdu_length(exponent); + + if (max_ampdu_length) { + printf("\t\tMaximum RX AMPDU length %d bytes (exponent: 0x0%02x)\n", + max_ampdu_length, exponent); + } else { + printf("\t\tMaximum RX AMPDU length: unrecognized bytes " + "(exponent: %d)\n", exponent); + } +} + +void print_ampdu_spacing(__u8 spacing) +{ + printf("\t\tMinimum RX AMPDU time spacing: %s (0x%02x)\n", + print_ampdu_space(spacing), spacing); +} + +void print_ht_capability(__u16 cap) +{ +#define PRINT_HT_CAP(_cond, _str) \ + do { \ + if (_cond) \ + printf("\t\t\t" _str "\n"); \ + } while (0) + + printf("\t\tCapabilities: 0x%02x\n", cap); + + PRINT_HT_CAP((cap & BIT(0)), "RX LDPC"); + PRINT_HT_CAP((cap & BIT(1)), "HT20/HT40"); + PRINT_HT_CAP(!(cap & BIT(1)), "HT20"); + + PRINT_HT_CAP(((cap >> 2) & 0x3) == 0, "Static SM Power Save"); + PRINT_HT_CAP(((cap >> 2) & 0x3) == 1, "Dynamic SM Power Save"); + PRINT_HT_CAP(((cap >> 2) & 0x3) == 3, "SM Power Save disabled"); + + PRINT_HT_CAP((cap & BIT(4)), "RX Greenfield"); + PRINT_HT_CAP((cap & BIT(5)), "RX HT20 SGI"); + PRINT_HT_CAP((cap & BIT(6)), "RX HT40 SGI"); + PRINT_HT_CAP((cap & BIT(7)), "TX STBC"); + + PRINT_HT_CAP(((cap >> 8) & 0x3) == 0, "No RX STBC"); + PRINT_HT_CAP(((cap >> 8) & 0x3) == 1, "RX STBC 1-stream"); + PRINT_HT_CAP(((cap >> 8) & 0x3) == 2, "RX STBC 2-streams"); + PRINT_HT_CAP(((cap >> 8) & 0x3) == 3, "RX STBC 3-streams"); + + PRINT_HT_CAP((cap & BIT(10)), "HT Delayed Block Ack"); + + PRINT_HT_CAP(!(cap & BIT(11)), "Max AMSDU length: 3839 bytes"); + PRINT_HT_CAP((cap & BIT(11)), "Max AMSDU length: 7935 bytes"); + + /* + * For beacons and probe response this would mean the BSS + * does or does not allow the usage of DSSS/CCK HT40. + * Otherwise it means the STA does or does not use + * DSSS/CCK HT40. + */ + PRINT_HT_CAP((cap & BIT(12)), "DSSS/CCK HT40"); + PRINT_HT_CAP(!(cap & BIT(12)), "No DSSS/CCK HT40"); + + /* BIT(13) is reserved */ + + PRINT_HT_CAP((cap & BIT(14)), "40 MHz Intolerant"); + + PRINT_HT_CAP((cap & BIT(15)), "L-SIG TXOP protection"); +#undef PRINT_HT_CAP +} + +void print_ht_mcs(const __u8 *mcs) +{ + /* As defined in 7.3.2.57.4 Supported MCS Set field */ + unsigned int tx_max_num_spatial_streams, max_rx_supp_data_rate; + bool tx_mcs_set_defined, tx_mcs_set_equal, tx_unequal_modulation; + + max_rx_supp_data_rate = ((mcs[10] >> 8) & ((mcs[11] & 0x3) << 8)); + tx_mcs_set_defined = !!(mcs[12] & (1 << 0)); + tx_mcs_set_equal = !(mcs[12] & (1 << 1)); + tx_max_num_spatial_streams = ((mcs[12] >> 2) & 3) + 1; + tx_unequal_modulation = !!(mcs[12] & (1 << 4)); + + if (max_rx_supp_data_rate) + printf("\t\tHT Max RX data rate: %d Mbps\n", max_rx_supp_data_rate); + /* XXX: else see 9.6.0e.5.3 how to get this I think */ + + if (tx_mcs_set_defined) { + if (tx_mcs_set_equal) { + printf("\t\tHT TX/RX MCS rate indexes supported:"); + print_mcs_index(mcs); + } else { + printf("\t\tHT RX MCS rate indexes supported:"); + print_mcs_index(mcs); + + if (tx_unequal_modulation) + printf("\t\tTX unequal modulation supported\n"); + else + printf("\t\tTX unequal modulation not supported\n"); + + printf("\t\tHT TX Max spatial streams: %d\n", + tx_max_num_spatial_streams); + + printf("\t\tHT TX MCS rate indexes supported may differ\n"); + } + } else { + printf("\t\tHT RX MCS rate indexes supported:"); + print_mcs_index(mcs); + printf("\t\tHT TX MCS rate indexes are undefined\n"); + } +} + +void print_vht_info(__u32 capa, const __u8 *mcs) +{ + __u16 tmp; + int i; + + printf("\t\tVHT Capabilities (0x%.8x):\n", capa); + +#define PRINT_VHT_CAPA(_bit, _str) \ + do { \ + if (capa & BIT(_bit)) \ + printf("\t\t\t" _str "\n"); \ + } while (0) + + printf("\t\t\tMax MPDU length: "); + switch (capa & 3) { + case 0: printf("3895\n"); break; + case 1: printf("7991\n"); break; + case 2: printf("11454\n"); break; + case 3: printf("(reserved)\n"); + } + printf("\t\t\tSupported Channel Width: "); + switch ((capa >> 2) & 3) { + case 0: printf("neither 160 nor 80+80\n"); break; + case 1: printf("160 MHz\n"); break; + case 2: printf("160 MHz, 80+80 MHz\n"); break; + case 3: printf("(reserved)\n"); + } + PRINT_VHT_CAPA(4, "RX LDPC"); + PRINT_VHT_CAPA(5, "short GI (80 MHz)"); + PRINT_VHT_CAPA(6, "short GI (160/80+80 MHz)"); + PRINT_VHT_CAPA(7, "TX STBC"); + /* RX STBC */ + PRINT_VHT_CAPA(11, "SU Beamformer"); + PRINT_VHT_CAPA(12, "SU Beamformee"); + /* compressed steering */ + /* # of sounding dimensions */ + PRINT_VHT_CAPA(19, "MU Beamformer"); + PRINT_VHT_CAPA(20, "MU Beamformee"); + PRINT_VHT_CAPA(21, "VHT TXOP PS"); + PRINT_VHT_CAPA(22, "+HTC-VHT"); + /* max A-MPDU */ + /* VHT link adaptation */ + PRINT_VHT_CAPA(29, "RX antenna pattern consistency"); + PRINT_VHT_CAPA(30, "TX antenna pattern consistency"); + + printf("\t\tVHT RX MCS set:\n"); + tmp = mcs[0] | (mcs[1] << 8); + for (i = 1; i <= 8; i++) { + printf("\t\t\t%d streams: ", i); + switch ((tmp >> ((i-1)*2) ) & 3) { + case 0: printf("MCS 0-7\n"); break; + case 1: printf("MCS 0-8\n"); break; + case 2: printf("MCS 0-9\n"); break; + case 3: printf("not supported\n"); break; + } + } + tmp = mcs[2] | (mcs[3] << 8); + printf("\t\tVHT RX highest supported: %d Mbps\n", tmp & 0x1fff); + + printf("\t\tVHT TX MCS set:\n"); + tmp = mcs[4] | (mcs[5] << 8); + for (i = 1; i <= 8; i++) { + printf("\t\t\t%d streams: ", i); + switch ((tmp >> ((i-1)*2) ) & 3) { + case 0: printf("MCS 0-7\n"); break; + case 1: printf("MCS 0-8\n"); break; + case 2: printf("MCS 0-9\n"); break; + case 3: printf("not supported\n"); break; + } + } + tmp = mcs[6] | (mcs[7] << 8); + printf("\t\tVHT TX highest supported: %d Mbps\n", tmp & 0x1fff); +}
diff --git a/iw_3.10/iw_3.10/version.sh b/iw_3.10/iw_3.10/version.sh new file mode 100755 index 0000000..4d955cb --- /dev/null +++ b/iw_3.10/iw_3.10/version.sh
@@ -0,0 +1,20 @@ +#!/bin/sh + +VERSION="3.10" + +SUFFIX= +if test "x$1" = x--suffix; then + shift + SUFFIX="-$1" + shift +fi +OUT="$1" + +if test "x$SUFFIX" != 'x'; then + v="$VERSION$SUFFIX" +else + v="$VERSION" +fi + +echo '#include "iw.h"' > "$OUT" +echo "const char iw_version[] = \"$v\";" >> "$OUT"
diff --git a/iw_3.10/iw_3.10/wowlan.c b/iw_3.10/iw_3.10/wowlan.c new file mode 100644 index 0000000..b4a2715 --- /dev/null +++ b/iw_3.10/iw_3.10/wowlan.c
@@ -0,0 +1,409 @@ +#include <net/if.h> +#include <errno.h> +#include <string.h> +#include <stdio.h> + +#include <netlink/genl/genl.h> +#include <netlink/genl/family.h> +#include <netlink/genl/ctrl.h> +#include <netlink/msg.h> +#include <netlink/attr.h> + +#include <arpa/inet.h> + +#include "nl80211.h" +#include "iw.h" + +SECTION(wowlan); + +static int wowlan_parse_tcp_file(struct nl_msg *msg, const char *fn) +{ + char buf[16768]; + int err = 1; + FILE *f = fopen(fn, "r"); + struct nlattr *tcp; + + if (!f) + return 1; + tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION); + if (!tcp) + goto nla_put_failure; + + while (!feof(f)) { + char *eol; + + if (!fgets(buf, sizeof(buf), f)) + break; + + eol = strchr(buf + 5, '\r'); + if (eol) + *eol = 0; + eol = strchr(buf + 5, '\n'); + if (eol) + *eol = 0; + + if (strncmp(buf, "source=", 7) == 0) { + struct in_addr in_addr; + char *addr = buf + 7; + char *port = strchr(buf + 7, ':'); + + if (port) { + *port = 0; + port++; + } + if (inet_aton(addr, &in_addr) == 0) + goto close; + NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_SRC_IPV4, + in_addr.s_addr); + if (port) + NLA_PUT_U16(msg, NL80211_WOWLAN_TCP_SRC_PORT, + atoi(port)); + } else if (strncmp(buf, "dest=", 5) == 0) { + struct in_addr in_addr; + char *addr = buf + 5; + char *port = strchr(buf + 5, ':'); + char *mac; + unsigned char macbuf[6]; + + if (!port) + goto close; + *port = 0; + port++; + mac = strchr(port, '@'); + if (!mac) + goto close; + *mac = 0; + mac++; + if (inet_aton(addr, &in_addr) == 0) + goto close; + NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_DST_IPV4, + in_addr.s_addr); + NLA_PUT_U16(msg, NL80211_WOWLAN_TCP_DST_PORT, + atoi(port)); + if (mac_addr_a2n(macbuf, mac)) + goto close; + NLA_PUT(msg, NL80211_WOWLAN_TCP_DST_MAC, + 6, macbuf); + } else if (strncmp(buf, "data=", 5) == 0) { + size_t len; + unsigned char *pkt = parse_hex(buf + 5, &len); + + if (!pkt) + goto close; + NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD, len, pkt); + free(pkt); + } else if (strncmp(buf, "data.interval=", 14) == 0) { + NLA_PUT_U32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL, + atoi(buf + 14)); + } else if (strncmp(buf, "wake=", 5) == 0) { + unsigned char *pat, *mask; + size_t patlen; + + if (parse_hex_mask(buf + 5, &pat, &patlen, &mask)) + goto close; + NLA_PUT(msg, NL80211_WOWLAN_TCP_WAKE_MASK, + DIV_ROUND_UP(patlen, 8), mask); + NLA_PUT(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD, + patlen, pat); + free(mask); + free(pat); + } else if (strncmp(buf, "data.seq=", 9) == 0) { + struct nl80211_wowlan_tcp_data_seq seq = {}; + char *len, *offs, *start; + + len = buf + 9; + offs = strchr(len, ','); + if (!offs) + goto close; + *offs = 0; + offs++; + start = strchr(offs, ','); + if (start) { + *start = 0; + start++; + seq.start = atoi(start); + } + seq.len = atoi(len); + seq.offset = atoi(offs); + + NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ, + sizeof(seq), &seq); + } else if (strncmp(buf, "data.tok=", 9) == 0) { + struct nl80211_wowlan_tcp_data_token *tok; + size_t stream_len; + char *len, *offs, *toks; + unsigned char *stream; + + len = buf + 9; + offs = strchr(len, ','); + if (!offs) + goto close; + *offs = 0; + offs++; + toks = strchr(offs, ','); + if (!toks) + goto close; + *toks = 0; + toks++; + + stream = parse_hex(toks, &stream_len); + if (!stream) + goto close; + tok = malloc(sizeof(*tok) + stream_len); + if (!tok) { + free(stream); + err = -ENOMEM; + goto close; + } + + tok->len = atoi(len); + tok->offset = atoi(offs); + memcpy(tok->token_stream, stream, stream_len); + + NLA_PUT(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, + sizeof(*tok) + stream_len, tok); + free(stream); + free(tok); + } else { + if (buf[0] == '#') + continue; + goto close; + } + } + + err = 0; + goto close; + nla_put_failure: + err = -ENOBUFS; + close: + fclose(f); + nla_nest_end(msg, tcp); + return err; +} + +static int handle_wowlan_enable(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + struct nlattr *wowlan, *pattern; + struct nl_msg *patterns = NULL; + enum { + PS_REG, + PS_PAT, + } parse_state = PS_REG; + int err = -ENOBUFS; + unsigned char *pat, *mask; + size_t patlen; + int patnum = 0, pkt_offset; + char *eptr, *value1, *value2, *sptr = NULL; + + wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); + if (!wowlan) + return -ENOBUFS; + + while (argc) { + switch (parse_state) { + case PS_REG: + if (strcmp(argv[0], "any") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_ANY); + else if (strcmp(argv[0], "disconnect") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); + else if (strcmp(argv[0], "magic-packet") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); + else if (strcmp(argv[0], "gtk-rekey-failure") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); + else if (strcmp(argv[0], "eap-identity-request") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); + else if (strcmp(argv[0], "4way-handshake") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); + else if (strcmp(argv[0], "rfkill-release") == 0) + NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); + else if (strcmp(argv[0], "tcp") == 0) { + argv++; + argc--; + if (!argc) { + err = 1; + goto nla_put_failure; + } + err = wowlan_parse_tcp_file(msg, argv[0]); + if (err) + goto nla_put_failure; + } else if (strcmp(argv[0], "patterns") == 0) { + parse_state = PS_PAT; + patterns = nlmsg_alloc(); + if (!patterns) { + err = -ENOMEM; + goto nla_put_failure; + } + } else { + err = 1; + goto nla_put_failure; + } + break; + case PS_PAT: + value1 = strtok_r(argv[0], "+", &sptr); + value2 = strtok_r(NULL, "+", &sptr); + + if (!value2) { + pkt_offset = 0; + value2 = value1; + } else { + pkt_offset = strtoul(value1, &eptr, 10); + if (eptr != value1 + strlen(value1)) { + err = 1; + goto nla_put_failure; + } + } + + if (parse_hex_mask(value2, &pat, &patlen, &mask)) { + err = 1; + goto nla_put_failure; + } + + pattern = nla_nest_start(patterns, ++patnum); + NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_MASK, + DIV_ROUND_UP(patlen, 8), mask); + NLA_PUT(patterns, NL80211_WOWLAN_PKTPAT_PATTERN, + patlen, pat); + NLA_PUT_U32(patterns, NL80211_WOWLAN_PKTPAT_OFFSET, pkt_offset); + nla_nest_end(patterns, pattern); + free(mask); + free(pat); + break; + } + argv++; + argc--; + } + + if (patterns) + nla_put_nested(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, + patterns); + + nla_nest_end(msg, wowlan); + err = 0; + nla_put_failure: + nlmsg_free(patterns); + return err; +} +COMMAND(wowlan, enable, "[any] [disconnect] [magic-packet] [gtk-rekey-failure] [eap-identity-request]" + " [4way-handshake] [rfkill-release] [tcp <config-file>] [patterns [offset1+]<pattern1> ...]", + NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_enable, + "Enable WoWLAN with the given triggers.\n" + "Each pattern is given as a bytestring with '-' in places where any byte\n" + "may be present, e.g. 00:11:22:-:44 will match 00:11:22:33:44 and\n" + "00:11:22:33:ff:44 etc.\n" + "Offset and pattern should be separated by '+', e.g. 18+43:34:00:12 will match " + "'43:34:00:12' after 18 bytes of offset in Rx packet.\n\n" + "The TCP configuration file contains:\n" + " source=ip[:port]\n" + " dest=ip:port@mac\n" + " data=<hex data packet>\n" + " data.interval=seconds\n" + " [wake=<hex packet with masked out bytes indicated by '-'>]\n" + " [data.seq=len,offset[,start]]\n" + " [data.tok=len,offset,<token stream>]"); + + +static int handle_wowlan_disable(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + /* just a set w/o wowlan attribute */ + return 0; +} +COMMAND(wowlan, disable, "", NL80211_CMD_SET_WOWLAN, 0, CIB_PHY, handle_wowlan_disable, + "Disable WoWLAN."); + + +static int print_wowlan_handler(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[NL80211_ATTR_MAX + 1]; + struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG]; + struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); + struct nlattr *pattern; + int rem_pattern; + + nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), + genlmsg_attrlen(gnlh, 0), NULL); + + if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { + printf("WoWLAN is disabled.\n"); + return NL_SKIP; + } + + /* XXX: use policy */ + nla_parse(trig, MAX_NL80211_WOWLAN_TRIG, + nla_data(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + nla_len(attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), + NULL); + + printf("WoWLAN is enabled:\n"); + if (trig[NL80211_WOWLAN_TRIG_ANY]) + printf(" * wake up on special any trigger\n"); + if (trig[NL80211_WOWLAN_TRIG_DISCONNECT]) + printf(" * wake up on disconnect\n"); + if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT]) + printf(" * wake up on magic packet\n"); + if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) + printf(" * wake up on GTK rekeying failure\n"); + if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) + printf(" * wake up on EAP identity request\n"); + if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) + printf(" * wake up on 4-way handshake\n"); + if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) + printf(" * wake up on RF-kill release\n"); + if (trig[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { + nla_for_each_nested(pattern, + trig[NL80211_WOWLAN_TRIG_PKT_PATTERN], + rem_pattern) { + struct nlattr *patattr[NUM_NL80211_WOWLAN_PKTPAT]; + int i, patlen, masklen, pkt_offset; + uint8_t *mask, *pat; + nla_parse(patattr, MAX_NL80211_WOWLAN_PKTPAT, + nla_data(pattern), nla_len(pattern), + NULL); + if (!patattr[NL80211_WOWLAN_PKTPAT_MASK] || + !patattr[NL80211_WOWLAN_PKTPAT_PATTERN] || + !patattr[NL80211_WOWLAN_PKTPAT_OFFSET]) { + printf(" * (invalid pattern specification)\n"); + continue; + } + masklen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_MASK]); + patlen = nla_len(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]); + pkt_offset = nla_get_u32(patattr[NL80211_WOWLAN_PKTPAT_OFFSET]); + if (DIV_ROUND_UP(patlen, 8) != masklen) { + printf(" * (invalid pattern specification)\n"); + continue; + } + printf(" * wake up on packet offset: %d", pkt_offset); + printf(" pattern: "); + pat = nla_data(patattr[NL80211_WOWLAN_PKTPAT_PATTERN]); + mask = nla_data(patattr[NL80211_WOWLAN_PKTPAT_MASK]); + for (i = 0; i < patlen; i++) { + if (mask[i / 8] & (1 << (i % 8))) + printf("%.2x", pat[i]); + else + printf("--"); + if (i != patlen - 1) + printf(":"); + } + printf("\n"); + } + } + if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) + printf(" * wake up on TCP connection\n"); + + return NL_SKIP; +} + +static int handle_wowlan_show(struct nl80211_state *state, struct nl_cb *cb, + struct nl_msg *msg, int argc, char **argv, + enum id_input id) +{ + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, + print_wowlan_handler, NULL); + + return 0; +} +COMMAND(wowlan, show, "", NL80211_CMD_GET_WOWLAN, 0, CIB_PHY, handle_wowlan_show, + "Show WoWLAN status.");