forked from osmocom/wireshark
Attach to all frames containing LEAP messages an indication of the state
of the LEAP negotiation, so we can properly dissect the LEAP message after the first pass through the packets. For that to be computed correctly, EAP frames have to be dissected on the first pass through the capture file, even if the protocol tree isn't being generated; that means that RADIUS AVPs need to be dissected even if the protocol tree isn't being generated. svn path=/trunk/; revision=5004
This commit is contained in:
parent
f970451d95
commit
fb18dbe6f5
208
packet-eap.c
208
packet-eap.c
|
@ -2,7 +2,7 @@
|
|||
* Routines for EAP Extensible Authentication Protocol dissection
|
||||
* RFC 2284
|
||||
*
|
||||
* $Id: packet-eap.c,v 1.19 2002/03/19 20:55:40 guy Exp $
|
||||
* $Id: packet-eap.c,v 1.20 2002/03/22 11:41:59 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -121,6 +121,29 @@ static const value_string eap_type_vals[] = {
|
|||
|
||||
};
|
||||
|
||||
/*
|
||||
* Attach to all frames containing LEAP messages an indication of
|
||||
* the state of the LEAP negotiation, so we can properly dissect
|
||||
* the LEAP message after the first pass through the packets.
|
||||
*/
|
||||
static GMemChunk *leap_state_chunk = NULL;
|
||||
|
||||
typedef struct {
|
||||
int state;
|
||||
} leap_state_t;
|
||||
|
||||
static void
|
||||
eap_init_protocol(void)
|
||||
{
|
||||
if (leap_state_chunk != NULL)
|
||||
g_mem_chunk_destroy(leap_state_chunk);
|
||||
|
||||
leap_state_chunk = g_mem_chunk_new("leap_state_chunk",
|
||||
sizeof (leap_state_t),
|
||||
100 * sizeof (leap_state_t),
|
||||
G_ALLOC_ONLY);
|
||||
}
|
||||
|
||||
static int
|
||||
dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
||||
gboolean fragmented)
|
||||
|
@ -132,6 +155,7 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
gint len;
|
||||
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");
|
||||
|
@ -184,151 +208,194 @@ dissect_eap_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
|
||||
val_to_str(eap_type, eap_type_vals,
|
||||
"Unknown type (0x%02X)"));
|
||||
if (tree) {
|
||||
if (tree)
|
||||
proto_tree_add_uint(eap_tree, hf_eap_type, tvb, 4, 1, eap_type);
|
||||
|
||||
if (len > 5) {
|
||||
int offset = 5;
|
||||
gint size = len - offset;
|
||||
if (len > 5) {
|
||||
int offset = 5;
|
||||
gint size = len - offset;
|
||||
|
||||
switch (eap_type) {
|
||||
switch (eap_type) {
|
||||
|
||||
case EAP_TYPE_ID:
|
||||
case EAP_TYPE_ID:
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, size,
|
||||
"Identity (%d byte%s): %s",
|
||||
size, plurality(size, "", "s"),
|
||||
tvb_format_text(tvb, offset, size));
|
||||
leap_state = 0;
|
||||
break;
|
||||
}
|
||||
leap_state = 0;
|
||||
break;
|
||||
|
||||
case EAP_TYPE_NOTIFY:
|
||||
case EAP_TYPE_NOTIFY:
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, size,
|
||||
"Notification (%d byte%s): %s",
|
||||
size, plurality(size, "", "s"),
|
||||
tvb_format_text(tvb, offset, size));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EAP_TYPE_NAK:
|
||||
case EAP_TYPE_NAK:
|
||||
if (tree) {
|
||||
proto_tree_add_uint(eap_tree, hf_eap_type_nak, tvb,
|
||||
offset, size, eap_type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EAP_TYPE_TLS:
|
||||
{
|
||||
guint8 flags = tvb_get_guint8(tvb, offset);
|
||||
case EAP_TYPE_TLS:
|
||||
{
|
||||
guint8 flags = tvb_get_guint8(tvb, offset);
|
||||
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, 1, "Flags(%i): %s%s%s",
|
||||
flags,
|
||||
flags & 128 ? "Length " : "",
|
||||
flags & 64 ? "More " : "",
|
||||
flags & 32 ? "Start " : "");
|
||||
size--;
|
||||
offset++;
|
||||
}
|
||||
size--;
|
||||
offset++;
|
||||
|
||||
if (flags >> 7) {
|
||||
guint32 length = tvb_get_ntohl(tvb, offset);
|
||||
if (flags >> 7) {
|
||||
guint32 length = tvb_get_ntohl(tvb, offset);
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, 4, "Length: %i",
|
||||
length);
|
||||
size -= 4;
|
||||
offset += 4;
|
||||
}
|
||||
size -= 4;
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
if (size>0) {
|
||||
tvbuff_t *next_tvb;
|
||||
gint tvb_len;
|
||||
if (size>0) {
|
||||
tvbuff_t *next_tvb;
|
||||
gint tvb_len;
|
||||
|
||||
tvb_len = tvb_length_remaining(tvb, offset);
|
||||
if (size < tvb_len)
|
||||
tvb_len = size;
|
||||
next_tvb = tvb_new_subset(tvb, offset, tvb_len, size);
|
||||
call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
|
||||
}
|
||||
}
|
||||
break;
|
||||
tvb_len = tvb_length_remaining(tvb, offset);
|
||||
if (size < tvb_len)
|
||||
tvb_len = size;
|
||||
next_tvb = tvb_new_subset(tvb, offset, tvb_len, size);
|
||||
call_dissector(ssl_handle, next_tvb, pinfo, eap_tree);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
Cisco's LEAP
|
||||
http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
|
||||
*/
|
||||
/*
|
||||
Cisco's LEAP
|
||||
http://www.missl.cs.umd.edu/wireless/ethereal/leap.txt
|
||||
*/
|
||||
|
||||
case EAP_TYPE_LEAP:
|
||||
{
|
||||
guint8 field,count,namesize;
|
||||
case EAP_TYPE_LEAP:
|
||||
{
|
||||
guint8 field,count,namesize;
|
||||
|
||||
/* Version (byte) */
|
||||
/* Version (byte) */
|
||||
if (tree) {
|
||||
field = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_text(eap_tree, tvb, offset, 1,
|
||||
"Version: %i",field);
|
||||
size--;
|
||||
offset++;
|
||||
}
|
||||
size--;
|
||||
offset++;
|
||||
|
||||
/* Unused (byte) */
|
||||
/* Unused (byte) */
|
||||
if (tree) {
|
||||
field = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_text(eap_tree, tvb, offset, 1,
|
||||
"Reserved: %i",field);
|
||||
size--;
|
||||
offset++;
|
||||
}
|
||||
size--;
|
||||
offset++;
|
||||
|
||||
/* Count (byte) */
|
||||
count = tvb_get_guint8(tvb, offset);
|
||||
/* Count (byte) */
|
||||
count = tvb_get_guint8(tvb, offset);
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, 1,
|
||||
"Count: %i",count);
|
||||
size--;
|
||||
offset++;
|
||||
}
|
||||
size--;
|
||||
offset++;
|
||||
|
||||
/* Data (byte*Count)
|
||||
This part is state-dependent. */
|
||||
if (leap_state==0) {
|
||||
/* 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);
|
||||
}
|
||||
|
||||
if (leap_state==0) {
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, count,
|
||||
"Peer Challenge [R8] (%d byte%s) Value:'%s'",
|
||||
count, plurality(count, "", "s"),
|
||||
tvb_bytes_to_str(tvb, offset, count));
|
||||
leap_state++;
|
||||
} else if (leap_state==1) {
|
||||
}
|
||||
leap_state++;
|
||||
} else if (leap_state==1) {
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, count,
|
||||
"Peer Response MSCHAP [24] (%d byte%s) NtChallengeResponse(%s)",
|
||||
count, plurality(count, "", "s"),
|
||||
tvb_bytes_to_str(tvb, offset, count));
|
||||
leap_state++;
|
||||
} else if (leap_state==2) {
|
||||
}
|
||||
leap_state++;
|
||||
} else if (leap_state==2) {
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, count,
|
||||
"AP Challenge [R8] (%d byte%s) Value:'%s'",
|
||||
count, plurality(count, "", "s"),
|
||||
tvb_bytes_to_str(tvb, offset, count));
|
||||
leap_state++;
|
||||
} else if (leap_state==3) {
|
||||
}
|
||||
leap_state++;
|
||||
} else if (leap_state==3) {
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, count,
|
||||
"AP Response [24] (%d byte%s) NtChallengeResponse(%s)",
|
||||
count, plurality(count, "", "s"),
|
||||
tvb_bytes_to_str(tvb, offset, count));
|
||||
leap_state++;
|
||||
} else
|
||||
}
|
||||
leap_state++;
|
||||
} else {
|
||||
if (tree) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
size -= count;
|
||||
offset += count;
|
||||
size -= count;
|
||||
offset += count;
|
||||
|
||||
/* Name (Length-(8+Count)) */
|
||||
namesize = eap_len - (8+count);
|
||||
/* Name (Length-(8+Count)) */
|
||||
namesize = eap_len - (8+count);
|
||||
if (tree) {
|
||||
proto_tree_add_text(eap_tree, tvb, offset, namesize,
|
||||
"Name (%d byte%s): %s",
|
||||
namesize, plurality(count, "", "s"),
|
||||
tvb_format_text(tvb, offset, namesize));
|
||||
size -= namesize;
|
||||
offset += namesize;
|
||||
}
|
||||
break;
|
||||
size -= namesize;
|
||||
offset += namesize;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
if (tree) {
|
||||
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));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,6 +443,7 @@ proto_register_eap(void)
|
|||
"EAP", "eap");
|
||||
proto_register_field_array(proto_eap, hf, array_length(hf));
|
||||
proto_register_subtree_array(ett, array_length(ett));
|
||||
register_init_routine(&eap_init_protocol);
|
||||
|
||||
new_register_dissector("eap", dissect_eap, proto_eap);
|
||||
new_register_dissector("eap_fragment", dissect_eap_fragment, proto_eap);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* RFC 2865, RFC 2866, RFC 2867, RFC 2868, RFC 2869
|
||||
*
|
||||
* $Id: packet-radius.c,v 1.50 2002/03/22 02:38:52 guy Exp $
|
||||
* $Id: packet-radius.c,v 1.51 2002/03/22 11:41:59 guy Exp $
|
||||
*
|
||||
* Ethereal - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@ethereal.com>
|
||||
|
@ -967,8 +967,9 @@ void dissect_attribute_value_pairs(tvbuff_t *tvb, int offset,proto_tree *tree,
|
|||
|
||||
if (avplength==0)
|
||||
{
|
||||
proto_tree_add_text(tree, tvb,offset,0,"No Attribute Value Pairs Found");
|
||||
return;
|
||||
if (tree)
|
||||
proto_tree_add_text(tree, tvb,offset,0,"No Attribute Value Pairs Found");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -988,23 +989,28 @@ void dissect_attribute_value_pairs(tvbuff_t *tvb, int offset,proto_tree *tree,
|
|||
* This AVP is bogus - the length includes the type and length
|
||||
* fields, so it must be >= 2.
|
||||
*/
|
||||
proto_tree_add_text(tree, tvb, offset, avph.avp_length,
|
||||
"t:%s(%u) l:%u (length not >= 2)",
|
||||
avptpstrval,avph.avp_type,avph.avp_length);
|
||||
if (tree) {
|
||||
proto_tree_add_text(tree, tvb, offset, avph.avp_length,
|
||||
"t:%s(%u) l:%u (length not >= 2)",
|
||||
avptpstrval, avph.avp_type, avph.avp_length);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (avph.avp_type == RD_TP_EAP_MESSAGE) {
|
||||
proto_item *ti;
|
||||
proto_tree *eap_tree;
|
||||
proto_tree *eap_tree = NULL;
|
||||
gint tvb_len;
|
||||
tvbuff_t *next_tvb;
|
||||
int data_len;
|
||||
int result;
|
||||
|
||||
ti = proto_tree_add_text(tree, tvb,offset,avph.avp_length,"t:%s(%u) l:%u",
|
||||
avptpstrval,avph.avp_type,avph.avp_length);
|
||||
eap_tree = proto_item_add_subtree(ti, ett_radius_eap);
|
||||
if (tree) {
|
||||
ti = proto_tree_add_text(tree, tvb, offset, avph.avp_length,
|
||||
"t:%s(%u) l:%u",
|
||||
avptpstrval, avph.avp_type, avph.avp_length);
|
||||
eap_tree = proto_item_add_subtree(ti, ett_radius_eap);
|
||||
}
|
||||
tvb_len = tvb_length_remaining(tvb, offset+2);
|
||||
data_len = avph.avp_length-2;
|
||||
if (data_len < tvb_len)
|
||||
|
@ -1014,13 +1020,6 @@ void dissect_attribute_value_pairs(tvbuff_t *tvb, int offset,proto_tree *tree,
|
|||
/*
|
||||
* Set the columns non-writable, so that the packet list
|
||||
* shows this as an RADIUS packet, not as an EAP packet.
|
||||
*
|
||||
* XXX - we'll call the EAP dissector only if we're building
|
||||
* a protocol tree. The EAP dissector currently saves no state,
|
||||
* and won't be modifying the columns, so that's OK right now,
|
||||
* but it might call the SSL dissector - if that maintains state
|
||||
* needed for dissection, we'll have to arrange that AVPs be
|
||||
* dissected even if we're not building a protocol tree.
|
||||
*/
|
||||
col_set_writable(pinfo->cinfo, FALSE);
|
||||
|
||||
|
@ -1039,7 +1038,8 @@ void dissect_attribute_value_pairs(tvbuff_t *tvb, int offset,proto_tree *tree,
|
|||
/* Are we in the process of reassembling? */
|
||||
if (reassembled_data != NULL) {
|
||||
/* Yes - show this as an EAP fragment. */
|
||||
proto_tree_add_text(eap_tree, next_tvb, 0, -1, "EAP fragment");
|
||||
if (tree)
|
||||
proto_tree_add_text(eap_tree, next_tvb, 0, -1, "EAP fragment");
|
||||
|
||||
/*
|
||||
* Do we have all of the data in this fragment?
|
||||
|
@ -1109,10 +1109,13 @@ void dissect_attribute_value_pairs(tvbuff_t *tvb, int offset,proto_tree *tree,
|
|||
}
|
||||
}
|
||||
} else {
|
||||
valstr = rd_value_to_str(&avph, tvb, offset);
|
||||
proto_tree_add_text(tree, tvb,offset,avph.avp_length,
|
||||
"t:%s(%u) l:%u, %s",
|
||||
avptpstrval,avph.avp_type,avph.avp_length,valstr);
|
||||
if (tree) {
|
||||
valstr = rd_value_to_str(&avph, tvb, offset);
|
||||
proto_tree_add_text(tree, tvb, offset, avph.avp_length,
|
||||
"t:%s(%u) l:%u, %s",
|
||||
avptpstrval, avph.avp_type, avph.avp_length,
|
||||
valstr);
|
||||
}
|
||||
}
|
||||
|
||||
offset = offset+avph.avp_length;
|
||||
|
@ -1128,7 +1131,7 @@ void dissect_attribute_value_pairs(tvbuff_t *tvb, int offset,proto_tree *tree,
|
|||
|
||||
static void dissect_radius(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
||||
{
|
||||
proto_tree *radius_tree,*avptree;
|
||||
proto_tree *radius_tree = NULL, *avptree = NULL;
|
||||
proto_item *ti,*avptf;
|
||||
int rhlength;
|
||||
int rhcode;
|
||||
|
@ -1176,24 +1179,23 @@ static void dissect_radius(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|||
proto_tree_add_text(radius_tree, tvb, 4,
|
||||
AUTHENTICATOR_LENGTH,
|
||||
"Authenticator");
|
||||
}
|
||||
|
||||
hdrlength=RD_HDR_LENGTH+AUTHENTICATOR_LENGTH;
|
||||
avplength= rhlength -hdrlength;
|
||||
hdrlength=RD_HDR_LENGTH+AUTHENTICATOR_LENGTH;
|
||||
avplength= rhlength -hdrlength;
|
||||
|
||||
if (avplength > 0) {
|
||||
/* list the attribute value pairs */
|
||||
if (avplength > 0) {
|
||||
/* list the attribute value pairs */
|
||||
|
||||
avptf = proto_tree_add_text(radius_tree,
|
||||
tvb,hdrlength,avplength,
|
||||
"Attribute value pairs");
|
||||
avptree = proto_item_add_subtree(avptf, ett_radius_avp);
|
||||
if (tree)
|
||||
{
|
||||
avptf = proto_tree_add_text(radius_tree,
|
||||
tvb,hdrlength,avplength,
|
||||
"Attribute value pairs");
|
||||
avptree = proto_item_add_subtree(avptf, ett_radius_avp);
|
||||
}
|
||||
|
||||
if (avptree !=NULL)
|
||||
{
|
||||
dissect_attribute_value_pairs(tvb, hdrlength,
|
||||
avptree,avplength,pinfo);
|
||||
}
|
||||
}
|
||||
dissect_attribute_value_pairs(tvb, hdrlength, avptree, avplength, pinfo);
|
||||
}
|
||||
}
|
||||
/* registration with the filtering engine */
|
||||
|
|
Loading…
Reference in New Issue