wlanstats.c revision 173306
1/*- 2 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 3. Neither the names of the above-listed copyright holders nor the names 16 * of any contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * Alternatively, this software may be distributed under the terms of the 20 * GNU General Public License ("GPL") version 2 as published by the Free 21 * Software Foundation. 22 * 23 * NO WARRANTY 24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 26 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 28 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 29 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 34 * THE POSSIBILITY OF SUCH DAMAGES. 35 * 36 * $FreeBSD: head/tools/tools/net80211/wlanstats/wlanstats.c 173306 2007-11-03 18:14:12Z sam $ 37 */ 38 39/* 40 * net80211 statistics class. 41 */ 42#include <sys/types.h> 43#include <sys/file.h> 44#include <sys/sockio.h> 45#include <sys/socket.h> 46#include <net/if.h> 47#include <net/if_dl.h> 48#include <net/if_media.h> 49#include <net/if_var.h> 50#include <net/ethernet.h> 51 52#include <stdio.h> 53#include <stdlib.h> 54#include <signal.h> 55#include <string.h> 56#include <unistd.h> 57#include <err.h> 58#include <ifaddrs.h> 59 60#include "../../../../sys/net80211/ieee80211_ioctl.h" 61 62#include "wlanstats.h" 63 64#ifndef IEEE80211_ADDR_COPY 65#define IEEE80211_ADDR_COPY(dst, src) memcpy(dst, src, IEEE80211_ADDR_LEN) 66#define IEEE80211_ADDR_EQ(a1,a2) (memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0) 67#endif 68 69#define AFTER(prev) ((prev)+1) 70 71static const struct fmt wlanstats[] = { 72#define S_RX_BADVERSION 0 73 { 5, "rx_badversion", "bvers", "rx frame with bad version" }, 74#define S_RX_TOOSHORT AFTER(S_RX_BADVERSION) 75 { 5, "rx_tooshort", "2short", "rx frame too short" }, 76#define S_RX_WRONGBSS AFTER(S_RX_TOOSHORT) 77 { 5, "rx_wrongbss", "wrbss", "rx from wrong bssid" }, 78#define S_RX_DUP AFTER(S_RX_WRONGBSS) 79 { 5, "rx_dup", "rxdup", "rx discard 'cuz dup" }, 80#define S_RX_WRONGDIR AFTER(S_RX_DUP) 81 { 5, "rx_wrongdir", "wrdir", "rx w/ wrong direction" }, 82#define S_RX_MCASTECHO AFTER(S_RX_WRONGDIR) 83 { 5, "rx_mcastecho", "mecho", "rx discard 'cuz mcast echo" }, 84#define S_RX_NOTASSOC AFTER(S_RX_MCASTECHO) 85 { 6, "rx_notassoc", "!assoc", "rx discard 'cuz sta !assoc" }, 86#define S_RX_NOPRIVACY AFTER(S_RX_NOTASSOC) 87 { 6, "rx_noprivacy", "nopriv", "rx w/ wep but privacy off" }, 88#define S_RX_UNENCRYPTED AFTER(S_RX_NOPRIVACY) 89 { 6, "rx_unencrypted", "unencr", "rx w/o wep and privacy on" }, 90#define S_RX_WEPFAIL AFTER(S_RX_UNENCRYPTED) 91 { 7, "rx_wepfail", "wepfail", "rx wep processing failed" }, 92#define S_RX_DECAP AFTER(S_RX_WEPFAIL) 93 { 5, "rx_decap", "decap", "rx decapsulation failed" }, 94#define S_RX_MGTDISCARD AFTER(S_RX_DECAP) 95 { 8, "rx_mgtdiscard", "mgtdiscard", "rx discard mgt frames" }, 96#define S_RX_CTL AFTER(S_RX_MGTDISCARD) 97 { 5, "rx_ctl", "ctl", "rx ctrl frames" }, 98#define S_RX_BEACON AFTER(S_RX_CTL) 99 { 6, "rx_beacon", "beacon", "rx beacon frames" }, 100#define S_RX_RSTOOBIG AFTER(S_RX_BEACON) 101 { 6, "rx_rstoobig", "rs2big", "rx rate set truncated" }, 102#define S_RX_ELEM_MISSING AFTER(S_RX_RSTOOBIG) 103 { 6, "rx_elem_missing","iemiss", "rx required element missing" }, 104#define S_RX_ELEM_TOOBIG AFTER(S_RX_ELEM_MISSING) 105 { 6, "rx_elem_toobig", "ie2big", "rx element too big" }, 106#define S_RX_ELEM_TOOSMALL AFTER(S_RX_ELEM_TOOBIG) 107 { 7, "rx_elem_toosmall","ie2small","rx element too small" }, 108#define S_RX_ELEM_UNKNOWN AFTER(S_RX_ELEM_TOOSMALL) 109 { 5, "rx_elem_unknown","ieunk", "rx element unknown" }, 110#define S_RX_BADCHAN AFTER(S_RX_ELEM_UNKNOWN) 111 { 6, "rx_badchan", "badchan", "rx frame w/ invalid chan" }, 112#define S_RX_CHANMISMATCH AFTER(S_RX_BADCHAN) 113 { 5, "rx_chanmismatch","chanmismatch", "rx frame chan mismatch" }, 114#define S_RX_NODEALLOC AFTER(S_RX_CHANMISMATCH) 115 { 5, "rx_nodealloc", "nodealloc", "nodes allocated (rx)" }, 116#define S_RX_SSIDMISMATCH AFTER(S_RX_NODEALLOC) 117 { 5, "rx_ssidmismatch","ssidmismatch", "rx frame ssid mismatch" }, 118#define S_RX_AUTH_UNSUPPORTED AFTER(S_RX_SSIDMISMATCH) 119 { 5, "rx_auth_unsupported","auth_unsupported", 120 "rx w/ unsupported auth alg" }, 121#define S_RX_AUTH_FAIL AFTER(S_RX_AUTH_UNSUPPORTED) 122 { 5, "rx_auth_fail", "auth_fail", "rx sta auth failure" }, 123#define S_RX_AUTH_COUNTERMEASURES AFTER(S_RX_AUTH_FAIL) 124 { 5, "rx_auth_countermeasures", "auth_countermeasures", 125 "rx sta auth failure 'cuz of TKIP countermeasures" }, 126#define S_RX_ASSOC_BSS AFTER(S_RX_AUTH_COUNTERMEASURES) 127 { 5, "rx_assoc_bss", "assoc_bss", "rx assoc from wrong bssid" }, 128#define S_RX_ASSOC_NOTAUTH AFTER(S_RX_ASSOC_BSS) 129 { 5, "rx_assoc_notauth","assoc_notauth", "rx assoc w/o auth" }, 130#define S_RX_ASSOC_CAPMISMATCH AFTER(S_RX_ASSOC_NOTAUTH) 131 { 5, "rx_assoc_capmismatch","assoc_capmismatch", 132 "rx assoc w/ cap mismatch" }, 133#define S_RX_ASSOC_NORATE AFTER(S_RX_ASSOC_CAPMISMATCH) 134 { 5, "rx_assoc_norate","assoc_norate", "rx assoc w/ no rate match" }, 135#define S_RX_ASSOC_BADWPAIE AFTER(S_RX_ASSOC_NORATE) 136 { 5, "rx_assoc_badwpaie","assoc_badwpaie", 137 "rx assoc w/ bad WPA IE" }, 138#define S_RX_DEAUTH AFTER(S_RX_ASSOC_BADWPAIE) 139 { 5, "rx_deauth", "deauth", "rx deauthentication" }, 140#define S_RX_DISASSOC AFTER(S_RX_DEAUTH) 141 { 5, "rx_disassoc", "disassoc", "rx disassociation" }, 142#define S_RX_BADSUBTYPE AFTER(S_RX_DISASSOC) 143 { 5, "rx_badsubtype", "badsubtype", "rx frame w/ unknown subtype" }, 144#define S_RX_NOBUF AFTER(S_RX_BADSUBTYPE) 145 { 5, "rx_nobuf", "nobuf", "rx failed for lack of mbuf" }, 146#define S_RX_DECRYPTCRC AFTER(S_RX_NOBUF) 147 { 5, "rx_decryptcrc", "decryptcrc", "rx decrypt failed on crc" }, 148#define S_RX_AHDEMO_MGT AFTER(S_RX_DECRYPTCRC) 149 { 5, "rx_ahdemo_mgt", "ahdemo_mgt", 150 "rx discard mgmt frame received in ahdoc demo mode" }, 151#define S_RX_BAD_AUTH AFTER(S_RX_AHDEMO_MGT) 152 { 5, "rx_bad_auth", "bad_auth", "rx bad authentication request" }, 153#define S_RX_UNAUTH AFTER(S_RX_BAD_AUTH) 154 { 5, "rx_unauth", "unauth", 155 "rx discard 'cuz port unauthorized" }, 156#define S_RX_BADKEYID AFTER(S_RX_UNAUTH) 157 { 5, "rx_badkeyid", "badkeyid", "rx w/ incorrect keyid" }, 158#define S_RX_CCMPREPLAY AFTER(S_RX_BADKEYID) 159 { 5, "rx_ccmpreplay", "ccmpreplay", "rx seq# violation (CCMP)" }, 160#define S_RX_CCMPFORMAT AFTER(S_RX_CCMPREPLAY) 161 { 5, "rx_ccmpformat", "ccmpformat", "rx format bad (CCMP)" }, 162#define S_RX_CCMPMIC AFTER(S_RX_CCMPFORMAT) 163 { 5, "rx_ccmpmic", "ccmpmic", "rx MIC check failed (CCMP)" }, 164#define S_RX_TKIPREPLAY AFTER(S_RX_CCMPMIC) 165 { 5, "rx_tkipreplay", "tkipreplay", "rx seq# violation (TKIP)" }, 166#define S_RX_TKIPFORMAT AFTER(S_RX_TKIPREPLAY) 167 { 5, "rx_tkipformat", "tkipformat", "rx format bad (TKIP)" }, 168#define S_RX_TKIPMIC AFTER(S_RX_TKIPFORMAT) 169 { 5, "rx_tkipmic", "tkipmic", "rx MIC check failed (TKIP)" }, 170#define S_RX_TKIPICV AFTER(S_RX_TKIPMIC) 171 { 5, "rx_tkipicv", "tkipicv", "rx ICV check failed (TKIP)" }, 172#define S_RX_BADCIPHER AFTER(S_RX_TKIPICV) 173 { 5, "rx_badcipher", "badcipher", "rx failed 'cuz bad cipher/key type" }, 174#define S_RX_NOCIPHERCTX AFTER(S_RX_BADCIPHER) 175 { 5, "rx_nocipherctx", "nocipherctx", "rx failed 'cuz key/cipher ctx not setup" }, 176#define S_RX_ACL AFTER(S_RX_NOCIPHERCTX) 177 { 5, "rx_acl", "acl", "rx discard 'cuz acl policy" }, 178#define S_TX_NOBUF AFTER(S_RX_ACL) 179 { 5, "tx_nobuf", "nobuf", "tx failed for lack of mbuf" }, 180#define S_TX_NONODE AFTER(S_TX_NOBUF) 181 { 5, "tx_nonode", "nonode", "tx failed for no node" }, 182#define S_TX_UNKNOWNMGT AFTER(S_TX_NONODE) 183 { 5, "tx_unknownmgt", "unknownmgt", "tx of unknown mgt frame" }, 184#define S_TX_BADCIPHER AFTER(S_TX_UNKNOWNMGT) 185 { 5, "tx_badcipher", "badcipher", "tx failed 'cuz bad ciper/key type" }, 186#define S_TX_NODEFKEY AFTER(S_TX_BADCIPHER) 187 { 5, "tx_nodefkey", "nodefkey", "tx failed 'cuz no defkey" }, 188#define S_TX_NOHEADROOM AFTER(S_TX_NODEFKEY) 189 { 5, "tx_noheadroom", "noheadroom", "tx failed 'cuz no space for crypto hdrs" }, 190#define S_TX_FRAGFRAMES AFTER(S_TX_NOHEADROOM) 191 { 5, "tx_fragframes", "fragframes", "tx frames fragmented" }, 192#define S_TX_FRAGS AFTER(S_TX_FRAGFRAMES) 193 { 5, "tx_frags", "frags", "tx frags generated" }, 194#define S_SCAN_ACTIVE AFTER(S_TX_FRAGS) 195 { 5, "scan_active", "scan_active", "active scans started" }, 196#define S_SCAN_PASSIVE AFTER(S_SCAN_ACTIVE) 197 { 5, "scan_passive", "scan_passive", "passive scans started" }, 198#define S_NODE_TIMEOUT AFTER(S_SCAN_PASSIVE) 199 { 5, "node_timeout", "node_timeout", "nodes timed out for inactivity" }, 200#define S_CRYPTO_NOMEM AFTER(S_NODE_TIMEOUT) 201 { 5, "crypto_nomem", "crypto_nomem", "cipher context malloc failed" }, 202#define S_CRYPTO_TKIP AFTER(S_CRYPTO_NOMEM) 203 { 5, "crypto_tkip", "crypto_tkip", "tkip crypto done in s/w" }, 204#define S_CRYPTO_TKIPENMIC AFTER(S_CRYPTO_TKIP) 205 { 5, "crypto_tkipenmic","crypto_tkipenmic", "tkip tx MIC done in s/w" }, 206#define S_CRYPTO_TKIPDEMIC AFTER(S_CRYPTO_TKIPENMIC) 207 { 5, "crypto_tkipdemic","crypto_tkipdemic", "tkip rx MIC done in s/w" }, 208#define S_CRYPTO_TKIPCM AFTER(S_CRYPTO_TKIPDEMIC) 209 { 5, "crypto_tkipcm", "crypto_tkipcm", "tkip dropped frames 'cuz of countermeasures" }, 210#define S_CRYPTO_CCMP AFTER(S_CRYPTO_TKIPCM) 211 { 5, "crypto_ccmp", "crypto_ccmp", "ccmp crypto done in s/w" }, 212#define S_CRYPTO_WEP AFTER(S_CRYPTO_CCMP) 213 { 5, "crypto_wep", "crypto_wep", "wep crypto done in s/w" }, 214#define S_CRYPTO_SETKEY_CIPHER AFTER(S_CRYPTO_WEP) 215 { 5, "crypto_setkey_cipher", "crypto_setkey_cipher","setkey failed 'cuz cipher rejected data" }, 216#define S_CRYPTO_SETKEY_NOKEY AFTER(S_CRYPTO_SETKEY_CIPHER) 217 { 5, "crypto_setkey_nokey", "crypto_setkey_nokey","setkey failed 'cuz no key index" }, 218#define S_CRYPTO_DELKEY AFTER(S_CRYPTO_SETKEY_NOKEY) 219 { 5, "crypto_delkey", "crypto_delkey", "driver key delete failed" }, 220#define S_CRYPTO_BADCIPHER AFTER(S_CRYPTO_DELKEY) 221 { 5, "crypto_badcipher","crypto_badcipher", "setkey failed 'cuz unknown cipher" }, 222#define S_CRYPTO_NOCIPHER AFTER(S_CRYPTO_BADCIPHER) 223 { 5, "crypto_nocipher","crypto_nocipher", "setkey failed 'cuz cipher module unavailable" }, 224#define S_CRYPTO_ATTACHFAIL AFTER(S_CRYPTO_NOCIPHER) 225 { 5, "crypto_attachfail","crypto_attachfail", "setkey failed 'cuz cipher attach failed" }, 226#define S_CRYPTO_SWFALLBACK AFTER(S_CRYPTO_ATTACHFAIL) 227 { 5, "crypto_swfallback","crypto_swfallback", "crypto fell back to s/w implementation" }, 228#define S_CRYPTO_KEYFAIL AFTER(S_CRYPTO_SWFALLBACK) 229 { 5, "crypto_keyfail", "crypto_keyfail", "setkey failed 'cuz driver key alloc failed" }, 230#define S_CRYPTO_ENMICFAIL AFTER(S_CRYPTO_KEYFAIL) 231 { 5, "crypto_enmicfail","crypto_enmicfail", "enmic failed (may be mbuf exhaustion)" }, 232#define S_IBSS_CAPMISMATCH AFTER(S_CRYPTO_ENMICFAIL) 233 { 5, "ibss_capmismatch","ibss_capmismatch", "ibss merge faied 'cuz capabilities mismatch" }, 234#define S_IBSS_NORATE AFTER(S_IBSS_CAPMISMATCH) 235 { 5, "ibss_norate", "ibss_norate", "ibss merge faied 'cuz rate set mismatch" }, 236#define S_PS_UNASSOC AFTER(S_IBSS_NORATE) 237 { 5, "ps_unassoc", "ps_unassoc", "ps-poll received for unassociated station" }, 238#define S_PS_BADAID AFTER(S_PS_UNASSOC) 239 { 5, "ps_badaid", "ps_badaid", "ps-poll received with invalid association id" }, 240#define S_PS_QEMPTY AFTER(S_PS_BADAID) 241 { 5, "ps_qempty", "ps_qempty", "ps-poll received with nothing to send" }, 242#define S_FF_BADHDR AFTER(S_PS_QEMPTY) 243 { 5, "ff_badhdr", "ff_badhdr", "fast frame rx'd w/ bad hdr" }, 244#define S_FF_TOOSHORT AFTER(S_FF_BADHDR) 245 { 5, "ff_tooshort", "ff_tooshort", "fast frame rx decap error" }, 246#define S_FF_SPLIT AFTER(S_FF_TOOSHORT) 247 { 5, "ff_split", "ff_split", "fast frame rx split error" }, 248#define S_FF_DECAP AFTER(S_FF_SPLIT) 249 { 5, "ff_decap", "ff_decap", "fast frames decap'd" }, 250#define S_FF_ENCAP AFTER(S_FF_DECAP) 251 { 5, "ff_encap", "ff_encap", "fast frames encap'd for tx" }, 252#define S_FF_ENCAPFAIL AFTER(S_FF_ENCAP) 253 { 5, "ff_encapfail", "ff_encapfail", "fast frames encap failed" }, 254#define S_RX_BADBINTVAL AFTER(S_FF_ENCAPFAIL) 255 { 5, "rx_badbintval", "rx_badbintval","rx frame with bogus beacon interval" }, 256#define S_RX_MGMT AFTER(S_RX_BADBINTVAL) 257 { 5, "rx_mgmt", "rx_mgmt", "rx management frames" }, 258#define S_RX_DEMICFAIL AFTER(S_RX_MGMT) 259 { 5, "rx_demicfail", "rx_demicfail", "rx demic failed" }, 260#define S_RX_DEFRAG AFTER(S_RX_DEMICFAIL) 261 { 5, "rx_defrag", "rx_defrag", "rx defragmentation failed" }, 262#define S_RX_ACTION AFTER(S_RX_DEFRAG) 263 { 5, "rx_action", "rx_action", "rx action frames" }, 264#define S_AMSDU_TOOSHORT AFTER(S_RX_ACTION) 265 { 8, "amsdu_tooshort", "tooshort","A-MSDU rx decap error" }, 266#define S_AMSDU_SPLIT AFTER(S_AMSDU_TOOSHORT) 267 { 8, "amsdu_split", "split", "A-MSDU rx failed on frame split" }, 268#define S_AMSDU_DECAP AFTER(S_AMSDU_SPLIT) 269 { 8, "amsdu_decap", "decap", "A-MSDU frames received" }, 270#define S_AMSDU_ENCAP AFTER(S_AMSDU_DECAP) 271 { 8, "amsdu_encap", "encap", "A-MSDU frames transmitted" }, 272#define S_AMPDU_REORDER AFTER(S_AMSDU_ENCAP) 273 { 8, "ampdu_reorder", "reorder","A-MPDU frames held in reorder q" }, 274#define S_AMPDU_FLUSH AFTER(S_AMPDU_REORDER) 275 { 8, "ampdu_flush", "flush", "A-MPDU frames sent up from reorder q" }, 276#define S_AMPDU_BARBAD AFTER(S_AMPDU_FLUSH) 277 { 6, "ampdu_barbad", "barbad", "A-MPDU BAR rx before ADDBA exchange (or disabled with net.link.ieee80211)" }, 278#define S_AMPDU_BAROOW AFTER(S_AMPDU_BARBAD) 279 { 6, "ampdu_baroow", "baroow", "A-MPDU BAR rx out of BA window" }, 280#define S_AMPDU_BARMOVE AFTER(S_AMPDU_BAROOW) 281 { 8, "ampdu_barmove", "barmove","A-MPDU BAR rx moved BA window" }, 282#define S_AMPDU_BAR AFTER(S_AMPDU_BARMOVE) 283 { 8, "ampdu_bar", "rxbar", "A-MPDU BAR rx successful" }, 284#define S_AMPDU_MOVE AFTER(S_AMPDU_BAR) 285 { 5, "ampdu_move", "move", "A-MPDU frame moved BA window" }, 286#define S_AMPDU_OOR AFTER(S_AMPDU_MOVE) 287 { 8, "ampdu_oor", "oorx", "A-MPDU frames rx out-of-order" }, 288#define S_AMPDU_COPY AFTER(S_AMPDU_OOR) 289 { 8, "ampdu_copy", "copy", "A-MPDU rx window slots copied" }, 290#define S_AMPDU_DROP AFTER(S_AMPDU_COPY) 291 { 5, "ampdu_drop", "drop", "A-MPDU frames discarded for out of range seqno" }, 292#define S_AMPDU_AGE AFTER(S_AMPDU_DROP) 293 { 5, "ampdu_age", "age", "A-MPDU frames sent up due to old age" }, 294#define S_AMPDU_STOP AFTER(S_AMPDU_AGE) 295 { 5, "ampdu_stop", "stop", "A-MPDU streams stopped" }, 296#define S_AMPDU_STOP_FAILED AFTER(S_AMPDU_STOP) 297 { 5, "ampdu_stop_failed","!stop", "A-MPDU stop requests failed 'cuz stream not running" }, 298#define S_ADDBA_REJECT AFTER(S_AMPDU_STOP_FAILED) 299 { 5, "addba_reject", "reject", "ADDBA requests rejected 'cuz A-MPDU rx is disabled" }, 300#define S_ADDBA_NOREQUEST AFTER(S_ADDBA_REJECT) 301 { 5, "addba_norequest","norequest","ADDBA response frames discarded because no ADDBA request was pending" }, 302#define S_ADDBA_BADTOKEN AFTER(S_ADDBA_NOREQUEST) 303 { 5, "addba_badtoken", "badtoken","ADDBA response frames discarded 'cuz rx'd dialog token is wrong" }, 304#define S_TX_BADSTATE AFTER(S_ADDBA_BADTOKEN) 305 { 4, "tx_badstate", "badstate", "tx failed 'cuz vap not in RUN state" }, 306#define S_TX_NOTASSOC AFTER(S_TX_BADSTATE) 307 { 4, "tx_notassoc", "notassoc", "tx failed 'cuz dest sta not associated" }, 308#define S_TX_CLASSIFY AFTER(S_TX_NOTASSOC) 309 { 4, "tx_classify", "classify", "tx packet classification failed" }, 310#define S_DWDS_MCAST AFTER(S_TX_CLASSIFY) 311 { 8, "dwds_mcast", "dwds_mcast", "mcast frame transmitted on dwds vap discarded" }, 312#define S_DWDS_QDROP AFTER(S_DWDS_MCAST) 313 { 8, "dwds_qdrop", "dwds_qdrop", "4-address frame discarded because dwds pending queue is full" }, 314#define S_HT_ASSOC_NOHTCAP AFTER(S_DWDS_QDROP) 315 { 4, "ht_nohtcap", "ht_nohtcap", "non-HT station rejected in HT-only BSS" }, 316#define S_HT_ASSOC_DOWNGRADE AFTER(S_HT_ASSOC_NOHTCAP) 317 { 4, "ht_downgrade", "ht_downgrade", "HT station downgraded to legacy operation" }, 318#define S_HT_ASSOC_NORATE AFTER(S_HT_ASSOC_DOWNGRADE) 319 { 4, "ht_norate", "ht_norate", "HT station rejected because of HT rate set" }, 320#define S_INPUT AFTER(S_HT_ASSOC_NORATE) 321 { 8, "input", "input", "total data frames received" }, 322#define S_RX_UCAST AFTER(S_INPUT) 323 { 8, "rx_ucast", "rx_ucast", "unicast data frames received" }, 324#define S_RX_MCAST AFTER(S_RX_UCAST) 325 { 8, "rx_mcast", "rx_mcast", "multicast data frames received" }, 326#define S_OUTPUT AFTER(S_RX_MCAST) 327 { 8, "output", "output", "total data frames transmit" }, 328#define S_TX_UCAST AFTER(S_OUTPUT) 329 { 8, "tx_ucast", "tx_ucast", "unicast data frames sent" }, 330#define S_TX_MCAST AFTER(S_TX_UCAST) 331 { 8, "tx_mcast", "tx_mcast", "multicast data frames sent" }, 332#define S_RATE AFTER(S_TX_MCAST) 333 { 4, "rate", "rate", "current transmit rate" }, 334#define S_RSSI AFTER(S_RATE) 335 { 4, "rssi", "rssi", "current rssi" }, 336#define S_NOISE AFTER(S_RSSI) 337 { 4, "noise", "noise", "current noise floor (dBm)" }, 338#define S_SIGNAL AFTER(S_NOISE) 339 { 4, "signal", "sig", "current signal (dBm)" }, 340}; 341 342struct wlanstatfoo_p { 343 struct wlanstatfoo base; 344 int s; 345 int opmode; 346 uint8_t mac[IEEE80211_ADDR_LEN]; 347 struct ifreq ifr; 348 struct ieee80211_stats cur; 349 struct ieee80211_stats total; 350 struct ieee80211req ireq; 351 union { 352 struct ieee80211req_sta_req info; 353 char buf[1024]; 354 } u_info; 355 struct ieee80211req_sta_stats ncur; 356 struct ieee80211req_sta_stats ntotal; 357}; 358 359static void 360wlan_setifname(struct wlanstatfoo *wf0, const char *ifname) 361{ 362 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 363 364 strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name)); 365 strncpy(wf->ireq.i_name, ifname, sizeof (wf->ireq.i_name)); 366} 367 368static const char * 369wlan_getifname(struct wlanstatfoo *wf0) 370{ 371 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 372 373 return wf->ifr.ifr_name; 374} 375 376static int 377wlan_getopmode(struct wlanstatfoo *wf0) 378{ 379 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 380 381 if (wf->opmode == -1) { 382 struct ifmediareq ifmr; 383 384 memset(&ifmr, 0, sizeof(ifmr)); 385 strlcpy(ifmr.ifm_name, wf->ifr.ifr_name, sizeof(ifmr.ifm_name)); 386 if (ioctl(wf->s, SIOCGIFMEDIA, &ifmr) < 0) 387 err(1, "%s (SIOCGIFMEDIA)", wf->ifr.ifr_name); 388 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) 389 wf->opmode = IEEE80211_M_IBSS; /* XXX ahdemo */ 390 else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 391 wf->opmode = IEEE80211_M_HOSTAP; 392 else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 393 wf->opmode = IEEE80211_M_MONITOR; 394 else 395 wf->opmode = IEEE80211_M_STA; 396 } 397 return wf->opmode; 398} 399 400static void 401getlladdr(struct wlanstatfoo_p *wf) 402{ 403 const struct sockaddr_dl *sdl; 404 struct ifaddrs *ifp, *p; 405 406 if (getifaddrs(&ifp) != 0) 407 err(1, "getifaddrs"); 408 for (p = ifp; p != NULL; p = p->ifa_next) 409 if (strcmp(p->ifa_name, wf->ifr.ifr_name) == 0 && 410 p->ifa_addr->sa_family == AF_LINK) 411 break; 412 if (p == NULL) 413 errx(1, "did not find link layer address for interface %s", 414 wf->ifr.ifr_name); 415 sdl = (const struct sockaddr_dl *) p->ifa_addr; 416 IEEE80211_ADDR_COPY(wf->mac, LLADDR(sdl)); 417 freeifaddrs(ifp); 418} 419 420static void 421wlan_setstamac(struct wlanstatfoo *wf0, const uint8_t *mac) 422{ 423 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 424 425 if (mac == NULL) { 426 switch (wlan_getopmode(wf0)) { 427 case IEEE80211_M_HOSTAP: 428 case IEEE80211_M_MONITOR: 429 case IEEE80211_M_IBSS: 430 case IEEE80211_M_AHDEMO: 431 getlladdr(wf); 432 break; 433 case IEEE80211_M_STA: 434 wf->ireq.i_type = IEEE80211_IOC_BSSID; 435 wf->ireq.i_data = wf->mac; 436 wf->ireq.i_len = IEEE80211_ADDR_LEN; 437 if (ioctl(wf->s, SIOCG80211, &wf->ireq) <0) 438 err(1, "%s (IEEE80211_IOC_BSSID)", wf->ireq.i_name); 439 break; 440 } 441 } else 442 IEEE80211_ADDR_COPY(wf->mac, mac); 443} 444 445/* XXX only fetch what's needed to do reports */ 446static void 447wlan_collect(struct wlanstatfoo_p *wf, 448 struct ieee80211_stats *stats, struct ieee80211req_sta_stats *nstats) 449{ 450 451 IEEE80211_ADDR_COPY(wf->u_info.info.is_u.macaddr, wf->mac); 452 wf->ireq.i_type = IEEE80211_IOC_STA_INFO; 453 wf->ireq.i_data = (caddr_t) &wf->u_info; 454 wf->ireq.i_len = sizeof(wf->u_info); 455 if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) 456 err(1, "%s (IEEE80211_IOC_STA_INFO)", wf->ireq.i_name); 457 458 IEEE80211_ADDR_COPY(nstats->is_u.macaddr, wf->mac); 459 wf->ireq.i_type = IEEE80211_IOC_STA_STATS; 460 wf->ireq.i_data = (caddr_t) nstats; 461 wf->ireq.i_len = sizeof(*nstats); 462 if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) 463 err(1, "%s (IEEE80211_IOC_STA_STATS)", wf->ireq.i_name); 464 465 wf->ifr.ifr_data = (caddr_t) stats; 466 if (ioctl(wf->s, SIOCG80211STATS, &wf->ifr) < 0) 467 err(1, "%s (SIOCG80211STATS)", wf->ifr.ifr_name); 468} 469 470static void 471wlan_collect_cur(struct statfoo *sf) 472{ 473 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 474 475 wlan_collect(wf, &wf->cur, &wf->ncur); 476} 477 478static void 479wlan_collect_tot(struct statfoo *sf) 480{ 481 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 482 483 wlan_collect(wf, &wf->total, &wf->ntotal); 484} 485 486static void 487wlan_update_tot(struct statfoo *sf) 488{ 489 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 490 491 wf->total = wf->cur; 492 wf->ntotal = wf->ncur; 493} 494 495static int 496wlan_getinfo(struct wlanstatfoo_p *wf, int s, char b[], size_t bs) 497{ 498 const struct ieee80211req_sta_info *si = &wf->u_info.info.info[0]; 499 uint8_t r; 500 501 switch (s) { 502 case S_RATE: 503 r = si->isi_rates[si->isi_txrate]; 504 snprintf(b, bs, "%uM", (r &~ 0x80) / 2); 505 return 1; 506 case S_RSSI: 507 snprintf(b, bs, "%d", si->isi_rssi); 508 return 1; 509 case S_NOISE: 510 snprintf(b, bs, "%d", si->isi_noise); 511 return 1; 512 case S_SIGNAL: 513 snprintf(b, bs, "%d", si->isi_rssi + si->isi_noise); 514 return 1; 515 } 516 b[0] = '\0'; 517 return 0; 518} 519 520static int 521wlan_get_curstat(struct statfoo *sf, int s, char b[], size_t bs) 522{ 523 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 524#define STAT(x) \ 525 snprintf(b, bs, "%u", wf->cur.is_##x - wf->total.is_##x); return 1 526#define NSTAT(x) \ 527 snprintf(b, bs, "%u", \ 528 wf->ncur.is_stats.ns_##x - wf->ntotal.is_stats.ns_##x); \ 529 return 1 530 531 switch (s) { 532 case S_RX_BADVERSION: STAT(rx_badversion); 533 case S_RX_TOOSHORT: STAT(rx_tooshort); 534 case S_RX_WRONGBSS: STAT(rx_wrongbss); 535 case S_RX_DUP: STAT(rx_dup); 536 case S_RX_WRONGDIR: STAT(rx_wrongdir); 537 case S_RX_MCASTECHO: STAT(rx_mcastecho); 538 case S_RX_NOTASSOC: STAT(rx_notassoc); 539 case S_RX_NOPRIVACY: STAT(rx_noprivacy); 540 case S_RX_UNENCRYPTED: STAT(rx_unencrypted); 541 case S_RX_WEPFAIL: STAT(rx_wepfail); 542 case S_RX_DECAP: STAT(rx_decap); 543 case S_RX_MGTDISCARD: STAT(rx_mgtdiscard); 544 case S_RX_CTL: STAT(rx_ctl); 545 case S_RX_BEACON: STAT(rx_beacon); 546 case S_RX_RSTOOBIG: STAT(rx_rstoobig); 547 case S_RX_ELEM_MISSING: STAT(rx_elem_missing); 548 case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig); 549 case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall); 550 case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown); 551 case S_RX_BADCHAN: STAT(rx_badchan); 552 case S_RX_CHANMISMATCH: STAT(rx_chanmismatch); 553 case S_RX_NODEALLOC: STAT(rx_nodealloc); 554 case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch); 555 case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported); 556 case S_RX_AUTH_FAIL: STAT(rx_auth_fail); 557 case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures); 558 case S_RX_ASSOC_BSS: STAT(rx_assoc_bss); 559 case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth); 560 case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch); 561 case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate); 562 case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie); 563 case S_RX_DEAUTH: STAT(rx_deauth); 564 case S_RX_DISASSOC: STAT(rx_disassoc); 565 case S_RX_BADSUBTYPE: STAT(rx_badsubtype); 566 case S_RX_NOBUF: STAT(rx_nobuf); 567 case S_RX_DECRYPTCRC: STAT(rx_decryptcrc); 568 case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt); 569 case S_RX_BAD_AUTH: STAT(rx_bad_auth); 570 case S_RX_UNAUTH: STAT(rx_unauth); 571 case S_RX_BADKEYID: STAT(rx_badkeyid); 572 case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay); 573 case S_RX_CCMPFORMAT: STAT(rx_ccmpformat); 574 case S_RX_CCMPMIC: STAT(rx_ccmpmic); 575 case S_RX_TKIPREPLAY: STAT(rx_tkipreplay); 576 case S_RX_TKIPFORMAT: STAT(rx_tkipformat); 577 case S_RX_TKIPMIC: STAT(rx_tkipmic); 578 case S_RX_TKIPICV: STAT(rx_tkipicv); 579 case S_RX_BADCIPHER: STAT(rx_badcipher); 580 case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx); 581 case S_RX_ACL: STAT(rx_acl); 582 case S_TX_NOBUF: STAT(tx_nobuf); 583 case S_TX_NONODE: STAT(tx_nonode); 584 case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt); 585 case S_TX_BADCIPHER: STAT(tx_badcipher); 586 case S_TX_NODEFKEY: STAT(tx_nodefkey); 587 case S_TX_NOHEADROOM: STAT(tx_noheadroom); 588 case S_TX_FRAGFRAMES: STAT(tx_fragframes); 589 case S_TX_FRAGS: STAT(tx_frags); 590 case S_SCAN_ACTIVE: STAT(scan_active); 591 case S_SCAN_PASSIVE: STAT(scan_passive); 592 case S_NODE_TIMEOUT: STAT(node_timeout); 593 case S_CRYPTO_NOMEM: STAT(crypto_nomem); 594 case S_CRYPTO_TKIP: STAT(crypto_tkip); 595 case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic); 596 case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic); 597 case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm); 598 case S_CRYPTO_CCMP: STAT(crypto_ccmp); 599 case S_CRYPTO_WEP: STAT(crypto_wep); 600 case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher); 601 case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey); 602 case S_CRYPTO_DELKEY: STAT(crypto_delkey); 603 case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher); 604 case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher); 605 case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail); 606 case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback); 607 case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail); 608 case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail); 609 case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch); 610 case S_IBSS_NORATE: STAT(ibss_norate); 611 case S_PS_UNASSOC: STAT(ps_unassoc); 612 case S_PS_BADAID: STAT(ps_badaid); 613 case S_PS_QEMPTY: STAT(ps_qempty); 614 case S_FF_BADHDR: STAT(ff_badhdr); 615 case S_FF_TOOSHORT: STAT(ff_tooshort); 616 case S_FF_SPLIT: STAT(ff_split); 617 case S_FF_DECAP: STAT(ff_decap); 618 case S_FF_ENCAP: STAT(ff_encap); 619 case S_RX_BADBINTVAL: STAT(rx_badbintval); 620 case S_RX_MGMT: STAT(rx_mgmt); 621 case S_RX_DEMICFAIL: STAT(rx_demicfail); 622 case S_RX_DEFRAG: STAT(rx_defrag); 623 case S_RX_ACTION: STAT(rx_action); 624 case S_AMSDU_TOOSHORT: STAT(amsdu_tooshort); 625 case S_AMSDU_SPLIT: STAT(amsdu_split); 626 case S_AMSDU_DECAP: STAT(amsdu_decap); 627 case S_AMSDU_ENCAP: STAT(amsdu_encap); 628 case S_AMPDU_REORDER: STAT(ampdu_rx_reorder); 629 case S_AMPDU_FLUSH: STAT(ampdu_rx_flush); 630 case S_AMPDU_BARBAD: STAT(ampdu_bar_bad); 631 case S_AMPDU_BAROOW: STAT(ampdu_bar_oow); 632 case S_AMPDU_BARMOVE: STAT(ampdu_bar_move); 633 case S_AMPDU_BAR: STAT(ampdu_bar_rx); 634 case S_AMPDU_MOVE: STAT(ampdu_rx_move); 635 case S_AMPDU_OOR: STAT(ampdu_rx_oor); 636 case S_AMPDU_COPY: STAT(ampdu_rx_copy); 637 case S_AMPDU_DROP: STAT(ampdu_rx_drop); 638 case S_AMPDU_AGE: STAT(ampdu_rx_age); 639 case S_AMPDU_STOP: STAT(ampdu_stop); 640 case S_AMPDU_STOP_FAILED:STAT(ampdu_stop_failed); 641 case S_ADDBA_REJECT: STAT(addba_reject); 642 case S_ADDBA_NOREQUEST: STAT(addba_norequest); 643 case S_ADDBA_BADTOKEN: STAT(addba_badtoken); 644 case S_TX_BADSTATE: STAT(tx_badstate); 645 case S_TX_NOTASSOC: STAT(tx_notassoc); 646 case S_TX_CLASSIFY: STAT(tx_classify); 647 case S_HT_ASSOC_NOHTCAP:STAT(ht_assoc_nohtcap); 648 case S_HT_ASSOC_DOWNGRADE:STAT(ht_assoc_downgrade); 649 case S_HT_ASSOC_NORATE: STAT(ht_assoc_norate); 650 case S_INPUT: NSTAT(rx_data); 651 case S_OUTPUT: NSTAT(tx_data); 652 case S_RX_UCAST: NSTAT(rx_ucast); 653 case S_RX_MCAST: NSTAT(rx_mcast); 654 case S_TX_UCAST: NSTAT(tx_ucast); 655 case S_TX_MCAST: NSTAT(tx_mcast); 656 } 657 return wlan_getinfo(wf, s, b, bs); 658#undef NSTAT 659#undef STAT 660} 661 662static int 663wlan_get_totstat(struct statfoo *sf, int s, char b[], size_t bs) 664{ 665 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 666#define STAT(x) \ 667 snprintf(b, bs, "%u", wf->total.is_##x); return 1 668#define NSTAT(x) \ 669 snprintf(b, bs, "%u", wf->ntotal.is_stats.ns_##x); return 1 670 671 switch (s) { 672 case S_RX_BADVERSION: STAT(rx_badversion); 673 case S_RX_TOOSHORT: STAT(rx_tooshort); 674 case S_RX_WRONGBSS: STAT(rx_wrongbss); 675 case S_RX_DUP: STAT(rx_dup); 676 case S_RX_WRONGDIR: STAT(rx_wrongdir); 677 case S_RX_MCASTECHO: STAT(rx_mcastecho); 678 case S_RX_NOTASSOC: STAT(rx_notassoc); 679 case S_RX_NOPRIVACY: STAT(rx_noprivacy); 680 case S_RX_UNENCRYPTED: STAT(rx_unencrypted); 681 case S_RX_WEPFAIL: STAT(rx_wepfail); 682 case S_RX_DECAP: STAT(rx_decap); 683 case S_RX_MGTDISCARD: STAT(rx_mgtdiscard); 684 case S_RX_CTL: STAT(rx_ctl); 685 case S_RX_BEACON: STAT(rx_beacon); 686 case S_RX_RSTOOBIG: STAT(rx_rstoobig); 687 case S_RX_ELEM_MISSING: STAT(rx_elem_missing); 688 case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig); 689 case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall); 690 case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown); 691 case S_RX_BADCHAN: STAT(rx_badchan); 692 case S_RX_CHANMISMATCH: STAT(rx_chanmismatch); 693 case S_RX_NODEALLOC: STAT(rx_nodealloc); 694 case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch); 695 case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported); 696 case S_RX_AUTH_FAIL: STAT(rx_auth_fail); 697 case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures); 698 case S_RX_ASSOC_BSS: STAT(rx_assoc_bss); 699 case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth); 700 case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch); 701 case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate); 702 case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie); 703 case S_RX_DEAUTH: STAT(rx_deauth); 704 case S_RX_DISASSOC: STAT(rx_disassoc); 705 case S_RX_BADSUBTYPE: STAT(rx_badsubtype); 706 case S_RX_NOBUF: STAT(rx_nobuf); 707 case S_RX_DECRYPTCRC: STAT(rx_decryptcrc); 708 case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt); 709 case S_RX_BAD_AUTH: STAT(rx_bad_auth); 710 case S_RX_UNAUTH: STAT(rx_unauth); 711 case S_RX_BADKEYID: STAT(rx_badkeyid); 712 case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay); 713 case S_RX_CCMPFORMAT: STAT(rx_ccmpformat); 714 case S_RX_CCMPMIC: STAT(rx_ccmpmic); 715 case S_RX_TKIPREPLAY: STAT(rx_tkipreplay); 716 case S_RX_TKIPFORMAT: STAT(rx_tkipformat); 717 case S_RX_TKIPMIC: STAT(rx_tkipmic); 718 case S_RX_TKIPICV: STAT(rx_tkipicv); 719 case S_RX_BADCIPHER: STAT(rx_badcipher); 720 case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx); 721 case S_RX_ACL: STAT(rx_acl); 722 case S_TX_NOBUF: STAT(tx_nobuf); 723 case S_TX_NONODE: STAT(tx_nonode); 724 case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt); 725 case S_TX_BADCIPHER: STAT(tx_badcipher); 726 case S_TX_NODEFKEY: STAT(tx_nodefkey); 727 case S_TX_NOHEADROOM: STAT(tx_noheadroom); 728 case S_TX_FRAGFRAMES: STAT(tx_fragframes); 729 case S_TX_FRAGS: STAT(tx_frags); 730 case S_SCAN_ACTIVE: STAT(scan_active); 731 case S_SCAN_PASSIVE: STAT(scan_passive); 732 case S_NODE_TIMEOUT: STAT(node_timeout); 733 case S_CRYPTO_NOMEM: STAT(crypto_nomem); 734 case S_CRYPTO_TKIP: STAT(crypto_tkip); 735 case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic); 736 case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic); 737 case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm); 738 case S_CRYPTO_CCMP: STAT(crypto_ccmp); 739 case S_CRYPTO_WEP: STAT(crypto_wep); 740 case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher); 741 case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey); 742 case S_CRYPTO_DELKEY: STAT(crypto_delkey); 743 case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher); 744 case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher); 745 case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail); 746 case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback); 747 case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail); 748 case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail); 749 case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch); 750 case S_IBSS_NORATE: STAT(ibss_norate); 751 case S_PS_UNASSOC: STAT(ps_unassoc); 752 case S_PS_BADAID: STAT(ps_badaid); 753 case S_PS_QEMPTY: STAT(ps_qempty); 754 case S_FF_BADHDR: STAT(ff_badhdr); 755 case S_FF_TOOSHORT: STAT(ff_tooshort); 756 case S_FF_SPLIT: STAT(ff_split); 757 case S_FF_DECAP: STAT(ff_decap); 758 case S_FF_ENCAP: STAT(ff_encap); 759 case S_RX_BADBINTVAL: STAT(rx_badbintval); 760 case S_RX_MGMT: STAT(rx_mgmt); 761 case S_RX_DEMICFAIL: STAT(rx_demicfail); 762 case S_RX_DEFRAG: STAT(rx_defrag); 763 case S_RX_ACTION: STAT(rx_action); 764 case S_AMSDU_TOOSHORT: STAT(amsdu_tooshort); 765 case S_AMSDU_SPLIT: STAT(amsdu_split); 766 case S_AMSDU_DECAP: STAT(amsdu_decap); 767 case S_AMSDU_ENCAP: STAT(amsdu_encap); 768 case S_AMPDU_REORDER: STAT(ampdu_rx_reorder); 769 case S_AMPDU_FLUSH: STAT(ampdu_rx_flush); 770 case S_AMPDU_BARBAD: STAT(ampdu_bar_bad); 771 case S_AMPDU_BAROOW: STAT(ampdu_bar_oow); 772 case S_AMPDU_BARMOVE: STAT(ampdu_bar_move); 773 case S_AMPDU_BAR: STAT(ampdu_bar_rx); 774 case S_AMPDU_MOVE: STAT(ampdu_rx_move); 775 case S_AMPDU_OOR: STAT(ampdu_rx_oor); 776 case S_AMPDU_COPY: STAT(ampdu_rx_copy); 777 case S_AMPDU_DROP: STAT(ampdu_rx_drop); 778 case S_AMPDU_AGE: STAT(ampdu_rx_age); 779 case S_AMPDU_STOP: STAT(ampdu_stop); 780 case S_AMPDU_STOP_FAILED:STAT(ampdu_stop_failed); 781 case S_ADDBA_REJECT: STAT(addba_reject); 782 case S_ADDBA_NOREQUEST: STAT(addba_norequest); 783 case S_ADDBA_BADTOKEN: STAT(addba_badtoken); 784 case S_TX_BADSTATE: STAT(tx_badstate); 785 case S_TX_NOTASSOC: STAT(tx_notassoc); 786 case S_TX_CLASSIFY: STAT(tx_classify); 787 case S_HT_ASSOC_NOHTCAP:STAT(ht_assoc_nohtcap); 788 case S_HT_ASSOC_DOWNGRADE:STAT(ht_assoc_downgrade); 789 case S_HT_ASSOC_NORATE: STAT(ht_assoc_norate); 790 case S_INPUT: NSTAT(rx_data); 791 case S_OUTPUT: NSTAT(tx_data); 792 case S_RX_UCAST: NSTAT(rx_ucast); 793 case S_RX_MCAST: NSTAT(rx_mcast); 794 case S_TX_UCAST: NSTAT(tx_ucast); 795 case S_TX_MCAST: NSTAT(tx_mcast); 796 } 797 return wlan_getinfo(wf, s, b, bs); 798#undef NSTAT 799#undef STAT 800} 801 802STATFOO_DEFINE_BOUNCE(wlanstatfoo) 803 804struct wlanstatfoo * 805wlanstats_new(const char *ifname, const char *fmtstring) 806{ 807#define N(a) (sizeof(a) / sizeof(a[0])) 808 struct wlanstatfoo_p *wf; 809 810 wf = calloc(1, sizeof(struct wlanstatfoo_p)); 811 if (wf != NULL) { 812 statfoo_init(&wf->base.base, "wlanstats", wlanstats, N(wlanstats)); 813 /* override base methods */ 814 wf->base.base.collect_cur = wlan_collect_cur; 815 wf->base.base.collect_tot = wlan_collect_tot; 816 wf->base.base.get_curstat = wlan_get_curstat; 817 wf->base.base.get_totstat = wlan_get_totstat; 818 wf->base.base.update_tot = wlan_update_tot; 819 820 /* setup bounce functions for public methods */ 821 STATFOO_BOUNCE(wf, wlanstatfoo); 822 823 /* setup our public methods */ 824 wf->base.setifname = wlan_setifname; 825 wf->base.getifname = wlan_getifname; 826 wf->base.getopmode = wlan_getopmode; 827 wf->base.setstamac = wlan_setstamac; 828 wf->opmode = -1; 829 830 wf->s = socket(AF_INET, SOCK_DGRAM, 0); 831 if (wf->s < 0) 832 err(1, "socket"); 833 834 wlan_setifname(&wf->base, ifname); 835 wf->base.setfmt(&wf->base, fmtstring); 836 } 837 return &wf->base; 838#undef N 839} 840