source: rtems-libbsd/freebsd/tools/tools/net80211/wlanstats/wlanstats.c @ d415406

55-freebsd-126-freebsd-12
Last change on this file since d415406 was d415406, checked in by Christian Mauderer <Christian.Mauderer@…>, on 12/09/16 at 08:15:24

freebsd/wlanstats: Import from FreeBSD.

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