add parameter dcerpc_info to PIDL_dissect_ipv?address()
[wireshark-wip.git] / ui / cli / tap-wspstat.c
blob56b511a5dc1c87b5ebf649e2fdda538965672f6c
1 /* tap-rpcstat.c
2 * wspstat 2003 Jean-Michel FAYARD
4 * $Id$
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 /* This module provides WSP statistics to tshark.
26 * It is only used by tshark and not wireshark
30 #include "config.h"
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
36 #include "epan/packet_info.h"
37 #include <epan/tap.h>
38 #include <epan/stat_cmd_args.h>
39 #include "epan/value_string.h"
40 #include <epan/dissectors/packet-wsp.h>
42 void register_tap_listener_wspstat(void);
44 /* used to keep track of the stats for a specific PDU type*/
45 typedef struct _wsp_pdu_t {
46 const gchar *type;
47 guint32 packets;
48 } wsp_pdu_t;
49 /* used to keep track of SRT statistics */
50 typedef struct _wsp_status_code_t {
51 const gchar *name;
52 guint32 packets;
53 } wsp_status_code_t;
54 /* used to keep track of the statictics for an entire program interface */
55 typedef struct _wsp_stats_t {
56 char *filter;
57 wsp_pdu_t *pdu_stats;
58 guint32 num_pdus;
59 GHashTable *hash;
60 } wspstat_t;
62 static void
63 wsp_reset_hash(gchar *key _U_ , wsp_status_code_t *data, gpointer ptr _U_ )
65 data->packets = 0;
67 static void
68 wsp_print_statuscode(gint *key, wsp_status_code_t *data, char* format)
70 if (data && (data->packets!=0))
71 printf(format, *key, data->packets ,data->name);
73 static void
74 wsp_free_hash_table( gpointer key, gpointer value, gpointer user_data _U_ )
76 g_free(key);
77 g_free(value);
79 static void
80 wspstat_reset(void *psp)
82 wspstat_t *sp=(wspstat_t *)psp;
83 guint32 i;
85 for(i=1;i<=sp->num_pdus;i++)
87 sp->pdu_stats[i].packets=0;
89 g_hash_table_foreach( sp->hash, (GHFunc)wsp_reset_hash, NULL);
93 /* This callback is invoked whenever the tap system has seen a packet
94 * we might be interested in.
95 * The function is to be used to only update internal state information
96 * in the *tapdata structure, and if there were state changes which requires
97 * the window to be redrawn, return 1 and (*draw) will be called sometime
98 * later.
100 * We didnt apply a filter when we registered so we will be called for
101 * ALL packets and not just the ones we are collecting stats for.
104 static gint
105 pdut2index(gint pdut)
107 if (pdut<=0x09) return pdut;
108 if (pdut>=0x40){
109 if (pdut <= 0x44){
110 return pdut-54;
111 } else if (pdut==0x60||pdut==0x61){
112 return pdut-81;
115 return 0;
117 static gint
118 index2pdut(gint pdut)
120 if (pdut<=0x09)
121 return pdut;
122 if (pdut<=14)
123 return pdut+54;
124 if (pdut<=16)
125 return pdut+81;
126 return 0;
128 static int
129 wspstat_packet(void *psp, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pri)
131 wspstat_t *sp=(wspstat_t *)psp;
132 const wsp_info_value_t *value=(const wsp_info_value_t *)pri;
133 gint idx = pdut2index(value->pdut);
134 int retour=0;
136 if (value->status_code != 0) {
137 gint *key=g_new(gint,1);
138 wsp_status_code_t *sc;
139 *key=value->status_code ;
140 sc = (wsp_status_code_t *)g_hash_table_lookup(
141 sp->hash,
142 key);
143 if (!sc) {
144 sc = g_new(wsp_status_code_t,1);
145 sc -> packets = 1;
146 sc -> name = NULL;
147 g_hash_table_insert(
148 sp->hash,
149 key,
150 sc);
151 } else {
152 sc->packets++;
154 retour=1;
159 if (idx!=0) {
160 sp->pdu_stats[ idx ].packets++;
161 retour = 1;
163 return retour;
167 /* This callback is used when tshark wants us to draw/update our
168 * data to the output device. Since this is tshark only output is
169 * stdout.
170 * TShark will only call this callback once, which is when tshark has
171 * finished reading all packets and exists.
172 * If used with wireshark this may be called any time, perhaps once every 3
173 * seconds or so.
174 * This function may even be called in parallell with (*reset) or (*draw)
175 * so make sure there are no races. The data in the rpcstat_t can thus change
176 * beneath us. Beware.
178 static void
179 wspstat_draw(void *psp)
181 wspstat_t *sp=(wspstat_t *)psp;
182 guint32 i;
184 printf("\n");
185 printf("===================================================================\n");
186 printf("WSP Statistics:\n");
187 printf("%-23s %9s || %-23s %9s\n","PDU Type", "Packets", "PDU Type", "Packets");
188 for(i=1; i<= ((sp->num_pdus+1)/2) ; i++)
190 guint32 ii=i+sp->num_pdus/2;
191 printf("%-23s %9d", sp->pdu_stats[i ].type, sp->pdu_stats[i ].packets);
192 printf(" || ");
193 if (ii< (sp->num_pdus) )
194 printf("%-23s %9d\n", sp->pdu_stats[ii].type, sp->pdu_stats[ii].packets);
195 else
196 printf("\n");
198 printf("\nStatus code in reply packets\n");
199 printf( "Status Code Packets Description\n");
200 g_hash_table_foreach( sp->hash, (GHFunc) wsp_print_statuscode,
201 (gpointer)" 0x%02X %9d %s\n" ) ;
202 printf("===================================================================\n");
205 /* When called, this function will create a new instance of wspstat.
206 * program and version are whick onc-rpc program/version we want to
207 * collect statistics for.
208 * This function is called from tshark when it parses the -z wsp, arguments
209 * and it creates a new instance to store statistics in and registers this
210 * new instance for the wsp tap.
212 static void
213 wspstat_init(const char *opt_arg, void* userdata _U_)
215 wspstat_t *sp;
216 const char *filter=NULL;
217 guint32 i;
218 GString *error_string;
219 wsp_status_code_t *sc;
220 const value_string *wsp_vals_status_p;
222 if (!strncmp (opt_arg, "wsp,stat," , 9)){
223 filter=opt_arg+9;
224 } else {
225 filter=NULL;
229 sp = g_new(wspstat_t,1);
230 sp->hash = g_hash_table_new( g_int_hash, g_int_equal);
231 wsp_vals_status_p = VALUE_STRING_EXT_VS_P(&wsp_vals_status_ext);
232 for (i=0 ; wsp_vals_status_p[i].strptr ; i++ )
234 gint *key;
235 sc=g_new(wsp_status_code_t,1);
236 key=g_new(gint,1);
237 sc->packets=0;
238 sc->name=wsp_vals_status_p[i].strptr;
239 *key=wsp_vals_status_p[i].value;
240 g_hash_table_insert(
241 sp->hash,
242 key,
243 sc);
245 sp->num_pdus = 16;
246 sp->pdu_stats=g_new(wsp_pdu_t,(sp->num_pdus+1));
247 if(filter){
248 sp->filter=g_strdup(filter);
249 } else {
250 sp->filter=NULL;
252 for (i=0;i<sp->num_pdus; i++)
254 sp->pdu_stats[i].packets=0;
255 sp->pdu_stats[i].type = try_val_to_str_ext( index2pdut( i ), &wsp_vals_pdu_type_ext) ;
258 error_string = register_tap_listener(
259 "wsp",
261 filter,
263 wspstat_reset,
264 wspstat_packet,
265 wspstat_draw);
266 if (error_string){
267 /* error, we failed to attach to the tap. clean up */
268 g_free(sp->pdu_stats);
269 g_free(sp->filter);
270 g_free(sp);
271 g_hash_table_foreach( sp->hash, (GHFunc) wsp_free_hash_table, NULL ) ;
272 g_hash_table_destroy( sp->hash );
273 fprintf(stderr, "tshark: Couldn't register wsp,stat tap: %s\n",
274 error_string->str);
275 g_string_free(error_string, TRUE);
276 exit(1);
279 void
280 register_tap_listener_wspstat(void)
282 register_stat_cmd_arg("wsp,stat,", wspstat_init,NULL);