1 /* packet-eap.c
2  * Routines for EAP Extensible Authentication Protocol dissection
3  * RFC 2284, RFC 3748
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 #include "config.h"
13 
14 #include <stdio.h>
15 
16 #include <epan/packet.h>
17 #include <epan/conversation.h>
18 #include <epan/ppptypes.h>
19 #include <epan/reassemble.h>
20 #include <epan/eap.h>
21 #include <epan/expert.h>
22 #include <epan/proto_data.h>
23 
24 #include "packet-eapol.h"
25 #include "packet-wps.h"
26 #include "packet-e212.h"
27 #include "packet-tls-utils.h"
28 
29 void proto_register_eap(void);
30 void proto_reg_handoff_eap(void);
31 
32 static int proto_eap = -1;
33 static int hf_eap_code = -1;
34 static int hf_eap_identifier = -1;
35 static int hf_eap_len = -1;
36 static int hf_eap_type = -1;
37 static int hf_eap_type_nak = -1;
38 
39 static int hf_eap_identity = -1;
40 static int hf_eap_identity_full = -1;
41 static int hf_eap_identity_actual_len = -1;
42 static int hf_eap_identity_prefix = -1;
43 static int hf_eap_identity_type = -1;
44 static int hf_eap_identity_mcc = -1;
45 static int hf_eap_identity_mcc_mnc_2digits = -1;
46 static int hf_eap_identity_mcc_mnc_3digits = -1;
47 static int hf_eap_identity_padding = -1;
48 
49 static int hf_eap_notification = -1;
50 
51 static int hf_eap_md5_value_size = -1;
52 static int hf_eap_md5_value = -1;
53 static int hf_eap_md5_extra_data = -1;
54 
55 static int hf_eap_sim_subtype = -1;
56 static int hf_eap_sim_reserved = -1;
57 static int hf_eap_sim_subtype_attribute = -1;
58 static int hf_eap_sim_subtype_type = -1;
59 static int hf_eap_sim_subtype_length = -1;
60 static int hf_eap_sim_notification_type = -1;
61 static int hf_eap_sim_error_code_type = -1;
62 static int hf_eap_sim_subtype_value = -1;
63 
64 static int hf_eap_aka_subtype = -1;
65 static int hf_eap_aka_reserved = -1;
66 static int hf_eap_aka_subtype_attribute = -1;
67 static int hf_eap_aka_subtype_type = -1;
68 static int hf_eap_aka_subtype_length = -1;
69 static int hf_eap_aka_notification_type = -1;
70 static int hf_eap_aka_error_code_type = -1;
71 static int hf_eap_aka_subtype_value = -1;
72 
73 static int hf_eap_leap_version = -1;
74 static int hf_eap_leap_reserved = -1;
75 static int hf_eap_leap_count = -1;
76 static int hf_eap_leap_peer_challenge = -1;
77 static int hf_eap_leap_peer_response = -1;
78 static int hf_eap_leap_ap_challenge = -1;
79 static int hf_eap_leap_ap_response = -1;
80 static int hf_eap_leap_data = -1;
81 static int hf_eap_leap_name = -1;
82 
83 static int hf_eap_ms_chap_v2_opcode = -1;
84 static int hf_eap_ms_chap_v2_id = -1;
85 static int hf_eap_ms_chap_v2_length = -1;
86 static int hf_eap_ms_chap_v2_value_size = -1;
87 static int hf_eap_ms_chap_v2_challenge = -1;
88 static int hf_eap_ms_chap_v2_name = -1;
89 static int hf_eap_ms_chap_v2_peer_challenge = -1;
90 static int hf_eap_ms_chap_v2_reserved = -1;
91 static int hf_eap_ms_chap_v2_nt_response = -1;
92 static int hf_eap_ms_chap_v2_flags = -1;
93 static int hf_eap_ms_chap_v2_response = -1;
94 static int hf_eap_ms_chap_v2_message = -1;
95 static int hf_eap_ms_chap_v2_failure_request = -1;
96 static int hf_eap_ms_chap_v2_data = -1;
97 
98 static int hf_eap_pax_opcode = -1;
99 static int hf_eap_pax_flags = -1;
100 static int hf_eap_pax_flags_mf = -1;
101 static int hf_eap_pax_flags_ce = -1;
102 static int hf_eap_pax_flags_ai = -1;
103 static int hf_eap_pax_flags_reserved = -1;
104 static int hf_eap_pax_mac_id = -1;
105 static int hf_eap_pax_dh_group_id = -1;
106 static int hf_eap_pax_public_key_id = -1;
107 static int hf_eap_pax_a_len = -1;
108 static int hf_eap_pax_a = -1;
109 static int hf_eap_pax_b_len = -1;
110 static int hf_eap_pax_b = -1;
111 static int hf_eap_pax_cid_len = -1;
112 static int hf_eap_pax_cid = -1;
113 static int hf_eap_pax_mac_ck_len = -1;
114 static int hf_eap_pax_mac_ck = -1;
115 static int hf_eap_pax_ade_len = -1;
116 static int hf_eap_pax_ade = -1;
117 static int hf_eap_pax_mac_icv = -1;
118 
119 static int hf_eap_psk_flags = -1;
120 static int hf_eap_psk_flags_t = -1;
121 static int hf_eap_psk_flags_reserved = -1;
122 static int hf_eap_psk_rand_p = -1;
123 static int hf_eap_psk_rand_s = -1;
124 static int hf_eap_psk_mac_p = -1;
125 static int hf_eap_psk_mac_s = -1;
126 static int hf_eap_psk_id_p = -1;
127 static int hf_eap_psk_id_s = -1;
128 static int hf_eap_psk_pchannel = -1;
129 
130 static int hf_eap_sake_version = -1;
131 static int hf_eap_sake_session_id = -1;
132 static int hf_eap_sake_subtype = -1;
133 static int hf_eap_sake_attr_type = -1;
134 static int hf_eap_sake_attr_len = -1;
135 static int hf_eap_sake_attr_value = -1;
136 static int hf_eap_sake_attr_value_str = -1;
137 static int hf_eap_sake_attr_value_uint48 = -1;
138 
139 static int hf_eap_gpsk_opcode = -1;
140 static int hf_eap_gpsk_id_server_len = -1;
141 static int hf_eap_gpsk_id_server = -1;
142 static int hf_eap_gpsk_id_peer_len = -1;
143 static int hf_eap_gpsk_id_peer = -1;
144 static int hf_eap_gpsk_rand_server = -1;
145 static int hf_eap_gpsk_rand_peer = -1;
146 static int hf_eap_gpsk_csuite_list_len = -1;
147 static int hf_eap_gpsk_csuite_vendor = -1;
148 static int hf_eap_gpsk_csuite_specifier = -1;
149 static int hf_eap_gpsk_pd_payload_len = -1;
150 static int hf_eap_gpsk_pd_payload = -1;
151 static int hf_eap_gpsk_payload_mac = -1;
152 static int hf_eap_gpsk_failure_code = -1;
153 
154 static int hf_eap_data = -1;
155 
156 static gint ett_eap = -1;
157 static gint ett_eap_pax_flags = -1;
158 static gint ett_eap_psk_flags = -1;
159 static gint ett_eap_sake_attr = -1;
160 static gint ett_eap_gpsk_csuite_list = -1;
161 static gint ett_eap_gpsk_csuite = -1;
162 static gint ett_eap_gpsk_csuite_sel = -1;
163 
164 static expert_field ei_eap_ms_chap_v2_length = EI_INIT;
165 static expert_field ei_eap_mitm_attacks = EI_INIT;
166 static expert_field ei_eap_md5_value_size_overflow = EI_INIT;
167 static expert_field ei_eap_dictionary_attacks = EI_INIT;
168 static expert_field ei_eap_identity_invalid = EI_INIT;
169 static expert_field ei_eap_retransmission = EI_INIT;
170 static expert_field ei_eap_bad_length = EI_INIT;
171 
172 static dissector_table_t eap_expanded_type_dissector_table;
173 
174 static dissector_handle_t eap_handle;
175 
176 static dissector_handle_t tls_handle;
177 static dissector_handle_t diameter_avps_handle;
178 static dissector_handle_t teap_handle;
179 
180 const value_string eap_code_vals[] = {
181   { EAP_REQUEST,  "Request" },
182   { EAP_RESPONSE, "Response" },
183   { EAP_SUCCESS,  "Success" },
184   { EAP_FAILURE,  "Failure" },
185   { EAP_INITIATE, "Initiate" }, /* [RFC5296] */
186   { EAP_FINISH,   "Finish" },   /* [RFC5296] */
187   { 0,            NULL }
188 };
189 
190 /*
191 References:
192   1) https://www.iana.org/assignments/ppp-numbers PPP EAP REQUEST/RESPONSE TYPES
193   2) https://tools.ietf.org/html/draft-ietf-pppext-rfc2284bis-02
194   3) RFC2284
195   4) RFC3748
196   5) https://www.iana.org/assignments/eap-numbers EAP registry (updated 2011-02-22)
197   6) https://tools.ietf.org/html/draft-bersani-eap-synthesis-sharedkeymethods-00
198 */
199 
200 static const value_string eap_type_vals[] = {
201     {   1,         "Identity" },
202     {   2,         "Notification" },
203     {   3,         "Legacy Nak (Response Only)" },
204     {   4,         "MD5-Challenge EAP (EAP-MD5-CHALLENGE)" },
205     {   5,         "One-Time Password EAP (EAP-OTP)" },
206     {   6,         "Generic Token Card EAP (EAP-GTC)" },
207     {   7,         "Allocated" },
208     {   8,         "Allocated" },
209     {   9,         "RSA Public Key Authentication EAP (EAP-RSA-PKA)" },
210     {  10,         "DSS Unilateral EAP (EAP-DSS)" },
211     {  11,         "KEA EAP (EAP-KEA)" },
212     {  12,         "KEA Validate EAP (EAP-KEA-VALIDATE)" },
213     {  13,         "TLS EAP (EAP-TLS)" },
214     {  14,         "Defender Token EAP (EAP-AXENT)" },
215     {  15,         "RSA Security SecurID EAP (EAP-RSA-SECURID)" },
216     {  16,         "Arcot Systems EAP (EAP-ARCOT-SYSTEMS)" },
217     {  17,         "Cisco Wireless EAP / Lightweight EAP (EAP-LEAP)" },
218     {  18,         "GSM Subscriber Identity Modules EAP (EAP-SIM)" },
219     {  19,         "Secure Remote Password SHA1 Part 1 EAP (EAP-SRP-SHA1-PART1)" },
220     {  20,         "Secure Remote Password SHA1 Part 2 EAP (EAP-SRP-SHA1-PART2)" },
221     {  21,         "Tunneled TLS EAP (EAP-TTLS)" },
222     {  22,         "Remote Access Service EAP (EAP-RAS)" },
223     {  23,         "UMTS Authentication and Key Agreement EAP (EAP-AKA)" },
224     {  24,         "3Com Wireless EAP (EAP-3COM-WIRELESS)" },
225     {  25,         "Protected EAP (EAP-PEAP)" },
226     {  26,         "MS-Authentication EAP (EAP-MS-AUTH)" },
227     {  27,         "Mutual Authentication w/Key Exchange EAP (EAP-MAKE)" },
228     {  28,         "CRYPTOCard EAP (EAP-CRYPTOCARD)" },
229     {  29,         "MS-CHAP-v2 EAP (EAP-MS-CHAP-V2)" },
230     {  30,         "DynamID EAP (EAP-DYNAMID)" },
231     {  31,         "Rob EAP (EAP-ROB)" },
232     {  32,         "Protected One-Time Password EAP (EAP-POTP)" },
233     {  33,         "MS-Authentication TLV EAP (EAP-MS-AUTH-TLV)" },
234     {  34,         "SentriNET (EAP-SENTRINET)" },
235     {  35,         "Actiontec Wireless EAP (EAP-ACTIONTEC-WIRELESS)" },
236     {  36,         "Cogent Systems Biometrics Authentication EAP (EAP-COGENT-BIOMETRIC)" },
237     {  37,         "AirFortress EAP (EAP-AIRFORTRESS)" },
238     {  38,         "HTTP Digest EAP (EAP-HTTP-DIGEST)" },
239     {  39,         "SecureSuite EAP (EAP-SECURESUITE)" },
240     {  40,         "DeviceConnect EAP (EAP-DEVICECONNECT)" },
241     {  41,         "Simple Password Exponential Key Exchange EAP (EAP-SPEKE)" },
242     {  42,         "MOBAC EAP (EAP-MOBAC)" },
243     {  43,         "Flexible Authentication via Secure Tunneling EAP (EAP-FAST)" },
244     {  44,         "ZoneLabs EAP (EAP-ZLXEAP)" },
245     {  45,         "Link EAP (EAP-LINK)" },
246     {  46,         "Password Authenticated eXchange EAP (EAP-PAX)" },
247     {  47,         "Pre-Shared Key EAP (EAP-PSK)" },
248     {  48,         "Shared-secret Authentication and Key Establishment EAP (EAP-SAKE)" },
249     {  49,         "Internet Key Exchange v2 EAP (EAP-IKEv2)" },
250     {  50,         "UMTS Authentication and Key Agreement' EAP (EAP-AKA')" },
251     {  51,         "Generalized Pre-Shared Key EAP (EAP-GPSK)" },
252     {  52,         "Password EAP (EAP-pwd)" },
253     {  53,         "Encrypted Key Exchange v1 EAP (EAP-EKEv1)" },
254     {  55,         "Tunneled EAP protocol" },
255     { 254,         "Expanded Type" },
256     { 255,         "Experimental" },
257     { 0,           NULL }
258 };
259 value_string_ext eap_type_vals_ext = VALUE_STRING_EXT_INIT(eap_type_vals);
260 
261 static const value_string eap_identity_prefix_vals[] = {
262   { 0x00, "Encrypted IMSI" },
263   {  '0', "EAP-AKA Permanent" },
264   {  '1', "EAP-SIM Permanent" },
265   {  '2', "EAP-AKA Pseudonym" },
266   {  '3', "EAP-SIM Pseudonym" },
267   {  '4', "EAP-AKA Reauth ID" },
268   {  '5', "EAP-SIM Reauth ID" },
269   {  '6', "EAP-AKA Prime Permanent" },
270   {  '7', "EAP-AKA Prime Pseudonym" },
271   {  '8', "EAP-AKA Prime Reauth ID" },
272   {  'C', "Conservative Peer" },
273   {  'a', "Anonymous Identity" },
274   { 0, NULL }
275 };
276 
277 const value_string eap_sim_subtype_vals[] = {
278   { SIM_START,             "Start" },
279   { SIM_CHALLENGE,         "Challenge" },
280   { SIM_NOTIFICATION,      "Notification" },
281   { SIM_RE_AUTHENTICATION, "Re-authentication" },
282   { SIM_CLIENT_ERROR,      "Client-Error" },
283   { 0, NULL }
284 };
285 
286 const value_string eap_aka_subtype_vals[] = {
287   { AKA_CHALLENGE,               "AKA-Challenge" },
288   { AKA_AUTHENTICATION_REJECT,   "AKA-Authentication-Reject" },
289   { AKA_SYNCHRONIZATION_FAILURE, "AKA-Synchronization-Failure" },
290   { AKA_IDENTITY,                "AKA-Identity" },
291   { AKA_NOTIFICATION,            "Notification" },
292   { AKA_REAUTHENTICATION,        "Re-authentication" },
293   { AKA_CLIENT_ERROR,            "Client-Error" },
294   { 0, NULL }
295 };
296 
297 /*
298 References:
299   1) http://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xml
300   3) RFC4186
301   3) RFC4187
302   4) RFC5448
303   5) 3GPP TS 24.302
304 */
305 
306 #define AT_NOTIFICATION 12
307 #define AT_IDENTITY 14
308 #define AT_CLIENT_ERROR_CODE 22
309 
310 static const value_string eap_sim_aka_attribute_vals[] = {
311   {   1, "AT_RAND" },
312   {   2, "AT_AUTN" },
313   {   3, "AT_RES" },
314   {   4, "AT_AUTS" },
315   {   6, "AT_PADDING" },
316   {   7, "AT_NONCE_MT" },
317   {  10, "AT_PERMANENT_ID_REQ" },
318   {  11, "AT_MAC" },
319   {  12, "AT_NOTIFICATION" },
320   {  13, "AT_ANY_ID_REQ" },
321   {  14, "AT_IDENTITY" },
322   {  15, "AT_VERSION_LIST" },
323   {  16, "AT_SELECTED_VERSION" },
324   {  17, "AT_FULLAUTH_ID_REQ" },
325   {  19, "AT_COUNTER" },
326   {  20, "AT_COUNTER_TOO_SMALL" },
327   {  21, "AT_NONCE_S" },
328   {  22, "AT_CLIENT_ERROR_CODE" },
329   {  23, "AT_KDF_INPUT"},
330   {  24, "AT_KDF"},
331   { 128, "Unassigned" },
332   { 129, "AT_IV" },
333   { 130, "AT_ENCR_DATA" },
334   { 131, "Unassigned" },
335   { 132, "AT_NEXT_PSEUDONYM" },
336   { 133, "AT_NEXT_REAUTH_ID" },
337   { 134, "AT_CHECKCODE" },
338   { 135, "AT_RESULT_IND" },
339   { 136, "AT_BIDDING" },
340   { 137, "AT_IPMS_IND" },
341   { 138, "AT_IPMS_RES" },
342   { 139, "AT_TRUST_IND" },
343   { 140, "AT_SHORT_NAME_FOR_NETWORK" },
344   { 141, "AT_FULL_NAME_FOR_NETWORK" },
345   { 142, "AT_RQSI_IND" },
346   { 143, "AT_RQSI_RES" },
347   { 144, "AT_TWAN_CONN_MODE" },
348   { 145, "AT_VIRTUAL_NETWORK_ID" },
349   { 146, "AT_VIRTUAL_NETWORK_REQ" },
350   { 147, "AT_CONNECTIVITY_TYPE" },
351   { 148, "AT_HANDOVER_INDICATION" },
352   { 149, "AT_HANDOVER_SESSION_ID" },
353   { 150, "AT_MN_SERIAL_ID" },
354   { 151, "AT_DEVICE_IDENTITY" },
355   { 0, NULL }
356 };
357 static value_string_ext eap_sim_aka_attribute_vals_ext = VALUE_STRING_EXT_INIT(eap_sim_aka_attribute_vals);
358 
359 static const value_string eap_sim_aka_notification_vals[] = {
360   {    0, "General Failure after Authentication" },
361   { 1026, "User has been temporarily denied access" },
362   { 1031, "User has not subscribed to the requested service" },
363   { 8192, "Failure to Terminate the Authentication Exchange" },
364   {16384, "General Failure" },
365   {32768, "Success" },
366   {0, NULL }
367 };
368 
369 static const value_string eap_sim_aka_client_error_codes[] = {
370   { 0, "Unable to process packet" },
371   { 1, "Unsupported version" },
372   { 2, "Insufficient number of challenges" },
373   { 3, "RANDs are not fresh" },
374   { 0, NULL }
375 };
376 
377 const value_string eap_ms_chap_v2_opcode_vals[] = {
378   { MS_CHAP_V2_CHALLENGE,       "Challenge" },
379   { MS_CHAP_V2_RESPONSE,        "Response" },
380   { MS_CHAP_V2_SUCCESS,         "Success" },
381   { MS_CHAP_V2_FAILURE,         "Failure" },
382   { MS_CHAP_V2_CHANGE_PASSWORD, "Change-Password" },
383   { 0, NULL }
384 };
385 
386 #define PAX_STD_1 0x01
387 #define PAX_STD_2 0x02
388 #define PAX_STD_3 0x03
389 #define PAX_SEC_1 0x11
390 #define PAX_SEC_2 0x12
391 #define PAX_SEC_3 0x13
392 #define PAX_SEC_4 0x14
393 #define PAX_SEC_5 0x15
394 #define PAX_ACK   0x21
395 
396 static const value_string eap_pax_opcode_vals[] = {
397   { PAX_STD_1, "STD-1" },
398   { PAX_STD_2, "STD-2" },
399   { PAX_STD_3, "STD-3" },
400   { PAX_SEC_1, "SEC-1" },
401   { PAX_SEC_2, "SEC-2" },
402   { PAX_SEC_3, "SEC-3" },
403   { PAX_SEC_4, "SEC-4" },
404   { PAX_SEC_5, "SEC-5" },
405   { PAX_ACK,   "ACK" },
406   { 0, NULL }
407 };
408 
409 #define EAP_PAX_FLAG_MF       0x01 /* more fragments */
410 #define EAP_PAX_FLAG_CE       0x02 /* certificate enabled */
411 #define EAP_PAX_FLAG_AI       0x04 /* ADE included */
412 #define EAP_PAX_FLAG_RESERVED 0xF8 /* reserved */
413 
414 #define PAX_MAC_ID_HMAC_SHA1_128   0x01
415 #define PAX_MAC_ID_HMAC_SHA256_128 0x02
416 
417 static const value_string eap_pax_mac_id_vals[] = {
418   { PAX_MAC_ID_HMAC_SHA1_128,   "HMAC_SHA1_128" },
419   { PAX_MAC_ID_HMAC_SHA256_128, "HMAXĆ_SHA256_128" },
420   { 0, NULL }
421 };
422 
423 #define PAX_DH_GROUP_ID_NONE     0x00
424 #define PAX_DH_GROUP_ID_DH_14    0x01
425 #define PAX_DH_GROUP_ID_DH_15    0x02
426 #define PAX_DH_GROUP_ID_ECC_P256 0x03
427 
428 static const value_string eap_pax_dh_group_id_vals[] = {
429   { PAX_DH_GROUP_ID_NONE,     "NONE" },
430   { PAX_DH_GROUP_ID_DH_14,    "2048-bit MODP Group (IANA DH Group 14)" },
431   { PAX_DH_GROUP_ID_DH_15,    "3072-bit MODP Group (IANA DH Group 15)" },
432   { PAX_DH_GROUP_ID_ECC_P256, "NIST ECC Group P-256" },
433   { 0, NULL }
434 };
435 
436 #define PAX_PUBLIC_KEY_ID_NONE              0x00
437 #define PAX_PUBLIC_KEY_ID_RSAES_OAEP        0x01
438 #define PAX_PUBLIC_KEY_ID_RSA_PKCS1_V1_5    0x02
439 #define PAX_PUBLIC_KEY_ID_EL_GAMAL_ECC_P256 0x03
440 
441 static const value_string eap_pax_public_key_id_vals[] = {
442   { PAX_PUBLIC_KEY_ID_NONE,              "NONE" },
443   { PAX_PUBLIC_KEY_ID_RSAES_OAEP,        "RSAES-OAEP" },
444   { PAX_PUBLIC_KEY_ID_RSA_PKCS1_V1_5,    "RSA-PKCS1-V1_5" },
445   { PAX_PUBLIC_KEY_ID_EL_GAMAL_ECC_P256, "El-Gamal Over NIST ECC Group P-256" },
446   { 0, NULL }
447 };
448 
449 #define EAP_PSK_FLAGS_T_MASK 0xC0
450 
451 #define SAKE_CHALLENGE      1
452 #define SAKE_CONFIRM        2
453 #define SAKE_AUTH_REJECT    3
454 #define SAKE_IDENTITY       4
455 
456 static const value_string eap_sake_subtype_vals[] = {
457   { SAKE_CHALLENGE,   "SAKE/Challenge" },
458   { SAKE_CONFIRM,     "SAKE/Confirm" },
459   { SAKE_AUTH_REJECT, "SAKE/Auth-Reject" },
460   { SAKE_IDENTITY,    "SAKE/Identity" },
461   { 0, NULL }
462 };
463 
464 #define SAKE_AT_RAND_S      1
465 #define SAKE_AT_RAND_P      2
466 #define SAKE_AT_MIC_S       3
467 #define SAKE_AT_MIC_P       4
468 #define SAKE_AT_SERVERID    5
469 #define SAKE_AT_PEERID      6
470 #define SAKE_AT_SPI_S       7
471 #define SAKE_AT_SPI_P       8
472 #define SAKE_AT_ANY_ID_REQ  9
473 #define SAKE_AT_PERM_ID_REQ 10
474 #define SAKE_AT_ENCR_DATA   128
475 #define SAKE_AT_IV          129
476 #define SAKE_AT_PADDING     130
477 #define SAKE_AT_NEXT_TMPID  131
478 #define SAKE_AT_MSK_LIFE    132
479 
480 static const value_string eap_sake_attr_type_vals[] = {
481   { SAKE_AT_RAND_S,      "Server Nonce RAND_S" },
482   { SAKE_AT_RAND_P,      "Peer Nonce RAND_P" },
483   { SAKE_AT_MIC_S,       "Server MIC" },
484   { SAKE_AT_MIC_P,       "Peer MIC" },
485   { SAKE_AT_SERVERID,    "Server FQDN" },
486   { SAKE_AT_PEERID,      "Peer NAI (tmp, perm)" },
487   { SAKE_AT_SPI_S,       "Server chosen SPI SPI_S" },
488   { SAKE_AT_SPI_P,       "Peer SPI list SPI_P" },
489   { SAKE_AT_ANY_ID_REQ,  "Requires any Peer Id (tmp, perm)" },
490   { SAKE_AT_PERM_ID_REQ, "Requires Peer's permanent Id/NAI" },
491   { SAKE_AT_ENCR_DATA,   "Contains encrypted attributes" },
492   { SAKE_AT_IV,          "IV for encrypted attributes" },
493   { SAKE_AT_PADDING,     "Padding for encrypted attributes" },
494   { SAKE_AT_NEXT_TMPID,  "TempID for next EAP-SAKE phase" },
495   { SAKE_AT_MSK_LIFE,    "MSK Lifetime" },
496   { 0, NULL }
497 };
498 
499 #define GPSK_RESERVED       0
500 #define GPSK_GPSK_1         1
501 #define GPSK_GPSK_2         2
502 #define GPSK_GPSK_3         3
503 #define GPSK_GPSK_4         4
504 #define GPSK_FAIL           5
505 #define GPSK_PROTECTED_FAIL 6
506 
507 static const value_string eap_gpsk_opcode_vals[] = {
508   { GPSK_RESERVED,       "Reserved" },
509   { GPSK_GPSK_1,         "GPSK-1" },
510   { GPSK_GPSK_2,         "GPSK-2" },
511   { GPSK_GPSK_3,         "GPSK-3" },
512   { GPSK_GPSK_4,         "GPSK-4" },
513   { GPSK_FAIL,           "Fail" },
514   { GPSK_PROTECTED_FAIL, "Protected Fail" },
515   { 0, NULL }
516 };
517 
518 static const value_string eap_gpsk_failure_code_vals[] = {
519   { 0x00000000, "Reserved" },
520   { 0x00000001, "PSK Not Found" },
521   { 0x00000002, "Authentication Failure" },
522   { 0x00000003, "Authorization Failure" },
523   { 0, NULL }
524 };
525 
526 /*
527  * State information for EAP-TLS (RFC2716) and Lightweight EAP:
528  *
529  *  http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
530  *
531  * Attach to all conversations:
532  *
533  *  a sequence number to be handed to "fragment_add_seq()" as
534  *  the fragment sequence number - if it's -1, no reassembly
535  *  is in progress, but if it's not, it's the sequence number
536  *  to use for the current fragment;
537  *
538  *  a value to be handed to "fragment_add_seq()" as the
539  *  reassembly ID - when a reassembly is started, it's set to
540  *  the frame number of the current frame, i.e. the frame
541  *  that starts the reassembly;
542  *
543  *  an indication of the current state of LEAP negotiation,
544  *  with -1 meaning no LEAP negotiation is in progress.
545  *
546  * Attach to frames containing fragments of EAP-TLS messages the
547  * reassembly ID for those fragments, so we can find the reassembled
548  * data after the first pass through the packets.
549  *
550  * Attach to LEAP frames the state of the LEAP negotiation when the
551  * frame was processed, so we can properly dissect
552  * the LEAP message after the first pass through the packets.
553  *
554  * Attach to all conversations both pieces of information, to keep
555  * track of EAP-TLS reassembly and the LEAP state machine.
556  */
557 
558 typedef struct {
559   int     eap_tls_seq;
560   guint32 eap_reass_cookie;
561   int     leap_state;
562   gint16  last_eap_id_req;  /* Last ID of the request from the authenticator. */
563   gint16  last_eap_id_resp; /* Last ID of the response from the peer. */
564 } conv_state_t;
565 
566 typedef struct {
567   int     info;  /* interpretation depends on EAP message type */
568 } frame_state_t;
569 
570 /*********************************************************************
571                            EAP-TLS
572 RFC2716
573 **********************************************************************/
574 
575 /*
576 from RFC2716, pg 17
577 
578    Flags
579 
580       0 1 2 3 4 5 6 7 8
581       +-+-+-+-+-+-+-+-+
582       |L M S R R Vers |
583       +-+-+-+-+-+-+-+-+
584 
585       L = Length included
586       M = More fragments
587       S = EAP-TLS start
588       R = Reserved
589       Vers = PEAP version (Reserved for TLS and TTLS)
590 */
591 
592 #define EAP_TLS_FLAG_L 0x80 /* Length included */
593 #define EAP_TLS_FLAG_M 0x40 /* More fragments  */
594 #define EAP_TLS_FLAG_S 0x20 /* EAP-TLS start   */
595 
596 #define EAP_TLS_FLAGS_VERSION 0x07 /* Version mask for PEAP, TTLS, FAST */
597 
598 /*
599  * reassembly of EAP-TLS
600  */
601 static reassembly_table eap_tls_reassembly_table;
602 
603 static int hf_eap_tls_flags = -1;
604 static int hf_eap_tls_flag_l = -1;
605 static int hf_eap_tls_flag_m = -1;
606 static int hf_eap_tls_flag_s = -1;
607 static int hf_eap_tls_flags_version = -1;
608 static int hf_eap_tls_len = -1;
609 static int hf_eap_tls_fragment  = -1;
610 static int hf_eap_tls_fragments = -1;
611 static int hf_eap_tls_fragment_overlap = -1;
612 static int hf_eap_tls_fragment_overlap_conflict = -1;
613 static int hf_eap_tls_fragment_multiple_tails = -1;
614 static int hf_eap_tls_fragment_too_long_fragment = -1;
615 static int hf_eap_tls_fragment_error = -1;
616 static int hf_eap_tls_fragment_count = -1;
617 static int hf_eap_tls_reassembled_length = -1;
618 static int hf_eap_fast_type = -1;
619 static int hf_eap_fast_length = -1;
620 static int hf_eap_fast_aidd = -1;
621 static gint ett_eap_tls_fragment  = -1;
622 static gint ett_eap_tls_fragments = -1;
623 static gint ett_eap_sim_attr = -1;
624 static gint ett_eap_aka_attr = -1;
625 static gint ett_eap_exp_attr = -1;
626 static gint ett_eap_tls_flags = -1;
627 static gint ett_identity = -1;
628 
629 static const fragment_items eap_tls_frag_items = {
630   &ett_eap_tls_fragment,
631   &ett_eap_tls_fragments,
632   &hf_eap_tls_fragments,
633   &hf_eap_tls_fragment,
634   &hf_eap_tls_fragment_overlap,
635   &hf_eap_tls_fragment_overlap_conflict,
636   &hf_eap_tls_fragment_multiple_tails,
637   &hf_eap_tls_fragment_too_long_fragment,
638   &hf_eap_tls_fragment_error,
639   &hf_eap_tls_fragment_count,
640   NULL,
641   &hf_eap_tls_reassembled_length,
642   /* Reassembled data field */
643   NULL,
644   "fragments"
645 };
646 
647 /**********************************************************************
648  Support for EAP Expanded Type.
649 
650  Currently this is limited to WifiProtectedSetup. Maybe we need
651  a generic method to support EAP extended types ?
652 *********************************************************************/
653 static int   hf_eap_ext_vendor_id   = -1;
654 static int   hf_eap_ext_vendor_type = -1;
655 
656 static const value_string eap_ext_vendor_id_vals[] = {
657   { WFA_VENDOR_ID, "WFA" },
658   { 0, NULL }
659 };
660 
661 static const value_string eap_ext_vendor_type_vals[] = {
662   { WFA_SIMPLECONFIG_TYPE, "SimpleConfig" },
663   { 0, NULL }
664 };
665 
666 static void
667 dissect_exteap(proto_tree *eap_tree, tvbuff_t *tvb, int offset,
668                gint size _U_, packet_info* pinfo, guint8 eap_code, guint8 eap_identifier)
669 {
670   tvbuff_t   *next_tvb;
671   guint32    vendor_id;
672   guint32    vendor_type;
673   eap_vendor_context *vendor_context;
674 
675   vendor_context = wmem_new(pinfo->pool, eap_vendor_context);
676 
677   proto_tree_add_item_ret_uint(eap_tree, hf_eap_ext_vendor_id, tvb, offset, 3, ENC_BIG_ENDIAN, &vendor_id);
678   offset += 3;
679 
680   proto_tree_add_item_ret_uint(eap_tree, hf_eap_ext_vendor_type, tvb, offset, 4, ENC_BIG_ENDIAN, &vendor_type);
681   offset += 4;
682 
683   vendor_context->eap_code = eap_code;
684   vendor_context->eap_identifier = eap_identifier;
685   vendor_context->vendor_id = vendor_id;
686   vendor_context->vendor_type = vendor_type;
687 
688   next_tvb = tvb_new_subset_remaining(tvb, offset);
689   if (!dissector_try_uint_new(eap_expanded_type_dissector_table,
690     vendor_id, next_tvb, pinfo, eap_tree,
691     FALSE, vendor_context)) {
692     call_data_dissector(next_tvb, pinfo, eap_tree);
693   }
694 }
695 /* *********************************************************************
696 ********************************************************************* */
697 
698 static gboolean
699 test_flag(unsigned char flag, unsigned char mask)
700 {
701   return ( ( flag & mask ) != 0 );
702 }
703 
704 static void
705 dissect_eap_mschapv2(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
706                      gint size)
707 {
708   proto_item *item;
709   gint        left = size;
710   gint        ms_len;
711   guint8      value_size;
712   guint8      opcode;
713 
714   /* OpCode (1 byte), MS-CHAPv2-ID (1 byte), MS-Length (2 bytes), Data */
715   opcode = tvb_get_guint8(tvb, offset);
716   proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
717   offset += 1;
718   left   -= 1;
719   if (left <= 0)
720     return;
721 
722   proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_id, tvb, offset, 1, ENC_BIG_ENDIAN);
723   offset += 1;
724   left   -= 1;
725   if (left <= 0)
726     return;
727 
728   item = proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_length, tvb, offset, 2, ENC_BIG_ENDIAN);
729   ms_len = tvb_get_ntohs(tvb, offset);
730   if (ms_len != size)
731     expert_add_info(pinfo, item, &ei_eap_ms_chap_v2_length);
732   offset += 2;
733   left   -= 2;
734 
735   switch (opcode) {
736   case MS_CHAP_V2_CHALLENGE:
737     if (left <= 0)
738       break;
739     value_size = tvb_get_guint8(tvb, offset);
740     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_value_size,
741                         tvb, offset, 1, ENC_BIG_ENDIAN);
742     offset += 1;
743     left   -= 1;
744     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_challenge,
745                         tvb, offset, value_size, ENC_NA);
746     offset += value_size;
747     left   -= value_size;
748     if (left <= 0)
749       break;
750     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_name,
751                         tvb, offset, left, ENC_ASCII|ENC_NA);
752     break;
753   case MS_CHAP_V2_RESPONSE:
754     if (left <= 0)
755       break;
756     value_size = tvb_get_guint8(tvb, offset);
757     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_value_size,
758                         tvb, offset, 1, ENC_BIG_ENDIAN);
759     offset += 1;
760     left   -= 1;
761     if (value_size == 49) {
762       proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_peer_challenge,
763                           tvb, offset, 16, ENC_NA);
764       offset += 16;
765       proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_reserved,
766                           tvb, offset, 8, ENC_NA);
767       offset += 8;
768       proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_nt_response,
769                          tvb, offset, 24, ENC_NA);
770       offset += 24;
771       proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_flags,
772                           tvb, offset, 1, ENC_BIG_ENDIAN);
773       offset += 1;
774       left   -= value_size;
775     } else {
776       proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_response, tvb, offset, value_size, ENC_NA);
777       offset += value_size;
778       left   -= value_size;
779     }
780     if (left <= 0)
781       break;
782     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_name, tvb, offset, left, ENC_ASCII|ENC_NA);
783     break;
784   case MS_CHAP_V2_SUCCESS:
785     if (left <= 0)
786       break;
787     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_message,
788                             tvb, offset, left, ENC_ASCII|ENC_NA);
789     break;
790   case MS_CHAP_V2_FAILURE:
791     if (left <= 0)
792       break;
793     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_failure_request,
794                             tvb, offset, left, ENC_ASCII|ENC_NA);
795     break;
796   default:
797     proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_data, tvb, offset, left, ENC_NA);
798     break;
799   }
800 }
801 
802 /* Dissect the WLAN identity */
803 static gboolean
804 dissect_eap_identity_wlan(tvbuff_t *tvb, packet_info* pinfo, proto_tree* tree, int offset, gint size)
805 {
806   guint       mnc = 0;
807   guint       mcc = 0;
808   guint       mcc_mnc = 0;
809   proto_tree* eap_identity_tree = NULL;
810   guint8      eap_identity_prefix = 0;
811   const gchar* eap_identity_value;
812   guint8*     identity = NULL;
813   gchar**     tokens = NULL;
814   gchar**     realm_tokens = NULL;
815   guint       ntokens = 0;
816   guint       nrealm_tokens = 0;
817   gboolean    ret = TRUE;
818   int         hf_eap_identity_mcc_mnc;
819   proto_item* item;
820 
821   identity = tvb_get_string_enc(pinfo->pool, tvb, offset, size, ENC_ASCII);
822 
823   /* Split the Identity and the NAI Realm first */
824   tokens = g_strsplit_set(identity, "@", -1);
825 
826   while(tokens[ntokens])
827     ntokens++;
828 
829   /* tokens[0] is the identity, tokens[1] is the NAI Realm */
830   if (ntokens != 2) {
831     ret = FALSE;
832     proto_tree_add_item(tree, hf_eap_identity, tvb, offset, size, ENC_ASCII|ENC_NA);
833     goto end;
834   }
835 
836   realm_tokens = g_strsplit_set(tokens[1], ".", -1);
837 
838   while(realm_tokens[nrealm_tokens])
839     nrealm_tokens++;
840 
841   /* The WLAN identity must have the form of
842      <imsi>@wlan.mnc<mnc>.mcc<mcc>.3gppnetwork.org
843      If not, we don't have a wlan identity
844   */
845   if (ntokens != 2 || nrealm_tokens != 5 || g_ascii_strncasecmp(realm_tokens[0], "wlan", 4) ||
846       g_ascii_strncasecmp(realm_tokens[3], "3gppnetwork", 11) ||
847       g_ascii_strncasecmp(realm_tokens[4], "org", 3)) {
848     ret = FALSE;
849     goto end;
850   }
851 
852   /* It is very likely that we have a WLAN identity (EAP-AKA/EAP-SIM) */
853   /* Go on with the dissection */
854   eap_identity_tree = proto_item_add_subtree(tree, ett_identity);
855   proto_tree_add_item(eap_identity_tree, hf_eap_identity_prefix, tvb, offset, 1, ENC_NA);
856   eap_identity_prefix = tvb_get_guint8(tvb, offset);
857   eap_identity_value = try_val_to_str(eap_identity_prefix, eap_identity_prefix_vals);
858   item = proto_tree_add_string(eap_identity_tree, hf_eap_identity_type,
859     tvb, offset, 1, eap_identity_value ? eap_identity_value : "Unknown");
860 
861   switch(eap_identity_prefix) {
862     case 0x00: /* Encrypted IMSI */
863       proto_tree_add_item(eap_identity_tree, hf_eap_identity_full, tvb, offset + 1, size - 1, ENC_ASCII || ENC_NA);
864       proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (guint)strlen(tokens[0]), ENC_ASCII || ENC_NA);
865       break;
866     case '0': /* EAP-AKA Permanent */
867     case '1': /* EAP-SIM Permanent */
868     case '6': /* EAP-AKA' Permanent */
869       proto_tree_add_item(eap_identity_tree, hf_eap_identity_full, tvb, offset + 1, size - 1, ENC_ASCII || ENC_NA);
870       dissect_e212_utf8_imsi(tvb, pinfo, eap_identity_tree, offset + 1, (guint)strlen(tokens[0]) - 1);
871       break;
872     case '2': /* EAP-AKA Pseudonym */
873     case '3': /* EAP-SIM Pseudonym */
874     case '7': /* EAP-AKA' Pseudonym */
875       proto_tree_add_item(eap_identity_tree, hf_eap_identity_full, tvb, offset + 1, size - 1, ENC_ASCII || ENC_NA);
876       proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (guint)strlen(tokens[0]) - 1, ENC_ASCII|ENC_NA);
877       break;
878     case '4': /* EAP-AKA Reauth ID */
879     case '5': /* EAP-SIM Reauth ID */
880     case '8': /* EAP-AKA' Reauth ID */
881       proto_tree_add_item(eap_identity_tree, hf_eap_identity_full, tvb, offset + 1, size - 1, ENC_ASCII || ENC_NA);
882       proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (guint)strlen(tokens[0]) - 1, ENC_ASCII|ENC_NA);
883       break;
884     case 'C': /* Conservative Peer */
885       proto_tree_add_item(eap_identity_tree, hf_eap_identity_full, tvb, offset + 1, size - 1, ENC_ASCII || ENC_NA);
886       proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (guint)strlen(tokens[0]) - 1, ENC_ASCII|ENC_NA);
887       break;
888     case 'a': /* Anonymous User */
889       proto_tree_add_item(eap_identity_tree, hf_eap_identity_full, tvb, offset, size, ENC_ASCII || ENC_NA);
890       proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset, (guint)strlen(tokens[0]), ENC_ASCII|ENC_NA);
891       break;
892     case 'G': /* TODO: 'G' Unknown */
893     case 'I': /* TODO: 'I' Unknown */
894     default:
895       proto_tree_add_item(eap_identity_tree, hf_eap_identity_full, tvb, offset + 1, size - 1, ENC_ASCII || ENC_NA);
896       proto_tree_add_item(eap_identity_tree, hf_eap_identity, tvb, offset + 1, (guint)strlen(tokens[0]) - 1, ENC_ASCII|ENC_NA);
897       expert_add_info(pinfo, item, &ei_eap_identity_invalid);
898   }
899 
900   /* EAP identities do not always equate to IMSIs.  We should
901    * still add the MCC and MNC values for non-permanent EAP
902    * identities. */
903   if (!sscanf(realm_tokens[1] + 3, "%u", &mnc) || !sscanf(realm_tokens[2] + 3, "%u", &mcc)) {
904     ret = FALSE;
905     goto end;
906   }
907 
908   if (!try_val_to_str_ext(mcc * 100 + mnc, &mcc_mnc_2digits_codes_ext)) {
909     /* May have
910      * (1) an invalid 2-digit MNC so it won't resolve,
911      * (2) an invalid 3-digit MNC so it won't resolve, or
912      * (3) a valid 3-digit MNC.
913      * For all cases we treat as 3-digit MNC and continue. */
914     mcc_mnc = 1000 * mcc + mnc;
915     hf_eap_identity_mcc_mnc = hf_eap_identity_mcc_mnc_3digits;
916   } else {
917     /* We got a 2-digit MNC match */
918     mcc_mnc = 100 * mcc + mnc;
919     hf_eap_identity_mcc_mnc = hf_eap_identity_mcc_mnc_2digits;
920   }
921 
922   proto_tree_add_uint(eap_identity_tree, hf_eap_identity_mcc_mnc,
923     tvb, offset + (guint)strlen(tokens[0]) + (guint)strlen("@wlan.") +
924     (guint)strlen("mnc"), (guint)strlen(realm_tokens[1]) - (guint)strlen("mnc"),
925     mcc_mnc);
926 
927   proto_tree_add_uint(eap_identity_tree, hf_eap_identity_mcc,
928     tvb, offset + (guint)(strlen(tokens[0]) + strlen("@wlan.") +
929     strlen(realm_tokens[1]) + 1 + strlen("mcc")),
930     (guint)(strlen(realm_tokens[2]) - strlen("mcc")), mcc);
931 end:
932   g_strfreev(tokens);
933   g_strfreev(realm_tokens);
934 
935   return ret;
936 }
937 
938 static void
939 dissect_eap_identity(tvbuff_t *tvb, packet_info* pinfo, proto_tree* tree, int offset, gint size)
940 {
941   /* Try to dissect as WLAN identity */
942   if (dissect_eap_identity_wlan(tvb, pinfo, tree, offset, size))
943     return;
944 }
945 
946 static void
947 dissect_eap_sim(proto_tree *eap_tree, tvbuff_t *tvb, packet_info* pinfo, int offset, gint size)
948 {
949   gint left = size;
950 
951   proto_tree_add_item(eap_tree, hf_eap_sim_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
952 
953   offset += 1;
954   left   -= 1;
955 
956   if (left < 2)
957     return;
958   proto_tree_add_item(eap_tree, hf_eap_sim_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
959   offset += 2;
960   left   -= 2;
961 
962   /* Rest of EAP-SIM data is in Type-Len-Value format. */
963   while (left >= 2) {
964     guint8      type, length;
965     gint        padding;
966     proto_item *pi;
967     proto_tree *attr_tree;
968     int         aoffset;
969     gint        aleft;
970 
971     aoffset = offset;
972     type    = tvb_get_guint8(tvb, aoffset);
973     length  = tvb_get_guint8(tvb, aoffset + 1);
974     aleft   = 4 * length;
975 
976     pi = proto_tree_add_none_format(eap_tree, hf_eap_sim_subtype_attribute, tvb,
977                                     aoffset, aleft, "EAP-SIM Attribute: %s (%d)",
978                                     val_to_str_ext_const(type,
979                                                          &eap_sim_aka_attribute_vals_ext,
980                                                          "Unknown"),
981                                     type);
982     attr_tree = proto_item_add_subtree(pi, ett_eap_sim_attr);
983     proto_tree_add_uint(attr_tree, hf_eap_sim_subtype_type, tvb, aoffset, 1, type);
984     aoffset += 1;
985     aleft   -= 1;
986 
987     if (aleft <= 0)
988       break;
989     proto_tree_add_item(attr_tree, hf_eap_sim_subtype_length, tvb, aoffset, 1, ENC_BIG_ENDIAN);
990     aoffset += 1;
991     aleft   -= 1;
992 
993     switch(type){
994       case AT_IDENTITY:
995         proto_tree_add_item(attr_tree, hf_eap_identity_actual_len, tvb, aoffset, 2, ENC_BIG_ENDIAN);
996         dissect_eap_identity(tvb, pinfo, attr_tree, aoffset + 2, tvb_get_ntohs(tvb, aoffset));
997         /* If we have a disparity between the EAP-SIM length (minus the
998          * first 4 bytes of header fields) * 4 and the Identity Actual
999          * Length then it's padding and we need to adjust for that
1000          * accurately before looking at the next EAP-SIM attribute. */
1001         padding = ((length - 1) * 4) - tvb_get_ntohs(tvb, aoffset);
1002         if (padding != 0) {
1003           proto_tree_add_item(attr_tree, hf_eap_identity_padding, tvb,
1004             aoffset + 2 + tvb_get_ntohs(tvb, aoffset), padding, ENC_NA);
1005         }
1006         break;
1007       case AT_NOTIFICATION:
1008         proto_tree_add_item(attr_tree, hf_eap_sim_notification_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1009         break;
1010       case AT_CLIENT_ERROR_CODE:
1011         proto_tree_add_item(attr_tree, hf_eap_sim_error_code_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1012         break;
1013       default:
1014         proto_tree_add_item(attr_tree, hf_eap_sim_subtype_value, tvb, aoffset, aleft, ENC_NA);
1015     }
1016 
1017     offset += 4 * length;
1018     left   -= 4 * length;
1019   }
1020 }
1021 
1022 static void
1023 dissect_eap_aka(proto_tree *eap_tree, tvbuff_t *tvb, packet_info* pinfo, int offset, gint size)
1024 {
1025   gint left = size;
1026 
1027   proto_tree_add_item(eap_tree, hf_eap_aka_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
1028 
1029   offset += 1;
1030   left   -= 1;
1031 
1032   if (left < 2)
1033     return;
1034   proto_tree_add_item(eap_tree, hf_eap_aka_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
1035   offset += 2;
1036   left   -= 2;
1037 
1038   /* Rest of EAP-AKA data is in Type-Len-Value format. */
1039   while (left >= 2) {
1040     guint8       type, length;
1041     gint         padding;
1042     proto_item  *pi;
1043     proto_tree  *attr_tree;
1044     int          aoffset;
1045     gint         aleft;
1046 
1047     aoffset = offset;
1048     type    = tvb_get_guint8(tvb, aoffset);
1049     length  = tvb_get_guint8(tvb, aoffset + 1);
1050     aleft   = 4 *  length;
1051 
1052     pi = proto_tree_add_none_format(eap_tree, hf_eap_aka_subtype_attribute, tvb,
1053                                     aoffset, aleft, "EAP-AKA Attribute: %s (%d)",
1054                                     val_to_str_ext_const(type,
1055                                                          &eap_sim_aka_attribute_vals_ext,
1056                                                          "Unknown"),
1057                                     type);
1058     attr_tree = proto_item_add_subtree(pi, ett_eap_aka_attr);
1059     proto_tree_add_uint(attr_tree, hf_eap_aka_subtype_type, tvb, aoffset, 1, type);
1060     aoffset += 1;
1061     aleft   -= 1;
1062 
1063     if (aleft <= 0)
1064       break;
1065     proto_tree_add_item(attr_tree, hf_eap_aka_subtype_length, tvb, aoffset, 1, ENC_BIG_ENDIAN);
1066     aoffset += 1;
1067     aleft   -= 1;
1068 
1069     switch(type){
1070       case AT_IDENTITY:
1071         proto_tree_add_item(attr_tree, hf_eap_identity_actual_len, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1072         dissect_eap_identity(tvb, pinfo, attr_tree, aoffset + 2, tvb_get_ntohs(tvb, aoffset));
1073         /* If we have a disparity between the EAP-AKA length (minus the
1074          * first 4 bytes of header fields) * 4 and the Identity Actual
1075          * Length then it's padding and we need to adjust for that
1076          * accurately before looking at the next EAP-AKA attribute. */
1077         padding = ((length - 1) * 4) - tvb_get_ntohs(tvb, aoffset);
1078         if (padding != 0) {
1079           proto_tree_add_item(attr_tree, hf_eap_identity_padding, tvb,
1080             aoffset + 2 + tvb_get_ntohs(tvb, aoffset), padding, ENC_NA);
1081         }
1082         break;
1083       case AT_NOTIFICATION:
1084         proto_tree_add_item(attr_tree, hf_eap_aka_notification_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1085         break;
1086       case AT_CLIENT_ERROR_CODE:
1087         proto_tree_add_item(attr_tree, hf_eap_aka_error_code_type, tvb, aoffset, 2, ENC_BIG_ENDIAN);
1088         break;
1089       default:
1090         proto_tree_add_item(attr_tree, hf_eap_aka_subtype_value, tvb, aoffset, aleft, ENC_NA);
1091     }
1092 
1093     offset += 4 * length;
1094     left   -= 4 * length;
1095   }
1096 }
1097 
1098 static int
1099 dissect_eap_pax(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset, gint size)
1100 {
1101   static int * const pax_flags[] = {
1102     &hf_eap_pax_flags_mf,
1103     &hf_eap_pax_flags_ce,
1104     &hf_eap_pax_flags_ai,
1105     &hf_eap_pax_flags_reserved,
1106     NULL
1107   };
1108   guint32 opcode;
1109   guint64 flags;
1110   guint32 len;
1111 
1112   proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_opcode, tvb, offset, 1, ENC_NA, &opcode);
1113   offset++;
1114 
1115   col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1116                   val_to_str(opcode, eap_pax_opcode_vals, "Unknown opcode (0x%02X)"));
1117 
1118   proto_tree_add_bitmask_ret_uint64(eap_tree, tvb, offset, hf_eap_pax_flags, ett_eap_pax_flags,
1119                                     pax_flags, ENC_BIG_ENDIAN, &flags);
1120   offset++;
1121 
1122   proto_tree_add_item(eap_tree, hf_eap_pax_mac_id, tvb, offset, 1, ENC_NA);
1123   offset++;
1124 
1125   proto_tree_add_item(eap_tree, hf_eap_pax_dh_group_id, tvb, offset, 1, ENC_NA);
1126   offset++;
1127 
1128   proto_tree_add_item(eap_tree, hf_eap_pax_public_key_id, tvb, offset, 1, ENC_NA);
1129   offset++;
1130 
1131   switch (opcode) {
1132     case PAX_STD_1:
1133       proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_a_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1134       offset += 2;
1135       proto_tree_add_item(eap_tree, hf_eap_pax_a, tvb, offset, len, ENC_NA);
1136       offset += len;
1137       len = 5 + size - offset;
1138       proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1139       offset += len;
1140       break;
1141     case PAX_STD_2:
1142       proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_b_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1143       offset += 2;
1144       proto_tree_add_item(eap_tree, hf_eap_pax_b, tvb, offset, len, ENC_NA);
1145       offset += len;
1146       proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_cid_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1147       offset += 2;
1148       proto_tree_add_item(eap_tree, hf_eap_pax_cid, tvb, offset, len, ENC_ASCII | ENC_NA);
1149       offset += len;
1150       proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_mac_ck_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1151       offset += 2;
1152       proto_tree_add_item(eap_tree, hf_eap_pax_mac_ck, tvb, offset, len, ENC_NA);
1153       offset += len;
1154       if (flags & EAP_PAX_FLAG_AI) {
1155         proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_ade_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1156         offset += 2;
1157         proto_tree_add_item(eap_tree, hf_eap_pax_ade, tvb, offset, len, ENC_NA);
1158         offset += len;
1159       }
1160       len = 5 + size - offset;
1161       proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1162       offset += len;
1163       break;
1164     case PAX_STD_3:
1165       proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_mac_ck_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1166       offset += 2;
1167       proto_tree_add_item(eap_tree, hf_eap_pax_mac_ck, tvb, offset, len, ENC_NA);
1168       offset += len;
1169       if (flags & EAP_PAX_FLAG_AI) {
1170         proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_ade_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1171         offset += 2;
1172         proto_tree_add_item(eap_tree, hf_eap_pax_ade, tvb, offset, len, ENC_NA);
1173         offset += len;
1174       }
1175       len = 5 + size - offset;
1176       proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1177       offset += len;
1178       break;
1179     case PAX_ACK:
1180       if (flags & EAP_PAX_FLAG_AI) {
1181         proto_tree_add_item_ret_uint(eap_tree, hf_eap_pax_ade_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1182         offset += 2;
1183         proto_tree_add_item(eap_tree, hf_eap_pax_ade, tvb, offset, len, ENC_NA);
1184         offset += len;
1185       }
1186       len = 5 + size - offset;
1187       proto_tree_add_item(eap_tree, hf_eap_pax_mac_icv, tvb, offset, len, ENC_NA);
1188       offset += len;
1189       break;
1190     case PAX_SEC_1:
1191     case PAX_SEC_2:
1192     case PAX_SEC_3:
1193     case PAX_SEC_4:
1194     case PAX_SEC_5:
1195       /* TODO implement */
1196     default:
1197       break;
1198   }
1199 
1200   return offset;
1201 }
1202 
1203 static int
1204 dissect_eap_psk_pchannel(proto_tree *eap_tree, tvbuff_t *tvb, int offset, gint size)
1205 {
1206   /* The protected channel (PCHANNEL) content is encrypted so for now just present
1207    * it as a binary blob */
1208   proto_tree_add_item(eap_tree, hf_eap_psk_pchannel, tvb, offset, size, ENC_NA);
1209   offset += size;
1210   return offset;
e1ap_MaxPacketLossRate_fmt(gchar * s,guint32 v)1211 }
1212 
1213 static int
1214 dissect_eap_psk(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset, gint size)
1215 {
1216   static int * const psk_flags[] = {
1217     &hf_eap_psk_flags_t,
1218     &hf_eap_psk_flags_reserved,
1219     NULL
1220   };
1221   guint64 flags;
1222 
1223   proto_tree_add_bitmask_ret_uint64(eap_tree, tvb, offset, hf_eap_psk_flags, ett_eap_psk_flags,
1224                                     psk_flags, ENC_NA, &flags);
1225   offset++;
1226 
1227   switch (flags & EAP_PSK_FLAGS_T_MASK) {
1228     case 0x00: /* T == 0 - EAP-PSK First Message */
1229       col_append_str(pinfo->cinfo, COL_INFO, " First Message");
1230       proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1231       offset += 16;
1232       proto_tree_add_item(eap_tree, hf_eap_psk_id_s, tvb, offset, size + 5 - offset, ENC_ASCII | ENC_NA);
1233       offset = size;
1234       break;
1235     case 0x40: /* T == 1 - EAP-PSK Second Message */
1236       col_append_str(pinfo->cinfo, COL_INFO, " Second Message");
1237       proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1238       offset += 16;
1239       proto_tree_add_item(eap_tree, hf_eap_psk_rand_p, tvb, offset, 16, ENC_NA);
1240       offset += 16;
1241       proto_tree_add_item(eap_tree, hf_eap_psk_mac_p, tvb, offset, 16, ENC_NA);
1242       offset += 16;
1243       proto_tree_add_item(eap_tree, hf_eap_psk_id_p, tvb, offset, size + 5 - offset, ENC_ASCII | ENC_NA);
1244       offset = size;
1245       break;
1246     case 0x80: /* T == 2 - EAP-PSK Third Message */
1247       col_append_str(pinfo->cinfo, COL_INFO, " Third Message");
1248       proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1249       offset += 16;
1250       proto_tree_add_item(eap_tree, hf_eap_psk_mac_s, tvb, offset, 16, ENC_NA);
1251       offset += 16;
1252       offset = dissect_eap_psk_pchannel(eap_tree, tvb, offset, size + 5 - offset);
1253       break;
1254     case 0xC0: /* T == 3 - EAP-PSK Fourth Message */
1255       col_append_str(pinfo->cinfo, COL_INFO, " Fourth Message");
1256       proto_tree_add_item(eap_tree, hf_eap_psk_rand_s, tvb, offset, 16, ENC_NA);
1257       offset += 16;
1258       offset = dissect_eap_psk_pchannel(eap_tree, tvb, offset, size + 5 - offset);
1259       break;
1260     default:
1261       break;
1262   }
1263 
1264   return offset;
1265 }
1266 
1267 static gint
1268 dissect_eap_gpsk_csuite_sel(proto_tree *eap_tree, tvbuff_t *tvb, int offset)
1269 {
1270   proto_tree *csuite_tree;
1271   csuite_tree = proto_tree_add_subtree(eap_tree, tvb, offset, 6, ett_eap_gpsk_csuite_sel,
dissect_e1ap_T_global(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1272                                         NULL, "EAP-GPSK CSuite_Sel");
1273   proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_vendor, tvb, offset, 4, ENC_BIG_ENDIAN);
1274   offset += 4;
1275   proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_specifier, tvb, offset, 2, ENC_BIG_ENDIAN);
1276   offset += 2;
1277   return offset;
1278 }
1279 
1280 static gint
1281 dissect_eap_gpsk_csuite_list(proto_tree *eap_tree, tvbuff_t *tvb, int offset)
1282 {
1283   gint start_offset = offset;
1284   guint16 len;
1285   proto_tree *list_tree, *csuite_tree;
1286 
1287   len = tvb_get_ntohs(tvb, offset) + 2;
1288   list_tree = proto_tree_add_subtree(eap_tree, tvb, offset, len, ett_eap_gpsk_csuite_list,
1289                                      NULL, "EAP-GPSK CSuite List");
1290   proto_tree_add_item(list_tree, hf_eap_gpsk_csuite_list_len, tvb, offset, 2, ENC_BIG_ENDIAN);
1291   offset += 2;
1292 
1293   while (offset < start_offset + len) {
1294     csuite_tree = proto_tree_add_subtree(list_tree, tvb, offset, 6, ett_eap_gpsk_csuite,
1295                                          NULL, "CSuite");
1296     proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_vendor, tvb, offset, 4, ENC_BIG_ENDIAN);
dissect_e1ap_PrivateIE_ID(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1297     offset += 4;
1298     proto_tree_add_item(csuite_tree, hf_eap_gpsk_csuite_specifier, tvb, offset, 2, ENC_BIG_ENDIAN);
1299     offset += 2;
1300   }
1301   return offset;
1302 }
1303 
1304 static gint
1305 dissect_eap_sake_attribute(proto_tree *eap_tree, tvbuff_t *tvb, int offset, gint size)
1306 {
1307   gint start_offset = offset;
1308   guint8 type;
1309   guint8 len;
1310   proto_tree *attr_tree;
1311 
1312   type = tvb_get_guint8(tvb, offset);
1313   len = tvb_get_guint8(tvb, offset + 1);
1314 
1315   if (len < 2 || len > size) {
1316     return -1;
1317   }
1318   attr_tree = proto_tree_add_subtree_format(eap_tree, tvb, offset, len, ett_eap_sake_attr, NULL,
1319                                             "EAP-SAKE Attribute: %s",
1320                                             val_to_str(type, eap_sake_attr_type_vals,
1321                                                        "Unknown (%d)"));
1322 
1323   proto_tree_add_item(attr_tree, hf_eap_sake_attr_type, tvb, offset, 1, ENC_NA);
1324   offset++;
1325   proto_tree_add_item(attr_tree, hf_eap_sake_attr_len, tvb, offset, 1, ENC_NA);
1326   offset++;
1327   len -= 2;
1328 
1329   switch (type) {
1330     case SAKE_AT_SERVERID:
1331     case SAKE_AT_PEERID:
1332       proto_tree_add_item(attr_tree, hf_eap_sake_attr_value_str, tvb, offset, len, ENC_ASCII | ENC_NA);
1333       offset += len;
1334       break;
1335     case SAKE_AT_MSK_LIFE:
1336       proto_tree_add_item(attr_tree, hf_eap_sake_attr_value_uint48, tvb, offset, len,
1337                           ENC_BIG_ENDIAN);
1338       offset += len;
1339       break;
1340     case SAKE_AT_RAND_S:
1341     case SAKE_AT_RAND_P:
1342     case SAKE_AT_MIC_S:
1343     case SAKE_AT_MIC_P:
1344     case SAKE_AT_SPI_S:
1345     case SAKE_AT_SPI_P:
1346     case SAKE_AT_ANY_ID_REQ:
dissect_e1ap_ProcedureCode(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1347     case SAKE_AT_PERM_ID_REQ:
1348     case SAKE_AT_ENCR_DATA:
1349     case SAKE_AT_IV:
1350     case SAKE_AT_PADDING:
1351     case SAKE_AT_NEXT_TMPID:
1352     default:
1353       proto_tree_add_item(attr_tree, hf_eap_sake_attr_value, tvb, offset, len, ENC_NA);
1354       offset += len;
1355       break;
1356   }
1357   return offset - start_offset;
1358 }
1359 
1360 static void
1361 dissect_eap_sake_attributes(proto_tree *eap_tree, tvbuff_t *tvb, int offset, gint size)
1362 {
1363   gint attr_size;
1364   while (offset < size) {
1365     attr_size = dissect_eap_sake_attribute(eap_tree, tvb, offset, size);
1366     if (attr_size == -1) {
1367       break;
1368     }
1369     offset += attr_size;
1370   }
1371 }
1372 
1373 static void
1374 dissect_eap_sake(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo _U_, int offset, gint size)
1375 {
1376   guint32 version;
1377   guint32 subtype;
1378 
1379   proto_tree_add_item_ret_uint(eap_tree, hf_eap_sake_version, tvb, offset, 1, ENC_NA, &version);
1380   offset++;
1381   if (version != 2) {
1382     /* RFC 4763 specify version 2. Everything else is unsupported */
1383     return;
1384   }
1385   proto_tree_add_item(eap_tree, hf_eap_sake_session_id, tvb, offset, 1, ENC_NA);
1386   offset++;
1387   proto_tree_add_item_ret_uint(eap_tree, hf_eap_sake_subtype, tvb, offset, 1, ENC_NA, &subtype);
1388   offset++;
1389 
1390   switch (subtype) {
1391     case SAKE_CHALLENGE:
1392     case SAKE_CONFIRM:
1393     case SAKE_AUTH_REJECT:
1394     case SAKE_IDENTITY:
1395       dissect_eap_sake_attributes(eap_tree, tvb, offset, size + 5 - offset);
1396       break;
1397     default:
1398       break;
1399   }
1400 }
1401 
1402 static int
1403 dissect_eap_gpsk(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset, gint size)
1404 {
1405   guint32 opcode;
1406   guint32 len;
1407 
1408   proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_opcode, tvb, offset, 1, ENC_NA, &opcode);
1409   offset++;
1410   col_append_fstr(pinfo->cinfo, COL_INFO, " %s",
1411                   val_to_str(opcode, eap_gpsk_opcode_vals, "Unknown opcode (0x%02X)"));
1412 
1413   switch (opcode) {
1414     case GPSK_GPSK_1:
1415       proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_server_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1416       offset += 2;
1417       proto_tree_add_item(eap_tree, hf_eap_gpsk_id_server, tvb, offset, len, ENC_ASCII | ENC_NA);
1418       offset += len;
1419       proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_server, tvb, offset, 32, ENC_NA);
1420       offset += 32;
1421       offset = dissect_eap_gpsk_csuite_list(eap_tree, tvb, offset);
1422       break;
1423     case GPSK_GPSK_2:
1424       proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_peer_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1425       offset += 2;
1426       proto_tree_add_item(eap_tree, hf_eap_gpsk_id_peer, tvb, offset, len, ENC_ASCII | ENC_NA);
1427       offset += len;
1428       proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_server_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1429       offset += 2;
1430       proto_tree_add_item(eap_tree, hf_eap_gpsk_id_server, tvb, offset, len, ENC_ASCII | ENC_NA);
1431       offset += len;
1432       proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_peer, tvb, offset, 32, ENC_NA);
1433       offset += 32;
1434       proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_server, tvb, offset, 32, ENC_NA);
1435       offset += 32;
1436       offset = dissect_eap_gpsk_csuite_list(eap_tree, tvb, offset);
1437       offset = dissect_eap_gpsk_csuite_sel(eap_tree, tvb, offset);
1438       proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_pd_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1439       offset += 2;
1440       if (len > 0) {
1441         proto_tree_add_item(eap_tree, hf_eap_gpsk_pd_payload, tvb, offset, len, ENC_NA);
1442         offset += len;
1443       }
1444       len = size + 5 - offset;
1445       proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1446       offset += len;
1447       break;
1448     case GPSK_GPSK_3:
1449       proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_peer, tvb, offset, 32, ENC_NA);
1450       offset += 32;
1451       proto_tree_add_item(eap_tree, hf_eap_gpsk_rand_server, tvb, offset, 32, ENC_NA);
1452       offset += 32;
1453       proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_id_server_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1454       offset += 2;
1455       proto_tree_add_item(eap_tree, hf_eap_gpsk_id_server, tvb, offset, len, ENC_ASCII | ENC_NA);
1456       offset += len;
1457       offset = dissect_eap_gpsk_csuite_sel(eap_tree, tvb, offset);
1458       proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_pd_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1459       offset += 2;
1460       if (len > 0) {
1461         proto_tree_add_item(eap_tree, hf_eap_gpsk_pd_payload, tvb, offset, len, ENC_NA);
1462         offset += len;
1463       }
1464       len = size + 5 - offset;
1465       proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1466       offset += len;
1467       break;
1468     case GPSK_GPSK_4:
1469       proto_tree_add_item_ret_uint(eap_tree, hf_eap_gpsk_pd_payload_len, tvb, offset, 2, ENC_BIG_ENDIAN, &len);
1470       offset += 2;
1471       if (len > 0) {
1472         proto_tree_add_item(eap_tree, hf_eap_gpsk_pd_payload, tvb, offset, len, ENC_NA);
1473         offset += len;
1474       }
1475       len = size + 5 - offset;
1476       proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1477       offset += len;
1478       break;
1479     case GPSK_FAIL:
1480       proto_tree_add_item(eap_tree, hf_eap_gpsk_failure_code, tvb, offset, 4, ENC_BIG_ENDIAN);
1481       offset += 4;
1482       break;
1483     case GPSK_PROTECTED_FAIL:
1484       proto_tree_add_item(eap_tree, hf_eap_gpsk_failure_code, tvb, offset, 4, ENC_BIG_ENDIAN);
1485       offset += 4;
1486       len = size + 5 - offset;
1487       proto_tree_add_item(eap_tree, hf_eap_gpsk_payload_mac, tvb, offset, len, ENC_NA);
1488       offset += len;
1489       break;
1490     default:
1491       break;
1492   }
1493 
1494   return offset;
1495 }
1496 
1497 static int
1498 dissect_eap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1499 {
1500   guint8          eap_code;
1501   guint8          eap_identifier;
1502   guint16         eap_len;
1503   guint8          eap_type;
1504   gint            len;
1505   conversation_t *conversation       = NULL;
1506   conv_state_t   *conversation_state = NULL;
dissect_e1ap_ProtocolIE_ID(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1507   frame_state_t  *packet_state;
1508   int             leap_state;
1509   proto_tree     *ti, *ti_id, *ti_len;
1510   proto_tree     *eap_tree;
1511   proto_tree     *eap_tls_flags_tree;
1512   proto_item     *eap_type_item;
1513 
1514   col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAP");
1515   col_clear(pinfo->cinfo, COL_INFO);
1516 
1517   eap_code = tvb_get_guint8(tvb, 0);
1518   eap_identifier = tvb_get_guint8(tvb, 1);
1519 
1520   col_add_str(pinfo->cinfo, COL_INFO,
1521                 val_to_str(eap_code, eap_code_vals, "Unknown code (0x%02X)"));
1522 
1523   /*
1524    * Find a conversation to which we belong; create one if we don't find it.
1525    *
1526    * If this is an EAP-Message (RFC 2869) encapsulated in Tunneled TLS EAP
1527    * (EAP-TTLS), then we should not attempt to create a conversation to detect
1528    * retransmitted messages, try TLS reassembly and so on.
1529    *
1530    * EAP runs over RADIUS (which runs over UDP), EAPOL (802.1X Authentication)
1531    * or other transports. In case of RADIUS, a single "session" may consist
1532    * of two UDP associations (one for authorization, one for accounting) which
1533    * results in two separate conversations. This wastes memory, but won't affect
1534    * the use cases below. In case of EAPOL, there are no ports. In any case,
1535    * force a new conversation when the EAP-Request/Identity message is found.
dissect_e1ap_TriggeringMessage(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1536    *
1537    * Conversation tracking is required for 1) EAP-TLS reassembly and 2) tracking
1538    * the stage in the LEAP protocol. In both cases, the protocol starts with an
1539    * EAP-Request/Identity message which cannot be found in the middle of the
1540    * session. Use it as a signal to start a new conversation. This ensures that
1541    * the TLS dissector associates new TLS messages with a unique TLS session.
1542    */
1543   if (!proto_is_frame_protocol(pinfo->layers, "tls")) {
1544     if (PINFO_FD_VISITED(pinfo) || !(eap_code == EAP_REQUEST && tvb_get_guint8(tvb, 4) == EAP_TYPE_ID)) {
1545       conversation = find_conversation_pinfo(pinfo, 0);
1546     }
1547     if (conversation == NULL) {
1548       conversation = conversation_new(pinfo->num, &pinfo->src,
1549                                       &pinfo->dst, conversation_pt_to_endpoint_type(pinfo->ptype),
1550                                       pinfo->srcport, pinfo->destport, 0);
1551     }
1552 
1553     /*
1554      * Get the state information for the conversation; attach some if
1555      * we don't find it.
1556      */
1557     conversation_state = (conv_state_t *)conversation_get_proto_data(conversation, proto_eap);
1558     if (conversation_state == NULL) {
1559       /*
1560        * Attach state information to the conversation.
1561        */
1562       conversation_state = wmem_new(wmem_file_scope(), conv_state_t);
1563       conversation_state->eap_tls_seq      = -1;
1564       conversation_state->eap_reass_cookie =  0;
1565       conversation_state->leap_state       = -1;
1566       conversation_state->last_eap_id_req  = -1;
1567       conversation_state->last_eap_id_resp = -1;
1568       conversation_add_proto_data(conversation, proto_eap, conversation_state);
1569     }
1570 
1571     /*
1572      * Set this now, so that it gets remembered even if we throw an exception
1573      * later.
1574      */
1575     if (eap_code == EAP_FAILURE)
1576       conversation_state->leap_state = -1;
1577   }
1578 
1579   eap_len = tvb_get_ntohs(tvb, 2);
1580   len     = eap_len;
1581 
1582   ti = proto_tree_add_item(tree, proto_eap, tvb, 0, len, ENC_NA);
1583   eap_tree = proto_item_add_subtree(ti, ett_eap);
1584 
dissect_e1ap_ProtocolIE_SingleContainer(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1585   proto_tree_add_item(eap_tree, hf_eap_code, tvb, 0, 1, ENC_BIG_ENDIAN);
1586   ti_id = proto_tree_add_item(eap_tree, hf_eap_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
1587   ti_len = proto_tree_add_item(eap_tree, hf_eap_len, tvb, 2, 2, ENC_BIG_ENDIAN);
1588   if (len < 4 || (guint)len > tvb_reported_length(tvb)) {
1589     expert_add_info(pinfo, ti_len, &ei_eap_bad_length);
1590   }
1591 
1592   /* Detect message retransmissions. Since the protocol proceeds in lock-step,
1593    * reordering is not expected. If retransmissions somehow occur, we would have
dissect_e1ap_T_extensionValue(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1594    * to detect retransmissions via a bitmap. */
1595   gboolean is_duplicate_id = FALSE;
1596   if (conversation_state) {
1597     if (eap_code == EAP_REQUEST || eap_code == EAP_RESPONSE ||
1598         eap_code == EAP_INITIATE || eap_code == EAP_FINISH) {
1599       if (!PINFO_FD_VISITED(pinfo)) {
1600         gint16 *last_eap_id = eap_code == EAP_REQUEST || eap_code == EAP_INITIATE ?
1601           &conversation_state->last_eap_id_req :
1602           &conversation_state->last_eap_id_resp;
1603         is_duplicate_id = *last_eap_id == eap_identifier;
1604         *last_eap_id = eap_identifier;
1605         if (is_duplicate_id) {
1606           // Use a dummy value to remember that this packet is a duplicate.
1607           p_add_proto_data(wmem_file_scope(), pinfo, proto_eap, 1, GINT_TO_POINTER(1));
1608         }
dissect_e1ap_ProtocolExtensionField(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1609       } else {
1610         is_duplicate_id = !!p_get_proto_data(wmem_file_scope(), pinfo, proto_eap, 1);
1611       }
1612       if (is_duplicate_id) {
1613         expert_add_info(pinfo, ti_id, &ei_eap_retransmission);
1614       }
1615     }
1616   }
1617 
1618   switch (eap_code) {
1619 
1620   case EAP_SUCCESS:
1621   case EAP_FAILURE:
dissect_e1ap_ProtocolExtensionContainer(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1622     break;
1623 
1624   case EAP_REQUEST:
1625   case EAP_RESPONSE:
1626     eap_type = tvb_get_guint8(tvb, 4);
1627 
1628     col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1629                       val_to_str_ext(eap_type, &eap_type_vals_ext,
1630                                      "Unknown type (0x%02x)"));
1631     eap_type_item = proto_tree_add_item(eap_tree, hf_eap_type, tvb, 4, 1, ENC_BIG_ENDIAN);
1632 
dissect_e1ap_T_value(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)1633     if ((len > 5) || ((len == 5) && (eap_type == EAP_TYPE_ID))) {
1634       int     offset = 5;
1635       gint    size   = len - offset;
1636 
1637       switch (eap_type) {
1638         /*********************************************************************
1639         **********************************************************************/
1640       case EAP_TYPE_ID:
1641         if (size > 0) {
1642           dissect_eap_identity(tvb, pinfo, eap_tree, offset, size);
1643         }
1644         if (conversation_state && !PINFO_FD_VISITED(pinfo)) {
1645           conversation_state->leap_state  =  0;
1646           conversation_state->eap_tls_seq = -1;
1647         }
1648         break;
1649 
1650         /*********************************************************************
1651         **********************************************************************/
1652       case EAP_TYPE_NOTIFY:
1653         proto_tree_add_item(eap_tree, hf_eap_notification, tvb,
1654             offset, size, ENC_ASCII|ENC_NA);
1655         break;
1656 
1657         /*********************************************************************
1658         **********************************************************************/
1659       case EAP_TYPE_NAK:
1660         proto_tree_add_item(eap_tree, hf_eap_type_nak, tvb,
1661             offset, 1, ENC_BIG_ENDIAN);
1662         break;
1663         /*********************************************************************
1664         **********************************************************************/
1665       case EAP_TYPE_MD5:
1666       {
1667         guint8      value_size = tvb_get_guint8(tvb, offset);
1668         gint        extra_len  = size - 1 - value_size;
1669         proto_item *item;
1670 
1671         /* Warn that this is an insecure EAP type. */
1672         expert_add_info(pinfo, eap_type_item, &ei_eap_mitm_attacks);
1673 
1674         item = proto_tree_add_item(eap_tree, hf_eap_md5_value_size, tvb, offset, 1, ENC_BIG_ENDIAN);
1675         if (value_size > (size - 1))
1676         {
1677           expert_add_info(pinfo, item, &ei_eap_md5_value_size_overflow);
1678           value_size = size - 1;
1679         }
1680 
1681         offset += 1;
1682         proto_tree_add_item(eap_tree, hf_eap_md5_value, tvb, offset, value_size, ENC_NA);
1683         offset += value_size;
1684         if (extra_len > 0) {
1685           proto_tree_add_item(eap_tree, hf_eap_md5_extra_data, tvb, offset, extra_len, ENC_NA);
1686         }
1687       }
1688       break;
1689 
1690       /*********************************************************************
1691                                 EAP-TLS
1692       **********************************************************************/
1693       case EAP_TYPE_FAST:
1694       case EAP_TYPE_PEAP:
1695       case EAP_TYPE_TTLS:
1696       case EAP_TYPE_TLS:
1697       case EAP_TYPE_TEAP:
1698       {
1699         guint8   flags            = tvb_get_guint8(tvb, offset);
1700         gboolean more_fragments;
1701         gboolean has_length;
1702         gboolean is_start;
1703         int      eap_tls_seq      = -1;
1704         guint32  eap_reass_cookie =  0;
1705         gboolean needs_reassembly =  FALSE;
1706 
1707         if (!conversation_state) {
1708           // XXX expert info? There cannot be another EAP-TTLS message within
1709           // the EAP-Message inside EAP-TTLS.
1710           break;
1711         }
1712 
1713         more_fragments = test_flag(flags,EAP_TLS_FLAG_M);
1714         has_length     = test_flag(flags,EAP_TLS_FLAG_L);
1715         is_start       = test_flag(flags,EAP_TLS_FLAG_S);
1716 
1717         if (is_start)
1718           conversation_state->eap_tls_seq = -1;
1719 
1720         /* Flags field, 1 byte */
1721         ti = proto_tree_add_item(eap_tree, hf_eap_tls_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
1722         eap_tls_flags_tree = proto_item_add_subtree(ti, ett_eap_tls_flags);
1723         proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flag_l, tvb, offset, 1, ENC_BIG_ENDIAN);
1724         proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flag_m, tvb, offset, 1, ENC_BIG_ENDIAN);
1725         proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flag_s, tvb, offset, 1, ENC_BIG_ENDIAN);
1726 
1727         if ((eap_type == EAP_TYPE_PEAP) || (eap_type == EAP_TYPE_TTLS) ||
1728             (eap_type == EAP_TYPE_FAST) || (eap_type == EAP_TYPE_TEAP)) {
1729           proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flags_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1730         }
1731         size   -= 1;
1732         offset += 1;
1733 
1734         /* Length field, 4 bytes, OPTIONAL. */
1735         if (has_length) {
1736           proto_tree_add_item(eap_tree, hf_eap_tls_len, tvb, offset, 4, ENC_BIG_ENDIAN);
1737           size   -= 4;
1738           offset += 4;
1739         }
1740 
1741         /* 4.1.1 Authority ID Data https://datatracker.ietf.org/doc/html/rfc4851#section-4.1.1 */
1742         if (eap_type == EAP_TYPE_FAST && is_start) {
1743           guint32 length, type;
1744 
1745           proto_tree_add_item_ret_uint(eap_tree, hf_eap_fast_type, tvb, offset, 2, ENC_BIG_ENDIAN, &type);
1746           size   -= 2;
1747           offset += 2;
1748 
1749           proto_tree_add_item_ret_uint(eap_tree, hf_eap_fast_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length);
1750           size   -= 2;
1751           offset += 2;
1752 
1753           proto_tree_add_item(eap_tree, hf_eap_data, tvb, offset, length, ENC_NA);
1754 
1755           switch (type) {
1756             case 4:
1757               proto_tree_add_item(eap_tree, hf_eap_fast_aidd, tvb, offset, length, ENC_NA);
1758             break;
1759           }
1760           size   -= length;
1761           offset += length;
1762 
1763         }
1764 
1765         if (size > 0) {
1766 
1767           tvbuff_t *next_tvb = NULL;
1768           gint      tvb_len;
1769           gboolean  save_fragmented;
1770 
1771           tvb_len = tvb_captured_length_remaining(tvb, offset);
1772           if (size < tvb_len)
1773             tvb_len = size;
1774 
1775           /* If this is a retransmission, do not save the fragment. */
1776           if (is_duplicate_id) {
1777             next_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_len, size);
1778             call_data_dissector(next_tvb, pinfo, eap_tree);
1779             break;
1780           }
1781 
1782           /*
1783             EAP/TLS is weird protocol (it comes from
1784             Microsoft after all).
1785 
1786             If we have series of fragmented packets,
1787             then there's no way of knowing that from
1788             the packet itself, if it is the last packet
1789             in series, that is that the packet part of
1790             bigger fragmented set of data.
1791 
1792             The only way to know is, by knowing
1793             that we are already in defragmentation
1794             "mode" and we are expecing packet
1795             carrying fragment of data. (either
1796             because we have not received expected
1797             amount of data, or because the packet before
1798             had "F"ragment flag set.)
1799 
1800             The situation is alleviated by fact that it
1801             is simple ack/nack protcol so there's no
1802             place for out-of-order packets like it is
1803             possible with IP.
1804 
1805             Anyway, point of this lengthy essay is that
1806             we have to keep state information in the
1807             conversation, so that we can put ourselves in
1808             defragmenting mode and wait for the last packet,
1809             and have to attach state to frames as well, so
1810             that we can handle defragmentation after the
1811             first pass through the capture.
1812           */
1813           /* See if we have a remembered defragmentation EAP ID. */
1814           packet_state = (frame_state_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_eap, 0);
1815           if (packet_state == NULL) {
1816             /*
1817              * We haven't - does this message require reassembly?
1818              */
1819             if (!pinfo->fd->visited) {
1820               /*
1821                * This is the first time we've looked at this frame,
1822                * so it wouldn't have any remembered information.
1823                *
1824                * Therefore, we check whether this conversation has
1825                * a reassembly operation in progress, or whether
1826                * this frame has the Fragment flag set.
1827                */
1828               if (conversation_state->eap_tls_seq != -1) {
1829                 /*
1830                  * There's a reassembly in progress; the sequence number
1831                  * of the previous fragment is
1832                  * "conversation_state->eap_tls_seq", and the reassembly
1833                  * ID is "conversation_state->eap_reass_cookie".
1834                  *
1835                  * We must include this frame in the reassembly.
1836                  * We advance the sequence number, giving us the
1837                  * sequence number for this fragment.
1838                  */
1839                 needs_reassembly = TRUE;
1840                 conversation_state->eap_tls_seq++;
1841 
1842                 eap_reass_cookie = conversation_state->eap_reass_cookie;
1843                 eap_tls_seq = conversation_state->eap_tls_seq;
1844               } else if (more_fragments && has_length) {
1845                 /*
1846                  * This message has the Fragment flag set, so it requires
1847                  * reassembly.  It's the message containing the first
1848                  * fragment (if it's a later fragment, the sequence
1849                  * number in the conversation state would not be -1).
1850                  *
1851                  * If it doesn't include a length, however, we can't
1852                  * do reassembly (either the message is in error, as
1853                  * the first fragment *must* contain a length, or we
1854                  * didn't capture the first fragment, and this just
1855                  * happens to be the first fragment we saw), so we
1856                  * also check that we have a length;
1857                  */
1858                 needs_reassembly = TRUE;
1859                 conversation_state->eap_reass_cookie = pinfo->num;
1860 
1861                 /*
1862                  * Start the reassembly sequence number at 0.
1863                  */
1864                 conversation_state->eap_tls_seq = 0;
1865 
1866                 eap_tls_seq = conversation_state->eap_tls_seq;
1867                 eap_reass_cookie = conversation_state->eap_reass_cookie;
1868               }
1869 
1870               if (needs_reassembly) {
1871                 /*
1872                  * This frame requires reassembly; remember the reassembly
1873                  * ID for subsequent accesses to it.
1874                  */
1875                 packet_state = wmem_new(wmem_file_scope(), frame_state_t);
1876                 packet_state->info = eap_reass_cookie;
1877                 p_add_proto_data(wmem_file_scope(), pinfo, proto_eap, 0, packet_state);
1878               }
1879             }
1880           } else {
1881             /*
1882              * This frame has a reassembly cookie associated with it, so
1883              * it requires reassembly.  We've already done the
1884              * reassembly in the first pass, so "fragment_add_seq()"
1885              * won't look at the sequence number; set it to 0.
1886              *
1887              * XXX - a frame isn't supposed to have more than one
1888              * EAP message in it, but if it includes both an EAP-TLS
1889              * message and a LEAP message, we might be mistakenly
1890              * concluding it requires reassembly because the "info"
1891              * field isn't -1.  We could, I guess, pack both EAP-TLS
1892              * ID and LEAP state into the structure, but that doesn't
1893              * work if you have multiple EAP-TLS or LEAP messages in
1894              * the frame.
1895              *
1896              * But it's not clear how much work we should do to handle
1897              * a bogus message such as that; as long as we don't crash
1898              * or do something else equally horrible, we may not
1899              * have to worry about this at all.
1900              */
1901             needs_reassembly = TRUE;
1902             eap_reass_cookie = packet_state->info;
1903             eap_tls_seq = 0;
1904           }
1905 
1906           /*
1907             We test here to see whether EAP-TLS packet
1908             carry fragmented of TLS data.
1909 
1910             If this is the case, we do reasembly below,
1911             otherwise we just call dissector.
1912           */
1913           if (needs_reassembly) {
1914             fragment_head   *fd_head;
1915 
1916             /*
1917              * Yes, this frame contains a fragment that requires
1918              * reassembly.
1919              */
1920             save_fragmented   = pinfo->fragmented;
1921             pinfo->fragmented = TRUE;
1922             fd_head = fragment_add_seq(&eap_tls_reassembly_table,
1923                                        tvb, offset,
1924                                        pinfo, eap_reass_cookie, NULL,
1925                                        eap_tls_seq,
1926                                        size,
1927                                        more_fragments, 0);
1928 
1929             if (fd_head != NULL && fd_head->reassembled_in == pinfo->num) {
1930               /* Reassembled  */
1931               proto_item *frag_tree_item;
1932 
1933               next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
1934               add_new_data_source(pinfo, next_tvb, "Reassembled EAP-TLS");
1935 
1936               show_fragment_seq_tree(fd_head, &eap_tls_frag_items,
1937                                      eap_tree, pinfo, next_tvb, &frag_tree_item);
1938 
1939               /*
1940                * We're finished reassembing this frame.
1941                * Reinitialize the reassembly state.
1942                */
1943               if (!pinfo->fd->visited)
1944                 conversation_state->eap_tls_seq = -1;
1945             }
1946 
1947             pinfo->fragmented = save_fragmented;
1948 
1949           } else { /* this data is NOT fragmented */
1950             next_tvb = tvb_new_subset_length_caplen(tvb, offset, tvb_len, size);
1951           }
1952 
1953           if (next_tvb) {
1954             switch (eap_type) {
1955               case EAP_TYPE_TTLS:
1956                 tls_set_appdata_dissector(tls_handle, pinfo, diameter_avps_handle);
1957                 break;
1958               case EAP_TYPE_PEAP:
1959                 tls_set_appdata_dissector(tls_handle, pinfo, eap_handle);
1960                 break;
1961               case EAP_TYPE_TEAP:
1962                 tls_set_appdata_dissector(tls_handle, pinfo, teap_handle);
1963                 break;
1964             }
1965             call_dissector(tls_handle, next_tvb, pinfo, eap_tree);
1966           }
1967         }
1968       }
1969       break; /*  EAP_TYPE_TLS */
1970 
1971       /*********************************************************************
1972         Cisco's Lightweight EAP (LEAP)
1973         https://web.archive.org/web/20070623090417if_/http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
1974       **********************************************************************/
1975       case EAP_TYPE_LEAP:
1976       {
1977         guint8 count, namesize;
1978 
1979         /* Warn that this is an insecure EAP type. */
1980         expert_add_info(pinfo, eap_type_item, &ei_eap_dictionary_attacks);
1981 
1982         /* Version (byte) */
1983         proto_tree_add_item(eap_tree, hf_eap_leap_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1984         offset += 1;
1985 
1986         /* Unused  (byte) */
1987         proto_tree_add_item(eap_tree, hf_eap_leap_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1988         offset += 1;
1989 
1990         /* Count   (byte) */
1991         count = tvb_get_guint8(tvb, offset);
1992         proto_tree_add_item(eap_tree, hf_eap_leap_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1993         offset += 1;
1994 
1995         /* Data    (byte*Count) */
1996         /* This part is state-dependent. */
1997 
1998         if (!conversation_state) {
1999           // XXX expert info? LEAP is not expected within the EAP-Message within EAP-TTLS.
2000           break;
2001         }
2002         /* XXX - are duplicates possible (is_duplicate_id)?
2003          * If so, should we stop here to avoid modifying conversation_state? */
2004 
2005         /* See if we've already remembered the state. */
2006         packet_state = (frame_state_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_eap, 0);
2007         if (packet_state == NULL) {
2008           /*
2009            * We haven't - compute the state based on the current
2010            * state in the conversation.
2011            */
2012           leap_state = conversation_state->leap_state;
2013 
2014           /* Advance the state machine. */
2015           if (leap_state==0) leap_state =  1; else
2016             if (leap_state==1) leap_state =  2; else
2017               if (leap_state==2) leap_state =  3; else
2018                 if (leap_state==3) leap_state =  4; else
2019                   if (leap_state==4) leap_state = -1;
2020 
2021           /*
2022            * Remember the state for subsequent accesses to this
2023            * frame.
2024            */
2025           packet_state = wmem_new(wmem_file_scope(), frame_state_t);
2026           packet_state->info = leap_state;
2027           p_add_proto_data(wmem_file_scope(), pinfo, proto_eap, 0, packet_state);
2028 
2029           /*
2030            * Update the conversation's state.
2031            */
2032           conversation_state->leap_state = leap_state;
2033         }
2034 
2035         /* Get the remembered state. */
2036         leap_state = packet_state->info;
2037 
2038         switch (leap_state) {
2039           case 1:
2040             proto_tree_add_item(eap_tree, hf_eap_leap_peer_challenge, tvb, offset, count, ENC_NA);
2041             break;
2042 
2043           case 2:
2044             proto_tree_add_item(eap_tree, hf_eap_leap_peer_response, tvb, offset, count, ENC_NA);
2045             break;
2046 
2047           case 3:
2048             proto_tree_add_item(eap_tree, hf_eap_leap_ap_challenge, tvb, offset, count, ENC_NA);
2049             break;
2050 
2051           case 4:
2052             proto_tree_add_item(eap_tree, hf_eap_leap_ap_response, tvb, offset, count, ENC_NA);
2053             break;
2054 
2055           default:
2056             proto_tree_add_item(eap_tree, hf_eap_leap_data, tvb, offset, count, ENC_NA);
2057             break;
2058         }
2059 
2060         offset += count;
2061 
2062         /* Name    (Length-(8+Count)) */
2063         namesize = eap_len - (8+count);
2064         proto_tree_add_item(eap_tree, hf_eap_leap_name, tvb, offset, namesize, ENC_ASCII|ENC_NA);
2065       }
2066 
2067       break; /* EAP_TYPE_LEAP */
2068 
2069       /*********************************************************************
2070             EAP-MSCHAPv2 - draft-kamath-pppext-eap-mschapv2-00.txt
2071       **********************************************************************/
2072       case EAP_TYPE_MSCHAPV2:
2073         dissect_eap_mschapv2(eap_tree, tvb, pinfo, offset, size);
2074         break; /* EAP_TYPE_MSCHAPV2 */
2075 
2076         /*********************************************************************
2077            EAP-SIM - draft-haverinen-pppext-eap-sim-13.txt
2078         **********************************************************************/
2079       case EAP_TYPE_SIM:
2080         dissect_eap_sim(eap_tree, tvb, pinfo, offset, size);
2081         break; /* EAP_TYPE_SIM */
2082 
2083         /*********************************************************************
2084             EAP-AKA - draft-arkko-pppext-eap-aka-12.txt
2085         **********************************************************************/
2086       case EAP_TYPE_AKA:
2087       case EAP_TYPE_AKA_PRIME:
2088         dissect_eap_aka(eap_tree, tvb, pinfo, offset, size);
2089         break; /* EAP_TYPE_AKA */
2090 
2091         /*********************************************************************
2092             EAP Expanded Type
2093         **********************************************************************/
2094       case EAP_TYPE_EXT:
2095       {
2096         proto_tree *exptree;
2097 
2098         exptree   = proto_tree_add_subtree(eap_tree, tvb, offset, size, ett_eap_exp_attr, NULL, "Expanded Type");
2099         dissect_exteap(exptree, tvb, offset, size, pinfo, eap_code, eap_identifier);
2100       }
2101       break;
2102 
2103       /*********************************************************************
2104             EAP-PAX - RFC 4746
2105       **********************************************************************/
2106       case EAP_TYPE_PAX:
2107         dissect_eap_pax(eap_tree, tvb, pinfo, offset, size);
2108         break; /* EAP_TYPE_PAX */
2109 
2110       /*********************************************************************
2111             EAP-PSK - RFC 4764
2112       **********************************************************************/
2113       case EAP_TYPE_PSK:
2114         dissect_eap_psk(eap_tree, tvb, pinfo, offset, size);
2115         break; /* EAP_TYPE_PSK */
2116 
2117       /*********************************************************************
2118             EAP-SAKE - RFC 4763
2119       **********************************************************************/
2120       case EAP_TYPE_SAKE:
2121         dissect_eap_sake(eap_tree, tvb, pinfo, offset, size);
2122         break; /* EAP_TYPE_SAKE */
2123 
2124       /*********************************************************************
2125             EAP-GPSK - RFC 5433
2126       **********************************************************************/
2127       case EAP_TYPE_GPSK:
2128         dissect_eap_gpsk(eap_tree, tvb, pinfo, offset, size);
2129         break; /* EAP_TYPE_GPSK */
2130 
2131       /*********************************************************************
2132       **********************************************************************/
2133       default:
2134         proto_tree_add_item(eap_tree, hf_eap_data, tvb, offset, size, ENC_NA);
2135         break;
2136         /*********************************************************************
2137         **********************************************************************/
2138       } /* switch (eap_type) */
2139 
2140     }
2141 
dissect_e1ap_Cause(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2142   } /* switch (eap_code) */
2143 
2144   return tvb_captured_length(tvb);
2145 }
2146 
2147 void
2148 proto_register_eap(void)
2149 {
2150   static hf_register_info hf[] = {
2151      { &hf_eap_code, {
2152       "Code", "eap.code",
dissect_e1ap_Cell_Group_ID(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2153       FT_UINT8, BASE_DEC, VALS(eap_code_vals), 0x0,
2154       NULL, HFILL }},
2155 
2156     { &hf_eap_identifier, {
2157       "Id", "eap.id",
2158       FT_UINT8, BASE_DEC, NULL, 0x0,
2159       NULL, HFILL }},
2160 
2161     { &hf_eap_len, {
2162       "Length", "eap.len",
2163       FT_UINT16, BASE_DEC, NULL, 0x0,
2164       NULL, HFILL }},
2165 
2166     { &hf_eap_type, {
2167       "Type", "eap.type",
2168       FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_type_vals_ext, 0x0,
2169       NULL, HFILL }},
dissect_e1ap_UL_Configuration(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2170 
2171     { &hf_eap_type_nak, {
2172       "Desired Auth Type", "eap.desired_type",
2173       FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_type_vals_ext, 0x0,
2174       NULL, HFILL }},
2175 
2176     { &hf_eap_identity, {
2177       "Identity", "eap.identity",
2178       FT_STRING, BASE_NONE, NULL, 0x0,
2179       NULL, HFILL }},
2180 
2181     { &hf_eap_identity_prefix, {
2182       "Identity Prefix", "eap.identity.prefix",
2183       FT_CHAR, BASE_HEX, NULL, 0x0,
2184       NULL, HFILL }},
2185 
dissect_e1ap_DL_TX_Stop(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2186     { &hf_eap_identity_type, {
2187       "Identity Type", "eap.identity.type",
2188       FT_STRING, BASE_NONE, NULL, 0x0,
2189       NULL, HFILL }},
2190 
2191     { &hf_eap_identity_full, {
2192       "Identity (Full)", "eap.identity.full",
2193       FT_STRING, BASE_NONE, NULL, 0x0,
2194       NULL, HFILL }},
2195 
2196     { &hf_eap_identity_mcc, {
2197       "Identity Mobile Country Code", "eap.identity.mcc",
2198       FT_UINT16, BASE_DEC|BASE_EXT_STRING, &E212_codes_ext, 0x0, NULL, HFILL }},
2199 
2200     { &hf_eap_identity_mcc_mnc_2digits, {
2201       "Identity Mobile Network Code", "eap.identity.mnc",
dissect_e1ap_RAT_Type(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2202       FT_UINT16, BASE_DEC|BASE_EXT_STRING, &mcc_mnc_2digits_codes_ext, 0x0, NULL, HFILL }},
2203 
2204     { &hf_eap_identity_mcc_mnc_3digits, {
2205       "Identity Mobile Network Code", "eap.identity.mnc",
2206       FT_UINT16, BASE_DEC|BASE_EXT_STRING, &mcc_mnc_3digits_codes_ext, 0x0, NULL, HFILL }},
2207 
2208     { &hf_eap_identity_padding, {
2209       "Padding", "eap.identity.padding",
2210       FT_BYTES, BASE_NONE, NULL, 0x0,
2211       NULL, HFILL }},
2212 
2213     { &hf_eap_identity_actual_len, {
2214       "Identity Actual Length", "eap.identity.actual_len",
2215       FT_UINT16, BASE_DEC, NULL, 0x0,
2216       NULL, HFILL }},
2217 
2218     { &hf_eap_notification, {
2219       "Notification", "eap.notification",
dissect_e1ap_Cell_Group_Information_Item(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2220       FT_STRING, BASE_NONE, NULL, 0x0,
2221       NULL, HFILL }},
2222 
2223     { &hf_eap_md5_value_size, {
2224       "EAP-MD5 Value-Size", "eap.md5.value_size",
2225       FT_UINT8, BASE_DEC, NULL, 0x0,
2226       NULL, HFILL }},
2227 
2228     { &hf_eap_md5_value, {
2229       "EAP-MD5 Value", "eap.md5.value",
2230       FT_BYTES, BASE_NONE, NULL, 0x0,
2231       NULL, HFILL }},
2232 
dissect_e1ap_Cell_Group_Information(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2233     { &hf_eap_md5_extra_data, {
2234       "EAP-MD5 Extra Data", "eap.md5.extra_data",
2235       FT_BYTES, BASE_NONE, NULL, 0x0,
2236       NULL, HFILL }},
2237 
2238     { &hf_eap_tls_flags, {
2239       "EAP-TLS Flags", "eap.tls.flags",
2240       FT_UINT8, BASE_HEX, NULL, 0x0,
2241       NULL, HFILL }},
2242 
2243     { &hf_eap_tls_flag_l, {
2244       "Length Included", "eap.tls.flags.len_included",
2245       FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_L,
2246       NULL, HFILL }},
2247 
2248     { &hf_eap_tls_flag_m, {
dissect_e1ap_CHOInitiation(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2249       "More Fragments", "eap.tls.flags.more_fragments",
2250       FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_M,
2251       NULL, HFILL }},
2252 
2253     { &hf_eap_tls_flag_s, {
2254       "Start", "eap.tls.flags.start",
2255       FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_S,
2256       NULL, HFILL }},
2257 
2258     { &hf_eap_tls_flags_version, {
dissect_e1ap_Number_of_tunnels(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2259       "Version", "eap.tls.flags.version",
2260       FT_UINT8, BASE_DEC, NULL, EAP_TLS_FLAGS_VERSION,
2261       NULL, HFILL }},
2262 
2263     { &hf_eap_tls_len, {
2264       "EAP-TLS Length", "eap.tls.len",
2265       FT_UINT32, BASE_DEC, NULL, 0x0,
2266       NULL, HFILL }},
2267 
2268     { &hf_eap_tls_fragment, {
2269       "EAP-TLS Fragment", "eap.tls.fragment",
2270       FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2271       NULL, HFILL }},
2272 
2273     { &hf_eap_tls_fragments, {
2274       "EAP-TLS Fragments", "eap.tls.fragments",
2275       FT_NONE, BASE_NONE, NULL, 0x0,
2276       NULL, HFILL }},
dissect_e1ap_CipheringAlgorithm(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2277 
2278     { &hf_eap_tls_fragment_overlap, {
2279       "Fragment Overlap", "eap.tls.fragment.overlap",
2280       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2281       "Fragment overlaps with other fragments", HFILL }},
2282 
2283     { &hf_eap_tls_fragment_overlap_conflict, {
2284       "Conflicting Data In Fragment Overlap", "eap.tls.fragment.overlap_conflict",
2285       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2286       "Overlapping fragments contained conflicting data", HFILL }},
2287 
2288     { &hf_eap_tls_fragment_multiple_tails, {
2289       "Multiple Tail Fragments Found", "eap.tls.fragment.multiple_tails",
2290       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2291       "Several tails were found when defragmenting the packet", HFILL }},
2292 
2293     { &hf_eap_tls_fragment_too_long_fragment,{
dissect_e1ap_CNSupport(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2294       "Fragment Too Long", "eap.tls.fragment.fragment.too_long",
2295       FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2296       "Fragment contained data past end of packet", HFILL }},
2297 
2298     { &hf_eap_tls_fragment_error, {
2299       "Defragmentation Error", "eap.tls.fragment.error",
2300       FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2301       "Defragmentation error due to illegal fragments", HFILL }},
2302 
2303     { &hf_eap_tls_fragment_count, {
dissect_e1ap_CommonNetworkInstance(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2304       "Fragment Count", "eap.tls.fragment.count",
2305       FT_UINT32, BASE_DEC, NULL, 0x0,
2306       "Total length of the reassembled payload", HFILL }},
2307 
2308     { &hf_eap_tls_reassembled_length, {
2309       "Reassembled EAP-TLS Length", "eap.tls.reassembled.len",
2310       FT_UINT32, BASE_DEC, NULL, 0x0,
2311       "Total length of the reassembled payload", HFILL }},
2312 
2313     { &hf_eap_sim_subtype, {
2314       "EAP-SIM Subtype", "eap.sim.subtype",
2315       FT_UINT8, BASE_DEC, VALS(eap_sim_subtype_vals), 0x0,
2316       NULL, HFILL }},
2317 
2318     { &hf_eap_sim_reserved, {
2319       "EAP-SIM Reserved", "eap.sim.reserved",
2320       FT_UINT16, BASE_HEX, NULL, 0x0,
dissect_e1ap_ConfidentialityProtectionIndication(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2321       NULL, HFILL }},
2322 
2323     { &hf_eap_sim_subtype_attribute, {
2324       "EAP-SIM Attribute", "eap.sim.subtype.attribute",
2325       FT_NONE, BASE_NONE, NULL, 0x0,
2326       NULL, HFILL }},
2327 
2328     { &hf_eap_sim_subtype_type, {
2329       "EAP-SIM Type", "eap.sim.subtype.type",
2330       FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_sim_aka_attribute_vals_ext, 0x0,
2331       NULL, HFILL }},
2332 
2333     { &hf_eap_sim_subtype_length, {
2334       "EAP-SIM Length", "eap.sim.subtype.len",
2335       FT_UINT8, BASE_DEC, NULL, 0x0,
2336       NULL, HFILL }},
dissect_e1ap_ConfidentialityProtectionResult(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2337 
2338     { &hf_eap_sim_notification_type, {
2339       "EAP-SIM Notification Type", "eap.sim.notification_type",
2340       FT_UINT16, BASE_DEC, VALS(eap_sim_aka_notification_vals), 0x0,
2341       NULL, HFILL }},
2342 
2343     { &hf_eap_sim_error_code_type, {
2344       "EAP-SIM Error Code", "eap.sim.error_code",
2345       FT_UINT16, BASE_DEC, VALS(eap_sim_aka_client_error_codes), 0x0,
2346       NULL, HFILL }},
dissect_e1ap_TransportLayerAddress(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2347 
2348     { &hf_eap_sim_subtype_value, {
2349       "EAP-SIM Value", "eap.sim.subtype.value",
2350       FT_BYTES, BASE_NONE, NULL, 0x0,
2351       NULL, HFILL }},
2352 
2353     { &hf_eap_aka_subtype, {
2354       "EAP-AKA Subtype", "eap.aka.subtype",
2355       FT_UINT8, BASE_DEC, VALS(eap_aka_subtype_vals), 0x0,
2356       NULL, HFILL }},
2357 
2358     { &hf_eap_aka_reserved, {
2359       "EAP-AKA Reserved", "eap.aka.reserved",
2360       FT_UINT16, BASE_HEX, NULL, 0x0,
2361       NULL, HFILL }},
2362 
2363     { &hf_eap_aka_subtype_attribute, {
2364       "EAP-AKA Attribute", "eap.aka.subtype.attribute",
2365       FT_NONE, BASE_NONE, NULL, 0x0,
2366       NULL, HFILL }},
2367 
2368     { &hf_eap_aka_subtype_type, {
2369       "EAP-AKA Type", "eap.aka.subtype.type",
2370       FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_sim_aka_attribute_vals_ext, 0x0,
2371       NULL, HFILL }},
2372 
2373     { &hf_eap_aka_subtype_length, {
2374       "EAP-AKA Length", "eap.aka.subtype.len",
2375       FT_UINT8, BASE_DEC, NULL, 0x0,
2376       NULL, HFILL }},
2377 
2378     { &hf_eap_aka_notification_type, {
2379       "EAP-AKA Notification Type", "eap.aka.notification_type",
2380       FT_UINT16, BASE_DEC, VALS(eap_sim_aka_notification_vals), 0x0,
2381       NULL, HFILL }},
2382 
2383     { &hf_eap_aka_error_code_type, {
2384       "EAP-AKA Error Code", "eap.aka.error_code",
2385       FT_UINT16, BASE_DEC, VALS(eap_sim_aka_client_error_codes), 0x0,
2386       NULL, HFILL }},
2387 
2388     { &hf_eap_aka_subtype_value, {
2389       "EAP-AKA Value", "eap.aka.subtype.value",
2390       FT_BYTES, BASE_NONE, NULL, 0x0,
2391       NULL, HFILL }},
dissect_e1ap_CP_TNL_Information(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2392 
2393     { &hf_eap_leap_version, {
2394       "EAP-LEAP Version", "eap.leap.version",
2395       FT_UINT8, BASE_DEC, NULL, 0x0,
2396       NULL, HFILL }},
2397 
2398     { &hf_eap_leap_reserved, {
2399       "EAP-LEAP Reserved", "eap.leap.reserved",
2400       FT_UINT8, BASE_HEX, NULL, 0x0,
2401       NULL, HFILL }},
2402 
dissect_e1ap_TransactionID(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2403     { &hf_eap_leap_count, {
2404       "EAP-LEAP Count", "eap.leap.count",
2405       FT_UINT8, BASE_DEC, NULL, 0x0,
2406       NULL, HFILL }},
2407 
2408     { &hf_eap_leap_peer_challenge, {
2409       "EAP-LEAP Peer-Challenge", "eap.leap.peer_challenge",
2410       FT_BYTES, BASE_NONE, NULL, 0x0,
2411       NULL, HFILL }},
2412 
2413     { &hf_eap_leap_peer_response, {
2414       "EAP-LEAP Peer-Response", "eap.leap.peer_response",
2415       FT_BYTES, BASE_NONE, NULL, 0x0,
2416       NULL, HFILL }},
2417 
2418     { &hf_eap_leap_ap_challenge, {
dissect_e1ap_TypeOfError(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2419       "EAP-LEAP AP-Challenge", "eap.leap.ap_challenge",
2420       FT_BYTES, BASE_NONE, NULL, 0x0,
2421       NULL, HFILL }},
2422 
2423     { &hf_eap_leap_ap_response, {
2424       "EAP-LEAP AP-Response", "eap.leap.ap_response",
2425       FT_BYTES, BASE_NONE, NULL, 0x0,
2426       NULL, HFILL }},
2427 
2428     { &hf_eap_leap_data, {
2429       "EAP-LEAP Data", "eap.leap.data",
2430       FT_BYTES, BASE_NONE, NULL, 0x0,
2431       NULL, HFILL }},
2432 
2433     { &hf_eap_leap_name, {
2434       "EAP-LEAP Name", "eap.leap.name",
2435       FT_STRING, BASE_NONE, NULL, 0x0,
dissect_e1ap_CriticalityDiagnostics_IE_List_item(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2436       NULL, HFILL }},
2437 
2438     { &hf_eap_ms_chap_v2_opcode, {
2439       "EAP-MS-CHAP-v2 OpCode", "eap.ms_chap_v2.opcode",
2440       FT_UINT8, BASE_DEC, VALS(eap_ms_chap_v2_opcode_vals), 0x0,
2441       NULL, HFILL }},
2442 
2443     { &hf_eap_ms_chap_v2_id, {
2444       "EAP-MS-CHAP-v2 Id", "eap.ms_chap_v2.id",
2445       FT_UINT8, BASE_DEC, NULL, 0x0,
2446       NULL, HFILL }},
2447 
2448     { &hf_eap_ms_chap_v2_length, {
dissect_e1ap_CriticalityDiagnostics_IE_List(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2449       "EAP-MS-CHAP-v2 Length", "eap.ms_chap_v2.length",
2450       FT_UINT16, BASE_DEC, NULL, 0x0,
2451       NULL, HFILL }},
2452 
2453     { &hf_eap_ms_chap_v2_value_size, {
2454       "EAP-MS-CHAP-v2 Value-Size", "eap.ms_chap_v2.value_size",
2455       FT_UINT8, BASE_DEC, NULL, 0x0,
2456       NULL, HFILL }},
2457 
2458     { &hf_eap_ms_chap_v2_challenge, {
2459       "EAP-MS-CHAP-v2 Challenge", "eap.ms_chap_v2.challenge",
2460       FT_BYTES, BASE_NONE, NULL, 0x0,
2461       NULL, HFILL }},
2462 
2463     { &hf_eap_ms_chap_v2_name, {
2464       "EAP-MS-CHAP-v2 Name", "eap.ms_chap_v2.name",
2465       FT_STRING, BASE_NONE, NULL, 0x0,
2466       NULL, HFILL }},
2467 
2468     { &hf_eap_ms_chap_v2_peer_challenge, {
dissect_e1ap_CriticalityDiagnostics(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2469       "EAP-MS-CHAP-v2 Peer-Challenge", "eap.ms_chap_v2.peer_challenge",
2470       FT_BYTES, BASE_NONE, NULL, 0x0,
2471       NULL, HFILL }},
2472 
2473     { &hf_eap_ms_chap_v2_reserved, {
2474       "EAP-MS-CHAP-v2 Reserved", "eap.ms_chap_v2.reserved",
2475       FT_BYTES, BASE_NONE, NULL, 0x0,
2476       NULL, HFILL }},
2477 
2478     { &hf_eap_ms_chap_v2_nt_response, {
2479       "EAP-MS-CHAP-v2 NT-Response", "eap.ms_chap_v2.nt_response",
2480       FT_BYTES, BASE_NONE, NULL, 0x0,
2481       NULL, HFILL }},
2482 
2483     { &hf_eap_ms_chap_v2_flags, {
dissect_e1ap_T_dapsIndicator(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2484       "EAP-MS-CHAP-v2 Flags", "eap.ms_chap_v2.flags",
2485       FT_UINT8, BASE_HEX, NULL, 0x0,
2486       NULL, HFILL }},
2487 
2488     { &hf_eap_ms_chap_v2_response, {
2489       "EAP-MS-CHAP-v2 Response (Unknown Length)", "eap.ms_chap_v2.response",
2490       FT_BYTES, BASE_NONE, NULL, 0x0,
2491       NULL, HFILL }},
2492 
2493     { &hf_eap_ms_chap_v2_message, {
2494       "EAP-MS-CHAP-v2 Message", "eap.ms_chap_v2.message",
2495       FT_STRING, BASE_NONE, NULL, 0x0,
2496       NULL, HFILL }},
2497 
2498     { &hf_eap_ms_chap_v2_failure_request, {
dissect_e1ap_DAPSRequestInfo(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2499       "EAP-MS-CHAP-v2 Failure-Request", "eap.ms_chap_v2.failure_request",
2500       FT_STRING, BASE_NONE, NULL, 0x0,
2501       NULL, HFILL }},
2502 
2503     { &hf_eap_ms_chap_v2_data, {
2504       "EAP-MS-CHAP-v2 Data", "eap.ms_chap_v2.data",
2505       FT_BYTES, BASE_NONE, NULL, 0x0,
2506       NULL, HFILL }},
2507 
2508     { &hf_eap_pax_opcode, {
2509       "EAP-PAX OP-Code", "eap.pax.opcode",
2510       FT_UINT8, BASE_HEX, VALS(eap_pax_opcode_vals), 0x0,
2511       NULL, HFILL }},
2512 
2513     { &hf_eap_pax_flags, {
2514       "EAP-PAX Flags", "eap.pax.flags",
2515       FT_UINT8, BASE_HEX, NULL, 0x0,
dissect_e1ap_Data_Forwarding_Request(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2516       NULL, HFILL }},
2517 
2518     { &hf_eap_pax_flags_mf, {
2519       "more fragments", "eap.pax.flags.mf",
2520       FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_MF,
2521       NULL, HFILL }},
2522 
2523     { &hf_eap_pax_flags_ce, {
2524       "certificate enabled", "eap.pax.flags.ce",
2525       FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_CE,
dissect_e1ap_QoS_Flow_Identifier(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2526       NULL, HFILL }},
2527 
2528     { &hf_eap_pax_flags_ai, {
2529       "ADE Included", "eap.pax.flags.ai",
2530       FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_AI,
2531       NULL, HFILL }},
2532 
2533     { &hf_eap_pax_flags_reserved, {
2534       "reserved", "eap.pax.flags.reserved",
2535       FT_BOOLEAN, 8, NULL, EAP_PAX_FLAG_RESERVED,
2536       NULL, HFILL }},
2537 
2538      { &hf_eap_pax_mac_id, {
2539       "EAP-PAX MAC ID", "eap.pax.mac_id",
2540       FT_UINT8, BASE_HEX, VALS(eap_pax_mac_id_vals), 0x0,
2541       NULL, HFILL }},
dissect_e1ap_QoS_Flow_Mapping_Indication(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2542 
2543      { &hf_eap_pax_dh_group_id, {
2544       "EAP-PAX DH Group ID", "eap.pax.dh_group_id",
2545       FT_UINT8, BASE_HEX, VALS(eap_pax_dh_group_id_vals), 0x0,
2546       NULL, HFILL }},
2547 
2548      { &hf_eap_pax_public_key_id, {
2549       "EAP-PAX Public Key ID", "eap.pax.public_key_id",
2550       FT_UINT8, BASE_HEX, VALS(eap_pax_public_key_id_vals), 0x0,
2551       NULL, HFILL }},
2552 
2553      { &hf_eap_pax_a_len, {
2554       "EAP-PAX A len", "eap.pax.a.len",
2555       FT_UINT16, BASE_DEC, NULL, 0x0,
2556       NULL, HFILL }},
2557 
dissect_e1ap_QoS_Flow_Mapping_Item(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2558      { &hf_eap_pax_a, {
2559       "EAP-PAX A", "eap.pax.a",
2560       FT_BYTES, BASE_NONE, NULL, 0x0,
2561       NULL, HFILL }},
2562 
2563      { &hf_eap_pax_b_len, {
2564       "EAP-PAX B len", "eap.pax.b.len",
2565       FT_UINT16, BASE_DEC, NULL, 0x0,
2566       NULL, HFILL }},
2567 
2568      { &hf_eap_pax_b, {
2569       "EAP-PAX B", "eap.pax.b",
2570       FT_BYTES, BASE_NONE, NULL, 0x0,
dissect_e1ap_QoS_Flow_Mapping_List(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2571       NULL, HFILL }},
2572 
2573      { &hf_eap_pax_cid_len, {
2574       "EAP-PAX CID len", "eap.pax.cid.len",
2575       FT_UINT16, BASE_DEC, NULL, 0x0,
2576       NULL, HFILL }},
2577 
2578      { &hf_eap_pax_cid, {
2579       "EAP-PAX CID", "eap.pax.cid",
2580       FT_STRING, BASE_NONE, NULL, 0x0,
2581       NULL, HFILL }},
2582 
2583      { &hf_eap_pax_mac_ck_len, {
2584       "EAP-PAX MAC_CK len", "eap.pax.mac_ck.len",
2585       FT_UINT16, BASE_DEC, NULL, 0x0,
2586       NULL, HFILL }},
2587 
dissect_e1ap_Data_Forwarding_Information_Request(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2588      { &hf_eap_pax_mac_ck, {
2589       "EAP-PAX MAC_CK", "eap.pax.mac_ck",
2590       FT_BYTES, BASE_NONE, NULL, 0x0,
2591       NULL, HFILL }},
2592 
2593      { &hf_eap_pax_ade_len, {
2594       "EAP-PAX ADE len", "eap.pax.ade.len",
2595       FT_UINT16, BASE_DEC, NULL, 0x0,
2596       NULL, HFILL }},
2597 
dissect_e1ap_GTP_TEID(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2598      { &hf_eap_pax_ade, {
2599       "EAP-PAX ADE", "eap.pax.ade",
2600       FT_BYTES, BASE_NONE, NULL, 0x0,
2601       NULL, HFILL }},
2602 
2603      { &hf_eap_pax_mac_icv, {
2604       "EAP-PAX ICV", "eap.pax.icv",
2605       FT_BYTES, BASE_NONE, NULL, 0x0,
2606       NULL, HFILL }},
2607 
2608     { &hf_eap_psk_flags, {
2609       "EAP-PSK Flags", "eap.psk.flags",
2610       FT_UINT8, BASE_HEX, NULL, 0x0,
2611       NULL, HFILL }},
2612 
2613     { &hf_eap_psk_flags_t, {
dissect_e1ap_GTPTunnel(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2614       "T", "eap.psk.flags.t",
2615       FT_UINT8, BASE_HEX, NULL, EAP_PSK_FLAGS_T_MASK,
2616       NULL, HFILL }},
2617 
2618     { &hf_eap_psk_flags_reserved, {
2619       "Reserved", "eap.psk.flags.reserved",
2620        FT_UINT8, BASE_HEX, NULL, 0x3F,
2621       NULL, HFILL }},
2622 
2623     { &hf_eap_psk_rand_p, {
2624       "EAP-PSK RAND_P", "eap.psk.rand_p",
2625       FT_BYTES, BASE_NONE, NULL, 0x0,
2626       NULL, HFILL }},
2627 
2628     { &hf_eap_psk_rand_s, {
2629       "EAP-PSK RAND_S", "eap.psk.rand_s",
2630       FT_BYTES, BASE_NONE, NULL, 0x0,
2631       NULL, HFILL }},
2632 
2633     { &hf_eap_psk_mac_p, {
2634       "EAP-PSK MAC_P", "eap.psk.mac_p",
dissect_e1ap_UP_TNL_Information(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2635       FT_BYTES, BASE_NONE, NULL, 0x0,
2636       NULL, HFILL }},
2637 
2638     { &hf_eap_psk_mac_s, {
2639       "EAP-PSK MAC_S", "eap.psk.mac_s",
2640       FT_BYTES, BASE_NONE, NULL, 0x0,
2641       NULL, HFILL }},
2642 
2643     { &hf_eap_psk_id_p, {
2644       "EAP-PSK ID_P", "eap.psk.id_p",
2645       FT_STRING, BASE_NONE, NULL, 0x0,
2646       NULL, HFILL }},
2647 
2648     { &hf_eap_psk_id_s, {
2649       "EAP-PSK ID_S", "eap.psk.id_s",
2650       FT_STRING, BASE_NONE, NULL, 0x0,
2651       NULL, HFILL }},
dissect_e1ap_Data_Forwarding_Information(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2652 
2653     { &hf_eap_psk_pchannel, {
2654       "EAP-PSK Protected Channel (encrypted)", "eap.psk.pchannel",
2655       FT_BYTES, BASE_NONE, NULL, 0x0,
2656       NULL, HFILL }},
2657 
2658     { &hf_eap_sake_version, {
2659       "EAP-SAKE Version", "eap.sake.version",
2660       FT_UINT8, BASE_HEX, NULL, 0x0,
2661       NULL, HFILL }},
2662 
2663     { &hf_eap_sake_session_id, {
2664       "EAP-SAKE Session ID", "eap.sake.session_id",
2665       FT_UINT8, BASE_HEX, NULL, 0x0,
2666       NULL, HFILL }},
dissect_e1ap_QoS_Flows_to_be_forwarded_Item(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2667 
2668      { &hf_eap_sake_subtype, {
2669       "EAP-SAKE Subtype", "eap.sake.subtype",
2670       FT_UINT8, BASE_HEX, VALS(eap_sake_subtype_vals), 0x0,
2671       NULL, HFILL }},
2672 
2673      { &hf_eap_sake_attr_type, {
2674       "Attribute Type", "eap.sake.attr.type",
2675       FT_UINT8, BASE_HEX, VALS(eap_sake_attr_type_vals), 0x0,
2676       NULL, HFILL }},
2677 
2678     { &hf_eap_sake_attr_len, {
2679       "Attribute Length", "eap.sake.attr.len",
dissect_e1ap_QoS_Flows_to_be_forwarded_List(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2680       FT_UINT8, BASE_DEC, NULL, 0x0,
2681       NULL, HFILL }},
2682 
2683     { &hf_eap_sake_attr_value, {
2684       "Attribute Value", "eap.sake.attr.val",
2685       FT_BYTES, BASE_NONE, NULL, 0x0,
2686       NULL, HFILL }},
2687 
2688     { &hf_eap_sake_attr_value_str, {
2689       "Attribute Value", "eap.sake.attr.val_str",
2690       FT_STRING, BASE_NONE, NULL, 0x0,
2691       NULL, HFILL }},
2692 
2693     { &hf_eap_sake_attr_value_uint48, {
2694       "Attribute Value", "eap.sake.attr.val_uint48",
2695       FT_UINT48, BASE_DEC, NULL, 0x0,
2696       NULL, HFILL }},
dissect_e1ap_DataForwardingtoE_UTRANInformationListItem(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2697 
2698      { &hf_eap_gpsk_opcode, {
2699       "EAP-GPSK OP-Code", "eap.gpsk.opcode",
2700       FT_UINT8, BASE_HEX, VALS(eap_gpsk_opcode_vals), 0x0,
2701       NULL, HFILL }},
2702 
2703     { &hf_eap_gpsk_id_server_len, {
2704       "EAP-GPSK ID_Server len", "eap.gpsk.id_server.len",
2705       FT_UINT16, BASE_DEC, NULL, 0x0,
2706       NULL, HFILL }},
2707 
2708     { &hf_eap_gpsk_id_server, {
2709       "EAP-GPSK ID_Server", "eap.gpsk.id_server",
dissect_e1ap_DataForwardingtoE_UTRANInformationList(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2710       FT_STRING, BASE_NONE, NULL, 0x0,
2711       NULL, HFILL }},
2712 
2713     { &hf_eap_gpsk_id_peer_len, {
2714       "EAP-GPSK ID_Peer len", "eap.gpsk.id_peer.len",
2715       FT_UINT16, BASE_DEC, NULL, 0x0,
2716       NULL, HFILL }},
2717 
2718     { &hf_eap_gpsk_id_peer, {
2719       "EAP-GPSK ID_Peer", "eap.gpsk.id_peer",
2720       FT_STRING, BASE_NONE, NULL, 0x0,
2721       NULL, HFILL }},
2722 
2723     { &hf_eap_gpsk_rand_server, {
2724       "EAP-GPSK Rand_Server", "eap.gpsk.rand_server",
2725       FT_BYTES, BASE_NONE, NULL, 0x0,
2726       NULL, HFILL }},
dissect_e1ap_T_secondaryRATType(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2727 
2728     { &hf_eap_gpsk_rand_peer, {
2729       "EAP-GPSK Rand_Peer", "eap.gpsk.rand_peer",
2730       FT_BYTES, BASE_NONE, NULL, 0x0,
2731       NULL, HFILL }},
2732 
2733     { &hf_eap_gpsk_csuite_list_len, {
2734       "Len", "eap.gpsk.csuite_list_len",
2735       FT_UINT16, BASE_DEC, NULL, 0x0,
2736       NULL, HFILL }},
dissect_e1ap_T_startTimeStamp_01(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2737 
2738     { &hf_eap_gpsk_csuite_vendor, {
2739       "Vendor", "eap.gpsk.csuite.vendor",
2740       FT_UINT32, BASE_HEX, NULL, 0x0,
2741       NULL, HFILL }},
2742 
2743     { &hf_eap_gpsk_csuite_specifier, {
2744       "Specifier", "eap.gpsk.csuite.specifier",
2745       FT_UINT16, BASE_HEX, NULL, 0x0,
2746       NULL, HFILL }},
2747 
2748     { &hf_eap_gpsk_pd_payload_len, {
2749       "EAP-GPSK PD_Payload len", "eap.gpsk.pd_payload.len",
2750       FT_UINT16, BASE_DEC, NULL, 0x0,
2751       NULL, HFILL }},
2752 
2753     { &hf_eap_gpsk_pd_payload, {
2754       "EAP-GPSK PD_Payload", "eap.gpsk.pd_payload",
2755       FT_BYTES, BASE_NONE, NULL, 0x0,
2756       NULL, HFILL }},
2757 
dissect_e1ap_T_endTimeStamp_01(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2758     { &hf_eap_gpsk_payload_mac, {
2759       "EAP-GPSK Payload MAC", "eap.gpsk.payload_mac",
2760       FT_BYTES, BASE_NONE, NULL, 0x0,
2761       NULL, HFILL }},
2762 
2763      { &hf_eap_gpsk_failure_code, {
2764       "EAP-GPSK Failure code", "eap.gpsk.failure_code",
2765       FT_UINT32, BASE_HEX, VALS(eap_gpsk_failure_code_vals), 0x0,
2766       NULL, HFILL }},
2767 
2768     { &hf_eap_data, {
2769       "EAP Data", "eap.data",
2770       FT_BYTES, BASE_NONE, NULL, 0x0,
2771       NULL, HFILL }},
2772 
2773     { &hf_eap_fast_type, {
2774       "EAP-FAST Type", "eap.fast.type",
2775       FT_UINT16, BASE_DEC, NULL, 0x0,
2776       NULL, HFILL }},
2777 
2778     { &hf_eap_fast_length, {
dissect_e1ap_INTEGER_0_18446744073709551615(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2779       "EAP-FAST Length", "eap.fast.length",
2780       FT_UINT16, BASE_DEC, NULL, 0x0,
2781       NULL, HFILL }},
2782 
2783     { &hf_eap_fast_aidd, {
2784       "Authority ID Data", "eap.fast.authority_id_data",
2785       FT_BYTES, BASE_NONE, NULL, 0x0,
2786       NULL, HFILL }},
2787 
2788     /* Expanded type fields */
2789     { &hf_eap_ext_vendor_id, {
2790       "EAP-EXT Vendor Id", "eap.ext.vendor_id",
2791       FT_UINT16, BASE_HEX, VALS(eap_ext_vendor_id_vals), 0x0,
2792       NULL, HFILL }},
2793 
2794     { &hf_eap_ext_vendor_type, {
2795       "EAP-EXT Vendor Type", "eap.ext.vendor_type",
2796       FT_UINT8, BASE_HEX, VALS(eap_ext_vendor_type_vals), 0x0,
dissect_e1ap_MRDC_Data_Usage_Report_Item(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2797       NULL, HFILL }}
2798   };
2799   static gint *ett[] = {
2800     &ett_eap,
2801     &ett_eap_pax_flags,
2802     &ett_eap_psk_flags,
2803     &ett_eap_gpsk_csuite_list,
2804     &ett_eap_gpsk_csuite,
2805     &ett_eap_gpsk_csuite_sel,
2806     &ett_eap_sake_attr,
2807     &ett_eap_tls_fragment,
2808     &ett_eap_tls_fragments,
2809     &ett_eap_sim_attr,
dissect_e1ap_SEQUENCE_SIZE_1_maxnooftimeperiods_OF_MRDC_Data_Usage_Report_Item(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2810     &ett_eap_aka_attr,
2811     &ett_eap_exp_attr,
2812     &ett_eap_tls_flags,
2813     &ett_identity
2814   };
2815   static ei_register_info ei[] = {
2816      { &ei_eap_ms_chap_v2_length, { "eap.ms_chap_v2.length.invalid", PI_PROTOCOL, PI_WARN, "Invalid Length", EXPFILL }},
2817      { &ei_eap_mitm_attacks, { "eap.mitm_attacks", PI_SECURITY, PI_WARN, "Vulnerable to MITM attacks. If possible, change EAP type.", EXPFILL }},
2818      { &ei_eap_md5_value_size_overflow, { "eap.md5.value_size.overflow", PI_PROTOCOL, PI_WARN, "Overflow", EXPFILL }},
2819      { &ei_eap_dictionary_attacks, { "eap.dictionary_attacks", PI_SECURITY, PI_WARN,
2820                                "Vulnerable to dictionary attacks. If possible, change EAP type."
2821                                " See http://www.cisco.com/warp/public/cc/pd/witc/ao350ap/prodlit/2331_pp.pdf", EXPFILL }},
2822      { &ei_eap_identity_invalid, { "eap.identity.invalid", PI_PROTOCOL, PI_WARN, "Invalid identity code", EXPFILL }},
2823      { &ei_eap_retransmission, { "eap.retransmission", PI_SEQUENCE, PI_NOTE, "This packet is a retransmission", EXPFILL }},
2824      { &ei_eap_bad_length, { "eap.bad_length", PI_PROTOCOL, PI_WARN, "Bad length (too small or too large)", EXPFILL }},
2825   };
2826 
dissect_e1ap_Data_Usage_per_PDU_Session_Report(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2827   expert_module_t* expert_eap;
2828 
2829   proto_eap = proto_register_protocol("Extensible Authentication Protocol",
2830                                       "EAP", "eap");
2831   proto_register_field_array(proto_eap, hf, array_length(hf));
2832   proto_register_subtree_array(ett, array_length(ett));
2833   expert_eap = expert_register_protocol(proto_eap);
2834   expert_register_field_array(expert_eap, ei, array_length(ei));
2835 
2836   eap_handle = register_dissector("eap", dissect_eap, proto_eap);
2837 
2838   reassembly_table_register(&eap_tls_reassembly_table,
2839                         &addresses_reassembly_table_functions);
2840 
2841   eap_expanded_type_dissector_table = register_dissector_table("eap.ext.vendor_id",
2842     "EAP-EXT Vendor Id",
dissect_e1ap_T_secondaryRATType_01(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2843     proto_eap, FT_UINT24,
2844     BASE_HEX);
2845 
2846 }
2847 
2848 void
2849 proto_reg_handoff_eap(void)
2850 {
2851   /*
2852    * Get a handle for the SSL/TLS dissector.
2853    */
2854   tls_handle = find_dissector_add_dependency("tls", proto_eap);
2855   diameter_avps_handle = find_dissector_add_dependency("diameter_avps", proto_eap);
2856   teap_handle = find_dissector_add_dependency("teap", proto_eap);
2857 
2858   dissector_add_uint("ppp.protocol", PPP_EAP, eap_handle);
2859   dissector_add_uint("eapol.type", EAPOL_EAP, eap_handle);
dissect_e1ap_Data_Usage_per_QoS_Flow_Item(tvbuff_t * tvb _U_,int offset _U_,asn1_ctx_t * actx _U_,proto_tree * tree _U_,int hf_index _U_)2860 }
2861 /*
2862  * Editor modelines
2863  *
2864  * Local Variables:
2865  * c-basic-offset: 2
2866  * tab-width: 8
2867  * indent-tabs-mode: nil
2868  * End:
2869  *
2870  * ex: set shiftwidth=2 tabstop=8 expandtab:
2871  * :indentSize=2:tabSize=8:noTabs=true:
2872  */
2873