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");

Reply via email to