aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDylan Ulis <daulis0@gmail.com>2018-02-07 08:53:45 -0500
committerMichael Mann <mmann78@netscape.net>2018-02-08 23:39:50 +0000
commit60c5ec67f81393d979534c47a069c154277e477b (patch)
tree891ffec17b33f76da126bceb557d0dd7de3bd494
parent41812f2d685d6a4f6d586972db1e10102e2f3021 (diff)
CIP Safety: Add decode options for I/O Payloads
1. Add Decode Options for 4 Safety I/O types. Previously, you could only decode as "CIP Safety", which only showed as a generic data block (because all important things for parsing are in the FwdOpen). 2. Change some timestamp display formatting to match other related timestamp fields (now all Dec) 3. Don't create connections for Null Forward Opens. Change-Id: Ia1031b3887739a864a453b9e566ebe6f29fa5b8b Reviewed-on: https://code.wireshark.org/review/25664 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r--epan/dissectors/packet-cipsafety.c109
-rw-r--r--epan/dissectors/packet-cipsafety.h1
-rw-r--r--epan/dissectors/packet-enip.c7
3 files changed, 113 insertions, 4 deletions
diff --git a/epan/dissectors/packet-cipsafety.c b/epan/dissectors/packet-cipsafety.c
index dbceb6e3ff..438c48879b 100644
--- a/epan/dissectors/packet-cipsafety.c
+++ b/epan/dissectors/packet-cipsafety.c
@@ -44,6 +44,10 @@ void proto_reg_handoff_cipsafety(void);
/* Protocol handle for CIP Safety */
static int proto_cipsafety = -1;
+static int proto_cipsafety_base_data = -1;
+static int proto_cipsafety_extended_data = -1;
+static int proto_cipsafety_base_time_coord = -1;
+static int proto_cipsafety_extended_time_coord = -1;
static int proto_cip_class_s_supervisor = -1;
static int proto_cip_class_s_validator = -1;
static int proto_cip = -1;
@@ -316,6 +320,10 @@ static expert_field ei_mal_svalidator_coordination_conn_inst = EI_INIT;
static expert_field ei_mal_svalidator_prod_cons_fault_count = EI_INIT;
static dissector_handle_t cipsafety_handle;
+static dissector_handle_t cipsafety_base_data_handle;
+static dissector_handle_t cipsafety_extended_data_handle;
+static dissector_handle_t cipsafety_base_time_coord_handle;
+static dissector_handle_t cipsafety_extended_time_coord_handle;
typedef struct cip_safety_packet_data {
guint16 rollover_value;
@@ -1495,7 +1503,7 @@ dissect_cip_safety_data( proto_tree *tree, proto_item *item, tvbuff_t *tvb, int
guint32 test_crc_c5, value_c5 = 0, tmp_c5;
proto_item *complement_item, *crc_s5_item, *crc_s5_status_item;
gboolean short_format = TRUE;
- gboolean compute_crc = ((safety_info != NULL) && (safety_info->eip_conn_info != NULL));
+ gboolean compute_crc = ((safety_info != NULL) && (safety_info->compute_crc == TRUE));
/* Make entries in Protocol column and Info column on summary display */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "CIP Safety");
@@ -1980,6 +1988,66 @@ dissect_cipsafety(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* dat
return tvb_captured_length(tvb);
}
+static int dissect_cipsafety_base_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ cip_safety_info_t safety_info;
+ enip_conn_val_t eip_conn_info;
+ safety_info.eip_conn_info = &eip_conn_info;
+ safety_info.compute_crc = FALSE;
+
+ // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
+ safety_info.conn_type = ECIDT_T2O;
+ safety_info.eip_conn_info->TransportClass_trigger = 0;
+ safety_info.eip_conn_info->safety.format = CIP_SAFETY_BASE_FORMAT;
+
+ return dissect_cipsafety(tvb, pinfo, tree, &safety_info);
+}
+
+static int dissect_cipsafety_extended_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ cip_safety_info_t safety_info;
+ enip_conn_val_t eip_conn_info;
+ safety_info.eip_conn_info = &eip_conn_info;
+ safety_info.compute_crc = FALSE;
+
+ // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
+ safety_info.conn_type = ECIDT_T2O;
+ safety_info.eip_conn_info->TransportClass_trigger = 0;
+ safety_info.eip_conn_info->safety.format = CIP_SAFETY_EXTENDED_FORMAT;
+
+ return dissect_cipsafety(tvb, pinfo, tree, &safety_info);
+}
+
+static int dissect_cipsafety_base_time_coord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ cip_safety_info_t safety_info;
+ enip_conn_val_t eip_conn_info;
+ safety_info.eip_conn_info = &eip_conn_info;
+ safety_info.compute_crc = FALSE;
+
+ // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
+ safety_info.conn_type = ECIDT_O2T;
+ safety_info.eip_conn_info->TransportClass_trigger = 0;
+ safety_info.eip_conn_info->safety.format = CIP_SAFETY_BASE_FORMAT;
+
+ return dissect_cipsafety(tvb, pinfo, tree, &safety_info);
+}
+
+static int dissect_cipsafety_extended_time_coord(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+ cip_safety_info_t safety_info;
+ enip_conn_val_t eip_conn_info;
+ safety_info.eip_conn_info = &eip_conn_info;
+ safety_info.compute_crc = FALSE;
+
+ // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
+ safety_info.conn_type = ECIDT_O2T;
+ safety_info.eip_conn_info->TransportClass_trigger = 0;
+ safety_info.eip_conn_info->safety.format = CIP_SAFETY_EXTENDED_FORMAT;
+
+ return dissect_cipsafety(tvb, pinfo, tree, &safety_info);
+}
+
static int dissect_sercosiii_link_error_count_p1p2(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
int offset, int total_len)
{
@@ -2194,7 +2262,7 @@ proto_register_cipsafety(void)
},
{ &hf_cipsafety_consumer_time_value,
{ "Consumer Time Value", "cipsafety.consumer_time_value",
- FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
+ FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
},
{ &hf_cipsafety_mcast_byte,
{ "MCAST Byte", "cipsafety.mcast_byte",
@@ -2226,7 +2294,7 @@ proto_register_cipsafety(void)
},
{ &hf_cipsafety_time_correction,
{ "Time Correction", "cipsafety.time_correction",
- FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
+ FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
},
{ &hf_cipsafety_crc_s5_0,
{ "CRC S5_0", "cipsafety.crc_s5_0",
@@ -2923,6 +2991,36 @@ proto_register_cipsafety(void)
cipsafety_handle = register_dissector( "cipsafety", dissect_cipsafety, proto_cipsafety);
+ // Register different protocols for "Decode As".
+ proto_cipsafety_base_data = proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Base - Data",
+ "CIP Safety - Base - Data",
+ "cipsafety_bd",
+ proto_cipsafety,
+ FT_PROTOCOL);
+ cipsafety_base_data_handle = register_dissector("cipsafety_bd", dissect_cipsafety_base_data, proto_cipsafety_base_data);
+
+ proto_cipsafety_extended_data = proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Extended - Data",
+ "CIP Safety - Extended - Data",
+ "cipsafety_ed",
+ proto_cipsafety,
+ FT_PROTOCOL);
+ cipsafety_extended_data_handle = register_dissector("cipsafety_ed", dissect_cipsafety_extended_data, proto_cipsafety_extended_data);
+
+ proto_cipsafety_base_time_coord = proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Base - Time Coordination",
+ "CIP Safety - Base - Time Coordination",
+ "cipsafety_bt",
+ proto_cipsafety,
+ FT_PROTOCOL);
+ cipsafety_base_time_coord_handle = register_dissector("cipsafety_bt", dissect_cipsafety_base_time_coord, proto_cipsafety_base_time_coord);
+
+ proto_cipsafety_extended_time_coord = proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Extended - Time Coordination",
+ "CIP Safety - Extended - Time Coordination",
+ "cipsafety_et",
+ proto_cipsafety,
+ FT_PROTOCOL);
+ cipsafety_extended_time_coord_handle = register_dissector("cipsafety_et", dissect_cipsafety_extended_time_coord, proto_cipsafety_extended_time_coord);
+
+
/* Register CIP Safety objects */
proto_cip_class_s_supervisor = proto_register_protocol("CIP Safety Supervisor",
"CIPSSupervisor", "cipssupervisor");
@@ -2962,7 +3060,10 @@ proto_reg_handoff_cipsafety(void)
heur_dissector_add("cip.sc", dissect_class_svalidator_heur, "CIP Safety Validator", "s_validator_cip", proto_cip_class_s_validator, HEURISTIC_ENABLE);
/* Register dissector for I/O data handling */
- dissector_add_for_decode_as("enip.io", cipsafety_handle );
+ dissector_add_for_decode_as("enip.io", cipsafety_base_data_handle );
+ dissector_add_for_decode_as("enip.io", cipsafety_extended_data_handle );
+ dissector_add_for_decode_as("enip.io", cipsafety_base_time_coord_handle );
+ dissector_add_for_decode_as("enip.io", cipsafety_extended_time_coord_handle );
proto_cip = proto_get_id_by_filter_name( "cip" );
subdissector_class_table = find_dissector_table("cip.class.iface");
diff --git a/epan/dissectors/packet-cipsafety.h b/epan/dissectors/packet-cipsafety.h
index ddcc2543b5..3706199f71 100644
--- a/epan/dissectors/packet-cipsafety.h
+++ b/epan/dissectors/packet-cipsafety.h
@@ -49,6 +49,7 @@
typedef struct cip_safety_info {
enum enip_connid_type conn_type;
enip_conn_val_t* eip_conn_info;
+ gboolean compute_crc;
} cip_safety_info_t;
diff --git a/epan/dissectors/packet-enip.c b/epan/dissectors/packet-enip.c
index 15fb9180f2..fa1f681fbd 100644
--- a/epan/dissectors/packet-enip.c
+++ b/epan/dissectors/packet-enip.c
@@ -1054,6 +1054,12 @@ enip_open_cip_connection( packet_info *pinfo, cip_conn_info_t* connInfo)
if (pinfo->fd->flags.visited)
return;
+ // Don't create connections for Null Forward Opens.
+ if (connInfo->T2O.type == CONN_TYPE_NULL && connInfo->O2T.type == CONN_TYPE_NULL)
+ {
+ return;
+ }
+
conn_key = wmem_new(wmem_file_scope(), enip_conn_key_t);
conn_key->ConnSerialNumber = connInfo->ConnSerialNumber;
conn_key->VendorID = connInfo->VendorID;
@@ -2386,6 +2392,7 @@ dissect_cpf(enip_request_key_t *request_key, int command, tvbuff_t *tvb,
/* Add any possible safety related data */
cip_safety.conn_type = connid_type;
cip_safety.eip_conn_info = conn_info;
+ cip_safety.compute_crc = TRUE;
call_dissector_with_data(cipsafety_handle, next_tvb, pinfo, dissector_tree, &cip_safety);
}