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