summaryrefslogtreecommitdiffstats
path: root/epan/exported_pdu.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/exported_pdu.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/exported_pdu.c')
-rw-r--r--epan/exported_pdu.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/epan/exported_pdu.c b/epan/exported_pdu.c
new file mode 100644
index 00000000..9efcb2df
--- /dev/null
+++ b/epan/exported_pdu.c
@@ -0,0 +1,345 @@
+/*
+ * exported_pdu.c
+ * exported_pdu helper functions
+ * Copyright 2013, Anders Broman <anders-broman@ericsson.com>
+ *
+ * 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 <glib.h>
+
+#include <epan/packet.h>
+#include <epan/exported_pdu.h>
+#include <epan/address_types.h>
+#include <epan/tap.h>
+#include <wiretap/wtap.h>
+
+#include <wsutil/pint.h>
+
+static GSList *export_pdu_tap_name_list = NULL;
+static wmem_map_t *export_pdu_encap_table = NULL;
+
+static int exp_pdu_data_ip_size(const address* addr)
+{
+ if (addr->type == AT_IPv4){
+ return 4 + EXP_PDU_TAG_IPV4_LEN;
+ } else if(addr->type == AT_IPv6){
+ return 4 + EXP_PDU_TAG_IPV6_LEN;
+ }
+
+ return 0;
+}
+
+static int exp_pdu_data_src_ip_size(packet_info *pinfo, void* data _U_)
+{
+ return exp_pdu_data_ip_size(&pinfo->net_src);
+}
+
+static int exp_pdu_data_src_ip_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size _U_)
+{
+ if(pinfo->net_src.type == AT_IPv4){
+ phton16(tlv_buffer+0, EXP_PDU_TAG_IPV4_SRC);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_IPV4_LEN); /* tag length */
+ memcpy(tlv_buffer+4, pinfo->net_src.data, EXP_PDU_TAG_IPV4_LEN);
+ return 4 + EXP_PDU_TAG_IPV4_LEN;
+ }else if(pinfo->net_src.type == AT_IPv6){
+ phton16(tlv_buffer+0, EXP_PDU_TAG_IPV6_SRC);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_IPV6_LEN); /* tag length */
+ memcpy(tlv_buffer+4, pinfo->net_src.data, EXP_PDU_TAG_IPV6_LEN);
+ return 4 + EXP_PDU_TAG_IPV6_LEN;
+ }
+
+ return 0;
+}
+
+static int exp_pdu_data_dst_ip_size(packet_info *pinfo, void* data _U_)
+{
+ return exp_pdu_data_ip_size(&pinfo->net_dst);
+}
+
+static int exp_pdu_data_dst_ip_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size _U_)
+{
+ if(pinfo->net_dst.type == AT_IPv4){
+ phton16(tlv_buffer+0, EXP_PDU_TAG_IPV4_DST);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_IPV4_LEN); /* tag length */
+ memcpy(tlv_buffer+4, pinfo->net_dst.data, EXP_PDU_TAG_IPV4_LEN);
+ return 4 + EXP_PDU_TAG_IPV4_LEN;
+ }else if(pinfo->net_dst.type == AT_IPv6){
+ phton16(tlv_buffer+0, EXP_PDU_TAG_IPV6_DST);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_IPV6_LEN); /* tag length */
+ memcpy(tlv_buffer+4, pinfo->net_dst.data, EXP_PDU_TAG_IPV6_LEN);
+ return 4 + EXP_PDU_TAG_IPV6_LEN;
+ }
+
+ return 0;
+}
+
+static int exp_pdu_data_port_type_size(packet_info *pinfo _U_, void* data _U_)
+{
+ return EXP_PDU_TAG_PORT_LEN + 4;
+}
+
+static guint exp_pdu_ws_port_type_to_exp_pdu_port_type(port_type pt)
+{
+ switch (pt)
+ {
+ case PT_NONE:
+ return EXP_PDU_PT_NONE;
+ case PT_SCTP:
+ return EXP_PDU_PT_SCTP;
+ case PT_TCP:
+ return EXP_PDU_PT_TCP;
+ case PT_UDP:
+ return EXP_PDU_PT_UDP;
+ case PT_DCCP:
+ return EXP_PDU_PT_DCCP;
+ case PT_IPX:
+ return EXP_PDU_PT_IPX;
+ case PT_DDP:
+ return EXP_PDU_PT_DDP;
+ case PT_IDP:
+ return EXP_PDU_PT_IDP;
+ case PT_USB:
+ return EXP_PDU_PT_USB;
+ case PT_I2C:
+ return EXP_PDU_PT_I2C;
+ case PT_IBQP:
+ return EXP_PDU_PT_IBQP;
+ case PT_BLUETOOTH:
+ return EXP_PDU_PT_BLUETOOTH;
+ case PT_IWARP_MPA:
+ return EXP_PDU_PT_IWARP_MPA;
+ case PT_MCTP:
+ return EXP_PDU_PT_MCTP;
+ }
+
+ DISSECTOR_ASSERT(FALSE);
+ return EXP_PDU_PT_NONE;
+}
+
+static int exp_pdu_data_port_type_populate_data(packet_info *pinfo, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
+{
+ guint pt;
+
+ phton16(tlv_buffer+0, EXP_PDU_TAG_PORT_TYPE);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_PORT_TYPE_LEN); /* tag length */
+ pt = exp_pdu_ws_port_type_to_exp_pdu_port_type(pinfo->ptype);
+ phton32(tlv_buffer+4, pt);
+
+ return exp_pdu_data_port_type_size(pinfo, data);
+}
+
+static int exp_pdu_data_port_size(packet_info *pinfo _U_, void* data _U_)
+{
+ return EXP_PDU_TAG_PORT_LEN + 4;
+}
+
+static int exp_pdu_data_port_populate_data(guint32 port, guint8 porttype, guint8 *tlv_buffer, guint32 buffer_size _U_)
+{
+ phton16(tlv_buffer+0, porttype);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_PORT_LEN); /* tag length */
+ phton32(tlv_buffer+4, port);
+
+ return EXP_PDU_TAG_PORT_LEN + 4;
+}
+
+static int exp_pdu_data_src_port_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size)
+{
+ return exp_pdu_data_port_populate_data(pinfo->srcport, EXP_PDU_TAG_SRC_PORT, tlv_buffer, buffer_size);
+}
+
+static int exp_pdu_data_dst_port_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size)
+{
+ return exp_pdu_data_port_populate_data(pinfo->destport, EXP_PDU_TAG_DST_PORT, tlv_buffer, buffer_size);
+}
+
+static int exp_pdu_data_orig_frame_num_size(packet_info *pinfo _U_, void* data _U_)
+{
+ return EXP_PDU_TAG_ORIG_FNO_LEN + 4;
+}
+
+static int exp_pdu_data_orig_frame_num_populate_data(packet_info *pinfo, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
+{
+ phton16(tlv_buffer+0, EXP_PDU_TAG_ORIG_FNO);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_ORIG_FNO_LEN); /* tag length */
+ phton32(tlv_buffer+4, pinfo->num);
+
+ return exp_pdu_data_orig_frame_num_size(pinfo, data);
+}
+
+WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_size(packet_info *pinfo _U_, void* data _U_)
+{
+ return EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN + 4;
+}
+
+WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_populate_data(packet_info *pinfo _U_, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
+{
+ guint32 value = GPOINTER_TO_UINT(data);
+
+ phton16(tlv_buffer+0, EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL);
+ phton16(tlv_buffer+2, EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN); /* tag length */
+ phton32(tlv_buffer+4, value);
+
+ return exp_pdu_data_dissector_table_num_value_size(pinfo, data);
+}
+
+
+exp_pdu_data_item_t exp_pdu_data_src_ip = {exp_pdu_data_src_ip_size, exp_pdu_data_src_ip_populate_data, NULL};
+exp_pdu_data_item_t exp_pdu_data_dst_ip = {exp_pdu_data_dst_ip_size, exp_pdu_data_dst_ip_populate_data, NULL};
+exp_pdu_data_item_t exp_pdu_data_port_type = {exp_pdu_data_port_type_size, exp_pdu_data_port_type_populate_data, NULL};
+exp_pdu_data_item_t exp_pdu_data_src_port = {exp_pdu_data_port_size, exp_pdu_data_src_port_populate_data, NULL};
+exp_pdu_data_item_t exp_pdu_data_dst_port = {exp_pdu_data_port_size, exp_pdu_data_dst_port_populate_data, NULL};
+exp_pdu_data_item_t exp_pdu_data_orig_frame_num = {exp_pdu_data_orig_frame_num_size, exp_pdu_data_orig_frame_num_populate_data, NULL};
+
+exp_pdu_data_t *export_pdu_create_common_tags(packet_info *pinfo, const char *proto_name, guint16 tag_type)
+{
+ const exp_pdu_data_item_t *common_exp_pdu_items[] = {
+ &exp_pdu_data_src_ip,
+ &exp_pdu_data_dst_ip,
+ &exp_pdu_data_port_type,
+ &exp_pdu_data_src_port,
+ &exp_pdu_data_dst_port,
+ &exp_pdu_data_orig_frame_num,
+ NULL
+ };
+
+ return export_pdu_create_tags(pinfo, proto_name, tag_type, common_exp_pdu_items);
+}
+
+/**
+ * Allocates and fills the exp_pdu_data_t struct according to the list of items
+ *
+ * The tags in the tag buffer SHOULD be added in numerical order.
+ */
+exp_pdu_data_t *
+export_pdu_create_tags(packet_info *pinfo, const char* proto_name, guint16 tag_type, const exp_pdu_data_item_t **items_list)
+{
+ exp_pdu_data_t *exp_pdu_data;
+ const exp_pdu_data_item_t **loop_items = items_list;
+ int tag_buf_size = 0;
+ int proto_str_len, proto_tag_len, buf_remaining, item_size;
+ guint8* buffer_data;
+
+ DISSECTOR_ASSERT(proto_name != NULL);
+ DISSECTOR_ASSERT((tag_type == EXP_PDU_TAG_DISSECTOR_NAME) || (tag_type == EXP_PDU_TAG_HEUR_DISSECTOR_NAME) || (tag_type == EXP_PDU_TAG_DISSECTOR_TABLE_NAME));
+
+ exp_pdu_data = wmem_new(pinfo->pool, exp_pdu_data_t);
+
+ /* Start by computing size of protocol name as a tag */
+ proto_str_len = (int)strlen(proto_name);
+
+ /* Ensure that tag length is a multiple of 4 bytes */
+ proto_tag_len = ((proto_str_len + 3) & 0xfffffffc);
+
+ /* Add Tag + length */
+ tag_buf_size += (proto_tag_len + 4);
+
+ /* Compute size of items */
+ while (*loop_items) {
+ tag_buf_size += (*loop_items)->size_func(pinfo, (*loop_items)->data);
+ loop_items++;
+ }
+
+ /* Add end of options length */
+ tag_buf_size+=4;
+
+ exp_pdu_data->tlv_buffer = (guint8 *)wmem_alloc0(pinfo->pool, tag_buf_size);
+ exp_pdu_data->tlv_buffer_len = tag_buf_size;
+
+ buffer_data = exp_pdu_data->tlv_buffer;
+ buf_remaining = exp_pdu_data->tlv_buffer_len;
+
+ /* Start by adding protocol name as a tag */
+ phton16(buffer_data+0, tag_type);
+ phton16(buffer_data+2, proto_tag_len); /* tag length */
+ memcpy(buffer_data+4, proto_name, proto_str_len);
+ buffer_data += (proto_tag_len+4);
+ buf_remaining -= (proto_tag_len+4);
+
+ /* Populate data */
+ loop_items = items_list;
+ while (*loop_items) {
+ item_size = (*loop_items)->populate_data(pinfo, (*loop_items)->data, buffer_data, buf_remaining);
+ buffer_data += item_size;
+ buf_remaining -= item_size;
+ loop_items++;
+ }
+
+ return exp_pdu_data;
+}
+
+gint
+register_export_pdu_tap_with_encap(const char *name, gint encap)
+{
+ gchar *tap_name = g_strdup(name);
+ export_pdu_tap_name_list = g_slist_prepend(export_pdu_tap_name_list, tap_name);
+ wmem_map_insert(export_pdu_encap_table, tap_name, GINT_TO_POINTER(encap));
+ return register_tap(tap_name);
+}
+
+gint
+register_export_pdu_tap(const char *name)
+{
+#if 0
+ /* XXX: We could register it like this, but don't have to, since
+ * export_pdu_tap_get_encap() returns WTAP_ENCAP_WIRESHARK_UPPER_PDU
+ * if it's not in the encap hash table anyway.
+ */
+ return register_export_pdu_tap_with_encap(name, WTAP_ENCAP_WIRESHARK_UPPER_PDU);
+#endif
+ gchar *tap_name = g_strdup(name);
+ export_pdu_tap_name_list = g_slist_prepend(export_pdu_tap_name_list, tap_name);
+ return register_tap(tap_name);
+}
+
+static
+gint sort_pdu_tap_name_list(gconstpointer a, gconstpointer b)
+{
+ return g_strcmp0((const char *)a, (const char*)b);
+}
+
+GSList *
+get_export_pdu_tap_list(void)
+{
+ export_pdu_tap_name_list = g_slist_sort(export_pdu_tap_name_list, sort_pdu_tap_name_list);
+ return export_pdu_tap_name_list;
+}
+
+gint
+export_pdu_tap_get_encap(const char* name)
+{
+ gpointer value;
+ if (wmem_map_lookup_extended(export_pdu_encap_table, name, NULL, &value)) {
+ return GPOINTER_TO_INT(value);
+ }
+
+ return WTAP_ENCAP_WIRESHARK_UPPER_PDU;
+}
+
+void export_pdu_init(void)
+{
+ export_pdu_encap_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
+}
+
+void export_pdu_cleanup(void)
+{
+ g_slist_free_full(export_pdu_tap_name_list, g_free);
+}
+
+/*
+ * 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:
+ */