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