From Harald Welte:
[obnox/wireshark/wip.git] / tap-sipstat.c
index be943031ff50953b4700fbb58ad72cba986c3e8a..b8273219baef0d3dc8da84210d0cfc214bef3f55 100644 (file)
@@ -1,11 +1,11 @@
 /* tap_sipstat.c
- * sip message counter for ethereal
+ * sip message counter for wireshark
  *
  * $Id$
- * Copied from gtk/sip_stat.c and tap-httpstat.c
+ * Copied from ui/gtk/sip_stat.c and tap-httpstat.c
  *
- * Ethereal - Network traffic analyzer
- * By Gerald Combs <gerald@ethereal.com>
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  *
  * This program is free software; you can redistribute it and/or
 #include <epan/tap.h>
 #include <epan/stat_cmd_args.h>
 #include "epan/value_string.h"
-#include "register.h"
 #include <epan/dissectors/packet-sip.h>
 
 /* used to keep track of the statictics for an entire program interface */
 typedef struct _sip_stats_t {
-       char            *filter;
+       char            *filter;
        guint32         packets;        /* number of sip packets, including continuations */
        guint32         resent_packets;
+       guint32         average_setup_time;
+       guint32         max_setup_time;
+       guint32         min_setup_time;
+       guint32         no_of_completed_calls;
+       guint64         total_setup_time;
        GHashTable      *hash_responses;
        GHashTable      *hash_requests;
 } sipstat_t;
