Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-eap.c
blob7d389bc65c350018405ad49f984469934cebee41
1 /* packet-eap.c
2 * Routines for EAP Extensible Authentication Protocol dissection
3 * RFC 2284, RFC 3748
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <epan/packet.h>
15 #include <epan/conversation.h>
16 #include <epan/ppptypes.h>
17 #include <epan/reassemble.h>
18 #include <epan/eap.h>
19 #include <epan/expert.h>
20 #include <epan/proto_data.h>
21 #include <wsutil/strtoi.h>
23 #include "packet-eapol.h"
24 #include "packet-wps.h"
25 #include "packet-e212.h"
26 #include "packet-tls-utils.h"
28 void proto_register_eap(void);
29 void proto_reg_handoff_eap(void);
31 static int proto_eap;
32 static int hf_eap_code;
33 static int hf_eap_identifier;
34 static int hf_eap_len;
35 static int hf_eap_type;
36 static int hf_eap_type_nak;
38 static int hf_eap_identity;
39 static int hf_eap_identity_full;
40 static int hf_eap_identity_actual_len;
41 static int hf_eap_identity_prefix;
42 static int hf_eap_identity_type;
43 static int hf_eap_identity_certificate_sn;
44 static int hf_eap_identity_mcc;
45 static int hf_eap_identity_mcc_mnc_2digits;
46 static int hf_eap_identity_mcc_mnc_3digits;
47 static int hf_eap_identity_padding;
49 static int hf_eap_notification;
51 static int hf_eap_md5_value_size;
52 static int hf_eap_md5_value;
53 static int hf_eap_md5_extra_data;
55 static int hf_eap_sim_subtype;
56 static int hf_eap_sim_reserved;
57 static int hf_eap_sim_subtype_attribute;
58 static int hf_eap_sim_subtype_type;
59 static int hf_eap_sim_subtype_length;
60 static int hf_eap_sim_notification_type;
61 static int hf_eap_sim_error_code_type;
62 static int hf_eap_sim_subtype_value;
64 static int hf_eap_aka_subtype;
65 static int hf_eap_aka_reserved;
66 static int hf_eap_aka_subtype_attribute;
67 static int hf_eap_aka_subtype_type;
68 static int hf_eap_aka_subtype_length;
69 static int hf_eap_aka_notification_type;
70 static int hf_eap_aka_error_code_type;
71 static int hf_eap_aka_rand;
72 static int hf_eap_aka_autn;
73 static int hf_eap_aka_res_len;
74 static int hf_eap_aka_res;
75 static int hf_eap_aka_auts;
76 static int hf_eap_aka_subtype_value;
78 static int hf_eap_leap_version;
79 static int hf_eap_leap_reserved;
80 static int hf_eap_leap_count;
81 static int hf_eap_leap_peer_challenge;
82 static int hf_eap_leap_peer_response;
83 static int hf_eap_leap_ap_challenge;
84 static int hf_eap_leap_ap_response;
85 static int hf_eap_leap_data;
86 static int hf_eap_leap_name;
88 static int hf_eap_ms_chap_v2_opcode;
89 static int hf_eap_ms_chap_v2_id;
90 static int hf_eap_ms_chap_v2_length;
91 static int hf_eap_ms_chap_v2_value_size;
92 static int hf_eap_ms_chap_v2_challenge;
93 static int hf_eap_ms_chap_v2_name;
94 static int hf_eap_ms_chap_v2_peer_challenge;
95 static int hf_eap_ms_chap_v2_reserved;
96 static int hf_eap_ms_chap_v2_nt_response;
97 static int hf_eap_ms_chap_v2_flags;
98 static int hf_eap_ms_chap_v2_response;
99 static int hf_eap_ms_chap_v2_message;
100 static int hf_eap_ms_chap_v2_failure_request;
101 static int hf_eap_ms_chap_v2_data;
103 static int hf_eap_pax_opcode;
104 static int hf_eap_pax_flags;
105 static int hf_eap_pax_flags_mf;
106 static int hf_eap_pax_flags_ce;
107 static int hf_eap_pax_flags_ai;
108 static int hf_eap_pax_flags_reserved;
109 static int hf_eap_pax_mac_id;
110 static int hf_eap_pax_dh_group_id;
111 static int hf_eap_pax_public_key_id;
112 static int hf_eap_pax_a_len;
113 static int hf_eap_pax_a;
114 static int hf_eap_pax_b_len;
115 static int hf_eap_pax_b;
116 static int hf_eap_pax_cid_len;
117 static int hf_eap_pax_cid;
118 static int hf_eap_pax_mac_ck_len;
119 static int hf_eap_pax_mac_ck;
120 static int hf_eap_pax_ade_len;
121 static int hf_eap_pax_ade;
122 static int hf_eap_pax_mac_icv;
124 static int hf_eap_psk_flags;
125 static int hf_eap_psk_flags_t;
126 static int hf_eap_psk_flags_reserved;
127 static int hf_eap_psk_rand_p;
128 static int hf_eap_psk_rand_s;
129 static int hf_eap_psk_mac_p;
130 static int hf_eap_psk_mac_s;
131 static int hf_eap_psk_id_p;
132 static int hf_eap_psk_id_s;
133 static int hf_eap_psk_pchannel;
135 static int hf_eap_sake_version;
136 static int hf_eap_sake_session_id;
137 static int hf_eap_sake_subtype;
138 static int hf_eap_sake_attr_type;
139 static int hf_eap_sake_attr_len;
140 static int hf_eap_sake_attr_value;
141 static int hf_eap_sake_attr_value_str;
142 static int hf_eap_sake_attr_value_uint48;
144 static int hf_eap_gpsk_opcode;
145 static int hf_eap_gpsk_id_server_len;
146 static int hf_eap_gpsk_id_server;
147 static int hf_eap_gpsk_id_peer_len;
148 static int hf_eap_gpsk_id_peer;
149 static int hf_eap_gpsk_rand_server;
150 static int hf_eap_gpsk_rand_peer;
151 static int hf_eap_gpsk_csuite_list_len;
152 static int hf_eap_gpsk_csuite_vendor;
153 static int hf_eap_gpsk_csuite_specifier;
154 static int hf_eap_gpsk_pd_payload_len;
155 static int hf_eap_gpsk_pd_payload;
156 static int hf_eap_gpsk_payload_mac;
157 static int hf_eap_gpsk_failure_code;
159 static int hf_eap_msauth_tlv_mandatory;
160 static int hf_eap_msauth_tlv_reserved;
161 static int hf_eap_msauth_tlv_type;
162 static int hf_eap_msauth_tlv_len;
163 static int hf_eap_msauth_tlv_val;
164 static int hf_eap_msauth_tlv_status;
165 static int hf_eap_msauth_tlv_crypto_reserved;
166 static int hf_eap_msauth_tlv_crypto_version;
167 static int hf_eap_msauth_tlv_crypto_rcv_version;
168 static int hf_eap_msauth_tlv_crypto_subtype;
169 static int hf_eap_msauth_tlv_crypto_nonce;
170 static int hf_eap_msauth_tlv_crypto_cmac;
172 static int hf_eap_data;
174 static int ett_eap;
175 static int ett_eap_pax_flags;
176 static int ett_eap_psk_flags;
177 static int ett_eap_sake_attr;
178 static int ett_eap_gpsk_csuite_list;
179 static int ett_eap_gpsk_csuite;
180 static int ett_eap_gpsk_csuite_sel;
181 static int ett_eap_msauth_tlv;
182 static int ett_eap_msauth_tlv_tree;
184 static expert_field ei_eap_ms_chap_v2_length;
185 static expert_field ei_eap_mitm_attacks;
186 static expert_field ei_eap_md5_value_size_overflow;
187 static expert_field ei_eap_dictionary_attacks;
188 static expert_field ei_eap_identity_nonascii;
189 static expert_field ei_eap_identity_invalid;
190 static expert_field ei_eap_retransmission;
191 static expert_field ei_eap_bad_length;
193 static dissector_table_t eap_expanded_type_dissector_table;
195 static dissector_handle_t eap_handle;
197 static dissector_handle_t tls_handle;
198 static dissector_handle_t diameter_avps_handle;
199 static dissector_handle_t peap_handle;
200 static dissector_handle_t teap_handle;
202 static dissector_handle_t isakmp_handle;
204 const value_string eap_code_vals[] = {
205 { EAP_REQUEST, "Request" },
206 { EAP_RESPONSE, "Response" },
207 { EAP_SUCCESS, "Success" },
208 { EAP_FAILURE, "Failure" },
209 { EAP_INITIATE, "Initiate" }, /* [RFC5296] */
210 { EAP_FINISH, "Finish" }, /* [RFC5296] */
211 { 0, NULL }
215 References:
216 1) https://www.iana.org/assignments/ppp-numbers PPP EAP REQUEST/RESPONSE TYPES
217 2) https://tools.ietf.org/html/draft-ietf-pppext-rfc2284bis-02
218 3) RFC2284
219 4) RFC3748
220 5) https://www.iana.org/assignments/eap-numbers EAP registry (updated 2011-02-22)
221 6) https://tools.ietf.org/html/draft-bersani-eap-synthesis-sharedkeymethods-00
224 static const value_string eap_type_vals[] = {
225 { 1, "Identity" },
226 { 2, "Notification" },
227 { 3, "Legacy Nak (Response Only)" },
228 { 4, "MD5-Challenge EAP (EAP-MD5-CHALLENGE)" },
229 { 5, "One-Time Password EAP (EAP-OTP)" },
230 { 6, "Generic Token Card EAP (EAP-GTC)" },
231 { 7, "Allocated" },
232 { 8, "Allocated" },
233 { 9, "RSA Public Key Authentication EAP (EAP-RSA-PKA)" },
234 { 10, "DSS Unilateral EAP (EAP-DSS)" },
235 { 11, "KEA EAP (EAP-KEA)" },
236 { 12, "KEA Validate EAP (EAP-KEA-VALIDATE)" },
237 { 13, "TLS EAP (EAP-TLS)" },
238 { 14, "Defender Token EAP (EAP-AXENT)" },
239 { 15, "RSA Security SecurID EAP (EAP-RSA-SECURID)" },
240 { 16, "Arcot Systems EAP (EAP-ARCOT-SYSTEMS)" },
241 { 17, "Cisco Wireless EAP / Lightweight EAP (EAP-LEAP)" },
242 { 18, "GSM Subscriber Identity Modules EAP (EAP-SIM)" },
243 { 19, "Secure Remote Password SHA1 Part 1 EAP (EAP-SRP-SHA1-PART1)" },
244 { 20, "Secure Remote Password SHA1 Part 2 EAP (EAP-SRP-SHA1-PART2)" },
245 { 21, "Tunneled TLS EAP (EAP-TTLS)" },
246 { 22, "Remote Access Service EAP (EAP-RAS)" },
247 { 23, "UMTS Authentication and Key Agreement EAP (EAP-AKA)" },
248 { 24, "3Com Wireless EAP (EAP-3COM-WIRELESS)" },
249 { 25, "Protected EAP (EAP-PEAP)" },
250 { 26, "MS-Authentication EAP (EAP-MS-AUTH)" },
251 { 27, "Mutual Authentication w/Key Exchange EAP (EAP-MAKE)" },
252 { 28, "CRYPTOCard EAP (EAP-CRYPTOCARD)" },
253 { 29, "MS-CHAP-v2 EAP (EAP-MS-CHAP-V2)" },
254 { 30, "DynamID EAP (EAP-DYNAMID)" },
255 { 31, "Rob EAP (EAP-ROB)" },
256 { 32, "Protected One-Time Password EAP (EAP-POTP)" },
257 { 33, "MS-Authentication TLV EAP (EAP-MS-AUTH-TLV)" },
258 { 34, "SentriNET (EAP-SENTRINET)" },
259 { 35, "Actiontec Wireless EAP (EAP-ACTIONTEC-WIRELESS)" },
260 { 36, "Cogent Systems Biometrics Authentication EAP (EAP-COGENT-BIOMETRIC)" },
261 { 37, "AirFortress EAP (EAP-AIRFORTRESS)" },
262 { 38, "HTTP Digest EAP (EAP-HTTP-DIGEST)" },
263 { 39, "SecureSuite EAP (EAP-SECURESUITE)" },
264 { 40, "DeviceConnect EAP (EAP-DEVICECONNECT)" },
265 { 41, "Simple Password Exponential Key Exchange EAP (EAP-SPEKE)" },
266 { 42, "MOBAC EAP (EAP-MOBAC)" },
267 { 43, "Flexible Authentication via Secure Tunneling EAP (EAP-FAST)" },
268 { 44, "ZoneLabs EAP (EAP-ZLXEAP)" },
269 { 45, "Link EAP (EAP-LINK)" },
270 { 46, "Password Authenticated eXchange EAP (EAP-PAX)" },
271 { 47, "Pre-Shared Key EAP (EAP-PSK)" },
272 { 48, "Shared-secret Authentication and Key Establishment EAP (EAP-SAKE)" },
273 { 49, "Internet Key Exchange v2 EAP (EAP-IKEv2)" },
274 { 50, "UMTS Authentication and Key Agreement' EAP (EAP-AKA')" },
275 { 51, "Generalized Pre-Shared Key EAP (EAP-GPSK)" },
276 { 52, "Password EAP (EAP-pwd)" },
277 { 53, "Encrypted Key Exchange v1 EAP (EAP-EKEv1)" },
278 { 55, "Tunneled EAP protocol" },
279 { 254, "Expanded Type" },
280 { 255, "Experimental" },
281 { 0, NULL }
283 value_string_ext eap_type_vals_ext = VALUE_STRING_EXT_INIT(eap_type_vals);
285 static const value_string eap_identity_prefix_vals[] = {
286 { 0x00, "Encrypted IMSI" },
287 { '0', "EAP-AKA Permanent" },
288 { '1', "EAP-SIM Permanent" },
289 { '2', "EAP-AKA Pseudonym" },
290 { '3', "EAP-SIM Pseudonym" },
291 { '4', "EAP-AKA Reauth ID" },
292 { '5', "EAP-SIM Reauth ID" },
293 { '6', "EAP-AKA Prime Permanent" },
294 { '7', "EAP-AKA Prime Pseudonym" },
295 { '8', "EAP-AKA Prime Reauth ID" },
296 { 'C', "Conservative Peer" },
297 { 'a', "Anonymous Identity" },
298 { 0, NULL }
301 const value_string eap_sim_subtype_vals[] = {
302 { SIM_START, "Start" },
303 { SIM_CHALLENGE, "Challenge" },
304 { SIM_NOTIFICATION, "Notification" },
305 { SIM_RE_AUTHENTICATION, "Re-authentication" },
306 { SIM_CLIENT_ERROR, "Client-Error" },
307 { 0, NULL }
310 const value_string eap_aka_subtype_vals[] = {
311 { AKA_CHALLENGE, "AKA-Challenge" },
312 { AKA_AUTHENTICATION_REJECT, "AKA-Authentication-Reject" },
313 { AKA_SYNCHRONIZATION_FAILURE, "AKA-Synchronization-Failure" },
314 { AKA_IDENTITY, "AKA-Identity" },
315 { AKA_NOTIFICATION, "Notification" },
316 { AKA_REAUTHENTICATION, "Re-authentication" },
317 { AKA_CLIENT_ERROR, "Client-Error" },
318 { 0, NULL }
322 References:
323 1) http://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xml
324 3) RFC4186
325 3) RFC4187
326 4) RFC5448
327 5) 3GPP TS 24.302
328 6) RFC9048
331 #define AT_RAND 1
332 #define AT_AUTN 2
333 #define AT_RES 3
334 #define AT_AUTS 4
335 #define AT_NOTIFICATION 12
336 #define AT_IDENTITY 14
337 #define AT_CLIENT_ERROR_CODE 22
339 static const value_string eap_sim_aka_attribute_vals[] = {
340 { 1, "AT_RAND" },
341 { 2, "AT_AUTN" },
342 { 3, "AT_RES" },
343 { 4, "AT_AUTS" },
344 { 6, "AT_PADDING" },
345 { 7, "AT_NONCE_MT" },
346 { 10, "AT_PERMANENT_ID_REQ" },
347 { 11, "AT_MAC" },
348 { 12, "AT_NOTIFICATION" },
349 { 13, "AT_ANY_ID_REQ" },
350 { 14, "AT_IDENTITY" },
351 { 15, "AT_VERSION_LIST" },
352 { 16, "AT_SELECTED_VERSION" },
353 { 17, "AT_FULLAUTH_ID_REQ" },
354 { 19, "AT_COUNTER" },
355 { 20, "AT_COUNTER_TOO_SMALL" },
356 { 21, "AT_NONCE_S" },
357 { 22, "AT_CLIENT_ERROR_CODE" },
358 { 23, "AT_KDF_INPUT"},
359 { 24, "AT_KDF"},
360 { 128, "Unassigned" },
361 { 129, "AT_IV" },
362 { 130, "AT_ENCR_DATA" },
363 { 131, "Unassigned" },
364 { 132, "AT_NEXT_PSEUDONYM" },
365 { 133, "AT_NEXT_REAUTH_ID" },
366 { 134, "AT_CHECKCODE" },
367 { 135, "AT_RESULT_IND" },
368 { 136, "AT_BIDDING" },
369 { 137, "AT_IPMS_IND" },
370 { 138, "AT_IPMS_RES" },
371 { 139, "AT_TRUST_IND" },
372 { 140, "AT_SHORT_NAME_FOR_NETWORK" },
373 { 141, "AT_FULL_NAME_FOR_NETWORK" },
374 { 142, "AT_RQSI_IND" },
375 { 143, "AT_RQSI_RES" },
376 { 144, "AT_TWAN_CONN_MODE" },
377 { 145, "AT_VIRTUAL_NETWORK_ID" },
378 { 146, "AT_VIRTUAL_NETWORK_REQ" },
379 { 147, "AT_CONNECTIVITY_TYPE" },
380 { 148, "AT_HANDOVER_INDICATION" },
381 { 149, "AT_HANDOVER_SESSION_ID" },
382 { 150, "AT_MN_SERIAL_ID" },
383 { 151, "AT_DEVICE_IDENTITY" },
384 { 0, NULL }
386 static value_string_ext eap_sim_aka_attribute_vals_ext = VALUE_STRING_EXT_INIT(eap_sim_aka_attribute_vals);
388 static const value_string eap_sim_aka_notification_vals[] = {
389 { 0, "General Failure after Authentication" },
390 { 1026, "User has been temporarily denied access" },
391 { 1031, "User has not subscribed to the requested service" },
392 { 8192, "Failure to Terminate the Authentication Exchange" },
393 {16384, "General Failure" },
394 {32768, "Success" },
395 {0, NULL }
398 static const value_string eap_sim_aka_client_error_codes[] = {
399 { 0, "Unable to process packet" },
400 { 1, "Unsupported version" },
401 { 2, "Insufficient number of challenges" },
402 { 3, "RANDs are not fresh" },
403 { 0, NULL }
406 const value_string eap_ms_chap_v2_opcode_vals[] = {
407 { MS_CHAP_V2_CHALLENGE, "Challenge" },
408 { MS_CHAP_V2_RESPONSE, "Response" },
409 { MS_CHAP_V2_SUCCESS, "Success" },
410 { MS_CHAP_V2_FAILURE, "Failure" },
411 { MS_CHAP_V2_CHANGE_PASSWORD, "Change-Password" },
412 { 0, NULL }
415 #define PAX_STD_1 0x01
416 #define PAX_STD_2 0x02
417 #define PAX_STD_3 0x03
418 #define PAX_SEC_1 0x11
419 #define PAX_SEC_2 0x12
420 #define PAX_SEC_3 0x13
421 #define PAX_SEC_4 0x14
422 #define PAX_SEC_5 0x15
423 #define PAX_ACK 0x21
425 static const value_string eap_pax_opcode_vals[] = {
426 { PAX_STD_1, "STD-1" },
427 { PAX_STD_2, "STD-2" },
428 { PAX_STD_3, "STD-3" },
429 { PAX_SEC_1, "SEC-1" },
430 { PAX_SEC_2, "SEC-2" },
431 { PAX_SEC_3, "SEC-3" },
432 { PAX_SEC_4, "SEC-4" },
433 { PAX_SEC_5, "SEC-5" },
434 { PAX_ACK, "ACK" },
435 { 0, NULL }
438 #define EAP_PAX_FLAG_MF 0x01 /* more fragments */
439 #define EAP_PAX_FLAG_CE 0x02 /* certificate enabled */
440 #define EAP_PAX_FLAG_AI 0x04 /* ADE included */
441 #define EAP_PAX_FLAG_RESERVED 0xF8 /* reserved */
443 #define PAX_MAC_ID_HMAC_SHA1_128 0x01
444 #define PAX_MAC_ID_HMAC_SHA256_128 0x02
446 static const value_string eap_pax_mac_id_vals[] = {
447 { PAX_MAC_ID_HMAC_SHA1_128, "HMAC_SHA1_128" },
448 { PAX_MAC_ID_HMAC_SHA256_128, "HMAXĆ_SHA256_128" },
449 { 0, NULL }
452 #define PAX_DH_GROUP_ID_NONE 0x00
453 #define PAX_DH_GROUP_ID_DH_14 0x01
454 #define PAX_DH_GROUP_ID_DH_15 0x02
455 #define PAX_DH_GROUP_ID_ECC_P256 0x03
457 static const value_string eap_pax_dh_group_id_vals[] = {
458 { PAX_DH_GROUP_ID_NONE, "NONE" },
459 { PAX_DH_GROUP_ID_DH_14, "2048-bit MODP Group (IANA DH Group 14)" },
460 { PAX_DH_GROUP_ID_DH_15, "3072-bit MODP Group (IANA DH Group 15)" },
461 { PAX_DH_GROUP_ID_ECC_P256, "NIST ECC Group P-256" },
462 { 0, NULL }
465 #define PAX_PUBLIC_KEY_ID_NONE 0x00
466 #define PAX_PUBLIC_KEY_ID_RSAES_OAEP 0x01
467 #define PAX_PUBLIC_KEY_ID_RSA_PKCS1_V1_5 0x02
468 #define PAX_PUBLIC_KEY_ID_EL_GAMAL_ECC_P256 0x03
470 static const value_string eap_pax_public_key_id_vals[] = {
471 { PAX_PUBLIC_KEY_ID_NONE, "NONE" },
472 { PAX_PUBLIC_KEY_ID_RSAES_OAEP, "RSAES-OAEP" },
473 { PAX_PUBLIC_KEY_ID_RSA_PKCS1_V1_5, "RSA-PKCS1-V1_5" },
474 { PAX_PUBLIC_KEY_ID_EL_GAMAL_ECC_P256, "El-Gamal Over NIST ECC Group P-256" },
475 { 0, NULL }
478 #define EAP_PSK_FLAGS_T_MASK 0xC0
480 #define SAKE_CHALLENGE 1
481 #define SAKE_CONFIRM 2
482 #define SAKE_AUTH_REJECT 3
483 #define SAKE_IDENTITY 4
485 static const value_string eap_sake_subtype_vals[] = {
486 { SAKE_CHALLENGE, "SAKE/Challenge" },
487 { SAKE_CONFIRM, "SAKE/Confirm" },
488 { SAKE_AUTH_REJECT, "SAKE/Auth-Reject" },
489 { SAKE_IDENTITY, "SAKE/Identity" },
490 { 0, NULL }
493 #define SAKE_AT_RAND_S 1
494 #define SAKE_AT_RAND_P 2
495 #define SAKE_AT_MIC_S 3
496 #define SAKE_AT_MIC_P 4
497 #define SAKE_AT_SERVERID 5
498 #define SAKE_AT_PEERID 6
499 #define SAKE_AT_SPI_S 7
500 #define SAKE_AT_SPI_P 8
501 #define SAKE_AT_ANY_ID_REQ 9
502 #define SAKE_AT_PERM_ID_REQ 10
503 #define SAKE_AT_ENCR_DATA 128
504 #define SAKE_AT_IV 129
505 #define SAKE_AT_PADDING 130
506 #define SAKE_AT_NEXT_TMPID 131
507 #define SAKE_AT_MSK_LIFE 132
509 static const value_string eap_sake_attr_type_vals[] = {
510 { SAKE_AT_RAND_S, "Server Nonce RAND_S" },
511 { SAKE_AT_RAND_P, "Peer Nonce RAND_P" },
512 { SAKE_AT_MIC_S, "Server MIC" },
513 { SAKE_AT_MIC_P, "Peer MIC" },
514 { SAKE_AT_SERVERID, "Server FQDN" },
515 { SAKE_AT_PEERID, "Peer NAI (tmp, perm)" },
516 { SAKE_AT_SPI_S, "Server chosen SPI SPI_S" },
517 { SAKE_AT_SPI_P, "Peer SPI list SPI_P" },
518 { SAKE_AT_ANY_ID_REQ, "Requires any Peer Id (tmp, perm)" },
519 { SAKE_AT_PERM_ID_REQ, "Requires Peer's permanent Id/NAI" },
520 { SAKE_AT_ENCR_DATA, "Contains encrypted attributes" },
521 { SAKE_AT_IV, "IV for encrypted attributes" },
522 { SAKE_AT_PADDING, "Padding for encrypted attributes" },
523 { SAKE_AT_NEXT_TMPID, "TempID for next EAP-SAKE phase" },
524 { SAKE_AT_MSK_LIFE, "MSK Lifetime" },
525 { 0, NULL }
528 #define GPSK_RESERVED 0
529 #define GPSK_GPSK_1 1
530 #define GPSK_GPSK_2 2
531 #define GPSK_GPSK_3 3
532 #define GPSK_GPSK_4 4
533 #define GPSK_FAIL 5
534 #define GPSK_PROTECTED_FAIL 6
536 static const value_string eap_gpsk_opcode_vals[] = {
537 { GPSK_RESERVED, "Reserved" },
538 { GPSK_GPSK_1, "GPSK-1" },
539 { GPSK_GPSK_2, "GPSK-2" },
540 { GPSK_GPSK_3, "GPSK-3" },
541 { GPSK_GPSK_4, "GPSK-4" },
542 { GPSK_FAIL, "Fail" },
543 { GPSK_PROTECTED_FAIL, "Protected Fail" },
544 { 0, NULL }
547 static const value_string eap_gpsk_failure_code_vals[] = {
548 { 0x00000000, "Reserved" },
549 { 0x00000001, "PSK Not Found" },
550 { 0x00000002, "Authentication Failure" },
551 { 0x00000003, "Authorization Failure" },
552 { 0, NULL }
555 #define MSAUTH_TLV_MANDATORY 0x8000
556 #define MSAUTH_TLV_RESERVED 0x4000
557 #define MSAUTH_TLV_TYPE 0x3FFF
559 #define MSAUTH_TLV_TYPE_EXTENSION_UNASSIGNED 0
560 #define MSAUTH_TLV_TYPE_EXTENSION_RESULT 3
561 #define MSAUTH_TLV_TYPE_EXTENSION_CRYPTOBINDING 12
563 #define MSAUTH_TLV_TYPE_EXPANDED_SOH 33
565 static const value_string eap_msauth_tlv_type_vals[] = {
566 { MSAUTH_TLV_TYPE_EXTENSION_UNASSIGNED, "Unassigned" },
567 { MSAUTH_TLV_TYPE_EXTENSION_RESULT, "Result" },
568 { MSAUTH_TLV_TYPE_EXTENSION_CRYPTOBINDING, "Cryptobinding" },
569 { 0, NULL }
572 static const value_string eap_msauth_tlv_status_vals[] = {
573 { 1, "Success" },
574 { 2, "Failure" },
575 { 0, NULL }
578 static const value_string eap_msauth_tlv_crypto_subtype_vals[] = {
579 { 0, "Binding Request" },
580 { 1, "Binding Response" },
581 { 0, NULL }
585 * State information for EAP-TLS (RFC2716) and Lightweight EAP:
587 * http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
589 * Attach to all conversations:
591 * a sequence number to be handed to "fragment_add_seq()" as
592 * the fragment sequence number - if it's -1, no reassembly
593 * is in progress, but if it's not, it's the sequence number
594 * to use for the current fragment;
596 * a value to be handed to "fragment_add_seq()" as the
597 * reassembly ID - when a reassembly is started, it's set to
598 * the frame number of the current frame, i.e. the frame
599 * that starts the reassembly;
601 * an indication of the current state of LEAP negotiation,
602 * with -1 meaning no LEAP negotiation is in progress.
604 * Attach to frames containing fragments of EAP-TLS messages the
605 * reassembly ID for those fragments, so we can find the reassembled
606 * data after the first pass through the packets.
608 * Attach to LEAP frames the state of the LEAP negotiation when the
609 * frame was processed, so we can properly dissect
610 * the LEAP message after the first pass through the packets.
612 * Attach to all conversations both pieces of information, to keep
613 * track of EAP-TLS reassembly and the LEAP state machine.
616 typedef struct {
617 int eap_tls_seq;
618 uint32_t eap_reass_cookie;
619 int leap_state;
620 int16_t last_eap_id_req; /* Last ID of the request from the authenticator. */
621 int16_t last_eap_id_resp; /* Last ID of the response from the peer. */
622 } conv_state_t;
624 typedef struct {
625 int info; /* interpretation depends on EAP message type */
626 } frame_state_t;
629 from RFC5216, pg 21
631 Flags
633 0 1 2 3 4 5 6 7 8
634 +-+-+-+-+-+-+-+-+
635 |L M S R R R R R| TLS (RFC5216)
636 +-+-+-+-+-+-+-+-+
637 |L M S R R| V | TTLS (RFC5281) and FAST (RFC4851)
638 +-+-+-+-+-+-+-+-+
639 |L M S O R| V | TEAP (RFC7170)
640 +-+-+-+-+-+-+-+-+
641 |L M S R R R| V | PEAPv0 (draft-kamath-pppext-peapv0)
642 +-+-+-+-+-+-+-+-+
643 |L M S R R| V | PEAPv1 (draft-josefsson-pppext-eap-tls-eap-06) and PEAPv2 (draft-josefsson-pppext-eap-tls-eap-10)
644 +-+-+-+-+-+-+-+-+
646 L = Length included
647 M = More fragments
648 S = EAP-TLS start
649 O = Outer TLV length included (TEAP only)
650 R = Reserved
651 V = TTLS/FAST/TEAP/PEAP version (Reserved for TLS)
654 #define EAP_TLS_FLAG_L 0x80 /* Length included */
655 #define EAP_TLS_FLAG_M 0x40 /* More fragments */
656 #define EAP_TLS_FLAG_S 0x20 /* EAP-TLS start */
657 #define EAP_TLS_FLAG_O 0x10 /* Outer TLV length included */
659 #define EAP_TLS_FLAGS_VERSION 0x07 /* Version mask */
662 * reassembly of EAP-TLS
664 static reassembly_table eap_tls_reassembly_table;
666 static int hf_eap_tls_flags;
667 static int hf_eap_tls_flag_l;
668 static int hf_eap_tls_flag_m;
669 static int hf_eap_tls_flag_s;
670 static int hf_eap_tls_flag_o;
671 static int hf_eap_tls_flags_version;
672 static int hf_eap_tls_len;
673 static int hf_eap_tls_outer_tlvs_len;
674 static int hf_eap_tls_fragment;
675 static int hf_eap_tls_fragments;
676 static int hf_eap_tls_fragment_overlap;
677 static int hf_eap_tls_fragment_overlap_conflict;
678 static int hf_eap_tls_fragment_multiple_tails;
679 static int hf_eap_tls_fragment_too_long_fragment;
680 static int hf_eap_tls_fragment_error;
681 static int hf_eap_tls_fragment_count;
682 static int hf_eap_tls_reassembled_in;
683 static int hf_eap_tls_reassembled_length;
684 static int hf_eap_fast_type;
685 static int hf_eap_fast_length;
686 static int hf_eap_fast_aidd;
687 static int ett_eap_tls_fragment;
688 static int ett_eap_tls_fragments;
689 static int ett_eap_sim_attr;
690 static int ett_eap_aka_attr;
691 static int ett_eap_exp_attr;
692 static int ett_eap_tls_flags;
693 static int ett_identity;
694 static int ett_eap_ikev2_flags;
696 static const fragment_items eap_tls_frag_items = {
697 &ett_eap_tls_fragment,
698 &ett_eap_tls_fragments,
699 &hf_eap_tls_fragments,
700 &hf_eap_tls_fragment,
701 &hf_eap_tls_fragment_overlap,
702 &hf_eap_tls_fragment_overlap_conflict,
703 &hf_eap_tls_fragment_multiple_tails,
704 &hf_eap_tls_fragment_too_long_fragment,
705 &hf_eap_tls_fragment_error,
706 &hf_eap_tls_fragment_count,
707 &hf_eap_tls_reassembled_in,
708 &hf_eap_tls_reassembled_length,
709 /* Reassembled data field */
710 NULL,
711 "fragments"
716 * EAP-IKE2, RFC5106
720 RFC5106, 8.1, page 17
722 0 1 2 3 4 5 6 7
723 +-+-+-+-+-+-+-+-+
724 |L M I 0 0 0 0 0|
725 +-+-+-+-+-+-+-+-+
727 L = Length included
728 M = More fragments
729 I = Integrity Checksum Data included
731 #define EAP_IKEV2_FLAG_L 0x80 /* Length included */
732 #define EAP_IKEV2_FLAG_M 0x40 /* More fragments */
733 #define EAP_IKEV2_FLAG_I 0x20 /* Integrity checksum data included */
735 static int hf_eap_ikev2_flags;
736 static int hf_eap_ikev2_flag_l;
737 static int hf_eap_ikev2_flag_m;
738 static int hf_eap_ikev2_flag_i;
739 static int hf_eap_ikev2_len;
740 static int hf_eap_ikev2_int_chk_data;
742 /**********************************************************************
743 Support for EAP Expanded Type.
745 Currently this is limited to WifiProtectedSetup. Maybe we need
746 a generic method to support EAP extended types ?
747 *********************************************************************/
748 static int hf_eap_ext_vendor_id;
749 static int hf_eap_ext_vendor_type;
751 static const value_string eap_ext_vendor_id_vals[] = {
752 { WFA_VENDOR_ID, "WFA" },
753 { 0, NULL }
756 static const value_string eap_ext_vendor_type_vals[] = {
757 { WFA_SIMPLECONFIG_TYPE, "SimpleConfig" },
758 { 0, NULL }
761 static void
762 dissect_exteap(proto_tree *eap_tree, tvbuff_t *tvb, int offset,
763 int size _U_, packet_info* pinfo, uint8_t eap_code, uint8_t eap_identifier)
765 tvbuff_t *next_tvb;
766 uint32_t vendor_id;
767 uint32_t vendor_type;
768 eap_vendor_context *vendor_context;
770 vendor_context = wmem_new(pinfo->pool, eap_vendor_context);
772 proto_tree_add_item_ret_uint(eap_tree, hf_eap_ext_vendor_id, tvb, offset, 3, ENC_BIG_ENDIAN, &vendor_id);
773 offset += 3;
775 proto_tree_add_item_ret_uint(eap_tree, hf_eap_ext_vendor_type, tvb, offset, 4, ENC_BIG_ENDIAN, &vendor_type);
776 offset += 4;
778 vendor_context->eap_code = eap_code;
779 vendor_context->eap_identifier = eap_identifier;
780 vendor_context->vendor_id = vendor_id;
781 vendor_context->vendor_type = vendor_type;
783 next_tvb = tvb_new_subset_remaining(tvb, offset);
784 if (!dissector_try_uint_with_data(eap_expanded_type_dissector_table,
785 vendor_id, next_tvb, pinfo, eap_tree,
786 false, vendor_context)) {
787 call_data_dissector(next_tvb, pinfo, eap_tree);
790 /* *********************************************************************
791 ********************************************************************* */
793 static void
794 dissect_eap_mschapv2(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
795 int size)
797 proto_item *item;
798 int left = size;
799 int ms_len;
800 uint8_t value_size;
801 uint8_t opcode;
803 /* OpCode (1 byte), MS-CHAPv2-ID (1 byte), MS-Length (2 bytes), Data */
804 opcode = tvb_get_uint8(tvb, offset);
805 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
806 offset += 1;
807 left -= 1;
808 if (left <= 0)
809 return;
811 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_id, tvb, offset, 1, ENC_BIG_ENDIAN);
812 offset += 1;
813 left -= 1;
814 if (left <= 0)
815 return;
817 item = proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_length, tvb, offset, 2, ENC_BIG_ENDIAN);
818 ms_len = tvb_get_ntohs(tvb, offset);
819 if (ms_len != size)
820 expert_add_info(pinfo, item, &ei_eap_ms_chap_v2_length);
821 offset += 2;
822 left -= 2;
824 switch (opcode) {
825 case MS_CHAP_V2_CHALLENGE:
826 if (left <= 0)
827 break;
828 value_size = tvb_get_uint8(tvb, offset);
829 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_value_size,
830 tvb, offset, 1, ENC_BIG_ENDIAN);
831 offset += 1;
832 left -= 1;
833 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_challenge,
834 tvb, offset, value_size, ENC_NA);
835 offset += value_size;
836 left -= value_size;
837 if (left <= 0)
838 break;
839 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_name,
840 tvb, offset, left, ENC_ASCII);
841 break;
842 case MS_CHAP_V2_RESPONSE:
843 if (left <= 0)
844 break;
845 value_size = tvb_get_uint8(tvb, offset);
846 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_value_size,
847 tvb, offset, 1, ENC_BIG_ENDIAN);
848 offset += 1;
849 left -= 1;
850 if (value_size == 49) {
851 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_peer_challenge,
852 tvb, offset, 16, ENC_NA);
853 offset += 16;
854 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_reserved,
855 tvb, offset, 8, ENC_NA);
856 offset += 8;
857 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_nt_response,
858 tvb, offset, 24, ENC_NA);
859 offset += 24;
860 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_flags,
861 tvb, offset, 1, ENC_BIG_ENDIAN);
862 offset += 1;
863 left -= value_size;
864 } else {
865 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_response, tvb, offset, value_size, ENC_NA);
866 offset += value_size;
867 left -= value_size;
869 if (left <= 0)
870 break;
871 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_name, tvb, offset, left, ENC_ASCII);
872 break;
873 case MS_CHAP_V2_SUCCESS:
874 if (left <= 0)
875 break;
876 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_message,
877 tvb, offset, left, ENC_ASCII);
878 break;
879 case MS_CHAP_V2_FAILURE:
880 if (left <= 0)
881 break;
882 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_failure_request,
883 tvb, offset, left, ENC_ASCII);
884 break;
885 default:
886 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_data, tvb, offset, left, ENC_NA);
887 break;
891 static bool
892 realm_is_3gpp(char** realm_tokens, unsigned *nrealm_tokensp)
894 unsigned nrealm_tokens = g_strv_length(realm_tokens);
895 if (nrealm_tokensp) {
896 *nrealm_tokensp = nrealm_tokens;
899 if (nrealm_tokens < 5 ||
900 g_ascii_strncasecmp(realm_tokens[nrealm_tokens - 4], "mnc", 3) ||
901 g_ascii_strncasecmp(realm_tokens[nrealm_tokens - 3], "mcc", 3) ||
902 g_ascii_strncasecmp(realm_tokens[nrealm_tokens - 2], "3gppnetwork", 11) ||
903 g_ascii_strncasecmp(realm_tokens[nrealm_tokens - 1], "org", 3)) {
904 return false;
906 return true;
909 /* Dissect the 3GPP identity */
910 bool
911 dissect_eap_identity_3gpp(tvbuff_t *tvb, packet_info* pinfo, proto_tree* tree, int offset, int size)
913 unsigned mnc = 0;
914 unsigned mcc = 0;
915 unsigned mcc_mnc = 0;
916 proto_tree* eap_identity_tree = NULL;
917 uint32_t eap_identity_prefix = 0;
918 uint8_t* identity = NULL;
919 char** tokens = NULL;
920 char** realm_tokens = NULL;
921 unsigned ntokens = 0;
922 unsigned nrealm_tokens = 0;
923 const char* mnc_token;
924 const char* mcc_token;
925 bool ret = false;
926 int hf_eap_identity_mcc_mnc;
927 proto_item* item;
929 /* See 3GPP TS 23.003, 3GPP TS 29.273, and RFCs 4186, 4187, 5247, 9048.
931 * XXX - The possible use of "Decorated NAIs" (prepending a string for
932 * source routing as described in RFC 4282 Section 2.7) is not handled
933 * here. We would need to process '!' as a delimiter in the username.
936 /* Check for Encrypted IMSI - NULL prefix byte */
937 if (tvb_get_uint8(tvb, offset) == 0x00) {
938 /* Check if the identity string complies with ASCII character set. Encrypted IMSI
939 * identities use Base64 encoding and should therefore be ASCII-compliant.
941 if (size < 2 || tvb_ascii_isprint(tvb, offset + 1, size - 1) == false) {
942 goto end;
944 identity = tvb_get_string_enc(pinfo->pool, tvb, offset + 1, size - 1, ENC_ASCII);
945 /* Encrypted IMSIs must be delimited twice:
946 * (1) Once to tokenize the 3GPP realm from the Certificate Serial Number
947 * using the ',' character
948 * (2) Once to tokenize the 3GPP realm using the '@' character
950 tokens = g_strsplit_set(identity, ",", -1);
952 ntokens = g_strv_length(tokens);
953 if (ntokens < 2 || g_ascii_strncasecmp(tokens[1], "CertificateSerialNumber=", strlen("CertificateSerialNumber="))) {
954 goto end;
957 /* The Realm is optional in the Encrypted IMSI format, apparently.
958 * So add the prefix, identity, and cert before checking for the realm.
959 * Consider the dissection successful and return true from this point.
961 ret = true;
963 /* Skip the null byte when adding the full identity to avoid an expert info.
964 * (Does escaping it make sense?)
966 item = proto_tree_add_item(tree, hf_eap_identity_full, tvb, offset + 1, size - 1, ENC_ASCII);
967 eap_identity_tree = proto_item_add_subtree(item, ett_identity);
968 proto_tree_add_item_ret_uint(eap_identity_tree, hf_eap_identity_prefix, tvb, offset, 1, ENC_NA, &eap_identity_prefix);
969 proto_tree_add_string(eap_identity_tree, hf_eap_identity_type,
970 tvb, offset, 1, val_to_str_const(eap_identity_prefix, eap_identity_prefix_vals, "Unknown"));
971 offset += 1;
972 size -= 1;
974 #if 0
975 /* XXX - Would adding the Base64 decoded (but still encrypted) IMSI
976 * be of any use?
978 tvbuff_t *decoded_tvb = base64_to_tvb(tvb, tokens[0]);
979 if (tvb_reported_length(decoded_tvb)) {
980 add_new_data_source(pinfo, decoded_tvb, "Encrypted IMSI");
982 #endif
984 /* We have already checked above that the identity was valid ASCII so
985 * offsets in the tokens are the same as in the TVB. */
986 proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset, (int)strlen(tokens[0]), ENC_ASCII);
987 offset += (int)(strlen(tokens[0]) + 1 + strlen("CertificateSerialNumber="));
988 const char* cert = tokens[1] + strlen("CertificateSerialNumber=");
990 /* Add Certificate Serial Number to the tree */
991 proto_tree_add_item(eap_identity_tree, hf_eap_identity_certificate_sn, tvb,
992 offset, (int)strlen(cert), ENC_ASCII);
994 /* Check for the optional NAI Realm string */
995 if (ntokens != 3 || g_ascii_strncasecmp(tokens[2], "Realm=", 6)) {
996 goto end;
999 const char* realm = strchr(tokens[2], '@');
1000 if (!realm) {
1001 goto end;
1004 realm += 1;
1005 realm_tokens = g_strsplit_set(realm, ".", -1);
1007 /* Check for a realm of the form
1008 .mnc<mnc>.mcc<mcc>.3gppnetwork.org
1010 if (!realm_is_3gpp(realm_tokens, &nrealm_tokens)) {
1011 goto end;
1013 } else {
1014 /* Check if identity string complies with ASCII character set */
1015 if (tvb_ascii_isprint(tvb, offset, size) == false) {
1016 goto end;
1018 /* All other identities may be delimited with the '@' character */
1019 identity = tvb_get_string_enc(pinfo->pool, tvb, offset, size, ENC_ASCII);
1020 tokens = g_strsplit_set(identity, "@", -1);
1022 ntokens = g_strv_length(tokens);
1023 /* tokens[0] is the identity, tokens[1] is the NAI Realm */
1024 if (ntokens != 2) {
1025 goto end;
1028 /* Check for valid EAP Identity strings based on tokens and 3GPP-format */
1029 realm_tokens = g_strsplit_set(tokens[1], ".", -1);
1031 /* The identity must have the form of
1032 <username>@...mnc<mnc>.mcc<mcc>.3gppnetwork.org
1033 If not, we don't have a 3GPP identity.
1035 if (!realm_is_3gpp(realm_tokens, &nrealm_tokens)) {
1036 goto end;
1039 const char* label = realm_tokens[nrealm_tokens - 5];
1041 /* We have a 3GPP realm. Add the full identity, and a tree to add the
1042 * MNC and MCC below.
1044 ret = true;
1045 item = proto_tree_add_item(tree, hf_eap_identity_full, tvb, offset, size, ENC_ASCII);
1046 eap_identity_tree = proto_item_add_subtree(item, ett_identity);
1048 if ((g_ascii_strncasecmp(label, "wlan", 4) == 0) ||
1049 (g_ascii_strncasecmp(label, "epc", 3) == 0) ||
1050 (g_ascii_strncasecmp(label, "gan", 3) == 0)) {
1052 /* It is very likely that we have an identity (EAP-AKA/EAP-SIM) using
1053 * a single-character prefix. (XXX - Perhaps not all of these should
1054 * be treated as prefixes. GAN might not use the prefix for fast
1055 * re-authentication.) */
1056 proto_tree_add_item_ret_uint(eap_identity_tree, hf_eap_identity_prefix, tvb, offset, 1, ENC_NA, &eap_identity_prefix);
1057 item = proto_tree_add_string(eap_identity_tree, hf_eap_identity_type,
1058 tvb, offset, 1, val_to_str_const(eap_identity_prefix, eap_identity_prefix_vals, "Unknown"));
1060 switch(eap_identity_prefix) {
1061 case '0': /* EAP-AKA Permanent */
1062 case '1': /* EAP-SIM Permanent */
1063 case '6': /* EAP-AKA' Permanent */
1064 dissect_e212_utf8_imsi(tvb, pinfo, eap_identity_tree, offset + 1, (unsigned)strlen(tokens[0]) - 1);
1065 break;
1066 case '2': /* EAP-AKA Pseudonym */
1067 case '3': /* EAP-SIM Pseudonym */
1068 case '7': /* EAP-AKA' Pseudonym */
1069 proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (unsigned)strlen(tokens[0]) - 1, ENC_ASCII);
1070 break;
1071 case '4': /* EAP-AKA Reauth ID */
1072 case '5': /* EAP-SIM Reauth ID */
1073 case '8': /* EAP-AKA' Reauth ID */
1074 proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (unsigned)strlen(tokens[0]) - 1, ENC_ASCII);
1075 break;
1076 case 'C': /* Conservative Peer */
1077 proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (unsigned)strlen(tokens[0]) - 1, ENC_ASCII);
1078 break;
1079 case 'a': /* Anonymous User */
1080 /* This is not really a prefix, just a username "anonymous" */
1081 proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset, (unsigned)strlen(tokens[0]), ENC_ASCII);
1082 break;
1083 case 'G': /* TODO: 'G' Unknown */
1084 case 'I': /* TODO: 'I' Unknown */
1085 default:
1086 proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (unsigned)strlen(tokens[0]) - 1, ENC_ASCII);
1087 expert_add_info(pinfo, item, &ei_eap_identity_invalid);
1089 } else {
1090 /* It's a 3GPP realm, but probably not using a prefix, e.g. in 5G. */
1091 proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset, (int)strlen(tokens[0]), ENC_ASCII);
1095 /* EAP identities do not always equate to IMSIs. We should
1096 * still add the MCC and MNC values if present. */
1097 mnc_token = realm_tokens[nrealm_tokens - 4];
1098 mcc_token = realm_tokens[nrealm_tokens - 3];
1099 if (!ws_strtou(mnc_token + 3, NULL, &mnc) || !ws_strtou(mcc_token + 3, NULL, &mcc)) {
1100 goto end;
1103 if (!try_val_to_str_ext(mcc * 100 + mnc, &mcc_mnc_2digits_codes_ext)) {
1104 /* May have
1105 * (1) an invalid 2-digit MNC so it won't resolve,
1106 * (2) an invalid 3-digit MNC so it won't resolve, or
1107 * (3) a valid 3-digit MNC.
1108 * For all cases we treat as 3-digit MNC and continue. */
1109 mcc_mnc = 1000 * mcc + mnc;
1110 hf_eap_identity_mcc_mnc = hf_eap_identity_mcc_mnc_3digits;
1111 } else {
1112 /* We got a 2-digit MNC match */
1113 mcc_mnc = 100 * mcc + mnc;
1114 hf_eap_identity_mcc_mnc = hf_eap_identity_mcc_mnc_2digits;
1117 offset = tvb_find_uint8(tvb, offset, size, '@');
1118 if (offset != -1) {
1119 /* Should always be true. */
1120 offset += 1;
1121 for (int i = 0; realm_tokens[i] != mnc_token; ++i) {
1122 offset += (int)(strlen(realm_tokens[i])) + 1;
1124 /* XXX - This presentation order is the opposite of the "usual" one.
1125 * Move the MCC item above after adding? (#16538)
1127 /* Add MNC to tree */
1128 proto_tree_add_uint(eap_identity_tree, hf_eap_identity_mcc_mnc, tvb,
1129 offset + (int)strlen("mnc"), (int)strlen(mnc_token) - (int)strlen("mnc"), mcc_mnc);
1130 offset += (int)strlen(mnc_token) + 1;
1131 /* Add MCC to tree */
1132 proto_tree_add_uint(eap_identity_tree, hf_eap_identity_mcc, tvb,
1133 offset + (int)strlen("mcc"), (int)strlen(mcc_token) - (int)strlen("mcc"), mcc);
1136 end:
1137 g_strfreev(tokens);
1138 g_strfreev(realm_tokens);
1140 return ret;
1143 static void
1144 dissect_eap_identity(tvbuff_t *tvb, packet_info* pinfo, proto_tree* tree, int offset, int size)
1146 proto_item *item;
1148 * Try to dissect as a 3GPP identity.
1150 * XXX - what other types of identity are there?
1152 if (!dissect_eap_identity_3gpp(tvb, pinfo, tree, offset, size)) {
1153 item = proto_tree_add_item(tree, hf_eap_identity, tvb, offset, size, ENC_ASCII);
1154 /* XXX - RFC 7542 revises earlier standards by allowing UTF-8 in the
1155 * NAI (username and realm); if this happens in EAP, remove the expert info. */
1156 if (tvb_ascii_isprint(tvb, offset, size) == false) {
1157 expert_add_info(pinfo, item, &ei_eap_identity_nonascii);
1162 static void
1163 dissect_eap_sim(proto_tree *eap_tree, tvbuff_t *tvb, packet_info* pinfo, int offset, int size)
1165 int left = size;
1167 proto_tree_add_item(eap_tree, hf_eap_sim_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
1169 offset += 1;
1170 left -= 1;
1172 if (left < 2)
1173 return;
1174 proto_tree_add_item(eap_tree, hf_eap_sim_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
1175 offset += 2;
1176 left -= 2;
1178 /* Rest of EAP-SIM data is in Type-Len-Value format. */
1179 while (left >= 2) {
1180 uint8_t type, length;
1181 int padding;
1182 proto_item *pi;
1183 proto_tree *attr_tree;
1184 int aoffset;
1185 int aleft;
1187 aoffset = offset;
1188 type = tvb_get_uint8(tvb, aoffset);
1189 length = tvb_get_uint8(tvb, aoffset + 1);
1190 aleft = 4 * length;
1192 pi = proto_tree_add_none_format(eap_tree, hf_eap_sim_subtype_attribute, tvb,
1193 aoffset, aleft, "EAP-SIM Attribute: %s (%d)",
1194 val_to_str_ext_const(type,
1195 &eap_sim_aka_attribute_vals_ext,
1196 "Unknown"),
1197 type);
1198 attr_tree = proto_item_add_subtree(pi, ett_eap_sim_attr);
1199 proto_tree_add_uint(attr_tree, hf_eap_sim_subtype_type, tvb, aoffset, 1, type);
1200 aoffset += 1;
1201 aleft -= 1;
1203 if (aleft <= 0)
1204 break;
1205 proto_tree_add_item(attr_tree, hf_eap_sim_subtype_length, tvb, aoffset, 1, ENC_BIG_ENDIAN);
1206 aoffset += 1;
1207 aleft -= 1;
1209 switch(type){
1210 case AT_IDENTITY:
1211 proto_tree_add_item(attr_tree, hf_eap_identity_actual_len, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1212 dissect_eap_identity(tvb, pinfo, attr_tree, aoffset + 2, tvb_get_ntohs(tvb, aoffset));
1213 /* If we have a disparity between the EAP-SIM length (minus the
1214 * first 4 bytes of header fields) * 4 and the Identity Actual
1215 * Length then it's padding and we need to adjust for that
1216 * accurately before looking at the next EAP-SIM attribute. */
1217 padding = ((length - 1) * 4) - tvb_get_ntohs(tvb, aoffset);
1218 if (padding != 0) {
1219 proto_tree_add_item(attr_tree, hf_eap_identity_padding, tvb,
1220 aoffset + 2 + tvb_get_ntohs(tvb, aoffset), padding, ENC_NA);
1222 break;
1223 case AT_NOTIFICATION:
1224 proto_tree_add_item(attr_tree, hf_eap_sim_notification_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1225 break;
1226 case AT_CLIENT_ERROR_CODE:
1227 proto_tree_add_item(attr_tree, hf_eap_sim_error_code_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1228 break;
1229 default:
1230 proto_tree_add_item(attr_tree, hf_eap_sim_subtype_value, tvb, aoffset, aleft, ENC_NA);
1233 offset += 4 * length;
1234 left -= 4 * length;
1238 static void
1239 dissect_eap_aka(proto_tree *eap_tree, tvbuff_t *tvb, packet_info* pinfo, int offset, int size)
1241 int left = size;
1243 proto_tree_add_item(eap_tree, hf_eap_aka_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
1245 offset += 1;
1246 left -= 1;
1248 if (left < 2)
1249 return;
1250 proto_tree_add_item(eap_tree, hf_eap_aka_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
1251 offset += 2;
1252 left -= 2;
1254 /* Rest of EAP-AKA data is in Type-Len-Value format. */
1255 while (left >= 2) {
1256 uint8_t type, length;
1257 uint32_t actual_length;
1258 int padding;
1259 proto_item *pi;
1260 proto_tree *attr_tree;
1261 int aoffset;
1262 int aleft;
1264 aoffset = offset;
1265 type = tvb_get_uint8(tvb, aoffset);
1266 length = tvb_get_uint8(tvb, aoffset + 1);
1267 aleft = 4 * length;
1269 pi = proto_tree_add_none_format(eap_tree, hf_eap_aka_subtype_attribute, tvb,
1270 aoffset, aleft, "EAP-AKA Attribute: %s (%d)",
1271 val_to_str_ext_const(type,
1272 &eap_sim_aka_attribute_vals_ext,
1273 "Unknown"),
1274 type);
1275 attr_tree = proto_item_add_subtree(pi, ett_eap_aka_attr);
1276 proto_tree_add_uint(attr_tree, hf_eap_aka_subtype_type, tvb, aoffset, 1, type);
1277 aoffset += 1;
1278 aleft -= 1;
1280 if (aleft <= 0)
1281 break;
1282 proto_tree_add_item(attr_tree, hf_eap_aka_subtype_length, tvb, aoffset, 1, ENC_BIG_ENDIAN);
1283 aoffset += 1;
1284 aleft -= 1;
1286 switch(type){
1287 case AT_RAND:
1288 proto_tree_add_item(attr_tree, hf_eap_aka_reserved, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1289 aoffset += 2;
1290 aleft -= 2;
1291 proto_tree_add_item(attr_tree, hf_eap_aka_rand, tvb, aoffset, aleft, ENC_NA);
1292 break;
1293 case AT_AUTN:
1294 proto_tree_add_item(attr_tree, hf_eap_aka_reserved, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1295 aoffset += 2;
1296 aleft -= 2;
1297 proto_tree_add_item(attr_tree, hf_eap_aka_autn, tvb, aoffset, aleft, ENC_NA);
1298 break;
1299 case AT_RES:
1300 proto_tree_add_item_ret_uint(attr_tree, hf_eap_aka_res_len, tvb, aoffset, 2, ENC_BIG_ENDIAN, &actual_length);
1301 aoffset += 2;
1302 proto_tree_add_bits_item(attr_tree, hf_eap_aka_res, tvb, aoffset << 3, actual_length, ENC_NA);
1303 break;
1304 case AT_AUTS:
1305 proto_tree_add_item(attr_tree, hf_eap_aka_auts, tvb, aoffset, aleft, ENC_NA);
1306 break;
1307 case AT_IDENTITY:
1308 proto_tree_add_item_ret_uint(attr_tree, hf_eap_identity_actual_len, tvb, aoffset, 2, ENC_BIG_ENDIAN, &actual_length);
1309 dissect_eap_identity(tvb, pinfo, attr_tree, aoffset + 2, actual_length);
1310 /* If we have a disparity between the EAP-AKA length (minus the
1311 * first 4 bytes of header fields) * 4 and the Identity Actual
1312 * Length then it's padding and we need to adjust for that
1313 * accurately before looking at the next EAP-AKA attribute. */
1314 padding = ((length - 1) * 4) - actual_length;
1315 if (padding != 0) {
1316 proto_tree_add_item(attr_tree, hf_eap_identity_padding, tvb,
1317 aoffset + 2 + actual_length, padding, ENC_NA);
1319 break;
1320 case AT_NOTIFICATION:
1321 proto_tree_add_item(attr_tree, hf_eap_aka_notification_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1322 break;
1323 case AT_CLIENT_ERROR_CODE:
1324 proto_tree_add_item(attr_tree, hf_eap_aka_error_code_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1325 break;
1326 default:
1327 proto_tree_add_item(attr_tree, hf_eap_aka_subtype_value, tvb, aoffset, aleft, ENC_NA);
1330 offset += 4 * length;
1331 left -= 4 * length;
1335 static int
1336 dissect_eap_pax(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int size)
1338 static int * const pax_flags[] = {
1339 &hf_eap_pax_flags_mf,
1340 &hf_eap_pax_flags_ce,
1341 &hf_eap_pax_flags_ai,
1342 &hf_eap_pax_flags_reserved,
1343 NULL
1345 uint32_t opcode;
1346 uint64_t flags;
1347 uint32_t len;
1349 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_opcode, tvb, offset, 1, ENC_NA, &opcode);
1350 offset++;
1352 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1353 val_to_str(opcode, eap_pax_opcode_vals, "Unknown opcode (0x%02X)"));
1355 proto_tree_add_bitmask_ret_uint64(eap_tree, tvb, offset, hf_eap_pax_flags, ett_eap_pax_flags,
1356 pax_flags, ENC_BIG_ENDIAN, &flags);
1357 offset++;
1359 proto_tree_add_item(eap_tree, hf_eap_pax_mac_id, tvb, offset, 1, ENC_NA);
1360 offset++;
1362 proto_tree_add_item(eap_tree, hf_eap_pax_dh_group_id, tvb, offset, 1, ENC_NA);
1363 offset++;
1365 proto_tree_add_item(eap_tree, hf_eap_pax_public_key_id, tvb, offset, 1, ENC_NA);
1366 offset++;
1368 switch (opcode) {
1369 case PAX_STD_1:
1370 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_a_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1371 offset += 2;
1372 proto_tree_add_item(eap_tree, hf_eap_pax_a, tvb, offset, len, ENC_NA);
1373 offset += len;
1374 len = 5 + size - offset;
1375 proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1376 offset += len;
1377 break;
1378 case PAX_STD_2:
1379 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_b_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1380 offset += 2;
1381 proto_tree_add_item(eap_tree, hf_eap_pax_b, tvb, offset, len, ENC_NA);
1382 offset += len;
1383 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_cid_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1384 offset += 2;
1385 proto_tree_add_item(eap_tree, hf_eap_pax_cid, tvb, offset, len, ENC_ASCII | ENC_NA);
1386 offset += len;
1387 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_mac_ck_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1388 offset += 2;
1389 proto_tree_add_item(eap_tree, hf_eap_pax_mac_ck, tvb, offset, len, ENC_NA);
1390 offset += len;
1391 if (flags & EAP_PAX_FLAG_AI) {
1392 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_ade_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1393 offset += 2;
1394 proto_tree_add_item(eap_tree, hf_eap_pax_ade, tvb, offset, len, ENC_NA);
1395 offset += len;
1397 len = 5 + size - offset;
1398 proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1399 offset += len;
1400 break;
1401 case PAX_STD_3:
1402 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_mac_ck_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1403 offset += 2;
1404 proto_tree_add_item(eap_tree, hf_eap_pax_mac_ck, tvb, offset, len, ENC_NA);
1405 offset += len;
1406 if (flags & EAP_PAX_FLAG_AI) {
1407 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_ade_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1408 offset += 2;
1409 proto_tree_add_item(eap_tree, hf_eap_pax_ade, tvb, offset, len, ENC_NA);
1410 offset += len;
1412 len = 5 + size - offset;
1413 proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1414 offset += len;
1415 break;
1416 case PAX_ACK:
1417 if (flags & EAP_PAX_FLAG_AI) {
1418 proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_ade_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1419 offset += 2;
1420 proto_tree_add_item(eap_tree, hf_eap_pax_ade, tvb, offset, len, ENC_NA);
1421 offset += len;
1423 len = 5 + size - offset;
1424 proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1425 offset += len;
1426 break;
1427 case PAX_SEC_1:
1428 case PAX_SEC_2:
1429 case PAX_SEC_3:
1430 case PAX_SEC_4:
1431 case PAX_SEC_5:
1432 /* TODO implement */
1433 default:
1434 break;
1437 return offset;
1440 static int
1441 dissect_eap_psk_pchannel(proto_tree *eap_tree, tvbuff_t *tvb, int offset, int size)
1443 /* The protected channel (PCHANNEL) content is encrypted so for now just present
1444 * it as a binary blob */
1445 proto_tree_add_item(eap_tree, hf_eap_psk_pchannel, tvb, offset, size, ENC_NA);
1446 offset += size;
1447 return offset;
1450 static int
1451 dissect_eap_psk(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int size)
1453 static int * const psk_flags[] = {
1454 &hf_eap_psk_flags_t,
1455 &hf_eap_psk_flags_reserved,
1456 NULL
1458 uint64_t flags;
1460 proto_tree_add_bitmask_ret_uint64(eap_tree, tvb, offset, hf_eap_psk_flags, ett_eap_psk_flags,
1461 psk_flags, ENC_NA, &flags);
1462 offset++;
1464 switch (flags & EAP_PSK_FLAGS_T_MASK) {
1465 case 0x00: /* T == 0 - EAP-PSK First Message */
1466 col_append_str(pinfo->cinfo, COL_INFO, " First Message");
1467 proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1468 offset += 16;
1469 proto_tree_add_item(eap_tree, hf_eap_psk_id_s, tvb, offset, size + 5 - offset, ENC_ASCII | ENC_NA);
1470 offset = size;
1471 break;
1472 case 0x40: /* T == 1 - EAP-PSK Second Message */
1473 col_append_str(pinfo->cinfo, COL_INFO, " Second Message");
1474 proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1475 offset += 16;
1476 proto_tree_add_item(eap_tree, hf_eap_psk_rand_p, tvb, offset, 16, ENC_NA);
1477 offset += 16;
1478 proto_tree_add_item(eap_tree, hf_eap_psk_mac_p, tvb, offset, 16, ENC_NA);
1479 offset += 16;
1480 proto_tree_add_item(eap_tree, hf_eap_psk_id_p, tvb, offset, size + 5 - offset, ENC_ASCII | ENC_NA);
1481 offset = size;
1482 break;
1483 case 0x80: /* T == 2 - EAP-PSK Third Message */
1484 col_append_str(pinfo->cinfo, COL_INFO, " Third Message");
1485 proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1486 offset += 16;
1487 proto_tree_add_item(eap_tree, hf_eap_psk_mac_s, tvb, offset, 16, ENC_NA);
1488 offset += 16;
1489 offset = dissect_eap_psk_pchannel(eap_tree, tvb, offset, size + 5 - offset);
1490 break;
1491 case 0xC0: /* T == 3 - EAP-PSK Fourth Message */
1492 col_append_str(pinfo->cinfo, COL_INFO, " Fourth Message");
1493 proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1494 offset += 16;
1495 offset = dissect_eap_psk_pchannel(eap_tree, tvb, offset, size + 5 - offset);
1496 break;
1497 default:
1498 break;
1501 return offset;
1504 static int
1505 dissect_eap_gpsk_csuite_sel(proto_tree *eap_tree, tvbuff_t *tvb, int offset)
1507 proto_tree *csuite_tree;
1508 csuite_tree = proto_tree_add_subtree(eap_tree, tvb, offset, 6, ett_eap_gpsk_csuite_sel,
1509 NULL, "EAP-GPSK CSuite_Sel");
1510 proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_vendor, tvb, offset, 4, ENC_BIG_ENDIAN);
1511 offset += 4;
1512 proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_specifier, tvb, offset, 2, ENC_BIG_ENDIAN);
1513 offset += 2;
1514 return offset;
1517 static int
1518 dissect_eap_gpsk_csuite_list(proto_tree *eap_tree, tvbuff_t *tvb, int offset)
1520 int start_offset = offset;
1521 uint16_t len;
1522 proto_tree *list_tree, *csuite_tree;
1524 len = tvb_get_ntohs(tvb, offset) + 2;
1525 list_tree = proto_tree_add_subtree(eap_tree, tvb, offset, len, ett_eap_gpsk_csuite_list,
1526 NULL, "EAP-GPSK CSuite List");
1527 proto_tree_add_item(list_tree, hf_eap_gpsk_csuite_list_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1528 offset += 2;
1530 while (offset < start_offset + len) {
1531 csuite_tree = proto_tree_add_subtree(list_tree, tvb, offset, 6, ett_eap_gpsk_csuite,
1532 NULL, "CSuite");
1533 proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_vendor, tvb, offset, 4, ENC_BIG_ENDIAN);
1534 offset += 4;
1535 proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_specifier, tvb, offset, 2, ENC_BIG_ENDIAN);
1536 offset += 2;
1538 return offset;
1541 static int
1542 dissect_eap_sake_attribute(proto_tree *eap_tree, tvbuff_t *tvb, int offset, int size)
1544 int start_offset = offset;
1545 uint8_t type;
1546 uint8_t len;
1547 proto_tree *attr_tree;
1549 type = tvb_get_uint8(tvb, offset);
1550 len = tvb_get_uint8(tvb, offset + 1);
1552 if (len < 2 || len > size) {
1553 return -1;
1555 attr_tree = proto_tree_add_subtree_format(eap_tree, tvb, offset, len, ett_eap_sake_attr, NULL,
1556 "EAP-SAKE Attribute: %s",
1557 val_to_str(type, eap_sake_attr_type_vals,
1558 "Unknown (%d)"));
1560 proto_tree_add_item(attr_tree, hf_eap_sake_attr_type, tvb, offset, 1, ENC_NA);
1561 offset++;
1562 proto_tree_add_item(attr_tree, hf_eap_sake_attr_len, tvb, offset, 1, ENC_NA);
1563 offset++;
1564 len -= 2;
1566 switch (type) {
1567 case SAKE_AT_SERVERID:
1568 case SAKE_AT_PEERID:
1569 proto_tree_add_item(attr_tree, hf_eap_sake_attr_value_str, tvb, offset, len, ENC_ASCII | ENC_NA);
1570 offset += len;
1571 break;
1572 case SAKE_AT_MSK_LIFE:
1573 proto_tree_add_item(attr_tree, hf_eap_sake_attr_value_uint48, tvb, offset, len,
1574 ENC_BIG_ENDIAN);
1575 offset += len;
1576 break;
1577 case SAKE_AT_RAND_S:
1578 case SAKE_AT_RAND_P:
1579 case SAKE_AT_MIC_S:
1580 case SAKE_AT_MIC_P:
1581 case SAKE_AT_SPI_S:
1582 case SAKE_AT_SPI_P:
1583 case SAKE_AT_ANY_ID_REQ:
1584 case SAKE_AT_PERM_ID_REQ:
1585 case SAKE_AT_ENCR_DATA:
1586 case SAKE_AT_IV:
1587 case SAKE_AT_PADDING:
1588 case SAKE_AT_NEXT_TMPID:
1589 default:
1590 proto_tree_add_item(attr_tree, hf_eap_sake_attr_value, tvb, offset, len, ENC_NA);
1591 offset += len;
1592 break;
1594 return offset - start_offset;
1597 static void
1598 dissect_eap_sake_attributes(proto_tree *eap_tree, tvbuff_t *tvb, int offset, int size)
1600 int attr_size;
1601 while (offset < size) {
1602 attr_size = dissect_eap_sake_attribute(eap_tree, tvb, offset, size);
1603 if (attr_size == -1) {
1604 break;
1606 offset += attr_size;
1610 static void
1611 dissect_eap_sake(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset, int size)
1613 uint32_t version;
1614 uint32_t subtype;
1616 proto_tree_add_item_ret_uint(eap_tree, hf_eap_sake_version, tvb, offset, 1, ENC_NA, &version);
1617 offset++;
1618 if (version != 2) {
1619 /* RFC 4763 specify version 2. Everything else is unsupported */
1620 return;
1622 proto_tree_add_item(eap_tree, hf_eap_sake_session_id, tvb, offset, 1, ENC_NA);
1623 offset++;
1624 proto_tree_add_item_ret_uint(eap_tree, hf_eap_sake_subtype, tvb, offset, 1, ENC_NA, &subtype);
1625 offset++;
1627 switch (subtype) {
1628 case SAKE_CHALLENGE:
1629 case SAKE_CONFIRM:
1630 case SAKE_AUTH_REJECT:
1631 case SAKE_IDENTITY:
1632 dissect_eap_sake_attributes(eap_tree, tvb, offset, size + 5 - offset);
1633 break;
1634 default:
1635 break;
1639 static int
1640 dissect_eap_gpsk(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int size)
1642 uint32_t opcode;
1643 uint32_t len;
1645 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_opcode, tvb, offset, 1, ENC_NA, &opcode);
1646 offset++;
1647 col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1648 val_to_str(opcode, eap_gpsk_opcode_vals, "Unknown opcode (0x%02X)"));
1650 switch (opcode) {
1651 case GPSK_GPSK_1:
1652 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_server_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1653 offset += 2;
1654 proto_tree_add_item(eap_tree, hf_eap_gpsk_id_server, tvb, offset, len, ENC_ASCII | ENC_NA);
1655 offset += len;
1656 proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_server, tvb, offset, 32, ENC_NA);
1657 offset += 32;
1658 offset = dissect_eap_gpsk_csuite_list(eap_tree, tvb, offset);
1659 break;
1660 case GPSK_GPSK_2:
1661 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_peer_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1662 offset += 2;
1663 proto_tree_add_item(eap_tree, hf_eap_gpsk_id_peer, tvb, offset, len, ENC_ASCII | ENC_NA);
1664 offset += len;
1665 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_server_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1666 offset += 2;
1667 proto_tree_add_item(eap_tree, hf_eap_gpsk_id_server, tvb, offset, len, ENC_ASCII | ENC_NA);
1668 offset += len;
1669 proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_peer, tvb, offset, 32, ENC_NA);
1670 offset += 32;
1671 proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_server, tvb, offset, 32, ENC_NA);
1672 offset += 32;
1673 offset = dissect_eap_gpsk_csuite_list(eap_tree, tvb, offset);
1674 offset = dissect_eap_gpsk_csuite_sel(eap_tree, tvb, offset);
1675 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_pd_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1676 offset += 2;
1677 if (len > 0) {
1678 proto_tree_add_item(eap_tree, hf_eap_gpsk_pd_payload, tvb, offset, len, ENC_NA);
1679 offset += len;
1681 len = size + 5 - offset;
1682 proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1683 offset += len;
1684 break;
1685 case GPSK_GPSK_3:
1686 proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_peer, tvb, offset, 32, ENC_NA);
1687 offset += 32;
1688 proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_server, tvb, offset, 32, ENC_NA);
1689 offset += 32;
1690 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_server_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1691 offset += 2;
1692 proto_tree_add_item(eap_tree, hf_eap_gpsk_id_server, tvb, offset, len, ENC_ASCII | ENC_NA);
1693 offset += len;
1694 offset = dissect_eap_gpsk_csuite_sel(eap_tree, tvb, offset);
1695 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_pd_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1696 offset += 2;
1697 if (len > 0) {
1698 proto_tree_add_item(eap_tree, hf_eap_gpsk_pd_payload, tvb, offset, len, ENC_NA);
1699 offset += len;
1701 len = size + 5 - offset;
1702 proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1703 offset += len;
1704 break;
1705 case GPSK_GPSK_4:
1706 proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_pd_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1707 offset += 2;
1708 if (len > 0) {
1709 proto_tree_add_item(eap_tree, hf_eap_gpsk_pd_payload, tvb, offset, len, ENC_NA);
1710 offset += len;
1712 len = size + 5 - offset;
1713 proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1714 offset += len;
1715 break;
1716 case GPSK_FAIL:
1717 proto_tree_add_item(eap_tree, hf_eap_gpsk_failure_code, tvb, offset, 4, ENC_BIG_ENDIAN);
1718 offset += 4;
1719 break;
1720 case GPSK_PROTECTED_FAIL:
1721 proto_tree_add_item(eap_tree, hf_eap_gpsk_failure_code, tvb, offset, 4, ENC_BIG_ENDIAN);
1722 offset += 4;
1723 len = size + 5 - offset;
1724 proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1725 offset += len;
1726 break;
1727 default:
1728 break;
1731 return offset;
1734 static int
1735 dissect_eap_msauth_tlv(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int size)
1737 unsigned tlv_type, tlv_len;
1738 proto_tree *tlv_tree, *tree, *ti_len;
1740 tlv_tree = proto_tree_add_subtree(eap_tree, tvb, offset, size, ett_eap_msauth_tlv,
1741 NULL, "Tag Length Values");
1743 next_tlv:
1744 tlv_type = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN) & MSAUTH_TLV_TYPE;
1745 tlv_len = tvb_get_uint16(tvb, offset + 2, ENC_BIG_ENDIAN);
1747 tree = proto_tree_add_subtree_format(tlv_tree, tvb, offset, 4 + tlv_len,
1748 ett_eap_msauth_tlv_tree, NULL, "TLV: t=%s(%d) l=%d",
1749 val_to_str_const(tlv_type, eap_msauth_tlv_type_vals, "Unknown"),
1750 tlv_type, 4 + tlv_len);
1752 proto_tree_add_item(tree, hf_eap_msauth_tlv_mandatory, tvb, offset, 2, ENC_BIG_ENDIAN);
1753 proto_tree_add_item(tree, hf_eap_msauth_tlv_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
1754 proto_tree_add_item(tree, hf_eap_msauth_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1755 offset += 2;
1757 proto_tree_add_item(tree, hf_eap_msauth_tlv_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1758 offset += 2;
1760 switch (tlv_type) {
1761 case MSAUTH_TLV_TYPE_EXTENSION_RESULT:
1762 proto_tree_add_item(tree, hf_eap_msauth_tlv_status, tvb, offset, 2, ENC_BIG_ENDIAN);
1763 offset += 2;
1764 break;
1766 case MSAUTH_TLV_TYPE_EXTENSION_CRYPTOBINDING:
1767 proto_tree_add_item(tree, hf_eap_msauth_tlv_crypto_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1768 offset += 1;
1769 proto_tree_add_item(tree, hf_eap_msauth_tlv_crypto_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1770 offset += 1;
1771 proto_tree_add_item(tree, hf_eap_msauth_tlv_crypto_rcv_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1772 offset += 1;
1773 proto_tree_add_item(tree, hf_eap_msauth_tlv_crypto_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
1774 offset += 1;
1775 proto_tree_add_item(tree, hf_eap_msauth_tlv_crypto_nonce, tvb, offset, 32, ENC_NA);
1776 offset += 32;
1777 proto_tree_add_item(tree, hf_eap_msauth_tlv_crypto_cmac, tvb, offset, 20, ENC_NA);
1778 offset += 20;
1779 break;
1781 default:
1782 ti_len = proto_tree_add_item(tree, hf_eap_msauth_tlv_val, tvb, offset, tlv_len, ENC_NA);
1783 if (4 + tlv_len > (unsigned)size - offset) {
1784 expert_add_info(pinfo, ti_len, &ei_eap_bad_length);
1786 offset += tlv_len;
1789 if (offset < size) {
1790 goto next_tlv;
1793 return offset;
1797 static int
1798 dissect_eap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1800 uint8_t eap_code;
1801 uint8_t eap_identifier;
1802 uint16_t eap_len;
1803 uint8_t eap_type;
1804 int len;
1805 conversation_t *conversation = NULL;
1806 conv_state_t *conversation_state = NULL;
1807 frame_state_t *packet_state;
1808 int leap_state;
1809 proto_tree *ti, *ti_id, *ti_len;
1810 proto_tree *eap_tree;
1811 proto_tree *eap_tls_flags_tree;
1812 proto_item *eap_type_item;
1813 static address null_address = ADDRESS_INIT_NONE;
1814 static uint8_t pae_group_address_mac_addr[6] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 };
1815 static address pae_group_address = ADDRESS_INIT(AT_ETHER, sizeof(pae_group_address_mac_addr), pae_group_address_mac_addr);
1817 col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAP");
1818 col_clear(pinfo->cinfo, COL_INFO);
1820 eap_code = tvb_get_uint8(tvb, 0);
1821 eap_identifier = tvb_get_uint8(tvb, 1);
1823 col_add_str(pinfo->cinfo, COL_INFO,
1824 val_to_str(eap_code, eap_code_vals, "Unknown code (0x%02X)"));
1827 * Find a conversation to which we belong; create one if we don't find it.
1829 * EAP runs over RADIUS (which runs over UDP), EAPOL (802.1X Authentication)
1830 * or other transports. In case of RADIUS, a single "session" may consist
1831 * of two UDP associations (one for authorization, one for accounting) which
1832 * results in two separate conversations. This wastes memory, but won't affect
1833 * the use cases below. In case of EAPOL, there are no ports. In any case,
1834 * force a new conversation when the EAP-Request/Identity message is found.
1836 * Conversation tracking is required for 1) EAP-TLS reassembly and 2) tracking
1837 * the stage in the LEAP protocol. In both cases, the protocol starts with an
1838 * EAP-Request/Identity message which cannot be found in the middle of the
1839 * session. Use it as a signal to start a new conversation. This ensures that
1840 * the TLS dissector associates new TLS messages with a unique TLS session.
1842 * For EAPOL frames we need to massage the source/destination addresses into
1843 * something stable for the TLS decoder as wireshark typically thinks there
1844 * are three conversations occurring when there is only one:
1845 * * src ether = server mac -> dst ether = PAE multicast group address
1846 * * src ether = server mac -> dst ether = client mac
1847 * * src ether = client mac -> dst ether = PAE multicast group address
1848 * We set the port so the TLS decoder can figure out which side is the server
1850 address conv_src, conv_dst;
1851 uint32_t tls_group = pinfo->curr_proto_layer_num << 16;
1852 uint32_t conv_srcport = pinfo->srcport;
1853 uint32_t conv_destport = pinfo->destport;
1854 if (pinfo->src.type == AT_ETHER) {
1855 if (eap_code == EAP_REQUEST) { /* server -> client */
1856 copy_address_shallow(&conv_src, &null_address);
1857 copy_address_shallow(&conv_dst, &pae_group_address);
1858 conv_srcport = 443;
1859 } else { /* client -> server */
1860 copy_address_shallow(&conv_src, &pae_group_address);
1861 copy_address_shallow(&conv_dst, &null_address);
1862 conv_destport = 443;
1865 else {
1866 copy_address_shallow(&conv_src, &pinfo->src);
1867 copy_address_shallow(&conv_dst, &pinfo->dst);
1871 * To support tunneled EAP-TLS (e.g. {TTLS,PEAP,TEAP,...}/EAP-TLS) we
1872 * group our TLS frames by the depth they are found at and use this
1873 * as offsets for p_get_proto_data/p_add_proto_data and as done for
1874 * EAPOL above we massage the client port using this too
1877 if (eap_code == EAP_REQUEST) { /* server -> client */
1878 conv_destport |= tls_group;
1880 else { /* client -> server */
1881 conv_srcport |= tls_group;
1884 conversation_set_conv_addr_port_endpoints(pinfo, &conv_src, &conv_dst,
1885 conversation_pt_to_conversation_type(pinfo->ptype), conv_srcport, conv_destport);
1887 if (PINFO_FD_VISITED(pinfo) || !(eap_code == EAP_REQUEST && tvb_get_uint8(tvb, 4) == EAP_TYPE_ID)) {
1888 conversation = find_or_create_conversation(pinfo);
1890 if (conversation == NULL) {
1891 conversation = conversation_new(pinfo->num, &conv_src,
1892 &conv_dst, conversation_pt_to_conversation_type(pinfo->ptype),
1893 conv_srcport, conv_destport, 0);
1897 * Get the state information for the conversation; attach some if
1898 * we don't find it.
1900 conversation_state = (conv_state_t *)conversation_get_proto_data(conversation, proto_eap);
1901 if (conversation_state == NULL) {
1903 * Attach state information to the conversation.
1905 conversation_state = wmem_new(wmem_file_scope(), conv_state_t);
1906 conversation_state->eap_tls_seq = -1;
1907 conversation_state->eap_reass_cookie = 0;
1908 conversation_state->leap_state = -1;
1909 conversation_state->last_eap_id_req = -1;
1910 conversation_state->last_eap_id_resp = -1;
1911 conversation_add_proto_data(conversation, proto_eap, conversation_state);
1915 * Set this now, so that it gets remembered even if we throw an exception
1916 * later.
1918 if (eap_code == EAP_FAILURE)
1919 conversation_state->leap_state = -1;
1921 eap_len = tvb_get_ntohs(tvb, 2);
1922 len = eap_len;
1924 ti = proto_tree_add_item(tree, proto_eap, tvb, 0, len, ENC_NA);
1925 eap_tree = proto_item_add_subtree(ti, ett_eap);
1927 proto_tree_add_item(eap_tree, hf_eap_code, tvb, 0, 1, ENC_BIG_ENDIAN);
1928 ti_id = proto_tree_add_item(eap_tree, hf_eap_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
1929 ti_len = proto_tree_add_item(eap_tree, hf_eap_len, tvb, 2, 2, ENC_BIG_ENDIAN);
1930 if (len < 4 || (unsigned)len > tvb_reported_length(tvb)) {
1931 expert_add_info(pinfo, ti_len, &ei_eap_bad_length);
1934 /* Detect message retransmissions. Since the protocol proceeds in lock-step,
1935 * reordering is not expected. If retransmissions somehow occur, we would have
1936 * to detect retransmissions via a bitmap. */
1937 bool is_duplicate_id = false;
1938 if (conversation_state) {
1939 if (eap_code == EAP_REQUEST || eap_code == EAP_RESPONSE ||
1940 eap_code == EAP_INITIATE || eap_code == EAP_FINISH) {
1941 if (!PINFO_FD_VISITED(pinfo)) {
1942 int16_t *last_eap_id = eap_code == EAP_REQUEST || eap_code == EAP_INITIATE ?
1943 &conversation_state->last_eap_id_req :
1944 &conversation_state->last_eap_id_resp;
1945 is_duplicate_id = *last_eap_id == eap_identifier;
1946 *last_eap_id = eap_identifier;
1947 if (is_duplicate_id) {
1948 // Use a dummy value to remember that this packet is a duplicate.
1949 p_add_proto_data(wmem_file_scope(), pinfo, proto_eap, PROTO_DATA_EAP_DUPLICATE_ID | tls_group, GINT_TO_POINTER(1));
1951 } else {
1952 is_duplicate_id = !!p_get_proto_data(wmem_file_scope(), pinfo, proto_eap, PROTO_DATA_EAP_DUPLICATE_ID | tls_group);
1954 if (is_duplicate_id) {
1955 expert_add_info(pinfo, ti_id, &ei_eap_retransmission);
1960 switch (eap_code) {
1962 case EAP_SUCCESS:
1963 case EAP_FAILURE:
1964 break;
1966 case EAP_REQUEST:
1967 case EAP_RESPONSE:
1968 eap_type = tvb_get_uint8(tvb, 4);
1970 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1971 val_to_str_ext(eap_type, &eap_type_vals_ext,
1972 "Unknown type (0x%02x)"));
1973 eap_type_item = proto_tree_add_item(eap_tree, hf_eap_type, tvb, 4, 1, ENC_BIG_ENDIAN);
1975 if ((len > 5) || ((len == 5) && (eap_type == EAP_TYPE_ID))) {
1976 int offset = 5;
1977 int size = len - offset;
1979 switch (eap_type) {
1980 /*********************************************************************
1981 **********************************************************************/
1982 case EAP_TYPE_ID:
1983 if (size > 0) {
1984 dissect_eap_identity(tvb, pinfo, eap_tree, offset, size);
1986 if (conversation_state && !PINFO_FD_VISITED(pinfo)) {
1987 conversation_state->leap_state = 0;
1988 conversation_state->eap_tls_seq = -1;
1990 break;
1992 /*********************************************************************
1993 **********************************************************************/
1994 case EAP_TYPE_NOTIFY:
1995 proto_tree_add_item(eap_tree, hf_eap_notification, tvb,
1996 offset, size, ENC_ASCII);
1997 break;
1999 /*********************************************************************
2000 **********************************************************************/
2001 case EAP_TYPE_NAK:
2002 proto_tree_add_item(eap_tree, hf_eap_type_nak, tvb,
2003 offset, 1, ENC_BIG_ENDIAN);
2004 break;
2005 /*********************************************************************
2006 **********************************************************************/
2007 case EAP_TYPE_MD5:
2009 uint8_t value_size = tvb_get_uint8(tvb, offset);
2010 int extra_len = size - 1 - value_size;
2011 proto_item *item;
2013 /* Warn that this is an insecure EAP type. */
2014 expert_add_info(pinfo, eap_type_item, &ei_eap_mitm_attacks);
2016 item = proto_tree_add_item(eap_tree, hf_eap_md5_value_size, tvb, offset, 1, ENC_BIG_ENDIAN);
2017 if (value_size > (size - 1))
2019 expert_add_info(pinfo, item, &ei_eap_md5_value_size_overflow);
2020 value_size = size - 1;
2023 offset += 1;
2024 proto_tree_add_item(eap_tree, hf_eap_md5_value, tvb, offset, value_size, ENC_NA);
2025 offset += value_size;
2026 if (extra_len > 0) {
2027 proto_tree_add_item(eap_tree, hf_eap_md5_extra_data, tvb, offset, extra_len, ENC_NA);
2030 break;
2032 /*********************************************************************
2033 EAP-TLS
2034 **********************************************************************/
2035 case EAP_TYPE_FAST:
2036 case EAP_TYPE_PEAP:
2037 case EAP_TYPE_TTLS:
2038 case EAP_TYPE_TLS:
2039 case EAP_TYPE_TEAP:
2041 bool more_fragments;
2042 bool has_length;
2043 bool is_start;
2044 bool outer_tlvs = false;
2045 int outer_tlvs_length = 0;
2046 int eap_tls_seq = -1;
2047 uint32_t eap_reass_cookie = 0;
2048 bool needs_reassembly = false;
2050 if (!conversation_state) {
2051 // XXX expert info? There cannot be another EAP-TTLS message within
2052 // the EAP-Message inside EAP-TTLS.
2053 break;
2056 /* Flags field, 1 byte */
2057 ti = proto_tree_add_item(eap_tree, hf_eap_tls_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
2058 eap_tls_flags_tree = proto_item_add_subtree(ti, ett_eap_tls_flags);
2059 proto_tree_add_item_ret_boolean(eap_tls_flags_tree, hf_eap_tls_flag_l, tvb, offset, 1, ENC_BIG_ENDIAN, &has_length);
2060 proto_tree_add_item_ret_boolean(eap_tls_flags_tree, hf_eap_tls_flag_m, tvb, offset, 1, ENC_BIG_ENDIAN, &more_fragments);
2061 proto_tree_add_item_ret_boolean(eap_tls_flags_tree, hf_eap_tls_flag_s, tvb, offset, 1, ENC_BIG_ENDIAN, &is_start);
2063 switch (eap_type) {
2064 case EAP_TYPE_TEAP:
2065 proto_tree_add_item_ret_boolean(eap_tls_flags_tree, hf_eap_tls_flag_o, tvb, offset, 1, ENC_BIG_ENDIAN, &outer_tlvs);
2066 /* FALLTHROUGH */
2067 case EAP_TYPE_TTLS:
2068 case EAP_TYPE_FAST:
2069 case EAP_TYPE_PEAP:
2070 proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flags_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2071 break;
2073 size -= 1;
2074 offset += 1;
2076 /* Length field, 4 bytes, OPTIONAL. */
2077 if (has_length) {
2078 proto_tree_add_item(eap_tree, hf_eap_tls_len, tvb, offset, 4, ENC_BIG_ENDIAN);
2079 size -= 4;
2080 offset += 4;
2083 /* Outer TLV Length field, 4 bytes, OPTIONAL. */
2084 if (outer_tlvs) {
2085 proto_tree_add_item_ret_uint(eap_tree, hf_eap_tls_outer_tlvs_len, tvb, offset, 4, ENC_BIG_ENDIAN, &outer_tlvs_length);
2086 size -= 4;
2087 offset += 4;
2090 if (is_start)
2091 conversation_state->eap_tls_seq = -1;
2093 /* 4.1.1 Authority ID Data https://datatracker.ietf.org/doc/html/rfc4851#section-4.1.1 */
2094 if (eap_type == EAP_TYPE_FAST && is_start) {
2095 uint32_t length, type;
2097 proto_tree_add_item_ret_uint(eap_tree, hf_eap_fast_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
2098 size -= 2;
2099 offset += 2;
2101 proto_tree_add_item_ret_uint(eap_tree, hf_eap_fast_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
2102 size -= 2;
2103 offset += 2;
2105 proto_tree_add_item(eap_tree, hf_eap_data, tvb, offset, length, ENC_NA);
2107 switch (type) {
2108 case 4:
2109 proto_tree_add_item(eap_tree, hf_eap_fast_aidd, tvb, offset, length, ENC_NA);
2110 break;
2112 size -= length;
2113 offset += length;
2117 if (size > 0) {
2119 tvbuff_t *next_tvb = NULL;
2120 int tvb_len;
2121 bool save_fragmented;
2123 tvb_len = tvb_captured_length_remaining(tvb, offset);
2124 if (size < tvb_len)
2125 tvb_len = size;
2127 /* If this is a retransmission, do not save the fragment. */
2128 if (is_duplicate_id) {
2129 next_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_len, size);
2130 call_data_dissector(next_tvb, pinfo, eap_tree);
2131 break;
2135 EAP/TLS is weird protocol (it comes from
2136 Microsoft after all).
2138 If we have series of fragmented packets,
2139 then there's no way of knowing that from
2140 the packet itself, if it is the last packet
2141 in series, that is that the packet part of
2142 bigger fragmented set of data.
2144 The only way to know is, by knowing
2145 that we are already in defragmentation
2146 "mode" and we are expecing packet
2147 carrying fragment of data. (either
2148 because we have not received expected
2149 amount of data, or because the packet before
2150 had "F"ragment flag set.)
2152 The situation is alleviated by fact that it
2153 is simple ack/nack protcol so there's no
2154 place for out-of-order packets like it is
2155 possible with IP.
2157 Anyway, point of this lengthy essay is that
2158 we have to keep state information in the
2159 conversation, so that we can put ourselves in
2160 defragmenting mode and wait for the last packet,
2161 and have to attach state to frames as well, so
2162 that we can handle defragmentation after the
2163 first pass through the capture.
2165 /* See if we have a remembered defragmentation EAP ID. */
2166 packet_state = (frame_state_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_eap, PROTO_DATA_EAP_FRAME_STATE | tls_group);
2167 if (packet_state == NULL) {
2169 * We haven't - does this message require reassembly?
2171 if (!pinfo->fd->visited) {
2173 * This is the first time we've looked at this frame,
2174 * so it wouldn't have any remembered information.
2176 * Therefore, we check whether this conversation has
2177 * a reassembly operation in progress, or whether
2178 * this frame has the Fragment flag set.
2180 if (conversation_state->eap_tls_seq != -1) {
2182 * There's a reassembly in progress; the sequence number
2183 * of the previous fragment is
2184 * "conversation_state->eap_tls_seq", and the reassembly
2185 * ID is "conversation_state->eap_reass_cookie".
2187 * We must include this frame in the reassembly.
2188 * We advance the sequence number, giving us the
2189 * sequence number for this fragment.
2191 needs_reassembly = true;
2192 conversation_state->eap_tls_seq++;
2194 eap_reass_cookie = conversation_state->eap_reass_cookie;
2195 eap_tls_seq = conversation_state->eap_tls_seq;
2196 } else if (more_fragments && has_length) {
2198 * This message has the Fragment flag set, so it requires
2199 * reassembly. It's the message containing the first
2200 * fragment (if it's a later fragment, the sequence
2201 * number in the conversation state would not be -1).
2203 * If it doesn't include a length, however, we can't
2204 * do reassembly (either the message is in error, as
2205 * the first fragment *must* contain a length, or we
2206 * didn't capture the first fragment, and this just
2207 * happens to be the first fragment we saw), so we
2208 * also check that we have a length;
2210 needs_reassembly = true;
2211 conversation_state->eap_reass_cookie = pinfo->num;
2214 * Start the reassembly sequence number at 0.
2216 conversation_state->eap_tls_seq = 0;
2218 eap_tls_seq = conversation_state->eap_tls_seq;
2219 eap_reass_cookie = conversation_state->eap_reass_cookie;
2222 if (needs_reassembly) {
2224 * This frame requires reassembly; remember the reassembly
2225 * ID for subsequent accesses to it.
2227 packet_state = wmem_new(wmem_file_scope(), frame_state_t);
2228 packet_state->info = eap_reass_cookie;
2229 p_add_proto_data(wmem_file_scope(), pinfo, proto_eap, PROTO_DATA_EAP_FRAME_STATE | tls_group, packet_state);
2232 } else {
2234 * This frame has a reassembly cookie associated with it, so
2235 * it requires reassembly. We've already done the
2236 * reassembly in the first pass, so "fragment_add_seq()"
2237 * won't look at the sequence number; set it to 0.
2239 * XXX - a frame isn't supposed to have more than one
2240 * EAP message in it, but if it includes both an EAP-TLS
2241 * message and a LEAP message, we might be mistakenly
2242 * concluding it requires reassembly because the "info"
2243 * field isn't -1. We could, I guess, pack both EAP-TLS
2244 * ID and LEAP state into the structure, but that doesn't
2245 * work if you have multiple EAP-TLS or LEAP messages in
2246 * the frame.
2248 * But it's not clear how much work we should do to handle
2249 * a bogus message such as that; as long as we don't crash
2250 * or do something else equally horrible, we may not
2251 * have to worry about this at all.
2253 needs_reassembly = true;
2254 eap_reass_cookie = packet_state->info;
2255 eap_tls_seq = 0;
2259 We test here to see whether EAP-TLS packet
2260 carry fragmented of TLS data.
2262 If this is the case, we do reasembly below,
2263 otherwise we just call dissector.
2265 if (needs_reassembly) {
2266 fragment_head *fd_head;
2269 * Yes, this frame contains a fragment that requires
2270 * reassembly.
2272 save_fragmented = pinfo->fragmented;
2273 pinfo->fragmented = true;
2274 fd_head = fragment_add_seq(&eap_tls_reassembly_table,
2275 tvb, offset,
2276 pinfo, eap_reass_cookie, NULL,
2277 eap_tls_seq,
2278 size,
2279 more_fragments, 0);
2281 if (fd_head != NULL) {
2282 if (fd_head->reassembled_in == pinfo->num) {
2283 /* Reassembled */
2284 proto_item* frag_tree_item;
2286 next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
2287 add_new_data_source(pinfo, next_tvb, "Reassembled EAP-TLS");
2289 show_fragment_seq_tree(fd_head, &eap_tls_frag_items,
2290 eap_tree, pinfo, next_tvb, &frag_tree_item);
2293 * We're finished reassembing this frame.
2294 * Reinitialize the reassembly state.
2296 if (!pinfo->fd->visited)
2297 conversation_state->eap_tls_seq = -1;
2298 } else {
2299 ti = proto_tree_add_uint(eap_tree, hf_eap_tls_reassembled_in, tvb,
2300 0, 0, fd_head->reassembled_in);
2301 proto_item_set_generated(ti);
2305 pinfo->fragmented = save_fragmented;
2307 } else { /* this data is NOT fragmented */
2308 next_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_len, size);
2311 if (next_tvb) {
2312 switch (eap_type) {
2313 case EAP_TYPE_TTLS:
2314 tls_set_appdata_dissector(tls_handle, pinfo, diameter_avps_handle);
2315 break;
2316 case EAP_TYPE_PEAP:
2317 p_add_proto_data(pinfo->pool, pinfo, proto_eap, PROTO_DATA_EAP_TVB | tls_group, tvb);
2318 tls_set_appdata_dissector(tls_handle, pinfo, peap_handle);
2319 break;
2320 case EAP_TYPE_TEAP:
2321 if (outer_tlvs) { /* https://www.rfc-editor.org/rfc/rfc7170.html#section-4.1 */
2322 tvbuff_t *teap_tvb = tvb_new_subset_length(tvb, offset + size - outer_tlvs_length, outer_tlvs_length);
2323 call_dissector(teap_handle, teap_tvb, pinfo, eap_tree);
2324 if (size == outer_tlvs_length) goto skip_tls_dissector;
2325 next_tvb = tvb_new_subset_length(next_tvb, 0, size - outer_tlvs_length);
2327 tls_set_appdata_dissector(tls_handle, pinfo, teap_handle);
2328 break;
2330 call_dissector(tls_handle, next_tvb, pinfo, eap_tree);
2334 skip_tls_dissector:
2335 break; /* EAP_TYPE_TLS */
2337 /*********************************************************************
2338 Cisco's Lightweight EAP (LEAP)
2339 https://web.archive.org/web/20070623090417if_/http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
2340 **********************************************************************/
2341 case EAP_TYPE_LEAP:
2343 uint8_t count, namesize;
2345 /* Warn that this is an insecure EAP type. */
2346 expert_add_info(pinfo, eap_type_item, &ei_eap_dictionary_attacks);
2348 /* Version (byte) */
2349 proto_tree_add_item(eap_tree, hf_eap_leap_version, tvb, offset, 1, ENC_BIG_ENDIAN);
2350 offset += 1;
2352 /* Unused (byte) */
2353 proto_tree_add_item(eap_tree, hf_eap_leap_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
2354 offset += 1;
2356 /* Count (byte) */
2357 count = tvb_get_uint8(tvb, offset);
2358 proto_tree_add_item(eap_tree, hf_eap_leap_count, tvb, offset, 1, ENC_BIG_ENDIAN);
2359 offset += 1;
2361 /* Data (byte*Count) */
2362 /* This part is state-dependent. */
2364 if (!conversation_state) {
2365 // XXX expert info? LEAP is not expected within the EAP-Message within EAP-TTLS.
2366 break;
2368 /* XXX - are duplicates possible (is_duplicate_id)?
2369 * If so, should we stop here to avoid modifying conversation_state? */
2371 /* See if we've already remembered the state. */
2372 packet_state = (frame_state_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_eap, PROTO_DATA_EAP_FRAME_STATE | tls_group);
2373 if (packet_state == NULL) {
2375 * We haven't - compute the state based on the current
2376 * state in the conversation.
2378 leap_state = conversation_state->leap_state;
2380 /* Advance the state machine. */
2381 if (leap_state==0) leap_state = 1; else
2382 if (leap_state==1) leap_state = 2; else
2383 if (leap_state==2) leap_state = 3; else
2384 if (leap_state==3) leap_state = 4; else
2385 if (leap_state==4) leap_state = -1;
2388 * Remember the state for subsequent accesses to this
2389 * frame.
2391 packet_state = wmem_new(wmem_file_scope(), frame_state_t);
2392 packet_state->info = leap_state;
2393 p_add_proto_data(wmem_file_scope(), pinfo, proto_eap, PROTO_DATA_EAP_FRAME_STATE | tls_group, packet_state);
2396 * Update the conversation's state.
2398 conversation_state->leap_state = leap_state;
2401 /* Get the remembered state. */
2402 leap_state = packet_state->info;
2404 switch (leap_state) {
2405 case 1:
2406 proto_tree_add_item(eap_tree, hf_eap_leap_peer_challenge, tvb, offset, count, ENC_NA);
2407 break;
2409 case 2:
2410 proto_tree_add_item(eap_tree, hf_eap_leap_peer_response, tvb, offset, count, ENC_NA);
2411 break;
2413 case 3:
2414 proto_tree_add_item(eap_tree, hf_eap_leap_ap_challenge, tvb, offset, count, ENC_NA);
2415 break;
2417 case 4:
2418 proto_tree_add_item(eap_tree, hf_eap_leap_ap_response, tvb, offset, count, ENC_NA);
2419 break;
2421 default:
2422 proto_tree_add_item(eap_tree, hf_eap_leap_data, tvb, offset, count, ENC_NA);
2423 break;
2426 offset += count;
2428 /* Name (Length-(8+Count)) */
2429 namesize = eap_len - (8+count);
2430 proto_tree_add_item(eap_tree, hf_eap_leap_name, tvb, offset, namesize, ENC_ASCII);
2433 break; /* EAP_TYPE_LEAP */
2435 /*********************************************************************
2436 EAP-MSCHAPv2 - draft-kamath-pppext-eap-mschapv2-00.txt
2437 **********************************************************************/
2438 case EAP_TYPE_MSCHAPV2:
2439 dissect_eap_mschapv2(eap_tree, tvb, pinfo, offset, size);
2440 break; /* EAP_TYPE_MSCHAPV2 */
2442 /*********************************************************************
2443 EAP-SIM - draft-haverinen-pppext-eap-sim-13.txt
2444 **********************************************************************/
2445 case EAP_TYPE_SIM:
2446 dissect_eap_sim(eap_tree, tvb, pinfo, offset, size);
2447 break; /* EAP_TYPE_SIM */
2449 /*********************************************************************
2450 EAP-AKA - draft-arkko-pppext-eap-aka-12.txt
2451 **********************************************************************/
2452 case EAP_TYPE_AKA:
2453 case EAP_TYPE_AKA_PRIME:
2454 dissect_eap_aka(eap_tree, tvb, pinfo, offset, size);
2455 break; /* EAP_TYPE_AKA */
2457 /*********************************************************************
2458 EAP Expanded Type
2459 **********************************************************************/
2460 case EAP_TYPE_EXT:
2462 proto_tree *exptree;
2464 exptree = proto_tree_add_subtree(eap_tree, tvb, offset, size, ett_eap_exp_attr, NULL, "Expanded Type");
2465 dissect_exteap(exptree, tvb, offset, size, pinfo, eap_code, eap_identifier);
2467 break;
2469 /*********************************************************************
2470 EAP-PAX - RFC 4746
2471 **********************************************************************/
2472 case EAP_TYPE_PAX:
2473 dissect_eap_pax(eap_tree, tvb, pinfo, offset, size);
2474 break; /* EAP_TYPE_PAX */
2476 /*********************************************************************
2477 EAP-PSK - RFC 4764
2478 **********************************************************************/
2479 case EAP_TYPE_PSK:
2480 dissect_eap_psk(eap_tree, tvb, pinfo, offset, size);
2481 break; /* EAP_TYPE_PSK */
2483 /*********************************************************************
2484 EAP-SAKE - RFC 4763
2485 **********************************************************************/
2486 case EAP_TYPE_SAKE:
2487 dissect_eap_sake(eap_tree, tvb, pinfo, offset, size);
2488 break; /* EAP_TYPE_SAKE */
2490 /*********************************************************************
2491 EAP-GPSK - RFC 5433
2492 **********************************************************************/
2493 case EAP_TYPE_GPSK:
2494 dissect_eap_gpsk(eap_tree, tvb, pinfo, offset, size);
2495 break; /* EAP_TYPE_GPSK */
2497 /*********************************************************************
2498 EAP-IKEv2 - RFC 5106
2499 **********************************************************************/
2500 case EAP_TYPE_IKEV2:
2502 bool more_fragments;
2503 bool has_length;
2504 bool icv_present;
2506 /* Flags field, 1 byte */
2507 ti = proto_tree_add_item(eap_tree, hf_eap_ikev2_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
2508 eap_tls_flags_tree = proto_item_add_subtree(ti, hf_eap_ikev2_flags);
2509 proto_tree_add_item_ret_boolean(eap_tls_flags_tree, hf_eap_ikev2_flag_l, tvb, offset, 1, ENC_BIG_ENDIAN, &has_length);
2510 proto_tree_add_item_ret_boolean(eap_tls_flags_tree, hf_eap_ikev2_flag_m, tvb, offset, 1, ENC_BIG_ENDIAN, &more_fragments);
2511 proto_tree_add_item_ret_boolean(eap_tls_flags_tree, hf_eap_ikev2_flag_i, tvb, offset, 1, ENC_BIG_ENDIAN, &icv_present);
2513 size -= 1;
2514 offset += 1;
2516 /* Length field, 4 bytes, OPTIONAL. */
2517 if (has_length) {
2518 proto_tree_add_item(eap_tree, hf_eap_ikev2_len, tvb, offset, 4, ENC_BIG_ENDIAN);
2519 size -= 4;
2520 offset += 4;
2523 if (size > 0) {
2524 tvbuff_t* next_tvb = NULL;
2525 int tvb_len;
2527 tvb_len = tvb_captured_length_remaining(tvb, offset);
2528 if (size < tvb_len) {
2529 tvb_len = size;
2532 if (has_length || more_fragments) {
2533 /* TODO: Add fragmentation support
2534 * Length of integrity check data needs to be determined in case of fragmentation. Chosen INTEG transform?
2536 } else {
2537 next_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_len, size);
2538 unsigned tmp = call_dissector(isakmp_handle, next_tvb, pinfo, eap_tree);
2539 size -= tmp;
2540 offset += tmp;
2542 if (icv_present && size > 0) {
2543 /* We assume that all data present is integrity check data. We cannot detect too short/long right now. */
2544 proto_tree_add_item(eap_tree, hf_eap_ikev2_int_chk_data, tvb, offset, size, ENC_NA);
2549 break;
2550 } /* EAP_TYPE_IKEV2 */
2552 /*********************************************************************
2553 MS-Authentication-TLV - MS-PEAP section 2.2.8.1
2554 **********************************************************************/
2555 case EAP_TYPE_MSAUTH_TLV:
2556 dissect_eap_msauth_tlv(eap_tree, tvb, pinfo, offset, size);
2557 break; /* EAP_TYPE_MSAUTH_TLV */
2559 /*********************************************************************
2560 **********************************************************************/
2561 default:
2562 proto_tree_add_item(eap_tree, hf_eap_data, tvb, offset, size, ENC_NA);
2563 break;
2564 /*********************************************************************
2565 **********************************************************************/
2566 } /* switch (eap_type) */
2570 } /* switch (eap_code) */
2572 return tvb_captured_length(tvb);
2575 void
2576 proto_register_eap(void)
2578 static hf_register_info hf[] = {
2579 { &hf_eap_code, {
2580 "Code", "eap.code",
2581 FT_UINT8, BASE_DEC, VALS(eap_code_vals), 0x0,
2582 NULL, HFILL }},
2584 { &hf_eap_identifier, {
2585 "Id", "eap.id",
2586 FT_UINT8, BASE_DEC, NULL, 0x0,
2587 NULL, HFILL }},
2589 { &hf_eap_len, {
2590 "Length", "eap.len",
2591 FT_UINT16, BASE_DEC, NULL, 0x0,
2592 NULL, HFILL }},
2594 { &hf_eap_type, {
2595 "Type", "eap.type",
2596 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_type_vals_ext, 0x0,
2597 NULL, HFILL }},
2599 { &hf_eap_type_nak, {
2600 "Desired Auth Type", "eap.desired_type",
2601 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_type_vals_ext, 0x0,
2602 NULL, HFILL }},
2604 { &hf_eap_identity, {
2605 "Identity", "eap.identity",
2606 FT_STRING, BASE_NONE, NULL, 0x0,
2607 NULL, HFILL }},
2609 { &hf_eap_identity_prefix, {
2610 "Identity Prefix", "eap.identity.prefix",
2611 FT_CHAR, BASE_HEX, NULL, 0x0,
2612 NULL, HFILL }},
2614 { &hf_eap_identity_type, {
2615 "Identity Type", "eap.identity.type",
2616 FT_STRING, BASE_NONE, NULL, 0x0,
2617 NULL, HFILL }},
2619 { &hf_eap_identity_full, {
2620 "Identity (Full)", "eap.identity.full",
2621 FT_STRING, BASE_NONE, NULL, 0x0,
2622 NULL, HFILL }},
2624 { &hf_eap_identity_certificate_sn, {
2625 "Certificate Serial Number", "eap.identity.cert_sn",
2626 FT_STRING, BASE_NONE, NULL, 0x0,
2627 NULL, HFILL }},
2629 { &hf_eap_identity_mcc, {
2630 "Identity Mobile Country Code", "eap.identity.mcc",
2631 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &E212_codes_ext, 0x0, NULL, HFILL }},
2633 { &hf_eap_identity_mcc_mnc_2digits, {
2634 "Identity Mobile Network Code", "eap.identity.mnc",
2635 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &mcc_mnc_2digits_codes_ext, 0x0, NULL, HFILL }},
2637 { &hf_eap_identity_mcc_mnc_3digits, {
2638 "Identity Mobile Network Code", "eap.identity.mnc",
2639 FT_UINT16, BASE_DEC|BASE_EXT_STRING, &mcc_mnc_3digits_codes_ext, 0x0, NULL, HFILL }},
2641 { &hf_eap_identity_padding, {
2642 "Padding", "eap.identity.padding",
2643 FT_BYTES, BASE_NONE, NULL, 0x0,
2644 NULL, HFILL }},
2646 { &hf_eap_identity_actual_len, {
2647 "Identity Actual Length", "eap.identity.actual_len",
2648 FT_UINT16, BASE_DEC, NULL, 0x0,
2649 NULL, HFILL }},
2651 { &hf_eap_notification, {
2652 "Notification", "eap.notification",
2653 FT_STRING, BASE_NONE, NULL, 0x0,
2654 NULL, HFILL }},
2656 { &hf_eap_md5_value_size, {
2657 "EAP-MD5 Value-Size", "eap.md5.value_size",
2658 FT_UINT8, BASE_DEC, NULL, 0x0,
2659 NULL, HFILL }},
2661 { &hf_eap_md5_value, {
2662 "EAP-MD5 Value", "eap.md5.value",
2663 FT_BYTES, BASE_NONE, NULL, 0x0,
2664 NULL, HFILL }},
2666 { &hf_eap_md5_extra_data, {
2667 "EAP-MD5 Extra Data", "eap.md5.extra_data",
2668 FT_BYTES, BASE_NONE, NULL, 0x0,
2669 NULL, HFILL }},
2671 { &hf_eap_tls_flags, {
2672 "EAP-TLS Flags", "eap.tls.flags",
2673 FT_UINT8, BASE_HEX, NULL, 0x0,
2674 NULL, HFILL }},
2676 { &hf_eap_tls_flag_l, {
2677 "Length Included", "eap.tls.flags.len_included",
2678 FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_L,
2679 NULL, HFILL }},
2681 { &hf_eap_tls_flag_m, {
2682 "More Fragments", "eap.tls.flags.more_fragments",
2683 FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_M,
2684 NULL, HFILL }},
2686 { &hf_eap_tls_flag_s, {
2687 "Start", "eap.tls.flags.start",
2688 FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_S,
2689 NULL, HFILL }},
2691 { &hf_eap_tls_flag_o, {
2692 "Outer TLV Length Included", "eap.tls.flags.outer_tlv_len_included",
2693 FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_O,
2694 NULL, HFILL }},
2696 { &hf_eap_tls_flags_version, {
2697 "Version", "eap.tls.flags.version",
2698 FT_UINT8, BASE_DEC, NULL, EAP_TLS_FLAGS_VERSION,
2699 NULL, HFILL }},
2701 { &hf_eap_tls_len, {
2702 "EAP-TLS Length", "eap.tls.len",
2703 FT_UINT32, BASE_DEC, NULL, 0x0,
2704 NULL, HFILL }},
2706 { &hf_eap_tls_outer_tlvs_len, {
2707 "TEAP Outer TLVs Length", "eap.tls.outer_tlvs_len",
2708 FT_UINT32, BASE_DEC, NULL, 0x0,
2709 NULL, HFILL }},
2711 { &hf_eap_tls_fragment, {
2712 "EAP-TLS Fragment", "eap.tls.fragment",
2713 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2714 NULL, HFILL }},
2716 { &hf_eap_tls_fragments, {
2717 "EAP-TLS Fragments", "eap.tls.fragments",
2718 FT_NONE, BASE_NONE, NULL, 0x0,
2719 NULL, HFILL }},
2721 { &hf_eap_tls_fragment_overlap, {
2722 "Fragment Overlap", "eap.tls.fragment.overlap",
2723 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2724 "Fragment overlaps with other fragments", HFILL }},
2726 { &hf_eap_tls_fragment_overlap_conflict, {
2727 "Conflicting Data In Fragment Overlap", "eap.tls.fragment.overlap_conflict",
2728 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2729 "Overlapping fragments contained conflicting data", HFILL }},
2731 { &hf_eap_tls_fragment_multiple_tails, {
2732 "Multiple Tail Fragments Found", "eap.tls.fragment.multiple_tails",
2733 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2734 "Several tails were found when defragmenting the packet", HFILL }},
2736 { &hf_eap_tls_fragment_too_long_fragment,{
2737 "Fragment Too Long", "eap.tls.fragment.fragment.too_long",
2738 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2739 "Fragment contained data past end of packet", HFILL }},
2741 { &hf_eap_tls_fragment_error, {
2742 "Defragmentation Error", "eap.tls.fragment.error",
2743 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2744 "Defragmentation error due to illegal fragments", HFILL }},
2746 { &hf_eap_tls_fragment_count, {
2747 "Fragment Count", "eap.tls.fragment.count",
2748 FT_UINT32, BASE_DEC, NULL, 0x0,
2749 NULL, HFILL }},
2751 { &hf_eap_tls_reassembled_in, {
2752 "Reassembled EAP-TLS PDU in frame", "eap.tls.reassembled_in",
2753 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2754 "A PDU with a fragment from this frame is reassembled in this frame", HFILL } },
2756 { &hf_eap_tls_reassembled_length, {
2757 "Reassembled EAP-TLS Length", "eap.tls.reassembled.len",
2758 FT_UINT32, BASE_DEC, NULL, 0x0,
2759 "Total length of the reassembled payload", HFILL }},
2761 { &hf_eap_sim_subtype, {
2762 "EAP-SIM Subtype", "eap.sim.subtype",
2763 FT_UINT8, BASE_DEC, VALS(eap_sim_subtype_vals), 0x0,
2764 NULL, HFILL }},
2766 { &hf_eap_sim_reserved, {
2767 "EAP-SIM Reserved", "eap.sim.reserved",
2768 FT_UINT16, BASE_HEX, NULL, 0x0,
2769 NULL, HFILL }},
2771 { &hf_eap_sim_subtype_attribute, {
2772 "EAP-SIM Attribute", "eap.sim.subtype.attribute",
2773 FT_NONE, BASE_NONE, NULL, 0x0,
2774 NULL, HFILL }},
2776 { &hf_eap_sim_subtype_type, {
2777 "EAP-SIM Type", "eap.sim.subtype.type",
2778 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_sim_aka_attribute_vals_ext, 0x0,
2779 NULL, HFILL }},
2781 { &hf_eap_sim_subtype_length, {
2782 "EAP-SIM Length", "eap.sim.subtype.len",
2783 FT_UINT8, BASE_DEC, NULL, 0x0,
2784 NULL, HFILL }},
2786 { &hf_eap_sim_notification_type, {
2787 "EAP-SIM Notification Type", "eap.sim.notification_type",
2788 FT_UINT16, BASE_DEC, VALS(eap_sim_aka_notification_vals), 0x0,
2789 NULL, HFILL }},
2791 { &hf_eap_sim_error_code_type, {
2792 "EAP-SIM Error Code", "eap.sim.error_code",
2793 FT_UINT16, BASE_DEC, VALS(eap_sim_aka_client_error_codes), 0x0,
2794 NULL, HFILL }},
2796 { &hf_eap_sim_subtype_value, {
2797 "EAP-SIM Value", "eap.sim.subtype.value",
2798 FT_BYTES, BASE_NONE, NULL, 0x0,
2799 NULL, HFILL }},
2801 { &hf_eap_aka_subtype, {
2802 "EAP-AKA Subtype", "eap.aka.subtype",
2803 FT_UINT8, BASE_DEC, VALS(eap_aka_subtype_vals), 0x0,
2804 NULL, HFILL }},
2806 { &hf_eap_aka_reserved, {
2807 "EAP-AKA Reserved", "eap.aka.reserved",
2808 FT_UINT16, BASE_HEX, NULL, 0x0,
2809 NULL, HFILL }},
2811 { &hf_eap_aka_subtype_attribute, {
2812 "EAP-AKA Attribute", "eap.aka.subtype.attribute",
2813 FT_NONE, BASE_NONE, NULL, 0x0,
2814 NULL, HFILL }},
2816 { &hf_eap_aka_subtype_type, {
2817 "EAP-AKA Type", "eap.aka.subtype.type",
2818 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_sim_aka_attribute_vals_ext, 0x0,
2819 NULL, HFILL }},
2821 { &hf_eap_aka_subtype_length, {
2822 "EAP-AKA Length", "eap.aka.subtype.len",
2823 FT_UINT8, BASE_DEC, NULL, 0x0,
2824 NULL, HFILL }},
2826 { &hf_eap_aka_notification_type, {
2827 "EAP-AKA Notification Type", "eap.aka.notification_type",
2828 FT_UINT16, BASE_DEC, VALS(eap_sim_aka_notification_vals), 0x0,
2829 NULL, HFILL }},
2831 { &hf_eap_aka_error_code_type, {
2832 "EAP-AKA Error Code", "eap.aka.error_code",
2833 FT_UINT16, BASE_DEC, VALS(eap_sim_aka_client_error_codes), 0x0,
2834 NULL, HFILL }},
2836 { &hf_eap_aka_rand, {
2837 "EAP-AKA RAND", "eap.aka.rand",
2838 FT_BYTES, BASE_NONE, NULL, 0x0,
2839 NULL, HFILL }},
2841 { &hf_eap_aka_autn, {
2842 "EAP-AKA AUTN", "eap.aka.autn",
2843 FT_BYTES, BASE_NONE, NULL, 0x0,
2844 NULL, HFILL }},
2846 { &hf_eap_aka_res_len, {
2847 "EAP-AKA RES Length", "eap.aka.res.len",
2848 FT_UINT16, BASE_DEC|BASE_UNIT_STRING, UNS(&units_bit_bits), 0x0,
2849 NULL, HFILL }},
2851 { &hf_eap_aka_res, {
2852 "EAP-AKA RES", "eap.aka.res",
2853 FT_BYTES, BASE_NONE, NULL, 0x0,
2854 NULL, HFILL }},
2856 { &hf_eap_aka_auts, {
2857 "EAP-AKA AUTS", "eap.aka.auts",
2858 FT_BYTES, BASE_NONE, NULL, 0x0,
2859 NULL, HFILL }},
2861 { &hf_eap_aka_subtype_value, {
2862 "EAP-AKA Value", "eap.aka.subtype.value",
2863 FT_BYTES, BASE_NONE, NULL, 0x0,
2864 NULL, HFILL }},
2866 { &hf_eap_leap_version, {
2867 "EAP-LEAP Version", "eap.leap.version",
2868 FT_UINT8, BASE_DEC, NULL, 0x0,
2869 NULL, HFILL }},
2871 { &hf_eap_leap_reserved, {
2872 "EAP-LEAP Reserved", "eap.leap.reserved",
2873 FT_UINT8, BASE_HEX, NULL, 0x0,
2874 NULL, HFILL }},
2876 { &hf_eap_leap_count, {
2877 "EAP-LEAP Count", "eap.leap.count",
2878 FT_UINT8, BASE_DEC, NULL, 0x0,
2879 NULL, HFILL }},
2881 { &hf_eap_leap_peer_challenge, {
2882 "EAP-LEAP Peer-Challenge", "eap.leap.peer_challenge",
2883 FT_BYTES, BASE_NONE, NULL, 0x0,
2884 NULL, HFILL }},
2886 { &hf_eap_leap_peer_response, {
2887 "EAP-LEAP Peer-Response", "eap.leap.peer_response",
2888 FT_BYTES, BASE_NONE, NULL, 0x0,
2889 NULL, HFILL }},
2891 { &hf_eap_leap_ap_challenge, {
2892 "EAP-LEAP AP-Challenge", "eap.leap.ap_challenge",
2893 FT_BYTES, BASE_NONE, NULL, 0x0,
2894 NULL, HFILL }},
2896 { &hf_eap_leap_ap_response, {
2897 "EAP-LEAP AP-Response", "eap.leap.ap_response",
2898 FT_BYTES, BASE_NONE, NULL, 0x0,
2899 NULL, HFILL }},
2901 { &hf_eap_leap_data, {
2902 "EAP-LEAP Data", "eap.leap.data",
2903 FT_BYTES, BASE_NONE, NULL, 0x0,
2904 NULL, HFILL }},
2906 { &hf_eap_leap_name, {
2907 "EAP-LEAP Name", "eap.leap.name",
2908 FT_STRING, BASE_NONE, NULL, 0x0,
2909 NULL, HFILL }},
2911 { &hf_eap_ms_chap_v2_opcode, {
2912 "EAP-MS-CHAP-v2 OpCode", "eap.ms_chap_v2.opcode",
2913 FT_UINT8, BASE_DEC, VALS(eap_ms_chap_v2_opcode_vals), 0x0,
2914 NULL, HFILL }},
2916 { &hf_eap_ms_chap_v2_id, {
2917 "EAP-MS-CHAP-v2 Id", "eap.ms_chap_v2.id",
2918 FT_UINT8, BASE_DEC, NULL, 0x0,
2919 NULL, HFILL }},
2921 { &hf_eap_ms_chap_v2_length, {
2922 "EAP-MS-CHAP-v2 Length", "eap.ms_chap_v2.length",
2923 FT_UINT16, BASE_DEC, NULL, 0x0,
2924 NULL, HFILL }},
2926 { &hf_eap_ms_chap_v2_value_size, {
2927 "EAP-MS-CHAP-v2 Value-Size", "eap.ms_chap_v2.value_size",
2928 FT_UINT8, BASE_DEC, NULL, 0x0,
2929 NULL, HFILL }},
2931 { &hf_eap_ms_chap_v2_challenge, {
2932 "EAP-MS-CHAP-v2 Challenge", "eap.ms_chap_v2.challenge",
2933 FT_BYTES, BASE_NONE, NULL, 0x0,
2934 NULL, HFILL }},
2936 { &hf_eap_ms_chap_v2_name, {
2937 "EAP-MS-CHAP-v2 Name", "eap.ms_chap_v2.name",
2938 FT_STRING, BASE_NONE, NULL, 0x0,
2939 NULL, HFILL }},
2941 { &hf_eap_ms_chap_v2_peer_challenge, {
2942 "EAP-MS-CHAP-v2 Peer-Challenge", "eap.ms_chap_v2.peer_challenge",
2943 FT_BYTES, BASE_NONE, NULL, 0x0,
2944 NULL, HFILL }},
2946 { &hf_eap_ms_chap_v2_reserved, {
2947 "EAP-MS-CHAP-v2 Reserved", "eap.ms_chap_v2.reserved",
2948 FT_BYTES, BASE_NONE, NULL, 0x0,
2949 NULL, HFILL }},
2951 { &hf_eap_ms_chap_v2_nt_response, {
2952 "EAP-MS-CHAP-v2 NT-Response", "eap.ms_chap_v2.nt_response",
2953 FT_BYTES, BASE_NONE, NULL, 0x0,
2954 NULL, HFILL }},
2956 { &hf_eap_ms_chap_v2_flags, {
2957 "EAP-MS-CHAP-v2 Flags", "eap.ms_chap_v2.flags",
2958 FT_UINT8, BASE_HEX, NULL, 0x0,
2959 NULL, HFILL }},
2961 { &hf_eap_ms_chap_v2_response, {
2962 "EAP-MS-CHAP-v2 Response (Unknown Length)", "eap.ms_chap_v2.response",
2963 FT_BYTES, BASE_NONE, NULL, 0x0,
2964 NULL, HFILL }},
2966 { &hf_eap_ms_chap_v2_message, {
2967 "EAP-MS-CHAP-v2 Message", "eap.ms_chap_v2.message",
2968 FT_STRING, BASE_NONE, NULL, 0x0,
2969 NULL, HFILL }},
2971 { &hf_eap_ms_chap_v2_failure_request, {
2972 "EAP-MS-CHAP-v2 Failure-Request", "eap.ms_chap_v2.failure_request",
2973 FT_STRING, BASE_NONE, NULL, 0x0,
2974 NULL, HFILL }},
2976 { &hf_eap_ms_chap_v2_data, {
2977 "EAP-MS-CHAP-v2 Data", "eap.ms_chap_v2.data",
2978 FT_BYTES, BASE_NONE, NULL, 0x0,
2979 NULL, HFILL }},
2981 { &hf_eap_pax_opcode, {
2982 "EAP-PAX OP-Code", "eap.pax.opcode",
2983 FT_UINT8, BASE_HEX, VALS(eap_pax_opcode_vals), 0x0,
2984 NULL, HFILL }},
2986 { &hf_eap_pax_flags, {
2987 "EAP-PAX Flags", "eap.pax.flags",
2988 FT_UINT8, BASE_HEX, NULL, 0x0,
2989 NULL, HFILL }},
2991 { &hf_eap_pax_flags_mf, {
2992 "more fragments", "eap.pax.flags.mf",
2993 FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_MF,
2994 NULL, HFILL }},
2996 { &hf_eap_pax_flags_ce, {
2997 "certificate enabled", "eap.pax.flags.ce",
2998 FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_CE,
2999 NULL, HFILL }},
3001 { &hf_eap_pax_flags_ai, {
3002 "ADE Included", "eap.pax.flags.ai",
3003 FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_AI,
3004 NULL, HFILL }},
3006 { &hf_eap_pax_flags_reserved, {
3007 "reserved", "eap.pax.flags.reserved",
3008 FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_RESERVED,
3009 NULL, HFILL }},
3011 { &hf_eap_pax_mac_id, {
3012 "EAP-PAX MAC ID", "eap.pax.mac_id",
3013 FT_UINT8, BASE_HEX, VALS(eap_pax_mac_id_vals), 0x0,
3014 NULL, HFILL }},
3016 { &hf_eap_pax_dh_group_id, {
3017 "EAP-PAX DH Group ID", "eap.pax.dh_group_id",
3018 FT_UINT8, BASE_HEX, VALS(eap_pax_dh_group_id_vals), 0x0,
3019 NULL, HFILL }},
3021 { &hf_eap_pax_public_key_id, {
3022 "EAP-PAX Public Key ID", "eap.pax.public_key_id",
3023 FT_UINT8, BASE_HEX, VALS(eap_pax_public_key_id_vals), 0x0,
3024 NULL, HFILL }},
3026 { &hf_eap_pax_a_len, {
3027 "EAP-PAX A len", "eap.pax.a.len",
3028 FT_UINT16, BASE_DEC, NULL, 0x0,
3029 NULL, HFILL }},
3031 { &hf_eap_pax_a, {
3032 "EAP-PAX A", "eap.pax.a",
3033 FT_BYTES, BASE_NONE, NULL, 0x0,
3034 NULL, HFILL }},
3036 { &hf_eap_pax_b_len, {
3037 "EAP-PAX B len", "eap.pax.b.len",
3038 FT_UINT16, BASE_DEC, NULL, 0x0,
3039 NULL, HFILL }},
3041 { &hf_eap_pax_b, {
3042 "EAP-PAX B", "eap.pax.b",
3043 FT_BYTES, BASE_NONE, NULL, 0x0,
3044 NULL, HFILL }},
3046 { &hf_eap_pax_cid_len, {
3047 "EAP-PAX CID len", "eap.pax.cid.len",
3048 FT_UINT16, BASE_DEC, NULL, 0x0,
3049 NULL, HFILL }},
3051 { &hf_eap_pax_cid, {
3052 "EAP-PAX CID", "eap.pax.cid",
3053 FT_STRING, BASE_NONE, NULL, 0x0,
3054 NULL, HFILL }},
3056 { &hf_eap_pax_mac_ck_len, {
3057 "EAP-PAX MAC_CK len", "eap.pax.mac_ck.len",
3058 FT_UINT16, BASE_DEC, NULL, 0x0,
3059 NULL, HFILL }},
3061 { &hf_eap_pax_mac_ck, {
3062 "EAP-PAX MAC_CK", "eap.pax.mac_ck",
3063 FT_BYTES, BASE_NONE, NULL, 0x0,
3064 NULL, HFILL }},
3066 { &hf_eap_pax_ade_len, {
3067 "EAP-PAX ADE len", "eap.pax.ade.len",
3068 FT_UINT16, BASE_DEC, NULL, 0x0,
3069 NULL, HFILL }},
3071 { &hf_eap_pax_ade, {
3072 "EAP-PAX ADE", "eap.pax.ade",
3073 FT_BYTES, BASE_NONE, NULL, 0x0,
3074 NULL, HFILL }},
3076 { &hf_eap_pax_mac_icv, {
3077 "EAP-PAX ICV", "eap.pax.icv",
3078 FT_BYTES, BASE_NONE, NULL, 0x0,
3079 NULL, HFILL }},
3081 { &hf_eap_psk_flags, {
3082 "EAP-PSK Flags", "eap.psk.flags",
3083 FT_UINT8, BASE_HEX, NULL, 0x0,
3084 NULL, HFILL }},
3086 { &hf_eap_psk_flags_t, {
3087 "T", "eap.psk.flags.t",
3088 FT_UINT8, BASE_HEX, NULL, EAP_PSK_FLAGS_T_MASK,
3089 NULL, HFILL }},
3091 { &hf_eap_psk_flags_reserved, {
3092 "Reserved", "eap.psk.flags.reserved",
3093 FT_UINT8, BASE_HEX, NULL, 0x3F,
3094 NULL, HFILL }},
3096 { &hf_eap_psk_rand_p, {
3097 "EAP-PSK RAND_P", "eap.psk.rand_p",
3098 FT_BYTES, BASE_NONE, NULL, 0x0,
3099 NULL, HFILL }},
3101 { &hf_eap_psk_rand_s, {
3102 "EAP-PSK RAND_S", "eap.psk.rand_s",
3103 FT_BYTES, BASE_NONE, NULL, 0x0,
3104 NULL, HFILL }},
3106 { &hf_eap_psk_mac_p, {
3107 "EAP-PSK MAC_P", "eap.psk.mac_p",
3108 FT_BYTES, BASE_NONE, NULL, 0x0,
3109 NULL, HFILL }},
3111 { &hf_eap_psk_mac_s, {
3112 "EAP-PSK MAC_S", "eap.psk.mac_s",
3113 FT_BYTES, BASE_NONE, NULL, 0x0,
3114 NULL, HFILL }},
3116 { &hf_eap_psk_id_p, {
3117 "EAP-PSK ID_P", "eap.psk.id_p",
3118 FT_STRING, BASE_NONE, NULL, 0x0,
3119 NULL, HFILL }},
3121 { &hf_eap_psk_id_s, {
3122 "EAP-PSK ID_S", "eap.psk.id_s",
3123 FT_STRING, BASE_NONE, NULL, 0x0,
3124 NULL, HFILL }},
3126 { &hf_eap_psk_pchannel, {
3127 "EAP-PSK Protected Channel (encrypted)", "eap.psk.pchannel",
3128 FT_BYTES, BASE_NONE, NULL, 0x0,
3129 NULL, HFILL }},
3131 { &hf_eap_sake_version, {
3132 "EAP-SAKE Version", "eap.sake.version",
3133 FT_UINT8, BASE_HEX, NULL, 0x0,
3134 NULL, HFILL }},
3136 { &hf_eap_sake_session_id, {
3137 "EAP-SAKE Session ID", "eap.sake.session_id",
3138 FT_UINT8, BASE_HEX, NULL, 0x0,
3139 NULL, HFILL }},
3141 { &hf_eap_sake_subtype, {
3142 "EAP-SAKE Subtype", "eap.sake.subtype",
3143 FT_UINT8, BASE_HEX, VALS(eap_sake_subtype_vals), 0x0,
3144 NULL, HFILL }},
3146 { &hf_eap_sake_attr_type, {
3147 "Attribute Type", "eap.sake.attr.type",
3148 FT_UINT8, BASE_HEX, VALS(eap_sake_attr_type_vals), 0x0,
3149 NULL, HFILL }},
3151 { &hf_eap_sake_attr_len, {
3152 "Attribute Length", "eap.sake.attr.len",
3153 FT_UINT8, BASE_DEC, NULL, 0x0,
3154 NULL, HFILL }},
3156 { &hf_eap_sake_attr_value, {
3157 "Attribute Value", "eap.sake.attr.val",
3158 FT_BYTES, BASE_NONE, NULL, 0x0,
3159 NULL, HFILL }},
3161 { &hf_eap_sake_attr_value_str, {
3162 "Attribute Value", "eap.sake.attr.val_str",
3163 FT_STRING, BASE_NONE, NULL, 0x0,
3164 NULL, HFILL }},
3166 { &hf_eap_sake_attr_value_uint48, {
3167 "Attribute Value", "eap.sake.attr.val_uint48",
3168 FT_UINT48, BASE_DEC, NULL, 0x0,
3169 NULL, HFILL }},
3171 { &hf_eap_gpsk_opcode, {
3172 "EAP-GPSK OP-Code", "eap.gpsk.opcode",
3173 FT_UINT8, BASE_HEX, VALS(eap_gpsk_opcode_vals), 0x0,
3174 NULL, HFILL }},
3176 { &hf_eap_gpsk_id_server_len, {
3177 "EAP-GPSK ID_Server len", "eap.gpsk.id_server.len",
3178 FT_UINT16, BASE_DEC, NULL, 0x0,
3179 NULL, HFILL }},
3181 { &hf_eap_gpsk_id_server, {
3182 "EAP-GPSK ID_Server", "eap.gpsk.id_server",
3183 FT_STRING, BASE_NONE, NULL, 0x0,
3184 NULL, HFILL }},
3186 { &hf_eap_gpsk_id_peer_len, {
3187 "EAP-GPSK ID_Peer len", "eap.gpsk.id_peer.len",
3188 FT_UINT16, BASE_DEC, NULL, 0x0,
3189 NULL, HFILL }},
3191 { &hf_eap_gpsk_id_peer, {
3192 "EAP-GPSK ID_Peer", "eap.gpsk.id_peer",
3193 FT_STRING, BASE_NONE, NULL, 0x0,
3194 NULL, HFILL }},
3196 { &hf_eap_gpsk_rand_server, {
3197 "EAP-GPSK Rand_Server", "eap.gpsk.rand_server",
3198 FT_BYTES, BASE_NONE, NULL, 0x0,
3199 NULL, HFILL }},
3201 { &hf_eap_gpsk_rand_peer, {
3202 "EAP-GPSK Rand_Peer", "eap.gpsk.rand_peer",
3203 FT_BYTES, BASE_NONE, NULL, 0x0,
3204 NULL, HFILL }},
3206 { &hf_eap_gpsk_csuite_list_len, {
3207 "Len", "eap.gpsk.csuite_list_len",
3208 FT_UINT16, BASE_DEC, NULL, 0x0,
3209 NULL, HFILL }},
3211 { &hf_eap_gpsk_csuite_vendor, {
3212 "Vendor", "eap.gpsk.csuite.vendor",
3213 FT_UINT32, BASE_HEX, NULL, 0x0,
3214 NULL, HFILL }},
3216 { &hf_eap_gpsk_csuite_specifier, {
3217 "Specifier", "eap.gpsk.csuite.specifier",
3218 FT_UINT16, BASE_HEX, NULL, 0x0,
3219 NULL, HFILL }},
3221 { &hf_eap_gpsk_pd_payload_len, {
3222 "EAP-GPSK PD_Payload len", "eap.gpsk.pd_payload.len",
3223 FT_UINT16, BASE_DEC, NULL, 0x0,
3224 NULL, HFILL }},
3226 { &hf_eap_gpsk_pd_payload, {
3227 "EAP-GPSK PD_Payload", "eap.gpsk.pd_payload",
3228 FT_BYTES, BASE_NONE, NULL, 0x0,
3229 NULL, HFILL }},
3231 { &hf_eap_gpsk_payload_mac, {
3232 "EAP-GPSK Payload MAC", "eap.gpsk.payload_mac",
3233 FT_BYTES, BASE_NONE, NULL, 0x0,
3234 NULL, HFILL }},
3236 { &hf_eap_gpsk_failure_code, {
3237 "EAP-GPSK Failure code", "eap.gpsk.failure_code",
3238 FT_UINT32, BASE_HEX, VALS(eap_gpsk_failure_code_vals), 0x0,
3239 NULL, HFILL }},
3241 { &hf_eap_data, {
3242 "EAP Data", "eap.data",
3243 FT_BYTES, BASE_NONE, NULL, 0x0,
3244 NULL, HFILL }},
3246 { &hf_eap_fast_type, {
3247 "EAP-FAST Type", "eap.fast.type",
3248 FT_UINT16, BASE_DEC, NULL, 0x0,
3249 NULL, HFILL }},
3251 { &hf_eap_fast_length, {
3252 "EAP-FAST Length", "eap.fast.length",
3253 FT_UINT16, BASE_DEC, NULL, 0x0,
3254 NULL, HFILL }},
3256 { &hf_eap_fast_aidd, {
3257 "Authority ID Data", "eap.fast.authority_id_data",
3258 FT_BYTES, BASE_NONE, NULL, 0x0,
3259 NULL, HFILL }},
3261 { &hf_eap_msauth_tlv_mandatory, {
3262 "Mandatory", "eap.msauth-tlv.mandatory",
3263 FT_BOOLEAN, 16, NULL, MSAUTH_TLV_MANDATORY,
3264 NULL, HFILL }},
3266 { &hf_eap_msauth_tlv_reserved, {
3267 "Reserved", "eap.msauth-tlv.reserved",
3268 FT_BOOLEAN, 16, NULL, MSAUTH_TLV_RESERVED,
3269 NULL, HFILL }},
3271 { &hf_eap_msauth_tlv_type, {
3272 "Type", "eap.msauth-tlv.type",
3273 FT_UINT16, BASE_DEC, VALS(eap_msauth_tlv_type_vals), MSAUTH_TLV_TYPE,
3274 NULL, HFILL }},
3276 { &hf_eap_msauth_tlv_len, {
3277 "Length", "eap.msauth-tlv.len",
3278 FT_UINT16, BASE_DEC, NULL, 0x00,
3279 NULL, HFILL }},
3281 { &hf_eap_msauth_tlv_val, {
3282 "Value", "eap.msauth-tlv.val",
3283 FT_BYTES, BASE_NONE, NULL, 0x0,
3284 NULL, HFILL }},
3286 { &hf_eap_msauth_tlv_status, {
3287 "Status", "eap.msauth-tlv.status",
3288 FT_UINT16, BASE_DEC, VALS(eap_msauth_tlv_status_vals), 0x0,
3289 NULL, HFILL }},
3291 { &hf_eap_msauth_tlv_crypto_reserved, {
3292 "Reserved", "eap.msauth-tlv.crypto.reserved",
3293 FT_UINT8, BASE_DEC, NULL, 0x0,
3294 NULL, HFILL }},
3296 { &hf_eap_msauth_tlv_crypto_version, {
3297 "Version", "eap.msauth-tlv.crypto.version",
3298 FT_UINT8, BASE_DEC, NULL, 0x0,
3299 NULL, HFILL }},
3301 { &hf_eap_msauth_tlv_crypto_rcv_version, {
3302 "Received Version", "eap.msauth-tlv.crypto.received-version",
3303 FT_UINT8, BASE_DEC, NULL, 0x0,
3304 NULL, HFILL }},
3306 { &hf_eap_msauth_tlv_crypto_subtype, {
3307 "Subtype", "eap.msauth-tlv.crypto.subtype",
3308 FT_UINT8, BASE_DEC, VALS(eap_msauth_tlv_crypto_subtype_vals), 0x0,
3309 NULL, HFILL }},
3311 { &hf_eap_msauth_tlv_crypto_nonce, {
3312 "Nonce", "eap.msauth-tlv.crypto.nonce",
3313 FT_BYTES, BASE_NONE, NULL, 0x0,
3314 NULL, HFILL }},
3316 { &hf_eap_msauth_tlv_crypto_cmac, {
3317 "Compound MAC", "eap.msauth-tlv.crypto.cmac",
3318 FT_BYTES, BASE_NONE, NULL, 0x0,
3319 NULL, HFILL }},
3321 /* Expanded type fields */
3322 { &hf_eap_ext_vendor_id, {
3323 "EAP-EXT Vendor Id", "eap.ext.vendor_id",
3324 FT_UINT24, BASE_HEX, VALS(eap_ext_vendor_id_vals), 0x0,
3325 NULL, HFILL }},
3327 { &hf_eap_ext_vendor_type, {
3328 "EAP-EXT Vendor Type", "eap.ext.vendor_type",
3329 FT_UINT32, BASE_HEX, VALS(eap_ext_vendor_type_vals), 0x0,
3330 NULL, HFILL }},
3332 { &hf_eap_ikev2_flags, {
3333 "EAP-IKEv2 Flags", "eap.ikev2.flags",
3334 FT_UINT8, BASE_HEX, NULL, 0x0,
3335 NULL, HFILL } },
3337 { &hf_eap_ikev2_flag_l, {
3338 "Length Included", "eap.ikve2.flags.len_included",
3339 FT_BOOLEAN, 8, NULL, EAP_IKEV2_FLAG_L,
3340 NULL, HFILL } },
3342 { &hf_eap_ikev2_flag_m, {
3343 "More Fragments", "eap.ikev2.flags.more_fragments",
3344 FT_BOOLEAN, 8, NULL, EAP_IKEV2_FLAG_M,
3345 NULL, HFILL } },
3347 { &hf_eap_ikev2_flag_i, {
3348 "Integrity Checksum Data present", "eap.ikev2.flags.icv_present",
3349 FT_BOOLEAN, 8, NULL, EAP_IKEV2_FLAG_I,
3350 NULL, HFILL } },
3352 { &hf_eap_ikev2_len, {
3353 "EAP-IKEv2 Length", "eap.ikev2.len",
3354 FT_UINT32, BASE_DEC, NULL, 0x0,
3355 NULL, HFILL } },
3357 { &hf_eap_ikev2_int_chk_data, {
3358 "EAP-IKEv2 Integrity Checksum Data", "eap.ikev2.integrity_checksum_data",
3359 FT_BYTES, BASE_NONE, NULL, 0x0,
3360 NULL, HFILL } },
3362 static int *ett[] = {
3363 &ett_eap,
3364 &ett_eap_pax_flags,
3365 &ett_eap_psk_flags,
3366 &ett_eap_gpsk_csuite_list,
3367 &ett_eap_gpsk_csuite,
3368 &ett_eap_gpsk_csuite_sel,
3369 &ett_eap_sake_attr,
3370 &ett_eap_msauth_tlv,
3371 &ett_eap_msauth_tlv_tree,
3372 &ett_eap_tls_fragment,
3373 &ett_eap_tls_fragments,
3374 &ett_eap_sim_attr,
3375 &ett_eap_aka_attr,
3376 &ett_eap_exp_attr,
3377 &ett_eap_tls_flags,
3378 &ett_identity,
3379 &ett_eap_ikev2_flags,
3381 static ei_register_info ei[] = {
3382 { &ei_eap_ms_chap_v2_length, { "eap.ms_chap_v2.length.invalid", PI_PROTOCOL, PI_WARN, "Invalid Length", EXPFILL }},
3383 { &ei_eap_mitm_attacks, { "eap.mitm_attacks", PI_SECURITY, PI_WARN, "Vulnerable to MITM attacks. If possible, change EAP type.", EXPFILL }},
3384 { &ei_eap_md5_value_size_overflow, { "eap.md5.value_size.overflow", PI_PROTOCOL, PI_WARN, "Overflow", EXPFILL }},
3385 { &ei_eap_dictionary_attacks, { "eap.dictionary_attacks", PI_SECURITY, PI_WARN,
3386 "Vulnerable to dictionary attacks. If possible, change EAP type."
3387 " See http://www.cisco.com/warp/public/cc/pd/witc/ao350ap/prodlit/2331_pp.pdf", EXPFILL }},
3388 { &ei_eap_identity_nonascii, { "eap.identity.nonascii", PI_PROTOCOL, PI_WARN, "Non-ASCII characters within identity", EXPFILL }},
3389 { &ei_eap_identity_invalid, { "eap.identity.invalid", PI_PROTOCOL, PI_WARN, "Invalid identity code", EXPFILL }},
3390 { &ei_eap_retransmission, { "eap.retransmission", PI_SEQUENCE, PI_NOTE, "This packet is a retransmission", EXPFILL }},
3391 { &ei_eap_bad_length, { "eap.bad_length", PI_PROTOCOL, PI_WARN, "Bad length (too small or too large)", EXPFILL }},
3394 expert_module_t* expert_eap;
3396 proto_eap = proto_register_protocol("Extensible Authentication Protocol",
3397 "EAP", "eap");
3398 proto_register_field_array(proto_eap, hf, array_length(hf));
3399 proto_register_subtree_array(ett, array_length(ett));
3400 expert_eap = expert_register_protocol(proto_eap);
3401 expert_register_field_array(expert_eap, ei, array_length(ei));
3403 eap_handle = register_dissector("eap", dissect_eap, proto_eap);
3405 reassembly_table_register(&eap_tls_reassembly_table,
3406 &addresses_reassembly_table_functions);
3408 eap_expanded_type_dissector_table = register_dissector_table("eap.ext.vendor_id",
3409 "EAP-EXT Vendor Id",
3410 proto_eap, FT_UINT24,
3411 BASE_HEX);
3415 void
3416 proto_reg_handoff_eap(void)
3419 * Get a handle for the SSL/TLS dissector.
3421 tls_handle = find_dissector_add_dependency("tls", proto_eap);
3422 diameter_avps_handle = find_dissector_add_dependency("diameter_avps", proto_eap);
3423 peap_handle = find_dissector_add_dependency("peap", proto_eap);
3424 teap_handle = find_dissector_add_dependency("teap", proto_eap);
3426 isakmp_handle = find_dissector_add_dependency("isakmp", proto_eap);
3428 dissector_add_uint("ppp.protocol", PPP_EAP, eap_handle);
3429 dissector_add_uint("eapol.type", EAPOL_EAP, eap_handle);
3432 * Editor modelines
3434 * Local Variables:
3435 * c-basic-offset: 2
3436 * tab-width: 8
3437 * indent-tabs-mode: nil
3438 * End:
3440 * ex: set shiftwidth=2 tabstop=8 expandtab:
3441 * :indentSize=2:tabSize=8:noTabs=true: