summaryrefslogtreecommitdiffstats
path: root/ui/cli/tap-flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'ui/cli/tap-flow.c')
-rw-r--r--ui/cli/tap-flow.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/ui/cli/tap-flow.c b/ui/cli/tap-flow.c
new file mode 100644
index 00000000..32e0a94f
--- /dev/null
+++ b/ui/cli/tap-flow.c
@@ -0,0 +1,147 @@
+/* tap-flow.c
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/* This module provides udp and tcp follow stream capabilities to tshark.
+ * It is only used by tshark and not wireshark.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <epan/sequence_analysis.h>
+#include <epan/stat_tap_ui.h>
+#include <epan/tap.h>
+
+void register_tap_listener_flow(void);
+
+#define STR_FLOW "flow,"
+#define STR_STANDARD ",standard"
+#define STR_NETWORK ",network"
+
+WS_NORETURN static void flow_exit(const char *strp)
+{
+ fprintf(stderr, "tshark: flow - %s\n", strp);
+ exit(1);
+}
+
+static void
+flow_draw(void *arg)
+{
+ seq_analysis_info_t* flow_info = (seq_analysis_info_t*)arg;
+
+ sequence_analysis_get_nodes(flow_info);
+
+ sequence_analysis_dump_to_file(stdout, flow_info, 0);
+
+ //clean up the data
+ sequence_analysis_list_free(flow_info);
+ sequence_analysis_info_free(flow_info);
+}
+
+static gboolean flow_arg_strncmp(const char **opt_argp, const char *strp)
+{
+ size_t len = strlen(strp);
+
+ if (strncmp(*opt_argp, strp, len) == 0)
+ {
+ *opt_argp += len;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static void
+flow_arg_mode(const char **opt_argp, seq_analysis_info_t *flow_info)
+{
+ if (flow_arg_strncmp(opt_argp, STR_STANDARD))
+ {
+ flow_info->any_addr = 1;
+ }
+ else if (flow_arg_strncmp(opt_argp, STR_NETWORK))
+ {
+ flow_info->any_addr = 0;
+ }
+ else
+ {
+ flow_exit("Invalid address type.");
+ }
+}
+
+static void
+flow_init(const char *opt_argp, void *userdata)
+{
+ seq_analysis_info_t *flow_info = g_new0(seq_analysis_info_t, 1);
+ GString *errp;
+ register_analysis_t* analysis = (register_analysis_t*)userdata;
+ const char *filter=NULL;
+
+ opt_argp += strlen(STR_FLOW);
+ opt_argp += strlen(sequence_analysis_get_name(analysis));
+
+ flow_arg_mode(&opt_argp, flow_info);
+ if (*opt_argp == ',') {
+ filter = opt_argp + 1;
+ }
+
+ sequence_analysis_list_free(flow_info);
+
+ errp = register_tap_listener(sequence_analysis_get_tap_listener_name(analysis), flow_info, filter, sequence_analysis_get_tap_flags(analysis),
+ NULL, sequence_analysis_get_packet_func(analysis), flow_draw, NULL);
+
+ if (errp != NULL)
+ {
+ sequence_analysis_list_free(flow_info);
+ sequence_analysis_info_free(flow_info);
+ g_string_free(errp, TRUE);
+ flow_exit("Error registering tap listener.");
+ }
+}
+
+static bool
+flow_register(const void *key _U_, void *value, void *userdata _U_)
+{
+ register_analysis_t* analysis = (register_analysis_t*)value;
+ stat_tap_ui flow_ui;
+ GString *cmd_str = g_string_new(STR_FLOW);
+ gchar *cli_string;
+
+ g_string_append(cmd_str, sequence_analysis_get_name(analysis));
+ cli_string = g_string_free(cmd_str, FALSE);
+
+ flow_ui.group = REGISTER_STAT_GROUP_GENERIC;
+ flow_ui.title = NULL; /* construct this from the protocol info? */
+ flow_ui.cli_string = cli_string;
+ flow_ui.tap_init_cb = flow_init;
+ flow_ui.nparams = 0;
+ flow_ui.params = NULL;
+ register_stat_tap_ui(&flow_ui, analysis);
+ g_free(cli_string);
+ return FALSE;
+}
+
+void
+register_tap_listener_flow(void)
+{
+ sequence_analysis_table_iterate_tables(flow_register, NULL);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */