2 * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
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.
40 * net80211 statistics class.
42 #include <sys/types.h>
44 #include <sys/sockio.h>
45 #include <sys/socket.h>
47 #include <net/if_dl.h>
48 #include <net/if_media.h>
49 #include <net/if_var.h>
50 #include <net/ethernet.h>
60 #include "../../../../sys/net80211/ieee80211_ioctl.h"
62 #include "wlanstats.h"
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)
69 #define AFTER(prev) ((prev)+1)
71 static 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)" },
342 struct wlanstatfoo_p {
343 struct wlanstatfoo base;
346 uint8_t mac[IEEE80211_ADDR_LEN];
348 struct ieee80211_stats cur;
349 struct ieee80211_stats total;
350 struct ieee80211req ireq;
352 struct ieee80211req_sta_req info;
355 struct ieee80211req_sta_stats ncur;
356 struct ieee80211req_sta_stats ntotal;
360 wlan_setifname(struct wlanstatfoo *wf0, const char *ifname)
362 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
364 strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name));
365 strncpy(wf->ireq.i_name, ifname, sizeof (wf->ireq.i_name));
369 wlan_getifname(struct wlanstatfoo *wf0)
371 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
373 return wf->ifr.ifr_name;
377 wlan_getopmode(struct wlanstatfoo *wf0)
379 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
381 if (wf->opmode == -1) {
382 struct ifmediareq ifmr;
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;
395 wf->opmode = IEEE80211_M_STA;
401 getlladdr(struct wlanstatfoo_p *wf)
403 const struct sockaddr_dl *sdl;
404 struct ifaddrs *ifp, *p;
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)
413 errx(1, "did not find link layer address for interface %s",
415 sdl = (const struct sockaddr_dl *) p->ifa_addr;
416 IEEE80211_ADDR_COPY(wf->mac, LLADDR(sdl));
421 wlan_setstamac(struct wlanstatfoo *wf0, const uint8_t *mac)
423 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
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:
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);
442 IEEE80211_ADDR_COPY(wf->mac, mac);
445 /* XXX only fetch what's needed to do reports */
447 wlan_collect(struct wlanstatfoo_p *wf,
448 struct ieee80211_stats *stats, struct ieee80211req_sta_stats *nstats)
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);
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);
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);
471 wlan_collect_cur(struct statfoo *sf)
473 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
475 wlan_collect(wf, &wf->cur, &wf->ncur);
479 wlan_collect_tot(struct statfoo *sf)
481 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
483 wlan_collect(wf, &wf->total, &wf->ntotal);
487 wlan_update_tot(struct statfoo *sf)
489 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
492 wf->ntotal = wf->ncur;
496 wlan_getinfo(struct wlanstatfoo_p *wf, int s, char b[], size_t bs)
498 const struct ieee80211req_sta_info *si = &wf->u_info.info.info[0];
503 r = si->isi_rates[si->isi_txrate];
504 snprintf(b, bs, "%uM", (r &~ 0x80) / 2);
507 snprintf(b, bs, "%d", si->isi_rssi);
510 snprintf(b, bs, "%d", si->isi_noise);
513 snprintf(b, bs, "%d", si->isi_rssi + si->isi_noise);
521 wlan_get_curstat(struct statfoo *sf, int s, char b[], size_t bs)
523 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
525 snprintf(b, bs, "%u", wf->cur.is_##x - wf->total.is_##x); return 1
527 snprintf(b, bs, "%u", \
528 wf->ncur.is_stats.ns_##x - wf->ntotal.is_stats.ns_##x); \
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);
657 return wlan_getinfo(wf, s, b, bs);
663 wlan_get_totstat(struct statfoo *sf, int s, char b[], size_t bs)
665 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
667 snprintf(b, bs, "%u", wf->total.is_##x); return 1
669 snprintf(b, bs, "%u", wf->ntotal.is_stats.ns_##x); return 1
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);
797 return wlan_getinfo(wf, s, b, bs);
802 STATFOO_DEFINE_BOUNCE(wlanstatfoo)
805 wlanstats_new(const char *ifname, const char *fmtstring)
807 #define N(a) (sizeof(a) / sizeof(a[0]))
808 struct wlanstatfoo_p *wf;
810 wf = calloc(1, sizeof(struct wlanstatfoo_p));
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;
820 /* setup bounce functions for public methods */
821 STATFOO_BOUNCE(wf, wlanstatfoo);
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;
830 wf->s = socket(AF_INET, SOCK_DGRAM, 0);
834 wlan_setifname(&wf->base, ifname);
835 wf->base.setfmt(&wf->base, fmtstring);