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>
59 #include "../../../../sys/net80211/ieee80211_ioctl.h"
61 #include "wlanstats.h"
63 #ifndef IEEE80211_ADDR_COPY
64 #define IEEE80211_ADDR_COPY(dst, src) memcpy(dst, src, IEEE80211_ADDR_LEN)
65 #define IEEE80211_ADDR_EQ(a1,a2) (memcmp(a1,a2,IEEE80211_ADDR_LEN) == 0)
68 static const struct fmt wlanstats[] = {
69 #define S_RX_BADVERSION 0
70 { 5, "rx_badversion", "badversion", "rx frame with bad version" },
71 #define S_RX_TOOSHORT 1
72 { 5, "rx_tooshort", "tooshort", "rx frame too short" },
73 #define S_RX_WRONGBSS 2
74 { 5, "rx_wrongbss", "wrongbss", "rx from wrong bssid" },
76 { 5, "rx_dup", "rx_dup", "rx discard 'cuz dup" },
77 #define S_RX_WRONGDIR 4
78 { 5, "rx_wrongdir", "wrongdir", "rx w/ wrong direction" },
79 #define S_RX_MCASTECHO 5
80 { 5, "rx_mcastecho", "mcastecho", "rx discard 'cuz mcast echo" },
81 #define S_RX_NOTASSOC 6
82 { 5, "rx_notassoc", "notassoc", "rx discard 'cuz sta !assoc" },
83 #define S_RX_NOPRIVACY 7
84 { 5, "rx_noprivacy", "noprivacy", "rx w/ wep but privacy off" },
85 #define S_RX_UNENCRYPTED 8
86 { 5, "rx_unencrypted", "unencrypted", "rx w/o wep and privacy on" },
87 #define S_RX_WEPFAIL 9
88 { 5, "rx_wepfail", "wepfail", "rx wep processing failed" },
90 { 5, "rx_decap", "decap", "rx decapsulation failed" },
91 #define S_RX_MGTDISCARD 11
92 { 5, "rx_mgtdiscard", "mgtdiscard", "rx discard mgt frames" },
94 { 5, "rx_ctl", "ctl", "rx discard ctrl frames" },
95 #define S_RX_BEACON 13
96 { 5, "rx_beacon", "beacon", "rx beacon frames" },
97 #define S_RX_RSTOOBIG 14
98 { 5, "rx_rstoobig", "rstoobig", "rx rate set truncated" },
99 #define S_RX_ELEM_MISSING 15
100 { 5, "rx_elem_missing","elem_missing", "rx required element missing" },
101 #define S_RX_ELEM_TOOBIG 16
102 { 5, "rx_elem_toobig", "elem_toobig", "rx element too big" },
103 #define S_RX_ELEM_TOOSMALL 17
104 { 5, "rx_elem_toosmall","elem_toosmall","rx element too small" },
105 #define S_RX_ELEM_UNKNOWN 18
106 { 5, "rx_elem_unknown","elem_unknown", "rx element unknown" },
107 #define S_RX_BADCHAN 19
108 { 5, "rx_badchan", "badchan", "rx frame w/ invalid chan" },
109 #define S_RX_CHANMISMATCH 20
110 { 5, "rx_chanmismatch","chanmismatch", "rx frame chan mismatch" },
111 #define S_RX_NODEALLOC 21
112 { 5, "rx_nodealloc", "nodealloc", "nodes allocated (rx)" },
113 #define S_RX_SSIDMISMATCH 22
114 { 5, "rx_ssidmismatch","ssidmismatch", "rx frame ssid mismatch" },
115 #define S_RX_AUTH_UNSUPPORTED 23
116 { 5, "rx_auth_unsupported","auth_unsupported",
117 "rx w/ unsupported auth alg" },
118 #define S_RX_AUTH_FAIL 24
119 { 5, "rx_auth_fail", "auth_fail", "rx sta auth failure" },
120 #define S_RX_AUTH_COUNTERMEASURES 25
121 { 5, "rx_auth_countermeasures", "auth_countermeasures",
122 "rx sta auth failure 'cuz of TKIP countermeasures" },
123 #define S_RX_ASSOC_BSS 26
124 { 5, "rx_assoc_bss", "assoc_bss", "rx assoc from wrong bssid" },
125 #define S_RX_ASSOC_NOTAUTH 27
126 { 5, "rx_assoc_notauth","assoc_notauth", "rx assoc w/o auth" },
127 #define S_RX_ASSOC_CAPMISMATCH 28
128 { 5, "rx_assoc_capmismatch","assoc_capmismatch",
129 "rx assoc w/ cap mismatch" },
130 #define S_RX_ASSOC_NORATE 29
131 { 5, "rx_assoc_norate","assoc_norate", "rx assoc w/ no rate match" },
132 #define S_RX_ASSOC_BADWPAIE 30
133 { 5, "rx_assoc_badwpaie","assoc_badwpaie",
134 "rx assoc w/ bad WPA IE" },
135 #define S_RX_DEAUTH 31
136 { 5, "rx_deauth", "deauth", "rx deauthentication" },
137 #define S_RX_DISASSOC 32
138 { 5, "rx_disassoc", "disassoc", "rx disassociation" },
139 #define S_RX_BADSUBTYPE 33
140 { 5, "rx_badsubtype", "badsubtype", "rx frame w/ unknown subtype" },
141 #define S_RX_NOBUF 34
142 { 5, "rx_nobuf", "nobuf", "rx failed for lack of mbuf" },
143 #define S_RX_DECRYPTCRC 35
144 { 5, "rx_decryptcrc", "decryptcrc", "rx decrypt failed on crc" },
145 #define S_RX_AHDEMO_MGT 36
146 { 5, "rx_ahdemo_mgt", "ahdemo_mgt",
147 "rx discard mgmt frame received in ahdoc demo mode" },
148 #define S_RX_BAD_AUTH 37
149 { 5, "rx_bad_auth", "bad_auth", "rx bad authentication request" },
150 #define S_RX_UNAUTH 38
151 { 5, "rx_unauth", "unauth",
152 "rx discard 'cuz port unauthorized" },
153 #define S_RX_BADKEYID 39
154 { 5, "rx_badkeyid", "badkeyid", "rx w/ incorrect keyid" },
155 #define S_RX_CCMPREPLAY 40
156 { 5, "rx_ccmpreplay", "ccmpreplay", "rx seq# violation (CCMP)" },
157 #define S_RX_CCMPFORMAT 41
158 { 5, "rx_ccmpformat", "ccmpformat", "rx format bad (CCMP)" },
159 #define S_RX_CCMPMIC 42
160 { 5, "rx_ccmpmic", "ccmpmic", "rx MIC check failed (CCMP)" },
161 #define S_RX_TKIPREPLAY 43
162 { 5, "rx_tkipreplay", "tkipreplay", "rx seq# violation (TKIP)" },
163 #define S_RX_TKIPFORMAT 44
164 { 5, "rx_tkipformat", "tkipformat", "rx format bad (TKIP)" },
165 #define S_RX_TKIPMIC 45
166 { 5, "rx_tkipmic", "tkipmic", "rx MIC check failed (TKIP)" },
167 #define S_RX_TKIPICV 46
168 { 5, "rx_tkipicv", "tkipicv", "rx ICV check failed (TKIP)" },
169 #define S_RX_BADCIPHER 47
170 { 5, "rx_badcipher", "badcipher", "rx failed 'cuz bad cipher/key type" },
171 #define S_RX_NOCIPHERCTX 48
172 { 5, "rx_nocipherctx", "nocipherctx", "rx failed 'cuz key/cipher ctx not setup" },
174 { 5, "rx_acl", "acl", "rx discard 'cuz acl policy" },
175 #define S_TX_NOBUF 50
176 { 5, "tx_nobuf", "nobuf", "tx failed for lack of mbuf" },
177 #define S_TX_NONODE 51
178 { 5, "tx_nonode", "nonode", "tx failed for no node" },
179 #define S_TX_UNKNOWNMGT 52
180 { 5, "tx_unknownmgt", "unknownmgt", "tx of unknown mgt frame" },
181 #define S_TX_BADCIPHER 53
182 { 5, "tx_badcipher", "badcipher", "tx failed 'cuz bad ciper/key type" },
183 #define S_TX_NODEFKEY 54
184 { 5, "tx_nodefkey", "nodefkey", "tx failed 'cuz no defkey" },
185 #define S_TX_NOHEADROOM 55
186 { 5, "tx_noheadroom", "noheadroom", "tx failed 'cuz no space for crypto hdrs" },
187 #define S_TX_FRAGFRAMES 56
188 { 5, "tx_fragframes", "fragframes", "tx frames fragmented" },
189 #define S_TX_FRAGS 57
190 { 5, "tx_frags", "frags", "tx frags generated" },
191 #define S_SCAN_ACTIVE 58
192 { 5, "scan_active", "scan_active", "active scans started" },
193 #define S_SCAN_PASSIVE 59
194 { 5, "scan_passive", "scan_passive", "passive scans started" },
195 #define S_NODE_TIMEOUT 60
196 { 5, "node_timeout", "node_timeout", "nodes timed out inactivity" },
197 #define S_CRYPTO_NOMEM 61
198 { 5, "crypto_nomem", "crypto_nomem", "cipher context malloc failed" },
199 #define S_CRYPTO_TKIP 62
200 { 5, "crypto_tkip", "crypto_tkip", "tkip crypto done in s/w" },
201 #define S_CRYPTO_TKIPENMIC 63
202 { 5, "crypto_tkipenmic","crypto_tkipenmic", "tkip tx MIC done in s/w" },
203 #define S_CRYPTO_TKIPDEMIC 64
204 { 5, "crypto_tkipdemic","crypto_tkipdemic", "tkip rx MIC done in s/w" },
205 #define S_CRYPTO_TKIPCM 65
206 { 5, "crypto_tkipcm", "crypto_tkipcm", "tkip dropped frames 'cuz of countermeasures" },
207 #define S_CRYPTO_CCMP 66
208 { 5, "crypto_ccmp", "crypto_ccmp", "ccmp crypto done in s/w" },
209 #define S_CRYPTO_WEP 67
210 { 5, "crypto_wep", "crypto_wep", "wep crypto done in s/w" },
211 #define S_CRYPTO_SETKEY_CIPHER 68
212 { 5, "crypto_setkey_cipher", "crypto_setkey_cipher","setkey failed 'cuz cipher rejected data" },
213 #define S_CRYPTO_SETKEY_NOKEY 69
214 { 5, "crypto_setkey_nokey", "crypto_setkey_nokey","setkey failed 'cuz no key index" },
215 #define S_CRYPTO_DELKEY 70
216 { 5, "crypto_delkey", "crypto_delkey", "driver key delete failed" },
217 #define S_CRYPTO_BADCIPHER 71
218 { 5, "crypto_badcipher","crypto_badcipher", "setkey failed 'cuz unknown cipher" },
219 #define S_CRYPTO_NOCIPHER 72
220 { 5, "crypto_nocipher","crypto_nocipher", "setkey failed 'cuz cipher module unavailable" },
221 #define S_CRYPTO_ATTACHFAIL 73
222 { 5, "crypto_attachfail","crypto_attachfail", "setkey failed 'cuz cipher attach failed" },
223 #define S_CRYPTO_SWFALLBACK 74
224 { 5, "crypto_swfallback","crypto_swfallback", "crypto fell back to s/w implementation" },
225 #define S_CRYPTO_KEYFAIL 75
226 { 5, "crypto_keyfail", "crypto_keyfail", "setkey failed 'cuz driver key alloc failed" },
227 #define S_CRYPTO_ENMICFAIL 76
228 { 5, "crypto_enmicfail","crypto_enmicfail", "enmic failed (may be mbuf exhaustion)" },
229 #define S_IBSS_CAPMISMATCH 77
230 { 5, "ibss_capmismatch","ibss_capmismatch", "ibss merge faied 'cuz capabilities mismatch" },
231 #define S_IBSS_NORATE 78
232 { 5, "ibss_norate", "ibss_norate", "ibss merge faied 'cuz rate set mismatch" },
233 #define S_PS_UNASSOC 79
234 { 5, "ps_unassoc", "ps_unassoc", "ps-poll received for unassociated station" },
235 #define S_PS_BADAID 80
236 { 5, "ps_badaid", "ps_badaid", "ps-poll received with invalid association id" },
237 #define S_PS_QEMPTY 81
238 { 5, "ps_qempty", "ps_qempty", "ps-poll received with nothing to send" },
239 #define S_FF_BADHDR 82
240 { 5, "ff_badhdr", "ff_badhdr", "fast frame rx'd w/ bad hdr" },
241 #define S_FF_TOOSHORT 83
242 { 5, "ff_tooshort", "ff_tooshort", "fast frame rx decap error" },
243 #define S_FF_SPLIT 84
244 { 5, "ff_split", "ff_split", "fast frame rx split error" },
245 #define S_FF_DECAP 85
246 { 5, "ff_decap", "ff_decap", "fast frames decap'd" },
247 #define S_FF_ENCAP 86
248 { 5, "ff_encap", "ff_encap", "fast frames encap'd for tx" },
249 #define S_FF_ENCAPFAIL 87
250 { 5, "ff_encapfail", "ff_encapfail", "fast frames encap failed" },
251 #define S_RX_BADBINTVAL 88
252 { 5, "rx_badbintval", "rx_badbintval","rx frame with bogus beacon interval" },
254 { 5, "rx_mgmt", "rx_mgmt", "rx management frames" },
255 #define S_RX_DEMICFAIL 90
256 { 5, "rx_demicfail", "rx_demicfail", "rx demic failed" },
257 #define S_RX_DEFRAG 91
258 { 5, "rx_defrag", "rx_defrag", "rx defragmentation failed" },
260 { 8, "input", "input", "data frames received" },
262 { 8, "output", "output", "data frames transmit" },
264 { 4, "rate", "rate", "current transmit rate" },
266 { 4, "rssi", "rssi", "current rssi" },
268 { 4, "noise", "noise", "current noise floor (dBm)" },
269 #define S_RX_UCAST 97
270 { 8, "rx_ucast", "rx_ucast", "unicast data frames received" },
271 #define S_RX_MCAST 98
272 { 8, "rx_mcast", "rx_mcast", "multicast data frames received" },
273 #define S_TX_UCAST 99
274 { 8, "tx_ucast", "tx_ucast", "unicast data frames sent" },
275 #define S_TX_MCAST 100
276 { 8, "tx_mcast", "tx_mcast", "multicast data frames sent" },
278 { 4, "signal", "sig", "current signal (dBm)" },
280 #define S_LAST S_RX_DEFRAG
281 #define S_MAX S_LAST+1
283 struct wlanstatfoo_p {
284 struct wlanstatfoo base;
287 uint8_t mac[IEEE80211_ADDR_LEN];
289 struct ieee80211_stats cur;
290 struct ieee80211_stats total;
291 struct ieee80211req ireq;
293 struct ieee80211req_sta_req info;
296 struct ieee80211req_sta_stats ncur;
297 struct ieee80211req_sta_stats ntotal;
301 wlan_setifname(struct wlanstatfoo *wf0, const char *ifname)
303 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
305 strncpy(wf->ifr.ifr_name, ifname, sizeof (wf->ifr.ifr_name));
306 strncpy(wf->ireq.i_name, ifname, sizeof (wf->ireq.i_name));
310 wlan_getifname(struct wlanstatfoo *wf0)
312 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
314 return wf->ifr.ifr_name;
318 wlan_getopmode(struct wlanstatfoo *wf0)
320 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
322 if (wf->opmode == -1) {
323 struct ifmediareq ifmr;
325 memset(&ifmr, 0, sizeof(ifmr));
326 strlcpy(ifmr.ifm_name, wf->ifr.ifr_name, sizeof(ifmr.ifm_name));
327 if (ioctl(wf->s, SIOCGIFMEDIA, &ifmr) < 0)
328 err(1, "%s (SIOCGIFMEDIA)", wf->ifr.ifr_name);
329 if (ifmr.ifm_current & IFM_IEEE80211_ADHOC)
330 wf->opmode = IEEE80211_M_IBSS; /* XXX ahdemo */
331 else if (ifmr.ifm_current & IFM_IEEE80211_HOSTAP)
332 wf->opmode = IEEE80211_M_HOSTAP;
333 else if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
334 wf->opmode = IEEE80211_M_MONITOR;
336 wf->opmode = IEEE80211_M_STA;
342 getlladdr(struct wlanstatfoo_p *wf)
344 const struct sockaddr_dl *sdl;
345 struct ifaddrs *ifp, *p;
347 if (getifaddrs(&ifp) != 0)
348 err(1, "getifaddrs");
349 for (p = ifp; p != NULL; p = p->ifa_next)
350 if (strcmp(p->ifa_name, wf->ifr.ifr_name) == 0 &&
351 p->ifa_addr->sa_family == AF_LINK)
354 errx(1, "did not find link layer address for interface %s",
356 sdl = (const struct sockaddr_dl *) p->ifa_addr;
357 IEEE80211_ADDR_COPY(wf->mac, LLADDR(sdl));
362 wlan_setstamac(struct wlanstatfoo *wf0, const uint8_t *mac)
364 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) wf0;
367 switch (wlan_getopmode(wf0)) {
368 case IEEE80211_M_HOSTAP:
369 case IEEE80211_M_MONITOR:
370 case IEEE80211_M_IBSS:
371 case IEEE80211_M_AHDEMO:
374 case IEEE80211_M_STA:
375 wf->ireq.i_type = IEEE80211_IOC_BSSID;
376 wf->ireq.i_data = wf->mac;
377 wf->ireq.i_len = IEEE80211_ADDR_LEN;
378 if (ioctl(wf->s, SIOCG80211, &wf->ireq) <0)
379 err(1, wf->ireq.i_name);
383 IEEE80211_ADDR_COPY(wf->mac, mac);
386 /* XXX only fetch what's needed to do reports */
388 wlan_collect(struct wlanstatfoo_p *wf,
389 struct ieee80211_stats *stats, struct ieee80211req_sta_stats *nstats)
392 IEEE80211_ADDR_COPY(wf->u_info.info.is_u.macaddr, wf->mac);
393 wf->ireq.i_type = IEEE80211_IOC_STA_INFO;
394 wf->ireq.i_data = (caddr_t) &wf->u_info;
395 wf->ireq.i_len = sizeof(wf->u_info);
396 if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0)
397 err(1, wf->ireq.i_name);
399 IEEE80211_ADDR_COPY(nstats->is_u.macaddr, wf->mac);
400 wf->ireq.i_type = IEEE80211_IOC_STA_STATS;
401 wf->ireq.i_data = (caddr_t) nstats;
402 wf->ireq.i_len = sizeof(*nstats);
403 if (ioctl(wf->s, SIOCG80211, &wf->ireq) < 0)
404 err(1, wf->ireq.i_name);
406 wf->ifr.ifr_data = (caddr_t) stats;
407 if (ioctl(wf->s, SIOCG80211STATS, &wf->ifr) < 0)
408 err(1, wf->ifr.ifr_name);
412 wlan_collect_cur(struct statfoo *sf)
414 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
416 wlan_collect(wf, &wf->cur, &wf->ncur);
420 wlan_collect_tot(struct statfoo *sf)
422 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
424 wlan_collect(wf, &wf->total, &wf->ntotal);
428 wlan_update_tot(struct statfoo *sf)
430 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
433 wf->ntotal = wf->ncur;
437 wlan_getinfo(struct wlanstatfoo_p *wf, int s, char b[], size_t bs)
439 const struct ieee80211req_sta_info *si = &wf->u_info.info.info[0];
444 r = si->isi_rates[si->isi_txrate];
445 snprintf(b, bs, "%uM", (r &~ 0x80) / 2);
448 snprintf(b, bs, "%d", si->isi_rssi);
451 snprintf(b, bs, "%d", si->isi_noise);
454 snprintf(b, bs, "%d", si->isi_rssi + si->isi_noise);
462 wlan_get_curstat(struct statfoo *sf, int s, char b[], size_t bs)
464 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
466 snprintf(b, bs, "%u", wf->cur.is_##x - wf->total.is_##x); return 1
468 snprintf(b, bs, "%u", \
469 wf->ncur.is_stats.ns_##x - wf->ntotal.is_stats.ns_##x); \
473 case S_RX_BADVERSION: STAT(rx_badversion);
474 case S_RX_TOOSHORT: STAT(rx_tooshort);
475 case S_RX_WRONGBSS: STAT(rx_wrongbss);
476 case S_RX_DUP: STAT(rx_dup);
477 case S_RX_WRONGDIR: STAT(rx_wrongdir);
478 case S_RX_MCASTECHO: STAT(rx_mcastecho);
479 case S_RX_NOTASSOC: STAT(rx_notassoc);
480 case S_RX_NOPRIVACY: STAT(rx_noprivacy);
481 case S_RX_UNENCRYPTED: STAT(rx_unencrypted);
482 case S_RX_WEPFAIL: STAT(rx_wepfail);
483 case S_RX_DECAP: STAT(rx_decap);
484 case S_RX_MGTDISCARD: STAT(rx_mgtdiscard);
485 case S_RX_CTL: STAT(rx_ctl);
486 case S_RX_BEACON: STAT(rx_beacon);
487 case S_RX_RSTOOBIG: STAT(rx_rstoobig);
488 case S_RX_ELEM_MISSING: STAT(rx_elem_missing);
489 case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig);
490 case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall);
491 case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown);
492 case S_RX_BADCHAN: STAT(rx_badchan);
493 case S_RX_CHANMISMATCH: STAT(rx_chanmismatch);
494 case S_RX_NODEALLOC: STAT(rx_nodealloc);
495 case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch);
496 case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported);
497 case S_RX_AUTH_FAIL: STAT(rx_auth_fail);
498 case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures);
499 case S_RX_ASSOC_BSS: STAT(rx_assoc_bss);
500 case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth);
501 case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch);
502 case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate);
503 case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie);
504 case S_RX_DEAUTH: STAT(rx_deauth);
505 case S_RX_DISASSOC: STAT(rx_disassoc);
506 case S_RX_BADSUBTYPE: STAT(rx_badsubtype);
507 case S_RX_NOBUF: STAT(rx_nobuf);
508 case S_RX_DECRYPTCRC: STAT(rx_decryptcrc);
509 case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt);
510 case S_RX_BAD_AUTH: STAT(rx_bad_auth);
511 case S_RX_UNAUTH: STAT(rx_unauth);
512 case S_RX_BADKEYID: STAT(rx_badkeyid);
513 case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay);
514 case S_RX_CCMPFORMAT: STAT(rx_ccmpformat);
515 case S_RX_CCMPMIC: STAT(rx_ccmpmic);
516 case S_RX_TKIPREPLAY: STAT(rx_tkipreplay);
517 case S_RX_TKIPFORMAT: STAT(rx_tkipformat);
518 case S_RX_TKIPMIC: STAT(rx_tkipmic);
519 case S_RX_TKIPICV: STAT(rx_tkipicv);
520 case S_RX_BADCIPHER: STAT(rx_badcipher);
521 case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx);
522 case S_RX_ACL: STAT(rx_acl);
523 case S_TX_NOBUF: STAT(tx_nobuf);
524 case S_TX_NONODE: STAT(tx_nonode);
525 case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt);
526 case S_TX_BADCIPHER: STAT(tx_badcipher);
527 case S_TX_NODEFKEY: STAT(tx_nodefkey);
528 case S_TX_NOHEADROOM: STAT(tx_noheadroom);
529 case S_TX_FRAGFRAMES: STAT(tx_fragframes);
530 case S_TX_FRAGS: STAT(tx_frags);
531 case S_SCAN_ACTIVE: STAT(scan_active);
532 case S_SCAN_PASSIVE: STAT(scan_passive);
533 case S_NODE_TIMEOUT: STAT(node_timeout);
534 case S_CRYPTO_NOMEM: STAT(crypto_nomem);
535 case S_CRYPTO_TKIP: STAT(crypto_tkip);
536 case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic);
537 case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic);
538 case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm);
539 case S_CRYPTO_CCMP: STAT(crypto_ccmp);
540 case S_CRYPTO_WEP: STAT(crypto_wep);
541 case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher);
542 case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey);
543 case S_CRYPTO_DELKEY: STAT(crypto_delkey);
544 case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher);
545 case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher);
546 case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail);
547 case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback);
548 case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail);
549 case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail);
550 case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch);
551 case S_IBSS_NORATE: STAT(ibss_norate);
552 case S_PS_UNASSOC: STAT(ps_unassoc);
553 case S_PS_BADAID: STAT(ps_badaid);
554 case S_PS_QEMPTY: STAT(ps_qempty);
555 case S_FF_BADHDR: STAT(ff_badhdr);
556 case S_FF_TOOSHORT: STAT(ff_tooshort);
557 case S_FF_SPLIT: STAT(ff_split);
558 case S_FF_DECAP: STAT(ff_decap);
559 case S_FF_ENCAP: STAT(ff_encap);
560 case S_RX_BADBINTVAL: STAT(rx_badbintval);
561 case S_RX_MGMT: STAT(rx_mgmt);
562 case S_RX_DEMICFAIL: STAT(rx_demicfail);
563 case S_RX_DEFRAG: STAT(rx_defrag);
564 case S_INPUT: NSTAT(rx_data);
565 case S_OUTPUT: NSTAT(tx_data);
566 case S_RX_UCAST: NSTAT(rx_ucast);
567 case S_RX_MCAST: NSTAT(rx_mcast);
568 case S_TX_UCAST: NSTAT(tx_ucast);
569 case S_TX_MCAST: NSTAT(tx_mcast);
571 return wlan_getinfo(wf, s, b, bs);
577 wlan_get_totstat(struct statfoo *sf, int s, char b[], size_t bs)
579 struct wlanstatfoo_p *wf = (struct wlanstatfoo_p *) sf;
581 snprintf(b, bs, "%u", wf->total.is_##x); return 1
583 snprintf(b, bs, "%u", wf->ntotal.is_stats.ns_##x); return 1
586 case S_RX_BADVERSION: STAT(rx_badversion);
587 case S_RX_TOOSHORT: STAT(rx_tooshort);
588 case S_RX_WRONGBSS: STAT(rx_wrongbss);
589 case S_RX_DUP: STAT(rx_dup);
590 case S_RX_WRONGDIR: STAT(rx_wrongdir);
591 case S_RX_MCASTECHO: STAT(rx_mcastecho);
592 case S_RX_NOTASSOC: STAT(rx_notassoc);
593 case S_RX_NOPRIVACY: STAT(rx_noprivacy);
594 case S_RX_UNENCRYPTED: STAT(rx_unencrypted);
595 case S_RX_WEPFAIL: STAT(rx_wepfail);
596 case S_RX_DECAP: STAT(rx_decap);
597 case S_RX_MGTDISCARD: STAT(rx_mgtdiscard);
598 case S_RX_CTL: STAT(rx_ctl);
599 case S_RX_BEACON: STAT(rx_beacon);
600 case S_RX_RSTOOBIG: STAT(rx_rstoobig);
601 case S_RX_ELEM_MISSING: STAT(rx_elem_missing);
602 case S_RX_ELEM_TOOBIG: STAT(rx_elem_toobig);
603 case S_RX_ELEM_TOOSMALL: STAT(rx_elem_toosmall);
604 case S_RX_ELEM_UNKNOWN: STAT(rx_elem_unknown);
605 case S_RX_BADCHAN: STAT(rx_badchan);
606 case S_RX_CHANMISMATCH: STAT(rx_chanmismatch);
607 case S_RX_NODEALLOC: STAT(rx_nodealloc);
608 case S_RX_SSIDMISMATCH: STAT(rx_ssidmismatch);
609 case S_RX_AUTH_UNSUPPORTED: STAT(rx_auth_unsupported);
610 case S_RX_AUTH_FAIL: STAT(rx_auth_fail);
611 case S_RX_AUTH_COUNTERMEASURES: STAT(rx_auth_countermeasures);
612 case S_RX_ASSOC_BSS: STAT(rx_assoc_bss);
613 case S_RX_ASSOC_NOTAUTH: STAT(rx_assoc_notauth);
614 case S_RX_ASSOC_CAPMISMATCH: STAT(rx_assoc_capmismatch);
615 case S_RX_ASSOC_NORATE: STAT(rx_assoc_norate);
616 case S_RX_ASSOC_BADWPAIE: STAT(rx_assoc_badwpaie);
617 case S_RX_DEAUTH: STAT(rx_deauth);
618 case S_RX_DISASSOC: STAT(rx_disassoc);
619 case S_RX_BADSUBTYPE: STAT(rx_badsubtype);
620 case S_RX_NOBUF: STAT(rx_nobuf);
621 case S_RX_DECRYPTCRC: STAT(rx_decryptcrc);
622 case S_RX_AHDEMO_MGT: STAT(rx_ahdemo_mgt);
623 case S_RX_BAD_AUTH: STAT(rx_bad_auth);
624 case S_RX_UNAUTH: STAT(rx_unauth);
625 case S_RX_BADKEYID: STAT(rx_badkeyid);
626 case S_RX_CCMPREPLAY: STAT(rx_ccmpreplay);
627 case S_RX_CCMPFORMAT: STAT(rx_ccmpformat);
628 case S_RX_CCMPMIC: STAT(rx_ccmpmic);
629 case S_RX_TKIPREPLAY: STAT(rx_tkipreplay);
630 case S_RX_TKIPFORMAT: STAT(rx_tkipformat);
631 case S_RX_TKIPMIC: STAT(rx_tkipmic);
632 case S_RX_TKIPICV: STAT(rx_tkipicv);
633 case S_RX_BADCIPHER: STAT(rx_badcipher);
634 case S_RX_NOCIPHERCTX: STAT(rx_nocipherctx);
635 case S_RX_ACL: STAT(rx_acl);
636 case S_TX_NOBUF: STAT(tx_nobuf);
637 case S_TX_NONODE: STAT(tx_nonode);
638 case S_TX_UNKNOWNMGT: STAT(tx_unknownmgt);
639 case S_TX_BADCIPHER: STAT(tx_badcipher);
640 case S_TX_NODEFKEY: STAT(tx_nodefkey);
641 case S_TX_NOHEADROOM: STAT(tx_noheadroom);
642 case S_TX_FRAGFRAMES: STAT(tx_fragframes);
643 case S_TX_FRAGS: STAT(tx_frags);
644 case S_SCAN_ACTIVE: STAT(scan_active);
645 case S_SCAN_PASSIVE: STAT(scan_passive);
646 case S_NODE_TIMEOUT: STAT(node_timeout);
647 case S_CRYPTO_NOMEM: STAT(crypto_nomem);
648 case S_CRYPTO_TKIP: STAT(crypto_tkip);
649 case S_CRYPTO_TKIPENMIC: STAT(crypto_tkipenmic);
650 case S_CRYPTO_TKIPDEMIC: STAT(crypto_tkipdemic);
651 case S_CRYPTO_TKIPCM: STAT(crypto_tkipcm);
652 case S_CRYPTO_CCMP: STAT(crypto_ccmp);
653 case S_CRYPTO_WEP: STAT(crypto_wep);
654 case S_CRYPTO_SETKEY_CIPHER: STAT(crypto_setkey_cipher);
655 case S_CRYPTO_SETKEY_NOKEY: STAT(crypto_setkey_nokey);
656 case S_CRYPTO_DELKEY: STAT(crypto_delkey);
657 case S_CRYPTO_BADCIPHER: STAT(crypto_badcipher);
658 case S_CRYPTO_NOCIPHER: STAT(crypto_nocipher);
659 case S_CRYPTO_ATTACHFAIL: STAT(crypto_attachfail);
660 case S_CRYPTO_SWFALLBACK: STAT(crypto_swfallback);
661 case S_CRYPTO_KEYFAIL: STAT(crypto_keyfail);
662 case S_CRYPTO_ENMICFAIL: STAT(crypto_enmicfail);
663 case S_IBSS_CAPMISMATCH: STAT(ibss_capmismatch);
664 case S_IBSS_NORATE: STAT(ibss_norate);
665 case S_PS_UNASSOC: STAT(ps_unassoc);
666 case S_PS_BADAID: STAT(ps_badaid);
667 case S_PS_QEMPTY: STAT(ps_qempty);
668 case S_FF_BADHDR: STAT(ff_badhdr);
669 case S_FF_TOOSHORT: STAT(ff_tooshort);
670 case S_FF_SPLIT: STAT(ff_split);
671 case S_FF_DECAP: STAT(ff_decap);
672 case S_FF_ENCAP: STAT(ff_encap);
673 case S_RX_BADBINTVAL: STAT(rx_badbintval);
674 case S_RX_MGMT: STAT(rx_mgmt);
675 case S_RX_DEMICFAIL: STAT(rx_demicfail);
676 case S_RX_DEFRAG: STAT(rx_defrag);
677 case S_INPUT: NSTAT(rx_data);
678 case S_OUTPUT: NSTAT(tx_data);
679 case S_RX_UCAST: NSTAT(rx_ucast);
680 case S_RX_MCAST: NSTAT(rx_mcast);
681 case S_TX_UCAST: NSTAT(tx_ucast);
682 case S_TX_MCAST: NSTAT(tx_mcast);
684 return wlan_getinfo(wf, s, b, bs);
689 STATFOO_DEFINE_BOUNCE(wlanstatfoo)
692 wlanstats_new(const char *ifname, const char *fmtstring)
694 #define N(a) (sizeof(a) / sizeof(a[0]))
695 struct wlanstatfoo_p *wf;
697 wf = calloc(1, sizeof(struct wlanstatfoo_p));
699 statfoo_init(&wf->base.base, "wlanstats", wlanstats, N(wlanstats));
700 /* override base methods */
701 wf->base.base.collect_cur = wlan_collect_cur;
702 wf->base.base.collect_tot = wlan_collect_tot;
703 wf->base.base.get_curstat = wlan_get_curstat;
704 wf->base.base.get_totstat = wlan_get_totstat;
705 wf->base.base.update_tot = wlan_update_tot;
707 /* setup bounce functions for public methods */
708 STATFOO_BOUNCE(wf, wlanstatfoo);
710 /* setup our public methods */
711 wf->base.setifname = wlan_setifname;
712 wf->base.getifname = wlan_getifname;
713 wf->base.getopmode = wlan_getopmode;
714 wf->base.setstamac = wlan_setstamac;
717 wf->s = socket(AF_INET, SOCK_DGRAM, 0);
721 wlan_setifname(&wf->base, ifname);
722 wf->base.setfmt(&wf->base, fmtstring);