@@ -54,8 +58,8 @@ typedef struct _sip_stats_t {
  * for example it can be { 3, 404, "Not Found" ,...}
  * which means we captured 3 reply sip/1.1 404 Not Found */
 typedef struct _sip_response_code_t {
-       guint32          packets;               /* 3 */
-       guint            response_code;         /* 404 */
+       guint32  packets;               /* 3 */
+       guint            response_code;         /* 404 */
        const gchar     *name;                  /* Not Found */
        sipstat_t       *sp;
 } sip_response_code_t;
@@ -78,6 +82,7 @@ static const value_string vals_status_code[] = {
 
     { 200, "OK"},
     { 202, "Accepted"},
+    { 204, "No Notification"},
     { 299, "Success - Others"},        /* used to keep track of other Success packets */
 
     { 300, "Multiple Choices"},
@@ -97,13 +102,25 @@ static const value_string vals_status_code[] = {
     { 407, "Proxy Authentication Required"},
     { 408, "Request Timeout"},
     { 410, "Gone"},
+    { 412, "Conditional Request Failed"},
     { 413, "Request Entity Too Large"},
     { 414, "Request-URI Too Long"},
     { 415, "Unsupported Media Type"},
     { 416, "Unsupported URI Scheme"},
     { 420, "Bad Extension"},
     { 421, "Extension Required"},
+    { 422, "Session Timer Too Small"},
     { 423, "Interval Too Brief"},
+    { 428, "Use Identity Header"},
+    { 429, "Provide Referrer Identity"},
+    { 430, "Flow Failed"},
+    { 433, "Anonymity Disallowed"},
+    { 436, "Bad Identity-Info"},
+    { 437, "Unsupported Certificate"},
+    { 438, "Invalid Identity Header"},
+    { 439, "First Hop Lacks Outbound Support"},
+    { 440, "Max-Breadth Exceeded"},
+    { 470, "Consent Needed"},
     { 480, "Temporarily Unavailable"},
     { 481, "Call/Transaction Does Not Exist"},
     { 482, "Loop Detected"},
@@ -116,6 +133,7 @@ static const value_string vals_status_code[] = {
     { 489, "Bad Event"},
     { 491, "Request Pending"},
     { 493, "Undecipherable"},
+    { 494, "Security Agreement Required"},
     { 499, "Client Error - Others"},
 
     { 500, "Server Internal Error"},
@@ -133,7 +151,7 @@ static const value_string vals_status_code[] = {
     { 606, "Not Acceptable"},
     { 699, "Global Failure - Others"},
 
-    { 0,       NULL}
+    { 0,       NULL}
 };
 
 /* Create tables for responses and requests */
@@ -210,6 +228,12 @@ sipstat_reset(void *psp  )
        if (sp) {
                sp->packets = 0;
                sp->resent_packets = 0;
+               sp->average_setup_time = 0;
+               sp->max_setup_time = 0;
+               sp->min_setup_time = 0;
+               sp->no_of_completed_calls = 0;
+               sp->total_setup_time = 0;
+
                g_hash_table_foreach( sp->hash_responses, (GHFunc)sip_reset_hash_responses, NULL);
                g_hash_table_foreach( sp->hash_requests, (GHFunc)sip_reset_hash_requests, NULL);
        }
@@ -222,17 +246,39 @@ sipstat_packet(void *psp, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const
 {
     const sip_info_value_t *value=pri;
     sipstat_t *sp = (sipstat_t *)psp;
-    
+
     /* Total number of packets, including continuation packets */
     sp->packets++;
-    
+
+       /* Calculate average setup time */
+       if (value->setup_time){
+               sp->no_of_completed_calls++;
+               /* Check if it's the first value */
+               if ( sp->total_setup_time == 0 ){
+                       sp->average_setup_time = value->setup_time;
+                       sp->total_setup_time = value->setup_time;
+                       sp->max_setup_time = value->setup_time;
+                       sp->min_setup_time = value->setup_time;
+               }else{
+                       sp->total_setup_time = sp->total_setup_time + value->setup_time;
+                       if (sp->max_setup_time < value->setup_time){
+                               sp->max_setup_time = value->setup_time;
+                       }
+                       if (sp->min_setup_time > value->setup_time){
+                               sp->min_setup_time = value->setup_time;
+                       }
+                       /* Calculate average */
+                       sp->average_setup_time = (guint32)(sp->total_setup_time / sp->no_of_completed_calls);
+               }
+       }
+
     /* Update resent count if flag set */
     if (value->resend)
     {
         sp->resent_packets++;
     }
 
-    
+
     /* Looking at both requests and responses */
     if (value->response_code != 0)
     {
@@ -341,11 +387,12 @@ sipstat_draw(void *psp  )
        printf("\n* List of SIP Request methods\n");
        g_hash_table_foreach( sp->hash_requests,  (GHFunc)sip_draw_hash_requests,
                "  %-15s : %5d Packets\n");
+       printf( "\n* Average setup time %d ms\n Min %d ms\n Max %d ms\n", sp->average_setup_time, sp->min_setup_time, sp->max_setup_time);
        printf("===================================================================\n");
 }
 
 static void
-sipstat_init(const char *optarg)
+sipstat_init(const char *optarg, void* userdata _U_)
 {
        sipstat_t *sp;
        const char *filter=NULL;
@@ -370,6 +417,7 @@ sipstat_init(const char *optarg)
                        "sip",
                        sp,
                        filter,
+                       0,
                        sipstat_reset,
                        sipstat_packet,
                        sipstat_draw);
@@ -377,7 +425,7 @@ sipstat_init(const char *optarg)
                /* error, we failed to attach to the tap. clean up */
                g_free(sp->filter);
                g_free(sp);
-               fprintf (stderr, "tethereal: Couldn't register sip,stat tap: %s\n",
+               fprintf (stderr, "tshark: Couldn't register sip,stat tap: %s\n",
                                error_string->str);
                g_string_free(error_string, TRUE);
                exit(1);
@@ -391,5 +439,5 @@ sipstat_init(const char *optarg)
 void
 register_tap_listener_sipstat(void)
 {
-       register_stat_cmd_arg("sip,stat", sipstat_init);
+       register_stat_cmd_arg("sip,stat", sipstat_init,NULL);
 }