aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorChris Maynard <Christopher.Maynard@GTECH.COM>2011-03-08 18:33:45 +0000
committerChris Maynard <Christopher.Maynard@GTECH.COM>2011-03-08 18:33:45 +0000
commit4d20bdd60d6559e536522664e6b616f9f0d40a1c (patch)
treeb2db1ad5603557da21fa72ff051e5e710f6135f6 /epan
parentcf8c877d0dd92e660fd6d011f2df2ca092fcba68 (diff)
Conversation tracking must be handled whether "tree" is NULL or not.
svn path=/trunk/; revision=36168
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-radius.c413
1 files changed, 205 insertions, 208 deletions
diff --git a/epan/dissectors/packet-radius.c b/epan/dissectors/packet-radius.c
index 35633741f6..c3765c9792 100644
--- a/epan/dissectors/packet-radius.c
+++ b/epan/dissectors/packet-radius.c
@@ -1312,21 +1312,17 @@ dissect_radius(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
e_radiushdr rh;
radius_info_t *rad_info;
-
conversation_t* conversation;
radius_call_info_key radius_call_key;
radius_call_info_key *new_radius_call_key;
radius_call_t *radius_call = NULL;
- nstime_t delta;
static address null_address = { AT_NONE, 0, NULL };
-
/* does this look like radius ? */
if(!is_radius(tvb)){
return 0;
}
-
col_set_str(pinfo->cinfo, COL_PROTOCOL, "RADIUS");
col_clear(pinfo->cinfo, COL_INFO);
@@ -1350,28 +1346,23 @@ dissect_radius(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
rad_info->ident = rh.rh_ident;
tap_queue_packet(radius_tap, pinfo, rad_info);
-
if (check_col(pinfo->cinfo, COL_INFO))
{
col_add_fstr(pinfo->cinfo,COL_INFO,"%s(%d) (id=%d, l=%d)",
- val_to_str(rh.rh_code,radius_vals,"Unknown Packet"),
- rh.rh_code, rh.rh_ident, rh.rh_pktlength);
+ val_to_str(rh.rh_code,radius_vals,"Unknown Packet"),
+ rh.rh_code, rh.rh_ident, rh.rh_pktlength);
}
-
if (tree)
{
/* Forces load of header fields, if not already done so */
DISSECTOR_ASSERT(proto_registrar_get_byname("radius.code"));
ti = proto_tree_add_item(tree,proto_radius, tvb, 0, rh.rh_pktlength, FALSE);
-
radius_tree = proto_item_add_subtree(ti, ett_radius);
-
proto_tree_add_uint(radius_tree,hf_radius_code, tvb, 0, 1, rh.rh_code);
-
proto_tree_add_uint_format(radius_tree,hf_radius_id, tvb, 1, 1, rh.rh_ident,
- "Packet identifier: 0x%01x (%d)", rh.rh_ident, rh.rh_ident);
+ "Packet identifier: 0x%01x (%d)", rh.rh_ident, rh.rh_ident);
}
/*
@@ -1382,245 +1373,251 @@ dissect_radius(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
if (tree)
{
proto_tree_add_uint_format(radius_tree, hf_radius_length,
- tvb, 2, 2, rh.rh_pktlength,
- "Length: %u (bogus, < %u)",
- rh.rh_pktlength, HDR_LENGTH);
+ tvb, 2, 2, rh.rh_pktlength, "Length: %u (bogus, < %u)",
+ rh.rh_pktlength, HDR_LENGTH);
}
- goto end_of_radius;
+ return tvb_length(tvb);
}
+
avplength = rh.rh_pktlength - HDR_LENGTH;
if (tree)
{
- proto_tree_add_uint(radius_tree, hf_radius_length, tvb,
- 2, 2, rh.rh_pktlength);
-
- proto_tree_add_item(radius_tree, hf_radius_authenticator, tvb, 4,AUTHENTICATOR_LENGTH,FALSE);
+ proto_tree_add_uint(radius_tree, hf_radius_length, tvb, 2, 2, rh.rh_pktlength);
+ proto_tree_add_item(radius_tree, hf_radius_authenticator, tvb, 4, AUTHENTICATOR_LENGTH,FALSE);
}
tvb_memcpy(tvb,authenticator,4,AUTHENTICATOR_LENGTH);
- if (tree) {
-
- /* Conversation support REQUEST/RESPONSES */
- switch (rh.rh_code)
- {
- case RADIUS_ACCESS_REQUEST:
- case RADIUS_ACCOUNTING_REQUEST:
- case RADIUS_ACCESS_PASSWORD_REQUEST:
- case RADIUS_ASCEND_ACCESS_EVENT_REQUEST:
- case RADIUS_DISCONNECT_REQUEST:
- case RADIUS_CHANGE_FILTER_REQUEST:
+ /* Conversation support REQUEST/RESPONSES */
+ switch (rh.rh_code)
+ {
+ case RADIUS_ACCESS_REQUEST:
+ case RADIUS_ACCOUNTING_REQUEST:
+ case RADIUS_ACCESS_PASSWORD_REQUEST:
+ case RADIUS_ASCEND_ACCESS_EVENT_REQUEST:
+ case RADIUS_DISCONNECT_REQUEST:
+ case RADIUS_CHANGE_FILTER_REQUEST:
+ if (tree)
+ {
hidden_item = proto_tree_add_boolean(radius_tree, hf_radius_req, tvb, 0, 0, TRUE);
PROTO_ITEM_SET_HIDDEN(hidden_item);
- /* Keep track of the address and port whence the call came
- * so that we can match up requests with replies.
- *
- * Because it is UDP and the reply can come from any IP
- * and port (not necessarly the request dest), we only
- * track the source IP and port of the request to match
- * the reply.
- */
+ }
- /*
- * XXX - can we just use NO_ADDR_B? Unfortunately,
- * you currently still have to pass a non-null
- * pointer for the second address argument even
- * if you do that.
- */
- conversation = find_conversation(pinfo->fd->num, &pinfo->src,
- &null_address, pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
- if (conversation == NULL)
+ /* Keep track of the address and port whence the call came
+ * so that we can match up requests with replies.
+ *
+ * Because it is UDP and the reply can come from any IP
+ * and port (not necessarly the request dest), we only
+ * track the source IP and port of the request to match
+ * the reply.
+ */
+
+ /*
+ * XXX - can we just use NO_ADDR_B? Unfortunately,
+ * you currently still have to pass a non-null
+ * pointer for the second address argument even
+ * if you do that.
+ */
+ conversation = find_conversation(pinfo->fd->num, &pinfo->src,
+ &null_address, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+ if (conversation == NULL)
+ {
+ /* It's not part of any conversation - create a new one. */
+ conversation = conversation_new(pinfo->fd->num, &pinfo->src,
+ &null_address, pinfo->ptype, pinfo->srcport,
+ pinfo->destport, 0);
+ }
+
+ /* Prepare the key data */
+ radius_call_key.code = rh.rh_code;
+ radius_call_key.ident = rh.rh_ident;
+ radius_call_key.conversation = conversation;
+ radius_call_key.req_time = pinfo->fd->abs_ts;
+
+ /* Look up the request */
+ radius_call = g_hash_table_lookup(radius_calls, &radius_call_key);
+ if (radius_call != NULL)
+ {
+ /* We've seen a request with this ID, with the same
+ destination, before - but was it *this* request? */
+ if (pinfo->fd->num != radius_call->req_num)
{
- /* It's not part of any conversation - create a new one. */
- conversation = conversation_new(pinfo->fd->num, &pinfo->src,
- &null_address, pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
+ /* No, so it's a duplicate request. Mark it as such. */
+ rad_info->is_duplicate = TRUE;
+ rad_info->req_num = radius_call->req_num;
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ", Duplicate Request ID:%u", rh.rh_ident);
+ }
+ if (tree)
+ {
+ proto_item* item;
+ hidden_item = proto_tree_add_uint(radius_tree, hf_radius_dup, tvb, 0,0, rh.rh_ident);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
+ item = proto_tree_add_uint(radius_tree, hf_radius_req_dup, tvb, 0,0, rh.rh_ident);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
}
+ }
+ else
+ {
+ /* Prepare the value data.
+ "req_num" and "rsp_num" are frame numbers;
+ frame numbers are 1-origin, so we use 0
+ to mean "we don't yet know in which frame
+ the reply for this call appears". */
+ new_radius_call_key = se_alloc(sizeof(radius_call_info_key));
+ *new_radius_call_key = radius_call_key;
+ radius_call = se_alloc(sizeof(radius_call_t));
+ radius_call->req_num = pinfo->fd->num;
+ radius_call->rsp_num = 0;
+ radius_call->ident = rh.rh_ident;
+ radius_call->code = rh.rh_code;
+ radius_call->responded = FALSE;
+ radius_call->req_time = pinfo->fd->abs_ts;
+ radius_call->rspcode = 0;
+
+ /* Store it */
+ g_hash_table_insert(radius_calls, new_radius_call_key, radius_call);
+ }
+ if (tree && radius_call && radius_call->rsp_num)
+ {
+ proto_item* item;
+ item = proto_tree_add_uint_format(radius_tree,
+ hf_radius_rsp_frame, tvb, 0, 0, radius_call->rsp_num,
+ "The response to this request is in frame %u",
+ radius_call->rsp_num);
+ PROTO_ITEM_SET_GENERATED(item);
+ }
+ break;
+ case RADIUS_ACCESS_ACCEPT:
+ case RADIUS_ACCESS_REJECT:
+ case RADIUS_ACCOUNTING_RESPONSE:
+ case RADIUS_ACCESS_PASSWORD_ACK:
+ case RADIUS_ACCESS_PASSWORD_REJECT:
+ case RADIUS_ASCEND_ACCESS_EVENT_RESPONSE:
+ case RADIUS_DISCONNECT_REQUEST_ACK:
+ case RADIUS_DISCONNECT_REQUEST_NAK:
+ case RADIUS_CHANGE_FILTER_REQUEST_ACK:
+ case RADIUS_CHANGE_FILTER_REQUEST_NAK:
+ if (tree)
+ {
+ hidden_item = proto_tree_add_boolean(radius_tree, hf_radius_rsp, tvb, 0, 0, TRUE);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
+ }
+ /* Check for RADIUS response. A response must match a call that
+ * we've seen, and the response must be sent to the same
+ * port and address that the call came from.
+ *
+ * Because it is UDP and the reply can come from any IP
+ * and port (not necessarly the request dest), we only
+ * track the source IP and port of the request to match
+ * the reply.
+ */
+
+ /* XXX - can we just use NO_ADDR_B? Unfortunately,
+ * you currently still have to pass a non-null
+ * pointer for the second address argument even
+ * if you do that.
+ */
+ conversation = find_conversation(pinfo->fd->num, &null_address,
+ &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
+ if (conversation != NULL)
+ {
+ /* Look only for matching request, if
+ matching conversation is available. */
/* Prepare the key data */
radius_call_key.code = rh.rh_code;
radius_call_key.ident = rh.rh_ident;
radius_call_key.conversation = conversation;
radius_call_key.req_time = pinfo->fd->abs_ts;
- /* Look up the request */
radius_call = g_hash_table_lookup(radius_calls, &radius_call_key);
- if (radius_call != NULL)
+ if (radius_call)
{
- /* We've seen a request with this ID, with the same
- destination, before - but was it *this* request? */
- if (pinfo->fd->num != radius_call->req_num)
+ /* Indicate the frame to which this is a reply. */
+ if (radius_call->req_num)
{
- /* No, so it's a duplicate request. Mark it as such. */
- rad_info->is_duplicate = TRUE;
+ rad_info->request_available = TRUE;
rad_info->req_num = radius_call->req_num;
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- col_append_fstr(pinfo->cinfo, COL_INFO,
- ", Duplicate Request ID:%u",
- rh.rh_ident);
- }
- if (tree)
- {
- proto_item* item;
- hidden_item = proto_tree_add_uint(radius_tree, hf_radius_dup, tvb, 0,0, rh.rh_ident);
- PROTO_ITEM_SET_HIDDEN(hidden_item);
- item = proto_tree_add_uint(radius_tree, hf_radius_req_dup, tvb, 0,0, rh.rh_ident);
- PROTO_ITEM_SET_GENERATED(item);
- }
- }
- }
- else
- {
- /* Prepare the value data.
- "req_num" and "rsp_num" are frame numbers;
- frame numbers are 1-origin, so we use 0
- to mean "we don't yet know in which frame
- the reply for this call appears". */
- new_radius_call_key = se_alloc(sizeof(radius_call_info_key));
- *new_radius_call_key = radius_call_key;
- radius_call = se_alloc(sizeof(radius_call_t));
- radius_call->req_num = pinfo->fd->num;
- radius_call->rsp_num = 0;
- radius_call->ident = rh.rh_ident;
- radius_call->code = rh.rh_code;
- radius_call->responded = FALSE;
- radius_call->req_time=pinfo->fd->abs_ts;
- radius_call->rspcode = 0;
-
- /* Store it */
- g_hash_table_insert(radius_calls, new_radius_call_key, radius_call);
- }
- if (radius_call && radius_call->rsp_num)
- {
- proto_item* item = proto_tree_add_uint_format(radius_tree, hf_radius_rsp_frame,
- tvb, 0, 0, radius_call->rsp_num,
- "The response to this request is in frame %u",
- radius_call->rsp_num);
- PROTO_ITEM_SET_GENERATED(item);
- }
- break;
- case RADIUS_ACCESS_ACCEPT:
- case RADIUS_ACCESS_REJECT:
- case RADIUS_ACCOUNTING_RESPONSE:
- case RADIUS_ACCESS_PASSWORD_ACK:
- case RADIUS_ACCESS_PASSWORD_REJECT:
- case RADIUS_ASCEND_ACCESS_EVENT_RESPONSE:
- case RADIUS_DISCONNECT_REQUEST_ACK:
- case RADIUS_DISCONNECT_REQUEST_NAK:
- case RADIUS_CHANGE_FILTER_REQUEST_ACK:
- case RADIUS_CHANGE_FILTER_REQUEST_NAK:
- hidden_item = proto_tree_add_boolean(radius_tree, hf_radius_rsp, tvb, 0, 0, TRUE);
- PROTO_ITEM_SET_HIDDEN(hidden_item);
- /* Check for RADIUS response. A response must match a call that
- * we've seen, and the response must be sent to the same
- * port and address that the call came from.
- *
- * Because it is UDP and the reply can come from any IP
- * and port (not necessarly the request dest), we only
- * track the source IP and port of the request to match
- * the reply.
- */
+ radius_call->responded = TRUE;
- /* XXX - can we just use NO_ADDR_B? Unfortunately,
- * you currently still have to pass a non-null
- * pointer for the second address argument even
- * if you do that.
- */
- conversation = find_conversation(pinfo->fd->num, &null_address,
- &pinfo->dst, pinfo->ptype, pinfo->srcport,
- pinfo->destport, 0);
- if (conversation != NULL)
- {
- /* Look only for matching request, if
- matching conversation is available. */
- /* Prepare the key data */
- radius_call_key.code = rh.rh_code;
- radius_call_key.ident = rh.rh_ident;
- radius_call_key.conversation = conversation;
- radius_call_key.req_time = pinfo->fd->abs_ts;
-
- radius_call = g_hash_table_lookup(radius_calls, &radius_call_key);
- if (radius_call)
- {
- /* Indicate the frame to which this is a reply. */
- if (radius_call->req_num)
+ if (tree)
{
+ nstime_t delta;
proto_item* item;
- rad_info->request_available = TRUE;
- rad_info->req_num = radius_call->req_num;
- radius_call->responded = TRUE;
-
- item = proto_tree_add_uint_format(radius_tree, hf_radius_req_frame,
- tvb, 0, 0, radius_call->req_num,
- "This is a response to a request in frame %u",
- radius_call->req_num);
+ item = proto_tree_add_uint_format(radius_tree,
+ hf_radius_req_frame, tvb, 0, 0,
+ radius_call->req_num,
+ "This is a response to a request in frame %u",
+ radius_call->req_num);
PROTO_ITEM_SET_GENERATED(item);
nstime_delta(&delta, &pinfo->fd->abs_ts, &radius_call->req_time);
item = proto_tree_add_time(radius_tree, hf_radius_time, tvb, 0, 0, &delta);
PROTO_ITEM_SET_GENERATED(item);
}
+ }
- if (radius_call->rsp_num == 0)
- {
- /* We have not yet seen a response to that call, so
- this must be the first response; remember its
- frame number. */
- radius_call->rsp_num = pinfo->fd->num;
- }
- else
+ if (radius_call->rsp_num == 0)
+ {
+ /* We have not yet seen a response to that call, so
+ this must be the first response; remember its
+ frame number. */
+ radius_call->rsp_num = pinfo->fd->num;
+ }
+ else
+ {
+ /* We have seen a response to this call - but was it
+ *this* response? (disregard provisional responses) */
+ if ( (radius_call->rsp_num != pinfo->fd->num) && (radius_call->rspcode == rh.rh_code) )
{
- /* We have seen a response to this call - but was it
- *this* response? (disregard provisional responses) */
- if ( (radius_call->rsp_num != pinfo->fd->num) && (radius_call->rspcode == rh.rh_code) )
+ /* No, so it's a duplicate response. Mark it as such. */
+ rad_info->is_duplicate = TRUE;
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ ", Duplicate Response ID:%u", rh.rh_ident);
+ }
+ if (tree)
{
- /* No, so it's a duplicate response. Mark it as such. */
- rad_info->is_duplicate = TRUE;
- if (check_col(pinfo->cinfo, COL_INFO))
- {
- col_append_fstr(pinfo->cinfo, COL_INFO,
- ", Duplicate Response ID:%u",
- rh.rh_ident);
- }
- if (tree)
- {
- proto_item* item;
- hidden_item = proto_tree_add_uint(radius_tree, hf_radius_dup, tvb, 0,0, rh.rh_ident);
- PROTO_ITEM_SET_HIDDEN(hidden_item);
- item = proto_tree_add_uint(radius_tree, hf_radius_rsp_dup,
- tvb, 0, 0, rh.rh_ident);
- PROTO_ITEM_SET_GENERATED(item);
- }
+ proto_item* item;
+ hidden_item = proto_tree_add_uint(radius_tree,
+ hf_radius_dup, tvb, 0,0, rh.rh_ident);
+ PROTO_ITEM_SET_HIDDEN(hidden_item);
+ item = proto_tree_add_uint(radius_tree,
+ hf_radius_rsp_dup, tvb, 0, 0, rh.rh_ident);
+ PROTO_ITEM_SET_GENERATED(item);
}
}
- /* Now store the response code (after comparison above) */
- radius_call->rspcode = rh.rh_code;
- rad_info->rspcode = rh.rh_code;
}
+ /* Now store the response code (after comparison above) */
+ radius_call->rspcode = rh.rh_code;
+ rad_info->rspcode = rh.rh_code;
}
- break;
- default:
- break;
- }
-
- if (radius_call)
- {
- rad_info->req_time.secs = radius_call->req_time.secs;
- rad_info->req_time.nsecs = radius_call->req_time.nsecs;
- }
+ }
+ break;
+ default:
+ break;
+ }
- if (avplength > 0) {
- /* list the attribute value pairs */
- avptf = proto_tree_add_text(radius_tree, tvb, HDR_LENGTH,
- avplength, "Attribute Value Pairs");
- avptree = proto_item_add_subtree(avptf, ett_radius_avp);
+ if (radius_call)
+ {
+ rad_info->req_time.secs = radius_call->req_time.secs;
+ rad_info->req_time.nsecs = radius_call->req_time.nsecs;
+ }
- dissect_attribute_value_pairs(avptree, pinfo, tvb, HDR_LENGTH,
- avplength);
- }
+ if (tree && avplength > 0)
+ {
+ /* list the attribute value pairs */
+ avptf = proto_tree_add_text(radius_tree, tvb, HDR_LENGTH,
+ avplength, "Attribute Value Pairs");
+ avptree = proto_item_add_subtree(avptf, ett_radius_avp);
+ dissect_attribute_value_pairs(avptree, pinfo, tvb, HDR_LENGTH,
+ avplength);
}
-end_of_radius:
return tvb_length(tvb);
}