1153317Ssam/*- 2174244Ssam * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting 3153317Ssam * All rights reserved. 4153317Ssam * 5153317Ssam * Redistribution and use in source and binary forms, with or without 6153317Ssam * modification, are permitted provided that the following conditions 7153317Ssam * are met: 8153317Ssam * 1. Redistributions of source code must retain the above copyright 9153317Ssam * notice, this list of conditions and the following disclaimer, 10153317Ssam * without modification. 11153317Ssam * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12153317Ssam * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13153317Ssam * redistribution must be conditioned upon including a substantially 14153317Ssam * similar Disclaimer requirement for further binary redistribution. 15153317Ssam * 16153317Ssam * NO WARRANTY 17153317Ssam * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18153317Ssam * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19153317Ssam * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20153317Ssam * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21153317Ssam * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22153317Ssam * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23153317Ssam * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24153317Ssam * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25153317Ssam * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26153317Ssam * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27153317Ssam * THE POSSIBILITY OF SUCH DAMAGES. 28153317Ssam * 29153317Ssam * $FreeBSD$ 30153317Ssam */ 31153317Ssam 32153317Ssam/* 33161200Ssam * net80211 statistics class. 34153317Ssam */ 35153317Ssam#include <sys/types.h> 36153317Ssam#include <sys/file.h> 37153317Ssam#include <sys/sockio.h> 38153317Ssam#include <sys/socket.h> 39153317Ssam#include <net/if.h> 40161200Ssam#include <net/if_dl.h> 41153317Ssam#include <net/if_media.h> 42153317Ssam#include <net/if_var.h> 43153317Ssam#include <net/ethernet.h> 44153317Ssam 45153317Ssam#include <stdio.h> 46170535Ssam#include <stdlib.h> 47153317Ssam#include <signal.h> 48161200Ssam#include <string.h> 49153317Ssam#include <unistd.h> 50153317Ssam#include <err.h> 51161200Ssam#include <ifaddrs.h> 52153317Ssam 53153392Ssam#include "../../../../sys/net80211/ieee80211_ioctl.h" 54153317Ssam 55161200Ssam#include "wlanstats.h" 56153317Ssam 57161200Ssam#ifndef IEEE80211_ADDR_COPY 58161200Ssam#define IEEE80211_ADDR_COPY(dst, src) memcpy(dst, src, IEEE80211_ADDR_LEN) 59161200Ssam#define IEEE80211_ADDR_EQ(a1,a2) (memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0) 60161200Ssam#endif 61161200Ssam 62173306Ssam#define AFTER(prev) ((prev)+1) 63173306Ssam 64161200Ssamstatic const struct fmt wlanstats[] = { 65173306Ssam#define S_RX_BADVERSION 0 66173306Ssam { 5, "rx_badversion", "bvers", "rx frame with bad version" }, 67173306Ssam#define S_RX_TOOSHORT AFTER(S_RX_BADVERSION) 68173306Ssam { 5, "rx_tooshort", "2short", "rx frame too short" }, 69173306Ssam#define S_RX_WRONGBSS AFTER(S_RX_TOOSHORT) 70173306Ssam { 5, "rx_wrongbss", "wrbss", "rx from wrong bssid" }, 71173306Ssam#define S_RX_DUP AFTER(S_RX_WRONGBSS) 72173306Ssam { 5, "rx_dup", "rxdup", "rx discard 'cuz dup" }, 73173306Ssam#define S_RX_WRONGDIR AFTER(S_RX_DUP) 74173306Ssam { 5, "rx_wrongdir", "wrdir", "rx w/ wrong direction" }, 75173306Ssam#define S_RX_MCASTECHO AFTER(S_RX_WRONGDIR) 76173306Ssam { 5, "rx_mcastecho", "mecho", "rx discard 'cuz mcast echo" }, 77173306Ssam#define S_RX_NOTASSOC AFTER(S_RX_MCASTECHO) 78173306Ssam { 6, "rx_notassoc", "!assoc", "rx discard 'cuz sta !assoc" }, 79173306Ssam#define S_RX_NOPRIVACY AFTER(S_RX_NOTASSOC) 80173306Ssam { 6, "rx_noprivacy", "nopriv", "rx w/ wep but privacy off" }, 81173306Ssam#define S_RX_UNENCRYPTED AFTER(S_RX_NOPRIVACY) 82173306Ssam { 6, "rx_unencrypted", "unencr", "rx w/o wep and privacy on" }, 83173306Ssam#define S_RX_WEPFAIL AFTER(S_RX_UNENCRYPTED) 84173306Ssam { 7, "rx_wepfail", "wepfail", "rx wep processing failed" }, 85173306Ssam#define S_RX_DECAP AFTER(S_RX_WEPFAIL) 86161200Ssam { 5, "rx_decap", "decap", "rx decapsulation failed" }, 87173306Ssam#define S_RX_MGTDISCARD AFTER(S_RX_DECAP) 88173306Ssam { 8, "rx_mgtdiscard", "mgtdiscard", "rx discard mgt frames" }, 89173306Ssam#define S_RX_CTL AFTER(S_RX_MGTDISCARD) 90170535Ssam { 5, "rx_ctl", "ctl", "rx ctrl frames" }, 91173306Ssam#define S_RX_BEACON AFTER(S_RX_CTL) 92173306Ssam { 6, "rx_beacon", "beacon", "rx beacon frames" }, 93173306Ssam#define S_RX_RSTOOBIG AFTER(S_RX_BEACON) 94173306Ssam { 6, "rx_rstoobig", "rs2big", "rx rate set truncated" }, 95173306Ssam#define S_RX_ELEM_MISSING AFTER(S_RX_RSTOOBIG) 96173306Ssam { 6, "rx_elem_missing","iemiss", "rx required element missing" }, 97173306Ssam#define S_RX_ELEM_TOOBIG AFTER(S_RX_ELEM_MISSING) 98173306Ssam { 6, "rx_elem_toobig", "ie2big", "rx element too big" }, 99173306Ssam#define S_RX_ELEM_TOOSMALL AFTER(S_RX_ELEM_TOOBIG) 100173306Ssam { 7, "rx_elem_toosmall","ie2small","rx element too small" }, 101173306Ssam#define S_RX_ELEM_UNKNOWN AFTER(S_RX_ELEM_TOOSMALL) 102173306Ssam { 5, "rx_elem_unknown","ieunk", "rx element unknown" }, 103173306Ssam#define S_RX_BADCHAN AFTER(S_RX_ELEM_UNKNOWN) 104173306Ssam { 6, "rx_badchan", "badchan", "rx frame w/ invalid chan" }, 105173306Ssam#define S_RX_CHANMISMATCH AFTER(S_RX_BADCHAN) 106161200Ssam { 5, "rx_chanmismatch","chanmismatch", "rx frame chan mismatch" }, 107173306Ssam#define S_RX_NODEALLOC AFTER(S_RX_CHANMISMATCH) 108161200Ssam { 5, "rx_nodealloc", "nodealloc", "nodes allocated (rx)" }, 109173306Ssam#define S_RX_SSIDMISMATCH AFTER(S_RX_NODEALLOC) 110161200Ssam { 5, "rx_ssidmismatch","ssidmismatch", "rx frame ssid mismatch" }, 111173306Ssam#define S_RX_AUTH_UNSUPPORTED AFTER(S_RX_SSIDMISMATCH) 112161200Ssam { 5, "rx_auth_unsupported","auth_unsupported", 113161200Ssam "rx w/ unsupported auth alg" }, 114173306Ssam#define S_RX_AUTH_FAIL AFTER(S_RX_AUTH_UNSUPPORTED) 115161200Ssam { 5, "rx_auth_fail", "auth_fail", "rx sta auth failure" }, 116178359Ssam#define S_RX_AUTH_FAIL_CODE AFTER(S_RX_AUTH_FAIL) 117178359Ssam { 5, "rx_auth_fail_code","auth_fail_code", 118178359Ssam "last rx auth failure reason" }, 119178359Ssam#define S_RX_AUTH_COUNTERMEASURES AFTER(S_RX_AUTH_FAIL_CODE) 120161200Ssam { 5, "rx_auth_countermeasures", "auth_countermeasures", 121161200Ssam "rx sta auth failure 'cuz of TKIP countermeasures" }, 122173306Ssam#define S_RX_ASSOC_BSS AFTER(S_RX_AUTH_COUNTERMEASURES) 123161200Ssam { 5, "rx_assoc_bss", "assoc_bss", "rx assoc from wrong bssid" }, 124173306Ssam#define S_RX_ASSOC_NOTAUTH AFTER(S_RX_ASSOC_BSS) 125161200Ssam { 5, "rx_assoc_notauth","assoc_notauth", "rx assoc w/o auth" }, 126173306Ssam#define S_RX_ASSOC_CAPMISMATCH AFTER(S_RX_ASSOC_NOTAUTH) 127161200Ssam { 5, "rx_assoc_capmismatch","assoc_capmismatch", 128161200Ssam "rx assoc w/ cap mismatch" }, 129173306Ssam#define S_RX_ASSOC_NORATE AFTER(S_RX_ASSOC_CAPMISMATCH) 130161200Ssam { 5, "rx_assoc_norate","assoc_norate", "rx assoc w/ no rate match" }, 131173306Ssam#define S_RX_ASSOC_BADWPAIE AFTER(S_RX_ASSOC_NORATE) 132161200Ssam { 5, "rx_assoc_badwpaie","assoc_badwpaie", 133161200Ssam "rx assoc w/ bad WPA IE" }, 134173306Ssam#define S_RX_DEAUTH AFTER(S_RX_ASSOC_BADWPAIE) 135161200Ssam { 5, "rx_deauth", "deauth", "rx deauthentication" }, 136178359Ssam#define S_RX_DEAUTH_CODE AFTER(S_RX_DEAUTH) 137178359Ssam { 5, "rx_deauth_code","deauth_code", "last rx deauth reason" }, 138178359Ssam#define S_RX_DISASSOC AFTER(S_RX_DEAUTH_CODE) 139161200Ssam { 5, "rx_disassoc", "disassoc", "rx disassociation" }, 140178359Ssam#define S_RX_DISASSOC_CODE AFTER(S_RX_DISASSOC) 141178359Ssam { 5, "rx_disassoc_code","disassoc_code", 142178359Ssam "last rx disassoc reason" }, 143178359Ssam#define S_BMISS AFTER(S_RX_DISASSOC_CODE) 144178359Ssam { 5, "bmiss", "bmiss", "beacon miss events handled" }, 145178359Ssam#define S_RX_BADSUBTYPE AFTER(S_BMISS) 146161200Ssam { 5, "rx_badsubtype", "badsubtype", "rx frame w/ unknown subtype" }, 147173306Ssam#define S_RX_NOBUF AFTER(S_RX_BADSUBTYPE) 148161200Ssam { 5, "rx_nobuf", "nobuf", "rx failed for lack of mbuf" }, 149173306Ssam#define S_RX_DECRYPTCRC AFTER(S_RX_NOBUF) 150161200Ssam { 5, "rx_decryptcrc", "decryptcrc", "rx decrypt failed on crc" }, 151173306Ssam#define S_RX_AHDEMO_MGT AFTER(S_RX_DECRYPTCRC) 152161200Ssam { 5, "rx_ahdemo_mgt", "ahdemo_mgt", 153161200Ssam "rx discard mgmt frame received in ahdoc demo mode" }, 154173306Ssam#define S_RX_BAD_AUTH AFTER(S_RX_AHDEMO_MGT) 155161200Ssam { 5, "rx_bad_auth", "bad_auth", "rx bad authentication request" }, 156173306Ssam#define S_RX_UNAUTH AFTER(S_RX_BAD_AUTH) 157161200Ssam { 5, "rx_unauth", "unauth", 158161200Ssam "rx discard 'cuz port unauthorized" }, 159173306Ssam#define S_RX_BADKEYID AFTER(S_RX_UNAUTH) 160178699Ssam { 5, "rx_badkeyid", "rxkid", "rx w/ incorrect keyid" }, 161173306Ssam#define S_RX_CCMPREPLAY AFTER(S_RX_BADKEYID) 162161200Ssam { 5, "rx_ccmpreplay", "ccmpreplay", "rx seq# violation (CCMP)" }, 163173306Ssam#define S_RX_CCMPFORMAT AFTER(S_RX_CCMPREPLAY) 164161200Ssam { 5, "rx_ccmpformat", "ccmpformat", "rx format bad (CCMP)" }, 165173306Ssam#define S_RX_CCMPMIC AFTER(S_RX_CCMPFORMAT) 166161200Ssam { 5, "rx_ccmpmic", "ccmpmic", "rx MIC check failed (CCMP)" }, 167173306Ssam#define S_RX_TKIPREPLAY AFTER(S_RX_CCMPMIC) 168161200Ssam { 5, "rx_tkipreplay", "tkipreplay", "rx seq# violation (TKIP)" }, 169173306Ssam#define S_RX_TKIPFORMAT AFTER(S_RX_TKIPREPLAY) 170161200Ssam { 5, "rx_tkipformat", "tkipformat", "rx format bad (TKIP)" }, 171173306Ssam#define S_RX_TKIPMIC AFTER(S_RX_TKIPFORMAT) 172161200Ssam { 5, "rx_tkipmic", "tkipmic", "rx MIC check failed (TKIP)" }, 173173306Ssam#define S_RX_TKIPICV AFTER(S_RX_TKIPMIC) 174161200Ssam { 5, "rx_tkipicv", "tkipicv", "rx ICV check failed (TKIP)" }, 175173306Ssam#define S_RX_BADCIPHER AFTER(S_RX_TKIPICV) 176161200Ssam { 5, "rx_badcipher", "badcipher", "rx failed 'cuz bad cipher/key type" }, 177173306Ssam#define S_RX_NOCIPHERCTX AFTER(S_RX_BADCIPHER) 178161200Ssam { 5, "rx_nocipherctx", "nocipherctx", "rx failed 'cuz key/cipher ctx not setup" }, 179173306Ssam#define S_RX_ACL AFTER(S_RX_NOCIPHERCTX) 180161200Ssam { 5, "rx_acl", "acl", "rx discard 'cuz acl policy" }, 181173306Ssam#define S_TX_NOBUF AFTER(S_RX_ACL) 182161200Ssam { 5, "tx_nobuf", "nobuf", "tx failed for lack of mbuf" }, 183173306Ssam#define S_TX_NONODE AFTER(S_TX_NOBUF) 184161200Ssam { 5, "tx_nonode", "nonode", "tx failed for no node" }, 185173306Ssam#define S_TX_UNKNOWNMGT AFTER(S_TX_NONODE) 186161200Ssam { 5, "tx_unknownmgt", "unknownmgt", "tx of unknown mgt frame" }, 187173306Ssam#define S_TX_BADCIPHER AFTER(S_TX_UNKNOWNMGT) 188161200Ssam { 5, "tx_badcipher", "badcipher", "tx failed 'cuz bad ciper/key type" }, 189173306Ssam#define S_TX_NODEFKEY AFTER(S_TX_BADCIPHER) 190161200Ssam { 5, "tx_nodefkey", "nodefkey", "tx failed 'cuz no defkey" }, 191173306Ssam#define S_TX_NOHEADROOM AFTER(S_TX_NODEFKEY) 192161200Ssam { 5, "tx_noheadroom", "noheadroom", "tx failed 'cuz no space for crypto hdrs" }, 193173306Ssam#define S_TX_FRAGFRAMES AFTER(S_TX_NOHEADROOM) 194161200Ssam { 5, "tx_fragframes", "fragframes", "tx frames fragmented" }, 195173306Ssam#define S_TX_FRAGS AFTER(S_TX_FRAGFRAMES) 196161200Ssam { 5, "tx_frags", "frags", "tx frags generated" }, 197173306Ssam#define S_SCAN_ACTIVE AFTER(S_TX_FRAGS) 198178699Ssam { 5, "scan_active", "ascan", "active scans started" }, 199173306Ssam#define S_SCAN_PASSIVE AFTER(S_SCAN_ACTIVE) 200178699Ssam { 5, "scan_passive", "pscan", "passive scans started" }, 201178359Ssam#define S_SCAN_BG AFTER(S_SCAN_PASSIVE) 202178699Ssam { 5, "scan_bg", "bgscn", "background scans started" }, 203178359Ssam#define S_NODE_TIMEOUT AFTER(S_SCAN_BG) 204173306Ssam { 5, "node_timeout", "node_timeout", "nodes timed out for inactivity" }, 205173306Ssam#define S_CRYPTO_NOMEM AFTER(S_NODE_TIMEOUT) 206161200Ssam { 5, "crypto_nomem", "crypto_nomem", "cipher context malloc failed" }, 207173306Ssam#define S_CRYPTO_TKIP AFTER(S_CRYPTO_NOMEM) 208161200Ssam { 5, "crypto_tkip", "crypto_tkip", "tkip crypto done in s/w" }, 209173306Ssam#define S_CRYPTO_TKIPENMIC AFTER(S_CRYPTO_TKIP) 210161200Ssam { 5, "crypto_tkipenmic","crypto_tkipenmic", "tkip tx MIC done in s/w" }, 211173306Ssam#define S_CRYPTO_TKIPDEMIC AFTER(S_CRYPTO_TKIPENMIC) 212161200Ssam { 5, "crypto_tkipdemic","crypto_tkipdemic", "tkip rx MIC done in s/w" }, 213173306Ssam#define S_CRYPTO_TKIPCM AFTER(S_CRYPTO_TKIPDEMIC) 214161200Ssam { 5, "crypto_tkipcm", "crypto_tkipcm", "tkip dropped frames 'cuz of countermeasures" }, 215173306Ssam#define S_CRYPTO_CCMP AFTER(S_CRYPTO_TKIPCM) 216161200Ssam { 5, "crypto_ccmp", "crypto_ccmp", "ccmp crypto done in s/w" }, 217173306Ssam#define S_CRYPTO_WEP AFTER(S_CRYPTO_CCMP) 218161200Ssam { 5, "crypto_wep", "crypto_wep", "wep crypto done in s/w" }, 219173306Ssam#define S_CRYPTO_SETKEY_CIPHER AFTER(S_CRYPTO_WEP) 220161200Ssam { 5, "crypto_setkey_cipher", "crypto_setkey_cipher","setkey failed 'cuz cipher rejected data" }, 221173306Ssam#define S_CRYPTO_SETKEY_NOKEY AFTER(S_CRYPTO_SETKEY_CIPHER) 222161200Ssam { 5, "crypto_setkey_nokey", "crypto_setkey_nokey","setkey failed 'cuz no key index" }, 223173306Ssam#define S_CRYPTO_DELKEY AFTER(S_CRYPTO_SETKEY_NOKEY) 224161200Ssam { 5, "crypto_delkey", "crypto_delkey", "driver key delete failed" }, 225173306Ssam#define S_CRYPTO_BADCIPHER AFTER(S_CRYPTO_DELKEY) 226161200Ssam { 5, "crypto_badcipher","crypto_badcipher", "setkey failed 'cuz unknown cipher" }, 227173306Ssam#define S_CRYPTO_NOCIPHER AFTER(S_CRYPTO_BADCIPHER) 228161200Ssam { 5, "crypto_nocipher","crypto_nocipher", "setkey failed 'cuz cipher module unavailable" }, 229173306Ssam#define S_CRYPTO_ATTACHFAIL AFTER(S_CRYPTO_NOCIPHER) 230161200Ssam { 5, "crypto_attachfail","crypto_attachfail", "setkey failed 'cuz cipher attach failed" }, 231173306Ssam#define S_CRYPTO_SWFALLBACK AFTER(S_CRYPTO_ATTACHFAIL) 232161200Ssam { 5, "crypto_swfallback","crypto_swfallback", "crypto fell back to s/w implementation" }, 233173306Ssam#define S_CRYPTO_KEYFAIL AFTER(S_CRYPTO_SWFALLBACK) 234161200Ssam { 5, "crypto_keyfail", "crypto_keyfail", "setkey failed 'cuz driver key alloc failed" }, 235173306Ssam#define S_CRYPTO_ENMICFAIL AFTER(S_CRYPTO_KEYFAIL) 236161200Ssam { 5, "crypto_enmicfail","crypto_enmicfail", "enmic failed (may be mbuf exhaustion)" }, 237173306Ssam#define S_IBSS_CAPMISMATCH AFTER(S_CRYPTO_ENMICFAIL) 238161200Ssam { 5, "ibss_capmismatch","ibss_capmismatch", "ibss merge faied 'cuz capabilities mismatch" }, 239173306Ssam#define S_IBSS_NORATE AFTER(S_IBSS_CAPMISMATCH) 240161200Ssam { 5, "ibss_norate", "ibss_norate", "ibss merge faied 'cuz rate set mismatch" }, 241173306Ssam#define S_PS_UNASSOC AFTER(S_IBSS_NORATE) 242161200Ssam { 5, "ps_unassoc", "ps_unassoc", "ps-poll received for unassociated station" }, 243173306Ssam#define S_PS_BADAID AFTER(S_PS_UNASSOC) 244161200Ssam { 5, "ps_badaid", "ps_badaid", "ps-poll received with invalid association id" }, 245173306Ssam#define S_PS_QEMPTY AFTER(S_PS_BADAID) 246161200Ssam { 5, "ps_qempty", "ps_qempty", "ps-poll received with nothing to send" }, 247173306Ssam#define S_FF_BADHDR AFTER(S_PS_QEMPTY) 248161200Ssam { 5, "ff_badhdr", "ff_badhdr", "fast frame rx'd w/ bad hdr" }, 249173306Ssam#define S_FF_TOOSHORT AFTER(S_FF_BADHDR) 250161200Ssam { 5, "ff_tooshort", "ff_tooshort", "fast frame rx decap error" }, 251173306Ssam#define S_FF_SPLIT AFTER(S_FF_TOOSHORT) 252161200Ssam { 5, "ff_split", "ff_split", "fast frame rx split error" }, 253173306Ssam#define S_FF_DECAP AFTER(S_FF_SPLIT) 254161200Ssam { 5, "ff_decap", "ff_decap", "fast frames decap'd" }, 255173306Ssam#define S_FF_ENCAP AFTER(S_FF_DECAP) 256161200Ssam { 5, "ff_encap", "ff_encap", "fast frames encap'd for tx" }, 257173306Ssam#define S_FF_ENCAPFAIL AFTER(S_FF_ENCAP) 258161200Ssam { 5, "ff_encapfail", "ff_encapfail", "fast frames encap failed" }, 259173306Ssam#define S_RX_BADBINTVAL AFTER(S_FF_ENCAPFAIL) 260161200Ssam { 5, "rx_badbintval", "rx_badbintval","rx frame with bogus beacon interval" }, 261173306Ssam#define S_RX_MGMT AFTER(S_RX_BADBINTVAL) 262178699Ssam { 8, "rx_mgmt", "mgmt", "rx management frames" }, 263173306Ssam#define S_RX_DEMICFAIL AFTER(S_RX_MGMT) 264161200Ssam { 5, "rx_demicfail", "rx_demicfail", "rx demic failed" }, 265173306Ssam#define S_RX_DEFRAG AFTER(S_RX_DEMICFAIL) 266161200Ssam { 5, "rx_defrag", "rx_defrag", "rx defragmentation failed" }, 267173306Ssam#define S_RX_ACTION AFTER(S_RX_DEFRAG) 268170535Ssam { 5, "rx_action", "rx_action", "rx action frames" }, 269173306Ssam#define S_AMSDU_TOOSHORT AFTER(S_RX_ACTION) 270173306Ssam { 8, "amsdu_tooshort", "tooshort","A-MSDU rx decap error" }, 271173306Ssam#define S_AMSDU_SPLIT AFTER(S_AMSDU_TOOSHORT) 272173306Ssam { 8, "amsdu_split", "split", "A-MSDU rx failed on frame split" }, 273173306Ssam#define S_AMSDU_DECAP AFTER(S_AMSDU_SPLIT) 274173306Ssam { 8, "amsdu_decap", "decap", "A-MSDU frames received" }, 275173306Ssam#define S_AMSDU_ENCAP AFTER(S_AMSDU_DECAP) 276173306Ssam { 8, "amsdu_encap", "encap", "A-MSDU frames transmitted" }, 277173306Ssam#define S_AMPDU_REORDER AFTER(S_AMSDU_ENCAP) 278173306Ssam { 8, "ampdu_reorder", "reorder","A-MPDU frames held in reorder q" }, 279173306Ssam#define S_AMPDU_FLUSH AFTER(S_AMPDU_REORDER) 280173306Ssam { 8, "ampdu_flush", "flush", "A-MPDU frames sent up from reorder q" }, 281173306Ssam#define S_AMPDU_BARBAD AFTER(S_AMPDU_FLUSH) 282173306Ssam { 6, "ampdu_barbad", "barbad", "A-MPDU BAR rx before ADDBA exchange (or disabled with net.link.ieee80211)" }, 283173306Ssam#define S_AMPDU_BAROOW AFTER(S_AMPDU_BARBAD) 284173306Ssam { 6, "ampdu_baroow", "baroow", "A-MPDU BAR rx out of BA window" }, 285173306Ssam#define S_AMPDU_BARMOVE AFTER(S_AMPDU_BAROOW) 286173306Ssam { 8, "ampdu_barmove", "barmove","A-MPDU BAR rx moved BA window" }, 287173306Ssam#define S_AMPDU_BAR AFTER(S_AMPDU_BARMOVE) 288173306Ssam { 8, "ampdu_bar", "rxbar", "A-MPDU BAR rx successful" }, 289173306Ssam#define S_AMPDU_MOVE AFTER(S_AMPDU_BAR) 290173306Ssam { 5, "ampdu_move", "move", "A-MPDU frame moved BA window" }, 291173306Ssam#define S_AMPDU_OOR AFTER(S_AMPDU_MOVE) 292173306Ssam { 8, "ampdu_oor", "oorx", "A-MPDU frames rx out-of-order" }, 293173306Ssam#define S_AMPDU_COPY AFTER(S_AMPDU_OOR) 294173306Ssam { 8, "ampdu_copy", "copy", "A-MPDU rx window slots copied" }, 295173306Ssam#define S_AMPDU_DROP AFTER(S_AMPDU_COPY) 296173306Ssam { 5, "ampdu_drop", "drop", "A-MPDU frames discarded for out of range seqno" }, 297173306Ssam#define S_AMPDU_AGE AFTER(S_AMPDU_DROP) 298173306Ssam { 5, "ampdu_age", "age", "A-MPDU frames sent up due to old age" }, 299173306Ssam#define S_AMPDU_STOP AFTER(S_AMPDU_AGE) 300173306Ssam { 5, "ampdu_stop", "stop", "A-MPDU streams stopped" }, 301173306Ssam#define S_AMPDU_STOP_FAILED AFTER(S_AMPDU_STOP) 302173306Ssam { 5, "ampdu_stop_failed","!stop", "A-MPDU stop requests failed 'cuz stream not running" }, 303173306Ssam#define S_ADDBA_REJECT AFTER(S_AMPDU_STOP_FAILED) 304173306Ssam { 5, "addba_reject", "reject", "ADDBA requests rejected 'cuz A-MPDU rx is disabled" }, 305173306Ssam#define S_ADDBA_NOREQUEST AFTER(S_ADDBA_REJECT) 306173306Ssam { 5, "addba_norequest","norequest","ADDBA response frames discarded because no ADDBA request was pending" }, 307173306Ssam#define S_ADDBA_BADTOKEN AFTER(S_ADDBA_NOREQUEST) 308173306Ssam { 5, "addba_badtoken", "badtoken","ADDBA response frames discarded 'cuz rx'd dialog token is wrong" }, 309173306Ssam#define S_TX_BADSTATE AFTER(S_ADDBA_BADTOKEN) 310173306Ssam { 4, "tx_badstate", "badstate", "tx failed 'cuz vap not in RUN state" }, 311173306Ssam#define S_TX_NOTASSOC AFTER(S_TX_BADSTATE) 312173306Ssam { 4, "tx_notassoc", "notassoc", "tx failed 'cuz dest sta not associated" }, 313173306Ssam#define S_TX_CLASSIFY AFTER(S_TX_NOTASSOC) 314173306Ssam { 4, "tx_classify", "classify", "tx packet classification failed" }, 315173306Ssam#define S_DWDS_MCAST AFTER(S_TX_CLASSIFY) 316173306Ssam { 8, "dwds_mcast", "dwds_mcast", "mcast frame transmitted on dwds vap discarded" }, 317173306Ssam#define S_DWDS_QDROP AFTER(S_DWDS_MCAST) 318173306Ssam { 8, "dwds_qdrop", "dwds_qdrop", "4-address frame discarded because dwds pending queue is full" }, 319173306Ssam#define S_HT_ASSOC_NOHTCAP AFTER(S_DWDS_QDROP) 320173306Ssam { 4, "ht_nohtcap", "ht_nohtcap", "non-HT station rejected in HT-only BSS" }, 321173306Ssam#define S_HT_ASSOC_DOWNGRADE AFTER(S_HT_ASSOC_NOHTCAP) 322173306Ssam { 4, "ht_downgrade", "ht_downgrade", "HT station downgraded to legacy operation" }, 323173306Ssam#define S_HT_ASSOC_NORATE AFTER(S_HT_ASSOC_DOWNGRADE) 324173306Ssam { 4, "ht_norate", "ht_norate", "HT station rejected because of HT rate set" }, 325195618Srpaulo#define S_MESH_WRONGMESH AFTER(S_HT_ASSOC_NORATE) 326195618Srpaulo { 4, "mesh_wrong", "mesh_wrong", "frame discarded because sender not a mesh sta" }, 327195618Srpaulo#define S_MESH_NOLINK AFTER(S_MESH_WRONGMESH) 328195618Srpaulo { 4, "mesh_nolink", "mesh_nolink", "frame discarded because link not established" }, 329195618Srpaulo#define S_MESH_FWD_TTL AFTER(S_MESH_NOLINK) 330195618Srpaulo { 4, "mesh_fwd_ttl", "mesh_fwd_ttl", "frame not forwarded because TTL zero" }, 331195618Srpaulo#define S_MESH_FWD_NOBUF AFTER(S_MESH_FWD_TTL) 332195618Srpaulo { 4, "mesh_fwd_nobuf", "mesh_fwd_nobuf", "frame not forwarded because mbuf could not be allocated" }, 333195618Srpaulo#define S_MESH_FWD_TOOSHORT AFTER(S_MESH_FWD_NOBUF) 334195618Srpaulo { 4, "mesh_fwd_tooshort", "mesh_fwd_tooshort", "frame not forwarded because too short to have 802.11 header" }, 335195618Srpaulo#define S_MESH_FWD_DISABLED AFTER(S_MESH_FWD_TOOSHORT) 336195618Srpaulo { 4, "mesh_fwd_disabled", "mesh_fwd_disabled", "frame not forwarded because administratively disabled" }, 337195618Srpaulo#define S_MESH_FWD_NOPATH AFTER(S_MESH_FWD_DISABLED) 338195618Srpaulo { 4, "mesh_fwd_nopath", "mesh_fwd_nopath", "frame not forwarded because no path found to destination" }, 339195618Srpaulo#define S_HWMP_WRONGSEQ AFTER(S_MESH_FWD_NOPATH) 340195618Srpaulo { 4, "hwmp_wrongseq", "hwmp_wrongseq", "frame discarded because mesh sequence number is invalid" }, 341195618Srpaulo#define S_HWMP_ROOTREQS AFTER(S_HWMP_WRONGSEQ) 342195618Srpaulo { 4, "hwmp_rootreqs", "hwmp_rootreqs", "root PREQ frames sent" }, 343195618Srpaulo#define S_HWMP_ROOTANN AFTER(S_HWMP_ROOTREQS) 344195618Srpaulo { 4, "hwmp_rootann", "hwmp_rootann", "root RANN frames received" }, 345195811Ssam#define S_MESH_BADAE AFTER(S_HWMP_ROOTANN) 346195811Ssam { 4, "mesh_badae", "mesh_badae", "frame discarded for bad AddressExtension (AE)" }, 347195811Ssam#define S_MESH_RTADDFAILED AFTER(S_MESH_BADAE) 348195811Ssam { 4, "mesh_rtadd", "mesh_rtadd", "mesh route add failed" }, 349195811Ssam#define S_MESH_NOTPROXY AFTER(S_MESH_RTADDFAILED) 350195811Ssam { 8, "mesh_notproxy", "mesh_notproxy","frame discarded because station not acting as a proxy" }, 351195811Ssam#define S_RX_BADALIGN AFTER(S_MESH_NOTPROXY) 352195811Ssam { 4, "rx_badalign", "rx_badalign","frame discarded because payload re-alignment failed" }, 353195811Ssam#define S_INPUT AFTER(S_RX_BADALIGN) 354173306Ssam { 8, "input", "input", "total data frames received" }, 355173306Ssam#define S_RX_UCAST AFTER(S_INPUT) 356161200Ssam { 8, "rx_ucast", "rx_ucast", "unicast data frames received" }, 357173306Ssam#define S_RX_MCAST AFTER(S_RX_UCAST) 358161200Ssam { 8, "rx_mcast", "rx_mcast", "multicast data frames received" }, 359173306Ssam#define S_OUTPUT AFTER(S_RX_MCAST) 360173306Ssam { 8, "output", "output", "total data frames transmit" }, 361173306Ssam#define S_TX_UCAST AFTER(S_OUTPUT) 362161200Ssam { 8, "tx_ucast", "tx_ucast", "unicast data frames sent" }, 363173306Ssam#define S_TX_MCAST AFTER(S_TX_UCAST) 364161200Ssam { 8, "tx_mcast", "tx_mcast", "multicast data frames sent" }, 365173306Ssam#define S_RATE AFTER(S_TX_MCAST) 366178699Ssam { 5, "rate", "rate", "current transmit rate" }, 367173306Ssam#define S_RSSI AFTER(S_RATE) 368178699Ssam { 5, "rssi", "rssi", "current rssi" }, 369173306Ssam#define S_NOISE AFTER(S_RSSI) 370178699Ssam { 5, "noise", "noise", "current noise floor (dBm)" }, 371173306Ssam#define S_SIGNAL AFTER(S_NOISE) 372178699Ssam { 5, "signal", "sig", "current signal (dBm)" }, 373161200Ssam}; 374161200Ssam 375161200Ssamstruct wlanstatfoo_p { 376161200Ssam struct wlanstatfoo base; 377161200Ssam int s; 378161200Ssam int opmode; 379161200Ssam uint8_t mac[IEEE80211_ADDR_LEN]; 380161200Ssam struct ifreq ifr; 381161200Ssam struct ieee80211_stats cur; 382161200Ssam struct ieee80211_stats total; 383161200Ssam struct ieee80211req ireq; 384161200Ssam union { 385161200Ssam struct ieee80211req_sta_req info; 386161200Ssam char buf[1024]; 387161200Ssam } u_info; 388161200Ssam struct ieee80211req_sta_stats ncur; 389161200Ssam struct ieee80211req_sta_stats ntotal; 390161200Ssam}; 391161200Ssam 392153317Ssamstatic void 393161200Ssamwlan_setifname(struct wlanstatfoo *wf0, const char *ifname) 394153317Ssam{ 395161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 396161200Ssam 397161200Ssam strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name)); 398161200Ssam strncpy(wf->ireq.i_name, ifname, sizeof (wf->ireq.i_name)); 399153317Ssam} 400153317Ssam 401161200Ssamstatic const char * 402161200Ssamwlan_getifname(struct wlanstatfoo *wf0) 403153317Ssam{ 404161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 405153317Ssam 406161200Ssam return wf->ifr.ifr_name; 407161200Ssam} 408153317Ssam 409161200Ssamstatic int 410161200Ssamwlan_getopmode(struct wlanstatfoo *wf0) 411161200Ssam{ 412161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 413153317Ssam 414161200Ssam if (wf->opmode == -1) { 415161200Ssam struct ifmediareq ifmr; 416153317Ssam 417161200Ssam memset(&ifmr, 0, sizeof(ifmr)); 418161200Ssam strlcpy(ifmr.ifm_name, wf->ifr.ifr_name, sizeof(ifmr.ifm_name)); 419161200Ssam if (ioctl(wf->s, SIOCGIFMEDIA, &ifmr) < 0) 420161200Ssam err(1, "%s (SIOCGIFMEDIA)", wf->ifr.ifr_name); 421188187Ssam if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) { 422188187Ssam if (ifmr.ifm_current & IFM_FLAG0) 423188187Ssam wf->opmode = IEEE80211_M_AHDEMO; 424188187Ssam else 425188187Ssam wf->opmode = IEEE80211_M_IBSS; 426188187Ssam } else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 427161200Ssam wf->opmode = IEEE80211_M_HOSTAP; 428161200Ssam else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 429161200Ssam wf->opmode = IEEE80211_M_MONITOR; 430161200Ssam else 431161200Ssam wf->opmode = IEEE80211_M_STA; 432161200Ssam } 433161200Ssam return wf->opmode; 434161200Ssam} 435153317Ssam 436161200Ssamstatic void 437161200Ssamgetlladdr(struct wlanstatfoo_p *wf) 438161200Ssam{ 439161200Ssam const struct sockaddr_dl *sdl; 440161200Ssam struct ifaddrs *ifp, *p; 441153317Ssam 442161200Ssam if (getifaddrs(&ifp) != 0) 443161200Ssam err(1, "getifaddrs"); 444161200Ssam for (p = ifp; p != NULL; p = p->ifa_next) 445161200Ssam if (strcmp(p->ifa_name, wf->ifr.ifr_name) == 0 && 446161200Ssam p->ifa_addr->sa_family == AF_LINK) 447161200Ssam break; 448161200Ssam if (p == NULL) 449161200Ssam errx(1, "did not find link layer address for interface %s", 450161200Ssam wf->ifr.ifr_name); 451161200Ssam sdl = (const struct sockaddr_dl *) p->ifa_addr; 452161200Ssam IEEE80211_ADDR_COPY(wf->mac, LLADDR(sdl)); 453161200Ssam freeifaddrs(ifp); 454153317Ssam} 455153317Ssam 456188187Ssamstatic int 457188187Ssamgetbssid(struct wlanstatfoo_p *wf) 458188187Ssam{ 459188187Ssam wf->ireq.i_type = IEEE80211_IOC_BSSID; 460188187Ssam wf->ireq.i_data = wf->mac; 461188187Ssam wf->ireq.i_len = IEEE80211_ADDR_LEN; 462188187Ssam return ioctl(wf->s, SIOCG80211, &wf->ireq); 463188187Ssam} 464188187Ssam 465161200Ssamstatic void 466161200Ssamwlan_setstamac(struct wlanstatfoo *wf0, const uint8_t *mac) 467153317Ssam{ 468188210Ssam static const uint8_t zeromac[IEEE80211_ADDR_LEN]; 469161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 470153317Ssam 471161200Ssam if (mac == NULL) { 472161200Ssam switch (wlan_getopmode(wf0)) { 473161200Ssam case IEEE80211_M_HOSTAP: 474161200Ssam case IEEE80211_M_MONITOR: 475188210Ssam getlladdr(wf); 476188210Ssam break; 477161200Ssam case IEEE80211_M_IBSS: 478161200Ssam case IEEE80211_M_AHDEMO: 479188210Ssam /* 480188210Ssam * NB: this may not work in which case the 481188210Ssam * mac must be specified on the command line 482188210Ssam */ 483188210Ssam if (getbssid(wf) < 0 || 484188210Ssam IEEE80211_ADDR_EQ(wf->mac, zeromac)) 485188210Ssam getlladdr(wf); 486153317Ssam break; 487161200Ssam case IEEE80211_M_STA: 488188187Ssam if (getbssid(wf) < 0) 489188187Ssam err(1, "%s (IEEE80211_IOC_BSSID)", 490188187Ssam wf->ireq.i_name); 491153317Ssam break; 492153317Ssam } 493161200Ssam } else 494161200Ssam IEEE80211_ADDR_COPY(wf->mac, mac); 495161200Ssam} 496153317Ssam 497161200Ssam/* XXX only fetch what's needed to do reports */ 498161200Ssamstatic void 499161200Ssamwlan_collect(struct wlanstatfoo_p *wf, 500161200Ssam struct ieee80211_stats *stats, struct ieee80211req_sta_stats *nstats) 501161200Ssam{ 502153317Ssam 503161200Ssam IEEE80211_ADDR_COPY(wf->u_info.info.is_u.macaddr, wf->mac); 504161200Ssam wf->ireq.i_type = IEEE80211_IOC_STA_INFO; 505161200Ssam wf->ireq.i_data = (caddr_t) &wf->u_info; 506161200Ssam wf->ireq.i_len = sizeof(wf->u_info); 507188187Ssam if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) { 508188187Ssam warn("%s:%s (IEEE80211_IOC_STA_INFO)", wf->ireq.i_name, 509188187Ssam ether_ntoa((const struct ether_addr*) wf->mac)); 510188187Ssam } 511161200Ssam 512161200Ssam IEEE80211_ADDR_COPY(nstats->is_u.macaddr, wf->mac); 513161200Ssam wf->ireq.i_type = IEEE80211_IOC_STA_STATS; 514161200Ssam wf->ireq.i_data = (caddr_t) nstats; 515161200Ssam wf->ireq.i_len = sizeof(*nstats); 516161200Ssam if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) 517188187Ssam warn("%s:%s (IEEE80211_IOC_STA_STATS)", wf->ireq.i_name, 518188187Ssam ether_ntoa((const struct ether_addr*) wf->mac)); 519161200Ssam 520161200Ssam wf->ifr.ifr_data = (caddr_t) stats; 521161200Ssam if (ioctl(wf->s, SIOCG80211STATS, &wf->ifr) < 0) 522170535Ssam err(1, "%s (SIOCG80211STATS)", wf->ifr.ifr_name); 523161200Ssam} 524161200Ssam 525161200Ssamstatic void 526161200Ssamwlan_collect_cur(struct statfoo *sf) 527161200Ssam{ 528161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 529161200Ssam 530161200Ssam wlan_collect(wf, &wf->cur, &wf->ncur); 531161200Ssam} 532161200Ssam 533161200Ssamstatic void 534161200Ssamwlan_collect_tot(struct statfoo *sf) 535161200Ssam{ 536161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 537161200Ssam 538161200Ssam wlan_collect(wf, &wf->total, &wf->ntotal); 539161200Ssam} 540161200Ssam 541161200Ssamstatic void 542161200Ssamwlan_update_tot(struct statfoo *sf) 543161200Ssam{ 544161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 545161200Ssam 546161200Ssam wf->total = wf->cur; 547161200Ssam wf->ntotal = wf->ncur; 548161200Ssam} 549161200Ssam 550178359Ssamvoid 551178359Ssamsetreason(char b[], size_t bs, int v) 552178359Ssam{ 553178359Ssam#define N(a) (sizeof(a)/sizeof(a[0])) 554178359Ssam static const char *reasons[] = { 555178359Ssam [IEEE80211_REASON_UNSPECIFIED] = "unspecified", 556178359Ssam [IEEE80211_REASON_AUTH_EXPIRE] = "auth expire", 557178359Ssam [IEEE80211_REASON_AUTH_LEAVE] = "auth leave", 558178359Ssam [IEEE80211_REASON_ASSOC_EXPIRE] = "assoc expire", 559178359Ssam [IEEE80211_REASON_ASSOC_TOOMANY] = "assoc toomany", 560178359Ssam [IEEE80211_REASON_NOT_AUTHED] = "not authed", 561178359Ssam [IEEE80211_REASON_NOT_ASSOCED] = "not assoced", 562178359Ssam [IEEE80211_REASON_ASSOC_LEAVE] = "assoc leave", 563178359Ssam [IEEE80211_REASON_ASSOC_NOT_AUTHED] = "assoc not authed", 564178359Ssam [IEEE80211_REASON_DISASSOC_PWRCAP_BAD] = "disassoc pwrcap bad", 565178359Ssam [IEEE80211_REASON_DISASSOC_SUPCHAN_BAD] = "disassoc supchan bad", 566178359Ssam [IEEE80211_REASON_IE_INVALID] = "ie invalid", 567178359Ssam [IEEE80211_REASON_MIC_FAILURE] = "mic failure", 568178359Ssam [IEEE80211_REASON_4WAY_HANDSHAKE_TIMEOUT]= "4-way handshake timeout", 569178359Ssam [IEEE80211_REASON_GROUP_KEY_UPDATE_TIMEOUT] = "group key update timeout", 570178359Ssam [IEEE80211_REASON_IE_IN_4WAY_DIFFERS] = "ie in 4-way differs", 571178359Ssam [IEEE80211_REASON_GROUP_CIPHER_INVALID] = "group cipher invalid", 572178359Ssam [IEEE80211_REASON_PAIRWISE_CIPHER_INVALID]= "pairwise cipher invalid", 573178359Ssam [IEEE80211_REASON_AKMP_INVALID] = "akmp invalid", 574178359Ssam [IEEE80211_REASON_UNSUPP_RSN_IE_VERSION]= "unsupported rsn ie version", 575178359Ssam [IEEE80211_REASON_INVALID_RSN_IE_CAP] = "invalid rsn ie cap", 576178359Ssam [IEEE80211_REASON_802_1X_AUTH_FAILED] = "802.1x auth failed", 577178359Ssam [IEEE80211_REASON_CIPHER_SUITE_REJECTED]= "cipher suite rejected", 578178359Ssam }; 579178359Ssam if (v < N(reasons) && reasons[v] != NULL) 580178359Ssam snprintf(b, bs, "%s (%u)", reasons[v], v); 581178359Ssam else 582178359Ssam snprintf(b, bs, "%u", v); 583178359Ssam#undef N 584178359Ssam} 585178359Ssam 586178359Ssamvoid 587178359Ssamsetstatus(char b[], size_t bs, int v) 588178359Ssam{ 589178359Ssam#define N(a) (sizeof(a)/sizeof(a[0])) 590178359Ssam static const char *status[] = { 591178359Ssam [IEEE80211_STATUS_SUCCESS] = "success", 592178359Ssam [IEEE80211_STATUS_UNSPECIFIED] = "unspecified", 593178359Ssam [IEEE80211_STATUS_CAPINFO] = "capinfo", 594178359Ssam [IEEE80211_STATUS_NOT_ASSOCED] = "not assoced", 595178359Ssam [IEEE80211_STATUS_OTHER] = "other", 596178359Ssam [IEEE80211_STATUS_ALG] = "algorithm", 597178359Ssam [IEEE80211_STATUS_SEQUENCE] = "sequence", 598178359Ssam [IEEE80211_STATUS_CHALLENGE] = "challenge", 599178359Ssam [IEEE80211_STATUS_TIMEOUT] = "timeout", 600178359Ssam [IEEE80211_STATUS_TOOMANY] = "toomany", 601178359Ssam [IEEE80211_STATUS_BASIC_RATE] = "basic rate", 602178359Ssam [IEEE80211_STATUS_SP_REQUIRED] = "sp required", 603178359Ssam [IEEE80211_STATUS_PBCC_REQUIRED] = "pbcc required", 604178359Ssam [IEEE80211_STATUS_CA_REQUIRED] = "ca required", 605178359Ssam [IEEE80211_STATUS_SPECMGMT_REQUIRED] = "specmgmt required", 606178359Ssam [IEEE80211_STATUS_PWRCAP_REQUIRED] = "pwrcap required", 607178359Ssam [IEEE80211_STATUS_SUPCHAN_REQUIRED] = "supchan required", 608178359Ssam [IEEE80211_STATUS_SHORTSLOT_REQUIRED] = "shortslot required", 609178359Ssam [IEEE80211_STATUS_DSSSOFDM_REQUIRED] = "dsssofdm required", 610178359Ssam [IEEE80211_STATUS_INVALID_IE] = "invalid ie", 611178359Ssam [IEEE80211_STATUS_GROUP_CIPHER_INVALID] = "group cipher invalid", 612178359Ssam [IEEE80211_STATUS_PAIRWISE_CIPHER_INVALID]= "pairwise cipher invalid", 613178359Ssam [IEEE80211_STATUS_AKMP_INVALID] = "akmp invalid", 614178359Ssam [IEEE80211_STATUS_UNSUPP_RSN_IE_VERSION]= "unsupported rsn ie version", 615178359Ssam [IEEE80211_STATUS_INVALID_RSN_IE_CAP] = "invalid rsn ie cap", 616178359Ssam [IEEE80211_STATUS_CIPHER_SUITE_REJECTED]= "cipher suite rejected", 617178359Ssam }; 618178359Ssam if (v < N(status) && status[v] != NULL) 619178359Ssam snprintf(b, bs, "%s (%u)", status[v], v); 620178359Ssam else 621178359Ssam snprintf(b, bs, "%u", v); 622178359Ssam#undef N 623178359Ssam} 624178359Ssam 625161200Ssamstatic int 626161200Ssamwlan_getinfo(struct wlanstatfoo_p *wf, int s, char b[], size_t bs) 627161200Ssam{ 628161200Ssam const struct ieee80211req_sta_info *si = &wf->u_info.info.info[0]; 629161200Ssam 630161200Ssam switch (s) { 631161200Ssam case S_RATE: 632178359Ssam snprintf(b, bs, "%uM", si->isi_txmbps/2); 633161200Ssam return 1; 634161200Ssam case S_RSSI: 635161200Ssam snprintf(b, bs, "%d", si->isi_rssi); 636161200Ssam return 1; 637161200Ssam case S_NOISE: 638161200Ssam snprintf(b, bs, "%d", si->isi_noise); 639161200Ssam return 1; 640161200Ssam case S_SIGNAL: 641161200Ssam snprintf(b, bs, "%d", si->isi_rssi + si->isi_noise); 642161200Ssam return 1; 643178359Ssam case S_RX_AUTH_FAIL_CODE: 644178359Ssam if (wf->cur.is_rx_authfail_code == 0) 645178359Ssam break; 646178359Ssam setstatus(b, bs, wf->cur.is_rx_authfail_code); 647178359Ssam return 1; 648178359Ssam case S_RX_DEAUTH_CODE: 649178359Ssam if (wf->cur.is_rx_deauth_code == 0) 650178359Ssam break; 651178359Ssam setreason(b, bs, wf->cur.is_rx_deauth_code); 652178359Ssam return 1; 653178359Ssam case S_RX_DISASSOC_CODE: 654178359Ssam if (wf->cur.is_rx_disassoc_code == 0) 655178359Ssam break; 656178359Ssam setreason(b, bs, wf->cur.is_rx_disassoc_code); 657178359Ssam return 1; 658153317Ssam } 659161200Ssam b[0] = '\0'; 660161200Ssam return 0; 661161200Ssam} 662161200Ssam 663161200Ssamstatic int 664161200Ssamwlan_get_curstat(struct statfoo *sf, int s, char b[], size_t bs) 665161200Ssam{ 666161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 667161200Ssam#define STAT(x) \ 668161200Ssam snprintf(b, bs, "%u", wf->cur.is_##x - wf->total.is_##x); return 1 669161200Ssam#define NSTAT(x) \ 670161200Ssam snprintf(b, bs, "%u", \ 671161200Ssam wf->ncur.is_stats.ns_##x - wf->ntotal.is_stats.ns_##x); \ 672161200Ssam return 1 673161200Ssam 674161200Ssam switch (s) { 675161200Ssam case S_RX_BADVERSION: STAT(rx_badversion); 676161200Ssam case S_RX_TOOSHORT: STAT(rx_tooshort); 677161200Ssam case S_RX_WRONGBSS: STAT(rx_wrongbss); 678161200Ssam case S_RX_DUP: STAT(rx_dup); 679161200Ssam case S_RX_WRONGDIR: STAT(rx_wrongdir); 680161200Ssam case S_RX_MCASTECHO: STAT(rx_mcastecho); 681161200Ssam case S_RX_NOTASSOC: STAT(rx_notassoc); 682161200Ssam case S_RX_NOPRIVACY: STAT(rx_noprivacy); 683161200Ssam case S_RX_UNENCRYPTED: STAT(rx_unencrypted); 684161200Ssam case S_RX_WEPFAIL: STAT(rx_wepfail); 685161200Ssam case S_RX_DECAP: STAT(rx_decap); 686161200Ssam case S_RX_MGTDISCARD: STAT(rx_mgtdiscard); 687161200Ssam case S_RX_CTL: STAT(rx_ctl); 688161200Ssam case S_RX_BEACON: STAT(rx_beacon); 689161200Ssam case S_RX_RSTOOBIG: STAT(rx_rstoobig); 690161200Ssam case S_RX_ELEM_MISSING: STAT(rx_elem_missing); 691161200Ssam case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig); 692161200Ssam case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall); 693161200Ssam case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown); 694161200Ssam case S_RX_BADCHAN: STAT(rx_badchan); 695161200Ssam case S_RX_CHANMISMATCH: STAT(rx_chanmismatch); 696161200Ssam case S_RX_NODEALLOC: STAT(rx_nodealloc); 697161200Ssam case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch); 698161200Ssam case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported); 699161200Ssam case S_RX_AUTH_FAIL: STAT(rx_auth_fail); 700161200Ssam case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures); 701161200Ssam case S_RX_ASSOC_BSS: STAT(rx_assoc_bss); 702161200Ssam case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth); 703161200Ssam case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch); 704161200Ssam case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate); 705161200Ssam case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie); 706161200Ssam case S_RX_DEAUTH: STAT(rx_deauth); 707161200Ssam case S_RX_DISASSOC: STAT(rx_disassoc); 708178359Ssam case S_BMISS: STAT(beacon_miss); 709161200Ssam case S_RX_BADSUBTYPE: STAT(rx_badsubtype); 710161200Ssam case S_RX_NOBUF: STAT(rx_nobuf); 711161200Ssam case S_RX_DECRYPTCRC: STAT(rx_decryptcrc); 712161200Ssam case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt); 713161200Ssam case S_RX_BAD_AUTH: STAT(rx_bad_auth); 714161200Ssam case S_RX_UNAUTH: STAT(rx_unauth); 715161200Ssam case S_RX_BADKEYID: STAT(rx_badkeyid); 716161200Ssam case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay); 717161200Ssam case S_RX_CCMPFORMAT: STAT(rx_ccmpformat); 718161200Ssam case S_RX_CCMPMIC: STAT(rx_ccmpmic); 719161200Ssam case S_RX_TKIPREPLAY: STAT(rx_tkipreplay); 720161200Ssam case S_RX_TKIPFORMAT: STAT(rx_tkipformat); 721161200Ssam case S_RX_TKIPMIC: STAT(rx_tkipmic); 722161200Ssam case S_RX_TKIPICV: STAT(rx_tkipicv); 723161200Ssam case S_RX_BADCIPHER: STAT(rx_badcipher); 724161200Ssam case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx); 725161200Ssam case S_RX_ACL: STAT(rx_acl); 726161200Ssam case S_TX_NOBUF: STAT(tx_nobuf); 727161200Ssam case S_TX_NONODE: STAT(tx_nonode); 728161200Ssam case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt); 729161200Ssam case S_TX_BADCIPHER: STAT(tx_badcipher); 730161200Ssam case S_TX_NODEFKEY: STAT(tx_nodefkey); 731161200Ssam case S_TX_NOHEADROOM: STAT(tx_noheadroom); 732161200Ssam case S_TX_FRAGFRAMES: STAT(tx_fragframes); 733161200Ssam case S_TX_FRAGS: STAT(tx_frags); 734161200Ssam case S_SCAN_ACTIVE: STAT(scan_active); 735161200Ssam case S_SCAN_PASSIVE: STAT(scan_passive); 736178359Ssam case S_SCAN_BG: STAT(scan_bg); 737161200Ssam case S_NODE_TIMEOUT: STAT(node_timeout); 738161200Ssam case S_CRYPTO_NOMEM: STAT(crypto_nomem); 739161200Ssam case S_CRYPTO_TKIP: STAT(crypto_tkip); 740161200Ssam case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic); 741161200Ssam case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic); 742161200Ssam case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm); 743161200Ssam case S_CRYPTO_CCMP: STAT(crypto_ccmp); 744161200Ssam case S_CRYPTO_WEP: STAT(crypto_wep); 745161200Ssam case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher); 746161200Ssam case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey); 747161200Ssam case S_CRYPTO_DELKEY: STAT(crypto_delkey); 748161200Ssam case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher); 749161200Ssam case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher); 750161200Ssam case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail); 751161200Ssam case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback); 752161200Ssam case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail); 753161200Ssam case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail); 754161200Ssam case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch); 755161200Ssam case S_IBSS_NORATE: STAT(ibss_norate); 756161200Ssam case S_PS_UNASSOC: STAT(ps_unassoc); 757161200Ssam case S_PS_BADAID: STAT(ps_badaid); 758161200Ssam case S_PS_QEMPTY: STAT(ps_qempty); 759161200Ssam case S_FF_BADHDR: STAT(ff_badhdr); 760161200Ssam case S_FF_TOOSHORT: STAT(ff_tooshort); 761161200Ssam case S_FF_SPLIT: STAT(ff_split); 762161200Ssam case S_FF_DECAP: STAT(ff_decap); 763161200Ssam case S_FF_ENCAP: STAT(ff_encap); 764161200Ssam case S_RX_BADBINTVAL: STAT(rx_badbintval); 765161200Ssam case S_RX_MGMT: STAT(rx_mgmt); 766161200Ssam case S_RX_DEMICFAIL: STAT(rx_demicfail); 767161200Ssam case S_RX_DEFRAG: STAT(rx_defrag); 768170535Ssam case S_RX_ACTION: STAT(rx_action); 769170535Ssam case S_AMSDU_TOOSHORT: STAT(amsdu_tooshort); 770170535Ssam case S_AMSDU_SPLIT: STAT(amsdu_split); 771170535Ssam case S_AMSDU_DECAP: STAT(amsdu_decap); 772170535Ssam case S_AMSDU_ENCAP: STAT(amsdu_encap); 773173306Ssam case S_AMPDU_REORDER: STAT(ampdu_rx_reorder); 774170535Ssam case S_AMPDU_FLUSH: STAT(ampdu_rx_flush); 775170535Ssam case S_AMPDU_BARBAD: STAT(ampdu_bar_bad); 776170535Ssam case S_AMPDU_BAROOW: STAT(ampdu_bar_oow); 777173306Ssam case S_AMPDU_BARMOVE: STAT(ampdu_bar_move); 778170535Ssam case S_AMPDU_BAR: STAT(ampdu_bar_rx); 779173306Ssam case S_AMPDU_MOVE: STAT(ampdu_rx_move); 780170535Ssam case S_AMPDU_OOR: STAT(ampdu_rx_oor); 781170535Ssam case S_AMPDU_COPY: STAT(ampdu_rx_copy); 782173306Ssam case S_AMPDU_DROP: STAT(ampdu_rx_drop); 783173306Ssam case S_AMPDU_AGE: STAT(ampdu_rx_age); 784173306Ssam case S_AMPDU_STOP: STAT(ampdu_stop); 785173306Ssam case S_AMPDU_STOP_FAILED:STAT(ampdu_stop_failed); 786173306Ssam case S_ADDBA_REJECT: STAT(addba_reject); 787173306Ssam case S_ADDBA_NOREQUEST: STAT(addba_norequest); 788173306Ssam case S_ADDBA_BADTOKEN: STAT(addba_badtoken); 789173306Ssam case S_TX_BADSTATE: STAT(tx_badstate); 790173306Ssam case S_TX_NOTASSOC: STAT(tx_notassoc); 791173306Ssam case S_TX_CLASSIFY: STAT(tx_classify); 792178359Ssam case S_DWDS_MCAST: STAT(dwds_mcast); 793178359Ssam case S_DWDS_QDROP: STAT(dwds_qdrop); 794173306Ssam case S_HT_ASSOC_NOHTCAP:STAT(ht_assoc_nohtcap); 795173306Ssam case S_HT_ASSOC_DOWNGRADE:STAT(ht_assoc_downgrade); 796173306Ssam case S_HT_ASSOC_NORATE: STAT(ht_assoc_norate); 797195618Srpaulo case S_MESH_WRONGMESH: STAT(mesh_wrongmesh); 798195618Srpaulo case S_MESH_NOLINK: STAT(mesh_nolink); 799195618Srpaulo case S_MESH_FWD_TTL: STAT(mesh_fwd_ttl); 800195618Srpaulo case S_MESH_FWD_NOBUF: STAT(mesh_fwd_nobuf); 801195618Srpaulo case S_MESH_FWD_TOOSHORT: STAT(mesh_fwd_tooshort); 802195618Srpaulo case S_MESH_FWD_DISABLED: STAT(mesh_fwd_disabled); 803195618Srpaulo case S_MESH_FWD_NOPATH: STAT(mesh_fwd_nopath); 804195618Srpaulo case S_HWMP_WRONGSEQ: STAT(hwmp_wrongseq); 805195618Srpaulo case S_HWMP_ROOTREQS: STAT(hwmp_rootreqs); 806195618Srpaulo case S_HWMP_ROOTANN: STAT(hwmp_rootrann); 807195811Ssam case S_MESH_BADAE: STAT(mesh_badae); 808195811Ssam case S_MESH_RTADDFAILED:STAT(mesh_rtaddfailed); 809195811Ssam case S_MESH_NOTPROXY: STAT(mesh_notproxy); 810195811Ssam case S_RX_BADALIGN: STAT(rx_badalign); 811161200Ssam case S_INPUT: NSTAT(rx_data); 812161200Ssam case S_OUTPUT: NSTAT(tx_data); 813161200Ssam case S_RX_UCAST: NSTAT(rx_ucast); 814161200Ssam case S_RX_MCAST: NSTAT(rx_mcast); 815161200Ssam case S_TX_UCAST: NSTAT(tx_ucast); 816161200Ssam case S_TX_MCAST: NSTAT(tx_mcast); 817153317Ssam } 818161200Ssam return wlan_getinfo(wf, s, b, bs); 819161200Ssam#undef NSTAT 820161200Ssam#undef STAT 821153317Ssam} 822161200Ssam 823161200Ssamstatic int 824161200Ssamwlan_get_totstat(struct statfoo *sf, int s, char b[], size_t bs) 825161200Ssam{ 826161200Ssam struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 827161200Ssam#define STAT(x) \ 828161200Ssam snprintf(b, bs, "%u", wf->total.is_##x); return 1 829161200Ssam#define NSTAT(x) \ 830161200Ssam snprintf(b, bs, "%u", wf->ntotal.is_stats.ns_##x); return 1 831161200Ssam 832161200Ssam switch (s) { 833161200Ssam case S_RX_BADVERSION: STAT(rx_badversion); 834161200Ssam case S_RX_TOOSHORT: STAT(rx_tooshort); 835161200Ssam case S_RX_WRONGBSS: STAT(rx_wrongbss); 836161200Ssam case S_RX_DUP: STAT(rx_dup); 837161200Ssam case S_RX_WRONGDIR: STAT(rx_wrongdir); 838161200Ssam case S_RX_MCASTECHO: STAT(rx_mcastecho); 839161200Ssam case S_RX_NOTASSOC: STAT(rx_notassoc); 840161200Ssam case S_RX_NOPRIVACY: STAT(rx_noprivacy); 841161200Ssam case S_RX_UNENCRYPTED: STAT(rx_unencrypted); 842161200Ssam case S_RX_WEPFAIL: STAT(rx_wepfail); 843161200Ssam case S_RX_DECAP: STAT(rx_decap); 844161200Ssam case S_RX_MGTDISCARD: STAT(rx_mgtdiscard); 845161200Ssam case S_RX_CTL: STAT(rx_ctl); 846161200Ssam case S_RX_BEACON: STAT(rx_beacon); 847161200Ssam case S_RX_RSTOOBIG: STAT(rx_rstoobig); 848161200Ssam case S_RX_ELEM_MISSING: STAT(rx_elem_missing); 849161200Ssam case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig); 850161200Ssam case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall); 851161200Ssam case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown); 852161200Ssam case S_RX_BADCHAN: STAT(rx_badchan); 853161200Ssam case S_RX_CHANMISMATCH: STAT(rx_chanmismatch); 854161200Ssam case S_RX_NODEALLOC: STAT(rx_nodealloc); 855161200Ssam case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch); 856161200Ssam case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported); 857161200Ssam case S_RX_AUTH_FAIL: STAT(rx_auth_fail); 858161200Ssam case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures); 859161200Ssam case S_RX_ASSOC_BSS: STAT(rx_assoc_bss); 860161200Ssam case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth); 861161200Ssam case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch); 862161200Ssam case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate); 863161200Ssam case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie); 864161200Ssam case S_RX_DEAUTH: STAT(rx_deauth); 865161200Ssam case S_RX_DISASSOC: STAT(rx_disassoc); 866178359Ssam case S_BMISS: STAT(beacon_miss); 867161200Ssam case S_RX_BADSUBTYPE: STAT(rx_badsubtype); 868161200Ssam case S_RX_NOBUF: STAT(rx_nobuf); 869161200Ssam case S_RX_DECRYPTCRC: STAT(rx_decryptcrc); 870161200Ssam case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt); 871161200Ssam case S_RX_BAD_AUTH: STAT(rx_bad_auth); 872161200Ssam case S_RX_UNAUTH: STAT(rx_unauth); 873161200Ssam case S_RX_BADKEYID: STAT(rx_badkeyid); 874161200Ssam case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay); 875161200Ssam case S_RX_CCMPFORMAT: STAT(rx_ccmpformat); 876161200Ssam case S_RX_CCMPMIC: STAT(rx_ccmpmic); 877161200Ssam case S_RX_TKIPREPLAY: STAT(rx_tkipreplay); 878161200Ssam case S_RX_TKIPFORMAT: STAT(rx_tkipformat); 879161200Ssam case S_RX_TKIPMIC: STAT(rx_tkipmic); 880161200Ssam case S_RX_TKIPICV: STAT(rx_tkipicv); 881161200Ssam case S_RX_BADCIPHER: STAT(rx_badcipher); 882161200Ssam case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx); 883161200Ssam case S_RX_ACL: STAT(rx_acl); 884161200Ssam case S_TX_NOBUF: STAT(tx_nobuf); 885161200Ssam case S_TX_NONODE: STAT(tx_nonode); 886161200Ssam case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt); 887161200Ssam case S_TX_BADCIPHER: STAT(tx_badcipher); 888161200Ssam case S_TX_NODEFKEY: STAT(tx_nodefkey); 889161200Ssam case S_TX_NOHEADROOM: STAT(tx_noheadroom); 890161200Ssam case S_TX_FRAGFRAMES: STAT(tx_fragframes); 891161200Ssam case S_TX_FRAGS: STAT(tx_frags); 892161200Ssam case S_SCAN_ACTIVE: STAT(scan_active); 893161200Ssam case S_SCAN_PASSIVE: STAT(scan_passive); 894178359Ssam case S_SCAN_BG: STAT(scan_bg); 895161200Ssam case S_NODE_TIMEOUT: STAT(node_timeout); 896161200Ssam case S_CRYPTO_NOMEM: STAT(crypto_nomem); 897161200Ssam case S_CRYPTO_TKIP: STAT(crypto_tkip); 898161200Ssam case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic); 899161200Ssam case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic); 900161200Ssam case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm); 901161200Ssam case S_CRYPTO_CCMP: STAT(crypto_ccmp); 902161200Ssam case S_CRYPTO_WEP: STAT(crypto_wep); 903161200Ssam case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher); 904161200Ssam case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey); 905161200Ssam case S_CRYPTO_DELKEY: STAT(crypto_delkey); 906161200Ssam case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher); 907161200Ssam case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher); 908161200Ssam case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail); 909161200Ssam case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback); 910161200Ssam case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail); 911161200Ssam case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail); 912161200Ssam case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch); 913161200Ssam case S_IBSS_NORATE: STAT(ibss_norate); 914161200Ssam case S_PS_UNASSOC: STAT(ps_unassoc); 915161200Ssam case S_PS_BADAID: STAT(ps_badaid); 916161200Ssam case S_PS_QEMPTY: STAT(ps_qempty); 917161200Ssam case S_FF_BADHDR: STAT(ff_badhdr); 918161200Ssam case S_FF_TOOSHORT: STAT(ff_tooshort); 919161200Ssam case S_FF_SPLIT: STAT(ff_split); 920161200Ssam case S_FF_DECAP: STAT(ff_decap); 921161200Ssam case S_FF_ENCAP: STAT(ff_encap); 922161200Ssam case S_RX_BADBINTVAL: STAT(rx_badbintval); 923161200Ssam case S_RX_MGMT: STAT(rx_mgmt); 924161200Ssam case S_RX_DEMICFAIL: STAT(rx_demicfail); 925161200Ssam case S_RX_DEFRAG: STAT(rx_defrag); 926170535Ssam case S_RX_ACTION: STAT(rx_action); 927170535Ssam case S_AMSDU_TOOSHORT: STAT(amsdu_tooshort); 928170535Ssam case S_AMSDU_SPLIT: STAT(amsdu_split); 929170535Ssam case S_AMSDU_DECAP: STAT(amsdu_decap); 930170535Ssam case S_AMSDU_ENCAP: STAT(amsdu_encap); 931173306Ssam case S_AMPDU_REORDER: STAT(ampdu_rx_reorder); 932170535Ssam case S_AMPDU_FLUSH: STAT(ampdu_rx_flush); 933170535Ssam case S_AMPDU_BARBAD: STAT(ampdu_bar_bad); 934170535Ssam case S_AMPDU_BAROOW: STAT(ampdu_bar_oow); 935173306Ssam case S_AMPDU_BARMOVE: STAT(ampdu_bar_move); 936170535Ssam case S_AMPDU_BAR: STAT(ampdu_bar_rx); 937173306Ssam case S_AMPDU_MOVE: STAT(ampdu_rx_move); 938170535Ssam case S_AMPDU_OOR: STAT(ampdu_rx_oor); 939170535Ssam case S_AMPDU_COPY: STAT(ampdu_rx_copy); 940173306Ssam case S_AMPDU_DROP: STAT(ampdu_rx_drop); 941173306Ssam case S_AMPDU_AGE: STAT(ampdu_rx_age); 942173306Ssam case S_AMPDU_STOP: STAT(ampdu_stop); 943173306Ssam case S_AMPDU_STOP_FAILED:STAT(ampdu_stop_failed); 944173306Ssam case S_ADDBA_REJECT: STAT(addba_reject); 945173306Ssam case S_ADDBA_NOREQUEST: STAT(addba_norequest); 946173306Ssam case S_ADDBA_BADTOKEN: STAT(addba_badtoken); 947173306Ssam case S_TX_BADSTATE: STAT(tx_badstate); 948173306Ssam case S_TX_NOTASSOC: STAT(tx_notassoc); 949173306Ssam case S_TX_CLASSIFY: STAT(tx_classify); 950178359Ssam case S_DWDS_MCAST: STAT(dwds_mcast); 951178359Ssam case S_DWDS_QDROP: STAT(dwds_qdrop); 952173306Ssam case S_HT_ASSOC_NOHTCAP:STAT(ht_assoc_nohtcap); 953173306Ssam case S_HT_ASSOC_DOWNGRADE:STAT(ht_assoc_downgrade); 954173306Ssam case S_HT_ASSOC_NORATE: STAT(ht_assoc_norate); 955195618Srpaulo case S_MESH_WRONGMESH: STAT(mesh_wrongmesh); 956195618Srpaulo case S_MESH_NOLINK: STAT(mesh_nolink); 957195618Srpaulo case S_MESH_FWD_TTL: STAT(mesh_fwd_ttl); 958195618Srpaulo case S_MESH_FWD_NOBUF: STAT(mesh_fwd_nobuf); 959195618Srpaulo case S_MESH_FWD_TOOSHORT: STAT(mesh_fwd_tooshort); 960195618Srpaulo case S_MESH_FWD_DISABLED: STAT(mesh_fwd_disabled); 961195618Srpaulo case S_MESH_FWD_NOPATH: STAT(mesh_fwd_nopath); 962195618Srpaulo case S_HWMP_WRONGSEQ: STAT(hwmp_wrongseq); 963195618Srpaulo case S_HWMP_ROOTREQS: STAT(hwmp_rootreqs); 964195618Srpaulo case S_HWMP_ROOTANN: STAT(hwmp_rootrann); 965195811Ssam case S_MESH_BADAE: STAT(mesh_badae); 966195811Ssam case S_MESH_RTADDFAILED:STAT(mesh_rtaddfailed); 967195811Ssam case S_MESH_NOTPROXY: STAT(mesh_notproxy); 968195811Ssam case S_RX_BADALIGN: STAT(rx_badalign); 969161200Ssam case S_INPUT: NSTAT(rx_data); 970161200Ssam case S_OUTPUT: NSTAT(tx_data); 971161200Ssam case S_RX_UCAST: NSTAT(rx_ucast); 972161200Ssam case S_RX_MCAST: NSTAT(rx_mcast); 973161200Ssam case S_TX_UCAST: NSTAT(tx_ucast); 974161200Ssam case S_TX_MCAST: NSTAT(tx_mcast); 975161200Ssam } 976161200Ssam return wlan_getinfo(wf, s, b, bs); 977161200Ssam#undef NSTAT 978161200Ssam#undef STAT 979161200Ssam} 980161200Ssam 981161200SsamSTATFOO_DEFINE_BOUNCE(wlanstatfoo) 982161200Ssam 983161200Ssamstruct wlanstatfoo * 984161200Ssamwlanstats_new(const char *ifname, const char *fmtstring) 985161200Ssam{ 986161200Ssam#define N(a) (sizeof(a) / sizeof(a[0])) 987161200Ssam struct wlanstatfoo_p *wf; 988161200Ssam 989161200Ssam wf = calloc(1, sizeof(struct wlanstatfoo_p)); 990161200Ssam if (wf != NULL) { 991161200Ssam statfoo_init(&wf->base.base, "wlanstats", wlanstats, N(wlanstats)); 992161200Ssam /* override base methods */ 993161200Ssam wf->base.base.collect_cur = wlan_collect_cur; 994161200Ssam wf->base.base.collect_tot = wlan_collect_tot; 995161200Ssam wf->base.base.get_curstat = wlan_get_curstat; 996161200Ssam wf->base.base.get_totstat = wlan_get_totstat; 997161200Ssam wf->base.base.update_tot = wlan_update_tot; 998161200Ssam 999161200Ssam /* setup bounce functions for public methods */ 1000161200Ssam STATFOO_BOUNCE(wf, wlanstatfoo); 1001161200Ssam 1002161200Ssam /* setup our public methods */ 1003161200Ssam wf->base.setifname = wlan_setifname; 1004161200Ssam wf->base.getifname = wlan_getifname; 1005161200Ssam wf->base.getopmode = wlan_getopmode; 1006161200Ssam wf->base.setstamac = wlan_setstamac; 1007161200Ssam wf->opmode = -1; 1008161200Ssam 1009161200Ssam wf->s = socket(AF_INET, SOCK_DGRAM, 0); 1010161200Ssam if (wf->s < 0) 1011161200Ssam err(1, "socket"); 1012161200Ssam 1013161200Ssam wlan_setifname(&wf->base, ifname); 1014161200Ssam wf->base.setfmt(&wf->base, fmtstring); 1015161200Ssam } 1016161200Ssam return &wf->base; 1017161200Ssam#undef N 1018161200Ssam} 1019