This makes tcpdump -v -y IEEE802_11_RADIO decode RSN beacon elements. Before:
rsn 0x0100000fac040100000fac040100000fac0200000000 After: rsn=<version 1,groupcipher ccmp,cipher ccmp,akm PSK,rsncap 0x0> Code which generates this element can be found in ieee80211_add_rsn_body() in the file sys/net80211/ieee80211_output.c. ok? Index: print-802_11.c =================================================================== RCS file: /cvs/src/usr.sbin/tcpdump/print-802_11.c,v retrieving revision 1.39 diff -u -p -r1.39 print-802_11.c --- print-802_11.c 4 Mar 2017 17:51:20 -0000 1.39 +++ print-802_11.c 30 Aug 2017 10:46:14 -0000 @@ -101,6 +101,9 @@ void ieee80211_print_essid(u_int8_t *, void ieee80211_print_country(u_int8_t *, u_int); void ieee80211_print_htcaps(u_int8_t *, u_int); void ieee80211_print_htop(u_int8_t *, u_int); +void ieee80211_print_rsncipher(u_int8_t []); +void ieee80211_print_akm(u_int8_t []); +void ieee80211_print_rsn(u_int8_t *, u_int); int ieee80211_print_beacon(struct ieee80211_frame *, u_int); int ieee80211_print_assocreq(struct ieee80211_frame *, u_int); int ieee80211_print_elements(uint8_t *); @@ -601,6 +604,193 @@ ieee80211_print_htop(u_int8_t *data, u_i printf(">"); } +void +ieee80211_print_rsncipher(uint8_t selector[4]) +{ + if (memcmp(selector, MICROSOFT_OUI, 3) != 0 && + memcmp(selector, IEEE80211_OUI, 3) != 0) { + printf("0x%x%x%x%x", selector[0], selector[1], selector[2], + selector[3]); + return; + } + + /* See 802.11-2012 Table 8-99 */ + switch (selector[3]) { + case 0: /* use group data cipher suite */ + printf("usegroup"); + break; + case 1: /* WEP-40 */ + printf("wep40"); + break; + case 2: /* TKIP */ + printf("tkip"); + break; + case 4: /* CCMP (RSNA default) */ + printf("ccmp"); + break; + case 5: /* WEP-104 */ + printf("wep104"); + break; + case 6: /* BIP */ + printf("bip"); + break; + default: + printf("%d", selector[3]); + break; + } +} + +void +ieee80211_print_akm(uint8_t selector[4]) +{ + if (memcmp(selector, MICROSOFT_OUI, 3) != 0 && + memcmp(selector, IEEE80211_OUI, 3) != 0) { + printf("0x%x%x%x%x", selector[0], selector[1], selector[2], + selector[3]); + return; + } + + switch (selector[3]) { + case 1: + printf("802.1x"); + break; + case 2: + printf("PSK"); + break; + case 5: + printf("SHA256-802.1x"); + break; + case 6: + printf("SHA256-PSK"); + break; + default: + printf("%d", selector[3]); + break; + } +} + +/* Caller checks len */ +void +ieee80211_print_rsn(u_int8_t *data, u_int len) +{ + uint16_t version, nciphers, nakms, rsncap, npmk; + int i, j; + uint8_t selector[4]; + + if (len < 2) { + ieee80211_print_element(data, len); + return; + } + + version = (data[0]) | (data[1] << 8); + printf("=<version %d", version); + + if (len < 6) { + printf(">"); + return; + } + + data += 2; + printf(",groupcipher "); + for (i = 0; i < 4; i++) + selector[i] = data[i]; + ieee80211_print_rsncipher(selector); + + if (len < 8) { + printf(">"); + return; + } + + data += 4; + nciphers = (data[0]) | ((data[1]) << 8); + data += 2; + + if (len < 8 + (nciphers * 4)) { + printf(">"); + return; + } + + printf(",cipher%s ", nciphers > 1 ? "s" : ""); + for (i = 0; i < nciphers; i++) { + for (j = 0; j < 4; j++) + selector[j] = data[i + j]; + ieee80211_print_rsncipher(selector); + if (i < nciphers - 1) + printf(" "); + data += 4; + } + + if (len < 8 + (nciphers * 4) + 2) { + printf(">"); + return; + } + + nakms = (data[0]) | ((data[1]) << 8); + data += 2; + + if (len < 8 + (nciphers * 4) + 2 + (nakms * 4)) { + printf(">"); + return; + } + + printf(",akm%s ", nakms > 1 ? "s" : ""); + for (i = 0; i < nciphers; i++) { + for (j = 0; j < 4; j++) + selector[j] = data[i + j]; + ieee80211_print_akm(selector); + if (i < nciphers - 1) + printf(" "); + data += 4; + } + + if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2) { + printf(">"); + return; + } + + rsncap = (data[0]) | ((data[1]) << 8); + printf(",rsncap 0x%x", rsncap); + data += 2; + + if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2) { + printf(">"); + return; + } + + npmk = (data[0]) | ((data[1]) << 8); + data += 2; + + if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 + + (npmk * IEEE80211_PMKID_LEN)) { + printf(">"); + return; + } + + if (npmk >= 1) + printf(",pmkid%s ", npmk > 1 ? "s" : ""); + for (i = 0; i < npmk; i++) { + printf("0x"); + for (j = 0; j < IEEE80211_PMKID_LEN; j++) + printf("%x", data[i + j]); + if (i < npmk - 1) + printf(" "); + data += IEEE80211_PMKID_LEN; + } + + if (len < 8 + (nciphers * 4) + 2 + (nakms * 4) + 2 + 2 + + (npmk * IEEE80211_PMKID_LEN) + 4) { + printf(">"); + return; + } + + printf(",integrity-groupcipher "); + for (i = 0; i < 4; i++) + selector[i] = data[i]; + ieee80211_print_rsncipher(selector); + + printf(">"); +} + int ieee80211_print_beacon(struct ieee80211_frame *wh, u_int len) { @@ -746,7 +936,7 @@ ieee80211_print_elements(uint8_t *frm) case IEEE80211_ELEMID_RSN: printf(", rsn"); if (vflag) - ieee80211_print_element(data, len); + ieee80211_print_rsn(data, len); break; case IEEE80211_ELEMID_XRATES: printf(", xrates");