2 * Routines for CIP (Common Industrial Protocol) Safety dissection
3 * CIP Safety Home: www.odva.org
5 * This dissector includes items from:
6 * CIP Volume 1: Common Industrial Protocol, Edition 3.24
7 * CIP Volume 5: CIP Safety, Edition 2.22
10 * Michael Mann <mmann@pyramidsolutions.com>
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1998 Gerald Combs
16 * SPDX-License-Identifier: GPL-2.0-or-later
22 #include <epan/packet.h>
23 #include <epan/expert.h>
24 #include <epan/proto_data.h>
27 #include <wsutil/pint.h>
28 #include <wsutil/crc8.h>
29 #include <wsutil/crc16.h>
30 #include <wsutil/crc32.h>
31 #include "packet-cip.h"
32 #include "packet-cipsafety.h"
35 void proto_register_cipsafety(void);
36 void proto_reg_handoff_cipsafety(void);
37 /* The entry point to the actual dissection is: dissect_cipsafety */
39 /* Protocol handle for CIP Safety */
40 static int proto_cipsafety
;
41 static int proto_cipsafety_base_data
;
42 static int proto_cipsafety_extended_data
;
43 static int proto_cipsafety_base_time_coord
;
44 static int proto_cipsafety_extended_time_coord
;
45 static int proto_cip_class_s_supervisor
;
46 static int proto_cip_class_s_validator
;
49 static dissector_table_t subdissector_class_table
;
50 static dissector_handle_t cip_class_s_supervisor_handle
;
51 static dissector_handle_t cip_class_s_validator_handle
;
53 /* CIP Safety field identifiers */
54 static int hf_cipsafety_data
;
55 static int hf_cipsafety_mode_byte
;
56 static int hf_cipsafety_mode_byte_run_idle
;
57 static int hf_cipsafety_mode_byte_not_run_idle
;
58 static int hf_cipsafety_mode_byte_tbd_2_bit
;
59 static int hf_cipsafety_mode_byte_tbd_2_copy
;
60 static int hf_cipsafety_mode_byte_ping_count
;
61 static int hf_cipsafety_mode_byte_tbd
;
62 static int hf_cipsafety_mode_byte_not_tbd
;
63 static int hf_cipsafety_crc_s1
;
64 static int hf_cipsafety_crc_s1_status
;
65 static int hf_cipsafety_crc_s2
;
66 static int hf_cipsafety_crc_s2_status
;
67 static int hf_cipsafety_crc_s3
;
68 static int hf_cipsafety_crc_s3_status
;
69 static int hf_cipsafety_complement_crc_s3
;
70 static int hf_cipsafety_complement_crc_s3_status
;
71 static int hf_cipsafety_timestamp
;
72 static int hf_cipsafety_ack_byte
;
73 static int hf_cipsafety_ack_byte_ping_count_reply
;
74 static int hf_cipsafety_ack_byte_reserved1
;
75 static int hf_cipsafety_ack_byte_ping_response
;
76 static int hf_cipsafety_ack_byte_reserved2
;
77 static int hf_cipsafety_ack_byte_parity_even
;
78 static int hf_cipsafety_ack_byte2
;
79 static int hf_cipsafety_consumer_time_value
;
80 static int hf_cipsafety_mcast_byte
;
81 static int hf_cipsafety_mcast_byte_consumer_num
;
82 static int hf_cipsafety_mcast_byte_reserved1
;
83 static int hf_cipsafety_mcast_byte_mai
;
84 static int hf_cipsafety_mcast_byte_reserved2
;
85 static int hf_cipsafety_mcast_byte_parity_even
;
86 static int hf_cipsafety_mcast_byte2
;
87 static int hf_cipsafety_time_correction
;
88 static int hf_cipsafety_crc_s5_0
;
89 static int hf_cipsafety_crc_s5_1
;
90 static int hf_cipsafety_crc_s5_2
;
91 static int hf_cipsafety_crc_s5_status
;
92 static int hf_cipsafety_complement_data
;
93 static int hf_cip_safety_message_encoding
;
95 /* CIP Safety header field identifiers */
96 static int hf_cip_reqrsp
;
97 static int hf_cip_data
;
99 /* Safety Supervisor header field identifiers */
100 static int hf_cip_ssupervisor_sc
;
101 static int hf_cip_ssupervisor_recover_data
;
102 static int hf_cip_ssupervisor_perform_diag_data
;
103 static int hf_cip_ssupervisor_configure_request_password
;
104 static int hf_cip_ssupervisor_configure_request_tunid
;
105 static int hf_cip_ssupervisor_configure_request_tunid_snn_timestamp
;
106 static int hf_cip_ssupervisor_configure_request_tunid_snn_date
;
107 static int hf_cip_ssupervisor_configure_request_tunid_snn_time
;
108 static int hf_cip_ssupervisor_configure_request_tunid_nodeid
;
109 static int hf_cip_ssupervisor_configure_request_ounid
;
110 static int hf_cip_ssupervisor_configure_request_ounid_snn_timestamp
;
111 static int hf_cip_ssupervisor_configure_request_ounid_snn_date
;
112 static int hf_cip_ssupervisor_configure_request_ounid_snn_time
;
113 static int hf_cip_ssupervisor_configure_request_ounid_nodeid
;
114 static int hf_cip_ssupervisor_validate_configuration_sccrc
;
115 static int hf_cip_ssupervisor_validate_configuration_scts_timestamp
;
116 static int hf_cip_ssupervisor_validate_configuration_scts_date
;
117 static int hf_cip_ssupervisor_validate_configuration_scts_time
;
118 static int hf_cip_ssupervisor_validate_configuration_ext_error
;
119 static int hf_cip_ssupervisor_set_password_current_password
;
120 static int hf_cip_ssupervisor_set_password_new_password
;
121 static int hf_cip_ssupervisor_configure_lock_value
;
122 static int hf_cip_ssupervisor_configure_lock_password
;
123 static int hf_cip_ssupervisor_configure_lock_tunid
;
124 static int hf_cip_ssupervisor_configure_lock_tunid_snn_timestamp
;
125 static int hf_cip_ssupervisor_configure_lock_tunid_snn_date
;
126 static int hf_cip_ssupervisor_configure_lock_tunid_snn_time
;
127 static int hf_cip_ssupervisor_configure_lock_tunid_nodeid
;
128 static int hf_cip_ssupervisor_mode_change_value
;
129 static int hf_cip_ssupervisor_mode_change_password
;
130 static int hf_cip_ssupervisor_reset_type
;
131 static int hf_cip_ssupervisor_reset_password
;
132 static int hf_cip_ssupervisor_reset_tunid
;
133 static int hf_cip_ssupervisor_reset_tunid_tunid_snn_timestamp
;
134 static int hf_cip_ssupervisor_reset_tunid_tunid_snn_date
;
135 static int hf_cip_ssupervisor_reset_tunid_tunid_snn_time
;
136 static int hf_cip_ssupervisor_reset_tunid_nodeid
;
137 static int hf_cip_ssupervisor_reset_attr_bitmap
;
138 static int hf_cip_ssupervisor_reset_attr_bitmap_macid
;
139 static int hf_cip_ssupervisor_reset_attr_bitmap_baudrate
;
140 static int hf_cip_ssupervisor_reset_attr_bitmap_tunid
;
141 static int hf_cip_ssupervisor_reset_attr_bitmap_password
;
142 static int hf_cip_ssupervisor_reset_attr_bitmap_cfunid
;
143 static int hf_cip_ssupervisor_reset_attr_bitmap_ocpunid
;
144 static int hf_cip_ssupervisor_reset_attr_bitmap_reserved
;
145 static int hf_cip_ssupervisor_reset_attr_bitmap_extended
;
146 static int hf_cip_ssupervisor_reset_password_data_size
;
147 static int hf_cip_ssupervisor_reset_password_data
;
148 static int hf_cip_ssupervisor_propose_tunid_tunid
;
149 static int hf_cip_ssupervisor_propose_tunid_tunid_snn_timestamp
;
150 static int hf_cip_ssupervisor_propose_tunid_tunid_snn_date
;
151 static int hf_cip_ssupervisor_propose_tunid_tunid_snn_time
;
152 static int hf_cip_ssupervisor_propose_tunid_tunid_nodeid
;
153 static int hf_cip_ssupervisor_apply_tunid_tunid
;
154 static int hf_cip_ssupervisor_apply_tunid_tunid_snn_timestamp
;
155 static int hf_cip_ssupervisor_apply_tunid_tunid_snn_date
;
156 static int hf_cip_ssupervisor_apply_tunid_tunid_snn_time
;
157 static int hf_cip_ssupervisor_apply_tunid_tunid_nodeid
;
159 static int hf_cip_ssupervisor_class_subclass
;
160 static int hf_cip_ssupervisor_num_attr
;
161 static int hf_cip_ssupervisor_attr_list
;
162 static int hf_cip_ssupervisor_manufacture_name
;
163 static int hf_cip_ssupervisor_manufacture_model_number
;
164 static int hf_cip_ssupervisor_sw_rev_level
;
165 static int hf_cip_ssupervisor_hw_rev_level
;
166 static int hf_cip_ssupervisor_manufacture_serial_number
;
167 static int hf_cip_ssupervisor_device_config
;
168 static int hf_cip_ssupervisor_device_status
;
169 static int hf_cip_ssupervisor_exception_status
;
170 static int hf_cip_ssupervisor_exception_detail_ced_size
;
171 static int hf_cip_ssupervisor_exception_detail_ced_detail
;
172 static int hf_cip_ssupervisor_exception_detail_ded_size
;
173 static int hf_cip_ssupervisor_exception_detail_ded_detail
;
174 static int hf_cip_ssupervisor_exception_detail_med_size
;
175 static int hf_cip_ssupervisor_exception_detail_med_detail
;
176 static int hf_cip_ssupervisor_alarm_enable
;
177 static int hf_cip_ssupervisor_warning_enable
;
178 static int hf_cip_ssupervisor_time
;
179 static int hf_cip_ssupervisor_clock_power_cycle_behavior
;
180 static int hf_cip_ssupervisor_last_maintenance_date
;
181 static int hf_cip_ssupervisor_next_scheduled_maintenance_date
;
182 static int hf_cip_ssupervisor_scheduled_maintenance_expiration_timer
;
183 static int hf_cip_ssupervisor_scheduled_maintenance_expiration_warning_enable
;
184 static int hf_cip_ssupervisor_run_hours
;
185 static int hf_cip_ssupervisor_configuration_lock
;
186 static int hf_cip_ssupervisor_configuration_unid_snn_timestamp
;
187 static int hf_cip_ssupervisor_configuration_unid_snn_date
;
188 static int hf_cip_ssupervisor_configuration_unid_snn_time
;
189 static int hf_cip_ssupervisor_configuration_unid_nodeid
;
190 static int hf_cip_ssupervisor_safety_configuration_id_snn_timestamp
;
191 static int hf_cip_ssupervisor_safety_configuration_id_snn_date
;
192 static int hf_cip_ssupervisor_safety_configuration_id_snn_time
;
193 static int hf_cip_ssupervisor_safety_configuration_id_sccrc
;
194 static int hf_cip_ssupervisor_target_unid_snn_timestamp
;
195 static int hf_cip_ssupervisor_target_unid_snn_date
;
196 static int hf_cip_ssupervisor_target_unid_snn_time
;
197 static int hf_cip_ssupervisor_target_unid_nodeid
;
198 static int hf_cip_ssupervisor_cp_owners_num_entries
;
199 static int hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_timestamp
;
200 static int hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_date
;
201 static int hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_time
;
202 static int hf_cip_ssupervisor_output_cp_owners_ocpunid_nodeid
;
203 static int hf_cip_ssupervisor_cp_owners_app_path_size
;
204 static int hf_cip_ssupervisor_proposed_tunid_snn_timestamp
;
205 static int hf_cip_ssupervisor_proposed_tunid_snn_date
;
206 static int hf_cip_ssupervisor_proposed_tunid_snn_time
;
207 static int hf_cip_ssupervisor_proposed_tunid_nodeid
;
208 static int hf_cip_ssupervisor_instance_subclass
;
211 /* Safety Validator header field identifiers */
212 static int hf_cip_svalidator_sc
;
214 static int hf_cip_svalidator_sconn_fault_count
;
215 static int hf_cip_svalidator_state
;
216 static int hf_cip_svalidator_type
;
217 static int hf_cip_svalidator_type_pc
;
218 static int hf_cip_svalidator_type_conn_type
;
219 static int hf_cip_svalidator_ping_epi
;
220 static int hf_cip_svalidator_time_coord_msg_min_mult_size
;
221 static int hf_cip_svalidator_time_coord_msg_min_mult_item
;
222 static int hf_cip_svalidator_network_time_multiplier_size
;
223 static int hf_cip_svalidator_network_time_multiplier_item
;
224 static int hf_cip_svalidator_timeout_multiplier_size
;
225 static int hf_cip_svalidator_timeout_multiplier_item
;
226 static int hf_cip_svalidator_max_consumer_num
;
227 static int hf_cip_svalidator_data_conn_inst
;
228 static int hf_cip_svalidator_coordination_conn_inst_size
;
229 static int hf_cip_svalidator_coordination_conn_inst_item
;
230 static int hf_cip_svalidator_correction_conn_inst
;
231 static int hf_cip_svalidator_cco_binding
;
232 static int hf_cip_svalidator_max_data_age
;
233 static int hf_cip_svalidator_error_code
;
234 static int hf_cip_svalidator_prod_cons_fault_count_size
;
235 static int hf_cip_svalidator_prod_cons_fault_count_item
;
237 static int hf_cip_sercosiii_link_snn
;
238 static int hf_cip_sercosiii_link_communication_cycle_time
;
239 static int hf_cip_sercosiii_link_interface_status
;
240 static int hf_cip_sercosiii_link_error_count_mstps
;
241 static int hf_cip_sercosiii_link_sercos_address
;
242 static int hf_cip_sercosiii_link_error_count_p1
;
243 static int hf_cip_sercosiii_link_error_count_p2
;
245 /* Initialize the subtree pointers */
246 static int ett_cip_safety
;
248 static int ett_cipsafety_mode_byte
;
249 static int ett_cipsafety_ack_byte
;
250 static int ett_cipsafety_mcast_byte
;
252 static int ett_cip_class_s_supervisor
;
253 static int ett_ssupervisor_rrsc
;
254 static int ett_ssupervisor_cmd_data
;
255 static int ett_ssupervisor_propose_tunid
;
256 static int ett_ssupervisor_propose_tunid_snn
;
257 static int ett_ssupervisor_configure_request_tunid
;
258 static int ett_ssupervisor_configure_request_tunid_snn
;
259 static int ett_ssupervisor_configure_request_ounid
;
260 static int ett_ssupervisor_configure_request_ounid_snn
;
261 static int ett_ssupervisor_configure_lock_tunid
;
262 static int ett_ssupervisor_configure_lock_tunid_snn
;
263 static int ett_ssupervisor_reset_tunid
;
264 static int ett_ssupervisor_reset_tunid_snn
;
265 static int ett_ssupervisor_apply_tunid
;
266 static int ett_ssupervisor_apply_tunid_snn
;
267 static int ett_exception_detail_common
;
268 static int ett_exception_detail_device
;
269 static int ett_exception_detail_manufacturer
;
270 static int ett_ssupervisor_configuration_unid
;
271 static int ett_ssupervisor_configuration_unid_snn
;
272 static int ett_ssupervisor_target_unid
;
273 static int ett_ssupervisor_target_unid_snn
;
274 static int ett_ssupervisor_output_cp_owners
;
275 static int ett_ssupervisor_output_cp_owners_ocpunid
;
276 static int ett_ssupervisor_output_cp_owners_ocpunid_snn
;
277 static int ett_ssupervisor_proposed_tunid
;
278 static int ett_ssupervisor_proposed_tunid_snn
;
279 static int ett_cip_ssupervisor_reset_attr_bitmap
;
281 static int ett_cip_class_s_validator
;
282 static int ett_svalidator_rrsc
;
283 static int ett_svalidator_cmd_data
;
284 static int ett_svalidator_type
;
286 static expert_field ei_cipsafety_tbd_not_complemented
;
287 static expert_field ei_cipsafety_tbd2_not_copied
;
288 static expert_field ei_cipsafety_run_idle_not_complemented
;
289 static expert_field ei_mal_io
;
290 static expert_field ei_mal_sercosiii_link_error_count_p1p2
;
291 static expert_field ei_cipsafety_not_complement_data
;
292 static expert_field ei_cipsafety_crc_s1
;
293 static expert_field ei_cipsafety_crc_s2
;
294 static expert_field ei_cipsafety_crc_s3
;
295 static expert_field ei_cipsafety_complement_crc_s3
;
296 static expert_field ei_cipsafety_crc_s5
;
298 static expert_field ei_mal_ssupervisor_exception_detail_ced
;
299 static expert_field ei_mal_ssupervisor_exception_detail_ded
;
300 static expert_field ei_mal_ssupervisor_exception_detail_med
;
301 static expert_field ei_mal_ssupervisor_configuration_unid
;
302 static expert_field ei_mal_ssupervisor_safety_configuration_id
;
303 static expert_field ei_mal_ssupervisor_target_unid
;
304 static expert_field ei_mal_ssupervisor_cp_owners
;
305 static expert_field ei_mal_ssupervisor_cp_owners_entry
;
306 static expert_field ei_mal_ssupervisor_cp_owners_app_path_size
;
307 static expert_field ei_mal_ssupervisor_proposed_tunid
;
308 static expert_field ei_info_ssupervisor_tunid_cancel
;
310 static expert_field ei_mal_svalidator_type
;
311 static expert_field ei_mal_svalidator_time_coord_msg_min_mult
;
312 static expert_field ei_mal_svalidator_network_time_multiplier
;
313 static expert_field ei_mal_svalidator_timeout_multiplier
;
314 static expert_field ei_mal_svalidator_coordination_conn_inst
;
315 static expert_field ei_mal_svalidator_prod_cons_fault_count
;
317 static dissector_handle_t cipsafety_handle
;
318 static dissector_handle_t cipsafety_base_data_handle
;
319 static dissector_handle_t cipsafety_extended_data_handle
;
320 static dissector_handle_t cipsafety_base_time_coord_handle
;
321 static dissector_handle_t cipsafety_extended_time_coord_handle
;
323 typedef struct cip_safety_packet_data
{
324 uint16_t rollover_value
;
325 } cip_safety_packet_data_t
;
327 #define MODE_BYTE_CRC_S1_MASK 0xE0
328 #define MODE_BYTE_CRC_S1_TIME_STAMP_MASK 0x1F
329 #define MODE_BYTE_CRC_S3_MASK 0xE0
330 #define MODE_BYTE_CRC_S5_BASE_MASK 0xE0
331 #define MODE_BYTE_CRC_S5_EXTENDED_MASK 0x1F
333 const value_string cipsafety_snn_date_vals
[8] = {
336 { 1, "Manual Setting - Backplane" },
337 { 2, "Manual Setting - ControlNet" },
338 { 4, "Manual Setting - EtherNet/IP" },
339 { 5, "Manual Setting - DeviceNet" },
340 { 6, "Manual Setting - SERCOS III" },
341 { 65535, "No SNN Set" },
346 static const true_false_string cip_safety_vals_active_idle
= {
351 /* Translate function to string - CIP Service codes for Safety Supervisor */
352 static const value_string cip_sc_vals_ssupervisor
[] = {
355 /* Some class specific services */
356 { SC_SSUPER_RECOVER
, "Recover" },
357 { SC_SSUPER_PERFORM_DIAGNOSTICS
, "Perform Diagnostics" },
358 { SC_SSUPER_CONFIGURE_REQUEST
, "Configure Request" },
359 { SC_SSUPER_VALIDATE_CONFIGURATION
, "Validate Configuration" },
360 { SC_SSUPER_SET_PASSWORD
, "Set Password" },
361 { SC_SSUPER_CONFIGURATION_LOCK
, "Configuration (Un)Lock" },
362 { SC_SSUPER_MODE_CHANGE
, "Mode Change" },
363 { SC_SSUPER_SAFETY_RESET
, "Safety Reset" },
364 { SC_SSUPER_RESET_PASSWORD
, "Reset Password" },
365 { SC_SSUPER_PROPOSE_TUNID
, "Propose TUNID" },
366 { SC_SSUPER_APPLY_TUNID
, "Apply TUNID" },
367 { SC_SSUPER_PROPOSE_TUNID_LIST
, "Propose TUNID List" },
368 { SC_SSUPER_APPLY_TUNID_LIST
, "Apply TUNID List" },
373 #define SC_SVALID_RESET_ERROR 0x4B
375 /* Translate function to string - CIP Service codes for Safety Validator */
376 static const value_string cip_sc_vals_svalidator
[] = {
379 /* Some class specific services */
380 { SC_SVALID_RESET_ERROR
, "Reset Error" },
385 static const value_string cip_ssupervisor_validate_configuration_ext_error_vals
[] = {
386 { 1, "CRC mismatch" },
387 { 2, "Invalid Configuration Parameter" },
388 { 3, "TUNID Not Set" },
393 static const value_string cip_ssupervisor_lock_vals
[] = {
400 static const value_string cip_ssupervisor_change_mode_vals
[] = {
407 static const value_string cip_ssupervisor_device_status_type_vals
[] = {
409 { 1, "Self-Testing" },
411 { 3, "Self-Test Exception" },
414 { 6, "Critical Fault" },
415 { 7, "Configuring" },
416 { 8, "Waiting for TUNID" },
417 { 51, "Waiting for TUNID with Torque Permitted" },
418 { 52, "Executing with Torque Permitted" },
423 static const value_string cip_ssupervisor_clock_power_cycle_type_vals
[] = {
424 { 0, "Clock always resets" },
425 { 1, "Clock in NVS at power down" },
426 { 2, "Clock is battery-backed" },
431 static const value_string cip_svalidator_state_vals
[] = {
432 { 0, "Unallocated" },
433 { 1, "Initializing" },
434 { 2, "Established" },
435 { 3, "Connection failed" },
440 static const value_string cip_svalidator_type_pc_vals
[] = {
447 static const value_string cip_svalidator_type_conn_type_vals
[] = {
448 { 0, "Unallocated" },
449 { 1, "Single-cast" },
455 const range_string safety_max_consumer_numbers
[] = {
456 { 1, 1, "Single-cast" },
457 { 2, 15, "Multicast" },
462 enum message_encoding_type
{
463 MSG_ENCODING_BASE_1_2_BYTE_DATA
,
464 MSG_ENCODING_EXTENDED_1_2_BYTE_DATA
,
465 MSG_ENCODING_BASE_3_250_BYTE_DATA
,
466 MSG_ENCODING_EXTENDED_3_250_BYTE_DATA
,
467 MSG_ENCODING_BASE_TIME_STAMP
,
468 MSG_ENCODING_BASE_TIME_COORDINATION
,
469 MSG_ENCODING_EXTENDED_TIME_COORDINATION
,
470 MSG_ENCODING_BASE_TIME_CORRECTION
,
471 MSG_ENCODING_EXTENDED_TIME_CORRECTION
,
474 static const value_string safety_message_encoding_vals
[] = {
475 { MSG_ENCODING_BASE_1_2_BYTE_DATA
, "Base Format, 1 or 2 Byte Data Section" },
476 { MSG_ENCODING_EXTENDED_1_2_BYTE_DATA
, "Extended Format, 1 or 2 Byte Data Section" },
477 { MSG_ENCODING_BASE_3_250_BYTE_DATA
, "Base Format, 3 to 250 Byte Data Section" },
478 { MSG_ENCODING_EXTENDED_3_250_BYTE_DATA
, "Extended Format, 3 to 250 Byte Data Section" },
479 { MSG_ENCODING_BASE_TIME_STAMP
, "Base Format, Time Stamp Section" },
480 { MSG_ENCODING_BASE_TIME_COORDINATION
, "Base Format, Time Coordination Section" },
481 { MSG_ENCODING_EXTENDED_TIME_COORDINATION
, "Extended Format, Time Coordination Section" },
482 { MSG_ENCODING_BASE_TIME_CORRECTION
, "Base Format, Time Correction Section" },
483 { MSG_ENCODING_EXTENDED_TIME_CORRECTION
, "Extended Format, Time Correction Section" },
488 void cip_safety_128us_fmt(char *s
, uint32_t value
)
490 // Each tick is 128us.
491 snprintf(s
, ITEM_LABEL_LENGTH
, "%d (%.3fms)", value
, value
* 0.128);
495 dissect_unid(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_item
*pi
,
496 const char* snn_name
, int hf_snn_timestamp
,
497 int hf_snn_date
, int hf_snn_time
, int hf_nodeid
, int ett
, int ett_snn
)
499 proto_tree
*tree
, *snn_tree
;
501 tree
= proto_item_add_subtree(pi
, ett
);
503 snn_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 6, ett_snn
, NULL
, snn_name
);
504 dissect_cipsafety_snn(snn_tree
, tvb
, pinfo
, offset
, hf_snn_timestamp
, hf_snn_date
, hf_snn_time
);
506 proto_tree_add_item(tree
, hf_nodeid
, tvb
, offset
+6, 4, ENC_LITTLE_ENDIAN
);
509 void dissect_cipsafety_snn(proto_tree
*tree
, tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
,
510 int hf_real_datetime
, int hf_date
, int hf_time
)
514 date
= tvb_get_letohs(tvb
, offset
+4);
516 if ((date
>= 11688) && (date
<= 65534))
518 /* value is an actual timestamp */
519 dissect_cip_date_and_time(tree
, tvb
, offset
, hf_real_datetime
);
523 /* Treated as UINT16 and UINT32 values */
524 proto_tree_add_item(tree
, hf_time
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
525 proto_tree_add_item(tree
, hf_date
, tvb
, offset
+ 4, 2, ENC_LITTLE_ENDIAN
);
529 static void dissect_safety_supervisor_safety_reset(proto_tree
* cmd_data_tree
, tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
)
532 proto_tree_add_item_ret_uint(cmd_data_tree
, hf_cip_ssupervisor_reset_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &reset_type
);
534 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_reset_password
, tvb
, offset
+ 1, 16, ENC_NA
);
535 proto_item
* pi
= proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_reset_tunid
, tvb
, offset
+ 17, 10, ENC_NA
);
536 dissect_unid(tvb
, pinfo
, offset
+ 17, pi
, "TUNID SNN",
537 hf_cip_ssupervisor_reset_tunid_tunid_snn_timestamp
,
538 hf_cip_ssupervisor_reset_tunid_tunid_snn_date
,
539 hf_cip_ssupervisor_reset_tunid_tunid_snn_time
,
540 hf_cip_ssupervisor_reset_tunid_nodeid
,
541 ett_ssupervisor_reset_tunid
,
542 ett_ssupervisor_reset_tunid_snn
);
544 /* Attribute bitmap only included on Reset Type 2 */
547 pi
= proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_reset_attr_bitmap
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
549 proto_tree
* bitmap_tree
= proto_item_add_subtree(pi
, ett_cip_ssupervisor_reset_attr_bitmap
);
550 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_macid
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
551 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_baudrate
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
552 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_tunid
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
553 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_password
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
554 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_cfunid
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
555 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_ocpunid
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
556 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_reserved
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
557 proto_tree_add_item(bitmap_tree
, hf_cip_ssupervisor_reset_attr_bitmap_extended
, tvb
, offset
+ 27, 1, ENC_LITTLE_ENDIAN
);
561 static void detect_cancel_propose_apply_operation(tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_item
* item
)
563 // Check for all FFs.
564 uint64_t part1
= tvb_get_uint64(tvb
, offset
, ENC_LITTLE_ENDIAN
);
565 uint16_t part2
= tvb_get_uint16(tvb
, offset
+ 8, ENC_LITTLE_ENDIAN
);
566 if (part1
== 0xFFFFFFFFFFFFFFFF && part2
== 0xFFFF)
568 expert_add_info(pinfo
, item
, &ei_info_ssupervisor_tunid_cancel
);
572 /************************************************
574 * Dissector for CIP Safety Supervisor Object
576 ************************************************/
578 dissect_cip_s_supervisor_data( proto_tree
*item_tree
,
579 tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
)
581 proto_item
*pi
, *rrsc_item
;
582 proto_tree
*rrsc_tree
, *cmd_data_tree
;
585 uint8_t service
, gen_status
, add_stat_size
;
586 cip_simple_request_info_t req_data
;
588 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIPS Supervisor");
590 /* Add Service code & Request/Response tree */
591 service
= tvb_get_uint8( tvb
, offset
);
592 rrsc_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
, 1, ett_ssupervisor_rrsc
, &rrsc_item
, "Service: " );
594 /* Add Request/Response */
595 proto_tree_add_item( rrsc_tree
, hf_cip_reqrsp
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
597 proto_item_append_text( rrsc_item
, "%s (%s)",
598 val_to_str( ( service
& CIP_SC_MASK
), cip_sc_vals_ssupervisor
, "Unknown Service (0x%02x)"),
599 val_to_str_const( ( service
& CIP_SC_RESPONSE_MASK
)>>7, cip_sc_rr
, "") );
601 /* Add Service code */
602 proto_tree_add_item(rrsc_tree
, hf_cip_ssupervisor_sc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
604 load_cip_request_data(pinfo
, &req_data
);
606 if (service
& CIP_SC_RESPONSE_MASK
)
608 /* Response message */
610 /* Add additional status size */
611 gen_status
= tvb_get_uint8( tvb
, offset
+2 );
612 add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
614 /* If there is any command specific data create a sub-tree for it */
615 if( ( item_length
-4-add_stat_size
) != 0 )
617 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+4+add_stat_size
,
618 item_length
-4-add_stat_size
, ett_ssupervisor_cmd_data
, NULL
, "Command Specific Data" );
620 if( gen_status
== CI_GRC_SUCCESS
)
622 switch (service
& CIP_SC_MASK
)
624 case SC_SSUPER_VALIDATE_CONFIGURATION
:
625 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_validate_configuration_sccrc
,
626 tvb
, offset
+4+add_stat_size
, 4, ENC_LITTLE_ENDIAN
);
627 dissect_cipsafety_snn(cmd_data_tree
,
628 tvb
, pinfo
, offset
+4+add_stat_size
+4,
629 hf_cip_ssupervisor_validate_configuration_scts_timestamp
,
630 hf_cip_ssupervisor_validate_configuration_scts_date
,
631 hf_cip_ssupervisor_validate_configuration_scts_time
);
635 else if ((gen_status
== 0xD0) && ((service
& CIP_SC_MASK
) == SC_SSUPER_VALIDATE_CONFIGURATION
))
637 if (add_stat_size
> 0)
639 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_validate_configuration_ext_error
,
640 tvb
, offset
+4, 2, ENC_LITTLE_ENDIAN
);
645 /* Error responses */
648 proto_tree_add_item(cmd_data_tree
, hf_cip_data
,
649 tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
653 } /* End of if reply */
656 /* Request message */
658 req_path_size
= tvb_get_uint8( tvb
, offset
+1 )*2;
660 /* If there is any command specific data create a sub-tree for it */
661 if( (item_length
-req_path_size
-2) != 0 )
663 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2,
664 ett_ssupervisor_cmd_data
, NULL
, "Command Specific Data" );
666 /* Check what service code that received */
669 case SC_SSUPER_RECOVER
:
670 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_recover_data
,
671 tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
673 case SC_SSUPER_PERFORM_DIAGNOSTICS
:
674 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_perform_diag_data
,
675 tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
677 case SC_SSUPER_CONFIGURE_REQUEST
:
678 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_configure_request_password
,
679 tvb
, offset
+2+req_path_size
, 16, ENC_NA
);
680 pi
= proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_configure_request_tunid
,
681 tvb
, offset
+2+req_path_size
+16, 10, ENC_NA
);
682 dissect_unid(tvb
, pinfo
, offset
+2+req_path_size
+16, pi
, "TUNID SNN",
683 hf_cip_ssupervisor_configure_request_tunid_snn_timestamp
,
684 hf_cip_ssupervisor_configure_request_tunid_snn_date
,
685 hf_cip_ssupervisor_configure_request_tunid_snn_time
,
686 hf_cip_ssupervisor_configure_request_tunid_nodeid
,
687 ett_ssupervisor_configure_request_tunid
,
688 ett_ssupervisor_configure_request_tunid_snn
);
689 pi
= proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_configure_request_ounid
,
690 tvb
, offset
+2+req_path_size
+26, 10, ENC_NA
);
691 dissect_unid(tvb
, pinfo
, offset
+2+req_path_size
+16, pi
, "OUNID SNN",
692 hf_cip_ssupervisor_configure_request_ounid_snn_timestamp
,
693 hf_cip_ssupervisor_configure_request_ounid_snn_date
,
694 hf_cip_ssupervisor_configure_request_ounid_snn_time
,
695 hf_cip_ssupervisor_configure_request_ounid_nodeid
,
696 ett_ssupervisor_configure_request_ounid
,
697 ett_ssupervisor_configure_request_ounid_snn
);
699 case SC_SSUPER_VALIDATE_CONFIGURATION
:
700 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_validate_configuration_sccrc
,
701 tvb
, offset
+2+req_path_size
, 4, ENC_LITTLE_ENDIAN
);
702 dissect_cipsafety_snn(cmd_data_tree
, tvb
, pinfo
, offset
+2+req_path_size
+4,
703 hf_cip_ssupervisor_validate_configuration_scts_timestamp
,
704 hf_cip_ssupervisor_validate_configuration_scts_date
,
705 hf_cip_ssupervisor_validate_configuration_scts_time
);
707 case SC_SSUPER_SET_PASSWORD
:
708 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_set_password_current_password
,
709 tvb
, offset
+2+req_path_size
, 16, ENC_NA
);
710 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_set_password_new_password
,
711 tvb
, offset
+2+req_path_size
+16, 16, ENC_NA
);
713 case SC_SSUPER_CONFIGURATION_LOCK
:
714 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_configure_lock_value
,
715 tvb
, offset
+2+req_path_size
, 1, ENC_LITTLE_ENDIAN
);
716 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_configure_lock_password
,
717 tvb
, offset
+2+req_path_size
+1, 16, ENC_NA
);
718 pi
= proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_configure_lock_tunid
,
719 tvb
, offset
+2+req_path_size
+17, 10, ENC_NA
);
720 dissect_unid(tvb
, pinfo
, offset
+2+req_path_size
+17, pi
, "TUNID SNN",
721 hf_cip_ssupervisor_configure_lock_tunid_snn_timestamp
,
722 hf_cip_ssupervisor_configure_lock_tunid_snn_date
,
723 hf_cip_ssupervisor_configure_lock_tunid_snn_time
,
724 hf_cip_ssupervisor_configure_lock_tunid_nodeid
,
725 ett_ssupervisor_configure_lock_tunid
,
726 ett_ssupervisor_configure_lock_tunid_snn
);
728 case SC_SSUPER_MODE_CHANGE
:
729 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_mode_change_value
,
730 tvb
, offset
+2+req_path_size
, 1, ENC_LITTLE_ENDIAN
);
731 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_mode_change_password
,
732 tvb
, offset
+2+req_path_size
+1, 16, ENC_NA
);
734 case SC_SSUPER_SAFETY_RESET
:
735 dissect_safety_supervisor_safety_reset(cmd_data_tree
, tvb
, offset
+ 2 + req_path_size
, pinfo
);
737 case SC_SSUPER_RESET_PASSWORD
:
738 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_reset_password_data_size
,
739 tvb
, offset
+2+req_path_size
, 1, ENC_LITTLE_ENDIAN
);
740 temp_data
= tvb_get_uint8(tvb
, offset
+2+req_path_size
);
741 proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_reset_password_data
,
742 tvb
, offset
+2+req_path_size
+1, temp_data
, ENC_NA
);
744 case SC_SSUPER_PROPOSE_TUNID
:
745 pi
= proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_propose_tunid_tunid
,
746 tvb
, offset
+2+req_path_size
, 10, ENC_NA
);
747 dissect_unid(tvb
, pinfo
, offset
+2+req_path_size
, pi
, "TUNID SNN",
748 hf_cip_ssupervisor_propose_tunid_tunid_snn_timestamp
,
749 hf_cip_ssupervisor_propose_tunid_tunid_snn_date
,
750 hf_cip_ssupervisor_propose_tunid_tunid_snn_time
,
751 hf_cip_ssupervisor_propose_tunid_tunid_nodeid
,
752 ett_ssupervisor_propose_tunid
,
753 ett_ssupervisor_propose_tunid_snn
);
755 detect_cancel_propose_apply_operation(tvb
, offset
+ 2 + req_path_size
, pinfo
, pi
);
757 case SC_SSUPER_APPLY_TUNID
:
758 pi
= proto_tree_add_item(cmd_data_tree
, hf_cip_ssupervisor_apply_tunid_tunid
,
759 tvb
, offset
+2+req_path_size
, 10, ENC_NA
);
760 dissect_unid(tvb
, pinfo
, offset
+2+req_path_size
, pi
, "TUNID SNN",
761 hf_cip_ssupervisor_apply_tunid_tunid_snn_timestamp
,
762 hf_cip_ssupervisor_apply_tunid_tunid_snn_date
,
763 hf_cip_ssupervisor_apply_tunid_tunid_snn_time
,
764 hf_cip_ssupervisor_apply_tunid_tunid_nodeid
,
765 ett_ssupervisor_apply_tunid
,
766 ett_ssupervisor_apply_tunid_snn
);
768 detect_cancel_propose_apply_operation(tvb
, offset
+ 2 + req_path_size
, pinfo
, pi
);
771 proto_tree_add_item(cmd_data_tree
, hf_cip_data
,
772 tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
775 } /* End of if command-specific data present */
777 } /* End of if-else( request ) */
779 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals_ssupervisor
);
783 dissect_cip_class_s_supervisor(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
786 proto_tree
*class_tree
;
788 /* Create display subtree for the protocol */
789 ti
= proto_tree_add_item(tree
, proto_cip_class_s_supervisor
, tvb
, 0, -1, ENC_NA
);
790 class_tree
= proto_item_add_subtree( ti
, ett_cip_class_s_supervisor
);
792 dissect_cip_s_supervisor_data( class_tree
, tvb
, 0, tvb_reported_length(tvb
), pinfo
);
794 return tvb_reported_length(tvb
);
797 static int dissect_s_supervisor_exception_detail(proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
, int hf_size
, int hf_data
)
800 proto_tree_add_item_ret_uint(tree
, hf_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &size
);
802 proto_tree_add_item(tree
, hf_data
, tvb
, offset
+1, size
, ENC_NA
);
803 proto_item_set_len(item
, size
+1);
808 static int dissect_s_supervisor_exception_detail_common(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
809 int offset
, int total_len
)
812 proto_tree
*item_tree
;
813 int total_size
= 0, size
;
815 item_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 1, ett_exception_detail_common
, &pi
, "Common Exception Detail");
816 size
= dissect_s_supervisor_exception_detail(item_tree
, pi
, tvb
, offset
,
817 hf_cip_ssupervisor_exception_detail_ced_size
,
818 hf_cip_ssupervisor_exception_detail_ced_detail
);
821 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_exception_detail_ced
);
826 item_tree
= proto_tree_add_subtree(tree
, tvb
, offset
+ total_size
, 1, ett_exception_detail_device
, &pi
, "Device Exception Detail");
827 size
= dissect_s_supervisor_exception_detail(item_tree
, pi
, tvb
, offset
+ total_size
,
828 hf_cip_ssupervisor_exception_detail_ded_size
,
829 hf_cip_ssupervisor_exception_detail_ded_detail
);
832 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_exception_detail_ded
);
837 item_tree
= proto_tree_add_subtree(tree
, tvb
, offset
+ total_size
, 1, ett_exception_detail_manufacturer
, &pi
, "Manufacturer Exception Detail");
838 size
= dissect_s_supervisor_exception_detail(item_tree
, pi
, tvb
, offset
+ total_size
,
839 hf_cip_ssupervisor_exception_detail_med_size
,
840 hf_cip_ssupervisor_exception_detail_med_detail
);
843 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_exception_detail_med
);
851 static int dissect_s_supervisor_configuration_unid(packet_info
*pinfo
, proto_tree
*tree _U_
, proto_item
*item
,
852 tvbuff_t
*tvb
, int offset
, int total_len
)
856 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_configuration_unid
);
860 dissect_unid(tvb
, pinfo
, offset
, item
, "CFUNID SNN",
861 hf_cip_ssupervisor_configuration_unid_snn_timestamp
,
862 hf_cip_ssupervisor_configuration_unid_snn_date
,
863 hf_cip_ssupervisor_configuration_unid_snn_time
,
864 hf_cip_ssupervisor_configuration_unid_nodeid
,
865 ett_ssupervisor_configuration_unid
,
866 ett_ssupervisor_configuration_unid_snn
);
870 static int dissect_s_supervisor_safety_configuration_id(packet_info
*pinfo
, proto_tree
*tree _U_
, proto_item
*item
,
871 tvbuff_t
*tvb
, int offset
, int total_len
)
875 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_safety_configuration_id
);
879 proto_tree_add_item(tree
, hf_cip_ssupervisor_safety_configuration_id_sccrc
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
881 dissect_cipsafety_snn(tree
, tvb
, pinfo
, offset
+ 4,
882 hf_cip_ssupervisor_safety_configuration_id_snn_timestamp
,
883 hf_cip_ssupervisor_safety_configuration_id_snn_date
,
884 hf_cip_ssupervisor_safety_configuration_id_snn_time
);
889 static int dissect_s_supervisor_target_unid(packet_info
*pinfo
, proto_tree
*tree _U_
, proto_item
*item
,
890 tvbuff_t
*tvb
, int offset
, int total_len
)
894 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_target_unid
);
898 dissect_unid(tvb
, pinfo
, offset
, item
, "TUNID SNN",
899 hf_cip_ssupervisor_target_unid_snn_timestamp
,
900 hf_cip_ssupervisor_target_unid_snn_date
,
901 hf_cip_ssupervisor_target_unid_snn_time
,
902 hf_cip_ssupervisor_target_unid_nodeid
,
903 ett_ssupervisor_target_unid
,
904 ett_ssupervisor_target_unid_snn
);
908 static int dissect_s_supervisor_output_connection_point_owners(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
,
909 tvbuff_t
*tvb
, int offset
, int total_len
)
911 uint16_t i
, num_entries
;
912 proto_item
*entry_item
, *app_path_item
;
913 proto_tree
*entry_tree
, *epath_tree
;
914 int attr_len
= 0, app_path_size
;
918 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_cp_owners
);
922 entry_item
= proto_tree_add_item(tree
, hf_cip_ssupervisor_cp_owners_num_entries
,
923 tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
924 num_entries
= tvb_get_letohs(tvb
, offset
);
929 entry_tree
= proto_item_add_subtree(entry_item
, ett_ssupervisor_output_cp_owners
);
931 for (i
= 0; i
< num_entries
; i
++)
933 if (total_len
< attr_len
+11)
935 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_cp_owners_entry
);
939 dissect_unid(tvb
, pinfo
, offset
+attr_len
, entry_item
, "OCPUNID SNN",
940 hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_timestamp
,
941 hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_date
,
942 hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_time
,
943 hf_cip_ssupervisor_output_cp_owners_ocpunid_nodeid
,
944 ett_ssupervisor_output_cp_owners_ocpunid
,
945 ett_ssupervisor_output_cp_owners_ocpunid_snn
);
948 proto_tree_add_item(entry_tree
, hf_cip_ssupervisor_cp_owners_app_path_size
,
949 tvb
, offset
+attr_len
, 1, ENC_LITTLE_ENDIAN
);
950 app_path_size
= tvb_get_uint8( tvb
, offset
+attr_len
);
953 if (total_len
< attr_len
+app_path_size
)
955 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_cp_owners_app_path_size
);
959 epath_tree
= proto_tree_add_subtree(entry_tree
,
960 tvb
, offset
+attr_len
, app_path_size
, ett_path
, &app_path_item
, "Application Resource: ");
961 dissect_epath(tvb
, pinfo
, epath_tree
, app_path_item
, offset
+attr_len
, app_path_size
, false, true, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
962 attr_len
+= app_path_size
;
969 static int dissect_s_supervisor_proposed_tunid(packet_info
*pinfo
, proto_tree
*tree _U_
, proto_item
*item
,
970 tvbuff_t
*tvb
, int offset
, int total_len
)
974 expert_add_info(pinfo
, item
, &ei_mal_ssupervisor_proposed_tunid
);
978 dissect_unid(tvb
, pinfo
, offset
, item
, "Proposed TUNID SNN",
979 hf_cip_ssupervisor_proposed_tunid_snn_timestamp
,
980 hf_cip_ssupervisor_proposed_tunid_snn_date
,
981 hf_cip_ssupervisor_proposed_tunid_snn_time
,
982 hf_cip_ssupervisor_proposed_tunid_nodeid
,
983 ett_ssupervisor_proposed_tunid
,
984 ett_ssupervisor_proposed_tunid_snn
);
989 /************************************************
991 * Dissector for CIP Safety Validator Object
993 ************************************************/
994 static int dissect_s_validator_type(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
995 int offset
, int total_len
)
999 expert_add_info(pinfo
, item
, &ei_mal_svalidator_type
);
1003 static int* const bits
[] = {
1004 &hf_cip_svalidator_type_pc
,
1005 &hf_cip_svalidator_type_conn_type
,
1008 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_cip_svalidator_type
, ett_svalidator_type
, bits
, ENC_LITTLE_ENDIAN
);
1013 static int dissect_s_validator_time_coord_msg_min_mult(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
,
1014 tvbuff_t
*tvb
, int offset
, int total_len
)
1018 proto_tree_add_item(tree
, hf_cip_svalidator_time_coord_msg_min_mult_size
,
1019 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1020 size
= tvb_get_uint8( tvb
, offset
)*2;
1022 if (total_len
< size
+1)
1024 expert_add_info(pinfo
, item
, &ei_mal_svalidator_time_coord_msg_min_mult
);
1028 for (i
= 0; i
< size
; i
+=2)
1030 proto_tree_add_item(tree
, hf_cip_svalidator_time_coord_msg_min_mult_item
,
1031 tvb
, offset
+1+i
, 2, ENC_LITTLE_ENDIAN
);
1037 static int dissect_s_validator_network_time_multiplier(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
,
1038 tvbuff_t
*tvb
, int offset
, int total_len
)
1042 proto_tree_add_item(tree
, hf_cip_svalidator_network_time_multiplier_size
,
1043 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1044 size
= tvb_get_uint8( tvb
, offset
)*2;
1046 if (total_len
< size
+1)
1048 expert_add_info(pinfo
, item
, &ei_mal_svalidator_network_time_multiplier
);
1052 for (i
= 0; i
< size
; i
+=2)
1054 proto_tree_add_item(tree
, hf_cip_svalidator_network_time_multiplier_item
,
1055 tvb
, offset
+1+i
, 2, ENC_LITTLE_ENDIAN
);
1061 static int dissect_s_validator_timeout_multiplier(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1062 int offset
, int total_len
)
1066 proto_tree_add_item(tree
, hf_cip_svalidator_timeout_multiplier_size
,
1067 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1068 size
= tvb_get_uint8( tvb
, offset
);
1070 if (total_len
< size
+1)
1072 expert_add_info(pinfo
, item
, &ei_mal_svalidator_timeout_multiplier
);
1076 for (i
= 0; i
< size
; i
++)
1078 proto_tree_add_item(tree
, hf_cip_svalidator_timeout_multiplier_item
,
1079 tvb
, offset
+1+i
, 1, ENC_LITTLE_ENDIAN
);
1085 static int dissect_s_validator_coordination_conn_inst(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
,
1086 tvbuff_t
*tvb
, int offset
, int total_len
)
1090 proto_tree_add_item(tree
, hf_cip_svalidator_coordination_conn_inst_size
,
1091 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1092 size
= tvb_get_uint8( tvb
, offset
)*2;
1094 if (total_len
< size
+1)
1096 expert_add_info(pinfo
, item
, &ei_mal_svalidator_coordination_conn_inst
);
1100 for (i
= 0; i
< size
; i
+=2)
1102 proto_tree_add_item(tree
, hf_cip_svalidator_coordination_conn_inst_item
,
1103 tvb
, offset
+1+i
, 2, ENC_LITTLE_ENDIAN
);
1109 static int dissect_s_validator_app_data_path(packet_info
*pinfo
, proto_tree
*tree
,
1110 proto_item
*item _U_
, tvbuff_t
*tvb
, int offset
, int total_len
)
1113 proto_tree
* epath_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_path
, &pi
, "Application Data Path: ");
1114 dissect_epath(tvb
, pinfo
, epath_tree
, pi
, offset
, total_len
, false, false, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
1118 static int dissect_s_validator_prod_cons_fault_count(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
,
1119 tvbuff_t
*tvb
, int offset
, int total_len
)
1123 proto_tree_add_item(tree
, hf_cip_svalidator_prod_cons_fault_count_size
,
1124 tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1125 size
= tvb_get_uint8( tvb
, offset
);
1127 if (total_len
< size
+1)
1129 expert_add_info(pinfo
, item
, &ei_mal_svalidator_prod_cons_fault_count
);
1133 for (i
= 0; i
< size
; i
++)
1135 proto_tree_add_item(tree
, hf_cip_svalidator_prod_cons_fault_count_item
,
1136 tvb
, offset
+1+i
, 1, ENC_LITTLE_ENDIAN
);
1143 dissect_cip_s_validator_data( proto_tree
*item_tree
,
1144 tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
)
1146 proto_item
*pi
, *rrsc_item
;
1147 proto_tree
*rrsc_tree
, *cmd_data_tree
;
1149 uint8_t service
, gen_status
, add_stat_size
;
1150 cip_simple_request_info_t req_data
;
1152 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIPS Validator");
1154 /* Add Service code & Request/Response tree */
1155 service
= tvb_get_uint8( tvb
, offset
);
1156 rrsc_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
, 1, ett_svalidator_rrsc
, &rrsc_item
, "Service: " );
1158 /* Add Request/Response */
1159 proto_tree_add_item( rrsc_tree
, hf_cip_reqrsp
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1161 proto_item_append_text( rrsc_item
, "%s (%s)",
1162 val_to_str( ( service
& CIP_SC_MASK
),
1163 cip_sc_vals_svalidator
, "Unknown Service (0x%02x)"),
1164 val_to_str_const( ( service
& CIP_SC_RESPONSE_MASK
)>>7,
1167 /* Add Service code */
1168 proto_tree_add_item(rrsc_tree
, hf_cip_svalidator_sc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1170 load_cip_request_data(pinfo
, &req_data
);
1172 if (service
& CIP_SC_RESPONSE_MASK
)
1174 /* Response message */
1176 /* Add additional status size */
1177 gen_status
= tvb_get_uint8( tvb
, offset
+2 );
1178 add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
1180 /* If there is any command specific data create a sub-tree for it */
1181 if( ( item_length
-4-add_stat_size
) != 0 )
1183 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
,
1184 ett_ssupervisor_cmd_data
, &pi
, "Command Specific Data" );
1186 if( gen_status
== CI_GRC_SUCCESS
)
1188 /* Success responses */
1189 if (((service
& CIP_SC_MASK
) == SC_GET_ATT_ALL
) &&
1190 (req_data
.iInstance
!= SEGMENT_VALUE_NOT_SET
) &&
1191 (req_data
.iInstance
!= 0))
1193 dissect_cip_get_attribute_all_rsp(tvb
, pinfo
, cmd_data_tree
, offset
+ 4 + add_stat_size
, &req_data
);
1198 proto_tree_add_item(cmd_data_tree
, hf_cip_data
,
1199 tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
1204 /* Error responses */
1207 proto_tree_add_item(cmd_data_tree
, hf_cip_data
,
1208 tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
1209 } /* end of if-else( CI_CRC_SUCCESS ) */
1211 } /* End of if command-specific data present */
1213 } /* End of if reply */
1216 /* Request message */
1218 req_path_size
= tvb_get_uint8( tvb
, offset
+1 )*2;
1220 /* If there is any command specific data create a sub-tree for it */
1221 if( (item_length
-req_path_size
-2) != 0 )
1223 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2,
1224 ett_ssupervisor_cmd_data
, NULL
, "Command Specific Data" );
1225 proto_tree_add_item(cmd_data_tree
, hf_cip_data
,
1226 tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
1231 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals_svalidator
);
1235 dissect_cip_class_s_validator(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1238 proto_tree
*class_tree
;
1240 /* Create display subtree for the protocol */
1241 ti
= proto_tree_add_item(tree
, proto_cip_class_s_validator
, tvb
, 0, -1, ENC_NA
);
1242 class_tree
= proto_item_add_subtree( ti
, ett_cip_class_s_validator
);
1244 dissect_cip_s_validator_data( class_tree
, tvb
, 0, tvb_reported_length(tvb
), pinfo
);
1246 return tvb_reported_length(tvb
);
1250 dissect_class_svalidator_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1252 unsigned char service
, service_code
, ioilen
, segment
;
1253 cip_req_info_t
* preq_info
;
1254 uint32_t classid
= 0;
1257 service
= tvb_get_uint8( tvb
, offset
);
1258 service_code
= service
& CIP_SC_MASK
;
1260 /* Handle GetAttributeAll and SetAttributeAll in CCO class */
1261 if (service_code
== SC_GET_ATT_ALL
)
1263 if (service
& CIP_SC_RESPONSE_MASK
)
1265 /* Service response */
1266 preq_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
1267 if ((preq_info
!= NULL
) &&
1268 (preq_info
->dissector
== dissector_get_uint_handle( subdissector_class_table
, CI_CLS_SAFETY_VALIDATOR
)))
1270 call_dissector(preq_info
->dissector
, tvb
, pinfo
, tree
);
1276 /* Service request */
1277 ioilen
= tvb_get_uint8( tvb
, offset
+ 1 );
1280 segment
= tvb_get_uint8( tvb
, offset
+ 2 );
1281 if (((segment
& CI_SEGMENT_TYPE_MASK
) == CI_LOGICAL_SEGMENT
) &&
1282 ((segment
& CI_LOGICAL_SEG_TYPE_MASK
) == CI_LOGICAL_SEG_CLASS_ID
))
1284 /* Logical Class ID, do a format check */
1285 switch ( segment
& CI_LOGICAL_SEG_FORMAT_MASK
)
1287 case CI_LOGICAL_SEG_8_BIT
:
1288 classid
= tvb_get_uint8( tvb
, offset
+ 3 );
1290 case CI_LOGICAL_SEG_16_BIT
:
1292 classid
= tvb_get_letohs( tvb
, offset
+ 4 );
1294 case CI_LOGICAL_SEG_32_BIT
:
1296 classid
= tvb_get_letohl( tvb
, offset
+ 4 );
1302 if (classid
== CI_CLS_SAFETY_VALIDATOR
)
1304 call_dissector(cip_class_s_validator_handle
, tvb
, pinfo
, tree
);
1314 /************************************************
1318 ************************************************/
1319 static uint8_t compute_crc_s1_pid(const cip_connection_triad_t
* triad
)
1321 uint8_t temp_buf
[8];
1322 memcpy(temp_buf
, &triad
->VendorID
, 2);
1323 memcpy(&temp_buf
[2], &triad
->DeviceSerialNumber
, 4);
1324 memcpy(&temp_buf
[6], &triad
->ConnSerialNumber
, 2);
1326 return crc8_0x37(temp_buf
, 8, 0);
1329 static uint8_t compute_crc_s1_timestamp(uint8_t pid_seed
, uint8_t mode_byte_mask
, uint16_t timestamp
)
1331 uint8_t mode_byte_crc
= crc8_0x37(&mode_byte_mask
, 1, pid_seed
);
1332 uint8_t timestamp_crc
= crc8_0x37((uint8_t*)×tamp
, 2, mode_byte_crc
);
1334 return timestamp_crc
;
1337 static uint8_t compute_crc_s1_data(uint8_t pid_seed
, uint8_t mode_byte_mask
, const uint8_t *buf
, int len
)
1339 uint8_t mode_byte_crc
= crc8_0x37(&mode_byte_mask
, 1, pid_seed
);
1341 return crc8_0x37(buf
, len
, mode_byte_crc
);
1344 static uint8_t compute_crc_s2_data(uint8_t pid_seed
, uint8_t mode_byte_mask
, uint8_t *comp_buf
, int len
)
1347 uint8_t mode_byte_crc
= crc8_0x3B(&mode_byte_mask
, 1, pid_seed
);
1349 for (i
= 0; i
< len
; i
++)
1350 comp_buf
[i
] ^= 0xFF;
1352 return crc8_0x3B(comp_buf
, len
, mode_byte_crc
);
1355 static uint16_t compute_crc_s3_pid(const cip_connection_triad_t
* triad
)
1357 uint8_t temp_buf
[8];
1358 memcpy(temp_buf
, &triad
->VendorID
, 2);
1359 memcpy(&temp_buf
[2], &triad
->DeviceSerialNumber
, 4);
1360 memcpy(&temp_buf
[6], &triad
->ConnSerialNumber
, 2);
1362 return crc16_0x080F_seed(temp_buf
, 8, 0);
1365 static uint16_t compute_crc_s3_base_data(uint16_t pid_seed
, uint8_t mode_byte_mask
, const uint8_t *buf
, int len
)
1367 uint16_t mode_byte_crc
= crc16_0x080F_seed(&mode_byte_mask
, 1, pid_seed
);
1369 return crc16_0x080F_seed(buf
, len
, mode_byte_crc
);
1372 static uint16_t compute_crc_s3_extended_data(uint16_t pid_seed
, uint16_t rollover_value
, uint8_t mode_byte_mask
, const uint8_t *buf
, int len
)
1374 uint16_t rollover_crc
= crc16_0x080F_seed((uint8_t*)&rollover_value
, 2, pid_seed
);
1375 uint16_t mode_byte_crc
= crc16_0x080F_seed(&mode_byte_mask
, 1, rollover_crc
);
1377 return crc16_0x080F_seed(buf
, len
, mode_byte_crc
);
1380 static uint16_t compute_crc_s3_time(uint16_t pid_seed
, uint8_t ack_mcast_byte
, uint16_t timestamp_value
)
1382 uint16_t mode_byte_crc
= crc16_0x080F_seed(&ack_mcast_byte
, 1, pid_seed
);
1383 uint16_t timestamp_crc
;
1385 timestamp_crc
= crc16_0x080F_seed((uint8_t*)×tamp_value
, 2, mode_byte_crc
);
1387 return timestamp_crc
;
1390 static uint32_t compute_crc_s5_pid(const cip_connection_triad_t
* triad
)
1392 uint8_t temp_buf
[8];
1393 memcpy(temp_buf
, &triad
->VendorID
, 2);
1394 memcpy(&temp_buf
[2], &triad
->DeviceSerialNumber
, 4);
1395 memcpy(&temp_buf
[6], &triad
->ConnSerialNumber
, 2);
1397 return crc32_0x5D6DCB_seed(temp_buf
, 8, 0);
1400 static uint32_t compute_crc_s5_short_data(uint32_t pid_seed
, uint16_t rollover_value
, uint8_t mode_byte_mask
, uint16_t timestamp_value
, const uint8_t *buf
, int len
)
1402 uint32_t rollover_crc
= crc32_0x5D6DCB_seed((uint8_t*)&rollover_value
, 2, pid_seed
);
1403 uint32_t mode_byte_crc
= crc32_0x5D6DCB_seed(&mode_byte_mask
, 1, rollover_crc
);
1404 uint32_t data_crc
, timestamp_crc
;
1406 data_crc
= crc32_0x5D6DCB_seed(buf
, len
, mode_byte_crc
);
1407 timestamp_crc
= crc32_0x5D6DCB_seed((uint8_t*)×tamp_value
, 2, data_crc
);
1409 return timestamp_crc
;
1412 static uint32_t compute_crc_s5_long_data(uint32_t pid_seed
, uint16_t rollover_value
, uint8_t mode_byte_mask
, uint16_t timestamp_value
, const uint8_t *comp_buf
, int len
)
1414 uint32_t rollover_crc
= crc32_0x5D6DCB_seed((uint8_t*)&rollover_value
, 2, pid_seed
);
1415 uint32_t mode_byte_crc
= crc32_0x5D6DCB_seed(&mode_byte_mask
, 1, rollover_crc
);
1416 uint32_t comp_data_crc
, timestamp_crc
;
1418 comp_data_crc
= crc32_0x5D6DCB_seed(comp_buf
, len
, mode_byte_crc
);
1419 timestamp_crc
= crc32_0x5D6DCB_seed((uint8_t*)×tamp_value
, 2, comp_data_crc
);
1421 return timestamp_crc
;
1424 static uint32_t compute_crc_s5_time(uint32_t pid_seed
, uint8_t ack_mcast_byte
, uint16_t timestamp_value
)
1426 uint32_t mode_byte_crc
= crc32_0x5D6DCB_seed(&ack_mcast_byte
, 1, pid_seed
);
1427 uint32_t timestamp_crc
;
1429 timestamp_crc
= crc32_0x5D6DCB_seed((uint8_t*)×tamp_value
, 2, mode_byte_crc
);
1431 return timestamp_crc
;
1434 static bool verify_compliment_data(tvbuff_t
*tvb
, int data_offset
, int complement_data_offset
, int data_size
)
1436 const uint8_t *data
= tvb_get_ptr(tvb
, data_offset
, data_size
);
1437 const uint8_t *complement_data
= tvb_get_ptr(tvb
, complement_data_offset
, data_size
);
1440 for (i
= 0; i
< data_size
; i
++)
1442 if ((data
[i
] ^ complement_data
[i
])!= 0xFF)
1449 static void validate_crc_s5(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
, bool compute_crc
,
1450 uint32_t crc_s5_0
, uint32_t crc_s5_1
, uint32_t crc_s5_2
, uint32_t computed_crc_s5
)
1452 proto_item
* crc_s5_status_item
;
1454 /* CRC-S5 doesn't use proto_tree_add_checksum because the checksum is broken up into multiple fields */
1457 uint32_t value_s5
= crc_s5_0
;
1458 value_s5
+= ((crc_s5_1
<< 8) & 0xFF00);
1459 value_s5
+= ((crc_s5_2
<< 16) & 0xFF0000);
1461 if (computed_crc_s5
== value_s5
)
1463 crc_s5_status_item
= proto_tree_add_uint(tree
, hf_cipsafety_crc_s5_status
, tvb
, 0, 0, PROTO_CHECKSUM_E_GOOD
);
1467 crc_s5_status_item
= proto_tree_add_uint(tree
, hf_cipsafety_crc_s5_status
, tvb
, 0, 0, PROTO_CHECKSUM_E_BAD
);
1468 expert_add_info_format(pinfo
, crc_s5_status_item
, &ei_cipsafety_crc_s5
, "%s [should be 0x%08x]", expert_get_summary(&ei_cipsafety_crc_s5
), computed_crc_s5
);
1473 crc_s5_status_item
= proto_tree_add_uint(tree
, hf_cipsafety_crc_s5_status
, tvb
, 0, 0, PROTO_CHECKSUM_E_UNVERIFIED
);
1476 proto_item_set_generated(crc_s5_status_item
);
1479 /************************************************
1481 * Dissector for CIP Safety I/O Data
1483 ************************************************/
1485 dissect_mode_byte( proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
)
1487 proto_item
*mode_item
, *run_idle_item
, *tbd_item
, *tbd2_item
;
1488 proto_tree
*mode_tree
;
1491 mode_byte
= tvb_get_uint8(tvb
, offset
);
1493 /* dissect Mode Byte bits */
1494 mode_item
= proto_tree_add_item(tree
, hf_cipsafety_mode_byte
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1495 mode_tree
= proto_item_add_subtree( mode_item
, ett_cipsafety_mode_byte
);
1497 proto_tree_add_item(mode_tree
, hf_cipsafety_mode_byte_ping_count
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1498 proto_tree_add_item(mode_tree
, hf_cipsafety_mode_byte_not_tbd
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1499 proto_tree_add_item(mode_tree
, hf_cipsafety_mode_byte_tbd_2_copy
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1500 proto_tree_add_item(mode_tree
, hf_cipsafety_mode_byte_not_run_idle
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1501 tbd_item
= proto_tree_add_item(mode_tree
, hf_cipsafety_mode_byte_tbd
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1502 tbd2_item
= proto_tree_add_item(mode_tree
, hf_cipsafety_mode_byte_tbd_2_bit
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1503 run_idle_item
= proto_tree_add_item(mode_tree
, hf_cipsafety_mode_byte_run_idle
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1505 /* verify Mode Byte bits */
1507 if ((((mode_byte
& 0x20) >> 5) & 0x01) == (((mode_byte
& 0x04) >> 2) & 0x01))
1508 expert_add_info(pinfo
, tbd_item
, &ei_cipsafety_tbd_not_complemented
);
1511 if ((((mode_byte
& 0x40) >> 6) & 0x01) != (((mode_byte
& 0x08) >> 3) & 0x01))
1512 expert_add_info(pinfo
, tbd2_item
, &ei_cipsafety_tbd2_not_copied
);
1515 if ((((mode_byte
& 0x80) >> 7) & 0x01) == (((mode_byte
& 0x10) >> 4) & 0x01))
1516 expert_add_info(pinfo
, run_idle_item
, &ei_cipsafety_run_idle_not_complemented
);
1520 dissect_ack_byte( proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1522 // TODO: add ack_byte validation
1523 static int* const bits
[] = {
1524 &hf_cipsafety_ack_byte_ping_count_reply
,
1525 &hf_cipsafety_ack_byte_reserved1
,
1526 &hf_cipsafety_ack_byte_ping_response
,
1527 &hf_cipsafety_ack_byte_reserved2
,
1528 &hf_cipsafety_ack_byte_parity_even
,
1532 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_cipsafety_ack_byte
, ett_cipsafety_ack_byte
, bits
, ENC_LITTLE_ENDIAN
);
1536 dissect_mcast_byte( proto_tree
*tree
, tvbuff_t
*tvb
, int offset
)
1538 // TODO: add mcast_byte validation
1539 static int* const bits
[] = {
1540 &hf_cipsafety_mcast_byte_consumer_num
,
1541 &hf_cipsafety_mcast_byte_reserved1
,
1542 &hf_cipsafety_mcast_byte_mai
,
1543 &hf_cipsafety_mcast_byte_reserved2
,
1544 &hf_cipsafety_mcast_byte_parity_even
,
1548 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_cipsafety_mcast_byte
, ett_cipsafety_mcast_byte
, bits
, ENC_LITTLE_ENDIAN
);
1551 // Base Format Time Correction Message
1552 static void dissect_base_format_time_correction_message(proto_tree
* tree
, tvbuff_t
* tvb
, int offset
)
1554 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_BASE_TIME_CORRECTION
);
1555 proto_item_set_generated(it
);
1557 dissect_mcast_byte(tree
, tvb
, offset
);
1558 proto_tree_add_item(tree
, hf_cipsafety_time_correction
, tvb
, offset
+ 1, 2, ENC_LITTLE_ENDIAN
);
1559 proto_tree_add_item(tree
, hf_cipsafety_mcast_byte2
, tvb
, offset
+ 3, 1, ENC_LITTLE_ENDIAN
);
1560 proto_tree_add_item(tree
, hf_cipsafety_crc_s3
, tvb
, offset
+ 4, 2, ENC_LITTLE_ENDIAN
);
1563 // Extended Format Time Correction Message
1564 static void dissect_extended_format_time_correction_message(proto_tree
* tree
, tvbuff_t
* tvb
, int offset
)
1566 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_EXTENDED_TIME_CORRECTION
);
1567 proto_item_set_generated(it
);
1569 dissect_mcast_byte(tree
, tvb
, offset
);
1570 proto_tree_add_item(tree
, hf_cipsafety_time_correction
, tvb
, offset
+ 1, 2, ENC_LITTLE_ENDIAN
);
1571 proto_tree_add_item(tree
, hf_cipsafety_crc_s5_0
, tvb
, offset
+ 3, 1, ENC_LITTLE_ENDIAN
);
1572 proto_tree_add_item(tree
, hf_cipsafety_crc_s5_1
, tvb
, offset
+ 4, 1, ENC_LITTLE_ENDIAN
);
1573 proto_tree_add_item(tree
, hf_cipsafety_crc_s5_2
, tvb
, offset
+ 5, 1, ENC_LITTLE_ENDIAN
);
1575 // TODO: Validate CRC S5.
1578 // Base Format, Time Stamp Section Format
1579 static void dissect_base_format_time_stamp_section(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
, int offset
,
1580 bool compute_crc
, uint8_t mode_byte
, const cip_connection_triad_t
* connection_triad
)
1582 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_BASE_TIME_STAMP
);
1583 proto_item_set_generated(it
);
1585 proto_tree_add_item(tree
, hf_cipsafety_timestamp
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1586 uint16_t timestamp
= tvb_get_letohs(tvb
, offset
);
1590 uint8_t computed_crc_s1
= compute_crc_s1_timestamp(compute_crc_s1_pid(connection_triad
),
1591 (mode_byte
& MODE_BYTE_CRC_S1_TIME_STAMP_MASK
),
1593 proto_tree_add_checksum(tree
, tvb
, offset
+ 2,
1594 hf_cipsafety_crc_s1
, hf_cipsafety_crc_s1_status
, &ei_cipsafety_crc_s1
, pinfo
,
1595 computed_crc_s1
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
1599 proto_tree_add_checksum(tree
, tvb
, offset
+ 2,
1600 hf_cipsafety_crc_s1
, hf_cipsafety_crc_s1_status
, &ei_cipsafety_crc_s1
,
1601 pinfo
, 0, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
1605 // Base Format Time Coordination Message
1606 // Note: All data starts from the beginning of the tvb buffer.
1607 static void dissect_base_format_time_coordination_message(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
,
1608 bool compute_crc
, const cip_connection_triad_t
* connection_triad
)
1610 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_BASE_TIME_COORDINATION
);
1611 proto_item_set_generated(it
);
1613 dissect_ack_byte(tree
, tvb
, 0);
1614 uint8_t ack_byte
= tvb_get_uint8(tvb
, 0);
1616 proto_tree_add_item(tree
, hf_cipsafety_consumer_time_value
, tvb
, 1, 2, ENC_LITTLE_ENDIAN
);
1617 uint16_t timestamp
= tvb_get_letohs(tvb
, 1);
1619 proto_tree_add_item(tree
, hf_cipsafety_ack_byte2
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
);
1623 uint16_t computed_crc_s3
= compute_crc_s3_time(compute_crc_s3_pid(connection_triad
), ack_byte
, timestamp
);
1624 proto_tree_add_checksum(tree
, tvb
, 4,
1625 hf_cipsafety_crc_s3
, hf_cipsafety_crc_s3_status
, &ei_cipsafety_crc_s3
, pinfo
,
1626 computed_crc_s3
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
1630 proto_tree_add_checksum(tree
, tvb
, 4,
1631 hf_cipsafety_crc_s3
, hf_cipsafety_crc_s3_status
, &ei_cipsafety_crc_s3
,
1632 pinfo
, 0, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
1636 // Extended Format Time Coordination Message
1637 // Note: All data starts from the beginning of the tvb buffer.
1638 static void dissect_extended_format_time_coordination_message(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
,
1639 bool compute_crc
, const cip_connection_triad_t
* connection_triad
)
1641 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_EXTENDED_TIME_COORDINATION
);
1642 proto_item_set_generated(it
);
1644 dissect_ack_byte(tree
, tvb
, 0);
1645 uint8_t ack_byte
= tvb_get_uint8(tvb
, 0);
1647 proto_tree_add_item(tree
, hf_cipsafety_consumer_time_value
, tvb
, 1, 2, ENC_LITTLE_ENDIAN
);
1648 uint16_t timestamp
= tvb_get_letohs(tvb
, 1);
1650 uint32_t crc_s5_0
, crc_s5_1
, crc_s5_2
;
1651 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_0
, tvb
, 3, 1, ENC_LITTLE_ENDIAN
, &crc_s5_0
);
1652 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_1
, tvb
, 4, 1, ENC_LITTLE_ENDIAN
, &crc_s5_1
);
1653 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_2
, tvb
, 5, 1, ENC_LITTLE_ENDIAN
, &crc_s5_2
);
1655 uint32_t computed_crc_s5
= compute_crc_s5_time(compute_crc_s5_pid(connection_triad
),
1658 validate_crc_s5(pinfo
, tree
, tvb
, compute_crc
, crc_s5_0
, crc_s5_1
, crc_s5_2
, computed_crc_s5
);
1661 // 1 or 2 Byte Data section, Base Format
1662 // Note: All data starts from the beginning of the tvb buffer.
1663 static void dissect_base_format_1_or_2_byte_data(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
, int io_data_size
,
1664 bool compute_crc
, const cip_connection_triad_t
* connection_triad
)
1666 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_BASE_1_2_BYTE_DATA
);
1667 proto_item_set_generated(it
);
1669 proto_tree_add_item(tree
, hf_cipsafety_data
, tvb
, 0, io_data_size
, ENC_NA
);
1670 dissect_mode_byte(tree
, tvb
, io_data_size
, pinfo
);
1671 uint8_t mode_byte
= tvb_get_uint8(tvb
, io_data_size
);
1675 uint8_t computed_crc_s1
= compute_crc_s1_data(compute_crc_s1_pid(connection_triad
),
1676 (mode_byte
& MODE_BYTE_CRC_S1_MASK
),
1677 tvb_get_ptr(tvb
, 0, io_data_size
), io_data_size
);
1679 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 1,
1680 hf_cipsafety_crc_s1
, hf_cipsafety_crc_s1_status
, &ei_cipsafety_crc_s1
, pinfo
,
1681 computed_crc_s1
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
1683 uint8_t computed_crc_s2
= compute_crc_s2_data(compute_crc_s1_pid(connection_triad
),
1684 ((mode_byte
^ 0xFF) & MODE_BYTE_CRC_S1_MASK
),
1685 /* I/O data is duplicated because it will be complemented inline */
1686 (uint8_t*)tvb_memdup(pinfo
->pool
, tvb
, 0, io_data_size
), io_data_size
);
1688 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 2,
1689 hf_cipsafety_crc_s2
, hf_cipsafety_crc_s2_status
, &ei_cipsafety_crc_s2
, pinfo
,
1690 computed_crc_s2
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
1694 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 1,
1695 hf_cipsafety_crc_s1
, hf_cipsafety_crc_s1_status
, &ei_cipsafety_crc_s1
,
1696 pinfo
, 0, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
1697 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 2,
1698 hf_cipsafety_crc_s2
, hf_cipsafety_crc_s2_status
, &ei_cipsafety_crc_s2
,
1699 pinfo
, 0, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
1703 // 3 to 250 Byte Data section, Base Format
1704 // Note: All data starts from the beginning of the tvb buffer.
1705 static void dissect_base_format_3_to_250_byte_data(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
, int io_data_size
,
1706 bool compute_crc
, const cip_connection_triad_t
* connection_triad
)
1708 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_BASE_3_250_BYTE_DATA
);
1709 proto_item_set_generated(it
);
1711 proto_tree_add_item(tree
, hf_cipsafety_data
, tvb
, 0, io_data_size
, ENC_NA
);
1712 dissect_mode_byte(tree
, tvb
, io_data_size
, pinfo
);
1713 unsigned mode_byte
= tvb_get_uint8(tvb
, io_data_size
);
1717 uint16_t computed_crc_s3
= compute_crc_s3_base_data(compute_crc_s3_pid(connection_triad
),
1718 mode_byte
& MODE_BYTE_CRC_S3_MASK
, tvb_get_ptr(tvb
, 0, io_data_size
), io_data_size
);
1720 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 1,
1721 hf_cipsafety_crc_s3
, hf_cipsafety_crc_s3_status
, &ei_cipsafety_crc_s3
, pinfo
,
1722 computed_crc_s3
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
1726 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 1,
1727 hf_cipsafety_crc_s3
, hf_cipsafety_crc_s3_status
, &ei_cipsafety_crc_s3
,
1728 pinfo
, 0, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
1731 proto_item
* complement_item
= proto_tree_add_item(tree
, hf_cipsafety_complement_data
, tvb
, io_data_size
+ 3, io_data_size
, ENC_NA
);
1732 if (!verify_compliment_data(tvb
, 0, io_data_size
+ 3, io_data_size
))
1733 expert_add_info(pinfo
, complement_item
, &ei_cipsafety_not_complement_data
);
1737 uint16_t computed_crc_s3
= compute_crc_s3_base_data(compute_crc_s3_pid(connection_triad
),
1738 ((mode_byte
^ 0xFF) & MODE_BYTE_CRC_S3_MASK
),
1739 tvb_get_ptr(tvb
, io_data_size
+ 3, io_data_size
), io_data_size
);
1741 proto_tree_add_checksum(tree
, tvb
, (io_data_size
* 2) + 3,
1742 hf_cipsafety_complement_crc_s3
, hf_cipsafety_complement_crc_s3_status
, &ei_cipsafety_complement_crc_s3
, pinfo
,
1743 computed_crc_s3
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
1747 proto_tree_add_checksum(tree
, tvb
, (io_data_size
* 2) + 3,
1748 hf_cipsafety_complement_crc_s3
, hf_cipsafety_complement_crc_s3_status
, &ei_cipsafety_complement_crc_s3
,
1749 pinfo
, 0, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
1753 // 1 or 2 Byte Data Section, Extended Format
1754 // Note: All data starts from the beginning of the tvb buffer.
1755 static void dissect_extended_format_1_or_2_byte_data(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
, int io_data_size
,
1756 bool compute_crc
, const cip_connection_triad_t
* connection_triad
, const cip_safety_packet_data_t
* packet_data
)
1758 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_EXTENDED_1_2_BYTE_DATA
);
1759 proto_item_set_generated(it
);
1761 proto_tree_add_item(tree
, hf_cipsafety_data
, tvb
, 0, io_data_size
, ENC_NA
);
1762 dissect_mode_byte(tree
, tvb
, io_data_size
, pinfo
);
1763 unsigned mode_byte
= tvb_get_uint8(tvb
, io_data_size
);
1765 uint32_t crc_s5_0
, crc_s5_1
, crc_s5_2
;
1766 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_0
, tvb
, io_data_size
+ 1, 1, ENC_LITTLE_ENDIAN
, &crc_s5_0
);
1767 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_1
, tvb
, io_data_size
+ 2, 1, ENC_LITTLE_ENDIAN
, &crc_s5_1
);
1768 proto_tree_add_item(tree
, hf_cipsafety_timestamp
, tvb
, io_data_size
+ 3, 2, ENC_LITTLE_ENDIAN
);
1769 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_2
, tvb
, io_data_size
+ 5, 1, ENC_LITTLE_ENDIAN
, &crc_s5_2
);
1771 uint16_t timestamp
= tvb_get_letohs(tvb
, io_data_size
+ 3);
1773 uint32_t computed_crc_s5
= 0;
1774 if (packet_data
!= NULL
)
1776 computed_crc_s5
= compute_crc_s5_short_data(compute_crc_s5_pid(connection_triad
),
1777 packet_data
->rollover_value
,
1778 mode_byte
& MODE_BYTE_CRC_S5_BASE_MASK
,
1780 tvb_get_ptr(tvb
, 0, io_data_size
),
1784 validate_crc_s5(pinfo
, tree
, tvb
, compute_crc
, crc_s5_0
, crc_s5_1
, crc_s5_2
, computed_crc_s5
);
1787 // 3 to 250 Byte Data section, Extended Format
1788 // Note: All data starts from the beginning of the tvb buffer.
1789 static void dissect_extended_format_3_to_250_byte_data(packet_info
* pinfo
, proto_tree
* tree
, tvbuff_t
* tvb
, int io_data_size
,
1790 bool compute_crc
, const cip_connection_triad_t
* connection_triad
, const cip_safety_packet_data_t
* packet_data
)
1792 proto_item
* it
= proto_tree_add_uint(tree
, hf_cip_safety_message_encoding
, tvb
, 0, 0, MSG_ENCODING_EXTENDED_3_250_BYTE_DATA
);
1793 proto_item_set_generated(it
);
1795 proto_tree_add_item(tree
, hf_cipsafety_data
, tvb
, 0, io_data_size
, ENC_NA
);
1796 dissect_mode_byte(tree
, tvb
, io_data_size
, pinfo
);
1797 unsigned mode_byte
= tvb_get_uint8(tvb
, io_data_size
);
1799 uint16_t timestamp
= tvb_get_letohs(tvb
, (io_data_size
* 2) + 5);
1803 if (packet_data
!= NULL
)
1805 uint16_t computed_crc_s3
= compute_crc_s3_extended_data(compute_crc_s3_pid(connection_triad
),
1806 packet_data
->rollover_value
,
1807 mode_byte
& MODE_BYTE_CRC_S3_MASK
,
1808 tvb_get_ptr(tvb
, 0, io_data_size
), io_data_size
);
1810 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 1,
1811 hf_cipsafety_crc_s3
, hf_cipsafety_crc_s3_status
, &ei_cipsafety_crc_s3
, pinfo
,
1812 computed_crc_s3
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
1817 proto_tree_add_checksum(tree
, tvb
, io_data_size
+ 1,
1818 hf_cipsafety_crc_s3
, hf_cipsafety_crc_s3_status
, &ei_cipsafety_crc_s3
,
1819 pinfo
, 0, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
1822 proto_item
* complement_item
= proto_tree_add_item(tree
, hf_cipsafety_complement_data
, tvb
, io_data_size
+ 3, io_data_size
, ENC_NA
);
1823 if (!verify_compliment_data(tvb
, 0, io_data_size
+ 3, io_data_size
))
1824 expert_add_info(pinfo
, complement_item
, &ei_cipsafety_not_complement_data
);
1826 uint32_t crc_s5_0
, crc_s5_1
, crc_s5_2
;
1827 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_0
, tvb
, (io_data_size
* 2) + 3, 1, ENC_LITTLE_ENDIAN
, &crc_s5_0
);
1828 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_1
, tvb
, (io_data_size
* 2) + 4, 1, ENC_LITTLE_ENDIAN
, &crc_s5_1
);
1829 proto_tree_add_item(tree
, hf_cipsafety_timestamp
, tvb
, (io_data_size
* 2) + 5, 2, ENC_LITTLE_ENDIAN
);
1830 proto_tree_add_item_ret_uint(tree
, hf_cipsafety_crc_s5_2
, tvb
, (io_data_size
* 2) + 7, 1, ENC_LITTLE_ENDIAN
, &crc_s5_2
);
1832 uint32_t computed_crc_s5
= 0;
1833 if (packet_data
!= NULL
)
1835 computed_crc_s5
= compute_crc_s5_long_data(compute_crc_s5_pid(connection_triad
),
1836 packet_data
->rollover_value
,
1837 mode_byte
& MODE_BYTE_CRC_S5_EXTENDED_MASK
,
1839 tvb_get_ptr(tvb
, io_data_size
+ 3, io_data_size
),
1842 validate_crc_s5(pinfo
, tree
, tvb
, compute_crc
, crc_s5_0
, crc_s5_1
, crc_s5_2
, computed_crc_s5
);
1845 // Note: This updates the running timestamp/rollover data in safety_info during the first pass.
1846 static cip_safety_packet_data_t
* get_timestamp_packet_data(packet_info
* pinfo
, cip_safety_info_t
* safety_info
, uint16_t timestamp
)
1848 cip_safety_packet_data_t
* packet_data
= NULL
;
1850 /* Determine if packet timestamp results in rollover count increment */
1851 if (!pinfo
->fd
->visited
)
1853 packet_data
= wmem_new0(wmem_file_scope(), cip_safety_packet_data_t
);
1855 if ((timestamp
== 0) && !safety_info
->eip_conn_info
->safety
.seen_non_zero_timestamp
)
1857 // The rollover value is zero, until the Time Coordination exchange is done.
1858 // When the timestamp is zero, that means we haven't seen the Time Coordination message.
1859 packet_data
->rollover_value
= 0;
1863 safety_info
->eip_conn_info
->safety
.seen_non_zero_timestamp
= true;
1865 if (timestamp
< safety_info
->eip_conn_info
->safety
.running_timestamp_value
)
1867 safety_info
->eip_conn_info
->safety
.running_rollover_value
++;
1870 /* Save the rollover value for CRC calculations */
1871 packet_data
->rollover_value
= safety_info
->eip_conn_info
->safety
.running_rollover_value
;
1872 safety_info
->eip_conn_info
->safety
.running_timestamp_value
= timestamp
;
1875 p_add_proto_data(wmem_file_scope(), pinfo
, proto_cipsafety
, 0, packet_data
);
1879 packet_data
= (cip_safety_packet_data_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cipsafety
, 0);
1885 enum cip_safety_data_type
{CIP_SAFETY_DATA_TYPE_UNKNOWN
, CIP_SAFETY_PRODUCE
, CIP_SAFETY_CONSUME
};
1886 static enum cip_safety_data_type
get_cip_safety_data_type(enum enip_connid_type conn_type
, const cip_safety_epath_info_t
* safety
)
1888 if (conn_type
== ECIDT_O2T
&& safety
->originator_type
== CIP_SAFETY_ORIGINATOR_PRODUCER
)
1890 return CIP_SAFETY_PRODUCE
;
1892 else if (conn_type
== ECIDT_O2T
&& safety
->originator_type
== CIP_SAFETY_ORIGINATOR_CONSUMER
)
1894 return CIP_SAFETY_CONSUME
;
1896 else if (conn_type
== ECIDT_T2O
&& safety
->originator_type
== CIP_SAFETY_ORIGINATOR_PRODUCER
)
1898 return CIP_SAFETY_CONSUME
;
1900 else if (conn_type
== ECIDT_T2O
&& safety
->originator_type
== CIP_SAFETY_ORIGINATOR_CONSUMER
)
1902 return CIP_SAFETY_PRODUCE
;
1906 return CIP_SAFETY_DATA_TYPE_UNKNOWN
;
1910 void add_safety_data_type_to_info_column(packet_info
*pinfo
, enum enip_connid_type conn_type
, const cip_safety_epath_info_t
* safety
)
1912 enum cip_safety_data_type data_type
= get_cip_safety_data_type(conn_type
, safety
);
1914 if (data_type
== CIP_SAFETY_CONSUME
)
1916 col_append_str(pinfo
->cinfo
, COL_INFO
, " [C->P]");
1918 else // CIP_SAFETY_PRODUCE
1920 col_append_str(pinfo
->cinfo
, COL_INFO
, " [P->C]");
1925 dissect_cip_safety_data( proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int item_length
, packet_info
*pinfo
, cip_safety_info_t
* safety_info
)
1927 bool multicast
= in4_addr_is_multicast(pntoh32(pinfo
->dst
.data
));
1928 bool server_dir
= false;
1929 enum enip_connid_type conn_type
= ECIDT_UNKNOWN
;
1930 enum cip_safety_format_type format
= CIP_SAFETY_BASE_FORMAT
;
1931 bool compute_crc
= ((safety_info
!= NULL
) && (safety_info
->compute_crc
== true));
1932 cip_connection_triad_t connection_triad
= {0};
1934 /* Make entries in Protocol column and Info column on summary display */
1935 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP Safety");
1937 /* determine the connection type as it affects the fields dissected */
1938 if (safety_info
!= NULL
&& safety_info
->eip_conn_info
!= NULL
)
1940 conn_type
= safety_info
->conn_type
;
1941 format
= safety_info
->eip_conn_info
->safety
.format
;
1942 server_dir
= (safety_info
->eip_conn_info
->TransportClass_trigger
& CI_PRODUCTION_DIR_MASK
) ? true : false;
1945 /* compute the base packet length to determine what is actual I/O data */
1946 int base_length
= multicast
? 12 : 6;
1948 if (item_length
< base_length
) {
1949 expert_add_info(pinfo
, item
, &ei_mal_io
);
1953 if (((conn_type
== ECIDT_O2T
) && (server_dir
== false)) ||
1954 ((conn_type
== ECIDT_T2O
) && (server_dir
== true)))
1958 if ((conn_type
== ECIDT_O2T
) && (server_dir
== false))
1960 connection_triad
= safety_info
->eip_conn_info
->triad
;
1964 connection_triad
= safety_info
->eip_conn_info
->safety
.target_triad
;
1969 proto_item_append_text(item
, " [Consume]");
1970 col_append_str(pinfo
->cinfo
, COL_INFO
, " [C->P]");
1974 case CIP_SAFETY_BASE_FORMAT
:
1975 dissect_base_format_time_coordination_message(pinfo
, tree
, tvb
, compute_crc
, &connection_triad
);
1977 case CIP_SAFETY_EXTENDED_FORMAT
:
1978 dissect_extended_format_time_coordination_message(pinfo
, tree
, tvb
, compute_crc
, &connection_triad
);
1982 else if (((conn_type
== ECIDT_O2T
) && (server_dir
== true)) ||
1983 ((conn_type
== ECIDT_T2O
) && (server_dir
== false)))
1987 if ((conn_type
== ECIDT_O2T
) && (server_dir
== true))
1989 connection_triad
= safety_info
->eip_conn_info
->triad
;
1993 connection_triad
= safety_info
->eip_conn_info
->safety
.target_triad
;
1997 bool short_format
= true;
1998 if (item_length
-base_length
> 2)
1999 short_format
= false;
2002 proto_item_append_text(item
, " [Produce]");
2003 col_append_str(pinfo
->cinfo
, COL_INFO
, " [P->C]");
2007 case CIP_SAFETY_BASE_FORMAT
:
2010 int io_data_size
= item_length
-base_length
;
2011 uint8_t mode_byte
= tvb_get_uint8(tvb
, io_data_size
);
2013 dissect_base_format_1_or_2_byte_data(pinfo
, tree
, tvb
, io_data_size
, compute_crc
, &connection_triad
);
2014 dissect_base_format_time_stamp_section(pinfo
, tree
, tvb
, io_data_size
+ 3, compute_crc
, mode_byte
, &connection_triad
);
2018 dissect_base_format_time_correction_message(tree
, tvb
, item_length
- 6);
2023 /* 3 to 250 Byte Data section, Base Format */
2024 if (item_length
%2 == 1)
2026 /* Malformed packet */
2027 expert_add_info(pinfo
, item
, &ei_mal_io
);
2031 int io_data_size
= multicast
? ((item_length
-14)/2) : ((item_length
-8)/2);
2032 uint8_t mode_byte
= tvb_get_uint8(tvb
, io_data_size
);
2034 dissect_base_format_3_to_250_byte_data(pinfo
, tree
, tvb
, io_data_size
, compute_crc
, &connection_triad
);
2035 dissect_base_format_time_stamp_section(pinfo
, tree
, tvb
, (io_data_size
* 2) + 5, compute_crc
, mode_byte
, &connection_triad
);
2039 dissect_base_format_time_correction_message(tree
, tvb
, (io_data_size
* 2) + 5);
2043 case CIP_SAFETY_EXTENDED_FORMAT
:
2050 io_data_size
= item_length
-base_length
;
2051 timestamp
= tvb_get_letohs(tvb
, io_data_size
+3);
2055 io_data_size
= multicast
? ((item_length
-14)/2) : ((item_length
-8)/2);
2056 timestamp
= tvb_get_letohs(tvb
, (io_data_size
*2)+5);
2059 cip_safety_packet_data_t
* packet_data
= NULL
;
2062 packet_data
= get_timestamp_packet_data(pinfo
, safety_info
, timestamp
);
2067 dissect_extended_format_1_or_2_byte_data(pinfo
, tree
, tvb
, io_data_size
, compute_crc
, &connection_triad
, packet_data
);
2071 dissect_extended_format_time_correction_message(tree
, tvb
, item_length
- 6);
2076 /* 3 to 250 Byte Data section, Extended Format */
2077 if (item_length
%2 == 1)
2079 /* Malformed packet */
2080 expert_add_info(pinfo
, item
, &ei_mal_io
);
2084 dissect_extended_format_3_to_250_byte_data(pinfo
, tree
, tvb
, io_data_size
, compute_crc
, &connection_triad
, packet_data
);
2088 dissect_extended_format_time_correction_message(tree
, tvb
, (io_data_size
* 2) + 8);
2092 } // END case CIP_SAFETY_EXTENDED_FORMAT
2097 /* Shouldn't happen, but at least dissect it as data */
2098 proto_tree_add_item(tree
, hf_cipsafety_data
, tvb
, 0, item_length
, ENC_NA
);
2103 dissect_cipsafety(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
2106 proto_tree
*safety_tree
;
2107 cip_safety_info_t
* safety_info
= (cip_safety_info_t
*)data
;
2109 /* Create display subtree for the protocol */
2110 ti
= proto_tree_add_item(tree
, proto_cipsafety
, tvb
, 0, -1, ENC_NA
);
2111 safety_tree
= proto_item_add_subtree( ti
, ett_cip_safety
);
2113 dissect_cip_safety_data(safety_tree
, ti
, tvb
, tvb_reported_length(tvb
), pinfo
, safety_info
);
2114 return tvb_captured_length(tvb
);
2117 static int dissect_cipsafety_base_data(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2119 cip_safety_info_t safety_info
;
2120 cip_conn_info_t eip_conn_info
;
2121 memset(&eip_conn_info
, 0, sizeof(eip_conn_info
));
2122 safety_info
.eip_conn_info
= &eip_conn_info
;
2123 safety_info
.compute_crc
= false;
2125 // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
2126 safety_info
.conn_type
= ECIDT_T2O
;
2127 safety_info
.eip_conn_info
->TransportClass_trigger
= 0;
2128 safety_info
.eip_conn_info
->safety
.format
= CIP_SAFETY_BASE_FORMAT
;
2130 return dissect_cipsafety(tvb
, pinfo
, tree
, &safety_info
);
2133 static int dissect_cipsafety_extended_data(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2135 cip_safety_info_t safety_info
;
2136 cip_conn_info_t eip_conn_info
;
2137 memset(&eip_conn_info
, 0, sizeof(eip_conn_info
));
2138 safety_info
.eip_conn_info
= &eip_conn_info
;
2139 safety_info
.compute_crc
= false;
2141 // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
2142 safety_info
.conn_type
= ECIDT_T2O
;
2143 safety_info
.eip_conn_info
->TransportClass_trigger
= 0;
2144 safety_info
.eip_conn_info
->safety
.format
= CIP_SAFETY_EXTENDED_FORMAT
;
2146 return dissect_cipsafety(tvb
, pinfo
, tree
, &safety_info
);
2149 static int dissect_cipsafety_base_time_coord(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2151 cip_safety_info_t safety_info
;
2152 cip_conn_info_t eip_conn_info
;
2153 memset(&eip_conn_info
, 0, sizeof(eip_conn_info
));
2154 safety_info
.eip_conn_info
= &eip_conn_info
;
2155 safety_info
.compute_crc
= false;
2157 // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
2158 safety_info
.conn_type
= ECIDT_O2T
;
2159 safety_info
.eip_conn_info
->TransportClass_trigger
= 0;
2160 safety_info
.eip_conn_info
->safety
.format
= CIP_SAFETY_BASE_FORMAT
;
2162 return dissect_cipsafety(tvb
, pinfo
, tree
, &safety_info
);
2165 static int dissect_cipsafety_extended_time_coord(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
2167 cip_safety_info_t safety_info
;
2168 cip_conn_info_t eip_conn_info
;
2169 memset(&eip_conn_info
, 0, sizeof(eip_conn_info
));
2170 safety_info
.eip_conn_info
= &eip_conn_info
;
2171 safety_info
.compute_crc
= false;
2173 // Set up parameters that will trigger dissect_cip_safety_data to parse the correct format.
2174 safety_info
.conn_type
= ECIDT_O2T
;
2175 safety_info
.eip_conn_info
->TransportClass_trigger
= 0;
2176 safety_info
.eip_conn_info
->safety
.format
= CIP_SAFETY_EXTENDED_FORMAT
;
2178 return dissect_cipsafety(tvb
, pinfo
, tree
, &safety_info
);
2181 static int dissect_sercosiii_link_error_count_p1p2(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2182 int offset
, int total_len
)
2186 expert_add_info(pinfo
, item
, &ei_mal_sercosiii_link_error_count_p1p2
);
2190 proto_tree_add_item(tree
, hf_cip_sercosiii_link_error_count_p1
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2191 proto_tree_add_item(tree
, hf_cip_sercosiii_link_error_count_p2
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
2195 static int dissect_sercosiii_safety_network_number(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
2196 int offset
, int total_len _U_
)
2198 proto_tree_add_item(tree
, hf_cip_sercosiii_link_snn
, tvb
, offset
, 6, ENC_NA
);
2202 const attribute_info_t cip_safety_attribute_vals
[] = {
2204 /* Safety Supervisor */
2205 {0x39, true, 99, -1, "Subclass", cip_uint
, &hf_cip_ssupervisor_class_subclass
, NULL
},
2206 {0x39, false, 1, -1, "Number of Attributes", cip_usint
, &hf_cip_ssupervisor_num_attr
, NULL
},
2207 {0x39, false, 2, -1, "Attribute List", cip_usint_array
, &hf_cip_ssupervisor_attr_list
, NULL
},
2208 {0x39, false, 5, -1, "Manufacturer Name", cip_short_string
, &hf_cip_ssupervisor_manufacture_name
, NULL
},
2209 {0x39, false, 6, -1, "Manufacturer Model Number", cip_short_string
, &hf_cip_ssupervisor_manufacture_model_number
, NULL
},
2210 {0x39, false, 7, -1, "Software Revision Level", cip_short_string
, &hf_cip_ssupervisor_sw_rev_level
, NULL
},
2211 {0x39, false, 8, -1, "Hardware Revision Level", cip_short_string
, &hf_cip_ssupervisor_hw_rev_level
, NULL
},
2212 {0x39, false, 9, -1, "Manufacturer Serial Number", cip_short_string
, &hf_cip_ssupervisor_manufacture_serial_number
, NULL
},
2213 {0x39, false, 10, -1, "Device Configuration", cip_short_string
, &hf_cip_ssupervisor_device_config
, NULL
},
2214 {0x39, false, 11, -1, "Device Status", cip_usint
, &hf_cip_ssupervisor_device_status
, NULL
},
2215 {0x39, false, 12, -1, "Exception Status", cip_byte
, &hf_cip_ssupervisor_exception_status
, NULL
},
2216 {0x39, false, 13, -1, "Exception Detail Alarm", cip_dissector_func
, NULL
, dissect_s_supervisor_exception_detail_common
},
2217 {0x39, false, 14, -1, "Exception Detail Warning", cip_dissector_func
, NULL
, dissect_s_supervisor_exception_detail_common
},
2218 {0x39, false, 15, -1, "Alarm Enable", cip_bool
, &hf_cip_ssupervisor_alarm_enable
, NULL
},
2219 {0x39, false, 16, -1, "Warning Enable", cip_bool
, &hf_cip_ssupervisor_warning_enable
, NULL
},
2220 {0x39, false, 17, -1, "Time", cip_date_and_time
, &hf_cip_ssupervisor_time
, NULL
},
2221 {0x39, false, 18, -1, "Clock Power Cycle Behavior", cip_usint
, &hf_cip_ssupervisor_clock_power_cycle_behavior
, NULL
},
2222 {0x39, false, 19, -1, "Last Maintenance Date", cip_date
, &hf_cip_ssupervisor_last_maintenance_date
, NULL
},
2223 {0x39, false, 20, -1, "Next Scheduled Maintenance Date", cip_date
, &hf_cip_ssupervisor_next_scheduled_maintenance_date
, NULL
},
2224 {0x39, false, 21, -1, "Scheduled Maintenance Expiration Timer", cip_int
, &hf_cip_ssupervisor_scheduled_maintenance_expiration_timer
, NULL
},
2225 {0x39, false, 22, -1, "Scheduled Maintenance Expiration Warning Enable", cip_bool
, &hf_cip_ssupervisor_scheduled_maintenance_expiration_warning_enable
, NULL
},
2226 {0x39, false, 23, -1, "Run Hours", cip_udint
, &hf_cip_ssupervisor_run_hours
, NULL
},
2227 {0x39, false, 24, -1, "Configuration Lock", cip_bool
, &hf_cip_ssupervisor_configuration_lock
, NULL
},
2228 {0x39, false, 25, -1, "Configuration UNID (CFUNID)", cip_dissector_func
, NULL
, dissect_s_supervisor_configuration_unid
},
2229 {0x39, false, 26, -1, "Safety Configuration Identifier (SCID)", cip_dissector_func
, NULL
, dissect_s_supervisor_safety_configuration_id
},
2230 {0x39, false, 27, -1, "Target UNID (TUNID)", cip_dissector_func
, NULL
, dissect_s_supervisor_target_unid
},
2231 {0x39, false, 28, -1, "Output Connection Point Owners", cip_dissector_func
, NULL
, dissect_s_supervisor_output_connection_point_owners
},
2232 {0x39, false, 29, -1, "Proposed TUNID", cip_dissector_func
, NULL
, dissect_s_supervisor_proposed_tunid
},
2233 {0x39, false, 99, -1, "Subclass", cip_uint
, &hf_cip_ssupervisor_instance_subclass
, NULL
},
2235 /* Safety Validator */
2236 {0x3A, true, 8, -1, "Safety Connection Fault Count", cip_uint
, &hf_cip_svalidator_sconn_fault_count
, NULL
},
2237 {0x3A, false, 1, 0, "Safety Validator State", cip_usint
, &hf_cip_svalidator_state
, NULL
},
2238 {0x3A, false, 2, 1, "Safety Validator Type", cip_dissector_func
, NULL
, dissect_s_validator_type
},
2239 {0x3A, false, 3, 2, "Ping Interval EPI Multiplier", cip_uint
, &hf_cip_svalidator_ping_epi
, NULL
},
2240 {0x3A, false, 4, 3, "Time Coord Msg Min Multiplier", cip_dissector_func
, NULL
, dissect_s_validator_time_coord_msg_min_mult
},
2241 {0x3A, false, 5, 4, "Network Time Expectation Multiplier", cip_dissector_func
, NULL
, dissect_s_validator_network_time_multiplier
},
2242 {0x3A, false, 6, 5, "Timeout Multiplier", cip_dissector_func
, NULL
, dissect_s_validator_timeout_multiplier
},
2243 {0x3A, false, 7, 6, "Max Consumer Number", cip_usint
, &hf_cip_svalidator_max_consumer_num
, NULL
},
2244 {0x3A, false, 8, 7, "Data Connection Instance", cip_uint
, &hf_cip_svalidator_data_conn_inst
, NULL
},
2245 {0x3A, false, 9, 8, "Coordination Connection Instance", cip_dissector_func
, NULL
, dissect_s_validator_coordination_conn_inst
},
2246 {0x3A, false, 10, 9, "Correction Connection Instance", cip_uint
, &hf_cip_svalidator_correction_conn_inst
, NULL
},
2247 {0x3A, false, 11, 10, "CCO Binding", cip_uint
, &hf_cip_svalidator_cco_binding
, NULL
},
2248 {0x3A, false, 12, 11, "Max Data Age", cip_uint
, &hf_cip_svalidator_max_data_age
, NULL
},
2249 {0x3A, false, 13, 12, "Application Data Path", cip_dissector_func
, NULL
, dissect_s_validator_app_data_path
},
2250 /* Note: Get Attributes All can't get to "Error Code", because dissect_s_validator_app_data_path() will use
2251 all remaining bytes. */
2252 {0x3A, false, 14, 13, "Error Code", cip_uint
, &hf_cip_svalidator_error_code
, NULL
},
2253 {0x3A, false, 15, -1, "Producer/Consumer Fault Counters", cip_dissector_func
, NULL
, dissect_s_validator_prod_cons_fault_count
},
2255 /* SERCOS III Link */
2256 {0x4C, false, 1, -1, "Safety Network Number", cip_dissector_func
, NULL
, dissect_sercosiii_safety_network_number
},
2257 {0x4C, false, 2, -1, "Communication Cycle Time", cip_udint
, &hf_cip_sercosiii_link_communication_cycle_time
, NULL
},
2258 {0x4C, false, 3, -1, "Interface Status", cip_word
, &hf_cip_sercosiii_link_interface_status
, NULL
},
2259 {0x4C, false, 4, -1, "Error counter MST-P/S", cip_uint
, &hf_cip_sercosiii_link_error_count_mstps
, NULL
},
2260 {0x4C, false, 5, -1, "Error counter Port1 and Port2", cip_dissector_func
, NULL
, dissect_sercosiii_link_error_count_p1p2
},
2261 {0x4C, false, 6, -1, "SERCOS address", cip_uint
, &hf_cip_sercosiii_link_sercos_address
, NULL
},
2265 * Protocol initialization
2269 * Function name: proto_register_cipsafety
2271 * Purpose: Register the protocol with Wireshark, a script will add this protocol
2272 * to the list of protocols during the build process. This function is where the
2273 * header fields and subtree identifiers are registered.
2278 proto_register_cipsafety(void)
2280 /* This is a list of header fields that can be used in the dissection or
2281 * to use in a filter expression */
2282 static hf_register_info hf
[] =
2285 { "Request/Response", "cip.rr",
2286 FT_UINT8
, BASE_HEX
, VALS(cip_sc_rr
), CIP_SC_RESPONSE_MASK
, "Request or Response message", HFILL
}
2289 { "Data", "cip.data",
2290 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2293 { &hf_cipsafety_data
,
2294 { "Data", "cipsafety.data",
2295 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2297 { &hf_cipsafety_mode_byte
,
2298 { "Mode Byte", "cipsafety.mode_byte",
2299 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2301 { &hf_cipsafety_mode_byte_ping_count
,
2302 { "Ping Count", "cipsafety.mode_byte.ping_count",
2303 FT_UINT8
, BASE_DEC
, NULL
, 0x03, NULL
, HFILL
}
2305 { &hf_cipsafety_mode_byte_not_tbd
,
2306 { "Not TBD Bit", "cipsafety.mode_byte.not_tbd",
2307 FT_BOOLEAN
, 8, NULL
, 0x04, NULL
, HFILL
}
2309 { &hf_cipsafety_mode_byte_tbd_2_copy
,
2310 { "TBD 2 Bit Copy", "cipsafety.mode_byte.tbd_2_copy",
2311 FT_BOOLEAN
, 8, NULL
, 0x08, NULL
, HFILL
}
2313 { &hf_cipsafety_mode_byte_not_run_idle
,
2314 { "Not Run/Idle", "cipsafety.mode_byte.not_run_idle",
2315 FT_BOOLEAN
, 8, NULL
, 0x10, NULL
, HFILL
}
2317 { &hf_cipsafety_mode_byte_tbd
,
2318 { "TBD Bit", "cipsafety.mode_byte.tbd",
2319 FT_BOOLEAN
, 8, NULL
, 0x20, NULL
, HFILL
}
2321 { &hf_cipsafety_mode_byte_tbd_2_bit
,
2322 { "TBD 2 Bit", "cipsafety.mode_byte.tbd_2_bit",
2323 FT_BOOLEAN
, 8, NULL
, 0x40, NULL
, HFILL
}
2325 { &hf_cipsafety_mode_byte_run_idle
,
2326 { "Run/Idle", "cipsafety.mode_byte.run_idle",
2327 FT_BOOLEAN
, 8, NULL
, 0x80, NULL
, HFILL
}
2329 { &hf_cipsafety_crc_s1
,
2330 { "CRC S1", "cipsafety.crc_s1",
2331 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2333 { &hf_cipsafety_crc_s1_status
,
2334 { "CRC S1 Status", "cipsafety.crc_s1.status",
2335 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0, NULL
, HFILL
}
2337 { &hf_cipsafety_crc_s2
,
2338 { "CRC S2", "cipsafety.crc_s2",
2339 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2341 { &hf_cipsafety_crc_s2_status
,
2342 { "CRC S2 Status", "cipsafety.crc_s2.status",
2343 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0, NULL
, HFILL
}
2345 { &hf_cipsafety_crc_s3
,
2346 { "CRC S3", "cipsafety.crc_s3",
2347 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2349 { &hf_cipsafety_crc_s3_status
,
2350 { "CRC S3 Status", "cipsafety.crc_s3.status",
2351 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0, NULL
, HFILL
}
2353 { &hf_cipsafety_complement_crc_s3
,
2354 { "Complement CRC S3", "cipsafety.complement_crc_s3",
2355 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2357 { &hf_cipsafety_complement_crc_s3_status
,
2358 { "Complement CRC S3 Status", "cipsafety.complement_crc_s3.status",
2359 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0, NULL
, HFILL
}
2361 { &hf_cipsafety_timestamp
,
2362 { "Timestamp", "cipsafety.timestamp",
2363 FT_UINT16
, BASE_CUSTOM
, CF_FUNC(cip_safety_128us_fmt
), 0, NULL
, HFILL
}
2365 { &hf_cipsafety_ack_byte
,
2366 { "ACK Byte", "cipsafety.ack_byte",
2367 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2369 { &hf_cipsafety_ack_byte_ping_count_reply
,
2370 { "Ping Count Reply", "cipsafety.ack_byte.ping_count_reply",
2371 FT_UINT8
, BASE_HEX
, NULL
, 0x03, NULL
, HFILL
}
2373 { &hf_cipsafety_ack_byte_reserved1
,
2374 { "Reserved", "cipsafety.ack_byte.reserved1",
2375 FT_UINT8
, BASE_HEX
, NULL
, 0x04, NULL
, HFILL
}
2377 { &hf_cipsafety_ack_byte_ping_response
,
2378 { "Ping Response", "cipsafety.ack_byte.ping_response",
2379 FT_BOOLEAN
, 8, NULL
, 0x08, NULL
, HFILL
}
2381 { &hf_cipsafety_ack_byte_reserved2
,
2382 { "Reserved", "cipsafety.ack_byte.reserved2",
2383 FT_UINT8
, BASE_HEX
, NULL
, 0x70, NULL
, HFILL
}
2385 { &hf_cipsafety_ack_byte_parity_even
,
2386 { "Parity Even", "cipsafety.ack_byte.parity_even",
2387 FT_BOOLEAN
, 8, NULL
, 0x80, NULL
, HFILL
}
2389 { &hf_cipsafety_ack_byte2
,
2390 { "ACK Byte 2", "cipsafety.ack_byte2",
2391 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2393 { &hf_cipsafety_consumer_time_value
,
2394 { "Consumer Time Value", "cipsafety.consumer_time_value",
2395 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2397 { &hf_cipsafety_mcast_byte
,
2398 { "MCAST Byte", "cipsafety.mcast_byte",
2399 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2401 { &hf_cipsafety_mcast_byte_consumer_num
,
2402 { "Consumer #", "cipsafety.mcast_byte.consumer_num",
2403 FT_UINT8
, BASE_HEX
, NULL
, 0x0F, NULL
, HFILL
}
2405 { &hf_cipsafety_mcast_byte_reserved1
,
2406 { "Reserved", "cipsafety.mcast_byte.reserved1",
2407 FT_UINT8
, BASE_HEX
, NULL
, 0x10, NULL
, HFILL
}
2409 { &hf_cipsafety_mcast_byte_mai
,
2410 { "Multicast Active/Idle", "cipsafety.mcast_byte.active_idle",
2411 FT_BOOLEAN
, 8, TFS(&cip_safety_vals_active_idle
), 0x20, NULL
, HFILL
}
2413 { &hf_cipsafety_mcast_byte_reserved2
,
2414 { "Reserved", "cipsafety.mcast_byte.reserved2",
2415 FT_UINT8
, BASE_HEX
, NULL
, 0x40, NULL
, HFILL
}
2417 { &hf_cipsafety_mcast_byte_parity_even
,
2418 { "Parity Even", "cipsafety.mcast_byte.parity_even",
2419 FT_BOOLEAN
, 8, NULL
, 0x80, NULL
, HFILL
}
2421 { &hf_cipsafety_mcast_byte2
,
2422 { "MCAST Byte 2", "cipsafety.mcast_byte2",
2423 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2425 { &hf_cipsafety_time_correction
,
2426 { "Time Correction", "cipsafety.time_correction",
2427 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2429 { &hf_cipsafety_crc_s5_0
,
2430 { "CRC S5_0", "cipsafety.crc_s5_0",
2431 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2433 { &hf_cipsafety_crc_s5_1
,
2434 { "CRC S5_1", "cipsafety.crc_s5_1",
2435 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2437 { &hf_cipsafety_crc_s5_2
,
2438 { "CRC S5_2", "cipsafety.crc_s5_2",
2439 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2441 { &hf_cipsafety_crc_s5_status
,
2442 { "CRC S5 Status", "cipsafety.crc_s5.status",
2443 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0, NULL
, HFILL
}
2445 { &hf_cipsafety_complement_data
,
2446 { "Complement Data", "cipsafety.complement_data",
2447 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2450 { &hf_cip_safety_message_encoding
,
2451 { "Safety Message Encoding", "cipsafety.message_encoding",
2452 FT_UINT32
, BASE_DEC
, VALS(safety_message_encoding_vals
), 0, NULL
, HFILL
}
2455 { &hf_cip_sercosiii_link_snn
,
2456 { "Data", "cipsafety.sercosiii_link.snn",
2457 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2459 { &hf_cip_sercosiii_link_communication_cycle_time
,
2460 { "Communication Cycle Time", "cipsafety.sercosiii_link.communication_cycle_time",
2461 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2463 { &hf_cip_sercosiii_link_interface_status
,
2464 { "Interface Status", "cipsafety.sercosiii_link.interface_status",
2465 FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2467 { &hf_cip_sercosiii_link_error_count_mstps
,
2468 { "Error Counter MST-P/S", "cipsafety.sercosiii_link.error_count_mstps",
2469 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2471 { &hf_cip_sercosiii_link_error_count_p1
,
2472 { "Error Count Port 1", "cipsafety.sercosiii_link.error_count_p1",
2473 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2475 { &hf_cip_sercosiii_link_error_count_p2
,
2476 { "Error Count Port 2", "cipsafety.sercosiii_link.error_count_p2",
2477 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2479 { &hf_cip_sercosiii_link_sercos_address
,
2480 { "SERCOS Address", "cipsafety.sercosiii_link.sercos_address",
2481 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2485 static hf_register_info hf_ssupervisor
[] = {
2486 { &hf_cip_ssupervisor_sc
,
2487 { "Service", "cipsafety.ssupervisor.sc",
2488 FT_UINT8
, BASE_HEX
, VALS(cip_sc_vals_ssupervisor
), CIP_SC_MASK
, NULL
, HFILL
}
2490 { &hf_cip_ssupervisor_recover_data
,
2491 { "Data", "cipsafety.ssupervisor.recover.data",
2492 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2494 { &hf_cip_ssupervisor_perform_diag_data
,
2495 { "Data", "cipsafety.ssupervisor.perform_diag.data",
2496 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2498 { &hf_cip_ssupervisor_configure_request_password
,
2499 { "Password", "cipsafety.ssupervisor.configure_request.password",
2500 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2502 { &hf_cip_ssupervisor_configure_request_tunid
,
2503 { "Target UNID", "cipsafety.ssupervisor.configure_request.tunid",
2504 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2506 { &hf_cip_ssupervisor_configure_request_tunid_snn_timestamp
,
2507 { "TUNID SNN Timestamp", "cipsafety.ssupervisor.configure_request.tunid.snn.timestamp",
2508 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2510 { &hf_cip_ssupervisor_configure_request_tunid_snn_date
,
2511 { "TUNID SNN (Manual) Date", "cipsafety.ssupervisor.configure_request.tunid.snn.date",
2512 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2514 { &hf_cip_ssupervisor_configure_request_tunid_snn_time
,
2515 { "TUNID SNN (Manual) Time", "cipsafety.ssupervisor.configure_request.tunid.snn.time",
2516 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2518 { &hf_cip_ssupervisor_configure_request_tunid_nodeid
,
2519 { "Node ID", "cipsafety.ssupervisor.configure_request.tunid.nodeid",
2520 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2522 { &hf_cip_ssupervisor_configure_request_ounid
,
2523 { "Originator UNID", "cipsafety.ssupervisor.configure_request.ounid",
2524 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2526 { &hf_cip_ssupervisor_configure_request_ounid_snn_timestamp
,
2527 { "OUNID SNN Timestamp", "cipsafety.ssupervisor.configure_request.ounid.snn.timestamp",
2528 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2530 { &hf_cip_ssupervisor_configure_request_ounid_snn_date
,
2531 { "OUNID SNN (Manual) Date", "cipsafety.ssupervisor.configure_request.ounid.snn.date",
2532 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2534 { &hf_cip_ssupervisor_configure_request_ounid_snn_time
,
2535 { "OUNID SNN (Manual) Time", "cipsafety.ssupervisor.configure_request.ounid.snn.time",
2536 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2538 { &hf_cip_ssupervisor_configure_request_ounid_nodeid
,
2539 { "Node ID", "cipsafety.ssupervisor.configure_request.ounid.nodeid",
2540 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2542 { &hf_cip_ssupervisor_validate_configuration_sccrc
,
2543 { "SCCRC", "cipsafety.ssupervisor.validate_configuration.sccrc",
2544 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2546 { &hf_cip_ssupervisor_validate_configuration_scts_timestamp
,
2547 { "SCTS (Timestamp)", "cipsafety.ssupervisor.validate_configuration.scts.timestamp",
2548 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2550 { &hf_cip_ssupervisor_validate_configuration_scts_date
,
2551 { "SCTS (Manual) Date", "cipsafety.ssupervisor.validate_configuration.scts.date",
2552 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2554 { &hf_cip_ssupervisor_validate_configuration_scts_time
,
2555 { "SCTS (Manual) Time", "cipsafety.ssupervisor.validate_configuration.scts.time",
2556 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2558 { &hf_cip_ssupervisor_validate_configuration_ext_error
,
2559 { "Extended Error", "cipsafety.ssupervisor.validate_configuration.ext_error",
2560 FT_UINT16
, BASE_DEC
, VALS(cip_ssupervisor_validate_configuration_ext_error_vals
), 0, NULL
, HFILL
}
2562 { &hf_cip_ssupervisor_set_password_current_password
,
2563 { "Current Password", "cipsafety.ssupervisor.set_password.current_pass",
2564 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2566 { &hf_cip_ssupervisor_set_password_new_password
,
2567 { "New Password", "cipsafety.ssupervisor.set_password.new_pass",
2568 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2570 { &hf_cip_ssupervisor_configure_lock_value
,
2571 { "Lock Value", "cipsafety.ssupervisor.configure_lock.lock",
2572 FT_UINT8
, BASE_DEC
, VALS(cip_ssupervisor_lock_vals
), 0, NULL
, HFILL
}
2574 { &hf_cip_ssupervisor_configure_lock_password
,
2575 { "Password", "cipsafety.ssupervisor.configure_lock.password",
2576 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2578 { &hf_cip_ssupervisor_configure_lock_tunid
,
2579 { "Target UNID", "cipsafety.ssupervisor.configure_lock.tunid",
2580 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2582 { &hf_cip_ssupervisor_configure_lock_tunid_snn_timestamp
,
2583 { "TUNID SNN Timestamp", "cipsafety.ssupervisor.configure_lock.tunid.snn.timestamp",
2584 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2586 { &hf_cip_ssupervisor_configure_lock_tunid_snn_date
,
2587 { "TUNID SNN (Manual) Date", "cipsafety.ssupervisor.configure_lock.tunid.snn.date",
2588 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2590 { &hf_cip_ssupervisor_configure_lock_tunid_snn_time
,
2591 { "TUNID SNN (Manual) Time", "cipsafety.ssupervisor.configure_lock.tunid.snn.time",
2592 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2594 { &hf_cip_ssupervisor_configure_lock_tunid_nodeid
,
2595 { "Node ID", "cipsafety.ssupervisor.configure_lock.tunid.nodeid",
2596 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2598 { &hf_cip_ssupervisor_mode_change_value
,
2599 { "Value", "cipsafety.ssupervisor.mode_change.value",
2600 FT_UINT8
, BASE_DEC
, VALS(cip_ssupervisor_change_mode_vals
), 0, NULL
, HFILL
}
2602 { &hf_cip_ssupervisor_mode_change_password
,
2603 { "Password", "cipsafety.ssupervisor.mode_change.password",
2604 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2606 { &hf_cip_ssupervisor_reset_type
,
2607 { "Reset Type", "cipsafety.ssupervisor.reset.type",
2608 FT_UINT8
, BASE_DEC
, VALS(cip_reset_type_vals
), 0, NULL
, HFILL
}
2610 { &hf_cip_ssupervisor_reset_password
,
2611 { "Password", "cipsafety.ssupervisor.reset.password",
2612 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2614 { &hf_cip_ssupervisor_reset_tunid
,
2615 { "Target UNID", "cipsafety.ssupervisor.reset.tunid",
2616 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2618 { &hf_cip_ssupervisor_reset_tunid_tunid_snn_timestamp
,
2619 { "TUNID SNN Timestamp", "cipsafety.ssupervisor.reset.tunid.snn.timestamp",
2620 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2622 { &hf_cip_ssupervisor_reset_tunid_tunid_snn_date
,
2623 { "TUNID SNN (Manual) Date", "cipsafety.ssupervisor.reset.tunid.snn.date",
2624 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2626 { &hf_cip_ssupervisor_reset_tunid_tunid_snn_time
,
2627 { "TUNID SNN (Manual) Time", "cipsafety.ssupervisor.reset.tunid.snn.time",
2628 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2630 { &hf_cip_ssupervisor_reset_tunid_nodeid
,
2631 { "Node ID", "cipsafety.ssupervisor.reset.tunid.nodeid",
2632 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2634 { &hf_cip_ssupervisor_reset_attr_bitmap
,
2635 { "Attribute Bit Map", "cipsafety.ssupervisor.reset.attr_bitmap",
2636 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2638 { &hf_cip_ssupervisor_reset_attr_bitmap_macid
,
2639 { "Preserve MacID", "cipsafety.ssupervisor.reset.attr_bitmap.macid",
2640 FT_BOOLEAN
, 8, NULL
, 0x01, NULL
, HFILL
}
2642 { &hf_cip_ssupervisor_reset_attr_bitmap_baudrate
,
2643 { "Preserve Baud Rate", "cipsafety.ssupervisor.reset.attr_bitmap.baudrate",
2644 FT_BOOLEAN
, 8, NULL
, 0x02, NULL
, HFILL
}
2646 { &hf_cip_ssupervisor_reset_attr_bitmap_tunid
,
2647 { "Preserve TUNID", "cipsafety.ssupervisor.reset.attr_bitmap.tunid",
2648 FT_BOOLEAN
, 8, NULL
, 0x04, NULL
, HFILL
}
2650 { &hf_cip_ssupervisor_reset_attr_bitmap_password
,
2651 { "Preserve Password", "cipsafety.ssupervisor.reset.attr_bitmap.password",
2652 FT_BOOLEAN
, 8, NULL
, 0x08, NULL
, HFILL
}
2654 { &hf_cip_ssupervisor_reset_attr_bitmap_cfunid
,
2655 { "Preserve CFUNID", "cipsafety.ssupervisor.reset.attr_bitmap.cfunid",
2656 FT_BOOLEAN
, 8, NULL
, 0x10, NULL
, HFILL
}
2658 { &hf_cip_ssupervisor_reset_attr_bitmap_ocpunid
,
2659 { "Preserve OPCUNID", "cipsafety.ssupervisor.reset.attr_bitmap.ocpunid",
2660 FT_BOOLEAN
, 8, NULL
, 0x20, NULL
, HFILL
}
2662 { &hf_cip_ssupervisor_reset_attr_bitmap_reserved
,
2663 { "Reserved", "cipsafety.ssupervisor.reset.attr_bitmap.reserved",
2664 FT_BOOLEAN
, 8, NULL
, 0x40, NULL
, HFILL
}
2666 { &hf_cip_ssupervisor_reset_attr_bitmap_extended
,
2667 { "Use Extended Map", "cipsafety.ssupervisor.reset.attr_bitmap.extended",
2668 FT_BOOLEAN
, 8, NULL
, 0x80, NULL
, HFILL
}
2670 { &hf_cip_ssupervisor_reset_password_data_size
,
2671 { "Data Size", "cipsafety.ssupervisor.reset_password.data_size",
2672 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2674 { &hf_cip_ssupervisor_reset_password_data
,
2675 { "Password Data", "cipsafety.ssupervisor.reset_password.password_data",
2676 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2678 { &hf_cip_ssupervisor_propose_tunid_tunid
,
2679 { "Target UNID", "cipsafety.ssupervisor.propose_tunid.tunid",
2680 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2682 { &hf_cip_ssupervisor_propose_tunid_tunid_snn_timestamp
,
2683 { "TUNID SNN Timestamp", "cipsafety.ssupervisor.propose_tunid.tunid.snn.timestamp",
2684 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2686 { &hf_cip_ssupervisor_propose_tunid_tunid_snn_date
,
2687 { "TUNID SNN (Manual) Date", "cipsafety.ssupervisor.propose_tunid.tunid.snn.date",
2688 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2690 { &hf_cip_ssupervisor_propose_tunid_tunid_snn_time
,
2691 { "TUNID SNN (Manual) Time", "cipsafety.ssupervisor.propose_tunid.tunid.snn.time",
2692 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2694 { &hf_cip_ssupervisor_propose_tunid_tunid_nodeid
,
2695 { "Node ID", "cipsafety.ssupervisor.propose_tunid.tunid.nodeid",
2696 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2698 { &hf_cip_ssupervisor_apply_tunid_tunid
,
2699 { "Target UNID", "cipsafety.ssupervisor.apply_tunid.tunid",
2700 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2702 { &hf_cip_ssupervisor_apply_tunid_tunid_snn_timestamp
,
2703 { "TUNID SNN Timestamp", "cipsafety.ssupervisor.apply_tunid.tunid.snn.timestamp",
2704 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2706 { &hf_cip_ssupervisor_apply_tunid_tunid_snn_date
,
2707 { "TUNID SNN (Manual) Date", "cipsafety.ssupervisor.apply_tunid.tunid.snn.date",
2708 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2710 { &hf_cip_ssupervisor_apply_tunid_tunid_snn_time
,
2711 { "TUNID SNN (Manual) Time", "cipsafety.ssupervisor.apply_tunid.tunid.snn.time",
2712 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2714 { &hf_cip_ssupervisor_apply_tunid_tunid_nodeid
,
2715 { "Node ID", "cipsafety.ssupervisor.apply_tunid.tunid.nodeid",
2716 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2718 { &hf_cip_ssupervisor_class_subclass
,
2719 { "Subclass", "cipsafety.ssupervisor.class_subclass",
2720 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2722 { &hf_cip_ssupervisor_num_attr
,
2723 { "Number of Attributes", "cipsafety.ssupervisor.num_attr",
2724 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2726 { &hf_cip_ssupervisor_attr_list
,
2727 { "Attributes List Item", "cipsafety.ssupervisor.attr_item",
2728 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2730 { &hf_cip_ssupervisor_manufacture_name
,
2731 { "Manufacturer Name", "cipsafety.ssupervisor.manufacture_name",
2732 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2734 { &hf_cip_ssupervisor_manufacture_model_number
,
2735 { "Manufacturer Model Number", "cipsafety.ssupervisor.manufacture_model_number",
2736 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2738 { &hf_cip_ssupervisor_sw_rev_level
,
2739 { "Software Revision Level", "cipsafety.ssupervisor.sw_rev_level",
2740 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2742 { &hf_cip_ssupervisor_hw_rev_level
,
2743 { "Hardware Revision Level", "cipsafety.ssupervisor.hw_rev_level",
2744 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2746 { &hf_cip_ssupervisor_manufacture_serial_number
,
2747 { "Manufacturer Serial Number", "cipsafety.ssupervisor.manufacture_serial_number",
2748 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2750 { &hf_cip_ssupervisor_device_config
,
2751 { "Device Configuration", "cipsafety.ssupervisor.device_config",
2752 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2754 { &hf_cip_ssupervisor_device_status
,
2755 { "Device Status", "cipsafety.ssupervisor.device_status",
2756 FT_UINT8
, BASE_DEC
, VALS(cip_ssupervisor_device_status_type_vals
), 0, NULL
, HFILL
}
2758 { &hf_cip_ssupervisor_exception_status
,
2759 { "Exception Status", "cipsafety.ssupervisor.exception_status",
2760 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2762 { &hf_cip_ssupervisor_exception_detail_ced_size
,
2763 { "Common Exception Detail Size", "cipsafety.ssupervisor.exception_detail.ced.size",
2764 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2766 { &hf_cip_ssupervisor_exception_detail_ced_detail
,
2767 { "Common Exception Detail Data", "cipsafety.ssupervisor.exception_detail.ced.detail",
2768 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2770 { &hf_cip_ssupervisor_exception_detail_ded_size
,
2771 { "Device Exception Detail Size", "cipsafety.ssupervisor.exception_detail.ded.size",
2772 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2774 { &hf_cip_ssupervisor_exception_detail_ded_detail
,
2775 { "Device Exception Detail Data", "cipsafety.ssupervisor.exception_detail.ded.detail",
2776 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2778 { &hf_cip_ssupervisor_exception_detail_med_size
,
2779 { "Manufacturer Exception Detail Size", "cipsafety.ssupervisor.exception_detail.med.size",
2780 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2782 { &hf_cip_ssupervisor_exception_detail_med_detail
,
2783 { "Manufacturer Exception Detail Data", "cipsafety.ssupervisor.exception_detail.med.detail",
2784 FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2786 { &hf_cip_ssupervisor_alarm_enable
,
2787 { "Exception Detail Alarm", "cipsafety.ssupervisor.alarm_enable",
2788 FT_BOOLEAN
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2790 { &hf_cip_ssupervisor_warning_enable
,
2791 { "Exception Detail Warning", "cipsafety.ssupervisor.warning_enable",
2792 FT_BOOLEAN
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
2794 { &hf_cip_ssupervisor_time
,
2795 { "Time", "cipsafety.ssupervisor.time",
2796 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2798 { &hf_cip_ssupervisor_clock_power_cycle_behavior
,
2799 { "Clock Power Cycle Behavior", "cipsafety.ssupervisor.clock_power_cycle_behavior",
2800 FT_UINT8
, BASE_DEC
, VALS(cip_ssupervisor_clock_power_cycle_type_vals
), 0, NULL
, HFILL
}
2802 { &hf_cip_ssupervisor_last_maintenance_date
,
2803 { "Last Maintenance Date", "cipsafety.ssupervisor.last_maintenance_date",
2804 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2806 { &hf_cip_ssupervisor_next_scheduled_maintenance_date
,
2807 { "Next Scheduled Maintenance Date", "cipsafety.ssupervisor.next_scheduled_maintenance_date",
2808 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2810 { &hf_cip_ssupervisor_scheduled_maintenance_expiration_timer
,
2811 { "Scheduled Maintenance Expiration Timer", "cipsafety.ssupervisor.scheduled_maintenance_expiration_timer",
2812 FT_INT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2814 { &hf_cip_ssupervisor_scheduled_maintenance_expiration_warning_enable
,
2815 { "Scheduled Maintenance Expiration Warning Enable", "cipsafety.ssupervisor.scheduled_maintenance_expiration_warning",
2816 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_enabled_disabled
), 0, NULL
, HFILL
}
2818 { &hf_cip_ssupervisor_run_hours
,
2819 { "Run Hours", "cipsafety.ssupervisor.run_hours",
2820 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2822 { &hf_cip_ssupervisor_configuration_lock
,
2823 { "Configuration Lock", "cipsafety.ssupervisor.configuration_lock",
2824 FT_UINT8
, BASE_DEC
, VALS(cip_ssupervisor_lock_vals
), 0, NULL
, HFILL
}
2826 { &hf_cip_ssupervisor_configuration_unid_snn_timestamp
,
2827 { "Configuration UNID SNN Timestamp", "cipsafety.ssupervisor.configuration_unid.snn.timestamp",
2828 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2830 { &hf_cip_ssupervisor_configuration_unid_snn_date
,
2831 { "Configuration UNID SNN (Manual) Date", "cipsafety.ssupervisor.configuration_unid.snn.date",
2832 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2834 { &hf_cip_ssupervisor_configuration_unid_snn_time
,
2835 { "Configuration UNID SNN (Manual) Time", "cipsafety.ssupervisor.configuration_unid.snn.time",
2836 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2838 { &hf_cip_ssupervisor_configuration_unid_nodeid
,
2839 { "Configuration UNID Node ID", "cipsafety.ssupervisor.configuration_unid.nodeid",
2840 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2842 { &hf_cip_ssupervisor_safety_configuration_id_snn_timestamp
,
2843 { "Safety Configuration ID SNN Timestamp", "cipsafety.ssupervisor.safety_configuration_id.snn.timestamp",
2844 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2846 { &hf_cip_ssupervisor_safety_configuration_id_snn_date
,
2847 { "Safety Configuration ID SNN (Manual) Date", "cipsafety.ssupervisor.safety_configuration_id.snn.date",
2848 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2850 { &hf_cip_ssupervisor_safety_configuration_id_snn_time
,
2851 { "Safety Configuration ID SNN (Manual) Time", "cipsafety.ssupervisor.safety_configuration_id.snn.time",
2852 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2854 { &hf_cip_ssupervisor_safety_configuration_id_sccrc
,
2855 { "Safety Configuration ID SCCRC", "cipsafety.ssupervisor.safety_configuration_id.sccrc",
2856 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2858 { &hf_cip_ssupervisor_target_unid_snn_timestamp
,
2859 { "Target UNID SNN Timestamp", "cipsafety.ssupervisor.target_unid.snn.timestamp",
2860 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2862 { &hf_cip_ssupervisor_target_unid_snn_date
,
2863 { "Target UNID SNN (Manual) Date", "cipsafety.ssupervisor.target_unid.snn.date",
2864 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2866 { &hf_cip_ssupervisor_target_unid_snn_time
,
2867 { "Target UNID SNN (Manual) Time", "cipsafety.ssupervisor.target_unid.snn.time",
2868 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2870 { &hf_cip_ssupervisor_target_unid_nodeid
,
2871 { "Target UNID Node ID", "cipsafety.ssupervisor.target_unid.nodeid",
2872 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2874 { &hf_cip_ssupervisor_cp_owners_num_entries
,
2875 { "Number of Array Entries", "cipsafety.ssupervisor.cp_owners.num_entries",
2876 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2878 { &hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_timestamp
,
2879 { "OCPUNID SNN Timestamp", "cipsafety.ssupervisor.cp_owners.snn.timestamp",
2880 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2882 { &hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_date
,
2883 { "OCPUNID SNN (Manual) Date", "cipsafety.ssupervisor.cp_owners.snn.date",
2884 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2886 { &hf_cip_ssupervisor_output_cp_owners_ocpunid_snn_time
,
2887 { "OCPUNID SNN (Manual) Time", "cipsafety.ssupervisor.cp_owners.snn.time",
2888 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2890 { &hf_cip_ssupervisor_output_cp_owners_ocpunid_nodeid
,
2891 { "OCPUNID Node ID", "cipsafety.ssupervisor.cp_owners.ocpunid.nodeid",
2892 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2894 { &hf_cip_ssupervisor_cp_owners_app_path_size
,
2895 { "EPATH Size", "cipsafety.ssupervisor.cp_owners.epath_size",
2896 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2898 { &hf_cip_ssupervisor_proposed_tunid_snn_timestamp
,
2899 { "Proposed TUNID SNN Timestamp", "cipsafety.ssupervisor.proposed_tunid.snn.timestamp",
2900 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}
2902 { &hf_cip_ssupervisor_proposed_tunid_snn_date
,
2903 { "Proposed TUNID SNN (Manual) Date", "cipsafety.ssupervisor.proposed_tunid.snn.date",
2904 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}
2906 { &hf_cip_ssupervisor_proposed_tunid_snn_time
,
2907 { "Proposed TUNID SNN (Manual) Time", "cipsafety.ssupervisor.proposed_tunid.snn.time",
2908 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2910 { &hf_cip_ssupervisor_proposed_tunid_nodeid
,
2911 { "Proposed TUNID Node ID", "cipsafety.ssupervisor.proposed_tunid.nodeid",
2912 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2914 { &hf_cip_ssupervisor_instance_subclass
,
2915 { "Subclass", "cipsafety.ssupervisor.instance_subclass",
2916 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2920 static hf_register_info hf_svalidator
[] = {
2921 { &hf_cip_svalidator_sc
,
2922 { "Service", "cipsafety.svalidator.sc",
2923 FT_UINT8
, BASE_HEX
, VALS(cip_sc_vals_svalidator
), CIP_SC_MASK
, NULL
, HFILL
}
2926 { &hf_cip_svalidator_sconn_fault_count
,
2927 { "Safety Connection Fault Count", "cipsafety.svalidator.sconn_fault_count",
2928 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2930 { &hf_cip_svalidator_state
,
2931 { "Safety Validator State", "cipsafety.svalidator.state",
2932 FT_UINT8
, BASE_DEC
, VALS(cip_svalidator_state_vals
), 0, NULL
, HFILL
}
2934 { &hf_cip_svalidator_type
,
2935 { "Safety Validator Type", "cipsafety.svalidator.type",
2936 FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
2938 { &hf_cip_svalidator_type_pc
,
2939 { "Producer/Consumer", "cipsafety.svalidator.type.pc",
2940 FT_UINT8
, BASE_HEX
, VALS(cip_svalidator_type_pc_vals
), 0x80, NULL
, HFILL
}
2942 { &hf_cip_svalidator_type_conn_type
,
2943 { "Safety Connection Type", "cipsafety.svalidator.type.conn_type",
2944 FT_UINT8
, BASE_DEC
, VALS(cip_svalidator_type_conn_type_vals
), 0x7F, NULL
, HFILL
}
2946 { &hf_cip_svalidator_ping_epi
,
2947 { "Ping Interval EPI Multiplier", "cipsafety.svalidator.ping_epi",
2948 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2950 { &hf_cip_svalidator_time_coord_msg_min_mult_size
,
2951 { "Time Coord Msg Min Multiplier Array Size", "cipsafety.svalidator.time_coord_msg_min_mult.size",
2952 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2954 { &hf_cip_svalidator_time_coord_msg_min_mult_item
,
2955 { "Time Coord Msg Min Multiplier", "cipsafety.svalidator.time_coord_msg_min_mult.item",
2956 FT_UINT16
, BASE_CUSTOM
, CF_FUNC(cip_safety_128us_fmt
), 0, NULL
, HFILL
}
2958 { &hf_cip_svalidator_network_time_multiplier_size
,
2959 { "Network Time Expectation Multiplier Array Size", "cipsafety.svalidator.network_time_multiplier.size",
2960 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2962 { &hf_cip_svalidator_network_time_multiplier_item
,
2963 { "Network Time Expectation Multiplier", "cipsafety.svalidator.network_time_multiplier.item",
2964 FT_UINT16
, BASE_CUSTOM
, CF_FUNC(cip_safety_128us_fmt
), 0, NULL
, HFILL
}
2966 { &hf_cip_svalidator_timeout_multiplier_size
,
2967 { "Timeout Multiplier Array Size", "cipsafety.svalidator.timeout_multiplier.size",
2968 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2970 { &hf_cip_svalidator_timeout_multiplier_item
,
2971 { "Timeout Multiplier", "cipsafety.svalidator.timeout_multiplier.item",
2972 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2974 { &hf_cip_svalidator_max_consumer_num
,
2975 { "Max Consumer Number", "cipsafety.svalidator.max_consumer_num",
2976 FT_UINT8
, BASE_DEC
|BASE_RANGE_STRING
, RVALS(safety_max_consumer_numbers
), 0, NULL
, HFILL
}
2978 { &hf_cip_svalidator_data_conn_inst
,
2979 { "Data Connection Instance", "cipsafety.svalidator.data_conn_inst",
2980 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2982 { &hf_cip_svalidator_coordination_conn_inst_size
,
2983 { "Coordination Connection Instance Size", "cipsafety.svalidator.coordination_conn_inst.size",
2984 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2986 { &hf_cip_svalidator_coordination_conn_inst_item
,
2987 { "Coordination Connection Instance Item", "cipsafety.svalidator.coordination_conn_inst.item",
2988 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2990 { &hf_cip_svalidator_correction_conn_inst
,
2991 { "Correction Connection Instance", "cipsafety.svalidator.correction_conn_inst",
2992 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2994 { &hf_cip_svalidator_cco_binding
,
2995 { "CCO Binding", "cipsafety.svalidator.cco_binding",
2996 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
2998 { &hf_cip_svalidator_max_data_age
,
2999 { "Max Data Age", "cipsafety.svalidator.max_data_age",
3000 FT_UINT16
, BASE_CUSTOM
, CF_FUNC(cip_safety_128us_fmt
), 0, NULL
, HFILL
}
3002 { &hf_cip_svalidator_error_code
,
3003 { "Error Code", "cipsafety.svalidator.error_code",
3004 FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
3006 { &hf_cip_svalidator_prod_cons_fault_count_size
,
3007 { "Producer/Consumer Counter Array Size", "cipsafety.svalidator.prod_cons_fault_count.size",
3008 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
3010 { &hf_cip_svalidator_prod_cons_fault_count_item
,
3011 { "Producer/Consumer Fault Counter", "cipsafety.svalidator.prod_cons_fault_count.item",
3012 FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
3016 static int *ett
[] = {
3019 &ett_cipsafety_mode_byte
,
3020 &ett_cipsafety_ack_byte
,
3021 &ett_cipsafety_mcast_byte
3024 static int *ett_ssupervisor
[] = {
3025 &ett_cip_class_s_supervisor
,
3026 &ett_ssupervisor_rrsc
,
3027 &ett_ssupervisor_cmd_data
,
3028 &ett_ssupervisor_propose_tunid
,
3029 &ett_ssupervisor_propose_tunid_snn
,
3030 &ett_ssupervisor_configure_request_tunid
,
3031 &ett_ssupervisor_configure_request_tunid_snn
,
3032 &ett_ssupervisor_configure_request_ounid
,
3033 &ett_ssupervisor_configure_request_ounid_snn
,
3034 &ett_ssupervisor_configure_lock_tunid
,
3035 &ett_ssupervisor_configure_lock_tunid_snn
,
3036 &ett_ssupervisor_reset_tunid
,
3037 &ett_ssupervisor_reset_tunid_snn
,
3038 &ett_ssupervisor_apply_tunid
,
3039 &ett_ssupervisor_apply_tunid_snn
,
3040 &ett_exception_detail_common
,
3041 &ett_exception_detail_device
,
3042 &ett_exception_detail_manufacturer
,
3043 &ett_ssupervisor_configuration_unid
,
3044 &ett_ssupervisor_configuration_unid_snn
,
3045 &ett_ssupervisor_target_unid
,
3046 &ett_ssupervisor_target_unid_snn
,
3047 &ett_ssupervisor_output_cp_owners
,
3048 &ett_ssupervisor_output_cp_owners_ocpunid
,
3049 &ett_ssupervisor_output_cp_owners_ocpunid_snn
,
3050 &ett_ssupervisor_proposed_tunid
,
3051 &ett_ssupervisor_proposed_tunid_snn
,
3052 &ett_cip_ssupervisor_reset_attr_bitmap
3055 static int *ett_svalidator
[] = {
3056 &ett_cip_class_s_validator
,
3057 &ett_svalidator_rrsc
,
3058 &ett_svalidator_cmd_data
,
3059 &ett_svalidator_type
3062 static ei_register_info ei
[] = {
3063 { &ei_cipsafety_tbd_not_complemented
, { "cipsafety.tbd_not_complemented", PI_PROTOCOL
, PI_ERROR
, "TBD bit not complemented", EXPFILL
}},
3064 { &ei_cipsafety_tbd2_not_copied
, { "cipsafety.tbd2_not_copied", PI_PROTOCOL
, PI_ERROR
, "TBD2 bit not copied", EXPFILL
}},
3065 { &ei_cipsafety_run_idle_not_complemented
, { "cipsafety.run_idle_not_complemented", PI_PROTOCOL
, PI_ERROR
, "Run/Idle bit not complemented", EXPFILL
}},
3066 { &ei_mal_io
, { "cipsafety.malformed.io", PI_MALFORMED
, PI_ERROR
, "Malformed CIP Safety I/O packet", EXPFILL
}},
3067 { &ei_mal_sercosiii_link_error_count_p1p2
, { "cipsafety.malformed.sercosiii_link.error_count_p1p2", PI_MALFORMED
, PI_ERROR
, "Malformed SERCOS III Attribute 5", EXPFILL
}},
3068 { &ei_cipsafety_not_complement_data
, { "cipsafety.not_complement_data", PI_PROTOCOL
, PI_ERROR
, "Data not complemented", EXPFILL
}},
3069 { &ei_cipsafety_crc_s1
, { "cipsafety.crc_s1.incorrect", PI_PROTOCOL
, PI_ERROR
, "CRC-S1 incorrect", EXPFILL
}},
3070 { &ei_cipsafety_crc_s2
, { "cipsafety.crc_s2.incorrect", PI_PROTOCOL
, PI_ERROR
, "CRC-S2 incorrect", EXPFILL
}},
3071 { &ei_cipsafety_crc_s3
, { "cipsafety.crc_s3.incorrect", PI_PROTOCOL
, PI_ERROR
, "CRC-S3 incorrect", EXPFILL
}},
3072 { &ei_cipsafety_complement_crc_s3
, { "cipsafety.complement_crc_s3.incorrect", PI_PROTOCOL
, PI_ERROR
, "Complement CRC-S3 incorrect", EXPFILL
}},
3073 { &ei_cipsafety_crc_s5
, { "cipsafety.crc_s5.incorrect", PI_PROTOCOL
, PI_ERROR
, "CRC-S5 incorrect", EXPFILL
}},
3076 static ei_register_info ei_ssupervisor
[] = {
3077 { &ei_mal_ssupervisor_exception_detail_ced
, { "cipsafety.ssupervisor.malformed.exception_detail.ced", PI_MALFORMED
, PI_ERROR
,
3078 "Malformed Safety Supervisor Exception Detail (Common Exception Detail)", EXPFILL
}},
3079 { &ei_mal_ssupervisor_exception_detail_ded
, { "cipsafety.ssupervisor.malformed.exception_detail.ded", PI_MALFORMED
, PI_ERROR
,
3080 "Malformed Safety Supervisor Exception Detail (Device Exception Detail)", EXPFILL
}},
3081 { &ei_mal_ssupervisor_exception_detail_med
, { "cipsafety.ssupervisor.malformed.exception_detail.med", PI_MALFORMED
, PI_ERROR
,
3082 "Malformed Safety Supervisor Exception Detail (Manufacturer Exception Detail)", EXPFILL
}},
3083 { &ei_mal_ssupervisor_configuration_unid
, { "cipsafety.ssupervisor.malformed.configuration_unid", PI_MALFORMED
, PI_ERROR
,
3084 "Malformed Safety Supervisor Configuration UNID", EXPFILL
}},
3085 { &ei_mal_ssupervisor_safety_configuration_id
, { "cipsafety.ssupervisor.malformed.safety_configuration_id", PI_MALFORMED
, PI_ERROR
,
3086 "Malformed Safety Supervisor Safety Configuration Identifier", EXPFILL
}},
3087 { &ei_mal_ssupervisor_target_unid
, { "cipsafety.ssupervisor.malformed.target_unid", PI_MALFORMED
, PI_ERROR
,
3088 "Malformed Safety Supervisor Target UNID", EXPFILL
}},
3089 { &ei_mal_ssupervisor_cp_owners
, { "cipsafety.ssupervisor.malformed.cp_owners", PI_MALFORMED
, PI_ERROR
,
3090 "Malformed Safety Supervisor Output Connection Point Owners", EXPFILL
}},
3091 { &ei_mal_ssupervisor_cp_owners_entry
, { "cipsafety.ssupervisor.malformed.cp_owners.entry", PI_MALFORMED
, PI_ERROR
,
3092 "Malformed Safety Supervisor Output Connection Point Owners (UNID)", EXPFILL
}},
3093 { &ei_mal_ssupervisor_cp_owners_app_path_size
, { "cipsafety.ssupervisor.malformed.cp_owners.app_path_size", PI_MALFORMED
, PI_ERROR
,
3094 "Malformed Safety Supervisor Output Connection Point Owners (EPATH)", EXPFILL
}},
3095 { &ei_mal_ssupervisor_proposed_tunid
, { "cipsafety.ssupervisor.malformed.proposed_tunid", PI_MALFORMED
, PI_ERROR
,
3096 "Malformed Safety Supervisor Proposed TUNID", EXPFILL
}},
3097 { &ei_info_ssupervisor_tunid_cancel
, { "cipsafety.ssupervisor.info.cancel_propose_apply", PI_PROTOCOL
, PI_WARN
,
3098 "Cancel Proposed/Apply Operation", EXPFILL
} },
3101 static ei_register_info ei_svalidator
[] = {
3102 { &ei_mal_svalidator_type
, { "cipsafety.ssupervisor.malformed.svalidator.type", PI_MALFORMED
, PI_ERROR
,
3103 "Malformed Safety Validator Type", EXPFILL
}},
3104 { &ei_mal_svalidator_time_coord_msg_min_mult
, { "cipsafety.ssupervisor.malformed.svalidator.time_coord_msg_min_mult", PI_MALFORMED
, PI_ERROR
,
3105 "Malformed Safety Validator Time Coord Msg Min Multiplier", EXPFILL
}},
3106 { &ei_mal_svalidator_network_time_multiplier
, { "cipsafety.ssupervisor.malformed.svalidator.network_time_multiplier", PI_MALFORMED
, PI_ERROR
,
3107 "Malformed Safety Validator Network Time Expectation Multiplier", EXPFILL
}},
3108 { &ei_mal_svalidator_timeout_multiplier
, { "cipsafety.ssupervisor.malformed.svalidator.timeout_multiplier", PI_MALFORMED
, PI_ERROR
,
3109 "Malformed Safety Validator Timeout Multiplier", EXPFILL
}},
3110 { &ei_mal_svalidator_coordination_conn_inst
, { "cipsafety.ssupervisor.malformed.svalidator.coordination_conn_inst", PI_MALFORMED
, PI_ERROR
,
3111 "Malformed Safety Validator Coordination Connection Instance", EXPFILL
}},
3112 { &ei_mal_svalidator_prod_cons_fault_count
, { "cipsafety.ssupervisor.malformed.svalidator.prod_cons_fault_count", PI_MALFORMED
, PI_ERROR
,
3113 "Malformed Safety Validator Produce/Consume Fault Counters", EXPFILL
}},
3116 expert_module_t
* expert_cip_safety
;
3117 expert_module_t
* expert_cip_class_s_supervisor
;
3118 expert_module_t
* expert_cip_class_s_validator
;
3120 /* Create a CIP Safety protocol handle */
3121 proto_cipsafety
= proto_register_protocol("Common Industrial Protocol, Safety", "CIP Safety", "cipsafety");
3122 proto_register_field_array(proto_cipsafety
, hf
, array_length(hf
));
3123 proto_register_subtree_array(ett
, array_length(ett
));
3124 expert_cip_safety
= expert_register_protocol(proto_cipsafety
);
3125 expert_register_field_array(expert_cip_safety
, ei
, array_length(ei
));
3127 cipsafety_handle
= register_dissector( "cipsafety", dissect_cipsafety
, proto_cipsafety
);
3129 // Register different protocols for "Decode As".
3130 proto_cipsafety_base_data
= proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Base - Data",
3131 "CIP Safety - Base - Data",
3135 cipsafety_base_data_handle
= register_dissector("cipsafety_bd", dissect_cipsafety_base_data
, proto_cipsafety_base_data
);
3137 proto_cipsafety_extended_data
= proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Extended - Data",
3138 "CIP Safety - Extended - Data",
3142 cipsafety_extended_data_handle
= register_dissector("cipsafety_ed", dissect_cipsafety_extended_data
, proto_cipsafety_extended_data
);
3144 proto_cipsafety_base_time_coord
= proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Base - Time Coordination",
3145 "CIP Safety - Base - Time Coordination",
3149 cipsafety_base_time_coord_handle
= register_dissector("cipsafety_bt", dissect_cipsafety_base_time_coord
, proto_cipsafety_base_time_coord
);
3151 proto_cipsafety_extended_time_coord
= proto_register_protocol_in_name_only("Common Industrial Protocol, Safety - Extended - Time Coordination",
3152 "CIP Safety - Extended - Time Coordination",
3156 cipsafety_extended_time_coord_handle
= register_dissector("cipsafety_et", dissect_cipsafety_extended_time_coord
, proto_cipsafety_extended_time_coord
);
3159 /* Register CIP Safety objects */
3160 proto_cip_class_s_supervisor
= proto_register_protocol("CIP Safety Supervisor",
3161 "CIPSSupervisor", "cipssupervisor");
3162 cip_class_s_supervisor_handle
= register_dissector("cipssupervisor", dissect_cip_class_s_supervisor
, proto_cip_class_s_supervisor
);
3163 proto_register_field_array(proto_cip_class_s_supervisor
, hf_ssupervisor
, array_length(hf_ssupervisor
));
3164 proto_register_subtree_array(ett_ssupervisor
, array_length(ett_ssupervisor
));
3165 expert_cip_class_s_supervisor
= expert_register_protocol(proto_cip_class_s_supervisor
);
3166 expert_register_field_array(expert_cip_class_s_supervisor
, ei_ssupervisor
, array_length(ei_ssupervisor
));
3168 proto_cip_class_s_validator
= proto_register_protocol("CIP Safety Validator",
3169 "CIPSValidator", "cipsvalidator");
3170 cip_class_s_validator_handle
= register_dissector("cipsvalidator", dissect_cip_class_s_validator
, proto_cip_class_s_validator
);
3171 proto_register_field_array(proto_cip_class_s_validator
, hf_svalidator
, array_length(hf_svalidator
));
3172 proto_register_subtree_array(ett_svalidator
, array_length(ett_svalidator
));
3173 expert_cip_class_s_validator
= expert_register_protocol(proto_cip_class_s_validator
);
3174 expert_register_field_array(expert_cip_class_s_validator
, ei_svalidator
, array_length(ei_svalidator
));
3178 * Function name: proto_reg_handoff_cipsafety
3180 * Purpose: This function will setup the automatic dissection of the CIP Safety datagram,
3181 * it is called by Wireshark when the protocol is registered
3186 proto_reg_handoff_cipsafety(void)
3188 /* Register dissector handle for Safety Supervisor */
3189 dissector_add_uint( "cip.class.iface", CI_CLS_SAFETY_SUPERVISOR
, cip_class_s_supervisor_handle
);
3191 /* Register dissector handle for Safety Validator */
3192 dissector_add_uint( "cip.class.iface", CI_CLS_SAFETY_VALIDATOR
, cip_class_s_validator_handle
);
3193 heur_dissector_add("cip.sc", dissect_class_svalidator_heur
, "CIP Safety Validator", "s_validator_cip", proto_cip_class_s_validator
, HEURISTIC_ENABLE
);
3195 /* Register dissector for I/O data handling */
3196 dissector_add_for_decode_as("cip.io", cipsafety_base_data_handle
);
3197 dissector_add_for_decode_as("cip.io", cipsafety_extended_data_handle
);
3198 dissector_add_for_decode_as("cip.io", cipsafety_base_time_coord_handle
);
3199 dissector_add_for_decode_as("cip.io", cipsafety_extended_time_coord_handle
);
3201 proto_cip
= proto_get_id_by_filter_name( "cip" );
3202 subdissector_class_table
= find_dissector_table("cip.class.iface");
3207 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3212 * indent-tabs-mode: nil
3215 * ex: set shiftwidth=3 tabstop=8 expandtab:
3216 * :indentSize=3:tabSize=8:noTabs=true: