i was trying to understand some packets that tcpdump didnt know about,
and discovered they were EAPOL. turns out EAPOL is a little container
around a bunch of different types of messages including EAP, the
MACsec Key Agreement protocol, and it's own type of capabilities
advertisements.

this implements basic parsing of the EAPOL container so it can print the
type. any further parsing will need code for each type of message to be
added.

i didnt think it was worth adding a new file just for eapol, so i put it
in print-ether.c. we do have something in src/sys/net/ethertypes.h for
0x888e, but i want to rename it to ETHERTYPE_EAPOL anyway.

ok?

Index: print-ether.c
===================================================================
RCS file: /cvs/src/usr.sbin/tcpdump/print-ether.c,v
retrieving revision 1.39
diff -u -p -r1.39 print-ether.c
--- print-ether.c       1 Dec 2021 18:28:46 -0000       1.39
+++ print-ether.c       4 Jan 2022 02:56:21 -0000
@@ -36,6 +36,7 @@
 #include <netinet/tcp.h>
 
 #include <stdio.h>
+#include <stddef.h>
 #include <pcap.h>
 
 
@@ -49,6 +50,7 @@ const u_char *snapend;
 
 void ether_macctl(const u_char *, u_int);
 void ether_pbb_print(const u_char *, u_int, u_int);
+void ether_eapol_print(const u_char *, u_int, u_int);
 
 void
 ether_print(const u_char *bp, u_int length)
@@ -294,6 +296,13 @@ recurse:
                nsh_print(p, length);
                return (1);
 
+#ifndef ETHERTYPE_EAPOL
+#define ETHERTYPE_EAPOL 0x888e
+#endif
+       case ETHERTYPE_EAPOL:
+               ether_eapol_print(p, length, caplen);
+               return (1);
+
 #ifndef ETHERTYPE_PBB
 #define ETHERTYPE_PBB 0x88e7
 #endif
@@ -367,4 +376,87 @@ ether_macctl(const u_char *p, u_int leng
 
 trunc:
        printf("[|MACCTL]");
+}
+
+/*
+ * 802.1X EAPOL PDU
+ */
+
+struct eapol_header {
+       uint8_t                 version;
+       uint8_t                 type;
+#define EAPOL_T_EAP                    0x00
+#define EAPOL_T_START                  0x01
+#define EAPOL_T_LOGOFF                 0x02
+#define EAPOL_T_KEY                    0x03
+#define EAPOL_T_ENCAP_ASF_ALERT                0x04
+#define EAPOL_T_MKA                    0x05
+#define EAPOL_T_ANNOUNCEMENT_GENERIC   0x06
+#define EAPOL_T_ANNOUNCEMENT_SPECIFIC  0x07
+#define EAPOL_T_ANNOUNCEMENT_REQ       0x08
+       uint16_t                length;
+};
+
+void
+ether_eapol_print(const u_char *bp, u_int length, u_int caplen)
+{
+       struct eapol_header h;
+
+       printf("EAPOL");
+
+       if (caplen < sizeof(h))
+               goto trunc;
+
+       h.version = *(bp + offsetof(struct eapol_header, version));
+       h.type = *(bp + offsetof(struct eapol_header, type));
+       h.length = EXTRACT_16BITS(bp + offsetof(struct eapol_header, length));
+
+       bp += sizeof(h);
+       length -= sizeof(h);
+       caplen -= sizeof(h);
+
+       if (vflag)
+               printf(" (v%u, len %u)", h.version, h.length);
+
+       if (length > h.length)
+               length = h.length;
+       else if (length < h.length) {
+               printf(" truncated-eapol - %u bytes missing!",
+                   h.length - length);
+       }
+
+       switch (h.type) {
+       case EAPOL_T_EAP:
+               printf(" EAP");
+               break;
+       case EAPOL_T_START:
+               printf(" Start");
+               break;
+       case EAPOL_T_LOGOFF:
+               printf(" Logoff");
+               break;
+       case EAPOL_T_KEY:
+               printf(" Key");
+               break;
+       case EAPOL_T_MKA:
+               printf(" MKA");
+               break;
+       case EAPOL_T_ANNOUNCEMENT_GENERIC:
+               printf(" Announcement (Generic)");
+               break;
+       case EAPOL_T_ANNOUNCEMENT_SPECIFIC:
+               printf(" Announcement (Specific)");
+               break;
+       case EAPOL_T_ANNOUNCEMENT_REQ:
+               printf(" Announcement Req");
+               break;
+       default:
+               printf(" unknown (%u)", h.type);
+               break;
+       }
+
+       return;
+
+trunc:
+       printf(" [|eapol] ");
 }

Reply via email to