forked from osmocom/wireshark
From Andrej Kuehnal:
tap-diameter-avp.patch: - make diameter.cmd_code configurable rather than hard coded in - more fields in the output - documetation/man pages + usage examples - switch option parser from stdlib to glib to avoid troubles with M$ c++ diameter-dict.patch remove strage spaces in the AVP names. svn path=/trunk/; revision=32294
This commit is contained in:
parent
12e2df52e1
commit
e3a0cf1fcb
|
@ -58,7 +58,7 @@
|
||||||
<avp name="3GPP-IPv6-DNS-Server" code="17" mandatory="must" may-encrypt="yes" protected="may" vendor-bit="must" vendor-id="TGPP">
|
<avp name="3GPP-IPv6-DNS-Server" code="17" mandatory="must" may-encrypt="yes" protected="may" vendor-bit="must" vendor-id="TGPP">
|
||||||
<type type-name="OctetString"/>
|
<type type-name="OctetString"/>
|
||||||
</avp>
|
</avp>
|
||||||
<avp name="3GPP-SGSN MCC-MNC" code="18" mandatory="must" may-encrypt="yes" protected="may" vendor-bit="must" vendor-id="TGPP">
|
<avp name="3GPP-SGSN-MCC-MNC" code="18" mandatory="must" may-encrypt="yes" protected="may" vendor-bit="must" vendor-id="TGPP">
|
||||||
<type type-name="UTF8String"/>
|
<type type-name="UTF8String"/>
|
||||||
</avp>
|
</avp>
|
||||||
<avp name="3GPP-Teardown Indicator" code="19" mandatory="must" may-encrypt="yes" protected="may" vendor-bit="must" vendor-id="TGPP">
|
<avp name="3GPP-Teardown Indicator" code="19" mandatory="must" may-encrypt="yes" protected="may" vendor-bit="must" vendor-id="TGPP">
|
||||||
|
|
|
@ -1943,7 +1943,7 @@ Note: The AVP codes from 800 to 822 are reserved for TS 32.299.
|
||||||
<gavp name="GGSN-Address"/>
|
<gavp name="GGSN-Address"/>
|
||||||
<gavp name="CG-Address"/>
|
<gavp name="CG-Address"/>
|
||||||
<gavp name="3GPP-IMSI-MCC-MNC"/>
|
<gavp name="3GPP-IMSI-MCC-MNC"/>
|
||||||
<gavp name="3GPP-GGSN- MCC-MNC"/>
|
<gavp name="3GPP-GGSN-MCC-MNC"/>
|
||||||
<gavp name="3GPP-NSAPI"/>
|
<gavp name="3GPP-NSAPI"/>
|
||||||
<gavp name="Called-Station-Id"/>
|
<gavp name="Called-Station-Id"/>
|
||||||
<gavp name="3GPP-Session-Stop-Indicator"/>
|
<gavp name="3GPP-Session-Stop-Indicator"/>
|
||||||
|
|
|
@ -671,6 +671,49 @@ B<-z "proto,colinfo,nfs.fh.hash && ip.src==1.2.3.4,nfs.fh.hash">
|
||||||
|
|
||||||
This option can be used multiple times on the command line.
|
This option can be used multiple times on the command line.
|
||||||
|
|
||||||
|
=item B<-z> diameter,avp[,I<cmd.code>,I<field>,I<field>,I<...>]
|
||||||
|
|
||||||
|
This option enables extraction of most important diameter fields from large capture files.
|
||||||
|
Exactly one text line for each diameter message with matched B<diameter.cmd.code> will be printed.
|
||||||
|
|
||||||
|
Empty diameter command code or '*' can be specified to mach any B<diameter.cmd.code>
|
||||||
|
|
||||||
|
Example: B<-z diameter,avp> extract default field set from diameter messages.
|
||||||
|
|
||||||
|
Example: B<-z diameter,avp,280> extract default field set from diameter DWR messages.
|
||||||
|
|
||||||
|
Example: B<-z diameter,avp,272> extract default field set from diameter CC messages.
|
||||||
|
|
||||||
|
Extract most important fields from diameter CC messages:
|
||||||
|
|
||||||
|
B<tshark -r file.cap.gz -q -z diameter,avp,272,CC-Request-Type,CC-Request-Number,Session-Id,Subscription-Id-Data,Rating-Group,Result-Code>
|
||||||
|
|
||||||
|
Following fields will be printed out for each diameter message:
|
||||||
|
|
||||||
|
"frame" Frame number.
|
||||||
|
"time" Unix time of the frame arrival.
|
||||||
|
"src" Source address.
|
||||||
|
"srcport" Source port.
|
||||||
|
"dst" Destination address.
|
||||||
|
"dstport" Destination port.
|
||||||
|
"proto" Constant string 'diameter', which can be used for post processing of tshark output. e.g. grep/sed/awk.
|
||||||
|
"msgnr" seq. number of diameter message within the frame. E.g. '2' for the third diameter message in the same frame.
|
||||||
|
"is_request" '0' if message is a request, '1' if message is an answer.
|
||||||
|
"cmd" diameter.cmd_code, E.g. '272' for credit control messages.
|
||||||
|
"req_frame" Number of frame where matched request was found or '0'.
|
||||||
|
"ans_frame" Number of frame where matched answer was found or '0'.
|
||||||
|
"resp_time" response time in seconds, '0' in case if matched Request/Answer is not found in trace. E.g. in the begin or end of capture.
|
||||||
|
|
||||||
|
B<-z diameter,avp> option is much faster than B<-V -T text> or B<-T pdml> options.
|
||||||
|
|
||||||
|
B<-z diameter,avp> option is more powerful than B<-T field> and B<-z proto,colinfo> options.
|
||||||
|
|
||||||
|
Multiple diameter messages in one frame are supported.
|
||||||
|
|
||||||
|
Several fields with same name within one diameter message are supported, e.g. I<diameter.Subscription-Id-Data> or I<diameter.Rating-Group>.
|
||||||
|
|
||||||
|
Note: B<tshark -q> option is recommended to suppress default B<tshark> output.
|
||||||
|
|
||||||
=item B<-z> rpc,rtt,I<program>,I<version>[,I<filter>]
|
=item B<-z> rpc,rtt,I<program>,I<version>[,I<filter>]
|
||||||
|
|
||||||
Collect call/reply RTT data for I<program>/I<version>. Data collected
|
Collect call/reply RTT data for I<program>/I<version>. Data collected
|
||||||
|
|
|
@ -55,17 +55,19 @@
|
||||||
#include "epan/nstime.h"
|
#include "epan/nstime.h"
|
||||||
#include "epan/ftypes/ftypes.h"
|
#include "epan/ftypes/ftypes.h"
|
||||||
#include "register.h"
|
#include "register.h"
|
||||||
#include <epan/dissectors/packet-diameter.h>
|
#include "epan/to_str.h"
|
||||||
|
#include "epan/dissectors/packet-diameter.h"
|
||||||
|
|
||||||
|
|
||||||
/* used to keep track of the statistics for an entire program interface */
|
/* used to keep track of the statistics for an entire program interface */
|
||||||
typedef struct _diameteravp_t {
|
typedef struct _diameteravp_t {
|
||||||
guint32 frame;
|
guint32 frame;
|
||||||
guint32 diammsg_toprocess;
|
guint32 diammsg_toprocess;
|
||||||
|
guint32 cmd_code;
|
||||||
guint32 req_count;
|
guint32 req_count;
|
||||||
guint32 ans_count;
|
guint32 ans_count;
|
||||||
guint32 paired_ans_count;
|
guint32 paired_ans_count;
|
||||||
char* filter;
|
gchar* filter;
|
||||||
} diameteravp_t;
|
} diameteravp_t;
|
||||||
|
|
||||||
/* Copied from proto.c */
|
/* Copied from proto.c */
|
||||||
|
@ -98,13 +100,13 @@ diam_tree_to_csv(proto_node* node, gpointer data)
|
||||||
field_info* fi;
|
field_info* fi;
|
||||||
header_field_info *hfi;
|
header_field_info *hfi;
|
||||||
if(!node) {
|
if(!node) {
|
||||||
fprintf(stderr,"traverse end: node='%p' data='%p'\n",node,data);
|
fprintf(stderr,"traverse end: empty node. node='%p' data='%p'\n",node,data);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
fi=node->finfo;
|
fi=node->finfo;
|
||||||
hfi=fi ? fi->hfinfo : NULL;
|
hfi=fi ? fi->hfinfo : NULL;
|
||||||
if(!hfi) {
|
if(!hfi) {
|
||||||
fprintf(stderr,"traverse end2: Hfi not found node='%p'\n",node);
|
fprintf(stderr,"traverse end: hfi not found. node='%p'\n",node);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
ftype=fi->value.ftype->ftype;
|
ftype=fi->value.ftype->ftype;
|
||||||
|
@ -144,32 +146,39 @@ diameteravp_packet(void *pds, packet_info *pinfo, epan_dissect_t *edt _U_, const
|
||||||
header_field_info* hfi=NULL;
|
header_field_info* hfi=NULL;
|
||||||
field_info* finfo=NULL;
|
field_info* finfo=NULL;
|
||||||
const diameter_req_ans_pair_t* dp=pdi;
|
const diameter_req_ans_pair_t* dp=pdi;
|
||||||
|
diameteravp_t *ds=NULL;
|
||||||
|
|
||||||
|
/* Validate paramerers. */
|
||||||
|
if(!dp || !edt || !edt->tree)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Several diameter messages within one frame are possible. *
|
/* Several diameter messages within one frame are possible. *
|
||||||
* Check if we processing the message in same frame like befor or in new frame.*/
|
* Check if we processing the message in same frame like befor or in new frame.*/
|
||||||
diameteravp_t *ds=(diameteravp_t *)pds;
|
ds=(diameteravp_t *)pds;
|
||||||
if(pinfo->fd->num > ds->frame) {
|
if(pinfo->fd->num > ds->frame) {
|
||||||
ds->frame=pinfo->fd->num;
|
ds->frame=pinfo->fd->num;
|
||||||
ds->diammsg_toprocess=0;
|
ds->diammsg_toprocess=0;
|
||||||
} else {
|
} else {
|
||||||
ds->diammsg_toprocess+=1;
|
ds->diammsg_toprocess+=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extract data from request/answer pair provided by diameter dissector.*/
|
/* Extract data from request/answer pair provided by diameter dissector.*/
|
||||||
if(dp) {
|
is_request=dp->processing_request;
|
||||||
is_request=dp->processing_request;
|
cmd_code=dp->cmd_code;
|
||||||
cmd_code=dp->cmd_code;
|
result_code=dp->result_code;
|
||||||
result_code=dp->result_code;
|
req_frame=dp->req_frame;
|
||||||
req_frame=dp->req_frame;
|
ans_frame=dp->ans_frame;
|
||||||
ans_frame=dp->ans_frame;
|
if(!is_request) {
|
||||||
if(!is_request) {
|
nstime_t ns;
|
||||||
nstime_t ns;
|
nstime_delta(&ns, &pinfo->fd->abs_ts, &dp->req_time);
|
||||||
nstime_delta(&ns, &pinfo->fd->abs_ts, &dp->req_time);
|
resp_time=nstime_to_sec(&ns);
|
||||||
resp_time=nstime_to_sec(&ns);
|
resp_time=resp_time<0?0.:resp_time;
|
||||||
resp_time=resp_time<0?0.:resp_time;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!edt || !edt->tree || cmd_code!=272)
|
|
||||||
|
/* Check command code provided by command line option.*/
|
||||||
|
if (ds->cmd_code && ds->cmd_code!=cmd_code)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* Loop over top level nodes */
|
/* Loop over top level nodes */
|
||||||
node = edt->tree->first_child;
|
node = edt->tree->first_child;
|
||||||
while (node != NULL) {
|
while (node != NULL) {
|
||||||
|
@ -177,7 +186,7 @@ diameteravp_packet(void *pds, packet_info *pinfo, epan_dissect_t *edt _U_, const
|
||||||
node = current->next;
|
node = current->next;
|
||||||
finfo=current->finfo;
|
finfo=current->finfo;
|
||||||
hfi=finfo ? finfo->hfinfo : NULL;
|
hfi=finfo ? finfo->hfinfo : NULL;
|
||||||
/*fprintf(stderr,"diameteravp_packet %d %p %p node=%p abbrev=%s\n",cmd_code,edt,edt->tree,current,hfi->abbrev);*/
|
/*fprintf(stderr,"DEBUG: diameteravp_packet %d %p %p node=%p abbrev=%s\n",cmd_code,edt,edt->tree,current,hfi->abbrev);*/
|
||||||
/* process current diameter subtree in the current frame. */
|
/* process current diameter subtree in the current frame. */
|
||||||
if(hfi && hfi->abbrev && strcmp(hfi->abbrev,"diameter")==0) {
|
if(hfi && hfi->abbrev && strcmp(hfi->abbrev,"diameter")==0) {
|
||||||
/* Process current diameter message in the frame */
|
/* Process current diameter message in the frame */
|
||||||
|
@ -190,7 +199,8 @@ diameteravp_packet(void *pds, packet_info *pinfo, epan_dissect_t *edt _U_, const
|
||||||
ds->paired_ans_count++;
|
ds->paired_ans_count++;
|
||||||
}
|
}
|
||||||
/* Output frame data.*/
|
/* Output frame data.*/
|
||||||
printf("frame='%d' proto='diameter' msgnr='%d' is_request='%d' cmd='%d' req_frame='%d' ans_frame='%d' resp_time='%f' ",pinfo->fd->num,ds->diammsg_toprocess,is_request,cmd_code,req_frame,ans_frame,resp_time);
|
printf("frame='%d' time='%f' src='%s' srcport='%d' dst='%s' dstport='%d' proto='diameter' msgnr='%d' is_request='%d' cmd='%d' req_frame='%d' ans_frame='%d' resp_time='%f' ",
|
||||||
|
pinfo->fd->num,nstime_to_sec(&pinfo->fd->abs_ts),ep_address_to_str(&pinfo->src),pinfo->srcport,ep_address_to_str(&pinfo->dst), pinfo->destport,ds->diammsg_toprocess,is_request,cmd_code,req_frame,ans_frame,resp_time);
|
||||||
/* Visit selected nodes of one diameter message.*/
|
/* Visit selected nodes of one diameter message.*/
|
||||||
tree_traverse_pre_order(current, diam_tree_to_csv, &ds);
|
tree_traverse_pre_order(current, diam_tree_to_csv, &ds);
|
||||||
/* End of message.*/
|
/* End of message.*/
|
||||||
|
@ -216,47 +226,45 @@ static void
|
||||||
diameteravp_init(const char *optarg, void* userdata _U_)
|
diameteravp_init(const char *optarg, void* userdata _U_)
|
||||||
{
|
{
|
||||||
diameteravp_t *ds;
|
diameteravp_t *ds;
|
||||||
char* options=NULL;
|
gchar* field=NULL;
|
||||||
char* saveptr=NULL;
|
gchar** tokens;
|
||||||
char* str=NULL;
|
guint opt_count=0;
|
||||||
int field_count=0;
|
guint opt_idx=0;
|
||||||
size_t filter_len=0;
|
GString* filter=NULL;
|
||||||
GString *error_string;
|
GString* error_string=NULL;
|
||||||
|
|
||||||
ds=g_malloc(sizeof(diameteravp_t));
|
ds=g_malloc(sizeof(diameteravp_t));
|
||||||
ds->frame=0;
|
ds->frame=0;
|
||||||
ds->diammsg_toprocess=0;
|
ds->diammsg_toprocess=0;
|
||||||
|
ds->cmd_code=0;
|
||||||
ds->req_count=0;
|
ds->req_count=0;
|
||||||
ds->ans_count=0;
|
ds->ans_count=0;
|
||||||
ds->paired_ans_count=0;
|
ds->paired_ans_count=0;
|
||||||
str=NULL;
|
|
||||||
ds->filter=NULL;
|
ds->filter=NULL;
|
||||||
|
|
||||||
options=g_strdup(optarg);
|
filter=g_string_new("diameter");
|
||||||
for(str=options;*str;str++)
|
|
||||||
{
|
|
||||||
if(*str==',')
|
|
||||||
field_count++;
|
|
||||||
}
|
|
||||||
filter_len=strlen(optarg)+sizeof("diameter")+field_count*sizeof("||diameter.");
|
|
||||||
ds->filter=g_malloc0(filter_len);
|
|
||||||
g_strlcat(ds->filter, "diameter", filter_len);
|
|
||||||
|
|
||||||
#if defined (_WIN32)
|
/* Split command line options. */
|
||||||
for(str=strtok_s(options+sizeof("diameter,avp"),",",&saveptr);str;str=strtok_s(NULL,",",&saveptr))
|
tokens = g_strsplit(optarg,",", 1024);
|
||||||
#else
|
opt_count=g_strv_length(tokens);
|
||||||
for(str=strtok_r(options+sizeof("diameter,avp"),",",&saveptr);str;str=strtok_r(NULL,",",&saveptr))
|
if (opt_count>2)
|
||||||
#endif
|
ds->cmd_code=(guint32)atoi(tokens[2]);
|
||||||
|
|
||||||
|
/* Loop over diameter field names. */
|
||||||
|
for(opt_idx=3;opt_idx<opt_count;opt_idx++)
|
||||||
{
|
{
|
||||||
|
/* Current field from command line arguments. */
|
||||||
|
field=tokens[opt_idx];
|
||||||
/* Connect all requested fields with logical OR. */
|
/* Connect all requested fields with logical OR. */
|
||||||
g_strlcat(ds->filter, "||", filter_len);
|
g_string_append(filter,"||");
|
||||||
/* Prefix field name with "diameter." by default. */
|
/* Prefix field name with "diameter." by default. */
|
||||||
if(!strchr(str,'.'))
|
if(!strchr(field,'.'))
|
||||||
g_strlcat(ds->filter, "diameter.", filter_len);
|
g_string_append(filter, "diameter.");
|
||||||
/* Append field name to the filter. */
|
/* Append field name to the filter. */
|
||||||
g_strlcat(ds->filter, str, filter_len);
|
g_string_append(filter, field);
|
||||||
}
|
}
|
||||||
g_free(options);
|
g_strfreev(tokens);
|
||||||
|
ds->filter=g_string_free(filter,FALSE);
|
||||||
|
|
||||||
error_string=register_tap_listener("diameter", ds, ds->filter, 0, NULL, diameteravp_packet, diameteravp_draw);
|
error_string=register_tap_listener("diameter", ds, ds->filter, 0, NULL, diameteravp_packet, diameteravp_draw);
|
||||||
if(error_string){
|
if(error_string){
|
||||||
|
|
Loading…
Reference in New Issue