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