Wireshark-dev: Re: [Wireshark-dev] Radius Statistics Patch
From: "Anders Broman" <a.broman@xxxxxxxxx>
Date: Tue, 24 Oct 2006 07:24:34 +0200
Checked in. BR Anders -----Ursprungligt meddelande----- Från: wireshark-dev-bounces@xxxxxxxxxxxxx [mailto:wireshark-dev-bounces@xxxxxxxxxxxxx] För Alejandro Vaquero Skickat: den 23 oktober 2006 17:43 Till: Developer support list for Wireshark Ämne: Re: [Wireshark-dev] Radius Statistics Patch Here it is... LEGO wrote: > Alejandro, > Could you (g)zip the patch and send it back? > > On 10/23/06, Alejandro Vaquero <alejandrovaquero@xxxxxxxxx> wrote: > >> Hi All, >> find attached a patch for the Radius dissector to add statistics in >> the "Service Response Time" menu and the tshark stats. >> >> Regards >> Alejandro >> >> >> Index: config.nmake >> =================================================================== >> --- config.nmake (revision 19652) >> +++ config.nmake (working copy) >> @@ -205,14 +205,16 @@ >> # If you don't have PORTAUDIO, comment this line out, so that >> # PORTAUDIO_DIR isn't defined. >> # >> -PORTAUDIO_DIR=$(WIRESHARK_LIBS)\portaudio_v18_1 >> +#PORTAUDIO_DIR=$(WIRESHARK_LIBS)\portaudio_v18_1 >> +PORTAUDIO_DIR=$(WIRESHARK_LIBS)\portaudio_v19 >> + >> #PORTAUDIO_DIR=$(WIRESHARK_LIBS)\portaudio_v19 >> >> # >> # Version number of PortAudio >> # >> -PORTAUDIO_VERSION=18 >> -#PORTAUDIO_VERSION=19 >> +#PORTAUDIO_VERSION=18 >> +PORTAUDIO_VERSION=19 >> >> # >> # Mandatory for GTK >= 2: Iconv >> Index: epan/dissectors/packet-radius.c >> =================================================================== >> --- epan/dissectors/packet-radius.c (revision 19652) >> +++ epan/dissectors/packet-radius.c (working copy) >> @@ -4,6 +4,7 @@ >> * Copyright 1999 Johan Feyaerts >> * Changed 03/12/2003 Rui Carmo (http://the.taoofmac.com - added all 3GPP VSAs, some parsing) >> * Changed 07/2005 Luis Ontanon <luis.ontanon@xxxxxxxxx> - use FreeRADIUS' dictionary >> + * Changed 10/2006 Alejandro Vaquero <alejandrovaquero@xxxxxxxxx> - add Conversations support >> * >> * $Id$ >> * >> @@ -60,6 +61,8 @@ >> #include <epan/crypt-md5.h> >> #include <epan/sminmpec.h> >> #include <epan/filesystem.h> >> +#include <epan/conversation.h> >> +#include <epan/tap.h> >> #include <epan/addr_resolv.h> >> #include <epan/emem.h> >> >> @@ -86,38 +89,20 @@ >> #define UDP_PORT_RADACCT 1646 >> #define UDP_PORT_RADACCT_NEW 1813 >> >> -#define RADIUS_ACCESS_REQUEST 1 >> -#define RADIUS_ACCESS_ACCEPT 2 >> -#define RADIUS_ACCESS_REJECT 3 >> -#define RADIUS_ACCOUNTING_REQUEST 4 >> -#define RADIUS_ACCOUNTING_RESPONSE 5 >> -#define RADIUS_ACCOUNTING_STATUS 6 >> -#define RADIUS_ACCESS_PASSWORD_REQUEST 7 >> -#define RADIUS_ACCESS_PASSWORD_ACK 8 >> -#define RADIUS_ACCESS_PASSWORD_REJECT 9 >> -#define RADIUS_ACCOUNTING_MESSAGE 10 >> -#define RADIUS_ACCESS_CHALLENGE 11 >> -#define RADIUS_STATUS_SERVER 12 >> -#define RADIUS_STATUS_CLIENT 13 >> +static radius_dictionary_t* dict = NULL; >> >> -#define RADIUS_VENDOR_SPECIFIC_CODE 26 >> -#define RADIUS_ASCEND_ACCESS_NEXT_CODE 29 >> -#define RADIUS_ASCEND_ACCESS_NEW_PIN 30 >> -#define RADIUS_ASCEND_PASSWORD_EXPIRED 32 >> -#define RADIUS_ASCEND_ACCESS_EVENT_REQUEST 33 >> -#define RADIUS_ASCEND_ACCESS_EVENT_RESPONSE 34 >> -#define RADIUS_DISCONNECT_REQUEST 40 >> -#define RADIUS_DISCONNECT_REQUEST_ACK 41 >> -#define RADIUS_DISCONNECT_REQUEST_NAK 42 >> -#define RADIUS_CHANGE_FILTER_REQUEST 43 >> -#define RADIUS_CHANGE_FILTER_REQUEST_ACK 44 >> -#define RADIUS_CHANGE_FILTER_REQUEST_NAK 45 >> -#define RADIUS_EAP_MESSAGE_CODE 79 >> -#define RADIUS_RESERVED 255 >> +static int proto_radius = -1; >> >> -static radius_dictionary_t* dict = NULL; >> +static int hf_radius_req = -1; >> +static int hf_radius_rsp = -1; >> +static int hf_radius_req_frame = -1; >> +static int hf_radius_rsp_frame = -1; >> +static int hf_radius_time = -1; >> >> -static int proto_radius = -1; >> +static int hf_radius_dup = -1; >> +static int hf_radius_req_dup = -1; >> +static int hf_radius_rsp_dup = -1; >> + >> static int hf_radius_id = -1; >> static int hf_radius_code = -1; >> static int hf_radius_length = -1; >> @@ -134,6 +119,11 @@ >> static gint ett_radius_avp = -1; >> static gint ett_eap = -1; >> >> +/* >> + * Define the tap for radius >> + */ >> +static int radius_tap = -1; >> + >> radius_vendor_info_t no_vendor = {"Unknown Vendor",0,NULL,-1}; >> >> radius_attr_info_t no_dictionary_entry = {"Unknown-Attribute",0,FALSE,FALSE,radius_octets, NULL, NULL, -1, -1, -1, -1, -1 }; >> @@ -150,6 +140,8 @@ >> >> static const value_string* radius_vendors = NULL; >> >> +static radius_info_t rad_info; >> + >> static const value_string radius_vals[] = >> { >> {RADIUS_ACCESS_REQUEST, "Access-Request"}, >> @@ -181,6 +173,67 @@ >> {0, NULL} >> }; >> >> +/* >> + * Init Hash table stuff for converation >> + */ >> + >> +typedef struct _radius_call_info_key >> +{ >> + guint code; >> + guint ident; >> + conversation_t *conversation; >> + nstime_t req_time; >> +} radius_call_info_key; >> + >> +static GMemChunk *radius_call_info_key_chunk; >> +static GMemChunk *radius_call_info_value_chunk; >> +static GHashTable *radius_calls; >> + >> +/* Compare 2 keys */ >> +static gint radius_call_equal(gconstpointer k1, gconstpointer k2) >> +{ >> + const radius_call_info_key* key1 = (const radius_call_info_key*) k1; >> + const radius_call_info_key* key2 = (const radius_call_info_key*) k2; >> + >> + if (key1->ident == key2->ident && key1->conversation == key2->conversation) { >> + nstime_t delta; >> + >> + nstime_delta(&delta, &key1->req_time, &key2->req_time); >> + if (abs(nstime_to_sec(&delta)) > (double) 5) return 0; >> + >> + if (key1->code == key2->code) >> + return 1; >> + /* check the request and response are of the same code type */ >> + if (key1->code == RADIUS_ACCESS_REQUEST && ( key2->code == RADIUS_ACCESS_ACCEPT || key2->code == RADIUS_ACCESS_REJECT ) ) >> + return 1; >> + >> + if (key1->code == RADIUS_ACCOUNTING_REQUEST && key2->code == RADIUS_ACCOUNTING_RESPONSE ) >> + return 1; >> + >> + if (key1->code == RADIUS_ACCESS_PASSWORD_REQUEST && ( key2->code == RADIUS_ACCESS_PASSWORD_ACK || key2->code == RADIUS_ACCESS_PASSWORD_REJECT ) ) >> + return 1; >> + >> + if (key1->code == RADIUS_ASCEND_ACCESS_EVENT_REQUEST && key2->code == RADIUS_ASCEND_ACCESS_EVENT_RESPONSE ) >> + return 1; >> + >> + if (key1->code == RADIUS_DISCONNECT_REQUEST && ( key2->code == RADIUS_DISCONNECT_REQUEST_ACK || key2->code == RADIUS_DISCONNECT_REQUEST_NAK ) ) >> + return 1; >> + >> + if (key1->code == RADIUS_CHANGE_FILTER_REQUEST && ( key2->code == RADIUS_CHANGE_FILTER_REQUEST_ACK || key2->code == RADIUS_CHANGE_FILTER_REQUEST_NAK ) ) >> + return 1; >> + } >> + return 0; >> +} >> + >> +/* Calculate a hash key */ >> +static guint radius_call_hash(gconstpointer k) >> +{ >> + const radius_call_info_key* key = (const radius_call_info_key*) k; >> + >> + return key->ident + /*key->code + */ key->conversation->index; >> +} >> + >> + >> static const gchar *dissect_framed_ip_address(proto_tree* tree, tvbuff_t* tvb) { >> int len; >> guint32 ip; >> @@ -790,7 +843,24 @@ >> guint rhident; >> guint avplength; >> e_radiushdr rh; >> - >> + >> + conversation_t* conversation; >> + radius_call_info_key radius_call_key; >> + radius_call_info_key *new_radius_call_key = NULL; >> + radius_call_t *radius_call = NULL; >> + nstime_t delta; >> + static address null_address = { AT_NONE, 0, NULL }; >> + >> + /* Initialise stat info for passing to tap */ >> + rad_info.code = 0; >> + rad_info.ident = 0; >> + rad_info.req_time.secs = 0; >> + rad_info.req_time.nsecs = 0; >> + rad_info.is_duplicate = FALSE; >> + rad_info.request_available = FALSE; >> + rad_info.req_num = 0; /* frame number request seen */ >> + rad_info.rspcode = 0; >> + >> if (check_col(pinfo->cinfo, COL_PROTOCOL)) >> col_set_str(pinfo->cinfo, COL_PROTOCOL, "RADIUS"); >> if (check_col(pinfo->cinfo, COL_INFO)) >> @@ -813,6 +883,10 @@ >> * is 4096. >> */ >> >> + /* tap stat info */ >> + rad_info.code = rhcode; >> + rad_info.ident = rhident; >> + >> if (check_col(pinfo->cinfo, COL_INFO)) >> { >> col_add_fstr(pinfo->cinfo,COL_INFO,"%s(%d) (id=%d, l=%d)", >> @@ -856,15 +930,225 @@ >> } >> tvb_memcpy(tvb,authenticator,4,AUTHENTICATOR_LENGTH); >> >> - 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); >> + if (tree) { >> + >> + /* Conversation support REQUEST/RESPONSES */ >> + switch (rhcode) >> + { >> + 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: >> + proto_tree_add_boolean_hidden(radius_tree, hf_radius_req, tvb, 0, 0, TRUE); >> + /* 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 = rhcode; >> + radius_call_key.ident = rhident; >> + 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) >> + { >> + /* 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", >> + rhident); >> + } >> + if (tree) >> + { >> + proto_item* item; >> + proto_tree_add_uint_hidden(radius_tree, hf_radius_dup, tvb, 0,0, rhident); >> + item = proto_tree_add_uint(radius_tree, hf_radius_req_dup, tvb, 0,0, rhident); >> + 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 = g_mem_chunk_alloc(radius_call_info_key_chunk); >> + *new_radius_call_key = radius_call_key; >> + radius_call = g_mem_chunk_alloc(radius_call_info_value_chunk); >> + radius_call->req_num = pinfo->fd->num; >> + radius_call->rsp_num = 0; >> + radius_call->ident = rhident; >> + radius_call->code = rhcode; >> + 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: >> + proto_tree_add_boolean_hidden(radius_tree, hf_radius_rsp, tvb, 0, 0, TRUE); >> + /* 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 = rhcode; >> + radius_call_key.ident = rhident; >> + 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) >> + { >> + 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); >> + 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 >> + { >> + /* 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 == rhcode) ) >> + { >> + /* 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", >> + rhident); >> + } >> + if (tree) >> + { >> + proto_item* item; >> + proto_tree_add_uint_hidden(radius_tree, hf_radius_dup, tvb, 0,0, rhident); >> + item = proto_tree_add_uint(radius_tree, hf_radius_rsp_dup, >> + tvb, 0, 0, rhident); >> + PROTO_ITEM_SET_GENERATED(item); >> + } >> + } >> + } >> + /* Now store the response code (after comparison above) */ >> + radius_call->rspcode = rhcode; >> + rad_info.rspcode = rhcode; >> + } >> + } >> + 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; >> + } >> + >> + 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); >> + >> + dissect_attribute_value_pairs(avptree, pinfo, tvb, HDR_LENGTH, >> + avplength); >> + } >> } >> + >> + tap_queue_packet(radius_tap, pinfo, &rad_info); >> } >> >> >> @@ -1034,10 +1318,62 @@ >> } >> } >> >> +/* Discard and init any state we've saved */ >> +static void >> +radius_init_protocol(void) >> +{ >> + if (radius_calls != NULL) >> + { >> + g_hash_table_destroy(radius_calls); >> + radius_calls = NULL; >> + } >> + if (radius_call_info_key_chunk != NULL) >> + { >> + g_mem_chunk_destroy(radius_call_info_key_chunk); >> + radius_call_info_key_chunk = NULL; >> + } >> + if (radius_call_info_value_chunk != NULL) >> + { >> + g_mem_chunk_destroy(radius_call_info_value_chunk); >> + radius_call_info_value_chunk = NULL; >> + } >> + >> + radius_calls = g_hash_table_new(radius_call_hash, radius_call_equal); >> + radius_call_info_key_chunk = g_mem_chunk_new("call_info_key_chunk", >> + sizeof(radius_call_info_key), >> + 200 * sizeof(radius_call_info_key), >> + G_ALLOC_ONLY); >> + radius_call_info_value_chunk = g_mem_chunk_new("call_info_value_chunk", >> + sizeof(radius_call_t), >> + 200 * sizeof(radius_call_t), >> + G_ALLOC_ONLY); >> +} >> + >> void >> proto_register_radius(void) >> { >> hf_register_info base_hf[] = { >> + >> + { &hf_radius_req, >> + { "Request", "radius.req", FT_BOOLEAN, BASE_NONE, NULL, 0x0, >> + "TRUE if RADIUS request", HFILL }}, >> + >> + { &hf_radius_rsp, >> + { "Response", "radius.rsp", FT_BOOLEAN, BASE_NONE, NULL, 0x0, >> + "TRUE if RADIUS response", HFILL }}, >> + >> + { &hf_radius_req_frame, >> + { "Request Frame", "radius.reqframe", FT_FRAMENUM, BASE_NONE, NULL, 0, >> + "Request Frame", HFILL }}, >> + >> + { &hf_radius_rsp_frame, >> + { "Response Frame", "radius.rspframe", FT_FRAMENUM, BASE_NONE, NULL, 0, >> + "Response Frame", HFILL }}, >> + >> + { &hf_radius_time, >> + { "Time from request", "radius.time", FT_RELATIVE_TIME, BASE_NONE, NULL, 0, >> + "Timedelta between Request and Response", HFILL }}, >> + >> { &hf_radius_code, >> { "Code","radius.code", FT_UINT8, BASE_DEC, VALS(radius_vals), 0x0, >> "", HFILL }}, >> @@ -1082,7 +1418,18 @@ >> { "Cosine-VCI","radius.Cosine-Vci", FT_UINT16, BASE_DEC, NULL, 0x0, >> "", HFILL }}, >> >> - >> + { &hf_radius_dup, >> + { "Duplicate Message", "radius.dup", FT_UINT32, BASE_DEC, NULL, 0x0, >> + "Duplicate Message", HFILL }}, >> + >> + { &hf_radius_req_dup, >> + { "Duplicate Request", "radius.req.dup", FT_UINT32, BASE_DEC, NULL, 0x0, >> + "Duplicate Request", HFILL }}, >> + >> + { &hf_radius_rsp_dup, >> + { "Duplicate Response", "radius.rsp.dup", FT_UINT32, BASE_DEC, NULL, 0x0, >> + "Duplicate Response", HFILL }}, >> + >> }; >> >> gint *base_ett[] = { >> @@ -1154,6 +1501,8 @@ >> proto_register_field_array(proto_radius,(hf_register_info*)(ri.hf->data),ri. hf->len); >> proto_register_subtree_array((gint**)(ri.ett->data), ri.ett->len); >> >> + register_init_routine(&radius_init_protocol); >> + >> g_array_free(ri.hf,FALSE); >> g_array_free(ri.ett,FALSE); >> g_array_free(ri.vend_vs,FALSE); >> @@ -1170,6 +1519,7 @@ >> >> no_vendor.attrs_by_id = g_hash_table_new(g_direct_hash,g_direct_equal); >> >> + radius_tap = register_tap("radius"); >> } >> >> void >> Index: epan/dissectors/packet-radius.h >> =================================================================== >> --- epan/dissectors/packet-radius.h (revision 19652) >> +++ epan/dissectors/packet-radius.h (working copy) >> @@ -23,6 +23,35 @@ >> * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. >> */ >> >> +#define RADIUS_ACCESS_REQUEST 1 >> +#define RADIUS_ACCESS_ACCEPT 2 >> +#define RADIUS_ACCESS_REJECT 3 >> +#define RADIUS_ACCOUNTING_REQUEST 4 >> +#define RADIUS_ACCOUNTING_RESPONSE 5 >> +#define RADIUS_ACCOUNTING_STATUS 6 >> +#define RADIUS_ACCESS_PASSWORD_REQUEST 7 >> +#define RADIUS_ACCESS_PASSWORD_ACK 8 >> +#define RADIUS_ACCESS_PASSWORD_REJECT 9 >> +#define RADIUS_ACCOUNTING_MESSAGE 10 >> +#define RADIUS_ACCESS_CHALLENGE 11 >> +#define RADIUS_STATUS_SERVER 12 >> +#define RADIUS_STATUS_CLIENT 13 >> + >> +#define RADIUS_VENDOR_SPECIFIC_CODE 26 >> +#define RADIUS_ASCEND_ACCESS_NEXT_CODE 29 >> +#define RADIUS_ASCEND_ACCESS_NEW_PIN 30 >> +#define RADIUS_ASCEND_PASSWORD_EXPIRED 32 >> +#define RADIUS_ASCEND_ACCESS_EVENT_REQUEST 33 >> +#define RADIUS_ASCEND_ACCESS_EVENT_RESPONSE 34 >> +#define RADIUS_DISCONNECT_REQUEST 40 >> +#define RADIUS_DISCONNECT_REQUEST_ACK 41 >> +#define RADIUS_DISCONNECT_REQUEST_NAK 42 >> +#define RADIUS_CHANGE_FILTER_REQUEST 43 >> +#define RADIUS_CHANGE_FILTER_REQUEST_ACK 44 >> +#define RADIUS_CHANGE_FILTER_REQUEST_NAK 45 >> +#define RADIUS_EAP_MESSAGE_CODE 79 >> +#define RADIUS_RESERVED 255 >> + >> typedef struct _radius_vendor_info_t { >> const gchar *name; >> guint code; >> @@ -71,3 +100,28 @@ >> >> /* from radius_dict.l */ >> radius_dictionary_t* radius_load_dictionary (gchar* directory, const gchar* filename, gchar** err_str); >> + >> +/* Item of request list */ >> +typedef struct _radius_call_t >> +{ >> + guint code; >> + guint ident; >> + >> + guint32 req_num; /* frame number request seen */ >> + guint32 rsp_num; /* frame number response seen */ >> + guint32 rspcode; >> + nstime_t req_time; >> + gboolean responded; >> +} radius_call_t; >> + >> +/* Container for tapping relevant data */ >> +typedef struct _radius_info_t >> +{ >> + guint code; >> + guint ident; >> + nstime_t req_time; >> + gboolean is_duplicate; >> + gboolean request_available; >> + guint32 req_num; /* frame number request seen */ >> + guint32 rspcode; >> +} radius_info_t; >> \ No newline at end of file >> Index: gtk/Makefile.common >> =================================================================== >> --- gtk/Makefile.common (revision 19652) >> +++ gtk/Makefile.common (working copy) >> @@ -164,6 +164,7 @@ >> mtp3_stat.c \ >> mtp3_summary.c \ >> ncp_stat.c \ >> + radius_stat.c \ >> rpc_progs.c \ >> rpc_stat.c \ >> rtp_analysis.c \ >> Index: gtk/radius_stat.c >> =================================================================== >> --- gtk/radius_stat.c (revision 0) >> +++ gtk/radius_stat.c (revision 0) >> @@ -0,0 +1,373 @@ >> +/* radius_stat.c >> + * radius-statistics for Wireshark >> + * Copyright 2006 Alejandro Vaquero <alejandrovaquero@xxxxxxxxx> >> + * >> + * >> + * >> + * Wireshark - Network traffic analyzer >> + * By Gerald Combs <gerald@xxxxxxxxxxxxx> >> + * 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. >> + */ >> + >> +#ifdef HAVE_CONFIG_H >> +# include "config.h" >> +#endif >> + >> +#ifdef HAVE_SYS_TYPES_H >> +# include <sys/types.h> >> +#endif >> + >> +#include <string.h> >> + >> +#include <gtk/gtk.h> >> + >> +#include <epan/packet_info.h> >> +#include <epan/epan.h> >> +#include <epan/value_string.h> >> + >> +#include <epan/tap.h> >> +#include "../register.h" >> +#include <epan/dissectors/packet-radius.h> >> +#include "../timestats.h" >> +#include "gui_stat_util.h" >> +#include "compat_macros.h" >> +#include "../simple_dialog.h" >> +#include "dlg_utils.h" >> +#include "../file.h" >> +#include "../globals.h" >> +#include "../stat_menu.h" >> +#include "../tap_dfilter_dlg.h" >> +#include "gui_utils.h" >> + >> + >> +#define NUM_TIMESTATS 8 >> +#define NUM_COLUMNS 11 >> + >> +/* Summary of response-time calculations*/ >> +typedef struct _radius_rtd_t { >> + guint32 open_req_num; >> + guint32 disc_rsp_num; >> + guint32 req_dup_num; >> + guint32 rsp_dup_num; >> + timestat_t stats; >> +} radius_rtd_t; >> + >> +/* used to keep track of the statistics for an entire program interface */ >> +typedef struct _radiusstat_t { >> + GtkWidget *win; >> + GtkWidget *vbox; >> + char *filter; >> + GtkWidget *scrolled_window; >> + GtkCList *table; >> + radius_rtd_t radius_rtd[NUM_TIMESTATS]; >> +} radiusstat_t; >> + >> +static const value_string radius_message_code[] = { >> + { 0, "Overall"}, >> + { 1, "Access"}, >> + { 2, "Accounting"}, >> + { 3, "Access Password"}, >> + { 4, "Ascend Access Event"}, >> + { 5, "Diconnect"}, >> + { 6, "Change Filter"}, >> + { 7, "Other"}, >> +}; >> + >> +typedef enum _radius_category { >> + OVERALL, >> + ACCESS, >> + ACCOUNTING, >> + ACCESS_PASSWORD, >> + ASCEND_ACCESS_EVENT, >> + DISCONNECT, >> + CHANGE_FILTER, >> + OTHERS >> +}radius_category; >> + >> +static void >> +radiusstat_reset(void *prs) >> +{ >> + radiusstat_t *rs=(radiusstat_t *)prs; >> + int i; >> + >> + >> + for(i=0;i<NUM_TIMESTATS;i++) { >> + rs->radius_rtd[i].stats.num=0; >> + rs->radius_rtd[i].stats.min_num=0; >> + rs->radius_rtd[i].stats.max_num=0; >> + rs->radius_rtd[i].stats.min.secs=0; >> + rs->radius_rtd[i].stats.min.nsecs=0; >> + rs->radius_rtd[i].stats.max.secs=0; >> + rs->radius_rtd[i].stats.max.nsecs=0; >> + rs->radius_rtd[i].stats.tot.secs=0; >> + rs->radius_rtd[i].stats.tot.nsecs=0; >> + rs->radius_rtd[i].open_req_num = 0; >> + rs->radius_rtd[i].disc_rsp_num = 0; >> + rs->radius_rtd[i].req_dup_num = 0; >> + rs->radius_rtd[i].rsp_dup_num = 0; >> + } >> + >> +} >> + >> + >> +static int >> +radiusstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pri) >> +{ >> + radiusstat_t *rs=(radiusstat_t *)prs; >> + const radius_info_t *ri=pri; >> + nstime_t delta; >> + radius_category radius_cat = OTHERS; >> + >> + switch (ri->code) { >> + case RADIUS_ACCESS_REQUEST: >> + case RADIUS_ACCESS_ACCEPT: >> + case RADIUS_ACCESS_REJECT: >> + radius_cat = ACCESS; >> + break; >> + case RADIUS_ACCOUNTING_REQUEST: >> + case RADIUS_ACCOUNTING_RESPONSE: >> + radius_cat = ACCOUNTING; >> + break; >> + case RADIUS_ACCESS_PASSWORD_REQUEST: >> + case RADIUS_ACCESS_PASSWORD_ACK: >> + case RADIUS_ACCESS_PASSWORD_REJECT: >> + radius_cat = ACCESS_PASSWORD; >> + break; >> + case RADIUS_ASCEND_ACCESS_EVENT_REQUEST: >> + case RADIUS_ASCEND_ACCESS_EVENT_RESPONSE: >> + radius_cat = ASCEND_ACCESS_EVENT; >> + break; >> + case RADIUS_DISCONNECT_REQUEST: >> + case RADIUS_DISCONNECT_REQUEST_ACK: >> + case RADIUS_DISCONNECT_REQUEST_NAK: >> + radius_cat = DISCONNECT; >> + break; >> + case RADIUS_CHANGE_FILTER_REQUEST: >> + case RADIUS_CHANGE_FILTER_REQUEST_ACK: >> + case RADIUS_CHANGE_FILTER_REQUEST_NAK: >> + radius_cat = CHANGE_FILTER; >> + break; >> + } >> + >> + switch (ri->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(ri->is_duplicate){ >> + /* Duplicate is ignored */ >> + rs->radius_rtd[OVERALL].req_dup_num++; >> + rs->radius_rtd[radius_cat].req_dup_num++; >> + return 0; >> + } >> + else { >> + rs->radius_rtd[OVERALL].open_req_num++; >> + rs->radius_rtd[radius_cat].open_req_num++; >> + return 0; >> + } >> + 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(ri->is_duplicate){ >> + /* Duplicate is ignored */ >> + rs->radius_rtd[OVERALL].rsp_dup_num++; >> + rs->radius_rtd[radius_cat].rsp_dup_num++; >> + return 0; >> + } >> + else if (!ri->request_available) { >> + /* no request was seen */ >> + rs->radius_rtd[OVERALL].disc_rsp_num++; >> + rs->radius_rtd[radius_cat].disc_rsp_num++; >> + return 0; >> + } >> + else { >> + rs->radius_rtd[OVERALL].open_req_num--; >> + rs->radius_rtd[radius_cat].open_req_num--; >> + /* calculate time delta between request and response */ >> + nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time); >> + >> + time_stat_update(&(rs->radius_rtd[OVERALL].stats),&delta, pinfo); >> + time_stat_update(&(rs->radius_rtd[radius_cat].stats),&delta, pinfo); >> + >> + return 1; >> + } >> + break; >> + >> + default: >> + return 0; >> + break; >> + } >> +} >> + >> +static void >> +radiusstat_draw(void *prs) >> +{ >> + radiusstat_t *rs=(radiusstat_t *)prs; >> + int i; >> + /* gtk1 using a scrollable clist*/ >> + char *str[NUM_COLUMNS]; >> + >> + for(i=0;i<NUM_COLUMNS;i++) { >> + str[i]=g_malloc(sizeof(char[256])); >> + } >> + >> + /* clear list before printing */ >> + gtk_clist_clear(rs->table); >> + >> + for(i=0;i<NUM_TIMESTATS;i++) { >> + /* nothing seen, nothing to do */ >> + if(rs->radius_rtd[i].stats.num==0){ >> + continue; >> + } >> + >> + g_snprintf(str[0], sizeof(char[256]), "%s", val_to_str(i,radius_message_code,"Other")); >> + g_snprintf(str[1], sizeof(char[256]), "%d", rs->radius_rtd[i].stats.num); >> + g_snprintf(str[2], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(rs->radius_rtd[i].stats.min))); >> + g_snprintf(str[3], sizeof(char[256]), "%8.2f msec", nstime_to_msec(&(rs->radius_rtd[i].stats.max))); >> + g_snprintf(str[4], sizeof(char[256]), "%8.2f msec", get_average(&(rs->radius_rtd[i].stats.tot), rs->radius_rtd[i].stats.num)); >> + g_snprintf(str[5], sizeof(char[256]), "%6u", rs->radius_rtd[i].stats.min_num); >> + g_snprintf(str[6], sizeof(char[256]), "%6u", rs->radius_rtd[i].stats.max_num); >> + g_snprintf(str[7], sizeof(char[256]), "%4u", rs->radius_rtd[i].open_req_num); >> + g_snprintf(str[8], sizeof(char[256]), "%4u", rs->radius_rtd[i].disc_rsp_num); >> + g_snprintf(str[9], sizeof(char[256]), "%4u (%4.2f%%)", rs->radius_rtd[i].req_dup_num, >> + rs->radius_rtd[i].stats.num?((double)rs->radius_rtd[i].req_dup_num*100)/(dou ble)rs->radius_rtd[i].stats.num:0); >> + g_snprintf(str[10], sizeof(char[256]), "%4u (%4.2f%%)", rs->radius_rtd[i].rsp_dup_num, >> + rs->radius_rtd[i].stats.num?((double)rs->radius_rtd[i].rsp_dup_num*100)/(dou ble)rs->radius_rtd[i].stats.num:0); >> + >> + gtk_clist_append(rs->table, str); >> + } >> + >> + gtk_widget_show(GTK_WIDGET(rs->table)); >> + for(i=0;i<NUM_COLUMNS;i++) { >> + g_free(str[i]); >> + } >> +} >> + >> +void protect_thread_critical_region(void); >> +void unprotect_thread_critical_region(void); >> +static void >> +win_destroy_cb(GtkWindow *win _U_, gpointer data) >> +{ >> + radiusstat_t *rs=(radiusstat_t *)data; >> + >> + protect_thread_critical_region(); >> + remove_tap_listener(rs); >> + unprotect_thread_critical_region(); >> + >> + if(rs->filter){ >> + g_free(rs->filter); >> + rs->filter=NULL; >> + } >> + g_free(rs); >> +} >> + >> +static const gchar *titles[]={ >> + "Type", >> + "Messages", >> + "Min SRT", >> + "Max SRT", >> + "Avg SRT", >> + "Min in Frame", >> + "Max in Frame", >> + "Open Requests", >> + "Discarded Responses", >> + "Repeated Requests", >> + "Repeated Responses" }; >> + >> +static void >> +gtk_radiusstat_init(const char *optarg, void *userdata _U_) >> +{ >> + radiusstat_t *rs; >> + const char *filter=NULL; >> + GString *error_string; >> + GtkWidget *bt_close; >> + GtkWidget *bbox; >> + >> + if(strncmp(optarg,"radius,srt,",11) == 0){ >> + filter=optarg+11; >> + } else { >> + filter=""; >> + } >> + >> + rs=g_malloc(sizeof(radiusstat_t)); >> + rs->filter=g_strdup(filter); >> + >> + radiusstat_reset(rs); >> + >> + rs->win=window_new(GTK_WINDOW_TOPLEVEL, "RADIUS SRT"); >> + gtk_window_set_default_size(GTK_WINDOW(rs->win), 600, 150); >> + >> + rs->vbox=gtk_vbox_new(FALSE, 3); >> + >> + init_main_stat_window(rs->win, rs->vbox, "RADIUS Service Response Time (SRT) Statistics", filter); >> + >> + /* GTK1 using a scrollable clist*/ >> + /* init a scrolled window*/ >> + rs->scrolled_window = scrolled_window_new(NULL, NULL); >> + >> + rs->table = create_stat_table(rs->scrolled_window, rs->vbox, NUM_COLUMNS, titles); >> + >> + error_string=register_tap_listener("radius", rs, filter, radiusstat_reset, radiusstat_packet, radiusstat_draw); >> + if(error_string){ >> + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, error_string->str); >> + g_string_free(error_string, TRUE); >> + g_free(rs->filter); >> + g_free(rs); >> + return; >> + } >> + >> + /* Button row. */ >> + bbox = dlg_button_row_new(GTK_STOCK_CLOSE, NULL); >> + gtk_box_pack_start(GTK_BOX(rs->vbox), bbox, FALSE, FALSE, 0); >> + >> + bt_close = OBJECT_GET_DATA(bbox, GTK_STOCK_CLOSE); >> + window_set_cancel_button(rs->win, bt_close, window_cancel_button_cb); >> + >> + SIGNAL_CONNECT(rs->win, "delete_event", window_delete_event_cb, NULL); >> + SIGNAL_CONNECT(rs->win, "destroy", win_destroy_cb, rs); >> + >> + gtk_widget_show_all(rs->win); >> + window_present(rs->win); >> + >> + cf_retap_packets(&cfile, FALSE); >> +} >> + >> +static tap_dfilter_dlg radius_srt_dlg = { >> + "RADIUS Service Response Time (SRT) Statistics", >> + "radius,srt", >> + gtk_radiusstat_init, >> + -1 >> +}; >> + >> +void >> +register_tap_listener_gtkradiusstat(void) >> +{ >> + register_dfilter_stat(&radius_srt_dlg, "RADIUS", >> + REGISTER_STAT_GROUP_RESPONSE_TIME); >> +} >> Index: Makefile.common >> =================================================================== >> --- Makefile.common (revision 19652) >> +++ Makefile.common (working copy) >> @@ -110,6 +110,7 @@ >> tap-mgcpstat.c \ >> tap-protocolinfo.c \ >> tap-protohierstat.c \ >> + tap-radiusstat.c \ >> tap-rpcstat.c \ >> tap-rpcprogs.c \ >> tap-sctpchunkstat.c \ >> Index: tap-radiusstat.c >> =================================================================== >> --- tap-radiusstat.c (revision 0) >> +++ tap-radiusstat.c (revision 0) >> @@ -0,0 +1,226 @@ >> +/* tap-radiusstat.c >> + * Copyright 2006 Alejandro Vaquero <alejandrovaquero@xxxxxxxxx> >> + * >> + * >> + * >> + * Wireshark - Network traffic analyzer >> + * By Gerald Combs <gerald@xxxxxxxxxxxxx> >> + * 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. >> + */ >> + >> +#ifdef HAVE_CONFIG_H >> +# include "config.h" >> +#endif >> + >> +#include <stdio.h> >> + >> +#ifdef HAVE_SYS_TYPES_H >> +# include <sys/types.h> >> +#endif >> + >> +#include <string.h> >> +#include "epan/packet_info.h" >> +#include <epan/tap.h> >> +#include <epan/stat_cmd_args.h> >> +#include "epan/value_string.h" >> +#include "register.h" >> +#include <epan/dissectors/packet-radius.h> >> +#include "timestats.h" >> + >> +#define NUM_TIMESTATS 8 >> + >> +/* used to keep track of the statistics for an entire program interface */ >> +typedef struct _radiusstat_t { >> + char *filter; >> + timestat_t rtd[NUM_TIMESTATS]; >> + guint32 open_req_num; >> + guint32 disc_rsp_num; >> + guint32 req_dup_num; >> + guint32 rsp_dup_num; >> +} radiusstat_t; >> + >> +static const value_string radius_message_code[] = { >> + { 0, "Overall "}, >> + { 1, "Access "}, >> + { 2, "Accounting "}, >> + { 3, "Access Passw "}, >> + { 4, "Ascend Acce Ev"}, >> + { 5, "Diconnect "}, >> + { 6, "Change Filter "}, >> + { 7, "Other "}, >> +}; >> + >> +static int >> +radiusstat_packet(void *prs, packet_info *pinfo, epan_dissect_t *edt _U_, const void *pri) >> +{ >> + radiusstat_t *rs=(radiusstat_t *)prs; >> + const radius_info_t *ri=pri; >> + nstime_t delta; >> + >> + switch (ri->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(ri->is_duplicate){ >> + /* Duplicate is ignored */ >> + rs->req_dup_num++; >> + return 0; >> + } >> + else { >> + rs->open_req_num++; >> + return 0; >> + } >> + 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(ri->is_duplicate){ >> + /* Duplicate is ignored */ >> + rs->rsp_dup_num++; >> + return 0; >> + } >> + else if (!ri->request_available) { >> + /* no request was seen */ >> + rs->disc_rsp_num++; >> + return 0; >> + } >> + else { >> + rs->open_req_num--; >> + /* calculate time delta between request and response */ >> + nstime_delta(&delta, &pinfo->fd->abs_ts, &ri->req_time); >> + >> + time_stat_update(&(rs->rtd[0]),&delta, pinfo); >> + if (ri->code == RADIUS_ACCESS_ACCEPT || ri->code == RADIUS_ACCESS_REJECT) { >> + time_stat_update(&(rs->rtd[1]),&delta, pinfo); >> + } >> + else if (ri->code == RADIUS_ACCOUNTING_RESPONSE) { >> + time_stat_update(&(rs->rtd[2]),&delta, pinfo); >> + } >> + >> + >> + >> + else { >> + time_stat_update(&(rs->rtd[7]),&delta, pinfo); >> + } >> + >> + return 1; >> + } >> + break; >> + >> + default: >> + return 0; >> + break; >> + } >> +} >> + >> +static void >> +radiusstat_draw(void *prs) >> +{ >> + radiusstat_t *rs=(radiusstat_t *)prs; >> + int i; >> + >> + /* printing results */ >> + printf("\n"); >> + printf("==================================================================== =======================================\n"); >> + printf("RADIUS Response Time Delay (RTD) Statistics:\n"); >> + printf("Filter for statistics: %s\n",rs->filter?rs->filter:""); >> + printf("Duplicate requests: %u\n",rs->req_dup_num); >> + printf("Duplicate responses: %u\n",rs->rsp_dup_num); >> + printf("Open requests: %u\n",rs->open_req_num); >> + printf("Discarded responses: %u\n",rs->disc_rsp_num); >> + printf("Type | Messages | Min RTD | Max RTD | Avg RTD | Min in Frame | Max in Frame |\n"); >> + for(i=0;i<NUM_TIMESTATS;i++) { >> + if(rs->rtd[i].num) { >> + printf("%s | %7u | %8.2f msec | %8.2f msec | %8.2f msec | %10u | %10u |\n", >> + val_to_str(i,radius_message_code,"Other "),rs->rtd[i].num, >> + nstime_to_msec(&(rs->rtd[i].min)), nstime_to_msec(&(rs->rtd[i].max)), >> + get_average(&(rs->rtd[i].tot), rs->rtd[i].num), >> + rs->rtd[i].min_num, rs->rtd[i].max_num >> + ); >> + } >> + } >> + printf("==================================================================== =======================================\n"); >> +} >> + >> + >> +static void >> +radiusstat_init(const char *optarg, void* userdata _U_) >> +{ >> + radiusstat_t *rs; >> + int i; >> + const char *filter=NULL; >> + GString *error_string; >> + >> + if(!strncmp(optarg,"radius,rtd,",11)){ >> + filter=optarg+11; >> + } else { >> + filter=""; >> + } >> + >> + rs=g_malloc(sizeof(radiusstat_t)); >> + rs->filter=g_malloc(strlen(filter)+1); >> + strcpy(rs->filter, filter); >> + >> + for(i=0;i<NUM_TIMESTATS;i++) { >> + rs->rtd[i].num=0; >> + rs->rtd[i].min_num=0; >> + rs->rtd[i].max_num=0; >> + rs->rtd[i].min.secs=0; >> + rs->rtd[i].min.nsecs=0; >> + rs->rtd[i].max.secs=0; >> + rs->rtd[i].max.nsecs=0; >> + rs->rtd[i].tot.secs=0; >> + rs->rtd[i].tot.nsecs=0; >> + } >> + >> + rs->open_req_num=0; >> + rs->disc_rsp_num=0; >> + rs->req_dup_num=0; >> + rs->rsp_dup_num=0; >> + >> + error_string=register_tap_listener("radius", rs, filter, NULL, radiusstat_packet, radiusstat_draw); >> + if(error_string){ >> + /* error, we failed to attach to the tap. clean up */ >> + g_free(rs->filter); >> + g_free(rs); >> + >> + fprintf(stderr, "tshark: Couldn't register radius,rtd tap: %s\n", >> + error_string->str); >> + g_string_free(error_string, TRUE); >> + exit(1); >> + } >> +} >> + >> + >> +void >> +register_tap_listener_radiusstat(void) >> +{ >> + register_stat_cmd_arg("radius,rtd", radiusstat_init, NULL); >> +} >> + >> >> >> _______________________________________________ >> Wireshark-dev mailing list >> Wireshark-dev@xxxxxxxxxxxxx >> http://www.wireshark.org/mailman/listinfo/wireshark-dev >> >> >> > > >
- References:
- Re: [Wireshark-dev] Radius Statistics Patch
- From: Alejandro Vaquero
- Re: [Wireshark-dev] Radius Statistics Patch
- Prev by Date: Re: [Wireshark-dev] Small (but annoying) display issue
- Next by Date: [Wireshark-dev] Pending stuff for 0.99.4
- Previous by thread: Re: [Wireshark-dev] Radius Statistics Patch
- Next by thread: [Wireshark-dev] News.txt of the 0.99.4pre NSIS installer showing outdated 0.99.3 information!
- Index(es):