1/* 2 * Copyright (c) 2004 - Michael Richardson <mcr@xelerance.com> 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that: (1) source code distributions 6 * retain the above copyright notice and this paragraph in its entirety, (2) 7 * distributions including binary code include the above copyright notice and 8 * this paragraph in its entirety in the documentation or other materials 9 * provided with the distribution, and (3) all advertising materials mentioning 10 * features or use of this software display the following acknowledgement: 11 * ``This product includes software developed by the University of California, 12 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 13 * the University nor the names of its contributors may be used to endorse 14 * or promote products derived from this software without specific prior 15 * written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * Format and print EAP packets. 21 * 22 */ 23 24#include <sys/cdefs.h> 25#ifndef lint 26#if 0 27static const char rcsid[] _U_ = 28 "@(#) Header: /tcpdump/master/tcpdump/print-eap.c,v 1.5 2007-10-04 16:41:33 hannes Exp"; 29#else 30__RCSID("$NetBSD$"); 31#endif 32#endif 33 34#ifdef HAVE_CONFIG_H 35#include "config.h" 36#endif 37 38#include <tcpdump-stdinc.h> 39 40#include <stdio.h> 41#include <string.h> 42 43#include "netdissect.h" 44#include "interface.h" 45#include "addrtoname.h" 46#include "extract.h" 47#include "ether.h" 48 49#define EAP_FRAME_TYPE_PACKET 0 50#define EAP_FRAME_TYPE_START 1 51#define EAP_FRAME_TYPE_LOGOFF 2 52#define EAP_FRAME_TYPE_KEY 3 53#define EAP_FRAME_TYPE_ENCAP_ASF_ALERT 4 54 55struct eap_frame_t { 56 unsigned char version; 57 unsigned char type; 58 unsigned char length[2]; 59}; 60 61static const struct tok eap_frame_type_values[] = { 62 { EAP_FRAME_TYPE_PACKET, "EAP packet" }, 63 { EAP_FRAME_TYPE_START, "EAPOL start" }, 64 { EAP_FRAME_TYPE_LOGOFF, "EAPOL logoff" }, 65 { EAP_FRAME_TYPE_KEY, "EAPOL key" }, 66 { EAP_FRAME_TYPE_ENCAP_ASF_ALERT, "Encapsulated ASF alert" }, 67 { 0, NULL} 68}; 69 70/* RFC 3748 */ 71struct eap_packet_t { 72 unsigned char code; 73 unsigned char id; 74 unsigned char length[2]; 75}; 76 77#define EAP_REQUEST 1 78#define EAP_RESPONSE 2 79#define EAP_SUCCESS 3 80#define EAP_FAILURE 4 81 82static const struct tok eap_code_values[] = { 83 { EAP_REQUEST, "Request" }, 84 { EAP_RESPONSE, "Response" }, 85 { EAP_SUCCESS, "Success" }, 86 { EAP_FAILURE, "Failure" }, 87 { 0, NULL} 88}; 89 90#define EAP_TYPE_NO_PROPOSED 0 91#define EAP_TYPE_IDENTITY 1 92#define EAP_TYPE_NOTIFICATION 2 93#define EAP_TYPE_NAK 3 94#define EAP_TYPE_MD5_CHALLENGE 4 95#define EAP_TYPE_OTP 5 96#define EAP_TYPE_GTC 6 97#define EAP_TYPE_TLS 13 /* RFC 2716 */ 98#define EAP_TYPE_SIM 18 /* RFC 4186 */ 99#define EAP_TYPE_TTLS 21 /* draft-funk-eap-ttls-v0-01.txt */ 100#define EAP_TYPE_AKA 23 /* RFC 4187 */ 101#define EAP_TYPE_FAST 43 /* RFC 4851 */ 102#define EAP_TYPE_EXPANDED_TYPES 254 103#define EAP_TYPE_EXPERIMENTAL 255 104 105static const struct tok eap_type_values[] = { 106 { EAP_TYPE_NO_PROPOSED, "No proposed" }, 107 { EAP_TYPE_IDENTITY, "Identity" }, 108 { EAP_TYPE_NOTIFICATION, "Notification" }, 109 { EAP_TYPE_NAK, "Nak" }, 110 { EAP_TYPE_MD5_CHALLENGE, "MD5-challenge" }, 111 { EAP_TYPE_OTP, "OTP" }, 112 { EAP_TYPE_GTC, "GTC" }, 113 { EAP_TYPE_TLS, "TLS" }, 114 { EAP_TYPE_SIM, "SIM" }, 115 { EAP_TYPE_TTLS, "TTLS" }, 116 { EAP_TYPE_AKA, "AKA" }, 117 { EAP_TYPE_FAST, "FAST" }, 118 { EAP_TYPE_EXPANDED_TYPES, "Expanded types" }, 119 { EAP_TYPE_EXPERIMENTAL, "Experimental" }, 120 { 0, NULL} 121}; 122 123#define EAP_TLS_EXTRACT_BIT_L(x) (((x)&0x80)>>7) 124 125/* RFC 2716 - EAP TLS bits */ 126#define EAP_TLS_FLAGS_LEN_INCLUDED (1 << 7) 127#define EAP_TLS_FLAGS_MORE_FRAGMENTS (1 << 6) 128#define EAP_TLS_FLAGS_START (1 << 5) 129 130static const struct tok eap_tls_flags_values[] = { 131 { EAP_TLS_FLAGS_LEN_INCLUDED, "L bit" }, 132 { EAP_TLS_FLAGS_MORE_FRAGMENTS, "More fragments bit"}, 133 { EAP_TLS_FLAGS_START, "Start bit"}, 134 { 0, NULL} 135}; 136 137#define EAP_TTLS_VERSION(x) ((x)&0x07) 138 139/* EAP-AKA and EAP-SIM - RFC 4187 */ 140#define EAP_AKA_CHALLENGE 1 141#define EAP_AKA_AUTH_REJECT 2 142#define EAP_AKA_SYNC_FAILURE 4 143#define EAP_AKA_IDENTITY 5 144#define EAP_SIM_START 10 145#define EAP_SIM_CHALLENGE 11 146#define EAP_AKA_NOTIFICATION 12 147#define EAP_AKA_REAUTH 13 148#define EAP_AKA_CLIENT_ERROR 14 149 150static const struct tok eap_aka_subtype_values[] = { 151 { EAP_AKA_CHALLENGE, "Challenge" }, 152 { EAP_AKA_AUTH_REJECT, "Auth reject" }, 153 { EAP_AKA_SYNC_FAILURE, "Sync failure" }, 154 { EAP_AKA_IDENTITY, "Identity" }, 155 { EAP_SIM_START, "Start" }, 156 { EAP_SIM_CHALLENGE, "Challenge" }, 157 { EAP_AKA_NOTIFICATION, "Notification" }, 158 { EAP_AKA_REAUTH, "Reauth" }, 159 { EAP_AKA_CLIENT_ERROR, "Client error" }, 160 { 0, NULL} 161}; 162 163/* 164 * Print EAP requests / responses 165 */ 166void 167eap_print(netdissect_options *ndo _U_, 168 register const u_char *cp, 169 u_int length _U_) 170{ 171 const struct eap_frame_t *eap; 172 const u_char *tptr; 173 u_int tlen, type, subtype; 174 int count=0, len; 175 176 tptr = cp; 177 tlen = length; 178 eap = (const struct eap_frame_t *)cp; 179 TCHECK(*eap); 180 181 /* in non-verbose mode just lets print the basic info */ 182 if (vflag < 1) { 183 printf("%s (%u) v%u, len %u", 184 tok2str(eap_frame_type_values, "unknown", eap->type), 185 eap->type, 186 eap->version, 187 EXTRACT_16BITS(eap->length)); 188 return; 189 } 190 191 printf("%s (%u) v%u, len %u", 192 tok2str(eap_frame_type_values, "unknown", eap->type), 193 eap->type, 194 eap->version, 195 EXTRACT_16BITS(eap->length)); 196 197 tptr += sizeof(const struct eap_frame_t); 198 tlen -= sizeof(const struct eap_frame_t); 199 200 switch (eap->type) { 201 case EAP_FRAME_TYPE_PACKET: 202 type = *(tptr); 203 len = EXTRACT_16BITS(tptr+2); 204 printf(", %s (%u), id %u, len %u", 205 tok2str(eap_code_values, "unknown", type), 206 type, 207 *(tptr+1), 208 len); 209 210 if (!TTEST2(*tptr, len)) 211 goto trunc; 212 213 if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */ 214 subtype = *(tptr+4); 215 printf("\n\t\t Type %s (%u)", 216 tok2str(eap_type_values, "unknown", *(tptr+4)), 217 *(tptr+4)); 218 219 switch (subtype) { 220 case EAP_TYPE_IDENTITY: 221 if (len - 5 > 0) { 222 printf(", Identity: "); 223 safeputs((const char *)tptr+5, len-5); 224 } 225 break; 226 227 case EAP_TYPE_NOTIFICATION: 228 if (len - 5 > 0) { 229 printf(", Notification: "); 230 safeputs((const char *)tptr+5, len-5); 231 } 232 break; 233 234 case EAP_TYPE_NAK: 235 count = 5; 236 237 /* 238 * one or more octets indicating 239 * the desired authentication 240 * type one octet per type 241 */ 242 while (count < len) { 243 printf(" %s (%u),", 244 tok2str(eap_type_values, "unknown", *(tptr+count)), 245 *(tptr+count)); 246 count++; 247 } 248 break; 249 250 case EAP_TYPE_TTLS: 251 printf(" TTLSv%u", 252 EAP_TTLS_VERSION(*(tptr+5))); /* fall through */ 253 case EAP_TYPE_TLS: 254 printf(" flags [%s] 0x%02x,", 255 bittok2str(eap_tls_flags_values, "none", *(tptr+5)), 256 *(tptr+5)); 257 258 if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { 259 printf(" len %u", EXTRACT_32BITS(tptr+6)); 260 } 261 break; 262 263 case EAP_TYPE_FAST: 264 printf(" FASTv%u", 265 EAP_TTLS_VERSION(*(tptr+5))); 266 printf(" flags [%s] 0x%02x,", 267 bittok2str(eap_tls_flags_values, "none", *(tptr+5)), 268 *(tptr+5)); 269 270 if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) { 271 printf(" len %u", EXTRACT_32BITS(tptr+6)); 272 } 273 274 /* FIXME - TLV attributes follow */ 275 break; 276 277 case EAP_TYPE_AKA: 278 case EAP_TYPE_SIM: 279 printf(" subtype [%s] 0x%02x,", 280 tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)), 281 *(tptr+5)); 282 283 /* FIXME - TLV attributes follow */ 284 break; 285 286 case EAP_TYPE_MD5_CHALLENGE: 287 case EAP_TYPE_OTP: 288 case EAP_TYPE_GTC: 289 case EAP_TYPE_EXPANDED_TYPES: 290 case EAP_TYPE_EXPERIMENTAL: 291 default: 292 break; 293 } 294 } 295 break; 296 297 case EAP_FRAME_TYPE_LOGOFF: 298 case EAP_FRAME_TYPE_ENCAP_ASF_ALERT: 299 default: 300 break; 301 } 302 return; 303 304 trunc: 305 printf("\n\t[|EAP]"); 306} 307 308/* 309 * Local Variables: 310 * c-basic-offset: 4 311 * End: 312 */ 313