summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-01-20 10:50:44 -0500
committerMichael Mann <mmann78@netscape.net>2016-01-22 12:37:15 +0000
commitfc511c3f11d1e744adbf8fff6b1e46adc9776c94 (patch)
tree162df846828d5c27edd7fac082077099355bd05b
parentdb111c4d9063bf145778ef41b139a6b9fdc0114c (diff)
downloadwireshark-fc511c3f11d1e744adbf8fff6b1e46adc9776c94.tar.gz
CIP: Add support for Get Attributes All
Get Attributes All is a predefined list of existing attribute IDs for a given class. Add a new index for each attribute for their place in GetAttributesAll response. Then a hash table of classes for existing attributes are created to handle the GetAttributesAll service. Added more TCP/IP object attributes since more have been added to the spec. Moved TCP/IP object attributes all to ENIP dissector. Bug: 11996 Change-Id: I7f50c9aadf04efdb17ef31f39e6a991c0a84bef2 Reviewed-on: https://code.wireshark.org/review/13186 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/dissectors/packet-cip.c331
-rw-r--r--epan/dissectors/packet-cip.h35
-rw-r--r--epan/dissectors/packet-cipsafety.c139
-rw-r--r--epan/dissectors/packet-cipsafety.h2
-rw-r--r--epan/dissectors/packet-enip.c187
-rw-r--r--epan/dissectors/packet-enip.h2
6 files changed, 473 insertions, 223 deletions
diff --git a/epan/dissectors/packet-cip.c b/epan/dissectors/packet-cip.c
index 2eedd44926..6bee51db8a 100644
--- a/epan/dissectors/packet-cip.c
+++ b/epan/dissectors/packet-cip.c
@@ -70,15 +70,15 @@ static int proto_cip_class_cco = -1;
static int proto_enip = -1;
static int proto_modbus = -1;
-static int hf_attr_class_revision = -1;
-static int hf_attr_class_max_instance = -1;
-static int hf_attr_class_num_instance = -1;
-static int hf_attr_class_opt_attr_num = -1;
-static int hf_attr_class_attr_num = -1;
-static int hf_attr_class_opt_service_num = -1;
-static int hf_attr_class_service_code = -1;
-static int hf_attr_class_num_class_attr = -1;
-static int hf_attr_class_num_inst_attr = -1;
+int hf_attr_class_revision = -1;
+int hf_attr_class_max_instance = -1;
+int hf_attr_class_num_instance = -1;
+int hf_attr_class_opt_attr_num = -1;
+int hf_attr_class_attr_num = -1;
+int hf_attr_class_opt_service_num = -1;
+int hf_attr_class_service_code = -1;
+int hf_attr_class_num_class_attr = -1;
+int hf_attr_class_num_inst_attr = -1;
static int hf_cip_data = -1;
static int hf_cip_service = -1;
static int hf_cip_service_code = -1;
@@ -314,6 +314,7 @@ static int hf_cip_reserved8 = -1;
static int hf_cip_reserved24 = -1;
static int hf_cip_pad8 = -1;
+static int hf_cip_sc_get_attr_all_attr_item = -1;
static int hf_cip_sc_get_attr_list_attr_count = -1;
static int hf_cip_sc_get_attr_list_attr_item = -1;
static int hf_cip_sc_get_attr_list_attr_status = -1;
@@ -487,6 +488,7 @@ static gint ett_status_item = -1;
static gint ett_add_status_item = -1;
static gint ett_cmd_data = -1;
+static gint ett_cip_get_attributes_all_item = -1;
static gint ett_cip_get_attribute_list = -1;
static gint ett_cip_get_attribute_list_item = -1;
static gint ett_cip_set_attribute_list = -1;
@@ -2530,7 +2532,7 @@ static const value_string cip_class_names_vals[] = {
{ 0xF3, "Connection Configuration Object" },
{ 0xF4, "Port Object" },
{ 0xF5, "TCP/IP Interface Object" },
- { 0xF6, "EtherNet Link Object" },
+ { 0xF6, "Ethernet Link Object" },
{ 0xF7, "CompoNet Object" },
{ 0xF8, "CompoNet Repeater Object" },
@@ -3040,7 +3042,7 @@ static int dissect_time_sync_sys_time_and_offset(packet_info *pinfo, proto_tree
return 16;
}
-static int dissect_optional_attr_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
+int dissect_optional_attr_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
int offset, int total_len)
{
guint32 i;
@@ -3062,7 +3064,7 @@ static int dissect_optional_attr_list(packet_info *pinfo, proto_tree *tree, prot
return 2 + num_attr * 2;
}
-static int dissect_optional_service_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
+int dissect_optional_service_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
int offset, int total_len)
{
guint32 i;
@@ -3087,61 +3089,96 @@ static int dissect_optional_service_list(packet_info *pinfo, proto_tree *tree, p
static attribute_info_t cip_attribute_vals[] = {
- /* Identity Object */
- {0x01, FALSE, 1, "Vendor ID", cip_uint, &hf_id_vendor_id, NULL},
- {0x01, FALSE, 2, "Device Type", cip_uint, &hf_id_device_type, NULL},
- {0x01, FALSE, 3, "Product Code", cip_uint, &hf_id_produce_code, NULL},
- {0x01, FALSE, 4, "Revision", cip_dissector_func, NULL, dissect_id_revision},
- {0x01, FALSE, 5, "Status", cip_word, &hf_id_status, NULL},
- {0x01, FALSE, 6, "Serial Number", cip_udint, &hf_id_serial_number, NULL},
- {0x01, FALSE, 7, "Product Name", cip_short_string, &hf_id_product_name, NULL},
-
- /* Message Router Object */
- {0x02, FALSE, 1, "Object List", cip_dissector_func, NULL, dissect_msg_rout_num_classes},
- {0x02, FALSE, 2, "Number Available", cip_uint, &hf_msg_rout_num_available, NULL},
- {0x02, FALSE, 3, "Number Active", cip_uint, &hf_msg_rout_num_active, NULL},
- {0x02, FALSE, 4, "Active Connections", cip_uint_array, &hf_msg_rout_active_connections, NULL},
-
- /* Connection Manager Object */
- {0x06, FALSE, 1, "Open Requests", cip_uint, &hf_conn_mgr_open_requests, NULL},
- {0x06, FALSE, 2, "Open Format Rejects", cip_uint, &hf_conn_mgr_open_format_rejects, NULL},
- {0x06, FALSE, 3, "Open Resource Rejects", cip_uint, &hf_conn_mgr_open_resource_rejects, NULL},
- {0x06, FALSE, 4, "Other Open Rejects", cip_uint, &hf_conn_mgr_other_open_rejects, NULL},
- {0x06, FALSE, 5, "Close Requests", cip_uint, &hf_conn_mgr_close_requests, NULL},
- {0x06, FALSE, 6, "Close Format Requests", cip_uint, &hf_conn_close_format_requests, NULL},
- {0x06, FALSE, 7, "Close Other Requests", cip_uint, &hf_conn_mgr_close_other_requests, NULL},
- {0x06, FALSE, 8, "Connection Timeouts", cip_uint, &hf_conn_mgr_conn_timouts, NULL},
-
- /* Time Sync Object */
- {0x43, FALSE, 1, "PTP Enable", cip_bool, &hf_time_sync_ptp_enable, NULL},
- {0x43, FALSE, 2, "Is Synchronized", cip_bool, &hf_time_sync_is_synchronized, NULL},
- {0x43, FALSE, 3, "System Time (Microseconds)", cip_ulint, &hf_time_sync_sys_time_micro, NULL},
- {0x43, FALSE, 4, "System Time (Nanoseconds)", cip_ulint, &hf_time_sync_sys_time_nano, NULL},
- {0x43, FALSE, 5, "Offset from Master", cip_lint, &hf_time_sync_offset_from_master, NULL},
- {0x43, FALSE, 6, "Max Offset from Master", cip_ulint, &hf_time_sync_max_offset_from_master, NULL},
- {0x43, FALSE, 7, "Mean Path Delay To Master", cip_lint, &hf_time_sync_mean_path_delay_to_master, NULL},
- {0x43, FALSE, 8, "Grand Master Clock Info", cip_dissector_func, NULL, dissect_time_sync_grandmaster_clock},
- {0x43, FALSE, 9, "Parent Clock Info", cip_dissector_func, NULL, dissect_time_sync_parent_clock},
- {0x43, FALSE, 10, "Local Clock Info", cip_dissector_func, NULL, dissect_time_sync_local_clock},
- {0x43, FALSE, 11, "Number of Ports", cip_uint, &hf_time_sync_num_ports, NULL},
- {0x43, FALSE, 12, "Port State Info", cip_dissector_func, NULL, dissect_time_sync_port_state_info},
- {0x43, FALSE, 13, "Port Enable Cfg", cip_dissector_func, NULL, dissect_time_sync_port_enable_cfg},
- {0x43, FALSE, 14, "Port Log Announcement Interval Cfg", cip_dissector_func, NULL, dissect_time_sync_port_log_announce},
- {0x43, FALSE, 15, "Port Log Sync Interval Cfg", cip_dissector_func, NULL, dissect_time_sync_port_log_sync},
- {0x43, FALSE, 16, "Priority1", cip_usint, &hf_time_sync_priority1, NULL},
- {0x43, FALSE, 17, "Priority2", cip_usint, &hf_time_sync_priority2, NULL},
- {0x43, FALSE, 18, "Domain number", cip_usint, &hf_time_sync_domain_number, NULL},
- {0x43, FALSE, 19, "Clock Type", cip_dissector_func, NULL, dissect_time_sync_clock_type},
- {0x43, FALSE, 20, "Manufacture Identity", cip_dissector_func, NULL, dissect_time_sync_manufacture_id},
- {0x43, FALSE, 21, "Product Description", cip_dissector_func, NULL, dissect_time_sync_prod_desc},
- {0x43, FALSE, 22, "Revision Data", cip_dissector_func, NULL, dissect_time_sync_revision_data},
- {0x43, FALSE, 23, "User Description", cip_dissector_func, NULL, dissect_time_sync_user_desc},
- {0x43, FALSE, 24, "Port Profile Identity Info", cip_dissector_func, NULL, dissect_time_sync_port_profile_id_info},
- {0x43, FALSE, 25, "Port Physical Address Info", cip_dissector_func, NULL, dissect_time_sync_port_phys_addr_info},
- {0x43, FALSE, 26, "Port Protocol Address Info", cip_dissector_func, NULL, dissect_time_sync_port_proto_addr_info},
- {0x43, FALSE, 27, "Steps Removed", cip_uint, &hf_time_sync_steps_removed, NULL},
- {0x43, FALSE, 28, "System Time and Offset", cip_dissector_func, NULL, dissect_time_sync_sys_time_and_offset},
-
+ /* Identity Object (class attributes) */
+ {0x01, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0x01, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0x01, TRUE, 3, -1, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0x01, TRUE, 4, -1, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0x01, TRUE, 5, -1, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0x01, TRUE, 6, 2, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0x01, TRUE, 7, 3, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* Identity Object (instance attributes) */
+ {0x01, FALSE, 1, 0, "Vendor ID", cip_uint, &hf_id_vendor_id, NULL},
+ {0x01, FALSE, 2, 1, "Device Type", cip_uint, &hf_id_device_type, NULL},
+ {0x01, FALSE, 3, 2, "Product Code", cip_uint, &hf_id_produce_code, NULL},
+ {0x01, FALSE, 4, 3, "Revision", cip_dissector_func, NULL, dissect_id_revision},
+ {0x01, FALSE, 5, 4, "Status", cip_word, &hf_id_status, NULL},
+ {0x01, FALSE, 6, 5, "Serial Number", cip_udint, &hf_id_serial_number, NULL},
+ {0x01, FALSE, 7, 6, "Product Name", cip_short_string, &hf_id_product_name, NULL},
+
+ /* Message Router Object (class attributes) */
+ {0x02, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0x02, TRUE, 2, -1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0x02, TRUE, 3, -1, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0x02, TRUE, 4, 1, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0x02, TRUE, 5, 2, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0x02, TRUE, 6, 3, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0x02, TRUE, 7, 4, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* Message Router Object (instance attributes) */
+ {0x02, FALSE, 1, 0, "Object List", cip_dissector_func, NULL, dissect_msg_rout_num_classes},
+ {0x02, FALSE, 2, 1, "Number Available", cip_uint, &hf_msg_rout_num_available, NULL},
+ {0x02, FALSE, 3, 2, "Number Active", cip_uint, &hf_msg_rout_num_active, NULL},
+ {0x02, FALSE, 4, 3, "Active Connections", cip_uint_array, &hf_msg_rout_active_connections, NULL},
+
+ /* Connection Manager Object (class attributes) */
+ {0x06, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0x06, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0x06, TRUE, 3, -1, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0x06, TRUE, 4, -1, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0x06, TRUE, 5, -1, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0x06, TRUE, 6, 2, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0x06, TRUE, 7, 3, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* Connection Manager Object (instance attributes) */
+ {0x06, FALSE, 1, 0, "Open Requests", cip_uint, &hf_conn_mgr_open_requests, NULL},
+ {0x06, FALSE, 2, 1, "Open Format Rejects", cip_uint, &hf_conn_mgr_open_format_rejects, NULL},
+ {0x06, FALSE, 3, 2, "Open Resource Rejects", cip_uint, &hf_conn_mgr_open_resource_rejects, NULL},
+ {0x06, FALSE, 4, 3, "Other Open Rejects", cip_uint, &hf_conn_mgr_other_open_rejects, NULL},
+ {0x06, FALSE, 5, 4, "Close Requests", cip_uint, &hf_conn_mgr_close_requests, NULL},
+ {0x06, FALSE, 6, 5, "Close Format Requests", cip_uint, &hf_conn_close_format_requests, NULL},
+ {0x06, FALSE, 7, 6, "Close Other Requests", cip_uint, &hf_conn_mgr_close_other_requests, NULL},
+ {0x06, FALSE, 8, 7, "Connection Timeouts", cip_uint, &hf_conn_mgr_conn_timouts, NULL},
+
+ /* Time Sync Object (class attributes) */
+ {0x43, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0x43, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0x43, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0x43, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0x43, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0x43, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0x43, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* Time Sync Object (instance attributes) */
+ {0x43, FALSE, 1, -1, "PTP Enable", cip_bool, &hf_time_sync_ptp_enable, NULL},
+ {0x43, FALSE, 2, -1, "Is Synchronized", cip_bool, &hf_time_sync_is_synchronized, NULL},
+ {0x43, FALSE, 3, -1, "System Time (Microseconds)", cip_ulint, &hf_time_sync_sys_time_micro, NULL},
+ {0x43, FALSE, 4, -1, "System Time (Nanoseconds)", cip_ulint, &hf_time_sync_sys_time_nano, NULL},
+ {0x43, FALSE, 5, -1, "Offset from Master", cip_lint, &hf_time_sync_offset_from_master, NULL},
+ {0x43, FALSE, 6, -1, "Max Offset from Master", cip_ulint, &hf_time_sync_max_offset_from_master, NULL},
+ {0x43, FALSE, 7, -1, "Mean Path Delay To Master", cip_lint, &hf_time_sync_mean_path_delay_to_master, NULL},
+ {0x43, FALSE, 8, -1, "Grand Master Clock Info", cip_dissector_func, NULL, dissect_time_sync_grandmaster_clock},
+ {0x43, FALSE, 9, -1, "Parent Clock Info", cip_dissector_func, NULL, dissect_time_sync_parent_clock},
+ {0x43, FALSE, 10, -1, "Local Clock Info", cip_dissector_func, NULL, dissect_time_sync_local_clock},
+ {0x43, FALSE, 11, -1, "Number of Ports", cip_uint, &hf_time_sync_num_ports, NULL},
+ {0x43, FALSE, 12, -1, "Port State Info", cip_dissector_func, NULL, dissect_time_sync_port_state_info},
+ {0x43, FALSE, 13, -1, "Port Enable Cfg", cip_dissector_func, NULL, dissect_time_sync_port_enable_cfg},
+ {0x43, FALSE, 14, -1, "Port Log Announcement Interval Cfg", cip_dissector_func, NULL, dissect_time_sync_port_log_announce},
+ {0x43, FALSE, 15, -1, "Port Log Sync Interval Cfg", cip_dissector_func, NULL, dissect_time_sync_port_log_sync},
+ {0x43, FALSE, 16, -1, "Priority1", cip_usint, &hf_time_sync_priority1, NULL},
+ {0x43, FALSE, 17, -1, "Priority2", cip_usint, &hf_time_sync_priority2, NULL},
+ {0x43, FALSE, 18, -1, "Domain number", cip_usint, &hf_time_sync_domain_number, NULL},
+ {0x43, FALSE, 19, -1, "Clock Type", cip_dissector_func, NULL, dissect_time_sync_clock_type},
+ {0x43, FALSE, 20, -1, "Manufacture Identity", cip_dissector_func, NULL, dissect_time_sync_manufacture_id},
+ {0x43, FALSE, 21, -1, "Product Description", cip_dissector_func, NULL, dissect_time_sync_prod_desc},
+ {0x43, FALSE, 22, -1, "Revision Data", cip_dissector_func, NULL, dissect_time_sync_revision_data},
+ {0x43, FALSE, 23, -1, "User Description", cip_dissector_func, NULL, dissect_time_sync_user_desc},
+ {0x43, FALSE, 24, -1, "Port Profile Identity Info", cip_dissector_func, NULL, dissect_time_sync_port_profile_id_info},
+ {0x43, FALSE, 25, -1, "Port Physical Address Info", cip_dissector_func, NULL, dissect_time_sync_port_phys_addr_info},
+ {0x43, FALSE, 26, -1, "Port Protocol Address Info", cip_dissector_func, NULL, dissect_time_sync_port_proto_addr_info},
+ {0x43, FALSE, 27, -1, "Steps Removed", cip_uint, &hf_time_sync_steps_removed, NULL},
+ {0x43, FALSE, 28, -1, "System Time and Offset", cip_dissector_func, NULL, dissect_time_sync_sys_time_and_offset},
};
typedef struct attribute_val_array {
@@ -3149,22 +3186,19 @@ typedef struct attribute_val_array {
attribute_info_t* attrs;
} attribute_val_array_t;
+/* Each entry in this table (eg: cip_attribute_vals) is a list of:
+ Attribute information (class_id/class_instance/attribute) to attribute property
+
+ Note: If more items are added to the individual tables, it may make sense
+ to switch to a more efficient implementation (eg: hash table).
+*/
+
static attribute_val_array_t all_attribute_vals[] = {
{sizeof(cip_attribute_vals)/sizeof(attribute_info_t), cip_attribute_vals},
{sizeof(enip_attribute_vals)/sizeof(attribute_info_t), enip_attribute_vals},
{sizeof(cip_safety_attribute_vals)/sizeof(attribute_info_t), cip_safety_attribute_vals}
};
-attribute_info_t class_attribute_vals[] = {
- { 0, TRUE, 1, "Revision", cip_uint, &hf_attr_class_revision, NULL },
- { 0, TRUE, 2, "Max Instance", cip_uint, &hf_attr_class_max_instance, NULL },
- { 0, TRUE, 3, "Number of Instances", cip_uint, &hf_attr_class_num_instance, NULL },
- { 0, TRUE, 4, "Optional Attribute List", cip_dissector_func, NULL, dissect_optional_attr_list },
- { 0, TRUE, 5, "Optional Service List", cip_dissector_func, NULL, dissect_optional_service_list },
- { 0, TRUE, 6, "Maximum ID Number Class Attributes", cip_uint, &hf_attr_class_num_class_attr, NULL },
- { 0, TRUE, 7, "Maximum ID Number Instance Attributes", cip_uint, &hf_attr_class_num_inst_attr, NULL },
-};
-
static void
dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info *pinfo, cip_req_info_t *preq_info );
@@ -3174,6 +3208,16 @@ attribute_info_t* cip_get_attribute(guint class_id, guint instance, guint attrib
attribute_val_array_t* att_array;
attribute_info_t* pattr;
+ static attribute_info_t class_attribute_vals[] = {
+ { 0, TRUE, 1, -1, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ { 0, TRUE, 2, -1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ { 0, TRUE, 3, -1, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ { 0, TRUE, 4, -1, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ { 0, TRUE, 5, -1, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ { 0, TRUE, 6, -1, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ { 0, TRUE, 7, -1, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+ };
+
for (i = 0; i < sizeof(all_attribute_vals)/sizeof(attribute_val_array_t); i++)
{
att_array = &all_attribute_vals[i];
@@ -4587,6 +4631,134 @@ dissect_cip_generic_service_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
return tvb_reported_length(tvb);
}
+typedef struct cip_gaa_key {
+ guint32 cip_class;
+ gboolean class_instance;
+} cip_gaa_key_t;
+
+typedef struct cip_gaa_val {
+ GList *attributes;
+} cip_gaa_val_t;
+
+static wmem_map_t *cip_gaa_hashtable = NULL;
+
+static guint
+cip_gaa_hash (gconstpointer v)
+{
+ const cip_gaa_key_t *key = (const cip_gaa_key_t *)v;
+ guint val;
+
+ val = (guint)((key->cip_class << 1) & 0xFFFFFFFE);
+ val |= (key->class_instance & 1);
+
+ return val;
+}
+
+static gint
+cip_gaa_equal(gconstpointer v, gconstpointer w)
+{
+ const cip_gaa_key_t *v1 = (const cip_gaa_key_t *)v;
+ const cip_gaa_key_t *v2 = (const cip_gaa_key_t *)w;
+
+ if ((v1->cip_class == v2->cip_class) &&
+ (v1->class_instance == v2->class_instance))
+ return 1;
+
+ return 0;
+}
+
+static void build_get_attr_all_table(void)
+{
+ size_t i, j;
+ attribute_val_array_t* att_array;
+ attribute_info_t* pattr;
+ cip_gaa_key_t key;
+ cip_gaa_key_t* new_key;
+ cip_gaa_val_t *gaa_val;
+ int last_attribute_index = -1;
+
+ cip_gaa_hashtable = wmem_map_new(wmem_epan_scope(), cip_gaa_hash, cip_gaa_equal);
+
+ for (i = 0; i < sizeof(all_attribute_vals)/sizeof(attribute_val_array_t); i++)
+ {
+ att_array = &all_attribute_vals[i];
+ for (j = 0; j < att_array->size; j++)
+ {
+ pattr = &att_array->attrs[j];
+ key.cip_class = pattr->class_id;
+ key.class_instance = pattr->class_instance;
+
+ gaa_val = (cip_gaa_val_t *)wmem_map_lookup( cip_gaa_hashtable, &key );
+ if (gaa_val == NULL)
+ {
+ new_key = (cip_gaa_key_t*)wmem_memdup(wmem_epan_scope(), &key, sizeof(cip_gaa_key_t));
+ gaa_val = wmem_new0(wmem_epan_scope(), cip_gaa_val_t);
+
+ wmem_map_insert(cip_gaa_hashtable, new_key, gaa_val );
+ last_attribute_index = -1;
+ }
+
+ if ((pattr->gaa_index >= 0) && (pattr->gaa_index > last_attribute_index))
+ {
+ gaa_val->attributes = g_list_append(gaa_val->attributes, pattr);
+ last_attribute_index = pattr->gaa_index;
+ }
+ }
+ }
+}
+
+static void
+dissect_cip_get_attribute_all_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
+ int offset, cip_simple_request_info_t* req_data)
+{
+ int att_size;
+ gint len_remain;
+ attribute_info_t* attr;
+ proto_item *att_item;
+ proto_tree *att_tree;
+ cip_gaa_key_t key;
+ cip_gaa_val_t *gaa_val;
+ GList *attribute_list;
+
+ key.cip_class = req_data->iClass;
+ key.class_instance = (req_data->iInstance == 0);
+
+ gaa_val = (cip_gaa_val_t *)wmem_map_lookup( cip_gaa_hashtable, &key );
+ if (gaa_val == NULL)
+ {
+ proto_tree_add_item(tree, hf_cip_sc_get_attribute_all_data, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA);
+ return;
+ }
+
+ for (attribute_list = g_list_first(gaa_val->attributes);
+ (attribute_list != NULL);
+ attribute_list = g_list_next(attribute_list))
+ {
+ attr = (attribute_info_t *)attribute_list->data;
+ len_remain = tvb_reported_length_remaining(tvb, offset);
+
+ /* If there are no more attributes defined or there is no data left. */
+ if (attr == NULL || len_remain <= 0)
+ break;
+
+ att_item = proto_tree_add_uint_format_value(tree, hf_cip_sc_get_attr_all_attr_item,
+ tvb, offset, 0, 0, "%d (%s)", attr->attribute, attr->text);
+ att_tree = proto_item_add_subtree(att_item, ett_cip_get_attributes_all_item);
+
+ att_size = dissect_cip_attribute(pinfo, att_tree, att_item, tvb, attr, offset, len_remain);
+ offset += att_size;
+
+ proto_item_set_len(att_item, att_size);
+ }
+
+ /* Add whatever is left as raw data. */
+ len_remain = tvb_reported_length_remaining(tvb, offset);
+ if (len_remain > 0)
+ {
+ proto_tree_add_item(tree, hf_cip_sc_get_attribute_all_data, tvb, offset, len_remain, ENC_NA);
+ }
+}
+
static void
dissect_cip_get_attribute_list_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item,
int offset, cip_simple_request_info_t* req_data)
@@ -4875,7 +5047,7 @@ dissect_cip_generic_service_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
switch(service)
{
case SC_GET_ATT_ALL:
- proto_tree_add_item(cmd_data_tree, hf_cip_sc_get_attribute_all_data, tvb, offset+4+add_stat_size, tvb_reported_length_remaining(tvb, offset+4+add_stat_size), ENC_NA);
+ dissect_cip_get_attribute_all_rsp(tvb, pinfo, cmd_data_tree, offset+4+add_stat_size, &req_data);
break;
case SC_SET_ATT_ALL:
proto_tree_add_item(cmd_data_tree, hf_cip_sc_set_attribute_all_data, tvb, offset+4+add_stat_size, tvb_reported_length_remaining(tvb, offset+4+add_stat_size), ENC_NA);
@@ -6663,6 +6835,7 @@ proto_register_cip(void)
{ &hf_cip_reserved24, { "Reserved", "cip.reserved", FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_cip_pad8, { "Pad Byte", "cip.pad", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
+ { &hf_cip_sc_get_attr_all_attr_item, { "Attribute", "cip.getall.attr_item", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
{ &hf_cip_sc_get_attr_list_attr_count, { "Attribute Count", "cip.getlist.attr_count", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_cip_sc_get_attr_list_attr_item, { "Attribute", "cip.getlist.attr_item", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_cip_sc_get_attr_list_attr_status, { "General Status", "cip.getlist.attr_status", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_gs_vals_ext, 0, NULL, HFILL }},
@@ -6986,6 +7159,7 @@ proto_register_cip(void)
&ett_cip_seg_safety_ounid_ssn,
&ett_status_item,
&ett_add_status_item,
+ &ett_cip_get_attributes_all_item,
&ett_cip_get_attribute_list,
&ett_cip_get_attribute_list_item,
&ett_cip_set_attribute_list,
@@ -7136,6 +7310,7 @@ proto_register_cip(void)
* can override the dissector for common services */
heur_subdissector_service = register_heur_dissector_list("cip.sc");
+ build_get_attr_all_table();
} /* end of proto_register_cip() */
diff --git a/epan/dissectors/packet-cip.h b/epan/dissectors/packet-cip.h
index 76c4556570..817e37a744 100644
--- a/epan/dissectors/packet-cip.h
+++ b/epan/dissectors/packet-cip.h
@@ -28,6 +28,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#ifndef PACKET_CIP_H
+#define PACKET_CIP_H
+
/* CIP Service Codes */
#define SC_GET_ATT_ALL 0x01
#define SC_SET_ATT_ALL 0x02
@@ -191,8 +194,8 @@
/* Define common services */
#define GENERIC_SC_LIST \
- { SC_GET_ATT_ALL, "Get Attribute All" }, \
- { SC_SET_ATT_ALL, "Set Attribute All" }, \
+ { SC_GET_ATT_ALL, "Get Attributes All" }, \
+ { SC_SET_ATT_ALL, "Set Attributes All" }, \
{ SC_GET_ATT_LIST, "Get Attribute List" }, \
{ SC_SET_ATT_LIST, "Set Attribute List" }, \
{ SC_RESET, "Reset" }, \
@@ -264,6 +267,7 @@ typedef struct attribute_info {
guint class_id;
gboolean class_instance;
guint attribute;
+ int gaa_index; /* Index of attribute in GetAttributeAll response (< 0 means not in GetAttrbuteAll */
const char *text;
enum cip_datatype datatype;
int* phf;
@@ -328,6 +332,31 @@ extern value_string_ext cip_vendor_vals_ext;
extern value_string_ext cip_devtype_vals_ext;
extern value_string_ext cip_class_names_vals_ext;
+/* Common class attributes and attribute dissection functions*/
+extern int hf_attr_class_revision;
+extern int hf_attr_class_max_instance;
+extern int hf_attr_class_num_instance;
+extern int hf_attr_class_opt_attr_num;
+extern int hf_attr_class_attr_num;
+extern int hf_attr_class_opt_service_num;
+extern int hf_attr_class_service_code;
+extern int hf_attr_class_num_class_attr;
+extern int hf_attr_class_num_inst_attr;
+
+#define CLASS_ATTRIBUTE_1_NAME "Revision"
+#define CLASS_ATTRIBUTE_2_NAME "Max Instance"
+#define CLASS_ATTRIBUTE_3_NAME "Number of Instances"
+#define CLASS_ATTRIBUTE_4_NAME "Optional Attribute List"
+#define CLASS_ATTRIBUTE_5_NAME "Optional Service List"
+#define CLASS_ATTRIBUTE_6_NAME "Maximum ID Number Class Attributes"
+#define CLASS_ATTRIBUTE_7_NAME "Maximum ID Number Instance Attributes"
+
+extern int dissect_optional_attr_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
+ int offset, int total_len);
+extern int dissect_optional_service_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
+ int offset, int total_len);
+
+
/*
* Editor modelines
*
@@ -340,3 +369,5 @@ extern value_string_ext cip_class_names_vals_ext;
* ex: set shiftwidth=3 tabstop=8 expandtab:
* :indentSize=3:tabSize=8:noTabs=true:
*/
+
+#endif /* PACKET_CIP_H */
diff --git a/epan/dissectors/packet-cipsafety.c b/epan/dissectors/packet-cipsafety.c
index ea7f029526..927d8eec03 100644
--- a/epan/dissectors/packet-cipsafety.c
+++ b/epan/dissectors/packet-cipsafety.c
@@ -236,10 +236,6 @@ static int hf_cip_sercosiii_link_sercos_address = -1;
static int hf_cip_sercosiii_link_error_count_p1 = -1;
static int hf_cip_sercosiii_link_error_count_p2 = -1;
-static int hf_tcpip_snn_timestamp = -1;
-static int hf_tcpip_snn_date = -1;
-static int hf_tcpip_snn_time = -1;
-
/* Initialize the subtree pointers */
static gint ett_cip_safety = -1;
static gint ett_path = -1;
@@ -291,7 +287,6 @@ static expert_field ei_cipsafety_tbd_not_copied = EI_INIT;
static expert_field ei_cipsafety_run_idle_not_complemented = EI_INIT;
static expert_field ei_mal_io = EI_INIT;
static expert_field ei_mal_sercosiii_link_error_count_p1p2 = EI_INIT;
-static expert_field ei_mal_tcpip_ssn = EI_INIT;
static expert_field ei_mal_ssupervisor_exception_detail_alarm_ced = EI_INIT;
static expert_field ei_mal_ssupervisor_exception_detail_alarm_ded = EI_INIT;
@@ -1633,80 +1628,64 @@ static int dissect_sercosiii_link_error_count_p1p2(packet_info *pinfo, proto_tre
return 4;
}
-static int dissect_tcpip_ssn(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
- int offset, int total_len)
-{
- if (total_len < 6)
- {
- expert_add_info(pinfo, item, &ei_mal_tcpip_ssn);
- return total_len;
- }
-
- dissect_cipsafety_ssn(tree, tvb, pinfo, offset, hf_tcpip_snn_timestamp, hf_tcpip_snn_date, hf_tcpip_snn_time);
- return 6;
-}
-
-attribute_info_t cip_safety_attribute_vals[52] = {
+attribute_info_t cip_safety_attribute_vals[51] = {
/* Safety Supervisor */
- {0x39, TRUE, 99, "Subclass", cip_uint, &hf_cip_ssupervisor_class_subclass, NULL},
- {0x39, FALSE, 1, "Number of Attributes", cip_usint, &hf_cip_ssupervisor_num_attr, NULL},
- {0x39, FALSE, 2, "Attribute List", cip_usint_array, &hf_cip_ssupervisor_attr_list, NULL},
- {0x39, FALSE, 5, "Manufacturer Name", cip_short_string, &hf_cip_ssupervisor_manufacture_name, NULL},
- {0x39, FALSE, 6, "Manufacturer Model Number", cip_short_string, &hf_cip_ssupervisor_manufacture_model_number, NULL},
- {0x39, FALSE, 7, "Software Revision Level", cip_short_string, &hf_cip_ssupervisor_sw_rev_level, NULL},
- {0x39, FALSE, 8, "Hardware Revision Level", cip_short_string, &hf_cip_ssupervisor_hw_rev_level, NULL},
- {0x39, FALSE, 9, "Manufacturer Serial Number", cip_short_string, &hf_cip_ssupervisor_manufacture_serial_number, NULL},
- {0x39, FALSE, 10, "Device Configuration", cip_short_string, &hf_cip_ssupervisor_device_config, NULL},
- {0x39, FALSE, 11, "Device Status", cip_usint, &hf_cip_ssupervisor_device_status, NULL},
- {0x39, FALSE, 12, "Exception Status", cip_byte, &hf_cip_ssupervisor_exception_status, NULL},
- {0x39, FALSE, 13, "Exception Detail Alarm", cip_dissector_func, NULL, dissect_s_supervisor_exception_detail_alarm},
- {0x39, FALSE, 14, "Exception Detail Warning", cip_dissector_func, NULL, dissect_s_supervisor_exception_detail_warning},
- {0x39, FALSE, 15, "Alarm Enable", cip_bool, &hf_cip_ssupervisor_alarm_enable, NULL},
- {0x39, FALSE, 16, "Warning Enable", cip_bool, &hf_cip_ssupervisor_warning_enable, NULL},
- {0x39, FALSE, 17, "Time", cip_date_and_time, &hf_cip_ssupervisor_time, NULL},
- {0x39, FALSE, 18, "Clock Power Cycle Behavior", cip_usint, &hf_cip_ssupervisor_clock_power_cycle_behavior, NULL},
- {0x39, FALSE, 19, "Last Maintenance Date", cip_date, &hf_cip_ssupervisor_last_maintenance_date, NULL},
- {0x39, FALSE, 20, "Next Scheduled Maintenance Date", cip_date, &hf_cip_ssupervisor_next_scheduled_maintenance_date, NULL},
- {0x39, FALSE, 21, "Scheduled Maintenance Expiration Timer", cip_int, &hf_cip_ssupervisor_scheduled_maintenance_expiration_timer, NULL},
- {0x39, FALSE, 22, "Scheduled Maintenance Expiration Warning Enable", cip_bool, &hf_cip_ssupervisor_scheduled_maintenance_expiration_warning_enable, NULL},
- {0x39, FALSE, 23, "Run Hours", cip_udint, &hf_cip_ssupervisor_run_hours, NULL},
- {0x39, FALSE, 24, "Configuration Lock", cip_bool, &hf_cip_ssupervisor_configuration_lock, NULL},
- {0x39, FALSE, 25, "Configuration UNID", cip_dissector_func, NULL, dissect_s_supervisor_configuration_unid},
- {0x39, FALSE, 26, "Safety Configuration Identifier", cip_dissector_func, NULL, dissect_s_supervisor_safety_configuration_id},
- {0x39, FALSE, 27, "Target UNID", cip_dissector_func, NULL, dissect_s_supervisor_target_unid},
- {0x39, FALSE, 28, "Output Connection Point Owners", cip_dissector_func, NULL, dissect_s_supervisor_output_connection_point_owners},
- {0x39, FALSE, 29, "Proposed TUNID", cip_dissector_func, NULL, dissect_s_supervisor_proposed_tunid},
- {0x39, FALSE, 99, "Subclass", cip_uint, &hf_cip_ssupervisor_instance_subclass, NULL},
+ {0x39, TRUE, 99, -1, "Subclass", cip_uint, &hf_cip_ssupervisor_class_subclass, NULL},
+ {0x39, FALSE, 1, -1, "Number of Attributes", cip_usint, &hf_cip_ssupervisor_num_attr, NULL},
+ {0x39, FALSE, 2, -1, "Attribute List", cip_usint_array, &hf_cip_ssupervisor_attr_list, NULL},
+ {0x39, FALSE, 5, -1, "Manufacturer Name", cip_short_string, &hf_cip_ssupervisor_manufacture_name, NULL},
+ {0x39, FALSE, 6, -1, "Manufacturer Model Number", cip_short_string, &hf_cip_ssupervisor_manufacture_model_number, NULL},
+ {0x39, FALSE, 7, -1, "Software Revision Level", cip_short_string, &hf_cip_ssupervisor_sw_rev_level, NULL},
+ {0x39, FALSE, 8, -1, "Hardware Revision Level", cip_short_string, &hf_cip_ssupervisor_hw_rev_level, NULL},
+ {0x39, FALSE, 9, -1, "Manufacturer Serial Number", cip_short_string, &hf_cip_ssupervisor_manufacture_serial_number, NULL},
+ {0x39, FALSE, 10, -1, "Device Configuration", cip_short_string, &hf_cip_ssupervisor_device_config, NULL},
+ {0x39, FALSE, 11, -1, "Device Status", cip_usint, &hf_cip_ssupervisor_device_status, NULL},
+ {0x39, FALSE, 12, -1, "Exception Status", cip_byte, &hf_cip_ssupervisor_exception_status, NULL},
+ {0x39, FALSE, 13, -1, "Exception Detail Alarm", cip_dissector_func, NULL, dissect_s_supervisor_exception_detail_alarm},
+ {0x39, FALSE, 14, -1, "Exception Detail Warning", cip_dissector_func, NULL, dissect_s_supervisor_exception_detail_warning},
+ {0x39, FALSE, 15, -1, "Alarm Enable", cip_bool, &hf_cip_ssupervisor_alarm_enable, NULL},
+ {0x39, FALSE, 16, -1, "Warning Enable", cip_bool, &hf_cip_ssupervisor_warning_enable, NULL},
+ {0x39, FALSE, 17, -1, "Time", cip_date_and_time, &hf_cip_ssupervisor_time, NULL},
+ {0x39, FALSE, 18, -1, "Clock Power Cycle Behavior", cip_usint, &hf_cip_ssupervisor_clock_power_cycle_behavior, NULL},
+ {0x39, FALSE, 19, -1, "Last Maintenance Date", cip_date, &hf_cip_ssupervisor_last_maintenance_date, NULL},
+ {0x39, FALSE, 20, -1, "Next Scheduled Maintenance Date", cip_date, &hf_cip_ssupervisor_next_scheduled_maintenance_date, NULL},
+ {0x39, FALSE, 21, -1, "Scheduled Maintenance Expiration Timer", cip_int, &hf_cip_ssupervisor_scheduled_maintenance_expiration_timer, NULL},
+ {0x39, FALSE, 22, -1, "Scheduled Maintenance Expiration Warning Enable", cip_bool, &hf_cip_ssupervisor_scheduled_maintenance_expiration_warning_enable, NULL},
+ {0x39, FALSE, 23, -1, "Run Hours", cip_udint, &hf_cip_ssupervisor_run_hours, NULL},
+ {0x39, FALSE, 24, -1, "Configuration Lock", cip_bool, &hf_cip_ssupervisor_configuration_lock, NULL},
+ {0x39, FALSE, 25, -1, "Configuration UNID", cip_dissector_func, NULL, dissect_s_supervisor_configuration_unid},
+ {0x39, FALSE, 26, -1, "Safety Configuration Identifier", cip_dissector_func, NULL, dissect_s_supervisor_safety_configuration_id},
+ {0x39, FALSE, 27, -1, "Target UNID", cip_dissector_func, NULL, dissect_s_supervisor_target_unid},
+ {0x39, FALSE, 28, -1, "Output Connection Point Owners", cip_dissector_func, NULL, dissect_s_supervisor_output_connection_point_owners},
+ {0x39, FALSE, 29, -1, "Proposed TUNID", cip_dissector_func, NULL, dissect_s_supervisor_proposed_tunid},
+ {0x39, FALSE, 99, -1, "Subclass", cip_uint, &hf_cip_ssupervisor_instance_subclass, NULL},
/* Safety Validator */
- {0x3A, TRUE, 8, "Safety Connection Fault Count", cip_uint, &hf_cip_svalidator_sconn_fault_count, NULL},
- {0x3A, FALSE, 1, "Safety Validator State", cip_usint, &hf_cip_svalidator_state, NULL},
- {0x3A, FALSE, 2, "Safety Validator Type", cip_dissector_func, NULL, dissect_s_validator_type},
- {0x3A, FALSE, 3, "Ping Interval ERI Multiplier", cip_uint, &hf_cip_svalidator_ping_eri, NULL},
- {0x3A, FALSE, 4, "Time Coord Msg Min Multiplier", cip_dissector_func, NULL, dissect_s_validator_time_coord_msg_min_mult},
- {0x3A, FALSE, 5, "Network Time Expectation Multiplier", cip_dissector_func, NULL, dissect_s_validator_network_time_multiplier},
- {0x3A, FALSE, 6, "Timeout Multiplier", cip_dissector_func, NULL, dissect_s_validator_timeout_multiplier},
- {0x3A, FALSE, 7, "Max Consumer Number", cip_usint, &hf_cip_svalidator_max_consumer_num, NULL},
- {0x3A, FALSE, 8, "Data Connection Instance", cip_uint, &hf_cip_svalidator_data_conn_inst, NULL},
- {0x3A, FALSE, 9, "Coordination Connection Instance", cip_dissector_func, NULL, dissect_s_validator_coordination_conn_inst},
- {0x3A, FALSE, 10, "Correction Connection Instance", cip_uint, &hf_cip_svalidator_correction_conn_inst, NULL},
- {0x3A, FALSE, 11, "CCO Binding", cip_uint, &hf_cip_svalidator_cco_binding, NULL},
- {0x3A, FALSE, 12, "Max Data Age", cip_uint, &hf_cip_svalidator_max_data_age, NULL},
- {0x3A, FALSE, 13, "Application Data Path", cip_dissector_func, NULL, dissect_s_validator_app_data_path},
- {0x3A, FALSE, 14, "Error Code", cip_uint, &hf_cip_svalidator_error_code, NULL},
- {0x3A, FALSE, 15, "Producer/Consumer Fault Counters", cip_dissector_func, NULL, dissect_s_validator_prod_cons_fault_count},
+ {0x3A, TRUE, 8, -1, "Safety Connection Fault Count", cip_uint, &hf_cip_svalidator_sconn_fault_count, NULL},
+ {0x3A, FALSE, 1, 0, "Safety Validator State", cip_usint, &hf_cip_svalidator_state, NULL},
+ {0x3A, FALSE, 2, 1, "Safety Validator Type", cip_dissector_func, NULL, dissect_s_validator_type},
+ {0x3A, FALSE, 3, 2, "Ping Interval ERI Multiplier", cip_uint, &hf_cip_svalidator_ping_eri, NULL},
+ {0x3A, FALSE, 4, 3, "Time Coord Msg Min Multiplier", cip_dissector_func, NULL, dissect_s_validator_time_coord_msg_min_mult},
+ {0x3A, FALSE, 5, 4, "Network Time Expectation Multiplier", cip_dissector_func, NULL, dissect_s_validator_network_time_multiplier},
+ {0x3A, FALSE, 6, 5, "Timeout Multiplier", cip_dissector_func, NULL, dissect_s_validator_timeout_multiplier},
+ {0x3A, FALSE, 7, 6, "Max Consumer Number", cip_usint, &hf_cip_svalidator_max_consumer_num, NULL},
+ {0x3A, FALSE, 8, 7, "Data Connection Instance", cip_uint, &hf_cip_svalidator_data_conn_inst, NULL},
+ {0x3A, FALSE, 9, 8, "Coordination Connection Instance", cip_dissector_func, NULL, dissect_s_validator_coordination_conn_inst},
+ {0x3A, FALSE, 10, 9, "Correction Connection Instance", cip_uint, &hf_cip_svalidator_correction_conn_inst, NULL},
+ {0x3A, FALSE, 11, 10, "CCO Binding", cip_uint, &hf_cip_svalidator_cco_binding, NULL},
+ {0x3A, FALSE, 12, 11, "Max Data Age", cip_uint, &hf_cip_svalidator_max_data_age, NULL},
+ {0x3A, FALSE, 13, 12, "Application Data Path", cip_dissector_func, NULL, dissect_s_validator_app_data_path},
+ {0x3A, FALSE, 14, 13, "Error Code", cip_uint, &hf_cip_svalidator_error_code, NULL},
+ {0x3A, FALSE, 15, -1, "Producer/Consumer Fault Counters", cip_dissector_func, NULL, dissect_s_validator_prod_cons_fault_count},
/* Sercos III Link */
- {0x4C, FALSE, 1, "Safety Network Number", cip_byte_array, &hf_cip_sercosiii_link_snn, NULL},
- {0x4C, FALSE, 2, "Communication Cycle Time", cip_dint, &hf_cip_sercosiii_link_communication_cycle_time, NULL},
- {0x4C, FALSE, 3, "Interface Status", cip_word, &hf_cip_sercosiii_link_interface_status, NULL},
- {0x4C, FALSE, 4, "Error counter MST-P/S", cip_int, &hf_cip_sercosiii_link_error_count_mstps, NULL},
- {0x4C, FALSE, 5, "Error counter Port1 and Port2", cip_dissector_func, NULL, dissect_sercosiii_link_error_count_p1p2},
- {0x4C, FALSE, 6, "SERCOS address", cip_int, &hf_cip_sercosiii_link_sercos_address, NULL},
-
- /* TCP/IP object (CIP-Safety specific) */
- {0xF5, FALSE, 7, "Safety Network Number", cip_dissector_func, NULL, dissect_tcpip_ssn}
+ {0x4C, FALSE, 1, -1, "Safety Network Number", cip_byte_array, &hf_cip_sercosiii_link_snn, NULL},
+ {0x4C, FALSE, 2, -1, "Communication Cycle Time", cip_dint, &hf_cip_sercosiii_link_communication_cycle_time, NULL},
+ {0x4C, FALSE, 3, -1, "Interface Status", cip_word, &hf_cip_sercosiii_link_interface_status, NULL},
+ {0x4C, FALSE, 4, -1, "Error counter MST-P/S", cip_int, &hf_cip_sercosiii_link_error_count_mstps, NULL},
+ {0x4C, FALSE, 5, -1, "Error counter Port1 and Port2", cip_dissector_func, NULL, dissect_sercosiii_link_error_count_p1p2},
+ {0x4C, FALSE, 6, -1, "SERCOS address", cip_int, &hf_cip_sercosiii_link_sercos_address, NULL},
};
/*
@@ -1899,19 +1878,6 @@ proto_register_cipsafety(void)
{ "SERCOS Address", "cipsafety.sercosiii_link.sercos_address",
FT_INT16, BASE_DEC, NULL, 0, NULL, HFILL }
},
-
- { &hf_tcpip_snn_timestamp,
- { "Safety Network Number (Timestamp)", "cip.tcpip.snn.timestamp",
- FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, NULL, HFILL }
- },
- { &hf_tcpip_snn_date,
- { "Safety Network Number (Manual) Date", "cip.tcpip.snn.date",
- FT_UINT16, BASE_HEX, VALS(cipsafety_ssn_date_vals), 0, NULL, HFILL }
- },
- { &hf_tcpip_snn_time,
- { "Safety Network Number (Manual) Time", "cip.tcpip.snn.time",
- FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
- },
};
static hf_register_info hf_ssupervisor[] = {
@@ -2526,7 +2492,6 @@ proto_register_cipsafety(void)
{ &ei_cipsafety_run_idle_not_complemented, { "cipsafety.run_idle_not_complemented", PI_PROTOCOL, PI_WARN, "Run/Idle bit not complemented", EXPFILL }},
{ &ei_mal_io, { "cipsafety.malformed.io", PI_MALFORMED, PI_ERROR, "Malformed CIP Safety I/O packet", EXPFILL }},
{ &ei_mal_sercosiii_link_error_count_p1p2, { "cipsafety.malformed.sercosiii_link.error_count_p1p2", PI_MALFORMED, PI_ERROR, "Malformed SERCOS III Attribute 5", EXPFILL }},
- { &ei_mal_tcpip_ssn, { "cip.malformed.tcpip.ssn", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Object Safety Network Number", EXPFILL }},
};
static ei_register_info ei_ssupervisor[] = {
diff --git a/epan/dissectors/packet-cipsafety.h b/epan/dissectors/packet-cipsafety.h
index 84f8afcec3..b17ffa1805 100644
--- a/epan/dissectors/packet-cipsafety.h
+++ b/epan/dissectors/packet-cipsafety.h
@@ -64,6 +64,6 @@ extern void dissect_cipsafety_ssn(proto_tree *tree, tvbuff_t *tvb, packet_info *
** Exported variables
*/
extern const value_string cipsafety_ssn_date_vals[8];
-extern attribute_info_t cip_safety_attribute_vals[52];
+extern attribute_info_t cip_safety_attribute_vals[51];
#endif /* PACKET_CIPSAFETY_H */
diff --git a/epan/dissectors/packet-enip.c b/epan/dissectors/packet-enip.c
index d4dda663d2..b1a29b57de 100644
--- a/epan/dissectors/packet-enip.c
+++ b/epan/dissectors/packet-enip.c
@@ -180,6 +180,9 @@ static int hf_tcpip_ic_name_server = -1;
static int hf_tcpip_ic_name_server2 = -1;
static int hf_tcpip_ic_domain_name = -1;
static int hf_tcpip_hostname = -1;
+static int hf_tcpip_snn_timestamp = -1;
+static int hf_tcpip_snn_date = -1;
+static int hf_tcpip_snn_time = -1;
static int hf_tcpip_ttl_value = -1;
static int hf_tcpip_mcast_alloc = -1;
static int hf_tcpip_mcast_reserved = -1;
@@ -190,6 +193,7 @@ static int hf_tcpip_lcd_remote_mac = -1;
static int hf_tcpip_lcd_arp_pdu = -1;
static int hf_tcpip_select_acd = -1;
static int hf_tcpip_quick_connect = -1;
+static int hf_tcpip_encap_inactivity = -1;
static int hf_elink_interface_flags = -1;
static int hf_elink_iflags_link_status = -1;
@@ -303,6 +307,7 @@ static expert_field ei_mal_tcpip_physical_link_size = EI_INIT;
static expert_field ei_mal_tcpip_interface_config = EI_INIT;
static expert_field ei_mal_tcpip_mcast_config = EI_INIT;
static expert_field ei_mal_tcpip_last_conflict = EI_INIT;
+static expert_field ei_mal_tcpip_ssn = EI_INIT;
static expert_field ei_mal_elink_interface_flags = EI_INIT;
static expert_field ei_mal_elink_physical_address = EI_INIT;
static expert_field ei_mal_elink_interface_counters = EI_INIT;
@@ -1390,6 +1395,19 @@ dissect_tcpip_interface_config(packet_info *pinfo, proto_tree *tree, proto_item
return (22+domain_length);
}
+static int dissect_tcpip_ssn(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
+ int offset, int total_len)
+{
+ if (total_len < 6)
+ {
+ expert_add_info(pinfo, item, &ei_mal_tcpip_ssn);
+ return total_len;
+ }
+
+ dissect_cipsafety_ssn(tree, tvb, pinfo, offset, hf_tcpip_snn_timestamp, hf_tcpip_snn_date, hf_tcpip_snn_time);
+ return 6;
+}
+
static int
dissect_tcpip_mcast_config(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
int offset, int total_len)
@@ -1711,60 +1729,98 @@ dissect_dlr_active_gateway_address(packet_info *pinfo, proto_tree *tree, proto_i
return 10;
}
-attribute_info_t enip_attribute_vals[45] = {
-
- /* TCP/IP object */
- {0xF5, FALSE, 1, "Status", cip_dissector_func, NULL, dissect_tcpip_status},
- {0xF5, FALSE, 2, "Configuration Capability", cip_dissector_func, NULL, dissect_tcpip_config_cap},
- {0xF5, FALSE, 3, "Configuration Control", cip_dissector_func, NULL, dissect_tcpip_config_control},
- {0xF5, FALSE, 4, "Physical Link Object", cip_dissector_func, NULL, dissect_tcpip_physical_link},
- {0xF5, FALSE, 5, "Interface Configuration", cip_dissector_func, NULL, dissect_tcpip_interface_config},
- {0xF5, FALSE, 6, "Host Name", cip_string, &hf_tcpip_hostname, NULL},
- {0xF5, FALSE, 8, "TTL Value", cip_usint, &hf_tcpip_ttl_value, NULL},
- {0xF5, FALSE, 9, "Multicast Configuration", cip_dissector_func, NULL, dissect_tcpip_mcast_config},
- {0xF5, FALSE, 10, "Select ACD", cip_bool, &hf_tcpip_select_acd, NULL},
- {0xF5, FALSE, 11, "Last Conflict Detected", cip_dissector_func, NULL, dissect_tcpip_last_conflict},
- {0xF5, FALSE, 12, "EtherNet/IP Quick Connect", cip_bool, &hf_tcpip_quick_connect, NULL},
-
- /* Ethernet Link object */
- {0xF6, FALSE, 1, "Interface Speed", cip_dword, &hf_elink_interface_speed, NULL},
- {0xF6, FALSE, 2, "Interface Flags", cip_dissector_func, NULL, dissect_elink_interface_flags},
- {0xF6, FALSE, 3, "Physical Address", cip_dissector_func, NULL, dissect_elink_physical_address },
- {0xF6, FALSE, 4, "Interface Counters", cip_dissector_func, NULL, dissect_elink_interface_counters},
- {0xF6, FALSE, 5, "Media Counters", cip_dissector_func, NULL, dissect_elink_media_counters},
- {0xF6, FALSE, 6, "Interface Control", cip_dissector_func, NULL, dissect_elink_interface_control},
- {0xF6, FALSE, 7, "Interface Type", cip_usint, &hf_elink_interface_type, NULL},
- {0xF6, FALSE, 8, "Interface State", cip_usint, &hf_elink_interface_state, NULL},
- {0xF6, FALSE, 9, "Admin State", cip_usint, &hf_elink_admin_state, NULL},
- {0xF6, FALSE, 10, "Interface Label", cip_short_string, &hf_elink_interface_label, NULL},
-
- /* QoS object */
- {0x48, FALSE, 1, "802.1Q Tag Enable", cip_bool, &hf_qos_8021q_enable, NULL},
- {0x48, FALSE, 2, "DSCP PTP Event", cip_usint, &hf_qos_dscp_ptp_event, NULL},
- {0x48, FALSE, 3, "DSCP PTP General", cip_usint, &hf_qos_dscp_ptp_general, NULL},
- {0x48, FALSE, 4, "DSCP Urgent", cip_usint, &hf_qos_dscp_urgent, NULL},
- {0x48, FALSE, 5, "DSCP Scheduled", cip_usint, &hf_qos_dscp_scheduled, NULL},
- {0x48, FALSE, 6, "DSCP High", cip_usint, &hf_qos_dscp_high, NULL},
- {0x48, FALSE, 7, "DSCP Low", cip_usint, &hf_qos_dscp_low, NULL},
- {0x48, FALSE, 8, "DSCP Explicit", cip_usint, &hf_qos_dscp_explicit, NULL},
-
- /* DLR object */
- {0x47, FALSE, 1, "Network Topology", cip_usint, &hf_dlr_network_topology, NULL},
- {0x47, FALSE, 2, "Network Status", cip_usint, &hf_dlr_network_status, NULL},
- {0x47, FALSE, 3, "Ring Supervisor Status", cip_usint, &hf_dlr_ring_supervisor_status, NULL},
- {0x47, FALSE, 4, "Ring Supervisor Config", cip_dissector_func, NULL, dissect_dlr_ring_supervisor_config},
- {0x47, FALSE, 5, "Ring Faults Count", cip_uint, &hf_dlr_ring_faults_count, NULL},
- {0x47, FALSE, 6, "Last Active Node on Port 1", cip_dissector_func, NULL, dissect_dlr_last_active_node_on_port_1},
- {0x47, FALSE, 7, "Last Active Node on Port 2", cip_dissector_func, NULL, dissect_dlr_last_active_node_on_port_2},
- {0x47, FALSE, 8, "Ring Protocol Participants Count", cip_uint, &hf_dlr_ring_protocol_participants_count, NULL},
- {0x47, FALSE, 9, "Ring Protocol Participants List", cip_dissector_func, NULL, dissect_dlr_ring_protocol_participants_list},
- {0x47, FALSE, 10, "Active Supervisor Address", cip_dissector_func, NULL, dissect_dlr_active_supervisor_address},
- {0x47, FALSE, 11, "Active Supervisor Precedence", cip_usint, &hf_dlr_active_supervisor_precedence, NULL},
- {0x47, FALSE, 12, "Capability Flags", cip_dissector_func, NULL, dissect_dlr_capability_flags},
- {0x47, FALSE, 13, "Redundant Gateway Config", cip_dissector_func, NULL, dissect_dlr_redundant_gateway_config},
- {0x47, FALSE, 14, "Redundant Gateway Status", cip_usint, &hf_dlr_redundant_gateway_status, NULL},
- {0x47, FALSE, 15, "Active Gateway Address", cip_dissector_func, NULL, dissect_dlr_active_gateway_address},
- {0x47, FALSE, 16, "Active Gateway Precedence", cip_usint, &hf_dlr_active_gateway_precedence, NULL},
+attribute_info_t enip_attribute_vals[75] = {
+
+ /* TCP/IP Object (class attributes) */
+ {0xF5, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0xF5, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0xF5, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0xF5, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0xF5, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0xF5, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0xF5, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* TCP/IP object (instance attributes) */
+ {0xF5, FALSE, 1, 0, "Status", cip_dissector_func, NULL, dissect_tcpip_status},
+ {0xF5, FALSE, 2, 1, "Configuration Capability", cip_dissector_func, NULL, dissect_tcpip_config_cap},
+ {0xF5, FALSE, 3, 2, "Configuration Control", cip_dissector_func, NULL, dissect_tcpip_config_control},
+ {0xF5, FALSE, 4, 3, "Physical Link Object", cip_dissector_func, NULL, dissect_tcpip_physical_link},
+ {0xF5, FALSE, 5, 4, "Interface Configuration", cip_dissector_func, NULL, dissect_tcpip_interface_config},
+ {0xF5, FALSE, 6, 5, "Host Name", cip_string, &hf_tcpip_hostname, NULL},
+ {0xF5, FALSE, 7, 6, "Safety Network Number", cip_dissector_func, NULL, dissect_tcpip_ssn},
+ {0xF5, FALSE, 8, 7, "TTL Value", cip_usint, &hf_tcpip_ttl_value, NULL},
+ {0xF5, FALSE, 9, 8, "Multicast Configuration", cip_dissector_func, NULL, dissect_tcpip_mcast_config},
+ {0xF5, FALSE, 10, 9, "Select ACD", cip_bool, &hf_tcpip_select_acd, NULL},
+ {0xF5, FALSE, 11, 10, "Last Conflict Detected", cip_dissector_func, NULL, dissect_tcpip_last_conflict},
+ {0xF5, FALSE, 12, 11, "EtherNet/IP Quick Connect", cip_bool, &hf_tcpip_quick_connect, NULL},
+ {0xF5, FALSE, 13, 12, "Encapsulation Inactivity Timeout", cip_uint, &hf_tcpip_encap_inactivity, NULL},
+
+ /* Ethernet Link Object (class attributes) */
+ {0xF6, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0xF6, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0xF6, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0xF6, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0xF6, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0xF6, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0xF6, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* Ethernet Link object (instance attributes) */
+ {0xF6, FALSE, 1, 0, "Interface Speed", cip_dword, &hf_elink_interface_speed, NULL},
+ {0xF6, FALSE, 2, 1, "Interface Flags", cip_dissector_func, NULL, dissect_elink_interface_flags},
+ {0xF6, FALSE, 3, 2, "Physical Address", cip_dissector_func, NULL, dissect_elink_physical_address },
+ {0xF6, FALSE, 4, 3, "Interface Counters", cip_dissector_func, NULL, dissect_elink_interface_counters},
+ {0xF6, FALSE, 5, 4, "Media Counters", cip_dissector_func, NULL, dissect_elink_media_counters},
+ {0xF6, FALSE, 6, 5, "Interface Control", cip_dissector_func, NULL, dissect_elink_interface_control},
+ {0xF6, FALSE, 7, 6, "Interface Type", cip_usint, &hf_elink_interface_type, NULL},
+ {0xF6, FALSE, 8, 7, "Interface State", cip_usint, &hf_elink_interface_state, NULL},
+ {0xF6, FALSE, 9, 8, "Admin State", cip_usint, &hf_elink_admin_state, NULL},
+ {0xF6, FALSE, 10, 9, "Interface Label", cip_short_string, &hf_elink_interface_label, NULL},
+
+ /* QoS Object (class attributes) */
+ {0x48, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0x48, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0x48, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0x48, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0x48, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0x48, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0x48, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* QoS object (instance attributes) */
+ {0x48, FALSE, 1, -1, "802.1Q Tag Enable", cip_bool, &hf_qos_8021q_enable, NULL},
+ {0x48, FALSE, 2, -1, "DSCP PTP Event", cip_usint, &hf_qos_dscp_ptp_event, NULL},
+ {0x48, FALSE, 3, -1, "DSCP PTP General", cip_usint, &hf_qos_dscp_ptp_general, NULL},
+ {0x48, FALSE, 4, -1, "DSCP Urgent", cip_usint, &hf_qos_dscp_urgent, NULL},
+ {0x48, FALSE, 5, -1, "DSCP Scheduled", cip_usint, &hf_qos_dscp_scheduled, NULL},
+ {0x48, FALSE, 6, -1, "DSCP High", cip_usint, &hf_qos_dscp_high, NULL},
+ {0x48, FALSE, 7, -1, "DSCP Low", cip_usint, &hf_qos_dscp_low, NULL},
+ {0x48, FALSE, 8, -1, "DSCP Explicit", cip_usint, &hf_qos_dscp_explicit, NULL},
+
+ /* DLR Object (class attributes) */
+ {0x47, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
+ {0x47, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
+ {0x47, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
+ {0x47, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
+ {0x47, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
+ {0x47, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
+ {0x47, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
+
+ /* DLR object (instance attributes) */
+ {0x47, FALSE, 1, 0, "Network Topology", cip_usint, &hf_dlr_network_topology, NULL},
+ {0x47, FALSE, 2, 1, "Network Status", cip_usint, &hf_dlr_network_status, NULL},
+ {0x47, FALSE, 3, -1, "Ring Supervisor Status", cip_usint, &hf_dlr_ring_supervisor_status, NULL},
+ {0x47, FALSE, 4, -1, "Ring Supervisor Config", cip_dissector_func, NULL, dissect_dlr_ring_supervisor_config},
+ {0x47, FALSE, 5, -1, "Ring Faults Count", cip_uint, &hf_dlr_ring_faults_count, NULL},
+ {0x47, FALSE, 6, -1, "Last Active Node on Port 1", cip_dissector_func, NULL, dissect_dlr_last_active_node_on_port_1},
+ {0x47, FALSE, 7, -1, "Last Active Node on Port 2", cip_dissector_func, NULL, dissect_dlr_last_active_node_on_port_2},
+ {0x47, FALSE, 8, -1, "Ring Protocol Participants Count", cip_uint, &hf_dlr_ring_protocol_participants_count, NULL},
+ {0x47, FALSE, 9, -1, "Ring Protocol Participants List", cip_dissector_func, NULL, dissect_dlr_ring_protocol_participants_list},
+ {0x47, FALSE, 10, -1, "Active Supervisor Address", cip_dissector_func, NULL, dissect_dlr_active_supervisor_address},
+ {0x47, FALSE, 11, -1, "Active Supervisor Precedence", cip_usint, &hf_dlr_active_supervisor_precedence, NULL},
+ {0x47, FALSE, 12, -1, "Capability Flags", cip_dissector_func, NULL, dissect_dlr_capability_flags},
+ {0x47, FALSE, 13, -1, "Redundant Gateway Config", cip_dissector_func, NULL, dissect_dlr_redundant_gateway_config},
+ {0x47, FALSE, 14, -1, "Redundant Gateway Status", cip_usint, &hf_dlr_redundant_gateway_status, NULL},
+ {0x47, FALSE, 15, -1, "Active Gateway Address", cip_dissector_func, NULL, dissect_dlr_active_gateway_address},
+ {0x47, FALSE, 16, -1, "Active Gateway Precedence", cip_usint, &hf_dlr_active_gateway_precedence, NULL},
};
@@ -2970,6 +3026,24 @@ proto_register_enip(void)
FT_STRING, BASE_NONE, NULL, 0,
NULL, HFILL }},
+ { &hf_tcpip_snn_timestamp,
+ { "Safety Network Number (Timestamp)", "cip.tcpip.snn.timestamp",
+ FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
+ NULL, HFILL }
+ },
+
+ { &hf_tcpip_snn_date,
+ { "Safety Network Number (Manual) Date", "cip.tcpip.snn.date",
+ FT_UINT16, BASE_HEX, VALS(cipsafety_ssn_date_vals), 0,
+ NULL, HFILL }
+ },
+
+ { &hf_tcpip_snn_time,
+ { "Safety Network Number (Manual) Time", "cip.tcpip.snn.time",
+ FT_UINT32, BASE_HEX, NULL, 0,
+ NULL, HFILL }
+ },
+
{ &hf_tcpip_ttl_value,
{ "TTL Value", "cip.tcpip.ttl_value",
FT_UINT8, BASE_DEC, NULL, 0,
@@ -3020,6 +3094,10 @@ proto_register_enip(void)
FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x1,
NULL, HFILL }},
+ { &hf_tcpip_encap_inactivity,
+ { "Encapsulation Inactivity Timeout", "cip.tcpip.encap_inactivity",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }},
{ &hf_elink_interface_speed,
{ "Interface Speed", "cip.elink.interface_speed",
@@ -3474,6 +3552,7 @@ proto_register_enip(void)
{ &ei_mal_tcpip_config_control, { "cip.malformed.tcpip.config_control", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Configuration Control", EXPFILL }},
{ &ei_mal_tcpip_physical_link_size, { "cip.malformed.tcpip.physical_link_size", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Physical Link Object", EXPFILL }},
{ &ei_mal_tcpip_interface_config, { "cip.malformed.tcpip.interface_config", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Interface Configuration", EXPFILL }},
+ { &ei_mal_tcpip_ssn, { "cip.malformed.tcpip.ssn", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Object Safety Network Number", EXPFILL }},
{ &ei_mal_tcpip_mcast_config, { "cip.malformed.tcpip.mcast_config", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Multicast Config", EXPFILL }},
{ &ei_mal_tcpip_last_conflict, { "cip.malformed.tcpip.last_conflict", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Last Conflict Detected", EXPFILL }},
{ &ei_mal_elink_interface_flags, { "cip.malformed.elink.interface_flags", PI_MALFORMED, PI_ERROR, "Malformed Ethernet Link Interface Flags", EXPFILL }},
diff --git a/epan/dissectors/packet-enip.h b/epan/dissectors/packet-enip.h
index 4b5ab0bb13..22ceaaee62 100644
--- a/epan/dissectors/packet-enip.h
+++ b/epan/dissectors/packet-enip.h
@@ -112,6 +112,6 @@ enum enip_connid_type {ECIDT_UNKNOWN, ECIDT_O2T, ECIDT_T2O};
void enip_close_cip_connection( packet_info *pinfo, guint16 ConnSerialNumber, guint16 VendorID, guint32 DeviceSerialNumber );
void enip_mark_connection_triad( packet_info *pinfo, guint16 ConnSerialNumber, guint16 VendorID, guint32 DeviceSerialNumber );
-extern attribute_info_t enip_attribute_vals[45];
+extern attribute_info_t enip_attribute_vals[75];
#endif /* PACKET_ENIP_H */