aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--diameter/TGPPGmb.xml2
-rw-r--r--diameter/dictionary.xml2
-rw-r--r--doc/tshark.pod43
-rw-r--r--tap-diameter-avp.c100
4 files changed, 99 insertions, 48 deletions
diff --git a/diameter/TGPPGmb.xml b/diameter/TGPPGmb.xml
index c6fa429cd3..186806c610 100644
--- a/diameter/TGPPGmb.xml
+++ b/diameter/TGPPGmb.xml
@@ -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">
<type type-name="OctetString"/>
</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"/>
</avp>
<avp name="3GPP-Teardown Indicator" code="19" mandatory="must" may-encrypt="yes" protected="may" vendor-bit="must" vendor-id="TGPP">
diff --git a/diameter/dictionary.xml b/diameter/dictionary.xml
index bd07fd22e2..1535f797f8 100644
--- a/diameter/dictionary.xml
+++ b/diameter/dictionary.xml
@@ -1943,7 +1943,7 @@ Note: The AVP codes from 800 to 822 are reserved for TS 32.299.
<gavp name="GGSN-Address"/>
<gavp name="CG-Address"/>
<gavp name="3GPP-IMSI-MCC-MNC"/>
- <gavp name="3GPP-GGSN- MCC-MNC"/>
+ <gavp name="3GPP-GGSN-MCC-MNC"/>
<gavp name="3GPP-NSAPI"/>
<gavp name="Called-Station-Id"/>
<gavp name="3GPP-Session-Stop-Indicator"/>
diff --git a/doc/tshark.pod b/doc/tshark.pod
index 8a7cb4e0f4..cc7375c54d 100644
--- a/doc/tshark.pod
+++ b/doc/tshark.pod
@@ -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.
+=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>]
Collect call/reply RTT data for I<program>/I<version>. Data collected
diff --git a/tap-diameter-avp.c b/tap-diameter-avp.c
index f7d8eb35d2..c602d71b8e 100644
--- a/tap-diameter-avp.c
+++ b/tap-diameter-avp.c
@@ -55,17 +55,19 @@
#include "epan/nstime.h"
#include "epan/ftypes/ftypes.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 */
typedef struct _diameteravp_t {
guint32 frame;
guint32 diammsg_toprocess;
+ guint32 cmd_code;
guint32 req_count;
guint32 ans_count;
guint32 paired_ans_count;
- char* filter;
+ gchar* filter;
} diameteravp_t;
/* Copied from proto.c */
@@ -98,13 +100,13 @@ diam_tree_to_csv(proto_node* node, gpointer data)
field_info* fi;
header_field_info *hfi;
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;
}
fi=node->finfo;
hfi=fi ? fi->hfinfo : NULL;
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;
}
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;
field_info* finfo=NULL;
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. *
* 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) {
ds->frame=pinfo->fd->num;
ds->diammsg_toprocess=0;
} else {
ds->diammsg_toprocess+=1;
}
+
/* Extract data from request/answer pair provided by diameter dissector.*/
- if(dp) {
- is_request=dp->processing_request;
- cmd_code=dp->cmd_code;
- result_code=dp->result_code;
- req_frame=dp->req_frame;
- ans_frame=dp->ans_frame;
- if(!is_request) {
- nstime_t ns;
- nstime_delta(&ns, &pinfo->fd->abs_ts, &dp->req_time);
- resp_time=nstime_to_sec(&ns);
- resp_time=resp_time<0?0.:resp_time;
- }
+ is_request=dp->processing_request;
+ cmd_code=dp->cmd_code;
+ result_code=dp->result_code;
+ req_frame=dp->req_frame;
+ ans_frame=dp->ans_frame;
+ if(!is_request) {
+ nstime_t ns;
+ nstime_delta(&ns, &pinfo->fd->abs_ts, &dp->req_time);
+ resp_time=nstime_to_sec(&ns);
+ 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;
+
/* Loop over top level nodes */
node = edt->tree->first_child;
while (node != NULL) {
@@ -177,7 +186,7 @@ diameteravp_packet(void *pds, packet_info *pinfo, epan_dissect_t *edt _U_, const
node = current->next;
finfo=current->finfo;
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. */
if(hfi && hfi->abbrev && strcmp(hfi->abbrev,"diameter")==0) {
/* 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++;
}
/* 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.*/
tree_traverse_pre_order(current, diam_tree_to_csv, &ds);
/* End of message.*/
@@ -216,47 +226,45 @@ static void
diameteravp_init(const char *optarg, void* userdata _U_)
{
diameteravp_t *ds;
- char* options=NULL;
- char* saveptr=NULL;
- char* str=NULL;
- int field_count=0;
- size_t filter_len=0;
- GString *error_string;
+ gchar* field=NULL;
+ gchar** tokens;
+ guint opt_count=0;
+ guint opt_idx=0;
+ GString* filter=NULL;
+ GString* error_string=NULL;
ds=g_malloc(sizeof(diameteravp_t));
ds->frame=0;
ds->diammsg_toprocess=0;
+ ds->cmd_code=0;
ds->req_count=0;
ds->ans_count=0;
ds->paired_ans_count=0;
- str=NULL;
ds->filter=NULL;
- options=g_strdup(optarg);
- 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);
+ filter=g_string_new("diameter");
-#if defined (_WIN32)
- for(str=strtok_s(options+sizeof("diameter,avp"),",",&saveptr);str;str=strtok_s(NULL,",",&saveptr))
-#else
- for(str=strtok_r(options+sizeof("diameter,avp"),",",&saveptr);str;str=strtok_r(NULL,",",&saveptr))
-#endif
+ /* Split command line options. */
+ tokens = g_strsplit(optarg,",", 1024);
+ opt_count=g_strv_length(tokens);
+ if (opt_count>2)
+ 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. */
- g_strlcat(ds->filter, "||", filter_len);
+ g_string_append(filter,"||");
/* Prefix field name with "diameter." by default. */
- if(!strchr(str,'.'))
- g_strlcat(ds->filter, "diameter.", filter_len);
+ if(!strchr(field,'.'))
+ g_string_append(filter, "diameter.");
/* 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);
if(error_string){