2 * Routines for EtherNet/IP (Industrial Protocol) dissection
3 * EtherNet/IP Home: www.odva.org
5 * This dissector includes items from:
6 * CIP Volume 1: Common Industrial Protocol, Edition 3.34
7 * CIP Volume 2: EtherNet/IP Adaptation of CIP, Edition 1.30
8 * CIP Volume 8: CIP Security, Edition 1.17
11 * Magnus Hansson <mah@hms.se>
12 * Joakim Wiberg <jow@hms.se>
14 * Conversation data support for CIP
15 * Jan Bartels, Siempelkamp Maschinen- und Anlagenbau GmbH & Co. KG
18 * Ethernet/IP object support
22 * Wireshark - Network traffic analyzer
23 * By Gerald Combs <gerald@wireshark.org>
24 * Copyright 1998 Gerald Combs
26 * SPDX-License-Identifier: GPL-2.0-or-later
31 #include <epan/packet.h>
32 #include <epan/conversation_filter.h>
33 #include <epan/prefs.h>
34 #include <epan/etypes.h>
35 #include <epan/expert.h>
36 #include <epan/decode_as.h>
37 #include <epan/proto_data.h>
41 #include "packet-tcp.h"
42 #include "packet-cip.h"
43 #include "packet-enip.h"
44 #include "packet-cipsafety.h"
45 #include "packet-dtls.h"
46 #include "packet-tls.h"
47 #include "packet-tls-utils.h"
49 void proto_register_enip(void);
50 void proto_reg_handoff_enip(void);
52 /* Communication Ports */
53 #define ENIP_ENCAP_PORT 44818 /* EtherNet/IP located on port 44818 */
54 #define ENIP_SECURE_PORT 2221 /* EtherNet/IP TLS/DTLS port */
55 #define ENIP_IO_PORT 2222 /* EtherNet/IP IO located on port 2222 */
57 /* EtherNet/IP function codes */
59 #define LIST_SERVICES 0x0004
60 #define LIST_IDENTITY 0x0063
61 #define LIST_INTERFACES 0x0064
62 #define REGISTER_SESSION 0x0065
63 #define UNREGISTER_SESSION 0x0066
64 #define SEND_RR_DATA 0x006F
65 #define SEND_UNIT_DATA 0x0070
66 #define START_DTLS 0x00C8
68 /* EtherNet/IP status codes */
69 #define SUCCESS 0x0000
70 #define INVALID_CMD 0x0001
71 #define NO_RESOURCES 0x0002
72 #define INCORRECT_DATA 0x0003
73 #define INVALID_SESSION 0x0064
74 #define INVALID_LENGTH 0x0065
75 #define UNSUPPORTED_PROT_REV 0x0069
76 #define ENCAP_HEADER_ERROR 0x006A
78 /* EtherNet/IP Common Packet Format Type IDs */
79 #define CPF_ITEM_NULL 0x0000
80 #define CPF_ITEM_CIP_IDENTITY 0x000C
81 #define CPF_ITEM_CIP_SECURITY 0x0086
82 #define CPF_ITEM_ENIP_CAPABILITY 0x0087
83 #define CPF_ITEM_ENIP_USAGE 0x0088
84 #define CPF_ITEM_CONNECTED_ADDRESS 0x00A1
85 #define CPF_ITEM_CONNECTED_DATA 0x00B1
86 #define CPF_ITEM_UNCONNECTED_DATA 0x00B2
87 #define CPF_ITEM_LIST_SERVICES_RESP 0x0100
88 #define CPF_ITEM_SOCK_ADR_INFO_OT 0x8000
89 #define CPF_ITEM_SOCK_ADR_INFO_TO 0x8001
90 #define CPF_ITEM_SEQUENCED_ADDRESS 0x8002
91 #define CPF_ITEM_UNCONNECTED_MSG_DTLS 0x8003
93 /* Initialize the protocol and registered fields */
94 static int proto_enip
;
95 static int proto_cipio
;
96 static int proto_cip_class1
;
98 static int hf_enip_command
;
99 static int hf_enip_length
;
100 static int hf_enip_options
;
101 static int hf_enip_sendercontex
;
102 static int hf_enip_listid_delay
;
103 static int hf_enip_status
;
104 static int hf_enip_session
;
105 static int hf_enip_encapver
;
106 static int hf_enip_sinfamily
;
107 static int hf_enip_sinport
;
108 static int hf_enip_sinaddr
;
109 static int hf_enip_sinzero
;
110 static int hf_enip_timeout
;
111 static int hf_enip_encap_data
;
113 static int hf_enip_lir_vendor
;
114 static int hf_enip_lir_devtype
;
115 static int hf_enip_lir_prodcode
;
116 static int hf_enip_lir_revision
;
117 static int hf_enip_lir_status
;
118 static int hf_enip_lir_serial
;
119 static int hf_enip_lir_namelen
;
120 static int hf_enip_lir_name
;
121 static int hf_enip_lir_state
;
123 static int hf_enip_lsr_capaflags
;
124 static int hf_enip_lsr_tcp
;
125 static int hf_enip_lsr_udp
;
126 static int hf_enip_lsr_servicename
;
128 static int hf_enip_rs_version
;
129 static int hf_enip_rs_optionflags
;
131 static int hf_enip_security_profiles
;
132 static int hf_enip_security_profiles_eip_integrity
;
133 static int hf_enip_security_profiles_eip_confidentiality
;
134 static int hf_enip_security_profiles_cip_authorization
;
135 static int hf_enip_security_profiles_cip_user_authentication
;
136 static int hf_enip_security_profiles_resource_constrained
;
137 static int hf_enip_security_profiles_reserved
;
138 static int hf_enip_cip_security_state
;
139 static int hf_enip_eip_security_state
;
140 static int hf_enip_iana_port_state_flags
;
141 static int hf_enip_iana_port_state_flags_tcp_44818
;
142 static int hf_enip_iana_port_state_flags_udp_44818
;
143 static int hf_enip_iana_port_state_flags_udp_2222
;
144 static int hf_enip_iana_port_state_flags_tcp_2221
;
145 static int hf_enip_iana_port_state_flags_udp_2221
;
146 static int hf_enip_iana_port_state_flags_reserved
;
148 static int hf_enip_srrd_ifacehnd
;
150 static int hf_enip_sud_ifacehnd
;
152 static int hf_enip_cpf_itemcount
;
153 static int hf_enip_cpf_typeid
;
154 static int hf_enip_cpf_length
;
155 static int hf_cip_sequence_count
;
156 static int hf_cip_cm_ot_api
;
157 static int hf_cip_cm_to_api
;
158 static int hf_enip_cpf_cai_connid
;
159 static int hf_enip_cpf_sai_connid
;
160 static int hf_cip_connid
;
161 static int hf_enip_cpf_sai_seqnum
;
162 static int hf_enip_cpf_ucmm_request
;
163 static int hf_enip_cpf_ucmm_msg_type
;
164 static int hf_enip_cpf_ucmm_trans_id
;
165 static int hf_enip_cpf_ucmm_status
;
167 static int hf_enip_cpf_data
;
169 static int hf_enip_response_in
;
170 static int hf_enip_response_to
;
171 static int hf_enip_time
;
172 static int hf_enip_fwd_open_in
;
173 static int hf_cip_connection
;
174 static int hf_cip_io_data
;
176 /* Parsed Attributes */
177 static int hf_tcpip_status
;
178 static int hf_tcpip_status_interface_config
;
179 static int hf_tcpip_status_mcast_pending
;
180 static int hf_tcpip_status_interface_config_pending
;
181 static int hf_tcpip_status_acd
;
182 static int hf_tcpip_acd_fault
;
183 static int hf_tcpip_status_iana_port_admin_change
;
184 static int hf_tcpip_status_iana_protocol_admin_change
;
185 static int hf_tcpip_status_reserved
;
186 static int hf_tcpip_config_cap
;
187 static int hf_tcpip_config_cap_bootp
;
188 static int hf_tcpip_config_cap_dns
;
189 static int hf_tcpip_config_cap_dhcp
;
190 static int hf_tcpip_config_cap_dhcp_dns_update
;
191 static int hf_tcpip_config_cap_config_settable
;
192 static int hf_tcpip_config_cap_hardware_config
;
193 static int hf_tcpip_config_cap_interface_reset
;
194 static int hf_tcpip_config_cap_acd
;
195 static int hf_tcpip_config_cap_reserved
;
196 static int hf_tcpip_config_control
;
197 static int hf_tcpip_config_control_config
;
198 static int hf_tcpip_config_control_dns
;
199 static int hf_tcpip_config_control_reserved
;
200 static int hf_tcpip_ic_ip_addr
;
201 static int hf_tcpip_ic_subnet_mask
;
202 static int hf_tcpip_ic_gateway
;
203 static int hf_tcpip_ic_name_server
;
204 static int hf_tcpip_ic_name_server2
;
205 static int hf_tcpip_ic_domain_name
;
206 static int hf_tcpip_hostname
;
207 static int hf_tcpip_snn_timestamp
;
208 static int hf_tcpip_snn_date
;
209 static int hf_tcpip_snn_time
;
210 static int hf_tcpip_ttl_value
;
211 static int hf_tcpip_mcast_alloc
;
212 static int hf_tcpip_mcast_reserved
;
213 static int hf_tcpip_mcast_num_mcast
;
214 static int hf_tcpip_mcast_addr_start
;
215 static int hf_tcpip_lcd_acd_activity
;
216 static int hf_tcpip_lcd_remote_mac
;
217 static int hf_tcpip_lcd_arp_pdu
;
218 static int hf_tcpip_select_acd
;
219 static int hf_tcpip_quick_connect
;
220 static int hf_tcpip_encap_inactivity
;
222 static int hf_tcpip_port_count
;
223 static int hf_tcpip_port_name
;
224 static int hf_tcpip_port_number
;
225 static int hf_tcpip_port_protocol
;
226 static int hf_tcpip_port_admin_state
;
227 static int hf_tcpip_port_admin_capability
;
228 static int hf_tcpip_admin_capability_configurable
;
229 static int hf_tcpip_admin_capability_reset_required
;
230 static int hf_tcpip_admin_capability_reserved
;
232 static int hf_elink_interface_flags
;
233 static int hf_elink_iflags_link_status
;
234 static int hf_elink_iflags_duplex
;
235 static int hf_elink_iflags_neg_status
;
236 static int hf_elink_iflags_manual_reset
;
237 static int hf_elink_iflags_local_hw_fault
;
238 static int hf_elink_iflags_reserved
;
239 static int hf_elink_interface_speed
;
240 static int hf_elink_physical_address
;
241 static int hf_elink_icount_in_octets
;
242 static int hf_elink_icount_in_ucast
;
243 static int hf_elink_icount_in_nucast
;
244 static int hf_elink_icount_in_discards
;
245 static int hf_elink_icount_in_errors
;
246 static int hf_elink_icount_in_unknown_protos
;
247 static int hf_elink_icount_out_octets
;
248 static int hf_elink_icount_out_ucast
;
249 static int hf_elink_icount_out_nucast
;
250 static int hf_elink_icount_out_discards
;
251 static int hf_elink_icount_out_errors
;
252 static int hf_elink_mcount_alignment_errors
;
253 static int hf_elink_mcount_fcs_errors
;
254 static int hf_elink_mcount_single_collisions
;
255 static int hf_elink_mcount_multiple_collisions
;
256 static int hf_elink_mcount_sqe_test_errors
;
257 static int hf_elink_mcount_deferred_transmission
;
258 static int hf_elink_mcount_late_collisions
;
259 static int hf_elink_mcount_excessive_collisions
;
260 static int hf_elink_mcount_mac_transmit_errors
;
261 static int hf_elink_mcount_carrier_sense_errors
;
262 static int hf_elink_mcount_frame_too_long
;
263 static int hf_elink_mcount_mac_receive_errors
;
264 static int hf_elink_icontrol_control_bits
;
265 static int hf_elink_icontrol_control_bits_auto_neg
;
266 static int hf_elink_icontrol_control_bits_forced_duplex
;
267 static int hf_elink_icontrol_control_bits_reserved
;
268 static int hf_elink_icontrol_forced_speed
;
269 static int hf_elink_icapability_capability_bits
;
270 static int hf_elink_icapability_capability_bits_manual
;
271 static int hf_elink_icapability_capability_bits_auto_neg
;
272 static int hf_elink_icapability_capability_bits_auto_mdix
;
273 static int hf_elink_icapability_capability_bits_manual_speed
;
274 static int hf_elink_icapability_capability_speed_duplex_array_count
;
275 static int hf_elink_icapability_capability_speed
;
276 static int hf_elink_icapability_capability_duplex
;
277 static int hf_elink_interface_type
;
278 static int hf_elink_interface_state
;
279 static int hf_elink_admin_state
;
280 static int hf_elink_interface_label
;
281 static int hf_elink_hc_icount_in_octets
;
282 static int hf_elink_hc_icount_in_ucast
;
283 static int hf_elink_hc_icount_in_mcast
;
284 static int hf_elink_hc_icount_in_broadcast
;
285 static int hf_elink_hc_icount_out_octets
;
286 static int hf_elink_hc_icount_out_ucast
;
287 static int hf_elink_hc_icount_out_mcast
;
288 static int hf_elink_hc_icount_out_broadcast
;
290 static int hf_elink_hc_mcount_stats_align_errors
;
291 static int hf_elink_hc_mcount_stats_fcs_errors
;
292 static int hf_elink_hc_mcount_stats_internal_mac_transmit_errors
;
293 static int hf_elink_hc_mcount_stats_frame_too_long
;
294 static int hf_elink_hc_mcount_stats_internal_mac_receive_errors
;
295 static int hf_elink_hc_mcount_stats_symbol_errors
;
297 static int hf_qos_8021q_enable
;
298 static int hf_qos_dscp_ptp_event
;
299 static int hf_qos_dscp_ptp_general
;
300 static int hf_qos_dscp_urgent
;
301 static int hf_qos_dscp_scheduled
;
302 static int hf_qos_dscp_high
;
303 static int hf_qos_dscp_low
;
304 static int hf_qos_dscp_explicit
;
306 static int hf_dlr_network_topology
;
307 static int hf_dlr_network_status
;
308 static int hf_dlr_ring_supervisor_status
;
309 static int hf_dlr_rsc_ring_supervisor_enable
;
310 static int hf_dlr_rsc_ring_supervisor_precedence
;
311 static int hf_dlr_rsc_beacon_interval
;
312 static int hf_dlr_rsc_beacon_timeout
;
313 static int hf_dlr_rsc_dlr_vlan_id
;
314 static int hf_dlr_ring_faults_count
;
315 static int hf_dlr_lanp1_dev_ip_addr
;
316 static int hf_dlr_lanp1_dev_physical_address
;
317 static int hf_dlr_lanp2_dev_ip_addr
;
318 static int hf_dlr_lanp2_dev_physical_address
;
319 static int hf_dlr_ring_protocol_participants_count
;
320 static int hf_dlr_rppl_dev_ip_addr
;
321 static int hf_dlr_rppl_dev_physical_address
;
322 static int hf_dlr_asa_supervisor_ip_addr
;
323 static int hf_dlr_asa_supervisor_physical_address
;
324 static int hf_dlr_active_supervisor_precedence
;
325 static int hf_dlr_capability_flags
;
326 static int hf_dlr_capflags_announce_base_node
;
327 static int hf_dlr_capflags_beacon_base_node
;
328 static int hf_dlr_capflags_reserved1
;
329 static int hf_dlr_capflags_supervisor_capable
;
330 static int hf_dlr_capflags_reserved2
;
331 static int hf_dlr_capflags_redundant_gateway_capable
;
332 static int hf_dlr_capflags_flush_frame_capable
;
333 static int hf_dlr_rgc_red_gateway_enable
;
334 static int hf_dlr_rgc_gateway_precedence
;
335 static int hf_dlr_rgc_advertise_interval
;
336 static int hf_dlr_rgc_advertise_timeout
;
337 static int hf_dlr_rgc_learning_update_enable
;
338 static int hf_dlr_redundant_gateway_status
;
339 static int hf_dlr_aga_ip_addr
;
340 static int hf_dlr_aga_physical_address
;
341 static int hf_dlr_active_gateway_precedence
;
343 static int hf_cip_security_state
;
344 static int hf_eip_security_state
;
345 static int hf_eip_security_verify_client_cert
;
346 static int hf_eip_security_send_cert_chain
;
347 static int hf_eip_security_check_expiration
;
348 static int hf_eip_security_capability_flags
;
349 static int hf_eip_security_capflags_secure_renegotiation
;
350 static int hf_eip_security_capflags_reserved
;
351 static int hf_eip_security_num_avail_cipher_suites
;
352 static int hf_eip_security_avail_cipher_suite
;
353 static int hf_eip_security_num_allow_cipher_suites
;
354 static int hf_eip_security_allow_cipher_suite
;
355 static int hf_eip_security_num_psk
;
356 static int hf_eip_security_psk_identity_size
;
357 static int hf_eip_security_psk_identity
;
358 static int hf_eip_security_psk_size
;
359 static int hf_eip_security_psk
;
360 static int hf_eip_security_psk_usage
;
361 static int hf_eip_security_num_active_certs
;
362 static int hf_eip_security_num_trusted_auths
;
363 static int hf_eip_security_num_trusted_identities
;
364 static int hf_eip_security_num_crl
;
365 static int hf_eip_cert_name
;
366 static int hf_eip_cert_state
;
367 static int hf_eip_cert_encoding
;
368 static int hf_eip_cert_device_cert_status
;
369 static int hf_eip_cert_ca_cert_status
;
370 static int hf_eip_cert_capflags_push
;
371 static int hf_eip_cert_capflags_reserved
;
372 static int hf_eip_cert_capability_flags
;
373 static int hf_eip_cert_num_certs
;
374 static int hf_eip_cert_cert_name
;
375 static int hf_eip_cert_verify_certificate
;
376 static int hf_lldp_subtype
;
377 static int hf_lldp_mac_address
;
378 static int hf_ingress_egress_num_ranges
;
379 static int hf_ingress_egress_port_range_low
;
380 static int hf_ingress_egress_port_range_high
;
381 static int hf_ingress_egress_num_rules
;
382 static int hf_ingress_egress_rule_string
;
383 static int hf_ingress_egress_rules_change_count
;
384 static int hf_ingress_egress_apply_behav_break_connections
;
385 static int hf_ingress_egress_apply_behav_reserved
;
386 static int hf_ingress_egress_apply_behavior
;
387 static int hf_ingress_egress_ins_num
;
388 static int hf_ingress_egress_ins
;
390 /* Initialize the subtree pointers */
392 static int ett_cip_io_generic
;
394 static int ett_count_tree
;
395 static int ett_type_tree
;
396 static int ett_command_tree
;
397 static int ett_sockadd
;
398 static int ett_lsrcf
;
399 static int ett_tcpip_status
;
400 static int ett_tcpip_admin_capability
;
401 static int ett_tcpip_config_cap
;
402 static int ett_tcpip_config_control
;
403 static int ett_elink_interface_flags
;
404 static int ett_elink_icontrol_bits
;
405 static int ett_elink_icapability_bits
;
406 static int ett_dlr_capability_flags
;
407 static int ett_dlr_lnknbrstatus_flags
;
408 static int ett_eip_security_capability_flags
;
409 static int ett_eip_security_psk
;
410 static int ett_eip_security_active_certs
;
411 static int ett_eip_security_trusted_auths
;
412 static int ett_eip_security_trusted_identities
;
413 static int ett_eip_security_crl
;
414 static int ett_eip_cert_capability_flags
;
415 static int ett_eip_cert_num_certs
;
416 static int ett_security_profiles
;
417 static int ett_ingress_egress_apply_behavior
;
418 static int ett_iana_port_state_flags
;
419 static int ett_connection_info
;
420 static int ett_connection_path_info
;
421 static int ett_cmd_data
;
423 static expert_field ei_mal_tcpip_status
;
424 static expert_field ei_mal_tcpip_config_cap
;
425 static expert_field ei_mal_tcpip_config_control
;
426 static expert_field ei_mal_tcpip_interface_config
;
427 static expert_field ei_mal_tcpip_mcast_config
;
428 static expert_field ei_mal_tcpip_last_conflict
;
429 static expert_field ei_mal_tcpip_snn
;
430 static expert_field ei_mal_elink_interface_flags
;
431 static expert_field ei_mal_elink_physical_address
;
432 static expert_field ei_mal_elink_interface_counters
;
433 static expert_field ei_mal_elink_media_counters
;
434 static expert_field ei_mal_elink_interface_control
;
435 static expert_field ei_mal_dlr_ring_supervisor_config
;
436 static expert_field ei_mal_dlr_last_active_node_on_port_1
;
437 static expert_field ei_mal_dlr_last_active_node_on_port_2
;
438 static expert_field ei_mal_dlr_ring_protocol_participants_list
;
439 static expert_field ei_mal_dlr_active_supervisor_address
;
440 static expert_field ei_mal_dlr_capability_flags
;
441 static expert_field ei_mal_dlr_redundant_gateway_config
;
442 static expert_field ei_mal_dlr_active_gateway_address
;
443 static expert_field ei_mal_eip_security_capability_flags
;
444 static expert_field ei_mal_eip_security_avail_cipher_suites
;
445 static expert_field ei_mal_eip_security_allow_cipher_suites
;
446 static expert_field ei_mal_eip_security_preshared_keys
;
447 static expert_field ei_mal_eip_security_active_certs
;
448 static expert_field ei_mal_eip_security_trusted_auths
;
449 static expert_field ei_mal_eip_security_trusted_identities
;
450 static expert_field ei_mal_eip_security_crl
;
451 static expert_field ei_mal_eip_cert_capability_flags
;
452 static expert_field ei_mal_cpf_item_length_mismatch
;
453 static expert_field ei_mal_cpf_item_minimum_size
;
455 static expert_field ei_cip_request_no_response
;
456 static expert_field ei_cip_io_heartbeat
;
459 static dissector_table_t subdissector_srrd_table
;
460 static dissector_table_t subdissector_io_table
;
461 static dissector_table_t subdissector_decode_as_io_table
;
462 static dissector_table_t subdissector_class_table
;
463 static dissector_table_t subdissector_cip_connection_table
;
465 static dissector_handle_t arp_handle
;
466 static dissector_handle_t cipsafety_handle
;
467 static dissector_handle_t cip_io_generic_handle
;
468 static dissector_handle_t cip_implicit_handle
;
469 static dissector_handle_t cip_handle
;
470 static dissector_handle_t enip_tcp_handle
;
471 static dissector_handle_t enip_udp_handle
;
472 static dissector_handle_t enip_cipio_handle
;
473 static dissector_handle_t cip_class1_handle
;
474 static dissector_handle_t dtls_handle
;
475 static dissector_handle_t dlr_handle
;
478 static bool enip_desegment
= true;
479 static bool enip_OTrun_idle
= true;
480 static bool enip_TOrun_idle
;
482 static int proto_dlr
;
484 static int hf_dlr_ringsubtype
;
485 static int hf_dlr_ringprotoversion
;
486 static int hf_dlr_frametype
;
487 static int hf_dlr_sourceport
;
488 static int hf_dlr_sourceip
;
489 static int hf_dlr_sequenceid
;
491 static int hf_dlr_ringstate
;
492 static int hf_dlr_supervisorprecedence
;
493 static int hf_dlr_beaconinterval
;
494 static int hf_dlr_beacontimeout
;
495 static int hf_dlr_beaconreserved
;
497 static int hf_dlr_nreqreserved
;
499 static int hf_dlr_nressourceport
;
500 static int hf_dlr_nresreserved
;
502 static int hf_dlr_lnknbrstatus
;
503 static int hf_dlr_lnknbrstatus_port1
;
504 static int hf_dlr_lnknbrstatus_port2
;
505 static int hf_dlr_lnknbrstatus_reserved
;
506 static int hf_dlr_lnknbrstatus_frame_type
;
507 static int hf_dlr_lnknbrreserved
;
509 static int hf_dlr_lfreserved
;
511 static int hf_dlr_anreserved
;
513 static int hf_dlr_sonumnodes
;
514 static int hf_dlr_somac
;
515 static int hf_dlr_soip
;
516 static int hf_dlr_soreserved
;
518 static int hf_dlr_advgatewaystate
;
519 static int hf_dlr_advgatewayprecedence
;
520 static int hf_dlr_advadvertiseinterval
;
521 static int hf_dlr_advadvertisetimeout
;
522 static int hf_dlr_advlearningupdateenable
;
523 static int hf_dlr_advreserved
;
525 static int hf_dlr_flushlearningupdateenable
;
526 static int hf_dlr_flushreserved
;
528 static int hf_dlr_learnreserved
;
532 /* Translate function to string - Encapsulation commands */
533 static const value_string encap_cmd_vals
[] = {
535 { LIST_SERVICES
, "List Services" },
536 { LIST_IDENTITY
, "List Identity" },
537 { LIST_INTERFACES
, "List Interfaces" },
538 { REGISTER_SESSION
, "Register Session" },
539 { UNREGISTER_SESSION
,"Unregister Session" },
540 { SEND_RR_DATA
, "Send RR Data" },
541 { SEND_UNIT_DATA
, "Send Unit Data" },
542 { START_DTLS
, "StartDTLS" },
547 /* Translate function to string - Encapsulation status */
548 static const value_string encap_status_vals
[] = {
549 { SUCCESS
, "Success" },
550 { INVALID_CMD
, "Invalid Command" },
551 { NO_RESOURCES
, "No Memory Resources" },
552 { INCORRECT_DATA
, "Incorrect Data" },
553 { INVALID_SESSION
, "Invalid Session Handle" },
554 { INVALID_LENGTH
, "Invalid Length" },
555 { UNSUPPORTED_PROT_REV
, "Unsupported Protocol Revision" },
556 { ENCAP_HEADER_ERROR
, "Encapsulated CIP service not allowed on this port" },
561 /* Translate function to Common packet format values */
562 static const value_string cpf_type_vals
[] = {
563 { CPF_ITEM_NULL
, "Null Address Item" },
564 { CPF_ITEM_CIP_IDENTITY
, "CIP Identity" },
565 { CPF_ITEM_CIP_SECURITY
, "CIP Security Information" },
566 { CPF_ITEM_ENIP_CAPABILITY
, "EtherNet/IP Capability" },
567 { CPF_ITEM_ENIP_USAGE
, "EtherNet/IP Usage" },
568 { CPF_ITEM_CONNECTED_ADDRESS
, "Connected Address Item" },
569 { CPF_ITEM_CONNECTED_DATA
, "Connected Data Item" },
570 { CPF_ITEM_UNCONNECTED_DATA
, "Unconnected Data Item" },
571 { CPF_ITEM_LIST_SERVICES_RESP
, "List Services Response" },
572 { CPF_ITEM_SOCK_ADR_INFO_OT
, "Socket Address Info O->T" },
573 { CPF_ITEM_SOCK_ADR_INFO_TO
, "Socket Address Info T->O" },
574 { CPF_ITEM_SEQUENCED_ADDRESS
, "Sequenced Address Item" },
575 { CPF_ITEM_UNCONNECTED_MSG_DTLS
, "Unconnected Message over UDP" },
580 static const value_string unconn_msg_type_vals
[] = {
587 static const value_string enip_tcpip_status_interface_config_vals
[] = {
588 { 0, "Not configured" },
589 { 1, "BOOTP/DHCP/NVS" },
590 { 2, "Hardware settings" },
595 static const value_string enip_tcpip_status_acd_vals
[] = {
596 { 0, "No Address Conflict Detected" },
597 { 1, "Address Conflict Detected" },
602 static const value_string enip_tcpip_config_control_config_vals
[] = {
610 static const value_string enip_tcpip_mcast_alloc_vals
[] = {
611 { 0, "Use default multicast algorithm" },
612 { 1, "Use Num Mcast and Mcast Start Addr" },
617 static const value_string enip_tcpip_acd_activity_vals
[] = {
618 { 0, "No Conflict Detected" },
619 { 1, "Probe IPv4 Address" },
620 { 2, "Ongoing Detection" },
621 { 3, "Semi Active Probe" },
626 static const value_string enip_elink_duplex_vals
[] = {
627 { 0, "Half Duplex" },
628 { 1, "Full Duplex" },
633 static const value_string enip_elink_iflags_neg_status_vals
[] = {
634 { 0, "Auto-negotiation in progress" },
635 { 1, "Auto-negotiation and speed detection failed" },
636 { 2, "Auto-negotiation failed but detected speed" },
637 { 3, "Successfully negotiated speed and duplex" },
638 { 4, "Auto-negotiation not attempted. Forced speed and duplex" },
643 static const value_string enip_elink_iflags_reset_vals
[] = {
644 { 0, "Activate change automatically" },
645 { 1, "Device requires Reset service for change" },
650 static const value_string enip_elink_iflags_hw_fault_vals
[] = {
651 { 0, "No local hardware fault" },
652 { 1, "Local hardware fault detected" },
657 static const value_string enip_elink_interface_type_vals
[] = {
658 { 0, "Unknown type" },
660 { 2, "Twisted-pair" },
661 { 3, "Optical fiber" },
666 static const value_string enip_elink_interface_state_vals
[] = {
667 { 0, "Unknown state" },
675 static const value_string enip_elink_admin_state_vals
[] = {
682 static const value_string enip_dlr_network_topology_vals
[] = {
689 static const value_string enip_dlr_network_status_vals
[] = {
692 { 2, "Unexpected Loop Detected" },
693 { 3, "Partial Network Failure" },
694 { 4, "Rapid Fault/Restore Cycle" },
699 static const value_string enip_dlr_ring_supervisor_status_vals
[] = {
700 { 0, "Backup Ring Supervisor" },
701 { 1, "Active Ring Supervisor" },
703 { 3, "Non-DLR Topology" },
704 { 4, "Cannot Support Parameters" },
709 static const value_string enip_dlr_redundant_gateway_status_vals
[] = {
710 { 0, "Non-Gateway DLR node" },
711 { 1, "Backup Gateway" },
712 { 2, "Active Gateway" },
713 { 3, "Gateway Fault" },
714 { 4, "Cannot Support Parameters" },
715 { 5, "Partial Network Fault" },
720 static const value_string cip_security_state_vals
[] = {
721 { 0, "Factory Default Configuration" },
722 { 1, "Configuration In Progress" },
724 { 3, "Incomplete Configuration" },
729 static const value_string eip_security_state_vals
[] = {
730 { 0, "Factory Default Configuration" },
731 { 1, "Configuration In Progress" },
733 { 3, "Pull Model In Progress" },
734 { 4, "Pull Model Completed" },
735 { 5, "Pull Model Disabled" },
740 static const value_string eip_security_psk_usage_vals
[] = {
748 static const value_string eip_cert_state_vals
[] = {
749 { 0, "Non-Existent" },
751 { 2, "Configuring" },
758 static const value_string eip_cert_status_vals
[] = {
759 { 0, "Not Verified" },
766 /* Translate interface handle to string */
767 static const value_string enip_interface_handle_vals
[] = {
773 /* Translate function to DLR Frame Type values */
774 static const value_string dlr_frame_type_vals
[] = {
775 { DLR_FT_BEACON
, "Beacon" },
776 { DLR_FT_NEIGHBOR_REQ
, "Neighbor_Check_Request" },
777 { DLR_FT_NEIGHBOR_RES
, "Neighbor_Check_Response" },
778 { DLR_FT_LINK_STAT
, "Link_Status / Neighbor_Status" },
779 { DLR_FT_LOCATE_FLT
, "Locate_Fault" },
780 { DLR_FT_ANNOUNCE
, "Announce" },
781 { DLR_FT_SIGN_ON
, "Sign_On" },
782 { DLR_FT_ADVERTISE
, "Advertise" },
783 { DLR_FT_FLUSH_TABLES
, "Flush_Tables" },
784 { DLR_FT_LEARNING_UPDATE
, "Learning_Update" },
789 /* Translate function to DLR Source Port values */
790 static const value_string dlr_source_port_vals
[] = {
791 { 0, "Port 1 or Port 2" },
798 /* Translate function to DLR Ring State values */
799 static const value_string dlr_ring_state_vals
[] = {
800 { 1, "RING_NORMAL_STATE" },
801 { 2, "RING_FAULT_STATE" },
806 /* Translate function to DLR Advertise State values */
807 static const value_string dlr_adv_state_vals
[] = {
808 { 0x01, "ACTIVE_LISTEN_STATE" },
809 { 0x02, "ACTIVE_NORMAL_STATE" },
810 { 0x03, "FAULT_STATE" },
815 /* Translate function to DLR Learning Update values */
816 static const value_string dlr_adv_learning_update_vals
[] = {
823 /* Translate function to DLR Flush Learning Update values */
824 static const value_string dlr_flush_learning_update_vals
[] = {
831 static const true_false_string dlr_lnknbrstatus_frame_type_vals
= {
832 "Neighbor_Status Frame",
836 static void enip_prompt(packet_info
*pinfo _U_
, char* result
)
838 snprintf(result
, MAX_DECODE_AS_PROMPT_LEN
, "Dissect unidentified I/O traffic as");
841 static wmem_map_t
*enip_request_hashtable
;
843 /* Return codes of function classifying packets as query/response */
844 enum enip_packet_type
{ENIP_REQUEST_PACKET
, ENIP_RESPONSE_PACKET
, ENIP_CANNOT_CLASSIFY
};
845 enum enip_packet_data_type
{ EPDT_UNKNOWN
, EPDT_CONNECTED_TRANSPORT
, EPDT_UNCONNECTED
};
847 typedef struct enip_request_key
{
848 uint32_t session_handle
;
849 enum enip_packet_type requesttype
;
850 enum enip_packet_data_type type
;
851 uint64_t sender_context
;
852 uint32_t conversation
;
857 } connected_transport
;
859 } enip_request_key_t
;
861 typedef struct enip_request_val
{
863 } enip_request_val_t
;
869 enip_request_equal(const void *v
, const void *w
)
871 const enip_request_key_t
*v1
= (const enip_request_key_t
*)v
;
872 const enip_request_key_t
*v2
= (const enip_request_key_t
*)w
;
874 if ( v1
->conversation
== v2
->conversation
875 && v1
->session_handle
== v2
->session_handle
876 && v1
->type
== v2
->type
877 && ( ( v1
->sender_context
== v2
->sender_context
/* heuristic approach */
878 && v1
->type
== EPDT_UNCONNECTED
881 ( v1
->data
.connected_transport
.connid
== v2
->data
.connected_transport
.connid
882 && v1
->data
.connected_transport
.sequence
== v2
->data
.connected_transport
.sequence
883 && v1
->type
== EPDT_CONNECTED_TRANSPORT
893 enip_fmt_lir_revision( char *result
, uint32_t revision
)
895 snprintf( result
, ITEM_LABEL_LENGTH
, "%d.%02d", (uint8_t)(( revision
& 0xFF00 ) >> 8), (uint8_t)(revision
& 0xFF) );
899 enip_request_hash (const void *v
)
901 const enip_request_key_t
*key
= (const enip_request_key_t
*)v
;
904 val
= (unsigned)(key
->conversation
* 37 + key
->session_handle
* 93 + key
->type
* 765);
906 if (key
->type
== EPDT_UNCONNECTED
)
908 val
+= ((unsigned)(key
->sender_context
* 23));
910 else if (key
->type
== EPDT_CONNECTED_TRANSPORT
)
912 val
+= ((unsigned)(key
->data
.connected_transport
.connid
* 87 + key
->data
.connected_transport
.sequence
* 834));
918 static enip_request_info_t
*
919 enip_match_request( packet_info
*pinfo
, proto_tree
*tree
, enip_request_key_t
*prequest_key
)
921 enip_request_key_t
*new_request_key
;
922 enip_request_val_t
*request_val
;
923 enip_request_info_t
*request_info
;
926 request_val
= (enip_request_val_t
*)wmem_map_lookup( enip_request_hashtable
, prequest_key
);
927 if (!pinfo
->fd
->visited
)
929 if ( prequest_key
&& prequest_key
->requesttype
== ENIP_REQUEST_PACKET
)
931 if ( request_val
== NULL
)
933 new_request_key
= (enip_request_key_t
*)wmem_memdup(wmem_file_scope(), prequest_key
, sizeof(enip_request_key_t
));
935 request_val
= wmem_new(wmem_file_scope(), enip_request_val_t
);
936 request_val
->frames
= wmem_tree_new(wmem_file_scope());
938 wmem_map_insert(enip_request_hashtable
, new_request_key
, request_val
);
941 request_info
= wmem_new(wmem_file_scope(), enip_request_info_t
);
942 request_info
->req_num
= pinfo
->num
;
943 request_info
->rep_num
= 0;
944 request_info
->req_time
= pinfo
->abs_ts
;
945 request_info
->cip_info
= NULL
;
946 wmem_tree_insert32(request_val
->frames
, pinfo
->num
, (void *)request_info
);
948 if ( request_val
&& prequest_key
&& prequest_key
->requesttype
== ENIP_RESPONSE_PACKET
)
950 request_info
= (enip_request_info_t
*)wmem_tree_lookup32_le( request_val
->frames
, pinfo
->num
);
953 request_info
->rep_num
= pinfo
->num
;
960 request_info
= (enip_request_info_t
*)wmem_tree_lookup32_le( request_val
->frames
, pinfo
->num
);
963 if ( tree
&& request_info
)
965 /* print state tracking in the tree */
966 if ( prequest_key
&& prequest_key
->requesttype
== ENIP_REQUEST_PACKET
)
968 /* This is a request */
969 if (request_info
->rep_num
)
973 it
= proto_tree_add_uint(tree
, hf_enip_response_in
,
974 NULL
, 0, 0, request_info
->rep_num
);
975 proto_item_set_generated(it
);
979 expert_add_info(pinfo
, tree
, &ei_cip_request_no_response
);
984 if ( prequest_key
&& prequest_key
->requesttype
== ENIP_RESPONSE_PACKET
)
986 /* This is a reply */
987 if (request_info
->req_num
)
992 it
= proto_tree_add_uint(tree
, hf_enip_response_to
,
993 NULL
, 0, 0, request_info
->req_num
);
994 proto_item_set_generated(it
);
996 nstime_delta(&ns
, &pinfo
->abs_ts
, &request_info
->req_time
);
997 it
= proto_tree_add_time(tree
, hf_enip_time
, NULL
, 0, 0, &ns
);
998 proto_item_set_generated(it
);
1003 return request_info
;
1006 typedef struct enip_conn_key
{
1007 cip_connection_triad_t triad
;
1012 // This is a per list of CIP connection IDs per conversation_t.
1013 typedef struct _enip_conv_info_t
{
1014 // Connection ID --> cip_conn_info_t
1015 wmem_tree_t
*O2TConnIDs
;
1016 // Connection ID --> cip_conn_info_t
1017 wmem_tree_t
*T2OConnIDs
;
1021 * Conversation filter
1024 enip_io_conv_valid(packet_info
*pinfo
, void *user_data _U_
)
1026 cip_conn_info_t
* conn
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
1031 return (((conn
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
) == 0) ||
1032 ((conn
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
) == 1));
1036 enip_io_conv_filter(packet_info
*pinfo
, void *user_data _U_
)
1039 cip_conn_info_t
* conn
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
1044 if (conn
->close_frame
> 0)
1046 buf
= ws_strdup_printf(
1047 "((frame.number == %u) || ((frame.number >= %u) && (frame.number <= %u))) && " /* Frames between ForwardOpen and ForwardClose reply */
1048 "((enip.cpf.sai.connid == 0x%08x || enip.cpf.sai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
1049 "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
1050 conn
->open_req_frame
, conn
->open_reply_frame
, conn
->close_frame
,
1051 conn
->O2T
.connID
, conn
->T2O
.connID
,
1052 conn
->triad
.ConnSerialNumber
, conn
->triad
.VendorID
, conn
->triad
.DeviceSerialNumber
);
1056 /* If Forward Close isn't found, don't limit the (end) frame range */
1057 buf
= ws_strdup_printf(
1058 "((frame.number == %u) || (frame.number >= %u)) && " /* Frames starting with ForwardOpen */
1059 "((enip.cpf.sai.connid == 0x%08x || enip.cpf.sai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
1060 "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
1061 conn
->open_req_frame
, conn
->open_reply_frame
,
1062 conn
->O2T
.connID
, conn
->T2O
.connID
,
1063 conn
->triad
.ConnSerialNumber
, conn
->triad
.VendorID
, conn
->triad
.DeviceSerialNumber
);
1070 enip_exp_conv_valid(packet_info
*pinfo
, void *user_data _U_
)
1072 cip_conn_info_t
* conn
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
1077 return (((conn
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
) == 2) ||
1078 ((conn
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
) == 3));
1082 enip_exp_conv_filter(packet_info
*pinfo
, void *user_data _U_
)
1085 cip_conn_info_t
* conn
= (cip_conn_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
);
1090 if (conn
->close_frame
> 0)
1092 buf
= ws_strdup_printf(
1093 "((frame.number == %u) || ((frame.number >= %u) && (frame.number <= %u))) && " /* Frames between ForwardOpen and ForwardClose reply */
1094 "((enip.cpf.cai.connid == 0x%08x || enip.cpf.cai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
1095 "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
1096 conn
->open_req_frame
, conn
->open_reply_frame
, conn
->close_frame
,
1097 conn
->O2T
.connID
, conn
->T2O
.connID
,
1098 conn
->triad
.ConnSerialNumber
, conn
->triad
.VendorID
, conn
->triad
.DeviceSerialNumber
);
1102 /* If Forward Close isn't found, don't limit the (end) frame range */
1103 buf
= ws_strdup_printf(
1104 "((frame.number == %u) || (frame.number >= %u)) && " /* Frames between ForwardOpen and ForwardClose */
1105 "((enip.cpf.cai.connid == 0x%08x || enip.cpf.cai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
1106 "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))", /* Connection Triad */
1107 conn
->open_req_frame
, conn
->open_reply_frame
,
1108 conn
->O2T
.connID
, conn
->T2O
.connID
,
1109 conn
->triad
.ConnSerialNumber
, conn
->triad
.VendorID
, conn
->triad
.DeviceSerialNumber
);
1114 static bool cip_connection_conv_valid(packet_info
*pinfo
, void *user_data
)
1116 return enip_io_conv_valid(pinfo
, user_data
) || enip_exp_conv_valid(pinfo
, user_data
);
1119 static char* cip_connection_conv_filter(packet_info
*pinfo
, void *user_data
)
1123 if (enip_io_conv_valid(pinfo
, user_data
))
1125 buf
= enip_io_conv_filter(pinfo
, user_data
);
1127 else if (enip_exp_conv_valid(pinfo
, user_data
))
1129 buf
= enip_exp_conv_filter(pinfo
, user_data
);
1136 * Connection management
1139 // Key: (triad, connection IDs), Value: cip_conn_info_t
1140 static wmem_map_t
*enip_conn_hashtable
;
1141 static uint32_t enip_unique_connid
;
1144 enip_conn_equal(const void *v
, const void *w
)
1146 const enip_conn_key_t
*v1
= (const enip_conn_key_t
*)v
;
1147 const enip_conn_key_t
*v2
= (const enip_conn_key_t
*)w
;
1149 if (cip_connection_triad_match(&v1
->triad
, &v2
->triad
) &&
1150 ((v1
->O2TConnID
== 0) || (v2
->O2TConnID
== 0) || (v1
->O2TConnID
== v2
->O2TConnID
)) &&
1151 ((v1
->T2OConnID
== 0) || (v2
->T2OConnID
== 0) || (v1
->T2OConnID
== v2
->T2OConnID
)))
1158 enip_conn_hash (const void *v
)
1160 const enip_conn_key_t
*key
= (const enip_conn_key_t
*)v
;
1163 val
= (unsigned)( key
->triad
.ConnSerialNumber
+ key
->triad
.VendorID
+ key
->triad
.DeviceSerialNumber
);
1168 // Create a list of connection IDs and attach it to the conversation.
1169 static enip_conv_info_t
* create_connection_id_list(conversation_t
* conversation
)
1171 enip_conv_info_t
* enip_info
= wmem_new(wmem_file_scope(), enip_conv_info_t
);
1172 enip_info
->O2TConnIDs
= wmem_tree_new(wmem_file_scope());
1173 enip_info
->T2OConnIDs
= wmem_tree_new(wmem_file_scope());
1175 conversation_add_proto_data(conversation
, proto_enip
, enip_info
);
1181 enip_conv_info_t
* get_conversation_info_one_direction(packet_info
* pinfo
, address
* src_address
, address
* dst_address
, cip_connID_info_t
* connid_info
)
1183 /* default some information if not included */
1184 if ((connid_info
->port
== 0) || (connid_info
->type
== CONN_TYPE_MULTICAST
))
1186 connid_info
->port
= ENIP_IO_PORT
;
1189 ws_in6_addr ipv6_zero
= {0};
1190 if ((connid_info
->ipaddress
.type
== AT_NONE
) ||
1191 ((connid_info
->ipaddress
.type
== AT_IPv4
) && ((*(const uint32_t*)connid_info
->ipaddress
.data
)) == 0) ||
1192 ((connid_info
->ipaddress
.type
== AT_IPv6
) && (memcmp(connid_info
->ipaddress
.data
, &ipv6_zero
, sizeof(ipv6_zero
)) == 0)) ||
1193 (connid_info
->type
!= CONN_TYPE_MULTICAST
))
1195 copy_address_wmem(wmem_file_scope(), &connid_info
->ipaddress
, dst_address
);
1198 address dest_address
= ADDRESS_INIT_NONE
;
1199 if (connid_info
->ipaddress
.type
== AT_IPv6
)
1201 dest_address
.type
= AT_IPv6
;
1202 dest_address
.len
= 16;
1206 dest_address
.type
= AT_IPv4
;
1207 dest_address
.len
= 4;
1209 dest_address
.data
= connid_info
->ipaddress
.data
;
1211 // Similar logic to find_or_create_conversation(), but since I/O traffic
1212 // is on UDP, the pinfo parameter doesn't have the correct information.
1213 conversation_t
* conversation
= find_conversation(pinfo
->num
, src_address
, &dest_address
,
1214 CONVERSATION_UDP
, connid_info
->port
, 0, NO_PORT_B
);
1215 if (conversation
== NULL
)
1217 conversation
= conversation_new(pinfo
->num
, src_address
, &dest_address
,
1218 CONVERSATION_UDP
, connid_info
->port
, 0, NO_PORT2
);
1221 enip_conv_info_t
* enip_info
= (enip_conv_info_t
*)conversation_get_proto_data(conversation
, proto_enip
);
1222 if (enip_info
== NULL
)
1224 enip_info
= create_connection_id_list(conversation
);
1230 // connInfo - Connection Information that is known so far (from the Forward Open Request).
1231 static void enip_open_cip_connection( packet_info
*pinfo
, cip_conn_info_t
* connInfo
, uint8_t service
)
1233 if (pinfo
->fd
->visited
)
1236 // Don't create connections for Null Forward Opens.
1237 if (connInfo
->IsNullFwdOpen
)
1242 enip_conn_key_t
* conn_key
= wmem_new(wmem_file_scope(), enip_conn_key_t
);
1243 conn_key
->triad
= connInfo
->triad
;
1244 conn_key
->O2TConnID
= connInfo
->O2T
.connID
;
1245 conn_key
->T2OConnID
= connInfo
->T2O
.connID
;
1247 cip_conn_info_t
* conn_val
= (cip_conn_info_t
*)wmem_map_lookup( enip_conn_hashtable
, conn_key
);
1248 if ( conn_val
== NULL
)
1250 conn_val
= wmem_new0(wmem_file_scope(), cip_conn_info_t
);
1252 // Copy initial connection data from the Forward Open Request.
1253 *conn_val
= *connInfo
;
1255 // These values are not copies from the Forward Open Request. Initialize these separately.
1256 conn_val
->open_reply_frame
= pinfo
->num
;
1257 conn_val
->connid
= enip_unique_connid
++;
1258 conn_val
->is_concurrent_connection
= (service
== SC_CM_CONCURRENT_FWD_OPEN
);
1260 wmem_map_insert(enip_conn_hashtable
, conn_key
, conn_val
);
1262 /* I/O connection */
1263 if (((connInfo
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
) == 0) ||
1264 ((connInfo
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
) == 1))
1266 /* check for O->T conversation */
1267 enip_conv_info_t
* enip_info
= get_conversation_info_one_direction(pinfo
, &pinfo
->dst
, &pinfo
->src
, &(connInfo
->O2T
));
1268 wmem_tree_insert32(enip_info
->O2TConnIDs
, connInfo
->O2T
.connID
, (void*)conn_val
);
1270 /* Check if separate T->O conversation is necessary. If either side is multicast
1271 or ports aren't equal, a separate conversation must be generated */
1272 enip_info
= get_conversation_info_one_direction(pinfo
, &pinfo
->src
, &pinfo
->dst
, &(connInfo
->T2O
));
1273 wmem_tree_insert32(enip_info
->T2OConnIDs
, connInfo
->T2O
.connID
, (void *)conn_val
);
1277 /* explicit message connection */
1278 conversation_t
* conversation
= find_or_create_conversation(pinfo
);
1280 enip_conv_info_t
* enip_info
= (enip_conv_info_t
*)conversation_get_proto_data(conversation
, proto_enip
);
1283 enip_info
= create_connection_id_list(conversation
);
1285 wmem_tree_insert32(enip_info
->O2TConnIDs
, connInfo
->O2T
.connID
, (void *)conn_val
);
1286 wmem_tree_insert32(enip_info
->T2OConnIDs
, connInfo
->T2O
.connID
, (void *)conn_val
);
1290 /* Save the connection info for the conversation filter */
1291 p_add_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
, conn_val
);
1295 enip_close_cip_connection(packet_info
*pinfo
, const cip_connection_triad_t
* triad
)
1297 if (pinfo
->fd
->visited
)
1300 enip_conn_key_t conn_key
;
1301 conn_key
.triad
= *triad
;
1302 conn_key
.O2TConnID
= 0;
1303 conn_key
.T2OConnID
= 0;
1305 cip_conn_info_t
* conn_val
= (cip_conn_info_t
*)wmem_map_lookup( enip_conn_hashtable
, &conn_key
);
1311 // Only mark the first Forward Close Request for a given connection.
1312 if (conn_val
->close_frame
== 0)
1314 conn_val
->close_frame
= pinfo
->num
;
1317 /* Save the connection info for the conversation filter */
1318 p_add_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
, conn_val
);
1321 /* Save the connection info for the conversation filter */
1322 void enip_mark_connection_triad(packet_info
*pinfo
, const cip_connection_triad_t
* triad
)
1324 enip_conn_key_t conn_key
;
1325 conn_key
.triad
= *triad
;
1326 conn_key
.O2TConnID
= 0;
1327 conn_key
.T2OConnID
= 0;
1329 cip_conn_info_t
* conn_val
= (cip_conn_info_t
*)wmem_map_lookup( enip_conn_hashtable
, &conn_key
);
1332 p_add_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
, conn_val
);
1336 static cip_conn_info_t
*
1337 enip_get_explicit_connid(packet_info
*pinfo
, enip_request_key_t
*prequest_key
, uint32_t connid
)
1339 conversation_t
*conversation
;
1340 enip_conv_info_t
*enip_info
;
1341 enum enip_packet_type requesttype
= ENIP_REQUEST_PACKET
;
1343 if (prequest_key
!= NULL
)
1346 if ((prequest_key
->requesttype
!= ENIP_REQUEST_PACKET
) && (prequest_key
->requesttype
!= ENIP_RESPONSE_PACKET
))
1349 requesttype
= prequest_key
->requesttype
;
1353 * Do we have a conversation for this connection?
1355 conversation
= find_conversation_pinfo(pinfo
, 0);
1356 if (conversation
== NULL
)
1360 * Do we already have a state structure for this conv
1362 enip_info
= (enip_conv_info_t
*)conversation_get_proto_data(conversation
, proto_enip
);
1366 cip_conn_info_t
* conn_val
= NULL
;
1367 switch (requesttype
)
1369 case ENIP_REQUEST_PACKET
:
1370 conn_val
= (cip_conn_info_t
*)wmem_tree_lookup32( enip_info
->O2TConnIDs
, connid
);
1371 if ( conn_val
== NULL
)
1372 conn_val
= (cip_conn_info_t
*)wmem_tree_lookup32( enip_info
->T2OConnIDs
, connid
);
1375 case ENIP_RESPONSE_PACKET
:
1376 conn_val
= (cip_conn_info_t
*)wmem_tree_lookup32( enip_info
->T2OConnIDs
, connid
);
1377 if ( conn_val
== NULL
)
1378 conn_val
= (cip_conn_info_t
*)wmem_tree_lookup32( enip_info
->O2TConnIDs
, connid
);
1380 case ENIP_CANNOT_CLASSIFY
:
1385 if ((conn_val
== NULL
) || (conn_val
->open_reply_frame
> pinfo
->num
))
1391 static cip_conn_info_t
*
1392 enip_get_io_connid(packet_info
*pinfo
, uint32_t connid
, enum enip_connid_type
* pconnid_type
)
1394 conversation_t
*conversation
;
1395 enip_conv_info_t
*enip_info
;
1396 cip_conn_info_t
*conn_val
= NULL
;
1398 *pconnid_type
= ECIDT_UNKNOWN
;
1401 * Do we have a conversation for this connection?
1403 conversation
= find_conversation(pinfo
->num
,
1404 &pinfo
->src
, &pinfo
->dst
,
1405 conversation_pt_to_conversation_type(pinfo
->ptype
),
1406 pinfo
->destport
, 0, NO_PORT_B
);
1408 if (conversation
== NULL
)
1412 * Do we already have a state structure for this conv
1414 if ((enip_info
= (enip_conv_info_t
*)conversation_get_proto_data(conversation
, proto_enip
)) == NULL
)
1417 if (enip_info
->O2TConnIDs
!= NULL
)
1419 conn_val
= (cip_conn_info_t
*)wmem_tree_lookup32(enip_info
->O2TConnIDs
, connid
);
1422 *pconnid_type
= ECIDT_O2T
;
1426 if ( conn_val
== NULL
)
1428 if (enip_info
->T2OConnIDs
!= NULL
)
1430 if ((conn_val
= (cip_conn_info_t
*)wmem_tree_lookup32( enip_info
->T2OConnIDs
, connid
)) != NULL
)
1431 *pconnid_type
= ECIDT_T2O
;
1435 if ((conn_val
== NULL
) || ( conn_val
->open_reply_frame
> pinfo
->num
))
1442 dissect_tcpip_status(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1443 int offset
, int total_len
)
1446 static int * const status
[] = {
1447 &hf_tcpip_status_interface_config
,
1448 &hf_tcpip_status_mcast_pending
,
1449 &hf_tcpip_status_interface_config_pending
,
1450 &hf_tcpip_status_acd
,
1451 &hf_tcpip_acd_fault
,
1452 &hf_tcpip_status_iana_port_admin_change
,
1453 &hf_tcpip_status_iana_protocol_admin_change
,
1454 &hf_tcpip_status_reserved
,
1460 expert_add_info(pinfo
, item
, &ei_mal_tcpip_status
);
1464 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_tcpip_status
, ett_tcpip_status
, status
, ENC_LITTLE_ENDIAN
);
1469 dissect_tcpip_config_cap(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1470 int offset
, int total_len
)
1473 static int * const capabilities
[] = {
1474 &hf_tcpip_config_cap_bootp
,
1475 &hf_tcpip_config_cap_dns
,
1476 &hf_tcpip_config_cap_dhcp
,
1477 &hf_tcpip_config_cap_dhcp_dns_update
,
1478 &hf_tcpip_config_cap_config_settable
,
1479 &hf_tcpip_config_cap_hardware_config
,
1480 &hf_tcpip_config_cap_interface_reset
,
1481 &hf_tcpip_config_cap_acd
,
1482 &hf_tcpip_config_cap_reserved
,
1488 expert_add_info(pinfo
, item
, &ei_mal_tcpip_config_cap
);
1492 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_tcpip_config_cap
, ett_tcpip_config_cap
, capabilities
, ENC_LITTLE_ENDIAN
);
1497 dissect_tcpip_config_control(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1498 int offset
, int total_len
)
1501 static int * const control_bits
[] = {
1502 &hf_tcpip_config_control_config
,
1503 &hf_tcpip_config_control_dns
,
1504 &hf_tcpip_config_control_reserved
,
1510 expert_add_info(pinfo
, item
, &ei_mal_tcpip_config_control
);
1514 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_tcpip_config_control
, ett_tcpip_config_control
, control_bits
, ENC_LITTLE_ENDIAN
);
1519 dissect_tcpip_physical_link(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1520 int offset
, int total_len
)
1523 return dissect_padded_epath_len_uint(pinfo
, tree
, item
, tvb
, offset
, total_len
);
1527 dissect_tcpip_interface_config(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1528 int offset
, int total_len
)
1531 uint16_t domain_length
;
1535 expert_add_info(pinfo
, item
, &ei_mal_tcpip_interface_config
);
1539 proto_tree_add_item(tree
, hf_tcpip_ic_ip_addr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1540 proto_tree_add_item(tree
, hf_tcpip_ic_subnet_mask
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1541 proto_tree_add_item(tree
, hf_tcpip_ic_gateway
, tvb
, offset
+8, 4, ENC_LITTLE_ENDIAN
);
1542 proto_tree_add_item(tree
, hf_tcpip_ic_name_server
, tvb
, offset
+12, 4, ENC_LITTLE_ENDIAN
);
1543 proto_tree_add_item(tree
, hf_tcpip_ic_name_server2
, tvb
, offset
+16, 4, ENC_LITTLE_ENDIAN
);
1545 domain_length
= tvb_get_letohs( tvb
, offset
+20);
1546 proto_tree_add_item(tree
, hf_tcpip_ic_domain_name
, tvb
, offset
+22, domain_length
, ENC_ASCII
);
1549 domain_length
+= domain_length
% 2;
1551 return (22+domain_length
);
1554 static int dissect_tcpip_hostname(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1555 int offset
, int total_len _U_
)
1558 parsed_len
= dissect_cip_string_type(pinfo
, tree
, item
, tvb
, offset
, hf_tcpip_hostname
, CIP_STRING_TYPE
);
1561 parsed_len
+= parsed_len
% 2;
1566 static int dissect_tcpip_snn(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1567 int offset
, int total_len
)
1571 expert_add_info(pinfo
, item
, &ei_mal_tcpip_snn
);
1575 dissect_cipsafety_snn(tree
, tvb
, pinfo
, offset
, hf_tcpip_snn_timestamp
, hf_tcpip_snn_date
, hf_tcpip_snn_time
);
1580 dissect_tcpip_mcast_config(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1581 int offset
, int total_len
)
1586 expert_add_info(pinfo
, item
, &ei_mal_tcpip_mcast_config
);
1590 proto_tree_add_item(tree
, hf_tcpip_mcast_alloc
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1591 proto_tree_add_item(tree
, hf_tcpip_mcast_reserved
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1592 proto_tree_add_item(tree
, hf_tcpip_mcast_num_mcast
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
1593 proto_tree_add_item(tree
, hf_tcpip_mcast_addr_start
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1598 dissect_tcpip_last_conflict(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1599 int offset
, int total_len
)
1607 expert_add_info(pinfo
, item
, &ei_mal_tcpip_last_conflict
);
1611 proto_tree_add_item(tree
, hf_tcpip_lcd_acd_activity
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1612 proto_tree_add_item(tree
, hf_tcpip_lcd_remote_mac
, tvb
, offset
+1, 6, ENC_NA
);
1614 if ( tvb_get_uint8(tvb
, offset
) == 0 )
1615 proto_tree_add_item(tree
, hf_tcpip_lcd_arp_pdu
, tvb
, offset
+7, 28, ENC_NA
);
1618 /* Dissect ARP PDU, but don't have it change column info */
1619 save_info
= col_get_writable(pinfo
->cinfo
, -1);
1620 col_set_writable(pinfo
->cinfo
, -1, false);
1622 next_tvb
= tvb_new_subset_length(tvb
, offset
+7, 28);
1623 call_dissector(arp_handle
, next_tvb
, pinfo
, tree
);
1625 col_set_writable(pinfo
->cinfo
, -1, save_info
);
1632 dissect_elink_interface_flags(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1633 int offset
, int total_len
)
1636 static int * const flags
[] = {
1637 &hf_elink_iflags_link_status
,
1638 &hf_elink_iflags_duplex
,
1639 &hf_elink_iflags_neg_status
,
1640 &hf_elink_iflags_manual_reset
,
1641 &hf_elink_iflags_local_hw_fault
,
1642 &hf_elink_iflags_reserved
,
1648 expert_add_info(pinfo
, item
, &ei_mal_elink_interface_flags
);
1652 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_elink_interface_flags
, ett_elink_interface_flags
, flags
, ENC_LITTLE_ENDIAN
);
1657 dissect_elink_physical_address(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1658 int offset
, int total_len
)
1663 expert_add_info(pinfo
, item
, &ei_mal_elink_physical_address
);
1667 proto_tree_add_item(tree
, hf_elink_physical_address
, tvb
, offset
, 6, ENC_NA
);
1673 dissect_elink_interface_counters(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1674 int offset
, int total_len
)
1679 expert_add_info(pinfo
, item
, &ei_mal_elink_interface_counters
);
1683 proto_tree_add_item(tree
, hf_elink_icount_in_octets
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1684 proto_tree_add_item(tree
, hf_elink_icount_in_ucast
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1685 proto_tree_add_item(tree
, hf_elink_icount_in_nucast
, tvb
, offset
+8, 4, ENC_LITTLE_ENDIAN
);
1686 proto_tree_add_item(tree
, hf_elink_icount_in_discards
, tvb
, offset
+12, 4, ENC_LITTLE_ENDIAN
);
1687 proto_tree_add_item(tree
, hf_elink_icount_in_errors
, tvb
, offset
+16, 4, ENC_LITTLE_ENDIAN
);
1688 proto_tree_add_item(tree
, hf_elink_icount_in_unknown_protos
, tvb
, offset
+20, 4, ENC_LITTLE_ENDIAN
);
1689 proto_tree_add_item(tree
, hf_elink_icount_out_octets
, tvb
, offset
+24, 4, ENC_LITTLE_ENDIAN
);
1690 proto_tree_add_item(tree
, hf_elink_icount_out_ucast
, tvb
, offset
+28, 4, ENC_LITTLE_ENDIAN
);
1691 proto_tree_add_item(tree
, hf_elink_icount_out_nucast
, tvb
, offset
+32, 4, ENC_LITTLE_ENDIAN
);
1692 proto_tree_add_item(tree
, hf_elink_icount_out_discards
, tvb
, offset
+36, 4, ENC_LITTLE_ENDIAN
);
1693 proto_tree_add_item(tree
, hf_elink_icount_out_errors
, tvb
, offset
+40, 4, ENC_LITTLE_ENDIAN
);
1698 dissect_elink_media_counters(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1699 int offset
, int total_len
)
1704 expert_add_info(pinfo
, item
, &ei_mal_elink_media_counters
);
1708 proto_tree_add_item(tree
, hf_elink_mcount_alignment_errors
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1709 proto_tree_add_item(tree
, hf_elink_mcount_fcs_errors
, tvb
, offset
+4, 4, ENC_LITTLE_ENDIAN
);
1710 proto_tree_add_item(tree
, hf_elink_mcount_single_collisions
, tvb
, offset
+8, 4, ENC_LITTLE_ENDIAN
);
1711 proto_tree_add_item(tree
, hf_elink_mcount_multiple_collisions
, tvb
, offset
+12, 4, ENC_LITTLE_ENDIAN
);
1712 proto_tree_add_item(tree
, hf_elink_mcount_sqe_test_errors
, tvb
, offset
+16, 4, ENC_LITTLE_ENDIAN
);
1713 proto_tree_add_item(tree
, hf_elink_mcount_deferred_transmission
, tvb
, offset
+20, 4, ENC_LITTLE_ENDIAN
);
1714 proto_tree_add_item(tree
, hf_elink_mcount_late_collisions
, tvb
, offset
+24, 4, ENC_LITTLE_ENDIAN
);
1715 proto_tree_add_item(tree
, hf_elink_mcount_excessive_collisions
, tvb
, offset
+28, 4, ENC_LITTLE_ENDIAN
);
1716 proto_tree_add_item(tree
, hf_elink_mcount_mac_transmit_errors
, tvb
, offset
+32, 4, ENC_LITTLE_ENDIAN
);
1717 proto_tree_add_item(tree
, hf_elink_mcount_carrier_sense_errors
, tvb
, offset
+36, 4, ENC_LITTLE_ENDIAN
);
1718 proto_tree_add_item(tree
, hf_elink_mcount_frame_too_long
, tvb
, offset
+40, 4, ENC_LITTLE_ENDIAN
);
1719 proto_tree_add_item(tree
, hf_elink_mcount_mac_receive_errors
, tvb
, offset
+44, 4, ENC_LITTLE_ENDIAN
);
1724 dissect_elink_interface_capability(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
1725 int offset
, int total_len _U_
)
1727 static int * const bits
[] = {
1728 &hf_elink_icapability_capability_bits_manual
,
1729 &hf_elink_icapability_capability_bits_auto_neg
,
1730 &hf_elink_icapability_capability_bits_auto_mdix
,
1731 &hf_elink_icapability_capability_bits_manual_speed
,
1735 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_elink_icapability_capability_bits
, ett_elink_icapability_bits
, bits
, ENC_LITTLE_ENDIAN
);
1738 uint32_t array_count
;
1739 proto_tree_add_item_ret_uint(tree
, hf_elink_icapability_capability_speed_duplex_array_count
, tvb
, offset
, 1, ENC_NA
, &array_count
);
1742 for (uint32_t i
= 0; i
< array_count
; i
++)
1744 proto_tree_add_item(tree
, hf_elink_icapability_capability_speed
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1747 proto_tree_add_item(tree
, hf_elink_icapability_capability_duplex
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1751 return 4 + 1 + array_count
* 3;
1755 dissect_elink_hc_interface_counters(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
1756 int offset
, int total_len _U_
)
1758 proto_tree_add_item(tree
, hf_elink_hc_icount_in_octets
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1759 proto_tree_add_item(tree
, hf_elink_hc_icount_in_ucast
, tvb
, offset
+ 8, 8, ENC_LITTLE_ENDIAN
);
1760 proto_tree_add_item(tree
, hf_elink_hc_icount_in_mcast
, tvb
, offset
+ 16, 8, ENC_LITTLE_ENDIAN
);
1761 proto_tree_add_item(tree
, hf_elink_hc_icount_in_broadcast
, tvb
, offset
+ 24, 8, ENC_LITTLE_ENDIAN
);
1762 proto_tree_add_item(tree
, hf_elink_hc_icount_out_octets
, tvb
, offset
+ 32, 8, ENC_LITTLE_ENDIAN
);
1763 proto_tree_add_item(tree
, hf_elink_hc_icount_out_ucast
, tvb
, offset
+ 40, 8, ENC_LITTLE_ENDIAN
);
1764 proto_tree_add_item(tree
, hf_elink_hc_icount_out_mcast
, tvb
, offset
+ 48, 8, ENC_LITTLE_ENDIAN
);
1765 proto_tree_add_item(tree
, hf_elink_hc_icount_out_broadcast
, tvb
, offset
+ 56, 8, ENC_LITTLE_ENDIAN
);
1771 dissect_elink_hc_media_counters(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
1772 int offset
, int total_len _U_
)
1774 proto_tree_add_item(tree
, hf_elink_hc_mcount_stats_align_errors
, tvb
, offset
, 8, ENC_LITTLE_ENDIAN
);
1775 proto_tree_add_item(tree
, hf_elink_hc_mcount_stats_fcs_errors
, tvb
, offset
+ 8, 8, ENC_LITTLE_ENDIAN
);
1776 proto_tree_add_item(tree
, hf_elink_hc_mcount_stats_internal_mac_transmit_errors
, tvb
, offset
+ 16, 8, ENC_LITTLE_ENDIAN
);
1777 proto_tree_add_item(tree
, hf_elink_hc_mcount_stats_frame_too_long
, tvb
, offset
+ 24, 8, ENC_LITTLE_ENDIAN
);
1778 proto_tree_add_item(tree
, hf_elink_hc_mcount_stats_internal_mac_receive_errors
, tvb
, offset
+ 32, 8, ENC_LITTLE_ENDIAN
);
1779 proto_tree_add_item(tree
, hf_elink_hc_mcount_stats_symbol_errors
, tvb
, offset
+ 40, 8, ENC_LITTLE_ENDIAN
);
1785 dissect_elink_interface_control(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1786 int offset
, int total_len
)
1789 static int * const control_bits
[] = {
1790 &hf_elink_icontrol_control_bits_auto_neg
,
1791 &hf_elink_icontrol_control_bits_forced_duplex
,
1792 &hf_elink_icontrol_control_bits_reserved
,
1798 expert_add_info(pinfo
, item
, &ei_mal_elink_interface_control
);
1802 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_elink_icontrol_control_bits
, ett_elink_icontrol_bits
, control_bits
, ENC_LITTLE_ENDIAN
);
1803 proto_tree_add_item(tree
, hf_elink_icontrol_forced_speed
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
1808 dissect_dlr_ring_supervisor_config(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1809 int offset
, int total_len
)
1814 expert_add_info(pinfo
, item
, &ei_mal_dlr_ring_supervisor_config
);
1818 proto_tree_add_item(tree
, hf_dlr_rsc_ring_supervisor_enable
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1819 proto_tree_add_item(tree
, hf_dlr_rsc_ring_supervisor_precedence
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1820 proto_tree_add_item(tree
, hf_dlr_rsc_beacon_interval
, tvb
, offset
+2, 4, ENC_LITTLE_ENDIAN
);
1821 proto_tree_add_item(tree
, hf_dlr_rsc_beacon_timeout
, tvb
, offset
+6, 4, ENC_LITTLE_ENDIAN
);
1822 proto_tree_add_item(tree
, hf_dlr_rsc_dlr_vlan_id
, tvb
, offset
+10, 2, ENC_LITTLE_ENDIAN
);
1827 dissect_dlr_last_active_node_on_port_1(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1828 int offset
, int total_len
)
1833 expert_add_info(pinfo
, item
, &ei_mal_dlr_last_active_node_on_port_1
);
1837 proto_tree_add_item(tree
, hf_dlr_lanp1_dev_ip_addr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1838 proto_tree_add_item(tree
, hf_dlr_lanp1_dev_physical_address
, tvb
, offset
+4, 6, ENC_NA
);
1843 dissect_dlr_last_active_node_on_port_2(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1844 int offset
, int total_len
)
1849 expert_add_info(pinfo
, item
, &ei_mal_dlr_last_active_node_on_port_2
);
1853 proto_tree_add_item(tree
, hf_dlr_lanp2_dev_ip_addr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1854 proto_tree_add_item(tree
, hf_dlr_lanp2_dev_physical_address
, tvb
, offset
+4, 6, ENC_NA
);
1859 dissect_dlr_ring_protocol_participants_list(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1860 int offset
, int total_len
)
1867 expert_add_info(pinfo
, item
, &ei_mal_dlr_ring_protocol_participants_list
);
1872 while ( pos
< total_len
)
1874 proto_tree_add_item(tree
, hf_dlr_rppl_dev_ip_addr
, tvb
, offset
+pos
, 4, ENC_LITTLE_ENDIAN
);
1875 proto_tree_add_item(tree
, hf_dlr_rppl_dev_physical_address
, tvb
, offset
+pos
+4, 6, ENC_NA
);
1882 dissect_dlr_active_supervisor_address(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1883 int offset
, int total_len
)
1888 expert_add_info(pinfo
, item
, &ei_mal_dlr_active_supervisor_address
);
1892 proto_tree_add_item(tree
, hf_dlr_asa_supervisor_ip_addr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1893 proto_tree_add_item(tree
, hf_dlr_asa_supervisor_physical_address
, tvb
, offset
+4, 6, ENC_NA
);
1898 dissect_dlr_capability_flags(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1899 int offset
, int total_len
)
1902 static int * const capabilities
[] = {
1903 &hf_dlr_capflags_announce_base_node
,
1904 &hf_dlr_capflags_beacon_base_node
,
1905 &hf_dlr_capflags_reserved1
,
1906 &hf_dlr_capflags_supervisor_capable
,
1907 &hf_dlr_capflags_redundant_gateway_capable
,
1908 &hf_dlr_capflags_flush_frame_capable
,
1909 &hf_dlr_capflags_reserved2
,
1915 expert_add_info(pinfo
, item
, &ei_mal_dlr_capability_flags
);
1919 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_dlr_capability_flags
, ett_dlr_capability_flags
, capabilities
, ENC_LITTLE_ENDIAN
);
1924 dissect_dlr_redundant_gateway_config(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1925 int offset
, int total_len
)
1930 expert_add_info(pinfo
, item
, &ei_mal_dlr_redundant_gateway_config
);
1934 proto_tree_add_item(tree
, hf_dlr_rgc_red_gateway_enable
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
1935 proto_tree_add_item(tree
, hf_dlr_rgc_gateway_precedence
, tvb
, offset
+1, 1, ENC_LITTLE_ENDIAN
);
1936 proto_tree_add_item(tree
, hf_dlr_rgc_advertise_interval
, tvb
, offset
+2, 4, ENC_LITTLE_ENDIAN
);
1937 proto_tree_add_item(tree
, hf_dlr_rgc_advertise_timeout
, tvb
, offset
+6, 4, ENC_LITTLE_ENDIAN
);
1938 proto_tree_add_item(tree
, hf_dlr_rgc_learning_update_enable
, tvb
, offset
+10, 1, ENC_LITTLE_ENDIAN
);
1943 dissect_dlr_active_gateway_address(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1944 int offset
, int total_len
)
1949 expert_add_info(pinfo
, item
, &ei_mal_dlr_active_gateway_address
);
1953 proto_tree_add_item(tree
, hf_dlr_aga_ip_addr
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1954 proto_tree_add_item(tree
, hf_dlr_aga_physical_address
, tvb
, offset
+4, 6, ENC_NA
);
1958 static int dissect_cip_security_profiles(packet_info
* pinfo _U_
, proto_tree
* tree
, proto_item
* item _U_
, tvbuff_t
* tvb
,
1959 int offset
, int total_len _U_
)
1961 static int* const security_profiles
[] = {
1962 &hf_enip_security_profiles_eip_integrity
,
1963 &hf_enip_security_profiles_eip_confidentiality
,
1964 &hf_enip_security_profiles_cip_authorization
,
1965 &hf_enip_security_profiles_cip_user_authentication
,
1966 &hf_enip_security_profiles_resource_constrained
,
1967 &hf_enip_security_profiles_reserved
,
1971 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_enip_security_profiles
, ett_security_profiles
, security_profiles
, ENC_LITTLE_ENDIAN
);
1977 dissect_eip_security_cap(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1978 int offset
, int total_len
)
1981 static int * const capabilities
[] = {
1982 &hf_eip_security_capflags_secure_renegotiation
,
1983 &hf_eip_security_capflags_reserved
,
1989 expert_add_info(pinfo
, item
, &ei_mal_eip_security_capability_flags
);
1993 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_eip_security_capability_flags
, ett_eip_security_capability_flags
, capabilities
, ENC_LITTLE_ENDIAN
);
1998 dissect_eip_security_avail_cipher_suites(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
1999 int offset
, int total_len
)
2002 uint32_t i
, num_suites
;
2006 expert_add_info(pinfo
, item
, &ei_mal_eip_security_avail_cipher_suites
);
2010 proto_tree_add_item_ret_uint(tree
, hf_eip_security_num_avail_cipher_suites
, tvb
, offset
, 1, ENC_NA
, &num_suites
);
2013 for (i
= 0; i
< num_suites
; i
++)
2015 proto_tree_add_item(tree
, hf_eip_security_avail_cipher_suite
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2019 return ((num_suites
*2)+1);
2023 dissect_eip_security_allow_cipher_suites(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2024 int offset
, int total_len
)
2027 uint32_t i
, num_suites
;
2031 expert_add_info(pinfo
, item
, &ei_mal_eip_security_allow_cipher_suites
);
2035 proto_tree_add_item_ret_uint(tree
, hf_eip_security_num_allow_cipher_suites
, tvb
, offset
, 1, ENC_NA
, &num_suites
);
2038 for (i
= 0; i
< num_suites
; i
++)
2040 proto_tree_add_item(tree
, hf_eip_security_allow_cipher_suite
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2044 return ((num_suites
*2)+1);
2048 dissect_eip_security_preshared_keys(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2049 int offset
, int total_len
)
2052 uint32_t i
, num
, id_size
, psk_size
;
2054 proto_tree
* psk_tree
;
2055 int start_offset
= offset
;
2059 expert_add_info(pinfo
, item
, &ei_mal_eip_security_preshared_keys
);
2063 ti
= proto_tree_add_item_ret_uint(tree
, hf_eip_security_num_psk
, tvb
, offset
, 1, ENC_NA
, &num
);
2064 psk_tree
= proto_item_add_subtree(ti
, ett_eip_security_psk
);
2067 for (i
= 0; i
< num
; i
++)
2069 proto_tree_add_item_ret_uint(psk_tree
, hf_eip_security_psk_identity_size
, tvb
, offset
, 1, ENC_NA
, &id_size
);
2070 if (total_len
< (int)(id_size
+2))
2072 expert_add_info(pinfo
, item
, &ei_mal_eip_security_preshared_keys
);
2076 proto_tree_add_item(psk_tree
, hf_eip_security_psk_identity
, tvb
, offset
, id_size
, ENC_ASCII
);
2079 proto_tree_add_item_ret_uint(psk_tree
, hf_eip_security_psk_size
, tvb
, offset
, 1, ENC_NA
, &psk_size
);
2081 if (total_len
< (int)(id_size
+psk_size
+2))
2083 expert_add_info(pinfo
, item
, &ei_mal_eip_security_preshared_keys
);
2086 proto_tree_add_item(psk_tree
, hf_eip_security_psk
, tvb
, offset
, psk_size
, ENC_ASCII
);
2089 proto_tree_add_item(psk_tree
, hf_eip_security_psk_usage
, tvb
, offset
, 1, ENC_NA
);
2093 proto_item_set_len(ti
, offset
-start_offset
);
2094 return offset
-start_offset
;
2098 dissect_eip_security_cert_epath_list(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
, int total_len
,
2099 expert_field
*expert_info
, int hf_num_of_certs
, const int ett_index
)
2101 uint32_t i
, num
, path_size
;
2103 proto_tree
* cert_tree
;
2104 int start_offset
= offset
;
2108 expert_add_info(pinfo
, item
, expert_info
);
2112 ti
= proto_tree_add_item_ret_uint(tree
, hf_num_of_certs
, tvb
, offset
, 1, ENC_NA
, &num
);
2113 cert_tree
= proto_item_add_subtree(ti
, ett_index
);
2116 for (i
= 0; i
< num
; i
++)
2118 path_size
= dissect_padded_epath_len_usint(pinfo
, cert_tree
, ti
, tvb
, offset
, total_len
);
2119 offset
+= path_size
;
2121 proto_item_set_len(ti
, offset
-start_offset
);
2122 return offset
-start_offset
;
2126 dissect_eip_security_active_certs(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
, int total_len
)
2128 return dissect_eip_security_cert_epath_list(pinfo
, tree
, item
, tvb
, offset
, total_len
,
2129 &ei_mal_eip_security_active_certs
, hf_eip_security_num_active_certs
, ett_eip_security_active_certs
);
2133 dissect_eip_security_trusted_auths(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
, int total_len
)
2135 return dissect_eip_security_cert_epath_list(pinfo
, tree
, item
, tvb
, offset
, total_len
,
2136 &ei_mal_eip_security_trusted_auths
, hf_eip_security_num_trusted_auths
, ett_eip_security_trusted_auths
);
2140 dissect_eip_security_cert_revocation_list(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
, int total_len
)
2142 return dissect_eip_security_cert_epath_list(pinfo
, tree
, item
, tvb
, offset
, total_len
,
2143 &ei_mal_eip_security_crl
, hf_eip_security_num_crl
, ett_eip_security_crl
);
2147 dissect_eip_security_trusted_identities(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
, int total_len
)
2149 return dissect_eip_security_cert_epath_list(pinfo
, tree
, item
, tvb
, offset
, total_len
,
2150 &ei_mal_eip_security_trusted_identities
, hf_eip_security_num_trusted_identities
, ett_eip_security_trusted_identities
);
2154 dissect_eip_cert_cap_flags(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2155 int offset
, int total_len
)
2157 static int * const capabilities
[] = {
2158 &hf_eip_cert_capflags_push
,
2159 &hf_eip_cert_capflags_reserved
,
2165 expert_add_info(pinfo
, item
, &ei_mal_eip_cert_capability_flags
);
2169 proto_tree_add_bitmask(tree
, tvb
, offset
, hf_eip_cert_capability_flags
, ett_eip_cert_capability_flags
, capabilities
, ENC_LITTLE_ENDIAN
);
2174 dissect_eip_cert_cert_list(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
2175 int offset
, int total_len
)
2177 uint32_t i
, num
, path_size
;
2179 proto_tree
* cert_tree
;
2180 int start_offset
= offset
;
2182 ti
= proto_tree_add_item_ret_uint(tree
, hf_eip_cert_num_certs
, tvb
, offset
, 1, ENC_NA
, &num
);
2183 cert_tree
= proto_item_add_subtree(ti
, ett_eip_cert_num_certs
);
2186 for (i
= 0; i
< num
; i
++)
2188 path_size
= tvb_get_uint8( tvb
, offset
);
2189 proto_tree_add_item(tree
, hf_eip_cert_cert_name
, tvb
, offset
+1, path_size
, ENC_ASCII
);
2190 offset
+= (1+path_size
);
2192 path_size
= dissect_padded_epath_len_usint(pinfo
, cert_tree
, ti
, tvb
, offset
, total_len
);
2193 offset
+= path_size
;
2195 proto_item_set_len(ti
, offset
-start_offset
);
2196 return offset
-start_offset
;
2200 dissect_eip_cert_device_cert(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2201 int offset
, int total_len
)
2205 proto_tree_add_item(tree
, hf_eip_cert_device_cert_status
, tvb
, offset
, 1, ENC_NA
);
2208 path_size
= dissect_padded_epath_len_usint(pinfo
, tree
, item
, tvb
, offset
, total_len
);
2210 return path_size
+ 1;
2214 dissect_eip_cert_ca_cert(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2215 int offset
, int total_len
)
2219 proto_tree_add_item(tree
, hf_eip_cert_ca_cert_status
, tvb
, offset
, 1, ENC_NA
);
2222 path_size
= dissect_padded_epath_len_usint(pinfo
, tree
, item
, tvb
, offset
, total_len
);
2224 return path_size
+ 1;
2227 static int dissect_certificate_management_object_verify_certificate(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
, int offset
, bool request
)
2231 proto_tree_add_item(tree
, hf_eip_cert_verify_certificate
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2240 /// Ingress Egress - Attributes
2241 int dissect_ingress_tcp_udp_ports_supported(packet_info
*pinfo _U_
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
,
2242 int offset
, int total_len _U_
)
2244 uint32_t port_ranges_array_size
;
2245 proto_tree_add_item_ret_uint(tree
, hf_ingress_egress_num_ranges
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &port_ranges_array_size
);
2248 for (uint32_t i
= 0; i
< port_ranges_array_size
; i
++)
2250 proto_item
*port_range_item
;
2251 proto_tree
*port_range_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+ parsed_len
, 4, ett_cmd_data
, &port_range_item
, "Port Range: %d", i
+ 1);
2252 proto_tree_add_item(port_range_tree
, hf_ingress_egress_port_range_low
, tvb
, offset
+ parsed_len
, 2, ENC_LITTLE_ENDIAN
);
2254 proto_tree_add_item(port_range_tree
, hf_ingress_egress_port_range_high
, tvb
, offset
+ parsed_len
, 2, ENC_LITTLE_ENDIAN
);
2261 int dissect_ingress_egress_rules(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2262 int offset
, int total_len _U_
)
2264 uint32_t array_size
;
2265 proto_tree_add_item_ret_uint(tree
, hf_ingress_egress_num_rules
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &array_size
);
2268 proto_item
*rule_string_item
;
2269 proto_tree
*rules_string_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+ parsed_len
, 0, ett_cmd_data
, &rule_string_item
, "Rules: ");
2271 for (uint32_t i
= 0; i
< array_size
; i
++)
2273 parsed_len
+= dissect_cip_string_type(pinfo
, rules_string_tree
, item
, tvb
, offset
+ parsed_len
, hf_ingress_egress_rule_string
, CIP_SHORT_STRING_TYPE
);
2280 /// Ingress Egress - Services
2281 int dissect_ingress_egress_set_rules(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item _U_
, tvbuff_t
*tvb
, int offset
, bool request
)
2289 proto_tree_add_item(tree
, hf_ingress_egress_rules_change_count
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2291 static int* const apply_behavior
[] = {
2292 &hf_ingress_egress_apply_behav_break_connections
,
2293 &hf_ingress_egress_apply_behav_reserved
,
2297 proto_tree_add_bitmask(tree
, tvb
, offset
+ 4, hf_ingress_egress_apply_behavior
, ett_ingress_egress_apply_behavior
, apply_behavior
, ENC_LITTLE_ENDIAN
);
2299 uint32_t instance_rules_array_size
;
2300 proto_tree_add_item_ret_uint(tree
, hf_ingress_egress_ins_num
, tvb
, offset
+ 8, 2, ENC_LITTLE_ENDIAN
, &instance_rules_array_size
);
2301 int parsed_len
= 10;
2303 for (uint32_t i
= 0; i
< instance_rules_array_size
; i
++)
2305 proto_item
*instance_rule_item
;
2306 proto_tree
*instance_rule_tree
= proto_tree_add_subtree_format(tree
, tvb
, offset
+ parsed_len
, 0, ett_cmd_data
, &instance_rule_item
, "Instance Rule: %d", i
+ 1);
2307 proto_tree_add_item(instance_rule_tree
, hf_ingress_egress_ins
, tvb
, offset
+ parsed_len
, 2, ENC_LITTLE_ENDIAN
);
2310 proto_item
*ingress_rules_item
;
2311 proto_tree
*ingress_rules_tree
= proto_tree_add_subtree(instance_rule_tree
, tvb
, offset
+ parsed_len
, 0, ett_cmd_data
, &ingress_rules_item
, "Ingress Rules");
2312 parsed_len
+= dissect_ingress_egress_rules(pinfo
, ingress_rules_tree
, ingress_rules_item
, tvb
, offset
+ parsed_len
, tvb_reported_length_remaining(tvb
, offset
+ parsed_len
));
2314 proto_item
*egress_rules_item
;
2315 proto_tree
*egress_rules_tree
= proto_tree_add_subtree(instance_rule_tree
, tvb
, offset
+ parsed_len
, 0, ett_cmd_data
, &egress_rules_item
, "Egress Rules");
2316 parsed_len
+= dissect_ingress_egress_rules(pinfo
, egress_rules_tree
, egress_rules_item
, tvb
, offset
+ parsed_len
, tvb_reported_length_remaining(tvb
, offset
+ parsed_len
));
2323 // Most of the information for the IANA Port Admin attribute and Set_Port_Admin_State service is the same.
2324 static int dissect_tcpip_port_information(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2325 int offset
, bool attribute_version
)
2327 int start_offset
= offset
;
2329 uint32_t port_count
;
2330 proto_tree_add_item_ret_uint(tree
, hf_tcpip_port_count
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
, &port_count
);
2333 for (uint32_t i
= 0; i
< port_count
; ++i
)
2335 proto_item
*port_item
;
2336 proto_tree
*port_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, 0, ett_cmd_data
, &port_item
, "Port: ");
2338 if (attribute_version
== true)
2340 uint8_t length
= tvb_get_uint8(tvb
, offset
);
2341 const char* port_name
= tvb_get_string_enc(wmem_packet_scope(), tvb
, offset
+ 1, length
, ENC_ASCII
);
2343 offset
+= dissect_cip_string_type(pinfo
, port_tree
, item
, tvb
, offset
, hf_tcpip_port_name
, CIP_SHORT_STRING_TYPE
);
2345 proto_item_append_text(port_item
, "Name: %s: ", port_name
);
2348 uint32_t port_number
;
2349 proto_tree_add_item_ret_uint(port_tree
, hf_tcpip_port_number
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &port_number
);
2351 proto_item_append_text(port_item
, "Number: %d", port_number
);
2353 proto_tree_add_item(port_tree
, hf_tcpip_port_protocol
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2356 proto_tree_add_item(port_tree
, hf_tcpip_port_admin_state
, tvb
, offset
, 1, ENC_LITTLE_ENDIAN
);
2359 if (attribute_version
== true)
2361 static int* const capability
[] = {
2362 &hf_tcpip_admin_capability_configurable
,
2363 &hf_tcpip_admin_capability_reset_required
,
2364 &hf_tcpip_admin_capability_reserved
,
2368 proto_tree_add_bitmask(port_tree
, tvb
, offset
, hf_tcpip_port_admin_capability
, ett_tcpip_admin_capability
, capability
, ENC_LITTLE_ENDIAN
);
2373 return offset
- start_offset
;
2376 static int dissect_tcpip_port_admin(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
,
2377 int offset
, int total_len _U_
)
2379 return dissect_tcpip_port_information(pinfo
, tree
, item
, tvb
, offset
, true);
2382 static int dissect_tcpip_set_port_admin_state(packet_info
*pinfo
, proto_tree
*tree
, proto_item
*item
, tvbuff_t
*tvb
, int offset
, bool request
)
2386 return dissect_tcpip_port_information(pinfo
, tree
, item
, tvb
, offset
, false);
2394 const attribute_info_t enip_attribute_vals
[] = {
2396 /* TCP/IP Object (class attributes) */
2397 {0xF5, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
2398 {0xF5, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
2399 {0xF5, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
2400 {0xF5, true, 4, 3, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
2401 {0xF5, true, 5, 4, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
2402 {0xF5, true, 6, 5, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
2403 {0xF5, true, 7, 6, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
2405 /* TCP/IP object (instance attributes) */
2406 {0xF5, false, 1, 0, "Status", cip_dissector_func
, NULL
, dissect_tcpip_status
},
2407 {0xF5, false, 2, 1, "Configuration Capability", cip_dissector_func
, NULL
, dissect_tcpip_config_cap
},
2408 {0xF5, false, 3, 2, "Configuration Control", cip_dissector_func
, NULL
, dissect_tcpip_config_control
},
2409 {0xF5, false, 4, 3, "Physical Link Object", cip_dissector_func
, NULL
, dissect_tcpip_physical_link
},
2410 {0xF5, false, 5, 4, "Interface Configuration", cip_dissector_func
, NULL
, dissect_tcpip_interface_config
},
2411 {0xF5, false, 6, 5, "Host Name", cip_dissector_func
, NULL
, dissect_tcpip_hostname
},
2412 {0xF5, false, 7, 6, "Safety Network Number", cip_dissector_func
, NULL
, dissect_tcpip_snn
},
2413 {0xF5, false, 8, 7, "TTL Value", cip_usint
, &hf_tcpip_ttl_value
, NULL
},
2414 {0xF5, false, 9, 8, "Multicast Configuration", cip_dissector_func
, NULL
, dissect_tcpip_mcast_config
},
2415 {0xF5, false, 10, 9, "Select ACD", cip_bool
, &hf_tcpip_select_acd
, NULL
},
2416 {0xF5, false, 11, 10, "Last Conflict Detected", cip_dissector_func
, NULL
, dissect_tcpip_last_conflict
},
2417 {0xF5, false, 12, 11, "EtherNet/IP Quick Connect", cip_bool
, &hf_tcpip_quick_connect
, NULL
},
2418 {0xF5, false, 13, 12, "Encapsulation Inactivity Timeout", cip_uint
, &hf_tcpip_encap_inactivity
, NULL
},
2419 {0xF5, false, 14, -1, "IANA Port Admin", cip_dissector_func
, NULL
, dissect_tcpip_port_admin
},
2421 /* Ethernet Link Object (class attributes) */
2422 {0xF6, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
2423 {0xF6, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
2424 {0xF6, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
2425 {0xF6, true, 4, 3, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
2426 {0xF6, true, 5, 4, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
2427 {0xF6, true, 6, 5, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
2428 {0xF6, true, 7, 6, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
2430 /* Ethernet Link object (instance attributes) */
2431 {0xF6, false, 1, 0, "Interface Speed", cip_dword
, &hf_elink_interface_speed
, NULL
},
2432 {0xF6, false, 2, 1, "Interface Flags", cip_dissector_func
, NULL
, dissect_elink_interface_flags
},
2433 {0xF6, false, 3, 2, "Physical Address", cip_dissector_func
, NULL
, dissect_elink_physical_address
},
2434 {0xF6, false, 4, 3, "Interface Counters", cip_dissector_func
, NULL
, dissect_elink_interface_counters
},
2435 {0xF6, false, 5, 4, "Media Counters", cip_dissector_func
, NULL
, dissect_elink_media_counters
},
2436 {0xF6, false, 6, 5, "Interface Control", cip_dissector_func
, NULL
, dissect_elink_interface_control
},
2437 {0xF6, false, 7, 6, "Interface Type", cip_usint
, &hf_elink_interface_type
, NULL
},
2438 {0xF6, false, 8, 7, "Interface State", cip_usint
, &hf_elink_interface_state
, NULL
},
2439 {0xF6, false, 9, 8, "Admin State", cip_usint
, &hf_elink_admin_state
, NULL
},
2440 {0xF6, false, 10, 9, "Interface Label", cip_short_string
, &hf_elink_interface_label
, NULL
},
2441 {0xF6, false, 11, 10, "Interface Capability", cip_dissector_func
, NULL
, dissect_elink_interface_capability
},
2442 {0xF6, false, 12, 11, "HC Interface Counters", cip_dissector_func
, NULL
, dissect_elink_hc_interface_counters
},
2443 {0xF6, false, 13, 12, "HC Media Counters", cip_dissector_func
, NULL
, dissect_elink_hc_media_counters
},
2445 /* QoS Object (class attributes) */
2446 {0x48, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
2447 {0x48, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
2448 {0x48, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
2449 {0x48, true, 4, 3, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
2450 {0x48, true, 5, 4, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
2451 {0x48, true, 6, 5, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
2452 {0x48, true, 7, 6, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
2454 /* QoS object (instance attributes) */
2455 {0x48, false, 1, -1, "802.1Q Tag Enable", cip_bool
, &hf_qos_8021q_enable
, NULL
},
2456 {0x48, false, 2, -1, "DSCP PTP Event", cip_usint
, &hf_qos_dscp_ptp_event
, NULL
},
2457 {0x48, false, 3, -1, "DSCP PTP General", cip_usint
, &hf_qos_dscp_ptp_general
, NULL
},
2458 {0x48, false, 4, -1, "DSCP Urgent", cip_usint
, &hf_qos_dscp_urgent
, NULL
},
2459 {0x48, false, 5, -1, "DSCP Scheduled", cip_usint
, &hf_qos_dscp_scheduled
, NULL
},
2460 {0x48, false, 6, -1, "DSCP High", cip_usint
, &hf_qos_dscp_high
, NULL
},
2461 {0x48, false, 7, -1, "DSCP Low", cip_usint
, &hf_qos_dscp_low
, NULL
},
2462 {0x48, false, 8, -1, "DSCP Explicit", cip_usint
, &hf_qos_dscp_explicit
, NULL
},
2464 /* DLR Object (class attributes) */
2465 {0x47, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
2466 {0x47, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
2467 {0x47, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
2468 {0x47, true, 4, 3, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
2469 {0x47, true, 5, 4, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
2470 {0x47, true, 6, 5, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
2471 {0x47, true, 7, 6, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
2473 /* DLR object (instance attributes) */
2474 /* Get Attributes All is not fully parsed here because there are multiple formats. */
2475 {0x47, false, 1, 0, "Network Topology", cip_usint
, &hf_dlr_network_topology
, NULL
},
2476 {0x47, false, 2, 1, "Network Status", cip_usint
, &hf_dlr_network_status
, NULL
},
2477 {0x47, false, 3, -1, "Ring Supervisor Status", cip_usint
, &hf_dlr_ring_supervisor_status
, NULL
},
2478 {0x47, false, 4, -1, "Ring Supervisor Config", cip_dissector_func
, NULL
, dissect_dlr_ring_supervisor_config
},
2479 {0x47, false, 5, -1, "Ring Faults Count", cip_uint
, &hf_dlr_ring_faults_count
, NULL
},
2480 {0x47, false, 6, -1, "Last Active Node on Port 1", cip_dissector_func
, NULL
, dissect_dlr_last_active_node_on_port_1
},
2481 {0x47, false, 7, -1, "Last Active Node on Port 2", cip_dissector_func
, NULL
, dissect_dlr_last_active_node_on_port_2
},
2482 {0x47, false, 8, -1, "Ring Protocol Participants Count", cip_uint
, &hf_dlr_ring_protocol_participants_count
, NULL
},
2483 {0x47, false, 9, -1, "Ring Protocol Participants List", cip_dissector_func
, NULL
, dissect_dlr_ring_protocol_participants_list
},
2484 {0x47, false, 10, -1, "Active Supervisor Address", cip_dissector_func
, NULL
, dissect_dlr_active_supervisor_address
},
2485 {0x47, false, 11, -1, "Active Supervisor Precedence", cip_usint
, &hf_dlr_active_supervisor_precedence
, NULL
},
2486 {0x47, false, 12, -1, "Capability Flags", cip_dissector_func
, NULL
, dissect_dlr_capability_flags
},
2487 {0x47, false, 13, -1, "Redundant Gateway Config", cip_dissector_func
, NULL
, dissect_dlr_redundant_gateway_config
},
2488 {0x47, false, 14, -1, "Redundant Gateway Status", cip_usint
, &hf_dlr_redundant_gateway_status
, NULL
},
2489 {0x47, false, 15, -1, "Active Gateway Address", cip_dissector_func
, NULL
, dissect_dlr_active_gateway_address
},
2490 {0x47, false, 16, -1, "Active Gateway Precedence", cip_usint
, &hf_dlr_active_gateway_precedence
, NULL
},
2492 /* CIP Security Object (instance attributes) */
2493 {0x5D, CIP_ATTR_INSTANCE
, 1, 0, "State", cip_usint
, &hf_cip_security_state
, NULL
},
2494 {0x5D, CIP_ATTR_INSTANCE
, 2, 1, "Security Profiles", cip_dissector_func
, NULL
, dissect_cip_security_profiles
},
2496 /* EtherNet/IP Security object (instance attributes) */
2497 {0x5E, false, 1, 0, "State", cip_usint
, &hf_eip_security_state
, NULL
},
2498 {0x5E, false, 2, 1, "Capability Flags", cip_dissector_func
, NULL
, dissect_eip_security_cap
},
2499 {0x5E, false, 3, 2, "Available Cipher Suites", cip_dissector_func
, NULL
, dissect_eip_security_avail_cipher_suites
},
2500 {0x5E, false, 4, 3, "Allowed Cipher Suites", cip_dissector_func
, NULL
, dissect_eip_security_allow_cipher_suites
},
2501 {0x5E, false, 5, 4, "Pre-Shared Keys", cip_dissector_func
, NULL
, dissect_eip_security_preshared_keys
},
2502 {0x5E, false, 6, 5, "Active Device Certificates", cip_dissector_func
, NULL
, dissect_eip_security_active_certs
},
2503 {0x5E, false, 7, 6, "Trusted Authorities", cip_dissector_func
, NULL
, dissect_eip_security_trusted_auths
},
2504 {0x5E, false, 8, 7, "Certificate Revocation List", cip_dissector_func
, NULL
, dissect_eip_security_cert_revocation_list
},
2505 {0x5E, false, 9, 8, "Verify Client Certificate", cip_bool
, &hf_eip_security_verify_client_cert
, NULL
},
2506 {0x5E, false, 10, 9, "Send Certificate Chain", cip_bool
, &hf_eip_security_send_cert_chain
, NULL
},
2507 {0x5E, false, 11, 10, "Check Expiration", cip_bool
, &hf_eip_security_check_expiration
, NULL
},
2508 {0x5E, false, 12, 11, "Trusted Identities", cip_dissector_func
, NULL
, dissect_eip_security_trusted_identities
},
2510 /* Certificate Management Object (class attributes) */
2511 {0x5F, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
2512 {0x5F, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
2513 {0x5F, true, 3, -1, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
2514 {0x5F, true, 4, -1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
2515 {0x5F, true, 5, -1, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
2516 {0x5F, true, 6, 2, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
2517 {0x5F, true, 7, 3, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
2518 {0x5F, true, 8, 4, "Capability Flags", cip_dissector_func
, NULL
, dissect_eip_cert_cap_flags
},
2519 {0x5F, true, 9, 5, "Certificate List", cip_dissector_func
, NULL
, dissect_eip_cert_cert_list
},
2521 /* Certificate Management Object (instance attributes) */
2522 {0x5F, false, 1, 0, "Name", cip_short_string
, &hf_eip_cert_name
, NULL
},
2523 {0x5F, false, 2, 1, "State", cip_usint
, &hf_eip_cert_state
, NULL
},
2524 {0x5F, false, 3, 2, "Device Certificate", cip_dissector_func
, NULL
, dissect_eip_cert_device_cert
},
2525 {0x5F, false, 4, 3, "CA Certificate", cip_dissector_func
, NULL
, dissect_eip_cert_ca_cert
},
2526 {0x5F, false, 5, 4, "Certificate Encoding", cip_usint
, &hf_eip_cert_encoding
, NULL
},
2528 /* Ingress Egress Object (class attributes) */
2529 {0x63, true, 1, 0, CLASS_ATTRIBUTE_1_NAME
, cip_uint
, &hf_attr_class_revision
, NULL
},
2530 {0x63, true, 2, 1, CLASS_ATTRIBUTE_2_NAME
, cip_uint
, &hf_attr_class_max_instance
, NULL
},
2531 {0x63, true, 3, 2, CLASS_ATTRIBUTE_3_NAME
, cip_uint
, &hf_attr_class_num_instance
, NULL
},
2532 {0x63, true, 4, -1, CLASS_ATTRIBUTE_4_NAME
, cip_dissector_func
, NULL
, dissect_optional_attr_list
},
2533 {0x63, true, 5, -1, CLASS_ATTRIBUTE_5_NAME
, cip_dissector_func
, NULL
, dissect_optional_service_list
},
2534 {0x63, true, 6, 3, CLASS_ATTRIBUTE_6_NAME
, cip_uint
, &hf_attr_class_num_class_attr
, NULL
},
2535 {0x63, true, 7, 4, CLASS_ATTRIBUTE_7_NAME
, cip_uint
, &hf_attr_class_num_inst_attr
, NULL
},
2536 {0x63, true, 8, 5, "Ingress Rules TCP Ports Supported", cip_dissector_func
, NULL
, dissect_ingress_tcp_udp_ports_supported
},
2537 {0x63, true, 9, 6, "Ingress Rules UDP Ports Supported", cip_dissector_func
, NULL
, dissect_ingress_tcp_udp_ports_supported
},
2539 /* Ingress Egress Object (instance attributes) */
2540 {0x63, false, 1, 0, "Ingress Rules", cip_dissector_func
, NULL
, dissect_ingress_egress_rules
},
2541 {0x63, false, 2, 1, "Egress Rules", cip_dissector_func
, NULL
, dissect_ingress_egress_rules
},
2545 // Table of CIP services defined by this dissector.
2546 static cip_service_info_t enip_obj_spec_service_table
[] = {
2548 { 0x5D, 0x4B, "Begin_Config", NULL
},
2549 { 0x5D, 0x4C, "Kick_Timer", NULL
},
2550 { 0x5D, 0x4D, "End_Config", NULL
},
2551 { 0x5D, 0x4E, "Object_Cleanup", NULL
},
2553 // EtherNet/IP Security
2554 { 0x5E, 0x4B, "Begin_Config", NULL
},
2555 { 0x5E, 0x4C, "Kick_Timer", NULL
},
2556 { 0x5E, 0x4E, "Abort_Config", NULL
},
2558 // Certificate Management
2559 { 0x5F, 0x4C, "Verify_Certificate", dissect_certificate_management_object_verify_certificate
},
2561 // Ingress Egress Object
2562 { 0x63, 0x4B, "Set_Rules", dissect_ingress_egress_set_rules
},
2565 { 0xF5, 0x4C, "Set_Port_Admin_State", dissect_tcpip_set_port_admin_state
},
2568 // Look up a given CIP service from this dissector.
2569 cip_service_info_t
* cip_get_service_enip(uint32_t class_id
, uint8_t service_id
)
2571 return cip_get_service_one_table(&enip_obj_spec_service_table
[0],
2572 array_length(enip_obj_spec_service_table
),
2577 static void enip_init_protocol(void)
2579 enip_unique_connid
= 0;
2582 // offset - Starts at the "Encapsulation Protocol Version" field.
2583 static void dissect_item_list_identity(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, proto_tree
* item_tree
)
2585 /* Encapsulation version */
2586 proto_tree_add_item(item_tree
, hf_enip_encapver
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2588 /* Socket Address */
2589 proto_tree
* sockaddr_tree
= proto_tree_add_subtree(item_tree
, tvb
, offset
+ 2, 16, ett_sockadd
, NULL
, "Socket Address");
2591 /* Socket address struct - sin_family */
2592 proto_tree_add_item(sockaddr_tree
, hf_enip_sinfamily
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
2594 /* Socket address struct - sin_port */
2595 proto_tree_add_item(sockaddr_tree
, hf_enip_sinport
, tvb
, offset
+ 4, 2, ENC_BIG_ENDIAN
);
2597 /* Socket address struct - sin_address */
2598 proto_tree_add_item(sockaddr_tree
, hf_enip_sinaddr
, tvb
, offset
+ 6, 4, ENC_BIG_ENDIAN
);
2600 /* Socket address struct - sin_zero */
2601 proto_tree_add_item(sockaddr_tree
, hf_enip_sinzero
, tvb
, offset
+ 10, 8, ENC_NA
);
2604 proto_tree_add_item(item_tree
, hf_enip_lir_vendor
, tvb
, offset
+ 18, 2, ENC_LITTLE_ENDIAN
);
2607 proto_tree_add_item(item_tree
, hf_enip_lir_devtype
, tvb
, offset
+ 20, 2, ENC_LITTLE_ENDIAN
);
2610 proto_tree_add_item(item_tree
, hf_enip_lir_prodcode
, tvb
, offset
+ 22, 2, ENC_LITTLE_ENDIAN
);
2613 proto_tree_add_item(item_tree
, hf_enip_lir_revision
, tvb
, offset
+ 24, 2, ENC_BIG_ENDIAN
);
2616 proto_tree_add_item(item_tree
, hf_enip_lir_status
, tvb
, offset
+ 26, 2, ENC_LITTLE_ENDIAN
);
2619 proto_tree_add_item(item_tree
, hf_enip_lir_serial
, tvb
, offset
+ 28, 4, ENC_LITTLE_ENDIAN
);
2621 /* Product Name Length */
2622 uint32_t name_length
;
2623 proto_tree_add_item_ret_uint(item_tree
, hf_enip_lir_namelen
, tvb
, offset
+ 32, 1, ENC_LITTLE_ENDIAN
, &name_length
);
2626 proto_tree_add_item(item_tree
, hf_enip_lir_name
, tvb
, offset
+ 33, name_length
, ENC_ASCII
| ENC_NA
);
2628 /* Append product name to info column */
2629 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s", tvb_format_text(pinfo
->pool
, tvb
, offset
+ 33, name_length
));
2632 proto_tree_add_item(item_tree
, hf_enip_lir_state
, tvb
, offset
+ name_length
+ 33, 1, ENC_LITTLE_ENDIAN
);
2635 // offset - Starts at the "Security Profiles" field.
2636 static void dissect_item_cip_security_information(tvbuff_t
* tvb
, int offset
, proto_tree
* item_tree
)
2638 static int * const iana_flags
[] = {
2639 &hf_enip_iana_port_state_flags_tcp_44818
,
2640 &hf_enip_iana_port_state_flags_udp_44818
,
2641 &hf_enip_iana_port_state_flags_udp_2222
,
2642 &hf_enip_iana_port_state_flags_tcp_2221
,
2643 &hf_enip_iana_port_state_flags_udp_2221
,
2644 &hf_enip_iana_port_state_flags_reserved
,
2648 dissect_cip_security_profiles(NULL
, item_tree
, NULL
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
));
2650 /* CIP Security object state */
2651 proto_tree_add_item(item_tree
, hf_enip_cip_security_state
, tvb
, offset
+ 2, 1, ENC_LITTLE_ENDIAN
);
2653 /* ENIP Security object state */
2654 proto_tree_add_item(item_tree
, hf_enip_eip_security_state
, tvb
, offset
+ 3, 1, ENC_LITTLE_ENDIAN
);
2656 /* IANA Port State flags */
2657 proto_tree_add_bitmask(item_tree
, tvb
, offset
+ 4, hf_enip_iana_port_state_flags
, ett_iana_port_state_flags
, iana_flags
, ENC_LITTLE_ENDIAN
);
2660 // offset - Starts at the "Encapsulation Protocol Version" field.
2661 static void dissect_item_list_services_response(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, proto_tree
* item_tree
)
2663 /* Encapsulation version */
2664 proto_tree_add_item(item_tree
, hf_enip_encapver
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2666 /* Capability flags */
2667 static int* const capability_bits
[] = {
2672 proto_tree_add_bitmask(item_tree
, tvb
, offset
+ 2, hf_enip_lsr_capaflags
, ett_lsrcf
, capability_bits
, ENC_LITTLE_ENDIAN
);
2674 /* Name of service */
2675 proto_tree_add_item(item_tree
, hf_enip_lsr_servicename
, tvb
, offset
+ 4, 16, ENC_ASCII
| ENC_NA
);
2677 /* Append service name to info column */
2678 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s",
2679 tvb_format_stringzpad(pinfo
->pool
, tvb
, offset
+ 4, 16));
2682 void display_fwd_open_connection_path(cip_conn_info_t
* conn_info
, proto_tree
* tree
, tvbuff_t
* tvb
, packet_info
* pinfo
)
2684 if (!conn_info
->pFwdOpenPathData
)
2689 tvbuff_t
* tvbIOI
= tvb_new_real_data((const uint8_t*)conn_info
->pFwdOpenPathData
, conn_info
->FwdOpenPathLenBytes
, conn_info
->FwdOpenPathLenBytes
);
2692 proto_item
* pi
= NULL
;
2693 proto_tree
* epath_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_connection_path_info
, &pi
, "Forward Open Connection Path: ");
2694 proto_item_set_generated(pi
);
2696 dissect_epath(tvbIOI
, pinfo
, epath_tree
, pi
, 0, conn_info
->FwdOpenPathLenBytes
, true, false, NULL
, NULL
, NO_DISPLAY
, NULL
, false);
2701 // returns true if this is a likely Heartbeat message
2702 // Note: item_length include the CIP Sequence Count, if applicable.
2703 static bool cip_io_is_likely_heartbeat(const cip_conn_info_t
* conn_info
, enum enip_connid_type connid_type
, uint32_t item_length
)
2705 // Heartbeat messages only occur in the O->T direction.
2706 if (connid_type
!= ECIDT_O2T
)
2711 // Class 0 heartbeat messages have 0 length.
2712 if (item_length
== 0)
2717 // The only other possibility for a heartbeat is for Class 1 (the 2 bytes is the Sequence Count)
2718 if (item_length
!= 2)
2723 // The only possibility for a heartbeat is: Class 1 with 2 bytes of data only, and it must be a "Fixed" size.
2724 uint8_t transport_class
= conn_info
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
;
2725 if (transport_class
== 1 && conn_info
->O2T
.connection_size_type
== CIP_CONNECTION_SIZE_TYPE_FIXED
)
2732 static void display_connection_information(packet_info
* pinfo
, tvbuff_t
* tvb
, proto_tree
* tree
, cip_conn_info_t
* conn_info
,
2733 enum enip_connid_type connid_type
, uint32_t item_length
)
2735 proto_item
* conn_info_item
= NULL
;
2736 proto_tree
* conn_info_tree
= proto_tree_add_subtree(tree
, tvb
, 0, 0, ett_connection_info
, &conn_info_item
, "Connection Information");
2737 proto_item_set_generated(conn_info_item
);
2739 if (connid_type
== ECIDT_O2T
)
2741 proto_item_append_text(conn_info_item
, ": O->T");
2743 else if (connid_type
== ECIDT_T2O
)
2745 proto_item_append_text(conn_info_item
, ": T->O");
2748 display_fwd_open_connection_path(conn_info
, conn_info_tree
, tvb
, pinfo
);
2750 proto_item
* pi
= proto_tree_add_uint(conn_info_tree
, hf_cip_cm_ot_api
, tvb
, 0, 0, conn_info
->O2T
.api
);
2751 proto_item_set_generated(pi
);
2753 pi
= proto_tree_add_uint(conn_info_tree
, hf_cip_cm_to_api
, tvb
, 0, 0, conn_info
->T2O
.api
);
2754 proto_item_set_generated(pi
);
2756 pi
= proto_tree_add_uint(conn_info_tree
, hf_cip_connection
, tvb
, 0, 0, conn_info
->connid
);
2757 proto_item_set_generated(pi
);
2759 pi
= proto_tree_add_uint(conn_info_tree
, hf_enip_fwd_open_in
, tvb
, 0, 0, conn_info
->open_req_frame
);
2760 proto_item_set_generated(pi
);
2762 if (cip_io_is_likely_heartbeat(conn_info
, connid_type
, item_length
))
2764 expert_add_info(pinfo
, conn_info_item
, &ei_cip_io_heartbeat
);
2768 // This dissects Class 0 or Class 1 I/O.
2769 // offset - Starts at the field after the Item Length field.
2770 static int dissect_cip_io_generic(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data
)
2772 cip_io_data_input
* io_data_input
= (cip_io_data_input
*)data
;
2776 proto_item
* ti
= proto_tree_add_item(tree
, proto_cipio
, tvb
, 0, -1, ENC_NA
);
2777 proto_tree
* io_tree
= proto_item_add_subtree(ti
, ett_cip_io_generic
);
2779 if (io_data_input
!= NULL
)
2781 if ((io_data_input
->conn_info
->TransportClass_trigger
& CI_TRANSPORT_CLASS_MASK
) == 1)
2783 proto_tree_add_item(io_tree
, hf_cip_sequence_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2787 if ((tvb_reported_length_remaining(tvb
, offset
) >= 4) &&
2788 (((io_data_input
->connid_type
== ECIDT_O2T
) && enip_OTrun_idle
) ||
2789 ((io_data_input
->connid_type
== ECIDT_T2O
) && enip_TOrun_idle
)))
2791 dissect_cip_run_idle(tvb
, offset
, io_tree
);
2796 proto_tree_add_item(io_tree
, hf_cip_io_data
, tvb
, offset
, tvb_reported_length_remaining(tvb
, offset
), ENC_NA
);
2798 return tvb_captured_length(tvb
);
2801 // Dissect the various kinds of CIP Class 0/1 I/O formats. This will determine the appropriate format and
2802 // call the appropriate related dissector.
2803 // offset - Starts at the field after the Item Length field.
2804 static void dissect_cip_class01_io(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
2805 int item_length
, cip_conn_info_t
* conn_info
, enum enip_connid_type connid_type
,
2806 proto_tree
* dissector_tree
)
2808 if (tvb_reported_length_remaining(tvb
, offset
) <= 0)
2814 tvbuff_t
* next_tvb
= tvb_new_subset_length(tvb
, offset
, item_length
);
2815 if (conn_info
!= NULL
)
2817 cip_io_data_input io_data_input
;
2818 io_data_input
.conn_info
= conn_info
;
2819 io_data_input
.connid_type
= connid_type
;
2821 if (conn_info
->safety
.safety_seg
== true)
2823 /* Add any possible safety related data */
2824 cip_safety_info_t cip_safety
;
2825 cip_safety
.conn_type
= connid_type
;
2826 cip_safety
.eip_conn_info
= conn_info
;
2827 cip_safety
.compute_crc
= true;
2829 call_dissector_with_data(cipsafety_handle
, next_tvb
, pinfo
, dissector_tree
, &cip_safety
);
2833 dissector_handle_t dissector
= dissector_get_uint_handle(subdissector_io_table
, conn_info
->connection_path
.iClass
);
2836 call_dissector_with_data(dissector
, next_tvb
, pinfo
, dissector_tree
, &io_data_input
);
2840 call_dissector_with_data(cip_io_generic_handle
, next_tvb
, pinfo
, dissector_tree
, &io_data_input
);
2846 // This handles the Decode As options
2847 if (!dissector_try_payload_with_data(subdissector_decode_as_io_table
, next_tvb
, pinfo
, dissector_tree
, true, NULL
))
2849 call_dissector_with_data(cip_io_generic_handle
, next_tvb
, pinfo
, dissector_tree
, NULL
);
2854 // Dissect CIP Class 2/3 data. This will determine the appropriate format and call the appropriate related dissector.
2855 // offset - Starts at the field after the Item Length field.
2856 static void dissect_cip_class23_data(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
2857 proto_tree
* tree
, proto_tree
* item_tree
, uint32_t item_length
,
2858 enip_request_key_t
* request_key
, cip_conn_info_t
* conn_info
, proto_tree
* dissector_tree
)
2860 enip_request_info_t
* request_info
= NULL
;
2864 request_key
->type
= EPDT_CONNECTED_TRANSPORT
;
2865 request_key
->data
.connected_transport
.sequence
= tvb_get_letohs(tvb
, offset
);
2866 request_info
= enip_match_request(pinfo
, tree
, request_key
);
2869 /* Add sequence count ( Transport Class 2,3 ) */
2870 proto_tree_add_item(item_tree
, hf_cip_sequence_count
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
2872 /* Call dissector for interface */
2873 tvbuff_t
* next_tvb
= tvb_new_subset_length(tvb
, offset
+ 2, item_length
- 2);
2875 p_add_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
, request_info
);
2877 if (conn_info
!= NULL
)
2879 dissector_handle_t dissector
= dissector_get_uint_handle(subdissector_cip_connection_table
, conn_info
->connection_path
.iClass
);
2882 call_dissector_with_data(dissector
, next_tvb
, pinfo
, dissector_tree
, GUINT_TO_POINTER(conn_info
->connection_path
.iClass
));
2886 call_dissector_with_data(cip_implicit_handle
, next_tvb
, pinfo
, dissector_tree
, GUINT_TO_POINTER(conn_info
->connection_path
.iClass
));
2891 // Default to Message Router format, since this is the most common. Since we don't have the connection
2892 // info, at least ensure that the data can at least meet the minimum explicit message size.
2893 if (tvb_reported_length(next_tvb
) >= 2)
2895 call_dissector(cip_handle
, next_tvb
, pinfo
, dissector_tree
);
2899 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
);
2902 // offset - Starts at the sin_family field.
2903 static void dissect_item_sockaddr_info(packet_info
*pinfo
, tvbuff_t
* tvb
, int offset
, proto_tree
* item_tree
,
2904 uint32_t item_type_id
, bool is_fwd_open
)
2906 /* Socket address struct - sin_family */
2907 proto_tree_add_item(item_tree
, hf_enip_sinfamily
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
2909 /* Socket address struct - sin_port */
2910 proto_tree_add_item(item_tree
, hf_enip_sinport
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
2912 /* Socket address struct - sin_address */
2913 proto_tree_add_item(item_tree
, hf_enip_sinaddr
, tvb
, offset
+ 4, 4, ENC_BIG_ENDIAN
);
2915 /* Socket address struct - sin_zero */
2916 proto_tree_add_item(item_tree
, hf_enip_sinzero
, tvb
, offset
+ 8, 8, ENC_NA
);
2920 enip_request_info_t
* request_info
= (enip_request_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
);
2921 if (request_info
!= NULL
)
2923 if (item_type_id
== CPF_ITEM_SOCK_ADR_INFO_OT
)
2925 request_info
->cip_info
->connInfo
->O2T
.port
= tvb_get_ntohs(tvb
, offset
+ 2);
2926 alloc_address_tvb(wmem_file_scope(), &request_info
->cip_info
->connInfo
->O2T
.ipaddress
,
2927 AT_IPv4
, sizeof(uint32_t), tvb
, offset
+ 4);
2931 request_info
->cip_info
->connInfo
->T2O
.port
= tvb_get_ntohs(tvb
, offset
+ 2);
2932 alloc_address_tvb(wmem_file_scope(), &request_info
->cip_info
->connInfo
->T2O
.ipaddress
,
2933 AT_IPv4
, sizeof(uint32_t), tvb
, offset
+ 4);
2939 // offset - Starts at the Connection ID
2940 // Returns: connid_type, conn_info
2941 static void dissect_item_sequenced_address(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
2942 proto_tree
* tree
, enum enip_connid_type
* connid_type
, cip_conn_info_t
** conn_info
)
2944 uint32_t connection_id
;
2945 proto_tree_add_item_ret_uint(tree
, hf_enip_cpf_sai_connid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &connection_id
);
2946 proto_item
* pi
= proto_tree_add_item(tree
, hf_cip_connid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2947 proto_item_set_hidden(pi
);
2949 uint32_t sequence_num
;
2950 proto_tree_add_item_ret_uint(tree
, hf_enip_cpf_sai_seqnum
, tvb
, offset
+ 4, 4, ENC_LITTLE_ENDIAN
, &sequence_num
);
2952 *conn_info
= enip_get_io_connid(pinfo
, connection_id
, connid_type
);
2954 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Connection: ID=0x%08X, SEQ=%010u", connection_id
, sequence_num
);
2955 if (*connid_type
== ECIDT_O2T
)
2957 col_append_str(pinfo
->cinfo
, COL_INFO
, ", O->T");
2959 else if (*connid_type
== ECIDT_T2O
)
2961 col_append_str(pinfo
->cinfo
, COL_INFO
, ", T->O");
2965 // offset - Starts at the Connection ID
2966 // Returns: conn_info
2967 static void dissect_item_connected_address(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
,
2968 proto_tree
* item_tree
, proto_item
* enip_item
,
2969 enip_request_key_t
* request_key
, cip_conn_info_t
** conn_info
)
2971 uint32_t connection_id
;
2972 proto_tree_add_item_ret_uint(item_tree
, hf_enip_cpf_cai_connid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
, &connection_id
);
2973 proto_item
* pi
= proto_tree_add_item(item_tree
, hf_cip_connid
, tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2974 proto_item_set_hidden(pi
);
2976 *conn_info
= enip_get_explicit_connid(pinfo
, request_key
, connection_id
);
2979 request_key
->type
= EPDT_CONNECTED_TRANSPORT
;
2980 request_key
->data
.connected_transport
.connid
= (*conn_info
!= NULL
) ? (*conn_info
)->connid
: 0;
2983 /* Add Connection ID to Info col and tree */
2984 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Connection: ID=0x%08X", connection_id
);
2988 proto_item_append_text(enip_item
, ", Connection ID: 0x%08X", connection_id
);
2992 // offset - Starts at Unconn Msg Type
2993 // returns - input_request_key
2994 // Dissects the following parts of the Unconnected Message over UDP item: Unconn Msg Type, Transaction Number, Status.
2995 // The Unconnected Message field is handled outside of this function.
2996 static void dissect_item_unconnected_message_over_udp(packet_info
* pinfo
, tvbuff_t
* tvb
, int offset
, proto_tree
* item_tree
, enip_request_key_t
** input_request_key
)
2998 uint32_t ucmm_request
;
2999 proto_tree_add_item_ret_uint(item_tree
, hf_enip_cpf_ucmm_request
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &ucmm_request
);
3000 proto_tree_add_item(item_tree
, hf_enip_cpf_ucmm_msg_type
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3003 proto_tree_add_item_ret_uint(item_tree
, hf_enip_cpf_ucmm_trans_id
, tvb
, offset
+ 2, 4, ENC_LITTLE_ENDIAN
, &trans_id
);
3004 proto_tree_add_item(item_tree
, hf_enip_cpf_ucmm_status
, tvb
, offset
+ 6, 4, ENC_LITTLE_ENDIAN
);
3006 if (*input_request_key
== NULL
)
3009 * Under normal circumstances request_key should always be NULL here
3010 * Duplicating setting up a request (like is done with explicit messaging)
3012 conversation_t
* conversation
= find_or_create_conversation(pinfo
);
3015 * Attach that information to the conversation, and add
3016 * it to the list of information structures later before dissection.
3018 enip_request_key_t
* request_key
= wmem_new0(pinfo
->pool
, enip_request_key_t
);
3019 request_key
->requesttype
= ucmm_request
? ENIP_RESPONSE_PACKET
: ENIP_REQUEST_PACKET
;
3020 request_key
->type
= EPDT_UNKNOWN
;
3022 /* UCMM over UDP doesn't have a session handle, so use conversation
3023 * pointer as "unique-ish ID"
3025 request_key
->session_handle
= GPOINTER_TO_UINT(conversation
);
3026 request_key
->sender_context
= trans_id
;
3027 request_key
->conversation
= conversation
->conv_index
;
3029 // Return the new request key.
3030 *input_request_key
= request_key
;
3034 static bool is_forward_open(uint8_t cip_service
)
3036 return (cip_service
== SC_CM_FWD_OPEN
3037 || cip_service
== SC_CM_CONCURRENT_FWD_OPEN
3038 || cip_service
== SC_CM_LARGE_FWD_OPEN
);
3041 /* Dissect Common Packet Format */
3043 dissect_cpf(enip_request_key_t
*request_key
, int command
, tvbuff_t
*tvb
,
3044 packet_info
*pinfo
, proto_tree
*tree
, proto_tree
*dissector_tree
, proto_tree
*enip_layer_tree
,
3045 proto_item
*enip_item
, int offset
, uint32_t ifacehndl
)
3047 proto_item
*count_item
;
3048 proto_tree
*count_tree
;
3051 // The following variables are set in one pass of the loop, and read in a second pass.
3052 cip_conn_info_t
* conn_info
= NULL
;
3053 bool FwdOpenRequest
= false;
3054 bool FwdOpenReply
= false;
3055 enum enip_connid_type connid_type
= ECIDT_UNKNOWN
;
3057 // Normal "Common Packet Format" configurations. See CIP Volume 2, Section 2-6.4.
3058 // SendRRData (Unconnected):
3059 // Item 1: CPF_ITEM_NULL
3060 // Item 2: CPF_ITEM_UNCONNECTED_DATA
3061 // SendUnitData (Connected, Class 3):
3062 // Item 1: CPF_ITEM_CONNECTED_ADDRESS
3063 // Item 2: CPF_ITEM_CONNECTED_DATA
3064 // Item 3 (Optional): CPF_ITEM_SOCK_ADR_INFO_OT/CPF_ITEM_SOCK_ADR_INFO_TO
3065 // Class 0/1 packet:
3066 // Item 1: CPF_ITEM_SEQUENCED_ADDRESS
3067 // Item 2: CPF_ITEM_CONNECTED_DATA
3068 // Unconnected Message over UDP:
3069 // Item 1: CPF_ITEM_UNCONNECTED_MSG_DTLS
3071 /* Create item count tree */
3072 item_count
= tvb_get_letohs( tvb
, offset
);
3073 count_item
= proto_tree_add_item( tree
, hf_enip_cpf_itemcount
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
3074 count_tree
= proto_item_add_subtree( count_item
, ett_count_tree
);
3077 while ( item_count
-- )
3079 // Verify that we have the minimum CPF Item size.
3080 if (tvb_reported_length_remaining(tvb
, offset
) < 4)
3082 expert_add_info_format(pinfo
, count_item
, &ei_mal_cpf_item_minimum_size
,
3083 "%s, but Remaining Data Length is %d",
3084 expert_get_summary(&ei_mal_cpf_item_minimum_size
), tvb_reported_length_remaining(tvb
, offset
));
3089 /* Add item type tree to item count tree*/
3090 uint32_t item_type_id
;
3091 proto_item
* type_item
= proto_tree_add_item_ret_uint( count_tree
, hf_enip_cpf_typeid
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_type_id
);
3092 proto_tree
* item_tree
= proto_item_add_subtree( type_item
, ett_type_tree
);
3095 /* Add length field to item type tree */
3096 uint32_t item_length
;
3097 proto_tree_add_item_ret_uint( item_tree
, hf_enip_cpf_length
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
, &item_length
);
3100 // Check if the declared item length is more bytes than we have available. But, don't exit early
3101 // so maybe it will be more obvious where the problem is.
3102 if ((int)item_length
> tvb_reported_length_remaining(tvb
, offset
))
3104 expert_add_info_format(pinfo
, type_item
, &ei_mal_cpf_item_length_mismatch
,
3105 "%s: Item Length %d, Remaining Data Length: %d",
3106 expert_get_summary(&ei_mal_cpf_item_length_mismatch
), item_length
, tvb_reported_length_remaining(tvb
, offset
));
3109 // offset now starts at the data field after the Item Length field. The name of this
3110 // field varies depending on the item type.
3113 /* Add item data field */
3115 switch ( item_type_id
)
3117 case CPF_ITEM_CONNECTED_ADDRESS
: // 1st Item for: Class 3 Connected Messages
3119 dissect_item_connected_address(pinfo
, tvb
, offset
, item_tree
, enip_item
, request_key
, &conn_info
);
3122 case CPF_ITEM_UNCONNECTED_MSG_DTLS
: // Only item for: Unconnected messages over DTLS
3124 ifacehndl
= ENIP_CIP_INTERFACE
;
3126 dissect_item_unconnected_message_over_udp(pinfo
, tvb
, offset
, item_tree
, &request_key
);
3128 // Skip over the fields already parsed before falling through.
3133 /* Intentionally fall through */
3135 case CPF_ITEM_UNCONNECTED_DATA
: // 2nd Item for: Unconnected Messages
3137 enip_request_info_t
* request_info
= NULL
;
3140 request_key
->type
= EPDT_UNCONNECTED
;
3141 request_info
= enip_match_request( pinfo
, tree
, request_key
);
3144 /* Call dissector for interface */
3145 tvbuff_t
* next_tvb
= tvb_new_subset_length( tvb
, offset
, item_length
);
3146 p_add_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
, request_info
);
3147 if ( tvb_reported_length_remaining(next_tvb
, 0) <= 0 || !dissector_try_uint(subdissector_srrd_table
, ifacehndl
, next_tvb
, pinfo
, dissector_tree
) )
3149 /* Show the undissected payload */
3150 if ( tvb_reported_length_remaining(tvb
, offset
) > 0 )
3151 call_data_dissector(next_tvb
, pinfo
, dissector_tree
);
3154 /* Check if this is a ForwardOpen packet, because special handling is needed
3155 to handle connection conversations */
3156 if ((request_info
!= NULL
) && (request_info
->cip_info
!= NULL
) &&
3157 (request_info
->cip_info
->connInfo
!= NULL
) &&
3158 (request_key
!= NULL
) &&
3159 is_forward_open(request_info
->cip_info
->bService
& CIP_SC_MASK
) &&
3160 (request_info
->cip_info
->dissector
== dissector_get_uint_handle(subdissector_class_table
, CI_CLS_CM
)))
3162 if (request_key
->requesttype
== ENIP_REQUEST_PACKET
)
3164 FwdOpenRequest
= true;
3168 FwdOpenReply
= true;
3173 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
);
3178 case CPF_ITEM_CONNECTED_DATA
: // 2nd item for: Connected messages (both Class 0/1 and Class 3)
3179 // Save the connection info for the conversation filter
3181 if (conn_info
&& conn_info
->is_concurrent_connection
)
3183 int cc_header_len
= dissect_concurrent_connection_packet(pinfo
, tvb
, offset
, dissector_tree
);
3185 // The header length only includes the beginning part of the header. But, the actual data length
3186 // needs to remove the header AND the CRC field. The CRC field was parsed as part of the previous
3188 offset
+= cc_header_len
;
3189 item_length
= item_length
- cc_header_len
- CC_CRC_LENGTH
;
3192 if (!pinfo
->fd
->visited
&& conn_info
)
3194 p_add_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_CONNECTION_INFO
, conn_info
);
3197 if (command
== SEND_UNIT_DATA
) // Class 2/3 over TCP.
3199 dissect_cip_class23_data(pinfo
, tvb
, offset
, tree
, item_tree
, item_length
, request_key
, conn_info
, dissector_tree
);
3201 else // No command. Send as CPF items only over UDP.
3203 dissect_cip_class01_io(pinfo
, tvb
, offset
, item_length
, conn_info
, connid_type
, dissector_tree
);
3208 display_connection_information(pinfo
, tvb
, enip_layer_tree
, conn_info
, connid_type
, item_length
);
3213 case CPF_ITEM_CIP_IDENTITY
:
3214 dissect_item_list_identity(pinfo
, tvb
, offset
, item_tree
);
3217 case CPF_ITEM_CIP_SECURITY
:
3218 dissect_item_cip_security_information(tvb
, offset
, item_tree
);
3221 case CPF_ITEM_SOCK_ADR_INFO_OT
: // Optional 3rd item for: Unconnected Messages
3222 case CPF_ITEM_SOCK_ADR_INFO_TO
:
3224 bool is_fwd_open
= (FwdOpenRequest
== true) || (FwdOpenReply
== true);
3225 dissect_item_sockaddr_info(pinfo
, tvb
, offset
, item_tree
, item_type_id
, is_fwd_open
);
3229 case CPF_ITEM_SEQUENCED_ADDRESS
: // 1st item for: Class 0/1 connected data
3231 dissect_item_sequenced_address(pinfo
, tvb
, offset
, item_tree
, &connid_type
, &conn_info
);
3234 case CPF_ITEM_LIST_SERVICES_RESP
:
3235 dissect_item_list_services_response(pinfo
, tvb
, offset
, item_tree
);
3239 proto_tree_add_item(item_tree
, hf_enip_cpf_data
, tvb
, offset
, item_length
, ENC_NA
);
3242 } /* end of switch ( item type ) */
3244 } /* end of if ( item length ) */
3246 offset
+= item_length
;
3247 } /* end of while ( item count ) */
3249 /* See if there is a CIP connection to establish */
3250 if (FwdOpenReply
== true)
3252 enip_request_info_t
* request_info
= (enip_request_info_t
*)p_get_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
);
3253 if (request_info
!= NULL
)
3255 enip_open_cip_connection(pinfo
, request_info
->cip_info
->connInfo
, request_info
->cip_info
->bService
& CIP_SC_MASK
);
3257 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
);
3259 else if (FwdOpenRequest
== true)
3261 p_remove_proto_data(wmem_file_scope(), pinfo
, proto_enip
, ENIP_REQUEST_INFO
);
3264 } /* end of dissect_cpf() */
3268 static enum enip_packet_type
3269 classify_packet(packet_info
*pinfo
)
3271 /* see if nature of packets can be derived from src/dst ports */
3272 /* if so, return as found */
3273 if (((ENIP_ENCAP_PORT
== pinfo
->srcport
&& ENIP_ENCAP_PORT
!= pinfo
->destport
)) ||
3274 ((ENIP_SECURE_PORT
== pinfo
->srcport
&& ENIP_SECURE_PORT
!= pinfo
->destport
)))
3276 return ENIP_RESPONSE_PACKET
;
3278 else if (((ENIP_ENCAP_PORT
!= pinfo
->srcport
&& ENIP_ENCAP_PORT
== pinfo
->destport
)) ||
3279 ((ENIP_SECURE_PORT
!= pinfo
->srcport
&& ENIP_SECURE_PORT
== pinfo
->destport
)))
3281 return ENIP_REQUEST_PACKET
;
3285 return ENIP_CANNOT_CLASSIFY
;
3290 get_enip_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
, int offset
, void *data _U_
)
3295 * Get the length of the data from the encapsulation header.
3297 plen
= tvb_get_letohs(tvb
, offset
+ 2);
3300 * That length doesn't include the encapsulation header itself;
3306 /* Code to actually dissect the packets */
3308 dissect_enip_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
3310 enum enip_packet_type packet_type
;
3311 uint16_t encap_cmd
, encap_data_length
;
3312 const char *pkt_type_str
;
3314 conversation_t
*conversation
;
3316 /* Set up structures needed to add the protocol subtree and manage it */
3317 proto_item
*ti
= NULL
;
3318 proto_tree
*enip_tree
, *header_tree
= NULL
, *csftree
;
3320 /* Make entries in Protocol column and Info column on summary display */
3321 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "ENIP");
3322 col_clear(pinfo
->cinfo
, COL_INFO
);
3324 encap_cmd
= tvb_get_letohs( tvb
, 0 );
3326 packet_type
= classify_packet(pinfo
);
3328 switch ( packet_type
)
3330 case ENIP_REQUEST_PACKET
:
3331 pkt_type_str
= "Req";
3334 case ENIP_RESPONSE_PACKET
:
3335 pkt_type_str
= "Rsp";
3338 case ENIP_CANNOT_CLASSIFY
:
3343 /* Add encapsulation command to info column */
3344 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, " | ", "%s (%s)",
3345 val_to_str(encap_cmd
, encap_cmd_vals
, "Unknown Command (0x%04x)"),
3349 * We need to track some state for this protocol on a per conversation
3350 * basis so we can do neat things like request/response tracking
3352 conversation
= find_or_create_conversation(pinfo
);
3355 * Attach that information to the conversation, and add
3356 * it to the list of information structures later before dissection.
3358 enip_request_key_t request_key
= {0};
3359 request_key
.requesttype
= packet_type
;
3360 request_key
.type
= EPDT_UNKNOWN
;
3361 request_key
.session_handle
= tvb_get_letohl( tvb
, 4 );
3362 request_key
.sender_context
= tvb_get_letoh64( tvb
, 12 );
3363 request_key
.conversation
= conversation
->conv_index
;
3365 /* create display subtree for the protocol */
3366 ti
= proto_tree_add_item(tree
, proto_enip
, tvb
, 0, -1, ENC_NA
);
3368 enip_tree
= proto_item_add_subtree(ti
, ett_enip
);
3370 /* Add encapsulation header tree */
3371 header_tree
= proto_tree_add_subtree( enip_tree
, tvb
, 0, 24, ett_enip
, NULL
, "Encapsulation Header");
3373 /* Add EtherNet/IP encapsulation header */
3374 proto_tree_add_item( header_tree
, hf_enip_command
, tvb
, 0, 2, ENC_LITTLE_ENDIAN
);
3376 encap_data_length
= tvb_get_letohs( tvb
, 2 );
3377 proto_tree_add_item( header_tree
, hf_enip_length
, tvb
, 2, 2, ENC_LITTLE_ENDIAN
);
3378 proto_tree_add_item( header_tree
, hf_enip_session
, tvb
, 4, 4, ENC_LITTLE_ENDIAN
);
3379 proto_tree_add_item( header_tree
, hf_enip_status
, tvb
, 8, 4, ENC_LITTLE_ENDIAN
);
3380 if ((encap_cmd
== LIST_IDENTITY
) &&
3381 /* Length of 0 probably indicates a request */
3382 ((encap_data_length
== 0) || (packet_type
== ENIP_REQUEST_PACKET
)))
3384 proto_tree_add_item( header_tree
, hf_enip_listid_delay
, tvb
, 12, 2, ENC_LITTLE_ENDIAN
);
3385 proto_tree_add_item( header_tree
, hf_enip_sendercontex
, tvb
, 14, 6, ENC_NA
);
3389 proto_tree_add_item( header_tree
, hf_enip_sendercontex
, tvb
, 12, 8, ENC_NA
);
3391 proto_tree_add_item( header_tree
, hf_enip_options
, tvb
, 20, 4, ENC_LITTLE_ENDIAN
);
3393 /* Append session and command to the protocol tree */
3394 proto_item_append_text( ti
, ", Session: 0x%08X, %s", tvb_get_letohl( tvb
, 4 ),
3395 val_to_str( encap_cmd
, encap_cmd_vals
, "Unknown Command (0x%04x)" ) );
3398 ** For some commands we want to add some info to the info column
3400 switch ( encap_cmd
)
3402 case REGISTER_SESSION
:
3403 case UNREGISTER_SESSION
:
3404 col_append_fstr( pinfo
->cinfo
, COL_INFO
, ", Session: 0x%08X",
3405 tvb_get_letohl( tvb
, 4 ) );
3409 /* The packet may have some command specific data, build a sub tree for it */
3410 csftree
= proto_tree_add_subtree( enip_tree
, tvb
, 24, encap_data_length
,
3411 ett_command_tree
, NULL
, "Command Specific Data");
3413 switch ( encap_cmd
)
3420 case LIST_INTERFACES
:
3421 if (packet_type
== ENIP_RESPONSE_PACKET
)
3423 dissect_cpf( &request_key
, encap_cmd
, tvb
, pinfo
, csftree
, tree
, enip_tree
, NULL
, 24, 0 );
3427 case REGISTER_SESSION
:
3428 proto_tree_add_item( csftree
, hf_enip_rs_version
, tvb
, 24, 2, ENC_LITTLE_ENDIAN
);
3429 proto_tree_add_item( csftree
, hf_enip_rs_optionflags
, tvb
, 26, 2, ENC_LITTLE_ENDIAN
);
3432 case UNREGISTER_SESSION
:
3436 proto_tree_add_item( csftree
, hf_enip_srrd_ifacehnd
, tvb
, 24, 4, ENC_LITTLE_ENDIAN
);
3437 proto_tree_add_item( csftree
, hf_enip_timeout
, tvb
, 28, 2, ENC_LITTLE_ENDIAN
);
3439 ifacehndl
= tvb_get_letohl( tvb
, 24 );
3440 dissect_cpf( &request_key
, encap_cmd
, tvb
, pinfo
, csftree
, tree
, enip_tree
, NULL
, 30, ifacehndl
);
3443 case SEND_UNIT_DATA
:
3444 proto_tree_add_item(csftree
, hf_enip_sud_ifacehnd
, tvb
, 24, 4, ENC_LITTLE_ENDIAN
);
3445 proto_tree_add_item( csftree
, hf_enip_timeout
, tvb
, 28, 2, ENC_LITTLE_ENDIAN
);
3447 ifacehndl
= tvb_get_letohl( tvb
, 24 );
3448 dissect_cpf( &request_key
, encap_cmd
, tvb
, pinfo
, csftree
, tree
, enip_tree
, ti
, 30, ifacehndl
);
3453 if (packet_type
== ENIP_RESPONSE_PACKET
)
3455 ssl_starttls_ack(dtls_handle
, pinfo
, enip_udp_handle
);
3460 /* Can not decode - Just show the data */
3461 proto_tree_add_item(header_tree
, hf_enip_encap_data
, tvb
, 24, encap_data_length
, ENC_NA
);
3464 } /* end of switch () */
3466 col_set_fence(pinfo
->cinfo
, COL_INFO
);
3468 return tvb_captured_length(tvb
);
3469 } /* end of dissect_enip_pdu() */
3472 dissect_enip_udp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
3474 /* An ENIP packet is at least 4 bytes long. */
3475 if (tvb_captured_length(tvb
) < 4)
3478 return dissect_enip_pdu(tvb
, pinfo
, tree
, data
);
3482 dissect_enip_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data
)
3484 // TCP connections for EtherNet/IP are typically open for extended periods of time.
3485 // This means that mostly likely, for real world traffic, a capture initiated for
3486 // EtherNet/IP traffic will start in the middle of a TCP connection. This check
3487 // ignores one byte TCP payloads because it is far more likely that a one byte TCP
3488 // payload is a TCP keep alive message, than a client actually sending real EtherNet/IP
3489 // messages in one byte chunks.
3490 if (tvb_captured_length(tvb
) < 2)
3493 tcp_dissect_pdus(tvb
, pinfo
, tree
, enip_desegment
, 4, get_enip_pdu_len
, dissect_enip_pdu
, data
);
3494 return tvb_captured_length(tvb
);
3497 /* Code to actually dissect the io packets*/
3499 dissect_enip_cipio(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
3501 /* Set up structures needed to add the protocol subtree and manage it */
3503 proto_tree
*enip_tree
;
3505 /* Make entries in Protocol column and Info column on summary display */
3506 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "CIP I/O");
3508 /* create display subtree for the protocol */
3509 ti
= proto_tree_add_item(tree
, proto_enip
, tvb
, 0, -1, ENC_NA
);
3511 enip_tree
= proto_item_add_subtree(ti
, ett_enip
);
3513 dissect_cpf( NULL
, 0xFFFF, tvb
, pinfo
, enip_tree
, tree
, enip_tree
, NULL
, 0, 0 );
3515 return tvb_captured_length(tvb
);
3520 dissect_dlr(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
3523 proto_tree
*dlr_tree
;
3524 uint8_t dlr_subtype
;
3525 uint8_t dlr_protover
;
3526 uint8_t dlr_frametype
;
3528 /* Make entries in Protocol column and Info column on summary display */
3529 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DLR");
3531 col_clear(pinfo
->cinfo
, COL_INFO
);
3533 /* Create display subtree for the protocol */
3534 ti
= proto_tree_add_item(tree
, proto_dlr
, tvb
, 0, -1, ENC_NA
);
3535 dlr_tree
= proto_item_add_subtree( ti
, ett_dlr
);
3537 /* Get values for the Common Frame Header Format */
3538 dlr_subtype
= tvb_get_uint8(tvb
, DLR_CFH_SUB_TYPE
);
3539 dlr_protover
= tvb_get_uint8(tvb
, DLR_CFH_PROTO_VERSION
);
3541 /* Dissect the Common Frame Header Format */
3542 proto_tree_add_uint( dlr_tree
, hf_dlr_ringsubtype
, tvb
, DLR_CFH_SUB_TYPE
, 1, dlr_subtype
);
3543 proto_tree_add_uint( dlr_tree
, hf_dlr_ringprotoversion
, tvb
, DLR_CFH_PROTO_VERSION
, 1, dlr_protover
);
3545 /* Get values for the DLR Message Payload Fields */
3546 dlr_frametype
= tvb_get_uint8(tvb
, DLR_MPF_FRAME_TYPE
);
3548 /* Dissect the DLR Message Payload Fields */
3549 proto_tree_add_item( dlr_tree
, hf_dlr_frametype
, tvb
, DLR_MPF_FRAME_TYPE
, 1, ENC_BIG_ENDIAN
);
3550 proto_tree_add_item( dlr_tree
, hf_dlr_sourceport
, tvb
, DLR_MPF_SOURCE_PORT
, 1, ENC_BIG_ENDIAN
);
3551 proto_tree_add_item( dlr_tree
, hf_dlr_sourceip
, tvb
, DLR_MPF_SOURCE_IP
, 4, ENC_BIG_ENDIAN
);
3552 proto_tree_add_item( dlr_tree
, hf_dlr_sequenceid
, tvb
, DLR_MPF_SEQUENCE_ID
, 4, ENC_BIG_ENDIAN
);
3554 /* Add frame type to col info */
3555 col_add_str(pinfo
->cinfo
, COL_INFO
,
3556 val_to_str(dlr_frametype
, dlr_frame_type_vals
, "Unknown (0x%04x)") );
3558 if ( dlr_frametype
== DLR_FT_BEACON
)
3561 proto_tree_add_item( dlr_tree
, hf_dlr_ringstate
, tvb
, DLR_BE_RING_STATE
, 1, ENC_BIG_ENDIAN
);
3562 proto_tree_add_item( dlr_tree
, hf_dlr_supervisorprecedence
, tvb
, DLR_BE_SUPERVISOR_PRECEDENCE
, 1, ENC_BIG_ENDIAN
);
3563 proto_tree_add_item( dlr_tree
, hf_dlr_beaconinterval
, tvb
, DLR_BE_BEACON_INTERVAL
, 4, ENC_BIG_ENDIAN
);
3564 proto_tree_add_item( dlr_tree
, hf_dlr_beacontimeout
, tvb
, DLR_BE_BEACON_TIMEOUT
, 4, ENC_BIG_ENDIAN
);
3565 proto_tree_add_item( dlr_tree
, hf_dlr_beaconreserved
, tvb
, DLR_BE_RESERVED
, 20, ENC_NA
);
3567 else if ( dlr_frametype
== DLR_FT_NEIGHBOR_REQ
)
3569 /* Neighbor_Check_Request */
3570 proto_tree_add_item( dlr_tree
, hf_dlr_nreqreserved
, tvb
, DLR_NREQ_RESERVED
, 30, ENC_NA
);
3572 else if ( dlr_frametype
== DLR_FT_NEIGHBOR_RES
)
3574 /* Neighbor_Check_Response */
3575 proto_tree_add_item( dlr_tree
, hf_dlr_nressourceport
, tvb
, DLR_NRES_SOURCE_PORT
, 1, ENC_BIG_ENDIAN
);
3576 proto_tree_add_item( dlr_tree
, hf_dlr_nresreserved
, tvb
, DLR_NRES_RESERVED
, 29, ENC_NA
);
3578 else if ( dlr_frametype
== DLR_FT_LINK_STAT
)
3580 /* Link_Status/Neighbor_Status */
3581 static int* const bits
[] = {
3582 &hf_dlr_lnknbrstatus_port1
,
3583 &hf_dlr_lnknbrstatus_port2
,
3584 &hf_dlr_lnknbrstatus_reserved
,
3585 &hf_dlr_lnknbrstatus_frame_type
,
3589 proto_tree_add_bitmask(dlr_tree
, tvb
, DLR_LNS_SOURCE_PORT
, hf_dlr_lnknbrstatus
, ett_dlr_lnknbrstatus_flags
, bits
, ENC_LITTLE_ENDIAN
);
3591 proto_tree_add_item( dlr_tree
, hf_dlr_lnknbrreserved
, tvb
, DLR_LNS_RESERVED
, 29, ENC_NA
);
3593 else if ( dlr_frametype
== DLR_FT_LOCATE_FLT
)
3596 proto_tree_add_item( dlr_tree
, hf_dlr_lfreserved
, tvb
, DLR_LF_RESERVED
, 30, ENC_NA
);
3598 else if ( dlr_frametype
== DLR_FT_ANNOUNCE
)
3601 proto_tree_add_item( dlr_tree
, hf_dlr_ringstate
, tvb
, DLR_AN_RING_STATE
, 1, ENC_BIG_ENDIAN
);
3602 proto_tree_add_item( dlr_tree
, hf_dlr_anreserved
, tvb
, DLR_AN_RESERVED
, 29, ENC_NA
);
3604 else if ( dlr_frametype
== DLR_FT_SIGN_ON
)
3612 nNumNodes
= tvb_get_ntohs(tvb
, DLR_SO_NUM_NODES
);
3614 proto_tree_add_uint( dlr_tree
, hf_dlr_sonumnodes
, tvb
, DLR_SO_NUM_NODES
, 2, nNumNodes
);
3616 /* Add each node in the list */
3617 for( nCnt
= 0, nOffset
= DLR_SO_NODE_1_MAC
; nCnt
< nNumNodes
; nCnt
++ )
3619 proto_tree_add_item( dlr_tree
, hf_dlr_somac
, tvb
, nOffset
, 6, ENC_NA
);
3621 proto_tree_add_item( dlr_tree
, hf_dlr_soip
, tvb
, nOffset
, 4, ENC_BIG_ENDIAN
);
3627 proto_tree_add_item( dlr_tree
, hf_dlr_soreserved
, tvb
, nOffset
, 42 - nOffset
, ENC_NA
);
3628 /* nOffset += (42 - nOffset); */
3631 else if ( dlr_frametype
== DLR_FT_ADVERTISE
)
3634 proto_tree_add_item( dlr_tree
, hf_dlr_advgatewaystate
, tvb
, DLR_ADV_GATEWAY_STATE
, 1, ENC_BIG_ENDIAN
);
3635 proto_tree_add_item( dlr_tree
, hf_dlr_advgatewayprecedence
, tvb
, DLR_ADV_GATEWAY_PRECEDENCE
, 1, ENC_BIG_ENDIAN
);
3636 proto_tree_add_item( dlr_tree
, hf_dlr_advadvertiseinterval
, tvb
, DLR_ADV_ADVERTISE_INTERVAL
, 4, ENC_BIG_ENDIAN
);
3637 proto_tree_add_item( dlr_tree
, hf_dlr_advadvertisetimeout
, tvb
, DLR_ADV_ADVERTISE_TIMEOUT
, 4, ENC_BIG_ENDIAN
);
3638 proto_tree_add_item( dlr_tree
, hf_dlr_advlearningupdateenable
, tvb
, DLR_ADV_LEARNING_UPDATE_ENABLE
, 1, ENC_BIG_ENDIAN
);
3639 proto_tree_add_item( dlr_tree
, hf_dlr_advreserved
, tvb
, DLR_ADV_RESERVED
, 19, ENC_NA
);
3641 else if ( dlr_frametype
== DLR_FT_FLUSH_TABLES
)
3643 proto_tree_add_item( dlr_tree
, hf_dlr_flushlearningupdateenable
, tvb
, DLR_FLUSH_LEARNING_UPDATE_ENABLE
, 1, ENC_BIG_ENDIAN
);
3644 proto_tree_add_item( dlr_tree
, hf_dlr_flushreserved
, tvb
, DLR_FLUSH_RESERVED
, 29, ENC_NA
);
3646 else if ( dlr_frametype
== DLR_FT_LEARNING_UPDATE
)
3648 proto_tree_add_item( dlr_tree
, hf_dlr_learnreserved
, tvb
, DLR_LEARN_RESERVED
, 34, ENC_NA
);
3652 /* Unknown Frame type */
3655 return tvb_captured_length(tvb
);
3657 } /* end of dissect_dlr() */
3659 static int dissect_cip_class1(tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
)
3661 cip_conn_info_t conn_info
;
3662 memset(&conn_info
, 0, sizeof(conn_info
));
3663 conn_info
.TransportClass_trigger
= 1;
3665 cip_io_data_input io_data_input
;
3666 io_data_input
.conn_info
= &conn_info
;
3667 io_data_input
.connid_type
= ECIDT_UNKNOWN
;
3669 return dissect_cip_io_generic(tvb
, pinfo
, tree
, &io_data_input
);
3672 /* Register the protocol with Wireshark */
3674 /* this format is require because a script is used to build the C function
3675 that calls all the protocol registration.
3679 proto_register_enip(void)
3681 /* Setup list of header fields */
3682 static hf_register_info hf
[] = {
3684 { "Command", "enip.command",
3685 FT_UINT16
, BASE_HEX
, VALS(encap_cmd_vals
), 0,
3686 "Encapsulation command", HFILL
}},
3689 { "Length", "enip.length",
3690 FT_UINT16
, BASE_DEC
, NULL
, 0,
3691 "Encapsulation length", HFILL
}},
3694 { "Session Handle", "enip.session",
3695 FT_UINT32
, BASE_HEX
, NULL
, 0,
3696 "Session identification", HFILL
}},
3699 { "Status", "enip.status",
3700 FT_UINT32
, BASE_HEX
, VALS(encap_status_vals
), 0,
3701 "Status code", HFILL
}},
3703 { &hf_enip_sendercontex
,
3704 { "Sender Context", "enip.context",
3705 FT_BYTES
, BASE_NONE
, NULL
, 0,
3706 "Information pertinent to the sender", HFILL
}},
3708 { &hf_enip_listid_delay
,
3709 { "Max Response Delay", "enip.listid_delay",
3710 FT_UINT16
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_milliseconds
), 0,
3711 "Maximum random delay allowed by target", HFILL
}},
3714 { "Options", "enip.options",
3715 FT_UINT32
, BASE_HEX
, NULL
, 0,
3716 "Options flags", HFILL
}},
3718 { &hf_enip_encapver
,
3719 { "Encapsulation Protocol Version", "enip.encapver",
3720 FT_UINT16
, BASE_DEC
, NULL
, 0,
3723 { &hf_enip_sinfamily
,
3724 { "sin_family", "enip.sinfamily",
3725 FT_UINT16
, BASE_DEC
, NULL
, 0,
3726 "Socket Address.Sin Family", HFILL
}},
3729 { "sin_port", "enip.sinport",
3730 FT_UINT16
, BASE_DEC
, NULL
, 0,
3731 "Socket Address.Sin Port", HFILL
}},
3734 { "sin_addr", "enip.sinaddr",
3735 FT_IPv4
, BASE_NONE
, NULL
, 0,
3736 "Socket Address.Sin Addr", HFILL
}},
3739 { "sin_zero", "enip.sinzero",
3740 FT_BYTES
, BASE_NONE
, NULL
, 0,
3741 "Socket Address.Sin Zero", HFILL
}},
3744 { "Timeout", "enip.timeout",
3745 FT_UINT16
, BASE_DEC
, NULL
, 0,
3746 "Encapsulation Timeout", HFILL
}},
3748 { &hf_enip_encap_data
,
3749 { "Encap Data", "enip.encap_data",
3750 FT_BYTES
, BASE_NONE
| BASE_ALLOW_ZERO
, NULL
, 0,
3751 "Encapsulation Data", HFILL
}},
3753 /* List Services Reply */
3754 { &hf_enip_lsr_capaflags
,
3755 { "Capability Flags", "enip.lsr.capaflags",
3756 FT_UINT16
, BASE_HEX
, NULL
, 0,
3757 "ListServices Reply: Capability Flags", HFILL
}},
3760 { "Supports CIP Encapsulation via TCP", "enip.lsr.capaflags.tcp",
3761 FT_BOOLEAN
, 16, NULL
, 0x0020,
3762 "ListServices Reply: Supports CIP Encapsulation via TCP", HFILL
}},
3765 { "Supports CIP Class 0 or 1 via UDP", "enip.lsr.capaflags.udp",
3766 FT_BOOLEAN
, 16, NULL
, 0x0100,
3767 "ListServices Reply: Supports CIP Class 0 or 1 via UDP", HFILL
}},
3769 { &hf_enip_lsr_servicename
,
3770 { "Name of Service", "enip.lsr.servicename",
3771 FT_STRING
, BASE_NONE
, NULL
, 0,
3772 "ListServices Reply: Name of Service", HFILL
}},
3774 /* Register Session */
3775 { &hf_enip_rs_version
,
3776 { "Protocol Version", "enip.rs.version",
3777 FT_UINT16
, BASE_DEC
, NULL
, 0,
3778 "Register Session: Protocol Version", HFILL
}},
3780 { &hf_enip_rs_optionflags
,
3781 { "Option Flags", "enip.rs.flags",
3782 FT_UINT16
, BASE_HEX
, NULL
, 0,
3783 "Register Session: Option Flags", HFILL
}},
3785 /* Send Request/Reply Data */
3786 { &hf_enip_srrd_ifacehnd
,
3787 { "Interface Handle", "enip.srrd.iface",
3788 FT_UINT32
, BASE_HEX
, VALS(enip_interface_handle_vals
), 0,
3789 "SendRRData: Interface handle", HFILL
}},
3791 /* Send Unit Data */
3792 { &hf_enip_sud_ifacehnd
,
3793 { "Interface Handle", "enip.sud.iface",
3794 FT_UINT32
, BASE_HEX
, VALS(enip_interface_handle_vals
), 0,
3795 "SendUnitData: Interface handle", HFILL
}},
3797 /* List identity reply */
3798 { &hf_enip_lir_vendor
,
3799 { "Vendor ID", "enip.lir.vendor",
3800 FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &cip_vendor_vals_ext
, 0,
3801 "ListIdentity Reply: Vendor ID", HFILL
}},
3803 { &hf_enip_lir_devtype
,
3804 { "Device Type", "enip.lir.devtype",
3805 FT_UINT16
, BASE_DEC
|BASE_EXT_STRING
, &cip_devtype_vals_ext
, 0,
3806 "ListIdentity Reply: Device Type", HFILL
}},
3808 { &hf_enip_lir_prodcode
,
3809 { "Product Code", "enip.lir.prodcode",
3810 FT_UINT16
, BASE_DEC
, NULL
, 0,
3811 "ListIdentity Reply: Product Code", HFILL
}},
3813 { &hf_enip_lir_revision
,
3814 { "Revision", "enip.lir.revision",
3815 FT_UINT16
, BASE_CUSTOM
, CF_FUNC(enip_fmt_lir_revision
), 0,
3816 "ListIdentity Reply: Revision", HFILL
}},
3818 { &hf_enip_lir_status
,
3819 { "Status", "enip.lir.status",
3820 FT_UINT16
, BASE_HEX
, NULL
, 0,
3821 "ListIdentity Reply: Status", HFILL
}},
3823 { &hf_enip_lir_serial
,
3824 { "Serial Number", "enip.lir.serial",
3825 FT_UINT32
, BASE_HEX
, NULL
, 0,
3826 "ListIdentity Reply: Serial Number", HFILL
}},
3828 { &hf_enip_lir_namelen
,
3829 { "Product Name Length", "enip.lir.namelen",
3830 FT_UINT8
, BASE_DEC
, NULL
, 0,
3831 "ListIdentity Reply: Product Name Length", HFILL
}},
3833 { &hf_enip_lir_name
,
3834 { "Product Name", "enip.lir.name",
3835 FT_STRING
, BASE_NONE
, NULL
, 0,
3836 "ListIdentity Reply: Product Name", HFILL
}},
3838 { &hf_enip_lir_state
,
3839 { "State", "enip.lir.state",
3840 FT_UINT8
, BASE_HEX
, NULL
, 0,
3841 "ListIdentity Reply: State", HFILL
}},
3843 { &hf_enip_security_profiles
,
3844 { "Security Profiles", "enip.security_profiles",
3845 FT_UINT16
, BASE_HEX
, NULL
, 0,
3848 { &hf_enip_security_profiles_eip_integrity
,
3849 { "EtherNet/IP Integrity Profile", "enip.security_profiles.eip_integrity",
3850 FT_BOOLEAN
, 16, TFS(&tfs_supported_not_supported
), 0x0001,
3853 { &hf_enip_security_profiles_eip_confidentiality
,
3854 { "EtherNet/IP Confidentiality Profile", "enip.security_profiles.eip_confidentiality",
3855 FT_BOOLEAN
, 16, TFS(&tfs_supported_not_supported
), 0x0002,
3858 { &hf_enip_security_profiles_cip_authorization
,
3859 { "CIP Authorization Profile", "enip.security_profiles.cip_authorization",
3860 FT_BOOLEAN
, 16, TFS(&tfs_supported_not_supported
), 0x0004,
3863 { &hf_enip_security_profiles_cip_user_authentication
,
3864 { "CIP User Authentication Profile", "enip.security_profiles.cip_user_authentication",
3865 FT_BOOLEAN
, 16, TFS(&tfs_supported_not_supported
), 0x0008,
3868 { &hf_enip_security_profiles_resource_constrained
,
3869 { "Resource-Constrained CIP Security Profile", "enip.security_profiles.resource_constrained",
3870 FT_BOOLEAN
, 16, TFS(&tfs_supported_not_supported
), 0x0010,
3873 { &hf_enip_security_profiles_reserved
,
3874 { "Reserved", "enip.security_profiles.reserved",
3875 FT_UINT16
, BASE_HEX
, NULL
, 0xFFE0,
3878 { &hf_enip_cip_security_state
,
3879 { "CIP Security State", "enip.cip_security_state",
3880 FT_UINT8
, BASE_DEC
, VALS(cip_security_state_vals
), 0,
3883 { &hf_enip_eip_security_state
,
3884 { "EtherNet/IP Security State", "enip.eip_security_state",
3885 FT_UINT8
, BASE_DEC
, VALS(eip_security_state_vals
), 0,
3888 { &hf_ingress_egress_num_ranges
,
3889 { "Number of Port Ranges", "cip.ingress_egress.num_port_ranges",
3890 FT_UINT16
, BASE_DEC
, NULL
, 0,
3892 { &hf_ingress_egress_port_range_low
,
3893 { "Port Range Low", "cip.ingress_egress.port_range.low",
3894 FT_UINT16
, BASE_DEC
, NULL
, 0,
3896 { &hf_ingress_egress_port_range_high
,
3897 { "Port Range High", "cip.ingress_egress.port_range.high",
3898 FT_UINT16
, BASE_DEC
, NULL
, 0,
3900 { &hf_ingress_egress_num_rules
,
3901 { "Number of Rules", "cip.ingress_egress.num_rules",
3902 FT_UINT16
, BASE_DEC
, NULL
, 0,
3904 { &hf_ingress_egress_rule_string
,
3905 { "Rule String", "cip.ingress_egress.rule_string",
3906 FT_STRING
, BASE_NONE
, NULL
, 0,
3908 { &hf_ingress_egress_rules_change_count
,
3909 { "Rules Change Count", "cip.ingress_egress.rules_change_count",
3910 FT_UINT32
, BASE_DEC
, NULL
, 0,
3912 { &hf_ingress_egress_apply_behavior
,
3913 { "Apply Behavior", "cip.ingress_egress.apply_behavior",
3914 FT_UINT32
, BASE_HEX
, NULL
, 0,
3916 { &hf_ingress_egress_apply_behav_break_connections
,
3917 { "Break Connections", "cip.ingress_egress.apply_behavior.break_connections",
3918 FT_BOOLEAN
, 32, TFS(&tfs_enabled_disabled
), 0x00000001,
3920 { &hf_ingress_egress_apply_behav_reserved
,
3921 { "Reserved", "cip.ingress_egress.apply_behavior.reserved",
3922 FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFFFFE,
3924 { &hf_ingress_egress_ins_num
,
3925 { "Number of Instance Rules", "cip.ingress_egress.num_instances",
3926 FT_UINT16
, BASE_DEC
, NULL
, 0,
3928 { &hf_ingress_egress_ins
,
3929 { "Instance Number", "cip.ingress_egress.instance",
3930 FT_UINT16
, BASE_DEC
, NULL
, 0,
3933 { &hf_enip_iana_port_state_flags
,
3934 { "IANA Port State", "enip.iana_port_state_flags",
3935 FT_UINT8
, BASE_HEX
, NULL
, 0,
3938 { &hf_enip_iana_port_state_flags_tcp_44818
,
3939 { "44818/tcp", "enip.security_profiles.iana_port_state_flags.tcp_44818",
3940 FT_BOOLEAN
, 8, TFS(&tfs_open_closed
), 0x01,
3943 { &hf_enip_iana_port_state_flags_udp_44818
,
3944 { "44818/udp", "enip.security_profiles.iana_port_state_flags.udp_44818",
3945 FT_BOOLEAN
, 8, TFS(&tfs_open_closed
), 0x02,
3948 { &hf_enip_iana_port_state_flags_udp_2222
,
3949 { "2222/udp", "enip.security_profiles.iana_port_state_flags.udp_2222",
3950 FT_BOOLEAN
, 8, TFS(&tfs_open_closed
), 0x04,
3953 { &hf_enip_iana_port_state_flags_tcp_2221
,
3954 { "2221/tcp", "enip.security_profiles.iana_port_state_flags.tcp_2221",
3955 FT_BOOLEAN
, 8, TFS(&tfs_open_closed
), 0x08,
3958 { &hf_enip_iana_port_state_flags_udp_2221
,
3959 { "2221/udp", "enip.security_profiles.iana_port_state_flags.udp_2221",
3960 FT_BOOLEAN
, 8, TFS(&tfs_open_closed
), 0x10,
3963 { &hf_enip_iana_port_state_flags_reserved
,
3964 { "Reserved", "enip.iana_port_state_flags.reserved",
3965 FT_UINT8
, BASE_HEX
, NULL
, 0xE0,
3968 /* Common Packet Format */
3969 { &hf_enip_cpf_itemcount
,
3970 { "Item Count", "enip.cpf.itemcount",
3971 FT_UINT16
, BASE_DEC
, NULL
, 0,
3972 "Common Packet Format: Item Count", HFILL
}},
3974 { &hf_enip_cpf_typeid
,
3975 { "Type ID", "enip.cpf.typeid",
3976 FT_UINT16
, BASE_HEX
, VALS(cpf_type_vals
), 0,
3977 "Common Packet Format: Type of encapsulated item", HFILL
}},
3979 { &hf_enip_cpf_length
,
3980 { "Length", "enip.cpf.length",
3981 FT_UINT16
, BASE_DEC
, NULL
, 0,
3982 "Common Packet Format: Length", HFILL
}},
3984 /* Connected Data Item */
3985 { &hf_cip_sequence_count
,
3986 { "CIP Sequence Count", "cip.seq",
3987 FT_UINT16
, BASE_DEC
, NULL
, 0,
3990 /* Connection Address Item */
3991 { &hf_enip_cpf_cai_connid
,
3992 { "Connection ID", "enip.cpf.cai.connid",
3993 FT_UINT32
, BASE_HEX
, NULL
, 0,
3994 "Common Packet Format: Connection Address Item, Connection Identifier", HFILL
}},
3996 { &hf_enip_cpf_ucmm_request
,
3997 { "Request/Response", "enip.cpf.ucmm.request",
3998 FT_UINT16
, BASE_DEC
, VALS(cip_sc_rr
), 0x8000,
3999 "Common Packet Format: UCMM Request/Response", HFILL
}},
4001 { &hf_enip_cpf_ucmm_msg_type
,
4002 { "Unconn Msg Type", "enip.cpf.ucmm.msg_type",
4003 FT_UINT16
, BASE_DEC
, VALS(unconn_msg_type_vals
), 0x7FFF,
4004 "Common Packet Format: UCMM Transaction ID", HFILL
}},
4006 { &hf_enip_cpf_ucmm_trans_id
,
4007 { "Transaction ID", "enip.cpf.ucmm.trans_id",
4008 FT_UINT32
, BASE_HEX
, NULL
, 0,
4009 "Common Packet Format: UCMM Transaction ID", HFILL
}},
4011 { &hf_enip_cpf_ucmm_status
,
4012 { "UCMM Status", "enip.cpf.ucmm.status",
4013 FT_UINT32
, BASE_HEX
, VALS(encap_status_vals
), 0,
4014 "Common Packet Format: UCMM Status", HFILL
}},
4016 /* Sequenced Address Type */
4017 { &hf_enip_cpf_sai_connid
,
4018 { "Connection ID", "enip.cpf.sai.connid",
4019 FT_UINT32
, BASE_HEX
, NULL
, 0,
4020 "Common Packet Format: Sequenced Address Item, Connection Identifier", HFILL
}},
4021 { &hf_cip_connid
, { "Connection ID", "cip.connid", FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
4023 { &hf_enip_cpf_sai_seqnum
,
4024 { "Encapsulation Sequence Number", "enip.cpf.sai.seq",
4025 FT_UINT32
, BASE_DEC
, NULL
, 0,
4026 "Common Packet Format: Sequenced Address Item, Sequence Number", HFILL
}},
4028 { &hf_enip_cpf_data
,
4029 { "Data", "enip.cpf.data",
4030 FT_BYTES
, BASE_NONE
, NULL
, 0,
4031 "Common Packet Format: Unknown Data", HFILL
}},
4033 /* Request/Response Matching */
4034 { &hf_enip_response_in
,
4035 { "Response In", "enip.response_in",
4036 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x0,
4037 "The response to this ENIP request is in this frame", HFILL
}},
4039 { &hf_enip_response_to
,
4040 { "Request In", "enip.response_to",
4041 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x0,
4042 "This is a response to the ENIP request in this frame", HFILL
}},
4045 { "Time", "enip.time",
4046 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
4047 "The time between the Call and the Reply", HFILL
}},
4049 { &hf_enip_fwd_open_in
,
4050 { "Forward Open Request In", "enip.fwd_open_in",
4051 FT_FRAMENUM
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
4053 // Generated API data.
4054 { &hf_cip_cm_ot_api
, { "O->T API", "cip.cm.otapi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
} },
4055 { &hf_cip_cm_to_api
, { "T->O API", "cip.cm.toapi", FT_UINT32
, BASE_CUSTOM
, CF_FUNC(cip_rpi_api_fmt
), 0, NULL
, HFILL
} },
4057 { &hf_cip_connection
,
4058 { "CIP Connection Index", "cip.connection",
4059 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
4063 { "Data", "cipio.data",
4064 FT_BYTES
, BASE_NONE
|BASE_ALLOW_ZERO
, NULL
, 0x0,
4068 { "Status", "cip.tcpip.status",
4069 FT_UINT32
, BASE_HEX
, NULL
, 0,
4072 { &hf_tcpip_status_interface_config
,
4073 { "Interface Configuration Status", "cip.tcpip.status.interface_config",
4074 FT_UINT32
, BASE_DEC
, VALS(enip_tcpip_status_interface_config_vals
), 0x0000000F,
4077 { &hf_tcpip_status_mcast_pending
,
4078 { "MCast Pending", "cip.tcpip.status.mcast_pending",
4079 FT_BOOLEAN
, 32, NULL
, 0x00000010,
4082 { &hf_tcpip_status_interface_config_pending
,
4083 { "Interface Configuration Pending", "cip.tcpip.status.interface_config_pending",
4084 FT_BOOLEAN
, 32, NULL
, 0x00000020,
4087 { &hf_tcpip_status_acd
,
4088 { "ACD Status", "cip.tcpip.status.acd",
4089 FT_UINT32
, BASE_DEC
, VALS(enip_tcpip_status_acd_vals
), 0x00000040,
4092 { &hf_tcpip_acd_fault
,
4093 { "ACD Fault", "cip.tcpip.status.acd_fault",
4094 FT_BOOLEAN
, 32, NULL
, 0x00000080,
4097 { &hf_tcpip_status_iana_port_admin_change
,
4098 { "IANA Port Admin Change Pending", "cip.tcpip.status.iana_port_admin",
4099 FT_BOOLEAN
, 32, NULL
, 0x00000100,
4102 { &hf_tcpip_status_iana_protocol_admin_change
,
4103 { "IANA Protocol Admin Change Pending", "cip.tcpip.status.iana_protocol_admin",
4104 FT_BOOLEAN
, 32, NULL
, 0x00000200,
4107 { &hf_tcpip_status_reserved
,
4108 { "Reserved", "cip.tcpip.status.reserved",
4109 FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFFC00,
4112 { &hf_tcpip_config_cap
,
4113 { "Configuration Capability", "cip.tcpip.config_cap",
4114 FT_UINT32
, BASE_HEX
, NULL
, 0,
4117 { &hf_tcpip_config_cap_bootp
,
4118 { "BOOTP Client", "cip.tcpip.config_cap.bootp",
4119 FT_BOOLEAN
, 32, NULL
, 0x00000001,
4122 { &hf_tcpip_config_cap_dns
,
4123 { "DNS Client", "cip.tcpip.config_cap.dns",
4124 FT_BOOLEAN
, 32, NULL
, 0x00000002,
4127 { &hf_tcpip_config_cap_dhcp
,
4128 { "DHCP Client", "cip.tcpip.config_cap.dhcp",
4129 FT_BOOLEAN
, 32, NULL
, 0x00000004,
4132 { &hf_tcpip_config_cap_dhcp_dns_update
,
4133 { "DHCP-DNS Update", "cip.tcpip.config_cap.dhcp_dns_update",
4134 FT_BOOLEAN
, 32, NULL
, 0x00000008,
4137 { &hf_tcpip_config_cap_config_settable
,
4138 { "Configuration Settable", "cip.tcpip.config_cap.config_settable",
4139 FT_BOOLEAN
, 32, NULL
, 0x00000010,
4142 { &hf_tcpip_config_cap_hardware_config
,
4143 { "Hardware Configurable", "cip.tcpip.config_cap.hardware_config",
4144 FT_BOOLEAN
, 32, NULL
, 0x00000020,
4147 { &hf_tcpip_config_cap_interface_reset
,
4148 { "Interface Configuration Change Requires Reset", "cip.tcpip.config_cap.interface_reset",
4149 FT_BOOLEAN
, 32, NULL
, 0x00000040,
4152 { &hf_tcpip_config_cap_acd
,
4153 { "ACD Capable", "cip.tcpip.config_cap.acd",
4154 FT_BOOLEAN
, 32, NULL
, 0x00000080,
4157 { &hf_tcpip_config_cap_reserved
,
4158 { "Reserved", "cip.tcpip.config_cap.reserved",
4159 FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFFF00,
4162 { &hf_tcpip_config_control
,
4163 { "Configuration Control", "cip.tcpip.config_control",
4164 FT_UINT32
, BASE_HEX
, NULL
, 0,
4167 { &hf_tcpip_config_control_config
,
4168 { "Configuration Method", "cip.tcpip.config_control.config",
4169 FT_UINT32
, BASE_DEC
, VALS(enip_tcpip_config_control_config_vals
), 0x0000000F,
4172 { &hf_tcpip_config_control_dns
,
4173 { "DNS Enable", "cip.tcpip.config_control.dns",
4174 FT_BOOLEAN
, 32, NULL
, 0x00000010,
4177 { &hf_tcpip_config_control_reserved
,
4178 { "Reserved", "cip.tcpip.config_control.reserved",
4179 FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFFFE0,
4182 { &hf_tcpip_ic_ip_addr
,
4183 { "IP Address", "cip.tcpip.ip_addr",
4184 FT_IPv4
, BASE_NONE
, NULL
, 0,
4187 { &hf_tcpip_ic_subnet_mask
,
4188 { "Subnet Mask", "cip.tcpip.subnet_mask",
4189 FT_IPv4
, BASE_NETMASK
, NULL
, 0,
4192 { &hf_tcpip_ic_gateway
,
4193 { "Gateway", "cip.tcpip.gateway",
4194 FT_IPv4
, BASE_NONE
, NULL
, 0,
4197 { &hf_tcpip_ic_name_server
,
4198 { "Name Server", "cip.tcpip.name_server",
4199 FT_IPv4
, BASE_NONE
, NULL
, 0,
4202 { &hf_tcpip_ic_name_server2
,
4203 { "Name Server2", "cip.tcpip.name_server2",
4204 FT_IPv4
, BASE_NONE
, NULL
, 0,
4207 { &hf_tcpip_ic_domain_name
,
4208 { "Domain Name", "cip.tcpip.domain_name",
4209 FT_STRING
, BASE_NONE
, NULL
, 0,
4212 { &hf_tcpip_hostname
,
4213 { "Hostname", "cip.tcpip.hostname",
4214 FT_STRING
, BASE_NONE
, NULL
, 0,
4217 { &hf_tcpip_snn_timestamp
,
4218 { "Safety Network Number (Timestamp)", "cip.tcpip.snn.timestamp",
4219 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0,
4223 { &hf_tcpip_snn_date
,
4224 { "Safety Network Number (Manual) Date", "cip.tcpip.snn.date",
4225 FT_UINT16
, BASE_HEX
, VALS(cipsafety_snn_date_vals
), 0,
4229 { &hf_tcpip_snn_time
,
4230 { "Safety Network Number (Manual) Time", "cip.tcpip.snn.time",
4231 FT_UINT32
, BASE_HEX
, NULL
, 0,
4235 { &hf_tcpip_ttl_value
,
4236 { "TTL Value", "cip.tcpip.ttl_value",
4237 FT_UINT8
, BASE_DEC
, NULL
, 0,
4240 { &hf_tcpip_mcast_alloc
,
4241 { "Alloc Control", "cip.tcpip.mcast.alloc",
4242 FT_UINT8
, BASE_DEC
, VALS(enip_tcpip_mcast_alloc_vals
), 0,
4245 { &hf_tcpip_mcast_reserved
,
4246 { "Reserved", "cip.tcpip.mcast.reserved",
4247 FT_UINT8
, BASE_HEX
, NULL
, 0,
4250 { &hf_tcpip_mcast_num_mcast
,
4251 { "Num MCast", "cip.tcpip.mcast.num_mcast",
4252 FT_UINT16
, BASE_DEC
, NULL
, 0,
4255 { &hf_tcpip_mcast_addr_start
,
4256 { "MCast Start Addr", "cip.tcpip.mcast.addr_start",
4257 FT_IPv4
, BASE_NONE
, NULL
, 0,
4260 { &hf_tcpip_select_acd
,
4261 { "Select ACD", "cip.tcpip.select_acd",
4262 FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_enabled_disabled
), 0,
4265 { &hf_tcpip_lcd_acd_activity
,
4266 { "ACD Activity", "cip.tcpip.last_conflict.acd_activity",
4267 FT_UINT8
, BASE_DEC
, VALS(enip_tcpip_acd_activity_vals
), 0,
4270 { &hf_tcpip_lcd_remote_mac
,
4271 { "RemoteMAC", "cip.tcpip.last_conflict.remote_mac",
4272 FT_ETHER
, BASE_NONE
, NULL
, 0,
4275 { &hf_tcpip_lcd_arp_pdu
,
4276 { "Arp PDU", "cip.tcpip.last_conflict.arp_pdu",
4277 FT_BYTES
, BASE_NONE
, NULL
, 0,
4280 { &hf_tcpip_quick_connect
,
4281 { "Ethernet/IP Quick Connection", "cip.tcpip.quick_connect",
4282 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), 0x1,
4285 { &hf_tcpip_encap_inactivity
,
4286 { "Encapsulation Inactivity Timeout", "cip.tcpip.encap_inactivity",
4287 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
4290 { &hf_tcpip_port_count
, { "Port Count", "cip.tcpip.port_count", FT_UINT8
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
4291 { &hf_tcpip_port_name
, { "Port Name", "cip.tcpip.port_name", FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
} },
4292 { &hf_tcpip_port_number
, { "Port Number", "cip.tcpip.port_number", FT_UINT16
, BASE_DEC
, NULL
, 0, NULL
, HFILL
} },
4293 { &hf_tcpip_port_protocol
, { "Protocol", "cip.tcpip.protocol", FT_UINT8
, BASE_DEC
| BASE_EXT_STRING
, &ipproto_val_ext
, 0, NULL
, HFILL
} },
4294 { &hf_tcpip_port_admin_state
, { "Admin State", "cip.tcpip.admin_state", FT_BOOLEAN
, BASE_NONE
, TFS(&tfs_open_closed
), 0, NULL
, HFILL
} },
4296 { &hf_tcpip_port_admin_capability
, { "Admin Capability", "cip.tcpip.admin_capability", FT_UINT8
, BASE_HEX
, NULL
, 0, NULL
, HFILL
} },
4297 { &hf_tcpip_admin_capability_configurable
, { "Configurable", "cip.tcpip.admin_capability.configurable", FT_BOOLEAN
, 8, NULL
, 0x01, NULL
, HFILL
} },
4298 { &hf_tcpip_admin_capability_reset_required
, { "Reset Required", "cip.tcpip.admin_capability.reset_required", FT_BOOLEAN
, 8, NULL
, 0x02, NULL
, HFILL
} },
4299 { &hf_tcpip_admin_capability_reserved
, { "Reserved", "cip.tcpip.admin_capability_reserved", FT_UINT8
, BASE_HEX
, NULL
, 0xFC, NULL
, HFILL
} },
4301 { &hf_elink_interface_speed
,
4302 { "Interface Speed", "cip.elink.interface_speed",
4303 FT_UINT32
, BASE_DEC
, NULL
, 0,
4306 { &hf_elink_interface_flags
,
4307 { "Interface Flags", "cip.elink.iflags",
4308 FT_UINT32
, BASE_HEX
, NULL
, 0,
4311 { &hf_elink_iflags_link_status
,
4312 { "Link Status", "cip.elink.iflags.link_status",
4313 FT_BOOLEAN
, 32, TFS(&tfs_active_inactive
), 0x00000001,
4316 { &hf_elink_iflags_duplex
,
4317 { "Duplex", "cip.elink.iflags.duplex",
4318 FT_UINT32
, BASE_DEC
, VALS(enip_elink_duplex_vals
), 0x00000002,
4321 { &hf_elink_iflags_neg_status
,
4322 { "Negotiation Status", "cip.elink.iflags.neg_status",
4323 FT_UINT32
, BASE_DEC
, VALS(enip_elink_iflags_neg_status_vals
), 0x0000001C,
4326 { &hf_elink_iflags_manual_reset
,
4327 { "Manual Reset Required", "cip.elink.iflags.manual_reset",
4328 FT_UINT32
, BASE_DEC
, VALS(enip_elink_iflags_reset_vals
), 0x00000020,
4331 { &hf_elink_iflags_local_hw_fault
,
4332 { "Local Hardware Fault", "cip.elink.iflags.local_hw_fault",
4333 FT_UINT32
, BASE_DEC
, VALS(enip_elink_iflags_hw_fault_vals
), 0x00000040,
4336 { &hf_elink_iflags_reserved
,
4337 { "Reserved", "cip.elink.iflags.reserved",
4338 FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFFF80,
4341 { &hf_elink_physical_address
,
4342 { "Physical Address", "cip.elink.physical_address",
4343 FT_ETHER
, BASE_NONE
, NULL
, 0,
4346 { &hf_elink_icount_in_octets
,
4347 { "In Octets", "cip.elink.icount.in_octets",
4348 FT_UINT32
, BASE_DEC
, NULL
, 0,
4351 { &hf_elink_icount_in_ucast
,
4352 { "In Ucast Packets", "cip.elink.icount.in_ucast",
4353 FT_UINT32
, BASE_DEC
, NULL
, 0,
4356 { &hf_elink_icount_in_nucast
,
4357 { "In NUcast Packets", "cip.elink.icount.in_nucast",
4358 FT_UINT32
, BASE_DEC
, NULL
, 0,
4361 { &hf_elink_icount_in_discards
,
4362 { "In Discards", "cip.elink.icount.in_discards",
4363 FT_UINT32
, BASE_DEC
, NULL
, 0,
4366 { &hf_elink_icount_in_errors
,
4367 { "In Errors", "cip.elink.icount.in_errors",
4368 FT_UINT32
, BASE_DEC
, NULL
, 0,
4371 { &hf_elink_icount_in_unknown_protos
,
4372 { "In Unknown Protos", "cip.elink.icount.in_unknown_protos",
4373 FT_UINT32
, BASE_DEC
, NULL
, 0,
4376 { &hf_elink_icount_out_octets
,
4377 { "Out Octets", "cip.elink.icount.out_octets",
4378 FT_UINT32
, BASE_DEC
, NULL
, 0,
4381 { &hf_elink_icount_out_ucast
,
4382 { "Out Ucast Packets", "cip.elink.icount.out_ucast",
4383 FT_UINT32
, BASE_DEC
, NULL
, 0,
4386 { &hf_elink_icount_out_nucast
,
4387 { "Out NUcast Packets", "cip.elink.icount.out_nucast",
4388 FT_UINT32
, BASE_DEC
, NULL
, 0,
4391 { &hf_elink_icount_out_discards
,
4392 { "Out Discards", "cip.elink.icount.out_discards",
4393 FT_UINT32
, BASE_DEC
, NULL
, 0,
4396 { &hf_elink_icount_out_errors
,
4397 { "Out Errors", "cip.elink.icount.out_errors",
4398 FT_UINT32
, BASE_DEC
, NULL
, 0,
4401 { &hf_elink_mcount_alignment_errors
,
4402 { "Alignment Errors", "cip.elink.mcount.alignment_errors",
4403 FT_UINT32
, BASE_DEC
, NULL
, 0,
4406 { &hf_elink_mcount_fcs_errors
,
4407 { "FCS Errors", "cip.elink.mcount.fcs_errors",
4408 FT_UINT32
, BASE_DEC
, NULL
, 0,
4411 { &hf_elink_mcount_single_collisions
,
4412 { "Single Collisions", "cip.elink.mcount.single_collisions",
4413 FT_UINT32
, BASE_DEC
, NULL
, 0,
4416 { &hf_elink_mcount_multiple_collisions
,
4417 { "Multiple Collisions", "cip.elink.mcount.multiple_collisions",
4418 FT_UINT32
, BASE_DEC
, NULL
, 0,
4421 { &hf_elink_mcount_sqe_test_errors
,
4422 { "SQE Test Errors", "cip.elink.mcount.sqe_test_errors",
4423 FT_UINT32
, BASE_DEC
, NULL
, 0,
4426 { &hf_elink_mcount_deferred_transmission
,
4427 { "Deferred Transmission", "cip.elink.mcount.deferred_transmission",
4428 FT_UINT32
, BASE_DEC
, NULL
, 0,
4431 { &hf_elink_mcount_late_collisions
,
4432 { "Late Collisions", "cip.elink.mcount.late_collisions",
4433 FT_UINT32
, BASE_DEC
, NULL
, 0,
4436 { &hf_elink_mcount_excessive_collisions
,
4437 { "Excessive Collisions", "cip.elink.mcount.excessive_collisions",
4438 FT_UINT32
, BASE_DEC
, NULL
, 0,
4441 { &hf_elink_mcount_mac_transmit_errors
,
4442 { "MAC Transmit Errors", "cip.elink.mcount.mac_transmit_errors",
4443 FT_UINT32
, BASE_DEC
, NULL
, 0,
4446 { &hf_elink_mcount_carrier_sense_errors
,
4447 { "Carrier Sense Errors", "cip.elink.mcount.carrier_sense_errors",
4448 FT_UINT32
, BASE_DEC
, NULL
, 0,
4451 { &hf_elink_mcount_frame_too_long
,
4452 { "Frame Too Long", "cip.elink.mcount.frame_too_long",
4453 FT_UINT32
, BASE_DEC
, NULL
, 0,
4456 { &hf_elink_mcount_mac_receive_errors
,
4457 { "MAC Receive Errors", "cip.elink.mcount.mac_receive_errors",
4458 FT_UINT32
, BASE_DEC
, NULL
, 0,
4461 { &hf_elink_icontrol_control_bits
,
4462 { "Control Bits", "cip.elink.icontrol.control_bits",
4463 FT_UINT16
, BASE_HEX
, NULL
, 0,
4466 { &hf_elink_icontrol_control_bits_auto_neg
,
4467 { "Auto-negotiate", "cip.elink.icontrol.control_bits.auto_neg",
4468 FT_BOOLEAN
, 16, TFS(&tfs_enabled_disabled
), 0x0001,
4471 { &hf_elink_icontrol_control_bits_forced_duplex
,
4472 { "Forced Duplex Mode", "cip.elink.icontrol.control_bits.forced_duplex",
4473 FT_UINT16
, BASE_DEC
, VALS(enip_elink_duplex_vals
), 0x0002,
4476 { &hf_elink_icontrol_control_bits_reserved
,
4477 { "Reserved", "cip.elink.icontrol.control_bits.reserved",
4478 FT_UINT16
, BASE_HEX
, NULL
, 0xFFFC,
4481 { &hf_elink_icontrol_forced_speed
,
4482 { "Forced Interface Speed", "cip.elink.icontrol.forced_speed",
4483 FT_UINT16
, BASE_DEC
, NULL
, 0,
4486 { &hf_elink_icapability_capability_bits
,
4487 { "Capability Bits", "cip.elink.icapability.capability_bits",
4488 FT_UINT32
, BASE_HEX
, NULL
, 0,
4491 { &hf_elink_icapability_capability_bits_manual
,
4492 { "Manual Setting Requires Reset", "cip.elink.icapability.capability_bits.manual",
4493 FT_BOOLEAN
, 32, TFS(&tfs_enabled_disabled
), 0x00000001,
4496 { &hf_elink_icapability_capability_bits_auto_neg
,
4497 { "Auto-negotiate", "cip.elink.icapability.capability_bits.auto_neg",
4498 FT_BOOLEAN
, 32, TFS(&tfs_enabled_disabled
), 0x00000002,
4501 { &hf_elink_icapability_capability_bits_auto_mdix
,
4502 { "Auto-MDIX", "cip.elink.icapability.capability_bits.auto_mdix",
4503 FT_BOOLEAN
, 32, TFS(&tfs_enabled_disabled
), 0x00000004,
4506 { &hf_elink_icapability_capability_bits_manual_speed
,
4507 { "Manual Speed/Duplex", "cip.elink.icapability.capability_bits.manual_speed",
4508 FT_BOOLEAN
, 32, TFS(&tfs_enabled_disabled
), 0x00000008,
4511 { &hf_elink_icapability_capability_speed_duplex_array_count
,
4512 { "Speed/Duplex Array Count", "cip.elink.icapability.array_count",
4513 FT_UINT8
, BASE_DEC
, NULL
, 0,
4516 { &hf_elink_icapability_capability_speed
,
4517 { "Interface Speed", "cip.elink.icapability.speed",
4518 FT_UINT16
, BASE_DEC
, NULL
, 0,
4521 { &hf_elink_icapability_capability_duplex
,
4522 { "Interface Duplex Mode", "cip.elink.icapability.duplex",
4523 FT_UINT8
, BASE_DEC
, VALS(enip_elink_duplex_vals
), 0,
4526 { &hf_elink_interface_type
,
4527 { "Interface Type", "cip.elink.interface_type",
4528 FT_UINT8
, BASE_DEC
, VALS(enip_elink_interface_type_vals
), 0,
4531 { &hf_elink_interface_state
,
4532 { "Interface State", "cip.elink.interface_state",
4533 FT_UINT8
, BASE_DEC
, VALS(enip_elink_interface_state_vals
), 0,
4536 { &hf_elink_admin_state
,
4537 { "Admin State", "cip.elink.admin_state",
4538 FT_UINT8
, BASE_DEC
, VALS(enip_elink_admin_state_vals
), 0,
4541 { &hf_elink_interface_label
,
4542 { "Interface Label", "cip.elink.interface_label",
4543 FT_STRING
, BASE_NONE
, NULL
, 0,
4546 { &hf_elink_hc_icount_in_octets
,
4547 { "In Octets", "cip.elink.hc_icount.in_octets",
4548 FT_UINT64
, BASE_DEC
, NULL
, 0,
4551 { &hf_elink_hc_icount_in_ucast
,
4552 { "In Ucast Packets", "cip.elink.hc_icount.in_ucast",
4553 FT_UINT64
, BASE_DEC
, NULL
, 0,
4556 { &hf_elink_hc_icount_in_mcast
,
4557 { "In Multicast Packets", "cip.elink.hc_icount.in_mcast",
4558 FT_UINT64
, BASE_DEC
, NULL
, 0,
4561 { &hf_elink_hc_icount_in_broadcast
,
4562 { "In Broadcast", "cip.elink.hc_icount.in_broadcast",
4563 FT_UINT64
, BASE_DEC
, NULL
, 0,
4566 { &hf_elink_hc_icount_out_octets
,
4567 { "Out Octets", "cip.elink.hc_icount.out_octets",
4568 FT_UINT64
, BASE_DEC
, NULL
, 0,
4571 { &hf_elink_hc_icount_out_ucast
,
4572 { "Out Ucast Packets", "cip.elink.hc_icount.out_ucast",
4573 FT_UINT64
, BASE_DEC
, NULL
, 0,
4576 { &hf_elink_hc_icount_out_mcast
,
4577 { "Out Multicast Packets", "cip.elink.hc_icount.out_mcast",
4578 FT_UINT64
, BASE_DEC
, NULL
, 0,
4581 { &hf_elink_hc_icount_out_broadcast
,
4582 { "Out Broadcast Packets", "cip.elink.hc_icount.out_broadcast",
4583 FT_UINT64
, BASE_DEC
, NULL
, 0,
4586 { &hf_elink_hc_mcount_stats_align_errors
,
4587 { "Stats Alignment Errors", "cip.elink.hc_mcount.stats_align_errors",
4588 FT_UINT64
, BASE_DEC
, NULL
, 0,
4591 { &hf_elink_hc_mcount_stats_fcs_errors
,
4592 { "Stats FCS Errors", "cip.elink.hc_mcount.stats_fcs_errors",
4593 FT_UINT64
, BASE_DEC
, NULL
, 0,
4596 { &hf_elink_hc_mcount_stats_internal_mac_transmit_errors
,
4597 { "Stats Internal MAC Transmit Errors", "cip.elink.hc_mcount.internal_mac_transmit_errors",
4598 FT_UINT64
, BASE_DEC
, NULL
, 0,
4601 { &hf_elink_hc_mcount_stats_frame_too_long
,
4602 { "Stats Frame Too Long", "cip.elink.hc_mcount.stats_frame_too_long",
4603 FT_UINT64
, BASE_DEC
, NULL
, 0,
4606 { &hf_elink_hc_mcount_stats_internal_mac_receive_errors
,
4607 { "Stats Internal MAC Receive Errors", "cip.elink.hc_mcount.internal_mac_receive_errors",
4608 FT_UINT64
, BASE_DEC
, NULL
, 0,
4611 { &hf_elink_hc_mcount_stats_symbol_errors
,
4612 { "Stats Symbol Errors", "cip.elink.hc_mcount.stats_symbol_errors",
4613 FT_UINT64
, BASE_DEC
, NULL
, 0,
4616 { &hf_qos_8021q_enable
,
4617 { "802.1Q Tag Enable", "cip.qos.8021q_enable",
4618 FT_BOOLEAN
, 8, TFS(&tfs_enabled_disabled
), 0x1,
4621 { &hf_qos_dscp_ptp_event
,
4622 { "DSCP PTP Event", "cip.qos.ptp_event",
4623 FT_UINT8
, BASE_DEC
, NULL
, 0,
4626 { &hf_qos_dscp_ptp_general
,
4627 { "DSCP PTP General", "cip.qos.ptp_general",
4628 FT_UINT8
, BASE_DEC
, NULL
, 0,
4631 { &hf_qos_dscp_urgent
,
4632 { "DSCP Urgent", "cip.qos.urgent",
4633 FT_UINT8
, BASE_DEC
, NULL
, 0,
4636 { &hf_qos_dscp_scheduled
,
4637 { "DSCP Scheduled", "cip.qos.scheduled",
4638 FT_UINT8
, BASE_DEC
, NULL
, 0,
4641 { &hf_qos_dscp_high
,
4642 { "DSCP High", "cip.qos.high",
4643 FT_UINT8
, BASE_DEC
, NULL
, 0,
4647 { "DSCP Low", "cip.qos.low",
4648 FT_UINT8
, BASE_DEC
, NULL
, 0,
4651 { &hf_qos_dscp_explicit
,
4652 { "DSCP Explicit", "cip.qos.explicit",
4653 FT_UINT8
, BASE_DEC
, NULL
, 0,
4656 { &hf_dlr_network_topology
,
4657 { "Network Topology", "cip.dlr.network_topology",
4658 FT_UINT8
, BASE_DEC
, VALS(enip_dlr_network_topology_vals
), 0,
4661 { &hf_dlr_network_status
,
4662 { "Network Status", "cip.dlr.network_status",
4663 FT_UINT8
, BASE_DEC
, VALS(enip_dlr_network_status_vals
), 0,
4666 { &hf_dlr_ring_supervisor_status
,
4667 { "Ring Supervisor Status", "cip.dlr.ring_supervisor_status",
4668 FT_UINT8
, BASE_DEC
, VALS(enip_dlr_ring_supervisor_status_vals
), 0,
4671 { &hf_dlr_rsc_ring_supervisor_enable
,
4672 { "Ring Supervisor Enable", "cip.dlr.rscconfig.supervisor_enable",
4673 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
4676 { &hf_dlr_rsc_ring_supervisor_precedence
,
4677 { "Ring Supervisor Precedence", "cip.dlr.rscconfig.supervisor_precedence",
4678 FT_UINT8
, BASE_DEC
, NULL
, 0,
4681 { &hf_dlr_rsc_beacon_interval
,
4682 { "Beacon Interval", "cip.dlr.rscconfig.beacon_interval",
4683 FT_UINT32
, BASE_DEC
, NULL
, 0,
4686 { &hf_dlr_rsc_beacon_timeout
,
4687 { "Beacon Timeout", "cip.dlr.rscconfig.beacon_timeout",
4688 FT_UINT32
, BASE_DEC
, NULL
, 0,
4691 { &hf_dlr_rsc_dlr_vlan_id
,
4692 { "DLR VLAN ID", "cip.dlr.rscconfig.dlr_vlan_id",
4693 FT_UINT16
, BASE_DEC
, NULL
, 0,
4696 { &hf_dlr_ring_faults_count
,
4697 { "Ring Faults Count", "cip.dlr.ring_faults_count",
4698 FT_UINT16
, BASE_DEC
, NULL
, 0,
4701 { &hf_dlr_lanp1_dev_ip_addr
,
4702 { "Device IP Address", "cip.dlr.lanp1.ip_addr",
4703 FT_IPv4
, BASE_NONE
, NULL
, 0,
4706 { &hf_dlr_lanp1_dev_physical_address
,
4707 { "Device Physical Address", "cip.dlr.lanp1.physical_address",
4708 FT_ETHER
, BASE_NONE
, NULL
, 0,
4711 { &hf_dlr_lanp2_dev_ip_addr
,
4712 { "Device IP Address", "cip.dlr.lanp2.ip_addr",
4713 FT_IPv4
, BASE_NONE
, NULL
, 0,
4716 { &hf_dlr_lanp2_dev_physical_address
,
4717 { "Device Physical Address", "cip.dlr.lanp2.physical_address",
4718 FT_ETHER
, BASE_NONE
, NULL
, 0,
4721 { &hf_dlr_ring_protocol_participants_count
,
4722 { "Participants Count", "cip.dlr.participants_count",
4723 FT_UINT16
, BASE_DEC
, NULL
, 0,
4726 { &hf_dlr_rppl_dev_ip_addr
,
4727 { "Device IP Address", "cip.dlr.rppl.ip_addr",
4728 FT_IPv4
, BASE_NONE
, NULL
, 0,
4731 { &hf_dlr_rppl_dev_physical_address
,
4732 { "Device Physical Address", "cip.dlr.rppl.physical_address",
4733 FT_ETHER
, BASE_NONE
, NULL
, 0,
4736 { &hf_dlr_asa_supervisor_ip_addr
,
4737 { "Supervisor IP Address", "cip.dlr.asa.ip_addr",
4738 FT_IPv4
, BASE_NONE
, NULL
, 0,
4741 { &hf_dlr_asa_supervisor_physical_address
,
4742 { "Supervisor Physical Address", "cip.dlr.asa.physical_address",
4743 FT_ETHER
, BASE_NONE
, NULL
, 0,
4746 { &hf_dlr_active_supervisor_precedence
,
4747 { "Active Supervisor Precedence", "cip.dlr.supervisor_precedence",
4748 FT_UINT8
, BASE_DEC
, NULL
, 0,
4751 { &hf_dlr_capability_flags
,
4752 { "Capability Flags", "cip.dlr.capflags",
4753 FT_UINT32
, BASE_HEX
, NULL
, 0,
4756 { &hf_dlr_capflags_announce_base_node
,
4757 { "Announce-based Ring Node", "cip.dlr.capflags.announce_based",
4758 FT_BOOLEAN
, 32, NULL
, 0x00000001,
4761 { &hf_dlr_capflags_beacon_base_node
,
4762 { "Beacon-based Ring Node", "cip.dlr.capflags.beacon_based",
4763 FT_BOOLEAN
, 32, NULL
, 0x00000002,
4766 { &hf_dlr_capflags_reserved1
,
4767 { "Reserved", "cip.dlr.capflags.reserved1",
4768 FT_BOOLEAN
, 32, NULL
, 0x0000001C,
4771 { &hf_dlr_capflags_supervisor_capable
,
4772 { "Supervisor Capable", "cip.dlr.capflags.supervisor_capable",
4773 FT_BOOLEAN
, 32, NULL
, 0x00000020,
4776 { &hf_dlr_capflags_redundant_gateway_capable
,
4777 { "Redundant Gateway Capable", "cip.dlr.capflags.redundant_gateway_capable",
4778 FT_BOOLEAN
, 32, NULL
, 0x00000040,
4781 { &hf_dlr_capflags_flush_frame_capable
,
4782 { "Flush_Table Frame Capable", "cip.dlr.capflags.flush_frame_capable",
4783 FT_BOOLEAN
, 32, NULL
, 0x00000080,
4786 { &hf_dlr_capflags_reserved2
,
4787 { "Reserved", "cip.dlr.capflags.reserved2",
4788 FT_BOOLEAN
, 32, NULL
, 0xFFFFFF00,
4791 { &hf_dlr_rgc_red_gateway_enable
,
4792 { "Redundant Gateway Enable", "cip.dlr.rgc.gateway_enable",
4793 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
4796 { &hf_dlr_rgc_gateway_precedence
,
4797 { "Gateway Precedence", "cip.dlr.rgc.gateway_precedence",
4798 FT_UINT8
, BASE_DEC
, NULL
, 0,
4801 { &hf_dlr_rgc_advertise_interval
,
4802 { "Advertise Interval", "cip.dlr.rgc.advertise_interval",
4803 FT_UINT32
, BASE_DEC
, NULL
, 0,
4806 { &hf_dlr_rgc_advertise_timeout
,
4807 { "Advertise Timeout", "cip.dlr.rgc.advertise_timeout",
4808 FT_UINT32
, BASE_DEC
, NULL
, 0,
4811 { &hf_dlr_rgc_learning_update_enable
,
4812 { "Learning Update Enable", "cip.dlr.rgc.learning_update_enable",
4813 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
4816 { &hf_dlr_redundant_gateway_status
,
4817 { "Redundant Gateway Status", "cip.dlr.redundant_gateway_status",
4818 FT_UINT8
, BASE_DEC
, VALS(enip_dlr_redundant_gateway_status_vals
), 0,
4821 { &hf_dlr_aga_ip_addr
,
4822 { "Active Gateway IP Address", "cip.dlr.aga.ip_addr",
4823 FT_IPv4
, BASE_NONE
, NULL
, 0,
4826 { &hf_dlr_aga_physical_address
,
4827 { "Active Gateway Physical Address", "cip.dlr.aga.physical_address",
4828 FT_ETHER
, BASE_NONE
, NULL
, 0,
4831 { &hf_dlr_active_gateway_precedence
,
4832 { "Active Gateway Precedence", "cip.dlr.active_gateway_precedence",
4833 FT_UINT8
, BASE_DEC
, NULL
, 0,
4836 { &hf_cip_security_state
, { "State", "cip.security.state", FT_UINT8
, BASE_DEC
, VALS(cip_security_state_vals
), 0, NULL
, HFILL
} },
4838 { &hf_eip_security_state
,
4839 { "State", "cip.eip_security.state",
4840 FT_UINT8
, BASE_DEC
, VALS(eip_security_state_vals
), 0,
4843 { &hf_eip_security_verify_client_cert
,
4844 { "Verify Client Certificate", "cip.eip_security.verify_client_cert",
4845 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
4848 { &hf_eip_security_send_cert_chain
,
4849 { "Send Certificate Chain", "cip.eip_security.send_cert_chain",
4850 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
4853 { &hf_eip_security_check_expiration
,
4854 { "Check Expiration", "cip.eip_security.check_expiration",
4855 FT_BOOLEAN
, BASE_NONE
, NULL
, 0,
4858 { &hf_eip_security_capability_flags
,
4859 { "Capability Flags", "cip.eip_security.capability_flags",
4860 FT_UINT32
, BASE_HEX
, NULL
, 0,
4863 { &hf_eip_security_capflags_secure_renegotiation
,
4864 { "Secure Renegotiation", "cip.eip_security.capability_flags.secure_renegotiation",
4865 FT_BOOLEAN
, 32, TFS(&tfs_supported_not_supported
), 0x00000001,
4868 { &hf_eip_security_capflags_reserved
,
4869 { "Reserved", "cip.eip_security.capability_flags.reserved",
4870 FT_UINT32
, BASE_HEX
, NULL
, 0xFFFFFFFE,
4873 { &hf_eip_security_num_avail_cipher_suites
,
4874 { "Number of Available Cipher Suites", "cip.eip_security.num_avail_cipher_suites",
4875 FT_UINT8
, BASE_DEC
, NULL
, 0,
4878 { &hf_eip_security_avail_cipher_suite
,
4879 { "Available Cipher Suite", "cip.eip_security.avail_cipher_suite",
4880 FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &ssl_31_ciphersuite_ext
, 0,
4883 { &hf_eip_security_num_allow_cipher_suites
,
4884 { "Number of Allowed Cipher Suites", "cip.eip_security.num_allow_cipher_suites",
4885 FT_UINT8
, BASE_DEC
, NULL
, 0,
4888 { &hf_eip_security_allow_cipher_suite
,
4889 { "Allowed Cipher Suite", "cip.eip_security.allow_cipher_suite",
4890 FT_UINT16
, BASE_HEX
|BASE_EXT_STRING
, &ssl_31_ciphersuite_ext
, 0,
4893 { &hf_eip_security_num_psk
,
4894 { "Number of PSKs", "cip.eip_security.num_psk",
4895 FT_UINT8
, BASE_DEC
, NULL
, 0,
4898 { &hf_eip_security_psk_identity_size
,
4899 { "PSK Identity Size", "cip.eip_security.psk_identity_size",
4900 FT_UINT8
, BASE_DEC
, NULL
, 0,
4903 { &hf_eip_security_psk_identity
,
4904 { "PSK Identity", "cip.eip_security.psk_identity",
4905 FT_STRING
, BASE_NONE
, NULL
, 0,
4908 { &hf_eip_security_psk_size
,
4909 { "PSK Size", "cip.eip_security.psk_size",
4910 FT_UINT8
, BASE_DEC
, NULL
, 0,
4913 { &hf_eip_security_psk
,
4914 { "PSK", "cip.eip_security.psk",
4915 FT_STRING
, BASE_NONE
, NULL
, 0,
4918 { &hf_eip_security_psk_usage
,
4919 { "PSK Usage", "cip.eip_security.psk_usage",
4920 FT_UINT8
, BASE_DEC
, VALS(eip_security_psk_usage_vals
), 0,
4923 { &hf_eip_security_num_active_certs
,
4924 { "Number of Active Certificates", "cip.eip_security.num_active_certs",
4925 FT_UINT8
, BASE_DEC
, NULL
, 0,
4928 { &hf_eip_security_num_trusted_auths
,
4929 { "Number of Trusted Authorities", "cip.eip_security.num_trusted_auths",
4930 FT_UINT8
, BASE_DEC
, NULL
, 0,
4932 { &hf_eip_security_num_trusted_identities
,
4933 { "Number of Trusted Identities", "cip.eip_security.num_trusted_identities",
4934 FT_UINT8
, BASE_DEC
, NULL
, 0,
4936 { &hf_eip_security_num_crl
,
4937 { "Number of Certificate Revocation Lists", "cip.eip_security.num_crl",
4938 FT_UINT8
, BASE_DEC
, NULL
, 0,
4941 { &hf_eip_cert_name
,
4942 { "Name", "cip.eip_cert.name",
4943 FT_STRING
, BASE_NONE
, NULL
, 0,
4946 { &hf_eip_cert_state
,
4947 { "State", "cip.eip_cert.state",
4948 FT_UINT8
, BASE_DEC
, VALS(eip_cert_state_vals
), 0,
4951 { &hf_eip_cert_encoding
,
4952 { "Certificate Encoding", "cip.eip_cert.encoding",
4953 FT_UINT8
, BASE_DEC
, NULL
, 0,
4956 { &hf_eip_cert_device_cert_status
,
4957 { "Certificate Status", "cip.eip_cert.device_cert.status",
4958 FT_UINT8
, BASE_DEC
, VALS(eip_cert_status_vals
), 0,
4961 { &hf_eip_cert_ca_cert_status
,
4962 { "Certificate Status", "cip.eip_cert.ca_cert.status",
4963 FT_UINT8
, BASE_DEC
, VALS(eip_cert_status_vals
), 0,
4966 { &hf_eip_cert_capflags_push
,
4967 { "Push", "cip.eip_cert.capflags.push",
4968 FT_BOOLEAN
, 32, NULL
, 0x00000001,
4971 { &hf_eip_cert_capflags_reserved
,
4972 { "Reserved", "cip.eip_cert.capflags.reserved",
4973 FT_BOOLEAN
, 32, NULL
, 0xFFFFFFFE,
4976 { &hf_eip_cert_capability_flags
,
4977 { "Capability flags", "cip.eip_cert.capflags",
4978 FT_UINT32
, BASE_HEX
, NULL
, 0,
4981 { &hf_eip_cert_num_certs
,
4982 { "Number of Certificates", "cip.eip_cert.num_certs",
4983 FT_UINT8
, BASE_DEC
, NULL
, 0,
4986 { &hf_eip_cert_cert_name
,
4987 { "Certificate name", "cip.eip_cert.cert_name",
4988 FT_STRING
, BASE_NONE
, NULL
, 0,
4991 { &hf_eip_cert_verify_certificate
,
4992 { "Certificate", "cip.eip_cert.verify_certificate",
4993 FT_UINT16
, BASE_DEC
, NULL
, 0,
4997 { "ODVA LLDP Subtype", "cip.lldp.subtype",
4998 FT_UINT8
, BASE_DEC
, VALS(lldp_cip_subtypes
), 0,
5001 { &hf_lldp_mac_address
,
5002 { "MAC Address", "cip.lldp.mac_address",
5003 FT_ETHER
, BASE_NONE
, NULL
, 0,
5007 /* Setup protocol subtree array */
5008 static int *ett
[] = {
5010 &ett_cip_io_generic
,
5018 &ett_tcpip_admin_capability
,
5019 &ett_tcpip_config_cap
,
5020 &ett_tcpip_config_control
,
5021 &ett_elink_interface_flags
,
5022 &ett_elink_icontrol_bits
,
5023 &ett_elink_icapability_bits
,
5024 &ett_dlr_capability_flags
,
5025 &ett_dlr_lnknbrstatus_flags
,
5026 &ett_eip_security_capability_flags
,
5027 &ett_eip_security_psk
,
5028 &ett_eip_security_active_certs
,
5029 &ett_eip_security_trusted_auths
,
5030 &ett_eip_security_trusted_identities
,
5031 &ett_eip_security_crl
,
5032 &ett_eip_cert_capability_flags
,
5033 &ett_eip_cert_num_certs
,
5034 &ett_security_profiles
,
5035 &ett_ingress_egress_apply_behavior
,
5036 &ett_iana_port_state_flags
,
5037 &ett_connection_info
,
5038 &ett_connection_path_info
,
5042 static ei_register_info ei
[] = {
5043 { &ei_mal_tcpip_status
, { "cip.malformed.tcpip.status", PI_MALFORMED
, PI_ERROR
, "Malformed TCP/IP Status", EXPFILL
}},
5044 { &ei_mal_tcpip_config_cap
, { "cip.malformed.tcpip.config_cap", PI_MALFORMED
, PI_ERROR
, "Malformed TCP/IP Configuration Capability", EXPFILL
}},
5045 { &ei_mal_tcpip_config_control
, { "cip.malformed.tcpip.config_control", PI_MALFORMED
, PI_ERROR
, "Malformed TCP/IP Configuration Control", EXPFILL
}},
5046 { &ei_mal_tcpip_interface_config
, { "cip.malformed.tcpip.interface_config", PI_MALFORMED
, PI_ERROR
, "Malformed TCP/IP Interface Configuration", EXPFILL
}},
5047 { &ei_mal_tcpip_snn
, { "cip.malformed.tcpip.snn", PI_MALFORMED
, PI_ERROR
, "Malformed TCP/IP Object Safety Network Number", EXPFILL
}},
5048 { &ei_mal_tcpip_mcast_config
, { "cip.malformed.tcpip.mcast_config", PI_MALFORMED
, PI_ERROR
, "Malformed TCP/IP Multicast Config", EXPFILL
}},
5049 { &ei_mal_tcpip_last_conflict
, { "cip.malformed.tcpip.last_conflict", PI_MALFORMED
, PI_ERROR
, "Malformed TCP/IP Last Conflict Detected", EXPFILL
}},
5050 { &ei_mal_elink_interface_flags
, { "cip.malformed.elink.interface_flags", PI_MALFORMED
, PI_ERROR
, "Malformed Ethernet Link Interface Flags", EXPFILL
}},
5051 { &ei_mal_elink_physical_address
, { "cip.malformed.elink.physical_address", PI_MALFORMED
, PI_ERROR
, "Malformed Ethernet Link Physical Address", EXPFILL
} },
5052 { &ei_mal_elink_interface_counters
, { "cip.malformed.elink.interface_counters", PI_MALFORMED
, PI_ERROR
, "Malformed Ethernet Link Interface Counters", EXPFILL
}},
5053 { &ei_mal_elink_media_counters
, { "cip.malformed.elink.media_counters", PI_MALFORMED
, PI_ERROR
, "Malformed Ethernet Link Media Counters", EXPFILL
}},
5054 { &ei_mal_elink_interface_control
, { "cip.malformed.elink.interface_control", PI_MALFORMED
, PI_ERROR
, "Malformed Ethernet Link Interface Control", EXPFILL
}},
5055 { &ei_mal_dlr_ring_supervisor_config
, { "cip.malformed.dlr.ring_supervisor_config", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Ring Supervisor Config", EXPFILL
}},
5056 { &ei_mal_dlr_last_active_node_on_port_1
, { "cip.malformed.dlr.last_active_node_on_port_1", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Last Active Node on Port 1", EXPFILL
}},
5057 { &ei_mal_dlr_last_active_node_on_port_2
, { "cip.malformed.dlr.last_active_node_on_port_2", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Last Active Node on Port 2", EXPFILL
}},
5058 { &ei_mal_dlr_ring_protocol_participants_list
, { "cip.malformed.dlr.ring_protocol_participants_list", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Ring Protocol Participants List", EXPFILL
}},
5059 { &ei_mal_dlr_active_supervisor_address
, { "cip.malformed.dlr.active_supervisor_address", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Active Supervisor Address", EXPFILL
}},
5060 { &ei_mal_dlr_capability_flags
, { "cip.malformed.dlr.capability_flags", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Capability Flag", EXPFILL
}},
5061 { &ei_mal_dlr_redundant_gateway_config
, { "cip.malformed.dlr.redundant_gateway_config", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Redundant Gateway Config", EXPFILL
}},
5062 { &ei_mal_dlr_active_gateway_address
, { "cip.malformed.dlr.active_gateway_address", PI_MALFORMED
, PI_ERROR
, "Malformed DLR Active Gateway Address", EXPFILL
}},
5063 { &ei_mal_eip_security_capability_flags
, { "cip.malformed.eip_security.capability_flags", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Capability Flags", EXPFILL
}},
5064 { &ei_mal_eip_security_avail_cipher_suites
, { "cip.malformed.eip_security.avail_cipher_suites", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Available Cipher Suites", EXPFILL
}},
5065 { &ei_mal_eip_security_allow_cipher_suites
, { "cip.malformed.eip_security.allow_cipher_suites", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Allowed Cipher Suites", EXPFILL
}},
5066 { &ei_mal_eip_security_preshared_keys
, { "cip.malformed.eip_security.preshared_keys", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Pre-Shared Keys", EXPFILL
}},
5067 { &ei_mal_eip_security_active_certs
, { "cip.malformed.eip_security.active_certs", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Active Device Certificates", EXPFILL
}},
5068 { &ei_mal_eip_security_trusted_auths
, { "cip.malformed.eip_security.trusted_auths", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Trusted Authorities", EXPFILL
}},
5069 { &ei_mal_eip_security_trusted_identities
, { "cip.malformed.eip_security.trusted_identities", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Trusted Identities", EXPFILL
}},
5070 { &ei_mal_eip_security_crl
, { "cip.malformed.eip_security.crl", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Security Certificate Revocation List", EXPFILL
}},
5071 { &ei_mal_eip_cert_capability_flags
, { "cip.malformed.eip_cert.capability_flags", PI_MALFORMED
, PI_ERROR
, "Malformed EIP Certificate Management Capability Flags", EXPFILL
}},
5072 { &ei_mal_cpf_item_length_mismatch
, { "enip.malformed.cpf_item_length_mismatch", PI_MALFORMED
, PI_ERROR
, "CPF Item Length Mismatch", EXPFILL
} },
5073 { &ei_mal_cpf_item_minimum_size
, { "enip.malformed.cpf_item_minimum_size", PI_MALFORMED
, PI_ERROR
, "CPF Item Minimum Size is 4", EXPFILL
} },
5076 { &ei_cip_request_no_response
, { "cip.analysis.request_no_response", PI_PROTOCOL
, PI_NOTE
, "CIP request without a response", EXPFILL
} },
5077 { &ei_cip_io_heartbeat
, { "cip.analysis.cip_io_heartbeat", PI_PROTOCOL
, PI_NOTE
, "[Likely] CIP I/O Heartbeat [Listen/Input Only Connection]", EXPFILL
} },
5080 /* Setup list of header fields for DLR See Section 1.6.1 for details*/
5081 static hf_register_info hfdlr
[] = {
5083 { &hf_dlr_ringsubtype
,
5084 { "Ring Sub-Type", "enip.dlr.ringsubtype",
5085 FT_UINT8
, BASE_HEX
, NULL
, 0,
5088 /* Ring Protocol Version */
5089 { &hf_dlr_ringprotoversion
,
5090 { "Ring Protocol Version", "enip.dlr.protversion",
5091 FT_UINT8
, BASE_DEC
, NULL
, 0,
5095 { &hf_dlr_frametype
,
5096 { "Frame Type", "enip.dlr.frametype",
5097 FT_UINT8
, BASE_HEX
, VALS(dlr_frame_type_vals
), 0,
5101 { &hf_dlr_sourceport
,
5102 { "Source Port", "enip.dlr.sourceport",
5103 FT_UINT8
, BASE_HEX
, VALS(dlr_source_port_vals
), 0,
5106 /* Source IP Address */
5108 { "Source IP", "enip.dlr.sourceip",
5109 FT_IPv4
, BASE_NONE
, NULL
, 0,
5110 "Source IP Address", HFILL
}
5113 { &hf_dlr_sequenceid
,
5114 { "Sequence Id", "enip.dlr.seqid",
5115 FT_UINT32
, BASE_HEX
, NULL
, 0,
5119 { &hf_dlr_ringstate
,
5120 { "Ring State", "enip.dlr.state",
5121 FT_UINT8
, BASE_HEX
, VALS(dlr_ring_state_vals
), 0,
5124 /* Supervisor Precedence */
5125 { &hf_dlr_supervisorprecedence
,
5126 { "Supervisor Precedence", "enip.dlr.supervisorprecedence",
5127 FT_UINT8
, BASE_DEC
, NULL
, 0,
5130 /* Beacon Interval */
5131 { &hf_dlr_beaconinterval
,
5132 { "Beacon Interval", "enip.dlr.beaconinterval",
5133 FT_UINT32
, BASE_DEC
, NULL
, 0,
5136 /* Beacon Timeout */
5137 { &hf_dlr_beacontimeout
,
5138 { "Beacon Timeout", "enip.dlr.beacontimeout",
5139 FT_UINT32
, BASE_DEC
|BASE_UNIT_STRING
, UNS(&units_microseconds
), 0,
5142 /* Beacon Reserved */
5143 { &hf_dlr_beaconreserved
,
5144 { "Reserved", "enip.dlr.beaconreserved",
5145 FT_BYTES
, BASE_NONE
, NULL
, 0,
5146 "Beacon Reserved", HFILL
}
5148 /* Neighbor_Check_Request Reserved */
5149 { &hf_dlr_nreqreserved
,
5150 { "Reserved", "enip.dlr.nreqreserved",
5151 FT_BYTES
, BASE_NONE
, NULL
, 0,
5152 "Neighbor_Check_Request Reserved", HFILL
}
5154 /* Neighbor_Check_Response Source Port */
5155 { &hf_dlr_nressourceport
,
5156 { "Request Source Port", "enip.dlr.nressourceport",
5157 FT_UINT8
, BASE_HEX
, VALS(dlr_source_port_vals
), 0,
5158 "Neighbor_Check_Response Source Port", HFILL
}
5160 /* Neighbor_Check_Response Reserved */
5161 { &hf_dlr_nresreserved
,
5162 { "Reserved", "enip.dlr.nresreserved",
5163 FT_BYTES
, BASE_NONE
, NULL
, 0,
5164 "Neighbor_Check_Response Reserved", HFILL
}
5166 /* Link_Status/Neighbor_Status Status */
5167 { &hf_dlr_lnknbrstatus
,
5168 { "Link/Neighbor Status", "enip.dlr.lnknbrstatus.status",
5169 FT_UINT8
, BASE_HEX
, NULL
, 0,
5170 "Link_Status/Neighbor_Status Status", HFILL
}
5172 { &hf_dlr_lnknbrstatus_port1
,
5173 { "Port 1 Active", "enip.dlr.lnknbrstatus.port1",
5174 FT_BOOLEAN
, 8, NULL
, 0x01,
5177 { &hf_dlr_lnknbrstatus_port2
,
5178 { "Port 2 Active", "enip.dlr.lnknbrstatus.port2",
5179 FT_BOOLEAN
, 8, NULL
, 0x02,
5182 { &hf_dlr_lnknbrstatus_reserved
,
5183 { "Reserved", "enip.dlr.lnknbrstatus.reserved",
5184 FT_BOOLEAN
, 8, NULL
, 0x7C,
5187 { &hf_dlr_lnknbrstatus_frame_type
,
5188 { "Link/Neighbor Status Frame Type", "enip.dlr.lnknbrstatus.frame_type",
5189 FT_BOOLEAN
, 8, TFS(&dlr_lnknbrstatus_frame_type_vals
), 0x80,
5192 /* Link_Status/Neighbor_Status Reserved */
5193 { &hf_dlr_lnknbrreserved
,
5194 { "Reserved", "enip.dlr.lnknbrreserved",
5195 FT_BYTES
, BASE_NONE
, NULL
, 0,
5196 "Link_Status/Neighbor_Status Reserved", HFILL
}
5198 /* Locate_Fault Reserved */
5199 { &hf_dlr_lfreserved
,
5200 { "Reserved", "enip.dlr.lfreserved",
5201 FT_BYTES
, BASE_NONE
, NULL
, 0,
5202 "Locate_Fault Reserved", HFILL
}
5204 /* Announce Reserved */
5205 { &hf_dlr_anreserved
,
5206 { "Reserved", "enip.dlr.anreserved",
5207 FT_BYTES
, BASE_NONE
, NULL
, 0,
5208 "Announce Reserved", HFILL
}
5210 /* Number of Nodes in List */
5211 { &hf_dlr_sonumnodes
,
5212 { "Num nodes", "enip.dlr.sonumnodes",
5213 FT_UINT16
, BASE_DEC
, NULL
, 0,
5214 "Number of Nodes in List", HFILL
}
5216 /* Sign_On Node # MAC Address */
5218 { "MAC Address", "enip.dlr.somac",
5219 FT_ETHER
, BASE_NONE
, NULL
, 0,
5220 "Sign_On Node MAC Address", HFILL
}
5222 /* Node # IP Address */
5224 { "IP Address", "enip.dlr.soip",
5225 FT_IPv4
, BASE_NONE
, NULL
, 0,
5226 "Sign_On Node IP Address", HFILL
}
5228 /* Sign_On Reserved */
5229 { &hf_dlr_soreserved
,
5230 { "Reserved", "enip.dlr.soreserved",
5231 FT_BYTES
, BASE_NONE
, NULL
, 0,
5232 "Sign_On Reserved", HFILL
}
5235 { &hf_dlr_advgatewaystate
,
5236 { "Gateway Status", "enip.dlr.advgatewaystate",
5237 FT_UINT8
, BASE_HEX
, VALS(dlr_adv_state_vals
), 0,
5238 "Gateway State", HFILL
}
5240 /* Gateway Precedence */
5241 { &hf_dlr_advgatewayprecedence
,
5242 { "Gateway Precedence", "enip.dlr.advgatewayprecedence",
5243 FT_UINT8
, BASE_DEC
, NULL
, 0,
5246 /* Advertise Interval */
5247 { &hf_dlr_advadvertiseinterval
,
5248 { "Advertise Interval", "enip.dlr.advadvertiseinterval",
5249 FT_UINT32
, BASE_DEC
, NULL
, 0,
5252 /* Advertise Timeout */
5253 { &hf_dlr_advadvertisetimeout
,
5254 { "Advertise Interval", "enip.dlr.advadvertisetimeout",
5255 FT_UINT32
, BASE_DEC
, NULL
, 0,
5258 /* Learning Update Enable */
5259 { &hf_dlr_advlearningupdateenable
,
5260 { "Learning Update Enable", "enip.dlr.advlearningupdateenable",
5261 FT_UINT8
, BASE_HEX
, VALS(dlr_adv_learning_update_vals
), 0,
5262 "Advertise Learning Update Enable", HFILL
}
5264 /* Advertise Reserved */
5265 { &hf_dlr_advreserved
,
5266 { "Reserved", "enip.dlr.advreserved",
5267 FT_BYTES
, BASE_NONE
, NULL
, 0,
5268 "Advertise Reserved", HFILL
}
5270 /* Flush_Tables Learning Update Enable */
5271 { &hf_dlr_flushlearningupdateenable
,
5272 { "Learning Update Enable", "enip.dlr.flushlearningupdateenable",
5273 FT_UINT8
, BASE_HEX
, VALS(dlr_flush_learning_update_vals
), 0,
5274 "Flush_Tables Learning Update Enable", HFILL
}
5276 /* Flush Reserved */
5277 { &hf_dlr_flushreserved
,
5278 { "Reserved", "enip.dlr.flushreserved",
5279 FT_BYTES
, BASE_NONE
, NULL
, 0,
5280 "Flush_Tables Reserved", HFILL
}
5282 /* Learning_Update Reserved */
5283 { &hf_dlr_learnreserved
,
5284 { "Reserved", "enip.dlr.learnreserved",
5285 FT_BYTES
, BASE_NONE
, NULL
, 0,
5286 "Learning_Update Reserved", HFILL
}
5290 /* Setup protocol subtree array for DLR */
5291 static int *ettdlr
[] = {
5295 module_t
*enip_module
;
5296 expert_module_t
* expert_enip
;
5298 /* Register the protocol name and description */
5299 proto_enip
= proto_register_protocol("EtherNet/IP (Industrial Protocol)", "ENIP", "enip");
5300 proto_cipio
= proto_register_protocol("Common Industrial Protocol, I/O", "CIP I/O", "cipio");
5301 proto_cip_class1
= proto_register_protocol_in_name_only(
5302 "Common Industrial Protocol, I/O Class 1",
5308 enip_tcp_handle
= register_dissector("enip", dissect_enip_tcp
, proto_enip
);
5309 enip_udp_handle
= register_dissector("enip.udp", dissect_enip_udp
, proto_enip
);
5310 enip_cipio_handle
= register_dissector_with_description("cipio", "ENIP CIP I/O", dissect_enip_cipio
, proto_enip
);
5311 cip_class1_handle
= register_dissector("cipio_class1", dissect_cip_class1
, proto_cip_class1
);
5312 cip_io_generic_handle
= register_dissector("cipgenericio", dissect_cip_io_generic
, proto_cipio
);
5314 /* Required function calls to register the header fields and subtrees used */
5315 proto_register_field_array(proto_enip
, hf
, array_length(hf
));
5316 proto_register_subtree_array(ett
, array_length(ett
));
5318 expert_enip
= expert_register_protocol(proto_enip
);
5319 expert_register_field_array(expert_enip
, ei
, array_length(ei
));
5321 enip_module
= prefs_register_protocol(proto_enip
, NULL
);
5322 prefs_register_bool_preference(enip_module
, "desegment",
5323 "Desegment all EtherNet/IP messages spanning multiple TCP segments",
5324 "Whether the EtherNet/IP dissector should desegment all messages spanning multiple TCP segments",
5327 prefs_register_bool_preference(enip_module
, "o2t_run_idle",
5328 "Dissect 32-bit header in the O->T direction",
5329 "Determines whether all I/O connections will assume a 32-bit header in the O->T direction",
5332 prefs_register_bool_preference(enip_module
, "t2o_run_idle",
5333 "Dissect 32-bit header in the T->O direction",
5334 "Determines whether all I/O connections will assume a 32-bit header in the T->O direction",
5337 prefs_register_obsolete_preference(enip_module
, "default_io_dissector");
5339 subdissector_srrd_table
= register_dissector_table("enip.srrd.iface",
5340 "ENIP SendRequestReplyData.Interface Handle", proto_enip
, FT_UINT32
, BASE_HEX
);
5342 subdissector_io_table
= register_dissector_table("cip.io.iface",
5343 "CIP Class 0/1 Interface Handle", proto_cipio
, FT_UINT32
, BASE_HEX
);
5345 subdissector_cip_connection_table
= register_dissector_table("cip.connection.class",
5346 "CIP Class 2/3 Interface Handle", proto_enip
, FT_UINT32
, BASE_HEX
);
5348 enip_request_hashtable
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), enip_request_hash
, enip_request_equal
);
5349 enip_conn_hashtable
= wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), enip_conn_hash
, enip_conn_equal
);
5351 register_init_routine(&enip_init_protocol
);
5353 /* Register the protocol name and description */
5354 proto_dlr
= proto_register_protocol("Device Level Ring", "DLR", "dlr");
5356 /* Required function calls to register the header fields and subtrees used */
5357 proto_register_field_array(proto_dlr
, hfdlr
, array_length(hfdlr
));
5358 proto_register_subtree_array(ettdlr
, array_length(ettdlr
));
5359 dlr_handle
= register_dissector("dlr", dissect_dlr
, proto_dlr
);
5361 register_conversation_filter("enip", "CIP Connection", cip_connection_conv_valid
, cip_connection_conv_filter
, NULL
);
5363 subdissector_decode_as_io_table
= register_decode_as_next_proto(proto_enip
, "cip.io", "CIP I/O Payload", enip_prompt
);
5364 } /* end of proto_register_enip() */
5366 const value_string lldp_cip_subtypes
[] = {
5367 { 1, "Deprecated CIP Identification" },
5368 { 2, "CIP MAC Address" },
5369 { 3, "CIP Interface Label" },
5370 { 4, "Position ID" },
5371 { 5, "T1S PHY Data" },
5372 { 6, "Commission Request" },
5373 { 7, "Commission Response" },
5374 { 8, "Discover Topology Response" },
5375 { 9, "CIP Identification" },
5380 int dissect_lldp_cip_tlv(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
)
5382 int total_len
= tvb_reported_length_remaining(tvb
, 0);
5385 proto_tree_add_item_ret_uint(tree
, hf_lldp_subtype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
, &subtype
);
5392 dissect_electronic_key_format(tvb
, offset
, tree
, false, CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL
, ENC_LITTLE_ENDIAN
);
5397 proto_tree_add_item(tree
, hf_lldp_mac_address
, tvb
, offset
, 6, ENC_NA
);
5402 // The string is all the data, minus Subtype (1 byte).
5403 int string_len
= total_len
- 1;
5404 proto_tree_add_item(tree
, hf_elink_interface_label
, tvb
, offset
, string_len
, ENC_ASCII
| ENC_NA
);
5410 dissect_electronic_key_format(tvb
, offset
, tree
, false, CI_E_SERIAL_NUMBER_KEY_FORMAT_VAL
, ENC_BIG_ENDIAN
);
5418 return tvb_reported_length(tvb
);
5422 proto_reg_handoff_enip(void)
5424 /* Register for EtherNet/IP, using TCP */
5425 dissector_add_uint_with_preference("tcp.port", ENIP_ENCAP_PORT
, enip_tcp_handle
);
5427 /* Register for EtherNet/IP, using UDP */
5428 dissector_add_uint_with_preference("udp.port", ENIP_ENCAP_PORT
, enip_udp_handle
);
5430 /* Register for EtherNet/IP IO data (UDP) */
5431 dissector_add_uint_with_preference("udp.port", ENIP_IO_PORT
, enip_cipio_handle
);
5433 /* Register for EtherNet/IP TLS */
5434 ssl_dissector_add(ENIP_SECURE_PORT
, enip_tcp_handle
);
5435 dtls_dissector_add(ENIP_SECURE_PORT
, enip_cipio_handle
);
5436 dtls_handle
= find_dissector("dtls");
5438 // Allow DecodeAs for DTLS --> ENIP. This supports "UDP-only EtherNet/IP transport profile" over
5439 // port 44818 (for Class 3 and Unconnected Messages)
5440 dissector_add_for_decode_as("dtls.port", enip_udp_handle
);
5442 /* Find ARP dissector for TCP/IP object */
5443 arp_handle
= find_dissector_add_dependency("arp", proto_enip
);
5445 /* I/O data dissectors */
5446 cipsafety_handle
= find_dissector("cipsafety");
5448 /* Implicit data dissector */
5449 cip_implicit_handle
= find_dissector_add_dependency("cip_implicit", proto_enip
);
5451 cip_handle
= find_dissector_add_dependency("cip", proto_enip
);
5453 /* Register for EtherNet/IP Device Level Ring protocol */
5454 dissector_add_uint("ethertype", ETHERTYPE_DLR
, dlr_handle
);
5456 subdissector_class_table
= find_dissector_table("cip.class.iface");
5458 dissector_add_for_decode_as("cip.io", cip_class1_handle
);
5459 } /* end of proto_reg_handoff_enip() */
5462 * Editor modelines - https://www.wireshark.org/tools/modelines.html
5467 * indent-tabs-mode: nil
5470 * ex: set shiftwidth=3 tabstop=8 expandtab:
5471 * :indentSize=3:tabSize=8:noTabs=true: