1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "Nl80211.h"
18 
19 #include "../../structs.h"
20 #include "common.h"
21 
22 #include <linux/nl80211.h>
23 
24 #include <iomanip>
25 
26 namespace android::nl::protocols::generic::families {
27 
28 /**
29  * Reduce verbosity of printed Information Elements.
30  */
31 static constexpr bool kCompactIE = true;
32 
33 enum {
34     // broken compatibility in Aug 2020
35     NL80211_ATTR_CNTDWN_OFFS_BEACON = NL80211_ATTR_CSA_C_OFF_BEACON,
36     NL80211_ATTR_CNTDWN_OFFS_PRESP = NL80211_ATTR_CSA_C_OFF_PRESP,
37 
38     // new fields not available in current Android
39     NL80211_ATTR_FILS_DISCOVERY = NL80211_ATTR_HE_6GHZ_CAPABILITY + 1,
40     NL80211_ATTR_UNSOL_BCAST_PROBE_RESP,
41     NL80211_ATTR_S1G_CAPABILITY,
42     NL80211_ATTR_S1G_CAPABILITY_MASK,
43 
44     NL80211_FREQUENCY_ATTR_1MHZ = NL80211_FREQUENCY_ATTR_OFFSET + 1,
45     NL80211_FREQUENCY_ATTR_2MHZ,
46     NL80211_FREQUENCY_ATTR_4MHZ,
47     NL80211_FREQUENCY_ATTR_8MHZ,
48     NL80211_FREQUENCY_ATTR_16MHZ,
49 };
50 
51 enum ieee80211_eid {
52     WLAN_EID_SSID = 0,
53 };
54 
55 using DataType = AttributeDefinition::DataType;
56 using Flags = AttributeDefinition::Flags;
57 
58 static void informationElementsToStream(std::stringstream& ss, const Buffer<nlattr> attr);
59 static void nl80211_pattern_supportToStream(std::stringstream& ss, const Buffer<nlattr> attr);
60 
61 static const AttributeMap iftypes{
62         {NL80211_IFTYPE_UNSPECIFIED, {"UNSPECIFIED", DataType::Flag}},
63         {NL80211_IFTYPE_ADHOC, {"ADHOC", DataType::Flag}},
64         {NL80211_IFTYPE_STATION, {"STATION", DataType::Flag}},
65         {NL80211_IFTYPE_AP, {"AP", DataType::Flag}},
66         {NL80211_IFTYPE_AP_VLAN, {"AP_VLAN", DataType::Flag}},
67         {NL80211_IFTYPE_WDS, {"WDS", DataType::Flag}},
68         {NL80211_IFTYPE_MONITOR, {"MONITOR", DataType::Flag}},
69         {NL80211_IFTYPE_MESH_POINT, {"MESH_POINT", DataType::Flag}},
70         {NL80211_IFTYPE_P2P_CLIENT, {"P2P_CLIENT", DataType::Flag}},
71         {NL80211_IFTYPE_P2P_GO, {"P2P_GO", DataType::Flag}},
72         {NL80211_IFTYPE_P2P_DEVICE, {"P2P_DEVICE", DataType::Flag}},
73         {NL80211_IFTYPE_OCB, {"OCB", DataType::Flag}},
74         {NL80211_IFTYPE_NAN, {"NAN", DataType::Flag}},
75 };
76 
77 // clang-format off
Nl80211(nlmsgtype_t familyId)78 Nl80211::Nl80211(nlmsgtype_t familyId) : GenericMessageBase(familyId, "nl80211", {
79     /* Script to generate the (initial) top-level list from linux/nl80211.h:
80      * sed -e 's/^  NL80211_CMD_\(.*\),$/    {NL80211_CMD_\1, "\1"},/g'
81      */
82     {NL80211_CMD_UNSPEC, "UNSPEC"},
83 
84     {NL80211_CMD_GET_WIPHY, "GET_WIPHY"},
85     {NL80211_CMD_SET_WIPHY, "SET_WIPHY"},
86     {NL80211_CMD_NEW_WIPHY, "NEW_WIPHY"},
87     {NL80211_CMD_DEL_WIPHY, "DEL_WIPHY"},
88 
89     {NL80211_CMD_GET_INTERFACE, "GET_INTERFACE"},
90     {NL80211_CMD_SET_INTERFACE, "SET_INTERFACE"},
91     {NL80211_CMD_NEW_INTERFACE, "NEW_INTERFACE"},
92     {NL80211_CMD_DEL_INTERFACE, "DEL_INTERFACE"},
93 
94     {NL80211_CMD_GET_KEY, "GET_KEY"},
95     {NL80211_CMD_SET_KEY, "SET_KEY"},
96     {NL80211_CMD_NEW_KEY, "NEW_KEY"},
97     {NL80211_CMD_DEL_KEY, "DEL_KEY"},
98 
99     {NL80211_CMD_GET_BEACON, "GET_BEACON"},
100     {NL80211_CMD_SET_BEACON, "SET_BEACON"},
101     {NL80211_CMD_START_AP, "START_AP"},
102     {NL80211_CMD_STOP_AP, "STOP_AP"},
103 
104     {NL80211_CMD_GET_STATION, "GET_STATION"},
105     {NL80211_CMD_SET_STATION, "SET_STATION"},
106     {NL80211_CMD_NEW_STATION, "NEW_STATION"},
107     {NL80211_CMD_DEL_STATION, "DEL_STATION"},
108 
109     {NL80211_CMD_GET_MPATH, "GET_MPATH"},
110     {NL80211_CMD_SET_MPATH, "SET_MPATH"},
111     {NL80211_CMD_NEW_MPATH, "NEW_MPATH"},
112     {NL80211_CMD_DEL_MPATH, "DEL_MPATH"},
113 
114     {NL80211_CMD_SET_BSS, "SET_BSS"},
115 
116     {NL80211_CMD_SET_REG, "SET_REG"},
117     {NL80211_CMD_REQ_SET_REG, "REQ_SET_REG"},
118 
119     {NL80211_CMD_GET_MESH_CONFIG, "GET_MESH_CONFIG"},
120     {NL80211_CMD_SET_MESH_CONFIG, "SET_MESH_CONFIG"},
121 
122     {NL80211_CMD_SET_MGMT_EXTRA_IE, "SET_MGMT_EXTRA_IE"},
123 
124     {NL80211_CMD_GET_REG, "GET_REG"},
125 
126     {NL80211_CMD_GET_SCAN, "GET_SCAN"},
127     {NL80211_CMD_TRIGGER_SCAN, "TRIGGER_SCAN"},
128     {NL80211_CMD_NEW_SCAN_RESULTS, "NEW_SCAN_RESULTS"},
129     {NL80211_CMD_SCAN_ABORTED, "SCAN_ABORTED"},
130 
131     {NL80211_CMD_REG_CHANGE, "REG_CHANGE"},
132 
133     {NL80211_CMD_AUTHENTICATE, "AUTHENTICATE"},
134     {NL80211_CMD_ASSOCIATE, "ASSOCIATE"},
135     {NL80211_CMD_DEAUTHENTICATE, "DEAUTHENTICATE"},
136     {NL80211_CMD_DISASSOCIATE, "DISASSOCIATE"},
137 
138     {NL80211_CMD_MICHAEL_MIC_FAILURE, "MICHAEL_MIC_FAILURE"},
139 
140     {NL80211_CMD_REG_BEACON_HINT, "REG_BEACON_HINT"},
141 
142     {NL80211_CMD_JOIN_IBSS, "JOIN_IBSS"},
143     {NL80211_CMD_LEAVE_IBSS, "LEAVE_IBSS"},
144 
145     {NL80211_CMD_TESTMODE, "TESTMODE"},
146 
147     {NL80211_CMD_CONNECT, "CONNECT"},
148     {NL80211_CMD_ROAM, "ROAM"},
149     {NL80211_CMD_DISCONNECT, "DISCONNECT"},
150 
151     {NL80211_CMD_SET_WIPHY_NETNS, "SET_WIPHY_NETNS"},
152 
153     {NL80211_CMD_GET_SURVEY, "GET_SURVEY"},
154     {NL80211_CMD_NEW_SURVEY_RESULTS, "NEW_SURVEY_RESULTS"},
155 
156     {NL80211_CMD_SET_PMKSA, "SET_PMKSA"},
157     {NL80211_CMD_DEL_PMKSA, "DEL_PMKSA"},
158     {NL80211_CMD_FLUSH_PMKSA, "FLUSH_PMKSA"},
159 
160     {NL80211_CMD_REMAIN_ON_CHANNEL, "REMAIN_ON_CHANNEL"},
161     {NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, "CANCEL_REMAIN_ON_CHANNEL"},
162 
163     {NL80211_CMD_SET_TX_BITRATE_MASK, "SET_TX_BITRATE_MASK"},
164 
165     {NL80211_CMD_REGISTER_FRAME, "REGISTER_FRAME"},
166     {NL80211_CMD_FRAME, "FRAME"},
167     {NL80211_CMD_FRAME_TX_STATUS, "FRAME_TX_STATUS"},
168 
169     {NL80211_CMD_SET_POWER_SAVE, "SET_POWER_SAVE"},
170     {NL80211_CMD_GET_POWER_SAVE, "GET_POWER_SAVE"},
171 
172     {NL80211_CMD_SET_CQM, "SET_CQM"},
173     {NL80211_CMD_NOTIFY_CQM, "NOTIFY_CQM"},
174 
175     {NL80211_CMD_SET_CHANNEL, "SET_CHANNEL"},
176     {NL80211_CMD_SET_WDS_PEER, "SET_WDS_PEER"},
177 
178     {NL80211_CMD_FRAME_WAIT_CANCEL, "FRAME_WAIT_CANCEL"},
179 
180     {NL80211_CMD_JOIN_MESH, "JOIN_MESH"},
181     {NL80211_CMD_LEAVE_MESH, "LEAVE_MESH"},
182 
183     {NL80211_CMD_UNPROT_DEAUTHENTICATE, "UNPROT_DEAUTHENTICATE"},
184     {NL80211_CMD_UNPROT_DISASSOCIATE, "UNPROT_DISASSOCIATE"},
185 
186     {NL80211_CMD_NEW_PEER_CANDIDATE, "NEW_PEER_CANDIDATE"},
187 
188     {NL80211_CMD_GET_WOWLAN, "GET_WOWLAN"},
189     {NL80211_CMD_SET_WOWLAN, "SET_WOWLAN"},
190 
191     {NL80211_CMD_START_SCHED_SCAN, "START_SCHED_SCAN"},
192     {NL80211_CMD_STOP_SCHED_SCAN, "STOP_SCHED_SCAN"},
193     {NL80211_CMD_SCHED_SCAN_RESULTS, "SCHED_SCAN_RESULTS"},
194     {NL80211_CMD_SCHED_SCAN_STOPPED, "SCHED_SCAN_STOPPED"},
195 
196     {NL80211_CMD_SET_REKEY_OFFLOAD, "SET_REKEY_OFFLOAD"},
197 
198     {NL80211_CMD_PMKSA_CANDIDATE, "PMKSA_CANDIDATE"},
199 
200     {NL80211_CMD_TDLS_OPER, "TDLS_OPER"},
201     {NL80211_CMD_TDLS_MGMT, "TDLS_MGMT"},
202 
203     {NL80211_CMD_UNEXPECTED_FRAME, "UNEXPECTED_FRAME"},
204 
205     {NL80211_CMD_PROBE_CLIENT, "PROBE_CLIENT"},
206 
207     {NL80211_CMD_REGISTER_BEACONS, "REGISTER_BEACONS"},
208 
209     {NL80211_CMD_UNEXPECTED_4ADDR_FRAME, "UNEXPECTED_4ADDR_FRAME"},
210 
211     {NL80211_CMD_SET_NOACK_MAP, "SET_NOACK_MAP"},
212 
213     {NL80211_CMD_CH_SWITCH_NOTIFY, "CH_SWITCH_NOTIFY"},
214 
215     {NL80211_CMD_START_P2P_DEVICE, "START_P2P_DEVICE"},
216     {NL80211_CMD_STOP_P2P_DEVICE, "STOP_P2P_DEVICE"},
217 
218     {NL80211_CMD_CONN_FAILED, "CONN_FAILED"},
219 
220     {NL80211_CMD_SET_MCAST_RATE, "SET_MCAST_RATE"},
221 
222     {NL80211_CMD_SET_MAC_ACL, "SET_MAC_ACL"},
223 
224     {NL80211_CMD_RADAR_DETECT, "RADAR_DETECT"},
225 
226     {NL80211_CMD_GET_PROTOCOL_FEATURES, "GET_PROTOCOL_FEATURES"},
227 
228     {NL80211_CMD_UPDATE_FT_IES, "UPDATE_FT_IES"},
229     {NL80211_CMD_FT_EVENT, "FT_EVENT"},
230 
231     {NL80211_CMD_CRIT_PROTOCOL_START, "CRIT_PROTOCOL_START"},
232     {NL80211_CMD_CRIT_PROTOCOL_STOP, "CRIT_PROTOCOL_STOP"},
233 
234     {NL80211_CMD_GET_COALESCE, "GET_COALESCE"},
235     {NL80211_CMD_SET_COALESCE, "SET_COALESCE"},
236 
237     {NL80211_CMD_CHANNEL_SWITCH, "CHANNEL_SWITCH"},
238 
239     {NL80211_CMD_VENDOR, "VENDOR"},
240 
241     {NL80211_CMD_SET_QOS_MAP, "SET_QOS_MAP"},
242 
243     {NL80211_CMD_ADD_TX_TS, "ADD_TX_TS"},
244     {NL80211_CMD_DEL_TX_TS, "DEL_TX_TS"},
245 
246     {NL80211_CMD_GET_MPP, "GET_MPP"},
247 
248     {NL80211_CMD_JOIN_OCB, "JOIN_OCB"},
249     {NL80211_CMD_LEAVE_OCB, "LEAVE_OCB"},
250 
251     {NL80211_CMD_CH_SWITCH_STARTED_NOTIFY, "CH_SWITCH_STARTED_NOTIFY"},
252 
253     {NL80211_CMD_TDLS_CHANNEL_SWITCH, "TDLS_CHANNEL_SWITCH"},
254     {NL80211_CMD_TDLS_CANCEL_CHANNEL_SWITCH, "TDLS_CANCEL_CHANNEL_SWITCH"},
255 
256     {NL80211_CMD_WIPHY_REG_CHANGE, "WIPHY_REG_CHANGE"},
257 
258     {NL80211_CMD_ABORT_SCAN, "ABORT_SCAN"},
259 
260     {NL80211_CMD_START_NAN, "START_NAN"},
261     {NL80211_CMD_STOP_NAN, "STOP_NAN"},
262     {NL80211_CMD_ADD_NAN_FUNCTION, "ADD_NAN_FUNCTION"},
263     {NL80211_CMD_DEL_NAN_FUNCTION, "DEL_NAN_FUNCTION"},
264     {NL80211_CMD_CHANGE_NAN_CONFIG, "CHANGE_NAN_CONFIG"},
265     {NL80211_CMD_NAN_MATCH, "NAN_MATCH"},
266 
267     {NL80211_CMD_SET_MULTICAST_TO_UNICAST, "SET_MULTICAST_TO_UNICAST"},
268 
269     {NL80211_CMD_UPDATE_CONNECT_PARAMS, "UPDATE_CONNECT_PARAMS"},
270 
271     {NL80211_CMD_SET_PMK, "SET_PMK"},
272     {NL80211_CMD_DEL_PMK, "DEL_PMK"},
273 
274     {NL80211_CMD_PORT_AUTHORIZED, "PORT_AUTHORIZED"},
275 
276     {NL80211_CMD_RELOAD_REGDB, "RELOAD_REGDB"},
277 
278     {NL80211_CMD_EXTERNAL_AUTH, "EXTERNAL_AUTH"},
279 
280     {NL80211_CMD_STA_OPMODE_CHANGED, "STA_OPMODE_CHANGED"},
281 
282     {NL80211_CMD_CONTROL_PORT_FRAME, "CONTROL_PORT_FRAME"},
283 
284     {NL80211_CMD_GET_FTM_RESPONDER_STATS, "GET_FTM_RESPONDER_STATS"},
285 
286     {NL80211_CMD_PEER_MEASUREMENT_START, "PEER_MEASUREMENT_START"},
287     {NL80211_CMD_PEER_MEASUREMENT_RESULT, "PEER_MEASUREMENT_RESULT"},
288     {NL80211_CMD_PEER_MEASUREMENT_COMPLETE, "PEER_MEASUREMENT_COMPLETE"},
289 
290     {NL80211_CMD_NOTIFY_RADAR, "NOTIFY_RADAR"},
291 
292     {NL80211_CMD_UPDATE_OWE_INFO, "UPDATE_OWE_INFO"},
293 
294     {NL80211_CMD_PROBE_MESH_LINK, "PROBE_MESH_LINK"},
295 
296     {NL80211_CMD_SET_TID_CONFIG, "SET_TID_CONFIG"},
297 
298     {NL80211_CMD_UNPROT_BEACON, "UNPROT_BEACON"},
299 
300     {NL80211_CMD_CONTROL_PORT_FRAME_TX_STATUS, "CONTROL_PORT_FRAME_TX_STATUS"},
301 }, {
302     /* Script to generate the (initial) top-level list from linux/nl80211.h:
303      * sed -e 's/^\tNL80211_ATTR_\(.*\),$/    {NL80211_ATTR_\1, {"\1"}},/g'
304      */
305     {NL80211_ATTR_UNSPEC, {"UNSPEC"}},
306 
307     {NL80211_ATTR_WIPHY, {"WIPHY", DataType::Uint}},
308     {NL80211_ATTR_WIPHY_NAME, {"WIPHY_NAME", DataType::StringNul}},
309 
310     {NL80211_ATTR_IFINDEX, {"IFINDEX", DataType::Uint}},
311     {NL80211_ATTR_IFNAME, {"IFNAME", DataType::StringNul}},
312     {NL80211_ATTR_IFTYPE, {"IFTYPE", DataType::Uint}},
313 
314     {NL80211_ATTR_MAC, {"MAC", DataType::Raw}},
315 
316     {NL80211_ATTR_KEY_DATA, {"KEY_DATA"}},
317     {NL80211_ATTR_KEY_IDX, {"KEY_IDX"}},
318     {NL80211_ATTR_KEY_CIPHER, {"KEY_CIPHER"}},
319     {NL80211_ATTR_KEY_SEQ, {"KEY_SEQ"}},
320     {NL80211_ATTR_KEY_DEFAULT, {"KEY_DEFAULT"}},
321 
322     {NL80211_ATTR_BEACON_INTERVAL, {"BEACON_INTERVAL"}},
323     {NL80211_ATTR_DTIM_PERIOD, {"DTIM_PERIOD"}},
324     {NL80211_ATTR_BEACON_HEAD, {"BEACON_HEAD"}},
325     {NL80211_ATTR_BEACON_TAIL, {"BEACON_TAIL"}},
326 
327     {NL80211_ATTR_STA_AID, {"STA_AID"}},
328     {NL80211_ATTR_STA_FLAGS, {"STA_FLAGS"}},
329     {NL80211_ATTR_STA_LISTEN_INTERVAL, {"STA_LISTEN_INTERVAL"}},
330     {NL80211_ATTR_STA_SUPPORTED_RATES, {"STA_SUPPORTED_RATES"}},
331     {NL80211_ATTR_STA_VLAN, {"STA_VLAN"}},
332     {NL80211_ATTR_STA_INFO, {"STA_INFO"}},
333 
334     {NL80211_ATTR_WIPHY_BANDS, {"WIPHY_BANDS", DataType::Nested, AttributeMap{
335         {std::nullopt, {"BAND", DataType::Nested, AttributeMap{
336             {NL80211_BAND_ATTR_FREQS, {"FREQS", DataType::Nested, AttributeMap{
337                 {std::nullopt, {"FQ", DataType::Nested, AttributeMap{
338                     {NL80211_FREQUENCY_ATTR_FREQ, {"FREQ", DataType::Uint}},
339                     {NL80211_FREQUENCY_ATTR_DISABLED, {"DISABLED", DataType::Flag}},
340                     {NL80211_FREQUENCY_ATTR_NO_IR, {"NO_IR", DataType::Flag}},
341                     {__NL80211_FREQUENCY_ATTR_NO_IBSS, {"_NO_IBSS", DataType::Flag}},
342                     {NL80211_FREQUENCY_ATTR_RADAR, {"RADAR", DataType::Flag}},
343                     {NL80211_FREQUENCY_ATTR_MAX_TX_POWER, {"MAX_TX_POWER", DataType::Uint}},
344                     {NL80211_FREQUENCY_ATTR_DFS_STATE, {"DFS_STATE", DataType::Uint}},
345                     {NL80211_FREQUENCY_ATTR_DFS_TIME, {"DFS_TIME", DataType::Uint}},
346                     {NL80211_FREQUENCY_ATTR_NO_HT40_MINUS, {"NO_HT40_MINUS", DataType::Flag}},
347                     {NL80211_FREQUENCY_ATTR_NO_HT40_PLUS, {"NO_HT40_PLUS", DataType::Flag}},
348                     {NL80211_FREQUENCY_ATTR_NO_80MHZ, {"NO_80MHZ", DataType::Flag}},
349                     {NL80211_FREQUENCY_ATTR_NO_160MHZ, {"NO_160MHZ", DataType::Flag}},
350                     {NL80211_FREQUENCY_ATTR_DFS_CAC_TIME, {"DFS_CAC_TIME", DataType::Uint}},
351                     {NL80211_FREQUENCY_ATTR_INDOOR_ONLY, {"INDOOR_ONLY", DataType::Flag}},
352                     {NL80211_FREQUENCY_ATTR_IR_CONCURRENT, {"IR_CONCURRENT", DataType::Flag}},
353                     {NL80211_FREQUENCY_ATTR_NO_20MHZ, {"NO_20MHZ", DataType::Flag}},
354                     {NL80211_FREQUENCY_ATTR_NO_10MHZ, {"NO_10MHZ", DataType::Flag}},
355                     {NL80211_FREQUENCY_ATTR_WMM, {"WMM"}},
356                     {NL80211_FREQUENCY_ATTR_NO_HE, {"NO_HE", DataType::Flag}},
357                     {NL80211_FREQUENCY_ATTR_OFFSET, {"OFFSET", DataType::Uint}},
358                     {NL80211_FREQUENCY_ATTR_1MHZ, {"1MHZ", DataType::Flag}},
359                     {NL80211_FREQUENCY_ATTR_2MHZ, {"2MHZ", DataType::Flag}},
360                     {NL80211_FREQUENCY_ATTR_4MHZ, {"4MHZ", DataType::Flag}},
361                     {NL80211_FREQUENCY_ATTR_8MHZ, {"8MHZ", DataType::Flag}},
362                     {NL80211_FREQUENCY_ATTR_16MHZ, {"16MHZ", DataType::Flag}},
363                 }}},
364             }, Flags::Verbose}},
365             {NL80211_BAND_ATTR_RATES, {"RATES", DataType::Nested, AttributeMap{
366                 {std::nullopt, {"RATE", DataType::Nested, AttributeMap{
367                     {NL80211_BITRATE_ATTR_RATE, {"RATE", DataType::Uint}},
368                     {NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE,
369                             {"2GHZ_SHORTPREAMBLE", DataType::Flag}},
370                 }}},
371             }}},
372 
373             {NL80211_BAND_ATTR_HT_MCS_SET, {"HT_MCS_SET"}},  // struct ieee80211_mcs_info
374             {NL80211_BAND_ATTR_HT_CAPA, {"HT_CAPA", DataType::Uint}},
375             {NL80211_BAND_ATTR_HT_AMPDU_FACTOR, {"HT_AMPDU_FACTOR", DataType::Uint}},
376             {NL80211_BAND_ATTR_HT_AMPDU_DENSITY, {"HT_AMPDU_DENSITY", DataType::Uint}},
377 
378             {NL80211_BAND_ATTR_VHT_MCS_SET, {"VHT_MCS_SET"}},  // struct ieee80211_vht_mcs_info
379             {NL80211_BAND_ATTR_VHT_CAPA, {"VHT_CAPA", DataType::Uint}},
380             {NL80211_BAND_ATTR_IFTYPE_DATA, {"IFTYPE_DATA"}},
381 
382             {NL80211_BAND_ATTR_EDMG_CHANNELS, {"EDMG_CHANNELS"}},
383             {NL80211_BAND_ATTR_EDMG_BW_CONFIG, {"EDMG_BW_CONFIG"}},
384         }}},
385     }, Flags::Verbose}},
386 
387     {NL80211_ATTR_MNTR_FLAGS, {"MNTR_FLAGS"}},
388 
389     {NL80211_ATTR_MESH_ID, {"MESH_ID"}},
390     {NL80211_ATTR_STA_PLINK_ACTION, {"STA_PLINK_ACTION"}},
391     {NL80211_ATTR_MPATH_NEXT_HOP, {"MPATH_NEXT_HOP"}},
392     {NL80211_ATTR_MPATH_INFO, {"MPATH_INFO"}},
393 
394     {NL80211_ATTR_BSS_CTS_PROT, {"BSS_CTS_PROT"}},
395     {NL80211_ATTR_BSS_SHORT_PREAMBLE, {"BSS_SHORT_PREAMBLE"}},
396     {NL80211_ATTR_BSS_SHORT_SLOT_TIME, {"BSS_SHORT_SLOT_TIME"}},
397 
398     {NL80211_ATTR_HT_CAPABILITY, {"HT_CAPABILITY"}},
399 
400     {NL80211_ATTR_SUPPORTED_IFTYPES, {"SUPPORTED_IFTYPES", DataType::Nested, iftypes}},
401 
402     {NL80211_ATTR_REG_ALPHA2, {"REG_ALPHA2"}},
403     {NL80211_ATTR_REG_RULES, {"REG_RULES"}},
404 
405     {NL80211_ATTR_MESH_CONFIG, {"MESH_CONFIG"}},
406 
407     {NL80211_ATTR_BSS_BASIC_RATES, {"BSS_BASIC_RATES"}},
408 
409     {NL80211_ATTR_WIPHY_TXQ_PARAMS, {"WIPHY_TXQ_PARAMS"}},
410     {NL80211_ATTR_WIPHY_FREQ, {"WIPHY_FREQ"}},
411     {NL80211_ATTR_WIPHY_CHANNEL_TYPE, {"WIPHY_CHANNEL_TYPE"}},
412 
413     {NL80211_ATTR_KEY_DEFAULT_MGMT, {"KEY_DEFAULT_MGMT"}},
414 
415     {NL80211_ATTR_MGMT_SUBTYPE, {"MGMT_SUBTYPE"}},
416     {NL80211_ATTR_IE, {"IE"}},
417 
418     {NL80211_ATTR_MAX_NUM_SCAN_SSIDS, {"MAX_NUM_SCAN_SSIDS", DataType::Uint}},
419 
420     {NL80211_ATTR_SCAN_FREQUENCIES, {"SCAN_FREQUENCIES", DataType::Nested, AttributeMap{
421         {std::nullopt, {"FQ", DataType::Uint}},
422     }, Flags::Verbose}},
423     {NL80211_ATTR_SCAN_SSIDS, {"SCAN_SSIDS", DataType::Nested, AttributeMap{
424         {std::nullopt, {"SSID", DataType::String}},
425     }}},
426     {NL80211_ATTR_GENERATION, {"GENERATION", DataType::Uint}},
427     {NL80211_ATTR_BSS, {"BSS", DataType::Nested, AttributeMap{
428         {NL80211_BSS_BSSID, {"BSSID", DataType::Raw}},
429         {NL80211_BSS_FREQUENCY, {"FREQUENCY", DataType::Uint}},
430         {NL80211_BSS_TSF, {"TSF", DataType::Uint}},
431         {NL80211_BSS_BEACON_INTERVAL, {"BEACON_INTERVAL", DataType::Uint}},
432         {NL80211_BSS_CAPABILITY, {"CAPABILITY", DataType::Uint}},
433         {NL80211_BSS_INFORMATION_ELEMENTS, {"INFORMATION_ELEMENTS",
434                 DataType::Struct, informationElementsToStream}},
435         {NL80211_BSS_SIGNAL_MBM, {"SIGNAL_MBM", DataType::Uint}},
436         {NL80211_BSS_SIGNAL_UNSPEC, {"SIGNAL_UNSPEC", DataType::Uint}},
437         {NL80211_BSS_STATUS, {"STATUS", DataType::Uint}},  // enum nl80211_bss_status
438         {NL80211_BSS_SEEN_MS_AGO, {"SEEN_MS_AGO", DataType::Uint}},
439         {NL80211_BSS_BEACON_IES, {"BEACON_IES", DataType::Struct, informationElementsToStream}},
440         {NL80211_BSS_CHAN_WIDTH, {"CHAN_WIDTH", DataType::Uint}},
441         {NL80211_BSS_BEACON_TSF, {"BEACON_TSF", DataType::Uint}},
442         {NL80211_BSS_PRESP_DATA, {"PRESP_DATA", DataType::Flag}},
443         {NL80211_BSS_LAST_SEEN_BOOTTIME, {"LAST_SEEN_BOOTTIME", DataType::Uint}},
444         {NL80211_BSS_PAD, {"PAD"}},
445         {NL80211_BSS_PARENT_TSF, {"PARENT_TSF"}},
446         {NL80211_BSS_PARENT_BSSID, {"PARENT_BSSID"}},
447         {NL80211_BSS_CHAIN_SIGNAL, {"CHAIN_SIGNAL", DataType::Nested, AttributeMap{
448             {std::nullopt, {"SIG", DataType::Uint}},
449         }}},
450         {NL80211_BSS_FREQUENCY_OFFSET, {"FREQUENCY_OFFSET"}},
451     }}},
452 
453     {NL80211_ATTR_REG_INITIATOR, {"REG_INITIATOR"}},
454     {NL80211_ATTR_REG_TYPE, {"REG_TYPE"}},
455 
456     {NL80211_ATTR_SUPPORTED_COMMANDS, {"SUPPORTED_COMMANDS", DataType::Nested,AttributeMap{
457         {std::nullopt, {"CMD", DataType::Uint}}, // enum nl80211_commands
458     }}},
459 
460     {NL80211_ATTR_FRAME, {"FRAME"}},
461     {NL80211_ATTR_SSID, {"SSID"}},
462     {NL80211_ATTR_AUTH_TYPE, {"AUTH_TYPE"}},
463     {NL80211_ATTR_REASON_CODE, {"REASON_CODE"}},
464 
465     {NL80211_ATTR_KEY_TYPE, {"KEY_TYPE"}},
466 
467     {NL80211_ATTR_MAX_SCAN_IE_LEN, {"MAX_SCAN_IE_LEN", DataType::Uint}},
468     {NL80211_ATTR_CIPHER_SUITES, {"CIPHER_SUITES", DataType::Struct, arrayToStream<int32_t>}},
469 
470     {NL80211_ATTR_FREQ_BEFORE, {"FREQ_BEFORE"}},
471     {NL80211_ATTR_FREQ_AFTER, {"FREQ_AFTER"}},
472 
473     {NL80211_ATTR_FREQ_FIXED, {"FREQ_FIXED"}},
474 
475     {NL80211_ATTR_WIPHY_RETRY_SHORT, {"WIPHY_RETRY_SHORT", DataType::Uint}},
476     {NL80211_ATTR_WIPHY_RETRY_LONG, {"WIPHY_RETRY_LONG", DataType::Uint}},
477     {NL80211_ATTR_WIPHY_FRAG_THRESHOLD, {"WIPHY_FRAG_THRESHOLD", DataType::Uint}},
478     {NL80211_ATTR_WIPHY_RTS_THRESHOLD, {"WIPHY_RTS_THRESHOLD", DataType::Uint}},
479 
480     {NL80211_ATTR_TIMED_OUT, {"TIMED_OUT"}},
481 
482     {NL80211_ATTR_USE_MFP, {"USE_MFP"}},
483 
484     {NL80211_ATTR_STA_FLAGS2, {"STA_FLAGS2"}},
485 
486     {NL80211_ATTR_CONTROL_PORT, {"CONTROL_PORT"}},
487 
488     {NL80211_ATTR_TESTDATA, {"TESTDATA"}},
489 
490     {NL80211_ATTR_PRIVACY, {"PRIVACY"}},
491 
492     {NL80211_ATTR_DISCONNECTED_BY_AP, {"DISCONNECTED_BY_AP"}},
493     {NL80211_ATTR_STATUS_CODE, {"STATUS_CODE"}},
494 
495     {NL80211_ATTR_CIPHER_SUITES_PAIRWISE, {"CIPHER_SUITES_PAIRWISE"}},
496     {NL80211_ATTR_CIPHER_SUITE_GROUP, {"CIPHER_SUITE_GROUP"}},
497     {NL80211_ATTR_WPA_VERSIONS, {"WPA_VERSIONS"}},
498     {NL80211_ATTR_AKM_SUITES, {"AKM_SUITES"}},
499 
500     {NL80211_ATTR_REQ_IE, {"REQ_IE"}},
501     {NL80211_ATTR_RESP_IE, {"RESP_IE"}},
502 
503     {NL80211_ATTR_PREV_BSSID, {"PREV_BSSID"}},
504 
505     {NL80211_ATTR_KEY, {"KEY"}},
506     {NL80211_ATTR_KEYS, {"KEYS"}},
507 
508     {NL80211_ATTR_PID, {"PID"}},
509 
510     {NL80211_ATTR_4ADDR, {"4ADDR"}},
511 
512     {NL80211_ATTR_SURVEY_INFO, {"SURVEY_INFO"}},
513 
514     {NL80211_ATTR_PMKID, {"PMKID"}},
515     {NL80211_ATTR_MAX_NUM_PMKIDS, {"MAX_NUM_PMKIDS", DataType::Uint}},
516 
517     {NL80211_ATTR_DURATION, {"DURATION"}},
518 
519     {NL80211_ATTR_COOKIE, {"COOKIE"}},
520 
521     {NL80211_ATTR_WIPHY_COVERAGE_CLASS, {"WIPHY_COVERAGE_CLASS", DataType::Uint}},
522 
523     {NL80211_ATTR_TX_RATES, {"TX_RATES"}},
524 
525     {NL80211_ATTR_FRAME_MATCH, {"FRAME_MATCH"}},
526 
527     {NL80211_ATTR_ACK, {"ACK"}},
528 
529     {NL80211_ATTR_PS_STATE, {"PS_STATE"}},
530 
531     {NL80211_ATTR_CQM, {"CQM"}},
532 
533     {NL80211_ATTR_LOCAL_STATE_CHANGE, {"LOCAL_STATE_CHANGE"}},
534 
535     {NL80211_ATTR_AP_ISOLATE, {"AP_ISOLATE"}},
536 
537     {NL80211_ATTR_WIPHY_TX_POWER_SETTING, {"WIPHY_TX_POWER_SETTING"}},
538     {NL80211_ATTR_WIPHY_TX_POWER_LEVEL, {"WIPHY_TX_POWER_LEVEL"}},
539 
540     {NL80211_ATTR_TX_FRAME_TYPES, {"TX_FRAME_TYPES", DataType::Nested, AttributeMap{
541         {std::nullopt, {"TFT", DataType::Nested, AttributeMap{
542             {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}},
543         }}},
544     }, Flags::Verbose}},
545     {NL80211_ATTR_RX_FRAME_TYPES, {"RX_FRAME_TYPES", DataType::Nested, AttributeMap{
546         {std::nullopt, {"RFT", DataType::Nested, AttributeMap{
547             {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}},
548         }}},
549     }, Flags::Verbose}},
550 
551     {NL80211_ATTR_FRAME_TYPE, {"FRAME_TYPE", DataType::Uint}},
552 
553     {NL80211_ATTR_CONTROL_PORT_ETHERTYPE, {"CONTROL_PORT_ETHERTYPE"}},
554     {NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, {"CONTROL_PORT_NO_ENCRYPT"}},
555 
556     {NL80211_ATTR_SUPPORT_IBSS_RSN, {"SUPPORT_IBSS_RSN"}},
557 
558     {NL80211_ATTR_WIPHY_ANTENNA_TX, {"WIPHY_ANTENNA_TX"}},
559     {NL80211_ATTR_WIPHY_ANTENNA_RX, {"WIPHY_ANTENNA_RX"}},
560 
561     {NL80211_ATTR_MCAST_RATE, {"MCAST_RATE"}},
562 
563     {NL80211_ATTR_OFFCHANNEL_TX_OK, {"OFFCHANNEL_TX_OK", DataType::Flag}},
564 
565     {NL80211_ATTR_BSS_HT_OPMODE, {"BSS_HT_OPMODE"}},
566 
567     {NL80211_ATTR_KEY_DEFAULT_TYPES, {"KEY_DEFAULT_TYPES"}},
568 
569     {NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
570             {"MAX_REMAIN_ON_CHANNEL_DURATION", DataType::Uint}},
571 
572     {NL80211_ATTR_MESH_SETUP, {"MESH_SETUP"}},
573 
574     {NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, {"WIPHY_ANTENNA_AVAIL_TX", DataType::Uint}},
575     {NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, {"WIPHY_ANTENNA_AVAIL_RX", DataType::Uint}},
576 
577     {NL80211_ATTR_SUPPORT_MESH_AUTH, {"SUPPORT_MESH_AUTH"}},
578     {NL80211_ATTR_STA_PLINK_STATE, {"STA_PLINK_STATE"}},
579 
580     {NL80211_ATTR_WOWLAN_TRIGGERS, {"WOWLAN_TRIGGERS"}},
581     {NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED,
582             {"WOWLAN_TRIGGERS_SUPPORTED", DataType::Nested, AttributeMap{
583         {NL80211_WOWLAN_TRIG_ANY, {"ANY", DataType::Flag}},
584         {NL80211_WOWLAN_TRIG_DISCONNECT, {"DISCONNECT", DataType::Flag}},
585         {NL80211_WOWLAN_TRIG_MAGIC_PKT, {"MAGIC_PKT", DataType::Flag}},
586         {NL80211_WOWLAN_TRIG_PKT_PATTERN,
587                 {"PKT_PATTERN", DataType::Struct, nl80211_pattern_supportToStream}},
588         {NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED, {"GTK_REKEY_SUPPORTED", DataType::Flag}},
589         {NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE, {"GTK_REKEY_FAILURE", DataType::Flag}},
590         {NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST, {"EAP_IDENT_REQUEST", DataType::Flag}},
591         {NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE, {"4WAY_HANDSHAKE", DataType::Flag}},
592         {NL80211_WOWLAN_TRIG_RFKILL_RELEASE, {"RFKILL_RELEASE", DataType::Flag}},
593         {NL80211_WOWLAN_TRIG_TCP_CONNECTION, {"TCP_CONNECTION", DataType::Nested, AttributeMap{
594             {NL80211_WOWLAN_TCP_SRC_IPV4, {"SRC_IPV4"}},
595             {NL80211_WOWLAN_TCP_DST_IPV4, {"DST_IPV4"}},
596             {NL80211_WOWLAN_TCP_DST_MAC, {"DST_MAC"}},
597             {NL80211_WOWLAN_TCP_SRC_PORT, {"SRC_PORT", DataType::Uint}},
598             {NL80211_WOWLAN_TCP_DST_PORT, {"DST_PORT", DataType::Uint}},
599             {NL80211_WOWLAN_TCP_DATA_PAYLOAD, {"DATA_PAYLOAD"}},
600             {NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ, {"DATA_PAYLOAD_SEQ"}},
601             {NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, {"DATA_PAYLOAD_TOKEN"}},
602             {NL80211_WOWLAN_TCP_DATA_INTERVAL, {"DATA_INTERVAL", DataType::Uint}},
603             {NL80211_WOWLAN_TCP_WAKE_PAYLOAD, {"WAKE_PAYLOAD"}},
604             {NL80211_WOWLAN_TCP_WAKE_MASK, {"WAKE_MASK"}},
605         }}},
606         {NL80211_WOWLAN_TRIG_NET_DETECT, {"NET_DETECT", DataType::Uint}},
607 
608         /* Not in WOWLAN_TRIGGERS_SUPPORTED:
609          * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211
610          * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_80211_LEN
611          * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023
612          * - NL80211_WOWLAN_TRIG_WAKEUP_PKT_8023_LEN
613          * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_MATCH
614          * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_CONNLOST
615          * - NL80211_WOWLAN_TRIG_WAKEUP_TCP_NOMORETOKENS
616          * - NL80211_WOWLAN_TRIG_NET_DETECT_RESULTS
617          */
618     }}},
619 
620     {NL80211_ATTR_SCHED_SCAN_INTERVAL, {"SCHED_SCAN_INTERVAL"}},
621 
622     {NL80211_ATTR_INTERFACE_COMBINATIONS, {"INTERFACE_COMBINATIONS", DataType::Nested, AttributeMap{
623         {std::nullopt, {"IC", DataType::Nested, AttributeMap{
624             {NL80211_IFACE_COMB_UNSPEC, {"UNSPEC"}},
625             {NL80211_IFACE_COMB_LIMITS, {"LIMITS", DataType::Nested, AttributeMap{
626                 {std::nullopt, {"LT", DataType::Nested, AttributeMap{
627                     {NL80211_IFACE_LIMIT_UNSPEC, {"UNSPEC"}},
628                     {NL80211_IFACE_LIMIT_MAX, {"MAX", DataType::Uint}},
629                     {NL80211_IFACE_LIMIT_TYPES, {"TYPES", DataType::Nested, iftypes}},
630                 }}},
631             }}},
632             {NL80211_IFACE_COMB_MAXNUM, {"MAXNUM", DataType::Uint}},
633             {NL80211_IFACE_COMB_STA_AP_BI_MATCH, {"STA_AP_BI_MATCH", DataType::Flag}},
634             {NL80211_IFACE_COMB_NUM_CHANNELS, {"NUM_CHANNELS", DataType::Uint}},
635             {NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, {"RADAR_DETECT_WIDTHS", DataType::Uint}},
636             {NL80211_IFACE_COMB_RADAR_DETECT_REGIONS, {"RADAR_DETECT_REGIONS", DataType::Uint}},
637             {NL80211_IFACE_COMB_BI_MIN_GCD, {"BI_MIN_GCD"}},
638         }}},
639     }, Flags::Verbose}},
640     {NL80211_ATTR_SOFTWARE_IFTYPES, {"SOFTWARE_IFTYPES", DataType::Nested, iftypes}},
641 
642     {NL80211_ATTR_REKEY_DATA, {"REKEY_DATA"}},
643 
644     {NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, {"MAX_NUM_SCHED_SCAN_SSIDS", DataType::Uint}},
645     {NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, {"MAX_SCHED_SCAN_IE_LEN", DataType::Uint}},
646 
647     {NL80211_ATTR_SCAN_SUPP_RATES, {"SCAN_SUPP_RATES"}},
648 
649     {NL80211_ATTR_HIDDEN_SSID, {"HIDDEN_SSID"}},
650 
651     {NL80211_ATTR_IE_PROBE_RESP, {"IE_PROBE_RESP"}},
652     {NL80211_ATTR_IE_ASSOC_RESP, {"IE_ASSOC_RESP"}},
653 
654     {NL80211_ATTR_STA_WME, {"STA_WME"}},
655     {NL80211_ATTR_SUPPORT_AP_UAPSD, {"SUPPORT_AP_UAPSD"}},
656 
657     {NL80211_ATTR_ROAM_SUPPORT, {"ROAM_SUPPORT", DataType::Flag}},
658 
659     {NL80211_ATTR_SCHED_SCAN_MATCH, {"SCHED_SCAN_MATCH"}},
660     {NL80211_ATTR_MAX_MATCH_SETS, {"MAX_MATCH_SETS", DataType::Uint}},
661 
662     {NL80211_ATTR_PMKSA_CANDIDATE, {"PMKSA_CANDIDATE"}},
663 
664     {NL80211_ATTR_TX_NO_CCK_RATE, {"TX_NO_CCK_RATE"}},
665 
666     {NL80211_ATTR_TDLS_ACTION, {"TDLS_ACTION"}},
667     {NL80211_ATTR_TDLS_DIALOG_TOKEN, {"TDLS_DIALOG_TOKEN"}},
668     {NL80211_ATTR_TDLS_OPERATION, {"TDLS_OPERATION"}},
669     {NL80211_ATTR_TDLS_SUPPORT, {"TDLS_SUPPORT", DataType::Flag}},
670     {NL80211_ATTR_TDLS_EXTERNAL_SETUP, {"TDLS_EXTERNAL_SETUP", DataType::Flag}},
671 
672     {NL80211_ATTR_DEVICE_AP_SME, {"DEVICE_AP_SME", DataType::Uint}},
673 
674     {NL80211_ATTR_DONT_WAIT_FOR_ACK, {"DONT_WAIT_FOR_ACK"}},
675 
676     {NL80211_ATTR_FEATURE_FLAGS, {"FEATURE_FLAGS", DataType::Uint}},
677 
678     {NL80211_ATTR_PROBE_RESP_OFFLOAD, {"PROBE_RESP_OFFLOAD", DataType::Uint}},
679 
680     {NL80211_ATTR_PROBE_RESP, {"PROBE_RESP"}},
681 
682     {NL80211_ATTR_DFS_REGION, {"DFS_REGION"}},
683 
684     {NL80211_ATTR_DISABLE_HT, {"DISABLE_HT"}},
685     {NL80211_ATTR_HT_CAPABILITY_MASK, {"HT_CAPABILITY_MASK"}},
686 
687     {NL80211_ATTR_NOACK_MAP, {"NOACK_MAP"}},
688 
689     {NL80211_ATTR_INACTIVITY_TIMEOUT, {"INACTIVITY_TIMEOUT"}},
690 
691     {NL80211_ATTR_RX_SIGNAL_DBM, {"RX_SIGNAL_DBM"}},
692 
693     {NL80211_ATTR_BG_SCAN_PERIOD, {"BG_SCAN_PERIOD"}},
694 
695     {NL80211_ATTR_WDEV, {"WDEV", DataType::Uint}},
696 
697     {NL80211_ATTR_USER_REG_HINT_TYPE, {"USER_REG_HINT_TYPE"}},
698 
699     {NL80211_ATTR_CONN_FAILED_REASON, {"CONN_FAILED_REASON"}},
700 
701     {NL80211_ATTR_AUTH_DATA, {"AUTH_DATA"}},
702 
703     {NL80211_ATTR_VHT_CAPABILITY, {"VHT_CAPABILITY"}},
704 
705     {NL80211_ATTR_SCAN_FLAGS, {"SCAN_FLAGS", DataType::Uint}},
706 
707     {NL80211_ATTR_CHANNEL_WIDTH, {"CHANNEL_WIDTH"}},
708     {NL80211_ATTR_CENTER_FREQ1, {"CENTER_FREQ1"}},
709     {NL80211_ATTR_CENTER_FREQ2, {"CENTER_FREQ2"}},
710 
711     {NL80211_ATTR_P2P_CTWINDOW, {"P2P_CTWINDOW"}},
712     {NL80211_ATTR_P2P_OPPPS, {"P2P_OPPPS"}},
713 
714     {NL80211_ATTR_LOCAL_MESH_POWER_MODE, {"LOCAL_MESH_POWER_MODE"}},
715 
716     {NL80211_ATTR_ACL_POLICY, {"ACL_POLICY"}},
717 
718     {NL80211_ATTR_MAC_ADDRS, {"MAC_ADDRS"}},
719 
720     {NL80211_ATTR_MAC_ACL_MAX, {"MAC_ACL_MAX", DataType::Uint}},
721 
722     {NL80211_ATTR_RADAR_EVENT, {"RADAR_EVENT"}},
723 
724     {NL80211_ATTR_EXT_CAPA, {"EXT_CAPA"}},
725     {NL80211_ATTR_EXT_CAPA_MASK, {"EXT_CAPA_MASK"}},
726 
727     {NL80211_ATTR_STA_CAPABILITY, {"STA_CAPABILITY"}},
728     {NL80211_ATTR_STA_EXT_CAPABILITY, {"STA_EXT_CAPABILITY"}},
729 
730     {NL80211_ATTR_PROTOCOL_FEATURES, {"PROTOCOL_FEATURES", DataType::Uint}},
731     {NL80211_ATTR_SPLIT_WIPHY_DUMP, {"SPLIT_WIPHY_DUMP", DataType::Flag}},
732 
733     {NL80211_ATTR_DISABLE_VHT, {"DISABLE_VHT", DataType::Flag}},
734     {NL80211_ATTR_VHT_CAPABILITY_MASK, {"VHT_CAPABILITY_MASK"}},
735 
736     {NL80211_ATTR_MDID, {"MDID"}},
737     {NL80211_ATTR_IE_RIC, {"IE_RIC"}},
738 
739     {NL80211_ATTR_CRIT_PROT_ID, {"CRIT_PROT_ID"}},
740     {NL80211_ATTR_MAX_CRIT_PROT_DURATION, {"MAX_CRIT_PROT_DURATION"}},
741 
742     {NL80211_ATTR_PEER_AID, {"PEER_AID"}},
743 
744     {NL80211_ATTR_COALESCE_RULE, {"COALESCE_RULE"}},
745 
746     {NL80211_ATTR_CH_SWITCH_COUNT, {"CH_SWITCH_COUNT"}},
747     {NL80211_ATTR_CH_SWITCH_BLOCK_TX, {"CH_SWITCH_BLOCK_TX"}},
748     {NL80211_ATTR_CSA_IES, {"CSA_IES"}},
749     {NL80211_ATTR_CNTDWN_OFFS_BEACON, {"CNTDWN_OFFS_BEACON"}},
750     {NL80211_ATTR_CNTDWN_OFFS_PRESP, {"CNTDWN_OFFS_PRESP"}},
751 
752     {NL80211_ATTR_RXMGMT_FLAGS, {"RXMGMT_FLAGS"}},
753 
754     {NL80211_ATTR_STA_SUPPORTED_CHANNELS, {"STA_SUPPORTED_CHANNELS"}},
755 
756     {NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES, {"STA_SUPPORTED_OPER_CLASSES"}},
757 
758     {NL80211_ATTR_HANDLE_DFS, {"HANDLE_DFS"}},
759 
760     {NL80211_ATTR_SUPPORT_5_MHZ, {"SUPPORT_5_MHZ"}},
761     {NL80211_ATTR_SUPPORT_10_MHZ, {"SUPPORT_10_MHZ"}},
762 
763     {NL80211_ATTR_OPMODE_NOTIF, {"OPMODE_NOTIF"}},
764 
765     {NL80211_ATTR_VENDOR_ID, {"VENDOR_ID"}},
766     {NL80211_ATTR_VENDOR_SUBCMD, {"VENDOR_SUBCMD"}},
767     {NL80211_ATTR_VENDOR_DATA, {"VENDOR_DATA", DataType::Raw, AttributeMap{}, Flags::Verbose}},
768     {NL80211_ATTR_VENDOR_EVENTS, {"VENDOR_EVENTS", DataType::Nested, AttributeMap{},
769             Flags::Verbose}},
770 
771     {NL80211_ATTR_QOS_MAP, {"QOS_MAP"}},
772 
773     {NL80211_ATTR_MAC_HINT, {"MAC_HINT"}},
774     {NL80211_ATTR_WIPHY_FREQ_HINT, {"WIPHY_FREQ_HINT"}},
775 
776     {NL80211_ATTR_MAX_AP_ASSOC_STA, {"MAX_AP_ASSOC_STA"}},
777 
778     {NL80211_ATTR_TDLS_PEER_CAPABILITY, {"TDLS_PEER_CAPABILITY"}},
779 
780     {NL80211_ATTR_SOCKET_OWNER, {"SOCKET_OWNER"}},
781 
782     {NL80211_ATTR_CSA_C_OFFSETS_TX, {"CSA_C_OFFSETS_TX"}},
783     {NL80211_ATTR_MAX_CSA_COUNTERS, {"MAX_CSA_COUNTERS"}},
784 
785     {NL80211_ATTR_TDLS_INITIATOR, {"TDLS_INITIATOR"}},
786 
787     {NL80211_ATTR_USE_RRM, {"USE_RRM"}},
788 
789     {NL80211_ATTR_WIPHY_DYN_ACK, {"WIPHY_DYN_ACK"}},
790 
791     {NL80211_ATTR_TSID, {"TSID"}},
792     {NL80211_ATTR_USER_PRIO, {"USER_PRIO"}},
793     {NL80211_ATTR_ADMITTED_TIME, {"ADMITTED_TIME"}},
794 
795     {NL80211_ATTR_SMPS_MODE, {"SMPS_MODE"}},
796 
797     {NL80211_ATTR_OPER_CLASS, {"OPER_CLASS"}},
798 
799     {NL80211_ATTR_MAC_MASK, {"MAC_MASK"}},
800 
801     {NL80211_ATTR_WIPHY_SELF_MANAGED_REG, {"WIPHY_SELF_MANAGED_REG"}},
802 
803     {NL80211_ATTR_EXT_FEATURES, {"EXT_FEATURES"}},
804 
805     {NL80211_ATTR_SURVEY_RADIO_STATS, {"SURVEY_RADIO_STATS"}},
806 
807     {NL80211_ATTR_NETNS_FD, {"NETNS_FD"}},
808 
809     {NL80211_ATTR_SCHED_SCAN_DELAY, {"SCHED_SCAN_DELAY"}},
810 
811     {NL80211_ATTR_REG_INDOOR, {"REG_INDOOR"}},
812 
813     {NL80211_ATTR_MAX_NUM_SCHED_SCAN_PLANS, {"MAX_NUM_SCHED_SCAN_PLANS", DataType::Uint}},
814     {NL80211_ATTR_MAX_SCAN_PLAN_INTERVAL, {"MAX_SCAN_PLAN_INTERVAL", DataType::Uint}},
815     {NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS, {"MAX_SCAN_PLAN_ITERATIONS", DataType::Uint}},
816     {NL80211_ATTR_SCHED_SCAN_PLANS, {"SCHED_SCAN_PLANS"}},
817 
818     {NL80211_ATTR_PBSS, {"PBSS"}},
819 
820     {NL80211_ATTR_BSS_SELECT, {"BSS_SELECT"}},
821 
822     {NL80211_ATTR_STA_SUPPORT_P2P_PS, {"STA_SUPPORT_P2P_PS"}},
823 
824     {NL80211_ATTR_PAD, {"PAD"}},
825 
826     {NL80211_ATTR_IFTYPE_EXT_CAPA, {"IFTYPE_EXT_CAPA"}},
827 
828     {NL80211_ATTR_MU_MIMO_GROUP_DATA, {"MU_MIMO_GROUP_DATA"}},
829     {NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR, {"MU_MIMO_FOLLOW_MAC_ADDR"}},
830 
831     {NL80211_ATTR_SCAN_START_TIME_TSF, {"SCAN_START_TIME_TSF"}},
832     {NL80211_ATTR_SCAN_START_TIME_TSF_BSSID, {"SCAN_START_TIME_TSF_BSSID"}},
833     {NL80211_ATTR_MEASUREMENT_DURATION, {"MEASUREMENT_DURATION"}},
834     {NL80211_ATTR_MEASUREMENT_DURATION_MANDATORY, {"MEASUREMENT_DURATION_MANDATORY"}},
835 
836     {NL80211_ATTR_MESH_PEER_AID, {"MESH_PEER_AID"}},
837 
838     {NL80211_ATTR_NAN_MASTER_PREF, {"NAN_MASTER_PREF"}},
839     {NL80211_ATTR_BANDS, {"BANDS"}},
840     {NL80211_ATTR_NAN_FUNC, {"NAN_FUNC"}},
841     {NL80211_ATTR_NAN_MATCH, {"NAN_MATCH"}},
842 
843     {NL80211_ATTR_FILS_KEK, {"FILS_KEK"}},
844     {NL80211_ATTR_FILS_NONCES, {"FILS_NONCES"}},
845 
846     {NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED, {"MULTICAST_TO_UNICAST_ENABLED"}},
847 
848     {NL80211_ATTR_BSSID, {"BSSID"}},
849 
850     {NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI, {"SCHED_SCAN_RELATIVE_RSSI"}},
851     {NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST, {"SCHED_SCAN_RSSI_ADJUST"}},
852 
853     {NL80211_ATTR_TIMEOUT_REASON, {"TIMEOUT_REASON"}},
854 
855     {NL80211_ATTR_FILS_ERP_USERNAME, {"FILS_ERP_USERNAME"}},
856     {NL80211_ATTR_FILS_ERP_REALM, {"FILS_ERP_REALM"}},
857     {NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM, {"FILS_ERP_NEXT_SEQ_NUM"}},
858     {NL80211_ATTR_FILS_ERP_RRK, {"FILS_ERP_RRK"}},
859     {NL80211_ATTR_FILS_CACHE_ID, {"FILS_CACHE_ID"}},
860 
861     {NL80211_ATTR_PMK, {"PMK"}},
862 
863     {NL80211_ATTR_SCHED_SCAN_MULTI, {"SCHED_SCAN_MULTI"}},
864     {NL80211_ATTR_SCHED_SCAN_MAX_REQS, {"SCHED_SCAN_MAX_REQS"}},
865 
866     {NL80211_ATTR_WANT_1X_4WAY_HS, {"WANT_1X_4WAY_HS"}},
867     {NL80211_ATTR_PMKR0_NAME, {"PMKR0_NAME"}},
868     {NL80211_ATTR_PORT_AUTHORIZED, {"PORT_AUTHORIZED"}},
869 
870     {NL80211_ATTR_EXTERNAL_AUTH_ACTION, {"EXTERNAL_AUTH_ACTION"}},
871     {NL80211_ATTR_EXTERNAL_AUTH_SUPPORT, {"EXTERNAL_AUTH_SUPPORT"}},
872 
873     {NL80211_ATTR_NSS, {"NSS"}},
874     {NL80211_ATTR_ACK_SIGNAL, {"ACK_SIGNAL"}},
875 
876     {NL80211_ATTR_CONTROL_PORT_OVER_NL80211, {"CONTROL_PORT_OVER_NL80211"}},
877 
878     {NL80211_ATTR_TXQ_STATS, {"TXQ_STATS"}},
879     {NL80211_ATTR_TXQ_LIMIT, {"TXQ_LIMIT"}},
880     {NL80211_ATTR_TXQ_MEMORY_LIMIT, {"TXQ_MEMORY_LIMIT"}},
881     {NL80211_ATTR_TXQ_QUANTUM, {"TXQ_QUANTUM"}},
882 
883     {NL80211_ATTR_HE_CAPABILITY, {"HE_CAPABILITY"}},
884 
885     {NL80211_ATTR_FTM_RESPONDER, {"FTM_RESPONDER"}},
886 
887     {NL80211_ATTR_FTM_RESPONDER_STATS, {"FTM_RESPONDER_STATS"}},
888 
889     {NL80211_ATTR_TIMEOUT, {"TIMEOUT"}},
890 
891     {NL80211_ATTR_PEER_MEASUREMENTS, {"PEER_MEASUREMENTS"}},
892 
893     {NL80211_ATTR_AIRTIME_WEIGHT, {"AIRTIME_WEIGHT"}},
894     {NL80211_ATTR_STA_TX_POWER_SETTING, {"STA_TX_POWER_SETTING"}},
895     {NL80211_ATTR_STA_TX_POWER, {"STA_TX_POWER"}},
896 
897     {NL80211_ATTR_SAE_PASSWORD, {"SAE_PASSWORD"}},
898 
899     {NL80211_ATTR_TWT_RESPONDER, {"TWT_RESPONDER"}},
900 
901     {NL80211_ATTR_HE_OBSS_PD, {"HE_OBSS_PD"}},
902 
903     {NL80211_ATTR_WIPHY_EDMG_CHANNELS, {"WIPHY_EDMG_CHANNELS"}},
904     {NL80211_ATTR_WIPHY_EDMG_BW_CONFIG, {"WIPHY_EDMG_BW_CONFIG"}},
905 
906     {NL80211_ATTR_VLAN_ID, {"VLAN_ID"}},
907 
908     {NL80211_ATTR_HE_BSS_COLOR, {"HE_BSS_COLOR"}},
909 
910     {NL80211_ATTR_IFTYPE_AKM_SUITES, {"IFTYPE_AKM_SUITES"}},
911 
912     {NL80211_ATTR_TID_CONFIG, {"TID_CONFIG"}},
913 
914     {NL80211_ATTR_CONTROL_PORT_NO_PREAUTH, {"CONTROL_PORT_NO_PREAUTH"}},
915 
916     {NL80211_ATTR_PMK_LIFETIME, {"PMK_LIFETIME"}},
917     {NL80211_ATTR_PMK_REAUTH_THRESHOLD, {"PMK_REAUTH_THRESHOLD"}},
918 
919     {NL80211_ATTR_RECEIVE_MULTICAST, {"RECEIVE_MULTICAST"}},
920     {NL80211_ATTR_WIPHY_FREQ_OFFSET, {"WIPHY_FREQ_OFFSET"}},
921     {NL80211_ATTR_CENTER_FREQ1_OFFSET, {"CENTER_FREQ1_OFFSET"}},
922     {NL80211_ATTR_SCAN_FREQ_KHZ, {"SCAN_FREQ_KHZ"}},
923 
924     {NL80211_ATTR_HE_6GHZ_CAPABILITY, {"HE_6GHZ_CAPABILITY"}},
925 
926     {NL80211_ATTR_FILS_DISCOVERY, {"FILS_DISCOVERY"}},
927 
928     {NL80211_ATTR_UNSOL_BCAST_PROBE_RESP, {"UNSOL_BCAST_PROBE_RESP"}},
929 
930     {NL80211_ATTR_S1G_CAPABILITY, {"S1G_CAPABILITY"}},
931     {NL80211_ATTR_S1G_CAPABILITY_MASK, {"S1G_CAPABILITY_MASK"}},
932 }) {}
933 // clang-format on
934 
informationElementsToStream(std::stringstream & ss,const Buffer<nlattr> attr)935 static void informationElementsToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
936     struct IEHeader {
937         uint8_t elementId;
938         uint8_t length;
939     } __attribute__((packed));
940     static_assert(sizeof(IEHeader) == 2);
941 
942     const auto alldata = attr.data<uint8_t>();
943     const auto bytes = alldata.getRaw();
944 
945     ss << '{';
946 
947     if constexpr (kCompactIE) {
948         ss << "len=" << bytes.len() << ", ";
949         ss << "crc=" << std::hex << std::setw(4) << crc16(alldata) << std::dec << ", ";
950     }
951 
952     bool first = true;
953     auto printComma = [&first, &ss]() {
954         // put separator at every but first entry
955         if (!first) ss << ", ";
956         first = false;
957     };
958 
959     for (size_t offset = 0; offset < bytes.len();) {
960         const auto ptr = bytes.ptr() + offset;
961         const auto remainingLen = bytes.len() - offset;
962 
963         // can we fit one more header?
964         if (sizeof(IEHeader) > remainingLen) break;
965         IEHeader ieHeader;
966         memcpy(&ieHeader, ptr, sizeof(IEHeader));
967         if (sizeof(IEHeader) + ieHeader.length > remainingLen) {
968             printComma();
969             ss << "ERR";
970             break;
971         }
972         offset += sizeof(IEHeader) + ieHeader.length;
973 
974         const Buffer<uint8_t> data(ptr + sizeof(IEHeader), ieHeader.length);
975 
976         if (ieHeader.elementId == WLAN_EID_SSID) {
977             printComma();
978 
979             const auto str = data.getRaw();
980             const std::string ssid(reinterpret_cast<const char*>(str.ptr()), str.len());
981             ss << "SSID=\"" << printableOnly(ssid) << '"';
982 
983             continue;
984         }
985 
986         if constexpr (kCompactIE) continue;
987 
988         // print entry ID:LENGTH/CRC16
989         printComma();
990         ss << (int)ieHeader.elementId << ':' << (int)ieHeader.length << '/';
991         ss << std::hex << std::setw(4) << crc16(data) << std::dec;
992     }
993     ss << '}';
994 }
995 
nl80211_pattern_supportToStream(std::stringstream & ss,const Buffer<nlattr> attr)996 static void nl80211_pattern_supportToStream(std::stringstream& ss, const Buffer<nlattr> attr) {
997     const auto& [ok, data] = attr.data<nl80211_pattern_support>().getFirst();
998     if (!ok) {
999         ss << "invalid structure";
1000         return;
1001     }
1002     ss << '{'                          //
1003        << data.max_patterns << ','     //
1004        << data.min_pattern_len << ','  //
1005        << data.max_pattern_len << ','  //
1006        << data.max_pkt_offset << '}';
1007 }
1008 
1009 }  // namespace android::nl::protocols::generic::families
1010