13563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <net/if.h> 23563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <errno.h> 33563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <string.h> 43563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <ctype.h> 5764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg#include <stdbool.h> 63563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 73563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <netlink/genl/genl.h> 83563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <netlink/genl/family.h> 93563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <netlink/genl/ctrl.h> 103563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <netlink/msg.h> 113563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include <netlink/attr.h> 123563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 133563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include "nl80211.h" 143563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg#include "iw.h" 153563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1692a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_ESS (1<<0) 1792a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_IBSS (1<<1) 1892a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) 1992a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) 2092a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_PRIVACY (1<<4) 2192a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) 2292a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_PBCC (1<<6) 2392a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) 2492a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) 2592a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_QOS (1<<9) 2692a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) 2792a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_APSD (1<<11) 282e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_RADIO_MEASURE (1<<12) 2992a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) 302e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DEL_BACK (1<<14) 312e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_IMM_BACK (1<<15) 322e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev/* DMG (60gHz) 802.11ad */ 332e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev/* type - bits 0..1 */ 342e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_TYPE_MASK (3<<0) 352e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 362e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_TYPE_IBSS (1<<0) /* Tx by: STA */ 372e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_TYPE_PBSS (2<<0) /* Tx by: PCP */ 382e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_TYPE_AP (3<<0) /* Tx by: AP */ 392e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 402e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_CBAP_ONLY (1<<2) 412e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_CBAP_SOURCE (1<<3) 422e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_PRIVACY (1<<4) 432e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_ECPAC (1<<5) 442e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 452e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_SPECTRUM_MGMT (1<<8) 462e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev#define WLAN_CAPABILITY_DMG_RADIO_MEASURE (1<<12) 4792a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann 483bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Bergstatic unsigned char ms_oui[3] = { 0x00, 0x50, 0xf2 }; 493bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Bergstatic unsigned char ieee80211_oui[3] = { 0x00, 0x0f, 0xac }; 509a22374a56b394000cfb98acb649355f76beb3a3Johannes Bergstatic unsigned char wfa_oui[3] = { 0x50, 0x6f, 0x9a }; 51857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 52764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Bergstruct scan_params { 53764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg bool unknown; 54febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg enum print_ie_type type; 55575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen bool show_both_ie_sets; 56764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg}; 57764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 582b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez#define IEEE80211_COUNTRY_EXTENSION_ID 201 592b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 6072725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Bergunion ieee80211_country_ie_triplet { 6172725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg struct { 6272725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg __u8 first_channel; 6372725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg __u8 num_channels; 6472725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg __s8 max_power; 6572725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg } __attribute__ ((packed)) chans; 6672725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg struct { 6772725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg __u8 reg_extension_id; 6872725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg __u8 reg_class; 6972725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg __u8 coverage_class; 7072725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg } __attribute__ ((packed)) ext; 712b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez} __attribute__ ((packed)); 722b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 735085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Bergstatic int parse_random_mac_addr(struct nl_msg *msg, char *arg) 745085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg{ 755085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg char *a_addr, *a_mask, *sep; 765085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg unsigned char addr[ETH_ALEN], mask[ETH_ALEN]; 775085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg char *addrs = arg + 9; 785085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg 795085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg if (*addrs != '=') 805085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg return 0; 815085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg 825085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg addrs++; 835085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg sep = strchr(addrs, '/'); 845085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg a_addr = addrs; 855085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg 865085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg if (!sep) 875085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg return 1; 885085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg 895085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg *sep = 0; 905085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg a_mask = sep + 1; 915085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg if (mac_addr_a2n(addr, a_addr) || mac_addr_a2n(mask, a_mask)) 925085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg return 1; 935085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg 945085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); 955085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg NLA_PUT(msg, NL80211_ATTR_MAC_MASK, ETH_ALEN, mask); 965085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg 975085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg return 0; 985085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg nla_put_failure: 995085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg return -ENOBUFS; 1005085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg} 1015085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg 102b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelhoint parse_sched_scan(struct nl_msg *msg, int *argc, char ***argv) 103b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho{ 104302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho struct nl_msg *matchset = NULL, *freqs = NULL, *ssids = NULL; 105b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho struct nlattr *match = NULL; 106b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho enum { 107b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho ND_TOPLEVEL, 108b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho ND_MATCH, 109b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho ND_FREQS, 110302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho ND_ACTIVE, 111b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } parse_state = ND_TOPLEVEL; 112b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho int c = *argc; 113b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho char *end, **v = *argv; 114b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho int err = 0, i = 0; 115b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho unsigned int freq, interval = 0, delay = 0; 116302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho bool have_matchset = false, have_freqs = false, have_ssids = false; 117302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho bool have_active = false, have_passive = false; 1185130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho uint32_t flags = 0; 119b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 120b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho matchset = nlmsg_alloc(); 121b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (!matchset) { 122b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -ENOBUFS; 123b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto out; 124b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 125b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 126b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho freqs = nlmsg_alloc(); 127b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (!freqs) { 128b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -ENOBUFS; 129b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto out; 130b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 131b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 132302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho ssids = nlmsg_alloc(); 133302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (!ssids) { 134302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho err = -ENOMEM; 135302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho goto out; 136302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } 137302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho 138b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho while (c) { 139b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho switch (parse_state) { 140b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho case ND_TOPLEVEL: 141b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (!strcmp(v[0], "interval")) { 142b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho c--; v++; 143b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (c == 0) { 144b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 145b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 146b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 147b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 148b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (interval) { 149b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 150b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 151b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 152b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho interval = strtoul(v[0], &end, 10); 153b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (*end || !interval) { 154b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 155b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 156b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 157b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho NLA_PUT_U32(msg, 158b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho NL80211_ATTR_SCHED_SCAN_INTERVAL, 159b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho interval); 160b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } else if (!strcmp(v[0], "delay")) { 161b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho c--; v++; 162b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (c == 0) { 163b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 164b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 165b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 166b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 167b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (delay) { 168b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 169b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 170b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 171b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho delay = strtoul(v[0], &end, 10); 172b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (*end) { 173b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 174b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 175b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 176b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho NLA_PUT_U32(msg, 177b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho NL80211_ATTR_SCHED_SCAN_DELAY, 178b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho delay); 179b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } else if (!strcmp(v[0], "matches")) { 180b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho parse_state = ND_MATCH; 181b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (have_matchset) { 182b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 183b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 184b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 185b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 186b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho i = 0; 187b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } else if (!strcmp(v[0], "freqs")) { 188b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho parse_state = ND_FREQS; 189b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (have_freqs) { 190b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 191b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 192b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 193b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 194b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho have_freqs = true; 195b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho i = 0; 196302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } else if (!strcmp(v[0], "active")) { 197302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho parse_state = ND_ACTIVE; 198302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (have_active || have_passive) { 199302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho err = -EINVAL; 200302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho goto nla_put_failure; 201302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } 202302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho 203302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho have_active = true; 204302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho i = 0; 205302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } else if (!strcmp(v[0], "passive")) { 206302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (have_active || have_passive) { 207302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho err = -EINVAL; 208302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho goto nla_put_failure; 209302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } 210302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho 211302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho have_passive = true; 2125130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho } else if (!strncmp(v[0], "randomise", 9) || 2135130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho !strncmp(v[0], "randomize", 9)) { 2145130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho flags |= NL80211_SCAN_FLAG_RANDOM_ADDR; 2155130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho if (c > 0) { 2165130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho err = parse_random_mac_addr(msg, v[0]); 2175130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho if (err) 2185130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho goto nla_put_failure; 2195130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho } 220b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } else { 221b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho /* this element is not for us, so 222b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho * return to continue parsing. 223b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho */ 224b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 225b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 226b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho c--; v++; 227b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 228b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho break; 229b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho case ND_MATCH: 230b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (!strcmp(v[0], "ssid")) { 231b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho c--; v++; 232b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (c == 0) { 233b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 234b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 235b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 236b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 237b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho /* TODO: for now we can only have an 238b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho * SSID in the match, so we can start 239b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho * the match nest here. 240b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho */ 241b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho match = nla_nest_start(matchset, i); 242b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (!match) { 243b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -ENOBUFS; 244b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 245b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 246b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 247b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho NLA_PUT(matchset, 248b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho NL80211_SCHED_SCAN_MATCH_ATTR_SSID, 249b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho strlen(v[0]), v[0]); 250b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho nla_nest_end(matchset, match); 251b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho match = NULL; 252b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 253b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho have_matchset = true; 254b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho i++; 255b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho c--; v++; 256b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } else { 257b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho /* other element that cannot be part 258b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho * of a match indicates the end of the 259b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho * match. */ 260b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho /* need at least one match in the matchset */ 261b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (i == 0) { 262b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 263b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 264b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 265b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 266b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho parse_state = ND_TOPLEVEL; 267b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 268b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 269b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho break; 270b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho case ND_FREQS: 271b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho freq = strtoul(v[0], &end, 10); 272b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (*end) { 273b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (i == 0) { 274b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho err = -EINVAL; 275b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho goto nla_put_failure; 276b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 277b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 278b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho parse_state = ND_TOPLEVEL; 279b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } else { 280b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho NLA_PUT_U32(freqs, i, freq); 281b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho i++; 282b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho c--; v++; 283b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 284b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho break; 285302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho case ND_ACTIVE: 286302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (!strcmp(v[0], "ssid")) { 287302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho c--; v++; 288302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (c == 0) { 289302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho err = -EINVAL; 290302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho goto nla_put_failure; 291302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } 292302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho 293302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho NLA_PUT(ssids, 294302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho NL80211_SCHED_SCAN_MATCH_ATTR_SSID, 295302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho strlen(v[0]), v[0]); 296302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho 297302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho have_ssids = true; 298302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho i++; 299302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho c--; v++; 300302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } else { 301302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho /* other element that cannot be part 302302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho * of a match indicates the end of the 303302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho * active set. */ 304302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho /* need at least one item in the set */ 305302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (i == 0) { 306302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho err = -EINVAL; 307302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho goto nla_put_failure; 308302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } 309302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho 310302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho parse_state = ND_TOPLEVEL; 311302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho } 312302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho break; 313b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 314b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho } 315b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 316302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (!have_ssids) 317302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho NLA_PUT(ssids, 1, 0, ""); 318302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho if (!have_passive) 319302a378a6dd975d5d4c5627d8e1caff6df7906deLuciano Coelho nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids); 320b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (have_freqs) 321b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); 322b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (have_matchset) 323b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, matchset); 3245130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho if (flags) 3255130bba08d4697e8261c1013d92aba6513804f04Luciano Coelho NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags); 326b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 327b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelhonla_put_failure: 328b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho if (match) 329b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho nla_nest_end(msg, match); 330b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho nlmsg_free(freqs); 331b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho nlmsg_free(matchset); 332b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 333b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelhoout: 334b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho *argc = c; 335b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho *argv = v; 336b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho return err; 337b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho} 338b1622287b09909886e578a66a09dfcb0417a33ceLuciano Coelho 3397c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Bergstatic int handle_scan(struct nl80211_state *state, 3407c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Berg struct nl_cb *cb, 3413563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nl_msg *msg, 34205514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg int argc, char **argv, 34305514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg enum id_input id) 3443563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 345559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg struct nl_msg *ssids = NULL, *freqs = NULL; 346559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg char *eptr; 3473563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int err = -ENOBUFS; 348559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int i; 349559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg enum { 350559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NONE, 351559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg FREQ, 35264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg IES, 353559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg SSID, 354851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall MESHID, 355559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg DONE, 356559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } parse = NONE; 357559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int freq; 358559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg bool passive = false, have_ssids = false, have_freqs = false; 359851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall size_t ies_len = 0, meshid_len = 0; 360851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall unsigned char *ies = NULL, *meshid = NULL, *tmpies; 3615085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg unsigned int flags = 0; 3623563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 3633563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg ssids = nlmsg_alloc(); 3643563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (!ssids) 3653563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return -ENOMEM; 366559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 367559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg freqs = nlmsg_alloc(); 368559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!freqs) { 369559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nlmsg_free(ssids); 370559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg return -ENOMEM; 371559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } 372559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 373559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg for (i = 0; i < argc; i++) { 374559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg switch (parse) { 375559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case NONE: 37664797a7fd7c49d95abc8540490c76bf493699176Johannes Berg if (strcmp(argv[i], "freq") == 0) { 37764797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = FREQ; 37864797a7fd7c49d95abc8540490c76bf493699176Johannes Berg have_freqs = true; 37964797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 38064797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } else if (strcmp(argv[i], "ies") == 0) { 38164797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = IES; 38264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 383fe862239636c303372184abc5635097b43777e77Sam Leffler } else if (strcmp(argv[i], "lowpri") == 0) { 384fe862239636c303372184abc5635097b43777e77Sam Leffler flags |= NL80211_SCAN_FLAG_LOW_PRIORITY; 385fe862239636c303372184abc5635097b43777e77Sam Leffler break; 386fe862239636c303372184abc5635097b43777e77Sam Leffler } else if (strcmp(argv[i], "flush") == 0) { 387fe862239636c303372184abc5635097b43777e77Sam Leffler flags |= NL80211_SCAN_FLAG_FLUSH; 388fe862239636c303372184abc5635097b43777e77Sam Leffler break; 389ced94d5f129e5d116b6a888f312deab081bb2231Antonio Quartulli } else if (strcmp(argv[i], "ap-force") == 0) { 390ced94d5f129e5d116b6a888f312deab081bb2231Antonio Quartulli flags |= NL80211_SCAN_FLAG_AP; 391ced94d5f129e5d116b6a888f312deab081bb2231Antonio Quartulli break; 3925085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg } else if (strncmp(argv[i], "randomise", 9) == 0 || 3935085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg strncmp(argv[i], "randomize", 9) == 0) { 3945085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg flags |= NL80211_SCAN_FLAG_RANDOM_ADDR; 3955085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg err = parse_random_mac_addr(msg, argv[i]); 3965085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg if (err) 3975085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg goto nla_put_failure; 3985085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes Berg break; 39964797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } else if (strcmp(argv[i], "ssid") == 0) { 40064797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = SSID; 40164797a7fd7c49d95abc8540490c76bf493699176Johannes Berg have_ssids = true; 40264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 40364797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } else if (strcmp(argv[i], "passive") == 0) { 40464797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = DONE; 40564797a7fd7c49d95abc8540490c76bf493699176Johannes Berg passive = true; 40664797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 407851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall } else if (strcmp(argv[i], "meshid") == 0) { 408851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall parse = MESHID; 409851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall break; 41064797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } 411559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case DONE: 412559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg return 1; 413559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case FREQ: 414559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg freq = strtoul(argv[i], &eptr, 10); 415cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg if (eptr != argv[i] + strlen(argv[i])) { 416cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg /* failed to parse as number -- maybe a tag? */ 417cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg i--; 418cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg parse = NONE; 419cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg continue; 420cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg } 421559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NLA_PUT_U32(freqs, i, freq); 42264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 42364797a7fd7c49d95abc8540490c76bf493699176Johannes Berg case IES: 424851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall ies = parse_hex(argv[i], &ies_len); 42564797a7fd7c49d95abc8540490c76bf493699176Johannes Berg if (!ies) 42664797a7fd7c49d95abc8540490c76bf493699176Johannes Berg goto nla_put_failure; 42764797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = NONE; 428559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg break; 429559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case SSID: 430559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NLA_PUT(ssids, i, strlen(argv[i]), argv[i]); 431559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg break; 432851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall case MESHID: 433851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall meshid_len = strlen(argv[i]); 434851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall meshid = (unsigned char *) malloc(meshid_len + 2); 435851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall if (!meshid) 436851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall goto nla_put_failure; 437851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall meshid[0] = 114; /* mesh element id */ 438851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall meshid[1] = meshid_len; 439851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall memcpy(&meshid[2], argv[i], meshid_len); 440851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall meshid_len += 2; 441851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall parse = NONE; 442851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall break; 443851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall } 444851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall } 445851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall 446851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall if (ies || meshid) { 447851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall tmpies = (unsigned char *) malloc(ies_len + meshid_len); 448851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall if (!tmpies) 449851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall goto nla_put_failure; 450851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall if (ies) { 451851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall memcpy(tmpies, ies, ies_len); 452851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall free(ies); 453851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall } 454851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall if (meshid) { 455851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall memcpy(&tmpies[ies_len], meshid, meshid_len); 456851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall free(meshid); 457559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } 458851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall NLA_PUT(msg, NL80211_ATTR_IE, ies_len + meshid_len, tmpies); 459851d35c2a3471b44d3546d07bac89e45741ad79fjacob minshall free(tmpies); 460559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } 461559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 462559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!have_ssids) 463559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NLA_PUT(ssids, 1, 0, ""); 464559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!passive) 465559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids); 466559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 467559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (have_freqs) 468559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); 469fe862239636c303372184abc5635097b43777e77Sam Leffler if (flags) 470fe862239636c303372184abc5635097b43777e77Sam Leffler NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags); 4713563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 4723563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg err = 0; 4733563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nla_put_failure: 4743563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nlmsg_free(ssids); 475559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nlmsg_free(freqs); 4763563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return err; 4773563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 4783563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 479857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmannstatic void tab_on_first(bool *first) 480857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 481857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (!*first) 482857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t"); 483857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann else 484857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann *first = false; 485857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 486857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 48783b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data) 4883563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 48983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" "); 490748f8489caad151e01922f0ba26847aedfd36dafJohannes Berg print_ssid_escaped(len, data); 4913563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 4923563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 4933563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 494ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126 4951fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 4961fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter 49783b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_supprates(const uint8_t type, uint8_t len, const uint8_t *data) 4983563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 4993563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int i; 5003563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 50183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" "); 5023563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 50383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg for (i = 0; i < len; i++) { 5043563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int r = data[i] & 0x7f; 5051fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter 506ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg if (r == BSS_MEMBERSHIP_SELECTOR_VHT_PHY && data[i] & 0x80) 507ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("VHT"); 508ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg else if (r == BSS_MEMBERSHIP_SELECTOR_HT_PHY && data[i] & 0x80) 5091fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter printf("HT"); 5101fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter else 5111fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter printf("%d.%d", r/2, 5*(r&1)); 5121fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter 5131fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter printf("%s ", data[i] & 0x80 ? "*" : ""); 5143563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 5153563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 5163563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 5173563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 51883b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_ds(const uint8_t type, uint8_t len, const uint8_t *data) 5193563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 52083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" channel %d\n", data[0]); 5213563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 5223563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 5232b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguezstatic const char *country_env_str(char environment) 524b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann{ 5252b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez switch (environment) { 526b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann case 'I': 5272b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "Indoor only"; 528b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann case 'O': 5292b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "Outdoor only"; 530b6c0d6340dbc969b4c53f583775e7c49b440c403Johannes Berg case ' ': 5312b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "Indoor/Outdoor"; 532b6c0d6340dbc969b4c53f583775e7c49b440c403Johannes Berg default: 5332b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "bogus"; 534b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann } 5352b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez} 5362b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5372b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguezstatic void print_country(const uint8_t type, uint8_t len, const uint8_t *data) 5382b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez{ 5392b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf(" %.*s", 2, data); 5402b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5412b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf("\tEnvironment: %s\n", country_env_str(data[2])); 5422b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5432b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez data += 3; 5442b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez len -= 3; 5452b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5462b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez if (len < 3) { 5472b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf("\t\tNo country IE triplets present\n"); 5482b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return; 5492b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez } 5502b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5512b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez while (len >= 3) { 5522b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez int end_channel; 55372725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg union ieee80211_country_ie_triplet *triplet = (void *) data; 5542b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5552b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez if (triplet->ext.reg_extension_id >= IEEE80211_COUNTRY_EXTENSION_ID) { 5562b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf("\t\tExtension ID: %d Regulatory Class: %d Coverage class: %d (up to %dm)\n", 5572b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.reg_extension_id, 5582b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.reg_class, 5592b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.coverage_class, 5602b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.coverage_class * 450); 5612b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5622b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez data += 3; 5632b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez len -= 3; 5642b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez continue; 5652b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez } 5662b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5672b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez /* 2 GHz */ 5682b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez if (triplet->chans.first_channel <= 14) 5692b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez end_channel = triplet->chans.first_channel + (triplet->chans.num_channels - 1); 5702b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez else 5712b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez end_channel = triplet->chans.first_channel + (4 * (triplet->chans.num_channels - 1)); 5722b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 573a9859d30ea1c19314d2d08285af9123714a4e6beLuis R. Rodriguez printf("\t\tChannels [%d - %d] @ %d dBm\n", triplet->chans.first_channel, end_channel, triplet->chans.max_power); 5742b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5752b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez data += 3; 5762b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez len -= 3; 5772b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez } 5782b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 5792b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return; 580b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann} 581b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann 582d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmannstatic void print_powerconstraint(const uint8_t type, uint8_t len, const uint8_t *data) 583d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann{ 584d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann printf(" %d dB\n", data[0]); 585d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann} 586d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann 587792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayerstatic void print_tpcreport(const uint8_t type, uint8_t len, const uint8_t *data) 588792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer{ 589792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer printf(" TX power: %d dBm\n", data[0]); 590792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer /* printf(" Link Margin (%d dB) is reserved in Beacons\n", data[1]); */ 591792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer} 592792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer 59383b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_erp(const uint8_t type, uint8_t len, const uint8_t *data) 594fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann{ 595fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] == 0x00) 59683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <no flags>"); 597fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] & 0x01) 598fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf(" NonERP_Present"); 599fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] & 0x02) 600fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf(" Use_Protection"); 601fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] & 0x04) 602fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf(" Barker_Preamble_Mode"); 603fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf("\n"); 604fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann} 605fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann 60683b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_cipher(const uint8_t *data) 607857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 6083bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg if (memcmp(data, ms_oui, 3) == 0) { 609857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 610510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 0: 611857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("Use group cipher suite"); 612857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 613510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 614857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-40"); 615857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 616510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 617857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("TKIP"); 618857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 619510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 4: 620857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("CCMP"); 621857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 622510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 5: 623857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-104"); 624857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 625857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 626332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 6275594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 628857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 629857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 630857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else if (memcmp(data, ieee80211_oui, 3) == 0) { 631857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 632510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 0: 633857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("Use group cipher suite"); 634857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 635510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 636857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-40"); 637857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 638510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 639857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("TKIP"); 640857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 641510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 4: 642857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("CCMP"); 643857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 644510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 5: 645857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-104"); 646857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 647510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 6: 648857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("AES-128-CMAC"); 649857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 650f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear case 7: 651f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear printf("NO-GROUP"); 652f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear break; 653a8b3da9df8d15b857b13887feccdd05c46c7347eVladimir Kondratiev case 8: 654a8b3da9df8d15b857b13887feccdd05c46c7347eVladimir Kondratiev printf("GCMP"); 655a8b3da9df8d15b857b13887feccdd05c46c7347eVladimir Kondratiev break; 656857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 657332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 6585594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 659857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 660857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 661857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else 662332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 6635594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 664857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 665857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 66683b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_auth(const uint8_t *data) 667857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 6683bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg if (memcmp(data, ms_oui, 3) == 0) { 669857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 670510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 671857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("IEEE 802.1X"); 672857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 673510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 674857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("PSK"); 675857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 676857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 677332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 6785594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 679857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 680857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 681857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else if (memcmp(data, ieee80211_oui, 3) == 0) { 682857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 683510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 684857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("IEEE 802.1X"); 685857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 686510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 687857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("PSK"); 688857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 6890fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 3: 6900fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("FT/IEEE 802.1X"); 6910fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 6920fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 4: 6930fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("FT/PSK"); 6940fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 6950fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 5: 6960fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("IEEE 802.1X/SHA-256"); 6970fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 6980fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 6: 6990fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("PSK/SHA-256"); 7000fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 7014361eef308869ae41395c8b32c5d9aa68d28e5aaJoerg Mayer case 7: 7024361eef308869ae41395c8b32c5d9aa68d28e5aaJoerg Mayer printf("TDLS/TPK"); 7034361eef308869ae41395c8b32c5d9aa68d28e5aaJoerg Mayer break; 704857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 705332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 7065594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 707857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 708857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 709f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear } else if (memcmp(data, wfa_oui, 3) == 0) { 710f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear switch (data[3]) { 711f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear case 1: 712f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear printf("OSEN"); 713f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear break; 714f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear default: 715f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear printf("%.02x-%.02x-%.02x:%d", 716f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear data[0], data[1] ,data[2], data[3]); 717f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear break; 718f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear } 719857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else 720332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 7215594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 722857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 723857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 724f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greearstatic void _print_rsn_ie(const char *defcipher, const char *defauth, 725f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear uint8_t len, const uint8_t *data, int is_osen) 726857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 727857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann bool first = true; 728f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear __u16 count, capa; 729857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann int i; 730857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 731f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear if (!is_osen) { 732f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear __u16 version; 733f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear version = data[0] + (data[1] << 8); 734f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear tab_on_first(&first); 735f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear printf("\t * Version: %d\n", version); 736857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 737f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear data += 2; 738f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear len -= 2; 739f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear } 740857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 741857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (len < 4) { 742857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 743857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Group cipher: %s\n", defcipher); 744857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Pairwise ciphers: %s\n", defcipher); 745857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann return; 746857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 747857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 748857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 749857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Group cipher: "); 750857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann print_cipher(data); 751857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\n"); 752857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 753857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann data += 4; 754857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann len -= 4; 755857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 756857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (len < 2) { 757857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 758857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Pairwise ciphers: %s\n", defcipher); 759857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann return; 760857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 761857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 762857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann count = data[0] | (data[1] << 8); 76331d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann if (2 + (count * 4) > len) 76431d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann goto invalid; 76531d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann 766857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 767857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Pairwise ciphers:"); 76831d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann for (i = 0; i < count; i++) { 769857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf(" "); 770857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann print_cipher(data + 2 + (i * 4)); 771857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 772857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\n"); 773857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 774857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann data += 2 + (count * 4); 775857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann len -= 2 + (count * 4); 776857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 777857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (len < 2) { 778857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 779857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Authentication suites: %s\n", defauth); 780857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann return; 781857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 782857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 783857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann count = data[0] | (data[1] << 8); 78431d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann if (2 + (count * 4) > len) 78531d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann goto invalid; 78631d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann 787857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 788857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Authentication suites:"); 78983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg for (i = 0; i < count; i++) { 790857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf(" "); 791857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann print_auth(data + 2 + (i * 4)); 792857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 793857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\n"); 794857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 795857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann data += 2 + (count * 4); 796857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann len -= 2 + (count * 4); 797857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 7986a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg if (len >= 2) { 7996a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg capa = data[0] | (data[1] << 8); 8006a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg tab_on_first(&first); 801cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf("\t * Capabilities:"); 802cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0001) 803cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" PreAuth"); 804cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0002) 805cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" NoPairwise"); 806cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg switch ((capa & 0x000c) >> 2) { 807cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 0: 8084361eef308869ae41395c8b32c5d9aa68d28e5aaJoerg Mayer printf(" 1-PTKSA-RC"); 809cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 810cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 1: 811cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 2-PTKSA-RC"); 812cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 813cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 2: 814cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 4-PTKSA-RC"); 815cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 816cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 3: 817cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 16-PTKSA-RC"); 818cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 819cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg } 820cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg switch ((capa & 0x0030) >> 4) { 821cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 0: 8224361eef308869ae41395c8b32c5d9aa68d28e5aaJoerg Mayer printf(" 1-GTKSA-RC"); 823cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 824cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 1: 825cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 2-GTKSA-RC"); 826cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 827cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 2: 828cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 4-GTKSA-RC"); 829cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 830cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 3: 831cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 16-GTKSA-RC"); 832cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 833cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg } 834cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0040) 835cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" MFP-required"); 836cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0080) 837cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" MFP-capable"); 838cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0200) 839cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" Peerkey-enabled"); 840cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0400) 841cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" SPP-AMSDU-capable"); 842cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0800) 843cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" SPP-AMSDU-required"); 844cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" (0x%.4x)\n", capa); 8456a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg data += 2; 8466a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg len -= 2; 8476a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg } 84831d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann 8495ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg if (len >= 2) { 8505ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg int pmkid_count = data[0] | (data[1] << 8); 8515ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg 8525ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg if (len >= 2 + 16 * pmkid_count) { 8535ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg tab_on_first(&first); 8545ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg printf("\t * %d PMKIDs\n", pmkid_count); 8555ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg /* not printing PMKID values */ 8565ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg data += 2 + 16 * pmkid_count; 8575ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg len -= 2 + 16 * pmkid_count; 8585ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg } else 8595ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg goto invalid; 8605ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg } 8615ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg 8625ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg if (len >= 4) { 8635ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg tab_on_first(&first); 8645ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg printf("\t * Group mgmt cipher suite: "); 8655ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg print_cipher(data); 8665ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg printf("\n"); 8675ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg data += 4; 8685ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg len -= 4; 8695ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg } 8705ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg 871cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg invalid: 87231d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann if (len != 0) { 87331d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann printf("\t\t * bogus tail data (%d):", len); 87431d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann while (len) { 87531d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann printf(" %.2x", *data); 87631d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann data++; 87731d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann len--; 87831d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann } 87931d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann printf("\n"); 88031d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann } 881857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 882857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 883f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greearstatic void print_rsn_ie(const char *defcipher, const char *defauth, 884f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear uint8_t len, const uint8_t *data) 885f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear{ 886f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear _print_rsn_ie(defcipher, defauth, len, data, 0); 887f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear} 888f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear 889f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greearstatic void print_osen_ie(const char *defcipher, const char *defauth, 890f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear uint8_t len, const uint8_t *data) 891f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear{ 892f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear printf("\n\t"); 893f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear _print_rsn_ie(defcipher, defauth, len, data, 1); 894f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear} 895f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear 89683b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_rsn(const uint8_t type, uint8_t len, const uint8_t *data) 897857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 89883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_rsn_ie("CCMP", "IEEE 802.1X", len, data); 899857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 900857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 9010c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguezstatic void print_ht_capa(const uint8_t type, uint8_t len, const uint8_t *data) 9020c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguez{ 903357c1a5df13f722027977a915cfd16a38bba3966Luis R. Rodriguez printf("\n"); 9047ddfb67953809357249e5a6f4293cebf59a4ad9bJohannes Berg print_ht_capability(data[0] | (data[1] << 8)); 9057ddfb67953809357249e5a6f4293cebf59a4ad9bJohannes Berg print_ampdu_length(data[2] & 3); 906c79c746440d22401d0aa8522bed2820f60eed2cdChristian Lamparter print_ampdu_spacing((data[2] >> 2) & 7); 9077ddfb67953809357249e5a6f4293cebf59a4ad9bJohannes Berg print_ht_mcs(data + 3); 9080c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguez} 9090c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguez 910489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greearstatic const char* ntype_11u(uint8_t t) 911489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear{ 912489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear switch (t) { 913489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 0: return "Private"; 914489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 1: return "Private with Guest"; 915489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 2: return "Chargeable Public"; 916489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 3: return "Free Public"; 917489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 4: return "Personal Device"; 918489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 5: return "Emergency Services Only"; 919489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 14: return "Test or Experimental"; 920489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 15: return "Wildcard"; 921489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear default: return "Reserved"; 922489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear } 923489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear} 924489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear 925489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greearstatic const char* vgroup_11u(uint8_t t) 926489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear{ 927489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear switch (t) { 928489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 0: return "Unspecified"; 929489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 1: return "Assembly"; 930489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 2: return "Business"; 931489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 3: return "Educational"; 932489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 4: return "Factory and Industrial"; 933489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 5: return "Institutional"; 934489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 6: return "Mercantile"; 935489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 7: return "Residential"; 936489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 8: return "Storage"; 937489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 9: return "Utility and Miscellaneous"; 938489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 10: return "Vehicular"; 939489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear case 11: return "Outdoor"; 940489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear default: return "Reserved"; 941489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear } 942489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear} 943489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear 944489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greearstatic void print_interworking(const uint8_t type, uint8_t len, const uint8_t *data) 945489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear{ 946489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear /* See Section 7.3.2.92 in the 802.11u spec. */ 947489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\n"); 948489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear if (len >= 1) { 949489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear uint8_t ano = data[0]; 950489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\tNetwork Options: 0x%hx\n", (unsigned short)(ano)); 951489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\t\tNetwork Type: %i (%s)\n", 952489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear (int)(ano & 0xf), ntype_11u(ano & 0xf)); 953489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear if (ano & (1<<4)) 954489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\t\tInternet\n"); 955489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear if (ano & (1<<5)) 956489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\t\tASRA\n"); 957489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear if (ano & (1<<6)) 958489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\t\tESR\n"); 959489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear if (ano & (1<<7)) 960489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\t\tUESA\n"); 961489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear } 962489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear if ((len == 3) || (len == 9)) { 963489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\tVenue Group: %i (%s)\n", 964489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear (int)(data[1]), vgroup_11u(data[1])); 965489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\tVenue Type: %i\n", (int)(data[2])); 966489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear } 967489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear if (len == 9) 968489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\tHESSID: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n", 969489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear data[3], data[4], data[5], data[6], data[7], data[8]); 970489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear else if (len == 7) 971489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear printf("\t\tHESSID: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n", 972489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear data[1], data[2], data[3], data[4], data[5], data[6]); 973489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear} 974489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear 9753f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greearstatic void print_11u_advert(const uint8_t type, uint8_t len, const uint8_t *data) 9763f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear{ 9773f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear /* See Section 7.3.2.93 in the 802.11u spec. */ 9783f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear /* TODO: This code below does not decode private protocol IDs */ 9793f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear int idx = 0; 9803f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\n"); 9813f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear while (idx < (len - 1)) { 9823f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear uint8_t qri = data[idx]; 9833f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear uint8_t proto_id = data[idx + 1]; 9843f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\tQuery Response Info: 0x%hx\n", (unsigned short)(qri)); 9853f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tQuery Response Length Limit: %i\n", 9863f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear (qri & 0x7f)); 9873f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear if (qri & (1<<7)) 9883f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tPAME-BI\n"); 9893f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear switch(proto_id) { 9903f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear case 0: 9913f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tANQP\n"); break; 9923f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear case 1: 9933f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tMIH Information Service\n"); break; 9943f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear case 2: 9953f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tMIH Command and Event Services Capability Discovery\n"); break; 9963f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear case 3: 9973f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tEmergency Alert System (EAS)\n"); break; 9983f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear case 221: 9993f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tVendor Specific\n"); break; 10003f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear default: 10013f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear printf("\t\t\tReserved: %i\n", proto_id); break; 10023f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear } 10033f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear idx += 2; 10043f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear } 10053f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear} 10063f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear 1007bc9e14f1271413bedf655750d09d7053df09279bBen Greearstatic void print_11u_rcon(const uint8_t type, uint8_t len, const uint8_t *data) 1008bc9e14f1271413bedf655750d09d7053df09279bBen Greear{ 1009bc9e14f1271413bedf655750d09d7053df09279bBen Greear /* See Section 7.3.2.96 in the 802.11u spec. */ 1010bc9e14f1271413bedf655750d09d7053df09279bBen Greear int idx = 0; 1011bc9e14f1271413bedf655750d09d7053df09279bBen Greear int ln0 = data[1] & 0xf; 1012bc9e14f1271413bedf655750d09d7053df09279bBen Greear int ln1 = ((data[1] & 0xf0) >> 4); 1013bc9e14f1271413bedf655750d09d7053df09279bBen Greear int ln2 = 0; 1014bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\n"); 1015bc9e14f1271413bedf655750d09d7053df09279bBen Greear 1016bc9e14f1271413bedf655750d09d7053df09279bBen Greear if (ln1) 1017bc9e14f1271413bedf655750d09d7053df09279bBen Greear ln2 = len - 2 - ln0 - ln1; 1018bc9e14f1271413bedf655750d09d7053df09279bBen Greear 1019bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\t\tANQP OIs: %i\n", data[0]); 1020bc9e14f1271413bedf655750d09d7053df09279bBen Greear 1021bc9e14f1271413bedf655750d09d7053df09279bBen Greear if (ln0 > 0) { 1022bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\t\tOI 1: "); 1023bc9e14f1271413bedf655750d09d7053df09279bBen Greear if (2 + ln0 > len) { 1024bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("Invalid IE length.\n"); 1025bc9e14f1271413bedf655750d09d7053df09279bBen Greear } else { 1026bc9e14f1271413bedf655750d09d7053df09279bBen Greear for (idx = 0; idx < ln0; idx++) { 1027bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("%02hx", data[2 + idx]); 1028bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1029bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\n"); 1030bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1031bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1032bc9e14f1271413bedf655750d09d7053df09279bBen Greear 1033bc9e14f1271413bedf655750d09d7053df09279bBen Greear if (ln1 > 0) { 1034bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\t\tOI 2: "); 1035bc9e14f1271413bedf655750d09d7053df09279bBen Greear if (2 + ln0 + ln1 > len) { 1036bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("Invalid IE length.\n"); 1037bc9e14f1271413bedf655750d09d7053df09279bBen Greear } else { 1038bc9e14f1271413bedf655750d09d7053df09279bBen Greear for (idx = 0; idx < ln1; idx++) { 1039bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("%02hx", data[2 + ln0 + idx]); 1040bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1041bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\n"); 1042bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1043bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1044bc9e14f1271413bedf655750d09d7053df09279bBen Greear 1045bc9e14f1271413bedf655750d09d7053df09279bBen Greear if (ln2 > 0) { 1046bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\t\tOI 3: "); 1047bc9e14f1271413bedf655750d09d7053df09279bBen Greear if (2 + ln0 + ln1 + ln2 > len) { 1048bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("Invalid IE length.\n"); 1049bc9e14f1271413bedf655750d09d7053df09279bBen Greear } else { 1050bc9e14f1271413bedf655750d09d7053df09279bBen Greear for (idx = 0; idx < ln2; idx++) { 1051bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("%02hx", data[2 + ln0 + ln1 + idx]); 1052bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1053bc9e14f1271413bedf655750d09d7053df09279bBen Greear printf("\n"); 1054bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1055bc9e14f1271413bedf655750d09d7053df09279bBen Greear } 1056bc9e14f1271413bedf655750d09d7053df09279bBen Greear} 1057bc9e14f1271413bedf655750d09d7053df09279bBen Greear 105829f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic const char *ht_secondary_offset[4] = { 105929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "no secondary", 106029f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "above", 106129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "[reserved!]", 106229f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "below", 106329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg}; 106429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 1065be7602fb865fcef72924c926729650c0db9cf254Johannes Bergstatic void print_ht_op(const uint8_t type, uint8_t len, const uint8_t *data) 1066be7602fb865fcef72924c926729650c0db9cf254Johannes Berg{ 1067be7602fb865fcef72924c926729650c0db9cf254Johannes Berg static const char *protection[4] = { 1068be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "no", 1069be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "nonmember", 1070be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "20 MHz", 1071be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "non-HT mixed", 1072be7602fb865fcef72924c926729650c0db9cf254Johannes Berg }; 1073be7602fb865fcef72924c926729650c0db9cf254Johannes Berg static const char *sta_chan_width[2] = { 1074be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "20 MHz", 1075be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "any", 1076be7602fb865fcef72924c926729650c0db9cf254Johannes Berg }; 1077be7602fb865fcef72924c926729650c0db9cf254Johannes Berg 1078be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\n"); 1079be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * primary channel: %d\n", data[0]); 1080be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * secondary channel offset: %s\n", 108129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg ht_secondary_offset[data[1] & 0x3]); 1082be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * STA channel width: %s\n", sta_chan_width[(data[1] & 0x4)>>2]); 1083be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * RIFS: %d\n", (data[1] & 0x8)>>3); 1084be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * HT protection: %s\n", protection[data[2] & 0x3]); 1085be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * non-GF present: %d\n", (data[2] & 0x4) >> 2); 1086be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * OBSS non-GF present: %d\n", (data[2] & 0x10) >> 4); 1087be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * dual beacon: %d\n", (data[4] & 0x40) >> 6); 1088be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * dual CTS protection: %d\n", (data[4] & 0x80) >> 7); 1089be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * STBC beacon: %d\n", data[5] & 0x1); 1090be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * L-SIG TXOP Prot: %d\n", (data[5] & 0x2) >> 1); 1091be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * PCO active: %d\n", (data[5] & 0x4) >> 2); 1092be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * PCO phase: %d\n", (data[5] & 0x8) >> 3); 1093be7602fb865fcef72924c926729650c0db9cf254Johannes Berg} 1094be7602fb865fcef72924c926729650c0db9cf254Johannes Berg 109583b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_capabilities(const uint8_t type, uint8_t len, const uint8_t *data) 10969b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann{ 109731d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg int i, base, bit; 109831d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg bool first = true; 109931d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 110031d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 110131d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg for (i = 0; i < len; i++) { 110231d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg base = i * 8; 110331d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 110431d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg for (bit = 0; bit < 8; bit++) { 110531d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg if (!(data[i] & (1 << bit))) 110631d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg continue; 110731d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 110831d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg if (!first) 110931d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg printf(","); 111031d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg else 111131d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg first = false; 111231d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 111370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg#define CAPA(bit, name) case bit: printf(" " name); break 111470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg 111531d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg switch (bit + base) { 111670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(0, "HT Information Exchange Supported"); 111770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(1, "reserved (On-demand Beacon)"); 111870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(2, "Extended Channel Switching"); 111970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(3, "reserved (Wave Indication)"); 112070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(4, "PSMP Capability"); 112170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(5, "reserved (Service Interval Granularity)"); 112270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(6, "S-PSMP Capability"); 112370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(7, "Event"); 112470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(8, "Diagnostics"); 112570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(9, "Multicast Diagnostics"); 112670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(10, "Location Tracking"); 112770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(11, "FMS"); 112870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(12, "Proxy ARP Service"); 112970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(13, "Collocated Interference Reporting"); 113070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(14, "Civic Location"); 113170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(15, "Geospatial Location"); 113270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(16, "TFS"); 113370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(17, "WNM-Sleep Mode"); 113470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(18, "TIM Broadcast"); 113570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(19, "BSS Transition"); 113670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(20, "QoS Traffic Capability"); 113770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(21, "AC Station Count"); 113870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(22, "Multiple BSSID"); 113970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(23, "Timing Measurement"); 114070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(24, "Channel Usage"); 114170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(25, "SSID List"); 114270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(26, "DMS"); 114370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(27, "UTC TSF Offset"); 114470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(28, "TDLS Peer U-APSD Buffer STA Support"); 114570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(29, "TDLS Peer PSM Support"); 114670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(30, "TDLS channel switching"); 114770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(31, "Interworking"); 114870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(32, "QoS Map"); 114970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(33, "EBR"); 115070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(34, "SSPN Interface"); 115170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(35, "Reserved"); 115270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(36, "MSGCF Capability"); 115370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(37, "TDLS Support"); 115470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(38, "TDLS Prohibited"); 115570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(39, "TDLS Channel Switching Prohibited"); 115670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(40, "Reject Unadmitted Frame"); 115770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(44, "Identifier Location"); 115870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(45, "U-APSD Coexistence"); 115970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(46, "WNM-Notification"); 116070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(47, "Reserved"); 116170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(48, "UTF-8 SSID"); 116231d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg default: 116331d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg printf(" %d", bit); 116431d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg break; 116531d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg } 116670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg#undef CAPA 116731d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg } 116831d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg } 11699b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann 11709b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann printf("\n"); 11719b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann} 11729b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann 1173575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinenstatic void print_tim(const uint8_t type, uint8_t len, const uint8_t *data) 1174575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen{ 1175575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf(" DTIM Count %u DTIM Period %u Bitmap Control 0x%x " 1176575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen "Bitmap[0] 0x%x", 1177575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen data[0], data[1], data[2], data[3]); 1178575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen if (len - 4) 1179575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf(" (+ %u octet%s)", len - 4, len - 4 == 1 ? "" : "s"); 1180575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf("\n"); 1181575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen} 1182575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen 1183792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayerstatic void print_ibssatim(const uint8_t type, uint8_t len, const uint8_t *data) 1184792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer{ 1185792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer printf(" %d TUs", (data[1] << 8) + data[0]); 1186792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer} 1187792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer 118854eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Bergstatic void print_vht_capa(const uint8_t type, uint8_t len, const uint8_t *data) 118954eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg{ 119054eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg printf("\n"); 119154eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg print_vht_info(data[0] | (data[1] << 8) | 119254eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg (data[2] << 16) | (data[3] << 24), 119354eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg data + 4); 119454eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg} 119554eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg 1196ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Bergstatic void print_vht_oper(const uint8_t type, uint8_t len, const uint8_t *data) 1197ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg{ 1198ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg const char *chandwidths[] = { 1199ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [0] = "20 or 40 MHz", 1200ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [1] = "80 MHz", 1201ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [3] = "80+80 MHz", 1202ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [2] = "160 MHz", 1203ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg }; 1204ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg 1205ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\n"); 1206ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * channel width: %d (%s)\n", data[0], 1207ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg data[0] < ARRAY_SIZE(chandwidths) ? chandwidths[data[0]] : "unknown"); 1208ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * center freq segment 1: %d\n", data[1]); 1209ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * center freq segment 2: %d\n", data[2]); 1210ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * VHT basic MCS set: 0x%.2x%.2x\n", data[4], data[3]); 1211ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg} 1212ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg 121329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic void print_obss_scan_params(const uint8_t type, uint8_t len, const uint8_t *data) 121429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg{ 121529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\n"); 121629f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * passive dwell: %d TUs\n", (data[1] << 8) | data[0]); 121729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * active dwell: %d TUs\n", (data[3] << 8) | data[2]); 121829f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * channel width trigger scan interval: %d s\n", (data[5] << 8) | data[4]); 121929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * scan passive total per channel: %d TUs\n", (data[7] << 8) | data[6]); 122029f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * scan active total per channel: %d TUs\n", (data[9] << 8) | data[8]); 122129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * BSS width channel transition delay factor: %d\n", (data[11] << 8) | data[10]); 122229f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * OBSS Scan Activity Threshold: %d.%02d %%\n", 122329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg ((data[13] << 8) | data[12]) / 100, ((data[13] << 8) | data[12]) % 100); 122429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg} 122529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 122629f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic void print_secchan_offs(const uint8_t type, uint8_t len, const uint8_t *data) 122729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg{ 122829f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg if (data[0] < ARRAY_SIZE(ht_secondary_offset)) 122929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf(" %s (%d)\n", ht_secondary_offset[data[0]], data[0]); 123029f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg else 123129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf(" %d\n", data[0]); 123229f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg} 123329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 123429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic void print_bss_load(const uint8_t type, uint8_t len, const uint8_t *data) 123529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg{ 123629f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\n"); 123729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * station count: %d\n", (data[1] << 8) | data[0]); 123829f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * channel utilisation: %d/255\n", data[2]); 123929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * available admission capacity: %d [*32us]\n", (data[4] << 8) | data[3]); 124029f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg} 124129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 12422d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeohstatic void print_mesh_conf(const uint8_t type, uint8_t len, const uint8_t *data) 12432d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh{ 12442d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\n"); 12452d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t * Active Path Selection Protocol ID: %d\n", data[0]); 12462d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t * Active Path Selection Metric ID: %d\n", data[1]); 12472d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t * Congestion Control Mode ID: %d\n", data[2]); 12482d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t * Synchronization Method ID: %d\n", data[3]); 12492d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t * Authentication Protocol ID: %d\n", data[4]); 12502d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t * Mesh Formation Info:\n"); 12512d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t Number of Peerings: %d\n", (data[5] & 0x7E) >> 1); 12522d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[5] & 0x01) 12532d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t Connected to Mesh Gate\n"); 12542d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[5] & 0x80) 12552d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t Connected to AS\n"); 12562d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t * Mesh Capability\n"); 12572d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[6] & 0x01) 12582d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t Accepting Additional Mesh Peerings\n"); 12592d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[6] & 0x02) 12602d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t MCCA Supported\n"); 12612d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[6] & 0x04) 12622d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t MCCA Enabled\n"); 12632d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[6] & 0x08) 12642d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t Forwarding\n"); 12652d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[6] & 0x10) 12662d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t MBCA Supported\n"); 12672d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[6] & 0x20) 12682d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t TBTT Adjusting\n"); 12692d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh if (data[6] & 0x40) 12702d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh printf("\t\t\t Mesh Power Save Level\n"); 12712d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh} 12722d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh 127383b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstruct ie_print { 127483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg const char *name; 127583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg void (*print)(const uint8_t type, uint8_t len, const uint8_t *data); 127683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg uint8_t minlen, maxlen; 1277febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg uint8_t flags; 1278764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg}; 1279764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 128083b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_ie(const struct ie_print *p, const uint8_t type, 128183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg uint8_t len, const uint8_t *data) 12824673a894dae2780e395204eab01af4d40220b9f5Johannes Berg{ 128383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg int i; 128483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 128583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg if (!p->print) 128683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg return; 128783b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 128883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf("\t%s:", p->name); 128983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg if (len < p->minlen || len > p->maxlen) { 129083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg if (len > 1) { 129183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <invalid: %d bytes:", len); 129283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg for (i = 0; i < len; i++) 129383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" %.02x", data[i]); 129483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(">\n"); 129583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg } else if (len) 129683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <invalid: 1 byte: %.02x>\n", data[0]); 129783b4934c612b84c28a656d496bea056e37fccb99Johannes Berg else 129883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <invalid: no data>\n"); 129983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg return; 130083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg } 130183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 130283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg p->print(type, len, data); 130383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg} 130483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 130583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg#define PRINT_IGN { \ 130683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .name = "IGNORE", \ 130783b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .print = NULL, \ 130883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .minlen = 0, \ 130983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .maxlen = 255, \ 13104673a894dae2780e395204eab01af4d40220b9f5Johannes Berg} 13114673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 131283b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic const struct ie_print ieprinters[] = { 1313febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [0] = { "SSID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), }, 1314febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, 1315014d581a9292b35d54e76793ec216ba15c2ec69cJohannes Berg [3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), }, 1316575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen [5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), }, 1317792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer [6] = { "IBSS ATIM window", print_ibssatim, 2, 2, BIT(PRINT_SCAN), }, 1318febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [7] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), }, 131929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg [11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), }, 1320febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), }, 1321792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer [35] = { "TPC report", print_tpcreport, 2, 2, BIT(PRINT_SCAN), }, 1322febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), }, 1323a2e61861abd4037ab29ddf4382c5d2f925c1be66Johannes Berg [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), }, 1324792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer [47] = { "ERP D4.0", print_erp, 1, 255, BIT(PRINT_SCAN), }, 132529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg [74] = { "Overlapping BSS scan params", print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), }, 1326be7602fb865fcef72924c926729650c0db9cf254Johannes Berg [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), }, 132729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg [62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), }, 132854eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), }, 1329ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), }, 1330febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), }, 1331febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, 13322d86b0f3334801e4d63576096810d9c963c3413dChun-Yeow Yeoh [113] = { "MESH Configuration", print_mesh_conf, 7, 7, BIT(PRINT_SCAN), }, 1333720583e9a9fce9b760b8794118e7a5d54cb428f5Chun-Yeow Yeoh [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), }, 1334febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), }, 1335489f0ea93ea4dd6f7cd6eea9eea6f6ff77e1d251Ben Greear [107] = { "802.11u Interworking", print_interworking, 0, 255, BIT(PRINT_SCAN), }, 13363f818f6d74a351d092ec18ecaa1118d2bcf7bf71Ben Greear [108] = { "802.11u Advertisement", print_11u_advert, 0, 255, BIT(PRINT_SCAN), }, 1337bc9e14f1271413bedf655750d09d7053df09279bBen Greear [111] = { "802.11u Roaming Consortium", print_11u_rcon, 0, 255, BIT(PRINT_SCAN), }, 133883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg}; 133983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 134083b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data) 134183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg{ 134283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_rsn_ie("TKIP", "IEEE 802.1X", len, data); 134383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg} 134483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 1345f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greearstatic void print_wifi_osen(const uint8_t type, uint8_t len, const uint8_t *data) 1346f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear{ 1347f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear print_osen_ie("OSEN", "OSEN", len, data); 1348f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear} 1349f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear 13501cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Bergstatic bool print_wifi_wmm_param(const uint8_t *data, uint8_t len) 13511cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg{ 13521cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg int i; 13531cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg static const char *aci_tbl[] = { "BE", "BK", "VI", "VO" }; 13541cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13551cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (len < 19) 13561cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg goto invalid; 13571cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13581cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (data[0] != 1) { 1359cee4fe2039a01208fbbae45dda1c7d3bbfbe5f36Johannes Berg printf("Parameter: not version 1: "); 13601cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return false; 13611cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg } 13621cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 136389ea706f0a177ff6e78b207bc08143d2d149dd08Marcel Holtmann printf("\t * Parameter version 1"); 13641cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13651cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg data++; 13661cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13671cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (data[0] & 0x80) 136889ea706f0a177ff6e78b207bc08143d2d149dd08Marcel Holtmann printf("\n\t\t * u-APSD"); 13691cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13701cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg data += 2; 13711cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13721cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg for (i = 0; i < 4; i++) { 137389ea706f0a177ff6e78b207bc08143d2d149dd08Marcel Holtmann printf("\n\t\t * %s:", aci_tbl[(data[0] >> 5) & 3]); 137487181516675a6d6a2ce0d6ce53b4ba601b62d427Yoni Divinsky if (data[0] & 0x10) 13751cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf(" acm"); 13761cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf(" CW %d-%d", (1 << (data[1] & 0xf)) - 1, 13771cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg (1 << (data[1] >> 4)) - 1); 1378a2a4c265af2e322e245b4fc1962d93a38da61f7aJohannes Berg printf(", AIFSN %d", data[0] & 0xf); 13791cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (data[2] | data[3]) 1380cee4fe2039a01208fbbae45dda1c7d3bbfbe5f36Johannes Berg printf(", TXOP %d usec", (data[2] + (data[3] << 8)) * 32); 13811cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg data += 4; 13821cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg } 13831cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13841cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf("\n"); 13851cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return true; 13861cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 13871cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg invalid: 13881cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf("invalid: "); 13891cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return false; 13901cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg} 13911cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 139283b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_wifi_wmm(const uint8_t type, uint8_t len, const uint8_t *data) 13936ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann{ 13946ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann int i; 13956ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann 13966ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann switch (data[0]) { 13976ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann case 0x00: 139883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" information:"); 13996ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann break; 14006ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann case 0x01: 14011cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (print_wifi_wmm_param(data + 1, len - 1)) 14021cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return; 14036ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann break; 14046ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann default: 140583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" type %d:", data[0]); 14066ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann break; 14076ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann } 14086ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann 14091cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg for(i = 1; i < len; i++) 14101cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf(" %.02x", data[i]); 14116ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann printf("\n"); 14126ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann} 14136ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann 1414a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinenstatic const char * wifi_wps_dev_passwd_id(uint16_t id) 1415a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen{ 1416a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen switch (id) { 1417a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0: 1418a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Default (PIN)"; 1419a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 1: 1420a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "User-specified"; 1421a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 2: 1422a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Machine-specified"; 1423a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 3: 1424a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Rekey"; 1425a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 4: 1426a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "PushButton"; 1427a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 5: 1428a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Registrar-specified"; 1429a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen default: 1430a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "??"; 1431a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 1432a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen} 1433a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen 143483b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data) 14354673a894dae2780e395204eab01af4d40220b9f5Johannes Berg{ 14364673a894dae2780e395204eab01af4d40220b9f5Johannes Berg bool first = true; 14374673a894dae2780e395204eab01af4d40220b9f5Johannes Berg __u16 subtype, sublen; 14384673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 14394673a894dae2780e395204eab01af4d40220b9f5Johannes Berg while (len >= 4) { 14404673a894dae2780e395204eab01af4d40220b9f5Johannes Berg subtype = (data[0] << 8) + data[1]; 14414673a894dae2780e395204eab01af4d40220b9f5Johannes Berg sublen = (data[2] << 8) + data[3]; 14424673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (sublen > len) 14434673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 14444673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 14454673a894dae2780e395204eab01af4d40220b9f5Johannes Berg switch (subtype) { 14464673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x104a: 14474673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 1448dffc6750fec6d97a4fc55a687836cd6437be76e2Johannes Berg printf("\t * Version: %d.%d\n", data[4] >> 4, data[4] & 0xF); 14494673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 14504673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x1011: 14514673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 14524673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t * Device name: %.*s\n", sublen, data + 4); 14534673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 1454a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1012: { 1455a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen uint16_t id; 1456a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1457a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen if (sublen != 2) { 1458a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Device Password ID: (invalid " 1459a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen "length %d)\n", sublen); 1460a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1461a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 1462a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen id = data[4] << 8 | data[5]; 1463a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Device Password ID: %u (%s)\n", 1464a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen id, wifi_wps_dev_passwd_id(id)); 1465a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1466a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 14674673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x1021: 14684673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 14694673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t * Manufacturer: %.*s\n", sublen, data + 4); 14704673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 14714673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x1023: 14724673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 14734673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t * Model: %.*s\n", sublen, data + 4); 14744673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 1475a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1024: 1476a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1477a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Model Number: %.*s\n", sublen, data + 4); 1478a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1479a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x103b: { 1480a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 1481a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1482a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Response Type: %d%s\n", 1483a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val, val == 3 ? " (AP)" : ""); 1484a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1485a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 1486a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x103c: { 1487a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 1488a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1489a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * RF Bands: 0x%x\n", val); 1490a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1491a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 1492a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1041: { 1493a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 1494a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1495a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Selected Registrar: 0x%x\n", val); 1496a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1497a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 1498a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1042: 1499a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1500a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Serial Number: %.*s\n", sublen, data + 4); 1501a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1502a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1044: { 1503a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 1504a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1505a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Wi-Fi Protected Setup State: %d%s%s\n", 1506a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val, 1507a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val == 1 ? " (Unconfigured)" : "", 1508a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val == 2 ? " (Configured)" : ""); 1509a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1510a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 151109fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg case 0x1047: 151209fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg tab_on_first(&first); 151309fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg printf("\t * UUID: "); 151409fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg if (sublen != 16) { 151509fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg printf("(invalid, length=%d)\n", sublen); 151609fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg break; 151709fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg } 151809fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-" 151909fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg "%02x%02x-%02x%02x%02x%02x%02x%02x\n", 152009fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[4], data[5], data[6], data[7], 152109fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[8], data[9], data[10], data[11], 152209fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[12], data[13], data[14], data[15], 152309fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[16], data[17], data[18], data[19]); 152409fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg break; 1525a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1054: { 1526a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 1527a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen if (sublen != 8) { 1528a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Primary Device Type: (invalid " 1529a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen "length %d)\n", sublen); 1530a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1531a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 1532a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Primary Device Type: " 1533a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen "%u-%02x%02x%02x%02x-%u\n", 1534a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen data[4] << 8 | data[5], 1535a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen data[6], data[7], data[8], data[9], 1536a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen data[10] << 8 | data[11]); 1537a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1538a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 15397ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg case 0x1057: { 1540fe31a22e04f62839e8ba41e6fc9241abe64e07c2Johannes Berg __u8 val = data[4]; 15417ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg tab_on_first(&first); 1542fe31a22e04f62839e8ba41e6fc9241abe64e07c2Johannes Berg printf("\t * AP setup locked: 0x%.2x\n", val); 15437ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg break; 15447ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg } 1545a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1008: 1546a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1053: { 15474673a894dae2780e395204eab01af4d40220b9f5Johannes Berg __u16 meth = (data[4] << 8) + data[5]; 15484673a894dae2780e395204eab01af4d40220b9f5Johannes Berg bool comma = false; 15494673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 1550a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * %sConfig methods:", 1551a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen subtype == 0x1053 ? "Selected Registrar ": ""); 15524673a894dae2780e395204eab01af4d40220b9f5Johannes Berg#define T(bit, name) do { \ 15534673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (meth & (1<<bit)) { \ 15544673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (comma) \ 15554673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(","); \ 15564673a894dae2780e395204eab01af4d40220b9f5Johannes Berg comma = true; \ 15574673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(" " name); \ 15584673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } } while (0) 15594673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(0, "USB"); 15604673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(1, "Ethernet"); 15614673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(2, "Label"); 15624673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(3, "Display"); 15634673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(4, "Ext. NFC"); 15644673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(5, "Int. NFC"); 15654673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(6, "NFC Intf."); 15664673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(7, "PBC"); 15674673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(8, "Keypad"); 15684673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\n"); 15694673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 15704673a894dae2780e395204eab01af4d40220b9f5Johannes Berg#undef T 15714673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 15722650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg default: { 15732650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg const __u8 *subdata = data + 4; 15742650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg __u16 tmplen = sublen; 15752650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg 15762650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg tab_on_first(&first); 15772650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg printf("\t * Unknown TLV (%#.4x, %d bytes):", 15782650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg subtype, tmplen); 15792650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg while (tmplen) { 15802650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg printf(" %.2x", *subdata); 15812650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg subdata++; 15822650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg tmplen--; 15832650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg } 15842650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg printf("\n"); 15854673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 15864673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 15872650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg } 15884673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 15894673a894dae2780e395204eab01af4d40220b9f5Johannes Berg data += sublen + 4; 15904673a894dae2780e395204eab01af4d40220b9f5Johannes Berg len -= sublen + 4; 15914673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 15924673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 15934673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (len != 0) { 15944673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t\t * bogus tail data (%d):", len); 15954673a894dae2780e395204eab01af4d40220b9f5Johannes Berg while (len) { 15964673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(" %.2x", *data); 15974673a894dae2780e395204eab01af4d40220b9f5Johannes Berg data++; 15984673a894dae2780e395204eab01af4d40220b9f5Johannes Berg len--; 15994673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 16004673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\n"); 16014673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 16024673a894dae2780e395204eab01af4d40220b9f5Johannes Berg} 16034673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 160483b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic const struct ie_print wifiprinters[] = { 1605febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [1] = { "WPA", print_wifi_wpa, 2, 255, BIT(PRINT_SCAN), }, 1606febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [2] = { "WMM", print_wifi_wmm, 1, 255, BIT(PRINT_SCAN), }, 1607febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [4] = { "WPS", print_wifi_wps, 0, 255, BIT(PRINT_SCAN), }, 16084673a894dae2780e395204eab01af4d40220b9f5Johannes Berg}; 16094673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 16109a22374a56b394000cfb98acb649355f76beb3a3Johannes Bergstatic inline void print_p2p(const uint8_t type, uint8_t len, const uint8_t *data) 16119a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg{ 16129a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg bool first = true; 16139a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg __u8 subtype; 16149a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg __u16 sublen; 16159a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 16169a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg while (len >= 3) { 16179a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg subtype = data[0]; 16189a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg sublen = (data[2] << 8) + data[1]; 16199a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 16209a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (sublen > len - 3) 16219a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 16229a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 16239a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg switch (subtype) { 16249a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x02: /* capability */ 16259a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tab_on_first(&first); 16269a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (sublen < 2) { 16279a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * malformed capability\n"); 16289a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 16299a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16309a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * Group capa: 0x%.2x, Device capa: 0x%.2x\n", 16319a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg data[3], data[4]); 16329a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 16339a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0d: /* device info */ 16349a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (sublen < 6 + 2 + 8 + 1) { 16359a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * malformed device info\n"); 16369a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 16379a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16389a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg /* fall through for now */ 16399a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x00: /* status */ 16409a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x01: /* minor reason */ 16419a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x03: /* device ID */ 16429a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x04: /* GO intent */ 16439a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x05: /* configuration timeout */ 16449a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x06: /* listen channel */ 16459a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x07: /* group BSSID */ 16469a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x08: /* ext listen timing */ 16479a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x09: /* intended interface address */ 16489a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0a: /* manageability */ 16499a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0b: /* channel list */ 16509a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0c: /* NoA */ 16519a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0e: /* group info */ 16529a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0f: /* group ID */ 16539a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x10: /* interface */ 16549a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x11: /* operating channel */ 16559a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x12: /* invitation flags */ 16569a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0xdd: /* vendor specific */ 16579a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg default: { 16589a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg const __u8 *subdata = data + 4; 16599a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg __u16 tmplen = sublen; 16609a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 16619a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tab_on_first(&first); 16629a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * Unknown TLV (%#.2x, %d bytes):", 16639a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg subtype, tmplen); 16649a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg while (tmplen) { 16659a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf(" %.2x", *subdata); 16669a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg subdata++; 16679a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tmplen--; 16689a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16699a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\n"); 16709a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 16719a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16729a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16739a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 16749a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg data += sublen + 3; 16759a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg len -= sublen + 3; 16769a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16779a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 16789a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (len != 0) { 16799a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tab_on_first(&first); 16809a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * bogus tail data (%d):", len); 16819a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg while (len) { 16829a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf(" %.2x", *data); 16839a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg data++; 16849a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg len--; 16859a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16869a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\n"); 16879a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 16889a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg} 16899a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 16907e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greearstatic inline void print_hs20_ind(const uint8_t type, uint8_t len, const uint8_t *data) 16917e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear{ 16927e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear /* I can't find the spec for this...just going off what wireshark uses. */ 16937e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear printf("\n"); 16947e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear if (len > 0) 16957e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear printf("\t\tDGAF: %i\n", (int)(data[0] & 0x1)); 16967e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear else 16977e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear printf("\t\tUnexpected length: %i\n", len); 16987e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear} 16997e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear 17009a22374a56b394000cfb98acb649355f76beb3a3Johannes Bergstatic const struct ie_print wfa_printers[] = { 17019a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg [9] = { "P2P", print_p2p, 2, 255, BIT(PRINT_SCAN), }, 17027e10c4ab5e99f23c4d8e78dbcda56af71f9f1d56Ben Greear [16] = { "HotSpot 2.0 Indication", print_hs20_ind, 1, 255, BIT(PRINT_SCAN), }, 1703f188ab676a69a1fa0f318be13755fd288d52bcdaBen Greear [18] = { "HotSpot 2.0 OSEN", print_wifi_osen, 1, 255, BIT(PRINT_SCAN), }, 17049a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg}; 17059a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 1706764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Bergstatic void print_vendor(unsigned char len, unsigned char *data, 1707febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg bool unknown, enum print_ie_type ptype) 17083563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 17093563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int i; 17103563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1711fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg if (len < 3) { 17124673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\tVendor specific: <too short> data:"); 1713fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg for(i = 0; i < len; i++) 1714fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf(" %.02x", data[i]); 1715fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf("\n"); 1716fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg return; 1717fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg } 1718fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg 17193bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg if (len >= 4 && memcmp(data, ms_oui, 3) == 0) { 1720febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (data[3] < ARRAY_SIZE(wifiprinters) && 1721febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg wifiprinters[data[3]].name && 1722febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg wifiprinters[data[3]].flags & BIT(ptype)) { 172383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_ie(&wifiprinters[data[3]], data[3], len - 4, data + 4); 172483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg return; 172583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg } 1726febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (!unknown) 17274673a894dae2780e395204eab01af4d40220b9f5Johannes Berg return; 17283bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg printf("\tMS/WiFi %#.2x, data:", data[3]); 17294673a894dae2780e395204eab01af4d40220b9f5Johannes Berg for(i = 0; i < len - 4; i++) 17304673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(" %.02x", data[i + 4]); 17314673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\n"); 17324673a894dae2780e395204eab01af4d40220b9f5Johannes Berg return; 17334673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 17344673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 17359a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (len >= 4 && memcmp(data, wfa_oui, 3) == 0) { 17369a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (data[3] < ARRAY_SIZE(wfa_printers) && 17379a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg wfa_printers[data[3]].name && 17389a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg wfa_printers[data[3]].flags & BIT(ptype)) { 17399a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg print_ie(&wfa_printers[data[3]], data[3], len - 4, data + 4); 17409a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg return; 17419a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 17429a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (!unknown) 17439a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg return; 17449a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\tWFA %#.2x, data:", data[3]); 17459a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg for(i = 0; i < len - 4; i++) 17469a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf(" %.02x", data[i + 4]); 17479a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\n"); 17489a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg return; 17499a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 17509a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 1751febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (!unknown) 1752764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg return; 1753764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 1754fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf("\tVendor specific: OUI %.2x:%.2x:%.2x, data:", 17553563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg data[0], data[1], data[2]); 1756fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg for (i = 3; i < len; i++) 1757fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf(" %.2x", data[i]); 17583563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 17593563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 17603563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1761febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Bergvoid print_ies(unsigned char *ie, int ielen, bool unknown, 1762febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg enum print_ie_type ptype) 17633563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 17643563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg while (ielen >= 2 && ielen >= ie[1]) { 1765febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (ie[0] < ARRAY_SIZE(ieprinters) && 1766febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg ieprinters[ie[0]].name && 1767febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg ieprinters[ie[0]].flags & BIT(ptype)) { 176883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_ie(&ieprinters[ie[0]], ie[0], ie[1], ie + 2); 1769764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg } else if (ie[0] == 221 /* vendor */) { 1770febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg print_vendor(ie[1], ie + 2, unknown, ptype); 1771febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg } else if (unknown) { 17723563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int i; 17733563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 17748086b7007d8a7f9d2bc22d154e26e9060f0e9676Johannes Berg printf("\tUnknown IE (%d):", ie[0]); 17753563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg for (i=0; i<ie[1]; i++) 17768086b7007d8a7f9d2bc22d154e26e9060f0e9676Johannes Berg printf(" %.2x", ie[2+i]); 17773563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 17783563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 17793563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg ielen -= ie[1] + 2; 17803563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg ie += ie[1] + 2; 17813563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 17823563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 17833563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 17842e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratievstatic void print_capa_dmg(__u16 capa) 17852e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev{ 17862e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev switch (capa & WLAN_CAPABILITY_DMG_TYPE_MASK) { 17872e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev case WLAN_CAPABILITY_DMG_TYPE_AP: 17882e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DMG_ESS"); 17892e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev break; 17902e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev case WLAN_CAPABILITY_DMG_TYPE_PBSS: 17912e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DMG_PCP"); 17922e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev break; 17932e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev case WLAN_CAPABILITY_DMG_TYPE_IBSS: 17942e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DMG_IBSS"); 17952e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev break; 17962e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev } 17972e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 17982e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_CBAP_ONLY) 17992e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CBAP_Only"); 18002e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_CBAP_SOURCE) 18012e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CBAP_Src"); 18022e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_PRIVACY) 18032e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" Privacy"); 18042e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_ECPAC) 18052e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ECPAC"); 18062e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_SPECTRUM_MGMT) 18072e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" SpectrumMgmt"); 18082e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_RADIO_MEASURE) 18092e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" RadioMeasure"); 18102e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev} 18112e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 18122e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratievstatic void print_capa_non_dmg(__u16 capa) 18132e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev{ 18142e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_ESS) 18152e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ESS"); 18162e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_IBSS) 18172e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" IBSS"); 18182e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_CF_POLLABLE) 18192e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CfPollable"); 18202e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_CF_POLL_REQUEST) 18212e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CfPollReq"); 18222e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_PRIVACY) 18232e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" Privacy"); 18242e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_SHORT_PREAMBLE) 18252e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ShortPreamble"); 18262e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_PBCC) 18272e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" PBCC"); 18282e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_CHANNEL_AGILITY) 18292e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ChannelAgility"); 18302e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_SPECTRUM_MGMT) 18312e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" SpectrumMgmt"); 18322e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_QOS) 18332e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" QoS"); 18342e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_SHORT_SLOT_TIME) 18352e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ShortSlotTime"); 18362e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_APSD) 18372e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" APSD"); 18382e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_RADIO_MEASURE) 18392e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" RadioMeasure"); 18402e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DSSS_OFDM) 18412e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DSSS-OFDM"); 18422e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DEL_BACK) 18432e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DelayedBACK"); 18442e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_IMM_BACK) 18452e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ImmediateBACK"); 18462e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev} 18472e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 18483563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Bergstatic int print_bss_handler(struct nl_msg *msg, void *arg) 18493563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 18503563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nlattr *tb[NL80211_ATTR_MAX + 1]; 18513563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); 18523563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nlattr *bss[NL80211_BSS_MAX + 1]; 18533563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg char mac_addr[20], dev[20]; 18543563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { 18553563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_TSF] = { .type = NLA_U64 }, 18563563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, 18573563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_BSSID] = { }, 18583563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 }, 18593563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 }, 18603563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_INFORMATION_ELEMENTS] = { }, 1861f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 }, 1862f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 }, 1863a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg [NL80211_BSS_STATUS] = { .type = NLA_U32 }, 1864c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 }, 1865575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen [NL80211_BSS_BEACON_IES] = { }, 18663563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg }; 1867febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg struct scan_params *params = arg; 18681c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg int show = params->show_both_ie_sets ? 2 : 1; 18692e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev bool is_dmg = false; 18703563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 18713563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), 18723563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg genlmsg_attrlen(gnlh, 0), NULL); 18733563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 18743563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (!tb[NL80211_ATTR_BSS]) { 18755fe70c0edb4bc3015d192977f4fb9a5d4fa07148Johannes Berg fprintf(stderr, "bss info missing!\n"); 18763563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 18773563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 18783563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (nla_parse_nested(bss, NL80211_BSS_MAX, 18793563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg tb[NL80211_ATTR_BSS], 18803563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg bss_policy)) { 18815fe70c0edb4bc3015d192977f4fb9a5d4fa07148Johannes Berg fprintf(stderr, "failed to parse nested attributes!\n"); 18823563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 18833563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 18843563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 18853563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (!bss[NL80211_BSS_BSSID]) 18863563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 18873563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 18883563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg mac_addr_n2a(mac_addr, nla_data(bss[NL80211_BSS_BSSID])); 188900889fb26e914c7485e1bae42f88259183728f78Johannes Berg printf("BSS %s", mac_addr); 189000889fb26e914c7485e1bae42f88259183728f78Johannes Berg if (tb[NL80211_ATTR_IFINDEX]) { 189100889fb26e914c7485e1bae42f88259183728f78Johannes Berg if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); 189200889fb26e914c7485e1bae42f88259183728f78Johannes Berg printf("(on %s)", dev); 189300889fb26e914c7485e1bae42f88259183728f78Johannes Berg } 1894a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg 1895a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg if (bss[NL80211_BSS_STATUS]) { 1896a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg switch (nla_get_u32(bss[NL80211_BSS_STATUS])) { 1897a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg case NL80211_BSS_STATUS_AUTHENTICATED: 1898a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- authenticated"); 1899a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1900a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg case NL80211_BSS_STATUS_ASSOCIATED: 1901a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- associated"); 1902a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1903a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg case NL80211_BSS_STATUS_IBSS_JOINED: 1904a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- joined"); 1905a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1906a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg default: 1907a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- unknown status: %d", 1908a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg nla_get_u32(bss[NL80211_BSS_STATUS])); 1909a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1910a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg } 1911a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg } 1912a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf("\n"); 19133563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1914e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg if (bss[NL80211_BSS_TSF]) { 1915e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg unsigned long long tsf; 1916e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg tsf = (unsigned long long)nla_get_u64(bss[NL80211_BSS_TSF]); 1917e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg printf("\tTSF: %llu usec (%llud, %.2lld:%.2llu:%.2llu)\n", 1918e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg tsf, tsf/1000/1000/60/60/24, (tsf/1000/1000/60/60) % 24, 1919e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg (tsf/1000/1000/60) % 60, (tsf/1000/1000) % 60); 1920e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg } 19212e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (bss[NL80211_BSS_FREQUENCY]) { 19222e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev int freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]); 19232e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf("\tfreq: %d\n", freq); 19242e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (freq > 45000) 19252e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev is_dmg = true; 19262e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev } 19273563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (bss[NL80211_BSS_BEACON_INTERVAL]) 1928792172b0f1dfbed179788e4944aaf4d4e0a91301Joerg Mayer printf("\tbeacon interval: %d TUs\n", 19293563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL])); 193092a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann if (bss[NL80211_BSS_CAPABILITY]) { 193192a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann __u16 capa = nla_get_u16(bss[NL80211_BSS_CAPABILITY]); 193292a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann printf("\tcapability:"); 19332e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (is_dmg) 19342e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev print_capa_dmg(capa); 19352e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev else 19362e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev print_capa_non_dmg(capa); 193792a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann printf(" (0x%.4x)\n", capa); 193892a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann } 1939f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg if (bss[NL80211_BSS_SIGNAL_MBM]) { 1940f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]); 1941f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg printf("\tsignal: %d.%.2d dBm\n", s/100, s%100); 1942f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg } 1943f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg if (bss[NL80211_BSS_SIGNAL_UNSPEC]) { 1944f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg unsigned char s = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); 1945f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg printf("\tsignal: %d/100\n", s); 1946f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg } 1947c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig if (bss[NL80211_BSS_SEEN_MS_AGO]) { 1948c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig int age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]); 1949c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig printf("\tlast seen: %d ms ago\n", age); 1950c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig } 1951c551449a3271ca1db60856fc2af20e1f2d01cce8Johannes Berg 19521c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg if (bss[NL80211_BSS_INFORMATION_ELEMENTS] && show--) { 1953575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen if (bss[NL80211_BSS_BEACON_IES]) 1954575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf("\tInformation elements from Probe Response " 1955575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen "frame:\n"); 19563563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), 1957764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), 1958febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg params->unknown, params->type); 1959575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen } 19601c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg if (bss[NL80211_BSS_BEACON_IES] && show--) { 1961575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf("\tInformation elements from Beacon frame:\n"); 1962575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen print_ies(nla_data(bss[NL80211_BSS_BEACON_IES]), 1963575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen nla_len(bss[NL80211_BSS_BEACON_IES]), 1964575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen params->unknown, params->type); 1965575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen } 19663563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 19673563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 19683563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 19693563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1970764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Bergstatic struct scan_params scan_params; 19713563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 19727c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Bergstatic int handle_scan_dump(struct nl80211_state *state, 19737c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Berg struct nl_cb *cb, 19743563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nl_msg *msg, 197505514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg int argc, char **argv, 197605514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg enum id_input id) 19773563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 1978764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg if (argc > 1) 1979764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg return 1; 1980764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 19811c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg memset(&scan_params, 0, sizeof(scan_params)); 19821c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg 1983764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg if (argc == 1 && !strcmp(argv[0], "-u")) 1984764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg scan_params.unknown = true; 1985575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen else if (argc == 1 && !strcmp(argv[0], "-b")) 1986575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen scan_params.show_both_ie_sets = true; 1987764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 1988febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg scan_params.type = PRINT_SCAN; 1989febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg 1990764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_bss_handler, 1991764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg &scan_params); 19923563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return 0; 19933563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 1994a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 1995a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Bergstatic int handle_scan_combined(struct nl80211_state *state, 1996a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg struct nl_cb *cb, 1997a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg struct nl_msg *msg, 199805514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg int argc, char **argv, 199905514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg enum id_input id) 2000a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg{ 2001559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg char **trig_argv; 2002a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg static char *dump_argv[] = { 2003a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NULL, 2004a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg "scan", 2005a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg "dump", 200692649eab6b3ccb0be600b8501fa7b83e9467819cMarcel Holtmann NULL, 2007a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg }; 2008a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg static const __u32 cmds[] = { 2009a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NL80211_CMD_NEW_SCAN_RESULTS, 2010a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NL80211_CMD_SCAN_ABORTED, 2011a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg }; 2012559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int trig_argc, dump_argc, err; 2013a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 2014559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (argc >= 3 && !strcmp(argv[2], "-u")) { 2015559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg dump_argc = 4; 2016559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg dump_argv[3] = "-u"; 2017575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen } else if (argc >= 3 && !strcmp(argv[2], "-b")) { 2018575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen dump_argc = 4; 2019575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen dump_argv[3] = "-b"; 2020559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } else 2021559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg dump_argc = 3; 2022559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 2023559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argc = 3 + (argc - 2) + (3 - dump_argc); 2024559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv = calloc(trig_argc, sizeof(*trig_argv)); 2025559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!trig_argv) 2026559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg return -ENOMEM; 2027a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg trig_argv[0] = argv[0]; 2028559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv[1] = "scan"; 2029559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv[2] = "trigger"; 2030559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int i; 2031559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg for (i = 0; i < argc - 2 - (dump_argc - 3); i++) 2032559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv[i + 3] = argv[i + 2 + (dump_argc - 3)]; 203375f4204cd7d27caa080d64f6f5cf3c4b366c839fJohannes Berg err = handle_cmd(state, id, trig_argc, trig_argv); 2034559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg free(trig_argv); 2035a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg if (err) 2036a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg return err; 2037a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 203861725dbed6df376809e8dc3865640244d8f1d690Johannes Berg /* 203961725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION 204061725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 204161725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * This code has a bug, which requires creating a separate 204261725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * nl80211 socket to fix: 204361725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or 204461725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel 204561725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * before (!) we listen to it, because we only start listening 204661725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * after we send our scan request. 204761725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 204861725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * Doing it the other way around has a race condition as well, 204961725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * if you first open the events socket you may get a notification 205061725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * for a previous scan. 205161725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 205261725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * The only proper way to fix this would be to listen to events 205361725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * before sending the command, and for the kernel to send the 205461725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * scan request along with the event, so that you can match up 205561725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * whether the scan you requested was finished or aborted (this 205661725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * may result in processing a scan that another application 205761725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * requested, but that doesn't seem to be a problem). 205861725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 205961725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * Alas, the kernel doesn't do that (yet). 206061725dbed6df376809e8dc3865640244d8f1d690Johannes Berg */ 206161725dbed6df376809e8dc3865640244d8f1d690Johannes Berg 2062a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg if (listen_events(state, ARRAY_SIZE(cmds), cmds) == 2063a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NL80211_CMD_SCAN_ABORTED) { 2064a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg printf("scan aborted!\n"); 2065a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg return 0; 2066a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg } 2067a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 2068a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg dump_argv[0] = argv[0]; 206975f4204cd7d27caa080d64f6f5cf3c4b366c839fJohannes Berg return handle_cmd(state, id, dump_argc, dump_argv); 2070a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg} 20715085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes BergTOPLEVEL(scan, "[-u] [freq <freq>*] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]", 0, 0, 20726ca98d28b949d20cca2e158bef3e0cfd75b59672Johannes Berg CIB_NETDEV, handle_scan_combined, 20736ca98d28b949d20cca2e158bef3e0cfd75b59672Johannes Berg "Scan on the given frequencies and probe for the given SSIDs\n" 20746ca98d28b949d20cca2e158bef3e0cfd75b59672Johannes Berg "(or wildcard if not given) unless passive scanning is requested.\n" 207564797a7fd7c49d95abc8540490c76bf493699176Johannes Berg "If -u is specified print unknown data in the scan results.\n" 207664797a7fd7c49d95abc8540490c76bf493699176Johannes Berg "Specified (vendor) IEs must be well-formed."); 20774698bfc235c20e955466b6362df2a39f7478c13fJohannes BergCOMMAND(scan, dump, "[-u]", 20784698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump, 20794698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "Dump the current scan results. If -u is specified, print unknown\n" 20804698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "data in scan results."); 20815085aa2b7ed0cb5e89eb0c85c10218f552f579aaJohannes BergCOMMAND(scan, trigger, "[freq <freq>*] [ies <hex as 00:11:..>] [meshid <meshid>] [lowpri,flush,ap-force] [randomise[=<addr>/<mask>]] [ssid <ssid>*|passive]", 20824698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan, 20834698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "Trigger a scan on the given frequencies with probing for the given\n" 20844698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "SSIDs (or wildcard if not given) unless passive scanning is requested."); 20853fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho 20863fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho 20873fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelhostatic int handle_start_sched_scan(struct nl80211_state *state, 20883fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho struct nl_cb *cb, struct nl_msg *msg, 20893fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho int argc, char **argv, enum id_input id) 20903fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho{ 20913fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho return parse_sched_scan(msg, &argc, &argv); 20923fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho} 20933fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho 20943fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelhostatic int handle_stop_sched_scan(struct nl80211_state *state, struct nl_cb *cb, 20953fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho struct nl_msg *msg, int argc, char **argv, 20963fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho enum id_input id) 20973fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho{ 20983fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho if (argc != 0) 20993fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho return 1; 21003fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho 21013fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho return 0; 21023fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho} 21033fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho 21043fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano CoelhoCOMMAND(scan, sched_start, 21053fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho SCHED_SCAN_OPTIONS, 21063fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho NL80211_CMD_START_SCHED_SCAN, 0, CIB_NETDEV, handle_start_sched_scan, 21073fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho "Start a scheduled scan at the specified interval on the given frequencies\n" 21083fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho "with probing for the given SSIDs (or wildcard if not given) unless passive\n" 21093fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho "scanning is requested. If matches are specified, only matching results\n" 21103fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho "will be returned."); 21113fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano CoelhoCOMMAND(scan, sched_stop, "", 21123fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho NL80211_CMD_STOP_SCHED_SCAN, 0, CIB_NETDEV, handle_stop_sched_scan, 21133fce58aafc3a28cbfbb496d7797e250eea99b6cbLuciano Coelho "Stop an ongoing scheduled scan."); 2114