aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDylan Ulis <daulis0@gmail.com>2021-07-22 17:41:23 -0400
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-07-28 06:18:56 +0000
commita1e05d09c6b9aa6eb8068dc463b05ffa2248121f (patch)
tree9cd7fd42ee585f618b965a1c07ab057d4802f1b1
parent6e8c7283d6f93b2dde6f16301c0f280a6cf7f481 (diff)
downloadwireshark-a1e05d09c6b9aa6eb8068dc463b05ffa2248121f.tar.gz
wireshark-a1e05d09c6b9aa6eb8068dc463b05ffa2248121f.tar.bz2
wireshark-a1e05d09c6b9aa6eb8068dc463b05ffa2248121f.zip
CIP: Updates to match current specification
1. Connection Manager parameter is called 'Redundant Owner' instead of 'Exclusive' 2. Add new CIP Class Names 3. Support new time types: UTIME, STIME, NTIME 4. Add units to data type
-rw-r--r--epan/dissectors/packet-cip.c76
-rw-r--r--epan/dissectors/packet-cip.h4
2 files changed, 64 insertions, 16 deletions
diff --git a/epan/dissectors/packet-cip.c b/epan/dissectors/packet-cip.c
index 97686e4d45..035d7e98ad 100644
--- a/epan/dissectors/packet-cip.c
+++ b/epan/dissectors/packet-cip.c
@@ -3,9 +3,10 @@
* CIP Home: www.odva.org
*
* This dissector includes items from:
- * CIP Volume 1: Common Industrial Protocol, Edition 3.27
+ * CIP Volume 1: Common Industrial Protocol, Edition 3.30
* CIP Volume 5: Integration of Modbus Devices into the CIP Architecture, Edition 2.17
* CIP Volume 7: CIP Safety, Edition 1.9
+ * CIP Volume 8: CIP Security, Edition 1.11
*
* Copyright 2004
* Magnus Hansson <mah@hms.se>
@@ -598,6 +599,8 @@ static gint ett_32bitheader_tree = -1;
static gint ett_connection_info = -1;
+static const unit_name_string units_safety_128us = { " (128 us increment)", " (128 us increments)" };
+
static expert_field ei_mal_identity_revision = EI_INIT;
static expert_field ei_mal_identity_status = EI_INIT;
static expert_field ei_mal_msg_rout_num_classes = EI_INIT;
@@ -769,7 +772,7 @@ static const value_string cip_con_fw_vals[] = {
/* Translate function to string - Connection owner */
static const value_string cip_con_owner_vals[] = {
- { 0, "Exclusive" },
+ { 0, "Non-Redundant" },
{ 1, "Redundant" },
{ 0, NULL }
@@ -2870,6 +2873,9 @@ const value_string cip_class_names_vals[] = {
{ 0x5D, "CIP Security" },
{ 0x5E, "EtherNet/IP Security" },
{ 0x5F, "Certificate Management" },
+ { 0x60, "Authority" },
+ { 0x61, "Password Authenticator" },
+ { 0x62, "Certificate Authenticator" },
{ 0x67, "PCCC Class" },
{ 0xF0, "ControlNet" },
{ 0xF1, "ControlNet Keeper" },
@@ -2896,6 +2902,10 @@ const value_string cip_class_names_vals[] = {
{ 0x10B, "IO-Link Service Parameter" },
{ 0x10C, "IO-Link Master PHY" },
{ 0x10D, "IO-Link Device PHY" },
+ { 0x10E, "Pilot Light Supervisor" },
+ { 0x10F, "Select Line Link" },
+ { 0x110, "In-Cabinet Actual Topology" },
+ { 0x111, "In-Cabinet Commissioning" },
{ 0, NULL }
};
@@ -3521,8 +3531,9 @@ static int dissect_time_sync_sys_time_and_offset(packet_info *pinfo, proto_tree
return total_len;
}
- proto_tree_add_item( tree, hf_time_sync_sys_time_and_offset_time, tvb, offset, 8, ENC_LITTLE_ENDIAN);
+ dissect_cip_utime(tree, tvb, offset, hf_time_sync_sys_time_and_offset_time);
proto_tree_add_item( tree, hf_time_sync_sys_time_and_offset_offset, tvb, offset+8, 8, ENC_LITTLE_ENDIAN);
+
return 16;
}
@@ -3779,11 +3790,11 @@ static attribute_info_t cip_attribute_vals[] = {
/* 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, 3, -1, "System Time (Microseconds)", cip_utime, &hf_time_sync_sys_time_micro, NULL},
+ {0x43, FALSE, 4, -1, "System Time (Nanoseconds)", cip_stime, &hf_time_sync_sys_time_nano, NULL},
+ {0x43, FALSE, 5, -1, "Offset from Master", cip_ntime, &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, 7, -1, "Mean Path Delay To Master", cip_ntime, &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},
@@ -5383,6 +5394,32 @@ void dissect_cip_date_and_time(proto_tree *tree, tvbuff_t *tvb, int offset, int
proto_tree_add_time(tree, hf_datetime, tvb, offset, 6, &computed_time);
}
+// CIP Type - STIME (nanoseconds)
+static int dissect_cip_stime(proto_tree* tree, tvbuff_t* tvb, int offset, int hf_datetime)
+{
+ nstime_t ts_nstime = { 0 };
+ guint64 timestamp = tvb_get_letoh64(tvb, offset);
+ ts_nstime.secs = timestamp / 1000000000;
+ ts_nstime.nsecs = timestamp % 1000000000;
+
+ proto_tree_add_time(tree, hf_datetime, tvb, offset, 8, &ts_nstime);
+
+ return 8;
+}
+
+// CIP Type - UTIME (microseconds)
+int dissect_cip_utime(proto_tree* tree, tvbuff_t* tvb, int offset, int hf_datetime)
+{
+ nstime_t ts_nstime = { 0 };
+ guint64 timestamp = tvb_get_letoh64(tvb, offset);
+ ts_nstime.secs = timestamp / 1000000;
+ ts_nstime.nsecs = timestamp % 1000000;
+
+ proto_tree_add_time(tree, hf_datetime, tvb, offset, 8, &ts_nstime);
+
+ return 8;
+}
+
int dissect_cip_string_type(packet_info *pinfo, proto_tree *tree, proto_item *item,
tvbuff_t *tvb, int offset, int hf_type, int string_type)
{
@@ -5520,6 +5557,7 @@ int dissect_cip_attribute(packet_info *pinfo, proto_tree *tree, proto_item *item
case cip_lword:
case cip_lreal:
case cip_ltime:
+ case cip_ntime:
proto_tree_add_item(tree, *(attr->phf), tvb, offset, 8, ENC_LITTLE_ENDIAN);
consumed = 8;
break;
@@ -5541,6 +5579,12 @@ int dissect_cip_attribute(packet_info *pinfo, proto_tree *tree, proto_item *item
dissect_cip_date_and_time(tree, tvb, offset, *(attr->phf));
consumed = 6;
break;
+ case cip_stime:
+ consumed = dissect_cip_stime(tree, tvb, offset, *(attr->phf));
+ break;
+ case cip_utime:
+ consumed = dissect_cip_utime(tree, tvb, offset, *(attr->phf));
+ break;
case cip_date:
temp_data = tvb_get_letohs( tvb, offset);
/* Convert to nstime epoch */
@@ -8333,7 +8377,7 @@ proto_register_cip(void)
{ &hf_cip_seg_safety_configuration_time, { "Configuration (Manual) Time", "cip.safety_segment.configuration_time", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_cip_seg_safety_time_correction_epi, { "Time Correction EPI", "cip.safety_segment.time_correction_eri", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_cip_seg_safety_time_correction_net_params, { "Time Correction Network Connection Parameters", "cip.safety_segment.time_correction.net_params", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
- { &hf_cip_seg_safety_time_correction_own, { "Owner", "cip.safety_segment.time_correction.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, "Time Correction: Redundant owner bit", HFILL }},
+ { &hf_cip_seg_safety_time_correction_own, { "Redundant Owner", "cip.safety_segment.time_correction.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, "Time Correction: Redundant owner bit", HFILL }},
{ &hf_cip_seg_safety_time_correction_typ, { "Connection Type", "cip.safety_segment.time_correction.type", FT_UINT16, BASE_DEC, VALS(cip_con_type_vals), 0x6000, "Time Correction: Connection type", HFILL }},
{ &hf_cip_seg_safety_time_correction_prio, { "Priority", "cip.safety_segment.time_correction.prio", FT_UINT16, BASE_DEC, VALS(cip_con_prio_vals), 0x0C00, "Time Correction: Connection priority", HFILL }},
{ &hf_cip_seg_safety_time_correction_fixed_var, { "Connection Size Type", "cip.safety_segment.time_correction.f_v", FT_UINT16, BASE_DEC, VALS(cip_con_fw_vals), 0x0200, "Time Correction: Fixed or variable connection size", HFILL }},
@@ -8350,7 +8394,7 @@ proto_register_cip(void)
{ &hf_cip_seg_safety_ounid_nodeid, { "Node ID", "cip.safety_segment.ounid.nodeid", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
{ &hf_cip_seg_safety_ping_eri_multiplier, { "Ping Interval EPI Multiplier", "cip.safety_segment.ping_eri_multiplier", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_cip_seg_safety_time_coord_msg_min_multiplier, { "Time Coord Msg Min Multiplier", "cip.safety_segment.time_coord_msg_min_multiplier", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
- { &hf_cip_seg_safety_network_time_expected_multiplier, { "Network Time Expectation Multiplier", "cip.safety_segment.network_time_expected_multiplier", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_cip_seg_safety_network_time_expected_multiplier, { "Network Time Expectation Multiplier", "cip.safety_segment.network_time_expected_multiplier", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, &units_safety_128us, 0, NULL, HFILL }},
{ &hf_cip_seg_safety_timeout_multiplier, { "Timeout Multiplier", "cip.safety_segment.timeout_multiplier", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_cip_seg_safety_max_consumer_number, { "Max Consumer Number", "cip.safety_segment.max_consumer_number", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_cip_seg_safety_conn_param_crc, { "Connection Param CRC (CPCRC)", "cip.safety_segment.conn_param_crc", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }},
@@ -8430,8 +8474,8 @@ proto_register_cip(void)
{ &hf_time_sync_ptp_enable, { "PTP Enable", "cip.time_sync.ptp_enable", FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0, NULL, HFILL }},
{ &hf_time_sync_is_synchronized, { "Is Synchronized", "cip.time_sync.is_synchronized", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0, NULL, HFILL }},
- { &hf_time_sync_sys_time_micro, { "System Time (Microseconds)", "cip.time_sync.sys_time_micro", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }},
- { &hf_time_sync_sys_time_nano, { "System Time (Nanoseconds)", "cip.time_sync.sys_time_nano", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_time_sync_sys_time_micro, { "System Time (Microseconds)", "cip.time_sync.sys_time_micro", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
+ { &hf_time_sync_sys_time_nano, { "System Time (Nanoseconds)", "cip.time_sync.sys_time_nano", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
{ &hf_time_sync_offset_from_master, { "Offset from Master", "cip.time_sync.offset_from_master", FT_INT64, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_time_sync_max_offset_from_master, { "Max Offset from Master", "cip.time_sync.max_offset_from_master", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_time_sync_mean_path_delay_to_master, { "Mean Path Delay To Master", "cip.time_sync.mean_path_delay_to_master", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }},
@@ -8511,7 +8555,7 @@ proto_register_cip(void)
{ &hf_time_sync_port_proto_addr_info_addr_size, { "Size of Address", "cip.time_sync.port_proto_addr_info.addr_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_time_sync_port_proto_addr_info_port_proto_addr, { "Port Protocol Address", "cip.time_sync.port_profile_id_info.port_proto_addr", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_time_sync_steps_removed, { "Steps Removed", "cip.time_sync.steps_removed", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
- { &hf_time_sync_sys_time_and_offset_time, { "System Time (Microseconds)", "cip.time_sync.sys_time_and_offset.time", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }},
+ { &hf_time_sync_sys_time_and_offset_time, { "System Time (Microseconds)", "cip.time_sync.sys_time_and_offset.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
{ &hf_time_sync_sys_time_and_offset_offset, { "System Offset (Microseconds)", "cip.time_sync.sys_time_and_offset.offset", FT_UINT64, BASE_DEC, NULL, 0, NULL, HFILL }},
{ &hf_cip_security_state, { "State", "cip.security.state", FT_UINT8, BASE_DEC, VALS(cip_security_state_vals), 0, NULL, HFILL }},
{ &hf_port_entry_port, { "Entry Port", "cip.port.entry_port", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
@@ -8577,8 +8621,8 @@ proto_register_cip(void)
{ &hf_cip_cm_lfwo_prio, { "Priority", "cip.cm.fwo.prio", FT_UINT32, BASE_DEC, VALS(cip_con_prio_vals), 0x0C000000, "Large Fwd Open: Connection priority", HFILL }},
{ &hf_cip_cm_fwo_typ, { "Connection Type", "cip.cm.fwo.type", FT_UINT16, BASE_DEC, VALS(cip_con_type_vals), 0x6000, "Fwd Open: Connection type", HFILL }},
{ &hf_cip_cm_lfwo_typ, { "Connection Type", "cip.cm.fwo.type", FT_UINT32, BASE_DEC, VALS(cip_con_type_vals), 0x60000000, "Large Fwd Open: Connection type", HFILL }},
- { &hf_cip_cm_fwo_own, { "Owner", "cip.cm.fwo.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, "Fwd Open: Redundant owner bit", HFILL }},
- { &hf_cip_cm_lfwo_own, { "Owner", "cip.cm.fwo.owner", FT_UINT32, BASE_DEC, VALS(cip_con_owner_vals), 0x80000000, "Large Fwd Open: Redundant owner bit", HFILL }},
+ { &hf_cip_cm_fwo_own, { "Redundant Owner", "cip.cm.fwo.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, "Fwd Open: Redundant owner bit", HFILL }},
+ { &hf_cip_cm_lfwo_own, { "Redundant Owner", "cip.cm.fwo.owner", FT_UINT32, BASE_DEC, VALS(cip_con_owner_vals), 0x80000000, "Large Fwd Open: Redundant owner bit", HFILL }},
{ &hf_cip_cm_fwo_dir, { "Direction", "cip.cm.fwo.dir", FT_UINT8, BASE_DEC, VALS(cip_con_dir_vals), CI_PRODUCTION_DIR_MASK, "Fwd Open: Direction", HFILL }},
{ &hf_cip_cm_fwo_trigg, { "Trigger", "cip.cm.fwo.trigger", FT_UINT8, BASE_DEC, VALS(cip_con_trigg_vals), CI_PRODUCTION_TRIGGER_MASK, "Fwd Open: Production trigger", HFILL }},
{ &hf_cip_cm_fwo_class, { "Class", "cip.cm.fwo.transport", FT_UINT8, BASE_DEC, VALS(cip_con_class_vals), CI_TRANSPORT_CLASS_MASK, "Fwd Open: Transport Class", HFILL }},
@@ -8688,8 +8732,8 @@ proto_register_cip(void)
{ &hf_cip_cco_lfwo_prio, { "Priority", "cip.cco.prio", FT_UINT32, BASE_DEC, VALS(cip_con_prio_vals), 0x0C000000, NULL, HFILL }},
{ &hf_cip_cco_fwo_typ, { "Connection Type", "cip.cco.type", FT_UINT16, BASE_DEC, VALS(cip_con_type_vals), 0x6000, NULL, HFILL }},
{ &hf_cip_cco_lfwo_typ, { "Connection Type", "cip.cco.type", FT_UINT32, BASE_DEC, VALS(cip_con_type_vals), 0x60000000, NULL, HFILL }},
- { &hf_cip_cco_fwo_own, { "Owner", "cip.cco.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, NULL, HFILL }},
- { &hf_cip_cco_lfwo_own, { "Owner", "cip.cco.owner", FT_UINT32, BASE_DEC, VALS(cip_con_owner_vals), 0x80000000, NULL, HFILL }},
+ { &hf_cip_cco_fwo_own, { "Redundant Owner", "cip.cco.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, NULL, HFILL }},
+ { &hf_cip_cco_lfwo_own, { "Redundant Owner", "cip.cco.owner", FT_UINT32, BASE_DEC, VALS(cip_con_owner_vals), 0x80000000, NULL, HFILL }},
{ &hf_cip_cco_fwo_dir, { "Direction", "cip.cco.dir", FT_UINT8, BASE_DEC, VALS(cip_con_dir_vals), CI_PRODUCTION_DIR_MASK, NULL, HFILL }},
{ &hf_cip_cco_fwo_trigger, { "Trigger", "cip.cco.trigger", FT_UINT8, BASE_DEC, VALS(cip_con_trigg_vals), CI_PRODUCTION_TRIGGER_MASK, NULL, HFILL }},
{ &hf_cip_cco_fwo_class, { "Class", "cip.cco.transport", FT_UINT8, BASE_DEC, VALS(cip_con_class_vals), CI_TRANSPORT_CLASS_MASK, NULL, HFILL }},
diff --git a/epan/dissectors/packet-cip.h b/epan/dissectors/packet-cip.h
index 30e214942c..a3e5e973f1 100644
--- a/epan/dissectors/packet-cip.h
+++ b/epan/dissectors/packet-cip.h
@@ -432,10 +432,13 @@ enum cip_datatype {
cip_ulint,
cip_real,
cip_lreal,
+ cip_stime,
+ cip_utime,
cip_itime,
cip_time,
cip_ftime,
cip_ltime,
+ cip_ntime,
cip_short_string,
cip_string,
cip_string2,
@@ -564,6 +567,7 @@ extern void cip_rpi_api_fmt(gchar *s, guint32 value);
extern int dissect_cip_attribute(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, attribute_info_t* attr, int offset, int total_len);
extern void dissect_cip_data(proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info *pinfo, cip_req_info_t *preq_info, proto_item* msp_item, gboolean is_msp_item);
extern void dissect_cip_date_and_time(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_datetime);
+extern int dissect_cip_utime(proto_tree* tree, tvbuff_t* tvb, int offset, int hf_datetime);
extern int dissect_cip_get_attribute_list_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item,
int offset, cip_simple_request_info_t* req_data);
extern int dissect_cip_multiple_service_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, int offset, gboolean request);