aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-11-06 20:13:32 +0000
committerRonnie Sahlberg <ronnie_sahlberg@ozemail.com.au>2006-11-06 20:13:32 +0000
commit258b3af06349fda8942890679ec32cf106454b0f (patch)
tree4616593afe43b2290738d77b16c710e9cd2dedfe
parent9cb8ab0b8a791e29b28eaf663c5f2dd882d9496d (diff)
new acn dissector from Bill Florac
svn path=/trunk/; revision=19830
-rw-r--r--AUTHORS4
-rw-r--r--epan/dissectors/Makefile.common2
-rwxr-xr-xepan/dissectors/packet-acn.c3024
-rwxr-xr-xepan/dissectors/packet-acn.h197
-rw-r--r--plugins/acn/AUTHORS3
-rw-r--r--plugins/acn/COPYING340
-rw-r--r--plugins/acn/ChangeLog2
-rw-r--r--plugins/acn/INSTALL0
-rw-r--r--plugins/acn/Makefile.am119
-rw-r--r--plugins/acn/Makefile.common35
-rw-r--r--plugins/acn/Makefile.nmake82
-rw-r--r--plugins/acn/NEWS0
-rw-r--r--plugins/acn/acn.h81
-rw-r--r--plugins/acn/moduleinfo.h17
-rw-r--r--plugins/acn/packet-acn.c1185
15 files changed, 3227 insertions, 1864 deletions
diff --git a/AUTHORS b/AUTHORS
index fd22f08b16..39e3698695 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2530,6 +2530,10 @@ David Buechi <bhd [AT] zhwin.ch> {
EPL v1 support
}
+Bill Florac <bill.florac [AT] etcconnect.com> {
+ ACN support
+}
+
and by:
Pavel Roskin <proski [AT] gnu.org>
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
index ebdb1f570d..899185954b 100644
--- a/epan/dissectors/Makefile.common
+++ b/epan/dissectors/Makefile.common
@@ -67,6 +67,7 @@ DISSECTOR_SRC = \
packet-9p.c \
packet-aarp.c \
packet-acap.c \
+ packet-acn.c \
packet-acp133.c \
packet-acse.c \
packet-actrace.c \
@@ -717,6 +718,7 @@ DISSECTOR_SRC = \
DISSECTOR_INCLUDES = \
$(PIDL_DISSECTOR_INCLUDES) \
format-oid.h \
+ packet-acn.h \
packet-acp133.h \
packet-acse.h \
packet-actrace.h \
diff --git a/epan/dissectors/packet-acn.c b/epan/dissectors/packet-acn.c
new file mode 100755
index 0000000000..b0b8906a2f
--- /dev/null
+++ b/epan/dissectors/packet-acn.c
@@ -0,0 +1,3024 @@
+/* packet-acn.c
+ * Routines for ACN packet disassembly
+ *
+ * $Id$
+ *
+ * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
+ * Copyright (c) 2006 by Electronic Theatre Controls, Inc.
+ * Bill Florac <bflorac@etcconnect.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+ /*
+ Todo:
+ Add reading of DDL files so we can futher explode DMP packets
+ For some of the Set/Get properties where we have a range of data
+ it would be better to show the block of data rather and
+ address-data pair on each line...
+
+ Version: 0.0.9 wrf 10-25-2006 Released to Wireshark community
+ Version: 0.0.10 wrf 10-25-2006 small revisions to submit...
+ Version: 0.0.11 wrf 10-29-2006 revisions to submit...
+ */
+
+/* Include files */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gmodule.h>
+
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/emem.h>
+#include <epan/packet.h>
+#include <epan/ipv6-utils.h>
+#include <string.h>
+
+#include "packet-acn.h"
+
+/*
+ * See
+ * ANSI BSR E1.17 Architecture for Control Networks
+ * ANSI BSR E1.31
+ */
+
+#define ACTUAL_ADDRESS 0
+/* forward reference */
+static gboolean dissect_acn_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree );
+static guint32 acn_add_channel_owner_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset);
+static guint32 acn_add_channel_member_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset);
+static guint32 acn_add_expiry(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, char *label);
+static guint32 acn_add_channel_parameter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset);
+static guint32 acn_add_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, char *label);
+static guint32 acn_add_dmp_address_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt);
+static guint32 acn_add_dmp_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt);
+static guint32 dissect_acn_dmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets);
+static guint32 dissect_acn_sdt_wrapped_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, acn_pdu_offsets *last_pdu_offsets);
+static guint32 dissect_acn_sdt_client_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets);
+static guint32 dissect_acn_dmx_data_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets);
+static guint32 dissect_acn_dmx_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets);
+static guint32 dissect_acn_sdt_base_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets);
+static guint32 dissect_acn_root_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets);
+static int dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static gboolean is_acn(tvbuff_t *tvb);
+void proto_register_acn(void);
+void proto_reg_handoff_acn(void);
+
+/* Global variables */
+static int proto_acn = -1;
+static gint ett_acn = -1;
+static gint ett_acn_channel_owner_info_block = -1;
+static gint ett_acn_channel_member_info_block = -1;
+static gint ett_acn_channel_parameter = -1;
+static gint ett_acn_address = -1;
+static gint ett_acn_address_type = -1;
+static gint ett_acn_pdu_flags = -1;
+static gint ett_acn_dmp_pdu = -1;
+static gint ett_acn_sdt_pdu = -1;
+static gint ett_acn_sdt_client_pdu = -1;
+static gint ett_acn_sdt_base_pdu = -1;
+static gint ett_acn_root_pdu = -1;
+static gint ett_acn_dmx_address = -1;
+static gint ett_acn_dmx_data_pdu = -1;
+static gint ett_acn_dmx_pdu = -1;
+
+/* Register fields */
+/* In alphabetical order */
+static int hf_acn_association = -1;
+static int hf_acn_channel_number = -1;
+static int hf_acn_cid = -1;
+static int hf_acn_client_protocol_id = -1;
+static int hf_acn_data = -1;
+static int hf_acn_data8 = -1;
+static int hf_acn_data16 = -1;
+static int hf_acn_data24 = -1;
+static int hf_acn_data32 = -1;
+static int hf_acn_dmp_address1 = -1;
+static int hf_acn_dmp_address2 = -1;
+static int hf_acn_dmp_address4 = -1;
+static int hf_acn_dmp_adt = -1; /* address and data type*/
+static int hf_acn_dmp_adt_a = -1;
+static int hf_acn_dmp_adt_v = -1;
+static int hf_acn_dmp_adt_r = -1;
+static int hf_acn_dmp_adt_d = -1;
+static int hf_acn_dmp_adt_x = -1;
+static int hf_acn_dmp_reason_code = -1;
+static int hf_acn_dmp_vector = -1;
+static int hf_acn_dmp_address_data_pairs = -1;
+static int hf_acn_expiry = -1;
+static int hf_acn_first_memeber_to_ack = -1;
+static int hf_acn_first_missed_sequence = -1;
+static int hf_acn_ip_address_type = -1;
+static int hf_acn_ipv4 = -1;
+static int hf_acn_ipv6 = -1;
+static int hf_acn_last_memeber_to_ack = -1;
+static int hf_acn_last_missed_sequence = -1;
+static int hf_acn_mak_threshold = -1;
+static int hf_acn_member_id = -1;
+static int hf_acn_nak_holdoff = -1;
+static int hf_acn_nak_max_wait = -1;
+static int hf_acn_nak_modulus = -1;
+static int hf_acn_nak_outbound_flag = -1;
+static int hf_acn_oldest_available_wrapper = -1;
+static int hf_acn_packet_identifier = -1;
+static int hf_acn_pdu = -1;
+static int hf_acn_pdu_flag_d = -1;
+static int hf_acn_pdu_flag_h = -1;
+static int hf_acn_pdu_flag_l = -1;
+static int hf_acn_pdu_flag_v = -1;
+static int hf_acn_pdu_flags = -1;
+static int hf_acn_pdu_length = -1;
+static int hf_acn_port = -1;
+static int hf_acn_postamble_size = -1;
+static int hf_acn_preamble_size = -1;
+static int hf_acn_protocol_id = -1;
+static int hf_acn_reason_code = -1;
+static int hf_acn_reciprocal_channel = -1;
+static int hf_acn_refuse_code = -1;
+static int hf_acn_reliable_sequence_number = -1;
+/* static int hf_acn_sdt_pdu = -1; */
+static int hf_acn_sdt_vector = -1;
+static int hf_acn_dmx_vector = -1;
+static int hf_acn_session_count = -1;
+static int hf_acn_total_sequence_number = -1;
+static int hf_acn_dmx_source_name = -1;
+static int hf_acn_dmx_priority = -1;
+static int hf_acn_dmx_sequence_number = -1;
+static int hf_acn_dmx_universe = -1;
+/* static int hf_acn_dmx_dmp_vector = -1; */
+
+/* Try heuristic ACN decode */
+static gboolean global_acn_heur = FALSE;
+static gboolean global_acn_dmx_enable = FALSE;
+static gint global_acn_dmx_display_view = 0;
+static gboolean global_acn_dmx_display_zeros = FALSE;
+static gboolean global_acn_dmx_display_leading_zeros = FALSE;
+
+
+static const value_string acn_protocol_id_vals[] = {
+ { ACN_PROTOCOL_ID_SDT, "SDT Protocol" },
+ { ACN_PROTOCOL_ID_DMP, "DMP Protocol" },
+ { ACN_PROTOCOL_ID_DMX, "DMX Protocol" },
+ { 0, NULL },
+};
+
+static const value_string acn_dmp_adt_r_vals[] = {
+ { 0, "Relative" },
+ { 1, "Absolute" },
+ { 0, NULL },
+};
+
+static const value_string acn_dmp_adt_v_vals[] = {
+ { 0, "Actual" },
+ { 1, "Virtual" },
+ { 0, NULL },
+};
+
+static const value_string acn_dmp_adt_d_vals[] = {
+ { 0, "Non-range, single data item" },
+ { 1, "Range, single data item" },
+ { 2, "Range, array of equal size data items" },
+ { 3, "Range, series of mixed size data items" },
+ { 0, NULL },
+};
+
+static const value_string acn_dmp_adt_a_vals[] = {
+ { 0, "1 octet" },
+ { 1, "2 octets" },
+ { 2, "4 octets" },
+ { 3, "reserved" },
+ { 0, NULL },
+};
+
+
+static const value_string acn_sdt_vector_vals[] = {
+ {ACN_SDT_VECTOR_UNKNOWN, "Unknown"},
+ {ACN_SDT_VECTOR_REL_WRAP, "Reliable Wrapper"},
+ {ACN_SDT_VECTOR_UNREL_WRAP, "Unreliable Wrapper"},
+ {ACN_SDT_VECTOR_CHANNEL_PARAMS, "Channel Parameters"},
+ {ACN_SDT_VECTOR_JOIN, "Join"},
+ {ACN_SDT_VECTOR_JOIN_REFUSE, "Join Refuse"},
+ {ACN_SDT_VECTOR_JOIN_ACCEPT, "Join Accept"},
+ {ACN_SDT_VECTOR_LEAVE, "Leave"},
+ {ACN_SDT_VECTOR_LEAVING, "Leaving"},
+ {ACN_SDT_VECTOR_CONNECT, "Connect"},
+ {ACN_SDT_VECTOR_CONNECT_ACCEPT, "Connect Accept"},
+ {ACN_SDT_VECTOR_CONNECT_REFUSE, "Connect Refuse"},
+ {ACN_SDT_VECTOR_DISCONNECT, "Disconnect"},
+ {ACN_SDT_VECTOR_DISCONNECTING, "Disconnecting"},
+ {ACN_SDT_VECTOR_ACK, "Ack"},
+ {ACN_SDT_VECTOR_NAK, "Nak"},
+ {ACN_SDT_VECTOR_GET_SESSION, "Get Session"},
+ {ACN_SDT_VECTOR_SESSIONS, "Sessions"},
+ { 0, NULL },
+};
+
+static const value_string acn_dmx_vector_vals[] = {
+ {ACN_DMX_VECTOR, "Streaming DMX"},
+ { 0, NULL },
+};
+
+static const value_string acn_dmp_vector_vals[] = {
+ {ACN_DMP_VECTOR_UNKNOWN, "Unknown"},
+ {ACN_DMP_VECTOR_GET_PROPERTY, "Get Property"},
+ {ACN_DMP_VECTOR_SET_PROPERTY, "Set Property"},
+ {ACN_DMP_VECTOR_GET_PROPERTY_REPLY, "Get property reply"},
+ {ACN_DMP_VECTOR_EVENT, "Event"},
+ {ACN_DMP_VECTOR_MAP_PROPERTY, "Map Property"},
+ {ACN_DMP_VECTOR_UNMAP_PROPERTY, "Unmap Property"},
+ {ACN_DMP_VECTOR_SUBSCRIBE, "Subscribe"},
+ {ACN_DMP_VECTOR_UNSUBSCRIBE, "Unsubscribe"},
+ {ACN_DMP_VECTOR_GET_PROPERTY_FAIL, "Get Property Fail"},
+ {ACN_DMP_VECTOR_SET_PROPERTY_FAIL, "Set Property Fail"},
+ {ACN_DMP_VECTOR_MAP_PROPERTY_FAIL, "Map Property Fail"},
+ {ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT, "Subscribe Accept"},
+ {ACN_DMP_VECTOR_SUBSCRIBE_REJECT, "Subscribe Reject"},
+ {ACN_DMP_VECTOR_ALLOCATE_MAP, "Allocate Map"},
+ {ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY, "Allocate Map Reply"},
+ {ACN_DMP_VECTOR_DEALLOCATE_MAP, "Deallocate Map"},
+ { 0, NULL },
+};
+
+static const value_string acn_ip_address_type_vals[] = {
+ { ACN_ADDR_NULL, "Null"},
+ { ACN_ADDR_IPV4, "IPv4"},
+ { ACN_ADDR_IPV6, "IPv6"},
+ { ACN_ADDR_IPPORT, "Port"},
+ { 0, NULL },
+};
+
+static const value_string acn_refuse_code_vals[] = {
+ { ACN_REFUSE_CODE_NONSPECIFIC, "Nonspecific" },
+ { ACN_REFUSE_CODE_ILLEGAL_PARAMS, "Illegal Parameters" },
+ { ACN_REFUSE_CODE_LOW_RESOURCES, "Low Resources" },
+ { ACN_REFUSE_CODE_ALREADY_MEMBER, "Already Member" },
+ { ACN_REFUSE_CODE_BAD_ADDR_TYPE, "Bad Address Type" },
+ { ACN_REFUSE_CODE_NO_RECIP_CHAN, "No Reciprocal Channel" },
+ { 0, NULL },
+};
+
+static const value_string acn_reason_code_vals[] = {
+ { ACN_REASON_CODE_NONSPECIFIC, "Nonspecific" },
+ { ACN_REASON_CODE_NO_RECIP_CHAN, "No Reciprocal Channel" },
+ { ACN_REASON_CODE_CHANNEL_EXPIRED, "Channel Expired" },
+ { ACN_REASON_CODE_LOST_SEQUENCE, "Lost Sequence" },
+ { ACN_REASON_CODE_SATURATED, "Saturated" },
+ { ACN_REASON_CODE_TRANS_ADDR_CHANGING, "Transport Address Changing" },
+ { ACN_REASON_CODE_ASKED_TO_LEAVE, "Asked to Leave" },
+ { ACN_REASON_CODE_NO_RECIPIENT, "No Recipient"},
+ { 0, NULL },
+};
+
+static const value_string acn_dmp_reason_code_vals[] = {
+ { ACN_DMP_REASON_CODE_NONSPECIFIC, "Nonspecific" },
+ { ACN_DMP_REASON_CODE_NOT_A_PROPERTY, "Not a Property" },
+ { ACN_DMP_REASON_CODE_WRITE_ONLY, "Write Only" },
+ { ACN_DMP_REASON_CODE_NOT_WRITABLE, "Not Writable" },
+ { ACN_DMP_REASON_CODE_DATA_ERROR, "Data Error" },
+ { ACN_DMP_REASON_CODE_MAPS_NOT_SUPPORTED, "Maps not Supported" },
+ { ACN_DMP_REASON_CODE_SPACE_NOT_AVAILABLE, "Space not Available" },
+ { ACN_DMP_REASON_CODE_PROP_NOT_MAPABLE, "Property not Mapable"},
+ { ACN_DMP_REASON_CODE_MAP_NOT_ALLOCATED, "Map not Allocated"},
+ { ACN_DMP_REASON_CODE_SUBSCRIPTION_NOT_SUPPORTED, "Subscription not Supported"},
+ { ACN_DMP_REASON_CODE_NO_SUBSCRIPTIONS_SUPPORTED, "No Subscriptions Supported"},
+ { 0, NULL },
+};
+
+static const enum_val_t dmx_display_view[] = {
+ { "hex" , "Hex ", ACN_PREF_DMX_DISPLAY_HEX },
+ { "decimal", "Decimal", ACN_PREF_DMX_DISPLAY_DEC },
+ { "percent", "Percent", ACN_PREF_DMX_DISPLAY_PER },
+ { NULL, NULL, 0 }
+};
+
+/******************************************************************************/
+/* Test to see if it is an ACN Packet */
+static gboolean is_acn(tvbuff_t *tvb)
+{
+ static char acn_packet_id[] = "ASC-E1.17\0\0\0"; /* must be 12 bytes */
+ guint8 *packet_id;
+
+ /* Get the fields in octets 2 - 12 octet */
+ packet_id = tvb_get_ephemeral_string(tvb, 4, 12);
+ if (memcmp(packet_id, &acn_packet_id, 12) == 0) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/******************************************************************************/
+/* Heuristic dissector */
+static gboolean
+dissect_acn_heur( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
+{
+ /* This is a heuristic dissector, which means we get all the UDP
+ * traffic not sent to a known dissector and not claimed by
+ * a heuristic dissector called before us!
+ */
+
+ /* abort if not enabled! */
+ if (!global_acn_heur) return FALSE;
+
+ /* abort if it is NOT an ACN packet */
+ if (!is_acn(tvb)) return FALSE;
+
+ /* else, dissect it */
+ dissect_acn(tvb, pinfo, tree);
+ return TRUE;
+}
+
+/******************************************************************************/
+/* Adds tree branch for channel owner info block */
+static guint32
+acn_add_channel_owner_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset)
+{
+ proto_item *pi;
+ proto_tree *this_tree = NULL;
+ guint32 session_count;
+ guint32 x;
+
+ pi = proto_tree_add_text(this_tree, tvb, offset, 8, "Channel Owner Info Block");
+ this_tree = proto_item_add_subtree(pi, ett_acn_channel_owner_info_block);
+
+ proto_tree_add_item(this_tree, hf_acn_member_id, tvb, offset, 2, FALSE);
+ offset += 2;
+ proto_tree_add_item(this_tree, hf_acn_channel_number, tvb, offset, 2, FALSE);
+ offset += 2;
+ offset += acn_add_address(tvb, pinfo, this_tree, offset, "Destination Address: ");
+ offset += acn_add_address(tvb, pinfo, this_tree, offset, "Source Address: ");
+
+ session_count = tvb_get_ntohs(tvb, offset);
+ for (x=0; x<session_count; x++) {
+ pi = proto_tree_add_item(this_tree, hf_acn_protocol_id, tvb, offset, 4, FALSE);
+ proto_item_append_text(pi, " #%d", x+1);
+ offset += 4;
+ }
+ return offset;
+}
+
+/******************************************************************************/
+/* Adds tree branch for channel member info block */
+static guint32
+acn_add_channel_member_info_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset)
+{
+ proto_item *pi;
+ proto_tree *this_tree = NULL;
+ guint32 session_count;
+ guint32 x;
+
+ pi = proto_tree_add_text(this_tree, tvb, offset, 8, "Channel Member Info Block");
+ this_tree = proto_item_add_subtree(pi, ett_acn_channel_member_info_block);
+
+ proto_tree_add_item(this_tree, hf_acn_member_id, tvb, offset, 2, FALSE);
+ offset += 2;
+ proto_tree_add_item(this_tree, hf_acn_cid, tvb, offset, 16, FALSE);
+ offset += 16;
+ proto_tree_add_item(this_tree, hf_acn_channel_number, tvb, offset, 2, FALSE);
+ offset += 2;
+ offset += acn_add_address(tvb, pinfo, this_tree, offset, "Destination Address: ");
+ offset += acn_add_address(tvb, pinfo, this_tree, offset, "Source Address: ");
+ proto_tree_add_item(this_tree, hf_acn_reciprocal_channel, tvb, offset, 2, FALSE);
+ offset += 2;
+
+ session_count = tvb_get_ntohs(tvb, offset);
+ for (x=0; x<session_count; x++) {
+ pi = proto_tree_add_item(this_tree, hf_acn_protocol_id, tvb, offset, 4, FALSE);
+ proto_item_append_text(pi, " #%d", x+1);
+ offset += 4;
+ }
+ return offset;
+}
+
+
+/******************************************************************************/
+/* Add labled exiry */
+static guint32
+acn_add_expiry(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, char *label)
+{
+ proto_item *pi;
+ guint32 expiry;
+
+ expiry = tvb_get_ntohs(tvb, offset);
+ pi = proto_tree_add_text(tree, tvb, offset, 2, label);
+ proto_item_append_text(pi, " %d", expiry);
+ offset += 2;
+ return offset;
+}
+
+
+/******************************************************************************/
+/* Adds tree branch for channel parameters */
+static guint32
+acn_add_channel_parameter(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset)
+{
+ proto_item *pi;
+ proto_tree *param_tree = NULL;
+
+ pi = proto_tree_add_text(tree, tvb, offset, 8, "Channel Parameter Block");
+ param_tree = proto_item_add_subtree(pi, ett_acn_channel_parameter);
+ proto_tree_add_item(param_tree, hf_acn_expiry, tvb, offset, 1, FALSE);
+ offset += 1;
+ proto_tree_add_item(param_tree, hf_acn_nak_outbound_flag, tvb, offset, 1, FALSE);
+ offset += 1;
+ proto_tree_add_item(param_tree, hf_acn_nak_holdoff, tvb, offset, 2, FALSE);
+ offset += 2;
+ proto_tree_add_item(param_tree, hf_acn_nak_modulus, tvb, offset, 2, FALSE);
+ offset += 2;
+ proto_tree_add_item(param_tree, hf_acn_nak_max_wait, tvb, offset, 2, FALSE);
+ offset += 2;
+ return offset; /* bytes used */
+}
+
+
+/******************************************************************************/
+/* Add an address tree */
+static guint32
+acn_add_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, char *label)
+{
+ proto_item *pi;
+ proto_tree *addr_tree = NULL;
+ guint8 ip_address_type;
+
+ address addr;
+ guint32 IPv4;
+ guint32 port;
+ struct e_in6_addr IPv6;
+
+
+ /* Get type */
+ ip_address_type = tvb_get_guint8(tvb, offset);
+
+ switch (ip_address_type) {
+ case ACN_ADDR_NULL:
+ break;
+ case ACN_ADDR_IPV4:
+ /* Build tree and add type*/
+ pi = proto_tree_add_text(tree, tvb, offset, 7, label);
+ addr_tree = proto_item_add_subtree(pi, ett_acn_address);
+ proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, FALSE);
+ offset +=1;
+ /* Add port */
+ port = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, FALSE);
+ offset += 2;
+ /* Add Address */
+ proto_tree_add_item(addr_tree, hf_acn_ipv4, tvb, offset, 4, FALSE);
+ /* Append port and address to tree item */
+ IPv4 = tvb_get_ipv4(tvb, offset);
+ SET_ADDRESS(&addr, AT_IPv4, sizeof(IPv4), &IPv4);
+ proto_item_append_text(pi, "%s, Port %d", address_to_str(&addr), port);
+ offset += 4;
+ break;
+ case ACN_ADDR_IPV6:
+ /* Build tree and add type*/
+ pi = proto_tree_add_text(tree, tvb, offset, 19, label);
+ addr_tree = proto_item_add_subtree(pi, ett_acn_address);
+ proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, FALSE);
+ offset +=1;
+ /* Add port */
+ port = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, FALSE);
+ offset += 2;
+ /* Add Address */
+ proto_tree_add_item(addr_tree, hf_acn_ipv6, tvb, offset, 16, FALSE);
+ /* Append port and address to tree item */
+ tvb_get_ipv6(tvb, offset, &IPv6);
+ SET_ADDRESS(&addr, AT_IPv6, sizeof(struct e_in6_addr), &IPv6);
+ proto_item_append_text(pi, "%s, Port %d", address_to_str(&addr), port);
+ offset += 16;
+ break;
+ case ACN_ADDR_IPPORT:
+ /* Build tree and add type*/
+ pi = proto_tree_add_text(tree, tvb, offset, 3, label);
+ addr_tree = proto_item_add_subtree(pi, ett_acn_address);
+ proto_tree_add_item(addr_tree, hf_acn_ip_address_type, tvb, offset, 1, FALSE);
+ offset +=1;
+ /* Add port */
+ port = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(addr_tree, hf_acn_port, tvb, offset, 2, FALSE);
+ /* Append port to tree item */
+ proto_item_append_text(pi, "%s Port %d", address_to_str(&addr), port);
+ offset += 2;
+ break;
+ }
+ return offset;
+}
+
+/******************************************************************************/
+/* Adds tree branch for address type */
+static guint32
+acn_add_dmp_address_type(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
+{
+ proto_item *pi;
+ proto_tree *this_tree = NULL;
+
+ /* header contains address and data type */
+ adt->byte = tvb_get_guint8(tvb, offset);
+
+ pi = proto_tree_add_text(tree, tvb, offset, 1, "Address and Data Type: %s (%d)", match_strval(adt->D, acn_dmp_adt_d_vals), adt->D);
+
+ this_tree = proto_item_add_subtree(pi, ett_acn_address_type);
+ proto_tree_add_uint(this_tree, hf_acn_dmp_adt_v, tvb, offset, 1, adt->byte);
+ proto_tree_add_uint(this_tree, hf_acn_dmp_adt_r, tvb, offset, 1, adt->byte);
+ proto_tree_add_uint(this_tree, hf_acn_dmp_adt_d, tvb, offset, 1, adt->byte);
+ proto_tree_add_uint(this_tree, hf_acn_dmp_adt_x, tvb, offset, 1, adt->byte);
+ proto_tree_add_uint(this_tree, hf_acn_dmp_adt_a, tvb, offset, 1, adt->byte);
+ offset++;
+
+ return offset; /* bytes used */
+}
+
+/******************************************************************************/
+/* Add an dmp address */
+static guint32
+acn_add_dmp_address(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
+{
+ guint32 start_offset;
+ guint32 bytes_used;
+
+ start_offset = offset;
+
+ switch (adt->D) {
+ case ACN_DMP_ADT_D_NS: /* Non-range address, Single data item */
+ adt->increment = 1;
+ adt->count = 1;
+ switch (adt->A) { /* address */
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ adt->address = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ bytes_used = 1;
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ adt->address = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ bytes_used = 2;
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: one octet address, increment, and count). */
+ adt->address = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ bytes_used = 4;
+ break;
+ default: /* and ACN_DMP_ADT_A_R (Four octet address, (range: four octet address, increment, and count)*/
+ return offset;
+ } /* of switch (adt->A) */
+
+ if (adt->V) {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Virtual Address: %d", adt->address);
+ } else {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Actual Address: %d", adt->address);
+ }
+ break;
+
+ case ACN_DMP_ADT_D_RS: /* Range address, Single data item */
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ adt->address = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ adt->increment = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ adt->count = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ bytes_used = 3;
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ adt->address = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ adt->increment = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ adt->count = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ bytes_used = 6;
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ adt->address = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ adt->increment = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ adt->count = tvb_get_ntohl(tvb, offset);
+ offset += 12;
+ bytes_used = 12;
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ } /* of switch (adt->A) */
+
+ if (adt->V) {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Virtual Address first: %d, inc: %d, count: %d", adt->address, adt->increment, adt->count);
+ } else {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Actual Address first: %d, inc: %d, count: %d", adt->address, adt->increment, adt->count);
+ }
+ break;
+
+ case ACN_DMP_ADT_D_RE: /* Range address, Array of equal size data items */
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ adt->address = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ adt->increment = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ adt->count = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ bytes_used = 3;
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ adt->address = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ adt->increment = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ adt->count = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ bytes_used = 6;
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ adt->address = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ adt->increment = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ adt->count = tvb_get_ntohl(tvb, offset);
+ offset += 12;
+ bytes_used = 12;
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ } /* of switch (adt->A) */
+
+ if (adt->V) {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Virtual Address first: %d, inc: %d, count: %d", adt->address, adt->increment, adt->count);
+ } else {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Actual Address first: %d, inc: %d, count: %d", adt->address, adt->increment, adt->count);
+ }
+ break;
+
+ case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ adt->address = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ adt->increment = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ adt->count = tvb_get_guint8(tvb, offset);
+ offset += 1;
+ bytes_used = 3;
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ adt->address = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ adt->increment = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ adt->count = tvb_get_ntohs(tvb, offset);
+ offset += 2;
+ bytes_used = 6;
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ adt->address = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ adt->increment = tvb_get_ntohl(tvb, offset);
+ offset += 4;
+ adt->count = tvb_get_ntohl(tvb, offset);
+ offset += 12;
+ bytes_used = 12;
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ } /* of switch (adt->A) */
+
+ if (adt->V) {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Virtual Address first: %d, inc: %d, count: %d", adt->address, adt->increment, adt->count);
+ } else {
+ proto_tree_add_text(tree, tvb, start_offset, bytes_used, "Actual Address first: %d, inc: %d, count: %d", adt->address, adt->increment, adt->count);
+ }
+ break;
+ } /* of switch (adt->D) */
+
+ return offset;
+}
+
+
+/*******************************************************************************/
+/* Display DMP Data */
+static guint32
+acn_add_dmp_data(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
+{
+ guint32 start_offset;
+ guint32 data_size;
+ guint32 data_value;
+ guint32 data_address;
+ guint32 x,y;
+ gchar *buffer=NULL;
+ proto_item *ti;
+ guint32 ok_to_process = FALSE;
+
+ start_offset = offset;
+
+ /* We would like to rip through Property Address-Data pairs */
+ /* but since we don't now how many there are nor how big the data size is, */
+ /* it not possible. So, we just show the whole thing as a block of date! */
+ /* */
+ /* There are a few exceptions however */
+ /* 1) if the address type is ACN_DMP_ADT_D_NS or ACN_DMP_ADT_D_RS and */
+ /* or ACN_DMP_ADT_D_RE */
+ /* then number of bytes is <= count + 4. Each value is at least one byte */
+ /* and another address/data pair is at least 4 bytes so if the remaining */
+ /* bytes is less than the count plus 4 then the remaining data */
+ /* must be all data */
+ /* */
+ /* 2) if the address type is ACN_DMP_ADT_D_RE and the number of bytes */
+ /* equals the number of bytes in remaining in the pdu then there is */
+ /* a 1 to one match */
+
+ switch (adt->D) {
+ case ACN_DMP_ADT_D_NS:
+ case ACN_DMP_ADT_D_RS:
+ if (adt->data_length <= adt->count + 4) {
+ ok_to_process = TRUE;
+ }
+ break;
+ case ACN_DMP_ADT_D_RE:
+ if (adt->data_length == adt->count) {
+ ok_to_process = TRUE;
+ }
+ if (adt->data_length <= adt->count + 4) {
+ ok_to_process = TRUE;
+ }
+ break;
+ }
+
+ if (!ok_to_process) {
+ data_size = adt->data_length;
+ ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, FALSE);
+ offset += data_size;
+ proto_item_set_text(ti, "Data and more Address-Data Pairs (further dissection not possible)");
+ return offset;
+ }
+
+ /* Allocate some memory, not using ep_alloc here as there could be LOT of calls to
+ this in the same capture frame. Could use se_alloc...
+ */
+ #define BUFFER_SIZE 128
+ buffer = g_malloc(BUFFER_SIZE);
+ buffer[0] = 0;
+
+ switch (adt->D) {
+ case ACN_DMP_ADT_D_NS: /* Non-range address, Single data item */
+ /* calculate data size */
+ data_size = adt->data_length;
+ data_address = adt->address;
+
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %2.2X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %4.4X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %8.8X ->", data_address);
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ }
+
+ switch (data_size) {
+ case 1:
+ data_value = tvb_get_guint8(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
+ break;
+ case 2:
+ data_value = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data16, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
+ break;
+ case 3:
+ data_value = tvb_get_ntoh24(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data24, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
+ break;
+ case 4:
+ data_value = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data32, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
+ break;
+ default:
+ /* build string of values */
+ for (y=0;y<20 && y<data_size;y++) {
+ data_value = tvb_get_guint8(tvb, offset+y);
+ g_snprintf(buffer, BUFFER_SIZE, "%s %2.2X", buffer, data_value);
+ }
+ /* add the item */
+ ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, FALSE);
+ offset += data_size;
+ /* change the text */
+ proto_item_set_text(ti, "%s", buffer);
+ break;
+ } /* of switch (data_size) */
+ offset += data_size;
+ break;
+
+ case ACN_DMP_ADT_D_RS: /* Range address, Single data item */
+ /* calculate data size */
+ data_size = adt->data_length;
+ data_address = adt->address;
+
+ for (x=0;x<adt->count;x++) {
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %2.2X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %4.4X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %8.8X ->", data_address);
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ }
+
+ switch (data_size) {
+ case 1:
+ data_value = tvb_get_guint8(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
+ break;
+ case 2:
+ data_value = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
+ break;
+ case 3:
+ data_value = tvb_get_ntoh24(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
+ break;
+ case 4:
+ data_value = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
+ break;
+ default:
+ /* build string of values */
+ for (y=0;y<20 && y<data_size;y++) {
+ data_value = tvb_get_guint8(tvb, offset+y);
+ g_snprintf(buffer, BUFFER_SIZE, "%s %2.2X", buffer, data_value);
+ }
+ /* add the item */
+ ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, FALSE);
+ /* change the text */
+ proto_item_set_text(ti, "%s", buffer);
+ break;
+ } /* of switch (data_size) */
+ data_address += adt->increment;
+ } /* of (x=0;x<adt->count;x++) */
+ offset += data_size;
+ break;
+
+ case ACN_DMP_ADT_D_RE: /* Range address, Array of equal size data items */
+ /* calculate data size */
+ data_size = adt->data_length / adt->count;
+ data_address = adt->address;
+
+ for (x=0;x<adt->count;x++) {
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %2.2X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %4.4X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %8.8X ->", data_address);
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ }
+
+ switch (data_size) {
+ case 1:
+ data_value = tvb_get_guint8(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %2.2X", buffer, data_value);
+ break;
+ case 2:
+ data_value = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 2, data_value, "%s %4.4X", buffer, data_value);
+ break;
+ case 3:
+ data_value = tvb_get_ntoh24(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 3, data_value, "%s %6.6X", buffer, data_value);
+ break;
+ case 4:
+ data_value = tvb_get_ntohl(tvb, offset);
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 4, data_value, "%s %8.8X", buffer, data_value);
+ break;
+ default:
+ /* build string of values */
+ for (y=0;y<20 && y<data_size;y++) {
+ data_value = tvb_get_guint8(tvb, offset+y);
+ g_snprintf(buffer, BUFFER_SIZE, "%s %2.2X", buffer, data_value);
+ }
+ /* add the item */
+ ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, FALSE);
+ /* change the text */
+ proto_item_set_text(ti, "%s", buffer);
+ break;
+ } /* of switch (data_size) */
+
+ offset += data_size;
+ data_address += adt->increment;
+ } /* of (x=0;x<adt->count;x++) */
+ break;
+
+ case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
+ data_size = adt->data_length;
+ ti = proto_tree_add_item(tree, hf_acn_data, tvb, offset, data_size, FALSE);
+ offset += data_size;
+ /* change the text */
+ proto_item_set_text(ti, "Mixed size data items");
+ break;
+ } /* of switch (adt->D) */
+ /* free our memory! */
+ g_free(buffer);
+
+ return offset;
+}
+
+/*******************************************************************************/
+/* Display DMP Reason codes */
+static guint32
+acn_add_dmp_reason_codes(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, acn_dmp_adt_type *adt)
+{
+ guint32 start_offset;
+ guint32 data_value;
+ guint32 data_address;
+ guint32 x;
+
+ char *buffer=NULL;
+ const gchar *ptr;
+
+ start_offset = offset;
+
+ /* Allocate some memory, not using ep_alloc here as there could be LOT of calls to
+ this in the same capture frame. Could use se_alloc...
+ */
+ #define BUFFER_SIZE 128
+ buffer = g_malloc(BUFFER_SIZE);
+
+ buffer[0] = 0;
+
+ switch (adt->D) {
+ case ACN_DMP_ADT_D_NS: /* Non-range address, Single data item */
+ data_address = adt->address;
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %2.2X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %4.4X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %8.8X ->", data_address);
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ }
+
+ /* Get reason */
+ data_value = tvb_get_guint8(tvb, offset);
+ /* convert to string */
+ ptr = match_strval(data_value, acn_dmp_reason_code_vals);
+ /* Add item */
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, ptr);
+ offset++;
+ break;
+
+ case ACN_DMP_ADT_D_RS: /* Range address, Single data item */
+ data_address = adt->address;
+ for (x=0;x<adt->count;x++) {
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %2.2X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %4.4X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %8.8X ->", data_address);
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ }
+
+ /* Get reason */
+ data_value = tvb_get_guint8(tvb, offset);
+ /* convert to string */
+ ptr = match_strval(data_value, acn_dmp_reason_code_vals);
+ /* Add item */
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, ptr);
+ data_address += adt->increment;
+ } /* of (x=0;x<adt->count;x++) */
+ offset++;
+ break;
+
+ case ACN_DMP_ADT_D_RE: /* Range address, Array of equal size data items */
+ case ACN_DMP_ADT_D_RM: /* Range address, Series of mixed size data items */
+ data_address = adt->address;
+ for (x=0;x<adt->count;x++) {
+ switch (adt->A) {
+ case ACN_DMP_ADT_A_1: /* One octet address, (range: one octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %2.2X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_2: /* Two octet address, (range: two octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %4.4X ->", data_address);
+ break;
+ case ACN_DMP_ADT_A_4: /* Four octet address, (range: four octet address, increment, and count). */
+ g_snprintf(buffer, BUFFER_SIZE, "Addr %8.8X ->", data_address);
+ break;
+ default: /* and ACN_DMP_ADT_A_R, this reserved....so it has no meaning yet */
+ return offset;
+ }
+ /* Get reason */
+ data_value = tvb_get_guint8(tvb, offset);
+ /* convert to string */
+ ptr = match_strval(data_value, acn_dmp_reason_code_vals);
+ /* Add item */
+ proto_tree_add_int_format(tree, hf_acn_data8, tvb, offset, 1, data_value, "%s %s", buffer, ptr);
+ data_address += adt->increment;
+ offset++;
+ } /* of (x=0;x<adt->count;x++) */
+ break;
+ } /* of switch (adt->D) */
+ /* free our memory! */
+ g_free(buffer);
+
+ return offset;
+}
+
+/******************************************************************************/
+/* Dissect wrapped SDT PDU */
+static guint32
+dissect_acn_dmp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
+{
+ /* common to all pdu */
+ acn_pdu_flags pdu_flags;
+ guint32 pdu_start;
+ guint32 pdu_length;
+ guint32 pdu_flvh_length; /* flags, length, vector, header */
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+ guint8 octet;
+ guint32 length1;
+ guint32 length2;
+ guint32 length3;
+ guint32 vector_offset;
+ guint32 header_offset;
+ guint32 data_offset;
+ guint32 old_offset;
+ guint32 end_offset;
+ guint32 data_length;
+ guint32 address_count;
+
+ proto_item *ti, *pi;
+ proto_tree *pdu_tree = NULL;
+ proto_tree *flag_tree = NULL;
+
+ /* this pdu */
+ const gchar *ptr;
+ acn_dmp_adt_type adt = {{0},0,0,0,0,0};
+ acn_dmp_adt_type adt2 = {{0},0,0,0,0,0};
+ guint32 vector;
+
+ /* save start of pdu block */
+ pdu_start = offset;
+ pdu_offsets.start = pdu_start;
+
+ /* get PDU flags and length flag first */
+ octet = tvb_get_guint8(tvb, offset++);
+ pdu_flags.byte = octet & 0xf0;
+ length1 = octet & 0x0f; /* bottom 4 bits only */
+ length2 = tvb_get_guint8(tvb, offset++);
+
+ /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
+ /* flvh = flags, length, vector, header */
+ if (pdu_flags.L) {
+ length3 = tvb_get_guint8(tvb, offset);
+ offset++;
+ pdu_length = length3 | (length2 << 8) | (length1 << 16);
+ pdu_flvh_length = 3;
+ } else {
+ pdu_length = length2 | (length1 << 8);
+ pdu_flvh_length = 2;
+ }
+ /* offset should now be pointing to vector (if one exists) */
+
+ /* Add pdu item and tree */
+ ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, FALSE);
+ pdu_tree = proto_item_add_subtree(ti, ett_acn_dmp_pdu);
+
+ /* Add flag item and tree */
+ pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags.byte);
+ flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, FALSE);
+
+ /* Add PDU Length item */
+ proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
+
+ /* Set vector offset */
+ if (pdu_flags.V) {
+ /* use new values */
+ vector_offset = offset;
+ last_pdu_offsets->vector = offset;
+ offset++;
+ pdu_flvh_length++;
+ } else {
+ /* use last values */
+ vector_offset = last_pdu_offsets->vector;
+ }
+ /* offset should now be pointing to header (if one exists) */
+
+ /* Add Vector item */
+ vector = tvb_get_guint8(tvb, vector_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_dmp_vector, tvb, vector_offset, 1, vector);
+
+ /* Add Vector item to tree*/
+ ptr = match_strval(vector, acn_dmp_vector_vals);
+ proto_item_append_text(ti, ": ");
+ proto_item_append_text(ti, ptr);
+
+ /* Set header offset */
+ if (pdu_flags.H) {
+ /* use new values */
+ header_offset = offset;
+ last_pdu_offsets->header = offset;
+ offset++;
+ pdu_flvh_length++;
+ } else {
+ /* use last values */
+ header_offset = last_pdu_offsets->header;
+ }
+ /* offset should now be pointing to data (if one exists) */
+
+ /* header contains address and data type */
+ acn_add_dmp_address_type(tvb, pinfo, pdu_tree, header_offset, &adt);
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ switch (vector) {
+ case ACN_DMP_VECTOR_UNKNOWN:
+ break;
+ case ACN_DMP_VECTOR_GET_PROPERTY:
+ /* Rip trough property address */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_SET_PROPERTY:
+ /* Rip through Property Address-Data pairs */
+ /* But, in reality, this generally won't work as we have know way of */
+ /* calculating the next Address-Data pair */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+
+ adt.data_length = data_length - (data_offset - old_offset);
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_GET_PROPERTY_REPLY:
+ /* Rip through Property Address-Data pairs */
+ /* But, in reality, this generally won't work as we have know way of */
+ /* calculating the next Address-Data pair */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+
+
+ adt.data_length = data_length - (data_offset - old_offset);
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_EVENT:
+ /* Rip through Property Address-Data pairs */
+ /* But, in reality, this generally won't work as we have know way of */
+ /* calculating the next Address-Data pair */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+
+ adt.data_length = data_length - (data_offset - old_offset);
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_data(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_MAP_PROPERTY:
+ /* Virtual Address type */
+ data_offset = acn_add_dmp_address_type(tvb, pinfo, pdu_tree, data_offset, &adt2);
+ /* Rip through Actual-Virtual Address Pairs */
+ while (data_offset < end_offset) {
+ /* actual */
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ switch (adt.D) {
+ case ACN_DMP_ADT_D_NS:
+ address_count = 1;
+ break;
+ case ACN_DMP_ADT_D_RS:
+ address_count = 1;
+ break;
+ case ACN_DMP_ADT_D_RE:
+ address_count = adt.count;
+ break;
+ /*case ACN_DMP_ADT_D_RM: */
+ default:
+ /* OUCH */
+ return pdu_start + pdu_length;
+ break;
+ }
+
+ /* virtual */
+ while (address_count > 0) {
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt2);
+ address_count--;
+ }
+ }
+ break;
+ case ACN_DMP_VECTOR_UNMAP_PROPERTY:
+ /* Rip trough Actaul Proptery Address */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_SUBSCRIBE:
+ /* Rip trough Proptery Address */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_UNSUBSCRIBE:
+ /* Rip trough Proptery Address */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_GET_PROPERTY_FAIL:
+ /* Rip trough Address-Reason Code Pairs */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+
+ adt.data_length = data_length - (data_offset - old_offset);
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_SET_PROPERTY_FAIL:
+ /* Rip trough Address-Reason Code Pairs */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+
+ adt.data_length = data_length - (data_offset - old_offset);
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_MAP_PROPERTY_FAIL:
+ /* Rip trough Address-Reason Code Pairs */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+
+ adt.data_length = data_length - (data_offset - old_offset);
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT:
+ /* Rip through Property Addrsses */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_SUBSCRIBE_REJECT:
+ /* Rip trough Address-Reason Code Pairs */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+
+ adt.data_length = data_length - (data_offset - old_offset);
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_reason_codes(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_DMP_VECTOR_ALLOCATE_MAP:
+ /* No data for this */
+ break;
+ case ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY:
+ /* Single reason code */
+ proto_tree_add_item(pdu_tree, hf_acn_dmp_reason_code, tvb, data_offset, 1, FALSE);
+ data_offset++;
+ case ACN_DMP_VECTOR_DEALLOCATE_MAP:
+ /* No data for this */
+ break;
+ }
+
+ return pdu_start + pdu_length;
+}
+
+
+/******************************************************************************/
+/* Dissect wrapped SDT PDU */
+static guint32
+dissect_acn_sdt_wrapped_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree _U_, int offset, acn_pdu_offsets *last_pdu_offsets)
+{
+ /* common to all pdu */
+ acn_pdu_flags pdu_flags;
+ guint32 pdu_start;
+ guint32 pdu_length;
+ guint32 pdu_flvh_length; /* flags, length, vector, header */
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+ guint8 octet;
+ guint32 length1;
+ guint32 length2;
+ guint32 length3;
+ guint32 vector_offset;
+ guint32 data_offset;
+ guint32 end_offset;
+ guint32 data_length;
+
+ proto_item *ti, *pi;
+ proto_tree *pdu_tree = NULL;
+ proto_tree *flag_tree = NULL;
+
+ /* this pdu */
+ const gchar *ptr;
+ guint32 vector;
+
+ /* save start of pdu block */
+ pdu_start = offset;
+ pdu_offsets.start = pdu_start;
+
+ /* get PDU flags and length flag first */
+ octet = tvb_get_guint8(tvb, offset++);
+ pdu_flags.byte = octet & 0xf0;
+ length1 = octet & 0x0f; /* bottom 4 bits only */
+ length2 = tvb_get_guint8(tvb, offset++);
+
+ /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
+ /* flvh = flags, length, vector, header */
+ if (pdu_flags.L) {
+ length3 = tvb_get_guint8(tvb, offset);
+ offset++;
+ pdu_length = length3 | (length2 << 8) | (length1 << 16);
+ pdu_flvh_length = 3;
+ } else {
+ pdu_length = length2 | (length1 << 8);
+ pdu_flvh_length = 2;
+ }
+ /* offset should now be pointing to vector (if one exists) */
+
+ /* Add pdu item and tree */
+ ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, FALSE);
+ pdu_tree = proto_item_add_subtree(ti, ett_acn_sdt_pdu);
+
+ /* Add flag item and tree */
+ pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags.byte);
+ flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, FALSE);
+
+ /* Add PDU Length item */
+ proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
+
+ /* Set vector offset */
+ if (pdu_flags.V) {
+ /* use new values */
+ vector_offset = offset;
+ last_pdu_offsets->vector = offset;
+ offset++;
+ pdu_flvh_length++;
+ } else {
+ /* use last values */
+ vector_offset = last_pdu_offsets->vector;
+ }
+ /* offset should now be pointing to header (if one exists) */
+
+ /* Add Vector item */
+ vector = tvb_get_guint8(tvb, vector_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_sdt_vector, tvb, vector_offset, 1, vector);
+
+ /* Add Vector item to tree*/
+ ptr = match_strval(vector, acn_sdt_vector_vals);
+ proto_item_append_text(ti, ": ");
+ proto_item_append_text(ti, ptr);
+
+ /* NO HEADER DATA ON THESE* (at least so far) */
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ switch (vector) {
+ case ACN_SDT_VECTOR_ACK:
+ proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ break;
+ case ACN_SDT_VECTOR_CHANNEL_PARAMS:
+ data_offset = acn_add_channel_parameter(tvb, pinfo, pdu_tree, data_offset);
+ data_offset = acn_add_address(tvb, pinfo, pdu_tree, data_offset, "Ad-hoc Address: ");
+ data_offset = acn_add_expiry(tvb, pinfo, pdu_tree, data_offset, "Ad-hoc Expiry: ");
+ break;
+ case ACN_SDT_VECTOR_LEAVE:
+ /* nothing more */
+ break;
+ case ACN_SDT_VECTOR_CONNECT:
+ /* Protocol ID item */
+ proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ break;
+ case ACN_SDT_VECTOR_CONNECT_ACCEPT:
+ /* Protocol ID item */
+ proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ break;
+ case ACN_SDT_VECTOR_CONNECT_REFUSE:
+ /* Protocol ID item */
+ proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_refuse_code, tvb, data_offset, 1, FALSE);
+ data_offset++;
+ break;
+ case ACN_SDT_VECTOR_DISCONNECT:
+ /* Protocol ID item */
+ proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ break;
+ case ACN_SDT_VECTOR_DISCONNECTING:
+ /* Protocol ID item */
+ proto_tree_add_item(pdu_tree, hf_acn_protocol_id, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_reason_code, tvb, data_offset, 1, FALSE);
+ data_offset++;
+ break;
+
+ }
+
+ return pdu_start + pdu_length;
+}
+
+
+/******************************************************************************/
+/* Dissect SDT Client PDU */
+static guint32
+dissect_acn_sdt_client_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
+{
+ /* common to all pdu */
+ acn_pdu_flags pdu_flags;
+ guint32 pdu_start;
+ guint32 pdu_length;
+ guint32 pdu_flvh_length; /* flags, length, vector, header */
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+ guint8 octet;
+ guint32 length1;
+ guint32 length2;
+ guint32 length3;
+ guint32 vector_offset;
+ guint32 header_offset;
+ guint32 data_offset;
+ guint32 data_length;
+ guint32 old_offset;
+ guint32 end_offset;
+
+ proto_item *ti, *pi;
+ proto_tree *pdu_tree = NULL;
+ proto_tree *flag_tree = NULL;
+
+ /* this pdu */
+ const gchar *ptr;
+ guint32 member_id;
+ guint32 protocol_id;
+ guint16 association;
+
+ /* save start of pdu block */
+ pdu_start = offset;
+ pdu_offsets.start = pdu_start;
+
+ /* get PDU flags and length flag first */
+ octet = tvb_get_guint8(tvb, offset++);
+ pdu_flags.byte = octet & 0xf0;
+ length1 = octet & 0x0f; /* bottom 4 bits only */
+ length2 = tvb_get_guint8(tvb, offset++);
+
+ /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
+ /* flvh = flags, length, vector, header */
+ if (pdu_flags.L) {
+ length3 = tvb_get_guint8(tvb, offset);
+ offset++;
+ pdu_length = length3 | (length2 << 8) | (length1 << 16);
+ pdu_flvh_length = 3;
+ } else {
+ pdu_length = length2 | (length1 << 8);
+ pdu_flvh_length = 2;
+ }
+ /* offset should now be pointing to vector (if one exists) */
+
+ /* Add pdu item and tree */
+ ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, FALSE);
+ pdu_tree = proto_item_add_subtree(ti, ett_acn_sdt_client_pdu);
+
+ /* Add flag item and tree */
+ pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags.byte);
+ flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, FALSE);
+
+ /* Add PDU Length item */
+ proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
+
+ /* Set vector offset */
+ if (pdu_flags.V) {
+ /* use new values */
+ vector_offset = offset;
+ last_pdu_offsets->vector = offset;
+ offset += 2;
+ pdu_flvh_length += 2;
+ } else {
+ /* use last values */
+ vector_offset = last_pdu_offsets->vector;
+ }
+ /* offset should now be pointing to header (if one exists) */
+
+ /* add Member ID item */
+ member_id = tvb_get_ntohs(tvb, vector_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_member_id, tvb, vector_offset, 2, member_id);
+
+ /* Set header offset */
+ if (pdu_flags.H) {
+ /* use new values */
+ header_offset = offset;
+ last_pdu_offsets->header = offset;
+ offset += 6;
+ pdu_flvh_length += 6;
+ } else {
+ /* use last values */
+ header_offset = last_pdu_offsets->header;
+ }
+ /* offset should now be pointing to data (if one exists) */
+
+ /* add Protocol ID item (Header)*/
+ protocol_id = tvb_get_ntohl(tvb, header_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_protocol_id, tvb, header_offset, 4, protocol_id);
+ header_offset += 4;
+
+ /* Add protocol to tree*/
+ ptr = match_strval(protocol_id, acn_protocol_id_vals);
+ proto_item_append_text(ti, ": ");
+ proto_item_append_text(ti, ptr);
+
+ /* add association item */
+ association = tvb_get_ntohs(tvb, header_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_association, tvb, header_offset, 2, association);
+ header_offset += 2;
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ switch (protocol_id) {
+ case ACN_PROTOCOL_ID_SDT:
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = dissect_acn_sdt_wrapped_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
+ if (old_offset == data_offset) break;
+ }
+ break;
+ case ACN_PROTOCOL_ID_DMP:
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = dissect_acn_dmp_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
+ if (data_offset == old_offset) break;
+ }
+ break;
+ }
+ return pdu_start + pdu_length;
+}
+
+
+/******************************************************************************/
+// reverses the characters in a string
+void reverse(char *s)
+{
+ char c;
+ long i,j;
+ for (i=0, j=strlen(s)-1; i < j; i++, j--) {
+ c = s[i];
+ s[i] = s[j];
+ s[j] = c;
+ }
+}
+
+
+/******************************************************************************/
+/* level to string (ascii) */
+/* level : 8 bit value */
+/* string : pointer to buffer to fill */
+/* leading_char: character to buffer left of digits */
+/* min_char : mininum number of characters (for filling, not including space)*/
+/* show_zero: show zeros or dots */
+/* also adds a space to right end */
+/* */
+/* returns end of string */
+/* faster than printf() */
+char *ltos(guint8 level, gchar *string, guint8 base, gchar leading_char, guint8 min_chars, gboolean show_zero)
+{
+ guint8 i;
+ // verify base
+ if (base < 2 || base > 16) {
+ *string = '\0';
+ return(string);
+ }
+ // deal with zeros
+ if ((level == 0) && (!show_zero)) {
+ for (i=0;i<min_chars;i++) {
+ string[i] = '.';
+ }
+ string[i++] = ' ';
+ string[i] = '\0';
+ return(string + i);
+ }
+
+ i = 0;
+ /* do our convert, comes out backwords! */
+ do {
+ string[i++] = "0123456789ABCDEF"[level % base];
+ } while ((level /= base) > 0);
+
+ /* expand to needed character */
+ for (;i<min_chars;i++) {
+ string[i] = leading_char;
+ }
+ /* terminate */
+ string[i] = '\0';
+
+ /* now reverse (and correct) the order */
+ reverse(string);
+
+ /* add a space at the end (ok its at the start but it will be at the end)*/
+ string[i++] = ' ';
+ string[i] = '\0';
+ return(string + i);
+}
+
+
+/******************************************************************************/
+/* Dissect DMX data PDU */
+static guint32
+dissect_acn_dmx_data_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
+{
+ /* common to all pdu */
+ acn_pdu_flags pdu_flags;
+ guint32 pdu_start;
+ guint32 pdu_length;
+ guint32 pdu_flvh_length; /* flags, length, vector, header */
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+ guint8 octet;
+ guint32 length1;
+ guint32 length2;
+ guint32 length3;
+ guint32 vector_offset;
+ guint32 data_offset;
+ guint32 end_offset;
+ guint32 old_offset;
+ guint32 data_length;
+ guint32 header_offset;
+ guint32 total_cnt;
+ guint32 item_cnt;
+
+
+ proto_item *ti, *pi;
+ proto_tree *pdu_tree = NULL;
+ proto_tree *flag_tree = NULL;
+/* proto_tree *addr_tree = NULL; */
+
+/* this pdu */
+ acn_dmp_adt_type adt = {{0},0,0,0,0,0};
+ const gchar *ptr;
+ guint32 vector;
+ char *buffer=NULL;
+ char *buf_ptr;
+ guint32 x;
+ guint8 level;
+ guint8 min_char;
+ guint8 base;
+ gchar leading_char;
+
+
+ /* save start of pdu block */
+ pdu_start = offset;
+ pdu_offsets.start = pdu_start;
+
+ /* get PDU flags and length flag first */
+ octet = tvb_get_guint8(tvb, offset++);
+ pdu_flags.byte = octet & 0xf0;
+ length1 = octet & 0x0f; /* bottom 4 bits only */
+ length2 = tvb_get_guint8(tvb, offset++);
+
+ /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
+ /* flvh = flags, length, vector, header */
+ if (pdu_flags.L) {
+ length3 = tvb_get_guint8(tvb, offset);
+ offset++;
+ pdu_length = length3 | (length2 << 8) | (length1 << 16);
+ pdu_flvh_length = 3;
+ } else {
+ pdu_length = length2 | (length1 << 8);
+ pdu_flvh_length = 2;
+ }
+ /* offset should now be pointing to vector (if one exists) */
+
+ /* Add pdu item and tree */
+ ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, FALSE);
+ pdu_tree = proto_item_add_subtree(ti, ett_acn_dmx_data_pdu);
+
+ /* Add flag item and tree */
+ pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags.byte);
+ flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, FALSE);
+
+ /* Add PDU Length item */
+ proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
+
+ /* Set vector offset */
+ if (pdu_flags.V) {
+ /* use new values */
+ vector_offset = offset;
+ last_pdu_offsets->vector = offset;
+ offset += 1;
+ pdu_flvh_length += 1;
+ } else {
+ /* use last values */
+ vector_offset = last_pdu_offsets->vector;
+ }
+ /* offset should now be pointing to header (if one exists) */
+
+ /* Add Vector item */
+ vector = tvb_get_guint8(tvb, vector_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_dmp_vector, tvb, vector_offset, 1, vector);
+
+ /* Add Vector item to tree*/
+ ptr = match_strval(vector, acn_dmp_vector_vals);
+ proto_item_append_text(ti, ": ");
+ proto_item_append_text(ti, ptr);
+
+ /* Set header offset */
+ if (pdu_flags.H) {
+ /* use new values */
+ header_offset = offset;
+ last_pdu_offsets->header = offset;
+ offset++;
+ pdu_flvh_length++;
+ } else {
+ /* use last values */
+ header_offset = last_pdu_offsets->header;
+ }
+ /* offset should now be pointing to data (if one exists) */
+
+ /* process based on vector */
+ acn_add_dmp_address_type(tvb, pinfo, pdu_tree, header_offset, &adt);
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ switch (vector) {
+ case ACN_DMP_VECTOR_SET_PROPERTY:
+ old_offset = data_offset;
+ data_offset = acn_add_dmp_address(tvb, pinfo, pdu_tree, data_offset, &adt);
+ if (data_offset == old_offset) break;
+
+#define BUFFER_SIZE 128
+
+ buffer = ep_alloc(BUFFER_SIZE);
+ buffer[0] = 0;
+ buf_ptr = buffer;
+
+ /* values base on display mode */
+ switch ((guint)global_acn_dmx_display_view) {
+ case ACN_PREF_DMX_DISPLAY_HEX:
+ min_char = 2;
+ base = 16;
+ break;
+/* case ACN_PREF_DMX_DISPLAY_PER: */
+ default:
+ min_char = 3;
+ base = 10;
+ }
+
+ /* do we display leading zeros */
+ if (global_acn_dmx_display_leading_zeros) {
+ leading_char = '0';
+ } else {
+ leading_char = ' ';
+ }
+
+ /* add a header line */
+ memset(buffer, ' ', 10);
+ buf_ptr += 9;
+ for (x=1;x<=20;x++) {
+ buf_ptr = ltos((guint8)x, buf_ptr, 10, ' ', min_char, FALSE);
+ if (x==10) {
+ *buf_ptr++ = '|';
+ *buf_ptr++ = ' ';
+ }
+ }
+ *buf_ptr = '\0';
+ proto_tree_add_text(pdu_tree, tvb, data_offset, 0, buffer);
+
+ /* start our line */
+ g_snprintf(buffer, BUFFER_SIZE, "001-020: ");
+ buf_ptr = buffer + 9;
+
+ total_cnt = 0;
+ item_cnt = 0;
+ for (x=data_offset; x < end_offset; x++) {
+ level = tvb_get_guint8(tvb, x);
+ if (global_acn_dmx_display_view==ACN_PREF_DMX_DISPLAY_PER) {
+ if ((level > 0) && (level < 3)) {
+ level = 1;
+ } else {
+ level = level * 100 / 255;
+ }
+ }
+ buf_ptr = ltos(level, buf_ptr, base, leading_char, min_char, global_acn_dmx_display_zeros);
+ total_cnt++;
+ item_cnt++;
+
+ if (item_cnt == 20 || x == (end_offset-1)) {
+ // add leader...
+ proto_tree_add_text(pdu_tree, tvb, data_offset, item_cnt, buffer);
+ data_offset += 20;
+ g_snprintf(buffer, BUFFER_SIZE, "%03d-%03d: ",total_cnt, total_cnt+20);
+ buf_ptr = buffer + 9;
+ item_cnt = 0;
+ } else {
+ /* add separater character */
+ if (item_cnt == 10) {
+ *buf_ptr++ = '|';
+ *buf_ptr++ = ' ';
+ *buf_ptr = '\0';
+ }
+ }
+ }
+ /* NOTE:
+ address data type (fixed at 0xA2)
+ start code - 1 byte, reserved (should be 0)
+ - 1 byte, start code (0x255)
+ - 2 bytes, packet offset (should be 0000)
+ address increment - 4 bytes (ignore)
+ number of dmx values - 4 bytes (0-512)
+ dmx values 0-512 bytes (data)
+ */
+
+ break;
+ }
+ return pdu_start + pdu_length;
+}
+
+
+
+/******************************************************************************/
+/* Dissect DMX Base PDU */
+static guint32
+dissect_acn_dmx_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
+{
+ /* common to all pdu */
+ acn_pdu_flags pdu_flags;
+ guint32 pdu_start;
+ guint32 pdu_length;
+ guint32 pdu_flvh_length; /* flags, length, vector, header */
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+ guint8 octet;
+ guint32 length1;
+ guint32 length2;
+ guint32 length3;
+ guint32 vector_offset;
+ guint32 data_offset;
+ guint32 end_offset;
+ guint32 data_length;
+
+ proto_item *ti, *pi;
+ proto_tree *pdu_tree = NULL;
+ proto_tree *flag_tree = NULL;
+
+/* this pdu */
+ guint32 vector;
+
+ guint32 universe;
+ guint32 priority;
+
+ /* save start of pdu block */
+ pdu_start = offset;
+ pdu_offsets.start = pdu_start;
+
+ /* get PDU flags and length flag first */
+ octet = tvb_get_guint8(tvb, offset++);
+ pdu_flags.byte = octet & 0xf0;
+ length1 = octet & 0x0f; /* bottom 4 bits only */
+ length2 = tvb_get_guint8(tvb, offset++);
+
+ /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
+ /* flvh = flags, length, vector, header */
+ if (pdu_flags.L) {
+ length3 = tvb_get_guint8(tvb, offset);
+ offset++;
+ pdu_length = length3 | (length2 << 8) | (length1 << 16);
+ pdu_flvh_length = 3;
+ } else {
+ pdu_length = length2 | (length1 << 8);
+ pdu_flvh_length = 2;
+ }
+
+ /* offset should now be pointing to vector (if one exists) */
+
+ /* Add pdu item and tree */
+ ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, FALSE);
+ pdu_tree = proto_item_add_subtree(ti, ett_acn_dmx_pdu);
+
+ /* Add flag item and tree */
+ pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags.byte);
+ flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, FALSE);
+
+ /* Add PDU Length item */
+ proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
+
+ /* Set vector offset */
+ if (pdu_flags.V) {
+ /* use new values */
+ vector_offset = offset;
+ last_pdu_offsets->vector = offset;
+ offset += 4;
+ pdu_flvh_length += 4;
+ } else {
+ /* use last values */
+ vector_offset = last_pdu_offsets->vector;
+ }
+ /* offset should now be pointing to header (if one exists) */
+
+ /* Add Vector item */
+ vector = tvb_get_ntohl(tvb, vector_offset);
+ proto_tree_add_item(pdu_tree, hf_acn_dmx_vector, tvb, vector_offset, 4, FALSE);
+ /* vector_offset +=4; */
+
+ /* Add Vector item to tree*/
+ proto_item_append_text(ti, ": %s", match_strval(vector, acn_dmx_vector_vals));
+
+ /* NO HEADER DATA ON THESE* (at least so far) */
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ /* process based on vector */
+ switch (vector) {
+ case 0x02:
+ proto_tree_add_item(pdu_tree, hf_acn_dmx_source_name, tvb, data_offset, 32, FALSE);
+ data_offset += 32;
+
+ priority = tvb_get_guint8(tvb, data_offset);
+ proto_tree_add_item(pdu_tree, hf_acn_dmx_priority, tvb, data_offset, 1, FALSE);
+ data_offset += 1;
+
+ proto_tree_add_item(pdu_tree, hf_acn_dmx_sequence_number, tvb, data_offset, 1, FALSE);
+ data_offset += 1;
+
+ universe = tvb_get_ntohs(tvb, data_offset);
+ proto_tree_add_item(pdu_tree, hf_acn_dmx_universe , tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+
+ proto_item_append_text(ti, ", Universe: %d, Priority: %d", universe, priority);
+
+ data_offset = dissect_acn_dmx_data_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
+
+ break;
+ }
+ return pdu_start + pdu_length;
+}
+
+/******************************************************************************/
+/* Dissect SDT Base PDU */
+static guint32
+dissect_acn_sdt_base_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
+{
+ /* common to all pdu */
+ acn_pdu_flags pdu_flags;
+ guint32 pdu_start;
+ guint32 pdu_length;
+ guint32 pdu_flvh_length; /* flags, length, vector, header */
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+ guint8 octet;
+ guint32 length1;
+ guint32 length2;
+ guint32 length3;
+ guint32 vector_offset;
+ guint32 data_offset;
+ guint32 end_offset;
+ guint32 old_offset;
+ guint32 data_length;
+
+ proto_item *ti, *pi;
+ proto_tree *pdu_tree = NULL;
+ proto_tree *flag_tree = NULL;
+
+ /* this pdu */
+ const gchar *ptr;
+ guint32 vector;
+ guint32 member_id;
+
+ /* save start of pdu block */
+ pdu_start = offset;
+ pdu_offsets.start = pdu_start;
+
+ /* get PDU flags and length flag first */
+ octet = tvb_get_guint8(tvb, offset++);
+ pdu_flags.byte = octet & 0xf0;
+ length1 = octet & 0x0f; /* bottom 4 bits only */
+ length2 = tvb_get_guint8(tvb, offset++);
+
+ /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
+ /* flvh = flags, length, vector, header */
+ if (pdu_flags.L) {
+ length3 = tvb_get_guint8(tvb, offset);
+ offset++;
+ pdu_length = length3 | (length2 << 8) | (length1 << 16);
+ pdu_flvh_length = 3;
+ } else {
+ pdu_length = length2 | (length1 << 8);
+ pdu_flvh_length = 2;
+ }
+ /* offset should now be pointing to vector (if one exists) */
+
+ /* Add pdu item and tree */
+ ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, FALSE);
+ pdu_tree = proto_item_add_subtree(ti, ett_acn_sdt_base_pdu);
+
+ /* Add flag item and tree */
+ pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags.byte);
+ flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, FALSE);
+
+ /* Add PDU Length item */
+ proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
+
+ /* Set vector offset */
+ if (pdu_flags.V) {
+ /* use new values */
+ vector_offset = offset;
+ last_pdu_offsets->vector = offset;
+ offset++;
+ pdu_flvh_length++;
+ } else {
+ /* use last values */
+ vector_offset = last_pdu_offsets->vector;
+ }
+ /* offset should now be pointing to header (if one exists) */
+
+ /* Add Vector item */
+ vector = tvb_get_guint8(tvb, vector_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_sdt_vector, tvb, vector_offset, 1, vector);
+
+ /* Add Vector item to tree*/
+ ptr = match_strval(vector, acn_sdt_vector_vals);
+ proto_item_append_text(ti, ": ");
+ proto_item_append_text(ti, ptr);
+
+ /* NO HEADER DATA ON THESE* (at least so far) */
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ /* process based on vector */
+ switch (vector) {
+ case ACN_SDT_VECTOR_UNKNOWN:
+ break;
+ case ACN_SDT_VECTOR_REL_WRAP:
+ case ACN_SDT_VECTOR_UNREL_WRAP:
+ proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_total_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_oldest_available_wrapper, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_first_memeber_to_ack, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_last_memeber_to_ack, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_mak_threshold, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = dissect_acn_sdt_client_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
+ if (data_offset == old_offset) break;
+ }
+ break;
+ case ACN_SDT_VECTOR_CHANNEL_PARAMS:
+ break;
+ case ACN_SDT_VECTOR_JOIN:
+ proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, FALSE);
+ data_offset += 16;
+ proto_tree_add_item(pdu_tree, hf_acn_member_id, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_reciprocal_channel, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_total_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ data_offset = acn_add_address(tvb, pinfo, pdu_tree, data_offset, "Destination Address: ");
+ data_offset = acn_add_channel_parameter(tvb, pinfo, pdu_tree, data_offset);
+ data_offset = acn_add_expiry(tvb, pinfo, pdu_tree, data_offset, "Ad-hoc Expiry: ");
+ break;
+ case ACN_SDT_VECTOR_JOIN_REFUSE:
+ pi = proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, FALSE);
+ data_offset += 16;
+ proto_item_append_text(pi, "(Leader)");
+ proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_member_id, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_refuse_code, tvb, data_offset, 1, FALSE);
+ data_offset ++;
+ break;
+ case ACN_SDT_VECTOR_JOIN_ACCEPT:
+ pi = proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, FALSE);
+ data_offset += 16;
+ proto_item_append_text(pi, "(Leader)");
+ proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_member_id, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_reciprocal_channel, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ break;
+ case ACN_SDT_VECTOR_LEAVE:
+ break;
+ case ACN_SDT_VECTOR_LEAVING:
+ pi = proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, FALSE);
+ data_offset += 16;
+ proto_item_append_text(pi, "(Leader)");
+ proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_member_id, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_reason_code, tvb, data_offset, 1, FALSE);
+ offset++;
+ break;
+ case ACN_SDT_VECTOR_CONNECT:
+ break;
+ case ACN_SDT_VECTOR_CONNECT_ACCEPT:
+ break;
+ case ACN_SDT_VECTOR_CONNECT_REFUSE:
+ break;
+ case ACN_SDT_VECTOR_DISCONNECT:
+ break;
+ case ACN_SDT_VECTOR_DISCONNECTING:
+ break;
+ case ACN_SDT_VECTOR_ACK:
+ break;
+ case ACN_SDT_VECTOR_NAK:
+ pi = proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, FALSE);
+ data_offset += 16;
+ proto_item_append_text(pi, "(Leader)");
+ proto_tree_add_item(pdu_tree, hf_acn_channel_number, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_member_id, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(pdu_tree, hf_acn_reliable_sequence_number, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_first_missed_sequence, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ proto_tree_add_item(pdu_tree, hf_acn_last_missed_sequence, tvb, data_offset, 4, FALSE);
+ data_offset += 4;
+ break;
+ case ACN_SDT_VECTOR_GET_SESSION:
+ proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, data_offset, 16, FALSE);
+ data_offset += 16;
+ break;
+ case ACN_SDT_VECTOR_SESSIONS:
+ member_id = tvb_get_ntohs(tvb, data_offset);
+ switch (member_id) {
+ case 0:
+ data_offset = acn_add_channel_owner_info_block(tvb, pinfo, pdu_tree, data_offset);
+ break;
+ case 1:
+ data_offset = acn_add_channel_member_info_block(tvb, pinfo, pdu_tree, data_offset);
+ break;
+ }
+ break;
+ }
+
+ return pdu_start + pdu_length;
+}
+
+/******************************************************************************/
+/* Dissect Root PDU */
+static guint32
+dissect_acn_root_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, acn_pdu_offsets *last_pdu_offsets)
+{
+ /* common to all pdu */
+ acn_pdu_flags pdu_flags;
+ guint32 pdu_start;
+ guint32 pdu_length;
+ guint32 pdu_flvh_length; /* flags, length, vector, header */
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+ guint8 octet;
+ guint32 length1;
+ guint32 length2;
+ guint32 length3;
+ guint32 vector_offset;
+ guint32 header_offset;
+ guint32 data_offset;
+ guint32 end_offset;
+ guint32 old_offset;
+ guint32 data_length;
+
+ proto_item *ti, *pi;
+ proto_tree *pdu_tree = NULL;
+ proto_tree *flag_tree = NULL;
+
+ /* this pdu */
+ guint32 protocol_id;
+ e_guid_t guid;
+ gchar buf[GUID_STR_LEN];
+
+ /* save start of pdu block */
+ pdu_start = offset;
+ pdu_offsets.start = pdu_start;
+
+ /* get PDU flags and length flag first */
+ octet = tvb_get_guint8(tvb, offset++);
+ pdu_flags.byte = octet & 0xf0;
+ length1 = octet & 0x0f; /* bottom 4 bits only */
+ length2 = tvb_get_guint8(tvb, offset++);
+
+ /* if length flag is set, then we have a 20 bit length else we have a 12 bit */
+ /* flvh = flags, length, vector, header */
+ if (pdu_flags.L) {
+ length3 = tvb_get_guint8(tvb, offset);
+ offset++;
+ pdu_length = length3 | (length2 << 8) | (length1 << 16);
+ pdu_flvh_length = 3;
+ } else {
+ pdu_length = length2 | (length1 << 8);
+ pdu_flvh_length = 2;
+ }
+ /* offset should now be pointing to vector (if one exists) */
+
+ /* Add pdu item and tree */
+ ti = proto_tree_add_item(tree, hf_acn_pdu, tvb, pdu_start, pdu_length, FALSE);
+ pdu_tree = proto_item_add_subtree(ti, ett_acn_root_pdu);
+
+ /* Add flag item and tree */
+ pi = proto_tree_add_uint(pdu_tree, hf_acn_pdu_flags, tvb, pdu_start, 1, pdu_flags.byte);
+ flag_tree = proto_item_add_subtree(pi, ett_acn_pdu_flags);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_l, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_v, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_h, tvb, pdu_start, 1, FALSE);
+ proto_tree_add_item(flag_tree, hf_acn_pdu_flag_d, tvb, pdu_start, 1, FALSE);
+
+ /* Add PDU Length item */
+ proto_tree_add_uint(pdu_tree, hf_acn_pdu_length, tvb, pdu_start, pdu_flvh_length, pdu_length);
+
+ /* Set vector offset */
+ if (pdu_flags.V) {
+ /* use new values */
+ vector_offset = offset;
+ last_pdu_offsets->vector = offset;
+ offset += 4;
+ pdu_flvh_length += 4;
+ } else {
+ /* use last values */
+ vector_offset = last_pdu_offsets->vector;
+ }
+ /* offset should now be pointing to header (if one exists) */
+
+
+
+ /* Get Protocol ID (vector) */
+ protocol_id = tvb_get_ntohl(tvb, vector_offset);
+ proto_tree_add_uint(pdu_tree, hf_acn_protocol_id, tvb, vector_offset, 4, protocol_id);
+
+ /* process based on protocol_id */
+ switch (protocol_id) {
+ case ACN_PROTOCOL_ID_DMX:
+ if (global_acn_dmx_enable) {
+ proto_item_append_text(ti,": Root DMX");
+
+ /* Set header offset */
+ if (pdu_flags.H) {
+ /* use new values */
+ header_offset = offset;
+ last_pdu_offsets->header = offset;
+ offset += 16;
+ pdu_flvh_length += 16;
+ } else {
+ /* use last values */
+ header_offset = last_pdu_offsets->header;
+ }
+ /* offset should now be pointing to data (if one exists) */
+
+ /* get Header (CID) 16 bytes */
+ tvb_get_guid(tvb, header_offset, &guid, FALSE);
+ guid_to_str_buf(&guid, buf, sizeof(buf));
+ proto_item_append_text(ti, ", Src: %s", buf);
+ proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, header_offset, 16, FALSE);
+ header_offset += 16;
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ /* adjust for what we used */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = dissect_acn_dmx_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
+ if (data_offset == old_offset) break;
+ }
+ }
+ break;
+ case ACN_PROTOCOL_ID_SDT:
+ /* Adjust header */
+ proto_item_append_text(ti,": Root SDT");
+
+ /* Set header offset */
+ if (pdu_flags.H) {
+ /* use new values */
+ header_offset = offset;
+ last_pdu_offsets->header = offset;
+ offset += 16;
+ pdu_flvh_length += 16;
+ } else {
+ /* use last values */
+ header_offset = last_pdu_offsets->header;
+ }
+ /* offset should now be pointing to data (if one exists) */
+
+ /* get Header (CID) 16 bytes */
+ tvb_get_guid(tvb, header_offset, &guid, FALSE);
+ guid_to_str_buf(&guid, buf, sizeof(buf));
+ proto_item_append_text(ti, ", Src: %s", buf);
+ proto_tree_add_item(pdu_tree, hf_acn_cid, tvb, header_offset, 16, FALSE);
+ header_offset += 16;
+
+ /* Adjust data */
+ if (pdu_flags.D) {
+ /* use new values */
+ data_offset = offset;
+ data_length = pdu_length - pdu_flvh_length;
+ last_pdu_offsets->data = offset;
+ last_pdu_offsets->data_length = data_length;
+ } else {
+ /* use last values */
+ data_offset = last_pdu_offsets->data;
+ data_length = last_pdu_offsets->data_length;
+ }
+ end_offset = data_offset + data_length;
+
+ /* adjust for what we used */
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = dissect_acn_sdt_base_pdu(tvb, pinfo, pdu_tree, data_offset, &pdu_offsets);
+ if (data_offset == old_offset) break;
+ }
+ break;
+ }
+
+ return pdu_start + pdu_length;
+}
+
+/******************************************************************************/
+/* Dissect ACN */
+static int
+dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *ti = NULL;
+ proto_tree *acn_tree = NULL;
+ guint32 data_offset = 0;
+ guint32 old_offset;
+ guint32 end_offset;
+ acn_pdu_offsets pdu_offsets = {0,0,0,0,0};
+
+/* if (!is_acn(tvb)) { */
+/* return 0; */
+/* } */
+
+ /* Set the protocol column */
+ if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "ACN");
+ }
+
+ /* Clear out stuff in the info column */
+ if(check_col(pinfo->cinfo,COL_INFO)){
+ /* col_clear(pinfo->cinfo,COL_INFO); */
+ col_add_fstr(pinfo->cinfo,COL_INFO, "ACN [Src Port: %d, Dst Port: %d]", pinfo->srcport, pinfo->destport );
+ }
+
+ if (tree) { /* we are being asked for details */
+ ti = proto_tree_add_item(tree, proto_acn, tvb, 0, -1, FALSE);
+ acn_tree = proto_item_add_subtree(ti, ett_acn);
+
+ pdu_offsets.start = data_offset;
+
+ /* add preamble, postamble and ACN Packet ID */
+ proto_tree_add_item(acn_tree, hf_acn_preamble_size, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(acn_tree, hf_acn_postamble_size, tvb, data_offset, 2, FALSE);
+ data_offset += 2;
+ proto_tree_add_item(acn_tree, hf_acn_packet_identifier, tvb, data_offset, 12, FALSE);
+ data_offset += 12;
+
+ /* one past the last byte */
+ end_offset = data_offset + tvb_reported_length_remaining(tvb, data_offset);
+ while (data_offset < end_offset) {
+ old_offset = data_offset;
+ data_offset = dissect_acn_root_pdu(tvb, pinfo, acn_tree, data_offset, &pdu_offsets);
+ if (data_offset == old_offset) break;
+ }
+ }
+ return tvb_length(tvb);
+}
+
+/******************************************************************************/
+/* Register protocol */
+void proto_register_acn(void)
+{
+ static hf_register_info hf[] = {
+ /**************************************************************************/
+ /* In alphabetical order */
+ /* Address Type */
+ /* PDU flags*/
+ { &hf_acn_ip_address_type,
+ { "Type", "acn.ip_address_type",
+ FT_UINT8, BASE_DEC, VALS(acn_ip_address_type_vals), 0x0,
+ "Type", HFILL }
+ },
+ /* Association */
+ { &hf_acn_association,
+ { "Association", "acn.association",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Association", HFILL }
+ },
+ /* Channel Number */
+ { &hf_acn_channel_number,
+ { "Channel Number", "acn.channel_number",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Channel Number", HFILL }
+ },
+ /* CID */
+ { &hf_acn_cid,
+ { "CID", "acn.cid",
+ FT_GUID, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ /* Client Protocol ID */
+ { &hf_acn_client_protocol_id,
+ { "Client Protocol ID", "acn.client_protocol_id",
+ FT_UINT32, BASE_DEC, VALS(acn_protocol_id_vals), 0x0,
+ "ClientProtocol ID", HFILL }
+ },
+ /* DMP data */
+ { &hf_acn_data,
+ { "Data", "acn.dmp_data",
+ FT_BYTES, BASE_HEX, NULL, 0x0,
+ "Data", HFILL }
+ },
+ { &hf_acn_data8,
+ { "Addr", "acn.dmp_data8",
+ FT_INT8, BASE_DEC_HEX, NULL, 0x0,
+ "Data8", HFILL }
+ },
+ { &hf_acn_data16,
+ { "Addr", "acn.dmp_data16",
+ FT_INT16, BASE_DEC_HEX, NULL, 0x0,
+ "Data16", HFILL }
+ },
+ { &hf_acn_data24,
+ { "Addr", "acn.dmp_data24",
+ FT_INT24, BASE_DEC_HEX, NULL, 0x0,
+ "Data24", HFILL }
+ },
+ { &hf_acn_data32,
+ { "Addr", "acn.dmp_data32",
+ FT_INT32, BASE_DEC_HEX, NULL, 0x0,
+ "Data32", HFILL }
+ },
+
+ { &hf_acn_dmp_address_data_pairs,
+ { "Address-Data Pairs", "acn.dmp_address_data_pairs",
+ FT_BYTES, BASE_DEC, NULL, 0x0,
+ "More address-data pairs", HFILL }
+ },
+
+ /* DMP Address */
+ { &hf_acn_dmp_address1,
+ { "Address", "acn.dmp_address",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ "Address", HFILL }
+ },
+ { &hf_acn_dmp_address2,
+ { "Address", "acn.dmp_address",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Address", HFILL }
+ },
+ { &hf_acn_dmp_address4,
+ { "Address", "acn.dmp_address",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ "Address", HFILL }
+ },
+
+ /* DMP Address type*/
+ { &hf_acn_dmp_adt,
+ { "Address and Data Type", "acn.dmp_adt",
+ FT_UINT8, BASE_DEC_HEX, NULL, 0x0,
+ "Address and Data Type", HFILL }
+ },
+ { &hf_acn_dmp_adt_a,
+ { "Size", "acn.dmp_adt_a",
+ FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_a_vals), 0x03,
+ "Size", HFILL }
+ },
+ { &hf_acn_dmp_adt_d,
+ { "Data Type", "acn.dmp_adt_d",
+ FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_d_vals), 0x30,
+ "Data Type", HFILL }
+ },
+ { &hf_acn_dmp_adt_r,
+ { "Relative", "acn.dmp_adt_r",
+ FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_r_vals), 0x40,
+ "Relative", HFILL }
+ },
+ { &hf_acn_dmp_adt_v,
+ { "Virtual", "acn.dmp_adt_v",
+ FT_UINT8, BASE_DEC, VALS(acn_dmp_adt_v_vals), 0x80,
+ "Virtual", HFILL }
+ },
+ { &hf_acn_dmp_adt_x,
+ { "Reserved", "acn.dmp_adt_x",
+ FT_UINT8, BASE_DEC, NULL, 0x0c,
+ "Reserved", HFILL }
+ },
+
+ /* DMP Reason Code */
+ { &hf_acn_dmp_reason_code,
+ { "Reason Code", "acn.dmp_reason_code",
+ FT_UINT8, BASE_DEC, VALS(acn_dmp_reason_code_vals), 0x0,
+ "Reason Code", HFILL }
+ },
+
+ /* DMP Vector */
+ { &hf_acn_dmp_vector,
+ { "DMP Vector", "acn.dmp_vector",
+ FT_UINT8, BASE_DEC, VALS(acn_dmp_vector_vals), 0x0,
+ "DMP Vector", HFILL }
+ },
+ /* Expiry */
+ { &hf_acn_expiry,
+ { "Expiry", "acn.expiry",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Expiry", HFILL }
+ },
+ /* First Member to ACK */
+ { &hf_acn_first_memeber_to_ack,
+ { "First Member to ACK", "acn.first_member_to_ack",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "First Member to ACK", HFILL }
+ },
+ /* First Missed Sequence */
+ { &hf_acn_first_missed_sequence,
+ { "First Missed Sequence", "acn.first_missed_sequence",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ "First Missed Sequence", HFILL }
+ },
+ /* IPV4 */
+ { &hf_acn_ipv4,
+ { "IPV4", "acn.ipv4",
+ FT_IPv4, BASE_NONE, NULL, 0x0,
+ "IPV4", HFILL }
+ },
+ /* IPV6 */
+ { &hf_acn_ipv6,
+ { "IPV6", "acn.ipv6",
+ FT_IPv6, BASE_NONE, NULL, 0x0,
+ "IPV6", HFILL }
+ },
+ /* Last Member to ACK */
+ { &hf_acn_last_memeber_to_ack,
+ { "Last Member to ACK", "acn.last_member_to_ack",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Last Member to ACK", HFILL }
+ },
+ /* Last Missed Sequence */
+ { &hf_acn_last_missed_sequence,
+ { "Last Missed Sequence", "acn.last_missed_sequence",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ "Last Missed Sequence", HFILL }
+ },
+ /* MAK threshold */
+ { &hf_acn_mak_threshold,
+ { "MAK Threshold", "acn.mak_threshold",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "MAK Threshold", HFILL }
+ },
+ /* MemberID */
+ { &hf_acn_member_id,
+ { "Member ID", "acn.member_id",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Member ID", HFILL }
+ },
+ /* NAK Holdoff */
+ { &hf_acn_nak_holdoff,
+ { "NAK holdoff (ms)", "acn.nak_holdoff",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "NAK holdoff", HFILL }
+ },
+ /* NAK Max Wait */
+ { &hf_acn_nak_max_wait,
+ { "NAK Max Wait (ms)", "acn.nak_max_wait",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "NAK Max Wait", HFILL }
+ },
+ /* NAK Modulus */
+ { &hf_acn_nak_modulus,
+ { "NAK Modulus", "acn.nak_modulus",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "NAK Modulus", HFILL }
+ },
+ /* NAK Outbound Flag */
+ { &hf_acn_nak_outbound_flag,
+ { "NAK Outbound Flag", "acn.nak_outbound_flag",
+ FT_BOOLEAN, 8, NULL, 0x80,
+ "NAK Outbound Flag", HFILL }
+ },
+ /* Oldest Available Wrapper */
+ { &hf_acn_oldest_available_wrapper,
+ { "Oldest Available Wrapper", "acn.oldest_available_wrapper",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ "Oldest Available Wrapper", HFILL }
+ },
+ /* Preamble Sizet */
+ { &hf_acn_preamble_size,
+ { "Size of preamble", "acn.preamble_size",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Preamble size in bytes", HFILL }
+ },
+ /* Packet Identifier */
+ { &hf_acn_packet_identifier,
+ { "Packet Identifier", "acn.packet_identifier",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ "Packet Identififer", HFILL }
+ },
+ /* PDU */
+ { &hf_acn_pdu,
+ { "PDU", "acn.pdu",
+ FT_NONE, BASE_NONE, NULL, 0x0,
+ "PDU", HFILL }
+ },
+ /* PDU flags*/
+ { &hf_acn_pdu_flags,
+ { "Flags", "acn.pdu.flags",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ "PDU Flags", HFILL }
+ },
+ { &hf_acn_pdu_flag_d,
+ { "Data", "acn.pdu.flag_d",
+ FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_D,
+ "Data flag", HFILL }
+ },
+ { &hf_acn_pdu_flag_h,
+ { "Header", "acn.pdu.flag_h",
+ FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_H,
+ "Header flag", HFILL }
+ },
+ { &hf_acn_pdu_flag_l,
+ { "Length", "acn.pdu.flag_l",
+ FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_L,
+ "Length flag", HFILL }
+ },
+ { &hf_acn_pdu_flag_v,
+ { "Vector", "acn.pdu.flag_v",
+ FT_BOOLEAN, 8, NULL, ACN_PDU_FLAG_V,
+ "Vector flag", HFILL }
+ },
+ /* PDU Length */
+ { &hf_acn_pdu_length,
+ { "Length", "acn.pdu.flag_d",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "PDU Length", HFILL }
+ },
+ /* Port */
+ { &hf_acn_port,
+ { "Port", "acn.port",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Port", HFILL }
+ },
+ /* Postamble Size */
+ { &hf_acn_postamble_size,
+ { "Size of postamble", "acn.postamble_size",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Postamble size in bytes", HFILL }
+ },
+ /* Protocol ID */
+ { &hf_acn_protocol_id,
+ { "Protocol ID", "acn.protocol_id",
+ FT_UINT32, BASE_DEC, VALS(acn_protocol_id_vals), 0x0,
+ "Protocol ID", HFILL }
+ },
+ /* Reason Code */
+ { &hf_acn_reason_code,
+ { "Reason Code", "acn.reason_code",
+ FT_UINT8, BASE_DEC, VALS(acn_reason_code_vals), 0x0,
+ "Reason Code", HFILL }
+ },
+ /* Reciprocal Channel */
+ { &hf_acn_reciprocal_channel,
+ { "Reciprocal Sequence Number", "acn.acn_reciprocal_channel",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Reciprocal Channel", HFILL }
+ },
+ /* Refuse Code */
+ { &hf_acn_refuse_code,
+ { "Refuse Code", "acn.acn_refuse_code",
+ FT_UINT8, BASE_DEC, VALS(acn_refuse_code_vals), 0x0,
+ "Refuse Code", HFILL }
+ },
+ /* Reliable Sequence Number */
+ { &hf_acn_reliable_sequence_number,
+ { "Reliable Sequence Number", "acn.reliable_sequence_number",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ "Reliable Sequence Number", HFILL }
+ },
+ /* SDT Vector */
+ { &hf_acn_sdt_vector,
+ { "STD Vector", "acn.sdt_vector",
+ FT_UINT8, BASE_DEC, VALS(acn_sdt_vector_vals), 0x0,
+ "STD Vector", HFILL }
+ },
+
+ /* DMX Vector */
+ { &hf_acn_dmx_vector,
+ { "Vector", "acn.dmx_vector",
+ FT_UINT32, BASE_DEC, VALS(acn_dmx_vector_vals), 0x0,
+ "DMX Vector", HFILL }
+ },
+ /* DMX Source Name */
+ { &hf_acn_dmx_source_name,
+ { "Source", "acn.dmx.source_name",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ "DMX Source Name", HFILL }
+ },
+
+ /* DMX priority */
+ { &hf_acn_dmx_priority,
+ { "Priority", "acn.dmx.priority",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "DMX Priority", HFILL }
+ },
+ /* DMX Sequence number */
+ { &hf_acn_dmx_sequence_number,
+ { "Seq No", "acn.dmx.seq_number",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ "DMX Sequence Number", HFILL }
+ },
+ /* DMX Universe */
+ { &hf_acn_dmx_universe,
+ { "Universe", "acn.dmx.universe",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "DMX Universe", HFILL }
+ },
+ /* Session Count */
+ { &hf_acn_session_count,
+ { "Session Count", "acn.session_count",
+ FT_UINT16, BASE_DEC_HEX, NULL, 0x0,
+ "Session Count", HFILL }
+ },
+ /* Total Sequence Number */
+ { &hf_acn_total_sequence_number,
+ { "Total Sequence Number", "acn.total_sequence_number",
+ FT_UINT32, BASE_DEC_HEX, NULL, 0x0,
+ "Total Sequence Number", HFILL }
+ },
+ };
+
+ /* Setup protocol subtree array */
+ static gint *ett[] = {
+ &ett_acn,
+ &ett_acn_channel_owner_info_block,
+ &ett_acn_channel_member_info_block,
+ &ett_acn_channel_parameter,
+ &ett_acn_address,
+ &ett_acn_address_type,
+ &ett_acn_pdu_flags,
+ &ett_acn_dmp_pdu,
+ &ett_acn_sdt_pdu,
+ &ett_acn_sdt_client_pdu,
+ &ett_acn_sdt_base_pdu,
+ &ett_acn_root_pdu,
+ &ett_acn_dmx_address,
+ &ett_acn_dmx_data_pdu,
+ &ett_acn_dmx_pdu
+ };
+
+ module_t *acn_module;
+ if (proto_acn == -1) {
+ proto_acn = proto_register_protocol (
+ "Architecture for Control Networks", /* name */
+ "ACN", /* short name */
+ "acn" /* abbrev */
+ );
+ }
+
+ acn_module = prefs_register_protocol(proto_acn, proto_reg_handoff_acn);
+ proto_register_field_array(proto_acn, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ prefs_register_bool_preference(acn_module, "heuristic_acn",
+ "Decode ACN",
+ "Enable Architecture for Control Networks dissector (ANSI BSR E1.17)",
+ &global_acn_heur);
+
+ prefs_register_bool_preference(acn_module, "dmx_enable",
+ "Streaming DMX",
+ "Enable Streaming DMX extension dissector (ANSI BSR E1.31)",
+ &global_acn_dmx_enable);
+
+ prefs_register_enum_preference(acn_module, "dmx_display_view",
+ "DMX, display format",
+ "Display format",
+ &global_acn_dmx_display_view,
+ dmx_display_view,
+ TRUE);
+
+ prefs_register_bool_preference(acn_module, "dmx_display_zeros",
+ "DMX, display zeros",
+ "Display zeros instead of dots",
+ &global_acn_dmx_display_zeros);
+
+ prefs_register_bool_preference(acn_module, "dmx_display_leading_zeros",
+ "DMX, display leading zeros",
+ "Display leading zeros on levels",
+ &global_acn_dmx_display_leading_zeros);
+}
+
+
+/******************************************************************************/
+/* Register handoff */
+void
+proto_reg_handoff_acn(void)
+{
+ static guint initialized = FALSE;
+ /* static dissector_handle_t acn_handle; */
+
+ if (!initialized) {
+ /* acn_handle = new_create_dissector_handle(dissect_acn, proto_acn); */
+ /* dissector_add("udp.port", 0, acn_handle); */
+ heur_dissector_add("udp", dissect_acn_heur, proto_acn);
+ initialized = TRUE;
+ }
+}
+
diff --git a/epan/dissectors/packet-acn.h b/epan/dissectors/packet-acn.h
new file mode 100755
index 0000000000..44bb903813
--- /dev/null
+++ b/epan/dissectors/packet-acn.h
@@ -0,0 +1,197 @@
+/* packet-acn.h
+ * Routines for ACN packet disassembly
+ *
+ * $Id$
+ *
+ * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
+ * Copyright (c) 2006 by Electronic Theatre Controls, Inc.
+ * Bill Florac <bflorac@etcconnect.com>
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1999 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+ /*
+ Version: 0.0.9 wrf 10-25-2006 Released to Wireshark community
+ Version: 0.0.10 wrf 10-25-2006 small revisions to submit...
+ Version: 0.0.11 wrf 10-29-2006 revisions to submit...
+ */
+
+#ifndef PACKET_ACN_H__
+#define PACKET_ACN_H__
+
+// pdu flags
+#define ACN_PDU_FLAG_L 0x80
+#define ACN_PDU_FLAG_V 0x40
+#define ACN_PDU_FLAG_H 0x20
+#define ACN_PDU_FLAG_D 0x10
+
+#define ACN_DMP_ADT_FLAG_V 0x80
+#define ACN_DMP_ADT_FLAG_R 0x40
+#define ACN_DMP_ADT_FLAG_D 0x30
+#define ACN_DMP_ADT_FLAG_X 0xc0
+#define ACN_DMP_ADT_FLAG_A 0x03
+
+#define ACN_DMP_ADT_V_VIRTUAL 0
+#define ACN_DMP_ADT_V_ACTUAL 1
+
+#define ACN_DMP_ADT_R_ABSOLUTE 0
+#define ACN_DMP_ADT_R_RELATIVE 1
+
+#define ACN_DMP_ADT_D_NS 0
+#define ACN_DMP_ADT_D_RS 1
+#define ACN_DMP_ADT_D_RE 2
+#define ACN_DMP_ADT_D_RM 3
+
+#define ACN_DMP_ADT_A_1 0
+#define ACN_DMP_ADT_A_2 1
+#define ACN_DMP_ADT_A_4 2
+#define ACN_DMP_ADT_A_R 3
+
+#define ACN_PROTOCOL_ID_SDT 1
+#define ACN_PROTOCOL_ID_DMP 2
+#define ACN_PROTOCOL_ID_DMX 3
+
+#define ACN_ADDR_NULL 0
+#define ACN_ADDR_IPV4 1
+#define ACN_ADDR_IPV6 2
+#define ACN_ADDR_IPPORT 3
+
+// STD Messages
+#define ACN_SDT_VECTOR_UNKNOWN 0
+#define ACN_SDT_VECTOR_REL_WRAP 1
+#define ACN_SDT_VECTOR_UNREL_WRAP 2
+#define ACN_SDT_VECTOR_CHANNEL_PARAMS 3
+#define ACN_SDT_VECTOR_JOIN 4
+#define ACN_SDT_VECTOR_JOIN_REFUSE 5
+#define ACN_SDT_VECTOR_JOIN_ACCEPT 6
+#define ACN_SDT_VECTOR_LEAVE 7
+#define ACN_SDT_VECTOR_LEAVING 8
+#define ACN_SDT_VECTOR_CONNECT 9
+#define ACN_SDT_VECTOR_CONNECT_ACCEPT 10
+#define ACN_SDT_VECTOR_CONNECT_REFUSE 11
+#define ACN_SDT_VECTOR_DISCONNECT 12
+#define ACN_SDT_VECTOR_DISCONNECTING 13
+#define ACN_SDT_VECTOR_ACK 14
+#define ACN_SDT_VECTOR_NAK 15
+#define ACN_SDT_VECTOR_GET_SESSION 16
+#define ACN_SDT_VECTOR_SESSIONS 17
+
+#define ACN_REFUSE_CODE_NONSPECIFIC 1
+#define ACN_REFUSE_CODE_ILLEGAL_PARAMS 2
+#define ACN_REFUSE_CODE_LOW_RESOURCES 3
+#define ACN_REFUSE_CODE_ALREADY_MEMBER 4
+#define ACN_REFUSE_CODE_BAD_ADDR_TYPE 5
+#define ACN_REFUSE_CODE_NO_RECIP_CHAN 6
+
+#define ACN_REASON_CODE_NONSPECIFIC 1
+/*#define ACN_REASON_CODE_ 2 */
+/*#define ACN_REASON_CODE_ 3 */
+/*#define ACN_REASON_CODE_ 4 */
+/*#define ACN_REASON_CODE_ 5 */
+#define ACN_REASON_CODE_NO_RECIP_CHAN 6
+#define ACN_REASON_CODE_CHANNEL_EXPIRED 7
+#define ACN_REASON_CODE_LOST_SEQUENCE 8
+#define ACN_REASON_CODE_SATURATED 9
+#define ACN_REASON_CODE_TRANS_ADDR_CHANGING 10
+#define ACN_REASON_CODE_ASKED_TO_LEAVE 11
+#define ACN_REASON_CODE_NO_RECIPIENT 12
+
+#define ACN_DMP_VECTOR_UNKNOWN 0
+#define ACN_DMP_VECTOR_GET_PROPERTY 1
+#define ACN_DMP_VECTOR_SET_PROPERTY 2
+#define ACN_DMP_VECTOR_GET_PROPERTY_REPLY 3
+#define ACN_DMP_VECTOR_EVENT 4
+#define ACN_DMP_VECTOR_MAP_PROPERTY 5
+#define ACN_DMP_VECTOR_UNMAP_PROPERTY 6
+#define ACN_DMP_VECTOR_SUBSCRIBE 7
+#define ACN_DMP_VECTOR_UNSUBSCRIBE 8
+#define ACN_DMP_VECTOR_GET_PROPERTY_FAIL 9
+#define ACN_DMP_VECTOR_SET_PROPERTY_FAIL 10
+#define ACN_DMP_VECTOR_MAP_PROPERTY_FAIL 11
+#define ACN_DMP_VECTOR_SUBSCRIBE_ACCEPT 12
+#define ACN_DMP_VECTOR_SUBSCRIBE_REJECT 13
+#define ACN_DMP_VECTOR_ALLOCATE_MAP 14
+#define ACN_DMP_VECTOR_ALLOCATE_MAP_REPLY 15
+#define ACN_DMP_VECTOR_DEALLOCATE_MAP 16
+
+#define ACN_DMP_REASON_CODE_NONSPECIFIC 1
+#define ACN_DMP_REASON_CODE_NOT_A_PROPERTY 2
+#define ACN_DMP_REASON_CODE_WRITE_ONLY 3
+#define ACN_DMP_REASON_CODE_NOT_WRITABLE 4
+#define ACN_DMP_REASON_CODE_DATA_ERROR 5
+#define ACN_DMP_REASON_CODE_MAPS_NOT_SUPPORTED 6
+#define ACN_DMP_REASON_CODE_SPACE_NOT_AVAILABLE 7
+#define ACN_DMP_REASON_CODE_PROP_NOT_MAPABLE 8
+#define ACN_DMP_REASON_CODE_MAP_NOT_ALLOCATED 9
+#define ACN_DMP_REASON_CODE_SUBSCRIPTION_NOT_SUPPORTED 10
+#define ACN_DMP_REASON_CODE_NO_SUBSCRIPTIONS_SUPPORTED 11
+
+
+
+#define ACN_DMX_VECTOR 2
+
+#define ACN_PREF_DMX_DISPLAY_HEX 0
+#define ACN_PREF_DMX_DISPLAY_DEC 1
+#define ACN_PREF_DMX_DISPLAY_PER 2
+
+
+typedef struct
+{
+ guint32 start;
+ guint32 vector;
+ guint32 header;
+ guint32 data;
+ guint32 data_length;
+} acn_pdu_offsets;
+
+typedef struct
+{
+ union {
+ guint8 byte;
+ struct {
+ guint8 dummy:4;
+ guint8 D:1;
+ guint8 H:1;
+ guint8 V:1;
+ guint8 L:1;
+ };
+ };
+} acn_pdu_flags;
+
+
+typedef struct
+{
+ union {
+ guint8 byte;
+ struct {
+ guint8 A:2; //A1, A0 = Size of Address elements
+ guint8 X:2; //X1, X0 = These bits are reserved and their values shall be set to 0 when encoded. Their values shall be ignored when decoding.
+ guint8 D:2; //D1, D0 = Specify non-range or range address, single data, equal size or mixed size data array
+ guint8 R:1; //R = Specifies whether address is relative to last valid address in packet or not.
+ guint8 V:1; //V = Specifies whether address is a virtual address or not.
+ };
+ };
+ guint32 address; /* or first address */
+ guint32 increment;
+ guint32 count;
+ guint32 size;
+ guint32 data_length;
+} acn_dmp_adt_type;
+
+#endif /* !PACKET_ACN_H */
diff --git a/plugins/acn/AUTHORS b/plugins/acn/AUTHORS
deleted file mode 100644
index 2f7c1251c4..0000000000
--- a/plugins/acn/AUTHORS
+++ /dev/null
@@ -1,3 +0,0 @@
-Author :
-Erwin Rol <erwin@erwinrol.com>
-
diff --git a/plugins/acn/COPYING b/plugins/acn/COPYING
deleted file mode 100644
index d60c31a97a..0000000000
--- a/plugins/acn/COPYING
+++ /dev/null
@@ -1,340 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
diff --git a/plugins/acn/ChangeLog b/plugins/acn/ChangeLog
deleted file mode 100644
index 7511f461eb..0000000000
--- a/plugins/acn/ChangeLog
+++ /dev/null
@@ -1,2 +0,0 @@
-$Id$
-
diff --git a/plugins/acn/INSTALL b/plugins/acn/INSTALL
deleted file mode 100644
index e69de29bb2..0000000000
--- a/plugins/acn/INSTALL
+++ /dev/null
diff --git a/plugins/acn/Makefile.am b/plugins/acn/Makefile.am
deleted file mode 100644
index 0455dbaf02..0000000000
--- a/plugins/acn/Makefile.am
+++ /dev/null
@@ -1,119 +0,0 @@
-# Makefile.am
-# Automake file for ACN plugin
-#
-# $Id$
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-
-INCLUDES = -I$(top_srcdir) -I$(includedir)
-
-include Makefile.common
-
-plugindir = @plugindir@
-
-plugin_LTLIBRARIES = acn.la
-acn_la_SOURCES = \
- plugin.c \
- moduleinfo.h \
- $(DISSECTOR_SRC) \
- $(DISSECTOR_INCLUDES)
-acn_la_LDFLAGS = -module -avoid-version
-acn_la_LIBADD = @PLUGIN_LIBS@
-
-# Libs must be cleared, or else libtool won't create a shared module.
-# If your module needs to be linked against any particular libraries,
-# add them here.
-LIBS =
-
-#
-# Build plugin.c, which contains the plugin version[] string, a
-# function plugin_register() that calls the register routines for all
-# protocols, and a function plugin_reg_handoff() that calls the handoff
-# registration routines for all protocols.
-#
-# We do this by scanning sources. If that turns out to be too slow,
-# maybe we could just require every .o file to have an register routine
-# of a given name (packet-aarp.o -> proto_register_aarp, etc.).
-#
-# Formatting conventions: The name of the proto_register_* routines an
-# proto_reg_handoff_* routines must start in column zero, or must be
-# preceded only by "void " starting in column zero, and must not be
-# inside #if.
-#
-# DISSECTOR_SRC is assumed to have all the files that need to be scanned.
-#
-# For some unknown reason, having a big "for" loop in the Makefile
-# to scan all the files doesn't work with some "make"s; they seem to
-# pass only the first few names in the list to the shell, for some
-# reason.
-#
-# Therefore, we have a script to generate the plugin.c file.
-# The shell script runs slowly, as multiple greps and seds are run
-# for each input file; this is especially slow on Windows. Therefore,
-# if Python is present (as indicated by PYTHON being defined), we run
-# a faster Python script to do that work instead.
-#
-# The first argument is the directory in which the source files live.
-# The second argument is "plugin", to indicate that we should build
-# a plugin.c file for a plugin.
-# All subsequent arguments are the files to scan.
-#
-plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \
- $(top_srcdir)/tools/make-dissector-reg.py
- @if test -n $(PYTHON); then \
- echo Making plugin.c with python ; \
- $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \
- plugin $(DISSECTOR_SRC) ; \
- else \
- echo Making plugin.c with shell script ; \
- $(top_srcdir)/tools/make-dissector-reg $(srcdir) \
- $(plugin_src) plugin $(DISSECTOR_SRC) ; \
- fi
-
-#
-# Currently plugin.c can be included in the distribution because
-# we always build all protocol dissectors. We used to have to check
-# whether or not to build the snmp dissector. If we again need to
-# variably build something, making plugin.c non-portable, uncomment
-# the dist-hook line below.
-#
-# Oh, yuk. We don't want to include "plugin.c" in the distribution, as
-# its contents depend on the configuration, and therefore we want it
-# to be built when the first "make" is done; however, Automake insists
-# on putting *all* source into the distribution.
-#
-# We work around this by having a "dist-hook" rule that deletes
-# "plugin.c", so that "dist" won't pick it up.
-#
-#dist-hook:
-# @rm -f $(distdir)/plugin.c
-
-CLEANFILES = \
- acn \
- *~
-
-MAINTAINERCLEANFILES = \
- Makefile.in \
- plugin.c
-
-EXTRA_DIST = \
- Makefile.common \
- Makefile.nmake
-
diff --git a/plugins/acn/Makefile.common b/plugins/acn/Makefile.common
deleted file mode 100644
index dbf9cf175e..0000000000
--- a/plugins/acn/Makefile.common
+++ /dev/null
@@ -1,35 +0,0 @@
-# Makefile.common for ACN plugin
-# Contains the stuff from Makefile.am and Makefile.nmake that is
-# a) common to both files and
-# b) portable between both files
-#
-# $Id$
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# the name of the plugin
-PLUGIN_NAME = acn
-
-# the dissector sources (without any helpers)
-DISSECTOR_SRC = \
- packet-acn.c
-
-# corresponding headers
-DISSECTOR_INCLUDES = \
- acn.h
diff --git a/plugins/acn/Makefile.nmake b/plugins/acn/Makefile.nmake
deleted file mode 100644
index d6b75a6f84..0000000000
--- a/plugins/acn/Makefile.nmake
+++ /dev/null
@@ -1,82 +0,0 @@
-# Makefile.nmake
-# nmake file for plugin
-#
-# $Id$
-#
-
-include ..\..\config.nmake
-
-############### no need to modify below this line #########
-
-include Makefile.common
-
-CFLAGS=/DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \
- /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
-
-LDFLAGS = /NOLOGO /INCREMENTAL:no /MACHINE:I386 $(LOCAL_LDFLAGS)
-
-!IFDEF ENABLE_LIBWIRESHARK
-LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib
-CFLAGS=/DHAVE_WIN32_LIBWIRESHARK_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS)
-
-DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj)
-
-DISSECTOR_SUPPORT_OBJECTS = $(DISSECTOR_SUPPORT_SRC:.c=.obj)
-
-OBJECTS = $(DISSECTOR_OBJECTS) $(DISSECTOR_SUPPORT_OBJECTS) plugin.obj
-
-$(PLUGIN_NAME).dll $(PLUGIN_NAME).exp $(PLUGIN_NAME).lib : $(OBJECTS) $(LINK_PLUGIN_WITH)
- link -dll /out:$(PLUGIN_NAME).dll $(LDFLAGS) $(OBJECTS) \
- $(LINK_PLUGIN_WITH) $(GLIB_LIBS)
-
-#
-# Build plugin.c, which contains the plugin version[] string, a
-# function plugin_register() that calls the register routines for all
-# protocols, and a function plugin_reg_handoff() that calls the handoff
-# registration routines for all protocols.
-#
-# We do this by scanning sources. If that turns out to be too slow,
-# maybe we could just require every .o file to have an register routine
-# of a given name (packet-aarp.o -> proto_register_aarp, etc.).
-#
-# Formatting conventions: The name of the proto_register_* routines an
-# proto_reg_handoff_* routines must start in column zero, or must be
-# preceded only by "void " starting in column zero, and must not be
-# inside #if.
-#
-# DISSECTOR_SRC is assumed to have all the files that need to be scanned.
-#
-# For some unknown reason, having a big "for" loop in the Makefile
-# to scan all the files doesn't work with some "make"s; they seem to
-# pass only the first few names in the list to the shell, for some
-# reason.
-#
-# Therefore, we have a script to generate the plugin.c file.
-# The shell script runs slowly, as multiple greps and seds are run
-# for each input file; this is especially slow on Windows. Therefore,
-# if Python is present (as indicated by PYTHON being defined), we run
-# a faster Python script to do that work instead.
-#
-# The first argument is the directory in which the source files live.
-# The second argument is "plugin", to indicate that we should build
-# a plugin.c file for a plugin.
-# All subsequent arguments are the files to scan.
-#
-plugin.c: $(DISSECTOR_SRC)
-!IFDEF PYTHON
- @echo Making plugin.c (using python)
- @$(PYTHON) "../../tools/make-dissector-reg.py" . plugin $(DISSECTOR_SRC)
-!ELSE
- @echo Making plugin.c (using sh)
- @$(SH) ../../tools/make-dissector-reg . plugin $(DISSECTOR_SRC)
-!ENDIF
-
-!ENDIF
-
-clean:
- rm -f $(OBJECTS) $(PLUGIN_NAME).dll $(PLUGIN_NAME).exp \
- $(PLUGIN_NAME).lib *.pdb
-
-distclean: clean
-
-maintainer-clean: distclean
diff --git a/plugins/acn/NEWS b/plugins/acn/NEWS
deleted file mode 100644
index e69de29bb2..0000000000
--- a/plugins/acn/NEWS
+++ /dev/null
diff --git a/plugins/acn/acn.h b/plugins/acn/acn.h
deleted file mode 100644
index 47866682a1..0000000000
--- a/plugins/acn/acn.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef __ACN_H__
-#define __ACN_H__
-
-#define ACN_PDU_MIN_SIZE 2
-
-#define ACN_PDU_DES 0xC0
-#define ACN_PDU_DES_SAME 0x00
-#define ACN_PDU_DES_PS 0x40
-#define ACN_PDU_DES_CID 0x80
-#define ACN_PDU_DES_ALL 0xC0
-
-#define ACN_PDU_SRC 0x30
-#define ACN_PDU_SRC_SAME 0x00
-#define ACN_PDU_SRC_PS 0x10
-#define ACN_PDU_SRC_CID 0x20
-#define ACN_PDU_SRC_UM 0x30
-
-#define ACN_PDU_FLAG_P 0x08
-#define ACN_PDU_FLAG_T 0x04
-#define ACN_PDU_FLAG_RES 0x02
-#define ACN_PDU_FLAG_Z 0x01
-
-typedef struct acn_pdu_history_s
-{
- guint8 source_type;
- union {
- guint16 ps;
- guint8 cid[16];
- } source;
-
- guint8 destination_type;
- union {
- guint16 ps;
- guint8 cid[16];
- } destination;
-
- guint16 protocol;
- guint16 type;
-} acn_pdu_history_t;
-
-
-#define ACN_PDU_PROTO_UNKNOWN 0
-#define ACN_PDU_PROTO_SDT 1
-#define ACN_PDU_PROTO_DMP 2
-
-#define ACN_PDU_TYPE_UNKNOWN 0
-
-/* SDT */
-#define ACN_SDT_TYPE_UNKNOWN 0
-#define ACN_SDT_TYPE_RELSEQDATA 1
-#define ACN_SDT_TYPE_UNRELSEQDATA 2
-#define ACN_SDT_TYPE_UNSEQDATA 3
-#define ACN_SDT_TYPE_JOIN 4
-#define ACN_SDT_TYPE_TRANSFER 5
-#define ACN_SDT_TYPE_JOINREF 6
-#define ACN_SDT_TYPE_JOINACC 7
-#define ACN_SDT_TYPE_LEAVEREQ 8
-#define ACN_SDT_TYPE_LEAVE 9
-#define ACN_SDT_TYPE_LEAVING 10
-#define ACN_SDT_TYPE_NAKUPON 11
-#define ACN_SDT_TYPE_NAKUPOFF 12
-#define ACN_SDT_TYPE_NAKDOWNON 13
-#define ACN_SDT_TYPE_NAKDOWNOFF 14
-#define ACN_SDT_TYPE_REPLOSTSEQON 15
-#define ACN_SDT_TYPE_REPLOSTSEQOFF 16
-#define ACN_SDT_TYPE_SESSEXPIRY 17
-#define ACN_SDT_TYPE_MAK 18
-#define ACN_SDT_TYPE_ACK 19
-#define ACN_SDT_TYPE_NAK 20
-#define ACN_SDT_TYPE_SEQLOST 21
-#define ACN_SDT_TYPE_NAKPARAMS 22
-
-
-#define ACN_SDT_ADDR_NULL 0
-#define ACN_SDT_ADDR_IPV4 1
-#define ACN_SDT_ADDR_IPV6 2
-
-/* DMP */
-#define ACN_DMP_TYPE_UNKNOWN 0
-
-#endif /* !__ACN_H__ */
diff --git a/plugins/acn/moduleinfo.h b/plugins/acn/moduleinfo.h
deleted file mode 100644
index d800851877..0000000000
--- a/plugins/acn/moduleinfo.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Included *after* config.h, in order to re-define these macros */
-
-#ifdef PACKAGE
-#undef PACKAGE
-#endif
-
-/* Name of package */
-#define PACKAGE "acn"
-
-
-#ifdef VERSION
-#undef VERSION
-#endif
-
-/* Version number of package */
-#define VERSION "0.0.1"
-
diff --git a/plugins/acn/packet-acn.c b/plugins/acn/packet-acn.c
deleted file mode 100644
index 9fcea45853..0000000000
--- a/plugins/acn/packet-acn.c
+++ /dev/null
@@ -1,1185 +0,0 @@
-/* packet-acn.c
- * Routines for ACN packet disassembly
- *
- * $Id$
- *
- * Copyright (c) 2003 by Erwin Rol <erwin@erwinrol.com>
- *
- * Wireshark - Network traffic analyzer
- * By Gerald Combs <gerald@wireshark.org>
- * Copyright 1999 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/* Include files */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-#include <string.h>
-
-#include <glib.h>
-
-#include <epan/packet.h>
-#include <epan/addr_resolv.h>
-#include <epan/prefs.h>
-#include <epan/strutil.h>
-
-#include "acn.h"
-
-/*
- * See
- *
- * http://www.esta.org/tsp/E1-17inst.htm
- */
-
-static const value_string acn_proto_vals[] = {
- { ACN_PDU_PROTO_UNKNOWN, "Unknown"},
- { ACN_PDU_PROTO_SDT, "SDT" },
- { ACN_PDU_PROTO_DMP, "DMP" },
- { 0, NULL }
-};
-
-static const value_string acn_sdt_type_vals[] = {
- { ACN_SDT_TYPE_UNKNOWN, "Unknown"},
- { ACN_SDT_TYPE_RELSEQDATA, "RELSEQDATA"},
- { ACN_SDT_TYPE_UNRELSEQDATA, "UNRELSEQDATA"},
- { ACN_SDT_TYPE_UNSEQDATA, "UNSEQDATA"},
- { ACN_SDT_TYPE_JOIN, "JOIN"},
- { ACN_SDT_TYPE_TRANSFER, "TRANSFER"},
- { ACN_SDT_TYPE_JOINREF, "JOINREF"},
- { ACN_SDT_TYPE_JOINACC, "JOINACC"},
- { ACN_SDT_TYPE_LEAVEREQ, "LEAVEREQ"},
- { ACN_SDT_TYPE_LEAVE, "LEAVE"},
- { ACN_SDT_TYPE_LEAVING, "LEAVING"},
- { ACN_SDT_TYPE_NAKUPON, "NAKUPON"},
- { ACN_SDT_TYPE_NAKUPOFF, "NAKUPOFF"},
- { ACN_SDT_TYPE_NAKDOWNON, "NAKDOWNON"},
- { ACN_SDT_TYPE_NAKDOWNOFF, "NAKDOWNOFF"},
- { ACN_SDT_TYPE_REPLOSTSEQON, "REPLOSTSEQON"},
- { ACN_SDT_TYPE_REPLOSTSEQOFF, "REPLOSTSEQOFF"},
- { ACN_SDT_TYPE_SESSEXPIRY, "SESEXPIRY"},
- { ACN_SDT_TYPE_MAK, "MAK"},
- { ACN_SDT_TYPE_ACK, "ACK"},
- { ACN_SDT_TYPE_NAK, "NAK"},
- { ACN_SDT_TYPE_SEQLOST, "SEQLOST"},
- { ACN_SDT_TYPE_NAKPARAMS, "NAKPARAMS"},
- { 0, NULL }
-};
-
-static const value_string acn_dmp_type_vals[] = {
- { ACN_DMP_TYPE_UNKNOWN, "Unknown"},
- { 0, NULL }
-};
-
-
-static const value_string acn_sdt_address_type_vals[] = {
- { ACN_SDT_ADDR_NULL, "Unspecified"},
- { ACN_SDT_ADDR_IPV4, "IP version 4"},
- { ACN_SDT_ADDR_IPV6, "IP version 6"},
- { 0, NULL }
-};
-
-static const value_string acn_sdt_des_flag_vals[] = {
- { 0, "Default"},
- { 1, "Protocol Specific"},
- { 2, "CID"},
- { 3, "All"},
- { 0, NULL }
-};
-
-static const value_string acn_sdt_src_flag_vals[] = {
- { 0, "Default"},
- { 1, "Protocol Specific"},
- { 2, "CID"},
- { 3, "Unspecified"},
- { 0, NULL }
-};
-
-
-void proto_reg_handoff_acn(void);
-
-/* Define the acn proto */
-static int proto_acn = -1;
-
-/* Define the tree for acn */
-static int ett_acn = -1;
-
-/* PDU */
-static int hf_acn_pdu = -1;
-
-static int hf_acn_pdu_flags = -1;
-
-static int hf_acn_pdu_des = -1;
-static int hf_acn_pdu_src = -1;
-static int hf_acn_pdu_flag_p = -1;
-static int hf_acn_pdu_flag_t = -1;
-static int hf_acn_pdu_flag_res = -1;
-static int hf_acn_pdu_flag_z = -1;
-static int hf_acn_pdu_length = -1;
-
-/* PDU optional */
-static int hf_acn_pdu_ext_length_16 = -1;
-static int hf_acn_pdu_ext_length_32 = -1;
-static int hf_acn_pdu_source_ps = -1;
-static int hf_acn_pdu_source_cid = -1;
-static int hf_acn_pdu_destination_ps = -1;
-static int hf_acn_pdu_destination_cid = -1;
-static int hf_acn_pdu_protocol = -1;
-static int hf_acn_pdu_type = -1;
-static int hf_acn_pdu_type_sdt = -1;
-static int hf_acn_pdu_type_dmp = -1;
-static int hf_acn_pdu_data = -1;
-static int hf_acn_pdu_unknown_data = -1;
-
-static int hf_acn_pdu_padding = -1;
-
-/* SDT */
-static int hf_acn_sdt_session_nr = -1;
-static int hf_acn_sdt_tot_seq_nr = -1;
-static int hf_acn_sdt_rel_seq_nr = -1;
-static int hf_acn_sdt_unavailable_wrappers = -1;
-static int hf_acn_sdt_refuse_code = -1;
-static int hf_acn_sdt_last_rel_seq = -1;
-static int hf_acn_sdt_new_rel_seq = -1;
-static int hf_acn_sdt_last_rel_wrapper = -1;
-static int hf_acn_sdt_nr_lost_wrappers = -1;
-static int hf_acn_sdt_session_exp_time = -1;
-static int hf_acn_sdt_upstream_address_type = -1;
-static int hf_acn_sdt_upstream_ipv4_address = -1;
-static int hf_acn_sdt_upstream_ipv6_address = -1;
-static int hf_acn_sdt_upstream_port = -1;
-static int hf_acn_sdt_downstream_address_type = -1;
-static int hf_acn_sdt_downstream_ipv4_address = -1;
-static int hf_acn_sdt_downstream_ipv6_address = -1;
-static int hf_acn_sdt_downstream_port = -1;
-
-static int hf_acn_sdt_flags = -1;
-static int hf_acn_sdt_flag_u = -1;
-static int hf_acn_sdt_flag_d = -1;
-static int hf_acn_sdt_flag_l = -1;
-
-static int hf_acn_sdt_mid = -1;
-static int hf_acn_sdt_nak_holdoff_interval = -1;
-static int hf_acn_sdt_nak_modulus = -1;
-static int hf_acn_sdt_max_nak_wait_time = -1;
-static int hf_acn_sdt_leader_cid = -1;
-static int hf_acn_sdt_member_cid = -1;
-static int hf_acn_sdt_ack_threshold = -1;
-
-/*
- * Here are the global variables associated with the preferences
- * for acn
- */
-
-static guint global_udp_port_acn = 0;
-static guint udp_port_acn = 0;
-
-/* A static handle for the ip dissector */
-static dissector_handle_t ip_handle;
-
-static guint dissect_pdu(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size);
-static guint dissect_sdt(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size);
-static guint dissect_dmp(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size);
-
-static guint
-dissect_sdt(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size)
-{
- proto_tree *flags_tree, *flags_item;
- guint start_offset = offset;
- acn_pdu_history_t hist;
- guint size = 0;
- guint flags;
- guint type;
- guint count;
-
- hist = *parent_hist;
-
- switch( parent_hist->type )
- {
- case ACN_SDT_TYPE_UNKNOWN:
- break;
-
- case ACN_SDT_TYPE_RELSEQDATA:
- case ACN_SDT_TYPE_UNRELSEQDATA:
- proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_tot_seq_nr, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_rel_seq_nr, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_unavailable_wrappers, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- max_size = max_size - (offset - start_offset);
- while( max_size >= ACN_PDU_MIN_SIZE) {
- size = dissect_pdu( tvb, offset, tree, &hist, max_size);
- offset += size;
- max_size -= size;
- }
-
- size = offset - start_offset;
-
- break;
-
- case ACN_SDT_TYPE_UNSEQDATA:
- proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- max_size = max_size - (offset - start_offset);
- while( max_size >= ACN_PDU_MIN_SIZE) {
- size = dissect_pdu( tvb, offset, tree, &hist, max_size);
- offset += size;
- max_size -= size;
- }
-
- size = offset - start_offset;
-
- break;
-
- case ACN_SDT_TYPE_JOIN:
- proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- flags = tvb_get_guint8(tvb, offset);
- flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
- offset, 1, flags);
-
- flags_tree=proto_item_add_subtree(flags_item, ett_acn);
- proto_tree_add_item(flags_tree, hf_acn_sdt_flag_u, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_sdt_flag_d, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_sdt_flag_l, tvb, offset, 1, FALSE);
- offset += 1;
-
- type = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_acn_sdt_upstream_address_type, tvb,
- offset, 1, FALSE);
- offset += 1;
-
- switch( type )
- {
- default:
- case ACN_SDT_ADDR_NULL:
- break;
-
- case ACN_SDT_ADDR_IPV4:
- proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv4_address, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- break;
-
- case ACN_SDT_ADDR_IPV6:
- proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv6_address, tvb,
- offset, 16, FALSE);
- offset += 16;
-
- break;
- }
-
- flags = tvb_get_guint8(tvb, offset);
- flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
- offset, 1, flags);
-
- flags_tree=proto_item_add_subtree(flags_item, ett_acn);
- offset += 1;
-
- type = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_acn_sdt_downstream_address_type, tvb,
- offset, 1, FALSE);
- offset += 1;
-
- switch( type )
- {
- default:
- case ACN_SDT_ADDR_NULL:
- break;
-
- case ACN_SDT_ADDR_IPV4:
- proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv4_address, tvb,
- offset, 4, FALSE);
- offset += 4;
-
-
- break;
-
- case ACN_SDT_ADDR_IPV6:
- proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv6_address, tvb,
- offset, 16, FALSE);
- offset += 16;
-
- break;
- }
-
-
- proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_tot_seq_nr, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_rel_seq_nr, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_session_exp_time, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_nak_holdoff_interval, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_nak_modulus, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_max_nak_wait_time, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- size = offset - start_offset;
-
- break;
-
- case ACN_SDT_TYPE_TRANSFER:
- proto_tree_add_item(tree, hf_acn_sdt_leader_cid, tvb,
- offset, 16, FALSE);
- offset += 16;
-
- proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- flags = tvb_get_guint8(tvb, offset);
- flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
- offset, 1, flags);
-
- flags_tree=proto_item_add_subtree(flags_item, ett_acn);
- proto_tree_add_item(flags_tree, hf_acn_sdt_flag_u, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_sdt_flag_d, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_sdt_flag_l, tvb, offset, 1, FALSE);
- offset += 1;
-
- type = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_acn_sdt_upstream_address_type, tvb,
- offset, 1, FALSE);
- offset += 1;
-
- switch( type )
- {
- default:
- case ACN_SDT_ADDR_NULL:
- break;
-
- case ACN_SDT_ADDR_IPV4:
- proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv4_address, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- break;
-
- case ACN_SDT_ADDR_IPV6:
- proto_tree_add_item(tree, hf_acn_sdt_upstream_ipv6_address, tvb,
- offset, 16, FALSE);
- offset += 16;
-
- proto_tree_add_item(tree, hf_acn_sdt_upstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
- break;
- }
-
- flags = tvb_get_guint8(tvb, offset);
- flags_item = proto_tree_add_uint(tree, hf_acn_sdt_flags, tvb,
- offset, 1, flags);
-
- flags_tree=proto_item_add_subtree(flags_item, ett_acn);
- offset += 1;
-
- type = tvb_get_guint8(tvb, offset);
- proto_tree_add_item(tree, hf_acn_sdt_downstream_address_type, tvb,
- offset, 1, FALSE);
- offset += 1;
-
- switch( type )
- {
- default:
- case ACN_SDT_ADDR_NULL:
- break;
-
- case ACN_SDT_ADDR_IPV4:
- proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv4_address, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- break;
-
- case ACN_SDT_ADDR_IPV6:
- proto_tree_add_item(tree, hf_acn_sdt_downstream_ipv6_address, tvb,
- offset, 16, FALSE);
- offset += 16;
-
- proto_tree_add_item(tree, hf_acn_sdt_downstream_port, tvb,
- offset, 2, FALSE);
- offset += 2;
- break;
- }
-
-
- proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_tot_seq_nr, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_rel_seq_nr, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_session_exp_time, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_nak_holdoff_interval, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_nak_modulus, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_max_nak_wait_time, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- /* CID+MID list */
- count = (max_size - (offset - start_offset)) / 18;
- while( count > 0) {
- proto_tree_add_item(tree, hf_acn_sdt_member_cid, tvb,
- offset, 16, FALSE);
- offset += 16;
-
- proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- count--;
- }
-
- size = offset - start_offset;
-
- break;
-
- case ACN_SDT_TYPE_JOINREF:
- proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_refuse_code, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- size = offset - start_offset;
- break;
-
- case ACN_SDT_TYPE_JOINACC:
- case ACN_SDT_TYPE_ACK:
- proto_tree_add_item(tree, hf_acn_sdt_last_rel_seq, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- size = offset - start_offset;
- break;
-
- case ACN_SDT_TYPE_LEAVING:
- proto_tree_add_item(tree, hf_acn_sdt_last_rel_wrapper, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- size = offset - start_offset;
- break;
-
-
- case ACN_SDT_TYPE_SESSEXPIRY:
- proto_tree_add_item(tree, hf_acn_sdt_session_exp_time, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- size = offset - start_offset;
- break;
-
- case ACN_SDT_TYPE_MAK:
- proto_tree_add_item(tree, hf_acn_sdt_ack_threshold, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- count = (max_size - (offset - start_offset)) / 2;
- while( count > 0) {
- proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- count--;
- }
-
- size = offset - start_offset;
- break;
-
- case ACN_SDT_TYPE_NAK:
- proto_tree_add_item(tree, hf_acn_sdt_session_nr, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_mid, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_last_rel_seq, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_nr_lost_wrappers, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- size = offset - start_offset;
- break;
-
- case ACN_SDT_TYPE_SEQLOST:
- proto_tree_add_item(tree, hf_acn_sdt_last_rel_seq, tvb,
- offset, 4, FALSE);
- offset += 4;
-
- proto_tree_add_item(tree, hf_acn_sdt_new_rel_seq, tvb,
- offset, 4, FALSE);
- offset += 4;
- size = offset - start_offset;
- break;
-
- case ACN_SDT_TYPE_NAKPARAMS:
- proto_tree_add_item(tree, hf_acn_sdt_nak_holdoff_interval, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_nak_modulus, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- proto_tree_add_item(tree, hf_acn_sdt_max_nak_wait_time, tvb,
- offset, 2, FALSE);
- offset += 2;
-
- size = offset - start_offset;
- break;
-
- case ACN_SDT_TYPE_LEAVEREQ:
- case ACN_SDT_TYPE_LEAVE:
- case ACN_SDT_TYPE_NAKUPON:
- case ACN_SDT_TYPE_NAKUPOFF:
- case ACN_SDT_TYPE_NAKDOWNON:
- case ACN_SDT_TYPE_NAKDOWNOFF:
- case ACN_SDT_TYPE_REPLOSTSEQON:
- case ACN_SDT_TYPE_REPLOSTSEQOFF:
- /* no data */
- size = offset - start_offset;
- break;
-
- default:
- break;
- }
-
- return size;
-}
-
-static guint
-dissect_dmp(tvbuff_t *tvb _U_, guint offset _U_, proto_tree *tree _U_, acn_pdu_history_t* parent_hist _U_, guint max_size _U_)
-{
- return 0;
-}
-
-static guint
-dissect_pdu(tvbuff_t *tvb, guint offset, proto_tree *tree, acn_pdu_history_t* parent_hist, guint max_size)
-{
- guint size,data_size;
- guint8 flags;
- guint src,des;
- proto_tree *ti, *si, *flags_tree, *flags_item, *data_tree, *data_item;
- guint start_offset = offset;
- acn_pdu_history_t hist = *parent_hist;
-
-
- ti = proto_tree_add_item(tree,
- hf_acn_pdu,
- tvb,
- offset,
- 0,
- FALSE);
-
- si = proto_item_add_subtree(ti, ett_acn);
-
- flags = tvb_get_guint8(tvb, offset);
- flags_item = proto_tree_add_uint(si, hf_acn_pdu_flags, tvb,
- offset, 1, flags);
-
- flags_tree=proto_item_add_subtree(flags_item, ett_acn);
-
- proto_tree_add_item(flags_tree, hf_acn_pdu_des, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_pdu_src, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_pdu_flag_p, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_pdu_flag_t, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_pdu_flag_res, tvb, offset, 1, FALSE);
- proto_tree_add_item(flags_tree, hf_acn_pdu_flag_z, tvb, offset, 1, FALSE);
-
- offset += 1;
-
- size = tvb_get_guint8(tvb, offset);
- proto_tree_add_uint(si, hf_acn_pdu_length, tvb,
- offset, 1, size);
- offset += 1;
-
-
- if( size == 0 ){
- size = tvb_get_ntohs(tvb, offset);
- proto_tree_add_uint(si, hf_acn_pdu_ext_length_16, tvb,
- offset, 2, size);
- offset += 2;
- } else if( size == 1 ){
- size = tvb_get_ntohl( tvb, offset);
- proto_tree_add_uint(si, hf_acn_pdu_ext_length_32, tvb,
- offset, 4, size);
- offset += 4;
- }
-
- if(size > max_size )
- size = max_size;
-
- switch( flags & ACN_PDU_DES )
- {
- case ACN_PDU_DES_SAME:
- break;
-
- case ACN_PDU_DES_PS:
- hist.destination_type = ACN_PDU_DES_PS;
- des = tvb_get_ntohs(tvb, offset);
- hist.destination.ps = des;
- proto_tree_add_uint(si, hf_acn_pdu_destination_ps, tvb,
- offset, 2, des);
- offset += 2;
- break;
-
- case ACN_PDU_DES_CID:
- hist.destination_type = ACN_PDU_DES_CID;
- tvb_memcpy(tvb, hist.destination.cid, offset, 16 );
- proto_tree_add_item(si, hf_acn_pdu_destination_cid, tvb,
- offset, 16, FALSE);
- offset += 16;
- break;
-
- case ACN_PDU_DES_ALL:
- hist.destination_type = ACN_PDU_DES_ALL;
- break;
- }
-
-
- switch( flags & ACN_PDU_SRC )
- {
- case ACN_PDU_SRC_SAME:
- break;
-
- case ACN_PDU_SRC_PS:
- hist.source_type = ACN_PDU_SRC_PS;
- src = tvb_get_ntohs(tvb, offset);
- hist.source.ps = src;
- proto_tree_add_uint(si, hf_acn_pdu_source_ps, tvb,
- offset, 2, src);
- offset += 2;
- break;
-
- case ACN_PDU_SRC_CID:
- hist.source_type = ACN_PDU_SRC_CID;
- tvb_memcpy(tvb, hist.source.cid, offset, 16 );
- proto_tree_add_item(si, hf_acn_pdu_source_cid, tvb,
- offset, 16, FALSE);
- offset += 16;
- break;
-
- case ACN_PDU_SRC_UM:
- hist.source_type = ACN_PDU_SRC_UM;
- break;
- }
-
-
-
- if( flags & ACN_PDU_FLAG_P )
- {
- hist.protocol = tvb_get_ntohs( tvb, offset );
- proto_tree_add_item(si, hf_acn_pdu_protocol, tvb,
- offset, 2, FALSE );
- offset += 2;
- }
-
- if( flags & ACN_PDU_FLAG_T )
- {
- hist.type = tvb_get_ntohs( tvb, offset );
-
- switch( hist.protocol ) {
- case ACN_PDU_PROTO_SDT:
- proto_tree_add_item(si, hf_acn_pdu_type_sdt, tvb,
- offset, 2, FALSE );
- break;
-
- case ACN_PDU_PROTO_DMP:
- proto_tree_add_item(si, hf_acn_pdu_type_dmp, tvb,
- offset, 2, FALSE );
- break;
-
- default:
- proto_tree_add_item(si, hf_acn_pdu_type, tvb,
- offset, 2, FALSE );
- break;
-
-
-
- }
-
- offset += 2;
- }
-
- if( flags & ACN_PDU_FLAG_Z )
- {
- data_size = size - (offset - start_offset);
-
-
- data_item = proto_tree_add_item(si, hf_acn_pdu_data, tvb,
- offset, data_size, FALSE);
-
- data_tree=proto_item_add_subtree(data_item, ett_acn);
-
-
- switch( hist.protocol ) {
- case ACN_PDU_PROTO_SDT:
- dissect_sdt( tvb, offset, data_tree, &hist, data_size);
- break;
-
- case ACN_PDU_PROTO_DMP:
- dissect_dmp( tvb, offset, data_tree, &hist, data_size);
- break;
-
- default:
- proto_tree_add_item(si, hf_acn_pdu_unknown_data, tvb,
- offset, data_size, FALSE );
- break;
- }
-
- offset += data_size;
- }
-
- if( size & 0x00000001 )
- {
-
- proto_tree_add_item(si, hf_acn_pdu_padding, tvb,
- offset, 1, TRUE );
-
- size += 1;
- offset += 1;
- }
-
- proto_item_set_len(si, size);
-
- return size;
-}
-
-static void
-dissect_acn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
- gint offset = 0;
- guint size,max_size;
- acn_pdu_history_t hist;
-
- /* Set the protocol column */
- if(check_col(pinfo->cinfo,COL_PROTOCOL)){
- col_set_str(pinfo->cinfo,COL_PROTOCOL,"ACN");
- }
-
- /* Clear out stuff in the info column */
- if(check_col(pinfo->cinfo,COL_INFO)){
- col_clear(pinfo->cinfo,COL_INFO);
- }
-
- if (tree)
- {
- /* history default values */
- hist.destination_type = ACN_PDU_DES_ALL;
- hist.source_type = ACN_PDU_SRC_UM;
- hist.protocol = ACN_PDU_PROTO_UNKNOWN;
- hist.type = ACN_PDU_TYPE_UNKNOWN;
-
- max_size = tvb_reported_length_remaining(tvb, offset);
-
- while( max_size >= ACN_PDU_MIN_SIZE) {
- size = dissect_pdu( tvb, offset, tree, &hist, max_size);
- offset += size;
- max_size -= size;
- }
- }
-}
-
-void
-proto_register_acn(void) {
- static hf_register_info hf[] = {
- /* PDU */
- { &hf_acn_pdu,
- { "ACN PDU", "acn.pdu",
- FT_NONE, BASE_NONE, NULL, 0,
- "ACN PDU", HFILL }},
-
- { &hf_acn_pdu_flags,
- { "Flags","acn.pdu.flags",
- FT_UINT8, BASE_HEX, NULL, 0x0,
- "Flags", HFILL }},
-
- { &hf_acn_pdu_des,
- { "des","acn.pdu.des",
- FT_UINT8, BASE_HEX, VALS( acn_sdt_des_flag_vals ), 0xC0,
- "des", HFILL }},
-
- { &hf_acn_pdu_src,
- { "src","acn.pdu.src",
- FT_UINT8, BASE_HEX, VALS( acn_sdt_src_flag_vals ), 0x30,
- "src", HFILL }},
-
- { &hf_acn_pdu_flag_p,
- { "P","acn.pdu.flag_p",
- FT_UINT8, BASE_HEX, NULL, 0x08,
- "P", HFILL }},
-
- { &hf_acn_pdu_flag_t,
- { "T","acn.pdu.flag_t",
- FT_UINT8, BASE_HEX, NULL, 0x04,
- "T", HFILL }},
-
- { &hf_acn_pdu_flag_z,
- { "Z","acn.pdu.flag_z",
- FT_UINT8, BASE_HEX, NULL, 0x01,
- "Z", HFILL }},
-
- { &hf_acn_pdu_flag_res,
- { "res","acn.pdu.flag_res",
- FT_UINT8, BASE_HEX, NULL, 0x02,
- "res", HFILL }},
-
- { &hf_acn_pdu_length,
- { "Length","acn.pdu.length",
- FT_UINT8, BASE_DEC, NULL, 0x0,
- "Length", HFILL }},
-
- { &hf_acn_pdu_ext_length_16,
- { "Ext Length 16bit","acn.pdu.ext_length_16",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "Ext Length 16bit", HFILL }},
-
- { &hf_acn_pdu_ext_length_32,
- { "Ext Length 32bit","acn.pdu.ext_length_32",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "Ext Length 32bit", HFILL }},
-
- { &hf_acn_pdu_source_ps,
- { "Source PS","acn.pdu.source_ps",
- FT_UINT16, BASE_HEX, NULL, 0x0,
- "Source PS", HFILL }},
-
- { &hf_acn_pdu_source_cid,
- { "Source CID","acn.pdu.source_cid",
- FT_BYTES, BASE_HEX, NULL, 0x0,
- "Source CID", HFILL }},
-
- { &hf_acn_pdu_destination_ps,
- { "Destination PS","acn.pdu.destination_ps",
- FT_UINT16, BASE_HEX, NULL, 0x0,
- "Destination PS", HFILL }},
-
- { &hf_acn_pdu_destination_cid,
- { "Destination CID","acn.pdu.destination_cid",
- FT_BYTES, BASE_HEX, NULL, 0x0,
- "Destination CID", HFILL }},
-
- { &hf_acn_pdu_protocol,
- { "Protocol","acn.pdu.protocol",
- FT_UINT16, BASE_HEX, VALS(acn_proto_vals), 0x0,
- "Protocol", HFILL }},
-
- { &hf_acn_pdu_type,
- { "Type","acn.pdu.type",
- FT_UINT16, BASE_HEX, NULL, 0x0,
- "Type", HFILL }},
-
- { &hf_acn_pdu_type_sdt,
- { "SDT Type","acn.pdu.type_sdt",
- FT_UINT16, BASE_HEX, VALS(acn_sdt_type_vals), 0x0,
- "SDT Type", HFILL }},
-
- { &hf_acn_pdu_type_dmp,
- { "DMP Type","acn.pdu.type_dmp",
- FT_UINT16, BASE_HEX, VALS(acn_dmp_type_vals), 0x0,
- "DMP Type", HFILL }},
-
- { &hf_acn_pdu_data,
- { "Data","acn.pdu.data",
- FT_NONE, BASE_HEX, NULL, 0x0,
- "Data", HFILL }},
-
- { &hf_acn_pdu_unknown_data,
- { "Unknown Data","acn.pdu.unknown_data",
- FT_BYTES, BASE_HEX, NULL, 0x0,
- "Unknown Data", HFILL }},
-
- { &hf_acn_pdu_padding,
- { "Padding","acn.pdu.padding",
- FT_UINT8, BASE_DEC, NULL, 0x0,
- "Padding", HFILL }},
-
- { &hf_acn_sdt_session_nr,
- { "SDT Session Nr","acn.sdt.session_nr",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT Session Nr", HFILL }},
-
- { &hf_acn_sdt_tot_seq_nr,
- { "SDT Total Sequence Nr","acn.sdt.tot_seq_nr",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "SDT Total Sequence Nr", HFILL }},
-
- { &hf_acn_sdt_rel_seq_nr,
- { "SDT Rel Seq Nr","acn.sdt.rel_seq_nr",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "SDT Rel Sequence Nr", HFILL }},
-
- { &hf_acn_sdt_unavailable_wrappers,
- { "SDT Unavailable Wrappers","acn.sdt.unavailable_wrappers",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "SDT Unavailable Wrappers", HFILL }},
-
- { &hf_acn_sdt_refuse_code,
- { "SDT Refuse code","acn.sdt.refuse_code",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT Refuse Code", HFILL }},
-
- { &hf_acn_sdt_last_rel_seq,
- { "SDT Last reliable seq nr","acn.sdt.last_rel_seq",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "SDT Last reliable seq nr", HFILL }},
-
- { &hf_acn_sdt_new_rel_seq,
- { "SDT reliable seq nr to continue with","acn.sdt.new_rel_seq",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "SDT reliable seq nr to continue with", HFILL }},
-
- { &hf_acn_sdt_last_rel_wrapper,
- { "SDT Last reliable Wrapper","acn.sdt.last_rel_wrapper",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "SDT Last reliable Wrapper", HFILL }},
-
- { &hf_acn_sdt_nr_lost_wrappers,
- { "SDT Nr of lost Wrappers","acn.sdt.nr_lost_wrappers",
- FT_UINT32, BASE_DEC, NULL, 0x0,
- "SDT Nr of lost Wrappers", HFILL }},
-
- { &hf_acn_sdt_session_exp_time,
- { "SDT Session expire time","acn.sdt.session_exp_time",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT Session expire time", HFILL }},
-
- { &hf_acn_sdt_flags,
- { "SDT Flags","acn.sdt.flags",
- FT_UINT8, BASE_HEX, NULL, 0x0,
- "SDT Flags", HFILL }},
-
- { &hf_acn_sdt_flag_u,
- { "U","acn.sdt.flag_u",
- FT_UINT8, BASE_HEX, NULL, 0x80,
- "U", HFILL }},
-
- { &hf_acn_sdt_flag_d,
- { "D","acn.sdt.flag_d",
- FT_UINT8, BASE_HEX, NULL, 0x40,
- "D", HFILL }},
-
- { &hf_acn_sdt_flag_l,
- { "L","acn.sdt.flag_l",
- FT_UINT8, BASE_HEX, NULL, 0x20,
- "L", HFILL }},
-
- { &hf_acn_sdt_upstream_address_type,
- { "SDT Upstream address type","acn.sdt.upstream_address_type",
- FT_UINT8, BASE_HEX, VALS(acn_sdt_address_type_vals), 0x0,
- "SDT Upstream address type", HFILL }},
-
- { &hf_acn_sdt_downstream_address_type,
- { "SDT Downstream address type","acn.sdt.downstream_address_type",
- FT_UINT8, BASE_HEX, VALS(acn_sdt_address_type_vals), 0x0,
- "SDT Downstream address type", HFILL }},
-
- { &hf_acn_sdt_upstream_port,
- { "SDT Upstream Port","acn.sdt.upstream_port",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT Upstream Port", HFILL }},
-
- { &hf_acn_sdt_downstream_port,
- { "SDT Donwstream Port","acn.sdt.downstream_port",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT Downstream Port", HFILL }},
-
- { &hf_acn_sdt_downstream_ipv4_address,
- { "SDT Donwstream IPv4 Address","acn.sdt.downstream_ipv4_address",
- FT_IPv4, BASE_DEC, NULL, 0x0,
- "SDT Downstream IPv4 Address", HFILL }},
-
- { &hf_acn_sdt_upstream_ipv4_address,
- { "SDT Upstream IPv4 Address","acn.sdt.upstream_ipv4_address",
- FT_IPv4, BASE_DEC, NULL, 0x0,
- "SDT Upstream IPv4 Address", HFILL }},
-
- { &hf_acn_sdt_downstream_ipv6_address,
- { "SDT Donwstream IPv6 Address","acn.sdt.downstream_ipv6_address",
- FT_IPv6, BASE_DEC, NULL, 0x0,
- "SDT Downstream IPv6 Address", HFILL }},
-
- { &hf_acn_sdt_upstream_ipv6_address,
- { "SDT Upstream IPv6 Address","acn.sdt.upstream_ipv6_address",
- FT_IPv6, BASE_DEC, NULL, 0x0,
- "SDT Upstream IPv6 Address", HFILL }},
-
- { &hf_acn_sdt_mid,
- { "SDT Member ID","acn.sdt.mid",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT Member ID", HFILL }},
-
- { &hf_acn_sdt_nak_holdoff_interval,
- { "SDT NAK holdoff interval","acn.sdt.nak_holdoff_interval",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT NAK holdoff interval", HFILL }},
-
- { &hf_acn_sdt_nak_modulus,
- { "SDT NAK modulus","acn.sdt.nak_modulus",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT NAK modulus", HFILL }},
-
- { &hf_acn_sdt_max_nak_wait_time,
- { "SDT Max. NAK wait time","acn.sdt.max_nak_wait_time",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT Max. NAK wait time ", HFILL }},
-
- { &hf_acn_sdt_ack_threshold,
- { "SDT ACK threshold","acn.sdt.ack_threshold",
- FT_UINT16, BASE_DEC, NULL, 0x0,
- "SDT ACK threshold", HFILL }},
-
- { &hf_acn_sdt_member_cid,
- { "SDT Memebr CID","acn.sdt.member_cid",
- FT_BYTES, BASE_HEX, NULL, 0x0,
- "SDT Member CID", HFILL }},
-
- { &hf_acn_sdt_leader_cid,
- { "SDT Leader CID","acn.sdt.leader_cid",
- FT_BYTES, BASE_HEX, NULL, 0x0,
- "SDT Leader CID", HFILL }}
-
- };
-
- static gint *ett[] = {
- &ett_acn,
- };
-
- module_t *acn_module;
-
- proto_acn = proto_register_protocol("ACN",
- "ACN","acn");
- proto_register_field_array(proto_acn,hf,array_length(hf));
- proto_register_subtree_array(ett,array_length(ett));
-
- acn_module = prefs_register_protocol(proto_acn,
- proto_reg_handoff_acn);
-#if 0
- prefs_register_uint_preference(artnet_module, "udp_port",
- "ARTNET UDP Port",
- "The UDP port on which "
- "Art-Net "
- "packets will be sent",
- 10,&global_udp_port_artnet);
-#endif
-}
-
-/* The registration hand-off routing */
-
-void
-proto_reg_handoff_acn(void) {
- static int acn_initialized = FALSE;
- static dissector_handle_t acn_handle;
-
- ip_handle = find_dissector("ip");
-
- if(!acn_initialized) {
- acn_handle = create_dissector_handle(dissect_acn,proto_acn);
- acn_initialized = TRUE;
- } else {
- dissector_delete("udp.port",udp_port_acn,acn_handle);
- }
-
- udp_port_acn = global_udp_port_acn;
-
- dissector_add("udp.port",global_udp_port_acn,acn_handle);
-}