FIXUP: WIP: verification_trailer
[wireshark-wip.git] / epan / dissectors / packet-eap.c
blobedb1584bff6c0b0687b352a49b9e03923fc27077
1 /* packet-eap.c
2 * Routines for EAP Extensible Authentication Protocol dissection
3 * RFC 2284, RFC 3748
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <glib.h>
29 #include <epan/packet.h>
30 #include <epan/conversation.h>
31 #include <epan/ppptypes.h>
32 #include <epan/reassemble.h>
33 #include <epan/wmem/wmem.h>
34 #include <epan/eap.h>
35 #include <epan/expert.h>
37 #include "packet-wps.h"
39 void proto_register_eap(void);
40 void proto_reg_handoff_eap(void);
42 static int proto_eap = -1;
43 static int hf_eap_code = -1;
44 static int hf_eap_identifier = -1;
45 static int hf_eap_len = -1;
46 static int hf_eap_type = -1;
47 static int hf_eap_type_nak = -1;
49 static int hf_eap_identity = -1;
51 static int hf_eap_notification = -1;
53 static int hf_eap_md5_value_size = -1;
54 static int hf_eap_md5_value = -1;
55 static int hf_eap_md5_extra_data = -1;
57 static int hf_eap_sim_subtype = -1;
58 static int hf_eap_sim_reserved = -1;
59 static int hf_eap_sim_subtype_attribute = -1;
60 static int hf_eap_sim_subtype_type = -1;
61 static int hf_eap_sim_subtype_length = -1;
62 static int hf_eap_sim_subtype_value = -1;
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_subtype_value = -1;
71 static int hf_eap_leap_version = -1;
72 static int hf_eap_leap_reserved = -1;
73 static int hf_eap_leap_count = -1;
74 static int hf_eap_leap_peer_challenge = -1;
75 static int hf_eap_leap_peer_response = -1;
76 static int hf_eap_leap_ap_challenge = -1;
77 static int hf_eap_leap_ap_response = -1;
78 static int hf_eap_leap_name = -1;
80 static int hf_eap_ms_chap_v2_opcode = -1;
81 static int hf_eap_ms_chap_v2_id = -1;
82 static int hf_eap_ms_chap_v2_length = -1;
83 static int hf_eap_ms_chap_v2_value_size = -1;
84 static int hf_eap_ms_chap_v2_challenge = -1;
85 static int hf_eap_ms_chap_v2_name = -1;
86 static int hf_eap_ms_chap_v2_peer_challenge = -1;
87 static int hf_eap_ms_chap_v2_reserved = -1;
88 static int hf_eap_ms_chap_v2_nt_response = -1;
89 static int hf_eap_ms_chap_v2_flags = -1;
90 static int hf_eap_ms_chap_v2_message = -1;
91 static int hf_eap_ms_chap_v2_failure_request = -1;
93 static gint ett_eap = -1;
95 static expert_field ei_eap_ms_chap_v2_length = EI_INIT;
96 static expert_field ei_eap_mitm_attacks = EI_INIT;
97 static expert_field ei_eap_md5_value_size_overflow = EI_INIT;
98 static expert_field ei_eap_dictionary_attacks = EI_INIT;
100 static dissector_handle_t eap_handle;
102 static dissector_handle_t ssl_handle;
104 const value_string eap_code_vals[] = {
105 { EAP_REQUEST, "Request" },
106 { EAP_RESPONSE, "Response" },
107 { EAP_SUCCESS, "Success" },
108 { EAP_FAILURE, "Failure" },
109 { EAP_INITIATE, "Initiate" }, /* [RFC5296] */
110 { EAP_FINISH, "Finish" }, /* [RFC5296] */
111 { 0, NULL }
115 References:
116 1) http://www.iana.org/assignments/ppp-numbers PPP EAP REQUEST/RESPONSE TYPES
117 2) http://www.ietf.org/internet-drafts/draft-ietf-pppext-rfc2284bis-02.txt
118 3) RFC2284
119 4) RFC3748
120 5) http://www.iana.org/assignments/eap-numbers EAP registry (updated 2011-02-22)
121 6) http://tools.ietf.org/html/draft-bersani-eap-synthesis-sharedkeymethods-00
124 static const value_string eap_type_vals[] = {
125 { 1, "Identity" },
126 { 2, "Notification" },
127 { 3, "Legacy Nak (Response Only)" },
128 { 4, "MD5-Challenge EAP (EAP-MD5-CHALLENGE)" },
129 { 5, "One-Time Password EAP (EAP-OTP)" },
130 { 6, "Generic Token Card EAP (EAP-GTC)" },
131 { 7, "Allocated" },
132 { 8, "Allocated" },
133 { 9, "RSA Public Key Authentication EAP (EAP-RSA-PKA)" },
134 { 10, "DSS Unilateral EAP (EAP-DSS)" },
135 { 11, "KEA EAP (EAP-KEA)" },
136 { 12, "KEA Validate EAP (EAP-KEA-VALIDATE)" },
137 { 13, "TLS EAP (EAP-TLS)" },
138 { 14, "Defender Token EAP (EAP-AXENT)" },
139 { 15, "RSA Security SecurID EAP (EAP-RSA-SECURID)" },
140 { 16, "Arcot Systems EAP (EAP-ARCOT-SYSTEMS)" },
141 { 17, "Cisco Wireless EAP / Lightweight EAP (EAP-LEAP)" },
142 { 18, "GSM Subscriber Identity Modules EAP (EAP-SIM)" },
143 { 19, "Secure Remote Password SHA1 Part 1 EAP (EAP-SRP-SHA1-PART1)" },
144 { 20, "Secure Remote Password SHA1 Part 2 EAP (EAP-SRP-SHA1-PART2)" },
145 { 21, "Tunneled TLS EAP (EAP-TTLS)" },
146 { 22, "Remote Access Service EAP (EAP-RAS)" },
147 { 23, "UMTS Authentication and Key Agreement EAP (EAP-AKA)" },
148 { 24, "3Com Wireless EAP (EAP-3COM-WIRELESS)" },
149 { 25, "Protected EAP (EAP-PEAP)" },
150 { 26, "MS-Authentication EAP (EAP-MS-AUTH)" },
151 { 27, "Mutual Authentication w/Key Exchange EAP (EAP-MAKE)" },
152 { 28, "CRYPTOCard EAP (EAP-CRYPTOCARD)" },
153 { 29, "MS-CHAP-v2 EAP (EAP-MS-CHAP-V2)" },
154 { 30, "DynamID EAP (EAP-DYNAMID)" },
155 { 31, "Rob EAP (EAP-ROB)" },
156 { 32, "Protected One-Time Password EAP (EAP-POTP)" },
157 { 33, "MS-Authentication TLV EAP (EAP-MS-AUTH-TLV)" },
158 { 34, "SentriNET (EAP-SENTRINET)" },
159 { 35, "Actiontec Wireless EAP (EAP-ACTIONTEC-WIRELESS)" },
160 { 36, "Cogent Systems Biometrics Authentication EAP (EAP-COGENT-BIOMETRIC)" },
161 { 37, "AirFortress EAP (EAP-AIRFORTRESS)" },
162 { 38, "HTTP Digest EAP (EAP-HTTP-DIGEST)" },
163 { 39, "SecureSuite EAP (EAP-SECURESUITE)" },
164 { 40, "DeviceConnect EAP (EAP-DEVICECONNECT)" },
165 { 41, "Simple Password Exponential Key Exchange EAP (EAP-SPEKE)" },
166 { 42, "MOBAC EAP (EAP-MOBAC)" },
167 { 43, "Flexible Authentication via Secure Tunneling EAP (EAP-FAST)" },
168 { 44, "ZoneLabs EAP (EAP-ZLXEAP)" },
169 { 45, "Link EAP (EAP-LINK)" },
170 { 46, "Password Authenticated eXchange EAP (EAP-PAX)" },
171 { 47, "Pre-Shared Key EAP (EAP-PSK)" },
172 { 48, "Shared-secret Authentication and Key Establishment EAP (EAP-SAKE)" },
173 { 49, "Internet Key Exchange v2 EAP (EAP-IKEv2)" },
174 { 50, "UMTS Authentication and Key Agreement' EAP (EAP-AKA')" },
175 { 51, "Generalized Pre-Shared Key EAP (EAP-GPSK)" },
176 { 52, "Password EAP (EAP-pwd)" },
177 { 53, "Encrypted Key Exchange v1 EAP (EAP-EKEv1)" },
178 { 254, "Expanded Type" },
179 { 255, "Experimental" },
180 { 0, NULL }
182 value_string_ext eap_type_vals_ext = VALUE_STRING_EXT_INIT(eap_type_vals);
184 const value_string eap_sim_subtype_vals[] = {
185 { SIM_START, "Start" },
186 { SIM_CHALLENGE, "Challenge" },
187 { SIM_NOTIFICATION, "Notification" },
188 { SIM_RE_AUTHENTICATION, "Re-authentication" },
189 { SIM_CLIENT_ERROR, "Client-Error" },
190 { 0, NULL }
193 const value_string eap_aka_subtype_vals[] = {
194 { AKA_CHALLENGE, "AKA-Challenge" },
195 { AKA_AUTHENTICATION_REJECT, "AKA-Authentication-Reject" },
196 { AKA_SYNCHRONIZATION_FAILURE, "AKA-Synchronization-Failure" },
197 { AKA_IDENTITY, "AKA-Identity" },
198 { AKA_NOTIFICATION, "Notification" },
199 { AKA_REAUTHENTICATION, "Re-authentication" },
200 { AKA_CLIENT_ERROR, "Client-Error" },
201 { 0, NULL }
205 References:
206 1) http://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xml
207 3) RFC4186
208 3) RFC4187
209 4) RFC5448
210 5) 3GPP TS 24.302
213 static const value_string eap_sim_aka_attribute_vals[] = {
214 { 1, "AT_RAND" },
215 { 2, "AT_AUTN" },
216 { 3, "AT_RES" },
217 { 4, "AT_AUTS" },
218 { 6, "AT_PADDING" },
219 { 7, "AT_NONCE_MT" },
220 { 10, "AT_PERMANENT_ID_REQ" },
221 { 11, "AT_MAC" },
222 { 12, "AT_NOTIFICATION" },
223 { 13, "AT_ANY_ID_REQ" },
224 { 14, "AT_IDENTITY" },
225 { 15, "AT_VERSION_LIST" },
226 { 16, "AT_SELECTED_VERSION" },
227 { 17, "AT_FULLAUTH_ID_REQ" },
228 { 19, "AT_COUNTER" },
229 { 20, "AT_COUNTER_TOO_SMALL" },
230 { 21, "AT_NONCE_S" },
231 { 22, "AT_CLIENT_ERROR_CODE" },
232 { 23, "AT_KDF_INPUT"},
233 { 24, "AT_KDF"},
234 { 129, "AT_IV" },
235 { 130, "AT_ENCR_DATA" },
236 { 132, "AT_NEXT_PSEUDONYM" },
237 { 133, "AT_NEXT_REAUTH_ID" },
238 { 134, "AT_CHECKCODE" },
239 { 135, "AT_RESULT_IND" },
240 { 136, "AT_BIDDING" },
241 { 137, "AT_IPMS_IND" },
242 { 138, "AT_IPMS_RES" },
243 { 139, "AT_TRUST_IND" },
244 { 0, NULL }
246 value_string_ext eap_sim_aka_attribute_vals_ext = VALUE_STRING_EXT_INIT(eap_sim_aka_attribute_vals);
248 const value_string eap_ms_chap_v2_opcode_vals[] = {
249 { MS_CHAP_V2_CHALLENGE, "Challenge" },
250 { MS_CHAP_V2_RESPONSE, "Response" },
251 { MS_CHAP_V2_SUCCESS, "Success" },
252 { MS_CHAP_V2_FAILURE, "Failure" },
253 { MS_CHAP_V2_CHANGE_PASSWORD, "Change-Password" },
254 { 0, NULL }
258 * State information for EAP-TLS (RFC2716) and Lightweight EAP:
260 * http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
262 * Attach to all conversations:
264 * a sequence number to be handed to "fragment_add_seq()" as
265 * the fragment sequence number - if it's -1, no reassembly
266 * is in progress, but if it's not, it's the sequence number
267 * to use for the current fragment;
269 * a value to be handed to "fragment_add_seq()" as the
270 * reassembly ID - when a reassembly is started, it's set to
271 * the frame number of the current frame, i.e. the frame
272 * that starts the reassembly;
274 * an indication of the current state of LEAP negotiation,
275 * with -1 meaning no LEAP negotiation is in progress.
277 * Attach to frames containing fragments of EAP-TLS messages the
278 * reassembly ID for those fragments, so we can find the reassembled
279 * data after the first pass through the packets.
281 * Attach to LEAP frames the state of the LEAP negotiation when the
282 * frame was processed, so we can properly dissect
283 * the LEAP message after the first pass through the packets.
285 * Attach to all conversations both pieces of information, to keep
286 * track of EAP-TLS reassembly and the LEAP state machine.
289 typedef struct {
290 int eap_tls_seq;
291 guint32 eap_reass_cookie;
292 int leap_state;
293 } conv_state_t;
295 typedef struct {
296 int info; /* interpretation depends on EAP message type */
297 } frame_state_t;
299 /*********************************************************************
300 EAP-TLS
301 RFC2716
302 **********************************************************************/
305 from RFC2716, pg 17
307 Flags
309 0 1 2 3 4 5 6 7 8
310 +-+-+-+-+-+-+-+-+
311 |L M S R R Vers |
312 +-+-+-+-+-+-+-+-+
314 L = Length included
315 M = More fragments
316 S = EAP-TLS start
317 R = Reserved
318 Vers = PEAP version (Reserved for TLS and TTLS)
321 #define EAP_TLS_FLAG_L 0x80 /* Length included */
322 #define EAP_TLS_FLAG_M 0x40 /* More fragments */
323 #define EAP_TLS_FLAG_S 0x20 /* EAP-TLS start */
325 #define EAP_TLS_FLAGS_VERSION 0x07 /* Version mask for PEAP, TTLS, FAST */
328 * reassembly of EAP-TLS
330 static reassembly_table eap_tls_reassembly_table;
332 static int hf_eap_tls_flags = -1;
333 static int hf_eap_tls_flag_l = -1;
334 static int hf_eap_tls_flag_m = -1;
335 static int hf_eap_tls_flag_s = -1;
336 static int hf_eap_tls_flags_version = -1;
337 static int hf_eap_tls_len = -1;
338 static int hf_eap_tls_fragment = -1;
339 static int hf_eap_tls_fragments = -1;
340 static int hf_eap_tls_fragment_overlap = -1;
341 static int hf_eap_tls_fragment_overlap_conflict = -1;
342 static int hf_eap_tls_fragment_multiple_tails = -1;
343 static int hf_eap_tls_fragment_too_long_fragment = -1;
344 static int hf_eap_tls_fragment_error = -1;
345 static int hf_eap_tls_fragment_count = -1;
346 static int hf_eap_tls_reassembled_length = -1;
347 static gint ett_eap_tls_fragment = -1;
348 static gint ett_eap_tls_fragments = -1;
349 static gint ett_eap_sim_attr = -1;
350 static gint ett_eap_aka_attr = -1;
351 static gint ett_eap_exp_attr = -1;
352 static gint ett_eap_tls_flags = -1;
354 static const fragment_items eap_tls_frag_items = {
355 &ett_eap_tls_fragment,
356 &ett_eap_tls_fragments,
357 &hf_eap_tls_fragments,
358 &hf_eap_tls_fragment,
359 &hf_eap_tls_fragment_overlap,
360 &hf_eap_tls_fragment_overlap_conflict,
361 &hf_eap_tls_fragment_multiple_tails,
362 &hf_eap_tls_fragment_too_long_fragment,
363 &hf_eap_tls_fragment_error,
364 &hf_eap_tls_fragment_count,
365 NULL,
366 &hf_eap_tls_reassembled_length,
367 /* Reassembled data field */
368 NULL,
369 "fragments"
372 /**********************************************************************
373 Support for EAP Expanded Type.
375 Currently this is limited to WifiProtectedSetup. Maybe we need
376 a generic method to support EAP extended types ?
377 *********************************************************************/
378 static int hf_eap_ext_vendor_id = -1;
379 static int hf_eap_ext_vendor_type = -1;
381 /* Vendor-Type and Vendor-id */
382 #define WFA_VENDOR_ID 0x00372A
383 #define WFA_SIMPLECONFIG_TYPE 0x1
385 static const value_string eap_ext_vendor_id_vals[] = {
386 { WFA_VENDOR_ID, "WFA" },
387 { 0, NULL }
390 static const value_string eap_ext_vendor_type_vals[] = {
391 { WFA_SIMPLECONFIG_TYPE, "SimpleConfig" },
392 { 0, NULL }
395 static void
396 dissect_exteap(proto_tree *eap_tree, tvbuff_t *tvb, int offset,
397 gint size, packet_info* pinfo)
400 proto_tree_add_item(eap_tree, hf_eap_ext_vendor_id, tvb, offset, 3, ENC_BIG_ENDIAN);
401 offset += 3;
402 size -= 3;
404 proto_tree_add_item(eap_tree, hf_eap_ext_vendor_type, tvb, offset, 4, ENC_BIG_ENDIAN);
405 offset += 4;
406 size -= 4;
408 /* Generic method to support multiple vendor-defined extended types goes here :-) */
409 dissect_exteap_wps(eap_tree, tvb, offset, size, pinfo);
411 /* *********************************************************************
412 ********************************************************************* */
414 static gboolean
415 test_flag(unsigned char flag, unsigned char mask)
417 return ( ( flag & mask ) != 0 );
420 static void
421 eap_tls_defragment_init(void)
423 reassembly_table_init(&eap_tls_reassembly_table,
424 &addresses_reassembly_table_functions);
427 static void
428 dissect_eap_mschapv2(proto_tree *eap_tree, tvbuff_t *tvb, packet_info *pinfo, int offset,
429 gint size)
431 proto_item *item;
432 gint left = size;
433 gint ms_len;
434 guint8 value_size;
435 guint8 opcode;
437 /* OpCode (1 byte), MS-CHAPv2-ID (1 byte), MS-Length (2 bytes), Data */
438 opcode = tvb_get_guint8(tvb, offset);
439 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_opcode, tvb, offset, 1, ENC_BIG_ENDIAN);
440 offset += 1;
441 left -= 1;
442 if (left <= 0)
443 return;
445 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_id, tvb, offset, 1, ENC_BIG_ENDIAN);
446 offset += 1;
447 left -= 1;
448 if (left <= 0)
449 return;
451 item = proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_length, tvb, offset, 2, ENC_BIG_ENDIAN);
452 ms_len = tvb_get_ntohs(tvb, offset);
453 if (ms_len != size)
454 expert_add_info(pinfo, item, &ei_eap_ms_chap_v2_length);
455 offset += 2;
456 left -= 2;
458 switch (opcode) {
459 case MS_CHAP_V2_CHALLENGE:
460 if (left <= 0)
461 break;
462 value_size = tvb_get_guint8(tvb, offset);
463 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_value_size,
464 tvb, offset, 1, ENC_BIG_ENDIAN);
465 offset += 1;
466 left -= 1;
467 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_challenge,
468 tvb, offset, value_size, ENC_NA);
469 offset += value_size;
470 left -= value_size;
471 if (left <= 0)
472 break;
473 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_name,
474 tvb, offset, left, ENC_ASCII|ENC_NA);
475 break;
476 case MS_CHAP_V2_RESPONSE:
477 if (left <= 0)
478 break;
479 value_size = tvb_get_guint8(tvb, offset);
480 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_value_size,
481 tvb, offset, 1, ENC_BIG_ENDIAN);
482 offset += 1;
483 left -= 1;
484 if (value_size == 49) {
485 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_peer_challenge,
486 tvb, offset, 16, ENC_NA);
487 offset += 16;
488 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_reserved,
489 tvb, offset, 8, ENC_NA);
490 offset += 8;
491 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_nt_response,
492 tvb, offset, 24, ENC_NA);
493 offset += 24;
494 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_flags,
495 tvb, offset, 1, ENC_BIG_ENDIAN);
496 offset += 1;
497 left -= value_size;
498 } else {
499 proto_tree_add_text(eap_tree, tvb, offset, value_size,
500 "EAP-MS-CHAP-v2 Response (Unknown Length): %s",
501 tvb_bytes_to_str(tvb, offset, value_size));
502 offset += value_size;
503 left -= value_size;
505 if (left <= 0)
506 break;
507 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_name, tvb, offset, left, ENC_ASCII|ENC_NA);
508 break;
509 case MS_CHAP_V2_SUCCESS:
510 if (left <= 0)
511 break;
512 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_message,
513 tvb, offset, left, ENC_ASCII|ENC_NA);
514 break;
515 case MS_CHAP_V2_FAILURE:
516 if (left <= 0)
517 break;
518 proto_tree_add_item(eap_tree, hf_eap_ms_chap_v2_failure_request,
519 tvb, offset, left, ENC_ASCII|ENC_NA);
520 break;
521 default:
522 proto_tree_add_text(eap_tree, tvb, offset, left,
523 "EAP-MS-CHAP-v2 Data (%d byte%s): \"%s\"",
524 left, plurality(left, "", "s"),
525 tvb_bytes_to_str(tvb, offset, left));
526 break;
530 static void
531 dissect_eap_sim(proto_tree *eap_tree, tvbuff_t *tvb, int offset, gint size)
533 gint left = size;
535 proto_tree_add_item(eap_tree, hf_eap_sim_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
537 offset += 1;
538 left -= 1;
540 if (left < 2)
541 return;
542 proto_tree_add_item(eap_tree, hf_eap_sim_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
543 offset += 2;
544 left -= 2;
546 /* Rest of EAP-SIM data is in Type-Len-Value format. */
547 while (left >= 2) {
548 guint8 type, length;
549 proto_item *pi;
550 proto_tree *attr_tree;
551 int aoffset;
552 gint aleft;
554 aoffset = offset;
555 type = tvb_get_guint8(tvb, aoffset);
556 length = tvb_get_guint8(tvb, aoffset + 1);
557 aleft = 4 * length;
559 pi = proto_tree_add_none_format(eap_tree, hf_eap_sim_subtype_attribute, tvb,
560 aoffset, aleft, "EAP-SIM Attribute: %s (%d)",
561 val_to_str_ext_const(type,
562 &eap_sim_aka_attribute_vals_ext,
563 "Unknown"),
564 type);
565 attr_tree = proto_item_add_subtree(pi, ett_eap_sim_attr);
566 proto_tree_add_uint(attr_tree, hf_eap_sim_subtype_type, tvb, aoffset, 1, type);
567 aoffset += 1;
568 aleft -= 1;
570 if (aleft <= 0)
571 break;
572 proto_tree_add_item(attr_tree, hf_eap_sim_subtype_length, tvb, aoffset, 1, ENC_BIG_ENDIAN);
573 aoffset += 1;
574 aleft -= 1;
575 proto_tree_add_item(attr_tree, hf_eap_sim_subtype_value, tvb, aoffset, aleft, ENC_NA);
577 offset += 4 * length;
578 left -= 4 * length;
582 static void
583 dissect_eap_aka(proto_tree *eap_tree, tvbuff_t *tvb, int offset, gint size)
585 gint left = size;
586 proto_tree_add_item(eap_tree, hf_eap_aka_subtype, tvb, offset, 1, ENC_BIG_ENDIAN);
588 offset += 1;
589 left -= 1;
591 if (left < 2)
592 return;
593 proto_tree_add_item(eap_tree, hf_eap_aka_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
594 offset += 2;
595 left -= 2;
597 /* Rest of EAP-AKA data is in Type-Len-Value format. */
598 while (left >= 2) {
599 guint8 type, length;
600 proto_item *pi;
601 proto_tree *attr_tree;
602 int aoffset;
603 gint aleft;
605 aoffset = offset;
606 type = tvb_get_guint8(tvb, aoffset);
607 length = tvb_get_guint8(tvb, aoffset + 1);
608 aleft = 4 * length;
610 pi = proto_tree_add_none_format(eap_tree, hf_eap_aka_subtype_attribute, tvb,
611 aoffset, aleft, "EAP-AKA Attribute: %s (%d)",
612 val_to_str_ext_const(type,
613 &eap_sim_aka_attribute_vals_ext,
614 "Unknown"),
615 type);
616 attr_tree = proto_item_add_subtree(pi, ett_eap_aka_attr);
617 proto_tree_add_uint(attr_tree, hf_eap_aka_subtype_type, tvb, aoffset, 1, type);
618 aoffset += 1;
619 aleft -= 1;
621 if (aleft <= 0)
622 break;
623 proto_tree_add_item(attr_tree, hf_eap_aka_subtype_length, tvb, aoffset, 1, ENC_BIG_ENDIAN);
624 aoffset += 1;
625 aleft -= 1;
626 proto_tree_add_item(attr_tree, hf_eap_aka_subtype_value, tvb, aoffset, aleft, ENC_NA);
628 offset += 4 * length;
629 left -= 4 * length;
633 static int
634 dissect_eap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
636 guint8 eap_code;
637 guint16 eap_len;
638 guint8 eap_type;
639 gint len;
640 conversation_t *conversation;
641 conv_state_t *conversation_state;
642 frame_state_t *packet_state;
643 int leap_state;
644 proto_tree *ti;
645 proto_tree *eap_tree = NULL;
646 proto_tree *eap_tls_flags_tree = NULL;
647 proto_item *eap_type_item = NULL;
649 col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAP");
650 col_clear(pinfo->cinfo, COL_INFO);
652 eap_code = tvb_get_guint8(tvb, 0);
654 col_add_str(pinfo->cinfo, COL_INFO,
655 val_to_str(eap_code, eap_code_vals, "Unknown code (0x%02X)"));
658 * Find a conversation to which we belong; create one if we don't find
659 * it.
661 * We use the source and destination addresses, and the *matched* port
662 * number, because if this is running over RADIUS, there's no guarantee
663 * that the source port number for request and the destination port
664 * number for replies will be the same in all messages - the client
665 * may use different port numbers for each request.
667 * We have to pair up the matched port number with the corresponding
668 * address; we determine which that is by comparing it with the
669 * destination port - if it matches, we matched on the destination
670 * port (this is a request), otherwise we matched on the source port
671 * (this is a reply).
673 * XXX - what if we're running over a TCP or UDP protocol with a
674 * heuristic dissector, meaning the matched port number won't be set?
676 * XXX - what if we have a capture file with captures on multiple
677 * PPP interfaces, with LEAP traffic on all of them? How can we
678 * keep them separate? (Or is that not going to happen?)
680 if (pinfo->destport == pinfo->match_uint) {
681 conversation = find_conversation(pinfo->fd->num, &pinfo->dst, &pinfo->src,
682 pinfo->ptype, pinfo->destport,
683 0, NO_PORT_B);
684 } else {
685 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
686 pinfo->ptype, pinfo->srcport,
687 0, NO_PORT_B);
689 if (conversation == NULL) {
690 if (pinfo->destport == pinfo->match_uint) {
691 conversation = conversation_new(pinfo->fd->num, &pinfo->dst, &pinfo->src,
692 pinfo->ptype, pinfo->destport,
693 0, NO_PORT2);
694 } else {
695 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
696 pinfo->ptype, pinfo->srcport,
697 0, NO_PORT2);
702 * Get the state information for the conversation; attach some if
703 * we don't find it.
705 conversation_state = (conv_state_t *)conversation_get_proto_data(conversation, proto_eap);
706 if (conversation_state == NULL) {
708 * Attach state information to the conversation.
710 conversation_state = wmem_new(wmem_file_scope(), conv_state_t);
711 conversation_state->eap_tls_seq = -1;
712 conversation_state->eap_reass_cookie = 0;
713 conversation_state->leap_state = -1;
714 conversation_add_proto_data(conversation, proto_eap, conversation_state);
718 * Set this now, so that it gets remembered even if we throw an exception
719 * later.
721 if (eap_code == EAP_FAILURE)
722 conversation_state->leap_state = -1;
724 eap_len = tvb_get_ntohs(tvb, 2);
725 len = eap_len;
727 if (tree) {
728 ti = proto_tree_add_item(tree, proto_eap, tvb, 0, len, ENC_NA);
729 eap_tree = proto_item_add_subtree(ti, ett_eap);
731 proto_tree_add_item(eap_tree, hf_eap_code, tvb, 0, 1, ENC_BIG_ENDIAN);
732 proto_tree_add_item(eap_tree, hf_eap_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
733 proto_tree_add_item(eap_tree, hf_eap_len, tvb, 2, 2, ENC_BIG_ENDIAN);
736 switch (eap_code) {
738 case EAP_SUCCESS:
739 case EAP_FAILURE:
740 break;
742 case EAP_REQUEST:
743 case EAP_RESPONSE:
744 eap_type = tvb_get_guint8(tvb, 4);
746 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
747 val_to_str_ext(eap_type, &eap_type_vals_ext,
748 "Unknown type (0x%02x)"));
749 if (tree)
750 eap_type_item = proto_tree_add_item(eap_tree, hf_eap_type, tvb, 4, 1, ENC_BIG_ENDIAN);
752 if ((len > 5) || ((len == 5) && (eap_type == EAP_TYPE_ID))) {
753 int offset = 5;
754 gint size = len - offset;
756 switch (eap_type) {
757 /*********************************************************************
758 **********************************************************************/
759 case EAP_TYPE_ID:
760 if (tree) {
761 proto_tree_add_item(eap_tree, hf_eap_identity, tvb, offset, size, ENC_ASCII|ENC_NA);
763 if(!pinfo->fd->flags.visited) {
764 conversation_state->leap_state = 0;
765 conversation_state->eap_tls_seq = -1;
767 break;
769 /*********************************************************************
770 **********************************************************************/
771 case EAP_TYPE_NOTIFY:
772 if (tree) {
773 proto_tree_add_item(eap_tree, hf_eap_notification, tvb,
774 offset, size, ENC_ASCII|ENC_NA);
776 break;
778 /*********************************************************************
779 **********************************************************************/
780 case EAP_TYPE_NAK:
781 if (tree) {
782 proto_tree_add_item(eap_tree, hf_eap_type_nak, tvb,
783 offset, 1, ENC_BIG_ENDIAN);
785 break;
786 /*********************************************************************
787 **********************************************************************/
788 case EAP_TYPE_MD5:
790 guint8 value_size = tvb_get_guint8(tvb, offset);
791 gint extra_len = size - 1 - value_size;
792 proto_item *item;
794 /* Warn that this is an insecure EAP type. */
795 expert_add_info(pinfo, eap_type_item, &ei_eap_mitm_attacks);
797 item = proto_tree_add_item(eap_tree, hf_eap_md5_value_size, tvb, offset, 1, ENC_BIG_ENDIAN);
798 if (value_size > (size - 1))
800 expert_add_info(pinfo, item, &ei_eap_md5_value_size_overflow);
801 value_size = size - 1;
804 offset += 1;
805 proto_tree_add_item(eap_tree, hf_eap_md5_value, tvb, offset, value_size, ENC_NA);
806 offset += value_size;
807 if (extra_len > 0) {
808 proto_tree_add_item(eap_tree, hf_eap_md5_extra_data, tvb, offset, extra_len, ENC_NA);
811 break;
813 /*********************************************************************
814 EAP-TLS
815 **********************************************************************/
816 case EAP_TYPE_FAST:
817 case EAP_TYPE_PEAP:
818 case EAP_TYPE_TTLS:
819 case EAP_TYPE_TLS:
821 guint8 flags = tvb_get_guint8(tvb, offset);
822 gboolean more_fragments;
823 gboolean has_length;
824 gboolean is_start;
825 int eap_tls_seq = -1;
826 guint32 eap_reass_cookie = 0;
827 gboolean needs_reassembly = FALSE;
829 more_fragments = test_flag(flags,EAP_TLS_FLAG_M);
830 has_length = test_flag(flags,EAP_TLS_FLAG_L);
831 is_start = test_flag(flags,EAP_TLS_FLAG_S);
833 if (is_start)
834 conversation_state->eap_tls_seq = -1;
836 /* Flags field, 1 byte */
837 if (tree) {
838 ti = proto_tree_add_item(eap_tree, hf_eap_tls_flags, tvb, offset, 1, ENC_BIG_ENDIAN);
839 eap_tls_flags_tree = proto_item_add_subtree(ti, ett_eap_tls_flags);
840 proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flag_l, tvb, offset, 1, ENC_BIG_ENDIAN);
841 proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flag_m, tvb, offset, 1, ENC_BIG_ENDIAN);
842 proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flag_s, tvb, offset, 1, ENC_BIG_ENDIAN);
844 if ((eap_type == EAP_TYPE_PEAP) || (eap_type == EAP_TYPE_TTLS) ||
845 (eap_type == EAP_TYPE_FAST)) {
846 proto_tree_add_item(eap_tls_flags_tree, hf_eap_tls_flags_version, tvb, offset, 1, ENC_BIG_ENDIAN);
849 size -= 1;
850 offset += 1;
852 /* Length field, 4 bytes, OPTIONAL. */
853 if (has_length) {
854 if (tree)
855 proto_tree_add_item(eap_tree, hf_eap_tls_len, tvb, offset, 4, ENC_BIG_ENDIAN);
856 size -= 4;
857 offset += 4;
860 if (size > 0) {
862 tvbuff_t *next_tvb;
863 gint tvb_len;
864 gboolean save_fragmented;
866 tvb_len = tvb_length_remaining(tvb, offset);
867 if (size < tvb_len)
868 tvb_len = size;
871 EAP/TLS is weird protocol (it comes from
872 Microsoft after all).
874 If we have series of fragmented packets,
875 then there's no way of knowing that from
876 the packet itself, if it is the last packet
877 in series, that is that the packet part of
878 bigger fragmented set of data.
880 The only way to know is, by knowing
881 that we are already in defragmentation
882 "mode" and we are expecing packet
883 carrying fragment of data. (either
884 because we have not received expected
885 amount of data, or because the packet before
886 had "F"ragment flag set.)
888 The situation is alleviated by fact that it
889 is simple ack/nack protcol so there's no
890 place for out-of-order packets like it is
891 possible with IP.
893 Anyway, point of this lengthy essay is that
894 we have to keep state information in the
895 conversation, so that we can put ourselves in
896 defragmenting mode and wait for the last packet,
897 and have to attach state to frames as well, so
898 that we can handle defragmentation after the
899 first pass through the capture.
901 /* See if we have a remembered defragmentation EAP ID. */
902 packet_state = (frame_state_t *)p_get_proto_data(pinfo->fd, proto_eap, 0);
903 if (packet_state == NULL) {
905 * We haven't - does this message require reassembly?
907 if (!pinfo->fd->flags.visited) {
909 * This is the first time we've looked at this frame,
910 * so it wouldn't have any remembered information.
912 * Therefore, we check whether this conversation has
913 * a reassembly operation in progress, or whether
914 * this frame has the Fragment flag set.
916 if (conversation_state->eap_tls_seq != -1) {
918 * There's a reassembly in progress; the sequence number
919 * of the previous fragment is
920 * "conversation_state->eap_tls_seq", and the reassembly
921 * ID is "conversation_state->eap_reass_cookie".
923 * We must include this frame in the reassembly.
924 * We advance the sequence number, giving us the
925 * sequence number for this fragment.
927 needs_reassembly = TRUE;
928 conversation_state->eap_tls_seq++;
930 eap_reass_cookie = conversation_state->eap_reass_cookie;
931 eap_tls_seq = conversation_state->eap_tls_seq;
932 } else if (more_fragments && has_length) {
934 * This message has the Fragment flag set, so it requires
935 * reassembly. It's the message containing the first
936 * fragment (if it's a later fragment, the sequence
937 * number in the conversation state would not be -1).
939 * If it doesn't include a length, however, we can't
940 * do reassembly (either the message is in error, as
941 * the first fragment *must* contain a length, or we
942 * didn't capture the first fragment, and this just
943 * happens to be the first fragment we saw), so we
944 * also check that we have a length;
946 needs_reassembly = TRUE;
947 conversation_state->eap_reass_cookie = pinfo->fd->num;
950 * Start the reassembly sequence number at 0.
952 conversation_state->eap_tls_seq = 0;
954 eap_tls_seq = conversation_state->eap_tls_seq;
955 eap_reass_cookie = conversation_state->eap_reass_cookie;
958 if (needs_reassembly) {
960 * This frame requires reassembly; remember the reassembly
961 * ID for subsequent accesses to it.
963 packet_state = wmem_new(wmem_file_scope(), frame_state_t);
964 packet_state->info = eap_reass_cookie;
965 p_add_proto_data(pinfo->fd, proto_eap, 0, packet_state);
968 } else {
970 * This frame has a reassembly cookie associated with it, so
971 * it requires reassembly. We've already done the
972 * reassembly in the first pass, so "fragment_add_seq()"
973 * won't look at the sequence number; set it to 0.
975 * XXX - a frame isn't supposed to have more than one
976 * EAP message in it, but if it includes both an EAP-TLS
977 * message and a LEAP message, we might be mistakenly
978 * concluding it requires reassembly because the "info"
979 * field isn't -1. We could, I guess, pack both EAP-TLS
980 * ID and LEAP state into the structure, but that doesn't
981 * work if you have multiple EAP-TLS or LEAP messages in
982 * the frame.
984 * But it's not clear how much work we should do to handle
985 * a bogus message such as that; as long as we don't crash
986 * or do something else equally horrible, we may not
987 * have to worry about this at all.
989 needs_reassembly = TRUE;
990 eap_reass_cookie = packet_state->info;
991 eap_tls_seq = 0;
995 We test here to see whether EAP-TLS packet
996 carry fragmented of TLS data.
998 If this is the case, we do reasembly below,
999 otherwise we just call dissector.
1001 if (needs_reassembly) {
1002 fragment_head *fd_head;
1005 * Yes, this frame contains a fragment that requires
1006 * reassembly.
1008 save_fragmented = pinfo->fragmented;
1009 pinfo->fragmented = TRUE;
1010 fd_head = fragment_add_seq(&eap_tls_reassembly_table,
1011 tvb, offset,
1012 pinfo, eap_reass_cookie, NULL,
1013 eap_tls_seq,
1014 size,
1015 more_fragments, 0);
1017 if (fd_head != NULL) /* Reassembled */
1019 proto_item *frag_tree_item;
1021 next_tvb = tvb_new_chain(tvb, fd_head->tvb_data);
1022 add_new_data_source(pinfo, next_tvb, "Reassembled EAP-TLS");
1024 show_fragment_seq_tree(fd_head, &eap_tls_frag_items,
1025 eap_tree, pinfo, next_tvb, &frag_tree_item);
1027 call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
1030 * We're finished reassembing this frame.
1031 * Reinitialize the reassembly state.
1033 if (!pinfo->fd->flags.visited)
1034 conversation_state->eap_tls_seq = -1;
1037 pinfo->fragmented = save_fragmented;
1039 } else { /* this data is NOT fragmented */
1040 next_tvb = tvb_new_subset(tvb, offset, tvb_len, size);
1041 call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
1045 break; /* EAP_TYPE_TLS */
1047 /*********************************************************************
1048 Cisco's Lightweight EAP (LEAP)
1049 http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
1050 **********************************************************************/
1051 case EAP_TYPE_LEAP:
1053 guint8 count, namesize;
1055 /* Warn that this is an insecure EAP type. */
1056 expert_add_info(pinfo, eap_type_item, &ei_eap_dictionary_attacks);
1058 /* Version (byte) */
1059 if (tree) {
1060 proto_tree_add_item(eap_tree, hf_eap_leap_version, tvb, offset, 1, ENC_BIG_ENDIAN);
1062 offset += 1;
1064 /* Unused (byte) */
1065 if (tree) {
1066 proto_tree_add_item(eap_tree, hf_eap_leap_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1068 offset += 1;
1070 /* Count (byte) */
1071 count = tvb_get_guint8(tvb, offset);
1072 if (tree) {
1073 proto_tree_add_item(eap_tree, hf_eap_leap_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1075 offset += 1;
1077 /* Data (byte*Count) */
1078 /* This part is state-dependent. */
1080 /* See if we've already remembered the state. */
1081 packet_state = (frame_state_t *)p_get_proto_data(pinfo->fd, proto_eap, 0);
1082 if (packet_state == NULL) {
1084 * We haven't - compute the state based on the current
1085 * state in the conversation.
1087 leap_state = conversation_state->leap_state;
1089 /* Advance the state machine. */
1090 if (leap_state==0) leap_state = 1; else
1091 if (leap_state==1) leap_state = 2; else
1092 if (leap_state==2) leap_state = 3; else
1093 if (leap_state==3) leap_state = 4; else
1094 if (leap_state==4) leap_state = -1;
1097 * Remember the state for subsequent accesses to this
1098 * frame.
1100 packet_state = wmem_new(wmem_file_scope(), frame_state_t);
1101 packet_state->info = leap_state;
1102 p_add_proto_data(pinfo->fd, proto_eap, 0, packet_state);
1105 * Update the conversation's state.
1107 conversation_state->leap_state = leap_state;
1110 /* Get the remembered state. */
1111 leap_state = packet_state->info;
1113 if (tree) {
1114 switch (leap_state) {
1115 case 1:
1116 proto_tree_add_item(eap_tree, hf_eap_leap_peer_challenge, tvb, offset, count, ENC_NA);
1117 break;
1119 case 2:
1120 proto_tree_add_item(eap_tree, hf_eap_leap_peer_response, tvb, offset, count, ENC_NA);
1121 break;
1123 case 3:
1124 proto_tree_add_item(eap_tree, hf_eap_leap_ap_challenge, tvb, offset, count, ENC_NA);
1125 break;
1127 case 4:
1128 proto_tree_add_item(eap_tree, hf_eap_leap_ap_response, tvb, offset, count, ENC_NA);
1129 break;
1131 default:
1132 proto_tree_add_text(eap_tree, tvb, offset, count,
1133 "EAP-LEAP Data (%d byte%s): \"%s\"",
1134 count, plurality(count, "", "s"),
1135 tvb_bytes_to_str(tvb, offset, count));
1136 break;
1140 offset += count;
1142 /* Name (Length-(8+Count)) */
1143 namesize = eap_len - (8+count);
1144 if (tree) {
1145 proto_tree_add_item(eap_tree, hf_eap_leap_name, tvb, offset, namesize, ENC_ASCII|ENC_NA);
1149 break; /* EAP_TYPE_LEAP */
1151 /*********************************************************************
1152 EAP-MSCHAPv2 - draft-kamath-pppext-eap-mschapv2-00.txt
1153 **********************************************************************/
1154 case EAP_TYPE_MSCHAPV2:
1155 dissect_eap_mschapv2(eap_tree, tvb, pinfo, offset, size);
1156 break; /* EAP_TYPE_MSCHAPV2 */
1158 /*********************************************************************
1159 EAP-SIM - draft-haverinen-pppext-eap-sim-13.txt
1160 **********************************************************************/
1161 case EAP_TYPE_SIM:
1162 if (tree)
1163 dissect_eap_sim(eap_tree, tvb, offset, size);
1164 break; /* EAP_TYPE_SIM */
1166 /*********************************************************************
1167 EAP-AKA - draft-arkko-pppext-eap-aka-12.txt
1168 **********************************************************************/
1169 case EAP_TYPE_AKA:
1170 case EAP_TYPE_AKA_PRIME:
1171 if (tree)
1172 dissect_eap_aka(eap_tree, tvb, offset, size);
1173 break; /* EAP_TYPE_AKA */
1175 /*********************************************************************
1176 EAP Expanded Type
1177 **********************************************************************/
1178 case EAP_TYPE_EXT:
1180 proto_item *expti = NULL;
1181 proto_tree *exptree = NULL;
1183 expti = proto_tree_add_text(eap_tree, tvb, offset, size, "Expanded Type");
1184 exptree = proto_item_add_subtree(expti, ett_eap_exp_attr);
1185 dissect_exteap(exptree, tvb, offset, size, pinfo);
1187 break;
1189 /*********************************************************************
1190 **********************************************************************/
1191 default:
1192 if (tree) {
1193 proto_tree_add_text(eap_tree, tvb, offset, size,
1194 "EAP Data (%d byte%s): \"%s\"",
1195 size, plurality(size, "", "s"),
1196 tvb_bytes_to_str(tvb, offset, size));
1198 break;
1199 /*********************************************************************
1200 **********************************************************************/
1201 } /* switch (eap_type) */
1205 } /* switch (eap_code) */
1207 return tvb_length(tvb);
1210 void
1211 proto_register_eap(void)
1213 static hf_register_info hf[] = {
1214 { &hf_eap_code, {
1215 "Code", "eap.code",
1216 FT_UINT8, BASE_DEC, VALS(eap_code_vals), 0x0,
1217 NULL, HFILL }},
1219 { &hf_eap_identifier, {
1220 "Id", "eap.id",
1221 FT_UINT8, BASE_DEC, NULL, 0x0,
1222 NULL, HFILL }},
1224 { &hf_eap_len, {
1225 "Length", "eap.len",
1226 FT_UINT16, BASE_DEC, NULL, 0x0,
1227 NULL, HFILL }},
1229 { &hf_eap_type, {
1230 "Type", "eap.type",
1231 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_type_vals_ext, 0x0,
1232 NULL, HFILL }},
1234 { &hf_eap_type_nak, {
1235 "Desired Auth Type", "eap.desired_type",
1236 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_type_vals_ext, 0x0,
1237 NULL, HFILL }},
1239 { &hf_eap_identity, {
1240 "Identity", "eap.identity",
1241 FT_STRING, BASE_NONE, NULL, 0x0,
1242 NULL, HFILL }},
1244 { &hf_eap_notification, {
1245 "Notification", "eap.notification",
1246 FT_STRING, BASE_NONE, NULL, 0x0,
1247 NULL, HFILL }},
1249 { &hf_eap_md5_value_size, {
1250 "EAP-MD5 Value-Size", "eap.md5.value_size",
1251 FT_UINT8, BASE_DEC, NULL, 0x0,
1252 NULL, HFILL }},
1254 { &hf_eap_md5_value, {
1255 "EAP-MD5 Value", "eap.md5.value",
1256 FT_BYTES, BASE_NONE, NULL, 0x0,
1257 NULL, HFILL }},
1259 { &hf_eap_md5_extra_data, {
1260 "EAP-MD5 Extra Data", "eap.md5.extra_data",
1261 FT_BYTES, BASE_NONE, NULL, 0x0,
1262 NULL, HFILL }},
1264 { &hf_eap_tls_flags, {
1265 "EAP-TLS Flags", "eap.tls.flags",
1266 FT_UINT8, BASE_HEX, NULL, 0x0,
1267 NULL, HFILL }},
1269 { &hf_eap_tls_flag_l, {
1270 "Length Included", "eap.tls.flags.len_included",
1271 FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_L,
1272 NULL, HFILL }},
1274 { &hf_eap_tls_flag_m, {
1275 "More Fragments", "eap.tls.flags.more_fragments",
1276 FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_M,
1277 NULL, HFILL }},
1279 { &hf_eap_tls_flag_s, {
1280 "Start", "eap.tls.flags.start",
1281 FT_BOOLEAN, 8, NULL, EAP_TLS_FLAG_S,
1282 NULL, HFILL }},
1284 { &hf_eap_tls_flags_version, {
1285 "Version", "eap.tls.flags.version",
1286 FT_UINT8, BASE_DEC, NULL, EAP_TLS_FLAGS_VERSION,
1287 NULL, HFILL }},
1289 { &hf_eap_tls_len, {
1290 "EAP-TLS Length", "eap.tls.len",
1291 FT_UINT32, BASE_DEC, NULL, 0x0,
1292 NULL, HFILL }},
1294 { &hf_eap_tls_fragment, {
1295 "EAP-TLS Fragment", "eap.tls.fragment",
1296 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1297 NULL, HFILL }},
1299 { &hf_eap_tls_fragments, {
1300 "EAP-TLS Fragments", "eap.tls.fragments",
1301 FT_NONE, BASE_NONE, NULL, 0x0,
1302 NULL, HFILL }},
1304 { &hf_eap_tls_fragment_overlap, {
1305 "Fragment Overlap", "eap.tls.fragment.overlap",
1306 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1307 "Fragment overlaps with other fragments", HFILL }},
1309 { &hf_eap_tls_fragment_overlap_conflict, {
1310 "Conflicting Data In Fragment Overlap", "eap.tls.fragment.overlap_conflict",
1311 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1312 "Overlapping fragments contained conflicting data", HFILL }},
1314 { &hf_eap_tls_fragment_multiple_tails, {
1315 "Multiple Tail Fragments Found", "eap.tls.fragment.multiple_tails",
1316 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1317 "Several tails were found when defragmenting the packet", HFILL }},
1319 { &hf_eap_tls_fragment_too_long_fragment,{
1320 "Fragment Too Long", "eap.tls.fragment.fragment.too_long",
1321 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1322 "Fragment contained data past end of packet", HFILL }},
1324 { &hf_eap_tls_fragment_error, {
1325 "Defragmentation Error", "eap.tls.fragment.error",
1326 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1327 "Defragmentation error due to illegal fragments", HFILL }},
1329 { &hf_eap_tls_fragment_count, {
1330 "Fragment Count", "eap.tls.fragment.count",
1331 FT_UINT32, BASE_DEC, NULL, 0x0,
1332 "Total length of the reassembled payload", HFILL }},
1334 { &hf_eap_tls_reassembled_length, {
1335 "Reassembled EAP-TLS Length", "eap.tls.reassembled.len",
1336 FT_UINT32, BASE_DEC, NULL, 0x0,
1337 "Total length of the reassembled payload", HFILL }},
1339 { &hf_eap_sim_subtype, {
1340 "EAP-SIM Subtype", "eap.sim.subtype",
1341 FT_UINT8, BASE_DEC, VALS(eap_sim_subtype_vals), 0x0,
1342 NULL, HFILL }},
1344 { &hf_eap_sim_reserved, {
1345 "EAP-SIM Reserved", "eap.sim.reserved",
1346 FT_UINT16, BASE_HEX, NULL, 0x0,
1347 NULL, HFILL }},
1349 { &hf_eap_sim_subtype_attribute, {
1350 "EAP-SIM Attribute", "eap.sim.subtype.attribute",
1351 FT_NONE, BASE_NONE, NULL, 0x0,
1352 NULL, HFILL }},
1354 { &hf_eap_sim_subtype_type, {
1355 "EAP-SIM Type", "eap.sim.subtype.type",
1356 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_sim_aka_attribute_vals_ext, 0x0,
1357 NULL, HFILL }},
1359 { &hf_eap_sim_subtype_length, {
1360 "EAP-SIM Length", "eap.sim.subtype.len",
1361 FT_UINT8, BASE_DEC, NULL, 0x0,
1362 NULL, HFILL }},
1364 { &hf_eap_sim_subtype_value, {
1365 "EAP-SIM Value", "eap.sim.subtype.value",
1366 FT_BYTES, BASE_NONE, NULL, 0x0,
1367 NULL, HFILL }},
1369 { &hf_eap_aka_subtype, {
1370 "EAP-AKA Subtype", "eap.aka.subtype",
1371 FT_UINT8, BASE_DEC, VALS(eap_aka_subtype_vals), 0x0,
1372 NULL, HFILL }},
1374 { &hf_eap_aka_reserved, {
1375 "EAP-AKA Reserved", "eap.aka.reserved",
1376 FT_UINT16, BASE_HEX, NULL, 0x0,
1377 NULL, HFILL }},
1379 { &hf_eap_aka_subtype_attribute, {
1380 "EAP-AKA Attribute", "eap.aka.subtype.attribute",
1381 FT_NONE, BASE_NONE, NULL, 0x0,
1382 NULL, HFILL }},
1384 { &hf_eap_aka_subtype_type, {
1385 "EAP-AKA Type", "eap.aka.subtype.type",
1386 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &eap_sim_aka_attribute_vals_ext, 0x0,
1387 NULL, HFILL }},
1389 { &hf_eap_aka_subtype_length, {
1390 "EAP-AKA Length", "eap.aka.subtype.len",
1391 FT_UINT8, BASE_DEC, NULL, 0x0,
1392 NULL, HFILL }},
1394 { &hf_eap_aka_subtype_value, {
1395 "EAP-AKA Value", "eap.aka.subtype.value",
1396 FT_BYTES, BASE_NONE, NULL, 0x0,
1397 NULL, HFILL }},
1399 { &hf_eap_leap_version, {
1400 "EAP-LEAP Version", "eap.leap.version",
1401 FT_UINT8, BASE_DEC, NULL, 0x0,
1402 NULL, HFILL }},
1404 { &hf_eap_leap_reserved, {
1405 "EAP-LEAP Reserved", "eap.leap.reserved",
1406 FT_UINT8, BASE_HEX, NULL, 0x0,
1407 NULL, HFILL }},
1409 { &hf_eap_leap_count, {
1410 "EAP-LEAP Count", "eap.leap.count",
1411 FT_UINT8, BASE_DEC, NULL, 0x0,
1412 NULL, HFILL }},
1414 { &hf_eap_leap_peer_challenge, {
1415 "EAP-LEAP Peer-Challenge", "eap.leap.peer_challenge",
1416 FT_BYTES, BASE_NONE, NULL, 0x0,
1417 NULL, HFILL }},
1419 { &hf_eap_leap_peer_response, {
1420 "EAP-LEAP Peer-Response", "eap.leap.peer_response",
1421 FT_BYTES, BASE_NONE, NULL, 0x0,
1422 NULL, HFILL }},
1424 { &hf_eap_leap_ap_challenge, {
1425 "EAP-LEAP AP-Challenge", "eap.leap.ap_challenge",
1426 FT_BYTES, BASE_NONE, NULL, 0x0,
1427 NULL, HFILL }},
1429 { &hf_eap_leap_ap_response, {
1430 "EAP-LEAP AP-Response", "eap.leap.ap_response",
1431 FT_BYTES, BASE_NONE, NULL, 0x0,
1432 NULL, HFILL }},
1434 { &hf_eap_leap_name, {
1435 "EAP-LEAP Name", "eap.leap.name",
1436 FT_STRING, BASE_NONE, NULL, 0x0,
1437 NULL, HFILL }},
1439 { &hf_eap_ms_chap_v2_opcode, {
1440 "EAP-MS-CHAP-v2 OpCode", "eap.ms_chap_v2.opcode",
1441 FT_UINT8, BASE_DEC, VALS(eap_ms_chap_v2_opcode_vals), 0x0,
1442 NULL, HFILL }},
1444 { &hf_eap_ms_chap_v2_id, {
1445 "EAP-MS-CHAP-v2 Id", "eap.ms_chap_v2.id",
1446 FT_UINT8, BASE_DEC, NULL, 0x0,
1447 NULL, HFILL }},
1449 { &hf_eap_ms_chap_v2_length, {
1450 "EAP-MS-CHAP-v2 Length", "eap.ms_chap_v2.length",
1451 FT_UINT16, BASE_DEC, NULL, 0x0,
1452 NULL, HFILL }},
1454 { &hf_eap_ms_chap_v2_value_size, {
1455 "EAP-MS-CHAP-v2 Value-Size", "eap.ms_chap_v2.value_size",
1456 FT_UINT8, BASE_DEC, NULL, 0x0,
1457 NULL, HFILL }},
1459 { &hf_eap_ms_chap_v2_challenge, {
1460 "EAP-MS-CHAP-v2 Challenge", "eap.ms_chap_v2.challenge",
1461 FT_BYTES, BASE_NONE, NULL, 0x0,
1462 NULL, HFILL }},
1464 { &hf_eap_ms_chap_v2_name, {
1465 "EAP-MS-CHAP-v2 Name", "eap.ms_chap_v2.name",
1466 FT_STRING, BASE_NONE, NULL, 0x0,
1467 NULL, HFILL }},
1469 { &hf_eap_ms_chap_v2_peer_challenge, {
1470 "EAP-MS-CHAP-v2 Peer-Challenge", "eap.ms_chap_v2.peer_challenge",
1471 FT_BYTES, BASE_NONE, NULL, 0x0,
1472 NULL, HFILL }},
1474 { &hf_eap_ms_chap_v2_reserved, {
1475 "EAP-MS-CHAP-v2 Reserved", "eap.ms_chap_v2.reserved",
1476 FT_BYTES, BASE_NONE, NULL, 0x0,
1477 NULL, HFILL }},
1479 { &hf_eap_ms_chap_v2_nt_response, {
1480 "EAP-MS-CHAP-v2 NT-Response", "eap.ms_chap_v2.nt_response",
1481 FT_BYTES, BASE_NONE, NULL, 0x0,
1482 NULL, HFILL }},
1484 { &hf_eap_ms_chap_v2_flags, {
1485 "EAP-MS-CHAP-v2 Flags", "eap.ms_chap_v2.flags",
1486 FT_UINT8, BASE_HEX, NULL, 0x0,
1487 NULL, HFILL }},
1489 { &hf_eap_ms_chap_v2_message, {
1490 "EAP-MS-CHAP-v2 Message", "eap.ms_chap_v2.message",
1491 FT_STRING, BASE_NONE, NULL, 0x0,
1492 NULL, HFILL }},
1494 { &hf_eap_ms_chap_v2_failure_request, {
1495 "EAP-MS-CHAP-v2 Failure-Request", "eap.ms_chap_v2.failure_request",
1496 FT_STRING, BASE_NONE, NULL, 0x0,
1497 NULL, HFILL }},
1499 /* Expanded type fields */
1500 { &hf_eap_ext_vendor_id, {
1501 "EAP-EXT Vendor Id", "eap.ext.vendor_id",
1502 FT_UINT16, BASE_HEX, VALS(eap_ext_vendor_id_vals), 0x0,
1503 NULL, HFILL }},
1505 { &hf_eap_ext_vendor_type, {
1506 "EAP-EXT Vendor Type", "eap.ext.vendor_type",
1507 FT_UINT8, BASE_HEX, VALS(eap_ext_vendor_type_vals), 0x0,
1508 NULL, HFILL }}
1510 static gint *ett[] = {
1511 &ett_eap,
1512 &ett_eap_tls_fragment,
1513 &ett_eap_tls_fragments,
1514 &ett_eap_sim_attr,
1515 &ett_eap_aka_attr,
1516 &ett_eap_exp_attr,
1517 &ett_eap_tls_flags
1519 static ei_register_info ei[] = {
1520 { &ei_eap_ms_chap_v2_length, { "eap.ms_chap_v2.length.invalid", PI_PROTOCOL, PI_WARN, "Invalid Length", EXPFILL }},
1521 { &ei_eap_mitm_attacks, { "eap.mitm_attacks", PI_SECURITY, PI_WARN, "Vulnerable to MITM attacks. If possible, change EAP type.", EXPFILL }},
1522 { &ei_eap_md5_value_size_overflow, { "eap.md5.value_size.overflow", PI_PROTOCOL, PI_WARN, "Overflow", EXPFILL }},
1523 { &ei_eap_dictionary_attacks, { "eap.dictionary_attacks", PI_SECURITY, PI_WARN,
1524 "Vulnerable to dictionary attacks. If possible, change EAP type."
1525 " See http://www.cisco.com/warp/public/cc/pd/witc/ao350ap/prodlit/2331_pp.pdf", EXPFILL }},
1528 expert_module_t* expert_eap;
1530 proto_eap = proto_register_protocol("Extensible Authentication Protocol",
1531 "EAP", "eap");
1532 proto_register_field_array(proto_eap, hf, array_length(hf));
1533 proto_register_subtree_array(ett, array_length(ett));
1534 expert_eap = expert_register_protocol(proto_eap);
1535 expert_register_field_array(expert_eap, ei, array_length(ei));
1537 eap_handle = new_register_dissector("eap", dissect_eap, proto_eap);
1538 register_init_routine(eap_tls_defragment_init);
1541 void
1542 proto_reg_handoff_eap(void)
1545 * Get a handle for the SSL/TLS dissector.
1547 ssl_handle = find_dissector("ssl");
1549 dissector_add_uint("ppp.protocol", PPP_EAP, eap_handle);
1552 * Editor modelines
1554 * Local Variables:
1555 * c-basic-offset: 2
1556 * tab-width: 8
1557 * indent-tabs-mode: nil
1558 * End:
1560 * ex: set shiftwidth=2 tabstop=8 expandtab:
1561 * :indentSize=2:tabSize=8:noTabs=true: