* Routines for EAP Extensible Authentication Protocol dissection
* RFC 2284
*
- * $Id: packet-eap.c,v 1.24 2002/03/28 09:51:17 guy Exp $
+ * $Id: packet-eap.c,v 1.34 2003/04/20 11:36:13 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
- *
+ *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# include "config.h"
#endif
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
#include <glib.h>
#include <epan/packet.h>
#include <epan/conversation.h>
#define EAP_SUCCESS 3
#define EAP_FAILURE 4
-static const value_string eap_code_vals[] = {
+static const value_string eap_code_vals[] = {
{ EAP_REQUEST, "Request" },
{ EAP_RESPONSE, "Response" },
{ EAP_SUCCESS, "Success" },
/*
References:
- 1) http://www.iana.org/assignments/ppp-numbers
+ 1) http://www.iana.org/assignments/ppp-numbers
PPP EAP REQUEST/RESPONSE TYPES
2) http://www.ietf.org/internet-drafts/draft-ietf-pppext-rfc2284bis-02.txt
3) RFC2284
#define EAP_TYPE_TLS 13
#define EAP_TYPE_LEAP 17
-static const value_string eap_type_vals[] = {
+static const value_string eap_type_vals[] = {
{EAP_TYPE_ID, "Identity [RFC2284]" },
{EAP_TYPE_NOTIFY,"Notification [RFC2284]" },
{EAP_TYPE_NAK, "Nak (Response only) [RFC2284]" },
{ 12, "KEA-VALIDATE [Nace]" },
{EAP_TYPE_TLS, "EAP-TLS [RFC2716] [Aboba]" },
{ 14, "Defender Token (AXENT) [Rosselli]" },
- { 15, "Windows 2000 EAP [Asnes]" },
+ { 15, "RSA Security SecurID EAP [Asnes, Liberman]" },
{ 16, "Arcot Systems EAP [Jerdonek]" },
- {EAP_TYPE_LEAP,"EAP-Cisco Wireless (LEAP) [Norman]" },
- { 18, "Nokia IP smart card authentication [Haverinen]" },
+ {EAP_TYPE_LEAP,"EAP-Cisco Wireless (LEAP) [Norman]" },
+ { 18, "Nokia IP smart card authentication [Haverinen]" },
{ 19, "SRP-SHA1 Part 1 [Carlson]" },
{ 20, "SRP-SHA1 Part 2 [Carlson]" },
{ 21, "EAP-TTLS [Funk]" },
{ 22, "Remote Access Service [Fields]" },
- { 23, "UMTS Authentication and Key Agreement [Haverinen]" },
- { 24, "EAP-3Com Wireless [Young]" },
+ { 23, "UMTS Authentication and Key Agreement [Haverinen]" },
+ { 24, "EAP-3Com Wireless [Young]" },
{ 25, "PEAP [Palekar]" },
{ 26, "MS-EAP-Authentication [Palekar]" },
{ 27, "Mutual Authentication w/Key Exchange (MAKE)[Berrendonner]" },
{ 30, "DynamID [Merlin]" },
{ 31, "Rob EAP [Ullah]" },
{ 32, "SecurID EAP [Josefsson]" },
+ { 33, "MS-Authentication-TLV [Palekar]" },
+ { 34, "SentriNET [Kelleher]" },
+ { 35, "EAP-Actiontec Wireless [Chang]" },
+ { 36, "Cogent Systems Biometrics Authentication EAP [Xiong]" },
+ { 37, "AirFortress EAP [Hibbard]" },
+ { 38, "EAP-HTTP Digest [Tavakoli]" },
+ { 39, "SecureSuite EAP [Clements]" },
+ { 40, "DeviceConnect EAP [Pitard]" },
+ { 41, "EAP-SPEKE [Zick]" },
{ 255, "Vendor-specific [draft-ietf-pppext-rfc2284bis-02.txt]" },
{ 0, NULL }
} frame_state_t;
/*********************************************************************
- EAP-TLS
+ EAP-TLS
RFC2716
**********************************************************************/
static int hf_eaptls_fragment = -1;
static int hf_eaptls_fragments = -1;
+static int hf_eaptls_fragment_overlap = -1;
+static int hf_eaptls_fragment_overlap_conflict = -1;
+static int hf_eaptls_fragment_multiple_tails = -1;
+static int hf_eaptls_fragment_too_long_fragment = -1;
+static int hf_eaptls_fragment_error = -1;
static gint ett_eaptls_fragment = -1;
static gint ett_eaptls_fragments = -1;
+static const fragment_items eaptls_frag_items = {
+ &ett_eaptls_fragment,
+ &ett_eaptls_fragments,
+ &hf_eaptls_fragments,
+ &hf_eaptls_fragment,
+ &hf_eaptls_fragment_overlap,
+ &hf_eaptls_fragment_overlap_conflict,
+ &hf_eaptls_fragment_multiple_tails,
+ &hf_eaptls_fragment_too_long_fragment,
+ &hf_eaptls_fragment_error,
+ NULL,
+ "fragments"
+};
+
/*********************************************************************
**********************************************************************/
static gboolean
-test_flag(unsigned char flag, unsigned char mask)
+test_flag(unsigned char flag, unsigned char mask)
{
return ( ( flag & mask ) != 0 );
}
**********************************************************************/
case EAP_TYPE_ID:
if (tree) {
- proto_tree_add_text(eap_tree, tvb, offset, size,
+ proto_tree_add_text(eap_tree, tvb, offset, size,
"Identity (%d byte%s): %s",
size, plurality(size, "", "s"),
tvb_format_text(tvb, offset, size));
**********************************************************************/
case EAP_TYPE_NOTIFY:
if (tree) {
- proto_tree_add_text(eap_tree, tvb, offset, size,
+ proto_tree_add_text(eap_tree, tvb, offset, size,
"Notification (%d byte%s): %s",
size, plurality(size, "", "s"),
tvb_format_text(tvb, offset, size));
**********************************************************************/
case EAP_TYPE_NAK:
if (tree) {
- proto_tree_add_uint(eap_tree, hf_eap_type_nak, tvb,
- offset, size, eap_type);
+ proto_tree_add_item(eap_tree, hf_eap_type_nak, tvb,
+ offset, 1, FALSE);
}
break;
/*********************************************************************
if (size>0) {
tvbuff_t *next_tvb;
- gint tvb_len;
+ gint tvb_len;
gboolean save_fragmented;
tvb_len = tvb_length_remaining(tvb, offset);
if (size < tvb_len)
tvb_len = size;
-
- /*
- EAP/TLS is weird protocol (it comes from
- Microsoft after all).
+
+ /*
+ EAP/TLS is weird protocol (it comes from
+ Microsoft after all).
If we have series of fragmented packets,
then there's no way of knowing that from
the packet itself, if it is the last packet
- in series, that is that the packet part of
+ in series, that is that the packet part of
bigger fragmented set of data.
The only way to know is, by knowing
that we are already in defragmentation
"mode" and we are expecing packet
- carrying fragment of data. (either
+ carrying fragment of data. (either
because we have not received expected
amount of data, or because the packet before
had "F"ragment flag set.)
- The situation is alleviated by fact that it
- is simple ack/nack protcol so there's no
- place for out-of-order packets like it is
- possible with IP.
+ The situation is alleviated by fact that it
+ is simple ack/nack protcol so there's no
+ place for out-of-order packets like it is
+ possible with IP.
Anyway, point of this lengthy essay is that
we have to keep state information in the
- conversation, so that we can put ourselves in
+ conversation, so that we can put ourselves in
defragmenting mode and wait for the last packet,
and have to attach state to frames as well, so
that we can handle defragmentation after the
eap_tls_seq = 0;
}
- /*
- We test here to see whether EAP-TLS packet
- carry fragmented of TLS data.
+ /*
+ We test here to see whether EAP-TLS packet
+ carry fragmented of TLS data.
If this is the case, we do reasembly below,
otherwise we just call dissector.
*/
save_fragmented = pinfo->fragmented;
pinfo->fragmented = TRUE;
- fd_head = fragment_add_seq(tvb, offset, pinfo,
+ fd_head = fragment_add_seq(tvb, offset, pinfo,
eap_reass_cookie,
eaptls_fragment_table,
- eap_tls_seq,
+ eap_tls_seq,
size,
more_fragments);
if (fd_head != NULL) /* Reassembled */
{
- fragment_data *ffd; /* fragment file descriptor */
- proto_tree *ft=NULL;
- proto_item *fi=NULL;
- guint32 frag_offset;
-
next_tvb = tvb_new_real_data(fd_head->data,
fd_head->len,
fd_head->len);
tvb_set_child_real_data_tvbuff(tvb, next_tvb);
- add_new_data_source(pinfo->fd, next_tvb,
- "Reassembled EAP-TLS");
- pinfo->fragmented = FALSE;
-
- fi = proto_tree_add_item(eap_tree, hf_eaptls_fragments,
- next_tvb, 0, -1, FALSE);
- ft = proto_item_add_subtree(fi, ett_eaptls_fragments);
- frag_offset = 0;
- for (ffd=fd_head->next; ffd; ffd=ffd->next){
- proto_tree_add_none_format(ft, hf_eaptls_fragment,
- next_tvb, frag_offset, ffd->len,
- "Frame:%u payload:%u-%u",
- ffd->frame,
- frag_offset,
- frag_offset+ffd->len-1
- );
- frag_offset += ffd->len;
- }
+ add_new_data_source(pinfo, next_tvb, "Reassembled EAP-TLS");
+
+ show_fragment_seq_tree(fd_head, &eaptls_frag_items,
+ eap_tree, pinfo, next_tvb);
+
call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
/*
}
pinfo->fragmented = save_fragmented;
-
+
} else { /* this data is NOT fragmented */
next_tvb = tvb_new_subset(tvb, offset, tvb_len, size);
call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
/* Version (byte) */
if (tree) {
field = tvb_get_guint8(tvb, offset);
- proto_tree_add_text(eap_tree, tvb, offset, 1,
+ proto_tree_add_text(eap_tree, tvb, offset, 1,
"Version: %i",field);
}
size--;
/* Unused (byte) */
if (tree) {
field = tvb_get_guint8(tvb, offset);
- proto_tree_add_text(eap_tree, tvb, offset, 1,
+ proto_tree_add_text(eap_tree, tvb, offset, 1,
"Reserved: %i",field);
}
size--;
/* Count (byte) */
count = tvb_get_guint8(tvb, offset);
if (tree) {
- proto_tree_add_text(eap_tree, tvb, offset, 1,
+ proto_tree_add_text(eap_tree, tvb, offset, 1,
"Count: %i",count);
}
size--;
* state in the conversation.
*/
leap_state = conversation_state->leap_state;
-
+
/* Advance the state machine. */
if (leap_state==0) leap_state = 1; else
if (leap_state==1) leap_state = 2; else
/* Get the remembered state. */
leap_state = packet_state->info;
- if (tree) {
+ if (tree) {
if (leap_state==1) {
- proto_tree_add_text(eap_tree, tvb, offset, count,
+ proto_tree_add_text(eap_tree, tvb, offset, count,
"Peer Challenge [8] Random Value:\"%s\"",
tvb_bytes_to_str(tvb, offset, count));
} else if (leap_state==2) {
- proto_tree_add_text(eap_tree, tvb, offset, count,
+ proto_tree_add_text(eap_tree, tvb, offset, count,
"Peer Response [24] NtChallengeResponse(%s)",
tvb_bytes_to_str(tvb, offset, count));
} else if (leap_state==3) {
- proto_tree_add_text(eap_tree, tvb, offset, count,
+ proto_tree_add_text(eap_tree, tvb, offset, count,
"AP Challenge [8] Random Value:\"%s\"",
tvb_bytes_to_str(tvb, offset, count));
} else if (leap_state==4) {
- proto_tree_add_text(eap_tree, tvb, offset, count,
+ proto_tree_add_text(eap_tree, tvb, offset, count,
"AP Response [24] ChallengeResponse(%s)",
tvb_bytes_to_str(tvb, offset, count));
} else {
- proto_tree_add_text(eap_tree, tvb, offset, count,
+ proto_tree_add_text(eap_tree, tvb, offset, count,
"Data (%d byte%s): \"%s\"",
count, plurality(count, "", "s"),
tvb_bytes_to_str(tvb, offset, count));
/* Name (Length-(8+Count)) */
namesize = eap_len - (8+count);
if (tree) {
- proto_tree_add_text(eap_tree, tvb, offset, namesize,
+ proto_tree_add_text(eap_tree, tvb, offset, namesize,
"Name (%d byte%s): %s",
namesize, plurality(count, "", "s"),
tvb_format_text(tvb, offset, namesize));
**********************************************************************/
default:
if (tree) {
- proto_tree_add_text(eap_tree, tvb, offset, size,
+ proto_tree_add_text(eap_tree, tvb, offset, size,
"Type-Data (%d byte%s) Value: %s",
size, plurality(size, "", "s"),
tvb_bytes_to_str(tvb, offset, size));
proto_register_eap(void)
{
static hf_register_info hf[] = {
- { &hf_eap_code, {
- "Code", "eap.code", FT_UINT8, BASE_DEC,
+ { &hf_eap_code, {
+ "Code", "eap.code", FT_UINT8, BASE_DEC,
VALS(eap_code_vals), 0x0, "", HFILL }},
{ &hf_eap_identifier, {
"Id", "eap.id", FT_UINT8, BASE_DEC,
{ &hf_eap_len, {
"Length", "eap.len", FT_UINT16, BASE_DEC,
NULL, 0x0, "", HFILL }},
- { &hf_eap_type, {
- "Type", "eap.type", FT_UINT8, BASE_DEC,
+ { &hf_eap_type, {
+ "Type", "eap.type", FT_UINT8, BASE_DEC,
VALS(eap_type_vals), 0x0, "", HFILL }},
- { &hf_eap_type_nak, {
- "Desired Auth Type", "eap.type", FT_UINT8, BASE_DEC,
+ { &hf_eap_type_nak, {
+ "Desired Auth Type", "eap.desired_type", FT_UINT8, BASE_DEC,
VALS(eap_type_vals), 0x0, "", HFILL }},
{ &hf_eaptls_fragment,
- { "EAP-TLS Fragment", "eaptls.fragment",
- FT_NONE, BASE_NONE, NULL, 0x0,
- "EAP-TLS Fragment", HFILL }},
+ { "EAP-TLS Fragment", "eaptls.fragment",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "EAP-TLS Fragment", HFILL }},
{ &hf_eaptls_fragments,
- { "EAP-TLS Fragments", "eaptls.fragments",
+ { "EAP-TLS Fragments", "eaptls.fragments",
FT_NONE, BASE_NONE, NULL, 0x0,
"EAP-TLS Fragments", HFILL }},
-
-
+ { &hf_eaptls_fragment_overlap,
+ { "Fragment overlap", "eaptls.fragment.overlap",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment overlaps with other fragments", HFILL }},
+ { &hf_eaptls_fragment_overlap_conflict,
+ { "Conflicting data in fragment overlap", "eaptls.fragment.overlap.conflict",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Overlapping fragments contained conflicting data", HFILL }},
+ { &hf_eaptls_fragment_multiple_tails,
+ { "Multiple tail fragments found", "eaptls.fragment.multipletails",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Several tails were found when defragmenting the packet", HFILL }},
+ { &hf_eaptls_fragment_too_long_fragment,
+ { "Fragment too long", "eaptls.fragment.toolongfragment",
+ FT_BOOLEAN, BASE_NONE, NULL, 0x0,
+ "Fragment contained data past end of packet", HFILL }},
+ { &hf_eaptls_fragment_error,
+ { "Defragmentation error", "eaptls.fragment.error",
+ FT_FRAMENUM, BASE_NONE, NULL, 0x0,
+ "Defragmentation error due to illegal fragments", HFILL }},
};
static gint *ett[] = {
&ett_eap,
&ett_eaptls_fragments,
};
- proto_eap = proto_register_protocol("Extensible Authentication Protocol",
+ proto_eap = proto_register_protocol("Extensible Authentication Protocol",
"EAP", "eap");
proto_register_field_array(proto_eap, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));