X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/f1fa25bfefac7dd95768d949ef0ef232c4540331..refs/pull/433/head:/print-eap.c diff --git a/print-eap.c b/print-eap.c index 95a2c97e..0e2c2d38 100644 --- a/print-eap.c +++ b/print-eap.c @@ -17,55 +17,280 @@ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * Format and print bootp packets. + * Format and print EAP packets. + * */ -#ifndef lint -static const char rcsid[] _U_ = - "@(#) $Header: /tcpdump/master/tcpdump/print-eap.c,v 1.3 2004-04-23 19:03:39 mcr Exp $"; -#endif - +#define NETDISSECT_REWORKED #ifdef HAVE_CONFIG_H #include "config.h" #endif #include -#include -#include - -#include "netdissect.h" -#include "addrtoname.h" +#include "interface.h" #include "extract.h" -#include "ether.h" +#define EAP_FRAME_TYPE_PACKET 0 +#define EAP_FRAME_TYPE_START 1 +#define EAP_FRAME_TYPE_LOGOFF 2 +#define EAP_FRAME_TYPE_KEY 3 +#define EAP_FRAME_TYPE_ENCAP_ASF_ALERT 4 + +struct eap_frame_t { + unsigned char version; + unsigned char type; + unsigned char length[2]; +}; + +static const struct tok eap_frame_type_values[] = { + { EAP_FRAME_TYPE_PACKET, "EAP packet" }, + { EAP_FRAME_TYPE_START, "EAPOL start" }, + { EAP_FRAME_TYPE_LOGOFF, "EAPOL logoff" }, + { EAP_FRAME_TYPE_KEY, "EAPOL key" }, + { EAP_FRAME_TYPE_ENCAP_ASF_ALERT, "Encapsulated ASF alert" }, + { 0, NULL} +}; + +/* RFC 3748 */ struct eap_packet_t { - unsigned char code; - unsigned char id; - unsigned char length[2]; - unsigned char data[1]; + unsigned char code; + unsigned char id; + unsigned char length[2]; +}; + +#define EAP_REQUEST 1 +#define EAP_RESPONSE 2 +#define EAP_SUCCESS 3 +#define EAP_FAILURE 4 + +static const struct tok eap_code_values[] = { + { EAP_REQUEST, "Request" }, + { EAP_RESPONSE, "Response" }, + { EAP_SUCCESS, "Success" }, + { EAP_FAILURE, "Failure" }, + { 0, NULL} +}; + +#define EAP_TYPE_NO_PROPOSED 0 +#define EAP_TYPE_IDENTITY 1 +#define EAP_TYPE_NOTIFICATION 2 +#define EAP_TYPE_NAK 3 +#define EAP_TYPE_MD5_CHALLENGE 4 +#define EAP_TYPE_OTP 5 +#define EAP_TYPE_GTC 6 +#define EAP_TYPE_TLS 13 /* RFC 2716 */ +#define EAP_TYPE_SIM 18 /* RFC 4186 */ +#define EAP_TYPE_TTLS 21 /* draft-funk-eap-ttls-v0-01.txt */ +#define EAP_TYPE_AKA 23 /* RFC 4187 */ +#define EAP_TYPE_FAST 43 /* RFC 4851 */ +#define EAP_TYPE_EXPANDED_TYPES 254 +#define EAP_TYPE_EXPERIMENTAL 255 + +static const struct tok eap_type_values[] = { + { EAP_TYPE_NO_PROPOSED, "No proposed" }, + { EAP_TYPE_IDENTITY, "Identity" }, + { EAP_TYPE_NOTIFICATION, "Notification" }, + { EAP_TYPE_NAK, "Nak" }, + { EAP_TYPE_MD5_CHALLENGE, "MD5-challenge" }, + { EAP_TYPE_OTP, "OTP" }, + { EAP_TYPE_GTC, "GTC" }, + { EAP_TYPE_TLS, "TLS" }, + { EAP_TYPE_SIM, "SIM" }, + { EAP_TYPE_TTLS, "TTLS" }, + { EAP_TYPE_AKA, "AKA" }, + { EAP_TYPE_FAST, "FAST" }, + { EAP_TYPE_EXPANDED_TYPES, "Expanded types" }, + { EAP_TYPE_EXPERIMENTAL, "Experimental" }, + { 0, NULL} +}; + +#define EAP_TLS_EXTRACT_BIT_L(x) (((x)&0x80)>>7) + +/* RFC 2716 - EAP TLS bits */ +#define EAP_TLS_FLAGS_LEN_INCLUDED (1 << 7) +#define EAP_TLS_FLAGS_MORE_FRAGMENTS (1 << 6) +#define EAP_TLS_FLAGS_START (1 << 5) + +static const struct tok eap_tls_flags_values[] = { + { EAP_TLS_FLAGS_LEN_INCLUDED, "L bit" }, + { EAP_TLS_FLAGS_MORE_FRAGMENTS, "More fragments bit"}, + { EAP_TLS_FLAGS_START, "Start bit"}, + { 0, NULL} +}; + +#define EAP_TTLS_VERSION(x) ((x)&0x07) + +/* EAP-AKA and EAP-SIM - RFC 4187 */ +#define EAP_AKA_CHALLENGE 1 +#define EAP_AKA_AUTH_REJECT 2 +#define EAP_AKA_SYNC_FAILURE 4 +#define EAP_AKA_IDENTITY 5 +#define EAP_SIM_START 10 +#define EAP_SIM_CHALLENGE 11 +#define EAP_AKA_NOTIFICATION 12 +#define EAP_AKA_REAUTH 13 +#define EAP_AKA_CLIENT_ERROR 14 + +static const struct tok eap_aka_subtype_values[] = { + { EAP_AKA_CHALLENGE, "Challenge" }, + { EAP_AKA_AUTH_REJECT, "Auth reject" }, + { EAP_AKA_SYNC_FAILURE, "Sync failure" }, + { EAP_AKA_IDENTITY, "Identity" }, + { EAP_SIM_START, "Start" }, + { EAP_SIM_CHALLENGE, "Challenge" }, + { EAP_AKA_NOTIFICATION, "Notification" }, + { EAP_AKA_REAUTH, "Reauth" }, + { EAP_AKA_CLIENT_ERROR, "Client error" }, + { 0, NULL} }; /* - * Print bootp requests + * Print EAP requests / responses */ void eap_print(netdissect_options *ndo, - register const u_char *cp, - u_int length _U_) + register const u_char *cp, + u_int length _U_) { - const struct eap_packet_t *eap; + const struct eap_frame_t *eap; + const u_char *tptr; + u_int tlen, type, subtype; + int count=0, len; + + tptr = cp; + tlen = length; + eap = (const struct eap_frame_t *)cp; + ND_TCHECK(*eap); + + /* in non-verbose mode just lets print the basic info */ + if (ndo->ndo_vflag < 1) { + ND_PRINT((ndo, "%s (%u) v%u, len %u", + tok2str(eap_frame_type_values, "unknown", eap->type), + eap->type, + eap->version, + EXTRACT_16BITS(eap->length))); + return; + } + + ND_PRINT((ndo, "%s (%u) v%u, len %u", + tok2str(eap_frame_type_values, "unknown", eap->type), + eap->type, + eap->version, + EXTRACT_16BITS(eap->length))); + + tptr += sizeof(const struct eap_frame_t); + tlen -= sizeof(const struct eap_frame_t); + + switch (eap->type) { + case EAP_FRAME_TYPE_PACKET: + type = *(tptr); + len = EXTRACT_16BITS(tptr+2); + ND_PRINT((ndo, ", %s (%u), id %u, len %u", + tok2str(eap_code_values, "unknown", type), + type, + *(tptr+1), + len)); + + ND_TCHECK2(*tptr, len); + + if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */ + subtype = *(tptr+4); + ND_PRINT((ndo, "\n\t\t Type %s (%u)", + tok2str(eap_type_values, "unknown", *(tptr+4)), + *(tptr + 4))); + + switch (subtype) { + case EAP_TYPE_IDENTITY: + if (len - 5 > 0) { + ND_PRINT((ndo, ", Identity: ")); + safeputs(ndo, tptr + 5, len - 5); + } + break; + + case EAP_TYPE_NOTIFICATION: + if (len - 5 > 0) { + ND_PRINT((ndo, ", Notification: ")); + safeputs(ndo, tptr + 5, len - 5); + } + break; - eap = (const struct eap_packet_t *)cp; - ND_TCHECK(eap->data); + case EAP_TYPE_NAK: + count = 5; - ND_PRINT((ndo, "EAP code=%u id=%u length=%u ", - eap->code, eap->id, (eap->length[0]<<8) + eap->length[1])); + /* + * one or more octets indicating + * the desired authentication + * type one octet per type + */ + while (count < len) { + ND_PRINT((ndo, " %s (%u),", + tok2str(eap_type_values, "unknown", *(tptr+count)), + *(tptr + count))); + count++; + } + break; - if (!ndo->ndo_vflag) - return; + case EAP_TYPE_TTLS: + ND_PRINT((ndo, " TTLSv%u", + EAP_TTLS_VERSION(*(tptr + 5)))); /* fall through */ + case EAP_TYPE_TLS: + ND_PRINT((ndo, " flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", *(tptr+5)), + *(tptr + 5))); -trunc: - ; + if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); + } + break; + + case EAP_TYPE_FAST: + ND_PRINT((ndo, " FASTv%u", + EAP_TTLS_VERSION(*(tptr + 5)))); + ND_PRINT((ndo, " flags [%s] 0x%02x,", + bittok2str(eap_tls_flags_values, "none", *(tptr+5)), + *(tptr + 5))); + + if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { + ND_PRINT((ndo, " len %u", EXTRACT_32BITS(tptr + 6))); + } + + /* FIXME - TLV attributes follow */ + break; + + case EAP_TYPE_AKA: + case EAP_TYPE_SIM: + ND_PRINT((ndo, " subtype [%s] 0x%02x,", + tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)), + *(tptr + 5))); + + /* FIXME - TLV attributes follow */ + break; + + case EAP_TYPE_MD5_CHALLENGE: + case EAP_TYPE_OTP: + case EAP_TYPE_GTC: + case EAP_TYPE_EXPANDED_TYPES: + case EAP_TYPE_EXPERIMENTAL: + default: + break; + } + } + break; + + case EAP_FRAME_TYPE_LOGOFF: + case EAP_FRAME_TYPE_ENCAP_ASF_ALERT: + default: + break; + } + return; + + trunc: + ND_PRINT((ndo, "\n\t[|EAP]")); } +/* + * Local Variables: + * c-basic-offset: 4 + * End: + */