Get rid of -Wshadow warning - I guess we're including something that
[metze/wireshark/wip.git] / ui / cli / tap-smbstat.c
1 /* tap-smbstat.c
2  * smbstat   2003 Ronnie Sahlberg
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
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.
14  *
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.
19  *
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.
23  */
24
25 #include "config.h"
26
27 #include <stdio.h>
28
29 #include <string.h>
30 #include "epan/packet_info.h"
31 #include <epan/tap.h>
32 #include <epan/stat_cmd_args.h>
33 #include "epan/value_string.h"
34 #include <epan/dissectors/packet-smb.h>
35 #include "epan/timestats.h"
36
37 #define MICROSECS_PER_SEC   1000000
38 #define NANOSECS_PER_SEC    1000000000
39
40 /* used to keep track of the statistics for an entire program interface */
41 typedef struct _smbstat_t {
42         char *filter;
43         timestat_t proc[256];
44         timestat_t trans2[256];
45         timestat_t nt_trans[256];
46 } smbstat_t;
47
48
49
50 static int
51 smbstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *psi)
52 {
53         smbstat_t *ss=(smbstat_t *)pss;
54         const smb_info_t *si=(const smb_info_t *)psi;
55         nstime_t t, deltat;
56         timestat_t *sp=NULL;
57
58         /* we are only interested in reply packets */
59         if(si->request){
60                 return 0;
61         }
62         /* if we havnt seen the request, just ignore it */
63         if(!si->sip){
64                 return 0;
65         }
66
67         if(si->cmd==0xA0 && si->sip->extra_info_type == SMB_EI_NTI){
68                 smb_nt_transact_info_t *sti=(smb_nt_transact_info_t *)si->sip->extra_info;
69
70                 /*nt transaction*/
71                 if(sti){
72                         sp=&(ss->nt_trans[sti->subcmd]);
73                 }
74         } else if(si->cmd==0x32 && si->sip->extra_info_type == SMB_EI_T2I){
75                 smb_transact2_info_t *st2i=(smb_transact2_info_t *)si->sip->extra_info;
76
77                 /*transaction2*/
78                 if(st2i){
79                         sp=&(ss->trans2[st2i->subcmd]);
80                 }
81         } else {
82                 sp=&(ss->proc[si->cmd]);
83         }
84
85         /* calculate time delta between request and reply */
86         t=pinfo->fd->abs_ts;
87         nstime_delta(&deltat, &t, &si->sip->req_time);
88
89         if(sp){
90                 time_stat_update(sp,&deltat, pinfo);
91         }
92
93         return 1;
94 }
95
96 static void
97 smbstat_draw(void *pss)
98 {
99         smbstat_t *ss=(smbstat_t *)pss;
100         guint32 i;
101         guint64 td;
102         printf("\n");
103         printf("=================================================================\n");
104         printf("SMB SRT Statistics:\n");
105         printf("Filter: %s\n",ss->filter?ss->filter:"");
106         printf("Commands                   Calls    Min SRT    Max SRT    Avg SRT\n");
107         for(i=0;i<256;i++){
108                 /* nothing seen, nothing to do */
109                 if(ss->proc[i].num==0){
110                         continue;
111                 }
112
113                 /* we deal with transaction2 later */
114                 if(i==0x32){
115                         continue;
116                 }
117
118                 /* we deal with nt transaction later */
119                 if(i==0xA0){
120                         continue;
121                 }
122
123                 /* Scale the average SRT in units of 1us and round to the nearest us. */
124                 td = ((guint64)(ss->proc[i].tot.secs)) * NANOSECS_PER_SEC + ss->proc[i].tot.nsecs;
125
126                 td = ((td / ss->proc[i].num) + 500) / 1000;
127
128                 printf("%-25s %6d %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u\n",
129                         val_to_str_ext(i, &smb_cmd_vals_ext, "Unknown (0x%02x)"),
130                         ss->proc[i].num,
131                         (int)(ss->proc[i].min.secs),(ss->proc[i].min.nsecs+500)/1000,
132                         (int)(ss->proc[i].max.secs),(ss->proc[i].max.nsecs+500)/1000,
133                         td/MICROSECS_PER_SEC, td%MICROSECS_PER_SEC
134                 );
135         }
136
137         printf("\n");
138         printf("Transaction2 Commands      Calls    Min SRT    Max SRT    Avg SRT\n");
139         for(i=0;i<256;i++){
140                 /* nothing seen, nothing to do */
141                 if(ss->trans2[i].num==0){
142                         continue;
143                 }
144
145                 /* Scale the average SRT in units of 1us and round to the nearest us. */
146                 td = ((guint64)(ss->trans2[i].tot.secs)) * NANOSECS_PER_SEC + ss->trans2[i].tot.nsecs;
147                 td = ((td / ss->trans2[i].num) + 500) / 1000;
148
149                 printf("%-25s %6d %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u\n",
150                         val_to_str_ext(i, &trans2_cmd_vals_ext, "Unknown (0x%02x)"),
151                         ss->trans2[i].num,
152                         (int)(ss->trans2[i].min.secs),(ss->trans2[i].min.nsecs+500)/1000,
153                         (int)(ss->trans2[i].max.secs),(ss->trans2[i].max.nsecs+500)/1000,
154                         td/MICROSECS_PER_SEC, td%MICROSECS_PER_SEC
155                 );
156         }
157
158         printf("\n");
159         printf("NT Transaction Commands    Calls    Min SRT    Max SRT    Avg SRT\n");
160         for(i=0;i<256;i++){
161                 /* nothing seen, nothing to do */
162                 if(ss->nt_trans[i].num==0){
163                         continue;
164                 }
165                 /* Scale the average SRT in units of 1us and round to the nearest us. */
166                 td = ((guint64)(ss->nt_trans[i].tot.secs)) * NANOSECS_PER_SEC + ss->nt_trans[i].tot.nsecs;
167                 td = ((td / ss->nt_trans[i].num) + 500) / 1000;
168
169                 printf("%-25s %6d %3d.%06d %3d.%06d %3" G_GINT64_MODIFIER "u.%06" G_GINT64_MODIFIER "u\n",
170                         val_to_str_ext(i, &nt_cmd_vals_ext, "Unknown (0x%02x)"),
171                         ss->nt_trans[i].num,
172                         (int)(ss->nt_trans[i].min.secs),(ss->nt_trans[i].min.nsecs+500)/1000,
173                         (int)(ss->nt_trans[i].max.secs),(ss->nt_trans[i].max.nsecs+500)/1000,
174                         td/MICROSECS_PER_SEC, td%MICROSECS_PER_SEC
175                 );
176         }
177
178         printf("=================================================================\n");
179 }
180
181
182 static void
183 smbstat_init(const char *opt_arg,void* userdata _U_)
184 {
185         smbstat_t *ss;
186         guint32 i;
187         const char *filter=NULL;
188         GString *error_string;
189
190         if(!strncmp(opt_arg,"smb,srt,",8)){
191                 filter=opt_arg+8;
192         } else {
193                 filter=NULL;
194         }
195
196         ss=g_new(smbstat_t,1);
197         if(filter){
198                 ss->filter=g_strdup(filter);
199         } else {
200                 ss->filter=NULL;
201         }
202
203         for(i=0;i<256;i++){
204                 ss->proc[i].num=0;
205                 ss->proc[i].min_num=0;
206                 ss->proc[i].max_num=0;
207                 ss->proc[i].min.secs=0;
208                 ss->proc[i].min.nsecs=0;
209                 ss->proc[i].max.secs=0;
210                 ss->proc[i].max.nsecs=0;
211                 ss->proc[i].tot.secs=0;
212                 ss->proc[i].tot.nsecs=0;
213
214                 ss->trans2[i].num=0;
215                 ss->trans2[i].min_num=0;
216                 ss->trans2[i].max_num=0;
217                 ss->trans2[i].min.secs=0;
218                 ss->trans2[i].min.nsecs=0;
219                 ss->trans2[i].max.secs=0;
220                 ss->trans2[i].max.nsecs=0;
221                 ss->trans2[i].tot.secs=0;
222                 ss->trans2[i].tot.nsecs=0;
223
224                 ss->nt_trans[i].num=0;
225                 ss->nt_trans[i].min_num=0;
226                 ss->nt_trans[i].max_num=0;
227                 ss->nt_trans[i].min.secs=0;
228                 ss->nt_trans[i].min.nsecs=0;
229                 ss->nt_trans[i].max.secs=0;
230                 ss->nt_trans[i].max.nsecs=0;
231                 ss->nt_trans[i].tot.secs=0;
232                 ss->nt_trans[i].tot.nsecs=0;
233         }
234
235         error_string=register_tap_listener("smb", ss, filter, 0, NULL, smbstat_packet, smbstat_draw);
236         if(error_string){
237                 /* error, we failed to attach to the tap. clean up */
238                 g_free(ss->filter);
239                 g_free(ss);
240
241                 fprintf(stderr, "tshark: Couldn't register smb,srt tap: %s\n",
242                     error_string->str);
243                 g_string_free(error_string, TRUE);
244                 exit(1);
245         }
246 }
247
248
249 void
250 register_tap_listener_smbstat(void)
251 {
252         register_stat_cmd_arg("smb,srt", smbstat_init,NULL);
253 }
254