2014-07-23 17:38:55 +00:00
|
|
|
/* conversations_table.c
|
|
|
|
* conversations_table 2003 Ronnie Sahlberg
|
|
|
|
* Helper routines common to all endpoint conversations tap.
|
2014-04-29 15:10:27 +00:00
|
|
|
*
|
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-08 16:59:17 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2014-04-29 15:10:27 +00:00
|
|
|
*/
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2014-04-29 15:10:27 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "proto.h"
|
2016-01-25 01:10:20 +00:00
|
|
|
#include "packet_info.h"
|
2014-07-23 17:38:55 +00:00
|
|
|
#include "conversation_table.h"
|
|
|
|
#include "addr_resolv.h"
|
2016-06-22 00:06:01 +00:00
|
|
|
#include "address_types.h"
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2014-11-14 18:51:40 +00:00
|
|
|
#include "stat_tap_ui.h"
|
2014-07-23 17:38:55 +00:00
|
|
|
|
|
|
|
struct register_ct {
|
|
|
|
gboolean hide_ports; /* hide TCP / UDP port columns */
|
|
|
|
int proto_id; /* protocol id (0-indexed) */
|
2022-08-23 07:52:07 +00:00
|
|
|
tap_packet_cb conv_func; /* function to be called for new incoming packets for conversations */
|
|
|
|
tap_packet_cb endpoint_func; /* function to be called for new incoming packets for endpoints */
|
2014-07-25 15:34:51 +00:00
|
|
|
conv_gui_init_cb conv_gui_init; /* GUI specific function to initialize conversation */
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_gui_init_cb endpoint_gui_init; /* GUI specific function to initialize endpoint */
|
2014-04-29 15:10:27 +00:00
|
|
|
};
|
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
gboolean get_conversation_hide_ports(register_ct_t* ct)
|
|
|
|
{
|
|
|
|
return ct->hide_ports;
|
|
|
|
}
|
2014-04-29 15:10:27 +00:00
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
int get_conversation_proto_id(register_ct_t* ct)
|
|
|
|
{
|
|
|
|
if (!ct) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return ct->proto_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
tap_packet_cb get_conversation_packet_func(register_ct_t* ct)
|
|
|
|
{
|
2014-07-25 15:34:51 +00:00
|
|
|
return ct->conv_func;
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
tap_packet_cb get_endpoint_packet_func(register_ct_t* ct)
|
|
|
|
{
|
|
|
|
return ct->endpoint_func;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For backwards source and binary compatibility */
|
2014-07-25 15:34:51 +00:00
|
|
|
tap_packet_cb get_hostlist_packet_func(register_ct_t* ct)
|
|
|
|
{
|
2022-08-23 07:52:07 +00:00
|
|
|
return get_endpoint_packet_func(ct);
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
|
2017-02-07 22:05:17 +00:00
|
|
|
static wmem_tree_t *registered_ct_tables = NULL;
|
2014-07-23 17:38:55 +00:00
|
|
|
|
|
|
|
void
|
|
|
|
dissector_conversation_init(const char *opt_arg, void* userdata)
|
|
|
|
{
|
|
|
|
register_ct_t *table = (register_ct_t*)userdata;
|
|
|
|
GString *cmd_str = g_string_new("conv,");
|
|
|
|
const char *filter=NULL;
|
|
|
|
|
|
|
|
g_string_append(cmd_str, proto_get_protocol_filter_name(table->proto_id));
|
|
|
|
if(!strncmp(opt_arg, cmd_str->str, cmd_str->len)){
|
2014-12-31 11:36:58 +00:00
|
|
|
if (opt_arg[cmd_str->len] == ',') {
|
|
|
|
filter = opt_arg + cmd_str->len + 1;
|
|
|
|
}
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
g_string_free(cmd_str, TRUE);
|
|
|
|
|
2014-07-25 15:34:51 +00:00
|
|
|
if (table->conv_gui_init)
|
|
|
|
table->conv_gui_init(table, filter);
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
2014-07-25 15:34:51 +00:00
|
|
|
void
|
2022-08-23 07:52:07 +00:00
|
|
|
dissector_endpoint_init(const char *opt_arg, void* userdata)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
|
|
|
register_ct_t *table = (register_ct_t*)userdata;
|
|
|
|
GString *cmd_str = g_string_new("");
|
|
|
|
const char *filter=NULL;
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
g_string_printf(cmd_str, "%s,%s", ENDPOINT_TAP_PREFIX, proto_get_protocol_filter_name(table->proto_id));
|
2014-07-25 15:34:51 +00:00
|
|
|
if(!strncmp(opt_arg, cmd_str->str, cmd_str->len)){
|
2014-12-31 11:36:58 +00:00
|
|
|
if (opt_arg[cmd_str->len] == ',') {
|
|
|
|
filter = opt_arg + cmd_str->len + 1;
|
|
|
|
}
|
2014-07-25 15:34:51 +00:00
|
|
|
} else {
|
|
|
|
filter=NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_string_free(cmd_str, TRUE);
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
if (table->endpoint_gui_init)
|
|
|
|
table->endpoint_gui_init(table, filter);
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
2022-08-23 07:52:07 +00:00
|
|
|
|
|
|
|
/* For backwards source and binary compatibility */
|
|
|
|
void
|
|
|
|
dissector_hostlist_init(const char *opt_arg, void* userdata)
|
|
|
|
{
|
|
|
|
dissector_endpoint_init(opt_arg, userdata);
|
|
|
|
}
|
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
/** get conversation from protocol ID
|
|
|
|
*
|
|
|
|
* @param proto_id protocol ID
|
|
|
|
* @return tap function handler of conversation
|
2014-04-29 15:10:27 +00:00
|
|
|
*/
|
2014-07-23 17:38:55 +00:00
|
|
|
register_ct_t* get_conversation_by_proto_id(int proto_id)
|
|
|
|
{
|
2017-02-07 22:05:17 +00:00
|
|
|
return (register_ct_t*)wmem_tree_lookup_string(registered_ct_tables, proto_get_protocol_short_name(find_protocol_by_id(proto_id)), 0);
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-08-23 07:52:07 +00:00
|
|
|
register_conversation_table(const int proto_id, gboolean hide_ports, tap_packet_cb conv_packet_func, tap_packet_cb endpoint_packet_func)
|
2014-04-29 15:10:27 +00:00
|
|
|
{
|
2014-07-23 17:38:55 +00:00
|
|
|
register_ct_t *table;
|
|
|
|
|
2017-02-07 22:05:17 +00:00
|
|
|
table = wmem_new(wmem_epan_scope(), register_ct_t);
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2014-07-25 15:34:51 +00:00
|
|
|
table->hide_ports = hide_ports;
|
|
|
|
table->proto_id = proto_id;
|
|
|
|
table->conv_func = conv_packet_func;
|
2022-08-23 07:52:07 +00:00
|
|
|
table->endpoint_func = endpoint_packet_func;
|
2014-07-25 15:34:51 +00:00
|
|
|
table->conv_gui_init = NULL;
|
2022-08-23 07:52:07 +00:00
|
|
|
table->endpoint_gui_init = NULL;
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2017-02-07 22:05:17 +00:00
|
|
|
if (registered_ct_tables == NULL)
|
|
|
|
registered_ct_tables = wmem_tree_new(wmem_epan_scope());
|
|
|
|
|
|
|
|
wmem_tree_insert_string(registered_ct_tables, proto_get_protocol_short_name(find_protocol_by_id(proto_id)), table, 0);
|
2014-12-30 22:46:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set GUI fields for register_ct list */
|
2017-02-07 22:05:17 +00:00
|
|
|
static gboolean
|
|
|
|
set_conv_gui_data(const void *key _U_, void *value, void *userdata)
|
2014-12-30 22:46:24 +00:00
|
|
|
{
|
|
|
|
GString *conv_cmd_str = g_string_new("conv,");
|
|
|
|
stat_tap_ui ui_info;
|
2017-02-07 22:05:17 +00:00
|
|
|
register_ct_t *table = (register_ct_t*)value;
|
2014-12-30 22:46:24 +00:00
|
|
|
|
2017-02-07 22:05:17 +00:00
|
|
|
table->conv_gui_init = (conv_gui_init_cb)userdata;
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2014-07-25 15:34:51 +00:00
|
|
|
g_string_append(conv_cmd_str, proto_get_protocol_filter_name(table->proto_id));
|
2014-11-14 18:31:04 +00:00
|
|
|
ui_info.group = REGISTER_STAT_GROUP_CONVERSATION_LIST;
|
2015-02-13 17:05:26 +00:00
|
|
|
ui_info.title = NULL; /* construct this from the protocol info? */
|
2015-01-13 23:13:40 +00:00
|
|
|
ui_info.cli_string = g_string_free(conv_cmd_str, FALSE);
|
2014-11-14 18:31:04 +00:00
|
|
|
ui_info.tap_init_cb = dissector_conversation_init;
|
|
|
|
ui_info.nparams = 0;
|
|
|
|
ui_info.params = NULL;
|
2014-11-14 18:42:26 +00:00
|
|
|
register_stat_tap_ui(&ui_info, table);
|
2017-02-11 23:04:31 +00:00
|
|
|
g_free((char*)ui_info.cli_string);
|
2017-02-07 22:05:17 +00:00
|
|
|
return FALSE;
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void conversation_table_set_gui_info(conv_gui_init_cb init_cb)
|
|
|
|
{
|
2017-02-07 22:05:17 +00:00
|
|
|
wmem_tree_foreach(registered_ct_tables, set_conv_gui_data, (void*)init_cb);
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
|
2017-02-07 22:05:17 +00:00
|
|
|
static gboolean
|
2022-08-23 07:52:07 +00:00
|
|
|
set_endpoint_gui_data(const void *key _U_, void *value, void *userdata)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
2014-12-30 22:46:24 +00:00
|
|
|
stat_tap_ui ui_info;
|
2017-02-07 22:05:17 +00:00
|
|
|
register_ct_t *table = (register_ct_t*)value;
|
2014-12-30 22:46:24 +00:00
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
table->endpoint_gui_init = (endpoint_gui_init_cb)userdata;
|
2014-12-30 22:46:24 +00:00
|
|
|
|
|
|
|
ui_info.group = REGISTER_STAT_GROUP_ENDPOINT_LIST;
|
2015-02-13 17:05:26 +00:00
|
|
|
ui_info.title = NULL; /* construct this from the protocol info? */
|
2022-08-23 07:52:07 +00:00
|
|
|
ui_info.cli_string = ws_strdup_printf("%s,%s", ENDPOINT_TAP_PREFIX, proto_get_protocol_filter_name(table->proto_id));
|
|
|
|
ui_info.tap_init_cb = dissector_endpoint_init;
|
2014-12-30 22:46:24 +00:00
|
|
|
ui_info.nparams = 0;
|
|
|
|
ui_info.params = NULL;
|
|
|
|
register_stat_tap_ui(&ui_info, table);
|
2017-02-07 22:05:17 +00:00
|
|
|
g_free((char*)ui_info.cli_string);
|
|
|
|
return FALSE;
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
void endpoint_table_set_gui_info(endpoint_gui_init_cb init_cb)
|
|
|
|
{
|
|
|
|
wmem_tree_foreach(registered_ct_tables, set_endpoint_gui_data, (void*)init_cb);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* For backwards source and binary compatibility */
|
|
|
|
void hostlist_table_set_gui_info(endpoint_gui_init_cb init_cb)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_table_set_gui_info(init_cb);
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
2017-02-07 22:05:17 +00:00
|
|
|
void conversation_table_iterate_tables(wmem_foreach_func func, void* user_data)
|
2014-07-23 17:38:55 +00:00
|
|
|
{
|
2017-02-07 22:05:17 +00:00
|
|
|
wmem_tree_foreach(registered_ct_tables, func, user_data);
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
guint conversation_table_get_num(void)
|
|
|
|
{
|
2017-02-07 22:05:17 +00:00
|
|
|
return wmem_tree_count(registered_ct_tables);
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Compute the hash value for two given address/port pairs.
|
|
|
|
* (Parameter type is gconstpointer for GHashTable compatibility.)
|
|
|
|
*
|
2014-08-28 16:49:03 +00:00
|
|
|
* @param v Conversation Key. MUST point to a conv_key_t struct.
|
2014-07-23 17:38:55 +00:00
|
|
|
* @return Computed key hash.
|
|
|
|
*/
|
|
|
|
static guint
|
|
|
|
conversation_hash(gconstpointer v)
|
|
|
|
{
|
|
|
|
const conv_key_t *key = (const conv_key_t *)v;
|
2014-04-29 15:10:27 +00:00
|
|
|
guint hash_val;
|
|
|
|
|
|
|
|
hash_val = 0;
|
2015-12-02 21:52:35 +00:00
|
|
|
hash_val = add_address_to_hash(hash_val, &key->addr1);
|
2014-07-23 17:38:55 +00:00
|
|
|
hash_val += key->port1;
|
2015-12-02 21:52:35 +00:00
|
|
|
hash_val = add_address_to_hash(hash_val, &key->addr2);
|
2014-07-23 17:38:55 +00:00
|
|
|
hash_val += key->port2;
|
|
|
|
hash_val ^= key->conv_id;
|
2014-04-29 15:10:27 +00:00
|
|
|
|
|
|
|
return hash_val;
|
|
|
|
}
|
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
/** Compare two conversation keys for an exact match.
|
|
|
|
* (Parameter types are gconstpointer for GHashTable compatibility.)
|
|
|
|
*
|
|
|
|
* @param key1 First conversation. MUST point to a conv_key_t struct.
|
|
|
|
* @param key2 Second conversation. MUST point to a conv_key_t struct.
|
|
|
|
* @return TRUE if conversations are equal, FALSE otherwise.
|
2014-04-29 15:10:27 +00:00
|
|
|
*/
|
2014-07-23 17:38:55 +00:00
|
|
|
static gboolean
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_equal(gconstpointer key1, gconstpointer key2)
|
|
|
|
{
|
|
|
|
const conv_key_t *ck1 = (const conv_key_t *)key1;
|
|
|
|
const conv_key_t *ck2 = (const conv_key_t *)key2;
|
|
|
|
|
|
|
|
if (ck1->conv_id == ck2->conv_id)
|
|
|
|
{
|
|
|
|
if (ck1->port1 == ck2->port1 &&
|
|
|
|
ck1->port2 == ck2->port2 &&
|
2015-10-21 19:04:16 +00:00
|
|
|
addresses_equal(&ck1->addr1, &ck2->addr1) &&
|
|
|
|
addresses_equal(&ck1->addr2, &ck2->addr2)) {
|
2014-04-29 15:10:27 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ck1->port2 == ck2->port1 &&
|
|
|
|
ck1->port1 == ck2->port2 &&
|
2015-10-21 19:04:16 +00:00
|
|
|
addresses_equal(&ck1->addr2, &ck2->addr1) &&
|
|
|
|
addresses_equal(&ck1->addr1, &ck2->addr2)) {
|
2014-04-29 15:10:27 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The addresses, ports, or conversation IDs don't match.
|
|
|
|
*/
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
reset_conversation_table_data(conv_hash_t *ch)
|
|
|
|
{
|
|
|
|
if (!ch) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ch->conv_array != NULL) {
|
|
|
|
guint i;
|
|
|
|
for(i = 0; i < ch->conv_array->len; i++){
|
|
|
|
conv_item_t *conv = &g_array_index(ch->conv_array, conv_item_t, i);
|
2015-11-26 04:44:52 +00:00
|
|
|
free_address(&conv->src_address);
|
|
|
|
free_address(&conv->dst_address);
|
2014-04-29 15:10:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_array_free(ch->conv_array, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ch->hashtable != NULL) {
|
|
|
|
g_hash_table_destroy(ch->hashtable);
|
|
|
|
}
|
|
|
|
|
|
|
|
ch->conv_array=NULL;
|
|
|
|
ch->hashtable=NULL;
|
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
void reset_endpoint_table_data(conv_hash_t *ch)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
|
|
|
if (!ch) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ch->conv_array != NULL) {
|
|
|
|
guint i;
|
|
|
|
for(i = 0; i < ch->conv_array->len; i++){
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_item_t *endpoint = &g_array_index(ch->conv_array, endpoint_item_t, i);
|
|
|
|
free_address(&endpoint->myaddress);
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_array_free(ch->conv_array, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ch->hashtable != NULL) {
|
|
|
|
g_hash_table_destroy(ch->hashtable);
|
|
|
|
}
|
|
|
|
|
|
|
|
ch->conv_array=NULL;
|
|
|
|
ch->hashtable=NULL;
|
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
/* For backwards source and binary compatibility */
|
|
|
|
void reset_hostlist_table_data(conv_hash_t *ch)
|
|
|
|
{
|
|
|
|
reset_endpoint_table_data(ch);
|
|
|
|
}
|
|
|
|
|
2016-01-20 03:11:16 +00:00
|
|
|
char *get_conversation_address(wmem_allocator_t *allocator, address *addr, gboolean resolve_names)
|
2014-04-29 15:10:27 +00:00
|
|
|
{
|
|
|
|
if (resolve_names) {
|
2015-01-05 02:40:05 +00:00
|
|
|
return address_to_display(allocator, addr);
|
2014-04-29 15:10:27 +00:00
|
|
|
} else {
|
2015-01-05 02:40:05 +00:00
|
|
|
return address_to_str(allocator, addr);
|
2014-04-29 15:10:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-26 02:42:38 +00:00
|
|
|
char *get_conversation_port(wmem_allocator_t *allocator, guint32 port, conversation_type ctype, gboolean resolve_names)
|
2014-04-29 15:10:27 +00:00
|
|
|
{
|
|
|
|
|
2022-08-26 02:42:38 +00:00
|
|
|
if(!resolve_names) ctype = CONVERSATION_NONE;
|
|
|
|
|
|
|
|
switch(ctype) {
|
|
|
|
case(CONVERSATION_TCP):
|
|
|
|
return tcp_port_to_display(allocator, port);
|
|
|
|
case(CONVERSATION_UDP):
|
|
|
|
return udp_port_to_display(allocator, port);
|
|
|
|
case(CONVERSATION_SCTP):
|
|
|
|
return sctp_port_to_display(allocator, port);
|
|
|
|
case(CONVERSATION_DCCP):
|
|
|
|
return dccp_port_to_display(allocator, port);
|
|
|
|
default:
|
|
|
|
return wmem_strdup_printf(allocator, "%d", port);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char *get_endpoint_port(wmem_allocator_t *allocator, endpoint_item_t *item, gboolean resolve_names)
|
|
|
|
{
|
|
|
|
endpoint_type etype = item->etype;
|
|
|
|
|
2017-10-29 18:29:27 +00:00
|
|
|
if(!resolve_names) etype = ENDPOINT_NONE;
|
2014-04-29 15:10:27 +00:00
|
|
|
|
2017-10-29 18:29:27 +00:00
|
|
|
switch(etype) {
|
|
|
|
case(ENDPOINT_TCP):
|
2022-08-26 02:42:38 +00:00
|
|
|
return tcp_port_to_display(allocator, item->port);
|
2017-10-29 18:29:27 +00:00
|
|
|
case(ENDPOINT_UDP):
|
2022-08-26 02:42:38 +00:00
|
|
|
return udp_port_to_display(allocator, item->port);
|
2017-10-29 18:29:27 +00:00
|
|
|
case(ENDPOINT_SCTP):
|
2022-08-26 02:42:38 +00:00
|
|
|
return sctp_port_to_display(allocator, item->port);
|
2022-08-03 16:00:45 +00:00
|
|
|
case(ENDPOINT_DCCP):
|
2022-08-26 02:42:38 +00:00
|
|
|
return dccp_port_to_display(allocator, item->port);
|
2014-04-29 15:10:27 +00:00
|
|
|
default:
|
2022-08-26 02:42:38 +00:00
|
|
|
return wmem_strdup_printf(allocator, "%d", item->port);
|
2014-04-29 15:10:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* given an address (to distinguish between ipv4 and ipv6 for tcp/udp),
|
2017-10-29 18:29:27 +00:00
|
|
|
a endpoint_type and a name_type (FN_...)
|
2014-04-29 15:10:27 +00:00
|
|
|
return a string for the filter name.
|
|
|
|
|
|
|
|
Some addresses, like AT_ETHER may actually be any of multiple types
|
|
|
|
of protocols, either ethernet, tokenring, fddi, wlan etc so we must be
|
|
|
|
more specific there; that's why we need specific_addr_type.
|
|
|
|
*/
|
|
|
|
static const char *
|
|
|
|
conversation_get_filter_name(conv_item_t *conv_item, conv_filter_type_e filter_type)
|
|
|
|
{
|
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
if ((conv_item == NULL) || (conv_item->dissector_info == NULL) || (conv_item->dissector_info->get_filter_type == NULL)) {
|
|
|
|
return CONV_FILTER_INVALID;
|
2014-04-29 15:10:27 +00:00
|
|
|
}
|
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
return conv_item->dissector_info->get_filter_type(conv_item, filter_type);
|
2014-04-29 15:10:27 +00:00
|
|
|
}
|
|
|
|
|
2014-07-25 15:34:51 +00:00
|
|
|
static const char *
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_get_filter_name(endpoint_item_t *endpoint, conv_filter_type_e filter_type)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
if ((endpoint == NULL) || (endpoint->dissector_info == NULL) || (endpoint->dissector_info->get_filter_type == NULL)) {
|
2014-07-25 15:34:51 +00:00
|
|
|
return CONV_FILTER_INVALID;
|
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
return endpoint->dissector_info->get_filter_type(endpoint, filter_type);
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
|
2014-04-29 15:10:27 +00:00
|
|
|
/* Convert a port number into a string or NULL */
|
|
|
|
static char *
|
2022-08-26 02:42:38 +00:00
|
|
|
ct_port_to_str(conversation_type ctype, guint32 port)
|
2014-04-29 15:10:27 +00:00
|
|
|
{
|
2022-08-26 02:42:38 +00:00
|
|
|
switch(ctype){
|
|
|
|
case CONVERSATION_TCP:
|
|
|
|
case CONVERSATION_UDP:
|
|
|
|
case CONVERSATION_SCTP:
|
|
|
|
case CONVERSATION_NCP:
|
2021-12-16 18:06:18 +00:00
|
|
|
return ws_strdup_printf("%d", port);
|
2014-04-29 15:10:27 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2016-06-22 00:06:01 +00:00
|
|
|
static int usb_address_type = -1;
|
|
|
|
|
2016-01-20 03:11:16 +00:00
|
|
|
char *get_conversation_filter(conv_item_t *conv_item, conv_direction_e direction)
|
2014-04-29 15:10:27 +00:00
|
|
|
{
|
2015-01-05 16:12:08 +00:00
|
|
|
char *sport, *dport, *src_addr, *dst_addr;
|
2016-01-20 03:11:16 +00:00
|
|
|
char *str;
|
2014-04-29 15:10:27 +00:00
|
|
|
|
2016-06-22 00:06:01 +00:00
|
|
|
/* XXX - Hack until we find something better */
|
|
|
|
if (usb_address_type == -1)
|
|
|
|
usb_address_type = address_type_get_by_name("AT_USB");
|
|
|
|
|
2022-08-26 02:42:38 +00:00
|
|
|
sport = ct_port_to_str(conv_item->ctype, conv_item->src_port);
|
|
|
|
dport = ct_port_to_str(conv_item->ctype, conv_item->dst_port);
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr = address_to_str(NULL, &conv_item->src_address);
|
|
|
|
dst_addr = address_to_str(NULL, &conv_item->dst_address);
|
2014-04-29 15:10:27 +00:00
|
|
|
|
2016-06-22 00:06:01 +00:00
|
|
|
if (conv_item->src_address.type == AT_STRINGZ || conv_item->src_address.type == usb_address_type) {
|
2015-01-08 10:16:27 +00:00
|
|
|
char *new_addr;
|
|
|
|
|
|
|
|
new_addr = wmem_strdup_printf(NULL, "\"%s\"", src_addr);
|
|
|
|
wmem_free(NULL, src_addr);
|
|
|
|
src_addr = new_addr;
|
|
|
|
}
|
2016-06-22 00:06:01 +00:00
|
|
|
if (conv_item->dst_address.type == AT_STRINGZ || conv_item->dst_address.type == usb_address_type) {
|
2015-01-08 10:16:27 +00:00
|
|
|
char *new_addr;
|
|
|
|
|
|
|
|
new_addr = wmem_strdup_printf(NULL, "\"%s\"", dst_addr);
|
|
|
|
wmem_free(NULL, dst_addr);
|
|
|
|
dst_addr = new_addr;
|
|
|
|
}
|
|
|
|
|
2014-04-29 15:10:27 +00:00
|
|
|
switch(direction){
|
|
|
|
case CONV_DIR_A_TO_FROM_B:
|
|
|
|
/* A <-> B */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
sport?" && ":"",
|
|
|
|
sport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
|
|
|
|
sport?"==":"",
|
|
|
|
sport?sport:"",
|
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
dst_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
dport?" && ":"",
|
|
|
|
dport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
|
|
|
|
dport?"==":"",
|
|
|
|
dport?dport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_A_TO_B:
|
|
|
|
/* A --> B */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
sport?" && ":"",
|
|
|
|
sport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
|
|
|
|
sport?"==":"",
|
|
|
|
sport?sport:"",
|
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
dst_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
dport?" && ":"",
|
|
|
|
dport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
|
|
|
|
dport?"==":"",
|
|
|
|
dport?dport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_A_FROM_B:
|
|
|
|
/* A <-- B */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s && %s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
sport?" && ":"",
|
|
|
|
sport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
|
|
|
|
sport?"==":"",
|
|
|
|
sport?sport:"",
|
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
dst_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
dport?" && ":"",
|
|
|
|
dport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
|
|
|
|
dport?"==":"",
|
|
|
|
dport?dport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_A_TO_FROM_ANY:
|
|
|
|
/* A <-> ANY */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
sport?" && ":"",
|
|
|
|
sport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
|
|
|
|
sport?"==":"",
|
|
|
|
sport?sport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_A_TO_ANY:
|
|
|
|
/* A --> ANY */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
sport?" && ":"",
|
|
|
|
sport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
|
|
|
|
sport?"==":"",
|
|
|
|
sport?sport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_A_FROM_ANY:
|
|
|
|
/* A <-- ANY */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
sport?" && ":"",
|
|
|
|
sport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
|
|
|
|
sport?"==":"",
|
|
|
|
sport?sport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_ANY_TO_FROM_B:
|
|
|
|
/* ANY <-> B */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_ANY_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
dst_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
dport?" && ":"",
|
|
|
|
dport?conversation_get_filter_name(conv_item, CONV_FT_ANY_PORT):"",
|
|
|
|
dport?"==":"",
|
|
|
|
dport?dport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_ANY_FROM_B:
|
|
|
|
/* ANY <-- B */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_SRC_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
dst_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
dport?" && ":"",
|
|
|
|
dport?conversation_get_filter_name(conv_item, CONV_FT_SRC_PORT):"",
|
|
|
|
dport?"==":"",
|
|
|
|
dport?dport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case CONV_DIR_ANY_TO_B:
|
|
|
|
/* ANY --> B */
|
2015-01-10 19:20:06 +00:00
|
|
|
str = wmem_strdup_printf(NULL, "%s==%s%s%s%s%s",
|
2014-04-29 15:10:27 +00:00
|
|
|
conversation_get_filter_name(conv_item, CONV_FT_DST_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
dst_addr,
|
2014-04-29 15:10:27 +00:00
|
|
|
dport?" && ":"",
|
|
|
|
dport?conversation_get_filter_name(conv_item, CONV_FT_DST_PORT):"",
|
|
|
|
dport?"==":"",
|
|
|
|
dport?dport:""
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
default:
|
2016-01-20 03:11:16 +00:00
|
|
|
str = wmem_strdup(NULL, "INVALID");
|
2014-04-29 15:10:27 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
g_free(sport);
|
|
|
|
g_free(dport);
|
2015-01-05 16:12:08 +00:00
|
|
|
wmem_free(NULL, src_addr);
|
|
|
|
wmem_free(NULL, dst_addr);
|
2014-04-29 15:10:27 +00:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
char *get_endpoint_filter(endpoint_item_t *endpoint_item)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
2015-01-05 16:12:08 +00:00
|
|
|
char *sport, *src_addr;
|
2016-01-20 03:11:16 +00:00
|
|
|
char *str;
|
2014-07-25 15:34:51 +00:00
|
|
|
|
2016-06-22 00:06:01 +00:00
|
|
|
/* XXX - Hack until we find something better */
|
|
|
|
if (usb_address_type == -1)
|
|
|
|
usb_address_type = address_type_get_by_name("AT_USB");
|
|
|
|
|
2022-08-26 02:42:38 +00:00
|
|
|
switch(endpoint_item->etype){
|
|
|
|
case ENDPOINT_TCP:
|
|
|
|
case ENDPOINT_UDP:
|
|
|
|
case ENDPOINT_SCTP:
|
|
|
|
case ENDPOINT_NCP:
|
|
|
|
sport = ws_strdup_printf("%d", endpoint_item->port);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
sport = NULL;
|
|
|
|
break;
|
|
|
|
}
|
2022-08-23 07:52:07 +00:00
|
|
|
src_addr = address_to_str(NULL, &endpoint_item->myaddress);
|
|
|
|
if (endpoint_item->myaddress.type == AT_STRINGZ || endpoint_item->myaddress.type == usb_address_type) {
|
2015-01-08 10:16:27 +00:00
|
|
|
char *new_addr;
|
|
|
|
|
|
|
|
new_addr = wmem_strdup_printf(NULL, "\"%s\"", src_addr);
|
|
|
|
wmem_free(NULL, src_addr);
|
|
|
|
src_addr = new_addr;
|
|
|
|
}
|
2014-07-25 15:34:51 +00:00
|
|
|
|
2021-12-16 18:06:18 +00:00
|
|
|
str = ws_strdup_printf("%s==%s%s%s%s%s",
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_get_filter_name(endpoint_item, CONV_FT_ANY_ADDRESS),
|
2015-01-05 16:12:08 +00:00
|
|
|
src_addr,
|
2014-07-25 15:34:51 +00:00
|
|
|
sport?" && ":"",
|
2022-08-23 07:52:07 +00:00
|
|
|
sport?endpoint_get_filter_name(endpoint_item, CONV_FT_ANY_PORT):"",
|
2014-07-25 15:34:51 +00:00
|
|
|
sport?"==":"",
|
|
|
|
sport?sport:"");
|
|
|
|
|
2015-01-05 16:12:08 +00:00
|
|
|
g_free(sport);
|
|
|
|
wmem_free(NULL, src_addr);
|
2014-07-25 15:34:51 +00:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
/* For backwards source and binary compatibility */
|
|
|
|
char *get_hostlist_filter(endpoint_item_t *endpoint_item)
|
|
|
|
{
|
|
|
|
return get_endpoint_filter(endpoint_item);
|
|
|
|
}
|
|
|
|
|
2014-07-23 17:38:55 +00:00
|
|
|
void
|
2014-07-26 16:41:27 +00:00
|
|
|
add_conversation_table_data(conv_hash_t *ch, const address *src, const address *dst, guint32 src_port, guint32 dst_port, int num_frames, int num_bytes,
|
2022-08-26 02:42:38 +00:00
|
|
|
nstime_t *ts, nstime_t *abs_ts, ct_dissector_info_t *ct_info, conversation_type ctype)
|
2014-07-23 17:38:55 +00:00
|
|
|
{
|
2022-08-26 02:42:38 +00:00
|
|
|
add_conversation_table_data_with_conv_id(ch, src, dst, src_port, dst_port, CONV_ID_UNSET, num_frames, num_bytes, ts, abs_ts, ct_info, ctype);
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
add_conversation_table_data_with_conv_id(
|
|
|
|
conv_hash_t *ch,
|
|
|
|
const address *src,
|
|
|
|
const address *dst,
|
|
|
|
guint32 src_port,
|
|
|
|
guint32 dst_port,
|
|
|
|
conv_id_t conv_id,
|
|
|
|
int num_frames,
|
|
|
|
int num_bytes,
|
|
|
|
nstime_t *ts,
|
2014-07-26 16:41:27 +00:00
|
|
|
nstime_t *abs_ts,
|
2014-07-23 17:38:55 +00:00
|
|
|
ct_dissector_info_t *ct_info,
|
2022-08-26 02:42:38 +00:00
|
|
|
conversation_type ctype)
|
2014-07-23 17:38:55 +00:00
|
|
|
{
|
|
|
|
conv_item_t *conv_item = NULL;
|
2021-02-03 23:48:25 +00:00
|
|
|
gboolean is_fwd_direction = FALSE; /* direction of any conversation found */
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2014-09-16 15:25:17 +00:00
|
|
|
/* if we don't have any entries at all yet */
|
2014-07-23 17:38:55 +00:00
|
|
|
if (ch->conv_array == NULL) {
|
|
|
|
ch->conv_array = g_array_sized_new(FALSE, FALSE, sizeof(conv_item_t), 10000);
|
|
|
|
|
|
|
|
ch->hashtable = g_hash_table_new_full(conversation_hash,
|
|
|
|
conversation_equal, /* key_equal_func */
|
|
|
|
g_free, /* key_destroy_func */
|
|
|
|
NULL); /* value_destroy_func */
|
|
|
|
|
2021-02-03 23:48:25 +00:00
|
|
|
} else { /* try to find it among the existing known conversations */
|
|
|
|
/* first, check in the fwd conversations */
|
2014-07-23 17:38:55 +00:00
|
|
|
conv_key_t existing_key;
|
2014-11-24 01:03:42 +00:00
|
|
|
gpointer conversation_idx_hash_val;
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2021-02-03 23:48:25 +00:00
|
|
|
existing_key.addr1 = *src;
|
|
|
|
existing_key.addr2 = *dst;
|
|
|
|
existing_key.port1 = src_port;
|
|
|
|
existing_key.port2 = dst_port;
|
2014-07-23 17:38:55 +00:00
|
|
|
existing_key.conv_id = conv_id;
|
2014-11-24 01:03:42 +00:00
|
|
|
if (g_hash_table_lookup_extended(ch->hashtable, &existing_key, NULL, &conversation_idx_hash_val)) {
|
|
|
|
conv_item = &g_array_index(ch->conv_array, conv_item_t, GPOINTER_TO_UINT(conversation_idx_hash_val));
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
2021-02-03 23:48:25 +00:00
|
|
|
if (conv_item == NULL) {
|
|
|
|
/* then, check in the rev conversations if not found in 'fwd' */
|
|
|
|
existing_key.addr1 = *dst;
|
|
|
|
existing_key.addr2 = *src;
|
|
|
|
existing_key.port1 = dst_port;
|
|
|
|
existing_key.port2 = src_port;
|
|
|
|
if (g_hash_table_lookup_extended(ch->hashtable, &existing_key, NULL, &conversation_idx_hash_val)) {
|
|
|
|
conv_item = &g_array_index(ch->conv_array, conv_item_t, GPOINTER_TO_UINT(conversation_idx_hash_val));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* a conversation was found in this same fwd direction */
|
|
|
|
is_fwd_direction = TRUE;
|
|
|
|
}
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
2014-09-16 15:25:17 +00:00
|
|
|
/* if we still don't know what conversation this is it has to be a new one
|
2014-07-23 17:38:55 +00:00
|
|
|
and we have to allocate it and append it to the end of the list */
|
|
|
|
if (conv_item == NULL) {
|
|
|
|
conv_key_t *new_key;
|
|
|
|
conv_item_t new_conv_item;
|
2021-01-20 08:14:19 +00:00
|
|
|
unsigned int conversation_idx;
|
2014-07-23 17:38:55 +00:00
|
|
|
|
2021-02-03 23:48:25 +00:00
|
|
|
copy_address(&new_conv_item.src_address, src);
|
|
|
|
copy_address(&new_conv_item.dst_address, dst);
|
2014-07-23 17:38:55 +00:00
|
|
|
new_conv_item.dissector_info = ct_info;
|
2022-08-26 02:42:38 +00:00
|
|
|
new_conv_item.ctype = ctype;
|
2021-02-03 23:48:25 +00:00
|
|
|
new_conv_item.src_port = src_port;
|
|
|
|
new_conv_item.dst_port = dst_port;
|
2014-07-23 17:38:55 +00:00
|
|
|
new_conv_item.conv_id = conv_id;
|
|
|
|
new_conv_item.rx_frames = 0;
|
|
|
|
new_conv_item.tx_frames = 0;
|
|
|
|
new_conv_item.rx_bytes = 0;
|
|
|
|
new_conv_item.tx_bytes = 0;
|
2022-06-06 22:22:31 +00:00
|
|
|
new_conv_item.rx_frames_total = 0;
|
|
|
|
new_conv_item.tx_frames_total = 0;
|
|
|
|
new_conv_item.rx_bytes_total = 0;
|
|
|
|
new_conv_item.tx_bytes_total = 0;
|
2014-07-23 17:38:55 +00:00
|
|
|
|
|
|
|
if (ts) {
|
|
|
|
memcpy(&new_conv_item.start_time, ts, sizeof(new_conv_item.start_time));
|
|
|
|
memcpy(&new_conv_item.stop_time, ts, sizeof(new_conv_item.stop_time));
|
2014-07-26 16:41:27 +00:00
|
|
|
memcpy(&new_conv_item.start_abs_time, abs_ts, sizeof(new_conv_item.start_abs_time));
|
2014-07-23 17:38:55 +00:00
|
|
|
} else {
|
2014-07-26 16:41:27 +00:00
|
|
|
nstime_set_unset(&new_conv_item.start_abs_time);
|
2014-07-23 17:38:55 +00:00
|
|
|
nstime_set_unset(&new_conv_item.start_time);
|
|
|
|
nstime_set_unset(&new_conv_item.stop_time);
|
|
|
|
}
|
|
|
|
g_array_append_val(ch->conv_array, new_conv_item);
|
|
|
|
conversation_idx = ch->conv_array->len - 1;
|
|
|
|
conv_item = &g_array_index(ch->conv_array, conv_item_t, conversation_idx);
|
|
|
|
|
|
|
|
/* ct->conversations address is not a constant but src/dst_address.data are */
|
|
|
|
new_key = g_new(conv_key_t, 1);
|
2015-10-21 19:04:16 +00:00
|
|
|
set_address(&new_key->addr1, conv_item->src_address.type, conv_item->src_address.len, conv_item->src_address.data);
|
|
|
|
set_address(&new_key->addr2, conv_item->dst_address.type, conv_item->dst_address.len, conv_item->dst_address.data);
|
2021-02-03 23:48:25 +00:00
|
|
|
new_key->port1 = src_port;
|
|
|
|
new_key->port2 = dst_port;
|
2014-07-23 17:38:55 +00:00
|
|
|
new_key->conv_id = conv_id;
|
|
|
|
g_hash_table_insert(ch->hashtable, new_key, GUINT_TO_POINTER(conversation_idx));
|
|
|
|
|
2021-02-03 23:48:25 +00:00
|
|
|
/* update the conversation struct */
|
2022-06-09 20:10:49 +00:00
|
|
|
conv_item->tx_frames_total += num_frames;
|
|
|
|
conv_item->tx_bytes_total += num_bytes;
|
|
|
|
conv_item->filtered = TRUE;
|
|
|
|
if (! (ch->flags & TL_DISPLAY_FILTER_IGNORED)) {
|
|
|
|
conv_item->tx_frames += num_frames;
|
|
|
|
conv_item->tx_bytes += num_bytes;
|
|
|
|
conv_item->filtered = FALSE;
|
|
|
|
}
|
2014-07-23 17:38:55 +00:00
|
|
|
} else {
|
2021-02-03 23:48:25 +00:00
|
|
|
/*
|
|
|
|
* update an existing conversation
|
|
|
|
* update the conversation struct
|
|
|
|
*/
|
|
|
|
if (is_fwd_direction) {
|
2022-06-09 20:10:49 +00:00
|
|
|
conv_item->tx_frames_total += num_frames;
|
|
|
|
conv_item->tx_bytes_total += num_bytes;
|
2021-02-03 23:48:25 +00:00
|
|
|
} else {
|
2022-06-09 20:10:49 +00:00
|
|
|
conv_item->rx_frames_total += num_frames;
|
|
|
|
conv_item->rx_bytes_total += num_bytes;
|
|
|
|
}
|
|
|
|
if (! (ch->flags & TL_DISPLAY_FILTER_IGNORED)) {
|
|
|
|
if( is_fwd_direction ){
|
|
|
|
conv_item->tx_frames += num_frames;
|
|
|
|
conv_item->tx_bytes += num_bytes;
|
|
|
|
} else {
|
|
|
|
conv_item->rx_frames += num_frames;
|
|
|
|
conv_item->rx_bytes += num_bytes;
|
|
|
|
}
|
|
|
|
conv_item->filtered = FALSE;
|
2021-02-03 23:48:25 +00:00
|
|
|
}
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ts) {
|
|
|
|
if (nstime_cmp(ts, &conv_item->stop_time) > 0) {
|
|
|
|
memcpy(&conv_item->stop_time, ts, sizeof(conv_item->stop_time));
|
|
|
|
} else if (nstime_cmp(ts, &conv_item->start_time) < 0) {
|
|
|
|
memcpy(&conv_item->start_time, ts, sizeof(conv_item->start_time));
|
2014-07-26 16:41:27 +00:00
|
|
|
memcpy(&conv_item->start_abs_time, abs_ts, sizeof(conv_item->start_abs_time));
|
2014-07-23 17:38:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-25 15:34:51 +00:00
|
|
|
/*
|
2022-08-23 07:52:07 +00:00
|
|
|
* Compute the hash value for a given address/port pair if the match
|
2014-07-25 15:34:51 +00:00
|
|
|
* is to be exact.
|
|
|
|
*/
|
|
|
|
static guint
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_hash(gconstpointer v)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
2022-08-23 07:52:07 +00:00
|
|
|
const endpoint_key_t *key = (const endpoint_key_t *)v;
|
2014-07-25 15:34:51 +00:00
|
|
|
guint hash_val;
|
|
|
|
|
|
|
|
hash_val = 0;
|
2015-12-02 21:52:35 +00:00
|
|
|
hash_val = add_address_to_hash(hash_val, &key->myaddress);
|
2014-07-25 15:34:51 +00:00
|
|
|
hash_val += key->port;
|
|
|
|
return hash_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2022-08-23 07:52:07 +00:00
|
|
|
* Compare two endpoint keys for an exact match.
|
2014-07-25 15:34:51 +00:00
|
|
|
*/
|
|
|
|
static gint
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_match(gconstpointer v, gconstpointer w)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
2022-08-23 07:52:07 +00:00
|
|
|
const endpoint_key_t *v1 = (const endpoint_key_t *)v;
|
|
|
|
const endpoint_key_t *v2 = (const endpoint_key_t *)w;
|
2014-07-25 15:34:51 +00:00
|
|
|
|
|
|
|
if (v1->port == v2->port &&
|
2015-10-21 19:04:16 +00:00
|
|
|
addresses_equal(&v1->myaddress, &v2->myaddress)) {
|
2014-07-25 15:34:51 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* The addresses or the ports don't match.
|
|
|
|
*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2022-08-23 07:52:07 +00:00
|
|
|
add_endpoint_table_data(conv_hash_t *ch, const address *addr, guint32 port, gboolean sender, int num_frames, int num_bytes, et_dissector_info_t *et_info, endpoint_type etype)
|
2014-07-25 15:34:51 +00:00
|
|
|
{
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_item_t *endpoint_item = NULL;
|
2014-07-25 15:34:51 +00:00
|
|
|
|
|
|
|
/* XXX should be optimized to allocate n extra entries at a time
|
|
|
|
instead of just one */
|
2014-09-16 15:25:17 +00:00
|
|
|
/* if we don't have any entries at all yet */
|
2014-07-25 15:34:51 +00:00
|
|
|
if(ch->conv_array==NULL){
|
2022-08-23 07:52:07 +00:00
|
|
|
ch->conv_array=g_array_sized_new(FALSE, FALSE, sizeof(endpoint_item_t), 10000);
|
|
|
|
ch->hashtable = g_hash_table_new_full(endpoint_hash,
|
|
|
|
endpoint_match, /* key_equal_func */
|
2014-07-25 15:34:51 +00:00
|
|
|
g_free, /* key_destroy_func */
|
|
|
|
NULL); /* value_destroy_func */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* try to find it among the existing known conversations */
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_key_t existing_key;
|
|
|
|
gpointer endpoint_idx_hash_val;
|
2014-07-25 15:34:51 +00:00
|
|
|
|
2015-11-26 04:44:52 +00:00
|
|
|
copy_address_shallow(&existing_key.myaddress, addr);
|
2014-07-25 15:34:51 +00:00
|
|
|
existing_key.port = port;
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
if (g_hash_table_lookup_extended(ch->hashtable, &existing_key, NULL, &endpoint_idx_hash_val)) {
|
|
|
|
endpoint_item = &g_array_index(ch->conv_array, endpoint_item_t, GPOINTER_TO_UINT(endpoint_idx_hash_val));
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
/* if we still don't know what endpoint this is it has to be a new one
|
2014-07-25 15:34:51 +00:00
|
|
|
and we have to allocate it and append it to the end of the list */
|
2022-08-23 07:52:07 +00:00
|
|
|
if(endpoint_item==NULL){
|
|
|
|
endpoint_key_t *new_key;
|
|
|
|
endpoint_item_t new_endpoint_item;
|
|
|
|
unsigned int endpoint_idx;
|
|
|
|
|
|
|
|
copy_address(&new_endpoint_item.myaddress, addr);
|
|
|
|
new_endpoint_item.dissector_info = et_info;
|
|
|
|
new_endpoint_item.etype=etype;
|
|
|
|
new_endpoint_item.port=port;
|
|
|
|
new_endpoint_item.rx_frames=0;
|
|
|
|
new_endpoint_item.tx_frames=0;
|
|
|
|
new_endpoint_item.rx_bytes=0;
|
|
|
|
new_endpoint_item.tx_bytes=0;
|
|
|
|
new_endpoint_item.rx_frames_total=0;
|
|
|
|
new_endpoint_item.tx_frames_total=0;
|
|
|
|
new_endpoint_item.rx_bytes_total=0;
|
|
|
|
new_endpoint_item.tx_bytes_total=0;
|
|
|
|
new_endpoint_item.modified = TRUE;
|
|
|
|
new_endpoint_item.filtered = TRUE;
|
|
|
|
|
|
|
|
g_array_append_val(ch->conv_array, new_endpoint_item);
|
|
|
|
endpoint_idx = ch->conv_array->len - 1;
|
|
|
|
endpoint_item = &g_array_index(ch->conv_array, endpoint_item_t, endpoint_idx);
|
2014-07-25 15:34:51 +00:00
|
|
|
|
|
|
|
/* hl->hosts address is not a constant but address.data is */
|
2022-08-23 07:52:07 +00:00
|
|
|
new_key = g_new(endpoint_key_t,1);
|
|
|
|
set_address(&new_key->myaddress, endpoint_item->myaddress.type, endpoint_item->myaddress.len, endpoint_item->myaddress.data);
|
2014-07-25 15:34:51 +00:00
|
|
|
new_key->port = port;
|
2022-08-23 07:52:07 +00:00
|
|
|
g_hash_table_insert(ch->hashtable, new_key, GUINT_TO_POINTER(endpoint_idx));
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
/* if this is a new endpoint we need to initialize the struct */
|
|
|
|
endpoint_item->modified = TRUE;
|
2014-07-25 15:34:51 +00:00
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
/* update the endpoint struct */
|
2022-06-09 20:10:49 +00:00
|
|
|
if (! (ch->flags & TL_DISPLAY_FILTER_IGNORED)) {
|
|
|
|
if( sender ){
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_item->tx_frames+=num_frames;
|
|
|
|
endpoint_item->tx_bytes+=num_bytes;
|
2022-06-09 20:10:49 +00:00
|
|
|
} else {
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_item->rx_frames+=num_frames;
|
|
|
|
endpoint_item->rx_bytes+=num_bytes;
|
2022-06-09 20:10:49 +00:00
|
|
|
}
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_item->filtered = FALSE;
|
2022-06-09 20:10:49 +00:00
|
|
|
}
|
2022-08-23 07:52:07 +00:00
|
|
|
/* update the endpoint struct for total values */
|
2014-07-25 15:34:51 +00:00
|
|
|
if( sender ){
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_item->tx_frames_total+=num_frames;
|
|
|
|
endpoint_item->tx_bytes_total+=num_bytes;
|
2014-07-25 15:34:51 +00:00
|
|
|
} else {
|
2022-08-23 07:52:07 +00:00
|
|
|
endpoint_item->rx_frames_total+=num_frames;
|
|
|
|
endpoint_item->rx_bytes_total+=num_bytes;
|
2014-07-25 15:34:51 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-23 07:52:07 +00:00
|
|
|
/* For backwards source and binary compatibility */
|
|
|
|
void
|
|
|
|
add_hostlist_table_data(conv_hash_t *ch, const address *addr, guint32 port, gboolean sender, int num_frames, int num_bytes, et_dissector_info_t *et_info, endpoint_type etype)
|
|
|
|
{
|
|
|
|
add_endpoint_table_data(ch, addr, port, sender, num_frames, num_bytes, et_info, etype);
|
|
|
|
}
|
|
|
|
|
2014-04-29 15:10:27 +00:00
|
|
|
/*
|
|
|
|
* 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:
|
|
|
|
*/
|