c37d02713ae830b3041216ad8ebe7b9a40a75645
[jlayton/wireshark.git] / ui / cli / tap-rtd.c
1 /* tap-rtd.c
2  *
3  * Based on tap-srt.c
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "config.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28
29 #include <string.h>
30 #include <epan/packet.h>
31 #include <epan/rtd_table.h>
32 #include <epan/timestamp.h>
33 #include <epan/stat_tap_ui.h>
34 #include <ui/cli/tshark-tap.h>
35
36 typedef struct _rtd_t {
37         const char *type;
38         const char *filter;
39         const value_string* vs_type;
40         rtd_data_t rtd;
41 } rtd_t;
42
43 static void
44 rtd_draw(void *arg)
45 {
46         rtd_data_t* rtd_data = (rtd_data_t*)arg;
47         rtd_t* rtd = (rtd_t*)rtd_data->user_data;
48         gchar* tmp_str;
49         guint i, j;
50
51         /* printing results */
52         printf("\n");
53         printf("=====================================================================================================\n");
54         printf("%s Response Time Delay (RTD) Statistics:\n", rtd->type);
55         printf("Filter for statistics: %s\n", rtd->filter ? rtd->filter : "");
56         if (rtd_data->stat_table.num_rtds == 1)
57         {
58                 printf("Duplicate requests: %u\n", rtd_data->stat_table.time_stats[0].req_dup_num);
59                 printf("Duplicate responses: %u\n", rtd_data->stat_table.time_stats[0].rsp_dup_num);
60                 printf("Open requests: %u\n", rtd_data->stat_table.time_stats[0].open_req_num);
61                 printf("Discarded responses: %u\n", rtd_data->stat_table.time_stats[0].disc_rsp_num);
62                 printf("Type    | Messages   |    Min RTD    |    Max RTD    |    Avg RTD    | Min in Frame | Max in Frame |\n");
63                 for (i=0; i<rtd_data->stat_table.time_stats[0].num_timestat; i++) {
64                         if (rtd_data->stat_table.time_stats[0].rtd[i].num) {
65                                 tmp_str = val_to_str_wmem(NULL, i, rtd->vs_type, "Other (%d)");
66                                 printf("%s | %7u    | %8.2f msec | %8.2f msec | %8.2f msec |  %10u  |  %10u  |\n",
67                                                 tmp_str, rtd_data->stat_table.time_stats[0].rtd[i].num,
68                                                 nstime_to_msec(&(rtd_data->stat_table.time_stats[0].rtd[i].min)), nstime_to_msec(&(rtd_data->stat_table.time_stats[0].rtd[i].max)),
69                                                 get_average(&(rtd_data->stat_table.time_stats[0].rtd[i].tot), rtd_data->stat_table.time_stats[0].rtd[i].num),
70                                                 rtd_data->stat_table.time_stats[0].rtd[i].min_num, rtd_data->stat_table.time_stats[0].rtd[i].max_num
71                                 );
72                                 wmem_free(NULL, tmp_str);
73                         }
74                 }
75         }
76         else
77         {
78                 printf("Type    | Messages   |    Min RTD    |    Max RTD    |    Avg RTD    | Min in Frame | Max in Frame | Open Requests | Discarded responses | Duplicate requests | Duplicate responses\n");
79                 for (i=0; i<rtd_data->stat_table.num_rtds; i++) {
80                         for (j=0; j<rtd_data->stat_table.time_stats[i].num_timestat; j++) {
81                                 if (rtd_data->stat_table.time_stats[i].rtd[j].num) {
82                                         tmp_str = val_to_str_wmem(NULL, i, rtd->vs_type, "Other (%d)");
83                                         printf("%s | %7u    | %8.2f msec | %8.2f msec | %8.2f msec |  %10u  |  %10u  |  %10u  |  %10u  | %4u (%4.2f%%) | %4u (%4.2f%%)  |\n",
84                                                         tmp_str, rtd_data->stat_table.time_stats[i].rtd[j].num,
85                                                         nstime_to_msec(&(rtd_data->stat_table.time_stats[i].rtd[j].min)), nstime_to_msec(&(rtd_data->stat_table.time_stats[i].rtd[j].max)),
86                                                         get_average(&(rtd_data->stat_table.time_stats[i].rtd[j].tot), rtd_data->stat_table.time_stats[i].rtd[j].num),
87                                                         rtd_data->stat_table.time_stats[i].rtd[j].min_num, rtd_data->stat_table.time_stats[i].rtd[j].max_num,
88                                                         rtd_data->stat_table.time_stats[i].open_req_num, rtd_data->stat_table.time_stats[i].disc_rsp_num,
89                                                         rtd_data->stat_table.time_stats[i].req_dup_num,
90                                                         rtd_data->stat_table.time_stats[i].rtd[j].num?((double)rtd_data->stat_table.time_stats[i].req_dup_num*100)/(double)rtd_data->stat_table.time_stats[i].rtd[j].num:0,
91                                                         rtd_data->stat_table.time_stats[i].rsp_dup_num,
92                                                         rtd_data->stat_table.time_stats[i].rtd[j].num?((double)rtd_data->stat_table.time_stats[i].rsp_dup_num*100)/(double)rtd_data->stat_table.time_stats[i].rtd[j].num:0
93                                         );
94                                         wmem_free(NULL, tmp_str);
95                                 }
96                         }
97                 }
98         }
99         printf("=====================================================================================================\n");
100 }
101
102 static void
103 init_rtd_tables(register_rtd_t* rtd, const char *filter)
104 {
105         gchar *error_string;
106         rtd_t* ui;
107
108         ui = g_new0(rtd_t, 1);
109         ui->type = proto_get_protocol_short_name(find_protocol_by_id(get_rtd_proto_id(rtd)));
110         ui->filter = g_strdup(filter);
111         ui->vs_type = get_rtd_value_string(rtd);
112         ui->rtd.user_data = ui;
113
114         rtd_table_dissector_init(rtd, &ui->rtd.stat_table, NULL, NULL);
115
116         error_string = register_tap_listener(get_rtd_tap_listener_name(rtd), &ui->rtd, filter, 0, NULL, get_rtd_packet_func(rtd), rtd_draw);
117         if (error_string) {
118                 free_rtd_table(&ui->rtd.stat_table, NULL, NULL);
119                 fprintf(stderr, "tshark: Couldn't register srt tap: %s\n", error_string);
120                 wmem_free(NULL, error_string);
121                 exit(1);
122         }
123 }
124
125 static void
126 dissector_rtd_init(const char *opt_arg, void* userdata)
127 {
128         register_rtd_t *rtd = (register_rtd_t*)userdata;
129         const char *filter=NULL;
130         char* err = NULL;
131
132         rtd_table_get_filter(rtd, opt_arg, &filter, &err);
133         if (err != NULL)
134         {
135                 fprintf(stderr, "tshark: %s\n", err);
136                 g_free(err);
137                 exit(1);
138         }
139
140         init_rtd_tables(rtd, filter);
141 }
142
143 /* Set GUI fields for register_rtd list */
144 void
145 register_rtd_tables(gpointer data, gpointer user_data _U_)
146 {
147         register_rtd_t *rtd = (register_rtd_t*)data;
148         stat_tap_ui ui_info;
149
150         ui_info.group = REGISTER_STAT_GROUP_RESPONSE_TIME;
151         ui_info.title = NULL;   /* construct this from the protocol info? */
152         ui_info.cli_string = rtd_table_get_tap_string(rtd);
153         ui_info.tap_init_cb = dissector_rtd_init;
154         ui_info.nparams = 0;
155         ui_info.params = NULL;
156         register_stat_tap_ui(&ui_info, rtd);
157 }
158
159 /*
160  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
161  *
162  * Local variables:
163  * c-basic-offset: 8
164  * tab-width: 8
165  * indent-tabs-mode: t
166  * End:
167  *
168  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
169  * :indentSize=8:tabSize=8:noTabs=false:
170  */