2 * Routines for EAP Extensible Authentication Protocol dissection
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
14 #include <epan/packet.h>
15 #include <epan/conversation.h>
16 #include <epan/ppptypes.h>
17 #include <epan/reassemble.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);
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
;
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] */
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
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
[] = {
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)" },
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" },
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" },
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" },
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" },
323 1) http://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xml
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
[] = {
345 { 7, "AT_NONCE_MT" },
346 { 10, "AT_PERMANENT_ID_REQ" },
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"},
360 { 128, "Unassigned" },
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" },
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" },
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" },
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" },
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
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" },
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" },
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" },
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" },
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" },
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" },
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
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" },
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" },
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" },
572 static const value_string eap_msauth_tlv_status_vals
[] = {
578 static const value_string eap_msauth_tlv_crypto_subtype_vals
[] = {
579 { 0, "Binding Request" },
580 { 1, "Binding Response" },
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.
618 uint32_t eap_reass_cookie
;
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. */
625 int info
; /* interpretation depends on EAP message type */
635 |L M S R R R R R| TLS (RFC5216)
637 |L M S R R| V | TTLS (RFC5281) and FAST (RFC4851)
639 |L M S O R| V | TEAP (RFC7170)
641 |L M S R R R| V | PEAPv0 (draft-kamath-pppext-peapv0)
643 |L M S R R| V | PEAPv1 (draft-josefsson-pppext-eap-tls-eap-06) and PEAPv2 (draft-josefsson-pppext-eap-tls-eap-10)
649 O = Outer TLV length included (TEAP only)
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 */
720 RFC5106, 8.1, page 17
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" },
756 static const value_string eap_ext_vendor_type_vals
[] = {
757 { WFA_SIMPLECONFIG_TYPE
, "SimpleConfig" },
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
)
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
);
775 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_ext_vendor_type
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &vendor_type
);
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 ********************************************************************* */
794 dissect_eap_mschapv2(proto_tree
*eap_tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
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
);
811 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_id
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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
);
820 expert_add_info(pinfo
, item
, &ei_eap_ms_chap_v2_length
);
825 case MS_CHAP_V2_CHALLENGE
:
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
);
833 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_challenge
,
834 tvb
, offset
, value_size
, ENC_NA
);
835 offset
+= value_size
;
839 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_name
,
840 tvb
, offset
, left
, ENC_ASCII
);
842 case MS_CHAP_V2_RESPONSE
:
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
);
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
);
854 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_reserved
,
855 tvb
, offset
, 8, ENC_NA
);
857 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_nt_response
,
858 tvb
, offset
, 24, ENC_NA
);
860 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_flags
,
861 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
865 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_response
, tvb
, offset
, value_size
, ENC_NA
);
866 offset
+= value_size
;
871 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_name
, tvb
, offset
, left
, ENC_ASCII
);
873 case MS_CHAP_V2_SUCCESS
:
876 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_message
,
877 tvb
, offset
, left
, ENC_ASCII
);
879 case MS_CHAP_V2_FAILURE
:
882 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_failure_request
,
883 tvb
, offset
, left
, ENC_ASCII
);
886 proto_tree_add_item(eap_tree
, hf_eap_ms_chap_v2_data
, tvb
, offset
, left
, ENC_NA
);
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)) {
909 /* Dissect the 3GPP identity */
911 dissect_eap_identity_3gpp(tvbuff_t
*tvb
, packet_info
* pinfo
, proto_tree
* tree
, int offset
, int size
)
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
;
926 int hf_eap_identity_mcc_mnc
;
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) {
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="))) {
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.
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"));
975 /* XXX - Would adding the Base64 decoded (but still encrypted) IMSI
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");
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)) {
999 const char* realm
= strchr(tokens
[2], '@');
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
)) {
1014 /* Check if identity string complies with ASCII character set */
1015 if (tvb_ascii_isprint(tvb
, offset
, size
) == false) {
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 */
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
)) {
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.
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);
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
);
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
);
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
);
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
);
1083 case 'G': /* TODO: 'G' Unknown */
1084 case 'I': /* TODO: 'I' Unknown */
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
);
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
)) {
1103 if (!try_val_to_str_ext(mcc
* 100 + mnc
, &mcc_mnc_2digits_codes_ext
)) {
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
;
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
, '@');
1119 /* Should always be true. */
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
);
1138 g_strfreev(realm_tokens
);
1144 dissect_eap_identity(tvbuff_t
*tvb
, packet_info
* pinfo
, proto_tree
* tree
, int offset
, int size
)
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
);
1163 dissect_eap_sim(proto_tree
*eap_tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, int offset
, int size
)
1167 proto_tree_add_item(eap_tree
, hf_eap_sim_subtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1174 proto_tree_add_item(eap_tree
, hf_eap_sim_reserved
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1178 /* Rest of EAP-SIM data is in Type-Len-Value format. */
1180 uint8_t type
, length
;
1183 proto_tree
*attr_tree
;
1188 type
= tvb_get_uint8(tvb
, aoffset
);
1189 length
= tvb_get_uint8(tvb
, aoffset
+ 1);
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
,
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
);
1205 proto_tree_add_item(attr_tree
, hf_eap_sim_subtype_length
, tvb
, aoffset
, 1, ENC_BIG_ENDIAN
);
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
);
1219 proto_tree_add_item(attr_tree
, hf_eap_identity_padding
, tvb
,
1220 aoffset
+ 2 + tvb_get_ntohs(tvb
, aoffset
), padding
, ENC_NA
);
1223 case AT_NOTIFICATION
:
1224 proto_tree_add_item(attr_tree
, hf_eap_sim_notification_type
, tvb
, aoffset
, 2, ENC_BIG_ENDIAN
);
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
);
1230 proto_tree_add_item(attr_tree
, hf_eap_sim_subtype_value
, tvb
, aoffset
, aleft
, ENC_NA
);
1233 offset
+= 4 * length
;
1239 dissect_eap_aka(proto_tree
*eap_tree
, tvbuff_t
*tvb
, packet_info
* pinfo
, int offset
, int size
)
1243 proto_tree_add_item(eap_tree
, hf_eap_aka_subtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1250 proto_tree_add_item(eap_tree
, hf_eap_aka_reserved
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1254 /* Rest of EAP-AKA data is in Type-Len-Value format. */
1256 uint8_t type
, length
;
1257 uint32_t actual_length
;
1260 proto_tree
*attr_tree
;
1265 type
= tvb_get_uint8(tvb
, aoffset
);
1266 length
= tvb_get_uint8(tvb
, aoffset
+ 1);
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
,
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
);
1282 proto_tree_add_item(attr_tree
, hf_eap_aka_subtype_length
, tvb
, aoffset
, 1, ENC_BIG_ENDIAN
);
1288 proto_tree_add_item(attr_tree
, hf_eap_aka_reserved
, tvb
, aoffset
, 2, ENC_BIG_ENDIAN
);
1291 proto_tree_add_item(attr_tree
, hf_eap_aka_rand
, tvb
, aoffset
, aleft
, ENC_NA
);
1294 proto_tree_add_item(attr_tree
, hf_eap_aka_reserved
, tvb
, aoffset
, 2, ENC_BIG_ENDIAN
);
1297 proto_tree_add_item(attr_tree
, hf_eap_aka_autn
, tvb
, aoffset
, aleft
, ENC_NA
);
1300 proto_tree_add_item_ret_uint(attr_tree
, hf_eap_aka_res_len
, tvb
, aoffset
, 2, ENC_BIG_ENDIAN
, &actual_length
);
1302 proto_tree_add_bits_item(attr_tree
, hf_eap_aka_res
, tvb
, aoffset
<< 3, actual_length
, ENC_NA
);
1305 proto_tree_add_item(attr_tree
, hf_eap_aka_auts
, tvb
, aoffset
, aleft
, ENC_NA
);
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
;
1316 proto_tree_add_item(attr_tree
, hf_eap_identity_padding
, tvb
,
1317 aoffset
+ 2 + actual_length
, padding
, ENC_NA
);
1320 case AT_NOTIFICATION
:
1321 proto_tree_add_item(attr_tree
, hf_eap_aka_notification_type
, tvb
, aoffset
, 2, ENC_BIG_ENDIAN
);
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
);
1327 proto_tree_add_item(attr_tree
, hf_eap_aka_subtype_value
, tvb
, aoffset
, aleft
, ENC_NA
);
1330 offset
+= 4 * length
;
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
,
1349 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_pax_opcode
, tvb
, offset
, 1, ENC_NA
, &opcode
);
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
);
1359 proto_tree_add_item(eap_tree
, hf_eap_pax_mac_id
, tvb
, offset
, 1, ENC_NA
);
1362 proto_tree_add_item(eap_tree
, hf_eap_pax_dh_group_id
, tvb
, offset
, 1, ENC_NA
);
1365 proto_tree_add_item(eap_tree
, hf_eap_pax_public_key_id
, tvb
, offset
, 1, ENC_NA
);
1370 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_pax_a_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1372 proto_tree_add_item(eap_tree
, hf_eap_pax_a
, tvb
, offset
, len
, ENC_NA
);
1374 len
= 5 + size
- offset
;
1375 proto_tree_add_item(eap_tree
, hf_eap_pax_mac_icv
, tvb
, offset
, len
, ENC_NA
);
1379 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_pax_b_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1381 proto_tree_add_item(eap_tree
, hf_eap_pax_b
, tvb
, offset
, len
, ENC_NA
);
1383 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_pax_cid_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1385 proto_tree_add_item(eap_tree
, hf_eap_pax_cid
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
);
1387 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_pax_mac_ck_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1389 proto_tree_add_item(eap_tree
, hf_eap_pax_mac_ck
, tvb
, offset
, len
, ENC_NA
);
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
);
1394 proto_tree_add_item(eap_tree
, hf_eap_pax_ade
, tvb
, offset
, len
, ENC_NA
);
1397 len
= 5 + size
- offset
;
1398 proto_tree_add_item(eap_tree
, hf_eap_pax_mac_icv
, tvb
, offset
, len
, ENC_NA
);
1402 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_pax_mac_ck_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1404 proto_tree_add_item(eap_tree
, hf_eap_pax_mac_ck
, tvb
, offset
, len
, ENC_NA
);
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
);
1409 proto_tree_add_item(eap_tree
, hf_eap_pax_ade
, tvb
, offset
, len
, ENC_NA
);
1412 len
= 5 + size
- offset
;
1413 proto_tree_add_item(eap_tree
, hf_eap_pax_mac_icv
, tvb
, offset
, len
, ENC_NA
);
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
);
1420 proto_tree_add_item(eap_tree
, hf_eap_pax_ade
, tvb
, offset
, len
, ENC_NA
);
1423 len
= 5 + size
- offset
;
1424 proto_tree_add_item(eap_tree
, hf_eap_pax_mac_icv
, tvb
, offset
, len
, ENC_NA
);
1432 /* TODO implement */
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
);
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
,
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
);
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
);
1469 proto_tree_add_item(eap_tree
, hf_eap_psk_id_s
, tvb
, offset
, size
+ 5 - offset
, ENC_ASCII
| ENC_NA
);
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
);
1476 proto_tree_add_item(eap_tree
, hf_eap_psk_rand_p
, tvb
, offset
, 16, ENC_NA
);
1478 proto_tree_add_item(eap_tree
, hf_eap_psk_mac_p
, tvb
, offset
, 16, ENC_NA
);
1480 proto_tree_add_item(eap_tree
, hf_eap_psk_id_p
, tvb
, offset
, size
+ 5 - offset
, ENC_ASCII
| ENC_NA
);
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
);
1487 proto_tree_add_item(eap_tree
, hf_eap_psk_mac_s
, tvb
, offset
, 16, ENC_NA
);
1489 offset
= dissect_eap_psk_pchannel(eap_tree
, tvb
, offset
, size
+ 5 - offset
);
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
);
1495 offset
= dissect_eap_psk_pchannel(eap_tree
, tvb
, offset
, size
+ 5 - offset
);
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
);
1512 proto_tree_add_item(csuite_tree
, hf_eap_gpsk_csuite_specifier
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1518 dissect_eap_gpsk_csuite_list(proto_tree
*eap_tree
, tvbuff_t
*tvb
, int offset
)
1520 int start_offset
= offset
;
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
);
1530 while (offset
< start_offset
+ len
) {
1531 csuite_tree
= proto_tree_add_subtree(list_tree
, tvb
, offset
, 6, ett_eap_gpsk_csuite
,
1533 proto_tree_add_item(csuite_tree
, hf_eap_gpsk_csuite_vendor
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1535 proto_tree_add_item(csuite_tree
, hf_eap_gpsk_csuite_specifier
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1542 dissect_eap_sake_attribute(proto_tree
*eap_tree
, tvbuff_t
*tvb
, int offset
, int size
)
1544 int start_offset
= offset
;
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
) {
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
,
1560 proto_tree_add_item(attr_tree
, hf_eap_sake_attr_type
, tvb
, offset
, 1, ENC_NA
);
1562 proto_tree_add_item(attr_tree
, hf_eap_sake_attr_len
, tvb
, offset
, 1, ENC_NA
);
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
);
1572 case SAKE_AT_MSK_LIFE
:
1573 proto_tree_add_item(attr_tree
, hf_eap_sake_attr_value_uint48
, tvb
, offset
, len
,
1577 case SAKE_AT_RAND_S
:
1578 case SAKE_AT_RAND_P
:
1583 case SAKE_AT_ANY_ID_REQ
:
1584 case SAKE_AT_PERM_ID_REQ
:
1585 case SAKE_AT_ENCR_DATA
:
1587 case SAKE_AT_PADDING
:
1588 case SAKE_AT_NEXT_TMPID
:
1590 proto_tree_add_item(attr_tree
, hf_eap_sake_attr_value
, tvb
, offset
, len
, ENC_NA
);
1594 return offset
- start_offset
;
1598 dissect_eap_sake_attributes(proto_tree
*eap_tree
, tvbuff_t
*tvb
, int offset
, int size
)
1601 while (offset
< size
) {
1602 attr_size
= dissect_eap_sake_attribute(eap_tree
, tvb
, offset
, size
);
1603 if (attr_size
== -1) {
1606 offset
+= attr_size
;
1611 dissect_eap_sake(proto_tree
*eap_tree
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
, int size
)
1616 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_sake_version
, tvb
, offset
, 1, ENC_NA
, &version
);
1619 /* RFC 4763 specify version 2. Everything else is unsupported */
1622 proto_tree_add_item(eap_tree
, hf_eap_sake_session_id
, tvb
, offset
, 1, ENC_NA
);
1624 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_sake_subtype
, tvb
, offset
, 1, ENC_NA
, &subtype
);
1628 case SAKE_CHALLENGE
:
1630 case SAKE_AUTH_REJECT
:
1632 dissect_eap_sake_attributes(eap_tree
, tvb
, offset
, size
+ 5 - offset
);
1640 dissect_eap_gpsk(proto_tree
*eap_tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, int size
)
1645 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_gpsk_opcode
, tvb
, offset
, 1, ENC_NA
, &opcode
);
1647 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s",
1648 val_to_str(opcode
, eap_gpsk_opcode_vals
, "Unknown opcode (0x%02X)"));
1652 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_gpsk_id_server_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1654 proto_tree_add_item(eap_tree
, hf_eap_gpsk_id_server
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
);
1656 proto_tree_add_item(eap_tree
, hf_eap_gpsk_rand_server
, tvb
, offset
, 32, ENC_NA
);
1658 offset
= dissect_eap_gpsk_csuite_list(eap_tree
, tvb
, offset
);
1661 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_gpsk_id_peer_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1663 proto_tree_add_item(eap_tree
, hf_eap_gpsk_id_peer
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
);
1665 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_gpsk_id_server_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1667 proto_tree_add_item(eap_tree
, hf_eap_gpsk_id_server
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
);
1669 proto_tree_add_item(eap_tree
, hf_eap_gpsk_rand_peer
, tvb
, offset
, 32, ENC_NA
);
1671 proto_tree_add_item(eap_tree
, hf_eap_gpsk_rand_server
, tvb
, offset
, 32, ENC_NA
);
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
);
1678 proto_tree_add_item(eap_tree
, hf_eap_gpsk_pd_payload
, tvb
, offset
, len
, ENC_NA
);
1681 len
= size
+ 5 - offset
;
1682 proto_tree_add_item(eap_tree
, hf_eap_gpsk_payload_mac
, tvb
, offset
, len
, ENC_NA
);
1686 proto_tree_add_item(eap_tree
, hf_eap_gpsk_rand_peer
, tvb
, offset
, 32, ENC_NA
);
1688 proto_tree_add_item(eap_tree
, hf_eap_gpsk_rand_server
, tvb
, offset
, 32, ENC_NA
);
1690 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_gpsk_id_server_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1692 proto_tree_add_item(eap_tree
, hf_eap_gpsk_id_server
, tvb
, offset
, len
, ENC_ASCII
| ENC_NA
);
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
);
1698 proto_tree_add_item(eap_tree
, hf_eap_gpsk_pd_payload
, tvb
, offset
, len
, ENC_NA
);
1701 len
= size
+ 5 - offset
;
1702 proto_tree_add_item(eap_tree
, hf_eap_gpsk_payload_mac
, tvb
, offset
, len
, ENC_NA
);
1706 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_gpsk_pd_payload_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &len
);
1709 proto_tree_add_item(eap_tree
, hf_eap_gpsk_pd_payload
, tvb
, offset
, len
, ENC_NA
);
1712 len
= size
+ 5 - offset
;
1713 proto_tree_add_item(eap_tree
, hf_eap_gpsk_payload_mac
, tvb
, offset
, len
, ENC_NA
);
1717 proto_tree_add_item(eap_tree
, hf_eap_gpsk_failure_code
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1720 case GPSK_PROTECTED_FAIL
:
1721 proto_tree_add_item(eap_tree
, hf_eap_gpsk_failure_code
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1723 len
= size
+ 5 - offset
;
1724 proto_tree_add_item(eap_tree
, hf_eap_gpsk_payload_mac
, tvb
, offset
, len
, ENC_NA
);
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");
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
);
1757 proto_tree_add_item(tree
, hf_eap_msauth_tlv_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
1761 case MSAUTH_TLV_TYPE_EXTENSION_RESULT
:
1762 proto_tree_add_item(tree
, hf_eap_msauth_tlv_status
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
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
);
1769 proto_tree_add_item(tree
, hf_eap_msauth_tlv_crypto_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1771 proto_tree_add_item(tree
, hf_eap_msauth_tlv_crypto_rcv_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1773 proto_tree_add_item(tree
, hf_eap_msauth_tlv_crypto_subtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
1775 proto_tree_add_item(tree
, hf_eap_msauth_tlv_crypto_nonce
, tvb
, offset
, 32, ENC_NA
);
1777 proto_tree_add_item(tree
, hf_eap_msauth_tlv_crypto_cmac
, tvb
, offset
, 20, ENC_NA
);
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
);
1789 if (offset
< size
) {
1798 dissect_eap(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1801 uint8_t eap_identifier
;
1805 conversation_t
*conversation
= NULL
;
1806 conv_state_t
*conversation_state
= NULL
;
1807 frame_state_t
*packet_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
);
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;
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
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
1918 if (eap_code
== EAP_FAILURE
)
1919 conversation_state
->leap_state
= -1;
1921 eap_len
= tvb_get_ntohs(tvb
, 2);
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));
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
);
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
))) {
1977 int size
= len
- offset
;
1980 /*********************************************************************
1981 **********************************************************************/
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;
1992 /*********************************************************************
1993 **********************************************************************/
1994 case EAP_TYPE_NOTIFY
:
1995 proto_tree_add_item(eap_tree
, hf_eap_notification
, tvb
,
1996 offset
, size
, ENC_ASCII
);
1999 /*********************************************************************
2000 **********************************************************************/
2002 proto_tree_add_item(eap_tree
, hf_eap_type_nak
, tvb
,
2003 offset
, 1, ENC_BIG_ENDIAN
);
2005 /*********************************************************************
2006 **********************************************************************/
2009 uint8_t value_size
= tvb_get_uint8(tvb
, offset
);
2010 int extra_len
= size
- 1 - value_size
;
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;
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
);
2032 /*********************************************************************
2034 **********************************************************************/
2041 bool more_fragments
;
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.
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
);
2065 proto_tree_add_item_ret_boolean(eap_tls_flags_tree
, hf_eap_tls_flag_o
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &outer_tlvs
);
2070 proto_tree_add_item(eap_tls_flags_tree
, hf_eap_tls_flags_version
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2076 /* Length field, 4 bytes, OPTIONAL. */
2078 proto_tree_add_item(eap_tree
, hf_eap_tls_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2083 /* Outer TLV Length field, 4 bytes, OPTIONAL. */
2085 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_tls_outer_tlvs_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
, &outer_tlvs_length
);
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
);
2101 proto_tree_add_item_ret_uint(eap_tree
, hf_eap_fast_length
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &length
);
2105 proto_tree_add_item(eap_tree
, hf_eap_data
, tvb
, offset
, length
, ENC_NA
);
2109 proto_tree_add_item(eap_tree
, hf_eap_fast_aidd
, tvb
, offset
, length
, ENC_NA
);
2119 tvbuff_t
*next_tvb
= NULL
;
2121 bool save_fragmented
;
2123 tvb_len
= tvb_captured_length_remaining(tvb
, offset
);
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
);
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
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
);
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
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
;
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
2272 save_fragmented
= pinfo
->fragmented
;
2273 pinfo
->fragmented
= true;
2274 fd_head
= fragment_add_seq(&eap_tls_reassembly_table
,
2276 pinfo
, eap_reass_cookie
, NULL
,
2281 if (fd_head
!= NULL
) {
2282 if (fd_head
->reassembled_in
== pinfo
->num
) {
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;
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
);
2314 tls_set_appdata_dissector(tls_handle
, pinfo
, diameter_avps_handle
);
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
);
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
);
2330 call_dissector(tls_handle
, next_tvb
, pinfo
, eap_tree
);
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 **********************************************************************/
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
);
2353 proto_tree_add_item(eap_tree
, hf_eap_leap_reserved
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
2357 count
= tvb_get_uint8(tvb
, offset
);
2358 proto_tree_add_item(eap_tree
, hf_eap_leap_count
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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.
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
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
) {
2406 proto_tree_add_item(eap_tree
, hf_eap_leap_peer_challenge
, tvb
, offset
, count
, ENC_NA
);
2410 proto_tree_add_item(eap_tree
, hf_eap_leap_peer_response
, tvb
, offset
, count
, ENC_NA
);
2414 proto_tree_add_item(eap_tree
, hf_eap_leap_ap_challenge
, tvb
, offset
, count
, ENC_NA
);
2418 proto_tree_add_item(eap_tree
, hf_eap_leap_ap_response
, tvb
, offset
, count
, ENC_NA
);
2422 proto_tree_add_item(eap_tree
, hf_eap_leap_data
, tvb
, offset
, count
, ENC_NA
);
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 **********************************************************************/
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 **********************************************************************/
2453 case EAP_TYPE_AKA_PRIME
:
2454 dissect_eap_aka(eap_tree
, tvb
, pinfo
, offset
, size
);
2455 break; /* EAP_TYPE_AKA */
2457 /*********************************************************************
2459 **********************************************************************/
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
);
2469 /*********************************************************************
2471 **********************************************************************/
2473 dissect_eap_pax(eap_tree
, tvb
, pinfo
, offset
, size
);
2474 break; /* EAP_TYPE_PAX */
2476 /*********************************************************************
2478 **********************************************************************/
2480 dissect_eap_psk(eap_tree
, tvb
, pinfo
, offset
, size
);
2481 break; /* EAP_TYPE_PSK */
2483 /*********************************************************************
2485 **********************************************************************/
2487 dissect_eap_sake(eap_tree
, tvb
, pinfo
, offset
, size
);
2488 break; /* EAP_TYPE_SAKE */
2490 /*********************************************************************
2492 **********************************************************************/
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
;
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
);
2516 /* Length field, 4 bytes, OPTIONAL. */
2518 proto_tree_add_item(eap_tree
, hf_eap_ikev2_len
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
2524 tvbuff_t
* next_tvb
= NULL
;
2527 tvb_len
= tvb_captured_length_remaining(tvb
, offset
);
2528 if (size
< tvb_len
) {
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?
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
);
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
);
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 **********************************************************************/
2562 proto_tree_add_item(eap_tree
, hf_eap_data
, tvb
, offset
, size
, ENC_NA
);
2564 /*********************************************************************
2565 **********************************************************************/
2566 } /* switch (eap_type) */
2570 } /* switch (eap_code) */
2572 return tvb_captured_length(tvb
);
2576 proto_register_eap(void)
2578 static hf_register_info hf
[] = {
2581 FT_UINT8
, BASE_DEC
, VALS(eap_code_vals
), 0x0,
2584 { &hf_eap_identifier
, {
2586 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2590 "Length", "eap.len",
2591 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2596 FT_UINT8
, BASE_DEC
|BASE_EXT_STRING
, &eap_type_vals_ext
, 0x0,
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,
2604 { &hf_eap_identity
, {
2605 "Identity", "eap.identity",
2606 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2609 { &hf_eap_identity_prefix
, {
2610 "Identity Prefix", "eap.identity.prefix",
2611 FT_CHAR
, BASE_HEX
, NULL
, 0x0,
2614 { &hf_eap_identity_type
, {
2615 "Identity Type", "eap.identity.type",
2616 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2619 { &hf_eap_identity_full
, {
2620 "Identity (Full)", "eap.identity.full",
2621 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2624 { &hf_eap_identity_certificate_sn
, {
2625 "Certificate Serial Number", "eap.identity.cert_sn",
2626 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
2646 { &hf_eap_identity_actual_len
, {
2647 "Identity Actual Length", "eap.identity.actual_len",
2648 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2651 { &hf_eap_notification
, {
2652 "Notification", "eap.notification",
2653 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2656 { &hf_eap_md5_value_size
, {
2657 "EAP-MD5 Value-Size", "eap.md5.value_size",
2658 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2661 { &hf_eap_md5_value
, {
2662 "EAP-MD5 Value", "eap.md5.value",
2663 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2666 { &hf_eap_md5_extra_data
, {
2667 "EAP-MD5 Extra Data", "eap.md5.extra_data",
2668 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2671 { &hf_eap_tls_flags
, {
2672 "EAP-TLS Flags", "eap.tls.flags",
2673 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2676 { &hf_eap_tls_flag_l
, {
2677 "Length Included", "eap.tls.flags.len_included",
2678 FT_BOOLEAN
, 8, NULL
, EAP_TLS_FLAG_L
,
2681 { &hf_eap_tls_flag_m
, {
2682 "More Fragments", "eap.tls.flags.more_fragments",
2683 FT_BOOLEAN
, 8, NULL
, EAP_TLS_FLAG_M
,
2686 { &hf_eap_tls_flag_s
, {
2687 "Start", "eap.tls.flags.start",
2688 FT_BOOLEAN
, 8, NULL
, EAP_TLS_FLAG_S
,
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
,
2696 { &hf_eap_tls_flags_version
, {
2697 "Version", "eap.tls.flags.version",
2698 FT_UINT8
, BASE_DEC
, NULL
, EAP_TLS_FLAGS_VERSION
,
2701 { &hf_eap_tls_len
, {
2702 "EAP-TLS Length", "eap.tls.len",
2703 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2706 { &hf_eap_tls_outer_tlvs_len
, {
2707 "TEAP Outer TLVs Length", "eap.tls.outer_tlvs_len",
2708 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
2711 { &hf_eap_tls_fragment
, {
2712 "EAP-TLS Fragment", "eap.tls.fragment",
2713 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
2716 { &hf_eap_tls_fragments
, {
2717 "EAP-TLS Fragments", "eap.tls.fragments",
2718 FT_NONE
, BASE_NONE
, NULL
, 0x0,
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,
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,
2766 { &hf_eap_sim_reserved
, {
2767 "EAP-SIM Reserved", "eap.sim.reserved",
2768 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2771 { &hf_eap_sim_subtype_attribute
, {
2772 "EAP-SIM Attribute", "eap.sim.subtype.attribute",
2773 FT_NONE
, BASE_NONE
, NULL
, 0x0,
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,
2781 { &hf_eap_sim_subtype_length
, {
2782 "EAP-SIM Length", "eap.sim.subtype.len",
2783 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
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,
2796 { &hf_eap_sim_subtype_value
, {
2797 "EAP-SIM Value", "eap.sim.subtype.value",
2798 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2801 { &hf_eap_aka_subtype
, {
2802 "EAP-AKA Subtype", "eap.aka.subtype",
2803 FT_UINT8
, BASE_DEC
, VALS(eap_aka_subtype_vals
), 0x0,
2806 { &hf_eap_aka_reserved
, {
2807 "EAP-AKA Reserved", "eap.aka.reserved",
2808 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
2811 { &hf_eap_aka_subtype_attribute
, {
2812 "EAP-AKA Attribute", "eap.aka.subtype.attribute",
2813 FT_NONE
, BASE_NONE
, NULL
, 0x0,
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,
2821 { &hf_eap_aka_subtype_length
, {
2822 "EAP-AKA Length", "eap.aka.subtype.len",
2823 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
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,
2836 { &hf_eap_aka_rand
, {
2837 "EAP-AKA RAND", "eap.aka.rand",
2838 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2841 { &hf_eap_aka_autn
, {
2842 "EAP-AKA AUTN", "eap.aka.autn",
2843 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
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,
2851 { &hf_eap_aka_res
, {
2852 "EAP-AKA RES", "eap.aka.res",
2853 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2856 { &hf_eap_aka_auts
, {
2857 "EAP-AKA AUTS", "eap.aka.auts",
2858 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2861 { &hf_eap_aka_subtype_value
, {
2862 "EAP-AKA Value", "eap.aka.subtype.value",
2863 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2866 { &hf_eap_leap_version
, {
2867 "EAP-LEAP Version", "eap.leap.version",
2868 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2871 { &hf_eap_leap_reserved
, {
2872 "EAP-LEAP Reserved", "eap.leap.reserved",
2873 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2876 { &hf_eap_leap_count
, {
2877 "EAP-LEAP Count", "eap.leap.count",
2878 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
2881 { &hf_eap_leap_peer_challenge
, {
2882 "EAP-LEAP Peer-Challenge", "eap.leap.peer_challenge",
2883 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2886 { &hf_eap_leap_peer_response
, {
2887 "EAP-LEAP Peer-Response", "eap.leap.peer_response",
2888 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2891 { &hf_eap_leap_ap_challenge
, {
2892 "EAP-LEAP AP-Challenge", "eap.leap.ap_challenge",
2893 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2896 { &hf_eap_leap_ap_response
, {
2897 "EAP-LEAP AP-Response", "eap.leap.ap_response",
2898 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2901 { &hf_eap_leap_data
, {
2902 "EAP-LEAP Data", "eap.leap.data",
2903 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2906 { &hf_eap_leap_name
, {
2907 "EAP-LEAP Name", "eap.leap.name",
2908 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
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,
2981 { &hf_eap_pax_opcode
, {
2982 "EAP-PAX OP-Code", "eap.pax.opcode",
2983 FT_UINT8
, BASE_HEX
, VALS(eap_pax_opcode_vals
), 0x0,
2986 { &hf_eap_pax_flags
, {
2987 "EAP-PAX Flags", "eap.pax.flags",
2988 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
2991 { &hf_eap_pax_flags_mf
, {
2992 "more fragments", "eap.pax.flags.mf",
2993 FT_BOOLEAN
, 8, NULL
, EAP_PAX_FLAG_MF
,
2996 { &hf_eap_pax_flags_ce
, {
2997 "certificate enabled", "eap.pax.flags.ce",
2998 FT_BOOLEAN
, 8, NULL
, EAP_PAX_FLAG_CE
,
3001 { &hf_eap_pax_flags_ai
, {
3002 "ADE Included", "eap.pax.flags.ai",
3003 FT_BOOLEAN
, 8, NULL
, EAP_PAX_FLAG_AI
,
3006 { &hf_eap_pax_flags_reserved
, {
3007 "reserved", "eap.pax.flags.reserved",
3008 FT_BOOLEAN
, 8, NULL
, EAP_PAX_FLAG_RESERVED
,
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,
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,
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,
3026 { &hf_eap_pax_a_len
, {
3027 "EAP-PAX A len", "eap.pax.a.len",
3028 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3032 "EAP-PAX A", "eap.pax.a",
3033 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3036 { &hf_eap_pax_b_len
, {
3037 "EAP-PAX B len", "eap.pax.b.len",
3038 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3042 "EAP-PAX B", "eap.pax.b",
3043 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3046 { &hf_eap_pax_cid_len
, {
3047 "EAP-PAX CID len", "eap.pax.cid.len",
3048 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3051 { &hf_eap_pax_cid
, {
3052 "EAP-PAX CID", "eap.pax.cid",
3053 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
3061 { &hf_eap_pax_mac_ck
, {
3062 "EAP-PAX MAC_CK", "eap.pax.mac_ck",
3063 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3066 { &hf_eap_pax_ade_len
, {
3067 "EAP-PAX ADE len", "eap.pax.ade.len",
3068 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3071 { &hf_eap_pax_ade
, {
3072 "EAP-PAX ADE", "eap.pax.ade",
3073 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3076 { &hf_eap_pax_mac_icv
, {
3077 "EAP-PAX ICV", "eap.pax.icv",
3078 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3081 { &hf_eap_psk_flags
, {
3082 "EAP-PSK Flags", "eap.psk.flags",
3083 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
3086 { &hf_eap_psk_flags_t
, {
3087 "T", "eap.psk.flags.t",
3088 FT_UINT8
, BASE_HEX
, NULL
, EAP_PSK_FLAGS_T_MASK
,
3091 { &hf_eap_psk_flags_reserved
, {
3092 "Reserved", "eap.psk.flags.reserved",
3093 FT_UINT8
, BASE_HEX
, NULL
, 0x3F,
3096 { &hf_eap_psk_rand_p
, {
3097 "EAP-PSK RAND_P", "eap.psk.rand_p",
3098 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3101 { &hf_eap_psk_rand_s
, {
3102 "EAP-PSK RAND_S", "eap.psk.rand_s",
3103 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3106 { &hf_eap_psk_mac_p
, {
3107 "EAP-PSK MAC_P", "eap.psk.mac_p",
3108 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3111 { &hf_eap_psk_mac_s
, {
3112 "EAP-PSK MAC_S", "eap.psk.mac_s",
3113 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3116 { &hf_eap_psk_id_p
, {
3117 "EAP-PSK ID_P", "eap.psk.id_p",
3118 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3121 { &hf_eap_psk_id_s
, {
3122 "EAP-PSK ID_S", "eap.psk.id_s",
3123 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3126 { &hf_eap_psk_pchannel
, {
3127 "EAP-PSK Protected Channel (encrypted)", "eap.psk.pchannel",
3128 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3131 { &hf_eap_sake_version
, {
3132 "EAP-SAKE Version", "eap.sake.version",
3133 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
3136 { &hf_eap_sake_session_id
, {
3137 "EAP-SAKE Session ID", "eap.sake.session_id",
3138 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
3141 { &hf_eap_sake_subtype
, {
3142 "EAP-SAKE Subtype", "eap.sake.subtype",
3143 FT_UINT8
, BASE_HEX
, VALS(eap_sake_subtype_vals
), 0x0,
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,
3151 { &hf_eap_sake_attr_len
, {
3152 "Attribute Length", "eap.sake.attr.len",
3153 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3156 { &hf_eap_sake_attr_value
, {
3157 "Attribute Value", "eap.sake.attr.val",
3158 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3161 { &hf_eap_sake_attr_value_str
, {
3162 "Attribute Value", "eap.sake.attr.val_str",
3163 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3166 { &hf_eap_sake_attr_value_uint48
, {
3167 "Attribute Value", "eap.sake.attr.val_uint48",
3168 FT_UINT48
, BASE_DEC
, NULL
, 0x0,
3171 { &hf_eap_gpsk_opcode
, {
3172 "EAP-GPSK OP-Code", "eap.gpsk.opcode",
3173 FT_UINT8
, BASE_HEX
, VALS(eap_gpsk_opcode_vals
), 0x0,
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,
3181 { &hf_eap_gpsk_id_server
, {
3182 "EAP-GPSK ID_Server", "eap.gpsk.id_server",
3183 FT_STRING
, BASE_NONE
, NULL
, 0x0,
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,
3191 { &hf_eap_gpsk_id_peer
, {
3192 "EAP-GPSK ID_Peer", "eap.gpsk.id_peer",
3193 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3196 { &hf_eap_gpsk_rand_server
, {
3197 "EAP-GPSK Rand_Server", "eap.gpsk.rand_server",
3198 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3201 { &hf_eap_gpsk_rand_peer
, {
3202 "EAP-GPSK Rand_Peer", "eap.gpsk.rand_peer",
3203 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3206 { &hf_eap_gpsk_csuite_list_len
, {
3207 "Len", "eap.gpsk.csuite_list_len",
3208 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3211 { &hf_eap_gpsk_csuite_vendor
, {
3212 "Vendor", "eap.gpsk.csuite.vendor",
3213 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3216 { &hf_eap_gpsk_csuite_specifier
, {
3217 "Specifier", "eap.gpsk.csuite.specifier",
3218 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
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,
3226 { &hf_eap_gpsk_pd_payload
, {
3227 "EAP-GPSK PD_Payload", "eap.gpsk.pd_payload",
3228 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3231 { &hf_eap_gpsk_payload_mac
, {
3232 "EAP-GPSK Payload MAC", "eap.gpsk.payload_mac",
3233 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
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,
3242 "EAP Data", "eap.data",
3243 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3246 { &hf_eap_fast_type
, {
3247 "EAP-FAST Type", "eap.fast.type",
3248 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3251 { &hf_eap_fast_length
, {
3252 "EAP-FAST Length", "eap.fast.length",
3253 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3256 { &hf_eap_fast_aidd
, {
3257 "Authority ID Data", "eap.fast.authority_id_data",
3258 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3261 { &hf_eap_msauth_tlv_mandatory
, {
3262 "Mandatory", "eap.msauth-tlv.mandatory",
3263 FT_BOOLEAN
, 16, NULL
, MSAUTH_TLV_MANDATORY
,
3266 { &hf_eap_msauth_tlv_reserved
, {
3267 "Reserved", "eap.msauth-tlv.reserved",
3268 FT_BOOLEAN
, 16, NULL
, MSAUTH_TLV_RESERVED
,
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
,
3276 { &hf_eap_msauth_tlv_len
, {
3277 "Length", "eap.msauth-tlv.len",
3278 FT_UINT16
, BASE_DEC
, NULL
, 0x00,
3281 { &hf_eap_msauth_tlv_val
, {
3282 "Value", "eap.msauth-tlv.val",
3283 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3286 { &hf_eap_msauth_tlv_status
, {
3287 "Status", "eap.msauth-tlv.status",
3288 FT_UINT16
, BASE_DEC
, VALS(eap_msauth_tlv_status_vals
), 0x0,
3291 { &hf_eap_msauth_tlv_crypto_reserved
, {
3292 "Reserved", "eap.msauth-tlv.crypto.reserved",
3293 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3296 { &hf_eap_msauth_tlv_crypto_version
, {
3297 "Version", "eap.msauth-tlv.crypto.version",
3298 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3301 { &hf_eap_msauth_tlv_crypto_rcv_version
, {
3302 "Received Version", "eap.msauth-tlv.crypto.received-version",
3303 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
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,
3311 { &hf_eap_msauth_tlv_crypto_nonce
, {
3312 "Nonce", "eap.msauth-tlv.crypto.nonce",
3313 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3316 { &hf_eap_msauth_tlv_crypto_cmac
, {
3317 "Compound MAC", "eap.msauth-tlv.crypto.cmac",
3318 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
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,
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,
3332 { &hf_eap_ikev2_flags
, {
3333 "EAP-IKEv2 Flags", "eap.ikev2.flags",
3334 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
3337 { &hf_eap_ikev2_flag_l
, {
3338 "Length Included", "eap.ikve2.flags.len_included",
3339 FT_BOOLEAN
, 8, NULL
, EAP_IKEV2_FLAG_L
,
3342 { &hf_eap_ikev2_flag_m
, {
3343 "More Fragments", "eap.ikev2.flags.more_fragments",
3344 FT_BOOLEAN
, 8, NULL
, EAP_IKEV2_FLAG_M
,
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
,
3352 { &hf_eap_ikev2_len
, {
3353 "EAP-IKEv2 Length", "eap.ikev2.len",
3354 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
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,
3362 static int *ett
[] = {
3366 &ett_eap_gpsk_csuite_list
,
3367 &ett_eap_gpsk_csuite
,
3368 &ett_eap_gpsk_csuite_sel
,
3370 &ett_eap_msauth_tlv
,
3371 &ett_eap_msauth_tlv_tree
,
3372 &ett_eap_tls_fragment
,
3373 &ett_eap_tls_fragments
,
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",
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
,
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
);
3437 * indent-tabs-mode: nil
3440 * ex: set shiftwidth=2 tabstop=8 expandtab:
3441 * :indentSize=2:tabSize=8:noTabs=true: