scan.c revision 2e8b82c16a312608d530856f3ab2c72dfd0e5cd2
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 737c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Bergstatic int handle_scan(struct nl80211_state *state, 747c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Berg struct nl_cb *cb, 753563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nl_msg *msg, 7605514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg int argc, char **argv, 7705514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg enum id_input id) 783563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 79559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg struct nl_msg *ssids = NULL, *freqs = NULL; 80559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg char *eptr; 813563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int err = -ENOBUFS; 82559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int i; 83559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg enum { 84559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NONE, 85559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg FREQ, 8664797a7fd7c49d95abc8540490c76bf493699176Johannes Berg IES, 87559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg SSID, 88559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg DONE, 89559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } parse = NONE; 90559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int freq; 91559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg bool passive = false, have_ssids = false, have_freqs = false; 9264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg size_t tmp; 9364797a7fd7c49d95abc8540490c76bf493699176Johannes Berg unsigned char *ies; 94fe862239636c303372184abc5635097b43777e77Sam Leffler int flags = 0; 953563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 963563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg ssids = nlmsg_alloc(); 973563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (!ssids) 983563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return -ENOMEM; 99559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 100559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg freqs = nlmsg_alloc(); 101559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!freqs) { 102559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nlmsg_free(ssids); 103559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg return -ENOMEM; 104559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } 105559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 106559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg for (i = 0; i < argc; i++) { 107559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg switch (parse) { 108559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case NONE: 10964797a7fd7c49d95abc8540490c76bf493699176Johannes Berg if (strcmp(argv[i], "freq") == 0) { 11064797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = FREQ; 11164797a7fd7c49d95abc8540490c76bf493699176Johannes Berg have_freqs = true; 11264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 11364797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } else if (strcmp(argv[i], "ies") == 0) { 11464797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = IES; 11564797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 116fe862239636c303372184abc5635097b43777e77Sam Leffler } else if (strcmp(argv[i], "lowpri") == 0) { 117fe862239636c303372184abc5635097b43777e77Sam Leffler parse = NONE; 118fe862239636c303372184abc5635097b43777e77Sam Leffler flags |= NL80211_SCAN_FLAG_LOW_PRIORITY; 119fe862239636c303372184abc5635097b43777e77Sam Leffler break; 120fe862239636c303372184abc5635097b43777e77Sam Leffler } else if (strcmp(argv[i], "flush") == 0) { 121fe862239636c303372184abc5635097b43777e77Sam Leffler parse = NONE; 122fe862239636c303372184abc5635097b43777e77Sam Leffler flags |= NL80211_SCAN_FLAG_FLUSH; 123fe862239636c303372184abc5635097b43777e77Sam Leffler break; 124ced94d5f129e5d116b6a888f312deab081bb2231Antonio Quartulli } else if (strcmp(argv[i], "ap-force") == 0) { 125ced94d5f129e5d116b6a888f312deab081bb2231Antonio Quartulli parse = NONE; 126ced94d5f129e5d116b6a888f312deab081bb2231Antonio Quartulli flags |= NL80211_SCAN_FLAG_AP; 127ced94d5f129e5d116b6a888f312deab081bb2231Antonio Quartulli break; 12864797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } else if (strcmp(argv[i], "ssid") == 0) { 12964797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = SSID; 13064797a7fd7c49d95abc8540490c76bf493699176Johannes Berg have_ssids = true; 13164797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 13264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } else if (strcmp(argv[i], "passive") == 0) { 13364797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = DONE; 13464797a7fd7c49d95abc8540490c76bf493699176Johannes Berg passive = true; 13564797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 13664797a7fd7c49d95abc8540490c76bf493699176Johannes Berg } 137559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case DONE: 138559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg return 1; 139559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case FREQ: 140559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg freq = strtoul(argv[i], &eptr, 10); 141cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg if (eptr != argv[i] + strlen(argv[i])) { 142cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg /* failed to parse as number -- maybe a tag? */ 143cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg i--; 144cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg parse = NONE; 145cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg continue; 146cc12e895302aa7dc82229f12b21e61c52fba80f6Johannes Berg } 147559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NLA_PUT_U32(freqs, i, freq); 14864797a7fd7c49d95abc8540490c76bf493699176Johannes Berg break; 14964797a7fd7c49d95abc8540490c76bf493699176Johannes Berg case IES: 15064797a7fd7c49d95abc8540490c76bf493699176Johannes Berg ies = parse_hex(argv[i], &tmp); 15164797a7fd7c49d95abc8540490c76bf493699176Johannes Berg if (!ies) 15264797a7fd7c49d95abc8540490c76bf493699176Johannes Berg goto nla_put_failure; 15364797a7fd7c49d95abc8540490c76bf493699176Johannes Berg NLA_PUT(msg, NL80211_ATTR_IE, tmp, ies); 15464797a7fd7c49d95abc8540490c76bf493699176Johannes Berg free(ies); 15564797a7fd7c49d95abc8540490c76bf493699176Johannes Berg parse = NONE; 156559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg break; 157559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg case SSID: 158559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NLA_PUT(ssids, i, strlen(argv[i]), argv[i]); 159559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg break; 160559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } 161559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } 162559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 163559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!have_ssids) 164559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg NLA_PUT(ssids, 1, 0, ""); 165559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!passive) 166559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nla_put_nested(msg, NL80211_ATTR_SCAN_SSIDS, ssids); 167559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 168559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (have_freqs) 169559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs); 170fe862239636c303372184abc5635097b43777e77Sam Leffler if (flags) 171fe862239636c303372184abc5635097b43777e77Sam Leffler NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags); 1723563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1733563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg err = 0; 1743563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nla_put_failure: 1753563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nlmsg_free(ssids); 176559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg nlmsg_free(freqs); 1773563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return err; 1783563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 1793563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 180857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmannstatic void tab_on_first(bool *first) 181857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 182857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (!*first) 183857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t"); 184857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann else 185857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann *first = false; 186857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 187857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 18883b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_ssid(const uint8_t type, uint8_t len, const uint8_t *data) 1893563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 19083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" "); 191748f8489caad151e01922f0ba26847aedfd36dafJohannes Berg print_ssid_escaped(len, data); 1923563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 1933563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 1943563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 195ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg#define BSS_MEMBERSHIP_SELECTOR_VHT_PHY 126 1961fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter#define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127 1971fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter 19883b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_supprates(const uint8_t type, uint8_t len, const uint8_t *data) 1993563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 2003563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int i; 2013563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 20283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" "); 2033563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 20483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg for (i = 0; i < len; i++) { 2053563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int r = data[i] & 0x7f; 2061fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter 207ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg if (r == BSS_MEMBERSHIP_SELECTOR_VHT_PHY && data[i] & 0x80) 208ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("VHT"); 209ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg else if (r == BSS_MEMBERSHIP_SELECTOR_HT_PHY && data[i] & 0x80) 2101fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter printf("HT"); 2111fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter else 2121fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter printf("%d.%d", r/2, 5*(r&1)); 2131fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter 2141fd19c397234b604a553b8156bd46baa88404aabChristian Lamparter printf("%s ", data[i] & 0x80 ? "*" : ""); 2153563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 2163563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 2173563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 2183563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 21983b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_ds(const uint8_t type, uint8_t len, const uint8_t *data) 2203563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 22183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" channel %d\n", data[0]); 2223563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 2233563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 2242b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguezstatic const char *country_env_str(char environment) 225b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann{ 2262b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez switch (environment) { 227b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann case 'I': 2282b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "Indoor only"; 229b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann case 'O': 2302b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "Outdoor only"; 231b6c0d6340dbc969b4c53f583775e7c49b440c403Johannes Berg case ' ': 2322b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "Indoor/Outdoor"; 233b6c0d6340dbc969b4c53f583775e7c49b440c403Johannes Berg default: 2342b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return "bogus"; 235b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann } 2362b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez} 2372b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2382b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguezstatic void print_country(const uint8_t type, uint8_t len, const uint8_t *data) 2392b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez{ 2402b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf(" %.*s", 2, data); 2412b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2422b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf("\tEnvironment: %s\n", country_env_str(data[2])); 2432b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2442b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez data += 3; 2452b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez len -= 3; 2462b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2472b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez if (len < 3) { 2482b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf("\t\tNo country IE triplets present\n"); 2492b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return; 2502b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez } 2512b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2522b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez while (len >= 3) { 2532b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez int end_channel; 25472725719af644b0a3a673cc9f1c376a2c0ef62e2Johannes Berg union ieee80211_country_ie_triplet *triplet = (void *) data; 2552b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2562b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez if (triplet->ext.reg_extension_id >= IEEE80211_COUNTRY_EXTENSION_ID) { 2572b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez printf("\t\tExtension ID: %d Regulatory Class: %d Coverage class: %d (up to %dm)\n", 2582b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.reg_extension_id, 2592b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.reg_class, 2602b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.coverage_class, 2612b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez triplet->ext.coverage_class * 450); 2622b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2632b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez data += 3; 2642b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez len -= 3; 2652b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez continue; 2662b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez } 2672b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2682b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez /* 2 GHz */ 2692b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez if (triplet->chans.first_channel <= 14) 2702b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez end_channel = triplet->chans.first_channel + (triplet->chans.num_channels - 1); 2712b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez else 2722b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez end_channel = triplet->chans.first_channel + (4 * (triplet->chans.num_channels - 1)); 2732b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 274a9859d30ea1c19314d2d08285af9123714a4e6beLuis R. Rodriguez printf("\t\tChannels [%d - %d] @ %d dBm\n", triplet->chans.first_channel, end_channel, triplet->chans.max_power); 2752b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2762b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez data += 3; 2772b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez len -= 3; 2782b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez } 2792b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez 2802b690f0aba9d7365ad824ea5f932de8f2a80ba76Luis R. Rodriguez return; 281b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann} 282b7e8fa37d03cb17e69cdcf37041ffdc299c693dfMarcel Holtmann 283d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmannstatic void print_powerconstraint(const uint8_t type, uint8_t len, const uint8_t *data) 284d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann{ 285d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann printf(" %d dB\n", data[0]); 286d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann} 287d1563a1b2d6e43fb12aeaa764c952cd2108b6862Marcel Holtmann 28883b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_erp(const uint8_t type, uint8_t len, const uint8_t *data) 289fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann{ 290fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] == 0x00) 29183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <no flags>"); 292fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] & 0x01) 293fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf(" NonERP_Present"); 294fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] & 0x02) 295fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf(" Use_Protection"); 296fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann if (data[0] & 0x04) 297fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf(" Barker_Preamble_Mode"); 298fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann printf("\n"); 299fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann} 300fc4d1484a18a2f67df901126123177ea94e8037bMarcel Holtmann 30183b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_cipher(const uint8_t *data) 302857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 3033bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg if (memcmp(data, ms_oui, 3) == 0) { 304857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 305510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 0: 306857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("Use group cipher suite"); 307857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 308510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 309857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-40"); 310857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 311510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 312857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("TKIP"); 313857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 314510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 4: 315857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("CCMP"); 316857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 317510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 5: 318857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-104"); 319857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 320857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 321332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 3225594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 323857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 324857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 325857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else if (memcmp(data, ieee80211_oui, 3) == 0) { 326857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 327510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 0: 328857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("Use group cipher suite"); 329857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 330510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 331857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-40"); 332857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 333510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 334857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("TKIP"); 335857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 336510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 4: 337857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("CCMP"); 338857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 339510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 5: 340857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("WEP-104"); 341857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 342510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 6: 343857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("AES-128-CMAC"); 344857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 345a8b3da9df8d15b857b13887feccdd05c46c7347eVladimir Kondratiev case 8: 346a8b3da9df8d15b857b13887feccdd05c46c7347eVladimir Kondratiev printf("GCMP"); 347a8b3da9df8d15b857b13887feccdd05c46c7347eVladimir Kondratiev break; 348857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 349332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 3505594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 351857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 352857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 353857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else 354332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 3555594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 356857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 357857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 35883b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_auth(const uint8_t *data) 359857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 3603bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg if (memcmp(data, ms_oui, 3) == 0) { 361857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 362510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 363857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("IEEE 802.1X"); 364857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 365510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 366857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("PSK"); 367857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 368857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 369332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 3705594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 371857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 372857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 373857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else if (memcmp(data, ieee80211_oui, 3) == 0) { 374857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann switch (data[3]) { 375510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 1: 376857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("IEEE 802.1X"); 377857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 378510e0e2faa8947de1bc97fea541d0182afeac0b7Johannes Berg case 2: 379857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("PSK"); 380857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 3810fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 3: 3820fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("FT/IEEE 802.1X"); 3830fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 3840fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 4: 3850fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("FT/PSK"); 3860fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 3870fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 5: 3880fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("IEEE 802.1X/SHA-256"); 3890fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 3900fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg case 6: 3910fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg printf("PSK/SHA-256"); 3920fe1c41537d2e7fbfcf70360198eddbb13bf7d07Johannes Berg break; 393857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann default: 394332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 3955594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 396857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann break; 397857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 398857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } else 399332769c689e75f372bdae8ade290433b31eebc3eJohannes Berg printf("%.02x-%.02x-%.02x:%d", 4005594fd2301775e7795899ed4ed3b8fff82551734Johannes Berg data[0], data[1] ,data[2], data[3]); 401857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 402857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 40383b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_rsn_ie(const char *defcipher, const char *defauth, 40483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg uint8_t len, const uint8_t *data) 405857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 406857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann bool first = true; 407857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann __u16 version, count, capa; 408857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann int i; 409857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 410857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann version = data[0] + (data[1] << 8); 411857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 412857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Version: %d\n", version); 413857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 414857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann data += 2; 415857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann len -= 2; 416857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 417857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (len < 4) { 418857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 419857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Group cipher: %s\n", defcipher); 420857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Pairwise ciphers: %s\n", defcipher); 421857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann return; 422857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 423857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 424857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 425857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Group cipher: "); 426857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann print_cipher(data); 427857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\n"); 428857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 429857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann data += 4; 430857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann len -= 4; 431857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 432857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (len < 2) { 433857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 434857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Pairwise ciphers: %s\n", defcipher); 435857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann return; 436857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 437857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 438857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann count = data[0] | (data[1] << 8); 43931d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann if (2 + (count * 4) > len) 44031d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann goto invalid; 44131d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann 442857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 443857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Pairwise ciphers:"); 44431d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann for (i = 0; i < count; i++) { 445857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf(" "); 446857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann print_cipher(data + 2 + (i * 4)); 447857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 448857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\n"); 449857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 450857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann data += 2 + (count * 4); 451857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann len -= 2 + (count * 4); 452857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 453857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann if (len < 2) { 454857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 455857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Authentication suites: %s\n", defauth); 456857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann return; 457857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 458857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 459857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann count = data[0] | (data[1] << 8); 46031d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann if (2 + (count * 4) > len) 46131d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann goto invalid; 46231d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann 463857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann tab_on_first(&first); 464857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\t * Authentication suites:"); 46583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg for (i = 0; i < count; i++) { 466857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf(" "); 467857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann print_auth(data + 2 + (i * 4)); 468857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann } 469857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann printf("\n"); 470857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 471857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann data += 2 + (count * 4); 472857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann len -= 2 + (count * 4); 473857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 4746a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg if (len >= 2) { 4756a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg capa = data[0] | (data[1] << 8); 4766a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg tab_on_first(&first); 477cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf("\t * Capabilities:"); 478cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0001) 479cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" PreAuth"); 480cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0002) 481cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" NoPairwise"); 482cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg switch ((capa & 0x000c) >> 2) { 483cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 0: 484cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 485cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 1: 486cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 2-PTKSA-RC"); 487cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 488cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 2: 489cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 4-PTKSA-RC"); 490cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 491cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 3: 492cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 16-PTKSA-RC"); 493cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 494cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg } 495cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg switch ((capa & 0x0030) >> 4) { 496cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 0: 497cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 498cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 1: 499cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 2-GTKSA-RC"); 500cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 501cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 2: 502cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 4-GTKSA-RC"); 503cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 504cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg case 3: 505cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" 16-GTKSA-RC"); 506cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg break; 507cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg } 508cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0040) 509cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" MFP-required"); 510cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0080) 511cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" MFP-capable"); 512cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0200) 513cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" Peerkey-enabled"); 514cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0400) 515cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" SPP-AMSDU-capable"); 516cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg if (capa & 0x0800) 517cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" SPP-AMSDU-required"); 518cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg printf(" (0x%.4x)\n", capa); 5196a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg data += 2; 5206a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg len -= 2; 5216a4f24e80e5e6d85bfd1c4d66b476b86e5fa35d3Johannes Berg } 52231d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann 5235ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg if (len >= 2) { 5245ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg int pmkid_count = data[0] | (data[1] << 8); 5255ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg 5265ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg if (len >= 2 + 16 * pmkid_count) { 5275ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg tab_on_first(&first); 5285ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg printf("\t * %d PMKIDs\n", pmkid_count); 5295ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg /* not printing PMKID values */ 5305ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg data += 2 + 16 * pmkid_count; 5315ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg len -= 2 + 16 * pmkid_count; 5325ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg } else 5335ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg goto invalid; 5345ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg } 5355ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg 5365ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg if (len >= 4) { 5375ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg tab_on_first(&first); 5385ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg printf("\t * Group mgmt cipher suite: "); 5395ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg print_cipher(data); 5405ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg printf("\n"); 5415ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg data += 4; 5425ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg len -= 4; 5435ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg } 5445ba3f5236af15d045c3278194fd198a1addd3868Johannes Berg 545cadbe89ab7b00d146a34419145bc8c0db948f977Johannes Berg invalid: 54631d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann if (len != 0) { 54731d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann printf("\t\t * bogus tail data (%d):", len); 54831d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann while (len) { 54931d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann printf(" %.2x", *data); 55031d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann data++; 55131d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann len--; 55231d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann } 55331d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann printf("\n"); 55431d477fb191d14e3860d2d0b162d33ea87237bdbMarcel Holtmann } 555857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 556857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 55783b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_rsn(const uint8_t type, uint8_t len, const uint8_t *data) 558857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann{ 55983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_rsn_ie("CCMP", "IEEE 802.1X", len, data); 560857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann} 561857d966ea902a23112697c93ec2dc3b919757c59Marcel Holtmann 5620c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguezstatic void print_ht_capa(const uint8_t type, uint8_t len, const uint8_t *data) 5630c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguez{ 564357c1a5df13f722027977a915cfd16a38bba3966Luis R. Rodriguez printf("\n"); 5657ddfb67953809357249e5a6f4293cebf59a4ad9bJohannes Berg print_ht_capability(data[0] | (data[1] << 8)); 5667ddfb67953809357249e5a6f4293cebf59a4ad9bJohannes Berg print_ampdu_length(data[2] & 3); 567c79c746440d22401d0aa8522bed2820f60eed2cdChristian Lamparter print_ampdu_spacing((data[2] >> 2) & 7); 5687ddfb67953809357249e5a6f4293cebf59a4ad9bJohannes Berg print_ht_mcs(data + 3); 5690c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguez} 5700c445c24c51e634af042fd10aa87e558a53699daLuis R. Rodriguez 57129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic const char *ht_secondary_offset[4] = { 57229f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "no secondary", 57329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "above", 57429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "[reserved!]", 57529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg "below", 57629f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg}; 57729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 578be7602fb865fcef72924c926729650c0db9cf254Johannes Bergstatic void print_ht_op(const uint8_t type, uint8_t len, const uint8_t *data) 579be7602fb865fcef72924c926729650c0db9cf254Johannes Berg{ 580be7602fb865fcef72924c926729650c0db9cf254Johannes Berg static const char *protection[4] = { 581be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "no", 582be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "nonmember", 583be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "20 MHz", 584be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "non-HT mixed", 585be7602fb865fcef72924c926729650c0db9cf254Johannes Berg }; 586be7602fb865fcef72924c926729650c0db9cf254Johannes Berg static const char *sta_chan_width[2] = { 587be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "20 MHz", 588be7602fb865fcef72924c926729650c0db9cf254Johannes Berg "any", 589be7602fb865fcef72924c926729650c0db9cf254Johannes Berg }; 590be7602fb865fcef72924c926729650c0db9cf254Johannes Berg 591be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\n"); 592be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * primary channel: %d\n", data[0]); 593be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * secondary channel offset: %s\n", 59429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg ht_secondary_offset[data[1] & 0x3]); 595be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * STA channel width: %s\n", sta_chan_width[(data[1] & 0x4)>>2]); 596be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * RIFS: %d\n", (data[1] & 0x8)>>3); 597be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * HT protection: %s\n", protection[data[2] & 0x3]); 598be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * non-GF present: %d\n", (data[2] & 0x4) >> 2); 599be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * OBSS non-GF present: %d\n", (data[2] & 0x10) >> 4); 600be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * dual beacon: %d\n", (data[4] & 0x40) >> 6); 601be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * dual CTS protection: %d\n", (data[4] & 0x80) >> 7); 602be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * STBC beacon: %d\n", data[5] & 0x1); 603be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * L-SIG TXOP Prot: %d\n", (data[5] & 0x2) >> 1); 604be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * PCO active: %d\n", (data[5] & 0x4) >> 2); 605be7602fb865fcef72924c926729650c0db9cf254Johannes Berg printf("\t\t * PCO phase: %d\n", (data[5] & 0x8) >> 3); 606be7602fb865fcef72924c926729650c0db9cf254Johannes Berg} 607be7602fb865fcef72924c926729650c0db9cf254Johannes Berg 60883b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_capabilities(const uint8_t type, uint8_t len, const uint8_t *data) 6099b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann{ 61031d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg int i, base, bit; 61131d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg bool first = true; 61231d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 61331d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 61431d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg for (i = 0; i < len; i++) { 61531d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg base = i * 8; 61631d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 61731d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg for (bit = 0; bit < 8; bit++) { 61831d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg if (!(data[i] & (1 << bit))) 61931d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg continue; 62031d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 62131d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg if (!first) 62231d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg printf(","); 62331d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg else 62431d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg first = false; 62531d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg 62670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg#define CAPA(bit, name) case bit: printf(" " name); break 62770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg 62831d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg switch (bit + base) { 62970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(0, "HT Information Exchange Supported"); 63070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(1, "reserved (On-demand Beacon)"); 63170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(2, "Extended Channel Switching"); 63270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(3, "reserved (Wave Indication)"); 63370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(4, "PSMP Capability"); 63470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(5, "reserved (Service Interval Granularity)"); 63570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(6, "S-PSMP Capability"); 63670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(7, "Event"); 63770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(8, "Diagnostics"); 63870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(9, "Multicast Diagnostics"); 63970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(10, "Location Tracking"); 64070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(11, "FMS"); 64170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(12, "Proxy ARP Service"); 64270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(13, "Collocated Interference Reporting"); 64370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(14, "Civic Location"); 64470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(15, "Geospatial Location"); 64570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(16, "TFS"); 64670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(17, "WNM-Sleep Mode"); 64770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(18, "TIM Broadcast"); 64870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(19, "BSS Transition"); 64970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(20, "QoS Traffic Capability"); 65070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(21, "AC Station Count"); 65170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(22, "Multiple BSSID"); 65270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(23, "Timing Measurement"); 65370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(24, "Channel Usage"); 65470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(25, "SSID List"); 65570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(26, "DMS"); 65670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(27, "UTC TSF Offset"); 65770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(28, "TDLS Peer U-APSD Buffer STA Support"); 65870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(29, "TDLS Peer PSM Support"); 65970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(30, "TDLS channel switching"); 66070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(31, "Interworking"); 66170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(32, "QoS Map"); 66270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(33, "EBR"); 66370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(34, "SSPN Interface"); 66470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(35, "Reserved"); 66570c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(36, "MSGCF Capability"); 66670c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(37, "TDLS Support"); 66770c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(38, "TDLS Prohibited"); 66870c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(39, "TDLS Channel Switching Prohibited"); 66970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(40, "Reject Unadmitted Frame"); 67070c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(44, "Identifier Location"); 67170c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(45, "U-APSD Coexistence"); 67270c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(46, "WNM-Notification"); 67370c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(47, "Reserved"); 67470c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg CAPA(48, "UTF-8 SSID"); 67531d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg default: 67631d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg printf(" %d", bit); 67731d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg break; 67831d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg } 67970c649d290f8e7de7e88000e45e0982b876dd84fJohannes Berg#undef CAPA 68031d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg } 68131d2d2599ee4ece941596e00e3bde3a15a514781Johannes Berg } 6829b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann 6839b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann printf("\n"); 6849b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann} 6859b880b00e4a3b4a9befbdf55f90c89568781cf73Marcel Holtmann 686575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinenstatic void print_tim(const uint8_t type, uint8_t len, const uint8_t *data) 687575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen{ 688575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf(" DTIM Count %u DTIM Period %u Bitmap Control 0x%x " 689575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen "Bitmap[0] 0x%x", 690575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen data[0], data[1], data[2], data[3]); 691575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen if (len - 4) 692575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf(" (+ %u octet%s)", len - 4, len - 4 == 1 ? "" : "s"); 693575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf("\n"); 694575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen} 695575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen 69654eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Bergstatic void print_vht_capa(const uint8_t type, uint8_t len, const uint8_t *data) 69754eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg{ 69854eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg printf("\n"); 69954eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg print_vht_info(data[0] | (data[1] << 8) | 70054eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg (data[2] << 16) | (data[3] << 24), 70154eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg data + 4); 70254eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg} 70354eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg 704ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Bergstatic void print_vht_oper(const uint8_t type, uint8_t len, const uint8_t *data) 705ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg{ 706ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg const char *chandwidths[] = { 707ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [0] = "20 or 40 MHz", 708ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [1] = "80 MHz", 709ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [3] = "80+80 MHz", 710ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [2] = "160 MHz", 711ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg }; 712ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg 713ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\n"); 714ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * channel width: %d (%s)\n", data[0], 715ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg data[0] < ARRAY_SIZE(chandwidths) ? chandwidths[data[0]] : "unknown"); 716ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * center freq segment 1: %d\n", data[1]); 717ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * center freq segment 2: %d\n", data[2]); 718ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg printf("\t\t * VHT basic MCS set: 0x%.2x%.2x\n", data[4], data[3]); 719ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg} 720ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg 72129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic void print_obss_scan_params(const uint8_t type, uint8_t len, const uint8_t *data) 72229f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg{ 72329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\n"); 72429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * passive dwell: %d TUs\n", (data[1] << 8) | data[0]); 72529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * active dwell: %d TUs\n", (data[3] << 8) | data[2]); 72629f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * channel width trigger scan interval: %d s\n", (data[5] << 8) | data[4]); 72729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * scan passive total per channel: %d TUs\n", (data[7] << 8) | data[6]); 72829f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * scan active total per channel: %d TUs\n", (data[9] << 8) | data[8]); 72929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * BSS width channel transition delay factor: %d\n", (data[11] << 8) | data[10]); 73029f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * OBSS Scan Activity Threshold: %d.%02d %%\n", 73129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg ((data[13] << 8) | data[12]) / 100, ((data[13] << 8) | data[12]) % 100); 73229f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg} 73329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 73429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic void print_secchan_offs(const uint8_t type, uint8_t len, const uint8_t *data) 73529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg{ 73629f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg if (data[0] < ARRAY_SIZE(ht_secondary_offset)) 73729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf(" %s (%d)\n", ht_secondary_offset[data[0]], data[0]); 73829f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg else 73929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf(" %d\n", data[0]); 74029f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg} 74129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 74229f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Bergstatic void print_bss_load(const uint8_t type, uint8_t len, const uint8_t *data) 74329f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg{ 74429f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\n"); 74529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * station count: %d\n", (data[1] << 8) | data[0]); 74629f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * channel utilisation: %d/255\n", data[2]); 74729f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg printf("\t\t * available admission capacity: %d [*32us]\n", (data[4] << 8) | data[3]); 74829f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg} 74929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg 75083b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstruct ie_print { 75183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg const char *name; 75283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg void (*print)(const uint8_t type, uint8_t len, const uint8_t *data); 75383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg uint8_t minlen, maxlen; 754febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg uint8_t flags; 755764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg}; 756764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 75783b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_ie(const struct ie_print *p, const uint8_t type, 75883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg uint8_t len, const uint8_t *data) 7594673a894dae2780e395204eab01af4d40220b9f5Johannes Berg{ 76083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg int i; 76183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 76283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg if (!p->print) 76383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg return; 76483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 76583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf("\t%s:", p->name); 76683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg if (len < p->minlen || len > p->maxlen) { 76783b4934c612b84c28a656d496bea056e37fccb99Johannes Berg if (len > 1) { 76883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <invalid: %d bytes:", len); 76983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg for (i = 0; i < len; i++) 77083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" %.02x", data[i]); 77183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(">\n"); 77283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg } else if (len) 77383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <invalid: 1 byte: %.02x>\n", data[0]); 77483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg else 77583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" <invalid: no data>\n"); 77683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg return; 77783b4934c612b84c28a656d496bea056e37fccb99Johannes Berg } 77883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 77983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg p->print(type, len, data); 78083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg} 78183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 78283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg#define PRINT_IGN { \ 78383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .name = "IGNORE", \ 78483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .print = NULL, \ 78583b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .minlen = 0, \ 78683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg .maxlen = 255, \ 7874673a894dae2780e395204eab01af4d40220b9f5Johannes Berg} 7884673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 78983b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic const struct ie_print ieprinters[] = { 790febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [0] = { "SSID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), }, 791febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [1] = { "Supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, 792014d581a9292b35d54e76793ec216ba15c2ec69cJohannes Berg [3] = { "DS Parameter set", print_ds, 1, 1, BIT(PRINT_SCAN), }, 793575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen [5] = { "TIM", print_tim, 4, 255, BIT(PRINT_SCAN), }, 794febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [7] = { "Country", print_country, 3, 255, BIT(PRINT_SCAN), }, 79529f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg [11] = { "BSS Load", print_bss_load, 5, 5, BIT(PRINT_SCAN), }, 796febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [32] = { "Power constraint", print_powerconstraint, 1, 1, BIT(PRINT_SCAN), }, 797febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [42] = { "ERP", print_erp, 1, 255, BIT(PRINT_SCAN), }, 798a2e61861abd4037ab29ddf4382c5d2f925c1be66Johannes Berg [45] = { "HT capabilities", print_ht_capa, 26, 26, BIT(PRINT_SCAN), }, 79929f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg [74] = { "Overlapping BSS scan params", print_obss_scan_params, 14, 255, BIT(PRINT_SCAN), }, 800be7602fb865fcef72924c926729650c0db9cf254Johannes Berg [61] = { "HT operation", print_ht_op, 22, 22, BIT(PRINT_SCAN), }, 80129f7579e27e0027ae663a05b3072dbd07f30b78aJohannes Berg [62] = { "Secondary Channel Offset", print_secchan_offs, 1, 1, BIT(PRINT_SCAN), }, 80254eb1613e695d72a71d7210b238a30e0ab2d5a3fJohannes Berg [191] = { "VHT capabilities", print_vht_capa, 12, 255, BIT(PRINT_SCAN), }, 803ca1599346b55aa4d9ca8ca85ec59036f15a8f686Johannes Berg [192] = { "VHT operation", print_vht_oper, 5, 255, BIT(PRINT_SCAN), }, 804febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [48] = { "RSN", print_rsn, 2, 255, BIT(PRINT_SCAN), }, 805febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [50] = { "Extended supported rates", print_supprates, 0, 255, BIT(PRINT_SCAN), }, 806720583e9a9fce9b760b8794118e7a5d54cb428f5Chun-Yeow Yeoh [114] = { "MESH ID", print_ssid, 0, 32, BIT(PRINT_SCAN) | BIT(PRINT_LINK), }, 807febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [127] = { "Extended capabilities", print_capabilities, 0, 255, BIT(PRINT_SCAN), }, 80883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg}; 80983b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 81083b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_wifi_wpa(const uint8_t type, uint8_t len, const uint8_t *data) 81183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg{ 81283b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_rsn_ie("TKIP", "IEEE 802.1X", len, data); 81383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg} 81483b4934c612b84c28a656d496bea056e37fccb99Johannes Berg 8151cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Bergstatic bool print_wifi_wmm_param(const uint8_t *data, uint8_t len) 8161cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg{ 8171cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg int i; 8181cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg static const char *aci_tbl[] = { "BE", "BK", "VI", "VO" }; 8191cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8201cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (len < 19) 8211cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg goto invalid; 8221cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8231cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (data[0] != 1) { 824cee4fe2039a01208fbbae45dda1c7d3bbfbe5f36Johannes Berg printf("Parameter: not version 1: "); 8251cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return false; 8261cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg } 8271cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 82889ea706f0a177ff6e78b207bc08143d2d149dd08Marcel Holtmann printf("\t * Parameter version 1"); 8291cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8301cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg data++; 8311cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8321cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (data[0] & 0x80) 83389ea706f0a177ff6e78b207bc08143d2d149dd08Marcel Holtmann printf("\n\t\t * u-APSD"); 8341cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8351cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg data += 2; 8361cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8371cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg for (i = 0; i < 4; i++) { 83889ea706f0a177ff6e78b207bc08143d2d149dd08Marcel Holtmann printf("\n\t\t * %s:", aci_tbl[(data[0] >> 5) & 3]); 83987181516675a6d6a2ce0d6ce53b4ba601b62d427Yoni Divinsky if (data[0] & 0x10) 8401cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf(" acm"); 8411cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf(" CW %d-%d", (1 << (data[1] & 0xf)) - 1, 8421cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg (1 << (data[1] >> 4)) - 1); 843a2a4c265af2e322e245b4fc1962d93a38da61f7aJohannes Berg printf(", AIFSN %d", data[0] & 0xf); 8441cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (data[2] | data[3]) 845cee4fe2039a01208fbbae45dda1c7d3bbfbe5f36Johannes Berg printf(", TXOP %d usec", (data[2] + (data[3] << 8)) * 32); 8461cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg data += 4; 8471cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg } 8481cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8491cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf("\n"); 8501cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return true; 8511cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 8521cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg invalid: 8531cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf("invalid: "); 8541cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return false; 8551cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg} 8561cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg 85783b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_wifi_wmm(const uint8_t type, uint8_t len, const uint8_t *data) 8586ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann{ 8596ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann int i; 8606ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann 8616ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann switch (data[0]) { 8626ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann case 0x00: 86383b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" information:"); 8646ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann break; 8656ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann case 0x01: 8661cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg if (print_wifi_wmm_param(data + 1, len - 1)) 8671cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg return; 8686ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann break; 8696ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann default: 87083b4934c612b84c28a656d496bea056e37fccb99Johannes Berg printf(" type %d:", data[0]); 8716ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann break; 8726ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann } 8736ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann 8741cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg for(i = 1; i < len; i++) 8751cab57eba4e42cc1dd26dd213807f58f98c71167Johannes Berg printf(" %.02x", data[i]); 8766ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann printf("\n"); 8776ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann} 8786ff0c93ad7c73c16892dd261612a71255fdbf978Marcel Holtmann 879a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinenstatic const char * wifi_wps_dev_passwd_id(uint16_t id) 880a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen{ 881a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen switch (id) { 882a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0: 883a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Default (PIN)"; 884a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 1: 885a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "User-specified"; 886a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 2: 887a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Machine-specified"; 888a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 3: 889a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Rekey"; 890a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 4: 891a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "PushButton"; 892a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 5: 893a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "Registrar-specified"; 894a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen default: 895a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen return "??"; 896a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 897a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen} 898a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen 89983b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic void print_wifi_wps(const uint8_t type, uint8_t len, const uint8_t *data) 9004673a894dae2780e395204eab01af4d40220b9f5Johannes Berg{ 9014673a894dae2780e395204eab01af4d40220b9f5Johannes Berg bool first = true; 9024673a894dae2780e395204eab01af4d40220b9f5Johannes Berg __u16 subtype, sublen; 9034673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 9044673a894dae2780e395204eab01af4d40220b9f5Johannes Berg while (len >= 4) { 9054673a894dae2780e395204eab01af4d40220b9f5Johannes Berg subtype = (data[0] << 8) + data[1]; 9064673a894dae2780e395204eab01af4d40220b9f5Johannes Berg sublen = (data[2] << 8) + data[3]; 9074673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (sublen > len) 9084673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 9094673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 9104673a894dae2780e395204eab01af4d40220b9f5Johannes Berg switch (subtype) { 9114673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x104a: 9124673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 913dffc6750fec6d97a4fc55a687836cd6437be76e2Johannes Berg printf("\t * Version: %d.%d\n", data[4] >> 4, data[4] & 0xF); 9144673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 9154673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x1011: 9164673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 9174673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t * Device name: %.*s\n", sublen, data + 4); 9184673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 919a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1012: { 920a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen uint16_t id; 921a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 922a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen if (sublen != 2) { 923a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Device Password ID: (invalid " 924a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen "length %d)\n", sublen); 925a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 926a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 927a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen id = data[4] << 8 | data[5]; 928a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Device Password ID: %u (%s)\n", 929a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen id, wifi_wps_dev_passwd_id(id)); 930a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 931a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 9324673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x1021: 9334673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 9344673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t * Manufacturer: %.*s\n", sublen, data + 4); 9354673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 9364673a894dae2780e395204eab01af4d40220b9f5Johannes Berg case 0x1023: 9374673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 9384673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t * Model: %.*s\n", sublen, data + 4); 9394673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 940a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1024: 941a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 942a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Model Number: %.*s\n", sublen, data + 4); 943a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 944a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x103b: { 945a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 946a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 947a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Response Type: %d%s\n", 948a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val, val == 3 ? " (AP)" : ""); 949a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 950a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 951a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x103c: { 952a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 953a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 954a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * RF Bands: 0x%x\n", val); 955a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 956a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 957a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1041: { 958a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 959a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 960a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Selected Registrar: 0x%x\n", val); 961a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 962a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 963a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1042: 964a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 965a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Serial Number: %.*s\n", sublen, data + 4); 966a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 967a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1044: { 968a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen __u8 val = data[4]; 969a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 970a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Wi-Fi Protected Setup State: %d%s%s\n", 971a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val, 972a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val == 1 ? " (Unconfigured)" : "", 973a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen val == 2 ? " (Configured)" : ""); 974a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 975a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 97609fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg case 0x1047: 97709fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg tab_on_first(&first); 97809fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg printf("\t * UUID: "); 97909fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg if (sublen != 16) { 98009fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg printf("(invalid, length=%d)\n", sublen); 98109fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg break; 98209fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg } 98309fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg printf("%02x%02x%02x%02x-%02x%02x-%02x%02x-" 98409fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg "%02x%02x-%02x%02x%02x%02x%02x%02x\n", 98509fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[4], data[5], data[6], data[7], 98609fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[8], data[9], data[10], data[11], 98709fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[12], data[13], data[14], data[15], 98809fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg data[16], data[17], data[18], data[19]); 98909fe09dc71e58b63ca9ba570cf6b24326ec9807aJohannes Berg break; 990a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1054: { 991a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen tab_on_first(&first); 992a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen if (sublen != 8) { 993a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Primary Device Type: (invalid " 994a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen "length %d)\n", sublen); 995a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 996a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 997a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * Primary Device Type: " 998a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen "%u-%02x%02x%02x%02x-%u\n", 999a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen data[4] << 8 | data[5], 1000a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen data[6], data[7], data[8], data[9], 1001a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen data[10] << 8 | data[11]); 1002a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen break; 1003a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen } 10047ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg case 0x1057: { 1005fe31a22e04f62839e8ba41e6fc9241abe64e07c2Johannes Berg __u8 val = data[4]; 10067ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg tab_on_first(&first); 1007fe31a22e04f62839e8ba41e6fc9241abe64e07c2Johannes Berg printf("\t * AP setup locked: 0x%.2x\n", val); 10087ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg break; 10097ee5a86565fcf11ea33356ae9b202bc0336e13d6Johannes Berg } 1010a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1008: 1011a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen case 0x1053: { 10124673a894dae2780e395204eab01af4d40220b9f5Johannes Berg __u16 meth = (data[4] << 8) + data[5]; 10134673a894dae2780e395204eab01af4d40220b9f5Johannes Berg bool comma = false; 10144673a894dae2780e395204eab01af4d40220b9f5Johannes Berg tab_on_first(&first); 1015a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen printf("\t * %sConfig methods:", 1016a6816965269a84edf063b0e04255cd64405bc9a3Jouni Malinen subtype == 0x1053 ? "Selected Registrar ": ""); 10174673a894dae2780e395204eab01af4d40220b9f5Johannes Berg#define T(bit, name) do { \ 10184673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (meth & (1<<bit)) { \ 10194673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (comma) \ 10204673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(","); \ 10214673a894dae2780e395204eab01af4d40220b9f5Johannes Berg comma = true; \ 10224673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(" " name); \ 10234673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } } while (0) 10244673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(0, "USB"); 10254673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(1, "Ethernet"); 10264673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(2, "Label"); 10274673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(3, "Display"); 10284673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(4, "Ext. NFC"); 10294673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(5, "Int. NFC"); 10304673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(6, "NFC Intf."); 10314673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(7, "PBC"); 10324673a894dae2780e395204eab01af4d40220b9f5Johannes Berg T(8, "Keypad"); 10334673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\n"); 10344673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 10354673a894dae2780e395204eab01af4d40220b9f5Johannes Berg#undef T 10364673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 10372650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg default: { 10382650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg const __u8 *subdata = data + 4; 10392650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg __u16 tmplen = sublen; 10402650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg 10412650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg tab_on_first(&first); 10422650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg printf("\t * Unknown TLV (%#.4x, %d bytes):", 10432650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg subtype, tmplen); 10442650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg while (tmplen) { 10452650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg printf(" %.2x", *subdata); 10462650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg subdata++; 10472650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg tmplen--; 10482650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg } 10492650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg printf("\n"); 10504673a894dae2780e395204eab01af4d40220b9f5Johannes Berg break; 10514673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 10522650d46b45f727ca8ee49faa4c6bd65da2550c4eJohannes Berg } 10534673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 10544673a894dae2780e395204eab01af4d40220b9f5Johannes Berg data += sublen + 4; 10554673a894dae2780e395204eab01af4d40220b9f5Johannes Berg len -= sublen + 4; 10564673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 10574673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 10584673a894dae2780e395204eab01af4d40220b9f5Johannes Berg if (len != 0) { 10594673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\t\t * bogus tail data (%d):", len); 10604673a894dae2780e395204eab01af4d40220b9f5Johannes Berg while (len) { 10614673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(" %.2x", *data); 10624673a894dae2780e395204eab01af4d40220b9f5Johannes Berg data++; 10634673a894dae2780e395204eab01af4d40220b9f5Johannes Berg len--; 10644673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 10654673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\n"); 10664673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 10674673a894dae2780e395204eab01af4d40220b9f5Johannes Berg} 10684673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 106983b4934c612b84c28a656d496bea056e37fccb99Johannes Bergstatic const struct ie_print wifiprinters[] = { 1070febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [1] = { "WPA", print_wifi_wpa, 2, 255, BIT(PRINT_SCAN), }, 1071febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [2] = { "WMM", print_wifi_wmm, 1, 255, BIT(PRINT_SCAN), }, 1072febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg [4] = { "WPS", print_wifi_wps, 0, 255, BIT(PRINT_SCAN), }, 10734673a894dae2780e395204eab01af4d40220b9f5Johannes Berg}; 10744673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 10759a22374a56b394000cfb98acb649355f76beb3a3Johannes Bergstatic inline void print_p2p(const uint8_t type, uint8_t len, const uint8_t *data) 10769a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg{ 10779a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg bool first = true; 10789a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg __u8 subtype; 10799a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg __u16 sublen; 10809a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 10819a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg while (len >= 3) { 10829a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg subtype = data[0]; 10839a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg sublen = (data[2] << 8) + data[1]; 10849a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 10859a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (sublen > len - 3) 10869a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 10879a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 10889a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg switch (subtype) { 10899a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x02: /* capability */ 10909a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tab_on_first(&first); 10919a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (sublen < 2) { 10929a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * malformed capability\n"); 10939a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 10949a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 10959a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * Group capa: 0x%.2x, Device capa: 0x%.2x\n", 10969a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg data[3], data[4]); 10979a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 10989a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0d: /* device info */ 10999a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (sublen < 6 + 2 + 8 + 1) { 11009a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * malformed device info\n"); 11019a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 11029a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11039a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg /* fall through for now */ 11049a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x00: /* status */ 11059a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x01: /* minor reason */ 11069a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x03: /* device ID */ 11079a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x04: /* GO intent */ 11089a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x05: /* configuration timeout */ 11099a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x06: /* listen channel */ 11109a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x07: /* group BSSID */ 11119a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x08: /* ext listen timing */ 11129a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x09: /* intended interface address */ 11139a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0a: /* manageability */ 11149a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0b: /* channel list */ 11159a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0c: /* NoA */ 11169a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0e: /* group info */ 11179a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x0f: /* group ID */ 11189a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x10: /* interface */ 11199a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x11: /* operating channel */ 11209a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0x12: /* invitation flags */ 11219a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg case 0xdd: /* vendor specific */ 11229a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg default: { 11239a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg const __u8 *subdata = data + 4; 11249a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg __u16 tmplen = sublen; 11259a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 11269a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tab_on_first(&first); 11279a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * Unknown TLV (%#.2x, %d bytes):", 11289a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg subtype, tmplen); 11299a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg while (tmplen) { 11309a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf(" %.2x", *subdata); 11319a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg subdata++; 11329a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tmplen--; 11339a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11349a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\n"); 11359a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg break; 11369a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11379a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11389a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 11399a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg data += sublen + 3; 11409a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg len -= sublen + 3; 11419a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11429a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 11439a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (len != 0) { 11449a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg tab_on_first(&first); 11459a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\t * bogus tail data (%d):", len); 11469a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg while (len) { 11479a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf(" %.2x", *data); 11489a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg data++; 11499a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg len--; 11509a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11519a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\n"); 11529a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11539a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg} 11549a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 11559a22374a56b394000cfb98acb649355f76beb3a3Johannes Bergstatic const struct ie_print wfa_printers[] = { 11569a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg [9] = { "P2P", print_p2p, 2, 255, BIT(PRINT_SCAN), }, 11579a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg}; 11589a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 1159764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Bergstatic void print_vendor(unsigned char len, unsigned char *data, 1160febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg bool unknown, enum print_ie_type ptype) 11613563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 11623563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int i; 11633563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1164fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg if (len < 3) { 11654673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\tVendor specific: <too short> data:"); 1166fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg for(i = 0; i < len; i++) 1167fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf(" %.02x", data[i]); 1168fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf("\n"); 1169fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg return; 1170fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg } 1171fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg 11723bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg if (len >= 4 && memcmp(data, ms_oui, 3) == 0) { 1173febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (data[3] < ARRAY_SIZE(wifiprinters) && 1174febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg wifiprinters[data[3]].name && 1175febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg wifiprinters[data[3]].flags & BIT(ptype)) { 117683b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_ie(&wifiprinters[data[3]], data[3], len - 4, data + 4); 117783b4934c612b84c28a656d496bea056e37fccb99Johannes Berg return; 117883b4934c612b84c28a656d496bea056e37fccb99Johannes Berg } 1179febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (!unknown) 11804673a894dae2780e395204eab01af4d40220b9f5Johannes Berg return; 11813bd60ef1276fc888fed699ee598b3b358d976f4cJohannes Berg printf("\tMS/WiFi %#.2x, data:", data[3]); 11824673a894dae2780e395204eab01af4d40220b9f5Johannes Berg for(i = 0; i < len - 4; i++) 11834673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf(" %.02x", data[i + 4]); 11844673a894dae2780e395204eab01af4d40220b9f5Johannes Berg printf("\n"); 11854673a894dae2780e395204eab01af4d40220b9f5Johannes Berg return; 11864673a894dae2780e395204eab01af4d40220b9f5Johannes Berg } 11874673a894dae2780e395204eab01af4d40220b9f5Johannes Berg 11889a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (len >= 4 && memcmp(data, wfa_oui, 3) == 0) { 11899a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (data[3] < ARRAY_SIZE(wfa_printers) && 11909a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg wfa_printers[data[3]].name && 11919a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg wfa_printers[data[3]].flags & BIT(ptype)) { 11929a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg print_ie(&wfa_printers[data[3]], data[3], len - 4, data + 4); 11939a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg return; 11949a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 11959a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg if (!unknown) 11969a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg return; 11979a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\tWFA %#.2x, data:", data[3]); 11989a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg for(i = 0; i < len - 4; i++) 11999a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf(" %.02x", data[i + 4]); 12009a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg printf("\n"); 12019a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg return; 12029a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg } 12039a22374a56b394000cfb98acb649355f76beb3a3Johannes Berg 1204febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (!unknown) 1205764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg return; 1206764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 1207fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf("\tVendor specific: OUI %.2x:%.2x:%.2x, data:", 12083563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg data[0], data[1], data[2]); 1209fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg for (i = 3; i < len; i++) 1210fbf80af54408799f7e3c03430b798759019dd79bJohannes Berg printf(" %.2x", data[i]); 12113563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 12123563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 12133563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1214febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Bergvoid print_ies(unsigned char *ie, int ielen, bool unknown, 1215febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg enum print_ie_type ptype) 12163563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 12173563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg while (ielen >= 2 && ielen >= ie[1]) { 1218febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg if (ie[0] < ARRAY_SIZE(ieprinters) && 1219febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg ieprinters[ie[0]].name && 1220febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg ieprinters[ie[0]].flags & BIT(ptype)) { 122183b4934c612b84c28a656d496bea056e37fccb99Johannes Berg print_ie(&ieprinters[ie[0]], ie[0], ie[1], ie + 2); 1222764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg } else if (ie[0] == 221 /* vendor */) { 1223febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg print_vendor(ie[1], ie + 2, unknown, ptype); 1224febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg } else if (unknown) { 12253563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg int i; 12263563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 12278086b7007d8a7f9d2bc22d154e26e9060f0e9676Johannes Berg printf("\tUnknown IE (%d):", ie[0]); 12283563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg for (i=0; i<ie[1]; i++) 12298086b7007d8a7f9d2bc22d154e26e9060f0e9676Johannes Berg printf(" %.2x", ie[2+i]); 12303563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\n"); 12313563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 12323563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg ielen -= ie[1] + 2; 12333563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg ie += ie[1] + 2; 12343563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 12353563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 12363563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 12372e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratievstatic void print_capa_dmg(__u16 capa) 12382e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev{ 12392e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev switch (capa & WLAN_CAPABILITY_DMG_TYPE_MASK) { 12402e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev case WLAN_CAPABILITY_DMG_TYPE_AP: 12412e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DMG_ESS"); 12422e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev break; 12432e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev case WLAN_CAPABILITY_DMG_TYPE_PBSS: 12442e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DMG_PCP"); 12452e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev break; 12462e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev case WLAN_CAPABILITY_DMG_TYPE_IBSS: 12472e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DMG_IBSS"); 12482e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev break; 12492e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev } 12502e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 12512e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_CBAP_ONLY) 12522e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CBAP_Only"); 12532e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_CBAP_SOURCE) 12542e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CBAP_Src"); 12552e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_PRIVACY) 12562e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" Privacy"); 12572e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_ECPAC) 12582e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ECPAC"); 12592e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_SPECTRUM_MGMT) 12602e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" SpectrumMgmt"); 12612e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DMG_RADIO_MEASURE) 12622e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" RadioMeasure"); 12632e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev} 12642e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 12652e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratievstatic void print_capa_non_dmg(__u16 capa) 12662e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev{ 12672e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_ESS) 12682e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ESS"); 12692e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_IBSS) 12702e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" IBSS"); 12712e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_CF_POLLABLE) 12722e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CfPollable"); 12732e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_CF_POLL_REQUEST) 12742e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" CfPollReq"); 12752e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_PRIVACY) 12762e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" Privacy"); 12772e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_SHORT_PREAMBLE) 12782e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ShortPreamble"); 12792e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_PBCC) 12802e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" PBCC"); 12812e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_CHANNEL_AGILITY) 12822e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ChannelAgility"); 12832e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_SPECTRUM_MGMT) 12842e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" SpectrumMgmt"); 12852e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_QOS) 12862e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" QoS"); 12872e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_SHORT_SLOT_TIME) 12882e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ShortSlotTime"); 12892e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_APSD) 12902e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" APSD"); 12912e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_RADIO_MEASURE) 12922e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" RadioMeasure"); 12932e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DSSS_OFDM) 12942e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DSSS-OFDM"); 12952e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_DEL_BACK) 12962e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" DelayedBACK"); 12972e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (capa & WLAN_CAPABILITY_IMM_BACK) 12982e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf(" ImmediateBACK"); 12992e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev} 13002e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev 13013563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Bergstatic int print_bss_handler(struct nl_msg *msg, void *arg) 13023563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 13033563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nlattr *tb[NL80211_ATTR_MAX + 1]; 13043563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); 13053563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nlattr *bss[NL80211_BSS_MAX + 1]; 13063563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg char mac_addr[20], dev[20]; 13073563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg static struct nla_policy bss_policy[NL80211_BSS_MAX + 1] = { 13083563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_TSF] = { .type = NLA_U64 }, 13093563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_FREQUENCY] = { .type = NLA_U32 }, 13103563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_BSSID] = { }, 13113563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_BEACON_INTERVAL] = { .type = NLA_U16 }, 13123563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_CAPABILITY] = { .type = NLA_U16 }, 13133563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg [NL80211_BSS_INFORMATION_ELEMENTS] = { }, 1314f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg [NL80211_BSS_SIGNAL_MBM] = { .type = NLA_U32 }, 1315f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg [NL80211_BSS_SIGNAL_UNSPEC] = { .type = NLA_U8 }, 1316a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg [NL80211_BSS_STATUS] = { .type = NLA_U32 }, 1317c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig [NL80211_BSS_SEEN_MS_AGO] = { .type = NLA_U32 }, 1318575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen [NL80211_BSS_BEACON_IES] = { }, 13193563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg }; 1320febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg struct scan_params *params = arg; 13211c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg int show = params->show_both_ie_sets ? 2 : 1; 13222e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev bool is_dmg = false; 13233563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 13243563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), 13253563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg genlmsg_attrlen(gnlh, 0), NULL); 13263563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 13273563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (!tb[NL80211_ATTR_BSS]) { 13285fe70c0edb4bc3015d192977f4fb9a5d4fa07148Johannes Berg fprintf(stderr, "bss info missing!\n"); 13293563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 13303563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 13313563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (nla_parse_nested(bss, NL80211_BSS_MAX, 13323563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg tb[NL80211_ATTR_BSS], 13333563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg bss_policy)) { 13345fe70c0edb4bc3015d192977f4fb9a5d4fa07148Johannes Berg fprintf(stderr, "failed to parse nested attributes!\n"); 13353563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 13363563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg } 13373563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 13383563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (!bss[NL80211_BSS_BSSID]) 13393563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 13403563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 13413563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg mac_addr_n2a(mac_addr, nla_data(bss[NL80211_BSS_BSSID])); 13423563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); 1343a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf("BSS %s (on %s)", mac_addr, dev); 1344a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg 1345a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg if (bss[NL80211_BSS_STATUS]) { 1346a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg switch (nla_get_u32(bss[NL80211_BSS_STATUS])) { 1347a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg case NL80211_BSS_STATUS_AUTHENTICATED: 1348a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- authenticated"); 1349a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1350a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg case NL80211_BSS_STATUS_ASSOCIATED: 1351a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- associated"); 1352a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1353a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg case NL80211_BSS_STATUS_IBSS_JOINED: 1354a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- joined"); 1355a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1356a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg default: 1357a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf(" -- unknown status: %d", 1358a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg nla_get_u32(bss[NL80211_BSS_STATUS])); 1359a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg break; 1360a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg } 1361a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg } 1362a56117a695f4109b061134a76cca22f7a8ba8db7Johannes Berg printf("\n"); 13633563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1364e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg if (bss[NL80211_BSS_TSF]) { 1365e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg unsigned long long tsf; 1366e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg tsf = (unsigned long long)nla_get_u64(bss[NL80211_BSS_TSF]); 1367e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg printf("\tTSF: %llu usec (%llud, %.2lld:%.2llu:%.2llu)\n", 1368e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg tsf, tsf/1000/1000/60/60/24, (tsf/1000/1000/60/60) % 24, 1369e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg (tsf/1000/1000/60) % 60, (tsf/1000/1000) % 60); 1370e7109a8aa93fab514d0c71803df622bec6dd23d4Johannes Berg } 13712e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (bss[NL80211_BSS_FREQUENCY]) { 13722e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev int freq = nla_get_u32(bss[NL80211_BSS_FREQUENCY]); 13732e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev printf("\tfreq: %d\n", freq); 13742e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (freq > 45000) 13752e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev is_dmg = true; 13762e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev } 13773563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg if (bss[NL80211_BSS_BEACON_INTERVAL]) 13783563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg printf("\tbeacon interval: %d\n", 13793563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg nla_get_u16(bss[NL80211_BSS_BEACON_INTERVAL])); 138092a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann if (bss[NL80211_BSS_CAPABILITY]) { 138192a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann __u16 capa = nla_get_u16(bss[NL80211_BSS_CAPABILITY]); 138292a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann printf("\tcapability:"); 13832e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev if (is_dmg) 13842e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev print_capa_dmg(capa); 13852e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev else 13862e8b82c16a312608d530856f3ab2c72dfd0e5cd2Vladimir Kondratiev print_capa_non_dmg(capa); 138792a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann printf(" (0x%.4x)\n", capa); 138892a04ecd916b20e151c4b40e740b6bd85131e31eMarcel Holtmann } 1389f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg if (bss[NL80211_BSS_SIGNAL_MBM]) { 1390f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]); 1391f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg printf("\tsignal: %d.%.2d dBm\n", s/100, s%100); 1392f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg } 1393f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg if (bss[NL80211_BSS_SIGNAL_UNSPEC]) { 1394f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg unsigned char s = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]); 1395f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg printf("\tsignal: %d/100\n", s); 1396f2e17e1fa6d4b2634564e2a8819cd4ce5f8469edJohannes Berg } 1397c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig if (bss[NL80211_BSS_SEEN_MS_AGO]) { 1398c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig int age = nla_get_u32(bss[NL80211_BSS_SEEN_MS_AGO]); 1399c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig printf("\tlast seen: %d ms ago\n", age); 1400c04a78dfa108063933d2c489896f8c7b417a0f3dHolger Schurig } 1401c551449a3271ca1db60856fc2af20e1f2d01cce8Johannes Berg 14021c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg if (bss[NL80211_BSS_INFORMATION_ELEMENTS] && show--) { 1403575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen if (bss[NL80211_BSS_BEACON_IES]) 1404575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf("\tInformation elements from Probe Response " 1405575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen "frame:\n"); 14063563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg print_ies(nla_data(bss[NL80211_BSS_INFORMATION_ELEMENTS]), 1407764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg nla_len(bss[NL80211_BSS_INFORMATION_ELEMENTS]), 1408febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg params->unknown, params->type); 1409575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen } 14101c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg if (bss[NL80211_BSS_BEACON_IES] && show--) { 1411575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen printf("\tInformation elements from Beacon frame:\n"); 1412575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen print_ies(nla_data(bss[NL80211_BSS_BEACON_IES]), 1413575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen nla_len(bss[NL80211_BSS_BEACON_IES]), 1414575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen params->unknown, params->type); 1415575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen } 14163563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 14173563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return NL_SKIP; 14183563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 14193563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 1420764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Bergstatic struct scan_params scan_params; 14213563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg 14227c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Bergstatic int handle_scan_dump(struct nl80211_state *state, 14237c37a24d7570cd9ff6b89d6fa8c1846c9b66969dJohannes Berg struct nl_cb *cb, 14243563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg struct nl_msg *msg, 142505514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg int argc, char **argv, 142605514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg enum id_input id) 14273563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg{ 1428764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg if (argc > 1) 1429764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg return 1; 1430764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 14311c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg memset(&scan_params, 0, sizeof(scan_params)); 14321c5bcd9c76dad08e54c3e6604a529c53b62e76eaJohannes Berg 1433764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg if (argc == 1 && !strcmp(argv[0], "-u")) 1434764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg scan_params.unknown = true; 1435575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen else if (argc == 1 && !strcmp(argv[0], "-b")) 1436575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen scan_params.show_both_ie_sets = true; 1437764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg 1438febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg scan_params.type = PRINT_SCAN; 1439febeb0c05600f8ce6b18ec624c73de53970403e1Johannes Berg 1440764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_bss_handler, 1441764fe7533b74fb064f112497c9a1d5651a1ee5b8Johannes Berg &scan_params); 14423563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg return 0; 14433563f4c510e0afbf18bf616f7e35a9b05a535ec2Johannes Berg} 1444a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 1445a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Bergstatic int handle_scan_combined(struct nl80211_state *state, 1446a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg struct nl_cb *cb, 1447a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg struct nl_msg *msg, 144805514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg int argc, char **argv, 144905514f9581f66b12ac9ee0f21c770ceb34310e9dJohannes Berg enum id_input id) 1450a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg{ 1451559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg char **trig_argv; 1452a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg static char *dump_argv[] = { 1453a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NULL, 1454a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg "scan", 1455a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg "dump", 145692649eab6b3ccb0be600b8501fa7b83e9467819cMarcel Holtmann NULL, 1457a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg }; 1458a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg static const __u32 cmds[] = { 1459a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NL80211_CMD_NEW_SCAN_RESULTS, 1460a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NL80211_CMD_SCAN_ABORTED, 1461a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg }; 1462559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int trig_argc, dump_argc, err; 1463a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 1464559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (argc >= 3 && !strcmp(argv[2], "-u")) { 1465559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg dump_argc = 4; 1466559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg dump_argv[3] = "-u"; 1467575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen } else if (argc >= 3 && !strcmp(argv[2], "-b")) { 1468575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen dump_argc = 4; 1469575280ccc907e98cc4146dbaeb7adabb6232e150Jouni Malinen dump_argv[3] = "-b"; 1470559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg } else 1471559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg dump_argc = 3; 1472559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg 1473559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argc = 3 + (argc - 2) + (3 - dump_argc); 1474559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv = calloc(trig_argc, sizeof(*trig_argv)); 1475559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg if (!trig_argv) 1476559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg return -ENOMEM; 1477a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg trig_argv[0] = argv[0]; 1478559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv[1] = "scan"; 1479559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv[2] = "trigger"; 1480559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg int i; 1481559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg for (i = 0; i < argc - 2 - (dump_argc - 3); i++) 1482559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg trig_argv[i + 3] = argv[i + 2 + (dump_argc - 3)]; 148375f4204cd7d27caa080d64f6f5cf3c4b366c839fJohannes Berg err = handle_cmd(state, id, trig_argc, trig_argv); 1484559a1713eba3ce41d260e01e2b68f2e28f71d3cdJohannes Berg free(trig_argv); 1485a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg if (err) 1486a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg return err; 1487a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 148861725dbed6df376809e8dc3865640244d8f1d690Johannes Berg /* 148961725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * WARNING: DO NOT COPY THIS CODE INTO YOUR APPLICATION 149061725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 149161725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * This code has a bug, which requires creating a separate 149261725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * nl80211 socket to fix: 149361725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * It is possible for a NL80211_CMD_NEW_SCAN_RESULTS or 149461725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * NL80211_CMD_SCAN_ABORTED message to be sent by the kernel 149561725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * before (!) we listen to it, because we only start listening 149661725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * after we send our scan request. 149761725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 149861725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * Doing it the other way around has a race condition as well, 149961725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * if you first open the events socket you may get a notification 150061725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * for a previous scan. 150161725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 150261725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * The only proper way to fix this would be to listen to events 150361725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * before sending the command, and for the kernel to send the 150461725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * scan request along with the event, so that you can match up 150561725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * whether the scan you requested was finished or aborted (this 150661725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * may result in processing a scan that another application 150761725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * requested, but that doesn't seem to be a problem). 150861725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * 150961725dbed6df376809e8dc3865640244d8f1d690Johannes Berg * Alas, the kernel doesn't do that (yet). 151061725dbed6df376809e8dc3865640244d8f1d690Johannes Berg */ 151161725dbed6df376809e8dc3865640244d8f1d690Johannes Berg 1512a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg if (listen_events(state, ARRAY_SIZE(cmds), cmds) == 1513a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg NL80211_CMD_SCAN_ABORTED) { 1514a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg printf("scan aborted!\n"); 1515a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg return 0; 1516a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg } 1517a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg 1518a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg dump_argv[0] = argv[0]; 151975f4204cd7d27caa080d64f6f5cf3c4b366c839fJohannes Berg return handle_cmd(state, id, dump_argc, dump_argv); 1520a5fe4ef2f3e282a789c86edee838f338b07d5033Johannes Berg} 1521ced94d5f129e5d116b6a888f312deab081bb2231Antonio QuartulliTOPLEVEL(scan, "[-u] [freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force] [ssid <ssid>*|passive]", 0, 0, 15226ca98d28b949d20cca2e158bef3e0cfd75b59672Johannes Berg CIB_NETDEV, handle_scan_combined, 15236ca98d28b949d20cca2e158bef3e0cfd75b59672Johannes Berg "Scan on the given frequencies and probe for the given SSIDs\n" 15246ca98d28b949d20cca2e158bef3e0cfd75b59672Johannes Berg "(or wildcard if not given) unless passive scanning is requested.\n" 152564797a7fd7c49d95abc8540490c76bf493699176Johannes Berg "If -u is specified print unknown data in the scan results.\n" 152664797a7fd7c49d95abc8540490c76bf493699176Johannes Berg "Specified (vendor) IEs must be well-formed."); 15274698bfc235c20e955466b6362df2a39f7478c13fJohannes BergCOMMAND(scan, dump, "[-u]", 15284698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump, 15294698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "Dump the current scan results. If -u is specified, print unknown\n" 15304698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "data in scan results."); 1531ced94d5f129e5d116b6a888f312deab081bb2231Antonio QuartulliCOMMAND(scan, trigger, "[freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force] [ssid <ssid>*|passive]", 15324698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan, 15334698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "Trigger a scan on the given frequencies with probing for the given\n" 15344698bfc235c20e955466b6362df2a39f7478c13fJohannes Berg "SSIDs (or wildcard if not given) unless passive scanning is requested."); 1535