aboutsummaryrefslogtreecommitdiffstats
path: root/packet-eap.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2002-03-23 21:24:38 +0000
committerGuy Harris <guy@alum.mit.edu>2002-03-23 21:24:38 +0000
commit3c36b98cca74501aa572e3da009646e697b892d7 (patch)
treeed5b9bdaf3c481eda6df9bf7a1e04874d774b7aa /packet-eap.c
parent4e576dc1f2a45b1d7c6cfe2cc4c64f5d2303a298 (diff)
From Adam Sulmicki: state machine changes to update the state better,
and changes to the display items for LEAP challenges and responses. Make the LEAP state per-conversation. Get rid of some unneeded includes. svn path=/trunk/; revision=5008
Diffstat (limited to 'packet-eap.c')
-rw-r--r--packet-eap.c188
1 files changed, 131 insertions, 57 deletions
diff --git a/packet-eap.c b/packet-eap.c
index d17a05e714..d78211b9ca 100644
--- a/packet-eap.c
+++ b/packet-eap.c
@@ -2,7 +2,7 @@
* Routines for EAP Extensible Authentication Protocol dissection
* RFC 2284
*
- * $Id: packet-eap.c,v 1.20 2002/03/22 11:41:59 guy Exp $
+ * $Id: packet-eap.c,v 1.21 2002/03/23 21:24:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -37,10 +37,7 @@
#include <glib.h>
#include <epan/packet.h>
-#include "packet-ieee8023.h"
-#include "packet-ipx.h"
-#include "packet-llc.h"
-#include "etypes.h"
+#include <epan/conversation.h>
#include "ppptypes.h"
static int proto_eap = -1;
@@ -52,8 +49,6 @@ static int hf_eap_type_nak = -1;
static gint ett_eap = -1;
-static int leap_state = -1;
-
static dissector_handle_t ssl_handle;
#define EAP_REQUEST 1
@@ -153,9 +148,11 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
guint16 eap_len;
guint8 eap_type;
gint len;
+ conversation_t *conversation;
+ leap_state_t *conversation_state, *packet_state;
+ int leap_state;
proto_tree *ti;
proto_tree *eap_tree = NULL;
- leap_state_t *leap_state_info;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "EAP");
@@ -167,8 +164,70 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_add_str(pinfo->cinfo, COL_INFO,
val_to_str(eap_code, eap_code_vals, "Unknown code (0x%02X)"));
+ /*
+ * Find a conversation to which we belong; create one if we don't find
+ * it.
+ *
+ * We use the source and destination addresses, and the *matched* port
+ * number, because if this is running over RADIUS, there's no guarantee
+ * that the source port number for request and the destination port
+ * number for replies will be the same in all messages - the client
+ * may use different port numbers for each request.
+ *
+ * We have to pair up the matched port number with the corresponding
+ * address; we determine which that is by comparing it with the
+ * destination port - if it matches, we matched on the destination
+ * port (this is a request), otherwise we matched on the source port
+ * (this is a reply).
+ *
+ * XXX - what if we're running over a TCP or UDP protocol with a
+ * heuristic dissector, meaning the matched port number won't be set?
+ *
+ * XXX - what if we have a capture file with captures on multiple
+ * PPP interfaces, with LEAP traffic on all of them? How can we
+ * keep them separate? (Or is that not going to happen?)
+ */
+ if (pinfo->destport == pinfo->match_port) {
+ conversation = find_conversation(&pinfo->dst, &pinfo->src,
+ pinfo->ptype, pinfo->destport,
+ 0, NO_PORT_B);
+ } else {
+ conversation = find_conversation(&pinfo->src, &pinfo->dst,
+ pinfo->ptype, pinfo->srcport,
+ 0, NO_PORT_B);
+ }
+ if (conversation == NULL) {
+ if (pinfo->destport == pinfo->match_port) {
+ conversation = conversation_new(&pinfo->dst, &pinfo->src,
+ pinfo->ptype, pinfo->destport,
+ 0, NO_PORT2);
+ } else {
+ conversation = conversation_new(&pinfo->src, &pinfo->dst,
+ pinfo->ptype, pinfo->srcport,
+ 0, NO_PORT2);
+ }
+ }
+
+ /*
+ * Get the LEAP state information for the conversation; attach some if
+ * we don't find it.
+ */
+ conversation_state = conversation_get_proto_data(conversation, proto_eap);
+ if (conversation_state == NULL) {
+ /*
+ * Attach LEAP state information to the conversation.
+ */
+ conversation_state = g_mem_chunk_alloc(leap_state_chunk);
+ conversation_state->state = -1;
+ conversation_add_proto_data(conversation, proto_eap, conversation_state);
+ }
+
+ /*
+ * Set this now, so that it gets remembered even if we throw an exception
+ * later.
+ */
if (eap_code == EAP_FAILURE)
- leap_state = -1;
+ conversation_state->state = -1;
eap_len = tvb_get_ntohs(tvb, 2);
len = eap_len;
@@ -200,6 +259,10 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
switch (eap_code) {
+ case EAP_SUCCESS:
+ case EAP_FAILURE:
+ break;
+
case EAP_REQUEST:
case EAP_RESPONSE:
eap_type = tvb_get_guint8(tvb, 4);
@@ -223,10 +286,10 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
"Identity (%d byte%s): %s",
size, plurality(size, "", "s"),
tvb_format_text(tvb, offset, size));
- }
- leap_state = 0;
+ }
+ conversation_state->state = 0;
break;
-
+
case EAP_TYPE_NOTIFY:
if (tree) {
proto_tree_add_text(eap_tree, tvb, offset, size,
@@ -278,7 +341,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
}
}
- break;
+ break; /* EAP_TYPE_TLS */
/*
Cisco's LEAP
@@ -316,61 +379,70 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
size--;
offset++;
- /* Data (byte*Count)
- This part is state-dependent.
-
- See if we've already remembered the state. */
- leap_state_info = p_get_proto_data(pinfo->fd, proto_eap);
- if (leap_state_info != NULL) {
- /* We have - use the remembered state. */
- leap_state = leap_state_info->state;
- } else {
- /* We haven't - remember the state for subsequent accesses. */
- leap_state_info = g_mem_chunk_alloc(leap_state_chunk);
- leap_state_info->state = leap_state;
- p_add_proto_data(pinfo->fd, proto_eap, leap_state_info);
+ /* Data (byte*Count) */
+ /* This part is state-dependent. */
+
+
+ /* See if we've already remembered the state. */
+ packet_state = p_get_proto_data(pinfo->fd, proto_eap);
+ if (packet_state == NULL) {
+ /*
+ * We haven't - compute the state based on the current
+ * state in the conversation.
+ */
+ leap_state = conversation_state->state;
+
+ /* Advance the state machine. */
+ if (leap_state==0) leap_state = 1; else
+ if (leap_state==1) leap_state = 2; else
+ if (leap_state==2) leap_state = 3; else
+ if (leap_state==3) leap_state = 4; else
+ if (leap_state==4) leap_state = -1;
+
+ /*
+ * Remember the state for subsequent accesses to this
+ * frame.
+ */
+ packet_state = g_mem_chunk_alloc(leap_state_chunk);
+ packet_state->state = leap_state;
+ p_add_proto_data(pinfo->fd, proto_eap, packet_state);
+
+ /*
+ * Update the conversation's state.
+ */
+ conversation_state->state = leap_state;
}
- if (leap_state==0) {
- if (tree) {
+ /* Get the remembered state. */
+ leap_state = packet_state->state;
+
+ if (tree) {
+
+ if (leap_state==1) {
proto_tree_add_text(eap_tree, tvb, offset, count,
- "Peer Challenge [R8] (%d byte%s) Value:'%s'",
- count, plurality(count, "", "s"),
+ "Peer Challenge [8] Random Value:\"%s\"",
tvb_bytes_to_str(tvb, offset, count));
- }
- leap_state++;
- } else if (leap_state==1) {
- if (tree) {
+ } else if (leap_state==2) {
proto_tree_add_text(eap_tree, tvb, offset, count,
- "Peer Response MSCHAP [24] (%d byte%s) NtChallengeResponse(%s)",
- count, plurality(count, "", "s"),
+ "Peer Response [24] NtChallengeResponse(%s)",
tvb_bytes_to_str(tvb, offset, count));
- }
- leap_state++;
- } else if (leap_state==2) {
- if (tree) {
+ } else if (leap_state==3) {
proto_tree_add_text(eap_tree, tvb, offset, count,
- "AP Challenge [R8] (%d byte%s) Value:'%s'",
- count, plurality(count, "", "s"),
+ "AP Challenge [8] Random Value:\"%s\"",
tvb_bytes_to_str(tvb, offset, count));
- }
- leap_state++;
- } else if (leap_state==3) {
- if (tree) {
+ } else if (leap_state==4) {
proto_tree_add_text(eap_tree, tvb, offset, count,
- "AP Response [24] (%d byte%s) NtChallengeResponse(%s)",
- count, plurality(count, "", "s"),
+ "AP Response [24] ChallengeResponse(%s)",
tvb_bytes_to_str(tvb, offset, count));
- }
- leap_state++;
- } else {
- if (tree) {
+ } else {
proto_tree_add_text(eap_tree, tvb, offset, count,
- "Data (%d byte%s): %s",
+ "Data (%d byte%s): \"%s\"",
count, plurality(count, "", "s"),
tvb_bytes_to_str(tvb, offset, count));
}
- }
+
+ } /* END: if (tree) */
+
size -= count;
offset += count;
@@ -386,7 +458,8 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
size -= namesize;
offset += namesize;
}
- break;
+
+ break; /* EAP_TYPE_LEAP */
default:
if (tree) {
@@ -396,9 +469,10 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
tvb_bytes_to_str(tvb, offset, size));
}
break;
- }
+ } /* switch (eap_type) */
}
- }
+
+ } /* switch (eap_code) */
return tvb_length(tvb);
}