aboutsummaryrefslogtreecommitdiffstats
path: root/epan/sequence_analysis.c
diff options
context:
space:
mode:
authorJakub Zawadzki <darkjames-ws@darkjames.pl>2017-09-16 16:52:23 +0200
committerMichael Mann <mmann78@netscape.net>2017-09-18 21:24:16 +0000
commitc41bab1f667cfe51b09b80869497a2db68abecce (patch)
treef61fbf402e9cfe58b9a694eabf4dd389bed94796 /epan/sequence_analysis.c
parenta593fce94cb7fd0fa3f5eef7fae9c0128cb6f7e3 (diff)
Move most of sequence analysis code from ui/ to epan/
Create registration system to allow creation of analysis items to be localized to the dissector. For now only frame (all) and TCP are supported. VOIP functionality will be covered in a separate patch. Change-Id: I5b05ef6d5afff8d0b162b03a0f451ab810602e81 Reviewed-on: https://code.wireshark.org/review/23571 Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/sequence_analysis.c')
-rw-r--r--epan/sequence_analysis.c275
1 files changed, 275 insertions, 0 deletions
diff --git a/epan/sequence_analysis.c b/epan/sequence_analysis.c
new file mode 100644
index 0000000000..7d8f03064f
--- /dev/null
+++ b/epan/sequence_analysis.c
@@ -0,0 +1,275 @@
+/* sequence-analysis.c
+ * Flow sequence analysis
+ *
+ * Some code from from gtk/flow_graph.c
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "config.h"
+
+#include "sequence_analysis.h"
+
+#include "addr_resolv.h"
+#include "proto.h"
+#include "tap.h"
+#include "wmem/wmem.h"
+
+#define NODE_OVERFLOW MAX_NUM_NODES+1
+
+struct register_analysis {
+ const char* name; /* Name (used for lookup) */
+ const char* ui_name; /* Name used for UI */
+ int proto_id; /* protocol id (0-indexed) */
+ const char* tap_listen_str; /* string used in register_tap_listener (NULL to use protocol name) */
+ guint tap_flags;
+ tap_packet_cb analysis_func; /* function to be called for new incoming packets for sequence analysis */
+};
+
+static wmem_tree_t *registered_seq_analysis = NULL;
+
+void
+register_seq_analysis(const char* name, const char* ui_name, const int proto_id, const char* tap_listener, guint tap_flags, tap_packet_cb tap_func)
+{
+ register_analysis_t* analysis;
+
+ DISSECTOR_ASSERT(tap_func);
+
+ analysis = wmem_new0(wmem_epan_scope(), register_analysis_t);
+
+ analysis->name = name;
+ analysis->ui_name = ui_name;
+ analysis->proto_id = proto_id;
+ if (tap_listener != NULL)
+ analysis->tap_listen_str = tap_listener;
+ else
+ analysis->tap_listen_str = proto_get_protocol_filter_name(proto_id);
+ analysis->tap_flags = tap_flags;
+ analysis->analysis_func = tap_func;
+
+ if (registered_seq_analysis == NULL)
+ registered_seq_analysis = wmem_tree_new(wmem_epan_scope());
+
+ wmem_tree_insert_string(registered_seq_analysis, name, analysis, 0);
+}
+
+const char* sequence_analysis_get_name(register_analysis_t* analysis)
+{
+ return analysis->name;
+}
+
+const char* sequence_analysis_get_ui_name(register_analysis_t* analysis)
+{
+ return analysis->ui_name;
+}
+
+const char* sequence_analysis_get_tap_listener_name(register_analysis_t* analysis)
+{
+ return analysis->tap_listen_str;
+}
+
+tap_packet_cb sequence_analysis_get_packet_func(register_analysis_t* analysis)
+{
+ return analysis->analysis_func;
+}
+
+guint sequence_analysis_get_tap_flags(register_analysis_t* analysis)
+{
+ return analysis->tap_flags;
+}
+
+
+register_analysis_t* sequence_analysis_find_by_name(const char* name)
+{
+ return (register_analysis_t*)wmem_tree_lookup_string(registered_seq_analysis, name, 0);
+}
+
+void sequence_analysis_table_iterate_tables(wmem_foreach_func func, gpointer user_data)
+{
+ wmem_tree_foreach(registered_seq_analysis, func, user_data);
+}
+
+seq_analysis_info_t *
+sequence_analysis_info_new(void)
+{
+ seq_analysis_info_t *sainfo = g_new0(seq_analysis_info_t, 1);
+
+ /* SEQ_ANALYSIS_DEBUG("adding new item"); */
+ sainfo->items = g_queue_new();
+ sainfo->ht= g_hash_table_new(g_int_hash, g_int_equal);
+ return sainfo;
+}
+
+void sequence_analysis_info_free(seq_analysis_info_t *sainfo)
+{
+ if (!sainfo) return;
+
+ /* SEQ_ANALYSIS_DEBUG("%d items", g_queue_get_length(sainfo->items)); */
+ sequence_analysis_list_free(sainfo);
+
+ g_queue_free(sainfo->items);
+ g_hash_table_destroy(sainfo->ht);
+
+ g_free(sainfo);
+}
+
+static void sequence_analysis_item_free(gpointer data)
+{
+ seq_analysis_item_t *seq_item = (seq_analysis_item_t *)data;
+ g_free(seq_item->frame_label);
+ g_free(seq_item->time_str);
+ g_free(seq_item->comment);
+ g_free(seq_item->protocol);
+ free_address(&seq_item->src_addr);
+ free_address(&seq_item->dst_addr);
+ g_free(data);
+}
+
+
+/* compare two list entries by packet no */
+static gint
+sequence_analysis_sort_compare(gconstpointer a, gconstpointer b, gpointer user_data _U_)
+{
+ const seq_analysis_item_t *entry_a = (const seq_analysis_item_t *)a;
+ const seq_analysis_item_t *entry_b = (const seq_analysis_item_t *)b;
+
+ if(entry_a->frame_number < entry_b->frame_number)
+ return -1;
+
+ if(entry_a->frame_number > entry_b->frame_number)
+ return 1;
+
+ return 0;
+}
+
+
+void
+sequence_analysis_list_sort(seq_analysis_info_t *sainfo)
+{
+ if (!sainfo) return;
+ g_queue_sort(sainfo->items, sequence_analysis_sort_compare, NULL);
+}
+
+void
+sequence_analysis_list_free(seq_analysis_info_t *sainfo)
+{
+ if (!sainfo) return;
+ /* SEQ_ANALYSIS_DEBUG("%d items", g_queue_get_length(sainfo->items)); */
+
+ /* free the graph data items */
+
+#if GLIB_CHECK_VERSION (2, 32, 0)
+ g_queue_free_full(sainfo->items, sequence_analysis_item_free);
+ sainfo->items = g_queue_new();
+#else
+ {
+ GList *list = g_queue_peek_nth_link(sainfo->items, 0);
+ while (list)
+ {
+ sequence_analysis_item_free(list->data);
+ list = g_list_next(list);
+ }
+ g_queue_clear(sainfo->items);
+ }
+#endif
+
+ if (NULL != sainfo->ht) {
+ g_hash_table_remove_all(sainfo->ht);
+ }
+ sainfo->nconv = 0;
+
+ sequence_analysis_free_nodes(sainfo);
+}
+
+/* Return the index array if the node is in the array. Return -1 if there is room in the array
+ * and Return -2 if the array is full
+ */
+/****************************************************************************/
+static guint add_or_get_node(seq_analysis_info_t *sainfo, address *node) {
+ guint i;
+
+ if (node->type == AT_NONE) return NODE_OVERFLOW;
+
+ for (i=0; i<MAX_NUM_NODES && i < sainfo->num_nodes ; i++) {
+ if ( cmp_address(&(sainfo->nodes[i]), node) == 0 ) return i; /* it is in the array */
+ }
+
+ if (i >= MAX_NUM_NODES) {
+ return NODE_OVERFLOW;
+ } else {
+ sainfo->num_nodes++;
+ copy_address(&(sainfo->nodes[i]), node);
+ return i;
+ }
+}
+
+struct sainfo_counter {
+ seq_analysis_info_t *sainfo;
+ int num_items;
+};
+
+static void sequence_analysis_get_nodes_item_proc(gpointer data, gpointer user_data)
+{
+ seq_analysis_item_t *gai = (seq_analysis_item_t *)data;
+ struct sainfo_counter *sc = (struct sainfo_counter *)user_data;
+ if (gai->display) {
+ (sc->num_items)++;
+ gai->src_node = add_or_get_node(sc->sainfo, &(gai->src_addr));
+ gai->dst_node = add_or_get_node(sc->sainfo, &(gai->dst_addr));
+ }
+}
+
+/* Get the nodes from the list */
+/****************************************************************************/
+int
+sequence_analysis_get_nodes(seq_analysis_info_t *sainfo)
+{
+ struct sainfo_counter sc = {sainfo, 0};
+
+ /* Fill the node array */
+ g_queue_foreach(sainfo->items, sequence_analysis_get_nodes_item_proc, &sc);
+
+ return sc.num_items;
+}
+
+/* Free the node address list */
+/****************************************************************************/
+void
+sequence_analysis_free_nodes(seq_analysis_info_t *sainfo)
+{
+ int i;
+
+ for (i=0; i<MAX_NUM_NODES; i++) {
+ free_address(&sainfo->nodes[i]);
+ }
+ sainfo->num_nodes = 0;
+}
+
+/*
+ * Editor modelines
+ *
+ * Local Variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */