1 /*- 2 * Copyright (c) 2002-2007 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 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 * 29 * $FreeBSD$ 30 */ 31 32 /* 33 * net80211 statistics class. 34 */ 35 36 #include <sys/param.h> 37 #include <sys/file.h> 38 #include <sys/sockio.h> 39 #include <sys/socket.h> 40 41 #include <net/if.h> 42 #include <net/if_dl.h> 43 #include <net/if_media.h> 44 #include <net/if_var.h> 45 #include <net/ethernet.h> 46 47 #include <err.h> 48 #include <ifaddrs.h> 49 #include <signal.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include <unistd.h> 54 55 #include "../../../../sys/net80211/ieee80211_ioctl.h" 56 57 #include "wlanstats.h" 58 59 #ifndef IEEE80211_ADDR_COPY 60 #define IEEE80211_ADDR_COPY(dst, src) memcpy(dst, src, IEEE80211_ADDR_LEN) 61 #define IEEE80211_ADDR_EQ(a1,a2) (memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0) 62 #endif 63 64 #define AFTER(prev) ((prev)+1) 65 66 static const struct fmt wlanstats[] = { 67 #define S_RX_BADVERSION 0 68 { 5, "rx_badversion", "bvers", "rx frame with bad version" }, 69 #define S_RX_TOOSHORT AFTER(S_RX_BADVERSION) 70 { 5, "rx_tooshort", "2short", "rx frame too short" }, 71 #define S_RX_WRONGBSS AFTER(S_RX_TOOSHORT) 72 { 5, "rx_wrongbss", "wrbss", "rx from wrong bssid" }, 73 #define S_RX_DUP AFTER(S_RX_WRONGBSS) 74 { 5, "rx_dup", "rxdup", "rx discard 'cuz dup" }, 75 #define S_RX_WRONGDIR AFTER(S_RX_DUP) 76 { 5, "rx_wrongdir", "wrdir", "rx w/ wrong direction" }, 77 #define S_RX_MCASTECHO AFTER(S_RX_WRONGDIR) 78 { 5, "rx_mcastecho", "mecho", "rx discard 'cuz mcast echo" }, 79 #define S_RX_NOTASSOC AFTER(S_RX_MCASTECHO) 80 { 6, "rx_notassoc", "!assoc", "rx discard 'cuz sta !assoc" }, 81 #define S_RX_NOPRIVACY AFTER(S_RX_NOTASSOC) 82 { 6, "rx_noprivacy", "nopriv", "rx w/ wep but privacy off" }, 83 #define S_RX_UNENCRYPTED AFTER(S_RX_NOPRIVACY) 84 { 6, "rx_unencrypted", "unencr", "rx w/o wep and privacy on" }, 85 #define S_RX_WEPFAIL AFTER(S_RX_UNENCRYPTED) 86 { 7, "rx_wepfail", "wepfail", "rx wep processing failed" }, 87 #define S_RX_DECAP AFTER(S_RX_WEPFAIL) 88 { 5, "rx_decap", "decap", "rx decapsulation failed" }, 89 #define S_RX_MGTDISCARD AFTER(S_RX_DECAP) 90 { 8, "rx_mgtdiscard", "mgtdiscard", "rx discard mgt frames" }, 91 #define S_RX_CTL AFTER(S_RX_MGTDISCARD) 92 { 5, "rx_ctl", "ctl", "rx ctrl frames" }, 93 #define S_RX_BEACON AFTER(S_RX_CTL) 94 { 6, "rx_beacon", "beacon", "rx beacon frames" }, 95 #define S_RX_RSTOOBIG AFTER(S_RX_BEACON) 96 { 6, "rx_rstoobig", "rs2big", "rx rate set truncated" }, 97 #define S_RX_ELEM_MISSING AFTER(S_RX_RSTOOBIG) 98 { 6, "rx_elem_missing","iemiss", "rx required element missing" }, 99 #define S_RX_ELEM_TOOBIG AFTER(S_RX_ELEM_MISSING) 100 { 6, "rx_elem_toobig", "ie2big", "rx element too big" }, 101 #define S_RX_ELEM_TOOSMALL AFTER(S_RX_ELEM_TOOBIG) 102 { 7, "rx_elem_toosmall","ie2small","rx element too small" }, 103 #define S_RX_ELEM_UNKNOWN AFTER(S_RX_ELEM_TOOSMALL) 104 { 5, "rx_elem_unknown","ieunk", "rx element unknown" }, 105 #define S_RX_BADCHAN AFTER(S_RX_ELEM_UNKNOWN) 106 { 6, "rx_badchan", "badchan", "rx frame w/ invalid chan" }, 107 #define S_RX_CHANMISMATCH AFTER(S_RX_BADCHAN) 108 { 5, "rx_chanmismatch","chanmismatch", "rx frame chan mismatch" }, 109 #define S_RX_NODEALLOC AFTER(S_RX_CHANMISMATCH) 110 { 5, "rx_nodealloc", "nodealloc", "nodes allocated (rx)" }, 111 #define S_RX_SSIDMISMATCH AFTER(S_RX_NODEALLOC) 112 { 5, "rx_ssidmismatch","ssidmismatch", "rx frame ssid mismatch" }, 113 #define S_RX_AUTH_UNSUPPORTED AFTER(S_RX_SSIDMISMATCH) 114 { 5, "rx_auth_unsupported","auth_unsupported", 115 "rx w/ unsupported auth alg" }, 116 #define S_RX_AUTH_FAIL AFTER(S_RX_AUTH_UNSUPPORTED) 117 { 5, "rx_auth_fail", "auth_fail", "rx sta auth failure" }, 118 #define S_RX_AUTH_FAIL_CODE AFTER(S_RX_AUTH_FAIL) 119 { 5, "rx_auth_fail_code","auth_fail_code", 120 "last rx auth failure reason" }, 121 #define S_RX_AUTH_COUNTERMEASURES AFTER(S_RX_AUTH_FAIL_CODE) 122 { 5, "rx_auth_countermeasures", "auth_countermeasures", 123 "rx sta auth failure 'cuz of TKIP countermeasures" }, 124 #define S_RX_ASSOC_BSS AFTER(S_RX_AUTH_COUNTERMEASURES) 125 { 5, "rx_assoc_bss", "assoc_bss", "rx assoc from wrong bssid" }, 126 #define S_RX_ASSOC_NOTAUTH AFTER(S_RX_ASSOC_BSS) 127 { 5, "rx_assoc_notauth","assoc_notauth", "rx assoc w/o auth" }, 128 #define S_RX_ASSOC_CAPMISMATCH AFTER(S_RX_ASSOC_NOTAUTH) 129 { 5, "rx_assoc_capmismatch","assoc_capmismatch", 130 "rx assoc w/ cap mismatch" }, 131 #define S_RX_ASSOC_NORATE AFTER(S_RX_ASSOC_CAPMISMATCH) 132 { 5, "rx_assoc_norate","assoc_norate", "rx assoc w/ no rate match" }, 133 #define S_RX_ASSOC_BADWPAIE AFTER(S_RX_ASSOC_NORATE) 134 { 5, "rx_assoc_badwpaie","assoc_badwpaie", 135 "rx assoc w/ bad WPA IE" }, 136 #define S_RX_DEAUTH AFTER(S_RX_ASSOC_BADWPAIE) 137 { 5, "rx_deauth", "deauth", "rx deauthentication" }, 138 #define S_RX_DEAUTH_CODE AFTER(S_RX_DEAUTH) 139 { 5, "rx_deauth_code","deauth_code", "last rx deauth reason" }, 140 #define S_RX_DISASSOC AFTER(S_RX_DEAUTH_CODE) 141 { 5, "rx_disassoc", "disassoc", "rx disassociation" }, 142 #define S_RX_DISASSOC_CODE AFTER(S_RX_DISASSOC) 143 { 5, "rx_disassoc_code","disassoc_code", 144 "last rx disassoc reason" }, 145 #define S_BMISS AFTER(S_RX_DISASSOC_CODE) 146 { 5, "bmiss", "bmiss", "beacon miss events handled" }, 147 #define S_RX_BADSUBTYPE AFTER(S_BMISS) 148 { 5, "rx_badsubtype", "badsubtype", "rx frame w/ unknown subtype" }, 149 #define S_RX_NOBUF AFTER(S_RX_BADSUBTYPE) 150 { 5, "rx_nobuf", "nobuf", "rx failed for lack of mbuf" }, 151 #define S_RX_DECRYPTCRC AFTER(S_RX_NOBUF) 152 { 5, "rx_decryptcrc", "decryptcrc", "rx decrypt failed on crc" }, 153 #define S_RX_AHDEMO_MGT AFTER(S_RX_DECRYPTCRC) 154 { 5, "rx_ahdemo_mgt", "ahdemo_mgt", 155 "rx discard mgmt frame received in ahdoc demo mode" }, 156 #define S_RX_BAD_AUTH AFTER(S_RX_AHDEMO_MGT) 157 { 5, "rx_bad_auth", "bad_auth", "rx bad authentication request" }, 158 #define S_RX_UNAUTH AFTER(S_RX_BAD_AUTH) 159 { 5, "rx_unauth", "unauth", 160 "rx discard 'cuz port unauthorized" }, 161 #define S_RX_BADKEYID AFTER(S_RX_UNAUTH) 162 { 5, "rx_badkeyid", "rxkid", "rx w/ incorrect keyid" }, 163 #define S_RX_CCMPREPLAY AFTER(S_RX_BADKEYID) 164 { 5, "rx_ccmpreplay", "ccmpreplay", "rx seq# violation (CCMP)" }, 165 #define S_RX_CCMPFORMAT AFTER(S_RX_CCMPREPLAY) 166 { 5, "rx_ccmpformat", "ccmpformat", "rx format bad (CCMP)" }, 167 #define S_RX_CCMPMIC AFTER(S_RX_CCMPFORMAT) 168 { 5, "rx_ccmpmic", "ccmpmic", "rx MIC check failed (CCMP)" }, 169 #define S_RX_TKIPREPLAY AFTER(S_RX_CCMPMIC) 170 { 5, "rx_tkipreplay", "tkipreplay", "rx seq# violation (TKIP)" }, 171 #define S_RX_TKIPFORMAT AFTER(S_RX_TKIPREPLAY) 172 { 5, "rx_tkipformat", "tkipformat", "rx format bad (TKIP)" }, 173 #define S_RX_TKIPMIC AFTER(S_RX_TKIPFORMAT) 174 { 5, "rx_tkipmic", "tkipmic", "rx MIC check failed (TKIP)" }, 175 #define S_RX_TKIPICV AFTER(S_RX_TKIPMIC) 176 { 5, "rx_tkipicv", "tkipicv", "rx ICV check failed (TKIP)" }, 177 #define S_RX_BADCIPHER AFTER(S_RX_TKIPICV) 178 { 5, "rx_badcipher", "badcipher", "rx failed 'cuz bad cipher/key type" }, 179 #define S_RX_NOCIPHERCTX AFTER(S_RX_BADCIPHER) 180 { 5, "rx_nocipherctx", "nocipherctx", "rx failed 'cuz key/cipher ctx not setup" }, 181 #define S_RX_ACL AFTER(S_RX_NOCIPHERCTX) 182 { 5, "rx_acl", "acl", "rx discard 'cuz acl policy" }, 183 #define S_TX_NOBUF AFTER(S_RX_ACL) 184 { 5, "tx_nobuf", "nobuf", "tx failed for lack of mbuf" }, 185 #define S_TX_NONODE AFTER(S_TX_NOBUF) 186 { 5, "tx_nonode", "nonode", "tx failed for no node" }, 187 #define S_TX_UNKNOWNMGT AFTER(S_TX_NONODE) 188 { 5, "tx_unknownmgt", "unknownmgt", "tx of unknown mgt frame" }, 189 #define S_TX_BADCIPHER AFTER(S_TX_UNKNOWNMGT) 190 { 5, "tx_badcipher", "badcipher", "tx failed 'cuz bad ciper/key type" }, 191 #define S_TX_NODEFKEY AFTER(S_TX_BADCIPHER) 192 { 5, "tx_nodefkey", "nodefkey", "tx failed 'cuz no defkey" }, 193 #define S_TX_NOHEADROOM AFTER(S_TX_NODEFKEY) 194 { 5, "tx_noheadroom", "noheadroom", "tx failed 'cuz no space for crypto hdrs" }, 195 #define S_TX_FRAGFRAMES AFTER(S_TX_NOHEADROOM) 196 { 5, "tx_fragframes", "fragframes", "tx frames fragmented" }, 197 #define S_TX_FRAGS AFTER(S_TX_FRAGFRAMES) 198 { 5, "tx_frags", "frags", "tx frags generated" }, 199 #define S_SCAN_ACTIVE AFTER(S_TX_FRAGS) 200 { 5, "scan_active", "ascan", "active scans started" }, 201 #define S_SCAN_PASSIVE AFTER(S_SCAN_ACTIVE) 202 { 5, "scan_passive", "pscan", "passive scans started" }, 203 #define S_SCAN_BG AFTER(S_SCAN_PASSIVE) 204 { 5, "scan_bg", "bgscn", "background scans started" }, 205 #define S_NODE_TIMEOUT AFTER(S_SCAN_BG) 206 { 5, "node_timeout", "node_timeout", "nodes timed out for inactivity" }, 207 #define S_CRYPTO_NOMEM AFTER(S_NODE_TIMEOUT) 208 { 5, "crypto_nomem", "crypto_nomem", "cipher context malloc failed" }, 209 #define S_CRYPTO_TKIP AFTER(S_CRYPTO_NOMEM) 210 { 5, "crypto_tkip", "crypto_tkip", "tkip crypto done in s/w" }, 211 #define S_CRYPTO_TKIPENMIC AFTER(S_CRYPTO_TKIP) 212 { 5, "crypto_tkipenmic","crypto_tkipenmic", "tkip tx MIC done in s/w" }, 213 #define S_CRYPTO_TKIPDEMIC AFTER(S_CRYPTO_TKIPENMIC) 214 { 5, "crypto_tkipdemic","crypto_tkipdemic", "tkip rx MIC done in s/w" }, 215 #define S_CRYPTO_TKIPCM AFTER(S_CRYPTO_TKIPDEMIC) 216 { 5, "crypto_tkipcm", "crypto_tkipcm", "tkip dropped frames 'cuz of countermeasures" }, 217 #define S_CRYPTO_CCMP AFTER(S_CRYPTO_TKIPCM) 218 { 5, "crypto_ccmp", "crypto_ccmp", "ccmp crypto done in s/w" }, 219 #define S_CRYPTO_WEP AFTER(S_CRYPTO_CCMP) 220 { 5, "crypto_wep", "crypto_wep", "wep crypto done in s/w" }, 221 #define S_CRYPTO_SETKEY_CIPHER AFTER(S_CRYPTO_WEP) 222 { 5, "crypto_setkey_cipher", "crypto_setkey_cipher","setkey failed 'cuz cipher rejected data" }, 223 #define S_CRYPTO_SETKEY_NOKEY AFTER(S_CRYPTO_SETKEY_CIPHER) 224 { 5, "crypto_setkey_nokey", "crypto_setkey_nokey","setkey failed 'cuz no key index" }, 225 #define S_CRYPTO_DELKEY AFTER(S_CRYPTO_SETKEY_NOKEY) 226 { 5, "crypto_delkey", "crypto_delkey", "driver key delete failed" }, 227 #define S_CRYPTO_BADCIPHER AFTER(S_CRYPTO_DELKEY) 228 { 5, "crypto_badcipher","crypto_badcipher", "setkey failed 'cuz unknown cipher" }, 229 #define S_CRYPTO_NOCIPHER AFTER(S_CRYPTO_BADCIPHER) 230 { 5, "crypto_nocipher","crypto_nocipher", "setkey failed 'cuz cipher module unavailable" }, 231 #define S_CRYPTO_ATTACHFAIL AFTER(S_CRYPTO_NOCIPHER) 232 { 5, "crypto_attachfail","crypto_attachfail", "setkey failed 'cuz cipher attach failed" }, 233 #define S_CRYPTO_SWFALLBACK AFTER(S_CRYPTO_ATTACHFAIL) 234 { 5, "crypto_swfallback","crypto_swfallback", "crypto fell back to s/w implementation" }, 235 #define S_CRYPTO_KEYFAIL AFTER(S_CRYPTO_SWFALLBACK) 236 { 5, "crypto_keyfail", "crypto_keyfail", "setkey failed 'cuz driver key alloc failed" }, 237 #define S_CRYPTO_ENMICFAIL AFTER(S_CRYPTO_KEYFAIL) 238 { 5, "crypto_enmicfail","crypto_enmicfail", "enmic failed (may be mbuf exhaustion)" }, 239 #define S_IBSS_CAPMISMATCH AFTER(S_CRYPTO_ENMICFAIL) 240 { 5, "ibss_capmismatch","ibss_capmismatch", "ibss merge faied 'cuz capabilities mismatch" }, 241 #define S_IBSS_NORATE AFTER(S_IBSS_CAPMISMATCH) 242 { 5, "ibss_norate", "ibss_norate", "ibss merge faied 'cuz rate set mismatch" }, 243 #define S_PS_UNASSOC AFTER(S_IBSS_NORATE) 244 { 5, "ps_unassoc", "ps_unassoc", "ps-poll received for unassociated station" }, 245 #define S_PS_BADAID AFTER(S_PS_UNASSOC) 246 { 5, "ps_badaid", "ps_badaid", "ps-poll received with invalid association id" }, 247 #define S_PS_QEMPTY AFTER(S_PS_BADAID) 248 { 5, "ps_qempty", "ps_qempty", "ps-poll received with nothing to send" }, 249 #define S_FF_BADHDR AFTER(S_PS_QEMPTY) 250 { 5, "ff_badhdr", "ff_badhdr", "fast frame rx'd w/ bad hdr" }, 251 #define S_FF_TOOSHORT AFTER(S_FF_BADHDR) 252 { 5, "ff_tooshort", "ff_tooshort", "fast frame rx decap error" }, 253 #define S_FF_SPLIT AFTER(S_FF_TOOSHORT) 254 { 5, "ff_split", "ff_split", "fast frame rx split error" }, 255 #define S_FF_DECAP AFTER(S_FF_SPLIT) 256 { 5, "ff_decap", "ff_decap", "fast frames decap'd" }, 257 #define S_FF_ENCAP AFTER(S_FF_DECAP) 258 { 5, "ff_encap", "ff_encap", "fast frames encap'd for tx" }, 259 #define S_FF_ENCAPFAIL AFTER(S_FF_ENCAP) 260 { 5, "ff_encapfail", "ff_encapfail", "fast frames encap failed" }, 261 #define S_RX_BADBINTVAL AFTER(S_FF_ENCAPFAIL) 262 { 5, "rx_badbintval", "rx_badbintval","rx frame with bogus beacon interval" }, 263 #define S_RX_MGMT AFTER(S_RX_BADBINTVAL) 264 { 8, "rx_mgmt", "mgmt", "rx management frames" }, 265 #define S_RX_DEMICFAIL AFTER(S_RX_MGMT) 266 { 5, "rx_demicfail", "rx_demicfail", "rx demic failed" }, 267 #define S_RX_DEFRAG AFTER(S_RX_DEMICFAIL) 268 { 5, "rx_defrag", "rx_defrag", "rx defragmentation failed" }, 269 #define S_RX_ACTION AFTER(S_RX_DEFRAG) 270 { 5, "rx_action", "rx_action", "rx action frames" }, 271 #define S_AMSDU_TOOSHORT AFTER(S_RX_ACTION) 272 { 8, "amsdu_tooshort", "tooshort","A-MSDU rx decap error" }, 273 #define S_AMSDU_SPLIT AFTER(S_AMSDU_TOOSHORT) 274 { 8, "amsdu_split", "split", "A-MSDU rx failed on frame split" }, 275 #define S_AMSDU_DECAP AFTER(S_AMSDU_SPLIT) 276 { 8, "amsdu_decap", "decap", "A-MSDU frames received" }, 277 #define S_AMSDU_ENCAP AFTER(S_AMSDU_DECAP) 278 { 8, "amsdu_encap", "encap", "A-MSDU frames transmitted" }, 279 #define S_AMSDU_RX_MORE AFTER(S_AMSDU_ENCAP) 280 { 13, "rx_amsdu_more", "rx_amsdu_more", "A-MSDU HW intermediary decap'ed received" }, 281 #define S_AMSDU_RX_MORE_END AFTER(S_AMSDU_RX_MORE) 282 { 17, "rx_amsdu_more_end", "rx_amsdu_more_end", "A-MSDU HW end decap'ed received" }, 283 #define S_AMPDU_REORDER AFTER(S_AMSDU_RX_MORE_END) 284 { 8, "ampdu_reorder", "reorder","A-MPDU frames held in reorder q" }, 285 #define S_AMPDU_FLUSH AFTER(S_AMPDU_REORDER) 286 { 8, "ampdu_flush", "flush", "A-MPDU frames sent up from reorder q" }, 287 #define S_AMPDU_BARBAD AFTER(S_AMPDU_FLUSH) 288 { 6, "ampdu_barbad", "barbad", "A-MPDU BAR rx before ADDBA exchange (or disabled with net.link.ieee80211)" }, 289 #define S_AMPDU_BAROOW AFTER(S_AMPDU_BARBAD) 290 { 6, "ampdu_baroow", "baroow", "A-MPDU BAR rx out of BA window" }, 291 #define S_AMPDU_BARMOVE AFTER(S_AMPDU_BAROOW) 292 { 8, "ampdu_barmove", "barmove","A-MPDU BAR rx moved BA window" }, 293 #define S_AMPDU_BAR AFTER(S_AMPDU_BARMOVE) 294 { 8, "ampdu_bar", "rxbar", "A-MPDU BAR rx successful" }, 295 #define S_AMPDU_MOVE AFTER(S_AMPDU_BAR) 296 { 5, "ampdu_move", "move", "A-MPDU frame moved BA window" }, 297 #define S_AMPDU_OOR AFTER(S_AMPDU_MOVE) 298 { 8, "ampdu_oor", "oorx", "A-MPDU frames rx out-of-order" }, 299 #define S_AMPDU_COPY AFTER(S_AMPDU_OOR) 300 { 8, "ampdu_copy", "copy", "A-MPDU rx window slots copied" }, 301 #define S_AMPDU_DROP AFTER(S_AMPDU_COPY) 302 { 5, "ampdu_drop", "drop", "A-MPDU frames discarded for out of range seqno" }, 303 #define S_AMPDU_AGE AFTER(S_AMPDU_DROP) 304 { 5, "ampdu_age", "age", "A-MPDU frames sent up due to old age" }, 305 #define S_AMPDU_STOP AFTER(S_AMPDU_AGE) 306 { 5, "ampdu_stop", "stop", "A-MPDU streams stopped" }, 307 #define S_AMPDU_STOP_FAILED AFTER(S_AMPDU_STOP) 308 { 5, "ampdu_stop_failed","!stop", "A-MPDU stop requests failed 'cuz stream not running" }, 309 #define S_ADDBA_REJECT AFTER(S_AMPDU_STOP_FAILED) 310 { 5, "addba_reject", "reject", "ADDBA requests rejected 'cuz A-MPDU rx is disabled" }, 311 #define S_ADDBA_NOREQUEST AFTER(S_ADDBA_REJECT) 312 { 5, "addba_norequest","norequest","ADDBA response frames discarded because no ADDBA request was pending" }, 313 #define S_ADDBA_BADTOKEN AFTER(S_ADDBA_NOREQUEST) 314 { 5, "addba_badtoken", "badtoken","ADDBA response frames discarded 'cuz rx'd dialog token is wrong" }, 315 #define S_TX_BADSTATE AFTER(S_ADDBA_BADTOKEN) 316 { 4, "tx_badstate", "badstate", "tx failed 'cuz vap not in RUN state" }, 317 #define S_TX_NOTASSOC AFTER(S_TX_BADSTATE) 318 { 4, "tx_notassoc", "notassoc", "tx failed 'cuz dest sta not associated" }, 319 #define S_TX_CLASSIFY AFTER(S_TX_NOTASSOC) 320 { 4, "tx_classify", "classify", "tx packet classification failed" }, 321 #define S_DWDS_MCAST AFTER(S_TX_CLASSIFY) 322 { 8, "dwds_mcast", "dwds_mcast", "mcast frame transmitted on dwds vap discarded" }, 323 #define S_DWDS_QDROP AFTER(S_DWDS_MCAST) 324 { 8, "dwds_qdrop", "dwds_qdrop", "4-address frame discarded because dwds pending queue is full" }, 325 #define S_HT_ASSOC_NOHTCAP AFTER(S_DWDS_QDROP) 326 { 4, "ht_nohtcap", "ht_nohtcap", "non-HT station rejected in HT-only BSS" }, 327 #define S_HT_ASSOC_DOWNGRADE AFTER(S_HT_ASSOC_NOHTCAP) 328 { 4, "ht_downgrade", "ht_downgrade", "HT station downgraded to legacy operation" }, 329 #define S_HT_ASSOC_NORATE AFTER(S_HT_ASSOC_DOWNGRADE) 330 { 4, "ht_norate", "ht_norate", "HT station rejected because of HT rate set" }, 331 #define S_MESH_WRONGMESH AFTER(S_HT_ASSOC_NORATE) 332 { 4, "mesh_wrong", "mesh_wrong", "frame discarded because sender not a mesh sta" }, 333 #define S_MESH_NOLINK AFTER(S_MESH_WRONGMESH) 334 { 4, "mesh_nolink", "mesh_nolink", "frame discarded because link not established" }, 335 #define S_MESH_FWD_TTL AFTER(S_MESH_NOLINK) 336 { 4, "mesh_fwd_ttl", "mesh_fwd_ttl", "frame not forwarded because TTL zero" }, 337 #define S_MESH_FWD_NOBUF AFTER(S_MESH_FWD_TTL) 338 { 4, "mesh_fwd_nobuf", "mesh_fwd_nobuf", "frame not forwarded because mbuf could not be allocated" }, 339 #define S_MESH_FWD_TOOSHORT AFTER(S_MESH_FWD_NOBUF) 340 { 4, "mesh_fwd_tooshort", "mesh_fwd_tooshort", "frame not forwarded because too short to have 802.11 header" }, 341 #define S_MESH_FWD_DISABLED AFTER(S_MESH_FWD_TOOSHORT) 342 { 4, "mesh_fwd_disabled", "mesh_fwd_disabled", "frame not forwarded because administratively disabled" }, 343 #define S_MESH_FWD_NOPATH AFTER(S_MESH_FWD_DISABLED) 344 { 4, "mesh_fwd_nopath", "mesh_fwd_nopath", "frame not forwarded because no path found to destination" }, 345 #define S_HWMP_WRONGSEQ AFTER(S_MESH_FWD_NOPATH) 346 { 4, "hwmp_wrongseq", "hwmp_wrongseq", "frame discarded because mesh sequence number is invalid" }, 347 #define S_HWMP_ROOTREQS AFTER(S_HWMP_WRONGSEQ) 348 { 4, "hwmp_rootreqs", "hwmp_rootreqs", "root PREQ frames sent" }, 349 #define S_HWMP_ROOTANN AFTER(S_HWMP_ROOTREQS) 350 { 4, "hwmp_rootann", "hwmp_rootann", "root RANN frames received" }, 351 #define S_MESH_BADAE AFTER(S_HWMP_ROOTANN) 352 { 4, "mesh_badae", "mesh_badae", "frame discarded for bad AddressExtension (AE)" }, 353 #define S_MESH_RTADDFAILED AFTER(S_MESH_BADAE) 354 { 4, "mesh_rtadd", "mesh_rtadd", "mesh route add failed" }, 355 #define S_MESH_NOTPROXY AFTER(S_MESH_RTADDFAILED) 356 { 8, "mesh_notproxy", "mesh_notproxy","frame discarded because station not acting as a proxy" }, 357 #define S_RX_BADALIGN AFTER(S_MESH_NOTPROXY) 358 { 4, "rx_badalign", "rx_badalign","frame discarded because payload re-alignment failed" }, 359 #define S_INPUT AFTER(S_RX_BADALIGN) 360 { 8, "input", "input", "total data frames received" }, 361 #define S_RX_UCAST AFTER(S_INPUT) 362 { 8, "rx_ucast", "rx_ucast", "unicast data frames received" }, 363 #define S_RX_MCAST AFTER(S_RX_UCAST) 364 { 8, "rx_mcast", "rx_mcast", "multicast data frames received" }, 365 #define S_OUTPUT AFTER(S_RX_MCAST) 366 { 8, "output", "output", "total data frames transmit" }, 367 #define S_TX_UCAST AFTER(S_OUTPUT) 368 { 8, "tx_ucast", "tx_ucast", "unicast data frames sent" }, 369 #define S_TX_MCAST AFTER(S_TX_UCAST) 370 { 8, "tx_mcast", "tx_mcast", "multicast data frames sent" }, 371 #define S_RATE AFTER(S_TX_MCAST) 372 { 7, "rate", "rate", "current transmit rate" }, 373 #define S_RSSI AFTER(S_RATE) 374 { 6, "rssi", "rssi", "current rssi" }, 375 #define S_NOISE AFTER(S_RSSI) 376 { 5, "noise", "noise", "current noise floor (dBm)" }, 377 #define S_SIGNAL AFTER(S_NOISE) 378 { 6, "signal", "sig", "current signal (dBm)" }, 379 #define S_BEACON_BAD AFTER(S_SIGNAL) 380 { 9, "beacon_bad", "beaconbad", "bad beacons received" }, 381 #define S_AMPDU_BARTX AFTER(S_BEACON_BAD) 382 { 5, "ampdu_bartx", "bartx", "BAR frames sent" }, 383 #define S_AMPDU_BARTX_FAIL AFTER(S_AMPDU_BARTX) 384 { 9, "ampdu_bartxfail", "bartx_fail", "BAR frames failed to send" }, 385 #define S_AMPDU_BARTX_RETRY AFTER(S_AMPDU_BARTX_FAIL) 386 { 10, "ampdu_bartxretry", "bartx_retry", "BAR frames retried" }, 387 }; 388 389 struct wlanstatfoo_p { 390 struct wlanstatfoo base; 391 int s; 392 int opmode; 393 uint8_t mac[IEEE80211_ADDR_LEN]; 394 struct ifreq ifr; 395 struct ieee80211_stats cur; 396 struct ieee80211_stats total; 397 struct ieee80211req ireq; 398 union { 399 struct ieee80211req_sta_req info; 400 char buf[1024]; 401 } u_info; 402 struct ieee80211req_sta_stats ncur; 403 struct ieee80211req_sta_stats ntotal; 404 }; 405 406 static void 407 wlan_setifname(struct wlanstatfoo *wf0, const char *ifname) 408 { 409 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 410 411 strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name)); 412 strncpy(wf->ireq.i_name, ifname, sizeof (wf->ireq.i_name)); 413 } 414 415 static const char * 416 wlan_getifname(struct wlanstatfoo *wf0) 417 { 418 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 419 420 return wf->ifr.ifr_name; 421 } 422 423 static int 424 wlan_getopmode(struct wlanstatfoo *wf0) 425 { 426 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 427 428 if (wf->opmode == -1) { 429 struct ifmediareq ifmr; 430 431 memset(&ifmr, 0, sizeof(ifmr)); 432 strlcpy(ifmr.ifm_name, wf->ifr.ifr_name, sizeof(ifmr.ifm_name)); 433 if (ioctl(wf->s, SIOCGIFMEDIA, &ifmr) < 0) 434 err(1, "%s (SIOCGIFMEDIA)", wf->ifr.ifr_name); 435 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC) { 436 if (ifmr.ifm_current & IFM_FLAG0) 437 wf->opmode = IEEE80211_M_AHDEMO; 438 else 439 wf->opmode = IEEE80211_M_IBSS; 440 } else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP) 441 wf->opmode = IEEE80211_M_HOSTAP; 442 else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR) 443 wf->opmode = IEEE80211_M_MONITOR; 444 else 445 wf->opmode = IEEE80211_M_STA; 446 } 447 return wf->opmode; 448 } 449 450 static void 451 getlladdr(struct wlanstatfoo_p *wf) 452 { 453 const struct sockaddr_dl *sdl; 454 struct ifaddrs *ifp, *p; 455 456 if (getifaddrs(&ifp) != 0) 457 err(1, "getifaddrs"); 458 for (p = ifp; p != NULL; p = p->ifa_next) 459 if (strcmp(p->ifa_name, wf->ifr.ifr_name) == 0 && 460 p->ifa_addr->sa_family == AF_LINK) 461 break; 462 if (p == NULL) 463 errx(1, "did not find link layer address for interface %s", 464 wf->ifr.ifr_name); 465 sdl = (const struct sockaddr_dl *) p->ifa_addr; 466 IEEE80211_ADDR_COPY(wf->mac, CLLADDR(sdl)); 467 freeifaddrs(ifp); 468 } 469 470 static int 471 getbssid(struct wlanstatfoo_p *wf) 472 { 473 wf->ireq.i_type = IEEE80211_IOC_BSSID; 474 wf->ireq.i_data = wf->mac; 475 wf->ireq.i_len = IEEE80211_ADDR_LEN; 476 return ioctl(wf->s, SIOCG80211, &wf->ireq); 477 } 478 479 static void 480 wlan_setstamac(struct wlanstatfoo *wf0, const uint8_t *mac) 481 { 482 static const uint8_t zeromac[IEEE80211_ADDR_LEN]; 483 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0; 484 485 if (mac == NULL) { 486 switch (wlan_getopmode(wf0)) { 487 case IEEE80211_M_HOSTAP: 488 case IEEE80211_M_MONITOR: 489 getlladdr(wf); 490 break; 491 case IEEE80211_M_IBSS: 492 case IEEE80211_M_AHDEMO: 493 /* 494 * NB: this may not work in which case the 495 * mac must be specified on the command line 496 */ 497 if (getbssid(wf) < 0 || 498 IEEE80211_ADDR_EQ(wf->mac, zeromac)) 499 getlladdr(wf); 500 break; 501 case IEEE80211_M_STA: 502 if (getbssid(wf) < 0) 503 err(1, "%s (IEEE80211_IOC_BSSID)", 504 wf->ireq.i_name); 505 break; 506 } 507 } else 508 IEEE80211_ADDR_COPY(wf->mac, mac); 509 } 510 511 /* XXX only fetch what's needed to do reports */ 512 static void 513 wlan_collect(struct wlanstatfoo_p *wf, 514 struct ieee80211_stats *stats, struct ieee80211req_sta_stats *nstats) 515 { 516 517 IEEE80211_ADDR_COPY(wf->u_info.info.is_u.macaddr, wf->mac); 518 wf->ireq.i_type = IEEE80211_IOC_STA_INFO; 519 wf->ireq.i_data = (caddr_t) &wf->u_info; 520 wf->ireq.i_len = sizeof(wf->u_info); 521 if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) { 522 warn("%s:%s (IEEE80211_IOC_STA_INFO)", wf->ireq.i_name, 523 ether_ntoa((const struct ether_addr*) wf->mac)); 524 } 525 526 IEEE80211_ADDR_COPY(nstats->is_u.macaddr, wf->mac); 527 wf->ireq.i_type = IEEE80211_IOC_STA_STATS; 528 wf->ireq.i_data = (caddr_t) nstats; 529 wf->ireq.i_len = sizeof(*nstats); 530 if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0) 531 warn("%s:%s (IEEE80211_IOC_STA_STATS)", wf->ireq.i_name, 532 ether_ntoa((const struct ether_addr*) wf->mac)); 533 534 wf->ifr.ifr_data = (caddr_t) stats; 535 if (ioctl(wf->s, SIOCG80211STATS, &wf->ifr) < 0) 536 err(1, "%s (SIOCG80211STATS)", wf->ifr.ifr_name); 537 } 538 539 static void 540 wlan_collect_cur(struct bsdstat *sf) 541 { 542 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 543 544 wlan_collect(wf, &wf->cur, &wf->ncur); 545 } 546 547 static void 548 wlan_collect_tot(struct bsdstat *sf) 549 { 550 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 551 552 wlan_collect(wf, &wf->total, &wf->ntotal); 553 } 554 555 static void 556 wlan_update_tot(struct bsdstat *sf) 557 { 558 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 559 560 wf->total = wf->cur; 561 wf->ntotal = wf->ncur; 562 } 563 564 static void 565 setreason(char b[], size_t bs, unsigned int v) 566 { 567 static const char *reasons[] = { 568 [IEEE80211_REASON_UNSPECIFIED] = "unspecified", 569 [IEEE80211_REASON_AUTH_EXPIRE] = "auth expire", 570 [IEEE80211_REASON_AUTH_LEAVE] = "auth leave", 571 [IEEE80211_REASON_ASSOC_EXPIRE] = "assoc expire", 572 [IEEE80211_REASON_ASSOC_TOOMANY] = "assoc toomany", 573 [IEEE80211_REASON_NOT_AUTHED] = "not authed", 574 [IEEE80211_REASON_NOT_ASSOCED] = "not assoced", 575 [IEEE80211_REASON_ASSOC_LEAVE] = "assoc leave", 576 [IEEE80211_REASON_ASSOC_NOT_AUTHED] = "assoc not authed", 577 [IEEE80211_REASON_DISASSOC_PWRCAP_BAD] = "disassoc pwrcap bad", 578 [IEEE80211_REASON_DISASSOC_SUPCHAN_BAD] = "disassoc supchan bad", 579 [IEEE80211_REASON_IE_INVALID] = "ie invalid", 580 [IEEE80211_REASON_MIC_FAILURE] = "mic failure", 581 [IEEE80211_REASON_4WAY_HANDSHAKE_TIMEOUT]= "4-way handshake timeout", 582 [IEEE80211_REASON_GROUP_KEY_UPDATE_TIMEOUT] = "group key update timeout", 583 [IEEE80211_REASON_IE_IN_4WAY_DIFFERS] = "ie in 4-way differs", 584 [IEEE80211_REASON_GROUP_CIPHER_INVALID] = "group cipher invalid", 585 [IEEE80211_REASON_PAIRWISE_CIPHER_INVALID]= "pairwise cipher invalid", 586 [IEEE80211_REASON_AKMP_INVALID] = "akmp invalid", 587 [IEEE80211_REASON_UNSUPP_RSN_IE_VERSION]= "unsupported rsn ie version", 588 [IEEE80211_REASON_INVALID_RSN_IE_CAP] = "invalid rsn ie cap", 589 [IEEE80211_REASON_802_1X_AUTH_FAILED] = "802.1x auth failed", 590 [IEEE80211_REASON_CIPHER_SUITE_REJECTED]= "cipher suite rejected", 591 }; 592 if (v < nitems(reasons) && reasons[v] != NULL) 593 snprintf(b, bs, "%s (%u)", reasons[v], v); 594 else 595 snprintf(b, bs, "%u", v); 596 } 597 598 static void 599 setstatus(char b[], size_t bs, unsigned int v) 600 { 601 static const char *status[] = { 602 [IEEE80211_STATUS_SUCCESS] = "success", 603 [IEEE80211_STATUS_UNSPECIFIED] = "unspecified", 604 [IEEE80211_STATUS_CAPINFO] = "capinfo", 605 [IEEE80211_STATUS_NOT_ASSOCED] = "not assoced", 606 [IEEE80211_STATUS_OTHER] = "other", 607 [IEEE80211_STATUS_ALG] = "algorithm", 608 [IEEE80211_STATUS_SEQUENCE] = "sequence", 609 [IEEE80211_STATUS_CHALLENGE] = "challenge", 610 [IEEE80211_STATUS_TIMEOUT] = "timeout", 611 [IEEE80211_STATUS_TOOMANY] = "toomany", 612 [IEEE80211_STATUS_BASIC_RATE] = "basic rate", 613 [IEEE80211_STATUS_SP_REQUIRED] = "sp required", 614 [IEEE80211_STATUS_PBCC_REQUIRED] = "pbcc required", 615 [IEEE80211_STATUS_CA_REQUIRED] = "ca required", 616 [IEEE80211_STATUS_SPECMGMT_REQUIRED] = "specmgmt required", 617 [IEEE80211_STATUS_PWRCAP_REQUIRED] = "pwrcap required", 618 [IEEE80211_STATUS_SUPCHAN_REQUIRED] = "supchan required", 619 [IEEE80211_STATUS_SHORTSLOT_REQUIRED] = "shortslot required", 620 [IEEE80211_STATUS_DSSSOFDM_REQUIRED] = "dsssofdm required", 621 [IEEE80211_STATUS_INVALID_IE] = "invalid ie", 622 [IEEE80211_STATUS_GROUP_CIPHER_INVALID] = "group cipher invalid", 623 [IEEE80211_STATUS_PAIRWISE_CIPHER_INVALID]= "pairwise cipher invalid", 624 [IEEE80211_STATUS_AKMP_INVALID] = "akmp invalid", 625 [IEEE80211_STATUS_UNSUPP_RSN_IE_VERSION]= "unsupported rsn ie version", 626 [IEEE80211_STATUS_INVALID_RSN_IE_CAP] = "invalid rsn ie cap", 627 [IEEE80211_STATUS_CIPHER_SUITE_REJECTED]= "cipher suite rejected", 628 }; 629 if (v < nitems(status) && status[v] != NULL) 630 snprintf(b, bs, "%s (%u)", status[v], v); 631 else 632 snprintf(b, bs, "%u", v); 633 } 634 635 static int 636 wlan_getinfo(struct wlanstatfoo_p *wf, int s, char b[], size_t bs) 637 { 638 const struct ieee80211req_sta_info *si = &wf->u_info.info.info[0]; 639 640 switch (s) { 641 case S_RATE: 642 snprintf(b, bs, "%.1fM", (float) si->isi_txmbps/2.0); 643 return 1; 644 case S_RSSI: 645 snprintf(b, bs, "%.1f", (float) si->isi_rssi/2.0); 646 return 1; 647 case S_NOISE: 648 snprintf(b, bs, "%d", si->isi_noise); 649 return 1; 650 case S_SIGNAL: 651 snprintf(b, bs, "%.1f", (float) si->isi_rssi/2.0 652 + (float) si->isi_noise); 653 return 1; 654 case S_RX_AUTH_FAIL_CODE: 655 if (wf->cur.is_rx_authfail_code == 0) 656 break; 657 setstatus(b, bs, wf->cur.is_rx_authfail_code); 658 return 1; 659 case S_RX_DEAUTH_CODE: 660 if (wf->cur.is_rx_deauth_code == 0) 661 break; 662 setreason(b, bs, wf->cur.is_rx_deauth_code); 663 return 1; 664 case S_RX_DISASSOC_CODE: 665 if (wf->cur.is_rx_disassoc_code == 0) 666 break; 667 setreason(b, bs, wf->cur.is_rx_disassoc_code); 668 return 1; 669 } 670 b[0] = '\0'; 671 return 0; 672 } 673 674 static int 675 wlan_get_curstat(struct bsdstat *sf, int s, char b[], size_t bs) 676 { 677 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 678 #define STAT(x) \ 679 snprintf(b, bs, "%u", wf->cur.is_##x - wf->total.is_##x); return 1 680 #define NSTAT(x) \ 681 snprintf(b, bs, "%u", \ 682 wf->ncur.is_stats.ns_##x - wf->ntotal.is_stats.ns_##x); \ 683 return 1 684 685 switch (s) { 686 case S_RX_BADVERSION: STAT(rx_badversion); 687 case S_RX_TOOSHORT: STAT(rx_tooshort); 688 case S_RX_WRONGBSS: STAT(rx_wrongbss); 689 case S_RX_DUP: STAT(rx_dup); 690 case S_RX_WRONGDIR: STAT(rx_wrongdir); 691 case S_RX_MCASTECHO: STAT(rx_mcastecho); 692 case S_RX_NOTASSOC: STAT(rx_notassoc); 693 case S_RX_NOPRIVACY: STAT(rx_noprivacy); 694 case S_RX_UNENCRYPTED: STAT(rx_unencrypted); 695 case S_RX_WEPFAIL: STAT(rx_wepfail); 696 case S_RX_DECAP: STAT(rx_decap); 697 case S_RX_MGTDISCARD: STAT(rx_mgtdiscard); 698 case S_RX_CTL: STAT(rx_ctl); 699 case S_RX_BEACON: STAT(rx_beacon); 700 case S_RX_RSTOOBIG: STAT(rx_rstoobig); 701 case S_RX_ELEM_MISSING: STAT(rx_elem_missing); 702 case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig); 703 case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall); 704 case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown); 705 case S_RX_BADCHAN: STAT(rx_badchan); 706 case S_RX_CHANMISMATCH: STAT(rx_chanmismatch); 707 case S_RX_NODEALLOC: STAT(rx_nodealloc); 708 case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch); 709 case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported); 710 case S_RX_AUTH_FAIL: STAT(rx_auth_fail); 711 case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures); 712 case S_RX_ASSOC_BSS: STAT(rx_assoc_bss); 713 case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth); 714 case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch); 715 case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate); 716 case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie); 717 case S_RX_DEAUTH: STAT(rx_deauth); 718 case S_RX_DISASSOC: STAT(rx_disassoc); 719 case S_BMISS: STAT(beacon_miss); 720 case S_RX_BADSUBTYPE: STAT(rx_badsubtype); 721 case S_RX_NOBUF: STAT(rx_nobuf); 722 case S_RX_DECRYPTCRC: STAT(rx_decryptcrc); 723 case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt); 724 case S_RX_BAD_AUTH: STAT(rx_bad_auth); 725 case S_RX_UNAUTH: STAT(rx_unauth); 726 case S_RX_BADKEYID: STAT(rx_badkeyid); 727 case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay); 728 case S_RX_CCMPFORMAT: STAT(rx_ccmpformat); 729 case S_RX_CCMPMIC: STAT(rx_ccmpmic); 730 case S_RX_TKIPREPLAY: STAT(rx_tkipreplay); 731 case S_RX_TKIPFORMAT: STAT(rx_tkipformat); 732 case S_RX_TKIPMIC: STAT(rx_tkipmic); 733 case S_RX_TKIPICV: STAT(rx_tkipicv); 734 case S_RX_BADCIPHER: STAT(rx_badcipher); 735 case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx); 736 case S_RX_ACL: STAT(rx_acl); 737 case S_TX_NOBUF: STAT(tx_nobuf); 738 case S_TX_NONODE: STAT(tx_nonode); 739 case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt); 740 case S_TX_BADCIPHER: STAT(tx_badcipher); 741 case S_TX_NODEFKEY: STAT(tx_nodefkey); 742 case S_TX_NOHEADROOM: STAT(tx_noheadroom); 743 case S_TX_FRAGFRAMES: STAT(tx_fragframes); 744 case S_TX_FRAGS: STAT(tx_frags); 745 case S_SCAN_ACTIVE: STAT(scan_active); 746 case S_SCAN_PASSIVE: STAT(scan_passive); 747 case S_SCAN_BG: STAT(scan_bg); 748 case S_NODE_TIMEOUT: STAT(node_timeout); 749 case S_CRYPTO_NOMEM: STAT(crypto_nomem); 750 case S_CRYPTO_TKIP: STAT(crypto_tkip); 751 case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic); 752 case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic); 753 case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm); 754 case S_CRYPTO_CCMP: STAT(crypto_ccmp); 755 case S_CRYPTO_WEP: STAT(crypto_wep); 756 case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher); 757 case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey); 758 case S_CRYPTO_DELKEY: STAT(crypto_delkey); 759 case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher); 760 case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher); 761 case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail); 762 case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback); 763 case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail); 764 case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail); 765 case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch); 766 case S_IBSS_NORATE: STAT(ibss_norate); 767 case S_PS_UNASSOC: STAT(ps_unassoc); 768 case S_PS_BADAID: STAT(ps_badaid); 769 case S_PS_QEMPTY: STAT(ps_qempty); 770 case S_FF_BADHDR: STAT(ff_badhdr); 771 case S_FF_TOOSHORT: STAT(ff_tooshort); 772 case S_FF_SPLIT: STAT(ff_split); 773 case S_FF_DECAP: STAT(ff_decap); 774 case S_FF_ENCAP: STAT(ff_encap); 775 case S_FF_ENCAPFAIL: STAT(ff_encapfail); 776 case S_RX_BADBINTVAL: STAT(rx_badbintval); 777 case S_RX_MGMT: STAT(rx_mgmt); 778 case S_RX_DEMICFAIL: STAT(rx_demicfail); 779 case S_RX_DEFRAG: STAT(rx_defrag); 780 case S_RX_ACTION: STAT(rx_action); 781 case S_AMSDU_TOOSHORT: STAT(amsdu_tooshort); 782 case S_AMSDU_SPLIT: STAT(amsdu_split); 783 case S_AMSDU_DECAP: STAT(amsdu_decap); 784 case S_AMSDU_ENCAP: STAT(amsdu_encap); 785 case S_AMSDU_RX_MORE: NSTAT(rx_amsdu_more); 786 case S_AMSDU_RX_MORE_END: NSTAT(rx_amsdu_more_end); 787 case S_AMPDU_REORDER: STAT(ampdu_rx_reorder); 788 case S_AMPDU_FLUSH: STAT(ampdu_rx_flush); 789 case S_AMPDU_BARBAD: STAT(ampdu_bar_bad); 790 case S_AMPDU_BAROOW: STAT(ampdu_bar_oow); 791 case S_AMPDU_BARMOVE: STAT(ampdu_bar_move); 792 case S_AMPDU_BAR: STAT(ampdu_bar_rx); 793 case S_AMPDU_MOVE: STAT(ampdu_rx_move); 794 case S_AMPDU_OOR: STAT(ampdu_rx_oor); 795 case S_AMPDU_COPY: STAT(ampdu_rx_copy); 796 case S_AMPDU_DROP: STAT(ampdu_rx_drop); 797 case S_AMPDU_AGE: STAT(ampdu_rx_age); 798 case S_AMPDU_STOP: STAT(ampdu_stop); 799 case S_AMPDU_STOP_FAILED:STAT(ampdu_stop_failed); 800 case S_ADDBA_REJECT: STAT(addba_reject); 801 case S_ADDBA_NOREQUEST: STAT(addba_norequest); 802 case S_ADDBA_BADTOKEN: STAT(addba_badtoken); 803 case S_TX_BADSTATE: STAT(tx_badstate); 804 case S_TX_NOTASSOC: STAT(tx_notassoc); 805 case S_TX_CLASSIFY: STAT(tx_classify); 806 case S_DWDS_MCAST: STAT(dwds_mcast); 807 case S_DWDS_QDROP: STAT(dwds_qdrop); 808 case S_HT_ASSOC_NOHTCAP:STAT(ht_assoc_nohtcap); 809 case S_HT_ASSOC_DOWNGRADE:STAT(ht_assoc_downgrade); 810 case S_HT_ASSOC_NORATE: STAT(ht_assoc_norate); 811 case S_MESH_WRONGMESH: STAT(mesh_wrongmesh); 812 case S_MESH_NOLINK: STAT(mesh_nolink); 813 case S_MESH_FWD_TTL: STAT(mesh_fwd_ttl); 814 case S_MESH_FWD_NOBUF: STAT(mesh_fwd_nobuf); 815 case S_MESH_FWD_TOOSHORT: STAT(mesh_fwd_tooshort); 816 case S_MESH_FWD_DISABLED: STAT(mesh_fwd_disabled); 817 case S_MESH_FWD_NOPATH: STAT(mesh_fwd_nopath); 818 case S_HWMP_WRONGSEQ: STAT(hwmp_wrongseq); 819 case S_HWMP_ROOTREQS: STAT(hwmp_rootreqs); 820 case S_HWMP_ROOTANN: STAT(hwmp_rootrann); 821 case S_MESH_BADAE: STAT(mesh_badae); 822 case S_MESH_RTADDFAILED:STAT(mesh_rtaddfailed); 823 case S_MESH_NOTPROXY: STAT(mesh_notproxy); 824 case S_RX_BADALIGN: STAT(rx_badalign); 825 case S_INPUT: NSTAT(rx_data); 826 case S_OUTPUT: NSTAT(tx_data); 827 case S_RX_UCAST: NSTAT(rx_ucast); 828 case S_RX_MCAST: NSTAT(rx_mcast); 829 case S_TX_UCAST: NSTAT(tx_ucast); 830 case S_TX_MCAST: NSTAT(tx_mcast); 831 case S_BEACON_BAD: STAT(beacon_bad); 832 case S_AMPDU_BARTX: STAT(ampdu_bar_tx); 833 case S_AMPDU_BARTX_RETRY: STAT(ampdu_bar_tx_retry); 834 case S_AMPDU_BARTX_FAIL: STAT(ampdu_bar_tx_fail); 835 } 836 return wlan_getinfo(wf, s, b, bs); 837 #undef NSTAT 838 #undef STAT 839 } 840 841 static int 842 wlan_get_totstat(struct bsdstat *sf, int s, char b[], size_t bs) 843 { 844 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf; 845 #define STAT(x) \ 846 snprintf(b, bs, "%u", wf->total.is_##x); return 1 847 #define NSTAT(x) \ 848 snprintf(b, bs, "%u", wf->ntotal.is_stats.ns_##x); return 1 849 850 switch (s) { 851 case S_RX_BADVERSION: STAT(rx_badversion); 852 case S_RX_TOOSHORT: STAT(rx_tooshort); 853 case S_RX_WRONGBSS: STAT(rx_wrongbss); 854 case S_RX_DUP: STAT(rx_dup); 855 case S_RX_WRONGDIR: STAT(rx_wrongdir); 856 case S_RX_MCASTECHO: STAT(rx_mcastecho); 857 case S_RX_NOTASSOC: STAT(rx_notassoc); 858 case S_RX_NOPRIVACY: STAT(rx_noprivacy); 859 case S_RX_UNENCRYPTED: STAT(rx_unencrypted); 860 case S_RX_WEPFAIL: STAT(rx_wepfail); 861 case S_RX_DECAP: STAT(rx_decap); 862 case S_RX_MGTDISCARD: STAT(rx_mgtdiscard); 863 case S_RX_CTL: STAT(rx_ctl); 864 case S_RX_BEACON: STAT(rx_beacon); 865 case S_RX_RSTOOBIG: STAT(rx_rstoobig); 866 case S_RX_ELEM_MISSING: STAT(rx_elem_missing); 867 case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig); 868 case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall); 869 case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown); 870 case S_RX_BADCHAN: STAT(rx_badchan); 871 case S_RX_CHANMISMATCH: STAT(rx_chanmismatch); 872 case S_RX_NODEALLOC: STAT(rx_nodealloc); 873 case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch); 874 case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported); 875 case S_RX_AUTH_FAIL: STAT(rx_auth_fail); 876 case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures); 877 case S_RX_ASSOC_BSS: STAT(rx_assoc_bss); 878 case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth); 879 case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch); 880 case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate); 881 case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie); 882 case S_RX_DEAUTH: STAT(rx_deauth); 883 case S_RX_DISASSOC: STAT(rx_disassoc); 884 case S_BMISS: STAT(beacon_miss); 885 case S_RX_BADSUBTYPE: STAT(rx_badsubtype); 886 case S_RX_NOBUF: STAT(rx_nobuf); 887 case S_RX_DECRYPTCRC: STAT(rx_decryptcrc); 888 case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt); 889 case S_RX_BAD_AUTH: STAT(rx_bad_auth); 890 case S_RX_UNAUTH: STAT(rx_unauth); 891 case S_RX_BADKEYID: STAT(rx_badkeyid); 892 case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay); 893 case S_RX_CCMPFORMAT: STAT(rx_ccmpformat); 894 case S_RX_CCMPMIC: STAT(rx_ccmpmic); 895 case S_RX_TKIPREPLAY: STAT(rx_tkipreplay); 896 case S_RX_TKIPFORMAT: STAT(rx_tkipformat); 897 case S_RX_TKIPMIC: STAT(rx_tkipmic); 898 case S_RX_TKIPICV: STAT(rx_tkipicv); 899 case S_RX_BADCIPHER: STAT(rx_badcipher); 900 case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx); 901 case S_RX_ACL: STAT(rx_acl); 902 case S_TX_NOBUF: STAT(tx_nobuf); 903 case S_TX_NONODE: STAT(tx_nonode); 904 case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt); 905 case S_TX_BADCIPHER: STAT(tx_badcipher); 906 case S_TX_NODEFKEY: STAT(tx_nodefkey); 907 case S_TX_NOHEADROOM: STAT(tx_noheadroom); 908 case S_TX_FRAGFRAMES: STAT(tx_fragframes); 909 case S_TX_FRAGS: STAT(tx_frags); 910 case S_SCAN_ACTIVE: STAT(scan_active); 911 case S_SCAN_PASSIVE: STAT(scan_passive); 912 case S_SCAN_BG: STAT(scan_bg); 913 case S_NODE_TIMEOUT: STAT(node_timeout); 914 case S_CRYPTO_NOMEM: STAT(crypto_nomem); 915 case S_CRYPTO_TKIP: STAT(crypto_tkip); 916 case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic); 917 case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic); 918 case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm); 919 case S_CRYPTO_CCMP: STAT(crypto_ccmp); 920 case S_CRYPTO_WEP: STAT(crypto_wep); 921 case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher); 922 case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey); 923 case S_CRYPTO_DELKEY: STAT(crypto_delkey); 924 case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher); 925 case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher); 926 case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail); 927 case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback); 928 case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail); 929 case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail); 930 case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch); 931 case S_IBSS_NORATE: STAT(ibss_norate); 932 case S_PS_UNASSOC: STAT(ps_unassoc); 933 case S_PS_BADAID: STAT(ps_badaid); 934 case S_PS_QEMPTY: STAT(ps_qempty); 935 case S_FF_BADHDR: STAT(ff_badhdr); 936 case S_FF_TOOSHORT: STAT(ff_tooshort); 937 case S_FF_SPLIT: STAT(ff_split); 938 case S_FF_DECAP: STAT(ff_decap); 939 case S_FF_ENCAP: STAT(ff_encap); 940 case S_FF_ENCAPFAIL: STAT(ff_encapfail); 941 case S_RX_BADBINTVAL: STAT(rx_badbintval); 942 case S_RX_MGMT: STAT(rx_mgmt); 943 case S_RX_DEMICFAIL: STAT(rx_demicfail); 944 case S_RX_DEFRAG: STAT(rx_defrag); 945 case S_RX_ACTION: STAT(rx_action); 946 case S_AMSDU_TOOSHORT: STAT(amsdu_tooshort); 947 case S_AMSDU_SPLIT: STAT(amsdu_split); 948 case S_AMSDU_DECAP: STAT(amsdu_decap); 949 case S_AMSDU_ENCAP: STAT(amsdu_encap); 950 case S_AMSDU_RX_MORE: NSTAT(rx_amsdu_more); 951 case S_AMSDU_RX_MORE_END: NSTAT(rx_amsdu_more_end); 952 case S_AMPDU_REORDER: STAT(ampdu_rx_reorder); 953 case S_AMPDU_FLUSH: STAT(ampdu_rx_flush); 954 case S_AMPDU_BARBAD: STAT(ampdu_bar_bad); 955 case S_AMPDU_BAROOW: STAT(ampdu_bar_oow); 956 case S_AMPDU_BARMOVE: STAT(ampdu_bar_move); 957 case S_AMPDU_BAR: STAT(ampdu_bar_rx); 958 case S_AMPDU_MOVE: STAT(ampdu_rx_move); 959 case S_AMPDU_OOR: STAT(ampdu_rx_oor); 960 case S_AMPDU_COPY: STAT(ampdu_rx_copy); 961 case S_AMPDU_DROP: STAT(ampdu_rx_drop); 962 case S_AMPDU_AGE: STAT(ampdu_rx_age); 963 case S_AMPDU_STOP: STAT(ampdu_stop); 964 case S_AMPDU_STOP_FAILED:STAT(ampdu_stop_failed); 965 case S_ADDBA_REJECT: STAT(addba_reject); 966 case S_ADDBA_NOREQUEST: STAT(addba_norequest); 967 case S_ADDBA_BADTOKEN: STAT(addba_badtoken); 968 case S_TX_BADSTATE: STAT(tx_badstate); 969 case S_TX_NOTASSOC: STAT(tx_notassoc); 970 case S_TX_CLASSIFY: STAT(tx_classify); 971 case S_DWDS_MCAST: STAT(dwds_mcast); 972 case S_DWDS_QDROP: STAT(dwds_qdrop); 973 case S_HT_ASSOC_NOHTCAP:STAT(ht_assoc_nohtcap); 974 case S_HT_ASSOC_DOWNGRADE:STAT(ht_assoc_downgrade); 975 case S_HT_ASSOC_NORATE: STAT(ht_assoc_norate); 976 case S_MESH_WRONGMESH: STAT(mesh_wrongmesh); 977 case S_MESH_NOLINK: STAT(mesh_nolink); 978 case S_MESH_FWD_TTL: STAT(mesh_fwd_ttl); 979 case S_MESH_FWD_NOBUF: STAT(mesh_fwd_nobuf); 980 case S_MESH_FWD_TOOSHORT: STAT(mesh_fwd_tooshort); 981 case S_MESH_FWD_DISABLED: STAT(mesh_fwd_disabled); 982 case S_MESH_FWD_NOPATH: STAT(mesh_fwd_nopath); 983 case S_HWMP_WRONGSEQ: STAT(hwmp_wrongseq); 984 case S_HWMP_ROOTREQS: STAT(hwmp_rootreqs); 985 case S_HWMP_ROOTANN: STAT(hwmp_rootrann); 986 case S_MESH_BADAE: STAT(mesh_badae); 987 case S_MESH_RTADDFAILED:STAT(mesh_rtaddfailed); 988 case S_MESH_NOTPROXY: STAT(mesh_notproxy); 989 case S_RX_BADALIGN: STAT(rx_badalign); 990 case S_INPUT: NSTAT(rx_data); 991 case S_OUTPUT: NSTAT(tx_data); 992 case S_RX_UCAST: NSTAT(rx_ucast); 993 case S_RX_MCAST: NSTAT(rx_mcast); 994 case S_TX_UCAST: NSTAT(tx_ucast); 995 case S_TX_MCAST: NSTAT(tx_mcast); 996 case S_BEACON_BAD: STAT(beacon_bad); 997 case S_AMPDU_BARTX: STAT(ampdu_bar_tx); 998 case S_AMPDU_BARTX_RETRY: STAT(ampdu_bar_tx_retry); 999 case S_AMPDU_BARTX_FAIL: STAT(ampdu_bar_tx_fail); 1000 } 1001 return wlan_getinfo(wf, s, b, bs); 1002 #undef NSTAT 1003 #undef STAT 1004 } 1005 1006 BSDSTAT_DEFINE_BOUNCE(wlanstatfoo) 1007 1008 struct wlanstatfoo * 1009 wlanstats_new(const char *ifname, const char *fmtstring) 1010 { 1011 struct wlanstatfoo_p *wf; 1012 1013 wf = calloc(1, sizeof(struct wlanstatfoo_p)); 1014 if (wf != NULL) { 1015 bsdstat_init(&wf->base.base, "wlanstats", wlanstats, 1016 nitems(wlanstats)); 1017 /* override base methods */ 1018 wf->base.base.collect_cur = wlan_collect_cur; 1019 wf->base.base.collect_tot = wlan_collect_tot; 1020 wf->base.base.get_curstat = wlan_get_curstat; 1021 wf->base.base.get_totstat = wlan_get_totstat; 1022 wf->base.base.update_tot = wlan_update_tot; 1023 1024 /* setup bounce functions for public methods */ 1025 BSDSTAT_BOUNCE(wf, wlanstatfoo); 1026 1027 /* setup our public methods */ 1028 wf->base.setifname = wlan_setifname; 1029 wf->base.getifname = wlan_getifname; 1030 wf->base.getopmode = wlan_getopmode; 1031 wf->base.setstamac = wlan_setstamac; 1032 wf->opmode = -1; 1033 1034 wf->s = socket(AF_INET, SOCK_DGRAM, 0); 1035 if (wf->s < 0) 1036 err(1, "socket"); 1037 1038 wlan_setifname(&wf->base, ifname); 1039 wf->base.setfmt(&wf->base, fmtstring); 1040 } 1041 return &wf->base; 1042 } 1043