aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-opensafety.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-opensafety.c')
-rw-r--r--epan/dissectors/packet-opensafety.c380
1 files changed, 235 insertions, 145 deletions
diff --git a/epan/dissectors/packet-opensafety.c b/epan/dissectors/packet-opensafety.c
index b6559416e2..252aacc606 100644
--- a/epan/dissectors/packet-opensafety.c
+++ b/epan/dissectors/packet-opensafety.c
@@ -33,6 +33,7 @@
#include <epan/reassemble.h>
#include <epan/strutil.h>
#include <epan/tap.h>
+#include <epan/conversation_table.h>
#include <wsutil/crc8.h>
#include <wsutil/crc16.h>
@@ -42,7 +43,7 @@
/* General definitions */
-/* Used to clasify incoming traffic and presort the heuristic */
+/* Used to classify incoming traffic and presort the heuristic */
#define OPENSAFETY_ANY_TRANSPORT 0x00
#define OPENSAFETY_CYCLIC_DATA 0x01
#define OPENSAFETY_ACYCLIC_DATA 0x02
@@ -71,6 +72,7 @@
#define OSS_SLIM_FRAME2_WITH_CRC8 0x06 /* 6 */
#define OSS_SLIM_FRAME2_WITH_CRC16 0x07 /* 7 */
#define OSS_MINIMUM_LENGTH 0x0b /* 11 */
+#define OSS_BROADCAST_ADDRESS 0x3ff
#define OPENSAFETY_SPDO_CONNECTION_VALID 0x04
@@ -88,153 +90,153 @@
#define OSS_FRAME_ID_T(f, offset) (tvb_get_guint8(f, OSS_FRAME_POS_ID + offset) & 0xFC)
#define OSS_FRAME_LENGTH_T(f, offset) (tvb_get_guint8(f, OSS_FRAME_POS_LEN + offset))
-static int proto_opensafety = -1;
-
-static gint ett_opensafety = -1;
-static gint ett_opensafety_checksum = -1;
-static gint ett_opensafety_snmt = -1;
-static gint ett_opensafety_ssdo = -1;
-static gint ett_opensafety_spdo = -1;
-static gint ett_opensafety_spdo_flags = -1;
-static gint ett_opensafety_ssdo_sacmd = -1;
-static gint ett_opensafety_ssdo_payload = -1;
-static gint ett_opensafety_ssdo_sodentry = -1;
-static gint ett_opensafety_ssdo_extpar = -1;
-static gint ett_opensafety_sod_mapping = -1;
-static gint ett_opensafety_node = -1;
-
-static expert_field ei_payload_length_not_positive = EI_INIT;
-static expert_field ei_payload_unknown_format = EI_INIT;
-static expert_field ei_crc_slimssdo_instead_of_spdo = EI_INIT;
-static expert_field ei_crc_frame_1_invalid = EI_INIT;
-static expert_field ei_crc_frame_1_valid_frame2_invalid = EI_INIT;
-static expert_field ei_crc_frame_2_invalid = EI_INIT;
-static expert_field ei_crc_frame_2_unknown_scm_udid = EI_INIT;
-static expert_field ei_crc_frame_2_scm_udid_encoded = EI_INIT;
-static expert_field ei_message_unknown_type = EI_INIT;
-static expert_field ei_message_reassembly_size_differs_from_header = EI_INIT;
-static expert_field ei_message_spdo_address_invalid = EI_INIT;
-static expert_field ei_message_id_field_mismatch = EI_INIT;
-static expert_field ei_scmudid_autodetected = EI_INIT;
-static expert_field ei_scmudid_invalid_preference = EI_INIT;
-static expert_field ei_scmudid_unknown = EI_INIT;
-static expert_field ei_40bit_default_domain = EI_INIT;
-
-static int hf_oss_msg = -1;
-static int hf_oss_msg_direction = -1;
-static int hf_oss_msg_category = -1;
-static int hf_oss_msg_node = -1;
-static int hf_oss_msg_network = -1;
-static int hf_oss_msg_sender = -1;
-static int hf_oss_msg_receiver = -1;
-static int hf_oss_length= -1;
-static int hf_oss_crc = -1;
-static int hf_oss_byte_offset = -1;
-
-static int hf_oss_crc_valid = -1;
-static int hf_oss_crc2_valid = -1;
-static int hf_oss_crc_type = -1;
-
-static int hf_oss_snmt_slave = -1;
-static int hf_oss_snmt_master = -1;
-static int hf_oss_snmt_udid = -1;
-static int hf_oss_snmt_scm = -1;
-static int hf_oss_snmt_tool = -1;
-static int hf_oss_snmt_service_id = -1;
-static int hf_oss_snmt_error_group = -1;
-static int hf_oss_snmt_error_code = -1;
-static int hf_oss_snmt_param_type = -1;
-static int hf_oss_snmt_ext_addsaddr = -1;
-static int hf_oss_snmt_ext_addtxspdo = -1;
-static int hf_oss_snmt_ext_initct = -1;
-
-static int hf_oss_ssdo_server = -1;
-static int hf_oss_ssdo_client = -1;
-static int hf_oss_ssdo_sano = -1;
-static int hf_oss_ssdo_sacmd = -1;
-static int hf_oss_ssdo_sod_index = -1;
-static int hf_oss_ssdo_sod_subindex = -1;
-static int hf_oss_ssdo_payload = -1;
-static int hf_oss_ssdo_payload_size = -1;
-static int hf_oss_ssdo_sodentry_size = -1;
-static int hf_oss_ssdo_sodentry_data = -1;
-static int hf_oss_ssdo_abort_code = -1;
-static int hf_oss_ssdo_preload_queue = -1;
-static int hf_oss_ssdo_preload_error = -1;
-
-static int hf_oss_sod_par_timestamp = -1;
-static int hf_oss_sod_par_checksum = -1;
-static int hf_oss_ssdo_sodmapping = -1;
-static int hf_oss_ssdo_sodmapping_bits = -1;
-
-static int hf_oss_ssdo_sacmd_access_type = -1;
-static int hf_oss_ssdo_sacmd_preload = -1;
-static int hf_oss_ssdo_sacmd_abort_transfer = -1;
-static int hf_oss_ssdo_sacmd_segmentation = -1;
-static int hf_oss_ssdo_sacmd_toggle = -1;
-static int hf_oss_ssdo_sacmd_initiate = -1;
-static int hf_oss_ssdo_sacmd_end_segment = -1;
+static int proto_opensafety;
+
+static gint ett_opensafety;
+static gint ett_opensafety_checksum;
+static gint ett_opensafety_snmt;
+static gint ett_opensafety_ssdo;
+static gint ett_opensafety_spdo;
+static gint ett_opensafety_spdo_flags;
+static gint ett_opensafety_ssdo_sacmd;
+static gint ett_opensafety_ssdo_payload;
+static gint ett_opensafety_ssdo_sodentry;
+static gint ett_opensafety_ssdo_extpar;
+static gint ett_opensafety_sod_mapping;
+static gint ett_opensafety_node;
+
+static expert_field ei_payload_length_not_positive;
+static expert_field ei_payload_unknown_format;
+static expert_field ei_crc_slimssdo_instead_of_spdo;
+static expert_field ei_crc_frame_1_invalid;
+static expert_field ei_crc_frame_1_valid_frame2_invalid;
+static expert_field ei_crc_frame_2_invalid;
+static expert_field ei_crc_frame_2_unknown_scm_udid;
+static expert_field ei_crc_frame_2_scm_udid_encoded;
+static expert_field ei_message_unknown_type;
+static expert_field ei_message_reassembly_size_differs_from_header;
+static expert_field ei_message_spdo_address_invalid;
+static expert_field ei_message_id_field_mismatch;
+static expert_field ei_scmudid_autodetected;
+static expert_field ei_scmudid_invalid_preference;
+static expert_field ei_scmudid_unknown;
+static expert_field ei_40bit_default_domain;
+
+static int hf_oss_msg;
+static int hf_oss_msg_direction;
+static int hf_oss_msg_category;
+static int hf_oss_msg_node;
+static int hf_oss_msg_network;
+static int hf_oss_msg_sender;
+static int hf_oss_msg_receiver;
+static int hf_oss_length;
+static int hf_oss_crc;
+static int hf_oss_byte_offset;
+
+static int hf_oss_crc_valid;
+static int hf_oss_crc2_valid;
+static int hf_oss_crc_type;
+
+static int hf_oss_snmt_slave;
+static int hf_oss_snmt_master;
+static int hf_oss_snmt_udid;
+static int hf_oss_snmt_scm;
+static int hf_oss_snmt_tool;
+static int hf_oss_snmt_service_id;
+static int hf_oss_snmt_error_group;
+static int hf_oss_snmt_error_code;
+static int hf_oss_snmt_param_type;
+static int hf_oss_snmt_ext_addsaddr;
+static int hf_oss_snmt_ext_addtxspdo;
+static int hf_oss_snmt_ext_initct;
+
+static int hf_oss_ssdo_server;
+static int hf_oss_ssdo_client;
+static int hf_oss_ssdo_sano;
+static int hf_oss_ssdo_sacmd;
+static int hf_oss_ssdo_sod_index;
+static int hf_oss_ssdo_sod_subindex;
+static int hf_oss_ssdo_payload;
+static int hf_oss_ssdo_payload_size;
+static int hf_oss_ssdo_sodentry_size;
+static int hf_oss_ssdo_sodentry_data;
+static int hf_oss_ssdo_abort_code;
+static int hf_oss_ssdo_preload_queue;
+static int hf_oss_ssdo_preload_error;
+
+static int hf_oss_sod_par_timestamp;
+static int hf_oss_sod_par_checksum;
+static int hf_oss_ssdo_sodmapping;
+static int hf_oss_ssdo_sodmapping_bits;
+
+static int hf_oss_ssdo_sacmd_access_type;
+static int hf_oss_ssdo_sacmd_preload;
+static int hf_oss_ssdo_sacmd_abort_transfer;
+static int hf_oss_ssdo_sacmd_segmentation;
+static int hf_oss_ssdo_sacmd_toggle;
+static int hf_oss_ssdo_sacmd_initiate;
+static int hf_oss_ssdo_sacmd_end_segment;
#if 0
-static int hf_oss_ssdo_sacmd_reserved = -1;
+static int hf_oss_ssdo_sacmd_reserved;
#endif
-static int hf_oss_ssdo_extpar_parset = -1;
-static int hf_oss_ssdo_extpar_version = -1;
-static int hf_oss_ssdo_extpar_saddr = -1;
-static int hf_oss_ssdo_extpar_length = -1;
-static int hf_oss_ssdo_extpar_crc = -1;
-static int hf_oss_ssdo_extpar_tstamp = -1;
-static int hf_oss_ssdo_extpar_data = -1;
-static int hf_oss_ssdo_extpar = -1;
-
-static int hf_oss_scm_udid = -1;
-static int hf_oss_scm_udid_auto = -1;
-static int hf_oss_scm_udid_valid = -1;
-
-static int hf_oss_spdo_direction = -1;
-static int hf_oss_spdo_connection_valid = -1;
-static int hf_oss_spdo_ct = -1;
-static int hf_oss_spdo_ct_40bit = -1;
-static int hf_oss_spdo_time_request = -1;
-static int hf_oss_spdo_time_request_to = -1;
-static int hf_oss_spdo_time_request_from = -1;
-static int hf_oss_spdo_feature_flags = -1;
-static int hf_oss_spdo_feature_flag_40bit_available = -1;
-static int hf_oss_spdo_feature_flag_40bit_used = -1;
-
-static int hf_oss_fragments = -1;
-static int hf_oss_fragment = -1;
-static int hf_oss_fragment_overlap = -1;
-static int hf_oss_fragment_overlap_conflicts = -1;
-static int hf_oss_fragment_multiple_tails = -1;
-static int hf_oss_fragment_too_long_fragment = -1;
-static int hf_oss_fragment_error = -1;
-static int hf_oss_fragment_count = -1;
-static int hf_oss_reassembled_in = -1;
-static int hf_oss_reassembled_length = -1;
-static int hf_oss_reassembled_data = -1;
-
-static gint ett_opensafety_ssdo_fragment = -1;
-static gint ett_opensafety_ssdo_fragments = -1;
+static int hf_oss_ssdo_extpar_parset;
+static int hf_oss_ssdo_extpar_version;
+static int hf_oss_ssdo_extpar_saddr;
+static int hf_oss_ssdo_extpar_length;
+static int hf_oss_ssdo_extpar_crc;
+static int hf_oss_ssdo_extpar_tstamp;
+static int hf_oss_ssdo_extpar_data;
+static int hf_oss_ssdo_extpar;
+
+static int hf_oss_scm_udid;
+static int hf_oss_scm_udid_auto;
+static int hf_oss_scm_udid_valid;
+
+static int hf_oss_spdo_direction;
+static int hf_oss_spdo_connection_valid;
+static int hf_oss_spdo_ct;
+static int hf_oss_spdo_ct_40bit;
+static int hf_oss_spdo_time_request;
+static int hf_oss_spdo_time_request_to;
+static int hf_oss_spdo_time_request_from;
+static int hf_oss_spdo_feature_flags;
+static int hf_oss_spdo_feature_flag_40bit_available;
+static int hf_oss_spdo_feature_flag_40bit_used;
+
+static int hf_oss_fragments;
+static int hf_oss_fragment;
+static int hf_oss_fragment_overlap;
+static int hf_oss_fragment_overlap_conflicts;
+static int hf_oss_fragment_multiple_tails;
+static int hf_oss_fragment_too_long_fragment;
+static int hf_oss_fragment_error;
+static int hf_oss_fragment_count;
+static int hf_oss_reassembled_in;
+static int hf_oss_reassembled_length;
+static int hf_oss_reassembled_data;
+
+static gint ett_opensafety_ssdo_fragment;
+static gint ett_opensafety_ssdo_fragments;
/* Definitions for the openSAFETY ov. UDP transport protocol */
static dissector_handle_t opensafety_udptransport_handle = NULL;
-static int proto_oss_udp_transport = -1;
+static int proto_oss_udp_transport;
-static int hf_oss_udp_transport_version = -1;
-static int hf_oss_udp_transport_flags_type = -1;
-static int hf_oss_udp_transport_counter = -1;
-static int hf_oss_udp_transport_sender = -1;
-static int hf_oss_udp_transport_datapoint = -1;
-static int hf_oss_udp_transport_length= -1;
+static int hf_oss_udp_transport_version;
+static int hf_oss_udp_transport_flags_type;
+static int hf_oss_udp_transport_counter;
+static int hf_oss_udp_transport_sender;
+static int hf_oss_udp_transport_datapoint;
+static int hf_oss_udp_transport_length;
-static gint ett_oss_udp_transport = -1;
+static gint ett_oss_udp_transport;
static const true_false_string tfs_udp_transport_cyclic_acyclic = { "Cyclic", "ACyclic" };
static guint global_network_oss_udp_port = OPENSAFETY_UDP_PORT;
-static int opensafety_tap = -1;
+static int opensafety_tap;
static const fragment_items oss_frag_items = {
/* Fragment subtrees */
@@ -568,7 +570,7 @@ static gboolean findSafetyFrame ( packet_info *pinfo, tvbuff_t *message_tvb, gui
* bit is set */
if ( ( b_ID != 0xFF ) && ( b_ID & 0x80 ) )
{
- /* The rem_length value might be poluted, due to the else statement of
+ /* The rem_length value might be polluted, due to the else statement of
* above if-decision (frame at end position detection). Therefore we
* calculate it here again, to have a sane value */
rem_length = tvb_reported_length_remaining(message_tvb, ctr);
@@ -1235,7 +1237,7 @@ dissect_opensafety_ssdo_message(tvbuff_t *message_tvb, packet_info *pinfo, proto
val_to_str_ext_const(((guint32) (ssdoIndex << 16)), &opensafety_sod_idx_names_ext, "Unknown") );
col_append_fstr(pinfo->cinfo, COL_INFO, " [%s", val_to_str_ext_const(((guint32) (ssdoIndex << 16)), &opensafety_sod_idx_names_ext, "Unknown"));
- /* Some SOD downloads (0x101A for instance) don't have sub-indeces */
+ /* Some SOD downloads (0x101A for instance) don't have sub-indices */
if ( ssdoSubIndex != 0x0 )
{
proto_tree_add_uint_format_value(ssdo_tree, hf_oss_ssdo_sod_subindex, message_tvb, db0Offset + 3, 1,
@@ -1810,8 +1812,8 @@ check_scmudid_validity(opensafety_packet_info *packet, tvbuff_t *message_tvb)
packet->scm_udid_valid = TRUE;
/* Now confirm, that the xor operation was successful. The ID fields of both frames have to be the same */
- b_ID = tvb_get_guint8(message_tvb, packet->frame.subframe2 + 1) ^ (guint8)(scmUDID->data[OSS_FRAME_POS_ID]);;
- if ( ( OSS_FRAME_ID_T(message_tvb, packet->frame.subframe1) ^ b_ID ) != 0 )
+ b_ID = tvb_get_guint8(message_tvb, packet->frame.subframe2 + 1) ^ (guint8)(scmUDID->data[OSS_FRAME_POS_ID]);
+ if ( ( OSS_FRAME_ID_T(message_tvb, packet->frame.subframe1) ^ (b_ID & 0xFC)) != 0 )
packet->scm_udid_valid = FALSE;
/* The IDs do not match, but the SCM UDID could still be ok. This happens, if this packet
@@ -1946,6 +1948,92 @@ dissect_opensafety_message(opensafety_packet_info *packet,
return TRUE;
}
+static const char* opensafety_conv_get_filter_type(conv_item_t* conv, conv_filter_type_e filter)
+{
+ if (filter == CONV_FT_SRC_ADDRESS) {
+ if (conv->src_address.type == AT_NUMERIC)
+ return "opensafety.msg.sender";
+ }
+
+ if (filter == CONV_FT_DST_ADDRESS) {
+ if (conv->dst_address.type == AT_NUMERIC)
+ return "opensafety.msg.receiver";
+ }
+
+ if (filter == CONV_FT_ANY_ADDRESS) {
+ if (conv->src_address.type == AT_NUMERIC && conv->dst_address.type == AT_NUMERIC)
+ return "opensafety.msg.node";
+ }
+
+ return CONV_FILTER_INVALID;
+}
+
+static ct_dissector_info_t opensafety_ct_dissector_info = {&opensafety_conv_get_filter_type};
+
+static const char* opensafety_get_filter_type(endpoint_item_t* endpoint, conv_filter_type_e filter)
+{
+ if (endpoint->myaddress.type == AT_NUMERIC) {
+ if (filter == CONV_FT_ANY_ADDRESS)
+ return "opensafety.msg.node";
+ else if (filter == CONV_FT_SRC_ADDRESS)
+ return "opensafety.msg.sender";
+ else if (filter == CONV_FT_DST_ADDRESS)
+ return "opensafety.msg.receiver";
+ }
+
+ return CONV_FILTER_INVALID;
+}
+
+static et_dissector_info_t opensafety_dissector_info = {&opensafety_get_filter_type};
+
+static tap_packet_status
+opensafety_conversation_packet(void *pct, packet_info *pinfo,
+ epan_dissect_t *edt _U_, const void *vip, tap_flags_t flags)
+{
+ address *src = wmem_new0(pinfo->pool, address);
+ address *dst = wmem_new0(pinfo->pool, address);
+ conv_hash_t *hash = (conv_hash_t*) pct;
+ const opensafety_packet_info *osinfo = (const opensafety_packet_info *)vip;
+ guint16 receiver = GUINT16_FROM_LE(osinfo->receiver);
+ if (osinfo->msg_type == OPENSAFETY_SPDO_MESSAGE_TYPE)
+ receiver = OSS_BROADCAST_ADDRESS;
+ guint16 sender = GUINT16_FROM_LE(osinfo->sender);
+
+ hash->flags = flags;
+
+ alloc_address_wmem(pinfo->pool, src, AT_NUMERIC, (int) sizeof(guint16), &sender);
+ alloc_address_wmem(pinfo->pool, dst, AT_NUMERIC, (int) sizeof(guint16), &receiver);
+
+ add_conversation_table_data(hash, src, dst, 0, 0, 1, osinfo->msg_len, &pinfo->rel_ts, &pinfo->abs_ts,
+ &opensafety_ct_dissector_info, CONVERSATION_NONE);
+
+ return TAP_PACKET_REDRAW;
+}
+
+static tap_packet_status
+opensafety_endpoint_packet(void *pit, packet_info *pinfo,
+ epan_dissect_t *edt _U_, const void *vip, tap_flags_t flags)
+{
+ address *src = wmem_new0(pinfo->pool, address);
+ address *dst = wmem_new0(pinfo->pool, address);
+ conv_hash_t *hash = (conv_hash_t*) pit;
+ const opensafety_packet_info *osinfo = (const opensafety_packet_info *)vip;
+ guint16 receiver = GUINT16_FROM_LE(osinfo->receiver);
+ if (osinfo->msg_type == OPENSAFETY_SPDO_MESSAGE_TYPE)
+ receiver = OSS_BROADCAST_ADDRESS;
+ guint16 sender = GUINT16_FROM_LE(osinfo->sender);
+
+ hash->flags = flags;
+
+ alloc_address_wmem(pinfo->pool, src, AT_NUMERIC, (int) sizeof(guint16), &sender);
+ alloc_address_wmem(pinfo->pool, dst, AT_NUMERIC, (int) sizeof(guint16), &receiver);
+
+ add_endpoint_table_data(hash, src, 0, TRUE, 1, osinfo->msg_len, &opensafety_dissector_info, ENDPOINT_NONE);
+ add_endpoint_table_data(hash, dst, 0, FALSE, 1, osinfo->msg_len, &opensafety_dissector_info, ENDPOINT_NONE);
+
+ return TAP_PACKET_REDRAW;
+}
+
static gboolean
opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_handle,
gboolean b_frame2First, gboolean do_byte_swap, guint8 force_nr_in_package,
@@ -2032,7 +2120,7 @@ opensafety_package_dissector(const gchar *protocolName, const gchar *sub_diss_ha
break;
/* Resetting packet, to ensure, that findSafetyFrame starts with a fresh frame.
- * As only packet_scope is used, this will not polute memory too much and get's
+ * As only packet_scope is used, this will not pollute memory too much and get's
* cleared with the next packet anyway */
packet = wmem_new0(pinfo->pool, opensafety_packet_info);
@@ -2697,17 +2785,17 @@ proto_register_opensafety(void)
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_oss_fragment_overlap,
{"Message fragment overlap", "opensafety.ssdo.fragment.overlap",
- FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_oss_fragment_overlap_conflicts,
{"Message fragment overlapping with conflicting data",
"opensafety.ssdo.fragment.overlap.conflicts",
- FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_oss_fragment_multiple_tails,
{"Message has multiple tail fragments", "opensafety.ssdo.fragment.multiple_tails",
- FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_oss_fragment_too_long_fragment,
{"Message fragment too long", "opensafety.ssdo.fragment.too_long_fragment",
- FT_BOOLEAN, 0, NULL, 0x00, NULL, HFILL } },
+ FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL } },
{&hf_oss_fragment_error,
{"Message defragmentation error", "opensafety.ssdo.fragment.error",
FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
@@ -2908,7 +2996,7 @@ proto_register_opensafety(void)
oss_udp_module = prefs_register_protocol(proto_oss_udp_transport, apply_prefs);
/* Register data dissector */
- heur_opensafety_spdo_subdissector_list = register_heur_dissector_list("opensafety.spdo", proto_opensafety);
+ heur_opensafety_spdo_subdissector_list = register_heur_dissector_list_with_description("opensafety.spdo", "openSAFETY data", proto_opensafety);
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_opensafety, hf, array_length(hf));
@@ -2997,6 +3085,8 @@ proto_register_opensafety(void)
register_dissector("opensafety_udptransport", dissect_opensafety_udpdata, proto_oss_udp_transport );
opensafety_mbtcp_handle = register_dissector("opensafety_mbtcp", dissect_opensafety_mbtcp, proto_opensafety );
opensafety_pnio_handle = register_dissector("opensafety_pnio", dissect_opensafety_pn_io, proto_opensafety);
+
+ register_conversation_table(proto_opensafety, TRUE, opensafety_conversation_packet, opensafety_endpoint_packet);
}
void