summaryrefslogtreecommitdiffstats
path: root/ui/cli/tap-srt.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/cli/tap-srt.c')
-rw-r--r--ui/cli/tap-srt.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/ui/cli/tap-srt.c b/ui/cli/tap-srt.c
new file mode 100644
index 0000000..62cef3a
--- /dev/null
+++ b/ui/cli/tap-srt.c
@@ -0,0 +1,196 @@
+/* tap-srt.c
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <string.h>
+#include <epan/packet.h>
+#include <epan/srt_table.h>
+#include <epan/timestamp.h>
+#include <epan/stat_tap_ui.h>
+#include <wsutil/cmdarg_err.h>
+#include <ui/cli/tshark-tap.h>
+
+#define NANOSECS_PER_SEC 1000000000
+
+typedef struct _srt_t {
+ const char *type;
+ const char *filter;
+ srt_data_t data;
+} srt_t;
+
+static void
+draw_srt_table_data(srt_stat_table *rst, gboolean draw_footer, const char *subfilter)
+{
+ int i;
+ guint64 td;
+ guint64 sum;
+
+ if (rst->num_procs > 0) {
+ if (rst->filter_string != NULL && subfilter != NULL) {
+ printf("Filter: %s and (%s)\n", rst->filter_string, subfilter);
+ } else if (subfilter != NULL) {
+ /* Print (subfilter) to disambiguate from just rst->filter_string. */
+ printf("Filter: (%s)\n", subfilter);
+ } else {
+ printf("Filter: %s\n", rst->filter_string ? rst->filter_string : "");
+ }
+ printf("Index %-22s Calls Min SRT Max SRT Avg SRT Sum SRT\n", (rst->proc_column_name != NULL) ? rst->proc_column_name : "Procedure");
+ }
+ for(i=0;i<rst->num_procs;i++){
+ /* ignore procedures with no calls (they don't have rows) */
+ if(rst->procedures[i].stats.num==0){
+ continue;
+ }
+ /* Scale the average SRT in units of 1us and round to the nearest us.
+ tot.secs is a time_t which may be 32 or 64 bits (or even floating)
+ depending uon the platform. After casting tot.secs to 64 bits, it
+ would take a capture with a duration of over 136 *years* to
+ overflow the secs portion of td. */
+ td = ((guint64)(rst->procedures[i].stats.tot.secs))*NANOSECS_PER_SEC + rst->procedures[i].stats.tot.nsecs;
+ sum = (td + 500) / 1000;
+ td = ((td / rst->procedures[i].stats.num) + 500) / 1000;
+
+ printf("%5d %-22s %6u %3d.%06d %3d.%06d %3d.%06d %3d.%06d\n",
+ i, rst->procedures[i].procedure,
+ rst->procedures[i].stats.num,
+ (int)rst->procedures[i].stats.min.secs, (rst->procedures[i].stats.min.nsecs+500)/1000,
+ (int)rst->procedures[i].stats.max.secs, (rst->procedures[i].stats.max.nsecs+500)/1000,
+ (int)(td/1000000), (int)(td%1000000),
+ (int)(sum/1000000), (int)(sum%1000000)
+ );
+ }
+
+ if (draw_footer)
+ printf("==================================================================\n");
+}
+
+static void
+srt_draw(void *arg)
+{
+ guint i = 0;
+ srt_data_t* data = (srt_data_t*)arg;
+ srt_t *ui = (srt_t *)data->user_data;
+ srt_stat_table *srt_table;
+ gboolean need_newline = FALSE;
+
+ printf("\n");
+ printf("===================================================================\n");
+ printf("%s SRT Statistics:\n", ui->type);
+
+ srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ draw_srt_table_data(srt_table, data->srt_array->len == 1, ui->filter);
+ if (srt_table->num_procs > 0) {
+ need_newline = TRUE;
+ }
+
+ for (i = 1; i < data->srt_array->len; i++)
+ {
+ if (need_newline)
+ {
+ printf("\n");
+ need_newline = FALSE;
+ }
+ srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+ draw_srt_table_data(srt_table, i == data->srt_array->len-1, ui->filter);
+ if (srt_table->num_procs > 0) {
+ need_newline = TRUE;
+ }
+ }
+}
+
+static GArray* global_srt_array;
+
+static void
+init_srt_tables(register_srt_t* srt, const char *filter)
+{
+ srt_t *ui;
+ GString *error_string;
+
+ ui = g_new0(srt_t, 1);
+ ui->type = proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt)));
+ ui->filter = g_strdup(filter);
+ ui->data.srt_array = global_srt_array;
+ ui->data.user_data = ui;
+
+ error_string = register_tap_listener(get_srt_tap_listener_name(srt), &ui->data, filter, 0, NULL, get_srt_packet_func(srt), srt_draw, NULL);
+ if (error_string) {
+ free_srt_table(srt, global_srt_array);
+ g_free(ui);
+ cmdarg_err("Couldn't register srt tap: %s", error_string->str);
+ g_string_free(error_string, TRUE);
+ exit(1);
+ }
+}
+
+static void
+dissector_srt_init(const char *opt_arg, void* userdata)
+{
+ register_srt_t *srt = (register_srt_t*)userdata;
+ const char *filter=NULL;
+ char* err;
+
+ srt_table_get_filter(srt, opt_arg, &filter, &err);
+ if (err != NULL)
+ {
+ gchar* cmd_str = srt_table_get_tap_string(srt);
+ cmdarg_err("invalid \"-z %s,%s\" argument", cmd_str, err);
+ g_free(cmd_str);
+ g_free(err);
+ exit(1);
+ }
+
+ /* Need to create the SRT array now */
+ global_srt_array = g_array_new(FALSE, TRUE, sizeof(srt_stat_table*));
+
+ srt_table_dissector_init(srt, global_srt_array);
+ init_srt_tables(srt, filter);
+}
+
+/* Set GUI fields for register_srt list */
+bool
+register_srt_tables(const void *key _U_, void *value, void *userdata _U_)
+{
+ register_srt_t *srt = (register_srt_t*)value;
+ const char* short_name = proto_get_protocol_short_name(find_protocol_by_id(get_srt_proto_id(srt)));
+ stat_tap_ui ui_info;
+ gchar *cli_string;
+
+ /* XXX - CAMEL dissector hasn't been converted over due seemingly different tap packet
+ handling functions. So let the existing TShark CAMEL tap keep its registration */
+ if (strcmp(short_name, "CAMEL") == 0)
+ return FALSE;
+
+ cli_string = srt_table_get_tap_string(srt);
+ ui_info.group = REGISTER_STAT_GROUP_RESPONSE_TIME;
+ ui_info.title = NULL; /* construct this from the protocol info? */
+ ui_info.cli_string = cli_string;
+ ui_info.tap_init_cb = dissector_srt_init;
+ ui_info.nparams = 0;
+ ui_info.params = NULL;
+ register_stat_tap_ui(&ui_info, srt);
+ g_free(cli_string);
+ return FALSE;
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */