2 * Routines for Common Industrial Protocol (CIP) dissection
3 * CIP Home: www.odva.org
5 * This dissector includes items from:
6 * CIP Volume 1: Common Industrial Protocol, Edition 3.34
7 * CIP Volume 5: CIP Safety, Edition 2.25
8 * CIP Volume 7A: Integration of Modbus Devices into the CIP Architecture, Edition 1.9
9 * CIP Volume 8: CIP Security, Edition 1.11
12 * Magnus Hansson <mah@hms.se>
13 * Joakim Wiberg <jow@hms.se>
15 * Added support for Connection Configuration Object
16 * ryan wamsley * Copyright 2007
18 * Object dependend services based on IOI
19 * Jan Bartels, Siempelkamp Maschinen- und Anlagenbau GmbH & Co. KG
22 * Improved support for CoCo, CM, MB objects
23 * Heuristic object support for common services
24 * Michael Mann * Copyright 2011
26 * Added support for PCCC Objects
27 * Jared Rittle - Cisco Talos
30 * Wireshark - Network traffic analyzer
31 * By Gerald Combs <gerald@wireshark.org>
32 * Copyright 1998 Gerald Combs
34 * SPDX-License-Identifier: GPL-2.0-or-later
37 // There are multiple different ways to add functionality based on CIP class-specific behavior:
38 // 1. Dissector Table "cip.io.iface" - Use this when Class 0/1 I/O needs different parsing based on
39 // the CIP Class in the Forward Open
40 // 2. Dissector Table "cip.connection.class" - Use this when Class 2/3 data needs different parsing
41 // based on the CIP Class in the Forward Open
42 // 3. Dissector Table "cip.class.iface" - Use this when a CIP Class has significantly different
43 // behavior that would be best handled through a separate dissector
44 // 4. Dissector Table "cip.data_segment.iface" - Unknown. This may be removed in the future
45 // 5. attribute_info_t: Use this to add handling for an attribute, using a 3 tuple key (Class, Instance, Attribute)
46 // See 'cip_attribute_vals' for an example.
47 // 6. cip_service_info_t: Use this to add handling for a service, using a 2 tuple key (Class, Service)
48 // See 'cip_obj_spec_service_table' for an example.
52 #include <epan/packet.h>
53 #include <epan/expert.h>
54 #include <epan/prefs.h>
55 #include <epan/proto_data.h>
56 #include <epan/wmem_scopes.h>
58 #include <epan/unit_strings.h>
59 #include <wsutil/array.h>
60 #include "packet-cip.h"
61 #include "packet-cipmotion.h"
62 #include "packet-cipsafety.h"
63 #include "packet-mbtcp.h"
65 void proto_register_cip(void);
66 void proto_reg_handoff_cip(void);
68 typedef struct mr_mult_req_info
{
71 cip_req_info_t
*requests
;
74 static dissector_handle_t cip_handle
;
75 static dissector_handle_t cip_class_generic_handle
;
76 static dissector_handle_t cip_class_cm_handle
;
77 static dissector_handle_t cip_class_pccc_handle
;
78 static dissector_handle_t cip_class_mb_handle
;
79 static dissector_handle_t modbus_handle
;
80 static dissector_handle_t cip_class_cco_handle
;
81 static heur_dissector_list_t heur_subdissector_service
;
83 static bool cip_enhanced_info_column
= true;
85 /* Initialize the protocol and registered fields */
87 static int proto_cip_class_generic
;
88 static int proto_cip_class_cm
;
89 static int proto_cip_class_pccc
;
90 static int proto_cip_class_mb
;
91 static int proto_cip_class_cco
;
92 static int proto_enip
;
93 static int proto_modbus
;
95 int hf_attr_class_revision
;
96 int hf_attr_class_max_instance
;
97 int hf_attr_class_num_instance
;
98 int hf_attr_class_opt_attr_num
;
99 int hf_attr_class_attr_num
;
100 int hf_attr_class_opt_service_num
;
101 int hf_attr_class_service_code
;
102 int hf_attr_class_num_class_attr
;
103 int hf_attr_class_num_inst_attr
;
104 static int hf_cip_data
;
105 static int hf_cip_service
;
106 static int hf_cip_service_code
;
107 static int hf_cip_reqrsp
;
108 static int hf_cip_epath
;
109 static int hf_cip_genstat
;
110 static int hf_cip_addstat_size
;
111 static int hf_cip_add_stat
;
112 static int hf_cip_request_path_size
;
114 static int hf_cip_cm_sc
;
115 static int hf_cip_cm_genstat
;
116 static int hf_cip_cm_addstat_size
;
117 static int hf_cip_cm_add_status
;
118 static int hf_cip_cm_ext_status
;
119 static int hf_cip_cm_priority
;
120 static int hf_cip_cm_tick_time
;
121 static int hf_cip_cm_timeout_tick
;
122 static int hf_cip_cm_timeout
;
123 static int hf_cip_cm_ot_connid
;
124 static int hf_cip_cm_to_connid
;
125 static int hf_cip_connid
;
126 static int hf_cip_cm_conn_serial_num
;
127 static int hf_cip_cm_orig_serial_num
;
128 static int hf_cip_cm_vendor
;
129 static int hf_cip_cm_timeout_multiplier
;
130 static int hf_cip_cm_ot_rpi
;
131 static int hf_cip_cm_ot_timeout
;
132 static int hf_cip_cm_ot_net_params32
;
133 static int hf_cip_cm_ot_net_params16
;
134 static int hf_cip_cm_to_rpi
;
135 static int hf_cip_cm_to_timeout
;
137 static int hf_cip_safety_nte_ms
;
139 static int hf_cip_cm_to_net_params32
;
140 static int hf_cip_cm_to_net_params16
;
141 static int hf_cip_cm_transport_type_trigger
;
142 static int hf_cip_cm_conn_path_size
;
143 static int hf_cip_cm_ot_api
;
144 static int hf_cip_cm_to_api
;
145 static int hf_cip_cm_app_reply_size
;
146 static int hf_cip_cm_app_reply_data
;
147 static int hf_cip_cm_consumer_number
;
148 static int hf_cip_cm_targ_vendor_id
;
149 static int hf_cip_cm_targ_dev_serial_num
;
150 static int hf_cip_cm_targ_conn_serial_num
;
151 static int hf_cip_cm_initial_timestamp
;
152 static int hf_cip_cm_initial_rollover
;
153 static int hf_cip_cm_remain_path_size
;
154 static int hf_cip_cm_msg_req_size
;
155 static int hf_cip_cm_route_path_size
;
156 static int hf_cip_cm_fwo_con_size
;
157 static int hf_cip_cm_lfwo_con_size
;
158 static int hf_cip_cm_fwo_fixed_var
;
159 static int hf_cip_cm_lfwo_fixed_var
;
160 static int hf_cip_cm_fwo_prio
;
161 static int hf_cip_cm_lfwo_prio
;
162 static int hf_cip_cm_fwo_typ
;
163 static int hf_cip_cm_lfwo_typ
;
164 static int hf_cip_cm_fwo_own
;
165 static int hf_cip_cm_lfwo_own
;
166 static int hf_cip_cm_fwo_dir
;
167 static int hf_cip_cm_fwo_trigg
;
168 static int hf_cip_cm_fwo_class
;
169 static int hf_cip_cm_gco_conn
;
170 static int hf_cip_cm_gco_coo_conn
;
171 static int hf_cip_cm_gco_roo_conn
;
172 static int hf_cip_cm_gco_last_action
;
173 static int hf_cip_cm_ext112_ot_rpi_type
;
174 static int hf_cip_cm_ext112_to_rpi_type
;
175 static int hf_cip_cm_ext112_ot_rpi
;
176 static int hf_cip_cm_ext112_to_rpi
;
177 static int hf_cip_cm_ext126_size
;
178 static int hf_cip_cm_ext127_size
;
179 static int hf_cip_cm_ext128_size
;
181 static int hf_cip_pccc_sc
;
182 static int hf_cip_pccc_req_id_len
;
183 static int hf_cip_pccc_cip_vend_id
;
184 static int hf_cip_pccc_cip_serial_num
;
185 static int hf_cip_pccc_cmd_code
;
186 static int hf_cip_pccc_sts_code
;
187 static int hf_cip_pccc_ext_sts_code
;
188 static int hf_cip_pccc_tns_code
;
189 static int hf_cip_pccc_fnc_code_06
;
190 static int hf_cip_pccc_fnc_code_07
;
191 static int hf_cip_pccc_fnc_code_0f
;
192 static int hf_cip_pccc_byte_size
;
193 static int hf_cip_pccc_file_num
;
194 static int hf_cip_pccc_file_type
;
195 static int hf_cip_pccc_element_num
;
196 static int hf_cip_pccc_subelement_num
;
198 static int hf_cip_pccc_cpu_mode_3a
;
200 static int hf_cip_pccc_cpu_mode_80
;
201 static int hf_cip_pccc_resp_code
;
202 static int hf_cip_pccc_execute_multi_count
;
203 static int hf_cip_pccc_execute_multi_len
;
204 static int hf_cip_pccc_execute_multi_fnc
;
205 static int hf_cip_pccc_data
;
207 static int hf_cip_mb_sc
;
208 static int hf_cip_mb_read_coils_start_addr
;
209 static int hf_cip_mb_read_coils_num_coils
;
210 static int hf_cip_mb_read_coils_data
;
211 static int hf_cip_mb_read_discrete_inputs_start_addr
;
212 static int hf_cip_mb_read_discrete_inputs_num_inputs
;
213 static int hf_cip_mb_read_discrete_inputs_data
;
214 static int hf_cip_mb_read_holding_register_start_addr
;
215 static int hf_cip_mb_read_holding_register_num_registers
;
216 static int hf_cip_mb_read_holding_register_data
;
217 static int hf_cip_mb_read_input_register_start_addr
;
218 static int hf_cip_mb_read_input_register_num_registers
;
219 static int hf_cip_mb_read_input_register_data
;
220 static int hf_cip_mb_write_coils_start_addr
;
221 static int hf_cip_mb_write_coils_outputs_forced
;
222 static int hf_cip_mb_write_coils_num_coils
;
223 static int hf_cip_mb_write_coils_data
;
224 static int hf_cip_mb_write_registers_start_addr
;
225 static int hf_cip_mb_write_registers_outputs_forced
;
226 static int hf_cip_mb_write_registers_num_registers
;
227 static int hf_cip_mb_write_registers_data
;
228 static int hf_cip_mb_data
;
230 static int hf_cip_cco_con_type
;
231 static int hf_cip_cco_ot_rtf
;
232 static int hf_cip_cco_to_rtf
;
233 static int hf_cip_cco_sc
;
234 static int hf_cip_cco_format_number
;
235 static int hf_cip_cco_edit_signature
;
236 static int hf_cip_cco_con_flags
;
237 static int hf_cip_cco_tdi_vendor
;
238 static int hf_cip_cco_tdi_devtype
;
239 static int hf_cip_cco_tdi_prodcode
;
240 static int hf_cip_cco_tdi_compatibility
;
241 static int hf_cip_cco_tdi_comp_bit
;
242 static int hf_cip_cco_tdi_majorrev
;
243 static int hf_cip_cco_tdi_minorrev
;
244 static int hf_cip_cco_pdi_vendor
;
245 static int hf_cip_cco_pdi_devtype
;
246 static int hf_cip_cco_pdi_prodcode
;
247 static int hf_cip_cco_pdi_compatibility
;
248 static int hf_cip_cco_pdi_comp_bit
;
249 static int hf_cip_cco_pdi_majorrev
;
250 static int hf_cip_cco_pdi_minorrev
;
251 static int hf_cip_cco_cs_data_index
;
252 static int hf_cip_cco_ot_rpi
;
253 static int hf_cip_cco_to_rpi
;
254 static int hf_cip_cco_ot_net_param16
;
255 static int hf_cip_cco_to_net_param16
;
256 static int hf_cip_cco_fwo_own
;
257 static int hf_cip_cco_fwo_typ
;
258 static int hf_cip_cco_fwo_prio
;
259 static int hf_cip_cco_fwo_fixed_var
;
260 static int hf_cip_cco_fwo_con_size
;
261 static int hf_cip_cco_ot_net_param32
;
262 static int hf_cip_cco_to_net_param32
;
263 static int hf_cip_cco_lfwo_own
;
264 static int hf_cip_cco_lfwo_typ
;
265 static int hf_cip_cco_lfwo_prio
;
266 static int hf_cip_cco_lfwo_fixed_var
;
267 static int hf_cip_cco_lfwo_con_size
;
268 static int hf_cip_cco_conn_path_size
;
269 static int hf_cip_cco_proxy_config_size
;
270 static int hf_cip_cco_target_config_size
;
271 static int hf_cip_cco_iomap_format_number
;
272 static int hf_cip_cco_iomap_size
;
273 static int hf_cip_cco_connection_disable
;
274 static int hf_cip_cco_net_conn_param_attr
;
275 static int hf_cip_cco_timeout_multiplier
;
276 static int hf_cip_cco_transport_type_trigger
;
277 static int hf_cip_cco_fwo_dir
;
278 static int hf_cip_cco_fwo_trigger
;
279 static int hf_cip_cco_fwo_class
;
280 static int hf_cip_cco_proxy_config_data
;
281 static int hf_cip_cco_target_config_data
;
282 static int hf_cip_cco_iomap_attribute
;
283 static int hf_cip_cco_safety
;
284 static int hf_cip_cco_change_type
;
285 static int hf_cip_cco_connection_name
;
286 static int hf_cip_cco_ext_status
;
288 static int hf_cip_path_segment
;
289 static int hf_cip_path_segment_type
;
290 static int hf_cip_port_ex_link_addr
;
291 static int hf_cip_port
;
292 static int hf_cip_port_extended
;
293 static int hf_cip_link_address_size
;
294 static int hf_cip_link_address_byte
;
295 static int hf_cip_link_address_string
;
296 static int hf_cip_logical_seg_type
;
297 static int hf_cip_logical_seg_format
;
298 static int hf_cip_class8
;
299 static int hf_cip_class16
;
300 static int hf_cip_class32
;
301 static int hf_cip_instance8
;
302 static int hf_cip_instance16
;
303 static int hf_cip_instance32
;
304 static int hf_cip_member8
;
305 static int hf_cip_member16
;
306 static int hf_cip_member32
;
307 static int hf_cip_attribute8
;
308 static int hf_cip_attribute16
;
309 static int hf_cip_attribute32
;
310 static int hf_cip_conpoint8
;
311 static int hf_cip_conpoint16
;
312 static int hf_cip_conpoint32
;
313 static int hf_cip_serviceid8
;
314 static int hf_cip_ekey_format
;
315 static int hf_cip_ekey_vendor
;
316 static int hf_cip_ekey_devtype
;
317 static int hf_cip_ekey_prodcode
;
318 static int hf_cip_ekey_compatibility
;
319 static int hf_cip_ekey_comp_bit
;
320 static int hf_cip_ekey_majorrev
;
321 static int hf_cip_ekey_minorrev
;
322 static int hf_cip_ekey_serial_number
;
323 static int hf_cip_ext_logical8
;
324 static int hf_cip_ext_logical16
;
325 static int hf_cip_ext_logical32
;
326 static int hf_cip_ext_logical_type
;
327 static int hf_cip_data_seg_type
;
328 static int hf_cip_data_seg_size_simple
;
329 static int hf_cip_data_seg_size_extended
;
330 static int hf_cip_data_seg_item
;
331 static int hf_cip_symbol
;
332 static int hf_cip_symbol_size
;
333 static int hf_cip_symbol_ascii
;
334 static int hf_cip_symbol_extended_format
;
335 static int hf_cip_symbol_numeric_format
;
336 static int hf_cip_symbol_double_size
;
337 static int hf_cip_symbol_triple_size
;
338 static int hf_cip_numeric_usint
;
339 static int hf_cip_numeric_uint
;
340 static int hf_cip_numeric_udint
;
341 static int hf_cip_network_seg_type
;
342 static int hf_cip_seg_schedule
;
343 static int hf_cip_seg_fixed_tag
;
344 static int hf_cip_seg_prod_inhibit_time
;
345 static int hf_cip_seg_prod_inhibit_time_us
;
346 static int hf_cip_seg_network_size
;
347 static int hf_cip_seg_network_subtype
;
348 static int hf_cip_seg_safety_format
;
349 static int hf_cip_seg_safety_reserved
;
350 static int hf_cip_seg_safety_configuration_crc
;
351 static int hf_cip_seg_safety_configuration_timestamp
;
352 static int hf_cip_seg_safety_configuration_date
;
353 static int hf_cip_seg_safety_configuration_time
;
354 static int hf_cip_seg_safety_time_correction_epi
;
355 static int hf_cip_seg_safety_time_correction_net_params
;
356 static int hf_cip_seg_safety_time_correction_own
;
357 static int hf_cip_seg_safety_time_correction_typ
;
358 static int hf_cip_seg_safety_time_correction_prio
;
359 static int hf_cip_seg_safety_time_correction_fixed_var
;
360 static int hf_cip_seg_safety_time_correction_con_size
;
361 static int hf_cip_seg_safety_tunid
;
362 static int hf_cip_seg_safety_tunid_snn_timestamp
;
363 static int hf_cip_seg_safety_tunid_snn_date
;
364 static int hf_cip_seg_safety_tunid_snn_time
;
365 static int hf_cip_seg_safety_tunid_nodeid
;
366 static int hf_cip_seg_safety_ounid
;
367 static int hf_cip_seg_safety_ounid_snn_timestamp
;
368 static int hf_cip_seg_safety_ounid_snn_date
;
369 static int hf_cip_seg_safety_ounid_snn_time
;
370 static int hf_cip_seg_safety_ounid_nodeid
;
371 static int hf_cip_seg_safety_ping_epi_multiplier
;
372 static int hf_cip_seg_safety_time_coord_msg_min_multiplier
;
373 static int hf_cip_seg_safety_network_time_expected_multiplier
;
374 static int hf_cip_seg_safety_timeout_multiplier
;
375 static int hf_cip_seg_safety_max_consumer_number
;
376 static int hf_cip_seg_safety_conn_param_crc
;
377 static int hf_cip_seg_safety_time_correction_conn_id
;
378 static int hf_cip_seg_safety_max_fault_number
;
379 static int hf_cip_seg_safety_init_timestamp
;
380 static int hf_cip_seg_safety_init_rollover
;
381 static int hf_cip_seg_safety_data
;
382 static int hf_cip_class_max_inst32
;
383 static int hf_cip_class_num_inst32
;
384 static int hf_cip_reserved8
;
385 static int hf_cip_reserved24
;
386 static int hf_cip_pad8
;
388 static int hf_cip_sc_get_attr_list_attr_count
;
389 static int hf_cip_sc_get_attr_list_attr_status
;
390 static int hf_cip_sc_set_attr_list_attr_count
;
391 static int hf_cip_sc_set_attr_list_attr_status
;
392 static int hf_cip_sc_reset_param
;
393 static int hf_cip_sc_create_instance
;
394 static int hf_cip_sc_mult_serv_pack_num_services
;
395 static int hf_cip_sc_mult_serv_pack_offset
;
396 static int hf_cip_find_next_object_max_instance
;
397 static int hf_cip_find_next_object_num_instances
;
398 static int hf_cip_find_next_object_instance_item
;
399 static int hf_cip_sc_group_sync_is_sync
;
401 /* Parsed Attributes */
402 static int hf_id_vendor_id
;
403 static int hf_id_device_type
;
404 static int hf_id_product_code
;
405 static int hf_id_major_rev
;
406 static int hf_id_minor_rev
;
407 static int hf_id_status
;
408 static int hf_id_serial_number
;
409 static int hf_id_product_name
;
410 static int hf_id_state
;
411 static int hf_id_config_value
;
412 static int hf_id_heartbeat
;
413 static int hf_id_status_owned
;
414 static int hf_id_status_conf
;
415 static int hf_id_status_extended1
;
416 static int hf_id_status_minor_fault_rec
;
417 static int hf_id_status_minor_fault_unrec
;
418 static int hf_id_status_major_fault_rec
;
419 static int hf_id_status_major_fault_unrec
;
420 static int hf_id_status_extended2
;
421 static int hf_msg_rout_num_classes
;
422 static int hf_msg_rout_classes
;
423 static int hf_msg_rout_num_available
;
424 static int hf_msg_rout_num_active
;
425 static int hf_msg_rout_active_connections
;
426 static int hf_conn_mgr_open_requests
;
427 static int hf_conn_mgr_open_format_rejects
;
428 static int hf_conn_mgr_open_resource_rejects
;
429 static int hf_conn_mgr_other_open_rejects
;
430 static int hf_conn_mgr_close_requests
;
431 static int hf_conn_close_format_requests
;
432 static int hf_conn_mgr_close_other_requests
;
433 static int hf_conn_mgr_conn_timouts
;
434 static int hf_conn_mgr_num_conn_entries
;
435 static int hf_conn_mgr_num_conn_entries_bytes
;
436 static int hf_conn_mgr_conn_open_bits
;
437 static int hf_conn_mgr_cpu_utilization
;
438 static int hf_conn_mgr_max_buff_size
;
439 static int hf_conn_mgr_buff_size_remaining
;
440 static int hf_stringi_number_char
;
441 static int hf_stringi_language_char
;
442 static int hf_stringi_char_string_struct
;
443 static int hf_stringi_char_set
;
444 static int hf_stringi_international_string
;
445 static int hf_file_filename
;
446 static int hf_time_sync_ptp_enable
;
447 static int hf_time_sync_is_synchronized
;
448 static int hf_time_sync_sys_time_micro
;
449 static int hf_time_sync_sys_time_nano
;
450 static int hf_time_sync_offset_from_master
;
451 static int hf_time_sync_max_offset_from_master
;
452 static int hf_time_sync_mean_path_delay_to_master
;
453 static int hf_time_sync_gm_clock_clock_id
;
454 static int hf_time_sync_gm_clock_clock_class
;
455 static int hf_time_sync_gm_clock_time_accuracy
;
456 static int hf_time_sync_gm_clock_offset_scaled_log_variance
;
457 static int hf_time_sync_gm_clock_current_utc_offset
;
458 static int hf_time_sync_gm_clock_time_property_flags
;
459 static int hf_time_sync_gm_clock_time_property_flags_leap61
;
460 static int hf_time_sync_gm_clock_time_property_flags_leap59
;
461 static int hf_time_sync_gm_clock_time_property_flags_current_utc_valid
;
462 static int hf_time_sync_gm_clock_time_property_flags_ptp_timescale
;
463 static int hf_time_sync_gm_clock_time_property_flags_time_traceable
;
464 static int hf_time_sync_gm_clock_time_property_flags_freq_traceable
;
465 static int hf_time_sync_gm_clock_time_source
;
466 static int hf_time_sync_gm_clock_priority1
;
467 static int hf_time_sync_gm_clock_priority2
;
468 static int hf_time_sync_parent_clock_clock_id
;
469 static int hf_time_sync_parent_clock_port_number
;
470 static int hf_time_sync_parent_clock_observed_offset_scaled_log_variance
;
471 static int hf_time_sync_parent_clock_observed_phase_change_rate
;
472 static int hf_time_sync_local_clock_clock_id
;
473 static int hf_time_sync_local_clock_clock_class
;
474 static int hf_time_sync_local_clock_time_accuracy
;
475 static int hf_time_sync_local_clock_offset_scaled_log_variance
;
476 static int hf_time_sync_local_clock_current_utc_offset
;
477 static int hf_time_sync_local_clock_time_property_flags
;
478 static int hf_time_sync_local_clock_time_property_flags_leap61
;
479 static int hf_time_sync_local_clock_time_property_flags_leap59
;
480 static int hf_time_sync_local_clock_time_property_flags_current_utc_valid
;
481 static int hf_time_sync_local_clock_time_property_flags_ptp_timescale
;
482 static int hf_time_sync_local_clock_time_property_flags_time_traceable
;
483 static int hf_time_sync_local_clock_time_property_flags_freq_traceable
;
484 static int hf_time_sync_local_clock_time_source
;
485 static int hf_time_sync_num_ports
;
486 static int hf_time_sync_port_state_info_num_ports
;
487 static int hf_time_sync_port_state_info_port_num
;
488 static int hf_time_sync_port_state_info_port_state
;
489 static int hf_time_sync_port_enable_cfg_num_ports
;
490 static int hf_time_sync_port_enable_cfg_port_num
;
491 static int hf_time_sync_port_enable_cfg_port_enable
;
492 static int hf_time_sync_port_log_announce_num_ports
;
493 static int hf_time_sync_port_log_announce_port_num
;
494 static int hf_time_sync_port_log_announce_interval
;
495 static int hf_time_sync_port_log_sync_num_ports
;
496 static int hf_time_sync_port_log_sync_port_num
;
497 static int hf_time_sync_port_log_sync_port_log_sync_interval
;
498 static int hf_time_sync_priority1
;
499 static int hf_time_sync_priority2
;
500 static int hf_time_sync_domain_number
;
501 static int hf_time_sync_clock_type
;
502 static int hf_time_sync_clock_type_ordinary
;
503 static int hf_time_sync_clock_type_boundary
;
504 static int hf_time_sync_clock_type_end_to_end
;
505 static int hf_time_sync_clock_type_management
;
506 static int hf_time_sync_clock_type_slave_only
;
507 static int hf_time_sync_manufacture_id_oui
;
508 static int hf_time_sync_manufacture_id_reserved
;
509 static int hf_time_sync_prod_desc_size
;
510 static int hf_time_sync_prod_desc_str
;
511 static int hf_time_sync_revision_data_size
;
512 static int hf_time_sync_revision_data_str
;
513 static int hf_time_sync_user_desc_size
;
514 static int hf_time_sync_user_desc_str
;
515 static int hf_time_sync_port_profile_id_info_num_ports
;
516 static int hf_time_sync_port_profile_id_info_port_num
;
517 static int hf_time_sync_port_profile_id_info_profile_id
;
518 static int hf_time_sync_port_phys_addr_info_num_ports
;
519 static int hf_time_sync_port_phys_addr_info_port_num
;
520 static int hf_time_sync_port_phys_addr_info_phys_proto
;
521 static int hf_time_sync_port_phys_addr_info_addr_size
;
522 static int hf_time_sync_port_phys_addr_info_phys_addr
;
523 static int hf_time_sync_port_proto_addr_info_num_ports
;
524 static int hf_time_sync_port_proto_addr_info_port_num
;
525 static int hf_time_sync_port_proto_addr_info_network_proto
;
526 static int hf_time_sync_port_proto_addr_info_addr_size
;
527 static int hf_time_sync_port_proto_addr_info_port_proto_addr
;
528 static int hf_time_sync_steps_removed
;
529 static int hf_time_sync_sys_time_and_offset_time
;
530 static int hf_time_sync_sys_time_and_offset_offset
;
531 static int hf_port_entry_port
;
532 static int hf_port_type
;
533 static int hf_port_number
;
534 static int hf_port_min_node_num
;
535 static int hf_port_max_node_num
;
536 static int hf_port_name
;
537 static int hf_port_num_comm_object_entries
;
538 static int hf_path_len_usint
;
539 static int hf_path_len_uint
;
541 static int hf_32bitheader
;
542 static int hf_32bitheader_roo
;
543 static int hf_32bitheader_coo
;
544 static int hf_32bitheader_run_idle
;
546 static int hf_cip_connection
;
547 static int hf_cip_fwd_open_in
;
548 static int hf_cip_fwd_close_in
;
550 /* Initialize the subtree pointers */
552 static int ett_cip_class_generic
;
553 static int ett_cip_class_cm
;
554 static int ett_cip_class_pccc
;
555 static int ett_cip_class_mb
;
556 static int ett_cip_class_cco
;
559 static int ett_path_seg
;
561 static int ett_cia_path
;
562 static int ett_data_seg
;
563 static int ett_port_path
;
564 static int ett_network_seg
;
565 static int ett_network_seg_safety
;
566 static int ett_network_seg_safety_time_correction_net_params
;
567 static int ett_cip_seg_safety_tunid
;
568 static int ett_cip_seg_safety_tunid_snn
;
569 static int ett_cip_seg_safety_ounid
;
570 static int ett_cip_seg_safety_ounid_snn
;
573 static int ett_status_item
;
574 static int ett_add_status_item
;
575 static int ett_cmd_data
;
577 static int ett_cip_get_attributes_all_item
;
578 static int ett_cip_get_attribute_list
;
579 static int ett_cip_get_attribute_list_item
;
580 static int ett_cip_set_attribute_list
;
581 static int ett_cip_set_attribute_list_item
;
582 static int ett_cip_mult_service_packet
;
583 static int ett_cip_msp_offset
;
585 static int ett_cm_rrsc
;
586 static int ett_cm_ncp
;
587 static int ett_cm_mes_req
;
588 static int ett_cm_cmd_data
;
589 static int ett_cm_ttt
;
590 static int ett_cm_add_status_item
;
591 static int ett_cip_cm_pid
;
592 static int ett_cip_cm_safety
;
594 static int ett_pccc_rrsc
;
595 static int ett_pccc_req_id
;
596 static int ett_pccc_cmd_data
;
598 static int ett_mb_rrsc
;
599 static int ett_mb_cmd_data
;
601 static int ett_cco_iomap
;
602 static int ett_cco_con_status
;
603 static int ett_cco_con_flag
;
604 static int ett_cco_tdi
;
605 static int ett_cco_pdi
;
606 static int ett_cco_ncp
;
607 static int ett_cco_rrsc
;
608 static int ett_cco_cmd_data
;
609 static int ett_cco_ttt
;
611 static int ett_time_sync_gm_clock_flags
;
612 static int ett_time_sync_local_clock_flags
;
613 static int ett_time_sync_port_state_info
;
614 static int ett_time_sync_port_enable_cfg
;
615 static int ett_time_sync_port_log_announce
;
616 static int ett_time_sync_port_log_sync
;
617 static int ett_time_sync_clock_type
;
618 static int ett_time_sync_port_profile_id_info
;
619 static int ett_time_sync_port_phys_addr_info
;
620 static int ett_time_sync_port_proto_addr_info
;
621 static int ett_id_status
;
622 static int ett_32bitheader_tree
;
624 static int ett_connection_info
;
626 static expert_field ei_mal_identity_revision
;
627 static expert_field ei_mal_identity_status
;
628 static expert_field ei_mal_msg_rout_num_classes
;
629 static expert_field ei_mal_time_sync_gm_clock
;
630 static expert_field ei_mal_time_sync_parent_clock
;
631 static expert_field ei_mal_time_sync_local_clock
;
632 static expert_field ei_mal_time_sync_port_state_info
;
633 static expert_field ei_mal_time_sync_port_state_info_ports
;
634 static expert_field ei_mal_time_sync_port_enable_cfg
;
635 static expert_field ei_mal_time_sync_port_enable_cfg_ports
;
636 static expert_field ei_mal_time_sync_port_log_announce
;
637 static expert_field ei_mal_time_sync_port_log_announce_ports
;
638 static expert_field ei_mal_time_sync_port_log_sync
;
639 static expert_field ei_mal_time_sync_port_log_sync_ports
;
640 static expert_field ei_mal_time_sync_clock_type
;
641 static expert_field ei_mal_time_sync_manufacture_id
;
642 static expert_field ei_mal_time_sync_prod_desc
;
643 static expert_field ei_mal_time_sync_prod_desc_64
;
644 static expert_field ei_mal_time_sync_prod_desc_size
;
645 static expert_field ei_mal_time_sync_revision_data
;
646 static expert_field ei_mal_time_sync_revision_data_32
;
647 static expert_field ei_mal_time_sync_revision_data_size
;
648 static expert_field ei_mal_time_sync_user_desc
;
649 static expert_field ei_mal_time_sync_user_desc_128
;
650 static expert_field ei_mal_time_sync_user_desc_size
;
651 static expert_field ei_mal_time_sync_port_profile_id_info
;
652 static expert_field ei_mal_time_sync_port_profile_id_info_ports
;
653 static expert_field ei_mal_time_sync_port_phys_addr_info
;
654 static expert_field ei_mal_time_sync_port_phys_addr_info_ports
;
655 static expert_field ei_mal_time_sync_port_proto_addr_info
;
656 static expert_field ei_mal_time_sync_port_proto_addr_info_ports
;
657 static expert_field ei_mal_time_sync_sys_time_and_offset
;
658 static expert_field ei_proto_log_seg_format
;
659 static expert_field ei_mal_incomplete_epath
;
660 static expert_field ei_proto_electronic_key_format
;
661 static expert_field ei_proto_special_segment_format
;
662 static expert_field ei_proto_log_seg_type
;
663 static expert_field ei_proto_log_sub_seg_type
;
664 static expert_field ei_proto_ext_string_format
;
665 static expert_field ei_proto_ext_network
;
666 static expert_field ei_proto_seg_type
;
667 static expert_field ei_proto_unsupported_datatype
;
668 static expert_field ei_mal_serv_gal
;
669 static expert_field ei_mal_serv_gal_count
;
670 static expert_field ei_mal_serv_sal
;
671 static expert_field ei_mal_serv_sal_count
;
672 static expert_field ei_mal_msp_services
;
673 static expert_field ei_mal_msp_inv_offset
;
674 static expert_field ei_mal_msp_missing_services
;
675 static expert_field ei_mal_serv_find_next_object
;
676 static expert_field ei_mal_serv_find_next_object_count
;
677 static expert_field ei_mal_rpi_no_data
;
678 static expert_field ei_mal_fwd_close_missing_data
;
679 static expert_field ei_mal_opt_attr_list
;
680 static expert_field ei_mal_opt_service_list
;
681 static expert_field ei_mal_padded_epath_size
;
682 static expert_field ei_mal_missing_string_data
;
684 static expert_field ei_cip_null_fwd_open
;
685 static expert_field ei_cip_safety_open_type1
;
686 static expert_field ei_cip_safety_open_type2a
;
687 static expert_field ei_cip_safety_open_type2b
;
688 static expert_field ei_cip_no_fwd_close
;
689 static expert_field ei_cip_safety_input
;
690 static expert_field ei_cip_safety_output
;
691 static expert_field ei_cip_listen_input_connection
;
693 //// Concurrent Connections
694 static int hf_cip_cm_cc_version
;
696 static int hf_cip_cc_packet_length
;
697 static int hf_cip_cc_packet_options
;
698 static int hf_cip_cc_packet_type
;
699 static int hf_cip_cc_packet_keepalive
;
700 static int hf_cip_cc_packet_keepalive_hop_count
;
701 static int hf_cip_cc_packet_reserved
;
702 static int hf_cip_cc_packet_seq_number
;
703 static int hf_cip_cc_crc
;
704 static int hf_cip_cc_crc_status
;
706 // Parameters for Concurrent Extended Network Segment
707 static int hf_ext_net_seg_hops_count
;
708 static int hf_ext_net_seg_length
;
709 static int hf_ext_net_seg_hop
;
710 static int hf_ext_net_seg_hop_egress_cip_port
;
711 static int hf_ext_net_seg_hop_link_adr_type
;
712 static int hf_ext_net_seg_hop_number_of_linkadr
;
713 static int hf_ext_net_seg_link_address
;
714 static int hf_ext_net_seg_link_ipv4
;
715 static int hf_ext_net_seg_link_hostname
;
719 /* Define the tree for the frame */
720 static int ett_cc_header
;
721 static int ett_cc_hop
;
723 static expert_field ei_cc_invalid_header_type
;
724 static expert_field ei_cc_crc
;
726 static const value_string cc_link_adr_type
[] = {
727 { 0, "8-bit numeric link addresses" },
728 { 1, "IPv4 addresses" },
734 static const value_string cc_packet_type_vals
[] = {
736 { 1, "Concurrent Connection Packet Format" },
741 static int* ett_cc
[] =
747 static dissector_table_t subdissector_class_table
;
748 static dissector_table_t subdissector_symbol_table
;
750 /* Translate function to string - CIP Service codes */
751 static const value_string cip_sc_vals
[] = {
757 /* Translate function to string - CIP Service codes for CM */
758 static const value_string cip_sc_vals_cm
[] = {
761 /* Some class specific services */
762 { SC_CM_FWD_CLOSE
, "Forward Close" },
763 { SC_CM_FWD_OPEN
, "Forward Open" },
764 { SC_CM_UNCON_SEND
, "Unconnected Send" },
765 { SC_CM_LARGE_FWD_OPEN
, "Large Forward Open" },
766 { SC_CM_GET_CONN_DATA
, "Get Connection Data" },
767 { SC_CM_SEARCH_CONN_DATA
, "Search Connection Data" },
768 { SC_CM_GET_CONN_OWNER
, "Get Connection Owner" },
769 { SC_CM_CONCURRENT_FWD_OPEN
, "Concurrent Forward Open" },
770 { SC_CM_CONCURRENT_FWD_CLOSE
, "Concurrent Forward Close" },
775 /* Translate function to string - CIP Service codes for PCCC */
776 static const value_string cip_sc_vals_pccc
[] = {
779 /* Some class specific services */
780 { SC_PCCC_EXECUTE_PCCC
, "Execute PCCC" },
785 /* Translate function to string - CIP Service codes for MB */
786 static const value_string cip_sc_vals_mb
[] = {
789 /* Some class specific services */
790 { SC_MB_READ_DISCRETE_INPUTS
, "Read Discrete" },
791 { SC_MB_READ_COILS
, "Read Coils" },
792 { SC_MB_READ_INPUT_REGISTERS
, "Read Input Registers" },
793 { SC_MB_READ_HOLDING_REGISTERS
, "Read Holding Registers" },
794 { SC_MB_WRITE_COILS
, "Write Coils" },
795 { SC_MB_WRITE_HOLDING_REGISTERS
, "Write Holding Registers" },
796 { SC_MB_PASSTHROUGH
, "Modbus Passthrough" },
801 /* Translate function to string - CIP Service codes for CCO */
802 static const value_string cip_sc_vals_cco
[] = {
805 /* Some class specific services */
806 { SC_CCO_KICK_TIMER
, "Kick Timer" },
807 { SC_CCO_OPEN_CONN
, "Open Connection" },
808 { SC_CCO_CLOSE_CONN
, "Close Connection" },
809 { SC_CCO_STOP_CONN
, "Stop Connection" },
810 { SC_CCO_CHANGE_START
, "Change Start" },
811 { SC_CCO_GET_STATUS
, "Get Status" },
812 { SC_CCO_CHANGE_COMPLETE
, "Change Complete" },
813 { SC_CCO_AUDIT_CHANGE
, "Audit Changes" },
818 /* Translate function to string - CIP Request/Response */
819 const value_string cip_sc_rr
[] = {
826 /* Translate function to string - Compatibility */
827 static const value_string cip_com_bit_vals
[] = {
828 { 0, "Bit Cleared" },
834 const value_string cip_reset_type_vals
[] = {
835 { 0, "Cycle Power" },
836 { 1, "Factory Default" },
837 { 2, "Keep Communication Parameters" },
842 /* Translate function to string - Connection priority */
843 const value_string cip_con_prio_vals
[] = {
844 { 0, "Low Priority" },
845 { 1, "High Priority" },
852 /* Translate function to string - Connection size fixed or variable */
853 static const value_string cip_con_fw_vals
[] = {
860 /* Translate function to string - Connection owner */
861 static const value_string cip_con_owner_vals
[] = {
862 { 0, "Non-Redundant" },
868 /* Translate function to string - Connection type*/
869 static const value_string cip_con_vals
[] = {
876 /* Translate function to string - Production trigger */
877 static const value_string cip_con_trigg_vals
[] = {
879 { 1, "Change-Of-State" },
880 { 2, "Application Object" },
885 /* Translate function to string - Transport class */
886 static const value_string cip_con_class_vals
[] = {
895 /* Translate function to string - Connection type */
896 const value_string cip_con_type_vals
[] = {
897 { CONN_TYPE_NULL
, "Null" },
898 { CONN_TYPE_MULTICAST
, "Multicast" },
899 { CONN_TYPE_P2P
, "Point to Point" },
900 { CONN_TYPE_RESERVED
, "Reserved" },
905 /* Translate function to string - Timeout Multiplier */
906 const value_string cip_con_time_mult_vals
[] = {
919 /* Translate function to string - Connection Last Action */
920 static const value_string cip_con_last_action_vals
[] = {
922 { 1, "Owner Is Idle Mode" },
923 { 2, "Owner Is Run Mode" },
924 { 255, "Implementation not supported" },
929 /* Translate function to string - real time transfer format type */
930 static const value_string cip_con_rtf_vals
[] = {
931 { 0, "32-bit Header" },
932 { 1, "Zero data length idle mode"},
941 /* Translate function to string - CCO change type */
942 static const value_string cip_cco_change_type_vals
[] = {
944 { 1, "Incremental" },
949 static const value_string cip_time_sync_clock_class_vals
[] = {
950 { 6, "Primary Reference" },
951 { 7, "Primary Reference (Hold)" },
952 { 52, "Degraded Reference A (Master only)" },
953 { 187, "Degraded Reference B (Master/Slave)" },
955 { 255, "Slave Only" },
960 static const value_string cip_time_sync_time_accuracy_vals
[] = {
961 { 0x20, "Accurate to within 25ns" },
962 { 0x21, "Accurate to within 100ns" },
963 { 0x22, "Accurate to within 250ns" },
964 { 0x23, "Accurate to within 1us" },
965 { 0x24, "Accurate to within 2.5us" },
966 { 0x25, "Accurate to within 10us" },
967 { 0x26, "Accurate to within 25us" },
968 { 0x27, "Accurate to within 100us" },
969 { 0x28, "Accurate to within 250us" },
970 { 0x29, "Accurate to within 1ms" },
971 { 0x2A, "Accurate to within 2.5ms" },
972 { 0x2B, "Accurate to within 10ms" },
973 { 0x2C, "Accurate to within 25ms" },
974 { 0x2D, "Accurate to within 100ms" },
975 { 0x2E, "Accurate to within 250ms" },
976 { 0x2F, "Accurate to within 1s" },
977 { 0x30, "Accurate to within 10s" },
978 { 0x31, "Accurate to >10s" },
982 static const value_string cip_time_sync_time_source_vals
[] = {
983 { 0x10, "Atomic Clock" },
985 { 0x30, "Terrestrial Radio" },
988 { 0x60, "Hand Set" },
990 { 0xA0, "Internal Oscillator" },
994 static const value_string cip_time_sync_port_state_vals
[] = {
995 { 1, "INITIALIZING" },
1002 { 8, "UNCALIBRATED" },
1007 static const value_string cip_time_sync_network_protocol_vals
[] = {
1010 { 3, "IEEE 802.3" },
1012 { 5, "ControlNet" },
1013 { 0xFFFF, "Local or Unknown protocol" },
1017 static const value_string cip_path_seg_vals
[] = {
1018 { ((CI_PORT_SEGMENT
>>5)&7), "Port Segment" },
1019 { ((CI_LOGICAL_SEGMENT
>>5)&7), "Logical Segment" },
1020 { ((CI_NETWORK_SEGMENT
>>5)&7), "Network Segment" },
1021 { ((CI_SYMBOLIC_SEGMENT
>>5)&7), "Symbolic Segment" },
1022 { ((CI_DATA_SEGMENT
>>5)&7), "Data Segment" },
1023 { 5, "Constructed Data Type" },
1024 { 6, "Elementary Data Type" },
1030 static const value_string cip_logical_segment_type_vals
[] = {
1031 { ((CI_LOGICAL_SEG_CLASS_ID
>>2)&7), "Class ID" },
1032 { ((CI_LOGICAL_SEG_INST_ID
>>2)&7), "Instance ID" },
1033 { ((CI_LOGICAL_SEG_MBR_ID
>>2)&7), "Member ID" },
1034 { ((CI_LOGICAL_SEG_CON_POINT
>>2)&7), "Connection Point" },
1035 { ((CI_LOGICAL_SEG_ATTR_ID
>>2)&7), "Attribute ID" },
1036 { ((CI_LOGICAL_SEG_SPECIAL
>>2)&7), "Special" },
1037 { ((CI_LOGICAL_SEG_SERV_ID
>>2)&7), "Service ID" },
1038 { ((CI_LOGICAL_SEG_EXT_LOGICAL
>>2)&7), "Extended Logical" },
1043 static const value_string cip_logical_segment_format_vals
[] = {
1044 { CI_LOGICAL_SEG_8_BIT
, "8-bit Logical Segment" },
1045 { CI_LOGICAL_SEG_16_BIT
, "16-bit Logical Segment" },
1046 { CI_LOGICAL_SEG_32_BIT
, "32-bit Logical Segment" },
1047 { CI_LOGICAL_SEG_RES_2
, "Reserved" },
1052 static const value_string cip_logical_seg_vals
[] = {
1053 {((CI_LOGICAL_SEG_CLASS_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_8_BIT
), "8-Bit Class Segment"},
1054 {((CI_LOGICAL_SEG_CLASS_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_16_BIT
), "16-Bit Class Segment"},
1055 {((CI_LOGICAL_SEG_CLASS_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_32_BIT
), "32-Bit Class Segment"},
1057 {((CI_LOGICAL_SEG_INST_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_8_BIT
), "8-Bit Instance Segment"},
1058 {((CI_LOGICAL_SEG_INST_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_16_BIT
), "16-Bit Instance Segment"},
1059 {((CI_LOGICAL_SEG_INST_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_32_BIT
), "32-Bit Instance Segment"},
1061 {((CI_LOGICAL_SEG_MBR_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_8_BIT
), "8-Bit Member Segment"},
1062 {((CI_LOGICAL_SEG_MBR_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_16_BIT
), "16-Bit Member Segment"},
1063 {((CI_LOGICAL_SEG_MBR_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_32_BIT
), "32-Bit Member Segment"},
1065 {((CI_LOGICAL_SEG_CON_POINT
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_8_BIT
), "8-Bit Connection Point Segment"},
1066 {((CI_LOGICAL_SEG_CON_POINT
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_16_BIT
), "16-Bit Connection Point Segment"},
1067 {((CI_LOGICAL_SEG_CON_POINT
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_32_BIT
), "32-Bit Connection Point Segment"},
1069 {((CI_LOGICAL_SEG_ATTR_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_8_BIT
), "8-Bit Attribute Segment"},
1070 {((CI_LOGICAL_SEG_ATTR_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_16_BIT
), "16-Bit Attribute Segment"},
1071 {((CI_LOGICAL_SEG_ATTR_ID
& CI_LOGICAL_SEG_TYPE_MASK
)|CI_LOGICAL_SEG_32_BIT
), "32-Bit Attribute Segment"},
1073 {((CI_LOGICAL_SEG_SERV_ID
& CI_LOGICAL_SEG_TYPE_MASK
) | CI_LOGICAL_SEG_8_BIT
), "8-Bit Service ID Segment"},
1075 {CI_LOGICAL_SEG_SPECIAL
, "Electronic Key Segment"},
1077 {((CI_LOGICAL_SEG_EXT_LOGICAL
& CI_LOGICAL_SEG_TYPE_MASK
) | CI_LOGICAL_SEG_8_BIT
), "8-Bit Extended Logical Segment"},
1078 {((CI_LOGICAL_SEG_EXT_LOGICAL
& CI_LOGICAL_SEG_TYPE_MASK
) | CI_LOGICAL_SEG_16_BIT
), "16-Bit Extended Logical Segment"},
1079 {((CI_LOGICAL_SEG_EXT_LOGICAL
& CI_LOGICAL_SEG_TYPE_MASK
) | CI_LOGICAL_SEG_32_BIT
), "32-Bit Extended Logical Segment"},
1084 static const value_string cip_ext_logical_segment_format_vals
[] = {
1086 { 1, "Array Index" },
1087 { 2, "Indirect Array Index" },
1089 { 4, "Indirect Bit Index" },
1090 { 5, "Structure Member Number" },
1091 { 6, "Structure Member Handle" },
1096 static const value_string cip_data_segment_type_vals
[] = {
1097 {CI_DATA_SEG_SIMPLE
, "Simple Data Segment"},
1098 {CI_DATA_SEG_SYMBOL
, "ANSI Extended Symbol Segment"},
1103 static const value_string cip_network_segment_type_vals
[] = {
1104 {CI_NETWORK_SEG_SCHEDULE
, "Schedule Segment"},
1105 {CI_NETWORK_SEG_FIXED_TAG
, "Fixed Tag Segment"},
1106 {CI_NETWORK_SEG_PROD_INHI
, "Production Inhibit Time in Milliseconds"},
1107 {CI_NETWORK_SEG_SAFETY
, "Safety Segment"},
1108 {CI_NETWORK_SEG_PROD_INHI_US
, "Production Inhibit Time in Microseconds"},
1109 {CI_NETWORK_SEG_EXTENDED
, "Extended Network Segment"},
1114 static const value_string cip_symbolic_format_vals
[] = {
1115 { 1, "Double Byte Segment" },
1116 { 2, "Triple Byte Segment" },
1117 { 6, "Numeric Segment" },
1122 static const value_string cip_symbolic_numeric_format_vals
[] = {
1130 static const value_string cip_safety_segment_format_type_vals
[] = {
1131 {0, "Target Format"},
1132 {1, "Router Format"},
1133 {2, "Extended Format"},
1138 static const value_string cip_cm_rpi_type_vals
[] = {
1139 {0, "RPI acceptable"},
1141 {2, "Minimum acceptable RPI"},
1142 {3, "Maximum acceptable RPI"},
1143 {4, "Required RPI to correct mismatch"},
1148 /* Translate function to string - CIP General Status codes */
1149 static const value_string cip_gs_vals
[] = {
1150 { CI_GRC_SUCCESS
, "Success" },
1151 { CI_GRC_FAILURE
, "Connection failure" },
1152 { CI_GRC_NO_RESOURCE
, "Resource unavailable" },
1153 { CI_GRC_BAD_DATA
, "Invalid parameter value" },
1154 { CI_GRC_BAD_PATH
, "Path segment error" },
1155 { CI_GRC_BAD_CLASS_INSTANCE
, "Path destination unknown" },
1156 { CI_GRC_PARTIAL_DATA
, "Partial transfer" },
1157 { CI_GRC_CONN_LOST
, "Connection lost" },
1158 { CI_GRC_BAD_SERVICE
, "Service not supported" },
1159 { CI_GRC_BAD_ATTR_DATA
, "Invalid attribute value" },
1160 { CI_GRC_ATTR_LIST_ERROR
, "Attribute list error" },
1161 { CI_GRC_ALREADY_IN_MODE
, "Already in requested mode/state" },
1162 { CI_GRC_BAD_OBJ_MODE
, "Object state conflict" },
1163 { CI_GRC_OBJ_ALREADY_EXISTS
, "Object already exists" },
1164 { CI_GRC_ATTR_NOT_SETTABLE
, "Attribute not settable" },
1165 { CI_GRC_PERMISSION_DENIED
, "Privilege violation" },
1166 { CI_GRC_DEV_IN_WRONG_STATE
, "Device state conflict" },
1167 { CI_GRC_REPLY_DATA_TOO_LARGE
,"Reply data too large" },
1168 { CI_GRC_FRAGMENT_PRIMITIVE
, "Fragmentation of a primitive value" },
1169 { CI_GRC_CONFIG_TOO_SMALL
, "Not enough data" },
1170 { CI_GRC_UNDEFINED_ATTR
, "Attribute not supported" },
1171 { CI_GRC_CONFIG_TOO_BIG
, "Too much data" },
1172 { CI_GRC_OBJ_DOES_NOT_EXIST
, "Object does not exist" },
1173 { CI_GRC_NO_FRAGMENTATION
, "Service fragmentation sequence not in progress" },
1174 { CI_GRC_DATA_NOT_SAVED
, "No stored attribute data" },
1175 { CI_GRC_DATA_WRITE_FAILURE
, "Store operation failure" },
1176 { CI_GRC_REQUEST_TOO_LARGE
, "Routing failure, request packet too large" },
1177 { CI_GRC_RESPONSE_TOO_LARGE
, "Routing failure, response packet too large" },
1178 { CI_GRC_MISSING_LIST_DATA
, "Missing attribute list entry data" },
1179 { CI_GRC_INVALID_LIST_STATUS
, "Invalid attribute value list" },
1180 { CI_GRC_SERVICE_ERROR
, "Embedded service error" },
1181 { CI_GRC_CONN_RELATED_FAILURE
,"Vendor specific error" },
1182 { CI_GRC_INVALID_PARAMETER
, "Invalid parameter" },
1183 { CI_GRC_WRITE_ONCE_FAILURE
, "Write-once value or medium already written" },
1184 { CI_GRC_INVALID_REPLY
, "Invalid reply received" },
1185 { CI_GRC_BUFFER_OVERFLOW
, "Buffer overflow" },
1186 { CI_GRC_MESSAGE_FORMAT
, "Invalid message format" },
1187 { CI_GRC_BAD_KEY_IN_PATH
, "Key failure in path" },
1188 { CI_GRC_BAD_PATH_SIZE
, "Path size invalid" },
1189 { CI_GRC_UNEXPECTED_ATTR
, "Unexpected attribute in list" },
1190 { CI_GRC_INVALID_MEMBER
, "Invalid Member ID" },
1191 { CI_GRC_MEMBER_NOT_SETTABLE
, "Member not settable" },
1192 { CI_GRC_G2_SERVER_FAILURE
, "Group 2 only server general failure" },
1193 { CI_GRC_UNKNOWN_MB_ERROR
, "Unknown Modbus error" },
1194 { CI_GRC_ATTRIBUTE_NOT_GET
, "Attribute not gettable" },
1199 value_string_ext cip_gs_vals_ext
= VALUE_STRING_EXT_INIT(cip_gs_vals
);
1201 /* Connection Manager Extended Status codes */
1202 #define CM_ES_DUP_FWD_OPEN 0x100
1203 #define CM_ES_CLASS_AND_TRIGGER 0x103
1204 #define CM_ES_OWNERSHIP_CONFLICT 0x106
1205 #define CM_ES_TARGET_CONN_NOT_FOUND 0x107
1206 #define CM_ES_INVALID_NET_CONN_PARAM 0x108
1207 #define CM_ES_INVALID_CONNECTION_SIZE 0x109
1208 #define CM_ES_TARGET_CONNECTION_NOT_CONFIGURED 0x110
1209 #define CM_ES_RPI_NOT_SUPPORTED 0x111
1210 #define CM_ES_RPI_NOT_ACCEPTABLE 0x112
1211 #define CM_ES_OUT_OF_CONNECTIONS 0x113
1212 #define CM_ES_VENDOR_ID_OR_PRODUCT_CODE_MISMATCH 0x114
1213 #define CM_ES_DEVICE_TYPE_MISMATCH 0x115
1214 #define CM_ES_REVISION_MISMATCH 0x116
1215 #define CM_ES_INVALID_PROD_CONS_APP_PATH 0x117
1216 #define CM_ES_INVALID_OR_INCONSISTENT_CONF_APP_PATH 0x118
1217 #define CM_ES_NON_LISTEN_ONLY_CONN_NOT_OPENED 0x119
1218 #define CM_ES_TARGET_OBJECT_OUT_OF_CONNECTIONS 0x11A
1219 #define CM_ES_RPI_SMALLER_THAN_PROD_INHIBIT_TIME 0x11B
1220 #define CM_ES_TRANSPORT_CLASS_NOT_SUPPORTED 0x11C
1221 #define CM_ES_PRODUCTION_TRIGGER_NOT_SUPPORTED 0x11D
1222 #define CM_ES_DIRECTION_NOT_SUPPORTED 0x11E
1223 #define CM_ES_INVALID_OT_NET_CONN_FIX_VAR 0x11F
1224 #define CM_ES_INVALID_TO_NET_CONN_FIX_VAR 0x120
1225 #define CM_ES_INVALID_OT_NET_CONN_PRIORITY 0x121
1226 #define CM_ES_INVALID_TO_NET_CONN_PRIORITY 0x122
1227 #define CM_ES_INVALID_OT_NET_CONN_TYPE 0x123
1228 #define CM_ES_INVALID_TO_NET_CONN_TYPE 0x124
1229 #define CM_ES_INVALID_OT_NET_CONN_REDUNDANT_OWNER 0x125
1230 #define CM_ES_INVALID_CONFIGURATION_SIZE 0x126
1231 #define CM_ES_INVALID_OT_SIZE 0x127
1232 #define CM_ES_INVALID_TO_SIZE 0x128
1233 #define CM_ES_INVALID_CONFIGURATION_APP_PATH 0x129
1234 #define CM_ES_INVALID_CONSUMING_APP_PATH 0x12A
1235 #define CM_ES_INVALID_PRODUCING_APP_PATH 0x12B
1236 #define CM_ES_CONFIGURATION_SYMBOL_NOT_EXIST 0x12C
1237 #define CM_ES_CONSUMING_SYMBOL_NOT_EXIST 0x12D
1238 #define CM_ES_PRODUCING_SYMBOL_NOT_EXIST 0x12E
1239 #define CM_ES_INCONSISTENT_APP_PATH_COMBO 0x12F
1240 #define CM_ES_INCONSISTENT_CONSUME_DATA_FORMAT 0x130
1241 #define CM_ES_INCONSISTENT_PRODUCE_DATA_FORMAT 0x131
1242 #define CM_ES_NULL_FORWARD_OPEN_NOT_SUPPORTED 0x132
1243 #define CM_ES_CONNECTION_TIMED_OUT 0x203
1244 #define CM_ES_UNCONNECTED_REQUEST_TIMED_OUT 0x204
1245 #define CM_ES_PARAMETER_ERROR_IN_UNCONNECTED_REQUEST 0x205
1246 #define CM_ES_MESSAGE_TOO_LARGE_FOR_UNCONNECTED_SEND 0x206
1247 #define CM_ES_UNCONNECTED_ACK_WITHOUT_REPLY 0x207
1248 #define CM_ES_NO_BUFFER_MEMORY_AVAILABLE 0x301
1249 #define CM_ES_NETWORK_BANDWIDTH_NOT_AVAIL_FOR_DATA 0x302
1250 #define CM_ES_NO_CONSUMED_CONN_ID_FILTER_AVAILABLE 0x303
1251 #define CM_ES_NOT_CONFIGURED_TO_SEND_SCHEDULED_DATA 0x304
1252 #define CM_ES_SCHEDULE_SIGNATURE_MISMATCH 0x305
1253 #define CM_ES_SCHEDULE_SIGNATURE_VALIDATION_NOT_POSS 0x306
1254 #define CM_ES_PORT_NOT_AVAILABLE 0x311
1255 #define CM_ES_LINK_ADDRESS_NOT_VALID 0x312
1256 #define CM_ES_INVALID_SEGMENT_IN_CONN_PATH 0x315
1257 #define CM_ES_FWD_CLOSE_CONN_PATH_MISMATCH 0x316
1258 #define CM_ES_SCHEDULING_NOT_SPECIFIED 0x317
1259 #define CM_ES_LINK_ADDRESS_TO_SELF_INVALID 0x318
1260 #define CM_ES_SECONDARY_RESOURCES_UNAVAILABLE 0x319
1261 #define CM_ES_RACK_CONNECTION_ALREADY_ESTABLISHED 0x31A
1262 #define CM_ES_MODULE_CONNECTION_ALREADY_ESTABLISHED 0x31B
1263 #define CM_ES_MISCELLANEOUS 0x31C
1264 #define CM_ES_REDUNDANT_CONNECTION_MISMATCH 0x31D
1265 #define CM_ES_NO_CONSUMER_RES_AVAIL_IN_PROD_MODULE 0x31E
1266 #define CM_ES_NO_CONSUMER_RES_CONF_IN_PROD_MODULE 0x31F
1267 #define CM_ES_NETWORK_LINK_OFFLINE 0x800
1268 #define CM_ES_INCOMPATIBLE_MULTICAST_RPI 0x801
1269 #define CM_ES_INVALID_SAFETY_CONN_SIZE 0x802
1270 #define CM_ES_INVALID_SAFETY_CONN_FORMAT 0x803
1271 #define CM_ES_INVALID_TIME_CORRECTION_CONN_PARAM 0x804
1272 #define CM_ES_INVALID_PING_INTERVAL_EPI_MULTIPLIER 0x805
1273 #define CM_ES_TIME_COORDINATION_MSG_MIN_MULTIPLIER 0x806
1274 #define CM_ES_NETWORK_TIME_EXPECTATION_MULTIPLIER 0x807
1275 #define CM_ES_TIMEOUT_MULTIPLIER 0x808
1276 #define CM_ES_INVALID_MAX_CONSUMER_NUMBER 0x809
1277 #define CM_ES_INVALID_CPCRC 0x80A
1278 #define CM_ES_TIME_CORRECTION_CONN_ID_INVALID 0x80B
1279 #define CM_ES_SCID_MISMATCH 0x80C
1280 #define CM_ES_TUNID_NOT_SET 0x80D
1281 #define CM_ES_TUNID_MISMATCH 0x80E
1282 #define CM_ES_CONFIGURATION_OPERATION_NOT_ALLOWED 0x80F
1283 #define CM_ES_NO_TARGET_APP_DATA_AVAILABLE 0x810
1284 #define CM_ES_NO_ORIG_APP_DATA_AVAILABLE 0x811
1285 #define CM_ES_NODE_ADDRESS_CHANGED_AFTER_SCHEDULED 0x812
1286 #define CM_ES_NOT_CONFIGURED_MULTICAST 0x813
1287 #define CM_ES_INVALID_PROD_CONS_DATA_FORMAT 0x814
1288 #define CM_ES_EGRESS_RULE_DENY 0x916
1289 #define CM_ES_EGRESS_RULE_CIPHER_NOT_ALLOWED 0x917
1290 #define CM_ES_NO_MATCHING_INGRESS_RULE 0x918
1291 #define CM_ES_INGRESS_RULE_DENY 0x919
1292 #define CM_ES_INGRESS_RULE_DENY_NON_SECURE 0x91A
1293 #define CM_ES_NO_MATCHING_EGRESS_RULE 0x91B
1295 /* Translate function to string - CIP Extended Status codes */
1296 static const value_string cip_cm_ext_st_vals
[] = {
1297 { CM_ES_DUP_FWD_OPEN
, "Connection in use or duplicate Forward Open" },
1298 { CM_ES_CLASS_AND_TRIGGER
, "Transport class and trigger combination not supported" },
1299 { CM_ES_OWNERSHIP_CONFLICT
, "Ownership conflict" },
1300 { CM_ES_TARGET_CONN_NOT_FOUND
, "Target connection not found" },
1301 { CM_ES_INVALID_NET_CONN_PARAM
, "Invalid network connection parameter" },
1302 { CM_ES_INVALID_CONNECTION_SIZE
, "Invalid connection size" },
1303 { CM_ES_TARGET_CONNECTION_NOT_CONFIGURED
, "Target for connection not configured" },
1304 { CM_ES_RPI_NOT_SUPPORTED
, "RPI not supported" },
1305 { CM_ES_RPI_NOT_ACCEPTABLE
, "RPI value(s) not acceptable" },
1306 { CM_ES_OUT_OF_CONNECTIONS
, "Out of connections" },
1307 { CM_ES_VENDOR_ID_OR_PRODUCT_CODE_MISMATCH
, "Vendor ID or product code mismatch" },
1308 { CM_ES_DEVICE_TYPE_MISMATCH
, "Device type mismatch" },
1309 { CM_ES_REVISION_MISMATCH
, "Revision mismatch" },
1310 { CM_ES_INVALID_PROD_CONS_APP_PATH
, "Invalid produced or consumed application path" },
1311 { CM_ES_INVALID_OR_INCONSISTENT_CONF_APP_PATH
, "Invalid or inconsistent configuration application path" },
1312 { CM_ES_NON_LISTEN_ONLY_CONN_NOT_OPENED
, "Non-listen only connection not opened" },
1313 { CM_ES_TARGET_OBJECT_OUT_OF_CONNECTIONS
, "Target object out of connections" },
1314 { CM_ES_RPI_SMALLER_THAN_PROD_INHIBIT_TIME
, "RPI is smaller than the production inhibit time" },
1315 { CM_ES_TRANSPORT_CLASS_NOT_SUPPORTED
, "Transport class not supported" },
1316 { CM_ES_PRODUCTION_TRIGGER_NOT_SUPPORTED
, "Production trigger not supported" },
1317 { CM_ES_DIRECTION_NOT_SUPPORTED
, "Direction not supported" },
1318 { CM_ES_INVALID_OT_NET_CONN_FIX_VAR
, "Invalid O->T Fixed/Variable" },
1319 { CM_ES_INVALID_TO_NET_CONN_FIX_VAR
, "Invalid T->O Fixed/Variable" },
1320 { CM_ES_INVALID_OT_NET_CONN_PRIORITY
, "Invalid O->T Priority" },
1321 { CM_ES_INVALID_TO_NET_CONN_PRIORITY
, "Invalid T->O Priority" },
1322 { CM_ES_INVALID_OT_NET_CONN_TYPE
, "Invalid O->T connection type" },
1323 { CM_ES_INVALID_TO_NET_CONN_TYPE
, "Invalid T->O connection type" },
1324 { CM_ES_INVALID_OT_NET_CONN_REDUNDANT_OWNER
, "Invalid O->T redundant owner" },
1325 { CM_ES_INVALID_CONFIGURATION_SIZE
, "Invalid configuration size" },
1326 { CM_ES_INVALID_OT_SIZE
, "Invalid O->T size" },
1327 { CM_ES_INVALID_TO_SIZE
, "Invalid T->O size" },
1328 { CM_ES_INVALID_CONFIGURATION_APP_PATH
, "Invalid configuration application path" },
1329 { CM_ES_INVALID_CONSUMING_APP_PATH
, "Invalid consuming application path" },
1330 { CM_ES_INVALID_PRODUCING_APP_PATH
, "Invalid producing application path" },
1331 { CM_ES_CONFIGURATION_SYMBOL_NOT_EXIST
, "Configuration symbol does not exist" },
1332 { CM_ES_CONSUMING_SYMBOL_NOT_EXIST
, "Consuming symbol does not exist" },
1333 { CM_ES_PRODUCING_SYMBOL_NOT_EXIST
, "Producing symbol does not exist" },
1334 { CM_ES_INCONSISTENT_APP_PATH_COMBO
, "Inconsistent application path combination" },
1335 { CM_ES_INCONSISTENT_CONSUME_DATA_FORMAT
, "Inconsistent consume data format" },
1336 { CM_ES_INCONSISTENT_PRODUCE_DATA_FORMAT
, "Inconsistent produce data format" },
1337 { CM_ES_NULL_FORWARD_OPEN_NOT_SUPPORTED
, "NULL ForwardOpen not supported" },
1338 { CM_ES_CONNECTION_TIMED_OUT
, "Connection timed out" },
1339 { CM_ES_UNCONNECTED_REQUEST_TIMED_OUT
, "Unconnected request timed out" },
1340 { CM_ES_PARAMETER_ERROR_IN_UNCONNECTED_REQUEST
, "Parameter error in unconnected request" },
1341 { CM_ES_MESSAGE_TOO_LARGE_FOR_UNCONNECTED_SEND
, "Message too large for UnconnectedSend" },
1342 { CM_ES_UNCONNECTED_ACK_WITHOUT_REPLY
, "Unconnected acknowledged without reply" },
1343 { CM_ES_NO_BUFFER_MEMORY_AVAILABLE
, "No buffer memory available" },
1344 { CM_ES_NETWORK_BANDWIDTH_NOT_AVAIL_FOR_DATA
, "Network bandwidth not available for data" },
1345 { CM_ES_NO_CONSUMED_CONN_ID_FILTER_AVAILABLE
, "No consumed connection ID filter available" },
1346 { CM_ES_NOT_CONFIGURED_TO_SEND_SCHEDULED_DATA
, "Not configured to send scheduled priority data" },
1347 { CM_ES_SCHEDULE_SIGNATURE_MISMATCH
, "Schedule signature mismatch" },
1348 { CM_ES_SCHEDULE_SIGNATURE_VALIDATION_NOT_POSS
, "Schedule signature validation not possible" },
1349 { CM_ES_PORT_NOT_AVAILABLE
, "Port not available" },
1350 { CM_ES_LINK_ADDRESS_NOT_VALID
, "Link address not valid" },
1351 { CM_ES_INVALID_SEGMENT_IN_CONN_PATH
, "Invalid segment in connection path" },
1352 { CM_ES_FWD_CLOSE_CONN_PATH_MISMATCH
, "ForwardClose connection path mismatch" },
1353 { CM_ES_SCHEDULING_NOT_SPECIFIED
, "Scheduling not specified" },
1354 { CM_ES_LINK_ADDRESS_TO_SELF_INVALID
, "Link address to self invalid" },
1355 { CM_ES_SECONDARY_RESOURCES_UNAVAILABLE
, "Secondary resources unavailable" },
1356 { CM_ES_RACK_CONNECTION_ALREADY_ESTABLISHED
, "Rack connection already established" },
1357 { CM_ES_MODULE_CONNECTION_ALREADY_ESTABLISHED
, "Module connection already established" },
1358 { CM_ES_MISCELLANEOUS
, "Miscellaneous" },
1359 { CM_ES_REDUNDANT_CONNECTION_MISMATCH
, "Redundant connection mismatch" },
1360 { CM_ES_NO_CONSUMER_RES_AVAIL_IN_PROD_MODULE
, "No more user configurable link consumer resources available in the producing module" },
1361 { CM_ES_NO_CONSUMER_RES_CONF_IN_PROD_MODULE
, "No more user configurable link consumer resources configured in the producing module" },
1362 { CM_ES_NETWORK_LINK_OFFLINE
, "Network link offline" },
1363 { CM_ES_INCOMPATIBLE_MULTICAST_RPI
, "Incompatible Multicast RPI" },
1364 { CM_ES_INVALID_SAFETY_CONN_SIZE
, "Invalid Safety Connection Size" },
1365 { CM_ES_INVALID_SAFETY_CONN_FORMAT
, "Invalid Safety Connection Format" },
1366 { CM_ES_INVALID_TIME_CORRECTION_CONN_PARAM
, "Invalid Time Correction Connection Parameters" },
1367 { CM_ES_INVALID_PING_INTERVAL_EPI_MULTIPLIER
, "Invalid Ping Interval EPI Multiplier" },
1368 { CM_ES_TIME_COORDINATION_MSG_MIN_MULTIPLIER
, "Time Coordination Msg Min Multiplier" },
1369 { CM_ES_NETWORK_TIME_EXPECTATION_MULTIPLIER
, "Network Time Expectation Multiplier" },
1370 { CM_ES_TIMEOUT_MULTIPLIER
, "Timeout Multiplier" },
1371 { CM_ES_INVALID_MAX_CONSUMER_NUMBER
, "Invalid Max Consumer Number" },
1372 { CM_ES_INVALID_CPCRC
, "Invalid CPCRC" },
1373 { CM_ES_TIME_CORRECTION_CONN_ID_INVALID
, "Time Correction Connection ID Invalid" },
1374 { CM_ES_SCID_MISMATCH
, "SCID Mismatch" },
1375 { CM_ES_TUNID_NOT_SET
, "TUNID not set" },
1376 { CM_ES_TUNID_MISMATCH
, "TUNID Mismatch" },
1377 { CM_ES_CONFIGURATION_OPERATION_NOT_ALLOWED
, "Configuration operation not allowed" },
1378 { CM_ES_NO_TARGET_APP_DATA_AVAILABLE
, "No target application data available" },
1379 { CM_ES_NO_ORIG_APP_DATA_AVAILABLE
, "No originator application data available" },
1380 { CM_ES_NODE_ADDRESS_CHANGED_AFTER_SCHEDULED
, "Node address has changed since the network was scheduled" },
1381 { CM_ES_NOT_CONFIGURED_MULTICAST
, "Not configured for off-subnet multicast" },
1382 { CM_ES_INVALID_PROD_CONS_DATA_FORMAT
, "Invalid produce/consume data format" },
1383 { CM_ES_EGRESS_RULE_DENY
, "Egress Rule deny" },
1384 { CM_ES_EGRESS_RULE_CIPHER_NOT_ALLOWED
, "Egress Rule Cipher not allowed" },
1385 { CM_ES_NO_MATCHING_INGRESS_RULE
, "No matching Ingress Rules" },
1386 { CM_ES_INGRESS_RULE_DENY
, "Ingress Rule deny" },
1387 { CM_ES_INGRESS_RULE_DENY_NON_SECURE
, "Ingress Rule deny non-secure" },
1388 { CM_ES_NO_MATCHING_EGRESS_RULE
, "No matching Egress Rule" },
1393 value_string_ext cip_cm_ext_st_vals_ext
= VALUE_STRING_EXT_INIT(cip_cm_ext_st_vals
);
1395 /* Translate function to string - PCCC Status codes */
1396 static const value_string cip_pccc_gs_st_vals
[] = {
1397 { PCCC_GS_SUCCESS
, "Success" },
1398 { PCCC_GS_ILLEGAL_CMD
, "Illegal command or format" },
1399 { PCCC_GS_HOST_COMMS
, "Host has a problem and will not communicate" },
1400 { PCCC_GS_MISSING_REMOTE_NODE
, "Remote node host is missing, disconnected, or shut down" },
1401 { PCCC_GS_HARDWARE_FAULT
, "Host could not complete function due to hardware fault" },
1402 { PCCC_GS_ADDRESSING_ERROR
, "Addressing problem or memory protect rungs" },
1403 { PCCC_GS_CMD_PROTECTION
, "Function not allowed due to command protection selection" },
1404 { PCCC_GS_PROGRAM_MODE
, "Processor is in Program mode" },
1405 { PCCC_GS_MISSING_COMPATIBILITY_FILE
, "Compatibility mode file missing or communication zone problem" },
1406 { PCCC_GS_BUFFER_FULL_1
, "Remote node cannot buffer command" },
1407 { PCCC_GS_WAIT_ACK
, "Wait ACK (1775-KA buffer full)" },
1408 { PCCC_GS_REMOTE_DOWNLOAD_ERROR
, "Remote node problem due to download" },
1409 { PCCC_GS_BUFFER_FULL_2
, "Wait ACK (1775-KA buffer full)" },
1410 { PCCC_GS_NOT_USED_1
, "Not used" },
1411 { PCCC_GS_NOT_USED_2
, "Not used" },
1412 { PCCC_GS_USE_EXTSTS
, "Error code in the EXT STS byte" },
1417 static value_string_ext cip_pccc_gs_st_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_gs_st_vals
);
1419 /* Translate function to string - PCCC Extended Status codes */
1420 static const value_string cip_pccc_es_st_vals
[] = {
1421 { PCCC_ES_ILLEGAL_VALUE
, "A field has an illegal value" },
1422 { PCCC_ES_SHORT_ADDRESS
, "Less levels specified in address than minimum for any address" },
1423 { PCCC_ES_LONG_ADDRESS
, "More levels specified in address than system supports" },
1424 { PCCC_ES_NOT_FOUND
, "Symbol not found" },
1425 { PCCC_ES_BAD_FORMAT
, "Symbol is of improper format" },
1426 { PCCC_ES_BAD_POINTER
, "Address doesn't point to something usable" },
1427 { PCCC_ES_BAD_SIZE
, "File is wrong size" },
1428 { PCCC_ES_SITUATION_CHANGED
, "Cannot complete request, situation has changed since the start of the command" },
1429 { PCCC_ES_DATA_TOO_LARGE
, "Data or file is too large" },
1430 { PCCC_ES_TRANS_TOO_LARGE
, "Transaction size plus word address is too large" },
1431 { PCCC_ES_ACCESS_DENIED
, "Access denied, improper privilege" },
1432 { PCCC_ES_NOT_AVAILABLE
, "Condition cannot be generated - resource is not available" },
1433 { PCCC_ES_ALREADY_EXISTS
, "Condition already exists - resource is already available" },
1434 { PCCC_ES_NO_EXECUTION
, "Command cannot be executed" },
1435 { PCCC_ES_HIST_OVERFLOW
, "Histogram overflow" },
1436 { PCCC_ES_NO_ACCESS
, "No access" },
1437 { PCCC_ES_ILLEGAL_DATA_TYPE
, "Illegal data type" },
1438 { PCCC_ES_INVALID_DATA
, "Invalid parameter or invalid data" },
1439 { PCCC_ES_BAD_REFERENCE
, "Address reference exists to deleted area" },
1440 { PCCC_ES_EXECUTION_FAILURE
, "Command execution failure for unknown reason; possible PLC-3 histogram overflow" },
1441 { PCCC_ES_CONVERSION_ERROR
, "Data conversion error" },
1442 { PCCC_ES_NO_COMMS
, "Scanner not able to communicate with 1771 rack adapter" },
1443 { PCCC_ES_TYPE_MISMATCH
, "Type mismatch" },
1444 { PCCC_ES_BAD_RESPONSE
, "1771 module response was not valid" },
1445 { PCCC_ES_DUP_LABEL
, "Duplicated label" },
1446 { PCCC_ES_FILE_ALREADY_OPEN
, "File is open; another node owns it" },
1447 { PCCC_ES_PROGRAM_ALREADY_OWNED
, "Another node is the program owner" },
1448 { PCCC_ES_RESERVED_1
, "Reserved" },
1449 { PCCC_ES_RESERVED_2
, "Reserved" },
1450 { PCCC_ES_PROTECTION_VIOLATION
, "Data table element protection violation" },
1451 { PCCC_ES_TMP_INTERNAL_ERROR
, "Temporary internal problem" },
1452 { PCCC_ES_RACK_FAULT
, "Remote rack fault" },
1453 { PCCC_ES_TIMEOUT
, "Timeout" },
1454 { PCCC_ES_UNKNOWN
, "Unknown error" },
1459 static value_string_ext cip_pccc_es_st_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_es_st_vals
);
1461 /* Translate PCCC Function Codes */
1462 static const value_string cip_pccc_fnc_06_vals
[] = {
1463 { PCCC_FNC_06_00
, "Echo" },
1464 { PCCC_FNC_06_01
, "Read diagnostic counters" },
1465 { PCCC_FNC_06_02
, "Set variables" },
1466 { PCCC_FNC_06_03
, "Diagnostic status" },
1467 { PCCC_FNC_06_04
, "Set timeout" },
1468 { PCCC_FNC_06_05
, "Set NAKs" },
1469 { PCCC_FNC_06_06
, "Set ENQs" },
1470 { PCCC_FNC_06_07
, "Reset diagnostic counters" },
1471 { PCCC_FNC_06_08
, "Set data table size" },
1472 { PCCC_FNC_06_09
, "Read link parameters" },
1473 { PCCC_FNC_06_0A
, "Set link parameters" },
1478 static value_string_ext cip_pccc_fnc_06_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_fnc_06_vals
);
1480 static const value_string cip_pccc_fnc_07_vals
[] = {
1481 { PCCC_FNC_07_00
, "Disable outputs" },
1482 { PCCC_FNC_07_01
, "Enable outputs" },
1483 { PCCC_FNC_07_03
, "Enable PLC scanning" },
1484 { PCCC_FNC_07_04
, "Enter download mode" },
1485 { PCCC_FNC_07_05
, "Exit download/upload mode" },
1486 { PCCC_FNC_07_06
, "Enter upload mode" },
1491 static value_string_ext cip_pccc_fnc_07_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_fnc_07_vals
);
1493 static const value_string cip_pccc_fnc_0f_vals
[] = {
1494 { PCCC_FNC_0F_00
, "Word range write" },
1495 { PCCC_FNC_0F_01
, "Word range read" },
1496 { PCCC_FNC_0F_02
, "Bit write" },
1497 { PCCC_FNC_0F_03
, "File write" },
1498 { PCCC_FNC_0F_04
, "File read" },
1499 { PCCC_FNC_0F_05
, "Download request" },
1500 { PCCC_FNC_0F_06
, "Upload" },
1501 { PCCC_FNC_0F_07
, "Shutdown" },
1502 { PCCC_FNC_0F_08
, "Physical write" },
1503 { PCCC_FNC_0F_09
, "Physical read" },
1504 { PCCC_FNC_0F_0A
, "Restart request" },
1505 { PCCC_FNC_0F_11
, "Get edit resource" },
1506 { PCCC_FNC_0F_12
, "Return edit resource" },
1507 { PCCC_FNC_0F_17
, "Read bytes physical" },
1508 { PCCC_FNC_0F_18
, "Write bytes physical" },
1509 { PCCC_FNC_0F_26
, "Read-modify-write" },
1510 { PCCC_FNC_0F_29
, "Read section size" },
1511 { PCCC_FNC_0F_3A
, "Set CPU mode" },
1512 { PCCC_FNC_0F_41
, "Disable forces" },
1513 { PCCC_FNC_0F_50
, "Download all request" },
1514 { PCCC_FNC_0F_52
, "Download completed" },
1515 { PCCC_FNC_0F_53
, "Upload all request (upload)" },
1516 { PCCC_FNC_0F_55
, "Upload completed" },
1517 { PCCC_FNC_0F_57
, "Initialize memory" },
1518 { PCCC_FNC_0F_5E
, "Modify PLC-2 compatibility file" },
1519 { PCCC_FNC_0F_67
, "Typed write" },
1520 { PCCC_FNC_0F_68
, "Typed read" },
1521 { PCCC_FNC_0F_79
, "Read-modify-write N" },
1522 { PCCC_FNC_0F_80
, "Change CPU mode" },
1523 { PCCC_FNC_0F_81
, "Open file" },
1524 { PCCC_FNC_0F_82
, "Close file" },
1525 { PCCC_FNC_0F_88
, "Execute Multiple Commands" },
1526 { PCCC_FNC_0F_8F
, "Apply port configuration" },
1527 { PCCC_FNC_0F_A1
, "Protected typed logical read with two address fields" },
1528 { PCCC_FNC_0F_A2
, "Protected typed logical read with three address fields" },
1529 { PCCC_FNC_0F_A7
, "Protected typed file read" },
1530 { PCCC_FNC_0F_A9
, "Protected typed logical write with two address fields" },
1531 { PCCC_FNC_0F_AA
, "Protected typed logical write with three address fields" },
1532 { PCCC_FNC_0F_AB
, "Protected typed logical masked-write with three address fields" },
1533 { PCCC_FNC_0F_AF
, "Protected typed file write" },
1538 static value_string_ext cip_pccc_fnc_0f_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_fnc_0f_vals
);
1540 /* Translate PCCC File Types */
1541 static const value_string cip_pccc_file_types_vals
[] = {
1542 { PCCC_FILE_TYPE_LOGIC
, "Ladder Logic File" },
1543 { PCCC_FILE_TYPE_CHANNEL_CONFIG
, "Channel Configuration File" },
1544 { PCCC_FILE_TYPE_FUNCTION_ES1
, "EtherNet/IP Function File" },
1545 { PCCC_FILE_TYPE_ONLINE_EDIT
, "Online Editing File" },
1546 { PCCC_FILE_TYPE_FUNCTION_IOS
, "IOS Function File" },
1547 { PCCC_FILE_TYPE_DATA_OUTPUT
, "Output Data File" },
1548 { PCCC_FILE_TYPE_DATA_INPUT
, "Input Data File" },
1549 { PCCC_FILE_TYPE_DATA_STATUS
, "Status Data File" },
1550 { PCCC_FILE_TYPE_DATA_BINARY
, "Binary Data File" },
1551 { PCCC_FILE_TYPE_DATA_TIMER
, "Timer Data File" },
1552 { PCCC_FILE_TYPE_DATA_COUNTER
, "Counter Data File" },
1553 { PCCC_FILE_TYPE_DATA_INTEGER
, "Integer Data File" },
1554 { PCCC_FILE_TYPE_DATA_FLOAT
, "Float Data File" },
1555 { PCCC_FILE_TYPE_FORCE_OUTPUT
, "Output Force File" },
1556 { PCCC_FILE_TYPE_FORCE_INPUT
, "Input Force File" },
1557 { PCCC_FILE_TYPE_FUNCTION_ES0
, "ES0 Function File" },
1558 { PCCC_FILE_TYPE_FUNCTION_STI
, "STI Function File" },
1559 { PCCC_FILE_TYPE_FUNCTION_EII
, "EII Function File" },
1560 { PCCC_FILE_TYPE_FUNCTION_RTC
, "RTC Function File" },
1561 { PCCC_FILE_TYPE_FUNCTION_BHI
, "BHI Function File" },
1562 { PCCC_FILE_TYPE_FUNCTION_MMI
, "Memory Module Function File" },
1563 { PCCC_FILE_TYPE_FUNCTION_LCD
, "Built-in LCD Function File" },
1564 { PCCC_FILE_TYPE_FUNCTION_PTOX
, "PTOX Function File" },
1565 { PCCC_FILE_TYPE_FUNCTION_PWMX
, "PWMX Function File" },
1570 static value_string_ext cip_pccc_file_type_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_file_types_vals
);
1572 /* Translate PCCC CPU Modes */
1574 static const value_string cip_pccc_cpu_mode_3a_vals
[] = {
1575 { PCCC_CPU_3A_PROGRAM
, "Remote Program" },
1576 { PCCC_CPU_3A_RUN
, "Remote Run" },
1581 value_string_ext cip_pccc_cpu_mode_3a_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_cpu_mode_3a_vals
);
1584 static const value_string cip_pccc_cpu_mode_80_vals
[] = {
1585 { PCCC_CPU_80_PROGRAM
, "Remote Program" },
1586 { PCCC_CPU_80_RUN
, "Remote Run" },
1587 { PCCC_CPU_80_TEST_CONT
, "Remote Test Continuous" },
1588 { PCCC_CPU_80_TEST_SINGLE
, "Remote Test Single" },
1589 { PCCC_CPU_80_TEST_DEBUG
, "Remote Test Debug" },
1594 static value_string_ext cip_pccc_cpu_mode_80_vals_ext
= VALUE_STRING_EXT_INIT(cip_pccc_cpu_mode_80_vals
);
1596 /* Translate Vendor IDs */
1597 static const value_string cip_vendor_vals
[] = {
1598 { 1, "Rockwell Automation/Allen-Bradley" },
1599 { 2, "Namco Controls Corp." },
1600 { 3, "Honeywell International Inc." },
1601 { 4, "Parker Hannifin Corporation" },
1602 { 5, "Rockwell Automation/Reliance Elec." },
1604 { 7, "SMC Corporation" },
1605 { 8, "Molex Incorporated" },
1606 { 9, "Western Reserve Controls Inc." },
1607 { 10, "Advanced Micro Controls Inc. (AMCI)" },
1608 { 11, "ASCO Pneumatic Controls" },
1609 { 12, "Banner Engineering Corporation" },
1610 { 13, "Belden Wire & Cable Company" },
1611 { 14, "Cooper Interconnect" },
1612 { 16, "Daniel Woodhead Co." },
1613 { 17, "Dearborn Group Inc." },
1615 { 19, "Helm Instrument Company" },
1616 { 20, "Huron Net Works" },
1617 { 21, "Belden Deutschland GmbH" },
1618 { 22, "Online Development, Inc. (OLDI)" },
1619 { 23, "Vorne Industries, Inc." },
1625 { 30, "Unico, Inc." },
1626 { 31, "Ross Controls" },
1628 { 34, "Hohner Corp." },
1629 { 35, "Micro Mo Electronics, Inc." },
1630 { 36, "MKS Instruments, Inc." },
1631 { 37, "Yaskawa Electric America formerly Magnetek Drives" },
1633 { 39, "AVG Automation (Uticor)" },
1634 { 40, "WAGO Corporation" },
1635 { 41, "Celerity, Inc." },
1636 { 42, "IMI Norgren Limited" },
1638 { 44, "Yaskawa America, Inc." },
1639 { 45, "Eurotherm by Schneider Electric" },
1640 { 46, "ABB, Inc." },
1641 { 47, "Omron Corporation" },
1643 { 49, "Grayhill Inc." },
1644 { 50, "Real Time Automation" },
1646 { 52, "ASCO Numatics" },
1651 { 57, "Pepperl+Fuchs" },
1652 { 58, "Spectrum Controls, Inc." },
1653 { 59, "D.I.P. Inc. MKS Inst." },
1654 { 60, "Applied Motion Products, Inc." },
1655 { 61, "Sencon Inc." },
1656 { 62, "High Country Tek" },
1657 { 63, "SWAC Automation Consult GmbH" },
1658 { 64, "Clippard Instrument Laboratory" },
1662 { 68, "Eaton Electrical" },
1665 { 71, "Toshiba Corporation" },
1666 { 72, "Control Technology Incorporated" },
1667 { 73, "TCS (NZ) Ltd." },
1668 { 74, "Hitachi, Ltd." },
1669 { 75, "ABB Robotics" },
1670 { 76, "NKE Corporation" },
1671 { 77, "Rockwell Software, Inc." },
1672 { 78, "Escort Memory Systems (A Datalogic Group Co.)" },
1674 { 80, "Industrial Devices Corporation" },
1675 { 81, "IXXAT Automation GmbH" },
1676 { 82, "Mitsubishi Electric Automation, Inc." },
1680 { 86, "Horner Electric" },
1681 { 87, "Buerkert Fluid Control Systems" },
1683 { 89, "Industrial Indexing Systems, Inc." },
1684 { 90, "HMS Networks" },
1686 { 92, "Helix Technology (Granville-Phillips)" },
1687 { 93, "Arlington Laboratory" },
1688 { 94, "Advantech Corporation" },
1689 { 95, "Square D Company" },
1690 { 96, "Digital Electronics Corp." },
1691 { 97, "Danfoss Drives A/S" },
1694 { 100, "AVENTICS" },
1695 { 101, "Applied Materials, Inc." },
1696 { 102, "SWCC Showa Cable Systems Co., Ltd." },
1697 { 103, "Pacific Scientific (API Controls Inc.)" },
1698 { 104, "Sharp Manufacturing Systems Corporation" },
1699 { 105, "Olflex Wire & Cable, Inc." },
1700 { 106, "Reserved" },
1701 { 107, "Unitrode" },
1702 { 108, "Beckhoff Automation" },
1703 { 109, "National Instruments" },
1704 { 110, "Mykrolis Corporation (Millipore)" },
1705 { 111, "International Motion Controls Corp." },
1706 { 112, "Reserved" },
1707 { 113, "SEG Kempen GmbH" },
1708 { 114, "Reserved" },
1709 { 115, "Reserved" },
1710 { 116, "Temposonics, LLC" },
1711 { 117, "Krones, Inc" },
1712 { 119, "EXOR Electronic R & D" },
1713 { 120, "SIEI S.p.A." },
1714 { 121, "KUKA Deutschland GmbH" },
1715 { 122, "Reserved" },
1716 { 123, "SEC (Samsung Electronics Co., Ltd)" },
1717 { 124, "Binary Electronics Ltd" },
1718 { 125, "Flexible Machine Controls" },
1719 { 126, "Reserved" },
1720 { 127, "ABB Inc. (Entrelec)" },
1721 { 128, "MAC Valves, Inc." },
1722 { 129, "AUMA Riester GmbH & Co. KG" },
1723 { 130, "JTEKT Corporation" },
1724 { 131, "Reserved" },
1725 { 132, "Reserved" },
1726 { 133, "Balogh T.A.G., Corporation" },
1727 { 134, "TR Electronic" },
1728 { 135, "UNIPULSE Corporation" },
1729 { 136, "Reserved" },
1730 { 137, "Reserved" },
1731 { 138, "Conxall Corporation Inc." },
1732 { 139, "Reserved" },
1733 { 140, "Reserved" },
1734 { 141, "Kuramo Electric Co., Ltd." },
1735 { 142, "Creative Micro Designs" },
1736 { 143, "GE Industrial Systems" },
1737 { 144, "Leybold GmbH" },
1738 { 145, "Siemens Energy & Automation/Drives" },
1739 { 146, "Kodensha Ltd" },
1740 { 147, "Motion Engineering, Inc." },
1741 { 148, "Honda Engineering Co., Ltd" },
1742 { 149, "EIM Valve Controls" },
1743 { 150, "Melec Inc." },
1744 { 151, "Sony Manufacturing Systems Corporation" },
1745 { 152, "North American Mfg." },
1747 { 154, "Japan Radio Co., Ltd" },
1748 { 155, "NADEX Co., Ltd" },
1749 { 156, "Ametek Automation & Process Technologies" },
1750 { 157, "Facts, Inc." },
1751 { 158, "KVASER AB" },
1752 { 159, "IDEC Corporation" },
1753 { 160, "Mitsubishi Heavy Industries Ltd" },
1754 { 161, "Mitsubishi Electric Corporation" },
1755 { 162, "HORIBA STEC, Co., Ltd." },
1756 { 163, "esd electronics gmbh" },
1757 { 164, "DAIHEN Corporation" },
1758 { 165, "Tyco Valves & Controls/Keystone" },
1759 { 166, "EBARA Corporation" },
1760 { 168, "Reserved" },
1761 { 169, "Hokuyo Automatic Co., Ltd." },
1762 { 170, "Pyramid Solutions, Inc." },
1763 { 171, "Denso Wave Incorporated" },
1764 { 172, "HLS Hard-Line Solutions Inc" },
1765 { 173, "Caterpillar, Inc." },
1766 { 174, "PDL Electronics Ltd." },
1767 { 175, "Reserved" },
1768 { 176, "Red Lion" },
1769 { 177, "CANON ANELVA Corporation" },
1770 { 178, "Toyo Denki Seizo KK" },
1771 { 179, "Sanyo Denki Co., Ltd." },
1772 { 180, "Hitachi Metals, Ltd. (formerly Advanced Energy Japan K.K.)" },
1773 { 181, "Pilz GmbH & Co KG" },
1774 { 182, "Marsh Bellofram-Bellofram PCD Division" },
1775 { 183, "Reserved" },
1776 { 184, "M-SYSTEM Co., Ltd." },
1777 { 185, "Nissin Electric Co., Ltd." },
1778 { 186, "Hitachi Metals Ltd." },
1779 { 187, "Oriental Motor Co., Ltd" },
1780 { 188, "A&D Company Limited" },
1781 { 189, "Phasetronics, Inc." },
1782 { 190, "Cummins Engine Company" },
1783 { 191, "Deltron Inc." },
1784 { 192, "Geneer Corporation" },
1785 { 193, "Anatol Automation, Inc." },
1786 { 194, "Reserved" },
1787 { 195, "Reserved" },
1788 { 196, "Medar, Inc." },
1789 { 197, "XP Power LLC" },
1790 { 198, "Advanced Energy Industries, Inc." },
1791 { 199, "Reserved" },
1792 { 200, "DAIDEN Co., Ltd" },
1793 { 201, "CKD Corporation" },
1794 { 202, "Toyo Electric Corporation" },
1795 { 203, "Reserved" },
1796 { 204, "AuCom Electronics Ltd" },
1797 { 205, "Sinfonia Technology Co., Ltd." },
1798 { 206, "Vector Informatik GmbH" },
1799 { 207, "Reserved" },
1800 { 208, "Moog Inc." },
1801 { 209, "Contemporary Controls" },
1802 { 210, "Tokyo Sokki Kenkyujo Co., Ltd" },
1803 { 211, "Schenck Process Group" },
1804 { 212, "The Oilgear Company" },
1805 { 213, "Reserved" },
1806 { 214, "ASM Japan K.K." },
1807 { 215, "HIRATA Corp." },
1808 { 216, "Panasonic Industrial Devices SUNX Co., Ltd." },
1809 { 217, "Meidensha Corporation" },
1810 { 218, "NIDEC SANKYO CORPORATION (Sankyo Seiki Mfg. Co., Ltd)" },
1811 { 219, "KAMRO Corp." },
1812 { 220, "NSD Co., Ltd." },
1813 { 221, "EBARA Technologies Inc." },
1814 { 222, "Reserved" },
1815 { 223, "Reserved" },
1816 { 224, "SG Co., Ltd" },
1817 { 225, "Vaasa Institute of Technology" },
1818 { 226, "MKS Instruments (ENI Technology)" },
1819 { 227, "Tateyama System Laboratory Co., Ltd." },
1820 { 228, "QLOG Corporation" },
1821 { 229, "Matric Limited Inc." },
1822 { 230, "NSD Corporation" },
1823 { 231, "Reserved" },
1824 { 232, "Sumitomo Wiring Systems, Ltd" },
1825 { 233, "Group 3 Technology Ltd" },
1826 { 234, "CTI Cryogenics" },
1827 { 235, "POLSYS CORP" },
1828 { 236, "Ampere Inc." },
1829 { 237, "Reserved" },
1830 { 238, "Simplatroll Ltd" },
1831 { 239, "Reserved" },
1832 { 240, "Reserved" },
1833 { 241, "Leading Edge Design" },
1834 { 242, "Humphrey Products" },
1835 { 243, "Schneider Electric" },
1836 { 244, "Westlock Controls Corp." },
1837 { 245, "Nihon Weidmuller Co., Ltd" },
1838 { 246, "Brooks Instrument" },
1839 { 247, "Reserved" },
1840 { 248, "Eaton Industries GmbH (formerly Moeller GmbH)" },
1841 { 249, "Varian Vacuum Products" },
1842 { 250, "Yokogawa Electric Corporation" },
1843 { 251, "Electrical Design Daiyu Co., Ltd" },
1844 { 252, "Omron Software Co., Ltd." },
1846 { 254, "Control Technology Corporation" },
1847 { 255, "Bosch Rexroth" },
1848 { 256, "TURCK (formerly InterlinkBT)" },
1849 { 257, "Control Techniques PLC" },
1850 { 258, "Hardy Process Solutions" },
1851 { 259, "LS ELECTRIC" },
1852 { 260, "E.O.A. Systems Inc." },
1853 { 261, "Reserved" },
1854 { 262, "New Cosmos Electric Co., Ltd." },
1855 { 263, "Sense Sense Eletronica LTDA" },
1856 { 264, "Xycom, Inc." },
1857 { 265, "Baldor Electric" },
1858 { 266, "Reserved" },
1859 { 267, "Patlite Corporation" },
1860 { 268, "Reserved" },
1861 { 269, "Mogami Wire & Cable Corporation" },
1862 { 270, "Welding Technology Corporation" },
1863 { 271, "Reserved" },
1864 { 272, "Deutschmann Automation GmbH" },
1865 { 273, "ICP Panel-Tec Inc." },
1866 { 274, "Bray International, Inc" },
1867 { 275, "Reserved" },
1868 { 276, "Status Technologies" },
1869 { 277, "Trio Motion Technology ltd" },
1870 { 278, "Sherrex Systems Ltd" },
1871 { 279, "Adept Technology, Inc." },
1872 { 280, "Spang Power Electronics" },
1873 { 281, "Reserved" },
1874 { 282, "Acrosser Technology Co., Ltd" },
1875 { 283, "Hilscher GmbH" },
1876 { 284, "IMAX Corporation" },
1877 { 285, "Electronic Innovation, Inc. (Falter Engineering)" },
1878 { 286, "Netlogic Inc." },
1879 { 287, "Bosch Rexroth AG" },
1880 { 288, "Reserved" },
1881 { 289, "Reserved" },
1882 { 290, "Murata Machinery Ltd." },
1883 { 291, "MTT Company Ltd." },
1884 { 292, "Kanematsu Semiconductor Corp." },
1885 { 293, "Takebishi Electric Sales Co." },
1886 { 294, "Tokyo Electron Device Ltd" },
1887 { 295, "PFU Limited" },
1888 { 296, "Hakko Automation Co., Ltd." },
1889 { 297, "Advanet Inc." },
1890 { 298, "Tokyo Electron Software Technologies Ltd." },
1891 { 299, "Reserved" },
1892 { 300, "Shinagawa Electric Wire Co., Ltd." },
1893 { 301, "Yokogawa M&C Corporation" },
1894 { 302, "KONAN Electric Co., Ltd." },
1895 { 303, "Binar Elektronik AB" },
1896 { 304, "Furukawa Electric Co." },
1897 { 305, "Cooper Energy Services" },
1898 { 306, "Schleicher GmbH & Co." },
1899 { 307, "Hirose Electric Co., Ltd" },
1900 { 308, "Western Servo Design Inc." },
1901 { 309, "ProSoft Technology" },
1902 { 310, "Reserved" },
1903 { 311, "Towa Shoko Co., Ltd" },
1904 { 312, "Kyopal Co., Ltd" },
1905 { 313, "Extron Co." },
1906 { 314, "Wieland Electric GmbH" },
1907 { 315, "SEW Eurodrive GmbH" },
1908 { 316, "Aera Corporation" },
1909 { 317, "STA Reutlingen" },
1910 { 318, "Reserved" },
1911 { 319, "Fuji Electric Group" },
1912 { 320, "Reserved" },
1913 { 321, "Reserved" },
1914 { 322, "ifm electronic gmbh" },
1915 { 323, "Reserved" },
1916 { 324, "IDEACOD-Hohner Automation S.A." },
1917 { 325, "CommScope Inc." },
1918 { 326, "Intelligent Platforms, LLC." },
1919 { 327, "Matsushita Electric Industrial Co., Ltd" },
1920 { 328, "Okaya Electronics Corporation" },
1921 { 329, "KASHIYAMA Industries, Ltd" },
1923 { 331, "Interface Corporation" },
1924 { 332, "Grape Systems Inc." },
1925 { 333, "Reserved" },
1926 { 334, "Reserved" },
1927 { 335, "Toshiba IT & Control Systems Corporation" },
1928 { 336, "Sanyo Machine Works, Ltd." },
1929 { 337, "Vansco Electronics Ltd." },
1930 { 338, "Dart Container Corp." },
1931 { 339, "Livingston & Co., Inc." },
1932 { 340, "Alfa Laval LKM as" },
1933 { 341, "BF ENTRON Ltd. (British Federal)" },
1934 { 342, "Bekaert Engineering NV" },
1935 { 343, "Ferran Scientific Inc." },
1936 { 344, "KEBA Industrial Automation GmbH" },
1937 { 345, "Endress + Hauser" },
1938 { 346, "Lincoln Electric Company" },
1939 { 347, "ABB ALSTOM Power UK Ltd. (EGT)" },
1940 { 348, "Berger Lahr GmbH" },
1941 { 349, "Reserved" },
1942 { 350, "Federal Signal Corp." },
1943 { 351, "Kawasaki Robotics (USA), Inc." },
1944 { 352, "Bently Nevada Corporation" },
1945 { 354, "FRABA Posital" },
1946 { 355, "Elsag Bailey, Inc." },
1947 { 356, "FANUC Robotics America" },
1948 { 357, "Reserved" },
1949 { 358, "Surface Combustion, Inc." },
1950 { 359, "Reserved" },
1951 { 360, "AILES Electronics Ind. Co., Ltd." },
1952 { 361, "Wonderware Corporation" },
1953 { 362, "Particle Measuring Systems, Inc." },
1954 { 363, "Reserved" },
1955 { 364, "Reserved" },
1956 { 365, "BITS Co., Ltd" },
1957 { 366, "Japan Aviation Electronics Industry Ltd" },
1958 { 367, "Keyence Corporation" },
1959 { 368, "Kuroda Precision Industries Ltd." },
1960 { 369, "Mitsubishi Electric Semiconductor Application" },
1961 { 370, "Nippon Seisen Cable, Ltd." },
1962 { 371, "Omron ASO Co., Ltd" },
1963 { 372, "Seiko Seiki Co., Ltd." },
1964 { 373, "Sumitomo Heavy Industries, Ltd." },
1965 { 374, "Tango Computer Service Corporation" },
1966 { 375, "Technology Service, Inc." },
1967 { 376, "Toshiba Information Systems (Japan) Corporation" },
1968 { 377, "TOSHIBA Schneider Inverter Corporation" },
1969 { 378, "Toyooki Kogyo Co., Ltd." },
1971 { 380, "Madison Cable Corporation" },
1972 { 381, "Hitati Engineering & Services Co., Ltd" },
1973 { 382, "TEM-TECH Lab Co., Ltd" },
1974 { 383, "International Laboratory Corporation" },
1975 { 384, "Dyadic Systems Co., Ltd." },
1976 { 385, "SETO Electronics Industry Co., Ltd" },
1977 { 386, "Tokyo Electron Kyushu Limited" },
1978 { 387, "KEI System Co., Ltd" },
1979 { 388, "Reserved" },
1980 { 389, "Asahi Engineering Co., Ltd" },
1981 { 390, "Contrex Inc." },
1982 { 391, "Paradigm Controls Ltd." },
1983 { 392, "Reserved" },
1984 { 393, "Ohm Electric Co., Ltd." },
1985 { 394, "RKC Instrument Inc." },
1986 { 395, "Suzuki Motor Corporation" },
1987 { 396, "Custom Servo Motors Inc." },
1988 { 397, "PACE Control Systems" },
1989 { 398, "Selectron Systems AG" },
1990 { 399, "Reserved" },
1991 { 400, "LINTEC Co., Ltd." },
1992 { 401, "Hitachi Cable Ltd." },
1993 { 402, "BUSWARE Direct" },
1994 { 403, "Eaton Electric B.V. (former Holec Holland N.V.)" },
1995 { 404, "VAT Vacuum Valves AG" },
1996 { 405, "Omron Robotics and Safety Technologies, Inc." },
1997 { 406, "Alfa Instrumentos Eletronicos Ltda" },
1998 { 407, "TWK Elektronik GmbH" },
1999 { 408, "ABB Welding Systems AB" },
2000 { 409, "BYSTRONIC Maschinen AG" },
2001 { 410, "Kimura Electric Co., Ltd" },
2002 { 411, "Nissei Plastic Industrial Co., Ltd" },
2003 { 412, "Reserved" },
2004 { 413, "Kistler-Morse" },
2005 { 414, "Proteus Industries Inc." },
2006 { 415, "IDC Corporation" },
2007 { 416, "Nordson Corporation" },
2008 { 417, "Rapistan Systems" },
2009 { 418, "LP-Elektronik GmbH" },
2010 { 419, "GERBI & FASE S.p.A.(Fase Saldatura)" },
2011 { 420, "Phoenix Digital Corporation" },
2012 { 421, "Z-World Engineering" },
2013 { 422, "Honda R&D Co., Ltd." },
2014 { 423, "Bionics Instrument Co., Ltd." },
2015 { 424, "Teknic, Incorporated" },
2016 { 425, "R.Stahl, Inc." },
2017 { 426, "Reserved" },
2018 { 427, "Ryco Graphic Manufacturing Inc." },
2019 { 428, "Giddings & Lewis, Inc." },
2020 { 429, "Koganei Corporation" },
2021 { 430, "Reserved" },
2022 { 431, "Nichigoh Communication Electric Wire Co., Ltd." },
2023 { 433, "Fujikura Ltd." },
2024 { 434, "AD Link Technology Inc." },
2025 { 435, "Valmet Flow Control Inc (formerly StoneL)" },
2026 { 436, "Computer Optical Products, Inc." },
2027 { 437, "CONOS Inc." },
2028 { 438, "Erhardt+Leimer GmbH" },
2029 { 439, "UNIQUE Co. Ltd" },
2030 { 440, "Roboticsware, Inc." },
2031 { 441, "Nachi Fujikoshi Corporation" },
2032 { 442, "Hengstler GmbH" },
2033 { 443, "Vacon Plc" },
2034 { 444, "SUNNY GIKEN Inc." },
2035 { 445, "Lenze Drive Systems GmbH" },
2036 { 446, "CD Systems B.V." },
2037 { 447, "FMT/Aircraft Gate Support Systems AB" },
2038 { 448, "Axiomatic Technologies Corp" },
2039 { 449, "Embedded System Products, Inc." },
2040 { 450, "Reserved" },
2041 { 451, "Mencom Corporation" },
2042 { 452, "Kollmorgen" },
2043 { 453, "Panasonic Connect Co., Ltd." },
2044 { 454, "Dengensha Mfg. Co. Ltd." },
2045 { 455, "Quinn Systems Ltd." },
2046 { 456, "Tellima Technology Ltd" },
2047 { 457, "MDT, Software" },
2048 { 458, "Taiwan Keiso Co., Ltd" },
2049 { 459, "Pinnacle Systems" },
2050 { 460, "Ascom Hasler Mailing Sys" },
2051 { 461, "INSTRUMAR Limited" },
2052 { 462, "Reserved" },
2053 { 463, "Navistar International Transportation Corp" },
2054 { 464, "TRUMPF Huettinger" },
2055 { 465, "OCM Technology Inc." },
2056 { 466, "Professional Supply Inc." },
2057 { 467, "Control Solutions" },
2058 { 468, "Baumer IVO GmbH & Co. KG" },
2059 { 469, "Worcester Controls Corporation" },
2060 { 470, "Pyramid Technical Consultants, Inc." },
2061 { 471, "Eilersen Electric A/S" },
2062 { 472, "Apollo Fire Detectors Limited" },
2063 { 473, "Avtron Manufacturing, Inc." },
2064 { 474, "Reserved" },
2065 { 475, "Tokyo Keiso Co., Ltd." },
2066 { 476, "Daishowa Swiki Co., Ltd." },
2067 { 477, "Kojima Instruments Inc." },
2068 { 478, "Shimadzu Corporation" },
2069 { 479, "Tatsuta Electric Wire & Cable Co., Ltd." },
2070 { 480, "MECS Corporation" },
2071 { 481, "Tahara Electric" },
2072 { 482, "JTEKT ELECTRONICS CORPORATION" },
2073 { 483, "Clever Devices" },
2074 { 484, "GCD Hardware & Software GmbH" },
2075 { 485, "Reserved" },
2076 { 486, "Miller Electric Mfg Co." },
2077 { 487, "GEA Tuchenhagen GmbH" },
2078 { 488, "Riken Keiki Co., Ltd." },
2079 { 489, "Keisokugiken Corporation" },
2080 { 490, "Fuji Machine Mfg. Co., Ltd" },
2081 { 491, "Reserved" },
2082 { 492, "Nidec-Shimpo Corp." },
2083 { 493, "UTEC Corporation" },
2084 { 494, "Sanyo Electric Co. Ltd." },
2085 { 495, "Reserved" },
2086 { 496, "Reserved" },
2087 { 497, "Okano Electric Wire Co. Ltd" },
2088 { 498, "Shimaden Co. Ltd." },
2089 { 499, "Teddington Controls Ltd" },
2090 { 500, "Reserved" },
2091 { 501, "YASKAWA Europe (formerly VIPA GmbH)" },
2092 { 502, "Warwick Manufacturing Group" },
2093 { 503, "Danaher Controls" },
2094 { 504, "Reserved" },
2095 { 505, "Reserved" },
2096 { 506, "American Science & Engineering" },
2097 { 507, "Accutron Controls International Inc." },
2098 { 508, "Norcott Technologies Ltd" },
2099 { 509, "TB Woods, Inc" },
2100 { 510, "Proportion-Air, Inc." },
2101 { 511, "SICK Stegmann GmbH" },
2102 { 512, "Reserved" },
2103 { 513, "Edwards Signaling" },
2104 { 514, "Sumitomo Metal Industries, Ltd" },
2105 { 515, "Cosmo Instruments Co., Ltd." },
2106 { 516, "Denshosha Co., Ltd." },
2107 { 517, "Kaijo Corp." },
2108 { 518, "Michiproducts Co., Ltd." },
2109 { 519, "Miura Corporation" },
2110 { 520, "TG Information Network Co., Ltd." },
2111 { 521, "Fujikin, Inc." },
2112 { 522, "Estic Corp." },
2113 { 523, "GS Hydraulic Sales" },
2114 { 524, "Leuze Electronic GmbH & Co. KG" },
2115 { 525, "MTE Limited" },
2116 { 526, "Hyde Park Electronics, Inc." },
2117 { 527, "Pfeiffer Vacuum GmbH" },
2118 { 528, "Cyberlogic Technologies" },
2119 { 529, "OKUMA Corporation FA Systems Division" },
2120 { 530, "Reserved" },
2121 { 531, "Kokusai Electric Corporation" },
2122 { 532, "SHINKO TECHNOS" },
2123 { 533, "Itoh Denki Co., Ltd." },
2124 { 534, "Colorado Flow Tech Inc." },
2125 { 535, "Love Controls Division/Dwyer Inst." },
2126 { 536, "Alstom Drives and Controls" },
2127 { 537, "The Foxboro Company" },
2128 { 538, "Tescom Corporation" },
2129 { 539, "Reserved" },
2130 { 540, "Atlas Copco Airpower NV" },
2131 { 541, "Reserved" },
2132 { 542, "Autojet Technologies" },
2133 { 543, "Prima Electronics S.p.A." },
2134 { 544, "PMA GmbH" },
2135 { 545, "Shimafuji Electric Co., Ltd" },
2136 { 546, "Oki Electric Industry Co., Ltd" },
2137 { 547, "Kyushu Matsushita Electric Co., Ltd" },
2139 { 549, "Tsuken Electric Ind Co., Ltd" },
2140 { 550, "Tamadic Co." },
2141 { 551, "MAATEL SA" },
2142 { 552, "OKUMA America" },
2143 { 553, "Control Techniques PLC-NA" },
2144 { 554, "TPC Wire & Cable" },
2145 { 555, "ATI Industrial Automation" },
2146 { 556, "Microcontrol (Australia) Pty Ltd" },
2147 { 557, "Serra Soldadura, S.A." },
2148 { 558, "Southwest Research Institute" },
2149 { 559, "Cabinplant International" },
2150 { 560, "Minebea Intec" },
2151 { 561, "Comau S.p.A." },
2152 { 562, "Phoenix Contact" },
2153 { 563, "Yokogawa MAT Corporation" },
2154 { 564, "asahi sangyo co., ltd." },
2156 { 566, "Akita Myotoku Ltd." },
2157 { 567, "OBARA Corp." },
2158 { 568, "Suetron Electronic GmbH" },
2159 { 569, "Reserved" },
2160 { 570, "Serck Controls Limited" },
2161 { 571, "Fairchild Industrial Products Company" },
2162 { 572, "ARO Welding Technologies S.A.S." },
2163 { 573, "M2C GmbH" },
2164 { 574, "Shin Caterpillar Mitsubishi Ltd." },
2165 { 575, "Santest Co., Ltd." },
2166 { 576, "Cosmotechs Co., Ltd." },
2167 { 577, "Hitachi Electric Systems" },
2168 { 578, "Smartscan Ltd" },
2169 { 579, "Woodhead Software & Electronics France" },
2170 { 580, "Athena Controls, Inc." },
2171 { 581, "Norgren Automation Solutions, LLC (previously Syron Engineering & Manufacturing, Inc.)" },
2172 { 582, "Asahi Optical Co., Ltd." },
2173 { 583, "Sansha Electric Mfg. Co.,Ltd." },
2174 { 584, "CKD Nikki Denso Co,. Ltd." },
2175 { 585, "Star Micronics, Co., Ltd." },
2176 { 586, "Ecotecnia Socirtat Corp." },
2178 { 588, "West Instruments Limited" },
2180 { 590, "Delta Computer Systems, Inc." },
2181 { 591, "FANUC CORPORATION" },
2182 { 592, "Hearn-Gu Lee" },
2184 { 594, "Orion Machinery Co., Ltd." },
2185 { 595, "Reserved" },
2186 { 596, "Wire-Pro, Inc." },
2187 { 597, "Beijing Huakong Technology Co. Ltd." },
2188 { 598, "Yokoyama Shokai Co., Ltd." },
2189 { 599, "Toyogiken Co., Ltd." },
2190 { 600, "Coester Equipamentos Eletronicos Ltda." },
2191 { 601, "Kawasaki Robot" },
2192 { 602, "Electroplating Engineers of Japan Ltd." },
2193 { 603, "Robox S.p.a." },
2194 { 604, "Spraying Systems Company" },
2195 { 605, "Benshaw Inc." },
2196 { 606, "ZPA-DP A.S." },
2197 { 607, "Wired Rite Systems" },
2198 { 608, "Tandis Research, Inc." },
2199 { 609, "SSD Drives GmbH" },
2200 { 610, "ULVAC Japan Ltd." },
2201 { 611, "DYNAX Corporation" },
2202 { 612, "Nor-Cal Products, Inc." },
2203 { 613, "Aros Electronics AB" },
2204 { 614, "Jun-Tech Co., Ltd." },
2205 { 615, "HAN-MI Co. Ltd." },
2206 { 616, "uniNtech (formerly SungGi Internet)" },
2207 { 617, "Hae Pyung Electronics Reserch Institute" },
2208 { 618, "Milwaukee Electronics" },
2209 { 619, "OBERG Industries" },
2210 { 620, "Parker Hannifin/Compumotor Division" },
2211 { 621, "TECHNO DIGITAL CORPORATION" },
2212 { 622, "Network Supply Co., Ltd." },
2213 { 623, "Union Electronics Co., Ltd." },
2214 { 624, "Tritronics Services PM Ltd." },
2215 { 625, "Rockwell Automation/Sprecher+Schuh" },
2216 { 626, "Panasonic Corporation/Motor Company" },
2217 { 627, "Rolls-Royce Energy Systems, Inc." },
2218 { 628, "JEONGIL INTERCOM CO., LTD" },
2219 { 629, "Interroll Software & Electronics GmbH" },
2220 { 630, "Hubbell Wiring Device-Kellems (Delaware)" },
2221 { 631, "Intelligent Motion Systems" },
2222 { 632, "Reserved" },
2223 { 633, "INFICON AG" },
2224 { 634, "Hirschmann, a Belden brand" },
2225 { 635, "The Siemon Company" },
2226 { 636, "YAMAHA Motor Co. Ltd." },
2227 { 637, "aska corporation" },
2228 { 638, "Woodhead Connectivity" },
2229 { 639, "Trimble AB" },
2230 { 640, "Murrelektronik GmbH" },
2231 { 641, "Creatrix Labs, Inc." },
2233 { 643, "Kumho Industrial Co., Ltd." },
2234 { 644, "Wind River Systems, Inc." },
2235 { 645, "Bihl + Wiedemann GmbH" },
2236 { 646, "Harmonic Drive Systems Inc." },
2237 { 647, "Rikei Corporation" },
2238 { 648, "BL Autotec, Ltd." },
2239 { 649, "Hana Information & Technology Co., Ltd." },
2240 { 650, "Seoil Electric Co., Ltd." },
2241 { 651, "Fife Corporation" },
2242 { 652, "Shanghai Electrical Apparatus Research Institute" },
2243 { 653, "Detector Electronics" },
2244 { 654, "Parasense Development Centre" },
2245 { 655, "Reserved" },
2246 { 656, "Reserved" },
2247 { 657, "Six Tau S.p.A." },
2248 { 658, "Aucos GmbH" },
2249 { 659, "Rotork Controls Ltd." },
2250 { 660, "Automationdirect.com" },
2251 { 661, "Thermo BLH" },
2252 { 662, "System Controls, Ltd." },
2253 { 663, "Univer S.p.A." },
2254 { 664, "MKS-Tenta Technology" },
2255 { 665, "Lika Electronic" },
2256 { 666, "Mettler-Toledo" },
2257 { 667, "DXL USA Inc." },
2258 { 668, "Rockwell Automation/Entek IRD Intl." },
2259 { 669, "Nippon Otis Elevator Company" },
2260 { 670, "Sinano Electric, Co., Ltd." },
2261 { 671, "Sony Manufacturing Systems" },
2262 { 672, "Reserved" },
2263 { 673, "CONTEC CO., LTD." },
2264 { 674, "Automated Solutions" },
2265 { 675, "Controlweigh" },
2266 { 677, "Fincor Electronics" },
2267 { 678, "Cognex Corporation" },
2268 { 679, "Qualiflow" },
2269 { 680, "Weidmuller, Inc." },
2270 { 681, "Morinaga Milk Industry Co., Ltd." },
2271 { 682, "Takagi Industrial Co., Ltd." },
2272 { 683, "Wittenstein SE" },
2273 { 684, "Sena Technologies, Inc." },
2274 { 685, "Reserved" },
2275 { 686, "SPX Flow Technology Germany GmbH" },
2276 { 687, "Creator Teknisk Utvedkling AB" },
2277 { 688, "Reserved" },
2278 { 689, "Mibu Denki Industrial Co., Ltd." },
2279 { 690, "Takamastsu Machineer Section" },
2280 { 691, "Littelfuse" },
2281 { 692, "Reserved" },
2282 { 693, "Holjeron" },
2283 { 694, "Pfeiffer Vacuum SAS" },
2284 { 695, "Taesan LCD Co., Ltd." },
2287 { 698, "Matsushita Electric Works, Ltd." },
2288 { 699, "IAI Corporation" },
2289 { 700, "Horst GmbH" },
2290 { 701, "MicroControl GmbH & Co." },
2291 { 702, "Leine & Linde AB" },
2292 { 703, "Reserved" },
2293 { 704, "EC Elettronica Srl" },
2294 { 705, "VIT Software HB" },
2295 { 706, "Bronkhorst High-Tech B.V." },
2296 { 707, "Optex Co., Ltd." },
2297 { 708, "Yosio Electronic Co." },
2298 { 709, "Terasaki Electric Co., Ltd." },
2299 { 710, "Sodick Co., Ltd." },
2300 { 711, "MTS Systems Corporation-Automation Division" },
2301 { 712, "Mesa Systemtechnik" },
2302 { 713, "SHIN HO SYSTEM Co., Ltd." },
2303 { 714, "Goyo Electronics Co, Ltd." },
2305 { 716, "SAB Brockskes GmbH & Co. KG" },
2306 { 717, "Trumpf Laser GmbH" },
2307 { 718, "Niigata Electronic Instruments Co., Ltd." },
2308 { 719, "Yokogawa Digital Computer Corporation" },
2309 { 720, "O.N. Electronic Co., Ltd." },
2310 { 721, "Industrial Control Communication, Inc." },
2311 { 722, "ABB, Inc." },
2312 { 723, "ElectroWave USA, Inc." },
2313 { 724, "Industrial Network Controls, LLC" },
2314 { 725, "KDT Systems Co., Ltd." },
2315 { 726, "SEFA Technology Inc." },
2316 { 727, "Nippon POP Rivets and Fasteners Ltd." },
2317 { 728, "Yamato Scale Co., Ltd." },
2318 { 729, "Zener Electric" },
2319 { 730, "GSE Scale Systems" },
2320 { 731, "ISAS (Integrated Switchgear & Sys. Pty Ltd)" },
2321 { 732, "Beta LaserMike Limited" },
2322 { 733, "TOEI Electric Co., Ltd." },
2323 { 734, "Hakko Electronics Co., Ltd" },
2324 { 735, "Reserved" },
2325 { 736, "RFID, Inc." },
2326 { 737, "Adwin Corporation" },
2327 { 738, "Osaka Vacuum, Ltd." },
2328 { 739, "A-Kyung Motion, Inc." },
2329 { 740, "Camozzi Automation spa" },
2330 { 741, "Crevis Co., LTD" },
2331 { 742, "Rice Lake Weighing Systems" },
2332 { 743, "Linux Network Services" },
2333 { 744, "KEB Automation KG" },
2334 { 745, "Hagiwara Electric Co., Ltd." },
2335 { 746, "Glass Inc. International" },
2336 { 748, "DVT Corporation" },
2337 { 749, "Woodward Governor" },
2338 { 750, "Mosaic Systems, Inc." },
2339 { 751, "Laserline GmbH" },
2340 { 752, "COM-TEC, Inc." },
2341 { 753, "Weed Instrument" },
2342 { 754, "Prof-face European Technology Center" },
2343 { 755, "Fuji Automation Co., Ltd." },
2344 { 756, "Matsutame Co., Ltd." },
2345 { 757, "Hitachi Via Mechanics, Ltd." },
2346 { 758, "Dainippon Screen Mfg. Co. Ltd." },
2347 { 759, "FLS Automation A/S" },
2348 { 760, "ABB Stotz Kontakt GmbH" },
2349 { 761, "Technical Marine Service" },
2350 { 762, "Advanced Automation Associates, Inc." },
2351 { 763, "Baumer Ident GmbH" },
2352 { 764, "Tsubakimoto Chain Co." },
2353 { 765, "Reserved" },
2354 { 766, "Furukawa Co., Ltd." },
2355 { 767, "Active Power" },
2356 { 768, "CSIRO Mining Automation" },
2357 { 769, "Matrix Integrated Systems" },
2358 { 770, "Digitronic Automationsanlagen GmbH" },
2359 { 771, "SICK STEGMANN Inc." },
2360 { 772, "TAE-Antriebstechnik GmbH" },
2361 { 773, "Electronic Solutions" },
2362 { 774, "Rocon L.L.C." },
2363 { 775, "Dijitized Communications Inc." },
2364 { 776, "Asahi Organic Chemicals Industry Co., Ltd." },
2365 { 777, "Hodensha" },
2366 { 778, "HARTING, Inc. of North America" },
2367 { 779, "Kuebler GmbH" },
2368 { 780, "Yamatake Corporation" },
2370 { 782, "Yamatake Industrial Systems Co., Ltd." },
2371 { 783, "HAEHNE Elektronische Messgerate GmbH" },
2372 { 784, "Ci Technologies Pty Ltd (for Pelamos Industries)" },
2373 { 785, "N. SCHLUMBERGER & CIE" },
2374 { 786, "Teijin Seiki Co., Ltd." },
2375 { 787, "DAIKIN Industries, Ltd" },
2376 { 788, "RyuSyo Industrial Co., Ltd." },
2377 { 789, "SAGINOMIYA SEISAKUSHO, INC." },
2378 { 790, "Seishin Engineering Co., Ltd." },
2379 { 791, "Japan Support System Ltd." },
2381 { 793, "Metronix Messgeraete und Elektronik GmbH" },
2382 { 794, "ROPEX Industrie - Elektronik GmbH" },
2383 { 795, "Vaccon Company, Inc." },
2384 { 796, "Siemens Industry, Inc." },
2385 { 797, "Ten X Technology, Inc." },
2386 { 798, "TE Connectivity" },
2387 { 799, "Delta Electronics, Inc." },
2389 { 801, "Autonics Corporation" },
2390 { 802, "JFE Electronic Engineering Pty. Ltd." },
2391 { 803, "Reserved" },
2392 { 804, "Electro-Sensors, Inc." },
2393 { 805, "Digi International, Inc." },
2394 { 806, "Texas Instruments" },
2395 { 807, "ADTEC Plasma Technology Co., Ltd" },
2397 { 809, "Ethernet Peripherals, Inc." },
2398 { 810, "Animatics Corporation" },
2399 { 811, "Reserved" },
2400 { 812, "Process Control Corporation" },
2401 { 813, "SystemV. Inc." },
2402 { 814, "Danaher Motion SRL" },
2403 { 815, "SHINKAWA Sensor Technology, Inc." },
2404 { 816, "Tesch GmbH & Co. KG" },
2405 { 817, "Reserved" },
2406 { 818, "Trend Controls Systems Ltd." },
2407 { 819, "Guangzhou ZHIYUAN Electronic Co., Ltd." },
2408 { 820, "Mykrolis Corporation" },
2409 { 821, "Bethlehem Steel Corporation" },
2411 { 823, "Takemoto Denki Corporation" },
2412 { 824, "Montalvo Corporation" },
2413 { 825, "Reserved" },
2414 { 826, "LEONI Special Cables GmbH" },
2415 { 827, "Reserved" },
2416 { 828, "ONO SOKKI CO.,LTD." },
2417 { 829, "RS Automation Co., Ltd." },
2418 { 830, "SHINDENGEN ELECTRIC MFG. CO. LTD" },
2419 { 831, "Origin Electric Co. Ltd." },
2420 { 832, "Quest Technical Solutions, Inc." },
2421 { 833, "LS Cable" },
2422 { 834, "NORD Electronic DRIVESYSTEMS GmbH" },
2423 { 835, "Northwire Inc." },
2424 { 836, "Engel Elektroantriebe GmbH" },
2425 { 837, "The Stanley Works" },
2426 { 838, "Celesco Transducer Products, Inc." },
2427 { 839, "Chugoku Electric Wire and Cable Co." },
2428 { 840, "Kongsberg Simrad AS" },
2429 { 841, "Panduit Corporation" },
2430 { 842, "Spellman High Voltage Electronics Corp." },
2431 { 843, "Kokusai Electric Alpha Co., Ltd." },
2432 { 844, "Brooks Automation, Inc." },
2433 { 845, "ANYWIRE CORPORATION" },
2434 { 846, "Honda Electronics Co. Ltd" },
2436 { 848, "Heraeus Noblelight Fusion UV Inc." },
2437 { 849, "ASI Advanced Semiconductor Instruments GmbH" },
2438 { 850, "Datalogic, Inc." },
2439 { 851, "SoftPLC Corporation" },
2440 { 852, "Dynisco Instruments LLC" },
2442 { 854, "Teledyne LeCroy (formerly Frontline Test Equipment)" },
2443 { 855, "Tamagawa Seiki Co., Ltd." },
2444 { 856, "Multi Computing Co., Ltd." },
2446 { 858, "Commercial Timesharing Inc." },
2447 { 859, "Tennessee Rand Automation LLC" },
2448 { 860, "Wacogiken Co., Ltd" },
2449 { 861, "Reflex Integration Inc." },
2450 { 862, "Siemens AG, A&D PI Flow Instruments" },
2451 { 863, "G. Bachmann Electronic GmbH" },
2452 { 864, "Entegris, Inc." },
2453 { 865, "Schweitzer Engineering Laboratories" },
2454 { 866, "ATR Industrie-Elektronik GmbH Co." },
2455 { 867, "PLASMATECH Co., Ltd" },
2456 { 868, "Reserved" },
2457 { 869, "GEMUE GmbH & Co. KG" },
2458 { 870, "Alcorn McBride Inc." },
2459 { 871, "MORI SEIKI CO., LTD" },
2460 { 872, "NodeTech Systems Ltd" },
2461 { 873, "Emhart Teknologies" },
2462 { 874, "Cervis, Inc." },
2463 { 875, "MSA Safety" },
2464 { 876, "NEDAP Power Supplies" },
2465 { 877, "Nippon Sanso Corporation" },
2466 { 878, "Mitomi Giken Co., Ltd." },
2467 { 879, "PULS GmbH" },
2468 { 880, "Reserved" },
2469 { 881, "Japan Control Engineering Ltd" },
2470 { 882, "Embedded Systems Korea (Former Zues Emtek Co Ltd.)" },
2471 { 883, "Automa SRL" },
2472 { 884, "Harms+Wende GmbH & Co KG" },
2473 { 885, "R. STAHL" },
2474 { 886, "Microwave Data Systems" },
2475 { 887, "Bernecker + Rainer Industrie-Elektronik GmbH" },
2476 { 888, "Hiprom Technologies" },
2477 { 889, "Reserved" },
2478 { 890, "Nitta Corporation" },
2479 { 891, "Kontron Modular Computers GmbH" },
2480 { 892, "Marlin Controls" },
2481 { 893, "Elcis Encoder s.r.l." },
2482 { 894, "Acromag, Inc." },
2483 { 895, "Avery Weigh-Tronix" },
2484 { 896, "Reserved" },
2485 { 897, "Reserved" },
2486 { 899, "Practicon Ltd." },
2487 { 900, "SCHUNK GmbH & Co. KG" },
2488 { 901, "MYNAH Technologies" },
2489 { 902, "Defontaine Groupe" },
2490 { 903, "Emerson Process Management Power & Water Solutions" },
2491 { 904, "F.A. Elec" },
2492 { 905, "Hottinger Baldwin Messtechnik GmbH" },
2493 { 906, "Teledyne DALSA" },
2494 { 907, "London Electronics Ltd." },
2496 { 909, "Pepperl+Fuchs Comtrol" },
2497 { 910, "TEAM, S.A. (Tecnica Electronica de Automatismo Y Medida)" },
2498 { 911, "Regulateurs Europa Ltd" },
2499 { 912, "Reserved" },
2500 { 913, "Reserved" },
2501 { 914, "Micro Motion" },
2502 { 915, "Eckelmann AG" },
2503 { 916, "Hanyoung Nux" },
2504 { 917, "CFT Ransburg Japan KK" },
2505 { 918, "Kun Hung Electric Co. Ltd." },
2506 { 919, "Brimos wegbebakening b.v." },
2507 { 920, "NITTO SEIKO CO., LTD." },
2508 { 921, "Datasensing S.r.l." },
2509 { 922, "Yamazaki Machinery Works" },
2510 { 923, "Schmidt Technology" },
2511 { 924, "Parker Hannifin SpA (SBC Division)" },
2512 { 925, "HIMA Paul Hildebrandt GmbH" },
2513 { 926, "RivaTek, Inc." },
2514 { 927, "Misumi Corporation" },
2515 { 928, "GE Multilin" },
2516 { 929, "Measurement Computing Corporation" },
2517 { 930, "Jetter AG" },
2518 { 931, "Tokyo Electronics Systems Corporation" },
2519 { 932, "Togami Electric Mfg. Co., Ltd." },
2520 { 933, "HK Systems" },
2521 { 934, "CDA Systems Ltd." },
2522 { 935, "Aerotech Inc." },
2524 { 937, "NovaTech Process Solutions LLC" },
2525 { 938, "Reserved" },
2526 { 939, "Cisco Systems" },
2527 { 940, "Grid Connect" },
2528 { 941, "ITW Automotive Finishing" },
2529 { 942, "HanYang System" },
2530 { 943, "ABB K.K. Technical Center" },
2531 { 944, "Taiyo Cable (Dongguan) Co., Ltd." },
2532 { 945, "Reserved" },
2533 { 946, "SEREN IPS INC" },
2535 { 948, "ControlNet International" },
2536 { 949, "Gefran S.P.A." },
2537 { 950, "ABB (Jokab Safety)" },
2538 { 951, "SUMITA OPTICAL GLASS, INC." },
2539 { 952, "Biffi Italia srl" },
2540 { 953, "Beck IPC GmbH" },
2541 { 954, "Copley Controls" },
2542 { 955, "Fagor Automation S. Coop." },
2544 { 957, "Frick Controls (div. of York International)" },
2545 { 958, "SymCom, Inc." },
2546 { 959, "Infranor" },
2547 { 960, "Kyosan Electric Mfg" },
2548 { 961, "Varian Vacuum Technologies" },
2549 { 962, "Messung Systems" },
2550 { 963, "Xantrex Technology, Inc." },
2551 { 964, "StarThis Inc." },
2552 { 965, "NF Chiyoda Electronics Co., Ltd." },
2553 { 966, "Flowserve Corporation" },
2554 { 967, "Spyder Controls Corp." },
2556 { 969, "SHIMOHIRA ELECTRIC MFG.CO.,LTD" },
2557 { 970, "Reserved" },
2558 { 971, "Siemens L&A" },
2559 { 972, "Eaton Automation GmbH (formerly Micro Innovation)" },
2560 { 973, "Switchgear & Instrumentation" },
2561 { 974, "Pre-Tech Co., Ltd." },
2562 { 975, "National Semiconductor" },
2563 { 976, "Invensys Operations Management" },
2564 { 977, "Ametek HDR Power Systems" },
2565 { 978, "Reserved" },
2566 { 979, "TETRA-K Corporation" },
2567 { 980, "C&M Corporation" },
2568 { 981, "Siempelkamp Maschinen" },
2569 { 982, "Reserved" },
2570 { 983, "Daifuku Co., Ltd" },
2571 { 984, "Electro-Matic Products Inc." },
2572 { 985, "BUSSAN MICROELECTRONICS CORP." },
2574 { 987, "Hetronic USA" },
2575 { 988, "NIIGATA POWER SYSTEMS Co., Ltd." },
2576 { 989, "Software Horizons Inc." },
2577 { 990, "B3 Systems, Inc." },
2578 { 991, "Moxa, Inc." },
2579 { 992, "Reserved" },
2580 { 993, "S4 Integration" },
2581 { 994, "Elettro Stemi S.R.L." },
2582 { 995, "AquaSensors" },
2583 { 996, "Ifak System GmbH" },
2584 { 997, "SANKEI MANUFACTURING Co.,LTD." },
2585 { 998, "Emerson Network Power Co., Ltd." },
2586 { 999, "Fairmount Automation, Inc." },
2587 { 1000, "Bird Electronic Corporation" },
2588 { 1001, "Nabtesco Corporation" },
2589 { 1002, "AGM Electronics, Inc." },
2590 { 1003, "ARCX Inc." },
2591 { 1004, "DELTA I/O Co." },
2592 { 1005, "Chun IL Electric Ind. Co." },
2593 { 1006, "N-Tron Corporation, a Red Lion Company" },
2594 { 1007, "Nippon Pneumatics/Fludics System CO.,LTD." },
2595 { 1008, "DDK Ltd." },
2596 { 1009, "Seiko Epson Corporation" },
2597 { 1010, "halstrup-walcher GmbH" },
2599 { 1012, "Ground Fault Systems bv" },
2600 { 1013, "Scolari Engineering S.p.A." },
2601 { 1014, "Vialis Traffic bv" },
2602 { 1015, "Weidmueller Group" },
2603 { 1016, "Shanghai Sibotech Automation Co. Ltd" },
2604 { 1017, "AEG Power Solutions GmbH" },
2605 { 1018, "Komatsu Electronics Inc." },
2606 { 1019, "Souriau" },
2607 { 1020, "Baumuller Chicago Corp." },
2608 { 1021, "J. Schmalz GmbH" },
2609 { 1022, "SEN Corporation" },
2610 { 1023, "Korenix Technology Co. Ltd" },
2611 { 1024, "Cooper Power Tools" },
2612 { 1025, "INNOBIS" },
2613 { 1026, "Shinho System" },
2614 { 1027, "Xm Services Ltd." },
2615 { 1028, "KVC Co., Ltd." },
2616 { 1029, "Sanyu Seiki Co., Ltd." },
2618 { 1031, "Northern Network Solutions" },
2619 { 1032, "Converteam GmbH" },
2620 { 1033, "Symbol Technologies" },
2621 { 1034, "S-TEAM Lab" },
2622 { 1035, "Maguire Products, Inc." },
2624 { 1037, "MITSUBISHI HEAVY INDUSTRIES, LTD. KOBE SHIPYARD & MACHINERY WORKS" },
2625 { 1038, "Hurletron Inc." },
2626 { 1039, "Chunichi Denshi Co., Ltd" },
2627 { 1040, "Cardinal Scale Mfg. Co." },
2628 { 1041, "METZ CONNECT USA Inc." },
2630 { 1043, "ASRC Aerospace" },
2631 { 1044, "Beijing Stone Automation" },
2632 { 1045, "Changshu Switchgear Manufacture Ltd." },
2633 { 1046, "METRONIX Corp." },
2635 { 1048, "ORMEC Systems Corp." },
2636 { 1049, "ASATech (China) Inc." },
2637 { 1050, "Controlled Systems Limited" },
2638 { 1051, "Mitsubishi Heavy Ind. Digital System Co., Ltd. (M.H.I.)" },
2639 { 1052, "Electrogrip" },
2640 { 1053, "TDS Automation" },
2641 { 1054, "T&C Power Conversion, Inc." },
2642 { 1055, "Robostar Co., Ltd" },
2643 { 1056, "Scancon A/S" },
2644 { 1057, "Haas Automation, Inc." },
2645 { 1058, "Eshed Technology" },
2646 { 1059, "Delta Electronic Inc." },
2647 { 1060, "Innovasic" },
2648 { 1061, "SoftDEL Systems Limited" },
2649 { 1062, "FiberFin, Inc." },
2650 { 1063, "Nicollet Technologies Corp." },
2651 { 1064, "B.F. Systems" },
2652 { 1065, "Empire Wire and Supply LLC" },
2653 { 1066, "ENDO KOGYO CO., LTD" },
2654 { 1067, "Elmo Motion Control LTD" },
2655 { 1068, "Reserved" },
2656 { 1069, "Asahi Keiki Co., Ltd." },
2657 { 1070, "Joy Mining Machinery" },
2658 { 1071, "MPM Engineering Ltd." },
2659 { 1072, "Wolke Inks & Printers GmbH" },
2660 { 1073, "Mitsubishi Electric Engineering Co., Ltd." },
2661 { 1074, "COMET AG" },
2662 { 1075, "Real Time Objects & Systems, LLC" },
2663 { 1076, "MISCO Refractometer" },
2664 { 1077, "JT Engineering Inc." },
2665 { 1078, "Automated Packing Systems" },
2666 { 1079, "Niobrara R&D Corp." },
2667 { 1080, "Garmin Ltd." },
2668 { 1081, "Japan Mobile Platform Co., Ltd" },
2669 { 1082, "Advosol Inc." },
2670 { 1083, "ABB Global Services Limited" },
2671 { 1084, "Sciemetric Instruments Inc." },
2672 { 1085, "Tata Elxsi Ltd." },
2673 { 1086, "Mechatronics Co.,Ltd" },
2674 { 1087, "Cooper Bussmann" },
2675 { 1088, "Trinite Automatisering B.V." },
2676 { 1089, "Peek Traffic B.V." },
2677 { 1090, "Acrison, Inc." },
2678 { 1091, "Applied Robotics, Inc." },
2679 { 1092, "FireBus LLC" },
2680 { 1093, "Sevenstar" },
2681 { 1094, "Magnetek" },
2682 { 1095, "Omron Microscan Systems, Inc." },
2683 { 1096, "Air Water Inc." },
2684 { 1097, "SensoPart Industriesensorik GmbH" },
2685 { 1098, "Tiefenbach Control Systems GmbH" },
2686 { 1099, "INOXPA S.A" },
2687 { 1100, "Zurich University of Applied Sciences" },
2688 { 1101, "Ethernet Direct" },
2689 { 1102, "GSI-Micro-E Systems" },
2690 { 1103, "S-Net Automation Co., Ltd." },
2691 { 1104, "Power Electronics S.L." },
2692 { 1105, "Renesas Electronics" },
2693 { 1106, "NSWCCD-SSES" },
2694 { 1107, "Porter Engineering Ltd." },
2695 { 1108, "Meggitt Airdynamics, Inc." },
2696 { 1109, "Inductive Automation" },
2697 { 1110, "Neural ID" },
2698 { 1111, "EEPod LLC" },
2699 { 1112, "Hitachi Industrial Equipment Systems Co.,Ltd." },
2700 { 1113, "Salem Automation" },
2701 { 1114, "port GmbH" },
2702 { 1115, "B & PLUS" },
2703 { 1116, "Graco Inc." },
2704 { 1117, "Altera Corporation" },
2705 { 1118, "Technology Brewing Corporation" },
2706 { 1119, "Reserved" },
2707 { 1120, "Reserved" },
2708 { 1121, "CSE Servelec" },
2709 { 1122, "Reserved" },
2710 { 1123, "Reserved" },
2711 { 1124, "Fluke Networks" },
2712 { 1125, "Tetra Pak Packaging Solutions SpA" },
2713 { 1126, "Racine Federated, Inc." },
2714 { 1127, "Pureron Japan Co., Ltd." },
2715 { 1128, "Reserved" },
2716 { 1129, "Reserved" },
2717 { 1130, "Brother Industries, Ltd." },
2718 { 1131, "Reserved" },
2719 { 1132, "Leroy Automation" },
2720 { 1133, "Reserved" },
2721 { 1134, "THK Co., Ltd." },
2722 { 1135, "Reserved" },
2723 { 1136, "Reserved" },
2724 { 1137, "TR-Electronic GmbH" },
2725 { 1138, "ASCON S.p.A." },
2726 { 1139, "Toledo do Brasil Industria de Balancas Ltda." },
2727 { 1140, "Caterpillar Global Mining Europe GmbH" },
2728 { 1141, "Emerson Process Management Valve Automation" },
2729 { 1142, "Alstom Transport" },
2730 { 1143, "Reserved" },
2731 { 1144, "Matrox Electronic Systems" },
2732 { 1145, "Littelfuse" },
2733 { 1146, "PLASMART, Inc." },
2734 { 1147, "Miyachi Corporation" },
2735 { 1148, "Reserved" },
2736 { 1149, "Reserved" },
2737 { 1150, "Promess Incorporated" },
2738 { 1151, "COPA-DATA GmbH" },
2739 { 1152, "Precision Engine Controls Corporation" },
2740 { 1153, "Alga Automacao e controle LTDA" },
2741 { 1154, "Lapp Group" },
2743 { 1156, "Philips Lighting bv" },
2744 { 1157, "Aseptomag AG" },
2745 { 1158, "ARC Informatique" },
2746 { 1159, "Hesmor GmbH" },
2747 { 1160, "Kobe Steel, Ltd." },
2748 { 1161, "FLIR Systems" },
2749 { 1162, "Xcelgo A/S" },
2750 { 1163, "STRATON AUTOMATION" },
2751 { 1164, "Zypcom, Inc." },
2752 { 1165, "Swagelok" },
2754 { 1167, "ITT Water & Wastewater AB" },
2755 { 1168, "Kunbus GmbH Industrial Communication" },
2756 { 1169, "Reserved" },
2757 { 1170, "Performance Controls, Inc." },
2758 { 1171, "ACS Motion Control, Ltd." },
2759 { 1172, "Reserved" },
2760 { 1173, "IStar Technology Limited" },
2761 { 1174, "Alicat Scientific, Inc." },
2762 { 1175, "Reserved" },
2763 { 1176, "ADFweb.com SRL" },
2764 { 1177, "Tata Consultancy Services Limited" },
2765 { 1178, "CXR Ltd." },
2766 { 1179, "Vishay Nobel AB" },
2767 { 1180, "Reserved" },
2768 { 1181, "Emerson - SolaHD" },
2769 { 1182, "Endress+Hauser" },
2770 { 1183, "Bartec GmbH" },
2771 { 1184, "Reserved" },
2772 { 1185, "AccuSentry, Inc." },
2773 { 1186, "Curtiss Wright - Exlar Actuator Solutions" },
2774 { 1187, "ILS Technology" },
2775 { 1188, "Control Concepts, Inc." },
2776 { 1189, "Reserved" },
2777 { 1190, "Procon Engineering A Division of National Oilwell Varco UK Ltd" },
2778 { 1191, "Hermary" },
2779 { 1192, "Q-Lambda" },
2780 { 1193, "Reserved" },
2781 { 1194, "VAMP Ltd" },
2782 { 1195, "FlexLink" },
2783 { 1196, "Office FA.com Co., Ltd." },
2784 { 1197, "SPMC (Changzhou) Co. Ltd." },
2785 { 1198, "Anton Paar GmbH" },
2786 { 1199, "Zhuzhou CSR Times Electric Co., Ltd." },
2787 { 1200, "DeStaCo" },
2788 { 1201, "Synrad, Inc" },
2789 { 1202, "Bonfiglioli Vectron GmbH" },
2790 { 1203, "Pivotal Systems" },
2792 { 1205, "Randy Nuernberger" },
2793 { 1206, "CENTRALP" },
2794 { 1207, "Tengen Group" },
2795 { 1208, "OES, Inc." },
2796 { 1209, "Actel Corporation" },
2797 { 1210, "Monaghan Engineering, Inc." },
2798 { 1211, "wenglor sensoric gmbh" },
2799 { 1212, "HSA Systems" },
2800 { 1213, "MKP Co., Ltd." },
2801 { 1214, "Tappan Wire and Cable" },
2802 { 1215, "Heinzmann GmbH & Co. KG" },
2803 { 1216, "Process Automation International Ltd." },
2804 { 1217, "Secure Crossing" },
2805 { 1218, "SMA Railway Technology GmbH" },
2806 { 1219, "FMS Force Measuring Systems AG" },
2807 { 1220, "ABT Endustri Enerji Sistemleri Sanayi Tic. Ltd. Sti." },
2808 { 1221, "MagneMotion Inc." },
2809 { 1222, "STS Co., Ltd." },
2810 { 1223, "Knorr-Bremse Espana, S.A. - Merak Division" },
2811 { 1224, "ABOUNDI, Inc." },
2812 { 1225, "Rosemount Inc." },
2813 { 1226, "GEA FES, Inc." },
2814 { 1227, "TMG Technologie und Engineering GmbH" },
2815 { 1228, "embeX GmbH" },
2816 { 1229, "GH Electrotermia, S.A." },
2817 { 1230, "Tolomatic" },
2819 { 1232, "Elco (Tian Jin) Electronics Co., Ltd." },
2820 { 1233, "Jacobs Automation" },
2821 { 1234, "Noda Radio Frequency Technologies Co., Ltd." },
2822 { 1235, "MSC Tuttlingen GmbH" },
2823 { 1236, "Hitachi Cable Manchester" },
2824 { 1237, "ACOREL SAS" },
2825 { 1238, "Global Engineering Solutions Co., Ltd." },
2826 { 1239, "ALTE Transportation, S.L." },
2827 { 1240, "Penko Engineering B.V." },
2828 { 1241, "Z-Tec Automation Systems Inc." },
2829 { 1242, "ENTRON Controls LLC" },
2830 { 1243, "Johannes Huebner Fabrik Elektrischer Maschinen GmbH" },
2831 { 1244, "RF IDeas, Inc." },
2832 { 1245, "Pentronic AB" },
2833 { 1246, "Atlas Copco IAS GmbH" },
2834 { 1247, "TDK-Lambda Corporation" },
2835 { 1248, "Reserved" },
2836 { 1249, "Reserved" },
2837 { 1250, "Altronic LLC" },
2838 { 1251, "Siemens AG" },
2839 { 1252, "Liebherr Transportation Systems GmbH & Co KG" },
2840 { 1253, "Reserved" },
2841 { 1254, "Reserved" },
2842 { 1255, "Reserved" },
2843 { 1256, "LMI Technologies" },
2844 { 1257, "Reserved" },
2845 { 1258, "Reserved" },
2846 { 1259, "Reserved" },
2847 { 1260, "Reserved" },
2848 { 1261, "CEPHALOS Automatisierung mbH" },
2849 { 1262, "Reserved" },
2850 { 1263, "Reserved" },
2851 { 1264, "Reserved" },
2852 { 1265, "Quabbin Wire & Cable Co., Inc." },
2853 { 1266, "Reserved" },
2854 { 1267, "Reserved" },
2855 { 1268, "HORIBA Precision Instruments (Beijing) Co.,Ltd." },
2856 { 1269, "Reserved" },
2857 { 1270, "Rovema GmbH" },
2858 { 1271, "Reserved" },
2859 { 1272, "IEP GmbH" },
2860 { 1273, "Reserved" },
2861 { 1274, "Reserved" },
2862 { 1275, "Reserved" },
2863 { 1276, "Reserved" },
2864 { 1277, "Control Chief Corporation" },
2865 { 1278, "Reserved" },
2866 { 1279, "Reserved" },
2867 { 1280, "Reserved" },
2868 { 1281, "Reserved" },
2869 { 1282, "PRIMES GmbH" },
2870 { 1283, "Branson Ultrasonics" },
2871 { 1284, "DEIF A/S" },
2872 { 1285, "CODESYS GmbH" },
2873 { 1286, "Reserved" },
2874 { 1287, "Smarteye Corporation" },
2875 { 1288, "Shibaura Machine" },
2876 { 1289, "HMS/BU Ewon" },
2879 { 1292, "Reserved" },
2880 { 1293, "Reserved" },
2881 { 1294, "Reserved" },
2882 { 1295, "Kistler Instrumente AG" },
2883 { 1296, "Reserved" },
2884 { 1297, "Reserved" },
2885 { 1298, "Reserved" },
2886 { 1299, "Reserved" },
2887 { 1300, "Reserved" },
2888 { 1301, "Xylem Analytics Germany GmbH" },
2889 { 1302, "Lenord, Bauer & Co. GmbH" },
2890 { 1303, "Carlo Gavazzi Controls" },
2891 { 1304, "Faiveley Transport" },
2892 { 1305, "Reserved" },
2893 { 1306, "Sensia LLC" },
2894 { 1307, "Kepware Technologies" },
2895 { 1308, "duagon AG" },
2896 { 1309, "Reserved" },
2897 { 1310, "Xylem Water Solutions" },
2898 { 1311, "Automation Professionals, LLC" },
2899 { 1312, "Reserved" },
2900 { 1313, "CEIA SpA" },
2901 { 1314, "Reserved" },
2902 { 1315, "Alphagate Automatisierungstechnik GmbH" },
2903 { 1316, "Mecco Partners, LLC" },
2904 { 1317, "LAP GmbH Laser Applikationen" },
2905 { 1318, "ABB S.p.A. - SACE Division" },
2906 { 1319, "Reserved" },
2907 { 1320, "Reserved" },
2908 { 1321, "C.E. Electronics, Inc." },
2909 { 1322, "Thermo Ramsey Inc., a part of Thermo Fisher Scientific" },
2910 { 1323, "Helmholz GmbH & Co. KG" },
2911 { 1324, "EUCHNER GmbH + Co. KG" },
2912 { 1325, "AMKmotion" },
2913 { 1326, "Badger Meter" },
2914 { 1327, "Reserved" },
2915 { 1328, "Fisher-Rosemount Systems, Inc. doing business as Process Systems & Solutions" },
2916 { 1329, "Conductix-Wampfler Automation GmbH" },
2917 { 1330, "Fairbanks Scales, Inc." },
2918 { 1331, "Imperx, Inc." },
2919 { 1332, "FRONIUS International GmbH" },
2920 { 1333, "Hoffman Enclosures" },
2921 { 1334, "Elecsys Corporation" },
2922 { 1335, "Reserved" },
2923 { 1336, "RACO Manufacturing and Engineering" },
2924 { 1337, "Hein Lanz Industrial Tech." },
2925 { 1338, "Codenomicon" },
2926 { 1339, "SABO Elektronik GmbH" },
2927 { 1340, "Reserved" },
2928 { 1341, "Sensirion AG" },
2929 { 1342, "SIKO GmbH" },
2930 { 1343, "Reserved" },
2931 { 1344, "GRUNDFOS" },
2932 { 1345, "Reserved" },
2933 { 1346, "Beijer Electronics Products AB" },
2934 { 1347, "Reserved" },
2936 { 1349, "Reserved" },
2938 { 1351, "Powell Industries" },
2939 { 1352, "Reserved" },
2940 { 1353, "IPDisplays" },
2941 { 1354, "SCAIME SAS" },
2942 { 1355, "Metal Work SpA" },
2943 { 1356, "Telsonic AG" },
2944 { 1357, "Reserved" },
2945 { 1358, "Hauch & Bach ApS" },
2946 { 1359, "Pago AG" },
2947 { 1360, "ULTIMATE Europe Transportation Equipment GmbH" },
2948 { 1361, "Reserved" },
2949 { 1362, "FW Murphy Production Controls, LLC" },
2950 { 1363, "Lake Cable LLC" },
2951 { 1364, "Reserved" },
2952 { 1365, "Reserved" },
2953 { 1366, "Reserved" },
2954 { 1367, "Reserved" },
2955 { 1368, "Nanotec Electronic GmbH & Co. KG" },
2956 { 1369, "SAMWON ACT Co., Ltd." },
2957 { 1370, "Aparian Inc." },
2958 { 1371, "Cosys Inc." },
2959 { 1372, "Insight Automation Inc." },
2960 { 1373, "Reserved" },
2961 { 1374, "FASTECH" },
2962 { 1375, "K.A. Schmersal GmbH & Co. KG" },
2963 { 1376, "Reserved" },
2964 { 1377, "Reserved" },
2965 { 1378, "SEIDENSHA ELECTRONICS CO., LTD" },
2966 { 1379, "Reserved" },
2967 { 1380, "Don Electronics Ltd" },
2968 { 1381, "burster gmbh & co kg" },
2969 { 1382, "Unitronics (1989) (RG) LTD" },
2970 { 1383, "OEM Technology Solutions" },
2971 { 1384, "Allied Motion" },
2972 { 1385, "Reserved" },
2973 { 1386, "DENGENSHA TOA CO., LTD" },
2974 { 1387, "Systec Systemtechnik und Industrieautomation GmbH" },
2975 { 1388, "Reserved" },
2976 { 1389, "Jenny Science AG" },
2977 { 1390, "Baumer Optronic GmbH" },
2978 { 1391, "Invertek Drives Ltd" },
2979 { 1392, "High Grade Controls Corporation" },
2980 { 1393, "Reserved" },
2981 { 1394, "Reserved" },
2982 { 1395, "Reserved" },
2983 { 1396, "Actia Systems" },
2984 { 1397, "Reserved" },
2985 { 1398, "Beijing Tianma Intelligent Control Technology Co., Ltd" },
2986 { 1399, "Universal Robots A/S" },
2987 { 1400, "Reserved" },
2988 { 1401, "Dialight" },
2989 { 1402, "E-T-A Elektrotechnische Apparate GmbH" },
2990 { 1403, "Kemppi Oy" },
2991 { 1404, "Reserved" },
2992 { 1405, "ORing Industrial Networking Corp." },
2993 { 1406, "Reserved" },
2994 { 1407, "Reserved" },
2995 { 1408, "ELAP S.R.L." },
2996 { 1409, "Applied Mining Technologies" },
2997 { 1410, "KITZ SCT Corporation" },
2998 { 1411, "VTEX Corporation" },
2999 { 1412, "ESYSE GmbH Embedded Systems Engineering" },
3000 { 1413, "Automation Controls" },
3001 { 1414, "Reserved" },
3002 { 1415, "Cincinnati Test Systems" },
3003 { 1416, "Reserved" },
3004 { 1417, "Zumbach Electronics Corp." },
3005 { 1418, "Emerson Automation Solutions" },
3006 { 1419, "CCS Inc." },
3007 { 1420, "Videojet, Inc." },
3008 { 1421, "Zebra Technologies" },
3009 { 1422, "ANRITSU CORPORATION" },
3010 { 1423, "Dimetix AG" },
3011 { 1424, "General Measure (China)" },
3012 { 1425, "Fortress Interlocks" },
3013 { 1426, "Reserved" },
3014 { 1427, "Task Force Tips" },
3015 { 1428, "SERVO-ROBOT INC." },
3016 { 1429, "Flow Devices and Systems, Inc." },
3017 { 1430, "nLIGHT, Inc." },
3018 { 1431, "Microchip Technology Inc." },
3019 { 1432, "Reserved" },
3020 { 1433, "Reserved" },
3021 { 1434, "Accutron Instruments Inc." },
3022 { 1435, "Kaeser Kompressoren SE" },
3023 { 1436, "Reserved" },
3024 { 1437, "Coherix, Inc." },
3025 { 1438, "FLSmidth A/S" },
3026 { 1439, "Reserved" },
3027 { 1440, "Cole-Parmer Instrument Company" },
3028 { 1441, "Wachendorff Automation GmbH & Co., KG" },
3029 { 1442, "SMAC Moving Coil Actuators" },
3030 { 1444, "PushCorp, Inc." },
3031 { 1445, "Fluke Process Instruments GmbH" },
3032 { 1446, "Mini Motor S.p.a" },
3033 { 1447, "I-CON Industry Tech." },
3034 { 1448, "Grace Technologies" },
3035 { 1449, "Zaxis Inc." },
3036 { 1450, "Lumasense Technologies" },
3037 { 1451, "Domino Printing" },
3038 { 1452, "Reserved" },
3039 { 1453, "Reserved" },
3040 { 1454, "Altus Sistemas de Automação S.A." },
3041 { 1455, "Reserved" },
3042 { 1456, "InterTech Development Company" },
3043 { 1457, "Reserved" },
3044 { 1458, "Perle Systems Limited" },
3045 { 1459, "Utthunga Technologies Pvt Ltd.," },
3046 { 1460, "Reserved" },
3047 { 1461, "WIPOTEC GmbH" },
3048 { 1462, "Atos spa" },
3049 { 1463, "Solartron Metrology LTD" },
3050 { 1464, "Reserved" },
3051 { 1465, "Analog Devices" },
3052 { 1466, "Power Electronics International, Inc." },
3053 { 1468, "Campbell Wrapper Corporation" },
3054 { 1469, "Herkules-Resotec Elektronik GmbH" },
3055 { 1470, "aignep spa" },
3056 { 1471, "Reserved" },
3057 { 1472, "PMV Automation AB" },
3058 { 1473, "Reserved" },
3059 { 1474, "ProTec Dynatronix LLC dba Dynatronix" },
3060 { 1475, "Reserved" },
3061 { 1476, "Bitronics, LLC." },
3062 { 1477, "Delta Tau Data Systems" },
3063 { 1478, "Reserved" },
3064 { 1479, "AUTOSOL" },
3065 { 1480, "ADB Safegate" },
3066 { 1481, "Reserved" },
3067 { 1482, "Reserved" },
3068 { 1483, "Artis GmbH" },
3069 { 1484, "REJ Co., LTD" },
3070 { 1485, "Vanderlande" },
3071 { 1486, "Packet Power" },
3072 { 1487, "ima-tec gmbh" },
3073 { 1488, "Vision Automation A/S" },
3074 { 1489, "PROCENTEC BV" },
3075 { 1490, "HETRONIK GmbH" },
3076 { 1491, "Lanmark Controls Inc." },
3077 { 1492, "Reserved" },
3078 { 1493, "flexlog GmbH" },
3079 { 1494, "YUCHANGTECH" },
3080 { 1495, "Dynapower Company" },
3081 { 1496, "TAKIKAWA ENGINEERING" },
3082 { 1497, "Ingersoll Rand" },
3083 { 1498, "ASA-RT s.r.l" },
3084 { 1499, "TRUMPF Schweiz AG" },
3085 { 1500, "Reserved" },
3086 { 1501, "Rinstrum" },
3087 { 1502, "Reserved" },
3088 { 1503, "Reserved" },
3089 { 1504, "BlueBotics SA" },
3090 { 1505, "Dynapar Corporation" },
3091 { 1506, "Blum-Novotest" },
3093 { 1508, "Dalian SeaSky Automation Co., ltd" },
3094 { 1509, "Rethink Robotics GmbH" },
3095 { 1510, "Ingeteam Power Technology S. A." },
3096 { 1511, "TOSEI ENGINEERING CORP." },
3097 { 1512, "SAMSON AG" },
3098 { 1513, "TGW Mechanics GmbH" },
3099 { 1514, "Diatrend Corporation" },
3100 { 1515, "Reserved" },
3101 { 1516, "VAHLE Automation GmbH" },
3102 { 1517, "JSL Technology Co.,Ltd." },
3103 { 1518, "NetTechnix E&P GmbH" },
3104 { 1519, "Reserved" },
3105 { 1520, "Tecweigh" },
3106 { 1521, "IVEK Corporation" },
3107 { 1522, "Reserved" },
3108 { 1523, "AQ M-TECH AB" },
3109 { 1524, "Rexnord Industries LLC" },
3110 { 1525, "Reserved" },
3111 { 1526, "OPTEX FA Co., Ltd" },
3112 { 1527, "Volktek Corporation" },
3113 { 1528, "INGENIA" },
3114 { 1529, "Reserved" },
3115 { 1530, "Analytical Technology, Inc." },
3116 { 1531, "Columbus McKinnon Corporation" },
3117 { 1532, "HBC-radiomatic GmbH" },
3118 { 1533, "Leonton Technologies" },
3119 { 1534, "Mitsubishi Electric India Pvt. Ltd." },
3120 { 1535, "FOBA Laser, ALLTEC GmbH" },
3121 { 1536, "Leakmaster Inc" },
3122 { 1537, "Buhler AG" },
3123 { 1538, "LINAK Denmark A/S" },
3124 { 1539, "Reserved" },
3125 { 1540, "SIEB & MEYER AG" },
3126 { 1541, "Reserved" },
3127 { 1542, "Watson-Marlow Ltd" },
3128 { 1543, "ABB Switzerland Ltd - Low Voltage Products" },
3129 { 1544, "Reserved" },
3131 { 1546, "Hangzhou Hikrobot Technology Co., Ltd." },
3132 { 1547, "TOSS GmbH & Co. KG" },
3133 { 1548, "Solar Turbines Incorporated" },
3134 { 1549, "Reserved" },
3135 { 1550, "Reserved" },
3136 { 1551, "Carlo Gavazzi Industri" },
3137 { 1552, "Nippon Gear" },
3138 { 1553, "OSIsoft, LLC" },
3139 { 1554, "Rinco Ultrasonics AG" },
3140 { 1555, "Reserved" },
3141 { 1556, "Reserved" },
3142 { 1557, "Mitutoyo" },
3144 { 1559, "Micro-Epsilon Messtechnik GmbH & Co. KG" },
3145 { 1560, "AMADA MIYACHI AMERICA" },
3146 { 1561, "Taihan Electric Wire Co., Ltd." },
3147 { 1562, "JANOME Corporation" },
3149 { 1564, "NAKANISHI INC." },
3150 { 1565, "Mecademic Inc." },
3151 { 1566, "Reserved" },
3152 { 1567, "Sigma (NSW) PTY LTD" },
3153 { 1568, "Hammond Power Solutions Inc.-Mesta" },
3154 { 1569, "Reserved" },
3155 { 1570, "Reserved" },
3156 { 1571, "TRIDIMEO" },
3157 { 1572, "Motortronics UK Ltd." },
3158 { 1573, "Doosan Robotics" },
3159 { 1574, "ADVANCED Motion Controls" },
3160 { 1575, "OnRobot A/S" },
3161 { 1576, "Reserved" },
3162 { 1577, "Oetiker" },
3163 { 1578, "SICK OPTEX" },
3164 { 1579, "Reserved" },
3165 { 1580, "Reserved" },
3166 { 1581, "Kahler Automation Corporation" },
3167 { 1582, "Accuenergy (Canada) Inc." },
3168 { 1583, "TCI, LLC - An Allied Motion Company" },
3169 { 1584, "Sun Automation" },
3170 { 1585, "READY Robotics Corporation" },
3171 { 1586, "PEM, Power Eng & Mfg., Inc" },
3172 { 1587, "Dürr Somac GmbH" },
3173 { 1588, "Reserved" },
3174 { 1589, "Reserved" },
3175 { 1590, "Reserved" },
3176 { 1591, "RICOH Industrial Solutions Inc." },
3177 { 1592, "Shanghai Junqian Sensing Technology Co. Ltd." },
3178 { 1593, "Knick Elektronische Messgeräte GmbH & Co. KG" },
3179 { 1594, "Magnescale. Co., Ltd." },
3180 { 1595, "Reserved" },
3181 { 1596, "Weintek Labs., Inc" },
3182 { 1597, "Sherpa, Inc." },
3183 { 1598, "Inspekto A.M.V LTD" },
3184 { 1599, "Hydronix Ltd" },
3185 { 1600, "AIOI- SYSTEMS CO. LTD." },
3186 { 1601, "Ingenieurbüro Mewes & Partner GmbH" },
3187 { 1602, "HIGHYAG Lasertechnologie GmbH" },
3188 { 1603, "Ningbo Jetron Technology Co. Ltd." },
3189 { 1604, "Myostat Motion Control" },
3190 { 1605, "A-T Controls, Inc" },
3191 { 1606, "M2M craft Co., Ltd." },
3192 { 1607, "FUTEK Advanced Sensor Technology, Inc." },
3194 { 1609, "Norgren Manufacturing Co., Ltd." },
3195 { 1610, "Bernstein AG" },
3196 { 1611, "Hitachi Industrial Products, Ltd." },
3197 { 1612, "Reserved" },
3198 { 1613, "Duplomatic MS spa" },
3199 { 1614, "Ambrit Ltd" },
3200 { 1615, "Highlight Tech Corp." },
3201 { 1616, "New Power Plasma Co. Ltd." },
3202 { 1617, "AGCO Corporation" },
3203 { 1618, "Techman Robot" },
3204 { 1619, "Nabeya Bi-tech Kaisha" },
3205 { 1620, "Reserved" },
3206 { 1621, "Panasonic Corporation / Electric Works Company" },
3208 { 1623, "Janasi Industries Ltd." },
3209 { 1624, "Haffmans BV" },
3210 { 1625, "Reserved" },
3211 { 1626, "Omniview Pty Ltd" },
3212 { 1627, "Reserved" },
3213 { 1628, "Dover Flexo Electronics" },
3214 { 1629, "Reserved" },
3215 { 1630, "IDEM Safety Switches" },
3216 { 1631, "Sonotroagel GmbH" },
3217 { 1632, "Thermo Gamma-Metrics LLC, a part of Thermo Fisher Scientific" },
3218 { 1633, "BBH Products" },
3219 { 1634, "RSI Elektrotechnik" },
3220 { 1635, "Carlo Gavazzi Ltd" },
3221 { 1636, "KOFLOC Corp." },
3222 { 1637, "VTScada by Trihedral" },
3224 { 1639, "Cogniac" },
3225 { 1640, "Toshiba Infrastructure Systems & Solutions Corporation" },
3226 { 1641, "Cannon-Automata" },
3227 { 1642, "Rosenberger" },
3228 { 1643, "Blue-White Industries" },
3229 { 1644, "Cellumation GmbH" },
3230 { 1645, "TEAC Corp." },
3231 { 1646, "AEG Identifikationssysteme GmbH" },
3232 { 1647, "MARS TOHKEN SOLUTION CO.LTD." },
3233 { 1648, "Midas Technology Corp." },
3234 { 1649, "Dinkle Enterprise Co., Ltd." },
3236 { 1651, "Dunkermotoren" },
3237 { 1652, "SONOTEC GmbH" },
3238 { 1653, "Brinkmann Pumpen" },
3239 { 1654, "Rheonics" },
3240 { 1655, "Precimeter" },
3241 { 1656, "Reserved" },
3242 { 1657, "ALGO SYSTEM CO., LTD." },
3243 { 1658, "Christ Electronic Systems GmbH" },
3244 { 1659, "JFcontrol Co., Ltd." },
3245 { 1660, "Shenzhen Inovance Technology Co., Ltd" },
3246 { 1661, "Rheonik Coriolis Mass Flow Sensors" },
3247 { 1662, "Ichor Systems, Inc." },
3248 { 1663, "di-soric GmbH & Co. KG" },
3249 { 1664, "Amphenol ICC" },
3250 { 1665, "Ningbo AirTAC Automation Industrial Co., Ltd." },
3252 { 1667, "Soft Robotics Inc." },
3253 { 1668, "MUSCLE CORPORATION" },
3254 { 1669, "Spotlight Systems LLC" },
3255 { 1670, "Afag Holding AG" },
3256 { 1671, "TELESIS TECHNOLOGIES INC" },
3257 { 1672, "SSI Schaefer Automation GmbH" },
3258 { 1673, "Super Systems, Inc." },
3259 { 1674, "CoreTigo LTD" },
3260 { 1675, "Inxpect SPA" },
3261 { 1676, "Kostal Industrie Elektrik GmbH" },
3262 { 1677, "JingQi (Tianjin) technology Co.,Ltd" },
3263 { 1678, "AGI Suretrack" },
3264 { 1679, "JAKA Robotics Co., Ltd." },
3265 { 1680, "Polarteknik Oy" },
3266 { 1681, "RoboteQ, Inc" },
3268 { 1683, "Opt Machine Vision Tech Co., Ltd" },
3269 { 1684, "Asyril SA" },
3270 { 1685, "Georg Fischer Piping Systems" },
3271 { 1686, "Aber Instruments Ltd" },
3272 { 1687, "CodeWrights GmbH" },
3273 { 1688, "Neurala, Inc." },
3274 { 1689, "Panasonic Software Development Center Dalian Co.,Ltd." },
3275 { 1690, "Perinet GmbH" },
3276 { 1691, "MS Ultraschall Technologie GmbH" },
3277 { 1692, "PLASUS GmbH" },
3278 { 1693, "Nikon Corporation" },
3279 { 1694, "Shenzhen Hengzhiyuan Technology Corporation Ltd." },
3280 { 1695, "Kowa Optronics Co., Ltd." },
3281 { 1696, "Specialist Mechanical Engineers" },
3282 { 1697, "CMD Corporation" },
3283 { 1698, "Sanwa Engineering Corp." },
3284 { 1699, "Intellore Systems Pvt. Ltd" },
3285 { 1700, "Toledo e Souza" },
3286 { 1701, "PBS Biotech, Inc" },
3287 { 1702, "PLANET Technology Corporation" },
3288 { 1703, "Robatech AG" },
3289 { 1704, "MARKEM-IMAJE" },
3290 { 1705, "Novanta IMS" },
3291 { 1706, "Bamboo-Dynamics" },
3292 { 1707, "FACTS Engineering, LLC" },
3293 { 1708, "Digital Dynamics" },
3294 { 1709, "Fatek Automation Corporation" },
3297 { 1712, "Zhejiang Eternal Automation Sci-Tec Co.,Ltd" },
3298 { 1713, "KYOWA ELECTRONIC INSTRUMENTS CO.,LTD." },
3299 { 1714, "Vaisala Oyj" },
3300 { 1715, "Hennecke GmbH" },
3301 { 1716, "Encoder Products Company" },
3302 { 1717, "Converting Equipment International (dba CEI)" },
3303 { 1718, "Reserved" },
3305 { 1720, "The Poling Group, Inc." },
3306 { 1721, "plating electronic GmbH" },
3307 { 1722, "HIWIN MIKROSYSTEM CORP." },
3308 { 1723, "Wuxi Xinje Electric Co.,Ltd." },
3309 { 1724, "ViSCO Technologies Corporation" },
3310 { 1725, "MinebeaMitsumi Inc." },
3311 { 1726, "FIAtec GmbH" },
3312 { 1727, "eSOL Co.,Ltd" },
3313 { 1728, "NTN TECHNICAL SERVICE" },
3314 { 1729, "Shanghai Flexem" },
3315 { 1730, "Magswitch" },
3316 { 1731, "VEGA Grieshaber KG" },
3317 { 1732, "H.D.T. S.R.L." },
3318 { 1733, "Tool-Temp AG" },
3319 { 1734, "Hollysys Technology Group Co., Ltd" },
3320 { 1735, "Basler Electric Company" },
3321 { 1736, "Shinwa Controls Co.,Ltd" },
3322 { 1737, "Nanjing Decowell Automation Co.,Ltd." },
3323 { 1738, "Reverity Inc" },
3324 { 1739, "TOSHIBA MITSUBISHI-ELECTRIC INDUSTRIAL SYSTEMS CORPORATION" },
3325 { 1740, "BizLink Special Cables Germany GmbH" },
3326 { 1741, "Electronics Inc." },
3327 { 1742, "Inexbot" },
3328 { 1743, "Mujin, Inc." },
3329 { 1744, "Shanghai AYAN Industry System Co., Ltd" },
3330 { 1745, "EKE-Electronics Ltd." },
3331 { 1746, "Bizerba SE & Co. KG" },
3332 { 1747, "Astrodyne TDI" },
3338 value_string_ext cip_vendor_vals_ext
= VALUE_STRING_EXT_INIT(cip_vendor_vals
);
3340 /* Translate Device Profile's */
3341 static const value_string cip_devtype_vals
[] = {
3342 { 0x00, "Generic Device (deprecated)" },
3343 { 0x02, "AC Drive" },
3344 { 0x03, "Motor Overload" },
3345 { 0x04, "Limit Switch" },
3346 { 0x05, "Inductive Proximity Switch" },
3347 { 0x06, "Photoelectric Sensor" },
3348 { 0x07, "General Purpose Discrete I/O" },
3349 { 0x09, "Resolver" },
3350 { 0x0C, "Communications Adapter" },
3351 { 0x0E, "Programmable Logic Controller" },
3352 { 0x10, "Position Controller", },
3353 { 0x13, "DC Drive" },
3354 { 0x15, "Contactor", },
3355 { 0x16, "Motor Starter", },
3356 { 0x17, "Soft Start", },
3357 { 0x18, "Human-Machine Interface" },
3358 { 0x1A, "Mass Flow Controller" },
3359 { 0x1B, "Pneumatic Valve" },
3360 { 0x1C, "Vacuum Pressure Gauge" },
3361 { 0x1D, "Process Control Value" },
3362 { 0x1E, "Residual Gas Analyzer" },
3363 { 0x1F, "DC Power Generator" },
3364 { 0x20, "RF Power Generator" },
3365 { 0x21, "Turbomolecular Vacuum Pump" },
3366 { 0x22, "Encoder" },
3367 { 0x23, "Safety Discrete I/O Device" },
3368 { 0x24, "Fluid Flow Controller" },
3369 { 0x25, "CIP Motion Drive" },
3370 { 0x26, "CompoNet Repeater" },
3371 { 0x27, "Mass Flow Controller, Enhanced" },
3372 { 0x28, "CIP Modbus Device" },
3373 { 0x29, "CIP Modbus Translator" },
3374 { 0x2A, "Safety Analog I/O Device" },
3375 { 0x2B, "Generic Device (keyable)" },
3376 { 0x2C, "Managed Ethernet Switch" },
3377 { 0x2D, "CIP Motion Safety Drive Device" },
3378 { 0x2E, "Safety Drive Device" },
3379 { 0x2F, "CIP Motion Encoder" },
3380 { 0x30, "CIP Motion Converter" },
3381 { 0x31, "CIP Motion I/O" },
3382 { 0x32, "ControlNet Physical Layer Component" },
3383 { 0x33, "Circuit Breaker" },
3384 { 0x34, "HART Device" },
3385 { 0x35, "CIP-HART Translator" },
3386 { 0xC8, "Embedded Component" },
3391 value_string_ext cip_devtype_vals_ext
= VALUE_STRING_EXT_INIT(cip_devtype_vals
);
3393 /* Translate class names */
3394 const value_string cip_class_names_vals
[] = {
3395 { 0x01, "Identity" },
3396 { 0x02, "Message Router" },
3397 { 0x03, "DeviceNet" },
3398 { 0x04, "Assembly" },
3399 { 0x05, "Connection" },
3400 { 0x06, "Connection Manager" },
3401 { 0x07, "Register" },
3402 { 0x08, "Discrete Input Point" },
3403 { 0x09, "Discrete Output Point" },
3404 { 0x0A, "Analog Input Point" },
3405 { 0x0B, "Analog Output Point" },
3406 { 0x0E, "Presence Sensing" },
3407 { 0x0F, "Parameter" },
3408 { 0x10, "Parameter Group" },
3410 { 0x1D, "Discrete Input Group" },
3411 { 0x1E, "Discrete Output Group" },
3412 { 0x1F, "Discrete Group" },
3413 { 0x20, "Analog Input Group" },
3414 { 0x21, "Analog Output Group" },
3415 { 0x22, "Analog Group" },
3416 { 0x23, "Position Sensor" },
3417 { 0x24, "Position Controller Supervisor" },
3418 { 0x25, "Position Controller" },
3419 { 0x26, "Block Sequencer" },
3420 { 0x27, "Command Block" },
3421 { 0x28, "Motor Data" },
3422 { 0x29, "Control Supervisor" },
3423 { 0x2A, "AC/DC Drive" },
3424 { 0x2B, "Acknowledge Handler" },
3425 { 0x2C, "Overload" },
3426 { 0x2D, "Softstart" },
3427 { 0x2E, "Selection" },
3428 { 0x30, "S-Device Supervisor" },
3429 { 0x31, "S-Analog Sensor" },
3430 { 0x32, "S-Analog Actuator" },
3431 { 0x33, "S-Single Stage Controller" },
3432 { 0x34, "S-Gas Calibration" },
3433 { 0x35, "Trip Point" },
3435 { 0x38, "S-Partial Pressure" },
3436 { 0x39, "Safety Supervisor" },
3437 { 0x3A, "Safety Validator" },
3438 { 0x3B, "Safety Discrete Output Point" },
3439 { 0x3C, "Safety Discrete Output Group" },
3440 { 0x3D, "Safety Discrete Input Point" },
3441 { 0x3E, "Safety Discrete Input Group" },
3442 { 0x3F, "Safety Dual Channel Output" },
3443 { 0x40, "S-Sensor Calibration" },
3444 { 0x41, "Event Log" },
3445 { 0x42, "Motion Device Axis" },
3446 { 0x43, "Time Sync" },
3448 { 0x45, "Originator Connection List" },
3449 { 0x46, "Modbus Serial Link" },
3450 { 0x47, "Device Level Ring (DLR)" },
3452 { 0x49, "Safety Analog Input Point" },
3453 { 0x4A, "Safety Analog Input Group" },
3454 { 0x4B, "Safety Dual Channel Analog Input" },
3455 { 0x4C, "SERCOS III Link" },
3456 { 0x4D, "Target Connection List" },
3457 { 0x4E, "Base Energy" },
3458 { 0x4F, "Electrical Energy" },
3459 { 0x50, "Non-Electrical Energy" },
3460 { 0x51, "Base Switch" },
3462 { 0x53, "Power Management" },
3463 { 0x54, "RSTP Bridge" },
3464 { 0x55, "RSTP Port" },
3465 { 0x56, "PRP/HSR Protocol" },
3466 { 0x57, "PRP/HSR Nodes Table" },
3467 { 0x58, "Safety Feedback" },
3468 { 0x59, "Safety Dual Channel Feedback" },
3469 { 0x5A, "Safety Stop Functions" },
3470 { 0x5B, "Safety Limit Functions" },
3471 { 0x5C, "Power Curtailment" },
3472 { 0x5D, "CIP Security" },
3473 { 0x5E, "EtherNet/IP Security" },
3474 { 0x5F, "Certificate Management" },
3475 { 0x60, "Authority" },
3476 { 0x61, "Password Authenticator" },
3477 { 0x62, "Certificate Authenticator" },
3478 { 0x63, "Ingress Egress" },
3479 { 0x67, "PCCC Class" },
3480 { 0xF0, "ControlNet" },
3481 { 0xF1, "ControlNet Keeper" },
3482 { 0xF2, "ControlNet Scheduling" },
3483 { 0xF3, "Connection Configuration" },
3485 { 0xF5, "TCP/IP Interface" },
3486 { 0xF6, "Ethernet Link" },
3487 { 0xF7, "CompoNet" },
3488 { 0xF8, "CompoNet Repeater" },
3489 { 0xF9, "HART Master Port" },
3490 { 0xFA, "I/O Aggregation" },
3491 { 0x100, "Protection Trip" },
3492 { 0x101, "Protection Alarm" },
3493 { 0x102, "Circuit Breaker Supervisor" },
3494 { 0x103, "Circuit Breaker Statistics" },
3495 { 0x104, "Electrical Demand" },
3496 { 0x105, "Electrical Statistics" },
3497 { 0x106, "Machine Base Data" },
3498 { 0x107, "HART Process Device" },
3499 { 0x108, "Process Device Diagnostics" },
3500 { 0x109, "LLDP Management" },
3501 { 0x10A, "LLDP Data Table" },
3502 { 0x10B, "IO-Link Service Parameter" },
3503 { 0x10C, "IO-Link Master PHY" },
3504 { 0x10D, "IO-Link Device PHY" },
3505 { 0x10E, "Pilot Light Supervisor" },
3506 { 0x10F, "Select Line Link" },
3507 { 0x110, "In-Cabinet Actual Topology" },
3508 { 0x111, "In-Cabinet Commissioning" },
3513 const value_string cip_id_state_vals
[] = {
3514 { 0, "Nonexistent" },
3515 { 1, "Device Self Testing" },
3517 { 3, "Operational" },
3518 { 4, "Major Recoverable Fault" },
3519 { 5, "Major Unrecoverable Fault" },
3524 static const range_string cip_port_type_vals
[] = {
3525 { 0, 0, "Any - no routing" },
3526 { 1, 1, "Reserved for legacy use" },
3527 { 2, 2, "ControlNet" },
3528 { 3, 3, "ControlNet with redundancy" },
3529 { 4, 4, "EtherNet/IP" },
3530 { 5, 5, "DeviceNet" },
3531 { 6, 99, "Reserved for legacy use" },
3532 { 100, 199, "Vendor Specific" },
3533 { 200, 200, "CompoNet" },
3534 { 201, 201, "Modbus/TCP" },
3535 { 202, 202, "Modbus/SL" },
3536 { 203, 203, "SERCOS III" },
3537 { 204, 65534, "Reserved for future use" },
3538 { 65535, 65535, "Any - user configurable" },
3543 const value_string cip_port_number_vals
[] = {
3550 value_string_ext cip_class_names_vals_ext
= VALUE_STRING_EXT_INIT(cip_class_names_vals
);
3552 /* Translate function to string - Run/Idle */
3553 static const value_string cip_run_idle_vals
[] = {
3560 void cip_rpi_api_fmt(char *s
, uint32_t value
)
3562 snprintf(s
, ITEM_LABEL_LENGTH
, "%.3fms", value
/ 1000.0);
3565 static void add_cip_class_to_info_column(packet_info
*pinfo
, uint32_t class_id
, int display_type
)
3567 cip_req_info_t
*cip_req_info
;
3569 /* Skip printing the top level class for certain common messages because it gets
3570 too wordy in the Info column. */
3571 cip_req_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
3573 && ((cip_req_info
->bService
== SC_CM_UNCON_SEND
&& class_id
== CI_CLS_CM
)
3574 || (cip_req_info
->bService
== SC_MULT_SERV_PACK
&& class_id
== CI_CLS_MR
)))
3579 // Don't show the Assembly class. It's a generic common class, and there are often multiple entries
3580 // which clutter the display.
3581 if (display_type
== DISPLAY_CONNECTION_PATH
&& class_id
== 4)
3586 if (display_type
== DISPLAY_CONNECTION_PATH
)
3588 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " (%s)", val_to_str(class_id
, cip_class_names_vals
, "Class (0x%02x)"));
3590 else if (display_type
== DISPLAY_REQUEST_PATH
)
3592 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s - ", val_to_str(class_id
, cip_class_names_vals
, "Class (0x%02x)"));
3596 static void add_cip_symbol_to_info_column(packet_info
*pinfo
, char *symbol_name
, int display_type
)
3598 if (symbol_name
== NULL
)
3603 if (display_type
== DISPLAY_CONNECTION_PATH
)
3605 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " ('%s')", symbol_name
);
3607 else if (display_type
== DISPLAY_REQUEST_PATH
)
3609 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "'%s' - ", symbol_name
);
3613 void add_cip_service_to_info_column(packet_info
*pinfo
, uint8_t service
, const value_string
* service_vals
)
3615 col_append_str( pinfo
->cinfo
, COL_INFO
,
3616 val_to_str(service
& CIP_SC_MASK
, service_vals
, "Service (0x%02x)"));
3617 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3620 static void add_cip_pccc_function_to_info_column(packet_info
*pinfo
, uint8_t fnc
, const value_string
* fnc_vals
)
3622 col_append_fstr( pinfo
->cinfo
, COL_INFO
,
3623 " - %s", val_to_str(fnc
, fnc_vals
, "Function (0x%02x)"));
3624 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3627 static int dissect_id_revision(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3628 int offset
, int total_len
)
3632 expert_add_info(pinfo
, item
, &ei_mal_identity_revision
);
3636 proto_tree_add_item( tree
, hf_id_major_rev
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
3637 proto_tree_add_item( tree
, hf_id_minor_rev
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
3641 static int dissect_id_status(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3642 int offset
, int total_len
)
3644 static int * const status
[] = {
3645 &hf_id_status_owned
,
3647 &hf_id_status_extended1
,
3648 &hf_id_status_minor_fault_rec
,
3649 &hf_id_status_minor_fault_unrec
,
3650 &hf_id_status_major_fault_rec
,
3651 &hf_id_status_major_fault_unrec
,
3652 &hf_id_status_extended2
,
3658 expert_add_info(pinfo
, item
, &ei_mal_identity_status
);
3662 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_id_status
, ett_id_status
, status
, ENC_LITTLE_ENDIAN
);
3667 static int dissect_msg_rout_num_classes(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3668 int offset
, int total_len
)
3670 uint16_t i
, num_classes
;
3672 num_classes
= tvb_get_letohs( tvb
, offset
);
3673 proto_tree_add_item( tree
, hf_msg_rout_num_classes
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3675 if (total_len
< (2+(num_classes
*2)))
3677 expert_add_info(pinfo
, item
, &ei_mal_msg_rout_num_classes
);
3681 for (i
= 0; i
< num_classes
; i
++)
3682 proto_tree_add_item( tree
, hf_msg_rout_classes
, tvb
, offset
+2+(i
*2), 2, ENC_LITTLE_ENDIAN
);
3684 return (2+(num_classes
*2));
3687 static int dissect_cm_connection_entry_list(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
3688 int offset
, int total_len _U_
)
3690 uint32_t num_conn_entries
= 0;
3691 uint32_t num_conn_entries_bytes
;
3693 proto_tree_add_item_ret_uint(tree
, hf_conn_mgr_num_conn_entries
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &num_conn_entries
);
3695 num_conn_entries_bytes
= (num_conn_entries
+7)/8;
3696 proto_tree_add_uint(tree
, hf_conn_mgr_num_conn_entries_bytes
, tvb
, 0, 0, num_conn_entries_bytes
);
3698 for (uint32_t i
= 0; i
< num_conn_entries_bytes
; i
++)
3700 proto_tree_add_item(tree
, hf_conn_mgr_conn_open_bits
, tvb
, offset
+ 2 + i
, 1, ENC_LITTLE_ENDIAN
);
3703 return 2 + num_conn_entries_bytes
;
3706 static int dissect_time_sync_grandmaster_clock(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3707 int offset
, int total_len
)
3711 expert_add_info(pinfo
, item
, &ei_mal_time_sync_gm_clock
);
3715 proto_tree_add_item( tree
, hf_time_sync_gm_clock_clock_id
, tvb
, offset
, 8, ENC_NA
);
3716 proto_tree_add_item( tree
, hf_time_sync_gm_clock_clock_class
, tvb
, offset
+8, 2, ENC_LITTLE_ENDIAN
);
3717 proto_tree_add_item( tree
, hf_time_sync_gm_clock_time_accuracy
, tvb
, offset
+10, 2, ENC_LITTLE_ENDIAN
);
3718 proto_tree_add_item( tree
, hf_time_sync_gm_clock_offset_scaled_log_variance
, tvb
, offset
+12, 2, ENC_LITTLE_ENDIAN
);
3719 proto_tree_add_item( tree
, hf_time_sync_gm_clock_current_utc_offset
, tvb
, offset
+14, 2, ENC_LITTLE_ENDIAN
);
3721 static int* const bits
[] = {
3722 &hf_time_sync_gm_clock_time_property_flags_leap61
,
3723 &hf_time_sync_gm_clock_time_property_flags_leap59
,
3724 &hf_time_sync_gm_clock_time_property_flags_current_utc_valid
,
3725 &hf_time_sync_gm_clock_time_property_flags_ptp_timescale
,
3726 &hf_time_sync_gm_clock_time_property_flags_time_traceable
,
3727 &hf_time_sync_gm_clock_time_property_flags_freq_traceable
,
3730 proto_tree_add_bitmask(tree
, tvb
, offset
+ 16, hf_time_sync_gm_clock_time_property_flags
, ett_time_sync_gm_clock_flags
, bits
, ENC_LITTLE_ENDIAN
);
3732 proto_tree_add_item( tree
, hf_time_sync_gm_clock_time_source
, tvb
, offset
+18, 2, ENC_LITTLE_ENDIAN
);
3733 proto_tree_add_item( tree
, hf_time_sync_gm_clock_priority1
, tvb
, offset
+20, 2, ENC_LITTLE_ENDIAN
);
3734 proto_tree_add_item( tree
, hf_time_sync_gm_clock_priority2
, tvb
, offset
+22, 2, ENC_LITTLE_ENDIAN
);
3738 static int dissect_time_sync_parent_clock(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3739 int offset
, int total_len
)
3743 expert_add_info(pinfo
, item
, &ei_mal_time_sync_parent_clock
);
3747 proto_tree_add_item( tree
, hf_time_sync_parent_clock_clock_id
, tvb
, offset
, 8, ENC_NA
);
3748 proto_tree_add_item( tree
, hf_time_sync_parent_clock_port_number
, tvb
, offset
+8, 2, ENC_LITTLE_ENDIAN
);
3749 proto_tree_add_item( tree
, hf_time_sync_parent_clock_observed_offset_scaled_log_variance
, tvb
, offset
+10, 2, ENC_LITTLE_ENDIAN
);
3750 proto_tree_add_item( tree
, hf_time_sync_parent_clock_observed_phase_change_rate
, tvb
, offset
+12, 4, ENC_LITTLE_ENDIAN
);
3754 static int dissect_time_sync_local_clock(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3755 int offset
, int total_len
)
3759 expert_add_info(pinfo
, item
, &ei_mal_time_sync_local_clock
);
3763 proto_tree_add_item( tree
, hf_time_sync_local_clock_clock_id
, tvb
, offset
, 8, ENC_NA
);
3764 proto_tree_add_item( tree
, hf_time_sync_local_clock_clock_class
, tvb
, offset
+8, 2, ENC_LITTLE_ENDIAN
);
3765 proto_tree_add_item( tree
, hf_time_sync_local_clock_time_accuracy
, tvb
, offset
+10, 2, ENC_LITTLE_ENDIAN
);
3766 proto_tree_add_item( tree
, hf_time_sync_local_clock_offset_scaled_log_variance
, tvb
, offset
+12, 2, ENC_LITTLE_ENDIAN
);
3767 proto_tree_add_item( tree
, hf_time_sync_local_clock_current_utc_offset
, tvb
, offset
+14, 2, ENC_LITTLE_ENDIAN
);
3769 static int* const bits
[] = {
3770 &hf_time_sync_local_clock_time_property_flags_leap61
,
3771 &hf_time_sync_local_clock_time_property_flags_leap59
,
3772 &hf_time_sync_local_clock_time_property_flags_current_utc_valid
,
3773 &hf_time_sync_local_clock_time_property_flags_ptp_timescale
,
3774 &hf_time_sync_local_clock_time_property_flags_time_traceable
,
3775 &hf_time_sync_local_clock_time_property_flags_freq_traceable
,
3778 proto_tree_add_bitmask(tree
, tvb
, offset
+ 16, hf_time_sync_local_clock_time_property_flags
, ett_time_sync_local_clock_flags
, bits
, ENC_LITTLE_ENDIAN
);
3780 proto_tree_add_item( tree
, hf_time_sync_local_clock_time_source
, tvb
, offset
+18, 2, ENC_LITTLE_ENDIAN
);
3784 static int dissect_time_sync_port_state_info(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3785 int offset
, int total_len
)
3787 uint16_t i
, num_ports
;
3788 proto_tree
* port_tree
;
3792 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_state_info
);
3796 num_ports
= tvb_get_letohs( tvb
, offset
);
3797 proto_tree_add_item( tree
, hf_time_sync_port_state_info_num_ports
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3799 if (2+num_ports
*4 > total_len
)
3801 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_state_info_ports
);
3805 for (i
= 0; i
< num_ports
; i
++)
3807 port_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+2+i
*4, 4, ett_time_sync_port_state_info
, NULL
, "Port #%d", i
+1);
3808 proto_tree_add_item(port_tree
, hf_time_sync_port_state_info_port_num
, tvb
, offset
+2+i
*4, 2, ENC_LITTLE_ENDIAN
);
3809 proto_tree_add_item(port_tree
, hf_time_sync_port_state_info_port_state
, tvb
, offset
+4+i
*4, 2, ENC_LITTLE_ENDIAN
);
3812 return 2+num_ports
*4;
3815 static int dissect_time_sync_port_enable_cfg(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3816 int offset
, int total_len
)
3818 uint16_t i
, num_ports
;
3819 proto_tree
* port_tree
;
3823 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_enable_cfg
);
3827 num_ports
= tvb_get_letohs( tvb
, offset
);
3828 proto_tree_add_item( tree
, hf_time_sync_port_enable_cfg_num_ports
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3830 if (2+num_ports
*4 > total_len
)
3832 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_enable_cfg_ports
);
3836 for (i
= 0; i
< num_ports
; i
++)
3838 port_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+2+i
*4, 4, ett_time_sync_port_enable_cfg
, NULL
, "Port #%d", i
+1);
3839 proto_tree_add_item(port_tree
, hf_time_sync_port_enable_cfg_port_num
, tvb
, offset
+2+i
*4, 2, ENC_LITTLE_ENDIAN
);
3840 proto_tree_add_item(port_tree
, hf_time_sync_port_enable_cfg_port_enable
, tvb
, offset
+4+i
*4, 2, ENC_LITTLE_ENDIAN
);
3843 return 2+num_ports
*4;
3846 static int dissect_time_sync_port_log_announce(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3847 int offset
, int total_len
)
3849 uint16_t i
, num_ports
;
3850 proto_tree
* port_tree
;
3854 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_log_announce
);
3858 num_ports
= tvb_get_letohs( tvb
, offset
);
3859 proto_tree_add_item( tree
, hf_time_sync_port_log_announce_num_ports
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3861 if (2+num_ports
*4 > total_len
)
3863 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_log_announce_ports
);
3867 for (i
= 0; i
< num_ports
; i
++)
3869 port_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+2+i
*4, 4, ett_time_sync_port_log_announce
, NULL
, "Port #%d", i
+1);
3870 proto_tree_add_item(port_tree
, hf_time_sync_port_log_announce_port_num
, tvb
, offset
+2+i
*4, 2, ENC_LITTLE_ENDIAN
);
3871 proto_tree_add_item(port_tree
, hf_time_sync_port_log_announce_interval
, tvb
, offset
+4+i
*4, 2, ENC_LITTLE_ENDIAN
);
3874 return 2+num_ports
*4;
3877 static int dissect_time_sync_port_log_sync(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3878 int offset
, int total_len
)
3880 uint16_t i
, num_ports
;
3881 proto_tree
* port_tree
;
3885 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_log_sync
);
3889 num_ports
= tvb_get_letohs( tvb
, offset
);
3890 proto_tree_add_item( tree
, hf_time_sync_port_log_sync_num_ports
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3892 if (2+num_ports
*4 > total_len
)
3894 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_log_sync_ports
);
3898 for (i
= 0; i
< num_ports
; i
++)
3900 port_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+2+i
*4, 4, ett_time_sync_port_log_sync
, NULL
, "Port #%d", i
+1);
3901 proto_tree_add_item(port_tree
, hf_time_sync_port_log_sync_port_num
, tvb
, offset
+2+i
*4, 2, ENC_LITTLE_ENDIAN
);
3902 proto_tree_add_item(port_tree
, hf_time_sync_port_log_sync_port_log_sync_interval
, tvb
, offset
+4+i
*4, 2, ENC_LITTLE_ENDIAN
);
3905 return 2+num_ports
*4;
3908 static int dissect_time_sync_clock_type(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3909 int offset
, int total_len
)
3913 expert_add_info(pinfo
, item
, &ei_mal_time_sync_clock_type
);
3917 static int* const bits
[] = {
3918 &hf_time_sync_clock_type_management
,
3919 &hf_time_sync_clock_type_end_to_end
,
3920 &hf_time_sync_clock_type_boundary
,
3921 &hf_time_sync_clock_type_ordinary
,
3922 &hf_time_sync_clock_type_slave_only
,
3925 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_time_sync_clock_type
, ett_time_sync_clock_type
, bits
, ENC_LITTLE_ENDIAN
);
3930 static int dissect_time_sync_manufacture_id(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3931 int offset
, int total_len
)
3935 expert_add_info(pinfo
, item
, &ei_mal_time_sync_manufacture_id
);
3939 proto_tree_add_item( tree
, hf_time_sync_manufacture_id_oui
, tvb
, offset
, 3, ENC_LITTLE_ENDIAN
);
3940 proto_tree_add_item( tree
, hf_time_sync_manufacture_id_reserved
, tvb
, offset
+3, 1, ENC_LITTLE_ENDIAN
);
3944 static int dissect_time_sync_prod_desc(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3945 int offset
, int total_len
)
3951 expert_add_info(pinfo
, item
, &ei_mal_time_sync_prod_desc
);
3955 proto_tree_add_item_ret_uint( tree
, hf_time_sync_prod_desc_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &size
);
3959 expert_add_info(pinfo
, item
, &ei_mal_time_sync_prod_desc_64
);
3963 if ((int)(size
+4) > total_len
)
3965 expert_add_info(pinfo
, item
, &ei_mal_time_sync_prod_desc_size
);
3969 proto_tree_add_item( tree
, hf_time_sync_prod_desc_str
, tvb
, offset
+4, size
, ENC_ASCII
);
3973 static int dissect_time_sync_revision_data(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
3974 int offset
, int total_len
)
3980 expert_add_info(pinfo
, item
, &ei_mal_time_sync_revision_data
);
3984 proto_tree_add_item_ret_uint( tree
, hf_time_sync_revision_data_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &size
);
3988 expert_add_info(pinfo
, item
, &ei_mal_time_sync_revision_data_32
);
3992 if ((int)(size
+4) > total_len
)
3994 expert_add_info(pinfo
, item
, &ei_mal_time_sync_revision_data_size
);
3998 proto_tree_add_item( tree
, hf_time_sync_revision_data_str
, tvb
, offset
+4, size
, ENC_ASCII
);
4002 static int dissect_time_sync_user_desc(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4003 int offset
, int total_len
)
4009 expert_add_info(pinfo
, item
, &ei_mal_time_sync_user_desc
);
4013 proto_tree_add_item_ret_uint( tree
, hf_time_sync_user_desc_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &size
);
4017 expert_add_info(pinfo
, item
, &ei_mal_time_sync_user_desc_128
);
4021 if ((int)(size
+4) > total_len
)
4023 expert_add_info(pinfo
, item
, &ei_mal_time_sync_user_desc_size
);
4027 proto_tree_add_item( tree
, hf_time_sync_user_desc_str
, tvb
, offset
+4, size
, ENC_ASCII
);
4031 static int dissect_time_sync_port_profile_id_info(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4032 int offset
, int total_len
)
4034 uint16_t i
, num_ports
;
4035 proto_tree
* port_tree
;
4039 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_profile_id_info
);
4043 num_ports
= tvb_get_letohs( tvb
, offset
);
4044 proto_tree_add_item( tree
, hf_time_sync_port_profile_id_info_num_ports
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4046 if (2+num_ports
*10 > total_len
)
4048 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_profile_id_info_ports
);
4052 for (i
= 0; i
< num_ports
; i
++)
4054 port_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+2+i
*10, 10, ett_time_sync_port_profile_id_info
, NULL
, "Port #%d", i
+1);
4055 proto_tree_add_item(port_tree
, hf_time_sync_port_profile_id_info_port_num
, tvb
, offset
+2+i
*10, 2, ENC_LITTLE_ENDIAN
);
4056 proto_tree_add_item(port_tree
, hf_time_sync_port_profile_id_info_profile_id
, tvb
, offset
+4+i
*10, 8, ENC_NA
);
4059 return 2+num_ports
*10;
4062 static int dissect_time_sync_port_phys_addr_info(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4063 int offset
, int total_len
)
4065 uint16_t i
, num_ports
;
4066 proto_tree
* port_tree
;
4070 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_phys_addr_info
);
4074 num_ports
= tvb_get_letohs( tvb
, offset
);
4075 proto_tree_add_item( tree
, hf_time_sync_port_phys_addr_info_num_ports
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4077 if (2+num_ports
*36 > total_len
)
4079 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_phys_addr_info_ports
);
4083 for (i
= 0; i
< num_ports
; i
++)
4085 port_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+2+i
*36, 36, ett_time_sync_port_phys_addr_info
, NULL
, "Port #%d", i
+1);
4086 proto_tree_add_item(port_tree
, hf_time_sync_port_phys_addr_info_port_num
, tvb
, offset
+2+i
*36, 2, ENC_LITTLE_ENDIAN
);
4087 proto_tree_add_item(port_tree
, hf_time_sync_port_phys_addr_info_phys_proto
, tvb
, offset
+4+i
*36, 16, ENC_ASCII
);
4090 proto_tree_add_item_ret_uint(port_tree
, hf_time_sync_port_phys_addr_info_addr_size
, tvb
, offset
+20+i
*36, 2, ENC_LITTLE_ENDIAN
, &addr_size
);
4092 // Field is 16 bytes, but only highlight the actual size.
4093 proto_tree_add_item(port_tree
, hf_time_sync_port_phys_addr_info_phys_addr
, tvb
, offset
+22+i
*36, addr_size
, ENC_NA
);
4096 return 2+num_ports
*36;
4099 static int dissect_time_sync_port_proto_addr_info(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4100 int offset
, int total_len
)
4102 uint16_t i
, num_ports
;
4103 proto_tree
* port_tree
;
4107 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_proto_addr_info
);
4111 num_ports
= tvb_get_letohs( tvb
, offset
);
4112 proto_tree_add_item( tree
, hf_time_sync_port_proto_addr_info_num_ports
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4114 if (2+num_ports
*22 > total_len
)
4116 expert_add_info(pinfo
, item
, &ei_mal_time_sync_port_proto_addr_info_ports
);
4120 for (i
= 0; i
< num_ports
; i
++)
4122 port_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+2+i
*22, 22, ett_time_sync_port_proto_addr_info
, NULL
, "Port #%d", i
+1);
4123 proto_tree_add_item(port_tree
, hf_time_sync_port_proto_addr_info_port_num
, tvb
, offset
+2+i
*22, 2, ENC_LITTLE_ENDIAN
);
4124 proto_tree_add_item(port_tree
, hf_time_sync_port_proto_addr_info_network_proto
, tvb
, offset
+4+i
*22, 2, ENC_LITTLE_ENDIAN
);
4125 proto_tree_add_item(port_tree
, hf_time_sync_port_proto_addr_info_addr_size
, tvb
, offset
+6+i
*22, 2, ENC_LITTLE_ENDIAN
);
4126 proto_tree_add_item(port_tree
, hf_time_sync_port_proto_addr_info_port_proto_addr
, tvb
, offset
+8+i
*22, 16, ENC_NA
);
4129 return 2+num_ports
*22;
4132 static int dissect_time_sync_sys_time_and_offset(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4133 int offset
, int total_len
)
4137 expert_add_info(pinfo
, item
, &ei_mal_time_sync_sys_time_and_offset
);
4141 dissect_cip_utime(tree
, tvb
, offset
, hf_time_sync_sys_time_and_offset_time
);
4142 proto_tree_add_item( tree
, hf_time_sync_sys_time_and_offset_offset
, tvb
, offset
+8, 8, ENC_LITTLE_ENDIAN
);
4147 int dissect_optional_attr_list(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4148 int offset
, int total_len
)
4151 uint32_t num_attr
= 0;
4153 proto_tree_add_item_ret_uint(tree
, hf_attr_class_opt_attr_num
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &num_attr
);
4155 if (total_len
< (int)(2 + num_attr
* 2))
4157 expert_add_info(pinfo
, item
, &ei_mal_opt_attr_list
);
4161 // Look up the request data to get the CIP Class.
4162 cip_req_info_t
*cip_req_info
;
4163 cip_req_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
4165 for (i
= 0; i
< num_attr
; ++i
)
4167 proto_item
* attr_item
= proto_tree_add_item(tree
, hf_attr_class_attr_num
, tvb
, offset
+ 2 + 2 * i
, 2, ENC_LITTLE_ENDIAN
);
4169 // Display attribute name.
4170 if (cip_req_info
&& cip_req_info
->ciaData
)
4172 const attribute_info_t
* attr
;
4173 attr
= cip_get_attribute(cip_req_info
->ciaData
->iClass
, 1, i
);
4176 proto_item_append_text(attr_item
, " (%s)", attr
->text
);
4181 return 2 + num_attr
* 2;
4184 int dissect_optional_service_list(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4185 int offset
, int total_len
)
4188 uint32_t num_services
= 0;
4190 proto_tree_add_item_ret_uint(tree
, hf_attr_class_opt_service_num
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &num_services
);
4192 if (total_len
< (int)(2 + num_services
* 2))
4194 expert_add_info(pinfo
, item
, &ei_mal_opt_service_list
);
4198 for (i
= 0; i
< num_services
; ++i
)
4200 proto_tree_add_item(tree
, hf_attr_class_service_code
, tvb
, offset
+ 2 + 2 * i
, 2, ENC_LITTLE_ENDIAN
);
4203 return 2 + num_services
* 2;
4206 static int dissect_port_instance_info(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
4207 int offset
, int total_len
)
4211 for (i
= 0; i
< total_len
; i
+= 4)
4213 proto_tree_add_item(tree
, hf_port_type
, tvb
, offset
+ i
, 2, ENC_LITTLE_ENDIAN
);
4214 proto_tree_add_item(tree
, hf_port_number
, tvb
, offset
+ i
+ 2, 2, ENC_LITTLE_ENDIAN
);
4220 static int dissect_port_associated_comm_objects(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4221 int offset
, int total_len _U_
)
4223 uint32_t num_entries
;
4224 proto_tree_add_item_ret_uint(tree
, hf_port_num_comm_object_entries
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &num_entries
);
4227 for (uint32_t i
= 0; i
< num_entries
; ++i
)
4229 parsed_len
+= dissect_padded_epath_len_usint(pinfo
, tree
, item
, tvb
, offset
+ parsed_len
,
4230 tvb_reported_length_remaining(tvb
, offset
+ parsed_len
));
4236 static int dissect_padded_epath_len(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4237 int offset
, int total_len
, bool one_byte_len
)
4240 proto_tree
*epath_tree
;
4241 proto_item
*path_item
;
4243 uint32_t path_size_len
;
4245 if (one_byte_len
== true)
4248 hf_path_len
= hf_path_len_usint
;
4253 hf_path_len
= hf_path_len_uint
;
4256 path_item
= proto_tree_add_item_ret_uint(tree
, hf_path_len
, tvb
, offset
, path_size_len
, ENC_LITTLE_ENDIAN
, &path_size
);
4258 if (total_len
< (int)(path_size
* 2 + path_size_len
))
4260 expert_add_info(pinfo
, item
, &ei_mal_padded_epath_size
);
4264 epath_tree
= proto_tree_add_subtree(tree
, tvb
, offset
+ path_size_len
, path_size
* 2, ett_path
, &path_item
, "Path: ");
4265 dissect_epath(tvb
, pinfo
, epath_tree
, path_item
, offset
+ path_size_len
, path_size
* 2, false, false, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
4267 return path_size
* 2 + path_size_len
;
4270 /* Format: USINT (Length of EPATH in 16-bit words) + Padded EPATH */
4271 int dissect_padded_epath_len_usint(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4272 int offset
, int total_len
)
4274 return dissect_padded_epath_len(pinfo
, tree
, item
, tvb
, offset
, total_len
, true);
4277 /* Format: UINT (Length of EPATH in 16-bit words) + Padded EPATH */
4278 int dissect_padded_epath_len_uint(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4279 int offset
, int total_len
)
4281 return dissect_padded_epath_len(pinfo
, tree
, item
, tvb
, offset
, total_len
, false);
4284 static int dissect_single_segment_packed_attr(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
4285 int offset
, int total_len _U_
)
4287 proto_tree
*subtree
;
4288 proto_item
*subitem
;
4289 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0, ett_port_path
, &subitem
, "Path: ");
4291 int parsed_len
= dissect_cip_segment_single(pinfo
, tvb
, offset
, subtree
, subitem
, false, true, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
4292 proto_item_set_len(subitem
, parsed_len
);
4297 static int dissect_single_segment_padded_attr(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
4298 int offset
, int total_len _U_
)
4300 proto_tree
*subtree
;
4301 proto_item
*subitem
;
4302 subtree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0, ett_port_path
, &subitem
, "Path: ");
4304 int parsed_len
= dissect_cip_segment_single(pinfo
, tvb
, offset
, subtree
, subitem
, false, false, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
4305 proto_item_set_len(subitem
, parsed_len
);
4310 static int dissect_port_link_object(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
4311 int offset
, int total_len
)
4313 return dissect_padded_epath_len_uint(pinfo
, tree
, item
, tvb
, offset
, total_len
);
4316 static int dissect_port_node_range(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
4317 int offset
, int total_len _U_
)
4319 proto_tree_add_item(tree
, hf_port_min_node_num
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4320 proto_tree_add_item(tree
, hf_port_max_node_num
, tvb
, offset
+ 2, 2, ENC_LITTLE_ENDIAN
);
4326 /// Identity - Services
4327 static int dissect_identity_reset(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
, int offset
, bool request
)
4333 if (tvb_reported_length_remaining(tvb
, offset
) > 0)
4335 proto_tree_add_item(tree
, hf_cip_sc_reset_param
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
4347 static const attribute_info_t cip_attribute_vals
[] = {
4348 /* Identity Object (class attributes) */
4349 {0x01, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
4350 {0x01, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
4351 {0x01, true, 3, -1, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
4352 {0x01, true, 4, -1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
4353 {0x01, true, 5, -1, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
4354 {0x01, true, 6, 2, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
4355 {0x01, true, 7, 3, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
4357 /* Identity Object (instance attributes) */
4358 {0x01, false, 1, 0, "Vendor ID", cip_uint
, &hf_id_vendor_id
, NULL
},
4359 {0x01, false, 2, 1, "Device Type", cip_uint
, &hf_id_device_type
, NULL
},
4360 {0x01, false, 3, 2, "Product Code", cip_uint
, &hf_id_product_code
, NULL
},
4361 {0x01, false, 4, 3, "Revision", cip_dissector_func
, NULL
, dissect_id_revision
},
4362 {0x01, false, 5, 4, "Status", cip_dissector_func
, NULL
, dissect_id_status
},
4363 {0x01, false, 6, 5, "Serial Number", cip_udint
, &hf_id_serial_number
, NULL
},
4364 {0x01, false, 7, 6, "Product Name", cip_short_string
, &hf_id_product_name
, NULL
},
4365 {0x01, false, 8, 7, "State", cip_usint
, &hf_id_state
, NULL
},
4366 {0x01, false, 9, 8, "Configuration Consistency Value", cip_uint
, &hf_id_config_value
, NULL
},
4367 {0x01, false, 10, 9, "Heartbeat Interval", cip_usint
, &hf_id_heartbeat
, NULL
},
4369 /* Message Router Object (class attributes) */
4370 {0x02, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
4371 {0x02, true, 2, -1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
4372 {0x02, true, 3, -1, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
4373 {0x02, true, 4, 1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
4374 {0x02, true, 5, 2, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
4375 {0x02, true, 6, 3, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
4376 {0x02, true, 7, 4, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
4378 /* Message Router Object (instance attributes) */
4379 {0x02, false, 1, 0, "Object List", cip_dissector_func
, NULL
, dissect_msg_rout_num_classes
},
4380 {0x02, false, 2, 1, "Number Available", cip_uint
, &hf_msg_rout_num_available
, NULL
},
4381 {0x02, false, 3, 2, "Number Active", cip_uint
, &hf_msg_rout_num_active
, NULL
},
4382 {0x02, false, 4, 3, "Active Connections", cip_uint_array
, &hf_msg_rout_active_connections
, NULL
},
4384 /* Connection Manager Object (class attributes) */
4385 {0x06, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
4386 {0x06, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
4387 {0x06, true, 3, -1, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
4388 {0x06, true, 4, -1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
4389 {0x06, true, 5, -1, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
4390 {0x06, true, 6, 2, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
4391 {0x06, true, 7, 3, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
4393 /* Connection Manager Object (instance attributes) */
4394 {0x06, false, 1, 0, "Open Requests", cip_uint
, &hf_conn_mgr_open_requests
, NULL
},
4395 {0x06, false, 2, 1, "Open Format Rejects", cip_uint
, &hf_conn_mgr_open_format_rejects
, NULL
},
4396 {0x06, false, 3, 2, "Open Resource Rejects", cip_uint
, &hf_conn_mgr_open_resource_rejects
, NULL
},
4397 {0x06, false, 4, 3, "Other Open Rejects", cip_uint
, &hf_conn_mgr_other_open_rejects
, NULL
},
4398 {0x06, false, 5, 4, "Close Requests", cip_uint
, &hf_conn_mgr_close_requests
, NULL
},
4399 {0x06, false, 6, 5, "Close Format Requests", cip_uint
, &hf_conn_close_format_requests
, NULL
},
4400 {0x06, false, 7, 6, "Close Other Requests", cip_uint
, &hf_conn_mgr_close_other_requests
, NULL
},
4401 {0x06, false, 8, 7, "Connection Timeouts", cip_uint
, &hf_conn_mgr_conn_timouts
, NULL
},
4402 {0x06, false, 9, 8, "Connection Entry List", cip_dissector_func
, NULL
, dissect_cm_connection_entry_list
},
4403 {0x06, false, 11, 9, "CPU Utilization", cip_uint
, &hf_conn_mgr_cpu_utilization
, NULL
},
4404 {0x06, false, 12, 10, "Max Buff Size", cip_udint
, &hf_conn_mgr_max_buff_size
, NULL
},
4405 {0x06, false, 13, 11, "Buff Size Remaining", cip_udint
, &hf_conn_mgr_buff_size_remaining
, NULL
},
4407 /* File Object (instance attributes) */
4408 {0x37, false, 4, -1, "File Name", cip_stringi
, &hf_file_filename
, NULL
},
4410 /* Time Sync Object (class attributes) */
4411 {0x43, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
4412 {0x43, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
4413 {0x43, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
4414 {0x43, true, 4, 3, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
4415 {0x43, true, 5, 4, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
4416 {0x43, true, 6, 5, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
4417 {0x43, true, 7, 6, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
4419 /* Time Sync Object (instance attributes) */
4420 {0x43, false, 1, -1, "PTP Enable", cip_bool
, &hf_time_sync_ptp_enable
, NULL
},
4421 {0x43, false, 2, -1, "Is Synchronized", cip_bool
, &hf_time_sync_is_synchronized
, NULL
},
4422 {0x43, false, 3, -1, "System Time (Microseconds)", cip_utime
, &hf_time_sync_sys_time_micro
, NULL
},
4423 {0x43, false, 4, -1, "System Time (Nanoseconds)", cip_stime
, &hf_time_sync_sys_time_nano
, NULL
},
4424 {0x43, false, 5, -1, "Offset from Master", cip_ntime
, &hf_time_sync_offset_from_master
, NULL
},
4425 {0x43, false, 6, -1, "Max Offset from Master", cip_ulint
, &hf_time_sync_max_offset_from_master
, NULL
},
4426 {0x43, false, 7, -1, "Mean Path Delay To Master", cip_ntime
, &hf_time_sync_mean_path_delay_to_master
, NULL
},
4427 {0x43, false, 8, -1, "Grand Master Clock Info", cip_dissector_func
, NULL
, dissect_time_sync_grandmaster_clock
},
4428 {0x43, false, 9, -1, "Parent Clock Info", cip_dissector_func
, NULL
, dissect_time_sync_parent_clock
},
4429 {0x43, false, 10, -1, "Local Clock Info", cip_dissector_func
, NULL
, dissect_time_sync_local_clock
},
4430 {0x43, false, 11, -1, "Number of Ports", cip_uint
, &hf_time_sync_num_ports
, NULL
},
4431 {0x43, false, 12, -1, "Port State Info", cip_dissector_func
, NULL
, dissect_time_sync_port_state_info
},
4432 {0x43, false, 13, -1, "Port Enable Cfg", cip_dissector_func
, NULL
, dissect_time_sync_port_enable_cfg
},
4433 {0x43, false, 14, -1, "Port Log Announcement Interval Cfg", cip_dissector_func
, NULL
, dissect_time_sync_port_log_announce
},
4434 {0x43, false, 15, -1, "Port Log Sync Interval Cfg", cip_dissector_func
, NULL
, dissect_time_sync_port_log_sync
},
4435 {0x43, false, 16, -1, "Priority1", cip_usint
, &hf_time_sync_priority1
, NULL
},
4436 {0x43, false, 17, -1, "Priority2", cip_usint
, &hf_time_sync_priority2
, NULL
},
4437 {0x43, false, 18, -1, "Domain number", cip_usint
, &hf_time_sync_domain_number
, NULL
},
4438 {0x43, false, 19, -1, "Clock Type", cip_dissector_func
, NULL
, dissect_time_sync_clock_type
},
4439 {0x43, false, 20, -1, "Manufacture Identity", cip_dissector_func
, NULL
, dissect_time_sync_manufacture_id
},
4440 {0x43, false, 21, -1, "Product Description", cip_dissector_func
, NULL
, dissect_time_sync_prod_desc
},
4441 {0x43, false, 22, -1, "Revision Data", cip_dissector_func
, NULL
, dissect_time_sync_revision_data
},
4442 {0x43, false, 23, -1, "User Description", cip_dissector_func
, NULL
, dissect_time_sync_user_desc
},
4443 {0x43, false, 24, -1, "Port Profile Identity Info", cip_dissector_func
, NULL
, dissect_time_sync_port_profile_id_info
},
4444 {0x43, false, 25, -1, "Port Physical Address Info", cip_dissector_func
, NULL
, dissect_time_sync_port_phys_addr_info
},
4445 {0x43, false, 26, -1, "Port Protocol Address Info", cip_dissector_func
, NULL
, dissect_time_sync_port_proto_addr_info
},
4446 {0x43, false, 27, -1, "Steps Removed", cip_uint
, &hf_time_sync_steps_removed
, NULL
},
4447 {0x43, false, 28, -1, "System Time and Offset", cip_dissector_func
, NULL
, dissect_time_sync_sys_time_and_offset
},
4450 /* Connection Configuration Object (class attributes) */
4451 /* Data sizes are different than common class attributes for some items. */
4452 { 0xF3, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
4453 { 0xF3, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_udint
, &hf_cip_class_max_inst32
, NULL
},
4454 { 0xF3, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_udint
, &hf_cip_class_num_inst32
, NULL
},
4455 { 0xF3, true, 4, -1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
4456 { 0xF3, true, 5, -1, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
4457 { 0xF3, true, 6, -1, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
4458 { 0xF3, true, 7, -1, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
4459 { 0xF3, true, 8, 3, "Format Number", cip_uint
, &hf_cip_cco_format_number
, NULL
},
4460 { 0xF3, true, 9, 4, "Edit Signature", cip_udint
, &hf_cip_cco_edit_signature
, NULL
},
4462 /* Port Object (class attributes) */
4463 { 0xF4, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
4464 { 0xF4, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
4465 { 0xF4, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
4466 { 0xF4, true, 4, -1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
4467 { 0xF4, true, 5, -1, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
4468 { 0xF4, true, 6, -1, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
4469 { 0xF4, true, 7, -1, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
4470 { 0xF4, true, 8, 3, "Entry Port", cip_uint
, &hf_port_entry_port
, NULL
},
4471 { 0xF4, true, 9, 4, "Port Instance Info", cip_dissector_func
, NULL
, dissect_port_instance_info
},
4473 /* Port Object (instance attributes) */
4474 { 0xF4, false, 1, 0, "Port Type", cip_uint
, &hf_port_type
, NULL
},
4475 { 0xF4, false, 2, 1, "Port Number", cip_uint
, &hf_port_number
, NULL
},
4476 { 0xF4, false, 3, 2, "Link Object", cip_dissector_func
, NULL
, dissect_port_link_object
},
4477 { 0xF4, false, 4, 3, "Port Name", cip_short_string
, &hf_port_name
, NULL
},
4478 { 0xF4, false, 7, 4, "Port Number and Node Address", cip_dissector_func
, NULL
, dissect_single_segment_padded_attr
},
4479 { 0xF4, false, 8, -1, "Port Node Range", cip_dissector_func
, NULL
, dissect_port_node_range
},
4480 { 0xF4, false, 9, -1, "Chassis Identity", cip_dissector_func
, NULL
, dissect_single_segment_packed_attr
},
4481 { 0xF4, false, 11, -1, "Associated Communication Objects", cip_dissector_func
, NULL
, dissect_port_associated_comm_objects
},
4484 // Table of CIP services defined by this dissector.
4485 static cip_service_info_t cip_obj_spec_service_table
[] = {
4486 { 0x1, SC_RESET
, "Reset", dissect_identity_reset
},
4489 // Look up a given CIP service from this dissector.
4490 static cip_service_info_t
* cip_get_service_cip(uint32_t class_id
, uint8_t service_id
)
4492 return cip_get_service_one_table(&cip_obj_spec_service_table
[0],
4493 array_length(cip_obj_spec_service_table
),
4498 typedef struct attribute_val_array
{
4500 const attribute_info_t
* attrs
;
4501 } attribute_val_array_t
;
4503 /* Each entry in this table (eg: cip_attribute_vals) is a list of:
4504 Attribute information (class_id/class_instance/attribute) to attribute property
4506 Note: If more items are added to the individual tables, it may make sense
4507 to switch to a more efficient implementation (eg: hash table).
4510 static attribute_val_array_t all_attribute_vals
[] = {
4511 {array_length(cip_attribute_vals
), cip_attribute_vals
},
4512 {array_length(enip_attribute_vals
), enip_attribute_vals
},
4513 {array_length(cip_safety_attribute_vals
), cip_safety_attribute_vals
},
4514 {array_length(cip_motion_attribute_vals
), cip_motion_attribute_vals
},
4517 const attribute_info_t
* cip_get_attribute(unsigned class_id
, unsigned instance
, unsigned attribute
)
4520 attribute_val_array_t
* att_array
;
4521 const attribute_info_t
* pattr
;
4523 static const attribute_info_t class_attribute_vals
[] = {
4524 { 0, true, 1, -1, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
4525 { 0, true, 2, -1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
4526 { 0, true, 3, -1, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
4527 { 0, true, 4, -1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
4528 { 0, true, 5, -1, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
4529 { 0, true, 6, -1, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
4530 { 0, true, 7, -1, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
4533 for (i
= 0; i
< array_length(all_attribute_vals
); i
++)
4535 att_array
= &all_attribute_vals
[i
];
4536 for (j
= 0; j
< att_array
->size
; j
++)
4538 pattr
= &att_array
->attrs
[j
];
4539 if ((pattr
->class_id
== class_id
) &&
4540 (instance
!= SEGMENT_VALUE_NOT_SET
) &&
4541 (((instance
== 0) && (pattr
->class_instance
== true)) || ((instance
!= 0) && (pattr
->class_instance
== false))) &&
4542 (pattr
->attribute
== attribute
))
4549 /* Check against common class attributes. */
4552 for (i
= 0; i
< array_length(class_attribute_vals
); i
++)
4554 pattr
= &class_attribute_vals
[i
];
4555 if (pattr
->attribute
== attribute
)
4565 // Look up a given CIP service from a table of cip_service_info_t.
4566 cip_service_info_t
* cip_get_service_one_table(cip_service_info_t
* services
, size_t size
, uint32_t class_id
, uint8_t service_id
)
4568 for (uint32_t i
= 0; i
< size
; i
++)
4570 cip_service_info_t
* entry
= &services
[i
];
4571 if (entry
->class_id
== class_id
&& entry
->service_id
== (service_id
& CIP_SC_MASK
))
4580 // Look through all CIP Service tables from different dissectors, to find a definition for a given CIP service.
4581 static cip_service_info_t
* cip_get_service(packet_info
*pinfo
, uint8_t service_id
)
4583 cip_req_info_t
*cip_req_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
4584 if (!cip_req_info
|| !cip_req_info
->ciaData
)
4589 cip_service_info_t
* pService
= cip_get_service_cip(cip_req_info
->ciaData
->iClass
, service_id
);
4595 pService
= cip_get_service_enip(cip_req_info
->ciaData
->iClass
, service_id
);
4605 segment_name_format(wmem_allocator_t
*scope
, const char *segment_name
, const char *fmt
)
4609 segment_name_format(wmem_allocator_t
*scope
, const char *segment_name
, const char *fmt
)
4611 wmem_strbuf_t
*strbuf
;
4613 strbuf
= wmem_strbuf_new(scope
, segment_name
);
4614 wmem_strbuf_append(strbuf
, fmt
);
4615 return wmem_strbuf_get_str(strbuf
);
4619 dissect_cia(tvbuff_t
*tvb
, int offset
, unsigned char segment_type
,
4620 bool generate
, bool packed
, packet_info
*pinfo
, proto_item
*epath_item
,
4621 proto_tree
*path_tree
, proto_item
*path_item
, proto_item
** ret_item
,
4622 const char* segment_name
, const value_string
* vals
, int* value
,
4623 int hf8
, int hf16
, int hf32
)
4625 unsigned char logical_format
;
4629 wmem_strbuf_t
*strbuf
;
4630 bool extended_logical
= false;
4631 uint8_t logical_seg_type
= segment_type
& CI_LOGICAL_SEG_TYPE_MASK
;
4633 /* Extended Logical Format is slightly different than other logical formats. An extra byte is
4634 inserted after the segment type. */
4635 if (logical_seg_type
== CI_LOGICAL_SEG_EXT_LOGICAL
)
4637 extended_logical
= true;
4641 temp_data
= tvb_get_uint8(tvb
, offset
+ 1);
4642 *ret_item
= proto_tree_add_uint(path_tree
, hf_cip_ext_logical_type
, tvb
, 0, 0, temp_data
);
4643 proto_item_set_generated(*ret_item
);
4647 *ret_item
= proto_tree_add_item(path_tree
, hf_cip_ext_logical_type
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
4651 logical_format
= segment_type
& CI_LOGICAL_SEG_FORMAT_MASK
;
4652 switch (logical_format
)
4654 case CI_LOGICAL_SEG_8_BIT
:
4655 value_offset
= offset
+ 1;
4657 if (extended_logical
== true)
4662 temp_data
= tvb_get_uint8(tvb
, value_offset
);
4666 *ret_item
= proto_tree_add_uint(path_tree
, hf8
, tvb
, 0, 0, temp_data
);
4667 proto_item_set_generated(*ret_item
);
4671 *ret_item
= proto_tree_add_item(path_tree
, hf8
, tvb
, value_offset
, 1, ENC_LITTLE_ENDIAN
);
4676 if (logical_seg_type
== CI_LOGICAL_SEG_ATTR_ID
)
4678 proto_item_append_text(epath_item
, "%s: %d", segment_name
, temp_data
);
4682 proto_item_append_text(epath_item
, "%s: 0x%02X", segment_name
, temp_data
);
4687 proto_item_append_text( epath_item
, "%s", val_to_str( temp_data
, vals
, segment_name_format( pinfo
->pool
, segment_name
, ": 0x%02X" ) ) );
4694 if (extended_logical
== true)
4706 case CI_LOGICAL_SEG_16_BIT
:
4707 if (packed
&& extended_logical
== false)
4709 value_offset
= offset
+ 1;
4714 value_offset
= offset
+ 2;
4718 temp_data
= tvb_get_letohs(tvb
, value_offset
);
4722 *ret_item
= proto_tree_add_uint(path_tree
, hf16
, tvb
, 0, 0, temp_data
);
4723 proto_item_set_generated(*ret_item
);
4727 *ret_item
= proto_tree_add_item(path_tree
, hf16
, tvb
, value_offset
, 2, ENC_LITTLE_ENDIAN
);
4732 if (logical_seg_type
== CI_LOGICAL_SEG_ATTR_ID
)
4734 proto_item_append_text(epath_item
, "%s: %d", segment_name
, temp_data
);
4738 proto_item_append_text(epath_item
, "%s: 0x%04X", segment_name
, temp_data
);
4743 strbuf
= wmem_strbuf_new(pinfo
->pool
, segment_name
);
4744 wmem_strbuf_append(strbuf
, ": 0x%04X");
4746 proto_item_append_text( epath_item
, "%s", val_to_str( temp_data
, vals
, segment_name_format( pinfo
->pool
, segment_name
, ": 0x%04X" ) ) );
4753 case CI_LOGICAL_SEG_32_BIT
:
4754 if (packed
&& extended_logical
== false)
4756 value_offset
= offset
+ 1;
4761 value_offset
= offset
+ 2;
4764 temp_data
= tvb_get_letohl(tvb
, value_offset
);
4768 *ret_item
= proto_tree_add_uint(path_tree
, hf32
, tvb
, 0, 0, temp_data
);
4769 proto_item_set_generated(*ret_item
);
4773 *ret_item
= proto_tree_add_item(path_tree
, hf32
, tvb
, value_offset
, 4, ENC_LITTLE_ENDIAN
);
4778 if (logical_seg_type
== CI_LOGICAL_SEG_ATTR_ID
)
4780 proto_item_append_text(epath_item
, "%s: %d", segment_name
, temp_data
);
4784 proto_item_append_text(epath_item
, "%s: 0x%08X", segment_name
, temp_data
);
4789 strbuf
= wmem_strbuf_new(pinfo
->pool
, segment_name
);
4790 wmem_strbuf_append(strbuf
, ": 0x%08X");
4792 proto_item_append_text( epath_item
, "%s", val_to_str( temp_data
, vals
, segment_name_format( pinfo
->pool
, segment_name
, ": 0x%08X" ) ) );
4800 expert_add_info(pinfo
, epath_item
, &ei_proto_log_seg_format
);
4804 if (generate
== false)
4806 proto_item_set_len(path_item
, segment_len
);
4812 /* Dissect Device ID structure */
4814 dissect_deviceid(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
4815 int hf_vendor
, int hf_devtype
, int hf_prodcode
,
4816 int hf_compatibility
, int hf_comp_bit
, int hf_majrev
, int hf_minrev
,
4817 bool generate
, unsigned encoding
)
4819 proto_item
* vendor_id_item
= proto_tree_add_item(tree
, hf_vendor
, tvb
, offset
, 2, encoding
);
4820 proto_item
* device_type_item
= proto_tree_add_item(tree
, hf_devtype
, tvb
, offset
+ 2, 2, encoding
);
4821 proto_item
* product_code_item
= proto_tree_add_item(tree
, hf_prodcode
, tvb
, offset
+ 4, 2, encoding
);
4823 /* Major revision/Compatibility */
4824 uint8_t compatibility
= tvb_get_uint8(tvb
, offset
+ 6);
4826 /* Add Major revision/Compatibility tree */
4827 proto_item
* compatibility_item
= proto_tree_add_uint_format_value(tree
, hf_compatibility
,
4828 tvb
, offset
+ 6, 1, compatibility
, "%s, Major Revision: %d",
4829 val_to_str_const((compatibility
& 0x80) >> 7, cip_com_bit_vals
, ""),
4830 compatibility
& 0x7F);
4831 proto_tree
* compatibility_tree
= proto_item_add_subtree(compatibility_item
, ett_mcsc
);
4833 proto_item
* comp_bit_item
= proto_tree_add_item(compatibility_tree
, hf_comp_bit
, tvb
, offset
+ 6, 1, encoding
);
4834 proto_item
* major_rev_item
= proto_tree_add_item(compatibility_tree
, hf_majrev
, tvb
, offset
+ 6, 1, encoding
);
4835 proto_item
* minor_rev_item
= proto_tree_add_item(tree
, hf_minrev
, tvb
, offset
+ 7, 1, encoding
);
4839 proto_item_set_generated(vendor_id_item
);
4840 proto_item_set_generated(device_type_item
);
4841 proto_item_set_generated(product_code_item
);
4842 proto_item_set_generated(compatibility_item
);
4843 proto_item_set_generated(comp_bit_item
);
4844 proto_item_set_generated(major_rev_item
);
4845 proto_item_set_generated(minor_rev_item
);
4850 dissect_net_param16(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
4851 int hf_net_param16
, int hf_owner
, int hf_type
,
4852 int hf_priority
, int hf_fixed_var
, int hf_con_size
, int ncp_ett
, cip_connID_info_t
* conn_info
)
4854 proto_item
*net_param_item
;
4855 proto_tree
*net_param_tree
;
4857 net_param_item
= proto_tree_add_item(tree
, hf_net_param16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4858 net_param_tree
= proto_item_add_subtree(net_param_item
, ncp_ett
);
4860 /* Add the data to the tree */
4861 proto_tree_add_item(net_param_tree
, hf_owner
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4862 proto_tree_add_item_ret_uint(net_param_tree
, hf_type
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &conn_info
->type
);
4863 proto_tree_add_item(net_param_tree
, hf_priority
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
4864 proto_tree_add_item_ret_uint(net_param_tree
, hf_fixed_var
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &conn_info
->connection_size_type
);
4865 proto_tree_add_item_ret_uint(net_param_tree
, hf_con_size
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &conn_info
->connection_size
);
4869 dissect_net_param32(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
4870 int hf_net_param16
, int hf_owner
, int hf_type
,
4871 int hf_priority
, int hf_fixed_var
, int hf_con_size
, int ncp_ett
, cip_connID_info_t
* conn_info
)
4873 proto_item
*net_param_item
;
4874 proto_tree
*net_param_tree
;
4876 net_param_item
= proto_tree_add_item(tree
, hf_net_param16
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4877 net_param_tree
= proto_item_add_subtree(net_param_item
, ncp_ett
);
4879 /* Add the data to the tree */
4880 proto_tree_add_item(net_param_tree
, hf_owner
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4881 proto_tree_add_item_ret_uint(net_param_tree
, hf_type
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &conn_info
->type
);
4882 proto_tree_add_item(net_param_tree
, hf_priority
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
4883 proto_tree_add_item_ret_uint(net_param_tree
, hf_fixed_var
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &conn_info
->connection_size_type
);
4884 proto_tree_add_item_ret_uint(net_param_tree
, hf_con_size
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &conn_info
->connection_size
);
4888 dissect_transport_type_trigger(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
4889 int hf_ttt
, int hf_direction
, int hf_trigger
, int hf_class
, int ett
)
4891 int* const bits
[] = {
4898 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_ttt
, ett
, bits
, ENC_LITTLE_ENDIAN
);
4901 static int dissect_segment_network_extended(packet_info
*pinfo
, proto_item
*epath_item
, tvbuff_t
*tvb
, int offset
, bool generate
, proto_tree
*net_tree
)
4904 data_words
= tvb_get_uint8(tvb
, offset
+ 1);
4911 it
= proto_tree_add_uint(net_tree
, hf_cip_seg_network_size
, tvb
, 0, 0, data_words
);
4912 proto_item_set_generated(it
);
4914 temp_data
= tvb_get_letohs(tvb
, offset
+ 2);
4915 it
= proto_tree_add_uint(net_tree
, hf_cip_seg_network_subtype
, tvb
, 0, 0, temp_data
);
4916 proto_item_set_generated(it
);
4920 proto_tree_add_item(net_tree
, hf_cip_seg_network_size
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
4921 proto_tree_add_item(net_tree
, hf_cip_seg_network_subtype
, tvb
, offset
+ 2, 2, ENC_LITTLE_ENDIAN
);
4924 // Extended Network Subtype is included in the Number of Data words, so we must have at least 1.
4927 expert_add_info(pinfo
, epath_item
, &ei_proto_ext_network
);
4931 if (generate
== false)
4933 /* The first word of the data is the extended segment subtype, so
4934 don't include that in the displayed data block. */
4935 int net_seg_data_offset
;
4936 int net_seg_data_len
;
4937 net_seg_data_offset
= offset
+ 4;
4938 net_seg_data_len
= (data_words
- 1) * 2;
4940 if (tvb_reported_length_remaining(tvb
, net_seg_data_offset
) < net_seg_data_len
)
4942 expert_add_info(pinfo
, epath_item
, &ei_proto_ext_network
);
4946 uint16_t net_seg_subtype
= tvb_get_letohs(tvb
, offset
+ 2);
4948 int data_len_parsed
= 0;
4949 switch (net_seg_subtype
)
4951 case CI_CONCURRENT_EXTENDED_NETWORK_SEG
:
4953 data_len_parsed
= 4;
4954 data_len_parsed
+= dissect_concurrent_connection_network_segment(pinfo
, tvb
, offset
+ data_len_parsed
, net_tree
);
4964 if (net_seg_data_len
- data_len_parsed
> 0)
4966 proto_tree_add_item(net_tree
, hf_cip_data
, tvb
, net_seg_data_offset
+ data_len_parsed
, net_seg_data_len
- data_len_parsed
, ENC_NA
);
4970 return data_words
* 2 + 2;
4973 static int dissect_segment_network_production_inhibit_us(tvbuff_t
*tvb
, int offset
, bool generate
, proto_tree
*net_tree
)
4976 uint32_t inhibit_time
;
4978 data_words
= tvb_get_uint8(tvb
, offset
+ 1);
4979 inhibit_time
= tvb_get_letohl(tvb
, offset
+ 2);
4981 if (generate
== true)
4984 it
= proto_tree_add_uint(net_tree
, hf_cip_seg_network_size
, tvb
, 0, 0, data_words
);
4985 proto_item_set_generated(it
);
4987 it
= proto_tree_add_uint(net_tree
, hf_cip_seg_prod_inhibit_time_us
, tvb
, 0, 0, inhibit_time
);
4988 proto_item_set_generated(it
);
4992 proto_tree_add_item(net_tree
, hf_cip_seg_network_size
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
4993 proto_tree_add_item(net_tree
, hf_cip_seg_prod_inhibit_time_us
,
4994 tvb
, offset
+ 2, 4, ENC_LITTLE_ENDIAN
);
4997 return (data_words
* 2) + 2;
5000 static int dissect_segment_symbolic(tvbuff_t
*tvb
, proto_tree
*path_seg_tree
,
5001 proto_item
*path_seg_item
, proto_item
*epath_item
,
5002 int offset
, bool generate
)
5006 uint8_t symbol_size
;
5008 symbol_size
= tvb_get_uint8(tvb
, offset
) & 0x1F;
5011 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_symbol_size
, tvb
, 0, 0, symbol_size
);
5012 proto_item_set_generated(it
);
5016 proto_tree_add_item(path_seg_tree
, hf_cip_symbol_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5019 if (symbol_size
!= 0)
5022 symbol_name
= tvb_format_text(wmem_packet_scope(), tvb
, offset
+ 1, symbol_size
);
5024 proto_item_append_text(path_seg_item
, " (Symbolic Segment)");
5028 it
= proto_tree_add_string(path_seg_tree
, hf_cip_symbol_ascii
, tvb
, 0, 0, symbol_name
);
5029 proto_item_set_generated(it
);
5033 proto_tree_add_item(path_seg_tree
, hf_cip_symbol_ascii
, tvb
, offset
+ 1, symbol_size
, ENC_ASCII
| ENC_NA
);
5036 proto_item_append_text(epath_item
, "%s", symbol_name
);
5038 seg_size
= symbol_size
+ 1;
5042 /* Extended String */
5043 uint8_t string_format
;
5044 uint8_t string_size
;
5047 proto_item_append_text(path_seg_item
, " (Extended String Symbolic Segment)");
5049 string_format
= tvb_get_uint8(tvb
, offset
+ 1) & CI_SYMBOL_SEG_FORMAT_MASK
;
5050 string_size
= tvb_get_uint8(tvb
, offset
+ 1) & CI_SYMBOL_SEG_SIZE_MASK
;
5054 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_symbol_extended_format
, tvb
, 0, 0, string_format
);
5055 proto_item_set_generated(it
);
5059 proto_tree_add_item(path_seg_tree
, hf_cip_symbol_extended_format
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5062 switch (string_format
)
5064 case CI_SYMBOL_SEG_DOUBLE
:
5065 data_size
= string_size
* 2;
5069 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_symbol_double_size
, tvb
, 0, 0, string_size
);
5070 proto_item_set_generated(it
);
5074 proto_tree_add_item(path_seg_tree
, hf_cip_symbol_double_size
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5075 proto_tree_add_item(path_seg_tree
, hf_cip_data
, tvb
, offset
+ 2, data_size
, ENC_NA
);
5078 proto_item_append_text(epath_item
, "[Data]");
5081 case CI_SYMBOL_SEG_TRIPLE
:
5082 data_size
= string_size
* 3;
5086 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_symbol_triple_size
, tvb
, 0, 0, string_size
);
5087 proto_item_set_generated(it
);
5091 proto_tree_add_item(path_seg_tree
, hf_cip_symbol_triple_size
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5092 proto_tree_add_item(path_seg_tree
, hf_cip_data
, tvb
, offset
+ 2, data_size
, ENC_NA
);
5095 proto_item_append_text(epath_item
, "[Data]");
5098 case CI_SYMBOL_SEG_NUMERIC
:
5100 uint32_t numeric_data
;
5104 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_symbol_numeric_format
, tvb
, 0, 0, string_size
);
5105 proto_item_set_generated(it
);
5109 proto_tree_add_item(path_seg_tree
, hf_cip_symbol_numeric_format
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5112 if (string_size
== CI_SYMBOL_NUMERIC_USINT
)
5115 numeric_data
= tvb_get_uint8(tvb
, offset
+ 2);
5119 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_numeric_usint
, tvb
, 0, 0, numeric_data
);
5120 proto_item_set_generated(it
);
5124 proto_tree_add_item(path_seg_tree
, hf_cip_numeric_usint
, tvb
, offset
+ 2, 1, ENC_LITTLE_ENDIAN
);
5127 else if (string_size
== CI_SYMBOL_NUMERIC_UINT
)
5130 numeric_data
= tvb_get_letohs(tvb
, offset
+ 2);
5134 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_numeric_uint
, tvb
, 0, 0, numeric_data
);
5135 proto_item_set_generated(it
);
5139 proto_tree_add_item(path_seg_tree
, hf_cip_numeric_uint
, tvb
, offset
+ 2, 2, ENC_LITTLE_ENDIAN
);
5142 else if (string_size
== CI_SYMBOL_NUMERIC_UDINT
)
5145 numeric_data
= tvb_get_letohl(tvb
, offset
+ 2);
5149 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_numeric_udint
, tvb
, 0, 0, numeric_data
);
5150 proto_item_set_generated(it
);
5154 proto_tree_add_item(path_seg_tree
, hf_cip_numeric_udint
, tvb
, offset
+ 2, 4, ENC_LITTLE_ENDIAN
);
5159 /* Unknown Extended String Format. */
5163 proto_item_append_text(epath_item
, "0x%x", numeric_data
);
5168 /* Unknown Extended String Format. */
5172 seg_size
= 2 + data_size
;
5176 seg_size
+= seg_size
% 2;
5181 static int dissect_segment_port(tvbuff_t
* tvb
, int offset
, bool generate
,
5182 proto_tree
* path_seg_tree
, proto_item
* path_seg_item
, proto_item
* epath_item
)
5184 int segment_len
= 0;
5185 bool extended_port
= false;
5186 int extended_port_offset
= 0;
5187 uint8_t segment_type
= tvb_get_uint8(tvb
, offset
);
5189 /* Add Extended Link Address flag & Port Identifier*/
5192 proto_item
* it
= proto_tree_add_boolean(path_seg_tree
, hf_cip_port_ex_link_addr
, tvb
, 0, 0, segment_type
& CI_PORT_SEG_EX_LINK_ADDRESS
);
5193 proto_item_set_generated(it
);
5194 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_port
, tvb
, 0, 0, (segment_type
& CI_PORT_SEG_PORT_ID_MASK
));
5195 proto_item_set_generated(it
);
5199 proto_tree_add_item(path_seg_tree
, hf_cip_port_ex_link_addr
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5200 proto_tree_add_item(path_seg_tree
, hf_cip_port
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5203 uint8_t port_id
= segment_type
& CI_PORT_SEG_PORT_ID_MASK
;
5206 extended_port
= true;
5209 proto_item_append_text(path_seg_item
, " (Port Segment)");
5211 const char *port_name
= try_val_to_str(port_id
, cip_port_number_vals
);
5214 proto_item_append_text(epath_item
, "Port: %s", port_name
);
5218 proto_item_append_text(epath_item
, "Port: %d", port_id
);
5221 if (segment_type
& CI_PORT_SEG_EX_LINK_ADDRESS
)
5223 int offset_link_address
= 2;
5225 if (extended_port
== true)
5227 offset_link_address
+= 2;
5228 extended_port_offset
= offset
+ 2;
5231 uint8_t opt_link_size
= tvb_get_uint8(tvb
, offset
+ 1);
5235 /* Add size of extended link address */
5236 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_link_address_size
, tvb
, 0, 0, opt_link_size
);
5237 proto_item_set_generated(it
);
5238 /* Add extended link address */
5239 it
= proto_tree_add_string(path_seg_tree
, hf_cip_link_address_string
, tvb
, 0, 0, tvb_format_text(wmem_packet_scope(), tvb
, offset
+ offset_link_address
, opt_link_size
));
5240 proto_item_set_generated(it
);
5244 proto_tree_add_item(path_seg_tree
, hf_cip_link_address_size
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5245 proto_tree_add_item(path_seg_tree
, hf_cip_link_address_string
, tvb
, offset
+ offset_link_address
, opt_link_size
, ENC_ASCII
| ENC_NA
);
5248 proto_item_append_text(epath_item
, ", Address: %s", tvb_format_text(wmem_packet_scope(), tvb
, offset
+ offset_link_address
, opt_link_size
));
5251 if (opt_link_size
% 2)
5253 segment_len
= 1 + offset_link_address
+ opt_link_size
;
5257 segment_len
= offset_link_address
+ opt_link_size
;
5262 int offset_link_address
= 1;
5266 if (extended_port
== true)
5269 offset_link_address
+= 2;
5270 extended_port_offset
= offset
+ 1;
5273 /* Add Link Address */
5276 uint8_t link_address_byte
= tvb_get_uint8(tvb
, offset
+ offset_link_address
);
5277 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_link_address_byte
, tvb
, 0, 0, link_address_byte
);
5278 proto_item_set_generated(it
);
5282 proto_tree_add_item(path_seg_tree
, hf_cip_link_address_byte
, tvb
, offset
+ offset_link_address
, 1, ENC_LITTLE_ENDIAN
);
5285 proto_item_append_text(epath_item
, ", Address: %d", tvb_get_uint8(tvb
, offset
+ offset_link_address
));
5288 if (extended_port
== true)
5292 uint16_t port_extended
= tvb_get_letohs(tvb
, extended_port_offset
);
5293 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_port_extended
, tvb
, 0, 0, port_extended
);
5294 proto_item_set_generated(it
);
5298 proto_tree_add_item(path_seg_tree
, hf_cip_port_extended
, tvb
, extended_port_offset
, 2, ENC_LITTLE_ENDIAN
);
5302 if (generate
== false)
5304 proto_item_set_len(path_seg_item
, segment_len
);
5310 static int dissect_segment_safety(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, bool generate
,
5311 proto_tree
* net_tree
, cip_safety_epath_info_t
* safety
, cip_simple_request_info_t
* req_data
)
5313 uint16_t seg_size
= tvb_get_uint8(tvb
, offset
+ 1) * 2;
5314 int segment_len
= seg_size
+ 2;
5316 uint32_t safety_format
;
5319 safety_format
= tvb_get_uint8(tvb
, offset
+ 2);
5321 proto_item
* it
= proto_tree_add_uint(net_tree
, hf_cip_seg_network_size
, tvb
, 0, 0, seg_size
/ 2);
5322 proto_item_set_generated(it
);
5324 it
= proto_tree_add_uint(net_tree
, hf_cip_seg_safety_format
, tvb
, 0, 0, safety_format
);
5325 proto_item_set_generated(it
);
5327 /* Skip printing further information in response packets. */
5332 proto_tree_add_item(net_tree
, hf_cip_seg_network_size
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5333 proto_tree_add_item_ret_uint(net_tree
, hf_cip_seg_safety_format
, tvb
, offset
+ 2, 1, ENC_LITTLE_ENDIAN
, &safety_format
);
5336 /* Safety Network Segment Format */
5337 if (safety_format
< 3)
5339 cip_connID_info_t ignore
;
5340 proto_tree
* safety_tree
= proto_tree_add_subtree(net_tree
, tvb
, offset
+ 3, seg_size
- 1,
5341 ett_network_seg_safety
, NULL
, val_to_str_const(safety_format
, cip_safety_segment_format_type_vals
, "Reserved"));
5343 bool has_scid
= false;
5344 uint32_t ntem_value
= 0;
5345 switch (safety_format
)
5351 /* Target Format - Deprecated*/
5353 safety
->format
= CIP_SAFETY_BASE_FORMAT
;
5355 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_reserved
, tvb
, offset
+ 3, 1, ENC_LITTLE_ENDIAN
);
5356 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_configuration_crc
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
);
5357 dissect_cipsafety_snn(safety_tree
, tvb
, pinfo
, offset
+ 8,
5358 hf_cip_seg_safety_configuration_timestamp
, hf_cip_seg_safety_configuration_date
, hf_cip_seg_safety_configuration_time
);
5359 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_correction_epi
, tvb
, offset
+ 14, 4, ENC_LITTLE_ENDIAN
);
5360 dissect_net_param16(tvb
, offset
+ 18, safety_tree
,
5361 hf_cip_seg_safety_time_correction_net_params
, hf_cip_seg_safety_time_correction_own
,
5362 hf_cip_seg_safety_time_correction_typ
, hf_cip_seg_safety_time_correction_prio
,
5363 hf_cip_seg_safety_time_correction_fixed_var
, hf_cip_seg_safety_time_correction_con_size
,
5364 ett_network_seg_safety_time_correction_net_params
, &ignore
);
5365 proto_item
* it
= proto_tree_add_item(safety_tree
, hf_cip_seg_safety_tunid
, tvb
, offset
+ 20, 10, ENC_NA
);
5366 dissect_unid(tvb
, pinfo
, offset
+ 20, it
, "Target UNID SNN", hf_cip_seg_safety_tunid_snn_timestamp
,
5367 hf_cip_seg_safety_tunid_snn_date
, hf_cip_seg_safety_tunid_snn_time
, hf_cip_seg_safety_tunid_nodeid
,
5368 ett_cip_seg_safety_tunid
, ett_cip_seg_safety_tunid_snn
);
5369 it
= proto_tree_add_item(safety_tree
, hf_cip_seg_safety_ounid
, tvb
, offset
+ 30, 10, ENC_NA
);
5370 dissect_unid(tvb
, pinfo
, offset
+ 30, it
, "Originator UNID SNN", hf_cip_seg_safety_ounid_snn_timestamp
,
5371 hf_cip_seg_safety_ounid_snn_date
, hf_cip_seg_safety_ounid_snn_time
, hf_cip_seg_safety_ounid_nodeid
,
5372 ett_cip_seg_safety_ounid
, ett_cip_seg_safety_ounid_snn
);
5373 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_ping_epi_multiplier
, tvb
, offset
+ 40, 2, ENC_LITTLE_ENDIAN
);
5374 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_coord_msg_min_multiplier
, tvb
, offset
+ 42, 2, ENC_LITTLE_ENDIAN
);
5375 proto_tree_add_item_ret_uint(safety_tree
, hf_cip_seg_safety_network_time_expected_multiplier
, tvb
, offset
+ 44, 2, ENC_LITTLE_ENDIAN
, &ntem_value
);
5376 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_timeout_multiplier
, tvb
, offset
+ 46, 1, ENC_LITTLE_ENDIAN
);
5377 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_max_consumer_number
, tvb
, offset
+ 47, 1, ENC_LITTLE_ENDIAN
);
5378 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_conn_param_crc
, tvb
, offset
+ 48, 4, ENC_LITTLE_ENDIAN
);
5379 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_correction_conn_id
, tvb
, offset
+ 52, 4, ENC_LITTLE_ENDIAN
);
5385 safety
->format
= CIP_SAFETY_BASE_FORMAT
;
5387 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_reserved
, tvb
, offset
+ 3, 1, ENC_LITTLE_ENDIAN
);
5388 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_correction_conn_id
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
);
5389 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_correction_epi
, tvb
, offset
+ 8, 4, ENC_LITTLE_ENDIAN
);
5390 dissect_net_param16(tvb
, offset
+ 12, safety_tree
,
5391 hf_cip_seg_safety_time_correction_net_params
, hf_cip_seg_safety_time_correction_own
,
5392 hf_cip_seg_safety_time_correction_typ
, hf_cip_seg_safety_time_correction_prio
,
5393 hf_cip_seg_safety_time_correction_fixed_var
, hf_cip_seg_safety_time_correction_con_size
,
5394 ett_network_seg_safety_time_correction_net_params
, &ignore
);
5400 /* Extended Format */
5402 safety
->format
= CIP_SAFETY_EXTENDED_FORMAT
;
5404 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_reserved
, tvb
, offset
+ 3, 1, ENC_LITTLE_ENDIAN
);
5405 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_configuration_crc
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
);
5406 dissect_cipsafety_snn(safety_tree
, tvb
, pinfo
, offset
+ 8,
5407 hf_cip_seg_safety_configuration_timestamp
, hf_cip_seg_safety_configuration_date
, hf_cip_seg_safety_configuration_time
);
5408 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_correction_epi
, tvb
, offset
+ 14, 4, ENC_LITTLE_ENDIAN
);
5409 dissect_net_param16(tvb
, offset
+ 18, safety_tree
,
5410 hf_cip_seg_safety_time_correction_net_params
, hf_cip_seg_safety_time_correction_own
,
5411 hf_cip_seg_safety_time_correction_typ
, hf_cip_seg_safety_time_correction_prio
,
5412 hf_cip_seg_safety_time_correction_fixed_var
, hf_cip_seg_safety_time_correction_con_size
,
5413 ett_network_seg_safety_time_correction_net_params
, &ignore
);
5414 proto_item
* it
= proto_tree_add_item(safety_tree
, hf_cip_seg_safety_tunid
, tvb
, offset
+ 20, 10, ENC_NA
);
5415 dissect_unid(tvb
, pinfo
, offset
+ 20, it
, "Target UNID SNN", hf_cip_seg_safety_tunid_snn_timestamp
,
5416 hf_cip_seg_safety_tunid_snn_date
, hf_cip_seg_safety_tunid_snn_time
, hf_cip_seg_safety_tunid_nodeid
,
5417 ett_cip_seg_safety_tunid
, ett_cip_seg_safety_tunid_snn
);
5418 it
= proto_tree_add_item(safety_tree
, hf_cip_seg_safety_ounid
, tvb
, offset
+ 30, 10, ENC_NA
);
5419 dissect_unid(tvb
, pinfo
, offset
+ 30, it
, "Originator UNID SNN", hf_cip_seg_safety_ounid_snn_timestamp
,
5420 hf_cip_seg_safety_ounid_snn_date
, hf_cip_seg_safety_ounid_snn_time
, hf_cip_seg_safety_ounid_nodeid
,
5421 ett_cip_seg_safety_ounid
, ett_cip_seg_safety_ounid_snn
);
5422 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_ping_epi_multiplier
, tvb
, offset
+ 40, 2, ENC_LITTLE_ENDIAN
);
5423 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_coord_msg_min_multiplier
, tvb
, offset
+ 42, 2, ENC_LITTLE_ENDIAN
);
5424 proto_tree_add_item_ret_uint(safety_tree
, hf_cip_seg_safety_network_time_expected_multiplier
, tvb
, offset
+ 44, 2, ENC_LITTLE_ENDIAN
, &ntem_value
);
5425 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_timeout_multiplier
, tvb
, offset
+ 46, 1, ENC_LITTLE_ENDIAN
);
5426 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_max_consumer_number
, tvb
, offset
+ 47, 1, ENC_LITTLE_ENDIAN
);
5427 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_max_fault_number
, tvb
, offset
+ 48, 2, ENC_LITTLE_ENDIAN
);
5428 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_conn_param_crc
, tvb
, offset
+ 50, 4, ENC_LITTLE_ENDIAN
);
5429 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_time_correction_conn_id
, tvb
, offset
+ 54, 4, ENC_LITTLE_ENDIAN
);
5430 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_init_timestamp
, tvb
, offset
+ 58, 2, ENC_LITTLE_ENDIAN
);
5431 proto_tree_add_item(safety_tree
, hf_cip_seg_safety_init_rollover
, tvb
, offset
+ 60, 2, ENC_LITTLE_ENDIAN
);
5436 if (safety
&& req_data
&& has_scid
)
5438 // Check if the SCID (SCCRC + SCTS) is all zeros.
5439 uint32_t sccrc_value
= tvb_get_letohl(tvb
, offset
+ 4);
5440 uint64_t scts_value
= tvb_get_letoh48(tvb
, offset
+ 8);
5441 bool scid_zero
= (sccrc_value
== 0) && (scts_value
== 0);
5443 if (req_data
->hasSimpleData
)
5445 safety
->safety_open_type
= CIP_SAFETY_OPEN_TYPE1
;
5449 safety
->safety_open_type
= CIP_SAFETY_OPEN_TYPE2B
;
5453 safety
->safety_open_type
= CIP_SAFETY_OPEN_TYPE2A
;
5459 safety
->nte_value_ms
= ntem_value
* 0.128f
;
5464 proto_tree_add_item(net_tree
, hf_cip_seg_safety_data
, tvb
, offset
+ 3, seg_size
- 1, ENC_NA
);
5469 safety
->safety_seg
= true;
5475 static int dissect_segment_data_simple(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, bool generate
,
5476 proto_tree
* path_seg_tree
, proto_item
* path_seg_item
, cip_simple_request_info_t
* req_data
)
5480 req_data
->hasSimpleData
= true;
5483 uint16_t seg_size
= tvb_get_uint8(tvb
, offset
+ 1) * 2;
5484 int segment_len
= seg_size
+ 2;
5488 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_data_seg_size_simple
, tvb
, 0, 0, seg_size
/ 2);
5489 proto_item_set_generated(it
);
5493 proto_tree_add_item(path_seg_tree
, hf_cip_data_seg_size_simple
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5504 int parsed_data_len
= 0;
5505 if (req_data
&& req_data
->iClass
== CI_CLS_MOTION
5506 && req_data
->iConnPointA
!= SEGMENT_VALUE_NOT_SET
5507 && req_data
->iConnPoint
!= SEGMENT_VALUE_NOT_SET
)
5509 parsed_data_len
+= dissect_motion_configuration_block(tvb
, pinfo
, path_seg_tree
, path_seg_item
, offset
+ 2);
5512 int remaining_data_len
= seg_size
- parsed_data_len
;
5513 if (remaining_data_len
> 0)
5515 proto_tree_add_item(path_seg_tree
, hf_cip_data_seg_item
, tvb
, offset
+ 2 + parsed_data_len
, remaining_data_len
, ENC_NA
);
5519 proto_item_set_len(path_seg_item
, segment_len
);
5524 static int dissect_segment_ansi_extended_symbol(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
5525 bool generate
, proto_tree
* path_seg_tree
, proto_item
* path_seg_item
,
5526 proto_item
* epath_item
, int display_type
,
5527 bool is_msp_item
, proto_item
* msp_item
)
5530 uint16_t seg_size
= tvb_get_uint8(tvb
, offset
+ 1);
5533 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_data_seg_size_extended
, tvb
, 0, 0, seg_size
);
5534 proto_item_set_generated(it
);
5537 proto_tree_add_item(path_seg_tree
, hf_cip_data_seg_size_extended
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5542 char* symbol_name
= tvb_format_text(pinfo
->pool
, tvb
, offset
+ 2, seg_size
);
5546 proto_item
* it
= proto_tree_add_string(path_seg_tree
, hf_cip_symbol
, tvb
, 0, 0, symbol_name
);
5547 proto_item_set_generated(it
);
5550 proto_tree_add_item(path_seg_tree
, hf_cip_symbol
, tvb
, offset
+ 2, seg_size
, ENC_ASCII
| ENC_NA
);
5552 proto_item_append_text(epath_item
, "%s", symbol_name
);
5554 if (cip_enhanced_info_column
== true && is_msp_item
== false)
5556 add_cip_symbol_to_info_column(pinfo
, symbol_name
, display_type
);
5559 if (msp_item
!= NULL
)
5561 proto_item_append_text(msp_item
, "'%s' - ", symbol_name
);
5565 /* Check for pad byte */
5571 proto_item_set_len(path_seg_item
, 2 + seg_size
);
5574 return 2 + seg_size
;
5577 // offset - Starts with the 'Key Data' section of the Electronic Key Segment Format.
5578 int dissect_electronic_key_format(tvbuff_t
* tvb
, int offset
, proto_tree
* tree
, bool generate
, uint8_t key_format
, unsigned encoding
)
5581 if (key_format
== CI_E_KEY_FORMAT_VAL
)
5585 else // CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL
5592 dissect_deviceid(tvb
, offset
, tree
,
5593 hf_cip_ekey_vendor
, hf_cip_ekey_devtype
, hf_cip_ekey_prodcode
,
5594 hf_cip_ekey_compatibility
, hf_cip_ekey_comp_bit
, hf_cip_ekey_majorrev
, hf_cip_ekey_minorrev
, true, encoding
);
5598 dissect_deviceid(tvb
, offset
, tree
,
5599 hf_cip_ekey_vendor
, hf_cip_ekey_devtype
, hf_cip_ekey_prodcode
,
5600 hf_cip_ekey_compatibility
, hf_cip_ekey_comp_bit
, hf_cip_ekey_majorrev
, hf_cip_ekey_minorrev
, false, encoding
);
5602 if (key_format
== CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL
)
5604 proto_tree_add_item(tree
, hf_cip_ekey_serial_number
, tvb
, offset
+ 8, 4, encoding
);
5611 static int dissect_segment_logical_special(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
5612 bool generate
, proto_tree
* path_seg_tree
,
5613 proto_item
* path_seg_item
, proto_item
* epath_item
)
5615 int segment_len
= 0;
5617 uint8_t segment_type
= tvb_get_uint8(tvb
, offset
);
5619 /* Logical Special ID, the only logical format specified is electronic key */
5620 if ((segment_type
& CI_LOGICAL_SEG_FORMAT_MASK
) == CI_LOGICAL_SEG_E_KEY
)
5622 uint8_t key_format
= tvb_get_uint8(tvb
, offset
+ 1);
5623 if (key_format
== CI_E_KEY_FORMAT_VAL
|| key_format
== CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL
)
5627 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_ekey_format
, tvb
, 0, 0, key_format
);
5628 proto_item_set_generated(it
);
5632 proto_tree_add_item(path_seg_tree
, hf_cip_ekey_format
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5636 segment_len
+= dissect_electronic_key_format(tvb
, offset
+ 2, path_seg_tree
, generate
, key_format
, ENC_LITTLE_ENDIAN
);
5638 proto_item_set_len(path_seg_item
, segment_len
);
5640 /* Add "summary" information to parent item */
5641 uint16_t vendor_id
= tvb_get_letohs(tvb
, offset
+ 2);
5642 proto_item_append_text(path_seg_tree
, " (VendorID: 0x%04X", vendor_id
);
5644 uint16_t device_type
= tvb_get_letohs(tvb
, offset
+ 4);
5645 proto_item_append_text(path_seg_tree
, ", DevTyp: 0x%04X", device_type
);
5647 uint8_t major_rev
= tvb_get_uint8(tvb
, offset
+ 8);
5648 uint8_t minor_rev
= tvb_get_uint8(tvb
, offset
+ 9);
5650 proto_item_append_text(path_seg_tree
, ", %d.%d)", (major_rev
& 0x7F), minor_rev
);
5651 proto_item_append_text(epath_item
, "[Key]");
5655 expert_add_info(pinfo
, epath_item
, &ei_proto_electronic_key_format
);
5660 expert_add_info(pinfo
, epath_item
, &ei_proto_special_segment_format
);
5666 static int dissect_segment_network(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
5667 bool generate
, proto_tree
* path_seg_tree
, proto_item
* path_seg_item
,
5668 proto_item
* epath_item
, int display_type
, cip_safety_epath_info_t
* safety
,
5669 cip_simple_request_info_t
* req_data
)
5671 int segment_len
= 0;
5673 uint8_t segment_type
= tvb_get_uint8(tvb
, offset
);
5675 /* Network segment -Determine the segment sub-type */
5678 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_network_seg_type
, tvb
, 0, 0, segment_type
& CI_NETWORK_SEG_TYPE_MASK
);
5679 proto_item_set_generated(it
);
5683 proto_tree_add_item(path_seg_tree
, hf_cip_network_seg_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5686 proto_item_append_text(path_seg_item
, " (%s)", val_to_str_const((segment_type
& CI_NETWORK_SEG_TYPE_MASK
), cip_network_segment_type_vals
, "Reserved"));
5688 switch (segment_type
& CI_NETWORK_SEG_TYPE_MASK
)
5690 case CI_NETWORK_SEG_SCHEDULE
:
5693 uint8_t schedule
= tvb_get_uint8(tvb
, offset
+ 1);
5694 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_seg_schedule
, tvb
, 0, 0, schedule
);
5695 proto_item_set_generated(it
);
5699 proto_tree_add_item(path_seg_tree
, hf_cip_seg_schedule
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5705 case CI_NETWORK_SEG_FIXED_TAG
:
5708 uint8_t fixed_tag
= tvb_get_uint8(tvb
, offset
+ 1);
5709 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_seg_fixed_tag
, tvb
, 0, 0, fixed_tag
);
5710 proto_item_set_generated(it
);
5714 proto_tree_add_item(path_seg_tree
, hf_cip_seg_fixed_tag
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5720 case CI_NETWORK_SEG_PROD_INHI
:
5723 uint8_t inhibit_time
= tvb_get_uint8(tvb
, offset
+ 1);
5724 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_seg_prod_inhibit_time
, tvb
, 0, 0, inhibit_time
);
5725 proto_item_set_generated(it
);
5729 proto_tree_add_item(path_seg_tree
, hf_cip_seg_prod_inhibit_time
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5735 case CI_NETWORK_SEG_PROD_INHI_US
:
5736 segment_len
= dissect_segment_network_production_inhibit_us(tvb
, offset
, generate
, path_seg_tree
);
5739 case CI_NETWORK_SEG_EXTENDED
:
5740 segment_len
= dissect_segment_network_extended(pinfo
, epath_item
, tvb
, offset
, generate
, path_seg_tree
);
5741 proto_item_append_text(epath_item
, "[Network]");
5744 case CI_NETWORK_SEG_SAFETY
:
5745 proto_item_append_text(epath_item
, "[Safety]");
5747 if (display_type
== DISPLAY_CONNECTION_PATH
)
5749 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Safety]");
5752 segment_len
= dissect_segment_safety(pinfo
, tvb
, offset
, generate
, path_seg_tree
, safety
, req_data
);
5756 expert_add_info(pinfo
, epath_item
, &ei_proto_log_sub_seg_type
);
5759 } /* End of switch sub-type */
5761 if (generate
== false)
5763 proto_item_set_len(path_seg_item
, segment_len
);
5769 static int dissect_segment_logical_service_id(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
5770 bool generate
, proto_tree
* path_seg_tree
, proto_item
* path_seg_item
, proto_item
* epath_item
)
5772 int segment_len
= 0;
5774 uint8_t segment_type
= tvb_get_uint8(tvb
, offset
);
5776 /* Logical Service ID - the only logical format specified is 8-bit Service ID */
5777 if ((segment_type
& CI_LOGICAL_SEG_FORMAT_MASK
) == CI_LOGICAL_SEG_8_BIT
)
5779 uint8_t service_id
= tvb_get_uint8(tvb
, offset
+ 1);
5783 proto_item
* it
= proto_tree_add_uint(path_seg_tree
, hf_cip_serviceid8
, tvb
, 0, 0, service_id
);
5784 proto_item_set_generated(it
);
5788 proto_tree_add_item(path_seg_tree
, hf_cip_serviceid8
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
5790 proto_item_set_len(path_seg_item
, 2);
5793 proto_item_append_text(epath_item
, "Service ID: 0x%x", service_id
);
5799 expert_add_info(pinfo
, epath_item
, &ei_proto_log_seg_type
);
5805 int dissect_cip_segment_single(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
, proto_tree
*path_tree
, proto_item
*epath_item
,
5806 bool generate
, bool packed
, cip_simple_request_info_t
* req_data
, cip_safety_epath_info_t
* safety
,
5807 int display_type
, proto_item
*msp_item
,
5810 int segment_len
= 0;
5811 unsigned char segment_type
;
5812 proto_tree
*path_seg_tree
;
5813 proto_item
*it
, *cia_ret_item
;
5814 proto_item
*path_seg_item
;
5817 if (tvb_reported_length_remaining(tvb
, offset
) <= 0)
5819 expert_add_info(pinfo
, epath_item
, &ei_mal_incomplete_epath
);
5823 /* Get segment type */
5824 segment_type
= tvb_get_uint8( tvb
, offset
);
5828 path_seg_item
= proto_tree_add_uint(path_tree
, hf_cip_path_segment
, tvb
, 0, 0, segment_type
);
5829 proto_item_set_generated(path_seg_item
);
5830 path_seg_tree
= proto_item_add_subtree( path_seg_item
, ett_path_seg
);
5831 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_path_segment_type
, tvb
, 0, 0, segment_type
&CI_SEGMENT_TYPE_MASK
);
5832 proto_item_set_generated(it
);
5836 path_seg_item
= proto_tree_add_item(path_tree
, hf_cip_path_segment
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5837 path_seg_tree
= proto_item_add_subtree( path_seg_item
, ett_path_seg
);
5838 proto_tree_add_item(path_seg_tree
, hf_cip_path_segment_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5841 /* Determine the segment type */
5843 switch( segment_type
& CI_SEGMENT_TYPE_MASK
)
5845 case CI_PORT_SEGMENT
:
5847 segment_len
= dissect_segment_port(tvb
, offset
, generate
, path_seg_tree
, path_seg_item
, epath_item
);
5851 case CI_LOGICAL_SEGMENT
:
5853 uint8_t logical_seg_type
;
5854 logical_seg_type
= segment_type
& CI_LOGICAL_SEG_TYPE_MASK
;
5856 /* Logical segment, determine the logical type */
5859 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_logical_seg_type
, tvb
, 0, 0, logical_seg_type
);
5860 proto_item_set_generated(it
);
5861 if (logical_seg_type
!= CI_LOGICAL_SEG_SPECIAL
&& logical_seg_type
!= CI_LOGICAL_SEG_SERV_ID
)
5863 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_logical_seg_format
, tvb
, 0, 0, segment_type
& CI_LOGICAL_SEG_FORMAT_MASK
);
5864 proto_item_set_generated(it
);
5869 proto_tree_add_item(path_seg_tree
, hf_cip_logical_seg_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5870 if (logical_seg_type
!= CI_LOGICAL_SEG_SPECIAL
&& logical_seg_type
!= CI_LOGICAL_SEG_SERV_ID
)
5871 proto_tree_add_item(path_seg_tree
, hf_cip_logical_seg_format
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
5874 proto_item_append_text( path_seg_item
, " (%s)", val_to_str_const( ((segment_type
& (CI_LOGICAL_SEG_TYPE_MASK
|CI_LOGICAL_SEG_FORMAT_MASK
))), cip_logical_seg_vals
, "Reserved"));
5876 switch (logical_seg_type
)
5878 case CI_LOGICAL_SEG_CLASS_ID
:
5881 segment_len
= dissect_cia(tvb
, offset
, segment_type
, generate
, packed
, pinfo
,
5882 epath_item
, path_seg_tree
, path_seg_item
, &cia_ret_item
,
5883 "Class", cip_class_names_vals
, &ClassID
,
5884 hf_cip_class8
, hf_cip_class16
, hf_cip_class32
);
5885 if (segment_len
== 0)
5892 req_data
->iClass
= ClassID
;
5894 // Save the first ClassID separately.
5895 if (req_data
->iClassA
== SEGMENT_VALUE_NOT_SET
)
5897 req_data
->iClassA
= ClassID
;
5901 if (req_data
!= NULL
)
5903 if (cip_enhanced_info_column
== true && is_msp_item
== false)
5905 add_cip_class_to_info_column(pinfo
, req_data
->iClass
, display_type
);
5908 if (msp_item
!= NULL
)
5910 proto_item_append_text(msp_item
, "%s - ", val_to_str(req_data
->iClass
, cip_class_names_vals
, "Class (0x%02x)"));
5917 case CI_LOGICAL_SEG_INST_ID
:
5919 uint32_t InstanceID
;
5920 segment_len
= dissect_cia(tvb
, offset
, segment_type
, generate
, packed
, pinfo
,
5921 epath_item
, path_seg_tree
, path_seg_item
, &cia_ret_item
,
5922 "Instance", NULL
, &InstanceID
,
5923 hf_cip_instance8
, hf_cip_instance16
, hf_cip_instance32
);
5924 if (segment_len
== 0)
5931 req_data
->iInstance
= InstanceID
;
5933 // Save the first InstanceID separately.
5934 if (req_data
->iInstanceA
== SEGMENT_VALUE_NOT_SET
)
5936 req_data
->iInstanceA
= InstanceID
;
5943 case CI_LOGICAL_SEG_MBR_ID
:
5944 segment_len
= dissect_cia(tvb
, offset
, segment_type
, generate
, packed
, pinfo
,
5945 epath_item
, path_seg_tree
, path_seg_item
, &cia_ret_item
,
5946 "Member", NULL
, (req_data
== NULL
) ? NULL
: &req_data
->iMember
,
5947 hf_cip_member8
, hf_cip_member16
, hf_cip_member32
);
5950 case CI_LOGICAL_SEG_ATTR_ID
:
5951 segment_len
= dissect_cia(tvb
, offset
, segment_type
, generate
, packed
, pinfo
,
5952 epath_item
, path_seg_tree
, path_seg_item
, &cia_ret_item
,
5953 "Attribute", NULL
, (req_data
== NULL
) ? NULL
: &req_data
->iAttribute
,
5954 hf_cip_attribute8
, hf_cip_attribute16
, hf_cip_attribute32
);
5955 if (segment_len
== 0)
5960 if (req_data
!= NULL
)
5962 const attribute_info_t
* att_info
= cip_get_attribute(req_data
->iClass
, req_data
->iInstance
,
5963 req_data
->iAttribute
);
5964 if (att_info
!= NULL
)
5966 proto_item_append_text(cia_ret_item
, " (%s)", att_info
->text
);
5967 proto_item_append_text(epath_item
, " (%s)", att_info
->text
);
5972 case CI_LOGICAL_SEG_CON_POINT
:
5975 segment_len
= dissect_cia(tvb
, offset
, segment_type
, generate
, packed
, pinfo
,
5976 epath_item
, path_seg_tree
, path_seg_item
, &cia_ret_item
,
5977 "Connection Point", NULL
, &ConnPoint
,
5978 hf_cip_conpoint8
, hf_cip_conpoint16
, hf_cip_conpoint32
);
5979 if (segment_len
== 0)
5986 req_data
->iConnPoint
= ConnPoint
;
5988 // Save the first ConnPoint separately.
5989 if (req_data
->iConnPointA
== SEGMENT_VALUE_NOT_SET
)
5991 req_data
->iConnPointA
= ConnPoint
;
5998 case CI_LOGICAL_SEG_SPECIAL
:
5999 segment_len
= dissect_segment_logical_special(pinfo
, tvb
, offset
, generate
,
6000 path_seg_tree
, path_seg_item
, epath_item
);
6003 case CI_LOGICAL_SEG_SERV_ID
:
6004 segment_len
= dissect_segment_logical_service_id(pinfo
, tvb
, offset
, generate
,
6005 path_seg_tree
, path_seg_item
, epath_item
);
6008 case CI_LOGICAL_SEG_EXT_LOGICAL
:
6009 segment_len
= dissect_cia(tvb
, offset
, segment_type
, generate
, packed
, pinfo
,
6010 epath_item
, path_seg_tree
, path_seg_item
, &cia_ret_item
,
6011 "Extended Logical", NULL
, NULL
,
6012 hf_cip_ext_logical8
, hf_cip_ext_logical16
, hf_cip_ext_logical32
);
6016 expert_add_info(pinfo
, epath_item
, &ei_proto_log_seg_type
);
6019 } /* end of switch( logical_seg_type ) */
6023 case CI_DATA_SEGMENT
:
6025 /* Data segment, determine the logical type */
6028 it
= proto_tree_add_uint(path_seg_tree
, hf_cip_data_seg_type
, tvb
, 0, 0, segment_type
& CI_DATA_SEG_TYPE_MASK
);
6029 proto_item_set_generated(it
);
6033 proto_tree_add_item(path_seg_tree
, hf_cip_data_seg_type
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
6036 proto_item_append_text( path_seg_item
, " (%s)", val_to_str_const( (segment_type
& CI_DATA_SEG_TYPE_MASK
), cip_data_segment_type_vals
, "Reserved"));
6038 switch( segment_type
& CI_DATA_SEG_TYPE_MASK
)
6040 case CI_DATA_SEG_SIMPLE
:
6041 segment_len
= dissect_segment_data_simple(pinfo
, tvb
, offset
, generate
, path_seg_tree
, path_seg_item
, req_data
);
6042 proto_item_append_text(epath_item
, "[Data]" );
6045 case CI_DATA_SEG_SYMBOL
:
6046 segment_len
= dissect_segment_ansi_extended_symbol(pinfo
, tvb
, offset
, generate
,
6047 path_seg_tree
, path_seg_item
, epath_item
, display_type
, is_msp_item
, msp_item
);
6051 expert_add_info(pinfo
, epath_item
, &ei_proto_log_sub_seg_type
);
6054 } /* End of switch sub-type */
6059 case CI_NETWORK_SEGMENT
:
6060 segment_len
= dissect_segment_network(pinfo
, tvb
, offset
, generate
, path_seg_tree
, path_seg_item
, epath_item
, display_type
, safety
, req_data
);
6063 case CI_SYMBOLIC_SEGMENT
:
6065 segment_len
= dissect_segment_symbolic(tvb
, path_seg_tree
,
6066 path_seg_item
, epath_item
,
6069 if (segment_len
== 0)
6071 expert_add_info(pinfo
, epath_item
, &ei_proto_ext_string_format
);
6075 if (generate
== false)
6077 proto_item_set_len(path_seg_item
, segment_len
);
6084 expert_add_info(pinfo
, epath_item
, &ei_proto_seg_type
);
6087 } /* end of switch( segment_type & CI_SEGMENT_TYPE_MASK ) */
6093 void reset_cip_request_info(cip_simple_request_info_t
* req_data
)
6095 req_data
->iClass
= SEGMENT_VALUE_NOT_SET
;
6096 req_data
->iClassA
= SEGMENT_VALUE_NOT_SET
;
6098 req_data
->iInstance
= SEGMENT_VALUE_NOT_SET
;
6099 req_data
->iInstanceA
= SEGMENT_VALUE_NOT_SET
;
6101 req_data
->iAttribute
= SEGMENT_VALUE_NOT_SET
;
6102 req_data
->iMember
= SEGMENT_VALUE_NOT_SET
;
6104 req_data
->iConnPoint
= SEGMENT_VALUE_NOT_SET
;
6105 req_data
->iConnPointA
= SEGMENT_VALUE_NOT_SET
;
6107 req_data
->hasSimpleData
= false;
6110 void dissect_epath(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*path_tree
, proto_item
*epath_item
, int offset
, int path_length
,
6111 bool generate
, bool packed
, cip_simple_request_info_t
* req_data
, cip_safety_epath_info_t
* safety
,
6112 int display_type
, proto_item
*msp_item
,
6116 proto_item
*hidden_item
;
6118 if (req_data
!= NULL
)
6120 reset_cip_request_info(req_data
);
6124 safety
->safety_seg
= false;
6128 hidden_item
= proto_tree_add_item(path_tree
, hf_cip_epath
,
6129 tvb
, offset
, path_length
, ENC_NA
);
6130 proto_item_set_hidden(hidden_item
);
6133 while( pathpos
< path_length
)
6136 segment_len
= dissect_cip_segment_single(pinfo
, tvb
, offset
+ pathpos
, path_tree
, epath_item
, generate
, packed
, req_data
, safety
, display_type
, msp_item
, is_msp_item
);
6137 if (segment_len
== 0)
6142 pathpos
+= segment_len
;
6144 /* Next path segment */
6145 if( pathpos
< path_length
)
6146 proto_item_append_text( epath_item
, ", " );
6148 } /* end of while( pathpos < path_length ) */
6150 } /* end of dissect_epath() */
6152 #define NUM_SECONDS_PER_DAY ((uint64_t)(60 * 60 * 24))
6154 /* Number of seconds between Jan 1, 1970 00:00:00 epoch and CIP's epoch time of Jan 1, 1972 00:00:00 */
6155 #define CIP_TIMEBASE ((uint64_t)(NUM_SECONDS_PER_DAY * 365 * 2))
6157 void dissect_cip_date_and_time(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, int hf_datetime
)
6159 nstime_t computed_time
;
6160 uint16_t num_days_since_1972
;
6161 uint32_t num_ms_today
;
6163 num_days_since_1972
= tvb_get_letohs(tvb
, offset
+4);
6164 num_ms_today
= tvb_get_letohl(tvb
, offset
);
6166 if ((num_days_since_1972
!= 0) || (num_ms_today
!= 0))
6168 computed_time
.secs
= CIP_TIMEBASE
+ (uint64_t)num_days_since_1972
* NUM_SECONDS_PER_DAY
;
6169 computed_time
.secs
+= num_ms_today
/1000;
6170 computed_time
.nsecs
= (num_ms_today
%1000)*1000000;
6174 computed_time
.secs
= 0;
6175 computed_time
.nsecs
= 0;
6178 proto_tree_add_time(tree
, hf_datetime
, tvb
, offset
, 6, &computed_time
);
6181 static int dissect_cip_date(proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, int hf_date
)
6185 uint16_t num_days_since_1972
= tvb_get_letohs(tvb
, offset
);
6186 /* Convert to nstime epoch */
6187 time_t computed_time
= CIP_TIMEBASE
+ (uint64_t)num_days_since_1972
* NUM_SECONDS_PER_DAY
;
6188 struct tm
* date
= gmtime(&computed_time
);
6191 strftime(date_str
, 20, "%Y-%m-%d", date
);
6193 (void) g_strlcpy(date_str
, "Not representable", sizeof date_str
);
6194 proto_tree_add_uint_format_value(tree
, hf_date
, tvb
, offset
, 2, num_days_since_1972
, "%s", date_str
);
6199 // CIP Type - STIME (nanoseconds)
6200 static int dissect_cip_stime(proto_tree
* tree
, tvbuff_t
* tvb
, int offset
, int hf_datetime
)
6202 nstime_t ts_nstime
= { 0 };
6203 uint64_t timestamp
= tvb_get_letoh64(tvb
, offset
);
6204 ts_nstime
.secs
= timestamp
/ 1000000000;
6205 ts_nstime
.nsecs
= timestamp
% 1000000000;
6207 proto_tree_add_time(tree
, hf_datetime
, tvb
, offset
, 8, &ts_nstime
);
6212 // CIP Type - UTIME (microseconds)
6213 int dissect_cip_utime(proto_tree
* tree
, tvbuff_t
* tvb
, int offset
, int hf_datetime
)
6215 nstime_t ts_nstime
= { 0 };
6216 uint64_t timestamp
= tvb_get_letoh64(tvb
, offset
);
6217 ts_nstime
.secs
= timestamp
/ 1000000;
6218 ts_nstime
.nsecs
= (timestamp
% 1000000) * 1000;
6220 proto_tree_add_time(tree
, hf_datetime
, tvb
, offset
, 8, &ts_nstime
);
6225 int dissect_cip_string_type(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
,
6226 tvbuff_t
*tvb
, int offset
, int hf_type
, int string_type
)
6228 uint32_t string_size_field_len
;
6229 uint32_t string_size
;
6230 unsigned string_encoding
;
6234 total_len
= tvb_reported_length_remaining(tvb
, offset
);
6236 switch (string_type
)
6238 case CIP_SHORT_STRING_TYPE
:
6239 string_size
= tvb_get_uint8(tvb
, offset
);
6240 string_encoding
= ENC_ASCII
| ENC_NA
;
6241 string_size_field_len
= 1;
6244 case CIP_STRING_TYPE
:
6245 string_size
= tvb_get_letohs(tvb
, offset
);
6246 string_encoding
= ENC_ASCII
| ENC_NA
;
6247 string_size_field_len
= 2;
6250 case CIP_STRING2_TYPE
:
6251 string_size
= tvb_get_letohs(tvb
, offset
) * 2;
6252 string_encoding
= ENC_UCS_2
| ENC_LITTLE_ENDIAN
;
6253 string_size_field_len
= 2;
6261 if (total_len
< (int)(string_size
+ string_size_field_len
))
6263 expert_add_info(pinfo
, item
, &ei_mal_missing_string_data
);
6264 parsed_len
= total_len
;
6268 proto_tree_add_item(tree
, hf_type
, tvb
, offset
+ string_size_field_len
, string_size
, string_encoding
);
6269 parsed_len
= string_size
+ string_size_field_len
;
6275 static int dissect_cip_stringi(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
)
6278 uint32_t num_char
= 0;
6279 proto_tree_add_item_ret_uint(tree
, hf_stringi_number_char
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &num_char
);
6281 for (uint32_t i
= 0; i
< num_char
; ++i
)
6283 proto_tree_add_item(tree
, hf_stringi_language_char
, tvb
, offset
+ 1, 3, ENC_ASCII
| ENC_NA
);
6285 uint32_t char_string_type
= 0;
6286 proto_tree_add_item_ret_uint(tree
, hf_stringi_char_string_struct
, tvb
, offset
+ 4, 1, ENC_LITTLE_ENDIAN
, &char_string_type
);
6287 proto_tree_add_item(tree
, hf_stringi_char_set
, tvb
, offset
+ 5, 2, ENC_LITTLE_ENDIAN
);
6290 if (char_string_type
!= CIP_STRING_TYPE
6291 && char_string_type
!= CIP_SHORT_STRING_TYPE
6292 && char_string_type
!= CIP_STRING2_TYPE
)
6294 // Unsupported type.
6298 parsed_len
+= dissect_cip_string_type(pinfo
, tree
, item
, tvb
, offset
+ parsed_len
, hf_stringi_international_string
, char_string_type
);
6304 int dissect_cip_attribute(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
6305 const attribute_info_t
* attr
, int offset
, int total_len
)
6307 int i
, temp_data
, temp_time
, hour
, min
, sec
, ms
,
6311 if (((attr
->datatype
== cip_dissector_func
) && (attr
->pdissect
== NULL
)) ||
6312 ((attr
->datatype
!= cip_dissector_func
) && (attr
->phf
== NULL
)))
6314 DISSECTOR_ASSERT(0);
6318 switch (attr
->datatype
)
6324 proto_tree_add_item(tree
, *(attr
->phf
), tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
6331 proto_tree_add_item(tree
, *(attr
->phf
), tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
6334 case cip_usint_array
:
6335 for (i
= 0; i
< total_len
; i
++)
6336 proto_tree_add_item(tree
, *(attr
->phf
), tvb
, offset
, total_len
, ENC_NA
);
6337 consumed
= total_len
;
6339 case cip_uint_array
:
6340 for (i
= 0; i
< total_len
; i
+=2)
6341 proto_tree_add_item(tree
, *(attr
->phf
), tvb
, offset
+i
, 2, ENC_LITTLE_ENDIAN
);
6350 proto_tree_add_item(tree
, *(attr
->phf
), tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
6359 proto_tree_add_item(tree
, *(attr
->phf
), tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
6362 case cip_short_string
:
6363 consumed
= dissect_cip_string_type(pinfo
, tree
, item
, tvb
, offset
, *(attr
->phf
), CIP_SHORT_STRING_TYPE
);
6366 consumed
= dissect_cip_string_type(pinfo
, tree
, item
, tvb
, offset
, *(attr
->phf
), CIP_STRING_TYPE
);
6368 case cip_dissector_func
:
6369 consumed
= attr
->pdissect(pinfo
, tree
, item
, tvb
, offset
, total_len
);
6372 consumed
= total_len
;
6376 case cip_date_and_time
:
6377 dissect_cip_date_and_time(tree
, tvb
, offset
, *(attr
->phf
));
6381 consumed
= dissect_cip_stime(tree
, tvb
, offset
, *(attr
->phf
));
6384 consumed
= dissect_cip_utime(tree
, tvb
, offset
, *(attr
->phf
));
6387 consumed
= dissect_cip_date(tree
, tvb
, offset
, *(attr
->phf
));
6389 case cip_time_of_day
:
6390 temp_time
= temp_data
= tvb_get_letohl( tvb
, offset
);
6391 hour
= temp_time
/(60*60*1000);
6392 temp_time
%= (60*60*1000);
6393 min
= temp_time
/(60*1000);
6394 temp_time
%= (60*1000);
6395 sec
= temp_time
/1000;
6396 ms
= temp_time
%1000;
6397 proto_tree_add_uint_format_value(tree
, *(attr
->phf
), tvb
, offset
, 4, temp_data
, "%02d:%02d:%02d.%03d", hour
, min
, sec
, ms
);
6401 consumed
= dissect_cip_string_type(pinfo
, tree
, item
, tvb
, offset
, *(attr
->phf
), CIP_STRING2_TYPE
);
6404 consumed
= dissect_cip_stringi(pinfo
, tree
, item
, tvb
, offset
);
6407 /* CURRENTLY NOT SUPPORTED */
6408 expert_add_info(pinfo
, item
, &ei_proto_unsupported_datatype
);
6409 consumed
= total_len
;
6416 static int dissect_cip_service(packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
,
6417 proto_item
*ti
, proto_tree
*item_tree
, cip_service_info_t
*service_entry
, uint8_t service
)
6421 if (service_entry
!= NULL
&& service_entry
->pdissect
)
6423 bool request
= !(service
& CIP_SC_RESPONSE_MASK
);
6424 parsed_len
= service_entry
->pdissect(pinfo
, item_tree
, ti
, tvb
, offset
, request
);
6430 static int dissect_cip_object_specific_service(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* msp_item
, cip_service_info_t
*service_entry
)
6432 DISSECTOR_ASSERT(service_entry
!= NULL
);
6435 uint8_t service
= tvb_get_uint8(tvb
, offset
);
6436 uint8_t gen_status
= 0;
6438 // Skip over the Request/Response header to get to the actual data.
6439 if (service
& CIP_SC_RESPONSE_MASK
)
6441 gen_status
= tvb_get_uint8(tvb
, offset
+ 2);
6443 uint16_t add_stat_size
= tvb_get_uint8(tvb
, offset
+ 3) * 2;
6444 offset
= 4 + add_stat_size
;
6448 uint16_t req_path_size
= tvb_get_uint8(tvb
, offset
+ 1) * 2;
6449 offset
= 2 + req_path_size
;
6452 // Display the service name, even if there is no payload data.
6453 if (service_entry
->service_name
)
6455 col_append_str(pinfo
->cinfo
, COL_INFO
, service_entry
->service_name
);
6456 col_set_fence(pinfo
->cinfo
, COL_INFO
);
6458 proto_item_append_text(msp_item
, "%s", service_entry
->service_name
);
6461 // Only dissect responses with specific response statuses.
6462 if ((service
& CIP_SC_RESPONSE_MASK
)
6463 && (should_dissect_cip_response(tvb
, offset
, gen_status
) == false))
6468 proto_item
*payload_item
;
6469 proto_tree
*payload_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), ett_cmd_data
, &payload_item
, "");
6471 // Add the service info to the tree item.
6472 proto_item_append_text(payload_item
, "%s", service_entry
->service_name
);
6474 if (service
& CIP_SC_RESPONSE_MASK
)
6476 proto_item_append_text(payload_item
, " (Response)");
6480 proto_item_append_text(payload_item
, " (Request)");
6483 // Process any known command-specific data.
6484 offset
+= dissect_cip_service(pinfo
, tvb
, offset
, payload_item
, payload_tree
, service_entry
, service
);
6486 // Add any remaining data.
6487 int len_remain
= tvb_reported_length_remaining(tvb
, offset
);
6490 proto_tree_add_item(payload_tree
, hf_cip_data
, tvb
, offset
, len_remain
, ENC_NA
);
6493 return tvb_reported_length(tvb
);
6496 /************************************************
6498 * Dissector for generic CIP object
6500 ************************************************/
6503 dissect_cip_generic_data( proto_tree
*item_tree
, tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
, proto_item
*ti
)
6505 proto_tree
*cmd_data_tree
;
6507 unsigned char add_stat_size
;
6509 int cmd_data_offset
;
6510 uint8_t service
= tvb_get_uint8( tvb
, offset
);
6512 if (service
& CIP_SC_RESPONSE_MASK
)
6514 /* Response message */
6515 add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
6516 cmd_data_len
= item_length
- 4 - add_stat_size
;
6517 cmd_data_offset
= offset
+ 4 + add_stat_size
;
6521 /* Request message */
6522 req_path_size
= tvb_get_uint8( tvb
, offset
+1 )*2;
6523 cmd_data_len
= item_length
- req_path_size
- 2;
6524 cmd_data_offset
= offset
+ 2 + req_path_size
;
6527 /* If there is any command specific data create a sub-tree for it */
6528 if (cmd_data_len
> 0)
6530 cmd_data_tree
= proto_tree_add_subtree(item_tree
, tvb
, cmd_data_offset
, cmd_data_len
,
6531 ett_cmd_data
, NULL
, "Command Specific Data");
6532 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, cmd_data_offset
, cmd_data_len
, ENC_NA
);
6536 proto_item_set_hidden(ti
);
6539 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals
);
6540 } /* End of dissect_cip_generic_data() */
6543 dissect_cip_class_generic(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
6546 proto_tree
*class_tree
;
6548 /* Create display subtree for the protocol */
6549 ti
= proto_tree_add_item(tree
, proto_cip_class_generic
, tvb
, 0, -1, ENC_NA
);
6550 class_tree
= proto_item_add_subtree( ti
, ett_cip_class_generic
);
6552 dissect_cip_generic_data( class_tree
, tvb
, 0, tvb_reported_length(tvb
), pinfo
, ti
);
6554 return tvb_reported_length(tvb
);
6558 dissect_cip_set_attribute_single_req(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
,
6559 int offset
, cip_simple_request_info_t
* req_data
)
6562 const attribute_info_t
* attr
;
6564 attr
= cip_get_attribute(req_data
->iClass
, req_data
->iInstance
, req_data
->iAttribute
);
6567 parsed_len
= dissect_cip_attribute(pinfo
, tree
, item
, tvb
, attr
, offset
, tvb_reported_length_remaining(tvb
, offset
));
6573 int dissect_cip_get_attribute_list_req(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
,
6574 int offset
, cip_simple_request_info_t
* req_data
)
6576 int i
, att_count
, att_value
;
6577 const attribute_info_t
* pattribute
;
6578 proto_item
*att_list
, *att_item
;
6579 proto_tree
* att_tree
;
6581 /* Get attribute list request */
6582 if (tvb_reported_length_remaining(tvb
, offset
) < 2)
6584 expert_add_info(pinfo
, item
, &ei_mal_serv_gal
);
6588 /* Add number of attributes */
6589 att_count
= tvb_get_letohs( tvb
, offset
);
6590 proto_tree_add_item(tree
, hf_cip_sc_get_attr_list_attr_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
6593 /* Add Attribute List */
6594 att_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, att_count
*2, ett_cip_get_attribute_list
, &att_list
, "Attribute List" );
6596 for( i
=0; i
< att_count
; i
++ )
6598 att_value
= tvb_get_letohs( tvb
, offset
);
6599 att_item
= proto_tree_add_item(att_tree
, hf_cip_attribute16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
6600 pattribute
= cip_get_attribute(req_data
->iClass
, req_data
->iInstance
, att_value
);
6601 if (pattribute
!= NULL
)
6602 proto_item_append_text(att_item
, " (%s)", pattribute
->text
);
6605 if ((tvb_reported_length_remaining(tvb
, offset
) < 2) && (i
< att_count
-1))
6607 expert_add_info(pinfo
, att_list
, &ei_mal_serv_gal_count
);
6612 return 2 + att_count
* 2;
6616 dissect_cip_set_attribute_list_req(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
,
6617 int offset
, cip_simple_request_info_t
* req_data
)
6619 int i
, start_offset
, att_count
,
6620 att_value
, att_size
;
6621 const attribute_info_t
* attr
;
6622 proto_item
*att_list
, *att_item
;
6623 proto_tree
*att_tree
, *att_list_tree
;
6625 /* Get attribute list request */
6626 if (tvb_reported_length_remaining(tvb
, offset
) < 2)
6628 expert_add_info(pinfo
, item
, &ei_mal_serv_sal
);
6632 /* Add number of attributes */
6633 att_count
= tvb_get_letohs( tvb
, offset
);
6634 proto_tree_add_item(tree
, hf_cip_sc_set_attr_list_attr_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
6636 /* Add Attribute List */
6637 att_list_tree
= proto_tree_add_subtree(tree
, tvb
, offset
+2, att_count
*2, ett_cip_set_attribute_list
, &att_list
, "Attribute List" );
6639 start_offset
= offset
;
6641 for( i
=0; i
< att_count
; i
++ )
6643 att_value
= tvb_get_letohs( tvb
, offset
);
6644 att_item
= proto_tree_add_item(att_list_tree
, hf_cip_attribute16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
6645 att_tree
= proto_item_add_subtree( att_item
, ett_cip_set_attribute_list_item
);
6648 attr
= cip_get_attribute(req_data
->iClass
, req_data
->iInstance
, att_value
);
6651 proto_item_append_text(att_item
, " (%s)", attr
->text
);
6652 /* provide attribute data */
6653 att_size
= dissect_cip_attribute(pinfo
, att_tree
, att_item
, tvb
, attr
, offset
, tvb_reported_length_remaining(tvb
, offset
));
6655 proto_item_set_len(att_item
, att_size
+2);
6659 /* Can't find the attribute. */
6663 if ((tvb_reported_length_remaining(tvb
, offset
) < 2) && (i
< att_count
-1))
6665 expert_add_info(pinfo
, att_list
, &ei_mal_serv_sal_count
);
6670 proto_item_set_len(att_list
, offset
-start_offset
);
6672 return 2 + (offset
- start_offset
);
6675 // NOLINTNEXTLINE(misc-no-recursion)
6676 int dissect_cip_multiple_service_packet(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
, int offset
, bool request
)
6678 proto_tree
*mult_serv_tree
, *offset_tree
;
6679 int i
, num_services
, serv_offset
, prev_offset
= 0;
6681 cip_req_info_t
*cip_req_info
, *mr_single_req_info
;
6682 mr_mult_req_info_t
*mr_mult_req_info
= NULL
;
6684 if (tvb_reported_length_remaining(tvb
, offset
) < 2)
6686 expert_add_info(pinfo
, item
, &ei_mal_msp_missing_services
);
6690 num_services
= tvb_get_letohs( tvb
, offset
);
6691 proto_tree_add_item(tree
, hf_cip_sc_mult_serv_pack_num_services
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
6693 /* Ensure a rough sanity check */
6694 if (num_services
*2 > tvb_reported_length_remaining(tvb
, offset
+2))
6696 expert_add_info(pinfo
, item
, &ei_mal_msp_services
);
6699 offset_tree
= proto_tree_add_subtree(tree
, tvb
, offset
+ 2, num_services
* 2, ett_cip_msp_offset
, NULL
, "Offset List");
6700 for (i
= 0; i
< num_services
; i
++)
6702 proto_tree_add_item(offset_tree
, hf_cip_sc_mult_serv_pack_offset
, tvb
, offset
+ 2 + i
* 2, 2, ENC_LITTLE_ENDIAN
);
6705 cip_req_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0 );
6708 /* Only allocate memory for requests. */
6709 if (cip_req_info
->pData
== NULL
&& request
== true)
6711 mr_mult_req_info
= wmem_new(wmem_file_scope(), mr_mult_req_info_t
);
6712 mr_mult_req_info
->service
= SC_MULT_SERV_PACK
;
6713 mr_mult_req_info
->num_services
= num_services
;
6714 mr_mult_req_info
->requests
= (cip_req_info_t
*)wmem_alloc0(wmem_file_scope(), sizeof(cip_req_info_t
)*num_services
);
6715 cip_req_info
->pData
= mr_mult_req_info
;
6718 mr_mult_req_info
= (mr_mult_req_info_t
*)cip_req_info
->pData
;
6720 if (mr_mult_req_info
6721 && (mr_mult_req_info
->service
!= SC_MULT_SERV_PACK
6722 || mr_mult_req_info
->num_services
!= num_services
))
6724 mr_mult_req_info
= NULL
;
6728 col_append_str(pinfo
->cinfo
, COL_INFO
, ": ");
6730 parsed_len
= 2 + num_services
* 2;
6731 for( i
=0; i
< num_services
; i
++ )
6733 proto_item
*mult_serv_item
;
6737 serv_offset
= tvb_get_letohs( tvb
, offset
+2+(i
*2) );
6739 if (tvb_reported_length_remaining(tvb
, serv_offset
) <= 0)
6741 expert_add_info(pinfo
, item
, &ei_mal_msp_inv_offset
);
6745 if( i
== (num_services
-1) )
6747 /* Last service to add */
6748 serv_length
= tvb_reported_length_remaining(tvb
, offset
)-serv_offset
;
6752 serv_length
= tvb_get_letohs( tvb
, offset
+2+((i
+1)*2) ) - serv_offset
;
6755 mult_serv_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+serv_offset
, serv_length
,
6756 ett_cip_mult_service_packet
, &mult_serv_item
, "Service Packet #%d: ", i
+1 );
6757 proto_tree_add_item(mult_serv_tree
, hf_cip_sc_mult_serv_pack_offset
, tvb
, offset
+2+(i
*2) , 2, ENC_LITTLE_ENDIAN
);
6759 /* Make sure the offset is valid */
6760 if ((tvb_reported_length_remaining(tvb
, serv_offset
) <= 0) ||
6761 (tvb_reported_length_remaining(tvb
, serv_offset
+serv_length
) <= 0) ||
6762 (serv_length
<= 0) ||
6763 (prev_offset
>= serv_offset
))
6765 expert_add_info(pinfo
, mult_serv_item
, &ei_mal_msp_inv_offset
);
6766 prev_offset
= serv_offset
;
6769 prev_offset
= serv_offset
;
6772 ** We call ourselves again to dissect embedded packet
6775 next_tvb
= tvb_new_subset_length(tvb
, offset
+serv_offset
, serv_length
);
6777 if ( mr_mult_req_info
)
6779 mr_single_req_info
= mr_mult_req_info
->requests
+ i
;
6780 dissect_cip_data(mult_serv_tree
, next_tvb
, 0, pinfo
, mr_single_req_info
, mult_serv_item
, true);
6784 dissect_cip_data(mult_serv_tree
, next_tvb
, 0, pinfo
, NULL
, mult_serv_item
, true);
6787 /* Add the embedded CIP service to the item. */
6788 if (mult_serv_item
!= NULL
)
6790 uint8_t service
= tvb_get_uint8(next_tvb
, 0);
6791 proto_item_append_text(mult_serv_item
, "%s", val_to_str(service
& CIP_SC_MASK
, cip_sc_vals
, "Service (0x%02x)"));
6794 if (i
!= num_services
- 1)
6796 col_append_str(pinfo
->cinfo
, COL_INFO
, ", ");
6799 parsed_len
+= serv_length
;
6806 // NOLINTNEXTLINE(misc-no-recursion)
6807 dissect_cip_generic_service_req(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, cip_simple_request_info_t
* req_data
)
6809 proto_item
*cmd_data_item
;
6812 proto_tree
*cmd_data_tree
;
6813 uint8_t service
= tvb_get_uint8( tvb
, offset
) & CIP_SC_MASK
;
6815 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals
);
6817 req_path_size
= tvb_get_uint8(tvb
, offset
+ 1);
6818 offset
+= ((req_path_size
* 2) + 2);
6820 /* Create service tree */
6821 cmd_data_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0, ett_cmd_data
, &cmd_data_item
,
6822 val_to_str(service
, cip_sc_vals
, "Unknown Service (0x%02x)"));
6823 proto_item_append_text(cmd_data_item
, " (Request)");
6829 case SC_GET_ATT_LIST
:
6830 parsed_len
= dissect_cip_get_attribute_list_req(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, req_data
);
6832 case SC_SET_ATT_LIST
:
6833 parsed_len
= dissect_cip_set_attribute_list_req(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, req_data
);
6835 case SC_MULT_SERV_PACK
:
6836 parsed_len
= dissect_cip_multiple_service_packet(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, true);
6838 case SC_SET_ATT_SINGLE
:
6839 parsed_len
= dissect_cip_set_attribute_single_req(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, req_data
);
6841 case SC_FIND_NEXT_OBJ_INST
:
6842 proto_tree_add_item(cmd_data_tree
, hf_cip_find_next_object_max_instance
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
6846 // No specific handling for other services.
6850 // Display any remaining unparsed data.
6851 int remain_len
= tvb_reported_length_remaining(tvb
, offset
+ parsed_len
);
6854 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+ parsed_len
, remain_len
, ENC_NA
);
6857 proto_item_set_len(cmd_data_item
, parsed_len
+ remain_len
);
6859 return tvb_reported_length(tvb
);
6862 typedef struct cip_gaa_key
{
6864 bool class_instance
;
6867 typedef struct cip_gaa_val
{
6868 wmem_list_t
*attributes
;
6871 static wmem_map_t
*cip_gaa_hashtable
;
6874 cip_gaa_hash (const void *v
)
6876 const cip_gaa_key_t
*key
= (const cip_gaa_key_t
*)v
;
6879 val
= (unsigned)((key
->cip_class
<< 1) & 0xFFFFFFFE);
6880 val
|= (key
->class_instance
& 1);
6886 cip_gaa_equal(const void *v
, const void *w
)
6888 const cip_gaa_key_t
*v1
= (const cip_gaa_key_t
*)v
;
6889 const cip_gaa_key_t
*v2
= (const cip_gaa_key_t
*)w
;
6891 if ((v1
->cip_class
== v2
->cip_class
) &&
6892 (v1
->class_instance
== v2
->class_instance
))
6898 static void build_get_attr_all_table(void)
6901 attribute_val_array_t
* att_array
;
6902 const attribute_info_t
* pattr
;
6904 cip_gaa_key_t
* new_key
;
6905 cip_gaa_val_t
*gaa_val
;
6906 int last_attribute_index
= -1;
6908 cip_gaa_hashtable
= wmem_map_new(wmem_epan_scope(), cip_gaa_hash
, cip_gaa_equal
);
6910 for (i
= 0; i
< array_length(all_attribute_vals
); i
++)
6912 att_array
= &all_attribute_vals
[i
];
6913 for (j
= 0; j
< att_array
->size
; j
++)
6915 pattr
= &att_array
->attrs
[j
];
6916 key
.cip_class
= pattr
->class_id
;
6917 key
.class_instance
= pattr
->class_instance
;
6919 gaa_val
= (cip_gaa_val_t
*)wmem_map_lookup( cip_gaa_hashtable
, &key
);
6920 if (gaa_val
== NULL
)
6922 new_key
= (cip_gaa_key_t
*)wmem_memdup(wmem_epan_scope(), &key
, sizeof(cip_gaa_key_t
));
6923 gaa_val
= wmem_new0(wmem_epan_scope(), cip_gaa_val_t
);
6924 gaa_val
->attributes
= wmem_list_new(wmem_epan_scope());
6926 wmem_map_insert(cip_gaa_hashtable
, new_key
, gaa_val
);
6927 last_attribute_index
= -1;
6930 if ((pattr
->gaa_index
>= 0) && (pattr
->gaa_index
> last_attribute_index
))
6932 wmem_list_append(gaa_val
->attributes
, (attribute_info_t
*)pattr
);
6933 last_attribute_index
= pattr
->gaa_index
;
6939 int dissect_cip_get_attribute_all_rsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
6940 int offset
, cip_simple_request_info_t
* req_data
)
6944 const attribute_info_t
* attr
;
6945 proto_item
*att_item
;
6946 proto_tree
*att_tree
;
6948 cip_gaa_val_t
*gaa_val
;
6949 wmem_list_frame_t
* attribute_list
;
6952 key
.cip_class
= req_data
->iClass
;
6953 key
.class_instance
= (req_data
->iInstance
== 0);
6955 gaa_val
= (cip_gaa_val_t
*)wmem_map_lookup( cip_gaa_hashtable
, &key
);
6956 if (gaa_val
== NULL
)
6961 for (attribute_list
= wmem_list_head(gaa_val
->attributes
);
6962 (attribute_list
!= NULL
);
6963 attribute_list
= wmem_list_frame_next(attribute_list
))
6965 attr
= (const attribute_info_t
*)wmem_list_frame_data(attribute_list
);
6966 len_remain
= tvb_reported_length_remaining(tvb
, offset
);
6968 /* If there are no more attributes defined or there is no data left. */
6969 if (attr
== NULL
|| len_remain
<= 0)
6972 att_item
= proto_tree_add_uint_format_value(tree
, hf_cip_attribute16
, tvb
, offset
, 0, attr
->attribute
, "%d (%s)", attr
->attribute
, attr
->text
);
6973 att_tree
= proto_item_add_subtree(att_item
, ett_cip_get_attributes_all_item
);
6975 att_size
= dissect_cip_attribute(pinfo
, att_tree
, att_item
, tvb
, attr
, offset
, len_remain
);
6976 proto_item_set_len(att_item
, att_size
);
6979 parsed_len
+= att_size
;
6986 dissect_cip_get_attribute_list_rsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
,
6987 int offset
, cip_simple_request_info_t
* req_data
)
6989 int i
, start_offset
, att_count
,
6990 att_value
, att_status
;
6992 const attribute_info_t
* attr
;
6993 proto_item
*att_list
, *att_item
;
6994 proto_tree
*att_tree
, *att_list_tree
;
6996 /* Get attribute list response */
6997 if (tvb_reported_length_remaining(tvb
, offset
) < 2)
6999 expert_add_info(pinfo
, item
, &ei_mal_serv_gal
);
7003 /* Add number of attributes */
7004 att_count
= tvb_get_letohs( tvb
, offset
);
7005 proto_tree_add_item(tree
, hf_cip_sc_get_attr_list_attr_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
7007 /* Add Attribute List */
7008 att_list_tree
= proto_tree_add_subtree(tree
, tvb
, offset
+2, att_count
*4, ett_cip_get_attribute_list
, &att_list
, "Attribute List" );
7010 start_offset
= offset
;
7012 for( i
=0; i
< att_count
; i
++ )
7014 att_value
= tvb_get_letohs( tvb
, offset
);
7015 att_item
= proto_tree_add_item(att_list_tree
, hf_cip_attribute16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
7016 att_tree
= proto_item_add_subtree( att_item
, ett_cip_get_attribute_list_item
);
7018 att_status
= tvb_get_letohs( tvb
, offset
+2);
7019 proto_tree_add_item(att_tree
, hf_cip_sc_get_attr_list_attr_status
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
7021 attr
= cip_get_attribute(req_data
->iClass
, req_data
->iInstance
, att_value
);
7023 proto_item_append_text(att_item
, " (%s)", attr
->text
);
7026 if (att_status
== 0)
7030 /* provide attribute data */
7031 att_size
= dissect_cip_attribute(pinfo
, att_tree
, att_item
, tvb
, attr
, offset
, tvb_reported_length_remaining(tvb
, offset
));
7033 proto_item_set_len(att_item
, att_size
+4);
7037 /* Can't find the attribute */
7042 if ((tvb_reported_length_remaining(tvb
, offset
) < 4) && (i
< att_count
-1))
7044 expert_add_info(pinfo
, att_list
, &ei_mal_serv_gal_count
);
7049 proto_item_set_len(att_list
, offset
-start_offset
);
7050 return 2 + (offset
- start_offset
);
7054 dissect_cip_set_attribute_list_rsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
,
7055 int offset
, cip_simple_request_info_t
* req_data
)
7057 int i
, start_offset
, att_count
, att_value
;
7058 const attribute_info_t
* attr
;
7059 proto_item
*att_list
, *att_item
;
7060 proto_tree
*att_tree
, *att_list_tree
;
7062 /* Get attribute list request */
7063 if (tvb_reported_length_remaining(tvb
, offset
) < 2)
7065 expert_add_info(pinfo
, item
, &ei_mal_serv_sal
);
7069 /* Add number of attributes */
7070 att_count
= tvb_get_letohs( tvb
, offset
);
7071 proto_tree_add_item(tree
, hf_cip_sc_set_attr_list_attr_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
7073 /* Add Attribute List */
7074 att_list_tree
= proto_tree_add_subtree(tree
, tvb
, offset
+2, att_count
*4, ett_cip_get_attribute_list
, &att_list
, "Attribute List" );
7076 start_offset
= offset
;
7078 for( i
=0; i
< att_count
; i
++ )
7080 att_value
= tvb_get_letohs( tvb
, offset
);
7081 att_item
= proto_tree_add_item(att_list_tree
, hf_cip_attribute16
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
7082 att_tree
= proto_item_add_subtree( att_item
, ett_cip_set_attribute_list_item
);
7084 proto_tree_add_item(att_tree
, hf_cip_sc_set_attr_list_attr_status
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
7086 attr
= cip_get_attribute(req_data
->iClass
, req_data
->iInstance
, att_value
);
7088 proto_item_append_text(att_item
, " (%s)", attr
->text
);
7091 if ((tvb_reported_length_remaining(tvb
, offset
) < 4) && (i
< att_count
-1))
7093 expert_add_info(pinfo
, att_list
, &ei_mal_serv_sal_count
);
7098 proto_item_set_len(att_list
, offset
-start_offset
);
7099 return 2 + (offset
- start_offset
);
7103 dissect_cip_get_attribute_single_rsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
,
7104 int offset
, cip_simple_request_info_t
* req_data
)
7108 const attribute_info_t
* attr
;
7110 total_len
= tvb_reported_length_remaining(tvb
, offset
);
7111 attr
= cip_get_attribute(req_data
->iClass
, req_data
->iInstance
, req_data
->iAttribute
);
7114 proto_item_append_text(item
, " (%s)", attr
->text
);
7115 parsed_len
= dissect_cip_attribute(pinfo
, tree
, item
, tvb
, attr
, offset
, total_len
);
7122 dissect_cip_find_next_object_rsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_item
* item
, int offset
)
7124 uint32_t i
, num_instances
;
7126 if (tvb_reported_length_remaining(tvb
, offset
) < 1)
7128 expert_add_info(pinfo
, item
, &ei_mal_serv_find_next_object
);
7132 proto_tree_add_item_ret_uint(tree
, hf_cip_find_next_object_num_instances
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &num_instances
);
7135 for (i
= 0; i
< num_instances
; i
++)
7137 proto_tree_add_item(tree
, hf_cip_find_next_object_instance_item
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
7140 if ((tvb_reported_length_remaining(tvb
, offset
) < 2) && (i
< num_instances
-1))
7142 expert_add_info(pinfo
, item
, &ei_mal_serv_find_next_object_count
);
7147 return 1 + num_instances
* 2;
7150 void load_cip_request_data(packet_info
*pinfo
, cip_simple_request_info_t
*req_data
)
7152 cip_req_info_t
* preq_info
;
7153 preq_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
7155 if ((preq_info
!= NULL
) &&
7156 (preq_info
->ciaData
!= NULL
))
7158 memcpy(req_data
, preq_info
->ciaData
, sizeof(cip_simple_request_info_t
));
7162 reset_cip_request_info(req_data
);
7166 bool should_dissect_cip_response(tvbuff_t
*tvb
, int offset
, uint8_t gen_status
)
7168 // Only parse the response if there is data left or it has a response status that allows additional data
7170 if ((tvb_reported_length_remaining(tvb
, offset
) == 0)
7171 && gen_status
!= CI_GRC_SUCCESS
7172 && gen_status
!= CI_GRC_ATTR_LIST_ERROR
7173 && gen_status
!= CI_GRC_SERVICE_ERROR
7174 && gen_status
!= CI_GRC_INVALID_LIST_STATUS
)
7183 // NOLINTNEXTLINE(misc-no-recursion)
7184 dissect_cip_generic_service_rsp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
7186 proto_item
*cmd_data_item
;
7187 proto_tree
*cmd_data_tree
;
7188 cip_simple_request_info_t req_data
;
7190 uint8_t gen_status
= tvb_get_uint8(tvb
, offset
+ 2);
7191 uint8_t service
= tvb_get_uint8(tvb
, offset
) & CIP_SC_MASK
;
7192 uint16_t add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
7194 offset
= 4 + add_stat_size
;
7196 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals
);
7198 cmd_data_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0,
7199 ett_cmd_data
, &cmd_data_item
, val_to_str(service
, cip_sc_vals
, "Unknown Service (0x%02x)"));
7200 proto_item_append_text(cmd_data_item
, " (Response)");
7202 load_cip_request_data(pinfo
, &req_data
);
7204 if (should_dissect_cip_response(tvb
, offset
, gen_status
) == false)
7213 case SC_GET_ATT_ALL
:
7214 parsed_len
= dissect_cip_get_attribute_all_rsp(tvb
, pinfo
, cmd_data_tree
, offset
, &req_data
);
7216 case SC_GET_ATT_LIST
:
7217 parsed_len
= dissect_cip_get_attribute_list_rsp(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, &req_data
);
7219 case SC_SET_ATT_LIST
:
7220 parsed_len
= dissect_cip_set_attribute_list_rsp(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, &req_data
);
7223 proto_tree_add_item(cmd_data_tree
, hf_cip_sc_create_instance
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
7226 case SC_MULT_SERV_PACK
:
7227 parsed_len
= dissect_cip_multiple_service_packet(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, false);
7229 case SC_GET_ATT_SINGLE
:
7230 parsed_len
= dissect_cip_get_attribute_single_rsp(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
, &req_data
);
7232 case SC_FIND_NEXT_OBJ_INST
:
7233 parsed_len
= dissect_cip_find_next_object_rsp(tvb
, pinfo
, cmd_data_tree
, cmd_data_item
, offset
);
7236 proto_tree_add_item(cmd_data_tree
, hf_cip_sc_group_sync_is_sync
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
7240 // No specific handling for other services.
7244 // Display any remaining unparsed data.
7245 int remain_len
= tvb_reported_length_remaining(tvb
, offset
+ parsed_len
);
7248 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+ parsed_len
, remain_len
, ENC_NA
);
7251 proto_item_set_len(cmd_data_item
, parsed_len
+ remain_len
);
7253 return tvb_reported_length(tvb
);
7256 /************************************************
7258 * Dissector for CIP Connection Manager
7260 ************************************************/
7263 dissect_cip_cm_timeout(proto_tree
*cmd_tree
, tvbuff_t
*tvb
, int offset
)
7265 uint8_t tick
, timeout_tick
;
7268 /* Display the priority/tick timer */
7269 tick
= tvb_get_uint8( tvb
, offset
) & 0x0F;
7270 proto_tree_add_item( cmd_tree
, hf_cip_cm_priority
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
7271 proto_tree_add_item( cmd_tree
, hf_cip_cm_tick_time
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
7273 /* Display the time-out ticks */
7274 timeout_tick
= tvb_get_uint8( tvb
, offset
+1 );
7275 proto_tree_add_item( cmd_tree
, hf_cip_cm_timeout_tick
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
7277 /* Display the actual time out */
7278 timeout
= ( 1 << tick
) * timeout_tick
;
7279 proto_tree_add_uint(cmd_tree
, hf_cip_cm_timeout
, tvb
, offset
, 2, timeout
);
7282 static void dissect_connection_triad(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
,
7283 int hf_conn_serial
, int hf_vendor
, int hf_orig_serial
,
7284 cip_connection_triad_t
*triad
)
7286 uint32_t ConnSerialNumber
;
7288 uint32_t DeviceSerialNumber
;
7290 proto_tree_add_item_ret_uint(tree
, hf_conn_serial
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &ConnSerialNumber
);
7291 proto_tree_add_item_ret_uint(tree
, hf_vendor
, tvb
, offset
+ 2, 2, ENC_LITTLE_ENDIAN
, &VendorID
);
7292 proto_tree_add_item_ret_uint(tree
, hf_orig_serial
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
, &DeviceSerialNumber
);
7296 triad
->ConnSerialNumber
= ConnSerialNumber
;
7297 triad
->VendorID
= VendorID
;
7298 triad
->DeviceSerialNumber
= DeviceSerialNumber
;
7302 // Mark this message as belonging to a specific CIP connection index.
7303 static void mark_cip_connection(packet_info
* pinfo
, tvbuff_t
* tvb
, proto_tree
* tree
)
7305 cip_conn_info_t
* conn_val
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
7308 proto_item
* pi
= proto_tree_add_uint(tree
, hf_cip_connection
, tvb
, 0, 0, conn_val
->connid
);
7309 proto_item_set_generated(pi
);
7313 // Save the Route or Connection Path for use in the response packet.
7314 static void save_route_connection_path(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, unsigned path_size_bytes
)
7316 if (pinfo
->fd
->visited
)
7321 cip_req_info_t
* preq_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
7324 preq_info
->pRouteConnectionPath
= wmem_alloc(wmem_file_scope(), path_size_bytes
);
7325 preq_info
->RouteConnectionPathLen
= path_size_bytes
/ 2;
7326 tvb_memcpy(tvb
, preq_info
->pRouteConnectionPath
, offset
, path_size_bytes
);
7330 static int get_connection_timeout_multiplier(uint32_t timeout_value
)
7332 uint32_t timeout_multiplier
;
7333 switch (timeout_value
)
7336 timeout_multiplier
= 4;
7339 timeout_multiplier
= 8;
7342 timeout_multiplier
= 16;
7345 timeout_multiplier
= 32;
7348 timeout_multiplier
= 64;
7351 timeout_multiplier
= 128;
7354 timeout_multiplier
= 256;
7357 timeout_multiplier
= 512;
7361 timeout_multiplier
= 0;
7365 return timeout_multiplier
;
7368 static void fwd_open_analysis_safety_open(packet_info
* pinfo
, proto_item
* cmd_item
, cip_safety_epath_info_t
* safety_fwdopen
)
7370 if (safety_fwdopen
->safety_seg
== false)
7375 if (safety_fwdopen
->safety_open_type
== CIP_SAFETY_OPEN_TYPE1
)
7377 expert_add_info(pinfo
, cmd_item
, &ei_cip_safety_open_type1
);
7379 else if (safety_fwdopen
->safety_open_type
== CIP_SAFETY_OPEN_TYPE2A
)
7381 expert_add_info(pinfo
, cmd_item
, &ei_cip_safety_open_type2a
);
7383 else if (safety_fwdopen
->safety_open_type
== CIP_SAFETY_OPEN_TYPE2B
)
7385 expert_add_info(pinfo
, cmd_item
, &ei_cip_safety_open_type2b
);
7388 if (safety_fwdopen
->originator_type
== CIP_SAFETY_ORIGINATOR_PRODUCER
)
7390 expert_add_info(pinfo
, cmd_item
, &ei_cip_safety_output
);
7392 else if (safety_fwdopen
->originator_type
== CIP_SAFETY_ORIGINATOR_CONSUMER
)
7394 expert_add_info(pinfo
, cmd_item
, &ei_cip_safety_input
);
7398 static void fwd_open_analysis_listen_input_connection(packet_info
* pinfo
, proto_item
* cmd_item
, uint8_t TransportClass_trigger
, const cip_connID_info_t
* O2T_info
)
7400 // Listen Only and Input Only connections must be 'Fixed'.
7401 if (O2T_info
->connection_size_type
!= CIP_CONNECTION_SIZE_TYPE_FIXED
)
7406 uint8_t transport_class
= TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
;
7407 if ((transport_class
== 0 && O2T_info
->connection_size
== 0)
7408 || (transport_class
== 1 && O2T_info
->connection_size
== 2))
7410 expert_add_info(pinfo
, cmd_item
, &ei_cip_listen_input_connection
);
7414 static void display_previous_route_connection_path(cip_req_info_t
* preq_info
, proto_tree
* item_tree
, tvbuff_t
* tvb
, packet_info
* pinfo
, int hf_path
, int display_type
);
7416 // Display all Connection Information and Analysis.
7417 static void display_connection_information_fwd_open_req(packet_info
* pinfo
, tvbuff_t
* tvb
, proto_tree
* tree
)
7419 cip_conn_info_t
* conn_info
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
7425 proto_item
* conn_info_item
= NULL
;
7426 proto_tree
* conn_info_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_connection_info
, &conn_info_item
, "Connection Information");
7427 proto_item_set_generated(conn_info_item
);
7429 mark_cip_connection(pinfo
, tvb
, conn_info_tree
);
7431 proto_item
* pi
= proto_tree_add_float(conn_info_tree
, hf_cip_cm_ot_timeout
, tvb
, 0, 0, (conn_info
->O2T
.rpi
/ 1000.0f
) * conn_info
->timeout_multiplier
);
7432 proto_item_set_generated(pi
);
7434 pi
= proto_tree_add_float(conn_info_tree
, hf_cip_cm_to_timeout
, tvb
, 0, 0, (conn_info
->T2O
.rpi
/ 1000.0f
) * conn_info
->timeout_multiplier
);
7435 proto_item_set_generated(pi
);
7437 if (conn_info
->safety
.safety_seg
)
7439 add_safety_data_type_to_info_column(pinfo
, ECIDT_O2T
, &conn_info
->safety
);
7441 pi
= proto_tree_add_float(conn_info_tree
, hf_cip_safety_nte_ms
, tvb
, 0, 0, conn_info
->safety
.nte_value_ms
);
7442 proto_item_set_generated(pi
);
7445 if (conn_info
->close_frame
!= 0)
7447 pi
= proto_tree_add_uint(conn_info_tree
, hf_cip_fwd_close_in
, tvb
, 0, 0, conn_info
->close_frame
);
7448 proto_item_set_generated(pi
);
7452 expert_add_info(pinfo
, conn_info_item
, &ei_cip_no_fwd_close
);
7455 fwd_open_analysis_safety_open(pinfo
, conn_info_item
, &conn_info
->safety
);
7456 fwd_open_analysis_listen_input_connection(pinfo
, conn_info_item
, conn_info
->TransportClass_trigger
, &conn_info
->O2T
);
7459 static void display_connection_information_fwd_open_rsp(packet_info
* pinfo
, tvbuff_t
* tvb
, proto_tree
* tree
, cip_req_info_t
* preq_info
)
7461 proto_item
* conn_info_item
= NULL
;
7462 proto_tree
* conn_info_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_connection_info
, &conn_info_item
, "Connection Information");
7463 proto_item_set_generated(conn_info_item
);
7465 mark_cip_connection(pinfo
, tvb
, conn_info_tree
);
7467 display_previous_route_connection_path(preq_info
, conn_info_tree
, tvb
, pinfo
, hf_cip_cm_conn_path_size
, DISPLAY_CONNECTION_PATH
);
7469 if (preq_info
&& preq_info
->connInfo
&& preq_info
->connInfo
->safety
.safety_seg
)
7471 add_safety_data_type_to_info_column(pinfo
, ECIDT_T2O
, &preq_info
->connInfo
->safety
);
7475 static void display_connection_information_fwd_close_req(packet_info
* pinfo
, tvbuff_t
* tvb
, proto_tree
* tree
)
7477 cip_conn_info_t
* conn_info
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
7483 proto_item
* conn_info_item
= NULL
;
7484 proto_tree
* conn_info_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_connection_info
, &conn_info_item
, "Connection Information");
7485 proto_item_set_generated(conn_info_item
);
7487 mark_cip_connection(pinfo
, tvb
, conn_info_tree
);
7489 display_fwd_open_connection_path(conn_info
, conn_info_tree
, tvb
, pinfo
);
7491 proto_item
*pi
= proto_tree_add_uint(conn_info_tree
, hf_cip_fwd_open_in
, tvb
, 0, 0, conn_info
->open_req_frame
);
7492 proto_item_set_generated(pi
);
7494 // Show the API values
7495 pi
= proto_tree_add_uint(conn_info_tree
, hf_cip_cm_ot_api
, tvb
, 0, 0, conn_info
->O2T
.api
);
7496 proto_item_set_generated(pi
);
7498 pi
= proto_tree_add_uint(conn_info_tree
, hf_cip_cm_to_api
, tvb
, 0, 0, conn_info
->T2O
.api
);
7499 proto_item_set_generated(pi
);
7501 // Connection timeout values
7502 float ot_timeout_ms
= (conn_info
->O2T
.rpi
/ 1000.0f
) * conn_info
->timeout_multiplier
;
7503 float to_timeout_ms
= (conn_info
->T2O
.rpi
/ 1000.0f
) * conn_info
->timeout_multiplier
;
7504 proto_item
* ot_timeout_item
= proto_tree_add_float(conn_info_tree
, hf_cip_cm_ot_timeout
, tvb
, 0, 0, ot_timeout_ms
);
7505 proto_item_set_generated(ot_timeout_item
);
7507 proto_item
* to_timeout_item
= proto_tree_add_float(conn_info_tree
, hf_cip_cm_to_timeout
, tvb
, 0, 0, to_timeout_ms
);
7508 proto_item_set_generated(to_timeout_item
);
7510 if (conn_info
->safety
.safety_seg
)
7512 pi
= proto_tree_add_float(conn_info_tree
, hf_cip_safety_nte_ms
, tvb
, 0, 0, conn_info
->safety
.nte_value_ms
);
7513 proto_item_set_generated(pi
);
7516 if (conn_info
->safety
.safety_seg
)
7518 // Make it obvious that the FwdClose is Safety, to match how the FwdOpen looks.
7519 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Safety]");
7520 add_safety_data_type_to_info_column(pinfo
, ECIDT_O2T
, &conn_info
->safety
);
7525 static void display_connection_information_fwd_close_rsp(packet_info
* pinfo
, tvbuff_t
* tvb
, proto_tree
* tree
)
7527 cip_conn_info_t
* conn_val
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
7533 proto_item
* conn_info_item
= NULL
;
7534 proto_tree
* conn_info_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_connection_info
, &conn_info_item
, "Connection Information");
7535 proto_item_set_generated(conn_info_item
);
7537 mark_cip_connection(pinfo
, tvb
, conn_info_tree
);
7539 cip_req_info_t
* preq_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
7540 display_previous_route_connection_path(preq_info
, conn_info_tree
, tvb
, pinfo
, hf_cip_cm_conn_path_size
, DISPLAY_CONNECTION_PATH
);
7542 if (conn_val
->safety
.safety_seg
)
7544 // Make it obvious that the FwdClose is Safety, to match how the FwdOpen looks.
7545 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Safety]");
7546 add_safety_data_type_to_info_column(pinfo
, ECIDT_T2O
, &conn_val
->safety
);
7550 //// Concurrent Connections
7551 static int dissect_cip_cc_hop(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, proto_tree
* hops_tree
, uint8_t hop_number
)
7555 proto_item
* item_hop
= proto_tree_add_uint(hops_tree
, hf_ext_net_seg_hop
, tvb
, offset
, 0, hop_number
);
7557 proto_tree
* hop_tree
= proto_item_add_subtree(item_hop
, ett_cc_hop
);
7558 proto_tree_add_item(hop_tree
, hf_ext_net_seg_hop_egress_cip_port
, tvb
, offset
+ parsed
, 1, ENC_LITTLE_ENDIAN
);
7561 proto_tree_add_item(hop_tree
, hf_ext_net_seg_hop_link_adr_type
, tvb
, offset
+ parsed
, 1, ENC_LITTLE_ENDIAN
);
7562 proto_tree_add_item(hop_tree
, hf_ext_net_seg_hop_number_of_linkadr
, tvb
, offset
+ parsed
, 1, ENC_LITTLE_ENDIAN
);
7565 uint8_t link_type
= tvb_get_uint8(tvb
, offset
+ 1) >> 4;
7566 uint8_t number_of_links
= tvb_get_uint8(tvb
, offset
+ 1) & 0x0F;
7568 for (uint8_t i
= 0; i
< number_of_links
; i
++)
7572 case 0: // Link addresses
7574 proto_tree_add_item(hop_tree
, hf_ext_net_seg_link_address
, tvb
, offset
+ parsed
, 1, ENC_LITTLE_ENDIAN
);
7579 case 1: // IPv4 addresses encoding
7580 proto_tree_add_item(hop_tree
, hf_ext_net_seg_link_ipv4
, tvb
, offset
+ parsed
, 4, ENC_LITTLE_ENDIAN
);
7584 case 2: // Host Name addresses encoding
7585 parsed
+= dissect_cip_string_type(pinfo
, hop_tree
, item_hop
, tvb
, offset
+ parsed
, hf_ext_net_seg_link_hostname
, CIP_STRING_TYPE
);
7587 // Add pad byte when string length is odd
7600 proto_item_set_len(item_hop
, parsed
);
7605 // From ODVA Volume 1
7606 static const uint32_t crc32_cc_table
[256] =
7608 0x00000000U
, 0x29800005U
, 0x5300000AU
, 0x7A80000FU
,
7609 0xA6000014U
, 0x8F800011U
, 0xF500001EU
, 0xDC80001BU
,
7610 0xCC000019U
, 0xE580001CU
, 0x9F000013U
, 0xB6800016U
,
7611 0x6A00000DU
, 0x43800008U
, 0x39000007U
, 0x10800002U
,
7612 0x18000003U
, 0x31800006U
, 0x4B000009U
, 0x6280000CU
,
7613 0xBE000017U
, 0x97800012U
, 0xED00001DU
, 0xC4800018U
,
7614 0xD400001AU
, 0xFD80001FU
, 0x87000010U
, 0xAE800015U
,
7615 0x7200000EU
, 0x5B80000BU
, 0x21000004U
, 0x08800001U
,
7616 0x30000006U
, 0x19800003U
, 0x6300000CU
, 0x4A800009U
,
7617 0x96000012U
, 0xBF800017U
, 0xC5000018U
, 0xEC80001DU
,
7618 0xFC00001FU
, 0xD580001AU
, 0xAF000015U
, 0x86800010U
,
7619 0x5A00000BU
, 0x7380000EU
, 0x09000001U
, 0x20800004U
,
7620 0x28000005U
, 0x01800000U
, 0x7B00000FU
, 0x5280000AU
,
7621 0x8E000011U
, 0xA7800014U
, 0xDD00001BU
, 0xF480001EU
,
7622 0xE400001CU
, 0xCD800019U
, 0xB7000016U
, 0x9E800013U
,
7623 0x42000008U
, 0x6B80000DU
, 0x11000002U
, 0x38800007U
,
7624 0x6000000CU
, 0x49800009U
, 0x33000006U
, 0x1A800003U
,
7625 0xC6000018U
, 0xEF80001DU
, 0x95000012U
, 0xBC800017U
,
7626 0xAC000015U
, 0x85800010U
, 0xFF00001FU
, 0xD680001AU
,
7627 0x0A000001U
, 0x23800004U
, 0x5900000BU
, 0x7080000EU
,
7628 0x7800000FU
, 0x5180000AU
, 0x2B000005U
, 0x02800000U
,
7629 0xDE00001BU
, 0xF780001EU
, 0x8D000011U
, 0xA4800014U
,
7630 0xB4000016U
, 0x9D800013U
, 0xE700001CU
, 0xCE800019U
,
7631 0x12000002U
, 0x3B800007U
, 0x41000008U
, 0x6880000DU
,
7632 0x5000000AU
, 0x7980000FU
, 0x03000000U
, 0x2A800005U
,
7633 0xF600001EU
, 0xDF80001BU
, 0xA5000014U
, 0x8C800011U
,
7634 0x9C000013U
, 0xB5800016U
, 0xCF000019U
, 0xE680001CU
,
7635 0x3A000007U
, 0x13800002U
, 0x6900000DU
, 0x40800008U
,
7636 0x48000009U
, 0x6180000CU
, 0x1B000003U
, 0x32800006U
,
7637 0xEE00001DU
, 0xC7800018U
, 0xBD000017U
, 0x94800012U
,
7638 0x84000010U
, 0xAD800015U
, 0xD700001AU
, 0xFE80001FU
,
7639 0x22000004U
, 0x0B800001U
, 0x7100000EU
, 0x5880000BU
,
7640 0xC0000018U
, 0xE980001DU
, 0x93000012U
, 0xBA800017U
,
7641 0x6600000CU
, 0x4F800009U
, 0x35000006U
, 0x1C800003U
,
7642 0x0C000001U
, 0x25800004U
, 0x5F00000BU
, 0x7680000EU
,
7643 0xAA000015U
, 0x83800010U
, 0xF900001FU
, 0xD080001AU
,
7644 0xD800001BU
, 0xF180001EU
, 0x8B000011U
, 0xA2800014U
,
7645 0x7E00000FU
, 0x5780000AU
, 0x2D000005U
, 0x04800000U
,
7646 0x14000002U
, 0x3D800007U
, 0x47000008U
, 0x6E80000DU
,
7647 0xB2000016U
, 0x9B800013U
, 0xE100001CU
, 0xC8800019U
,
7648 0xF000001EU
, 0xD980001BU
, 0xA3000014U
, 0x8A800011U
,
7649 0x5600000AU
, 0x7F80000FU
, 0x05000000U
, 0x2C800005U
,
7650 0x3C000007U
, 0x15800002U
, 0x6F00000DU
, 0x46800008U
,
7651 0x9A000013U
, 0xB3800016U
, 0xC9000019U
, 0xE080001CU
,
7652 0xE800001DU
, 0xC1800018U
, 0xBB000017U
, 0x92800012U
,
7653 0x4E000009U
, 0x6780000CU
, 0x1D000003U
, 0x34800006U
,
7654 0x24000004U
, 0x0D800001U
, 0x7700000EU
, 0x5E80000BU
,
7655 0x82000010U
, 0xAB800015U
, 0xD100001AU
, 0xF880001FU
,
7656 0xA0000014U
, 0x89800011U
, 0xF300001EU
, 0xDA80001BU
,
7657 0x06000000U
, 0x2F800005U
, 0x5500000AU
, 0x7C80000FU
,
7658 0x6C00000DU
, 0x45800008U
, 0x3F000007U
, 0x16800002U
,
7659 0xCA000019U
, 0xE380001CU
, 0x99000013U
, 0xB0800016U
,
7660 0xB8000017U
, 0x91800012U
, 0xEB00001DU
, 0xC2800018U
,
7661 0x1E000003U
, 0x37800006U
, 0x4D000009U
, 0x6480000CU
,
7662 0x7400000EU
, 0x5D80000BU
, 0x27000004U
, 0x0E800001U
,
7663 0xD200001AU
, 0xFB80001FU
, 0x81000010U
, 0xA8800015U
,
7664 0x90000012U
, 0xB9800017U
, 0xC3000018U
, 0xEA80001DU
,
7665 0x36000006U
, 0x1F800003U
, 0x6500000CU
, 0x4C800009U
,
7666 0x5C00000BU
, 0x7580000EU
, 0x0F000001U
, 0x26800004U
,
7667 0xFA00001FU
, 0xD380001AU
, 0xA9000015U
, 0x80800010U
,
7668 0x88000011U
, 0xA1800014U
, 0xDB00001BU
, 0xF280001EU
,
7669 0x2E000005U
, 0x07800000U
, 0x7D00000FU
, 0x5480000AU
,
7670 0x44000008U
, 0x6D80000DU
, 0x17000002U
, 0x3E800007U
,
7671 0xE200001CU
, 0xCB800019U
, 0xB1000016U
, 0x98800013L
7674 static uint32_t compute_crc_cc(const uint8_t* pData
, size_t size
)
7676 uint32_t crc
= 0xFFFFFFFF;
7677 for (; size
> 0; --size
)
7679 crc
= crc32_cc_table
[*pData
++ ^ (uint8_t)crc
] ^ (crc
>> 8);
7684 #define CC_PACKET_TYPE_MASK (0x001F)
7685 int dissect_concurrent_connection_packet(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, proto_tree
* tree
)
7687 proto_item
* type_item
= proto_tree_add_item(tree
, proto_cc
, tvb
, offset
, -1, ENC_NA
);
7688 proto_tree
* CC_tree
= proto_item_add_subtree(type_item
, ett_cc_header
);
7690 uint16_t header_type
= tvb_get_letohs(tvb
, offset
) & CC_PACKET_TYPE_MASK
;
7693 if (header_type
== 1)
7695 static int* const options
[] = {
7696 &hf_cip_cc_packet_type
,
7697 &hf_cip_cc_packet_keepalive
,
7698 &hf_cip_cc_packet_keepalive_hop_count
,
7699 &hf_cip_cc_packet_reserved
,
7703 proto_tree_add_bitmask(CC_tree
, tvb
, offset
+ parsed_len
, hf_cip_cc_packet_options
, ett_cc_header
, options
, ENC_LITTLE_ENDIAN
);
7706 uint32_t CC_frame_length
;
7707 proto_tree_add_item_ret_uint(CC_tree
, hf_cip_cc_packet_length
, tvb
, offset
+ parsed_len
, 2, ENC_LITTLE_ENDIAN
, &CC_frame_length
);
7711 proto_tree_add_item_ret_uint(CC_tree
, hf_cip_cc_packet_seq_number
, tvb
, offset
+ parsed_len
, 4, ENC_LITTLE_ENDIAN
, &ccSeq
);
7712 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", CC_SEQ=%010u", ccSeq
);
7715 const uint8_t* payloadToCRC
= tvb_get_ptr(tvb
, offset
, CC_frame_length
);
7716 uint32_t computed_cc_crc
= compute_crc_cc(payloadToCRC
, CC_frame_length
);
7718 proto_tree_add_checksum(CC_tree
, tvb
, offset
+ CC_frame_length
,
7719 hf_cip_cc_crc
, hf_cip_cc_crc_status
, &ei_cc_crc
, pinfo
,
7720 computed_cc_crc
, ENC_LITTLE_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
7721 proto_tree_set_appendix(CC_tree
, tvb
, offset
+ CC_frame_length
, CC_CRC_LENGTH
);
7725 expert_add_info(pinfo
, type_item
, &ei_cc_invalid_header_type
);
7728 proto_item_set_len(type_item
, parsed_len
);
7733 void proto_register_cc(void)
7735 static hf_register_info hf_cc
[] =
7737 /// Concurrent Connections
7738 { &hf_cip_cm_cc_version
, { "Concurrent Connections Protocol Version", "cip.cm.cc_version", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
7740 // Concurrent Connection Packet
7741 { &hf_cip_cc_packet_length
,{ "Packet Length", "cip.cc.packet.length", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
7742 { &hf_cip_cc_packet_type
,{ "Packet Type", "cip.cc.packet_type", FT_UINT16
, BASE_DEC
, VALS(cc_packet_type_vals
), CC_PACKET_TYPE_MASK
, NULL
, HFILL
} },
7743 { &hf_cip_cc_packet_options
, { "Packet Type and Keep-alive", "cip.cc.packet.type_and_keepalive", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
7744 { &hf_cip_cc_packet_keepalive
,{ "Keep-alive Flag", "cip.cc.packet.keep_alive_flag", FT_UINT16
, BASE_HEX
, NULL
, 0x0020, NULL
, HFILL
} },
7745 { &hf_cip_cc_packet_keepalive_hop_count
,{ "Keep-alive Hop Count", "cip.cc.packet.keep_alive_count", FT_UINT16
, BASE_DEC
, NULL
, 0x01C0, NULL
, HFILL
} },
7746 { &hf_cip_cc_packet_reserved
,{ "Reserved", "cip.cc.packet.reserved", FT_UINT16
, BASE_HEX
, NULL
, 0xFE00, NULL
, HFILL
} },
7747 { &hf_cip_cc_packet_seq_number
,{ "Concurrent Connection Sequence Count", "cip.cc.packet.sequence_count", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
7748 { &hf_cip_cc_crc
,{ "CRC", "cip.cc.crc", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
7749 { &hf_cip_cc_crc_status
, { "CC CRC Status", "cip.cc.crc.status", FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0, NULL
, HFILL
} },
7751 // Concurrent Connection Path
7752 { &hf_ext_net_seg_hops_count
,{ "Hops Count", "cip.cc.netsegment.hopsCount", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
7753 { &hf_ext_net_seg_length
,{ "Length of Concurrent Connection Path", "cip.cc.netsegment.length", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
7755 // Concurrent Connection Hops
7756 { &hf_ext_net_seg_hop
,{ "CC Hop", "cip.cc.netsegment.hop", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
7757 { &hf_ext_net_seg_hop_egress_cip_port
,{ "Egress Port", "cip.cc.netsegment.HopEgreeCipPort", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
7758 { &hf_ext_net_seg_hop_link_adr_type
,{ "Link Address Type", "cip.cc.netsegment.HopLnkAdrType", FT_UINT8
, BASE_DEC
, VALS(cc_link_adr_type
), 0xF0, NULL
, HFILL
} },
7759 { &hf_ext_net_seg_hop_number_of_linkadr
,{ "Number of link addresses", "cip.cc.netsegment.HopNumberOfLnkAdr", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
} },
7760 { &hf_ext_net_seg_link_address
,{ "Link address", "cip.cc.netsegment.link", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
7761 { &hf_ext_net_seg_link_ipv4
,{ "IPv4 address", "cip.cc.netsegment.ip", FT_IPv4
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
7762 { &hf_ext_net_seg_link_hostname
, { "Hostname", "cip.cc.netsegment.hostname", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
7765 static ei_register_info ei_cc
[] = {
7766 { &ei_cc_invalid_header_type
, { "cip.cc.invalid_packet_type", PI_MALFORMED
, PI_ERROR
, "Invalid Concurrent Connections Packet Type", EXPFILL
}},
7767 { &ei_cc_crc
, { "cip.cc.crc.incorrect", PI_PROTOCOL
, PI_ERROR
, "CC CRC incorrect", EXPFILL
}},
7770 proto_cc
= proto_register_protocol("Concurrent Connection Packet",
7774 proto_register_field_array(proto_cc
, hf_cc
, array_length(hf_cc
));
7775 proto_register_subtree_array(ett_cc
, array_length(ett_cc
));
7777 expert_module_t
* expert_cc
= expert_register_protocol(proto_cc
);
7778 expert_register_field_array(expert_cc
, ei_cc
, array_length(ei_cc
));
7781 // Offset - Starts after the Extended Network Segment Subtype
7782 int dissect_concurrent_connection_network_segment(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, proto_tree
* tree
)
7784 uint32_t hops_count
;
7785 proto_tree_add_item_ret_uint(tree
, hf_ext_net_seg_hops_count
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &hops_count
);
7787 proto_tree_add_item(tree
, hf_ext_net_seg_length
, tvb
, offset
+ 1, 1, ENC_LITTLE_ENDIAN
);
7790 for (uint32_t i
= 0; i
< hops_count
; i
++)
7792 parsed_len
+= dissect_cip_cc_hop(pinfo
, tvb
, offset
+ parsed_len
, tree
, i
+ 1);
7795 // Add padding when the Network segment length is odd.
7796 if (parsed_len
& 0x0001)
7805 dissect_cip_cm_fwd_open_req(cip_req_info_t
*preq_info
, proto_tree
*cmd_tree
, proto_item
* cmd_item
, tvbuff_t
*tvb
, int offset
,
7806 bool large_fwd_open
, packet_info
*pinfo
, bool concurrent_connection
)
7809 proto_tree
*epath_tree
;
7810 int conn_path_size
, net_param_offset
= 0;
7811 uint8_t TransportClass_trigger
;
7812 cip_simple_request_info_t connection_path
;
7813 cip_safety_epath_info_t safety_fwdopen
= {0};
7815 cip_connID_info_t O2T_info
= {0};
7816 cip_connID_info_t T2O_info
= {0};
7818 dissect_cip_cm_timeout(cmd_tree
, tvb
, offset
);
7819 proto_tree_add_item_ret_uint( cmd_tree
, hf_cip_cm_ot_connid
, tvb
, offset
+2, 4, ENC_LITTLE_ENDIAN
, &O2T_info
.connID
);
7820 proto_tree_add_item_ret_uint( cmd_tree
, hf_cip_cm_to_connid
, tvb
, offset
+6, 4, ENC_LITTLE_ENDIAN
, &T2O_info
.connID
);
7822 // Add Connection IDs as hidden items so that it's easy to find all Connection IDs in different fields.
7823 pi
= proto_tree_add_item(cmd_tree
, hf_cip_connid
, tvb
, offset
+ 2, 4, ENC_LITTLE_ENDIAN
);
7824 proto_item_set_hidden(pi
);
7825 pi
= proto_tree_add_item(cmd_tree
, hf_cip_connid
, tvb
, offset
+ 6, 4, ENC_LITTLE_ENDIAN
);
7826 proto_item_set_hidden(pi
);
7828 cip_connection_triad_t conn_triad
;
7829 dissect_connection_triad(tvb
, offset
+ 10, cmd_tree
,
7830 hf_cip_cm_conn_serial_num
, hf_cip_cm_vendor
, hf_cip_cm_orig_serial_num
,
7833 if (concurrent_connection
)
7835 // For CC there is additional 1 byte containing CC Version and one reserved byte after.
7836 proto_tree_add_item(cmd_tree
, hf_cip_cm_cc_version
, tvb
, offset
+ 18, 1, ENC_LITTLE_ENDIAN
);
7840 uint32_t timeout_value
;
7841 proto_tree_add_item_ret_uint(cmd_tree
, hf_cip_cm_timeout_multiplier
, tvb
, offset
+18, 1, ENC_LITTLE_ENDIAN
, &timeout_value
);
7842 uint32_t timeout_multiplier
= get_connection_timeout_multiplier(timeout_value
);
7844 proto_tree_add_item(cmd_tree
, hf_cip_reserved24
, tvb
, offset
+19, 3, ENC_LITTLE_ENDIAN
);
7847 proto_tree_add_item_ret_uint(cmd_tree
, hf_cip_cm_ot_rpi
, tvb
, offset
+ 22, 4, ENC_LITTLE_ENDIAN
, &O2T_info
.rpi
);
7850 dissect_net_param32(tvb
, offset
+26, cmd_tree
,
7851 hf_cip_cm_ot_net_params32
, hf_cip_cm_lfwo_own
, hf_cip_cm_lfwo_typ
,
7852 hf_cip_cm_lfwo_prio
, hf_cip_cm_lfwo_fixed_var
, hf_cip_cm_lfwo_con_size
, ett_cm_ncp
, &O2T_info
);
7853 net_param_offset
= 4;
7857 dissect_net_param16(tvb
, offset
+26, cmd_tree
,
7858 hf_cip_cm_ot_net_params16
, hf_cip_cm_fwo_own
, hf_cip_cm_fwo_typ
,
7859 hf_cip_cm_fwo_prio
, hf_cip_cm_fwo_fixed_var
, hf_cip_cm_fwo_con_size
, ett_cm_ncp
, &O2T_info
);
7860 net_param_offset
= 2;
7864 proto_tree_add_item_ret_uint(cmd_tree
, hf_cip_cm_to_rpi
, tvb
, offset
+ 26 + net_param_offset
, 4, ENC_LITTLE_ENDIAN
, &T2O_info
.rpi
);
7867 dissect_net_param32(tvb
, offset
+26+net_param_offset
+4, cmd_tree
,
7868 hf_cip_cm_to_net_params32
, hf_cip_cm_lfwo_own
, hf_cip_cm_lfwo_typ
,
7869 hf_cip_cm_lfwo_prio
, hf_cip_cm_lfwo_fixed_var
, hf_cip_cm_lfwo_con_size
, ett_cm_ncp
, &T2O_info
);
7870 net_param_offset
+= 4;
7874 dissect_net_param16(tvb
, offset
+26+net_param_offset
+4, cmd_tree
,
7875 hf_cip_cm_to_net_params16
, hf_cip_cm_fwo_own
, hf_cip_cm_fwo_typ
,
7876 hf_cip_cm_fwo_prio
, hf_cip_cm_fwo_fixed_var
, hf_cip_cm_fwo_con_size
, ett_cm_ncp
, &T2O_info
);
7877 net_param_offset
+= 2;
7880 TransportClass_trigger
= tvb_get_uint8( tvb
, offset
+26+net_param_offset
+4);
7881 dissect_transport_type_trigger(tvb
, offset
+26+net_param_offset
+4, cmd_tree
, hf_cip_cm_transport_type_trigger
,
7882 hf_cip_cm_fwo_dir
, hf_cip_cm_fwo_trigg
, hf_cip_cm_fwo_class
, ett_cm_ttt
);
7885 conn_path_size
= tvb_get_uint8( tvb
, offset
+26+net_param_offset
+5 )*2;
7886 proto_tree_add_item(cmd_tree
, hf_cip_cm_conn_path_size
, tvb
, offset
+26+net_param_offset
+5, 1, ENC_LITTLE_ENDIAN
);
7889 epath_tree
= proto_tree_add_subtree(cmd_tree
, tvb
, offset
+26+net_param_offset
+6, conn_path_size
, ett_path
, &pi
, "Connection Path: ");
7890 dissect_epath( tvb
, pinfo
, epath_tree
, pi
, offset
+26+net_param_offset
+6, conn_path_size
, false, false, &connection_path
, &safety_fwdopen
, DISPLAY_CONNECTION_PATH
, NULL
, false);
7891 save_route_connection_path(pinfo
, tvb
, offset
+ 26 + net_param_offset
+ 6, conn_path_size
);
7893 // Null Forward Opens are a special case, so make it obvious.
7894 if ((O2T_info
.type
== CONN_TYPE_NULL
) && (T2O_info
.type
== CONN_TYPE_NULL
))
7896 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Null]");
7897 expert_add_info(pinfo
, cmd_item
, &ei_cip_null_fwd_open
);
7900 if (pinfo
->fd
->visited
)
7902 /* "Connection" is created during ForwardOpen reply (which will be after ForwardOpen request),
7903 so ForwardOpen request can only be marked after the first pass */
7904 enip_mark_connection_triad(pinfo
, &conn_triad
);
7908 if (preq_info
!= NULL
)
7910 DISSECTOR_ASSERT(preq_info
->connInfo
== NULL
);
7911 preq_info
->connInfo
= wmem_new0(wmem_file_scope(), cip_conn_info_t
);
7913 preq_info
->connInfo
->triad
= conn_triad
;
7914 preq_info
->connInfo
->open_req_frame
= pinfo
->num
;
7916 preq_info
->connInfo
->O2T
= O2T_info
;
7917 preq_info
->connInfo
->T2O
= T2O_info
;
7919 preq_info
->connInfo
->TransportClass_trigger
= TransportClass_trigger
;
7920 preq_info
->connInfo
->IsNullFwdOpen
= (O2T_info
.type
== CONN_TYPE_NULL
) && (T2O_info
.type
== CONN_TYPE_NULL
);
7921 preq_info
->connInfo
->timeout_multiplier
= timeout_multiplier
;
7922 preq_info
->connInfo
->safety
= safety_fwdopen
;
7923 if (preq_info
->connInfo
->safety
.safety_seg
)
7925 bool server_dir
= (TransportClass_trigger
& CI_PRODUCTION_DIR_MASK
) ? true : false;
7928 preq_info
->connInfo
->safety
.originator_type
= CIP_SAFETY_ORIGINATOR_PRODUCER
;
7932 preq_info
->connInfo
->safety
.originator_type
= CIP_SAFETY_ORIGINATOR_CONSUMER
;
7936 preq_info
->connInfo
->connection_path
= connection_path
;
7938 preq_info
->connInfo
->FwdOpenPathLenBytes
= conn_path_size
;
7939 preq_info
->connInfo
->pFwdOpenPathData
= wmem_alloc(wmem_file_scope(), conn_path_size
);
7940 tvb_memcpy(tvb
, preq_info
->connInfo
->pFwdOpenPathData
, offset
+ 26 + net_param_offset
+ 6, conn_path_size
);
7944 display_connection_information_fwd_open_req(pinfo
, tvb
, cmd_tree
);
7947 static void display_previous_route_connection_path(cip_req_info_t
*preq_info
, proto_tree
*item_tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, int hf_path
, int display_type
)
7949 if (preq_info
&& preq_info
->RouteConnectionPathLen
&& preq_info
->pRouteConnectionPath
)
7951 tvbuff_t
* tvbIOI
= tvb_new_real_data((const uint8_t *)preq_info
->pRouteConnectionPath
, preq_info
->RouteConnectionPathLen
* 2, preq_info
->RouteConnectionPathLen
* 2);
7957 proto_item
* pi
= proto_tree_add_uint(item_tree
, hf_path
, tvb
, 0, 0, preq_info
->RouteConnectionPathLen
);
7958 proto_item_set_generated(pi
);
7960 proto_tree
* epath_tree
= proto_tree_add_subtree(item_tree
, tvb
, 0, 0, ett_path
, &pi
, "Route/Connection Path: ");
7961 proto_item_set_generated(pi
);
7963 cip_simple_request_info_t route_conn_path
;
7964 dissect_epath(tvbIOI
, pinfo
, epath_tree
, pi
, 0, preq_info
->RouteConnectionPathLen
* 2, true, false, &route_conn_path
, NULL
, display_type
, NULL
, false);
7967 if (preq_info
->connInfo
&& preq_info
->connInfo
->IsNullFwdOpen
)
7969 col_append_str(pinfo
->cinfo
, COL_INFO
, " [Null]");
7970 expert_add_info(pinfo
, item_tree
, &ei_cip_null_fwd_open
);
7975 typedef struct safety_application_reply_data
{
7976 cip_connection_triad_t target_triad
;
7977 uint16_t init_rollover_value
;
7978 uint16_t init_timestamp_value
;
7979 } safety_application_reply_data_t
;
7981 static int dissect_fwd_open_rsp_safety_application_reply_data(cip_req_info_t
* preq_info
, proto_tree
* tree
, tvbuff_t
* tvb
, int offset
, safety_application_reply_data_t
* safety_reply_data
)
7983 int reply_parsed_len
= 10;
7985 proto_item
* safety_item
;
7986 proto_tree
* safety_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0, ett_cip_cm_safety
, &safety_item
, "");
7988 // Consumer Number and PID/CID are common to all formats.
7989 proto_tree_add_item(safety_tree
, hf_cip_cm_consumer_number
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
7991 proto_item
* pid_item
;
7992 proto_tree
* pid_tree
= proto_tree_add_subtree(safety_tree
, tvb
, offset
+ 2, 8, ett_cip_cm_pid
, &pid_item
, "");
7993 bool server_dir
= (preq_info
->connInfo
->TransportClass_trigger
& CI_PRODUCTION_DIR_MASK
) ? true : false;
7996 proto_item_set_text(pid_item
, "Consumer ID (CID)");
8000 proto_item_set_text(pid_item
, "Producer ID (PID)");
8003 proto_tree_add_item(pid_tree
, hf_cip_cm_targ_vendor_id
, tvb
, offset
+ 2, 2, ENC_LITTLE_ENDIAN
);
8004 safety_reply_data
->target_triad
.VendorID
= tvb_get_letohs(tvb
, offset
+ 2);
8006 proto_tree_add_item_ret_uint(pid_tree
, hf_cip_cm_targ_dev_serial_num
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
, &(safety_reply_data
->target_triad
.DeviceSerialNumber
));
8008 proto_tree_add_item(pid_tree
, hf_cip_cm_targ_conn_serial_num
, tvb
, offset
+ 8, 2, ENC_LITTLE_ENDIAN
);
8009 safety_reply_data
->target_triad
.ConnSerialNumber
= tvb_get_letohs(tvb
, offset
+ 8);
8011 if (preq_info
->connInfo
->safety
.format
== CIP_SAFETY_EXTENDED_FORMAT
)
8013 proto_tree_add_item(safety_tree
, hf_cip_cm_initial_timestamp
, tvb
, offset
+ 10, 2, ENC_LITTLE_ENDIAN
);
8014 safety_reply_data
->init_timestamp_value
= tvb_get_letohs(tvb
, offset
+ 10);
8016 proto_tree_add_item(safety_tree
, hf_cip_cm_initial_rollover
, tvb
, offset
+ 12, 2, ENC_LITTLE_ENDIAN
);
8017 safety_reply_data
->init_rollover_value
= tvb_get_letohs(tvb
, offset
+ 12);
8019 reply_parsed_len
+= 4;
8021 proto_item_set_text(safety_item
, "CIP Safety Extended Format Target Application Reply");
8023 else // CIP_SAFETY_BASE_FORMAT
8025 proto_item_set_text(safety_item
, "CIP Safety Target Application Reply");
8028 proto_item_set_len(safety_item
, reply_parsed_len
);
8030 return reply_parsed_len
;
8033 bool cip_connection_triad_match(const cip_connection_triad_t
* left
, const cip_connection_triad_t
* right
)
8035 return (left
->ConnSerialNumber
== right
->ConnSerialNumber
) &&
8036 (left
->VendorID
== right
->VendorID
) &&
8037 (left
->DeviceSerialNumber
== right
->DeviceSerialNumber
);
8041 dissect_cip_cm_fwd_open_rsp_success(cip_req_info_t
*preq_info
, proto_tree
*tree
, tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
)
8043 int parsed_len
= 26;
8045 /* Display originator to target connection ID */
8047 proto_tree_add_item_ret_uint(tree
, hf_cip_cm_ot_connid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &O2TConnID
);
8049 /* Display target to originator connection ID */
8051 proto_tree_add_item_ret_uint(tree
, hf_cip_cm_to_connid
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
, &T2OConnID
);
8053 // Add Connection IDs as hidden items so that it's easy to find all Connection IDs in different fields.
8054 proto_item
* pi
= proto_tree_add_item(tree
, hf_cip_connid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
8055 proto_item_set_hidden(pi
);
8056 pi
= proto_tree_add_item(tree
, hf_cip_connid
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
);
8057 proto_item_set_hidden(pi
);
8059 cip_connection_triad_t conn_triad
;
8060 dissect_connection_triad(tvb
, offset
+ 8, tree
,
8061 hf_cip_cm_conn_serial_num
, hf_cip_cm_vendor
, hf_cip_cm_orig_serial_num
,
8064 /* Display originator to target actual packet interval */
8066 proto_tree_add_item_ret_uint(tree
, hf_cip_cm_ot_api
, tvb
, offset
+ 16, 4, ENC_LITTLE_ENDIAN
, &O2TAPI
);
8068 /* Display originator to target actual packet interval */
8070 proto_tree_add_item_ret_uint(tree
, hf_cip_cm_to_api
, tvb
, offset
+ 20, 4, ENC_LITTLE_ENDIAN
, &T2OAPI
);
8072 /* Display the application reply size */
8073 uint16_t app_rep_size
= tvb_get_uint8( tvb
, offset
+24 ) * 2;
8074 proto_tree_add_item(tree
, hf_cip_cm_app_reply_size
, tvb
, offset
+24, 1, ENC_LITTLE_ENDIAN
);
8076 /* Display the Reserved byte */
8077 proto_tree_add_item(tree
, hf_cip_reserved8
, tvb
, offset
+25, 1, ENC_LITTLE_ENDIAN
);
8079 // Handle the Application Reply Data.
8080 int reply_parsed_len
= 0;
8081 safety_application_reply_data_t safety_reply_data
= {0};
8082 if (preq_info
&& preq_info
->connInfo
&& preq_info
->connInfo
->safety
.safety_seg
== true)
8084 reply_parsed_len
= dissect_fwd_open_rsp_safety_application_reply_data(preq_info
, tree
, tvb
, offset
+ 26, &safety_reply_data
);
8087 int remaining_reply_len
= app_rep_size
- reply_parsed_len
;
8088 if (remaining_reply_len
> 0)
8090 proto_tree_add_item(tree
, hf_cip_cm_app_reply_data
, tvb
, offset
+ 26 + reply_parsed_len
, remaining_reply_len
, ENC_NA
);
8093 display_connection_information_fwd_open_rsp(pinfo
, tvb
, tree
, preq_info
);
8095 /* See if we've captured the ForwardOpen request. If so some of the conversation data has already been
8096 populated and we just need to update it. */
8097 if (pinfo
->fd
->visited
)
8098 return parsed_len
+ app_rep_size
;
8100 if ((preq_info
!= NULL
) && (preq_info
->connInfo
!= NULL
))
8102 /* Ensure the connection triad matches before updating the connection IDs */
8103 if (cip_connection_triad_match(&(preq_info
->connInfo
->triad
), &conn_triad
))
8105 /* Update the connection IDs as ForwardOpen reply is allowed to update them from
8106 the ForwardOpen request */
8107 preq_info
->connInfo
->O2T
.connID
= O2TConnID
;
8108 preq_info
->connInfo
->T2O
.connID
= T2OConnID
;
8110 preq_info
->connInfo
->O2T
.api
= O2TAPI
;
8111 preq_info
->connInfo
->T2O
.api
= T2OAPI
;
8112 if (preq_info
->connInfo
->safety
.safety_seg
== true)
8114 preq_info
->connInfo
->safety
.running_rollover_value
= safety_reply_data
.init_rollover_value
;
8115 preq_info
->connInfo
->safety
.running_timestamp_value
= safety_reply_data
.init_timestamp_value
;
8116 preq_info
->connInfo
->safety
.target_triad
= safety_reply_data
.target_triad
;
8117 preq_info
->connInfo
->safety
.seen_non_zero_timestamp
= false;
8122 return parsed_len
+ app_rep_size
;
8125 static void dissect_cip_cm_unconnected_send_req(proto_tree
* cmd_data_tree
, tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
)
8127 /* Display timeout fields */
8128 dissect_cip_cm_timeout(cmd_data_tree
, tvb
, offset
);
8130 /* Message request size */
8131 uint16_t msg_req_siz
= tvb_get_letohs(tvb
, offset
+ 2);
8132 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_msg_req_size
, tvb
, offset
+ 2, 2, ENC_LITTLE_ENDIAN
);
8134 /* Message Request */
8135 proto_tree
* temp_tree
= proto_tree_add_subtree(cmd_data_tree
, tvb
, offset
+ 4, msg_req_siz
, ett_cm_mes_req
, NULL
, "CIP Embedded Message Request");
8138 ** We call ourselves again to dissect embedded packet
8141 col_append_str(pinfo
->cinfo
, COL_INFO
, ": ");
8143 tvbuff_t
* next_tvb
= tvb_new_subset_length(tvb
, offset
+ 4, msg_req_siz
);
8144 cip_req_info_t
* preq_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
8145 cip_req_info_t
* pembedded_req_info
= NULL
;
8148 if (preq_info
->pData
== NULL
)
8150 pembedded_req_info
= wmem_new0(wmem_file_scope(), cip_req_info_t
);
8151 preq_info
->pData
= pembedded_req_info
;
8155 pembedded_req_info
= (cip_req_info_t
*)preq_info
->pData
;
8159 dissect_cip_data(temp_tree
, next_tvb
, 0, pinfo
, pembedded_req_info
, NULL
, false);
8161 if (msg_req_siz
% 2)
8164 proto_tree_add_item(cmd_data_tree
, hf_cip_pad8
, tvb
, offset
+ 4 + msg_req_siz
, 1, ENC_LITTLE_ENDIAN
);
8165 msg_req_siz
++; /* include the padding */
8168 /* Route Path Size */
8169 uint16_t route_path_size
= tvb_get_uint8(tvb
, offset
+ 4 + msg_req_siz
) * 2;
8170 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_route_path_size
, tvb
, offset
+ 4 + msg_req_siz
, 1, ENC_LITTLE_ENDIAN
);
8172 /* Display the Reserved byte */
8173 proto_tree_add_item(cmd_data_tree
, hf_cip_reserved8
, tvb
, offset
+ 5 + msg_req_siz
, 1, ENC_LITTLE_ENDIAN
);
8176 proto_item
* epath_item
;
8177 proto_tree
* epath_tree
= proto_tree_add_subtree(cmd_data_tree
, tvb
, offset
+ 6 + msg_req_siz
, route_path_size
, ett_path
, &epath_item
, "Route Path: ");
8178 dissect_epath(tvb
, pinfo
, epath_tree
, epath_item
, offset
+ 6 + msg_req_siz
, route_path_size
, false, false, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
8180 save_route_connection_path(pinfo
, tvb
, offset
+ 6 + msg_req_siz
, route_path_size
);
8183 static void dissect_cip_cm_fwd_close_req(proto_tree
* cmd_data_tree
, tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
)
8185 cip_simple_request_info_t conn_path
;
8187 dissect_cip_cm_timeout(cmd_data_tree
, tvb
, offset
);
8189 cip_connection_triad_t conn_triad
;
8190 dissect_connection_triad(tvb
, offset
+ 2, cmd_data_tree
,
8191 hf_cip_cm_conn_serial_num
, hf_cip_cm_vendor
, hf_cip_cm_orig_serial_num
,
8194 /* Add the path size */
8195 uint16_t conn_path_size
= tvb_get_uint8(tvb
, offset
+ 10) * 2;
8196 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_conn_path_size
, tvb
, offset
+ 10, 1, ENC_LITTLE_ENDIAN
);
8198 /* Display the Reserved byte */
8199 proto_tree_add_item(cmd_data_tree
, hf_cip_reserved8
, tvb
, offset
+ 11, 1, ENC_LITTLE_ENDIAN
);
8203 proto_tree
* epath_tree
= proto_tree_add_subtree(cmd_data_tree
, tvb
, offset
+ 12, conn_path_size
, ett_path
, &pi
, "Connection Path: ");
8204 dissect_epath(tvb
, pinfo
, epath_tree
, pi
, offset
+ 12, conn_path_size
, false, false, &conn_path
, NULL
, DISPLAY_CONNECTION_PATH
, NULL
, false);
8205 save_route_connection_path(pinfo
, tvb
, offset
+ 12, conn_path_size
);
8207 enip_close_cip_connection(pinfo
, &conn_triad
);
8208 display_connection_information_fwd_close_req(pinfo
, tvb
, cmd_data_tree
);
8211 static int dissect_cip_cm_fwd_close_rsp_success(proto_tree
* cmd_data_tree
, tvbuff_t
* tvb
, int offset
, packet_info
* pinfo
, proto_item
* cmd_item
)
8213 cip_connection_triad_t conn_triad
;
8214 dissect_connection_triad(tvb
, offset
, cmd_data_tree
,
8215 hf_cip_cm_conn_serial_num
, hf_cip_cm_vendor
, hf_cip_cm_orig_serial_num
,
8218 /* Display the application reply size */
8219 uint16_t app_rep_size
= tvb_get_uint8(tvb
, offset
+ 8) * 2;
8220 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_app_reply_size
, tvb
, offset
+ 8, 1, ENC_LITTLE_ENDIAN
);
8222 /* Display the Reserved byte */
8223 proto_tree_add_item(cmd_data_tree
, hf_cip_reserved8
, tvb
, offset
+ 9, 1, ENC_LITTLE_ENDIAN
);
8224 if (app_rep_size
> 0)
8226 if (tvb_reported_length_remaining(tvb
, offset
+ 10) < app_rep_size
)
8228 expert_add_info(pinfo
, cmd_item
, &ei_mal_fwd_close_missing_data
);
8231 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_app_reply_data
, tvb
, offset
+ 10, app_rep_size
, ENC_NA
);
8234 if (!pinfo
->fd
->visited
)
8235 enip_mark_connection_triad(pinfo
, &conn_triad
);
8237 display_connection_information_fwd_close_rsp(pinfo
, tvb
, cmd_data_tree
);
8239 return 10 + app_rep_size
;
8242 static void display_previous_request_path(cip_req_info_t
*preq_info
, proto_tree
*item_tree
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_item
* msp_item
, bool is_msp_item
)
8244 if (preq_info
&& preq_info
->IOILen
&& preq_info
->pIOI
)
8247 proto_tree
*epath_tree
;
8250 tvbIOI
= tvb_new_real_data((const uint8_t *)preq_info
->pIOI
, preq_info
->IOILen
* 2, preq_info
->IOILen
* 2);
8253 pi
= proto_tree_add_uint(item_tree
, hf_cip_request_path_size
, tvb
, 0, 0, preq_info
->IOILen
);
8254 proto_item_set_generated(pi
);
8257 epath_tree
= proto_tree_add_subtree(item_tree
, tvb
, 0, 0, ett_path
, &pi
, "Request Path: ");
8258 proto_item_set_generated(pi
);
8260 if (preq_info
->ciaData
== NULL
)
8262 preq_info
->ciaData
= wmem_new(wmem_file_scope(), cip_simple_request_info_t
);
8265 dissect_epath(tvbIOI
, pinfo
, epath_tree
, pi
, 0, preq_info
->IOILen
* 2, true, false, preq_info
->ciaData
, NULL
, DISPLAY_REQUEST_PATH
, msp_item
, is_msp_item
);
8272 dissect_cip_cm_data( proto_tree
*item_tree
, tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
)
8274 proto_item
*rrsc_item
, *status_item
;
8275 proto_tree
*rrsc_tree
, *cmd_data_tree
;
8277 unsigned char service
, gen_status
, add_stat_size
;
8278 unsigned short add_status
;
8280 cip_req_info_t
*preq_info
;
8282 service
= tvb_get_uint8( tvb
, offset
);
8284 /* Special handling for Unconnected send response. If successful, embedded service code is sent.
8285 * If failed, it can be either an Unconnected send response or the embedded service code response. */
8286 preq_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0 );
8287 if ( preq_info
!= NULL
&& ( service
& CIP_SC_RESPONSE_MASK
)
8288 && preq_info
->bService
== SC_CM_UNCON_SEND
8291 gen_status
= tvb_get_uint8( tvb
, offset
+2 );
8292 add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
8293 if ( add_stat_size
== 2 )
8294 add_status
= tvb_get_letohs( tvb
, offset
+ 4 );
8298 if( gen_status
== CI_GRC_SUCCESS
8299 || ( ( service
& CIP_SC_MASK
) != SC_CM_UNCON_SEND
)
8300 || !( ( gen_status
== CI_GRC_FAILURE
&& (add_status
== CM_ES_UNCONNECTED_REQUEST_TIMED_OUT
||
8301 add_status
== CM_ES_PORT_NOT_AVAILABLE
||
8302 add_status
== CM_ES_LINK_ADDRESS_NOT_VALID
||
8303 add_status
== CM_ES_INVALID_SEGMENT_IN_CONN_PATH
||
8304 add_status
== CM_ES_LINK_ADDRESS_TO_SELF_INVALID
))
8305 || gen_status
== CI_GRC_NO_RESOURCE
8306 || gen_status
== CI_GRC_BAD_PATH
8310 cip_req_info_t
* pembedded_req_info
= (cip_req_info_t
*)preq_info
->pData
;
8312 if ( pembedded_req_info
)
8315 void *p_save_proto_data
;
8317 heur_dtbl_entry_t
*hdtbl_entry
;
8319 p_save_proto_data
= p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0 );
8320 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
8321 p_add_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0, pembedded_req_info
);
8323 proto_item_set_generated(proto_tree_add_uint_format( item_tree
, hf_cip_cm_sc
, tvb
, 0, 0, SC_CM_UNCON_SEND
|CIP_SC_RESPONSE_MASK
, "Service: Unconnected Send (Response)" ));
8324 next_tvb
= tvb_new_subset_length(tvb
, offset
, item_length
);
8326 display_previous_request_path(pembedded_req_info
, item_tree
, tvb
, pinfo
, NULL
, false);
8327 display_previous_route_connection_path(preq_info
, item_tree
, tvb
, pinfo
, hf_cip_cm_route_path_size
, NO_DISPLAY
);
8329 /* Check to see if service is 'generic' */
8330 try_val_to_str_idx((service
& CIP_SC_MASK
), cip_sc_vals
, &service_index
);
8332 cip_service_info_t
* service_entry
= cip_get_service(pinfo
, service
);
8333 if ( pembedded_req_info
&& pembedded_req_info
->dissector
)
8335 call_dissector(pembedded_req_info
->dissector
, next_tvb
, pinfo
, item_tree
);
8337 else if (service_index
>= 0 && !service_entry
)
8339 /* See if object dissector wants to override generic service handling */
8340 if (!dissector_try_heuristic(heur_subdissector_service
, tvb
, pinfo
, item_tree
, &hdtbl_entry
, NULL
))
8342 dissect_cip_generic_service_rsp(tvb
, pinfo
, item_tree
);
8345 else if (service_entry
)
8347 dissect_cip_object_specific_service(tvb
, pinfo
, item_tree
, NULL
, service_entry
);
8351 call_dissector( cip_class_generic_handle
, next_tvb
, pinfo
, item_tree
);
8354 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
8355 p_add_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0, p_save_proto_data
);
8357 /* Return early because the response was only the embedded message response. */
8363 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP CM");
8365 /* Add Service code & Request/Response tree */
8366 rrsc_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
, 1, ett_cm_rrsc
, &rrsc_item
, "Service: " );
8368 /* Add Request/Response */
8369 proto_tree_add_item( rrsc_tree
, hf_cip_reqrsp
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8371 /* watch for service collisions */
8372 proto_item_append_text( rrsc_item
, "%s (%s)",
8373 val_to_str( ( service
& CIP_SC_MASK
),
8374 cip_sc_vals_cm
, "Unknown Service (0x%02x)"),
8375 val_to_str_const( ( service
& CIP_SC_RESPONSE_MASK
)>>7,
8378 /* Add Service code */
8379 proto_tree_add_item(rrsc_tree
, hf_cip_cm_sc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8380 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals_cm
);
8382 if( service
& CIP_SC_RESPONSE_MASK
)
8384 /* Response message */
8385 gen_status
= tvb_get_uint8( tvb
, offset
+2 );
8386 add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
8388 if (gen_status
== CI_GRC_FAILURE
)
8390 /* Dissect object specific error codes */
8391 proto_tree
* status_tree
= proto_tree_add_subtree(item_tree
, tvb
, offset
+2, 1, ett_status_item
, &status_item
, "Status: " );
8393 /* Add general status */
8394 proto_tree_add_item(status_tree
, hf_cip_cm_genstat
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
8395 proto_item_append_text( status_item
, "%s", val_to_str_ext( gen_status
,
8396 &cip_gs_vals_ext
, "Unknown Response (%x)") );
8398 /* Add additional status size */
8399 proto_tree_add_item(status_tree
, hf_cip_cm_addstat_size
, tvb
, offset
+3, 1, ENC_LITTLE_ENDIAN
);
8403 add_status
= tvb_get_letohs( tvb
, offset
+ 4 );
8404 proto_tree_add_item(status_tree
, hf_cip_cm_ext_status
, tvb
, offset
+4, 2, ENC_LITTLE_ENDIAN
);
8405 proto_item_append_text(status_item
, ", Extended: %s", val_to_str_ext(add_status
, &cip_cm_ext_st_vals_ext
, "Reserved (0x%04x)"));
8409 case CM_ES_RPI_NOT_ACCEPTABLE
:
8410 if (add_stat_size
< 3)
8412 expert_add_info(pinfo
, status_item
, &ei_mal_rpi_no_data
);
8416 proto_tree_add_item(status_tree
, hf_cip_cm_ext112_ot_rpi_type
, tvb
, offset
+6, 1, ENC_LITTLE_ENDIAN
);
8417 proto_tree_add_item(status_tree
, hf_cip_cm_ext112_to_rpi_type
, tvb
, offset
+7, 1, ENC_LITTLE_ENDIAN
);
8418 proto_tree_add_item(status_tree
, hf_cip_cm_ext112_ot_rpi
, tvb
, offset
+ 8, 4, ENC_LITTLE_ENDIAN
);
8419 proto_tree_add_item(status_tree
, hf_cip_cm_ext112_to_rpi
, tvb
, offset
+ 12, 4, ENC_LITTLE_ENDIAN
);
8422 case CM_ES_INVALID_CONFIGURATION_SIZE
:
8423 proto_tree_add_item(status_tree
, hf_cip_cm_ext126_size
, tvb
, offset
+6, 2, ENC_LITTLE_ENDIAN
);
8425 case CM_ES_INVALID_OT_SIZE
:
8426 proto_tree_add_item(status_tree
, hf_cip_cm_ext127_size
, tvb
, offset
+6, 2, ENC_LITTLE_ENDIAN
);
8428 case CM_ES_INVALID_TO_SIZE
:
8429 proto_tree_add_item(status_tree
, hf_cip_cm_ext128_size
, tvb
, offset
+6, 2, ENC_LITTLE_ENDIAN
);
8432 /* Add additional status */
8433 if (add_stat_size
> 1)
8435 proto_tree
* add_status_tree
= proto_tree_add_subtree( status_tree
, tvb
, offset
+4, add_stat_size
, ett_cm_add_status_item
, NULL
, "Additional Status" );
8437 for( i
=0; i
< add_stat_size
-2; i
+= 2 )
8438 proto_tree_add_item(add_status_tree
, hf_cip_cm_add_status
, tvb
, offset
+4+i
, 2, ENC_LITTLE_ENDIAN
);
8444 /* If there is any command specific data create a sub-tree for it */
8445 int data_len
= item_length
- 4 - add_stat_size
;
8449 offset
+= (4 + add_stat_size
);
8451 proto_item
*cmd_item
;
8452 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
, data_len
,
8453 ett_cm_cmd_data
, &cmd_item
, "Command Specific Data" );
8455 if( gen_status
== CI_GRC_SUCCESS
)
8457 /* Success responses */
8458 switch (service
& CIP_SC_MASK
)
8460 case SC_CM_FWD_OPEN
:
8461 case SC_CM_LARGE_FWD_OPEN
:
8462 case SC_CM_CONCURRENT_FWD_OPEN
:
8463 parsed_len
= dissect_cip_cm_fwd_open_rsp_success(preq_info
, cmd_data_tree
, tvb
, offset
, pinfo
);
8465 case SC_CM_FWD_CLOSE
:
8466 case SC_CM_CONCURRENT_FWD_CLOSE
:
8467 parsed_len
= dissect_cip_cm_fwd_close_rsp_success(cmd_data_tree
, tvb
, offset
, pinfo
, cmd_item
);
8469 case SC_CM_GET_CONN_OWNER
:
8471 /* Get Connection owner response (Success) */
8472 proto_tree_add_item( cmd_data_tree
, hf_cip_cm_gco_conn
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8473 proto_tree_add_item( cmd_data_tree
, hf_cip_cm_gco_coo_conn
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
8474 proto_tree_add_item( cmd_data_tree
, hf_cip_cm_gco_roo_conn
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
8475 proto_tree_add_item( cmd_data_tree
, hf_cip_cm_gco_last_action
, tvb
, offset
+3, 1, ENC_LITTLE_ENDIAN
);
8477 dissect_connection_triad(tvb
, offset
+ 4, cmd_data_tree
,
8478 hf_cip_cm_conn_serial_num
, hf_cip_cm_vendor
, hf_cip_cm_orig_serial_num
,
8484 case SC_CM_UNCON_SEND
: // Unconnected send response (Success)
8492 /* Error responses */
8493 switch (service
& CIP_SC_MASK
)
8495 case SC_CM_FWD_OPEN
:
8496 case SC_CM_LARGE_FWD_OPEN
:
8497 case SC_CM_FWD_CLOSE
:
8498 case SC_CM_CONCURRENT_FWD_OPEN
:
8499 case SC_CM_CONCURRENT_FWD_CLOSE
:
8501 /* Forward open and forward close error response look the same */
8502 cip_connection_triad_t conn_triad
;
8503 dissect_connection_triad(tvb
, offset
, cmd_data_tree
,
8504 hf_cip_cm_conn_serial_num
, hf_cip_cm_vendor
, hf_cip_cm_orig_serial_num
,
8507 // Remaining Path Size is an optional structure.
8508 if (tvb_reported_length_remaining(tvb
, offset
+ 8) > 0)
8510 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_remain_path_size
, tvb
, offset
+8, 1, ENC_LITTLE_ENDIAN
);
8511 proto_tree_add_item(cmd_data_tree
, hf_cip_reserved8
, tvb
, offset
+9, 1, ENC_LITTLE_ENDIAN
);
8514 /* With an error reply the connection will either never be established or it has since already closed
8515 That means the conversation should end too */
8516 enip_close_cip_connection(pinfo
, &conn_triad
);
8517 if (preq_info
!= NULL
)
8519 /* Remove any connection information */
8520 preq_info
->connInfo
= NULL
;
8524 display_previous_route_connection_path(preq_info
, cmd_data_tree
, tvb
, pinfo
, hf_cip_cm_conn_path_size
, DISPLAY_CONNECTION_PATH
);
8529 case SC_CM_UNCON_SEND
:
8530 /* Unconnected send response (Unsuccess) */
8531 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_remain_path_size
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8532 proto_tree_add_item(cmd_data_tree
, hf_cip_reserved8
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
8533 display_previous_route_connection_path(preq_info
, item_tree
, tvb
, pinfo
, hf_cip_cm_route_path_size
, NO_DISPLAY
);
8540 } /* end of if-else( CI_CRC_SUCCESS ) */
8542 int remain_len
= tvb_reported_length_remaining(tvb
, offset
+ parsed_len
);
8545 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+ parsed_len
, remain_len
, ENC_NA
);
8547 } /* End of if command-specific data present */
8549 } /* End of if reply */
8552 /* Request message */
8554 req_path_size
= tvb_get_uint8( tvb
, offset
+1 )*2;
8556 /* If there is any command specific data creat a sub-tree for it */
8557 if( (item_length
-req_path_size
-2) != 0 )
8559 proto_item
* cmd_data_item
;
8560 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2,
8561 ett_cm_cmd_data
, &cmd_data_item
, "Command Specific Data" );
8563 /* Check what service code that received */
8566 case SC_CM_FWD_OPEN
:
8567 /* Forward open Request*/
8568 dissect_cip_cm_fwd_open_req(preq_info
, cmd_data_tree
, cmd_data_item
, tvb
, offset
+2+req_path_size
, false, pinfo
, false);
8570 case SC_CM_CONCURRENT_FWD_OPEN
:
8571 dissect_cip_cm_fwd_open_req(preq_info
, cmd_data_tree
, cmd_data_item
, tvb
, offset
+2+req_path_size
, false, pinfo
, true);
8573 case SC_CM_LARGE_FWD_OPEN
:
8574 /* Large Forward open Request*/
8575 dissect_cip_cm_fwd_open_req(preq_info
, cmd_data_tree
, cmd_data_item
, tvb
, offset
+2+req_path_size
, true, pinfo
, false);
8577 case SC_CM_FWD_CLOSE
:
8578 case SC_CM_CONCURRENT_FWD_CLOSE
:
8579 dissect_cip_cm_fwd_close_req(cmd_data_tree
, tvb
, offset
+ 2 + req_path_size
, pinfo
);
8581 case SC_CM_UNCON_SEND
:
8582 dissect_cip_cm_unconnected_send_req(cmd_data_tree
, tvb
, offset
+ 2 + req_path_size
, pinfo
);
8584 case SC_CM_GET_CONN_OWNER
:
8586 /* Get Connection Owner Request */
8588 /* Display the Reserved byte */
8589 proto_tree_add_item(cmd_data_tree
, hf_cip_reserved8
, tvb
, offset
+2+req_path_size
, 1, ENC_LITTLE_ENDIAN
);
8592 uint16_t conn_path_size
= tvb_get_uint8( tvb
, offset
+2+req_path_size
+1 )*2;
8593 proto_tree_add_item(cmd_data_tree
, hf_cip_cm_conn_path_size
, tvb
, offset
+2+req_path_size
+1, 1, ENC_LITTLE_ENDIAN
);
8597 proto_tree
* epath_tree
= proto_tree_add_subtree(cmd_data_tree
, tvb
, offset
+2+req_path_size
+2, conn_path_size
, ett_path
, &pi
, "Connection Path: ");
8598 dissect_epath(tvb
, pinfo
, epath_tree
, pi
, offset
+2+req_path_size
+2, conn_path_size
, false, false, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
8603 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
8606 } /* End of if command-specific data present */
8608 } /* End of if-else( request ) */
8610 } /* End of dissect_cip_cm_data() */
8613 dissect_cip_class_cm(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
8616 proto_tree
*class_tree
;
8618 /* Create display subtree for the protocol */
8619 ti
= proto_tree_add_item(tree
, proto_cip_class_cm
, tvb
, 0, -1, ENC_NA
);
8620 class_tree
= proto_item_add_subtree( ti
, ett_cip_class_cm
);
8622 dissect_cip_cm_data( class_tree
, tvb
, 0, tvb_reported_length(tvb
), pinfo
);
8624 return tvb_reported_length(tvb
);
8627 /************************************************
8629 * Dissector for CIP PCCC Object
8631 ************************************************/
8633 dissect_cip_pccc_data( proto_tree
*item_tree
, tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
)
8635 proto_item
*rrsc_item
;
8636 proto_tree
*rrsc_tree
, *req_id_tree
, *pccc_cmd_tree
, *cmd_data_tree
;
8638 unsigned char service
;
8641 service
= tvb_get_uint8( tvb
, offset
);
8643 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP PCCC");
8645 /* Add Service code & Request/Response tree */
8646 rrsc_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
, 1, ett_pccc_rrsc
, &rrsc_item
, "Service: " );
8648 /* Add Request/Response */
8649 proto_tree_add_item( rrsc_tree
, hf_cip_reqrsp
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8651 /* watch for service collisions */
8652 proto_item_append_text( rrsc_item
, "%s (%s)",
8653 val_to_str( ( service
& CIP_SC_MASK
),
8654 cip_sc_vals_pccc
, "Unknown Service (0x%02x)"),
8655 val_to_str_const( ( service
& CIP_SC_RESPONSE_MASK
)>>7,
8658 /* Add Service code */
8659 proto_tree_add_item(rrsc_tree
, hf_cip_pccc_sc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8660 add_cip_service_to_info_column (pinfo
, service
, cip_sc_vals_pccc
);
8662 /* There is a minimum of two bytes different between the request and response request path */
8663 /* Response message */
8664 if ( service
& CIP_SC_RESPONSE_MASK
)
8666 req_path_size
= 2 + tvb_get_uint8( tvb
, offset
+2 )*2;
8668 /* Request message */
8671 req_path_size
= tvb_get_uint8( tvb
, offset
+1 )*2;
8674 int req_id_offset
= offset
+req_path_size
+2;
8675 int req_id_size
= tvb_get_uint8( tvb
, req_id_offset
);
8676 int pccc_cmd_offset
= req_id_offset
+req_id_size
;
8678 /* Add Requestor ID tree */
8679 req_id_tree
= proto_tree_add_subtree( item_tree
, tvb
, req_id_offset
, req_id_size
, ett_pccc_req_id
, NULL
, "Requestor ID" );
8680 /* Add Length of Requestor ID code */
8681 proto_tree_add_item(req_id_tree
, hf_cip_pccc_req_id_len
, tvb
, req_id_offset
, 1, ENC_LITTLE_ENDIAN
);
8682 /* Add CIP Vendor ID */
8683 proto_tree_add_item(req_id_tree
, hf_cip_pccc_cip_vend_id
, tvb
, req_id_offset
+1, 2, ENC_LITTLE_ENDIAN
);
8684 /* Add CIP Serial Number */
8685 proto_tree_add_item(req_id_tree
, hf_cip_pccc_cip_serial_num
, tvb
, req_id_offset
+3, 4, ENC_LITTLE_ENDIAN
);
8687 if( service
& CIP_SC_RESPONSE_MASK
)
8689 /* Add PCCC Response Data tree */
8690 pccc_cmd_tree
= proto_tree_add_subtree( item_tree
, tvb
, pccc_cmd_offset
, item_length
-req_path_size
-2-req_id_size
, ett_pccc_req_id
, NULL
, "PCCC Response Data" );
8692 /* Add Command Code */
8693 proto_tree_add_item(pccc_cmd_tree
, hf_cip_pccc_resp_code
, tvb
, pccc_cmd_offset
, 1, ENC_LITTLE_ENDIAN
);
8694 /* Add Status Code */
8695 proto_tree_add_item(pccc_cmd_tree
, hf_cip_pccc_sts_code
, tvb
, pccc_cmd_offset
+1, 1, ENC_LITTLE_ENDIAN
);
8696 /* Add Transaction Code */
8697 proto_tree_add_item(pccc_cmd_tree
, hf_cip_pccc_tns_code
, tvb
, pccc_cmd_offset
+2, 2, ENC_LITTLE_ENDIAN
);
8699 /* Check the status byte for the EXT_STS signifier - 0xF0 */
8700 add_status
= tvb_get_uint8( tvb
, pccc_cmd_offset
+1 );
8701 // TODO: still need to test this
8702 if ( add_status
== PCCC_GS_USE_EXTSTS
)
8704 proto_tree_add_item(pccc_cmd_tree
, hf_cip_pccc_ext_sts_code
, tvb
, pccc_cmd_offset
+4, 1, ENC_LITTLE_ENDIAN
);
8706 // handle cases where data is returned in the response
8707 else if (item_length
-req_path_size
-2-req_id_size
-4 != 0)
8709 /* Add the data tree */
8710 cmd_data_tree
= proto_tree_add_subtree( pccc_cmd_tree
, tvb
, pccc_cmd_offset
+4, item_length
-req_path_size
-2-req_id_size
-4, ett_pccc_cmd_data
, NULL
, "Function Specific Response Data" );
8711 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_data
, tvb
, pccc_cmd_offset
+4, item_length
-req_path_size
-2-req_id_size
-4, ENC_NA
);
8714 } /* end of if reply */
8716 /* Request message */
8719 /* If there is any command specific data create a sub-tree for it */
8720 if( (item_length
-req_path_size
-2) != 0 )
8722 uint32_t cmd_code
, fnc_code
;
8724 /* Add PCCC CMD Data tree */
8725 pccc_cmd_tree
= proto_tree_add_subtree( item_tree
, tvb
, pccc_cmd_offset
, item_length
-req_path_size
-2-req_id_size
, ett_pccc_req_id
, NULL
, "PCCC Command Data" );
8727 /* Add Command Code */
8728 proto_tree_add_item_ret_uint(pccc_cmd_tree
, hf_cip_pccc_cmd_code
, tvb
, pccc_cmd_offset
, 1, ENC_LITTLE_ENDIAN
, &cmd_code
);
8729 /* Add Status Code */
8730 proto_tree_add_item(pccc_cmd_tree
, hf_cip_pccc_sts_code
, tvb
, pccc_cmd_offset
+1, 1, ENC_LITTLE_ENDIAN
);
8731 /* Add Transaction Code */
8732 proto_tree_add_item(pccc_cmd_tree
, hf_cip_pccc_tns_code
, tvb
, pccc_cmd_offset
+2, 2, ENC_LITTLE_ENDIAN
);
8733 /* Add Function Code */
8737 proto_tree_add_item_ret_uint(pccc_cmd_tree
, hf_cip_pccc_fnc_code_06
, tvb
, pccc_cmd_offset
+4, 1, ENC_LITTLE_ENDIAN
, &fnc_code
);
8738 add_cip_pccc_function_to_info_column(pinfo
, fnc_code
, cip_pccc_fnc_06_vals
);
8742 proto_tree_add_item_ret_uint(pccc_cmd_tree
, hf_cip_pccc_fnc_code_07
, tvb
, pccc_cmd_offset
+4, 1, ENC_LITTLE_ENDIAN
, &fnc_code
);
8743 add_cip_pccc_function_to_info_column(pinfo
, fnc_code
, cip_pccc_fnc_07_vals
);
8747 proto_tree_add_item_ret_uint(pccc_cmd_tree
, hf_cip_pccc_fnc_code_0f
, tvb
, pccc_cmd_offset
+4, 1, ENC_LITTLE_ENDIAN
, &fnc_code
);
8748 add_cip_pccc_function_to_info_column(pinfo
, fnc_code
, cip_pccc_fnc_0f_vals
);
8756 if (item_length
-req_path_size
-2-req_id_size
-5 != 0 )
8758 /* Add the data tree */
8759 cmd_data_tree
= proto_tree_add_subtree( pccc_cmd_tree
, tvb
, pccc_cmd_offset
+5, item_length
-req_path_size
-req_id_size
-7,
8760 ett_pccc_cmd_data
, NULL
, "Function Specific Data" );
8762 int running_offset
= pccc_cmd_offset
+6;
8765 proto_tree
*sub_fnc_tree
;
8767 /* Add in parsing of instructions that contain data beyond the FNC code */
8768 /* Instructions that end at the FNC codes are already processed */
8773 /* Change CPU Mode */
8774 case PCCC_FNC_0F_80
:
8775 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_cpu_mode_80
, tvb
, pccc_cmd_offset
+5, 1, ENC_NA
);
8777 /* Execute Multiple Commands */
8778 case PCCC_FNC_0F_88
:
8779 num_cmds
= tvb_get_uint8( tvb
, pccc_cmd_offset
+5 );
8780 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_execute_multi_count
, tvb
, pccc_cmd_offset
+5, 1, ENC_NA
);
8782 /* iterate over each of the commands and break them out */
8783 for( int i
=0; i
< num_cmds
; i
++ ){
8784 sub_fnc_len
= tvb_get_uint8( tvb
, running_offset
);
8785 sub_fnc_tree
= proto_tree_add_subtree_format(cmd_data_tree
, tvb
, running_offset
, sub_fnc_len
+1, ett_pccc_req_id
, NULL
, "Sub Function #%d", i
+1);
8787 proto_tree_add_item(sub_fnc_tree
, hf_cip_pccc_execute_multi_len
, tvb
, running_offset
, 1, ENC_NA
);
8788 proto_tree_add_item(sub_fnc_tree
, hf_cip_pccc_execute_multi_fnc
, tvb
, running_offset
+1, 1, ENC_NA
);
8789 if( sub_fnc_len
> 2 ){
8790 proto_tree_add_item(sub_fnc_tree
, hf_cip_pccc_data
, tvb
, running_offset
+2, sub_fnc_len
-1, ENC_NA
);
8792 running_offset
= running_offset
+sub_fnc_len
+1;
8795 /* Protected Typed Logical Read with Three Address Fields */
8796 case PCCC_FNC_0F_A2
:
8797 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_byte_size
, tvb
, pccc_cmd_offset
+5, 1, ENC_NA
);
8798 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_file_num
, tvb
, pccc_cmd_offset
+6, 1, ENC_NA
);
8799 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_file_type
, tvb
, pccc_cmd_offset
+7, 1, ENC_NA
);
8800 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_element_num
, tvb
, pccc_cmd_offset
+8, 1, ENC_NA
);
8801 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_subelement_num
, tvb
, pccc_cmd_offset
+9, 1, ENC_NA
);
8803 /* Protected Typed Logical Write with Three Address Fields */
8804 case PCCC_FNC_0F_AA
:
8805 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_byte_size
, tvb
, pccc_cmd_offset
+5, 1, ENC_NA
);
8806 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_file_num
, tvb
, pccc_cmd_offset
+6, 1, ENC_NA
);
8807 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_file_type
, tvb
, pccc_cmd_offset
+7, 1, ENC_NA
);
8808 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_element_num
, tvb
, pccc_cmd_offset
+8, 1, ENC_NA
);
8809 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_subelement_num
, tvb
, pccc_cmd_offset
+9, 1, ENC_NA
);
8811 byte_size
= tvb_get_uint8( tvb
, pccc_cmd_offset
+5 );
8813 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_data
, tvb
, pccc_cmd_offset
+10, byte_size
, ENC_NA
);
8815 default: /* just print the command data if no known command code is passed */
8816 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_data
, tvb
, pccc_cmd_offset
+5, item_length
-pccc_cmd_offset
-5, ENC_NA
);
8819 default: /* just print the command data if no known command code is passed */
8820 proto_tree_add_item(cmd_data_tree
, hf_cip_pccc_data
, tvb
, pccc_cmd_offset
+5, 1, ENC_NA
);
8823 } /* End of if-else( request ) */
8826 } /* End of dissect_cip_pccc_data() */
8829 dissect_cip_class_pccc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
8832 proto_tree
*class_tree
;
8834 /* Create display subtree for the protocol */
8835 ti
= proto_tree_add_item(tree
, proto_cip_class_pccc
, tvb
, 0, -1, ENC_NA
);
8836 class_tree
= proto_item_add_subtree( ti
, ett_cip_class_pccc
);
8838 dissect_cip_pccc_data( class_tree
, tvb
, 0, tvb_reported_length(tvb
), pinfo
);
8840 return tvb_reported_length(tvb
);
8843 /************************************************
8845 * Dissector for CIP Modbus Object
8847 ************************************************/
8849 dissect_cip_mb_data( proto_tree
*item_tree
, tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
)
8851 proto_item
*rrsc_item
;
8852 proto_tree
*rrsc_tree
, *cmd_data_tree
;
8855 uint8_t gen_status
, add_stat_size
, service
;
8857 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP MB");
8859 /* Add Service code & Request/Response tree */
8860 service
= tvb_get_uint8( tvb
, offset
);
8861 rrsc_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
, 1, ett_mb_rrsc
, &rrsc_item
, "Service: " );
8863 /* Add Request/Response */
8864 proto_tree_add_item( rrsc_tree
, hf_cip_reqrsp
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8866 proto_item_append_text( rrsc_item
, "%s (%s)",
8867 val_to_str( ( service
& CIP_SC_MASK
),
8868 cip_sc_vals_mb
, "Unknown Service (0x%02x)"),
8869 val_to_str_const( ( service
& CIP_SC_RESPONSE_MASK
)>>7,
8872 /* Add Service code */
8873 proto_tree_add_item(rrsc_tree
, hf_cip_mb_sc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
8875 if( service
& CIP_SC_RESPONSE_MASK
)
8877 /* Response message */
8878 gen_status
= tvb_get_uint8( tvb
, offset
+2 );
8879 add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
8881 /* If there is any command specific data create a sub-tree for it */
8882 if( ( item_length
-4-add_stat_size
) != 0 )
8884 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
,
8885 ett_mb_cmd_data
, NULL
, "Command Specific Data" );
8887 if( gen_status
== CI_GRC_SUCCESS
|| gen_status
== CI_GRC_SERVICE_ERROR
)
8889 /* Success responses */
8890 switch (service
& CIP_SC_MASK
)
8892 case SC_MB_READ_DISCRETE_INPUTS
:
8893 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_discrete_inputs_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
8896 case SC_MB_READ_COILS
:
8897 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_coils_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
8900 case SC_MB_READ_INPUT_REGISTERS
:
8901 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_input_register_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
8904 case SC_MB_READ_HOLDING_REGISTERS
:
8905 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_holding_register_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
8908 case SC_MB_WRITE_COILS
:
8909 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_coils_start_addr
, tvb
, offset
+4+add_stat_size
, 2, ENC_LITTLE_ENDIAN
);
8910 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_coils_outputs_forced
, tvb
, offset
+4+add_stat_size
+2, 2, ENC_LITTLE_ENDIAN
);
8913 case SC_MB_WRITE_HOLDING_REGISTERS
:
8914 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_registers_start_addr
, tvb
, offset
+4+add_stat_size
, 2, ENC_LITTLE_ENDIAN
);
8915 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_registers_outputs_forced
, tvb
, offset
+4+add_stat_size
+2, 2, ENC_LITTLE_ENDIAN
);
8918 case SC_MB_PASSTHROUGH
:
8919 /* Passthrough response (Success) */
8920 if( tvb_reported_length_remaining(tvb
, offset
) > 0 )
8922 modbus_data_t modbus_data
;
8923 modbus_data
.packet_type
= RESPONSE_PACKET
;
8924 modbus_data
.mbtcp_transid
= 0;
8925 modbus_data
.unit_id
= 0;
8927 /* dissect the Modbus PDU */
8928 next_tvb
= tvb_new_subset_length( tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
);
8930 /* Call Modbus Dissector */
8931 call_dissector_with_data(modbus_handle
, next_tvb
, pinfo
, cmd_data_tree
, &modbus_data
);
8937 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
8942 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
8945 } /* End of if command-specific data present */
8947 } /* End of if reply */
8950 /* Request message */
8951 req_path_size
= tvb_get_uint8( tvb
, offset
+1 )*2;
8953 /* If there is any command specific data creat a sub-tree for it */
8954 if( (item_length
-req_path_size
-2) != 0 )
8956 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2,
8957 ett_mb_cmd_data
, NULL
, "Command Specific Data" );
8959 /* Check what service code that received */
8962 case SC_MB_READ_DISCRETE_INPUTS
:
8963 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_discrete_inputs_start_addr
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
8964 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_discrete_inputs_num_inputs
, tvb
, offset
+2+req_path_size
+2, 2, ENC_LITTLE_ENDIAN
);
8967 case SC_MB_READ_COILS
:
8968 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_coils_start_addr
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
8969 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_coils_num_coils
, tvb
, offset
+2+req_path_size
+2, 2, ENC_LITTLE_ENDIAN
);
8972 case SC_MB_READ_INPUT_REGISTERS
:
8973 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_input_register_start_addr
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
8974 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_input_register_num_registers
, tvb
, offset
+2+req_path_size
+2, 2, ENC_LITTLE_ENDIAN
);
8977 case SC_MB_READ_HOLDING_REGISTERS
:
8978 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_holding_register_start_addr
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
8979 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_read_holding_register_num_registers
, tvb
, offset
+2+req_path_size
+2, 2, ENC_LITTLE_ENDIAN
);
8982 case SC_MB_WRITE_COILS
:
8986 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_coils_start_addr
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
8987 NumCoils
= tvb_get_letohs( tvb
, offset
+2+req_path_size
+2 );
8988 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_coils_num_coils
, tvb
, offset
+2+req_path_size
+2, 2, ENC_LITTLE_ENDIAN
);
8989 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_coils_data
, tvb
, offset
+2+req_path_size
+4, (NumCoils
+7)/8, ENC_NA
);
8993 case SC_MB_WRITE_HOLDING_REGISTERS
:
8995 uint16_t NumRegisters
;
8997 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_registers_start_addr
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
8998 NumRegisters
= tvb_get_letohs( tvb
, offset
+2+req_path_size
+2 );
8999 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_registers_num_registers
, tvb
, offset
+2+req_path_size
+2, 2, ENC_LITTLE_ENDIAN
);
9000 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_write_registers_data
, tvb
, offset
+2+req_path_size
+4, NumRegisters
*2, ENC_NA
);
9004 case SC_MB_PASSTHROUGH
:
9005 /* Passthrough Request */
9006 if( tvb_reported_length_remaining(tvb
, offset
) > 0 )
9008 modbus_data_t modbus_data
;
9009 modbus_data
.packet_type
= QUERY_PACKET
;
9010 modbus_data
.mbtcp_transid
= 0;
9011 modbus_data
.unit_id
= 0;
9013 /* dissect the Modbus PDU */
9014 next_tvb
= tvb_new_subset_length( tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2);
9016 /* Call Modbus Dissector */
9017 call_dissector_with_data(modbus_handle
, next_tvb
, pinfo
, cmd_data_tree
, &modbus_data
);
9022 proto_tree_add_item(cmd_data_tree
, hf_cip_mb_data
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
9025 } /* End of if command-specific data present */
9027 } /* End of if-else( request ) */
9029 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals_mb
);
9030 } /* End of dissect_cip_mb_data() */
9033 dissect_cip_class_mb(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
9036 proto_tree
*class_tree
;
9038 /* Create display subtree for the protocol */
9039 ti
= proto_tree_add_item(tree
, proto_cip_class_mb
, tvb
, 0, -1, ENC_NA
);
9040 class_tree
= proto_item_add_subtree( ti
, ett_cip_class_mb
);
9042 dissect_cip_mb_data( class_tree
, tvb
, 0, tvb_reported_length(tvb
), pinfo
);
9044 return tvb_reported_length(tvb
);
9047 /************************************************
9049 * Dissector for CIP Connection Configuration Object
9051 ************************************************/
9053 dissect_cip_cco_all_attribute_common( proto_tree
*cmd_tree
, proto_item
*ti
,
9054 tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
)
9057 proto_tree
*tdi_tree
, *iomap_tree
, *epath_tree
;
9058 proto_tree
*ncp_tree
;
9059 int conn_path_size
, variable_data_size
= 0, config_data_size
;
9060 int iomap_size
, ot_rtf
, to_rtf
;
9063 /* Connection flags */
9064 temp_data
= tvb_get_letohs( tvb
, offset
);
9065 ot_rtf
= (temp_data
>> 1) & 7;
9066 to_rtf
= (temp_data
>> 4) & 7;
9068 static int *const connection_flags
[] = {
9069 &hf_cip_cco_con_type
,
9074 proto_tree_add_bitmask(cmd_tree
, tvb
, offset
, hf_cip_cco_con_flags
, ett_cco_con_flag
, connection_flags
, ENC_LITTLE_ENDIAN
);
9076 /* Target device id */
9077 tdi_tree
= proto_tree_add_subtree( cmd_tree
, tvb
, offset
+2, 10, ett_cco_tdi
, NULL
, "Target Device ID");
9079 dissect_deviceid(tvb
, offset
+2, tdi_tree
,
9080 hf_cip_cco_tdi_vendor
, hf_cip_cco_tdi_devtype
, hf_cip_cco_tdi_prodcode
,
9081 hf_cip_cco_tdi_compatibility
, hf_cip_cco_tdi_comp_bit
, hf_cip_cco_tdi_majorrev
, hf_cip_cco_tdi_minorrev
, false, ENC_LITTLE_ENDIAN
);
9083 /* CS Data Index Number */
9084 proto_tree_add_item(cmd_tree
, hf_cip_cco_cs_data_index
, tvb
, offset
+10, 4, ENC_LITTLE_ENDIAN
);
9086 /* Net Connection Parameters */
9087 ncp_tree
= proto_tree_add_subtree( cmd_tree
, tvb
, offset
+14, 14, ett_cco_ncp
, NULL
, "Net Connection Parameters");
9089 /* Timeout multiplier */
9090 proto_tree_add_item(ncp_tree
, hf_cip_cco_timeout_multiplier
, tvb
, offset
+14, 1, ENC_LITTLE_ENDIAN
);
9092 dissect_transport_type_trigger(tvb
, offset
+15, ncp_tree
, hf_cip_cco_transport_type_trigger
,
9093 hf_cip_cco_fwo_dir
, hf_cip_cco_fwo_trigger
, hf_cip_cco_fwo_class
, ett_cco_ttt
);
9095 proto_tree_add_item(ncp_tree
, hf_cip_cco_ot_rpi
, tvb
, offset
+ 16, 4, ENC_LITTLE_ENDIAN
);
9097 /* Display O->T network connection parameters */
9098 cip_connID_info_t ignore
;
9099 dissect_net_param16(tvb
, offset
+20, ncp_tree
,
9100 hf_cip_cco_ot_net_param16
, hf_cip_cco_fwo_own
, hf_cip_cco_fwo_typ
,
9101 hf_cip_cco_fwo_prio
, hf_cip_cco_fwo_fixed_var
, hf_cip_cco_fwo_con_size
, ett_cco_ncp
, &ignore
);
9103 proto_tree_add_item(ncp_tree
, hf_cip_cco_to_rpi
, tvb
, offset
+ 22, 4, ENC_LITTLE_ENDIAN
);
9105 /* Display T->O network connection parameters */
9106 dissect_net_param16(tvb
, offset
+26, ncp_tree
,
9107 hf_cip_cco_to_net_param16
, hf_cip_cco_fwo_own
, hf_cip_cco_fwo_typ
,
9108 hf_cip_cco_fwo_prio
, hf_cip_cco_fwo_fixed_var
, hf_cip_cco_fwo_con_size
, ett_cco_ncp
, &ignore
);
9110 /* Connection Path */
9111 conn_path_size
= tvb_get_uint8( tvb
, offset
+28 )*2;
9112 proto_tree_add_item(cmd_tree
, hf_cip_cco_conn_path_size
, tvb
, offset
+28, 1, ENC_LITTLE_ENDIAN
);
9114 /* Display the Reserved byte */
9115 proto_tree_add_item(cmd_tree
, hf_cip_reserved8
, tvb
, offset
+29, 1, ENC_LITTLE_ENDIAN
);
9118 epath_tree
= proto_tree_add_subtree(cmd_tree
, tvb
, offset
+30, conn_path_size
, ett_path
, &pi
, "Connection Path: ");
9119 dissect_epath(tvb
, pinfo
, epath_tree
, pi
, offset
+30, conn_path_size
, false, false, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
9121 variable_data_size
+= (conn_path_size
+30);
9123 /* Config #1 Data */
9124 config_data_size
= tvb_get_letohs( tvb
, offset
+variable_data_size
);
9125 proto_tree_add_item(cmd_tree
, hf_cip_cco_proxy_config_size
, tvb
, offset
+variable_data_size
, 2, ENC_LITTLE_ENDIAN
);
9126 if (config_data_size
> 0)
9127 proto_tree_add_item(cmd_tree
, hf_cip_cco_proxy_config_data
, tvb
, offset
+variable_data_size
+2, config_data_size
, ENC_NA
);
9129 variable_data_size
+= (config_data_size
+2);
9131 /* Config #2 Data */
9132 config_data_size
= tvb_get_letohs( tvb
, offset
+variable_data_size
);
9133 proto_tree_add_item(cmd_tree
, hf_cip_cco_target_config_size
, tvb
, offset
+variable_data_size
, 2, ENC_LITTLE_ENDIAN
);
9134 if (config_data_size
> 0)
9135 proto_tree_add_item(cmd_tree
, hf_cip_cco_target_config_data
, tvb
, offset
+variable_data_size
+2, config_data_size
, ENC_NA
);
9137 variable_data_size
+= (config_data_size
+2);
9139 /* Connection Name */
9140 variable_data_size
+= dissect_cip_string_type(pinfo
, cmd_tree
, ti
, tvb
, offset
+ variable_data_size
, hf_cip_cco_connection_name
, CIP_STRING2_TYPE
);
9143 iomap_size
= tvb_get_letohs( tvb
, offset
+variable_data_size
+2);
9145 iomap_tree
= proto_tree_add_subtree( cmd_tree
, tvb
, offset
+variable_data_size
, iomap_size
+4, ett_cco_iomap
, NULL
, "I/O Mapping");
9147 proto_tree_add_item(iomap_tree
, hf_cip_cco_iomap_format_number
, tvb
, offset
+variable_data_size
, 2, ENC_LITTLE_ENDIAN
);
9148 proto_tree_add_item(iomap_tree
, hf_cip_cco_iomap_size
, tvb
, offset
+variable_data_size
+2, 2, ENC_LITTLE_ENDIAN
);
9150 /* Attribute data */
9152 proto_tree_add_item(iomap_tree
, hf_cip_cco_iomap_attribute
, tvb
, offset
+variable_data_size
+4, iomap_size
, ENC_NA
);
9154 variable_data_size
+= (iomap_size
+4);
9156 /* Proxy device id */
9157 tdi_tree
= proto_tree_add_subtree( cmd_tree
, tvb
, offset
+variable_data_size
, 8, ett_cco_pdi
, NULL
, "Proxy Device ID");
9159 dissect_deviceid(tvb
, offset
+variable_data_size
, tdi_tree
,
9160 hf_cip_cco_pdi_vendor
, hf_cip_cco_pdi_devtype
, hf_cip_cco_pdi_prodcode
,
9161 hf_cip_cco_pdi_compatibility
, hf_cip_cco_pdi_comp_bit
, hf_cip_cco_pdi_majorrev
, hf_cip_cco_pdi_minorrev
, false, ENC_LITTLE_ENDIAN
);
9163 /* Add in proxy device id size */
9164 variable_data_size
+= 8;
9166 if ((offset
+variable_data_size
< item_length
) &&
9167 ((ot_rtf
== 5) || (to_rtf
== 5)))
9169 /* Safety parameters */
9170 proto_tree_add_item(cmd_tree
, hf_cip_cco_safety
, tvb
, offset
+variable_data_size
, 55, ENC_NA
);
9171 variable_data_size
+= 55;
9174 if (offset
+variable_data_size
< item_length
)
9176 proto_tree_add_item(cmd_tree
, hf_cip_cco_connection_disable
, tvb
, offset
+variable_data_size
, 1, ENC_LITTLE_ENDIAN
);
9177 variable_data_size
++;
9180 if (offset
+variable_data_size
< item_length
)
9182 proto_tree_add_item(cmd_tree
, hf_cip_cco_net_conn_param_attr
, tvb
, offset
+variable_data_size
, 1, ENC_LITTLE_ENDIAN
);
9183 variable_data_size
++;
9186 if (offset
+variable_data_size
< item_length
)
9188 /* Large Net Connection Parameter */
9189 ncp_tree
= proto_tree_add_subtree( cmd_tree
, tvb
, offset
+variable_data_size
, 18, ett_cco_ncp
, NULL
, "Large Net Connection Parameters");
9191 proto_tree_add_item(ncp_tree
, hf_cip_cco_timeout_multiplier
, tvb
, offset
+variable_data_size
, 1, ENC_LITTLE_ENDIAN
);
9192 dissect_transport_type_trigger(tvb
, offset
+variable_data_size
+1, ncp_tree
, hf_cip_cco_transport_type_trigger
,
9193 hf_cip_cco_fwo_dir
, hf_cip_cco_fwo_trigger
, hf_cip_cco_fwo_class
, ett_cco_ttt
);
9195 proto_tree_add_item(ncp_tree
, hf_cip_cco_ot_rpi
, tvb
, offset
+ variable_data_size
+ 2, 4, ENC_LITTLE_ENDIAN
);
9197 /* Display O->T network connection parameters */
9198 dissect_net_param32(tvb
, offset
+variable_data_size
+6, ncp_tree
,
9199 hf_cip_cco_ot_net_param32
, hf_cip_cco_lfwo_own
, hf_cip_cco_lfwo_typ
,
9200 hf_cip_cco_lfwo_prio
, hf_cip_cco_lfwo_fixed_var
, hf_cip_cco_lfwo_con_size
, ett_cco_ncp
, &ignore
);
9202 proto_tree_add_item(ncp_tree
, hf_cip_cco_to_rpi
, tvb
, offset
+ variable_data_size
+ 10, 4, ENC_LITTLE_ENDIAN
);
9204 /* Display T->O network connection parameters */
9205 dissect_net_param32(tvb
, offset
+variable_data_size
+14, ncp_tree
,
9206 hf_cip_cco_to_net_param32
, hf_cip_cco_lfwo_own
, hf_cip_cco_lfwo_typ
,
9207 hf_cip_cco_lfwo_prio
, hf_cip_cco_lfwo_fixed_var
, hf_cip_cco_lfwo_con_size
, ett_cco_ncp
, &ignore
);
9209 variable_data_size
+= 18;
9212 return variable_data_size
;
9216 dissect_cip_cco_data( proto_tree
*item_tree
, proto_item
*ti
, tvbuff_t
*tvb
, int offset
, int item_length
, packet_info
*pinfo
)
9218 proto_item
*rrsc_item
;
9219 proto_tree
*rrsc_tree
, *cmd_data_tree
, *con_st_tree
;
9221 uint8_t service
, gen_status
, add_stat_size
;
9222 cip_simple_request_info_t req_data
;
9224 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP CCO");
9226 /* Add Service code & Request/Response tree */
9227 service
= tvb_get_uint8( tvb
, offset
);
9228 rrsc_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
, 1, ett_cco_rrsc
, &rrsc_item
, "Service: " );
9230 /* Add Request/Response */
9231 proto_tree_add_item( rrsc_tree
, hf_cip_reqrsp
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
9233 proto_item_append_text( rrsc_item
, "%s (%s)",
9234 val_to_str( ( service
& CIP_SC_MASK
),
9235 cip_sc_vals_cco
, "Unknown Service (0x%02x)"),
9236 val_to_str_const( ( service
& CIP_SC_RESPONSE_MASK
)>>7,
9239 /* Add Service code */
9240 proto_tree_add_item(rrsc_tree
, hf_cip_cco_sc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
9242 load_cip_request_data(pinfo
, &req_data
);
9244 if(service
& CIP_SC_RESPONSE_MASK
)
9246 /* Response message */
9248 /* Add additional status size */
9249 gen_status
= tvb_get_uint8( tvb
, offset
+2 );
9250 add_stat_size
= tvb_get_uint8( tvb
, offset
+3 ) * 2;
9252 /* If there is any command specific data create a sub-tree for it */
9253 if( ( item_length
-4-add_stat_size
) != 0 )
9255 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
,
9256 ett_cco_cmd_data
, NULL
, "Command Specific Data" );
9258 if( gen_status
== CI_GRC_SUCCESS
)
9260 /* Success responses */
9261 if (((service
& CIP_SC_MASK
) == SC_GET_ATT_ALL
) &&
9262 (req_data
.iInstance
!= SEGMENT_VALUE_NOT_SET
))
9264 if (req_data
.iInstance
== 0)
9266 /* Get Attribute All (class) request */
9267 dissect_cip_get_attribute_all_rsp(tvb
, pinfo
, cmd_data_tree
, offset
+ 4 + add_stat_size
, &req_data
);
9271 /* Get Attribute All (instance) request */
9273 /* Connection status */
9274 con_st_tree
= proto_tree_add_subtree( cmd_data_tree
, tvb
, offset
+4+add_stat_size
, 4, ett_cco_con_status
, NULL
, "Connection Status");
9276 proto_tree_add_item(con_st_tree
, hf_cip_genstat
, tvb
, offset
+4+add_stat_size
, 1, ENC_LITTLE_ENDIAN
);
9277 proto_tree_add_item(con_st_tree
, hf_cip_pad8
, tvb
, offset
+4+add_stat_size
+1, 1, ENC_LITTLE_ENDIAN
);
9279 /* Extended Status */
9280 proto_tree_add_item(con_st_tree
, hf_cip_cco_ext_status
, tvb
, offset
+4+add_stat_size
+2, 2, ENC_LITTLE_ENDIAN
);
9282 dissect_cip_cco_all_attribute_common(cmd_data_tree
, ti
, tvb
, offset
+4+add_stat_size
+4, item_length
, pinfo
);
9288 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
9293 /* Error responses */
9296 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+4+add_stat_size
, item_length
-4-add_stat_size
, ENC_NA
);
9297 } /* end of if-else( CI_CRC_SUCCESS ) */
9299 } /* End of if command-specific data present */
9301 } /* End of if reply */
9304 /* Request message */
9305 req_path_size
= tvb_get_uint8( tvb
, offset
+1 )*2;
9307 /* If there is any command specific data create a sub-tree for it */
9308 if( (item_length
-req_path_size
-2) != 0 )
9311 cmd_data_tree
= proto_tree_add_subtree( item_tree
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2,
9312 ett_cco_cmd_data
, NULL
, "Command Specific Data" );
9314 /* Check what service code that received */
9318 case SC_CCO_AUDIT_CHANGE
:
9319 proto_tree_add_item(cmd_data_tree
, hf_cip_cco_change_type
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
9321 case SC_CCO_CHANGE_COMPLETE
:
9322 proto_tree_add_item(cmd_data_tree
, hf_cip_cco_change_type
, tvb
, offset
+2+req_path_size
, 2, ENC_LITTLE_ENDIAN
);
9324 case SC_SET_ATT_ALL
:
9325 if ((req_data
.iInstance
== 0) ||
9326 (req_data
.iInstance
== SEGMENT_VALUE_NOT_SET
))
9328 /* Just add raw data */
9329 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
9333 /* Set Attribute All (instance) request */
9334 dissect_cip_cco_all_attribute_common(cmd_data_tree
, ti
, tvb
, offset
+2+req_path_size
, item_length
, pinfo
);
9339 proto_tree_add_item(cmd_data_tree
, hf_cip_data
, tvb
, offset
+2+req_path_size
, item_length
-req_path_size
-2, ENC_NA
);
9340 } /* End of check service code */
9342 } /* End of if command-specific data present */
9344 } /* End of if-else( request ) */
9346 add_cip_service_to_info_column(pinfo
, service
, cip_sc_vals_cco
);
9347 } /* End of dissect_cip_cco_data() */
9350 dissect_cip_class_cco(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
9353 proto_tree
*class_tree
;
9355 /* Create display subtree for the protocol */
9356 ti
= proto_tree_add_item(tree
, proto_cip_class_cco
, tvb
, 0, -1, ENC_NA
);
9357 class_tree
= proto_item_add_subtree( ti
, ett_cip_class_cco
);
9359 dissect_cip_cco_data( class_tree
, ti
, tvb
, 0, tvb_reported_length(tvb
), pinfo
);
9361 return tvb_reported_length(tvb
);
9365 dissect_class_cco_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
9367 unsigned char service
, service_code
, ioilen
, segment
;
9368 cip_req_info_t
* preq_info
;
9369 uint32_t classid
= 0;
9372 service
= tvb_get_uint8( tvb
, offset
);
9373 service_code
= service
& CIP_SC_MASK
;
9375 /* Handle GetAttributeAll and SetAttributeAll in CCO class */
9376 if ((service_code
== SC_GET_ATT_ALL
) ||
9377 (service_code
== SC_SET_ATT_ALL
))
9379 if (service
& CIP_SC_RESPONSE_MASK
)
9381 /* Service response */
9382 preq_info
= (cip_req_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
9383 if ((preq_info
!= NULL
) &&
9384 (preq_info
->dissector
== dissector_get_uint_handle( subdissector_class_table
, CI_CLS_CCO
)))
9386 call_dissector(preq_info
->dissector
, tvb
, pinfo
, tree
);
9392 /* Service request */
9393 ioilen
= tvb_get_uint8( tvb
, offset
+ 1 );
9396 segment
= tvb_get_uint8( tvb
, offset
+ 2 );
9397 if (((segment
& CI_SEGMENT_TYPE_MASK
) == CI_LOGICAL_SEGMENT
) &&
9398 ((segment
& CI_LOGICAL_SEG_TYPE_MASK
) == CI_LOGICAL_SEG_CLASS_ID
))
9400 /* Logical Class ID, do a format check */
9401 switch ( segment
& CI_LOGICAL_SEG_FORMAT_MASK
)
9403 case CI_LOGICAL_SEG_8_BIT
:
9404 classid
= tvb_get_uint8( tvb
, offset
+ 3 );
9406 case CI_LOGICAL_SEG_16_BIT
:
9408 classid
= tvb_get_letohs( tvb
, offset
+ 4 );
9410 case CI_LOGICAL_SEG_32_BIT
:
9412 classid
= tvb_get_letohl( tvb
, offset
+ 4 );
9418 if (classid
== CI_CLS_CCO
)
9420 call_dissector(cip_class_cco_handle
, tvb
, pinfo
, tree
);
9430 /************************************************
9432 * Dissector for CIP Request/Response
9433 * - matches requests/responses
9434 * - calls class specific dissector
9436 ************************************************/
9438 // NOLINTNEXTLINE(misc-no-recursion)
9439 void dissect_cip_data( proto_tree
*item_tree
, tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
, cip_req_info_t
* preq_info
, proto_item
* msp_item
, bool is_msp_item
)
9442 proto_tree
*cip_tree
, *epath_tree
;
9443 proto_item
*pi
, *rrsc_item
, *status_item
;
9444 proto_tree
*rrsc_tree
, *status_tree
, *add_status_tree
;
9446 unsigned char i
, gen_status
;
9447 unsigned char service
,ioilen
,segment
;
9448 void *p_save_proto_data
;
9449 cip_simple_request_info_t path_info
;
9450 dissector_handle_t dissector
;
9452 heur_dtbl_entry_t
*hdtbl_entry
;
9454 p_save_proto_data
= p_get_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
9455 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
9456 p_add_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0, preq_info
);
9458 /* Create display subtree for the protocol */
9459 ti
= proto_tree_add_item(item_tree
, proto_cip
, tvb
, 0, -1, ENC_NA
);
9460 cip_tree
= proto_item_add_subtree( ti
, ett_cip
);
9462 service
= tvb_get_uint8( tvb
, offset
);
9464 /* Add Service code & Request/Response tree */
9465 rrsc_item
= proto_tree_add_uint_format_value(cip_tree
, hf_cip_service
,
9466 tvb
, offset
, 1, service
, "%s (%s)",
9467 val_to_str( ( service
& CIP_SC_MASK
), cip_sc_vals
, "Unknown Service (0x%02x)"),
9468 val_to_str_const( ( service
& CIP_SC_RESPONSE_MASK
)>>7, cip_sc_rr
, ""));
9470 rrsc_tree
= proto_item_add_subtree( rrsc_item
, ett_rrsc
);
9472 proto_tree_add_item( rrsc_tree
, hf_cip_reqrsp
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
9473 proto_tree_add_item(rrsc_tree
, hf_cip_service_code
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
9475 increment_dissection_depth(pinfo
);
9476 if( service
& CIP_SC_RESPONSE_MASK
)
9478 /* Response message */
9479 status_tree
= proto_tree_add_subtree( cip_tree
, tvb
, offset
+2, 1, ett_status_item
, &status_item
, "Status: " );
9481 /* Add general status */
9482 gen_status
= tvb_get_uint8( tvb
, offset
+2 );
9483 proto_tree_add_item(status_tree
, hf_cip_genstat
, tvb
, offset
+2, 1, ENC_LITTLE_ENDIAN
);
9484 proto_item_append_text( status_item
, "%s: ", val_to_str_ext( gen_status
,
9485 &cip_gs_vals_ext
, "Unknown Response (%x)") );
9487 if (is_msp_item
== false)
9489 /* Add reply status to info column */
9490 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s: ",
9491 val_to_str_ext(gen_status
, &cip_gs_vals_ext
, "Unknown Response (%x)"));
9495 proto_item_append_text(msp_item
, "%s: ",
9496 val_to_str_ext(gen_status
, &cip_gs_vals_ext
, "Unknown Response (%x)"));
9499 /* Add additional status size */
9500 uint8_t add_stat_size
= tvb_get_uint8( tvb
, offset
+3 );
9501 proto_tree_add_item(status_tree
, hf_cip_addstat_size
, tvb
, offset
+3, 1, ENC_LITTLE_ENDIAN
);
9505 /* Add additional status */
9506 add_status_tree
= proto_tree_add_subtree( status_tree
, tvb
, offset
+4, add_stat_size
*2, ett_add_status_item
, NULL
, "Additional Status" );
9508 for( i
=0; i
< add_stat_size
; i
++ )
9509 proto_tree_add_item(add_status_tree
, hf_cip_add_stat
, tvb
, offset
+4+(i
*2), 2, ENC_LITTLE_ENDIAN
);
9512 proto_item_set_len( status_item
, 2 + add_stat_size
*2);
9514 /* The previous packet service must be Unconnected Send, or match the current
9515 service to be a valid match. If they don't, ignore the previous data.*/
9517 && !( preq_info
->bService
== ( service
& CIP_SC_MASK
)
9518 || ( preq_info
->bService
== SC_CM_UNCON_SEND
&& preq_info
->dissector
== cip_class_cm_handle
)
9523 display_previous_request_path(preq_info
, cip_tree
, tvb
, pinfo
, msp_item
, is_msp_item
);
9525 /* Check to see if service is 'generic' */
9526 try_val_to_str_idx((service
& CIP_SC_MASK
), cip_sc_vals
, &service_index
);
9528 cip_service_info_t
* service_entry
= cip_get_service(pinfo
, service
);
9530 /* If the request set a dissector, then check that first. This ensures
9531 that Unconnected Send responses are properly parsed based on the
9532 embedded request. */
9533 if (preq_info
&& preq_info
->dissector
)
9535 call_dissector(preq_info
->dissector
, tvb
, pinfo
, item_tree
);
9537 else if (service_index
>= 0 && !service_entry
)
9539 /* See if object dissector wants to override generic service handling */
9540 if(!dissector_try_heuristic(heur_subdissector_service
, tvb
, pinfo
, item_tree
, &hdtbl_entry
, NULL
))
9542 dissect_cip_generic_service_rsp(tvb
, pinfo
, cip_tree
);
9545 else if (service_entry
)
9547 dissect_cip_object_specific_service(tvb
, pinfo
, cip_tree
, msp_item
, service_entry
);
9551 call_dissector( cip_class_generic_handle
, tvb
, pinfo
, item_tree
);
9553 } /* End of if reply */
9556 /* Request message */
9558 /* Add path size to tree */
9559 req_path_size
= tvb_get_uint8( tvb
, offset
+1);
9560 proto_tree_add_item(cip_tree
, hf_cip_request_path_size
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
9563 epath_tree
= proto_tree_add_subtree(cip_tree
, tvb
, offset
+2, req_path_size
*2, ett_path
, &pi
, "Request Path: ");
9566 preq_info
->ciaData
= wmem_new(wmem_file_scope(), cip_simple_request_info_t
);
9567 dissect_epath(tvb
, pinfo
, epath_tree
, pi
, offset
+2, req_path_size
*2, false, false, preq_info
->ciaData
, NULL
, DISPLAY_REQUEST_PATH
, msp_item
, is_msp_item
);
9568 memcpy(&path_info
, preq_info
->ciaData
, sizeof(cip_simple_request_info_t
));
9572 dissect_epath(tvb
, pinfo
, epath_tree
, pi
, offset
+2, req_path_size
*2, false, false, &path_info
, NULL
, DISPLAY_REQUEST_PATH
, msp_item
, is_msp_item
);
9575 ioilen
= tvb_get_uint8( tvb
, offset
+ 1 );
9578 preq_info
->dissector
= NULL
;
9581 /* The class ID should already be extracted if it's available */
9582 if (path_info
.iClass
!= 0xFFFFFFFF)
9584 dissector
= dissector_get_uint_handle( subdissector_class_table
, path_info
.iClass
);
9590 segment
= tvb_get_uint8( tvb
, offset
+ 2 );
9591 if ((segment
& CI_SEGMENT_TYPE_MASK
) == CI_DATA_SEGMENT
)
9593 dissector
= dissector_get_uint_handle( subdissector_symbol_table
, segment
);
9600 preq_info
->dissector
= dissector
;
9602 /* copy IOI for access by response packet */
9603 preq_info
->pIOI
= wmem_alloc(wmem_file_scope(), ioilen
*2);
9604 preq_info
->IOILen
= ioilen
;
9605 tvb_memcpy(tvb
, preq_info
->pIOI
, offset
+2, ioilen
*2);
9607 preq_info
->bService
= service
;
9610 /* Check to see if service is 'generic' */
9611 try_val_to_str_idx(service
, cip_sc_vals
, &service_index
);
9613 cip_service_info_t
* service_entry
= cip_get_service(pinfo
, service
);
9614 if (service_index
>= 0 && !service_entry
)
9616 /* See if object dissector wants to override generic service handling */
9617 if(!dissector_try_heuristic(heur_subdissector_service
, tvb
, pinfo
, item_tree
, &hdtbl_entry
, NULL
))
9619 /* No need to set a custom dissector if this is just a generic service. */
9622 preq_info
->dissector
= NULL
;
9625 dissect_cip_generic_service_req(tvb
, pinfo
, cip_tree
, &path_info
);
9628 else if ( dissector
)
9630 call_dissector( dissector
, tvb
, pinfo
, item_tree
);
9632 else if (service_entry
)
9634 dissect_cip_object_specific_service(tvb
, pinfo
, cip_tree
, msp_item
, service_entry
);
9638 call_dissector( cip_class_generic_handle
, tvb
, pinfo
, item_tree
);
9640 } /* End of if-else( request ) */
9642 decrement_dissection_depth(pinfo
);
9644 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0);
9645 p_add_proto_data(wmem_file_scope(), pinfo
, proto_cip
, 0, p_save_proto_data
);
9647 } /* End of dissect_cip_data() */
9649 void dissect_cip_run_idle(tvbuff_t
* tvb
, int offset
, proto_tree
* item_tree
)
9651 static int * const run_idle_header
[] = {
9652 &hf_32bitheader_roo
,
9653 &hf_32bitheader_coo
,
9654 &hf_32bitheader_run_idle
,
9658 proto_tree_add_bitmask(item_tree
, tvb
, offset
, hf_32bitheader
, ett_32bitheader_tree
, run_idle_header
, ENC_LITTLE_ENDIAN
);
9662 dissect_cip(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
9664 enip_request_info_t
*enip_info
;
9665 cip_req_info_t
*preq_info
;
9667 /* Make entries in Protocol column and Info column on summary display */
9668 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP");
9670 col_clear(pinfo
->cinfo
, COL_INFO
);
9671 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, " | ", "");
9673 /* Each CIP request received by ENIP gets a unique ID */
9674 enip_info
= (enip_request_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
);
9678 preq_info
= enip_info
->cip_info
;
9679 if ( preq_info
== NULL
)
9681 preq_info
= wmem_new0(wmem_file_scope(), cip_req_info_t
);
9682 enip_info
->cip_info
= preq_info
;
9684 dissect_cip_data( tree
, tvb
, 0, pinfo
, enip_info
->cip_info
, NULL
, false );
9688 dissect_cip_data( tree
, tvb
, 0, pinfo
, NULL
, NULL
, false );
9691 return tvb_reported_length(tvb
);
9695 dissect_cip_implicit(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
9698 proto_tree
*cip_tree
;
9700 uint32_t ClassID
= GPOINTER_TO_UINT(data
);
9701 int length
= tvb_reported_length_remaining(tvb
, 0);
9703 /* Make entries in Protocol column and Info column on summary display */
9704 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP");
9705 col_clear(pinfo
->cinfo
, COL_INFO
);
9707 /* Create display subtree for the protocol */
9708 ti
= proto_tree_add_item(tree
, proto_cip
, tvb
, 0, length
, ENC_NA
);
9709 cip_tree
= proto_item_add_subtree(ti
, ett_cip
);
9711 proto_tree_add_item(cip_tree
, hf_cip_data
, tvb
, 0, length
, ENC_NA
);
9713 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "Implicit Data - %s",
9714 val_to_str(ClassID
, cip_class_names_vals
, "Class (0x%02x)"));
9716 return tvb_reported_length(tvb
);
9720 * Protocol initialization
9724 proto_register_cip(void)
9726 /* Setup list of header fields */
9727 static hf_register_info hf
[] = {
9728 { &hf_attr_class_revision
, { "Revision", "cip.class_revision", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9729 { &hf_attr_class_max_instance
, { "Max Instance", "cip.max_instance", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9730 { &hf_attr_class_num_instance
, { "Number of Instances", "cip.num_instance", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9731 { &hf_attr_class_opt_attr_num
, { "Number of Attributes", "cip.num_attr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9732 { &hf_attr_class_attr_num
, { "Attribute Number", "cip.attr_num", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9733 { &hf_attr_class_opt_service_num
, { "Number of Services", "cip.num_service", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9734 { &hf_attr_class_service_code
, { "Service Code", "cip.service_code", FT_UINT16
, BASE_HEX
, VALS(cip_sc_vals
), 0, NULL
, HFILL
} },
9735 { &hf_attr_class_num_class_attr
, { "Maximum ID Number Class Attributes", "cip.num_class_attr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9736 { &hf_attr_class_num_inst_attr
, { "Maximum ID Number Instance Attributes", "cip.num_inst_attr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9738 { &hf_cip_service
, { "Service", "cip.service", FT_UINT8
, BASE_HEX
, NULL
, 0, "Service Code + Request/Response", HFILL
}},
9739 { &hf_cip_reqrsp
, { "Request/Response", "cip.rr", FT_UINT8
, BASE_HEX
, VALS(cip_sc_rr
), CIP_SC_RESPONSE_MASK
, "Request or Response message", HFILL
}},
9740 { &hf_cip_service_code
, { "Service", "cip.sc", FT_UINT8
, BASE_HEX
, VALS(cip_sc_vals
), CIP_SC_MASK
, "Service Code", HFILL
}},
9741 { &hf_cip_epath
, { "EPath", "cip.epath", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9742 { &hf_cip_genstat
, { "General Status", "cip.genstat", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_gs_vals_ext
, 0, NULL
, HFILL
}},
9743 { &hf_cip_addstat_size
, { "Additional Status Size", "cip.addstat_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
9744 { &hf_cip_add_stat
, { "Additional Status", "cip.addstat", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9745 { &hf_cip_request_path_size
, { "Request Path Size", "cip.request_path_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
9747 { &hf_cip_path_segment
, { "Path Segment", "cip.path_segment", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9748 { &hf_cip_path_segment_type
, { "Path Segment Type", "cip.path_segment.type", FT_UINT8
, BASE_DEC
, VALS(cip_path_seg_vals
), CI_SEGMENT_TYPE_MASK
, NULL
, HFILL
}},
9749 { &hf_cip_port_ex_link_addr
, { "Extended Link Address", "cip.ex_linkaddress", FT_BOOLEAN
, 8, NULL
, CI_PORT_SEG_EX_LINK_ADDRESS
, NULL
, HFILL
}},
9750 { &hf_cip_port
, { "Port", "cip.port", FT_UINT8
, BASE_DEC
, VALS(cip_port_number_vals
), CI_PORT_SEG_PORT_ID_MASK
, "Port Identifier", HFILL
} },
9751 { &hf_cip_port_extended
,{ "Port Extended", "cip.port", FT_UINT16
, BASE_HEX
, NULL
, 0, "Port Identifier Extended", HFILL
} },
9752 { &hf_cip_link_address_byte
, { "Link Address", "cip.linkaddress.byte", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9753 { &hf_cip_link_address_size
, { "Link Address Size", "cip.linkaddress_size", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9754 { &hf_cip_link_address_string
, { "Link Address", "cip.linkaddress.string", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9755 { &hf_cip_logical_seg_type
, { "Logical Segment Type", "cip.logical_segment.type", FT_UINT8
, BASE_DEC
, VALS(cip_logical_segment_type_vals
), CI_LOGICAL_SEG_TYPE_MASK
, NULL
, HFILL
}},
9756 { &hf_cip_logical_seg_format
, { "Logical Segment Format", "cip.logical_segment.format", FT_UINT8
, BASE_DEC
, VALS(cip_logical_segment_format_vals
), CI_LOGICAL_SEG_FORMAT_MASK
, NULL
, HFILL
}},
9757 { &hf_cip_class8
, { "Class", "cip.class", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_class_names_vals_ext
, 0, NULL
, HFILL
}},
9758 { &hf_cip_class16
, { "Class", "cip.class", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_class_names_vals_ext
, 0, NULL
, HFILL
}},
9759 { &hf_cip_class32
, { "Class", "cip.class", FT_UINT32
, BASE_HEX
|BASE_EXT_STRING
, &cip_class_names_vals_ext
, 0, NULL
, HFILL
}},
9760 { &hf_cip_instance8
, { "Instance", "cip.instance", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9761 { &hf_cip_instance16
, { "Instance", "cip.instance", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9762 { &hf_cip_instance32
, { "Instance", "cip.instance", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9763 { &hf_cip_member8
, { "Member", "cip.member", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9764 { &hf_cip_member16
, { "Member", "cip.member", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9765 { &hf_cip_member32
, { "Member", "cip.member", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9766 { &hf_cip_attribute8
, { "Attribute", "cip.attribute", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9767 { &hf_cip_attribute16
, { "Attribute", "cip.attribute", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9768 { &hf_cip_attribute32
, { "Attribute", "cip.attribute", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9769 { &hf_cip_conpoint8
, { "Connection Point", "cip.connpoint", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9770 { &hf_cip_conpoint16
, { "Connection Point", "cip.connpoint", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9771 { &hf_cip_conpoint32
, { "Connection Point", "cip.connpoint", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9772 { &hf_cip_serviceid8
,{ "Service ID", "cip.serviceid", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9773 { &hf_cip_ekey_format
, { "Key Format", "cip.ekey.format", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9774 { &hf_cip_ekey_vendor
, { "Vendor ID", "cip.ekey.vendor", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_vendor_vals_ext
, 0, NULL
, HFILL
}},
9775 { &hf_cip_ekey_devtype
, { "Device Type", "cip.ekey.devtype", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_devtype_vals_ext
, 0, NULL
, HFILL
}},
9776 { &hf_cip_ekey_prodcode
, { "Product Code", "cip.ekey.product_code", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9777 { &hf_cip_ekey_compatibility
, { "Compatibility", "cip.ekey.compatibility", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9778 { &hf_cip_ekey_comp_bit
, { "Compatibility", "cip.ekey.comp_bit", FT_UINT8
, BASE_HEX
, VALS(cip_com_bit_vals
), 0x80, "EKey: Compatibility bit", HFILL
}},
9779 { &hf_cip_ekey_majorrev
, { "Major Revision", "cip.ekey.major_rev", FT_UINT8
, BASE_DEC
, NULL
, 0x7F, "EKey: Major Revision", HFILL
}},
9780 { &hf_cip_ekey_minorrev
, { "Minor Revision", "cip.ekey.minor_rev", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9781 { &hf_cip_ekey_serial_number
, { "Serial Number", "cip.ekey.serial_number", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9782 { &hf_cip_ext_logical8
,{ "Extended Logical", "cip.extlogical", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9783 { &hf_cip_ext_logical16
,{ "Extended Logical", "cip.extlogical", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9784 { &hf_cip_ext_logical32
,{ "Extended Logical", "cip.extlogical", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9785 { &hf_cip_ext_logical_type
,{ "Extended Logical Type", "cip.extlogical.type", FT_UINT8
, BASE_HEX
, VALS(cip_ext_logical_segment_format_vals
), 0, NULL
, HFILL
} },
9786 { &hf_cip_data_seg_type
, { "Data Segment Type", "cip.data_segment.type", FT_UINT8
, BASE_DEC
, VALS(cip_data_segment_type_vals
), CI_DATA_SEG_TYPE_MASK
, NULL
, HFILL
}},
9787 { &hf_cip_data_seg_size_simple
, { "Data Size", "cip.data_segment.size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
9788 { &hf_cip_data_seg_size_extended
, { "Data Size", "cip.data_segment.size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0, NULL
, HFILL
} },
9789 { &hf_cip_data_seg_item
, { "Data", "cip.data_segment.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9790 { &hf_cip_symbol
, { "ANSI Symbol", "cip.symbol", FT_STRING
, BASE_NONE
, NULL
, 0, "ANSI Extended Symbol Segment", HFILL
}},
9791 { &hf_cip_symbol_size
, { "Symbolic Symbol Size", "cip.symbol.size", FT_UINT8
, BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
9792 { &hf_cip_symbol_ascii
, { "ASCII Symbol", "cip.ascii_symbol", FT_STRING
, BASE_NONE
, NULL
, 0, "ASCII Symbol Segment", HFILL
} },
9793 { &hf_cip_symbol_extended_format
,{ "Extended String Format", "cip.symbol.format", FT_UINT8
, BASE_DEC
, VALS(cip_symbolic_format_vals
), CI_SYMBOL_SEG_FORMAT_MASK
, NULL
, HFILL
} },
9794 { &hf_cip_symbol_numeric_format
,{ "Extended String Numeric Format", "cip.symbol.numformat", FT_UINT8
, BASE_DEC
, VALS(cip_symbolic_numeric_format_vals
), 0x1F, NULL
, HFILL
} },
9795 { &hf_cip_symbol_double_size
, { "Double Byte Chars", "cip.symbol.size", FT_UINT8
, BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
9796 { &hf_cip_symbol_triple_size
, { "Triple Byte Chars", "cip.symbol.size", FT_UINT8
, BASE_DEC
, NULL
, 0x1F, NULL
, HFILL
} },
9797 { &hf_cip_numeric_usint
,{ "Numeric Symbol", "cip.numeric_symbol", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9798 { &hf_cip_numeric_uint
,{ "Numeric Symbol", "cip.numeric_symbol", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9799 { &hf_cip_numeric_udint
,{ "Numeric Symbol", "cip.numeric_symbol", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9800 { &hf_cip_network_seg_type
, { "Network Segment Type", "cip.network_segment.type", FT_UINT8
, BASE_DEC
, VALS(cip_network_segment_type_vals
), CI_NETWORK_SEG_TYPE_MASK
, NULL
, HFILL
}},
9801 { &hf_cip_seg_schedule
, { "Multiplier/Phase", "cip.network_segment.schedule", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9802 { &hf_cip_seg_fixed_tag
, { "Fixed Tag", "cip.network_segment.fixed_tag", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9803 { &hf_cip_seg_prod_inhibit_time
, { "Production Inhibit Time (ms)", "cip.network_segment.prod_inhibit", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9804 { &hf_cip_seg_prod_inhibit_time_us
, { "Production Inhibit Time (us)", "cip.network_segment.prod_inhibit", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9805 { &hf_cip_seg_network_size
, { "Network Segment Length", "cip.network_segment.length", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
9806 { &hf_cip_seg_network_subtype
, { "Extended Segment Subtype", "cip.network_segment.subtype", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9807 { &hf_cip_seg_safety_format
, { "Safety Format", "cip.safety_segment.format", FT_UINT8
, BASE_DEC
, VALS(cip_safety_segment_format_type_vals
), 0, NULL
, HFILL
}},
9808 { &hf_cip_seg_safety_reserved
, { "Reserved", "cip.safety_segment.reserved", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9809 { &hf_cip_seg_safety_configuration_crc
, { "Configuration CRC (SCCRC)", "cip.safety_segment.configuration_crc", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9810 { &hf_cip_seg_safety_configuration_timestamp
, { "Configuration Timestamp (SCTS)", "cip.safety_segment.configuration_timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}},
9811 { &hf_cip_seg_safety_configuration_date
, { "Configuration (Manual) Date", "cip.safety_segment.configuration_date", FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}},
9812 { &hf_cip_seg_safety_configuration_time
, { "Configuration (Manual) Time", "cip.safety_segment.configuration_time", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9813 { &hf_cip_seg_safety_time_correction_epi
, { "Time Correction EPI", "cip.safety_segment.time_correction_epi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
9814 { &hf_cip_seg_safety_time_correction_net_params
, { "Time Correction Network Connection Parameters", "cip.safety_segment.time_correction.net_params", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9815 { &hf_cip_seg_safety_time_correction_own
, { "Redundant Owner", "cip.safety_segment.time_correction.owner", FT_UINT16
, BASE_DEC
, VALS(cip_con_owner_vals
), 0x8000, "Time Correction: Redundant owner bit", HFILL
}},
9816 { &hf_cip_seg_safety_time_correction_typ
, { "Connection Type", "cip.safety_segment.time_correction.type", FT_UINT16
, BASE_DEC
, VALS(cip_con_type_vals
), 0x6000, "Time Correction: Connection type", HFILL
}},
9817 { &hf_cip_seg_safety_time_correction_prio
, { "Priority", "cip.safety_segment.time_correction.prio", FT_UINT16
, BASE_DEC
, VALS(cip_con_prio_vals
), 0x0C00, "Time Correction: Connection priority", HFILL
}},
9818 { &hf_cip_seg_safety_time_correction_fixed_var
, { "Connection Size Type", "cip.safety_segment.time_correction.f_v", FT_UINT16
, BASE_DEC
, VALS(cip_con_fw_vals
), 0x0200, "Time Correction: Fixed or variable connection size", HFILL
}},
9819 { &hf_cip_seg_safety_time_correction_con_size
, { "Connection Size", "cip.safety_segment.time_correction.consize", FT_UINT16
, BASE_DEC
, NULL
, 0x01FF, "Time Correction: Connection size", HFILL
}},
9820 { &hf_cip_seg_safety_tunid
, { "Target UNID (TUNID)", "cip.safety_segment.tunid", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9821 { &hf_cip_seg_safety_tunid_snn_timestamp
, { "SNN Timestamp", "cip.safety_segment.tunid.snn.timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}},
9822 { &hf_cip_seg_safety_tunid_snn_date
, { "SNN (Manual) Date", "cip.safety_segment.tunid.snn.date", FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}},
9823 { &hf_cip_seg_safety_tunid_snn_time
, { "SNN (Manual) Time", "cip.safety_segment.tunid.snn.time", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9824 { &hf_cip_seg_safety_tunid_nodeid
, { "Node ID", "cip.safety_segment.tunid.nodeid", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9825 { &hf_cip_seg_safety_ounid
, { "Originator UNID (OUNID)", "cip.safety_segment.ounid", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9826 { &hf_cip_seg_safety_ounid_snn_timestamp
, { "SNN Timestamp", "cip.safety_segment.ounid.snn.timestamp", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0, NULL
, HFILL
}},
9827 { &hf_cip_seg_safety_ounid_snn_date
, { "SNN (Manual) Date", "cip.safety_segment.ounid.snn.date", FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0, NULL
, HFILL
}},
9828 { &hf_cip_seg_safety_ounid_snn_time
, { "SNN (Manual) Time", "cip.safety_segment.ounid.snn.time", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9829 { &hf_cip_seg_safety_ounid_nodeid
, { "Node ID", "cip.safety_segment.ounid.nodeid", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9830 { &hf_cip_seg_safety_ping_epi_multiplier
, { "Ping Interval EPI Multiplier", "cip.safety_segment.ping_epi_multiplier", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9831 { &hf_cip_seg_safety_time_coord_msg_min_multiplier
, { "Time Coord Msg Min Multiplier", "cip.safety_segment.time_coord_msg_min_multiplier", FT_UINT16
, BASE_CUSTOM
, CF_FUNC(cip_safety_128us_fmt
), 0, NULL
, HFILL
}},
9832 { &hf_cip_seg_safety_network_time_expected_multiplier
, { "Network Time Expectation Multiplier", "cip.safety_segment.network_time_expected_multiplier", FT_UINT16
, BASE_CUSTOM
, CF_FUNC(cip_safety_128us_fmt
), 0, NULL
, HFILL
}},
9833 { &hf_cip_seg_safety_timeout_multiplier
, { "Timeout Multiplier", "cip.safety_segment.timeout_multiplier", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9834 { &hf_cip_seg_safety_max_consumer_number
, { "Max Consumer Number", "cip.safety_segment.max_consumer_number", FT_UINT8
, BASE_DEC
|BASE_RANGE_STRING
, RVALS(safety_max_consumer_numbers
), 0, NULL
, HFILL
}},
9835 { &hf_cip_seg_safety_conn_param_crc
, { "Connection Parameters CRC (CPCRC)", "cip.safety_segment.conn_param_crc", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9836 { &hf_cip_seg_safety_time_correction_conn_id
, { "Time Correction Connection ID", "cip.safety_segment.time_correction_conn_id", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9837 { &hf_cip_seg_safety_max_fault_number
, { "Max Fault Number", "cip.safety_segment.max_fault_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9838 { &hf_cip_seg_safety_init_timestamp
, { "Initial Timestamp", "cip.safety_segment.init_timestamp", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9839 { &hf_cip_seg_safety_init_rollover
, { "Initial Rollover Value", "cip.safety_segment.init_rollover", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9840 { &hf_cip_seg_safety_data
, { "Safety Data", "cip.safety_segment.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9841 { &hf_cip_class_max_inst32
, { "Max Instance", "cip.class.max_inst", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9842 { &hf_cip_class_num_inst32
, { "Number of Instances", "cip.class.num_inst", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9843 { &hf_cip_reserved8
, { "Reserved", "cip.reserved", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9844 { &hf_cip_reserved24
, { "Reserved", "cip.reserved", FT_UINT24
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9845 { &hf_cip_pad8
, { "Pad Byte", "cip.pad", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9847 { &hf_cip_sc_get_attr_list_attr_count
, { "Attribute Count", "cip.getlist.attr_count", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9848 { &hf_cip_sc_get_attr_list_attr_status
, { "Attribute Status", "cip.getlist.attr_status", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_gs_vals_ext
, 0, NULL
, HFILL
}},
9849 { &hf_cip_sc_set_attr_list_attr_count
, { "Attribute Count", "cip.setlist.attr_count", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9850 { &hf_cip_sc_set_attr_list_attr_status
, { "Attribute Status", "cip.setlist.attr_status", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_gs_vals_ext
, 0, NULL
, HFILL
}},
9851 { &hf_cip_sc_reset_param
, { "Reset type", "cip.reset.type", FT_UINT8
, BASE_DEC
, VALS(cip_reset_type_vals
), 0, NULL
, HFILL
}},
9852 { &hf_cip_sc_create_instance
, { "Instance", "cip.create.instance", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9853 { &hf_cip_sc_mult_serv_pack_num_services
, { "Number of Services", "cip.msp.num_services", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9854 { &hf_cip_sc_mult_serv_pack_offset
, { "Offset", "cip.msp.offset", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9855 { &hf_cip_find_next_object_max_instance
, { "Maximum ID", "cip.find_next_object.max_instance", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9856 { &hf_cip_find_next_object_num_instances
, { "Number of Instances", "cip.find_next_object.num_instances", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9857 { &hf_cip_find_next_object_instance_item
, { "Instance", "cip.find_next_object.instance", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9858 { &hf_cip_sc_group_sync_is_sync
, { "IsSynchronized", "cip.group_sync.is_sync", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9859 { &hf_cip_data
, { "Data", "cip.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9861 { &hf_id_vendor_id
, { "Vendor ID", "cip.id.vendor_id", FT_UINT16
, BASE_HEX
| BASE_EXT_STRING
, &cip_vendor_vals_ext
, 0, NULL
, HFILL
} },
9862 { &hf_id_device_type
, { "Device Type", "cip.id.device_type", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_devtype_vals_ext
, 0, NULL
, HFILL
}},
9863 { &hf_id_product_code
, { "Product Code", "cip.id.product_code", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9864 { &hf_id_major_rev
, { "Major Revision", "cip.id.major_rev", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9865 { &hf_id_minor_rev
, { "Minor Revision", "cip.id.minor_rev", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9866 { &hf_id_status
, { "Status", "cip.id.status", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9867 { &hf_id_serial_number
, { "Serial Number", "cip.id.serial_number", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9868 { &hf_id_product_name
, { "Product Name", "cip.id.product_name", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9869 { &hf_id_state
, { "State", "cip.id.state", FT_UINT8
, BASE_HEX
, VALS(cip_id_state_vals
), 0, NULL
, HFILL
} },
9870 { &hf_id_config_value
, { "Configuration Consistency Value", "cip.id.config_value", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9871 { &hf_id_heartbeat
, { "Heartbeat Interval", "cip.id.heartbeat", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9872 { &hf_id_status_owned
, { "Owned", "cip.id.owned", FT_UINT16
, BASE_DEC
, NULL
, 0x0001, NULL
, HFILL
} },
9873 { &hf_id_status_conf
, { "Configured", "cip.id.conf", FT_UINT16
, BASE_DEC
, NULL
, 0x0004, NULL
, HFILL
} },
9874 { &hf_id_status_extended1
, { "Extended Device Status", "cip.id.ext", FT_UINT16
, BASE_HEX
, NULL
, 0x00F0, NULL
, HFILL
} },
9875 { &hf_id_status_minor_fault_rec
, { "Minor Recoverable Fault", "cip.id.minor_fault1", FT_UINT16
, BASE_DEC
, NULL
, 0x0100, NULL
, HFILL
} },
9876 { &hf_id_status_minor_fault_unrec
, { "Minor Unrecoverable Fault", "cip.id.minor_fault2", FT_UINT16
, BASE_DEC
, NULL
, 0x0200, NULL
, HFILL
} },
9877 { &hf_id_status_major_fault_rec
, { "Major Recoverable Fault", "cip.id.major_fault1", FT_UINT16
, BASE_DEC
, NULL
, 0x0400, NULL
, HFILL
} },
9878 { &hf_id_status_major_fault_unrec
, { "Major Unrecoverable Fault", "cip.id.major_fault2", FT_UINT16
, BASE_DEC
, NULL
, 0x0800, NULL
, HFILL
} },
9879 { &hf_id_status_extended2
, { "Extended Device Status 2", "cip.id.ext2", FT_UINT16
, BASE_HEX
, NULL
, 0xF000, NULL
, HFILL
} },
9881 { &hf_msg_rout_num_classes
, { "Number of Classes", "cip.mr.num_classes", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9882 { &hf_msg_rout_classes
, { "Class", "cip.mr.class", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_class_names_vals_ext
, 0, NULL
, HFILL
}},
9883 { &hf_msg_rout_num_available
, { "Number Available", "cip.mr.num_available", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9884 { &hf_msg_rout_num_active
, { "Number Active", "cip.mr.num_active", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9885 { &hf_msg_rout_active_connections
, { "Active Connection", "cip.mr.active_connections", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9887 { &hf_conn_mgr_open_requests
, { "Open Requests", "cip.cm.open_requests", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9888 { &hf_conn_mgr_open_format_rejects
, { "Open Format Rejects", "cip.cm.open_format_rejects", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9889 { &hf_conn_mgr_open_resource_rejects
, { "Open Resource Rejects", "cip.cm.open_resource_rejects", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9890 { &hf_conn_mgr_other_open_rejects
, { "Other Open Rejects", "cip.cm.other_open_rejects", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9891 { &hf_conn_mgr_close_requests
, { "Close Requests", "cip.cm.close_requests", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9892 { &hf_conn_close_format_requests
, { "Close Format Requests", "cip.cm.close_format_requests", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9893 { &hf_conn_mgr_close_other_requests
, { "Close Other Requests", "cip.cm.close_other_requests", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9894 { &hf_conn_mgr_conn_timouts
, { "Connection Timeouts", "cip.cm.conn_timouts", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9895 { &hf_conn_mgr_num_conn_entries
, { "Number of Connection Entries (Bits)", "cip.cm.conn_entries", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9896 { &hf_conn_mgr_num_conn_entries_bytes
, { "Number of Connection Entries (Bytes)", "cip.cm.conn_entries_bytes", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9897 { &hf_conn_mgr_conn_open_bits
, { "Connection Open Bits", "cip.cm.conn_open_bits", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9898 { &hf_conn_mgr_cpu_utilization
, { "CPU Utilization", "cip.cm.cpu_util", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9899 { &hf_conn_mgr_max_buff_size
, { "Max Buff Size", "cip.cm.max_buff_size", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9900 { &hf_conn_mgr_buff_size_remaining
, { "Buff Size Remaining", "cip.cm.buff_remain", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9902 { &hf_stringi_number_char
, { "Number of Characters", "cip.stringi.num", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9903 { &hf_stringi_language_char
, { "Language Chars", "cip.stringi.language_char", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
9904 { &hf_stringi_char_string_struct
, { "Char String Struct", "cip.stringi.char_string_struct", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
9905 { &hf_stringi_char_set
, { "Char Set", "cip.stringi.char_set", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9906 { &hf_stringi_international_string
, { "International String", "cip.stringi.int_string", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
9908 { &hf_file_filename
, { "File Name", "cip.file.file_name", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
9910 { &hf_time_sync_ptp_enable
, { "PTP Enable", "cip.time_sync.ptp_enable", FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_enabled_disabled
), 0, NULL
, HFILL
}},
9911 { &hf_time_sync_is_synchronized
, { "Is Synchronized", "cip.time_sync.is_synchronized", FT_BOOLEAN
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9912 { &hf_time_sync_sys_time_micro
, { "System Time (Microseconds)", "cip.time_sync.sys_time_micro", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0, NULL
, HFILL
}},
9913 { &hf_time_sync_sys_time_nano
, { "System Time (Nanoseconds)", "cip.time_sync.sys_time_nano", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0, NULL
, HFILL
}},
9914 { &hf_time_sync_offset_from_master
, { "Offset from Master", "cip.time_sync.offset_from_master", FT_INT64
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9915 { &hf_time_sync_max_offset_from_master
, { "Max Offset from Master", "cip.time_sync.max_offset_from_master", FT_UINT64
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9916 { &hf_time_sync_mean_path_delay_to_master
, { "Mean Path Delay To Master", "cip.time_sync.mean_path_delay_to_master", FT_UINT64
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9917 { &hf_time_sync_gm_clock_clock_id
, { "Clock Identity", "cip.time_sync.gm_clock.clock_id", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9918 { &hf_time_sync_gm_clock_clock_class
, { "Clock Class", "cip.time_sync.gm_clock.clock_class", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_clock_class_vals
), 0, NULL
, HFILL
}},
9919 { &hf_time_sync_gm_clock_time_accuracy
, { "Time Accuracy", "cip.time_sync.gm_clock.time_accuracy", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_time_accuracy_vals
), 0, NULL
, HFILL
}},
9920 { &hf_time_sync_gm_clock_offset_scaled_log_variance
, { "Offset Scaled Log Variance", "cip.time_sync.gm_clock.offset_scaled_log_variance", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9921 { &hf_time_sync_gm_clock_current_utc_offset
, { "Current UTC Offset", "cip.time_sync.gm_clock.current_utc_offset", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9922 { &hf_time_sync_gm_clock_time_property_flags
, { "Time Property Flags", "cip.time_sync.gm_clock.time_property_flags", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9923 { &hf_time_sync_gm_clock_time_property_flags_leap61
, { "Leap indicator 61", "cip.time_sync.gm_clock.time_property_flags.leap61", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0001, NULL
, HFILL
}},
9924 { &hf_time_sync_gm_clock_time_property_flags_leap59
, { "Leap indicator 59", "cip.time_sync.gm_clock.time_property_flags.leap59", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0002, NULL
, HFILL
}},
9925 { &hf_time_sync_gm_clock_time_property_flags_current_utc_valid
, { "Current UTC Offset Valid", "cip.time_sync.gm_clock.time_property_flags.current_utc_valid", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0004, NULL
, HFILL
}},
9926 { &hf_time_sync_gm_clock_time_property_flags_ptp_timescale
, { "PTP Timescale", "cip.time_sync.gm_clock.time_property_flags.ptp_timescale", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0008, NULL
, HFILL
}},
9927 { &hf_time_sync_gm_clock_time_property_flags_time_traceable
, { "Time traceable", "cip.time_sync.gm_clock.time_property_flags.time_traceable", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0010, NULL
, HFILL
}},
9928 { &hf_time_sync_gm_clock_time_property_flags_freq_traceable
, { "Frequency traceable", "cip.time_sync.gm_clock.time_property_flags.freq_traceable", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0020, NULL
, HFILL
}},
9929 { &hf_time_sync_gm_clock_time_source
, { "Time Source", "cip.time_sync.gm_clock.time_source", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_time_source_vals
), 0, NULL
, HFILL
}},
9930 { &hf_time_sync_gm_clock_priority1
, { "Priority1", "cip.time_sync.gm_clock.priority1", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9931 { &hf_time_sync_gm_clock_priority2
, { "Priority2", "cip.time_sync.gm_clock.priority2", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9932 { &hf_time_sync_parent_clock_clock_id
, { "Clock Identity", "cip.time_sync.parent_clock.clock_id", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9933 { &hf_time_sync_parent_clock_port_number
, { "Port Number", "cip.time_sync.parent_clock.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9934 { &hf_time_sync_parent_clock_observed_offset_scaled_log_variance
, { "Observed Offset Scaled Log Variance", "cip.time_sync.parent_clock.observed_offset_scaled_log_variance", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9935 { &hf_time_sync_parent_clock_observed_phase_change_rate
, { "Observed Phase Change Rate", "cip.time_sync.parent_clock.observed_phase_change_rate", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9936 { &hf_time_sync_local_clock_clock_id
, { "Clock Identity", "cip.time_sync.local_clock.clock_id", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9937 { &hf_time_sync_local_clock_clock_class
, { "Clock Class", "cip.time_sync.local_clock.clock_class", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_clock_class_vals
), 0, NULL
, HFILL
}},
9938 { &hf_time_sync_local_clock_time_accuracy
, { "Time Accuracy", "cip.time_sync.local_clock.time_accuracy", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_time_accuracy_vals
), 0, NULL
, HFILL
}},
9939 { &hf_time_sync_local_clock_offset_scaled_log_variance
, { "Offset Scaled Log Variance", "cip.time_sync.local_clock.offset_scaled_log_variance", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9940 { &hf_time_sync_local_clock_current_utc_offset
, { "Current UTC Offset", "cip.time_sync.local_clock.current_utc_offset", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9941 { &hf_time_sync_local_clock_time_property_flags
, { "Time Property Flags", "cip.time_sync.local_clock.time_property_flags", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9942 { &hf_time_sync_local_clock_time_property_flags_leap61
, { "Leap indicator 61", "cip.time_sync.local_clock.time_property_flags.leap61", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0001, NULL
, HFILL
}},
9943 { &hf_time_sync_local_clock_time_property_flags_leap59
, { "Leap indicator 59", "cip.time_sync.local_clock.time_property_flags.leap59", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0002, NULL
, HFILL
}},
9944 { &hf_time_sync_local_clock_time_property_flags_current_utc_valid
, { "Current UTC Offset Valid", "cip.time_sync.local_clock.time_property_flags.current_utc_valid", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0004, NULL
, HFILL
}},
9945 { &hf_time_sync_local_clock_time_property_flags_ptp_timescale
, { "PTP Timescale", "cip.time_sync.local_clock.time_property_flags.ptp_timescale", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0008, NULL
, HFILL
}},
9946 { &hf_time_sync_local_clock_time_property_flags_time_traceable
, { "Time traceable", "cip.time_sync.local_clock.time_property_flags.time_traceable", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0010, NULL
, HFILL
}},
9947 { &hf_time_sync_local_clock_time_property_flags_freq_traceable
, { "Frequency traceable", "cip.time_sync.local_clock.time_property_flags.freq_traceable", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0020, NULL
, HFILL
}},
9948 { &hf_time_sync_local_clock_time_source
, { "Time Source", "cip.time_sync.local_clock.time_source", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_time_source_vals
), 0, NULL
, HFILL
}},
9949 { &hf_time_sync_num_ports
, { "Port Number", "cip.time_sync.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9950 { &hf_time_sync_port_state_info_num_ports
, { "Number of Ports", "cip.time_sync.port_state_info.num_ports", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9951 { &hf_time_sync_port_state_info_port_num
, { "Port Number", "cip.time_sync.port_state_info.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9952 { &hf_time_sync_port_state_info_port_state
, { "Port State", "cip.time_sync.port_state_info.port_state", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_port_state_vals
), 0, NULL
, HFILL
}},
9953 { &hf_time_sync_port_enable_cfg_num_ports
, { "Number of Ports", "cip.time_sync.port_enable_cfg.num_ports", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9954 { &hf_time_sync_port_enable_cfg_port_num
, { "Port Number", "cip.time_sync.port_enable_cfg.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9955 { &hf_time_sync_port_enable_cfg_port_enable
, { "Port Enable", "cip.time_sync.port_enable_cfg.port_enable", FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_enabled_disabled
), 0, NULL
, HFILL
}},
9956 { &hf_time_sync_port_log_announce_num_ports
, { "Number of Ports", "cip.time_sync.port_log_announce.num_ports", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9957 { &hf_time_sync_port_log_announce_port_num
, { "Port Number", "cip.time_sync.port_log_announce.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9958 { &hf_time_sync_port_log_announce_interval
, { "Port Log Announce Interval", "cip.time_sync.port_log_announce.interval", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9959 { &hf_time_sync_port_log_sync_num_ports
, { "Number of Ports", "cip.time_sync.port_log_sync.num_ports", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9960 { &hf_time_sync_port_log_sync_port_num
, { "Port Number", "cip.time_sync.port_log_sync.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9961 { &hf_time_sync_port_log_sync_port_log_sync_interval
, { "Port Log Sync Interval", "cip.time_sync.port_log_sync.port_log_sync_interval", FT_INT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9962 { &hf_time_sync_priority1
, { "Priority1", "cip.time_sync.priority1", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9963 { &hf_time_sync_priority2
, { "Priority2", "cip.time_sync.priority2", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9964 { &hf_time_sync_domain_number
, { "Domain number", "cip.time_sync.domain_number", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9965 { &hf_time_sync_clock_type
, { "Clock Type", "cip.time_sync.clock_type", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9966 { &hf_time_sync_clock_type_ordinary
, { "Ordinary Clock", "cip.time_sync.clock_type.ordinary", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0080, NULL
, HFILL
}},
9967 { &hf_time_sync_clock_type_boundary
, { "Boundary Clock", "cip.time_sync.clock_type.boundary", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0040, NULL
, HFILL
}},
9968 { &hf_time_sync_clock_type_end_to_end
, { "End-to-End Transparent Clock", "cip.time_sync.clock_type.end_to_end", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0010, NULL
, HFILL
}},
9969 { &hf_time_sync_clock_type_management
, { "Management Node", "cip.time_sync.clock_type.management", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0008, NULL
, HFILL
}},
9970 { &hf_time_sync_clock_type_slave_only
, { "Slave Only", "cip.time_sync.clock_type.slave_only", FT_BOOLEAN
, 16, TFS(&tfs_set_notset
), 0x0100, NULL
, HFILL
}},
9971 { &hf_time_sync_manufacture_id_oui
, { "Manufacture Identity OUI", "cip.time_sync.manufacture_id.oui", FT_UINT24
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9972 { &hf_time_sync_manufacture_id_reserved
, { "Reserved", "cip.time_sync.manufacture_id.reserved", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
9973 { &hf_time_sync_prod_desc_size
, { "Product Description Size", "cip.time_sync.prod_desc_size", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9974 { &hf_time_sync_prod_desc_str
, { "Product Description", "cip.time_sync.prod_desc", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9975 { &hf_time_sync_revision_data_size
, { "Revision Data Size", "cip.time_sync.revision_data_size", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9976 { &hf_time_sync_revision_data_str
, { "Revision Data", "cip.time_sync.revision_data", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9977 { &hf_time_sync_user_desc_size
, { "User Description Size", "cip.time_sync.user_desc_size", FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9978 { &hf_time_sync_user_desc_str
, { "User Description", "cip.time_sync.user_desc", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9979 { &hf_time_sync_port_profile_id_info_num_ports
, { "Number of Ports", "cip.time_sync.port_profile_id_info.num_ports", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9980 { &hf_time_sync_port_profile_id_info_port_num
, { "Port Number", "cip.time_sync.port_profile_id_info.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9981 { &hf_time_sync_port_profile_id_info_profile_id
, { "Port Profile Identity", "cip.time_sync.port_profile_id_info.profile_id", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9982 { &hf_time_sync_port_phys_addr_info_num_ports
, { "Number of Ports", "cip.time_sync.port_phys_addr_info.num_ports", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9983 { &hf_time_sync_port_phys_addr_info_port_num
, { "Port Number", "cip.time_sync.port_phys_addr_info.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9984 { &hf_time_sync_port_phys_addr_info_phys_proto
, { "Physical Protocol", "cip.time_sync.port_profile_id_info.phys_proto", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9985 { &hf_time_sync_port_phys_addr_info_addr_size
, { "Size of Address", "cip.time_sync.port_phys_addr_info.addr_size", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9986 { &hf_time_sync_port_phys_addr_info_phys_addr
, { "Port Physical Address", "cip.time_sync.port_profile_id_info.phys_addr", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9987 { &hf_time_sync_port_proto_addr_info_num_ports
, { "Number of Ports", "cip.time_sync.port_proto_addr_info.num_ports", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9988 { &hf_time_sync_port_proto_addr_info_port_num
, { "Port Number", "cip.time_sync.port_proto_addr_info.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9989 { &hf_time_sync_port_proto_addr_info_network_proto
, { "Network Protocol", "cip.time_sync.port_proto_addr_info.network_proto", FT_UINT16
, BASE_DEC
, VALS(cip_time_sync_network_protocol_vals
), 0, NULL
, HFILL
}},
9990 { &hf_time_sync_port_proto_addr_info_addr_size
, { "Size of Address", "cip.time_sync.port_proto_addr_info.addr_size", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9991 { &hf_time_sync_port_proto_addr_info_port_proto_addr
, { "Port Protocol Address", "cip.time_sync.port_profile_id_info.port_proto_addr", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
9992 { &hf_time_sync_steps_removed
, { "Steps Removed", "cip.time_sync.steps_removed", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9993 { &hf_time_sync_sys_time_and_offset_time
, { "System Time (Microseconds)", "cip.time_sync.sys_time_and_offset.time", FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0, NULL
, HFILL
}},
9994 { &hf_time_sync_sys_time_and_offset_offset
, { "System Offset (Microseconds)", "cip.time_sync.sys_time_and_offset.offset", FT_UINT64
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
9995 { &hf_port_entry_port
, { "Entry Port", "cip.port.entry_port", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9996 { &hf_port_type
, { "Port Type", "cip.port.type", FT_UINT16
, BASE_DEC
| BASE_RANGE_STRING
, RVALS(cip_port_type_vals
), 0, NULL
, HFILL
} },
9997 { &hf_port_number
, { "Port Number", "cip.port.number", FT_UINT16
, BASE_DEC
, VALS(cip_port_number_vals
), 0, NULL
, HFILL
} },
9998 { &hf_port_min_node_num
, { "Minimum Node Number", "cip.port.min_node", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
9999 { &hf_port_max_node_num
, { "Maximum Node Number", "cip.port.max_node", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
10000 { &hf_port_name
, { "Port Name", "cip.port.name", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
10001 { &hf_port_num_comm_object_entries
, { "Number of entries", "cip.port.num_comm_object_entries", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
10002 { &hf_path_len_usint
, { "Path Length", "cip.path_len", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
} },
10003 { &hf_path_len_uint
, { "Path Length", "cip.path_len", FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
} },
10005 { &hf_32bitheader
, { "32-bit Header", "cip.32bitheader", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
10006 { &hf_32bitheader_roo
, { "ROO", "cip.32bitheader.roo", FT_UINT32
, BASE_HEX
, NULL
, 0xC, "Ready for Ownership of Outputs", HFILL
} },
10007 { &hf_32bitheader_coo
, { "COO", "cip.32bitheader.coo", FT_UINT32
, BASE_HEX
, NULL
, 0x2, "Claim Output Ownership", HFILL
} },
10008 { &hf_32bitheader_run_idle
, { "Run/Idle", "cip.32bitheader.run_idle", FT_UINT32
, BASE_HEX
, VALS(cip_run_idle_vals
), 0x1, NULL
, HFILL
} },
10010 { &hf_cip_connection
, { "CIP Connection Index", "cip.connection", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
} },
10011 { &hf_cip_fwd_open_in
, { "Forward Open Request In", "cip.fwd_open_in", FT_FRAMENUM
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
10012 { &hf_cip_fwd_close_in
, { "Forward Close Request In", "cip.fwd_close_in", FT_FRAMENUM
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
10015 static hf_register_info hf_cm
[] = {
10016 { &hf_cip_cm_sc
, { "Service", "cip.cm.sc", FT_UINT8
, BASE_HEX
, VALS(cip_sc_vals_cm
), CIP_SC_MASK
, NULL
, HFILL
}},
10017 { &hf_cip_cm_genstat
, { "General Status", "cip.cm.genstat", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_gs_vals_ext
, 0, NULL
, HFILL
}},
10018 { &hf_cip_cm_addstat_size
, { "Additional Status Size", "cip.cm.addstat_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
10019 { &hf_cip_cm_ext_status
, { "Extended Status", "cip.cm.ext_status", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_cm_ext_st_vals_ext
, 0, NULL
, HFILL
}},
10020 { &hf_cip_cm_add_status
, { "Additional Status", "cip.cm.addstat", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10021 { &hf_cip_cm_priority
, { "Priority", "cip.cm.priority", FT_UINT8
, BASE_DEC
, NULL
, 0x10, NULL
, HFILL
}},
10022 { &hf_cip_cm_tick_time
, { "Tick time", "cip.cm.tick_time", FT_UINT8
, BASE_DEC
, NULL
, 0x0F, NULL
, HFILL
}},
10023 { &hf_cip_cm_timeout_tick
, { "Time-out ticks", "cip.cm.timeout_tick", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10024 { &hf_cip_cm_timeout
, { "Actual Time Out", "cip.cm.timeout", FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_milliseconds
), 0, NULL
, HFILL
}},
10025 { &hf_cip_cm_ot_connid
, { "O->T Network Connection ID", "cip.cm.ot_connid", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10026 { &hf_cip_cm_to_connid
, { "T->O Network Connection ID", "cip.cm.to_connid", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10027 { &hf_cip_connid
, { "Connection ID", "cip.connid", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10028 { &hf_cip_cm_conn_serial_num
, { "Connection Serial Number", "cip.cm.conn_serial_num", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10029 { &hf_cip_cm_vendor
, { "Originator Vendor ID", "cip.cm.vendor", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_vendor_vals_ext
, 0, NULL
, HFILL
}},
10030 { &hf_cip_cm_timeout_multiplier
, { "Connection Timeout Multiplier", "cip.cm.timeout_multiplier", FT_UINT8
, BASE_DEC
, VALS(cip_con_time_mult_vals
), 0, NULL
, HFILL
}},
10031 { &hf_cip_cm_ot_rpi
, { "O->T RPI", "cip.cm.otrpi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10032 { &hf_cip_cm_ot_timeout
, { "O->T Timeout Threshold", "cip.cm.ot_timeout", FT_FLOAT
, BASE_NONE
|BASE_UNIT_STRING
, UNS(&units_milliseconds
), 0, NULL
, HFILL
}},
10033 { &hf_cip_cm_ot_net_params32
, { "O->T Network Connection Parameters", "cip.cm.ot_net_params", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10034 { &hf_cip_cm_ot_net_params16
, { "O->T Network Connection Parameters", "cip.cm.ot_net_params", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10035 { &hf_cip_cm_to_rpi
, { "T->O RPI", "cip.cm.torpi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10036 { &hf_cip_cm_to_timeout
, { "T->O Timeout Threshold", "cip.cm.to_timeout", FT_FLOAT
, BASE_NONE
|BASE_UNIT_STRING
, UNS(&units_milliseconds
), 0, NULL
, HFILL
}},
10038 { &hf_cip_safety_nte_ms
, { "Network Time Expectation (Produce Timeout)", "cip.safety.nte", FT_FLOAT
, BASE_NONE
|BASE_UNIT_STRING
, UNS(&units_milliseconds
), 0, NULL
, HFILL
}},
10040 { &hf_cip_cm_to_net_params32
, { "T->O Network Connection Parameters", "cip.cm.to_net_params", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10041 { &hf_cip_cm_to_net_params16
, { "T->O Network Connection Parameters", "cip.cm.to_net_params", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10042 { &hf_cip_cm_transport_type_trigger
, { "Transport Type/Trigger", "cip.cm.transport_type_trigger", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10043 { &hf_cip_cm_conn_path_size
, { "Connection Path Size", "cip.cm.connpath_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
10044 { &hf_cip_cm_ot_api
, { "O->T API", "cip.cm.otapi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10045 { &hf_cip_cm_to_api
, { "T->O API", "cip.cm.toapi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10046 { &hf_cip_cm_app_reply_size
, { "Application Reply Size", "cip.cm.app_reply_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
10047 { &hf_cip_cm_app_reply_data
, { "Application Reply", "cip.cm.app_reply_data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10048 { &hf_cip_cm_consumer_number
, { "Consumer Number", "cip.cm.consumer_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10049 { &hf_cip_cm_targ_vendor_id
, { "Target Vendor ID", "cip.cm.targ_vendor", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_vendor_vals_ext
, 0, NULL
, HFILL
}},
10050 { &hf_cip_cm_targ_dev_serial_num
, { "Target Device Serial Number", "cip.cm.targ_dev_serial_num", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10051 { &hf_cip_cm_targ_conn_serial_num
, { "Target Connection Serial Number", "cip.cm.targ_conn_serial_num", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10052 { &hf_cip_cm_initial_timestamp
, { "Initial Timestamp", "cip.cm.initial_timestamp", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10053 { &hf_cip_cm_initial_rollover
, { "Initial Rollover Value", "cip.cm.initial_rollover", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10054 { &hf_cip_cm_remain_path_size
, { "Remaining Path Size", "cip.cm.remain_path_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
10055 { &hf_cip_cm_msg_req_size
, { "Embedded Message Request Size", "cip.cm.msg_req_size", FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0, NULL
, HFILL
}},
10056 { &hf_cip_cm_route_path_size
, { "Route Path Size", "cip.cm.route_path_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
10057 { &hf_cip_cm_orig_serial_num
, { "Originator Serial Number", "cip.cm.orig_serial_num", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10058 { &hf_cip_cm_fwo_con_size
, { "Connection Size", "cip.cm.fwo.consize", FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0x01FF, "Fwd Open: Connection size", HFILL
}},
10059 { &hf_cip_cm_lfwo_con_size
, { "Connection Size", "cip.cm.fwo.consize", FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0xFFFF, "Large Fwd Open: Connection size", HFILL
}},
10060 { &hf_cip_cm_fwo_fixed_var
, { "Connection Size Type", "cip.cm.fwo.f_v", FT_UINT16
, BASE_DEC
, VALS(cip_con_fw_vals
), 0x0200, "Fwd Open: Fixed or variable connection size", HFILL
}},
10061 { &hf_cip_cm_lfwo_fixed_var
, { "Connection Size Type", "cip.cm.fwo.f_v", FT_UINT32
, BASE_DEC
, VALS(cip_con_fw_vals
), 0x02000000, "Large Fwd Open: Fixed or variable connection size", HFILL
}},
10062 { &hf_cip_cm_fwo_prio
, { "Priority", "cip.cm.fwo.prio", FT_UINT16
, BASE_DEC
, VALS(cip_con_prio_vals
), 0x0C00, "Fwd Open: Connection priority", HFILL
}},
10063 { &hf_cip_cm_lfwo_prio
, { "Priority", "cip.cm.fwo.prio", FT_UINT32
, BASE_DEC
, VALS(cip_con_prio_vals
), 0x0C000000, "Large Fwd Open: Connection priority", HFILL
}},
10064 { &hf_cip_cm_fwo_typ
, { "Connection Type", "cip.cm.fwo.type", FT_UINT16
, BASE_DEC
, VALS(cip_con_type_vals
), 0x6000, "Fwd Open: Connection type", HFILL
}},
10065 { &hf_cip_cm_lfwo_typ
, { "Connection Type", "cip.cm.fwo.type", FT_UINT32
, BASE_DEC
, VALS(cip_con_type_vals
), 0x60000000, "Large Fwd Open: Connection type", HFILL
}},
10066 { &hf_cip_cm_fwo_own
, { "Redundant Owner", "cip.cm.fwo.owner", FT_UINT16
, BASE_DEC
, VALS(cip_con_owner_vals
), 0x8000, "Fwd Open: Redundant owner bit", HFILL
}},
10067 { &hf_cip_cm_lfwo_own
, { "Redundant Owner", "cip.cm.fwo.owner", FT_UINT32
, BASE_DEC
, VALS(cip_con_owner_vals
), 0x80000000, "Large Fwd Open: Redundant owner bit", HFILL
}},
10068 { &hf_cip_cm_fwo_dir
, { "Direction", "cip.cm.fwo.dir", FT_BOOLEAN
, 8, TFS(&tfs_server_client
), CI_PRODUCTION_DIR_MASK
, "Fwd Open: Direction", HFILL
}},
10069 { &hf_cip_cm_fwo_trigg
, { "Trigger", "cip.cm.fwo.trigger", FT_UINT8
, BASE_DEC
, VALS(cip_con_trigg_vals
), CI_PRODUCTION_TRIGGER_MASK
, "Fwd Open: Production trigger", HFILL
}},
10070 { &hf_cip_cm_fwo_class
, { "Class", "cip.cm.fwo.transport", FT_UINT8
, BASE_DEC
, VALS(cip_con_class_vals
), CI_TRANSPORT_CLASS_MASK
, "Fwd Open: Transport Class", HFILL
}},
10071 { &hf_cip_cm_gco_conn
, { "Number of Connections", "cip.cm.gco.conn", FT_UINT8
, BASE_DEC
, NULL
, 0, "GetConnOwner: Number of Connections", HFILL
}},
10072 { &hf_cip_cm_gco_coo_conn
, { "COO Connections", "cip.cm.gco.coo_conn", FT_UINT8
, BASE_DEC
, NULL
, 0, "GetConnOwner: COO Connections", HFILL
}},
10073 { &hf_cip_cm_gco_roo_conn
, { "ROO Connections", "cip.cm.gco.roo_conn", FT_UINT8
, BASE_DEC
, NULL
, 0, "GetConnOwner: ROO Connections", HFILL
}},
10074 { &hf_cip_cm_gco_last_action
, { "Last Action", "cip.cm.gco.la", FT_UINT8
, BASE_DEC
, VALS(cip_con_last_action_vals
), 0, "GetConnOwner: Last Action", HFILL
}},
10075 { &hf_cip_cm_ext112_ot_rpi_type
, { "Trigger", "cip.cm.ext112otrpi_type", FT_UINT8
, BASE_DEC
, VALS(cip_cm_rpi_type_vals
), 0, NULL
, HFILL
}},
10076 { &hf_cip_cm_ext112_to_rpi_type
, { "Trigger", "cip.cm.ext112torpi_type", FT_UINT8
, BASE_DEC
, VALS(cip_cm_rpi_type_vals
), 0, NULL
, HFILL
}},
10077 { &hf_cip_cm_ext112_ot_rpi
, { "Acceptable O->T RPI", "cip.cm.ext112otrpi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10078 { &hf_cip_cm_ext112_to_rpi
, { "Acceptable T->O RPI", "cip.cm.ext112torpi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10079 { &hf_cip_cm_ext126_size
, { "Maximum Size", "cip.cm.ext126_size", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10080 { &hf_cip_cm_ext127_size
, { "Maximum Size", "cip.cm.ext127_size", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10081 { &hf_cip_cm_ext128_size
, { "Maximum Size", "cip.cm.ext128_size", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}}
10084 static hf_register_info hf_pccc
[] = {
10085 { &hf_cip_pccc_sc
, { "Service", "cip.pccc.sc", FT_UINT8
, BASE_HEX
, VALS(cip_sc_vals_pccc
), CIP_SC_MASK
, NULL
, HFILL
}},
10086 { &hf_cip_pccc_req_id_len
, { "Requestor ID Length", "cip.pccc.req.id.len", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10087 { &hf_cip_pccc_cip_vend_id
, { "CIP Vendor ID", "cip.pccc.cip.vend.id", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10088 { &hf_cip_pccc_cip_serial_num
, { "CIP Serial Number", "cip.pccc.cip.serial.num", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10089 { &hf_cip_pccc_cmd_code
, { "Command Code", "cip.pccc.cmd.code", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10090 { &hf_cip_pccc_sts_code
, { "Status", "cip.pccc.gs.status", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_gs_st_vals_ext
, 0, NULL
, HFILL
}},
10091 { &hf_cip_pccc_ext_sts_code
, { "Extended Status", "cip.pccc.es.status", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_es_st_vals_ext
, 0, NULL
, HFILL
}},
10092 { &hf_cip_pccc_tns_code
, { "Transaction Code", "cip.pccc.tns.code", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10093 { &hf_cip_pccc_fnc_code_06
, { "Function Code", "cip.pccc.fnc.code_06", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_fnc_06_vals_ext
, 0, NULL
, HFILL
}},
10094 { &hf_cip_pccc_fnc_code_07
, { "Function Code", "cip.pccc.fnc.code_07", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_fnc_07_vals_ext
, 0, NULL
, HFILL
}},
10095 { &hf_cip_pccc_fnc_code_0f
, { "Function Code", "cip.pccc.fnc.code_0f", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_fnc_0f_vals_ext
, 0, NULL
, HFILL
}},
10096 { &hf_cip_pccc_byte_size
, { "Byte Size", "cip.pccc.byte.size", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10097 { &hf_cip_pccc_file_num
, { "File Number", "cip.pccc.file.num", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10098 { &hf_cip_pccc_file_type
, { "File Type", "cip.pccc.file.type", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_file_type_vals_ext
, 0, NULL
, HFILL
}},
10099 { &hf_cip_pccc_element_num
, { "Element Number", "cip.pccc.element.num", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10100 { &hf_cip_pccc_subelement_num
, { "Sub-Element Number", "cip.pccc.subelement.num", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10102 { &hf_cip_pccc_cpu_mode_3a
, { "CPU Mode", "cip.pccc.cpu.mode_3a", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_cpu_mode_3a_vals_ext
, 0, NULL
, HFILL
}},
10104 { &hf_cip_pccc_cpu_mode_80
, { "CPU Mode", "cip.pccc.cpu.mode_80", FT_UINT8
, BASE_HEX
|BASE_EXT_STRING
, &cip_pccc_cpu_mode_80_vals_ext
, 0, NULL
, HFILL
}},
10105 { &hf_cip_pccc_resp_code
, { "Response Code", "cip.pccc.resp.code", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10106 { &hf_cip_pccc_execute_multi_count
, { "Execute Multiple Command - Number of Commands", "cip.pccc.execute.multi.count", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10107 { &hf_cip_pccc_execute_multi_len
, { "Execute Multiple Command - Command Length", "cip.pccc.execute.multi.len", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10108 { &hf_cip_pccc_execute_multi_fnc
, { "Execute Multiple Command - Function Code", "cip.pccc.execute.multi.code", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10110 { &hf_cip_pccc_data
, { "Data", "cip.pccc.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}}
10113 static hf_register_info hf_mb
[] = {
10114 { &hf_cip_mb_sc
, { "Service", "cip.mb.sc", FT_UINT8
, BASE_HEX
, VALS(cip_sc_vals_mb
), CIP_SC_MASK
, NULL
, HFILL
}},
10115 { &hf_cip_mb_read_coils_start_addr
, { "Starting Address", "cip.mb.read_coils.start_addr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10116 { &hf_cip_mb_read_coils_num_coils
, { "Quantity of Coils", "cip.mb.read_coils.num_coils", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10117 { &hf_cip_mb_read_coils_data
, { "Data", "cip.mb.read_coils.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10118 { &hf_cip_mb_read_discrete_inputs_start_addr
, { "Starting Address", "cip.mb.read_discrete_inputs.start_addr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10119 { &hf_cip_mb_read_discrete_inputs_num_inputs
, { "Quantity of Inputs", "cip.mb.read_discrete_inputs.num_inputs", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10120 { &hf_cip_mb_read_discrete_inputs_data
, { "Data", "cip.mb.read_discrete_inputs.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10121 { &hf_cip_mb_read_holding_register_start_addr
, { "Starting Address", "cip.mb.read_holding_register.start_addr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10122 { &hf_cip_mb_read_holding_register_num_registers
, { "Quantity of Holding Registers", "cip.mb.read_holding_register.num_registers", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10123 { &hf_cip_mb_read_holding_register_data
, { "Data", "cip.mb.read_holding_register.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10124 { &hf_cip_mb_read_input_register_start_addr
, { "Starting Address", "cip.mb.read_input_register.start_addr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10125 { &hf_cip_mb_read_input_register_num_registers
, { "Quantity of Input Registers", "cip.mb.read_input_register.num_registers", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10126 { &hf_cip_mb_read_input_register_data
, { "Data", "cip.mb.read_input_register.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10127 { &hf_cip_mb_write_coils_start_addr
, { "Starting Address", "cip.mb.write_coils.start_addr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10128 { &hf_cip_mb_write_coils_outputs_forced
, { "Outputs Forced", "cip.mb.write_coils.outputs_forced", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10129 { &hf_cip_mb_write_coils_num_coils
, { "Quantity of Coils", "cip.mb.write_coils.num_coils", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10130 { &hf_cip_mb_write_coils_data
, { "Data", "cip.mb.write_coils.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10131 { &hf_cip_mb_write_registers_start_addr
, { "Starting Address", "cip.mb.write_registers.start_addr", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10132 { &hf_cip_mb_write_registers_outputs_forced
, { "Outputs Forced", "cip.mb.write_registers.outputs_forced", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10133 { &hf_cip_mb_write_registers_num_registers
, { "Quantity of Holding Registers", "cip.mb.write_registers.num_registers", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10134 { &hf_cip_mb_write_registers_data
, { "Data", "cip.mb.write_registers.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10135 { &hf_cip_mb_data
, { "Data", "cip.mb.data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}}
10138 static hf_register_info hf_cco
[] = {
10139 { &hf_cip_cco_sc
, { "Service", "cip.cco.sc", FT_UINT8
, BASE_HEX
, VALS(cip_sc_vals_cco
), CIP_SC_MASK
, NULL
, HFILL
}},
10140 { &hf_cip_cco_format_number
, { "Format Number", "cip.cco.format_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10141 { &hf_cip_cco_edit_signature
, { "Edit Signature", "cip.cco.edit_signature", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10142 { &hf_cip_cco_con_flags
, { "Connection Flags", "cip.cco.connflags", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10143 { &hf_cip_cco_con_type
, { "Connection O_T", "cip.cco.con", FT_UINT16
, BASE_DEC
, VALS(cip_con_vals
), 0x0001, NULL
, HFILL
}},
10144 { &hf_cip_cco_ot_rtf
, { "O->T real time transfer format", "cip.cco.otrtf", FT_UINT16
, BASE_DEC
, VALS(cip_con_rtf_vals
), 0x000E, NULL
, HFILL
}},
10145 { &hf_cip_cco_to_rtf
, { "T->O real time transfer format", "cip.cco.tortf", FT_UINT16
, BASE_DEC
, VALS(cip_con_rtf_vals
), 0x0070, NULL
, HFILL
}},
10146 { &hf_cip_cco_tdi_vendor
, { "Vendor ID", "cip.cco.tdi.vendor", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_vendor_vals_ext
, 0, NULL
, HFILL
}},
10147 { &hf_cip_cco_tdi_devtype
, { "Device Type", "cip.cco.tdi.devtype", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_devtype_vals_ext
, 0, NULL
, HFILL
}},
10148 { &hf_cip_cco_tdi_prodcode
, { "Product Code", "cip.cco.tdi.product_code", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10149 { &hf_cip_cco_tdi_compatibility
, { "Compatibility", "cip.cco.tdi.compatibility", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10150 { &hf_cip_cco_tdi_comp_bit
, { "Compatibility", "cip.cco.tdi.comp_bit", FT_UINT8
, BASE_HEX
, VALS(cip_com_bit_vals
), 0x80, NULL
, HFILL
}},
10151 { &hf_cip_cco_tdi_majorrev
, { "Major Revision", "cip.cco.tdi.major_rev", FT_UINT8
, BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
}},
10152 { &hf_cip_cco_tdi_minorrev
, { "Minor Revision", "cip.cco.tdi.minor_rev", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10153 { &hf_cip_cco_pdi_vendor
, { "Vendor ID", "cip.cco.pdi.vendor", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_vendor_vals_ext
, 0, NULL
, HFILL
}},
10154 { &hf_cip_cco_pdi_devtype
, { "Device Type", "cip.cco.pdi.devtype", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_devtype_vals_ext
, 0, NULL
, HFILL
}},
10155 { &hf_cip_cco_pdi_prodcode
, { "Product Code", "cip.cco.pdi.product_code", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10156 { &hf_cip_cco_pdi_compatibility
, { "Compatibility", "cip.cco.pdi.compatibility", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10157 { &hf_cip_cco_pdi_comp_bit
, { "Compatibility", "cip.cco.pdi.comp_bit", FT_UINT8
, BASE_HEX
, VALS(cip_com_bit_vals
), 0x80, NULL
, HFILL
}},
10158 { &hf_cip_cco_pdi_majorrev
, { "Major Revision", "cip.cco.pdi.major_rev", FT_UINT8
, BASE_DEC
, NULL
, 0x7F, NULL
, HFILL
}},
10159 { &hf_cip_cco_pdi_minorrev
, { "Minor Revision", "cip.cco.pdi.minor_rev", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10160 { &hf_cip_cco_cs_data_index
, { "CS Data Index Number", "cip.cco.cs_data_index", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10161 { &hf_cip_cco_timeout_multiplier
, { "Connection Timeout Multiplier", "cip.cco.timeout_multiplier", FT_UINT8
, BASE_DEC
, VALS(cip_con_time_mult_vals
), 0, NULL
, HFILL
}},
10162 { &hf_cip_cco_ot_rpi
, { "O->T RPI", "cip.cco.otrpi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10163 { &hf_cip_cco_ot_net_param32
, { "O->T Network Connection Parameters", "cip.cco.ot_net_params", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10164 { &hf_cip_cco_ot_net_param16
, { "O->T Network Connection Parameters", "cip.cco.ot_net_params", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10165 { &hf_cip_cco_to_rpi
, { "T->O RPI", "cip.cco.torpi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
}},
10166 { &hf_cip_cco_to_net_param16
, { "T->O Network Connection Parameters", "cip.cco.to_net_params", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10167 { &hf_cip_cco_to_net_param32
, { "T->O Network Connection Parameters", "cip.cco.to_net_params", FT_UINT16
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10168 { &hf_cip_cco_transport_type_trigger
, { "Transport Type/Trigger", "cip.cco.transport_type_trigger", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}},
10169 { &hf_cip_cco_fwo_con_size
, { "Connection Size", "cip.cco.consize", FT_UINT16
, BASE_DEC
, NULL
, 0x01FF, NULL
, HFILL
}},
10170 { &hf_cip_cco_lfwo_con_size
, { "Connection Size", "cip.cco.consize", FT_UINT32
, BASE_DEC
, NULL
, 0xFFFF, NULL
, HFILL
}},
10171 { &hf_cip_cco_fwo_fixed_var
, { "Connection Size Type", "cip.cco.f_v", FT_UINT16
, BASE_DEC
, VALS(cip_con_fw_vals
), 0x0200, NULL
, HFILL
}},
10172 { &hf_cip_cco_lfwo_fixed_var
, { "Connection Size Type", "cip.cco.f_v", FT_UINT32
, BASE_DEC
, VALS(cip_con_fw_vals
), 0x02000000, NULL
, HFILL
}},
10173 { &hf_cip_cco_fwo_prio
, { "Priority", "cip.cco.prio", FT_UINT16
, BASE_DEC
, VALS(cip_con_prio_vals
), 0x0C00, NULL
, HFILL
}},
10174 { &hf_cip_cco_lfwo_prio
, { "Priority", "cip.cco.prio", FT_UINT32
, BASE_DEC
, VALS(cip_con_prio_vals
), 0x0C000000, NULL
, HFILL
}},
10175 { &hf_cip_cco_fwo_typ
, { "Connection Type", "cip.cco.type", FT_UINT16
, BASE_DEC
, VALS(cip_con_type_vals
), 0x6000, NULL
, HFILL
}},
10176 { &hf_cip_cco_lfwo_typ
, { "Connection Type", "cip.cco.type", FT_UINT32
, BASE_DEC
, VALS(cip_con_type_vals
), 0x60000000, NULL
, HFILL
}},
10177 { &hf_cip_cco_fwo_own
, { "Redundant Owner", "cip.cco.owner", FT_UINT16
, BASE_DEC
, VALS(cip_con_owner_vals
), 0x8000, NULL
, HFILL
}},
10178 { &hf_cip_cco_lfwo_own
, { "Redundant Owner", "cip.cco.owner", FT_UINT32
, BASE_DEC
, VALS(cip_con_owner_vals
), 0x80000000, NULL
, HFILL
}},
10179 { &hf_cip_cco_fwo_dir
, { "Direction", "cip.cco.dir", FT_BOOLEAN
, 8, TFS(&tfs_server_client
), CI_PRODUCTION_DIR_MASK
, NULL
, HFILL
}},
10180 { &hf_cip_cco_fwo_trigger
, { "Trigger", "cip.cco.trigger", FT_UINT8
, BASE_DEC
, VALS(cip_con_trigg_vals
), CI_PRODUCTION_TRIGGER_MASK
, NULL
, HFILL
}},
10181 { &hf_cip_cco_fwo_class
, { "Class", "cip.cco.transport", FT_UINT8
, BASE_DEC
, VALS(cip_con_class_vals
), CI_TRANSPORT_CLASS_MASK
, NULL
, HFILL
}},
10182 { &hf_cip_cco_conn_path_size
, { "Connection Path Size", "cip.cco.connpath_size", FT_UINT8
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_word_words
), 0, NULL
, HFILL
}},
10183 { &hf_cip_cco_proxy_config_size
, { "Proxy Config Data Size", "cip.cco.proxy_config_size", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10184 { &hf_cip_cco_target_config_size
, { "Target Config Data Size", "cip.cco.target_config_size", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10185 { &hf_cip_cco_iomap_format_number
, { "Format number", "cip.cco.iomap_format_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10186 { &hf_cip_cco_iomap_size
, { "Mapping data size", "cip.cco.iomap_size", FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_byte_bytes
), 0, NULL
, HFILL
}},
10187 { &hf_cip_cco_connection_disable
, { "Connection Disable", "cip.cco.connection_disable", FT_UINT8
, BASE_DEC
, NULL
, 0x01, NULL
, HFILL
}},
10188 { &hf_cip_cco_net_conn_param_attr
, { "Net Connection Parameter Attribute Selection", "cip.cco.net_conn_param_attr", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}},
10189 { &hf_cip_cco_proxy_config_data
, { "Proxy Config Data", "cip.cco.proxy_config_data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10190 { &hf_cip_cco_target_config_data
, { "Target Config Data", "cip.cco.target_config_data", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10191 { &hf_cip_cco_iomap_attribute
, { "Attribute Data", "cip.cco.iomap", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10192 { &hf_cip_cco_safety
, { "Safety Parameters", "cip.cco.safety", FT_BYTES
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10193 { &hf_cip_cco_change_type
, { "Change Type", "cip.cco.change_type", FT_UINT16
, BASE_DEC
, VALS(cip_cco_change_type_vals
), 0, NULL
, HFILL
}},
10194 { &hf_cip_cco_connection_name
, { "Connection Name", "cip.cco.connection_name", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
10195 { &hf_cip_cco_ext_status
, { "Extended Status", "cip.cco.ext_status", FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_cm_ext_st_vals_ext
, 0, NULL
, HFILL
}},
10198 /* Setup protocol subtree array */
10199 static int *ett
[] = {
10200 &ett_cip_class_generic
,
10211 &ett_network_seg_safety
,
10212 &ett_network_seg_safety_time_correction_net_params
,
10213 &ett_cip_seg_safety_tunid
,
10214 &ett_cip_seg_safety_tunid_snn
,
10215 &ett_cip_seg_safety_ounid
,
10216 &ett_cip_seg_safety_ounid_snn
,
10218 &ett_add_status_item
,
10219 &ett_cip_get_attributes_all_item
,
10220 &ett_cip_get_attribute_list
,
10221 &ett_cip_get_attribute_list_item
,
10222 &ett_cip_set_attribute_list
,
10223 &ett_cip_set_attribute_list_item
,
10224 &ett_cip_mult_service_packet
,
10225 &ett_cip_msp_offset
,
10226 &ett_time_sync_gm_clock_flags
,
10227 &ett_time_sync_local_clock_flags
,
10228 &ett_time_sync_port_state_info
,
10229 &ett_time_sync_port_enable_cfg
,
10230 &ett_time_sync_port_log_announce
,
10231 &ett_time_sync_port_log_sync
,
10232 &ett_time_sync_clock_type
,
10233 &ett_time_sync_port_profile_id_info
,
10234 &ett_time_sync_port_phys_addr_info
,
10235 &ett_time_sync_port_proto_addr_info
,
10237 &ett_32bitheader_tree
,
10238 &ett_connection_info
,
10241 static int *ett_cm
[] = {
10248 &ett_cm_add_status_item
,
10253 static int *ett_pccc
[] = {
10254 &ett_cip_class_pccc
,
10260 static int *ett_mb
[] = {
10266 static int *ett_cco
[] = {
10267 &ett_cip_class_cco
,
10269 &ett_cco_con_status
,
10279 static ei_register_info ei
[] = {
10280 { &ei_mal_identity_revision
, { "cip.malformed.id.revision", PI_MALFORMED
, PI_ERROR
, "Malformed Identity revision", EXPFILL
}},
10281 { &ei_mal_identity_status
, { "cip.malformed.id.status", PI_MALFORMED
, PI_ERROR
, "Malformed Identity status", EXPFILL
} },
10282 { &ei_mal_msg_rout_num_classes
, { "cip.malformed.msg_rout.num_classes", PI_MALFORMED
, PI_ERROR
, "Malformed Message Router Attribute 1", EXPFILL
}},
10283 { &ei_mal_time_sync_gm_clock
, { "cip.malformed.time_sync.gm_clock", PI_MALFORMED
, PI_ERROR
, "Malformed Grandmaster clock info", EXPFILL
}},
10284 { &ei_mal_time_sync_parent_clock
, { "cip.malformed.time_sync.parent_clock", PI_MALFORMED
, PI_ERROR
, "Malformed Parent clock info", EXPFILL
}},
10285 { &ei_mal_time_sync_local_clock
, { "cip.malformed.time_sync.local_clock", PI_MALFORMED
, PI_ERROR
, "Malformed Local clock info", EXPFILL
}},
10286 { &ei_mal_time_sync_port_state_info
, { "cip.malformed.time_sync.port_state_info", PI_MALFORMED
, PI_ERROR
, "Malformed Port State Info", EXPFILL
}},
10287 { &ei_mal_time_sync_port_state_info_ports
, { "cip.malformed.time_sync.port_state_info.ports", PI_MALFORMED
, PI_ERROR
, "Malformed Port State Info - too many ports", EXPFILL
}},
10288 { &ei_mal_time_sync_port_enable_cfg
, { "cip.malformed.time_sync.port_enable_cfg", PI_MALFORMED
, PI_ERROR
, "Malformed Port Enable Cfg", EXPFILL
}},
10289 { &ei_mal_time_sync_port_enable_cfg_ports
, { "cip.malformed.time_sync.port_enable_cfg.ports", PI_MALFORMED
, PI_ERROR
, "Malformed Port Enable Cfg - too many ports", EXPFILL
}},
10290 { &ei_mal_time_sync_port_log_announce
, { "cip.malformed.time_sync.port_log_announce", PI_MALFORMED
, PI_ERROR
, "Malformed Port Log Announcement Interval Cfg", EXPFILL
}},
10291 { &ei_mal_time_sync_port_log_announce_ports
, { "cip.malformed.time_sync.port_log_announce.ports", PI_MALFORMED
, PI_ERROR
, "Malformed Port Log Announcement Interval Cfg - too many ports", EXPFILL
}},
10292 { &ei_mal_time_sync_port_log_sync
, { "cip.malformed.time_sync.port_log_sync", PI_MALFORMED
, PI_ERROR
, "Malformed Port Log Sync Interval Cfg", EXPFILL
}},
10293 { &ei_mal_time_sync_port_log_sync_ports
, { "cip.malformed.time_sync.port_log_sync.ports", PI_MALFORMED
, PI_ERROR
, "Malformed Port Log Sync Interval Cfg - too many ports", EXPFILL
}},
10294 { &ei_mal_time_sync_clock_type
, { "cip.malformed.time_sync.clock_type", PI_MALFORMED
, PI_ERROR
, "Malformed Clock Type", EXPFILL
}},
10295 { &ei_mal_time_sync_manufacture_id
, { "cip.malformed.time_sync.manufacture_id", PI_MALFORMED
, PI_ERROR
, "Malformed Manufacture Identity", EXPFILL
}},
10296 { &ei_mal_time_sync_prod_desc
, { "cip.malformed.time_sync.prod_desc", PI_MALFORMED
, PI_ERROR
, "Malformed Product Description", EXPFILL
}},
10297 { &ei_mal_time_sync_prod_desc_64
, { "cip.malformed.time_sync.prod_desc.limit_64", PI_PROTOCOL
, PI_WARN
, "Product Description limited to 64 characters", EXPFILL
}},
10298 { &ei_mal_time_sync_prod_desc_size
, { "cip.malformed.time_sync.prod_desc.size", PI_MALFORMED
, PI_ERROR
, "Malformed Product Description - invalid size", EXPFILL
}},
10299 { &ei_mal_time_sync_revision_data
, { "cip.malformed.time_sync.revision_data", PI_MALFORMED
, PI_ERROR
, "Malformed Revision Data", EXPFILL
}},
10300 { &ei_mal_time_sync_revision_data_32
, { "cip.malformed.time_sync.revision_data.limit_32", PI_PROTOCOL
, PI_WARN
, "Revision Data limited to 32 characters", EXPFILL
}},
10301 { &ei_mal_time_sync_revision_data_size
, { "cip.malformed.time_sync.revision_data.size", PI_MALFORMED
, PI_ERROR
, "Malformed Revision Data - invalid size", EXPFILL
}},
10302 { &ei_mal_time_sync_user_desc
, { "cip.malformed.time_sync.user_desc", PI_MALFORMED
, PI_ERROR
, "Malformed User Description", EXPFILL
}},
10303 { &ei_mal_time_sync_user_desc_128
, { "cip.malformed.time_sync.user_desc.limit_128", PI_PROTOCOL
, PI_WARN
, "User Description limited to 128 characters", EXPFILL
}},
10304 { &ei_mal_time_sync_user_desc_size
, { "cip.malformed.time_sync.user_desc.size", PI_MALFORMED
, PI_ERROR
, "Malformed User Description - invalid size", EXPFILL
}},
10305 { &ei_mal_time_sync_port_profile_id_info
, { "cip.malformed.time_sync.port_profile_id_info", PI_MALFORMED
, PI_ERROR
, "Malformed Port Profile Identity Info", EXPFILL
}},
10306 { &ei_mal_time_sync_port_profile_id_info_ports
, { "cip.malformed.time_sync.port_profile_id_info.ports", PI_MALFORMED
, PI_ERROR
, "Malformed Port Profile Identity Info - too many ports", EXPFILL
}},
10307 { &ei_mal_time_sync_port_phys_addr_info
, { "cip.malformed.time_sync.port_phys_addr_info", PI_MALFORMED
, PI_ERROR
, "Malformed Port Physical Address Info", EXPFILL
}},
10308 { &ei_mal_time_sync_port_phys_addr_info_ports
, { "cip.malformed.time_sync.port_phys_addr_info.ports", PI_MALFORMED
, PI_ERROR
, "Malformed Port Physical Address Info - too many ports", EXPFILL
}},
10309 { &ei_mal_time_sync_port_proto_addr_info
, { "cip.malformed.time_sync.port_proto_addr_info", PI_MALFORMED
, PI_ERROR
, "Malformed Port Protocol Address Info", EXPFILL
}},
10310 { &ei_mal_time_sync_port_proto_addr_info_ports
, { "cip.malformed.time_sync.port_proto_addr_info.ports", PI_MALFORMED
, PI_ERROR
, "Malformed Port Protocol Address Info - too many ports", EXPFILL
}},
10311 { &ei_mal_time_sync_sys_time_and_offset
, { "cip.malformed.time_sync.sys_time_and_offset", PI_MALFORMED
, PI_ERROR
, "Malformed System Time and Offset", EXPFILL
}},
10312 { &ei_proto_log_seg_format
, { "cip.unsupported.log_seg_format", PI_PROTOCOL
, PI_WARN
, "Unsupported Logical Segment Format", EXPFILL
}},
10313 { &ei_mal_incomplete_epath
, { "cip.malformed.incomplete_epath", PI_MALFORMED
, PI_ERROR
, "Incomplete EPATH", EXPFILL
}},
10314 { &ei_proto_electronic_key_format
, { "cip.unsupported.electronic_key_format", PI_PROTOCOL
, PI_WARN
, "Unsupported Electronic Key Format", EXPFILL
}},
10315 { &ei_proto_special_segment_format
, { "cip.unsupported.special_segment_format", PI_PROTOCOL
, PI_WARN
, "Unsupported Special Segment Format", EXPFILL
}},
10316 { &ei_proto_log_seg_type
, { "cip.unsupported.log_seg_type", PI_PROTOCOL
, PI_WARN
, "Unsupported Logical Segment Type", EXPFILL
}},
10317 { &ei_proto_log_sub_seg_type
, { "cip.unsupported.log_sub_seg_type", PI_PROTOCOL
, PI_WARN
, "Unsupported Sub-Segment Type", EXPFILL
}},
10318 { &ei_proto_ext_string_format
, { "cip.unsupported.ext_string_format", PI_PROTOCOL
, PI_WARN
, "Unsupported Extended String Format", EXPFILL
} },
10319 { &ei_proto_ext_network
, { "cip.malformed.ext_network", PI_PROTOCOL
, PI_ERROR
, "Malformed Extended Network Segment Format", EXPFILL
} },
10320 { &ei_proto_seg_type
, { "cip.unsupported.seg_type", PI_PROTOCOL
, PI_WARN
, "Unsupported Segment Type", EXPFILL
}},
10321 { &ei_proto_unsupported_datatype
, { "cip.unsupported.datatype", PI_PROTOCOL
, PI_WARN
, "Unsupported Datatype", EXPFILL
}},
10322 { &ei_mal_serv_gal
, { "cip.malformed.get_attribute_list", PI_MALFORMED
, PI_ERROR
, "Malformed Get Attribute List service", EXPFILL
}},
10323 { &ei_mal_serv_gal_count
, { "cip.malformed.get_attribute_list.count", PI_MALFORMED
, PI_ERROR
, "Malformed Get Attribute List attribute list count greater than packet size", EXPFILL
}},
10324 { &ei_mal_serv_sal
, { "cip.malformed.set_attribute_list", PI_MALFORMED
, PI_ERROR
, "Malformed Set Attribute List service", EXPFILL
}},
10325 { &ei_mal_serv_sal_count
, { "cip.malformed.set_attribute_list.count", PI_MALFORMED
, PI_ERROR
, "Malformed Set Attribute List attribute list count greater than packet size", EXPFILL
}},
10326 { &ei_mal_msp_services
, { "cip.malformed.msp.services", PI_MALFORMED
, PI_WARN
, "Multiple Service Packet too many services for packet", EXPFILL
}},
10327 { &ei_mal_msp_inv_offset
, { "cip.malformed.msp.inv_offset", PI_MALFORMED
, PI_WARN
, "Multiple Service Packet service invalid offset", EXPFILL
}},
10328 { &ei_mal_msp_missing_services
, { "cip.malformed.msp.missing_services", PI_MALFORMED
, PI_ERROR
, "Multiple Service Packet service missing Number of Services field", EXPFILL
}},
10329 { &ei_mal_serv_find_next_object
, { "cip.malformed.find_next_object", PI_MALFORMED
, PI_ERROR
, "Find Next Object service missing Number of List Members field", EXPFILL
}},
10330 { &ei_mal_serv_find_next_object_count
, { "cip.malformed.find_next_object.count", PI_MALFORMED
, PI_ERROR
, "Find Next Object instance list count greater than packet size", EXPFILL
}},
10331 { &ei_mal_rpi_no_data
, { "cip.malformed.rpi_no_data", PI_MALFORMED
, PI_WARN
, "RPI not acceptable - missing extended data", EXPFILL
}},
10332 { &ei_mal_fwd_close_missing_data
, { "cip.malformed.fwd_close_missing_data", PI_MALFORMED
, PI_ERROR
, "Forward Close response missing application reply data", EXPFILL
}},
10333 { &ei_mal_opt_attr_list
, { "cip.malformed.opt_attr_list", PI_MALFORMED
, PI_ERROR
, "Optional attribute list missing data", EXPFILL
}},
10334 { &ei_mal_opt_service_list
, { "cip.malformed.opt_service_list", PI_MALFORMED
, PI_ERROR
, "Optional service list missing data", EXPFILL
}},
10335 { &ei_mal_padded_epath_size
, { "cip.malformed.epath.size", PI_MALFORMED
, PI_ERROR
, "Malformed EPATH vs Size", EXPFILL
} },
10336 { &ei_mal_missing_string_data
, { "cip.malformed.missing_str_data", PI_MALFORMED
, PI_ERROR
, "Missing string data", EXPFILL
} },
10338 { &ei_cip_null_fwd_open
, { "cip.analysis.null_fwd_open", PI_PROTOCOL
, PI_NOTE
, "Null Forward Open", EXPFILL
} },
10339 { &ei_cip_safety_open_type1
, { "cip.analysis.safety_open_type1", PI_PROTOCOL
, PI_NOTE
, "Type 1 - Safety Open with Data", EXPFILL
} },
10340 { &ei_cip_safety_open_type2a
, { "cip.analysis.safety_open_type2a", PI_PROTOCOL
, PI_NOTE
, "Type 2a - Safety Open with SCID check", EXPFILL
} },
10341 { &ei_cip_safety_open_type2b
, { "cip.analysis.safety_open_type2b", PI_PROTOCOL
, PI_NOTE
, "Type 2b - Safety Open without SCID check", EXPFILL
} },
10342 { &ei_cip_safety_input
, { "cip.analysis.safety_input", PI_PROTOCOL
, PI_NOTE
, "Safety Input Connection", EXPFILL
} },
10343 { &ei_cip_safety_output
, { "cip.analysis.safety_output", PI_PROTOCOL
, PI_NOTE
, "Safety Output Connection", EXPFILL
} },
10344 { &ei_cip_listen_input_connection
, { "cip.analysis.listen_input_connection", PI_PROTOCOL
, PI_NOTE
, "[Likely] Listen Only or Input Only Connection", EXPFILL
} },
10345 { &ei_cip_no_fwd_close
, { "cip.analysis.no_fwd_close", PI_PROTOCOL
, PI_NOTE
, "No Forward Close seen for this CIP Connection", EXPFILL
} },
10348 module_t
*cip_module
;
10349 expert_module_t
* expert_cip
;
10351 /* Register the protocol name and description */
10352 proto_cip
= proto_register_protocol("Common Industrial Protocol",
10354 cip_handle
= register_dissector("cip", dissect_cip
, proto_cip
);
10356 register_dissector("cip_implicit", dissect_cip_implicit
, proto_cip
);
10358 /* Required function calls to register the header fields and subtrees used */
10359 proto_register_field_array(proto_cip
, hf
, array_length(hf
));
10360 proto_register_subtree_array(ett
, array_length(ett
));
10362 expert_cip
= expert_register_protocol(proto_cip
);
10363 expert_register_field_array(expert_cip
, ei
, array_length(ei
));
10365 cip_module
= prefs_register_protocol(proto_cip
, NULL
);
10366 prefs_register_bool_preference(cip_module
, "enhanced_info_column",
10367 "Display enhanced Info column data",
10368 "Whether the CIP dissector should display enhanced/verbose data in the Info column for CIP explicit messages",
10369 &cip_enhanced_info_column
);
10371 subdissector_class_table
= register_dissector_table("cip.class.iface",
10372 "CIP Class Interface Handle", proto_cip
, FT_UINT32
, BASE_HEX
);
10373 subdissector_symbol_table
= register_dissector_table("cip.data_segment.iface",
10374 "CIP Data Segment Interface Handle", proto_cip
, FT_UINT32
, BASE_HEX
);
10376 /* Register the protocol name and description */
10377 proto_cip_class_generic
= proto_register_protocol("CIP Class Generic",
10378 "CIPCLS", "cipcls");
10379 cip_class_generic_handle
= register_dissector("cipcls",
10380 dissect_cip_class_generic
, proto_cip_class_generic
);
10382 /* Register the protocol name and description */
10383 proto_cip_class_cm
= proto_register_protocol("CIP Connection Manager",
10385 cip_class_cm_handle
= register_dissector("cipcm",
10386 dissect_cip_class_cm
, proto_cip_class_cm
);
10387 proto_register_field_array(proto_cip_class_cm
, hf_cm
, array_length(hf_cm
));
10388 proto_register_subtree_array(ett_cm
, array_length(ett_cm
));
10390 proto_cip_class_pccc
= proto_register_protocol("CIP PCCC Object",
10391 "CIPPCCC", "cippccc");
10392 cip_class_pccc_handle
= register_dissector("cippccc",
10393 dissect_cip_class_pccc
, proto_cip_class_pccc
);
10394 proto_register_field_array(proto_cip_class_pccc
, hf_pccc
, array_length(hf_pccc
));
10395 proto_register_subtree_array(ett_pccc
, array_length(ett_pccc
));
10397 proto_cip_class_mb
= proto_register_protocol("CIP Modbus Object",
10399 cip_class_mb_handle
= register_dissector("cipmb",
10400 dissect_cip_class_mb
, proto_cip_class_mb
);
10401 proto_register_field_array(proto_cip_class_mb
, hf_mb
, array_length(hf_mb
));
10402 proto_register_subtree_array(ett_mb
, array_length(ett_mb
));
10404 proto_cip_class_cco
= proto_register_protocol("CIP Connection Configuration Object",
10405 "CIPCCO", "cipcco");
10406 cip_class_cco_handle
= register_dissector("cipcco",
10407 dissect_cip_class_cco
, proto_cip_class_cco
);
10408 proto_register_field_array(proto_cip_class_cco
, hf_cco
, array_length(hf_cco
));
10409 proto_register_subtree_array(ett_cco
, array_length(ett_cco
));
10411 /* Register a heuristic dissector on the service of the message so objects
10412 * can override the dissector for common services */
10413 heur_subdissector_service
= register_heur_dissector_list_with_description("cip.sc", "CIP Service data", proto_cip
);
10415 build_get_attr_all_table();
10416 } /* end of proto_register_cip() */
10419 proto_reg_handoff_cip(void)
10421 /* Register for UCMM CIP data, using EtherNet/IP SendRRData service*/
10422 dissector_add_uint( "enip.srrd.iface", ENIP_CIP_INTERFACE
, cip_handle
);
10424 dissector_add_uint("cip.connection.class", CI_CLS_MR
, cip_handle
);
10426 /* Register dissector handle for generic class */
10427 dissector_add_uint( "cip.class.iface", 0, cip_class_generic_handle
);
10429 /* Register dissector handle for Connection Manager */
10430 dissector_add_uint( "cip.class.iface", CI_CLS_CM
, cip_class_cm_handle
);
10432 /* Register dissector handle for the PCCC class */
10433 dissector_add_uint( "cip.class.iface", CI_CLS_PCCC
, cip_class_pccc_handle
);
10435 /* Register dissector handle for Modbus Object */
10436 dissector_add_uint( "cip.class.iface", CI_CLS_MB
, cip_class_mb_handle
);
10437 modbus_handle
= find_dissector_add_dependency("modbus", proto_cip_class_mb
);
10439 /* Register dissector handle for Connection Configuration Object */
10440 dissector_add_uint( "cip.class.iface", CI_CLS_CCO
, cip_class_cco_handle
);
10441 heur_dissector_add("cip.sc", dissect_class_cco_heur
, "CIP Connection Configuration Object", "cco_cip", proto_cip_class_cco
, HEURISTIC_ENABLE
);
10443 proto_enip
= proto_get_id_by_filter_name( "enip" );
10444 proto_modbus
= proto_get_id_by_filter_name( "modbus" );
10446 } /* end of proto_reg_handoff_cip() */
10452 * c-basic-offset: 3
10454 * indent-tabs-mode: nil
10457 * ex: set shiftwidth=3 tabstop=8 expandtab:
10458 * :indentSize=3:tabSize=8:noTabs=true: