1 /* packet-enip.c
2  * Routines for EtherNet/IP (Industrial Protocol) dissection
3  * EtherNet/IP Home: www.odva.org
4  *
5  * This dissector includes items from:
6  *    CIP Volume 1: Common Industrial Protocol, Edition 3.24
7  *    CIP Volume 2: EtherNet/IP Adaptation of CIP, Edition 1.27
8  *    CIP Volume 8: CIP Security, Edition 1.11
9  *
10  * Copyright 2003-2004
11  * Magnus Hansson <mah@hms.se>
12  * Joakim Wiberg <jow@hms.se>
13  *
14  * Conversation data support for CIP
15  *   Jan Bartels, Siempelkamp Maschinen- und Anlagenbau GmbH & Co. KG
16  *   Copyright 2007
17  *
18  * Ethernet/IP object support
19  *   Michael Mann
20  *   Copyright 2011
21  *
22  * Wireshark - Network traffic analyzer
23  * By Gerald Combs <gerald@wireshark.org>
24  * Copyright 1998 Gerald Combs
25  *
26  * SPDX-License-Identifier: GPL-2.0-or-later
27  */
28 
29 #include "config.h"
30 
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>
38 #include <ipproto.h>
39 
40 #include "packet-tcp.h"
41 #include "packet-cip.h"
42 #include "packet-enip.h"
43 #include "packet-cipsafety.h"
44 #include "packet-dtls.h"
45 #include "packet-tls.h"
46 #include "packet-tls-utils.h"
47 
48 void proto_register_enip(void);
49 void proto_reg_handoff_enip(void);
50 
51 /* Communication Ports */
52 #define ENIP_ENCAP_PORT    44818 /* EtherNet/IP located on port 44818    */
53 #define ENIP_SECURE_PORT   2221  /* EtherNet/IP TLS/DTLS port            */
54 #define ENIP_IO_PORT       2222  /* EtherNet/IP IO located on port 2222  */
55 
56 /* EtherNet/IP function codes */
57 #define NOP                0x0000
58 #define LIST_SERVICES      0x0004
59 #define LIST_IDENTITY      0x0063
60 #define LIST_INTERFACES    0x0064
61 #define REGISTER_SESSION   0x0065
62 #define UNREGISTER_SESSION 0x0066
63 #define SEND_RR_DATA       0x006F
64 #define SEND_UNIT_DATA     0x0070
65 #define START_DTLS         0x00C8
66 
67 /* EtherNet/IP status codes */
68 #define SUCCESS               0x0000
69 #define INVALID_CMD           0x0001
70 #define NO_RESOURCES          0x0002
71 #define INCORRECT_DATA        0x0003
72 #define INVALID_SESSION       0x0064
73 #define INVALID_LENGTH        0x0065
74 #define UNSUPPORTED_PROT_REV  0x0069
75 #define ENCAP_HEADER_ERROR    0x006A
76 
77 /* EtherNet/IP Common Packet Format Type IDs */
78 #define CPF_ITEM_NULL                 0x0000
79 #define CPF_ITEM_CIP_IDENTITY         0x000C
80 #define CPF_ITEM_CIP_SECURITY         0x0086
81 #define CPF_ITEM_ENIP_CAPABILITY      0x0087
82 #define CPF_ITEM_ENIP_USAGE           0x0088
83 #define CPF_ITEM_CONNECTED_ADDRESS    0x00A1
84 #define CPF_ITEM_CONNECTED_DATA       0x00B1
85 #define CPF_ITEM_UNCONNECTED_DATA     0x00B2
86 #define CPF_ITEM_LIST_SERVICES_RESP   0x0100
87 #define CPF_ITEM_SOCK_ADR_INFO_OT     0x8000
88 #define CPF_ITEM_SOCK_ADR_INFO_TO     0x8001
89 #define CPF_ITEM_SEQUENCED_ADDRESS    0x8002
90 #define CPF_ITEM_UNCONNECTED_MSG_DTLS 0x8003
91 
92 /* Initialize the protocol and registered fields */
93 static int proto_enip = -1;
94 static int proto_cipio = -1;
95 static int proto_cip_class1 = -1;
96 
97 static int hf_enip_command = -1;
98 static int hf_enip_length = -1;
99 static int hf_enip_options = -1;
100 static int hf_enip_sendercontex = -1;
101 static int hf_enip_listid_delay = -1;
102 static int hf_enip_status = -1;
103 static int hf_enip_session = -1;
104 static int hf_enip_encapver = -1;
105 static int hf_enip_sinfamily = -1;
106 static int hf_enip_sinport = -1;
107 static int hf_enip_sinaddr = -1;
108 static int hf_enip_sinzero = -1;
109 static int hf_enip_timeout = -1;
110 static int hf_enip_encap_data = -1;
111 
112 static int hf_enip_lir_vendor = -1;
113 static int hf_enip_lir_devtype = -1;
114 static int hf_enip_lir_prodcode = -1;
115 static int hf_enip_lir_revision = -1;
116 static int hf_enip_lir_status = -1;
117 static int hf_enip_lir_serial = -1;
118 static int hf_enip_lir_namelen = -1;
119 static int hf_enip_lir_name = -1;
120 static int hf_enip_lir_state = -1;
121 
122 static int hf_enip_lsr_capaflags = -1;
123 static int hf_enip_lsr_tcp = -1;
124 static int hf_enip_lsr_udp = -1;
125 static int hf_enip_lsr_servicename = -1;
126 
127 static int hf_enip_rs_version = -1;
128 static int hf_enip_rs_optionflags = -1;
129 
130 static int hf_enip_security_profiles = -1;
131 static int hf_enip_security_profiles_eip_integrity = -1;
132 static int hf_enip_security_profiles_eip_confidentiality = -1;
133 static int hf_enip_security_profiles_cip_authorization = -1;
134 static int hf_enip_security_profiles_cip_user_authentication = -1;
135 static int hf_enip_security_profiles_resource_constrained = -1;
136 static int hf_enip_security_profiles_reserved = -1;
137 static int hf_enip_cip_security_state = -1;
138 static int hf_enip_eip_security_state = -1;
139 static int hf_enip_iana_port_state_flags = -1;
140 static int hf_enip_iana_port_state_flags_tcp_44818 = -1;
141 static int hf_enip_iana_port_state_flags_udp_44818 = -1;
142 static int hf_enip_iana_port_state_flags_udp_2222 = -1;
143 static int hf_enip_iana_port_state_flags_tcp_2221 = -1;
144 static int hf_enip_iana_port_state_flags_udp_2221 = -1;
145 static int hf_enip_iana_port_state_flags_reserved = -1;
146 
147 static int hf_enip_srrd_ifacehnd = -1;
148 
149 static int hf_enip_sud_ifacehnd = -1;
150 
151 static int hf_enip_cpf_itemcount = -1;
152 static int hf_enip_cpf_typeid = -1;
153 static int hf_enip_cpf_length = -1;
154 static int hf_cip_sequence_count = -1;
155 static int hf_cip_cm_ot_api = -1;
156 static int hf_cip_cm_to_api = -1;
157 static int hf_enip_cpf_cai_connid = -1;
158 static int hf_enip_cpf_sai_connid = -1;
159 static int hf_cip_connid = -1;
160 static int hf_enip_cpf_sai_seqnum = -1;
161 static int hf_enip_cpf_ucmm_request = -1;
162 static int hf_enip_cpf_ucmm_msg_type = -1;
163 static int hf_enip_cpf_ucmm_trans_id = -1;
164 static int hf_enip_cpf_ucmm_status = -1;
165 
166 static int hf_enip_cpf_data = -1;
167 
168 static int hf_enip_response_in = -1;
169 static int hf_enip_response_to = -1;
170 static int hf_enip_time = -1;
171 static int hf_enip_fwd_open_in = -1;
172 static int hf_cip_connection = -1;
173 static int hf_cip_io_data = -1;
174 
175 /* Parsed Attributes */
176 static int hf_tcpip_status = -1;
177 static int hf_tcpip_status_interface_config = -1;
178 static int hf_tcpip_status_mcast_pending = -1;
179 static int hf_tcpip_status_interface_config_pending = -1;
180 static int hf_tcpip_status_acd = -1;
181 static int hf_tcpip_acd_fault = -1;
182 static int hf_tcpip_status_iana_port_admin_change = -1;
183 static int hf_tcpip_status_iana_protocol_admin_change = -1;
184 static int hf_tcpip_status_reserved = -1;
185 static int hf_tcpip_config_cap = -1;
186 static int hf_tcpip_config_cap_bootp = -1;
187 static int hf_tcpip_config_cap_dns = -1;
188 static int hf_tcpip_config_cap_dhcp = -1;
189 static int hf_tcpip_config_cap_dhcp_dns_update = -1;
190 static int hf_tcpip_config_cap_config_settable = -1;
191 static int hf_tcpip_config_cap_hardware_config = -1;
192 static int hf_tcpip_config_cap_interface_reset = -1;
193 static int hf_tcpip_config_cap_acd = -1;
194 static int hf_tcpip_config_cap_reserved = -1;
195 static int hf_tcpip_config_control = -1;
196 static int hf_tcpip_config_control_config = -1;
197 static int hf_tcpip_config_control_dns = -1;
198 static int hf_tcpip_config_control_reserved = -1;
199 static int hf_tcpip_ic_ip_addr = -1;
200 static int hf_tcpip_ic_subnet_mask = -1;
201 static int hf_tcpip_ic_gateway = -1;
202 static int hf_tcpip_ic_name_server = -1;
203 static int hf_tcpip_ic_name_server2 = -1;
204 static int hf_tcpip_ic_domain_name = -1;
205 static int hf_tcpip_hostname = -1;
206 static int hf_tcpip_snn_timestamp = -1;
207 static int hf_tcpip_snn_date = -1;
208 static int hf_tcpip_snn_time = -1;
209 static int hf_tcpip_ttl_value = -1;
210 static int hf_tcpip_mcast_alloc = -1;
211 static int hf_tcpip_mcast_reserved = -1;
212 static int hf_tcpip_mcast_num_mcast = -1;
213 static int hf_tcpip_mcast_addr_start = -1;
214 static int hf_tcpip_lcd_acd_activity = -1;
215 static int hf_tcpip_lcd_remote_mac = -1;
216 static int hf_tcpip_lcd_arp_pdu = -1;
217 static int hf_tcpip_select_acd = -1;
218 static int hf_tcpip_quick_connect = -1;
219 static int hf_tcpip_encap_inactivity = -1;
220 
221 static int hf_tcpip_port_count = -1;
222 static int hf_tcpip_port_name = -1;
223 static int hf_tcpip_port_number = -1;
224 static int hf_tcpip_port_protocol = -1;
225 static int hf_tcpip_port_admin_state = -1;
226 static int hf_tcpip_port_admin_capability = -1;
227 static int hf_tcpip_admin_capability_configurable = -1;
228 static int hf_tcpip_admin_capability_reset_required = -1;
229 static int hf_tcpip_admin_capability_reserved = -1;
230 
231 static int hf_elink_interface_flags = -1;
232 static int hf_elink_iflags_link_status = -1;
233 static int hf_elink_iflags_duplex = -1;
234 static int hf_elink_iflags_neg_status = -1;
235 static int hf_elink_iflags_manual_reset = -1;
236 static int hf_elink_iflags_local_hw_fault = -1;
237 static int hf_elink_iflags_reserved = -1;
238 static int hf_elink_interface_speed = -1;
239 static int hf_elink_physical_address = -1;
240 static int hf_elink_icount_in_octets = -1;
241 static int hf_elink_icount_in_ucast = -1;
242 static int hf_elink_icount_in_nucast = -1;
243 static int hf_elink_icount_in_discards = -1;
244 static int hf_elink_icount_in_errors = -1;
245 static int hf_elink_icount_in_unknown_protos = -1;
246 static int hf_elink_icount_out_octets = -1;
247 static int hf_elink_icount_out_ucast = -1;
248 static int hf_elink_icount_out_nucast = -1;
249 static int hf_elink_icount_out_discards = -1;
250 static int hf_elink_icount_out_errors = -1;
251 static int hf_elink_mcount_alignment_errors = -1;
252 static int hf_elink_mcount_fcs_errors = -1;
253 static int hf_elink_mcount_single_collisions = -1;
254 static int hf_elink_mcount_multiple_collisions = -1;
255 static int hf_elink_mcount_sqe_test_errors = -1;
256 static int hf_elink_mcount_deferred_transmission = -1;
257 static int hf_elink_mcount_late_collisions = -1;
258 static int hf_elink_mcount_excessive_collisions = -1;
259 static int hf_elink_mcount_mac_transmit_errors = -1;
260 static int hf_elink_mcount_carrier_sense_errors = -1;
261 static int hf_elink_mcount_frame_too_long = -1;
262 static int hf_elink_mcount_mac_receive_errors = -1;
263 static int hf_elink_icontrol_control_bits = -1;
264 static int hf_elink_icontrol_control_bits_auto_neg = -1;
265 static int hf_elink_icontrol_control_bits_forced_duplex = -1;
266 static int hf_elink_icontrol_control_bits_reserved = -1;
267 static int hf_elink_icontrol_forced_speed = -1;
268 static int hf_elink_icapability_capability_bits = -1;
269 static int hf_elink_icapability_capability_bits_manual = -1;
270 static int hf_elink_icapability_capability_bits_auto_neg = -1;
271 static int hf_elink_icapability_capability_bits_auto_mdix = -1;
272 static int hf_elink_icapability_capability_bits_manual_speed = -1;
273 static int hf_elink_icapability_capability_speed_duplex_array_count = -1;
274 static int hf_elink_icapability_capability_speed = -1;
275 static int hf_elink_icapability_capability_duplex = -1;
276 static int hf_elink_interface_type = -1;
277 static int hf_elink_interface_state = -1;
278 static int hf_elink_admin_state = -1;
279 static int hf_elink_interface_label = -1;
280 static int hf_elink_hc_icount_in_octets = -1;
281 static int hf_elink_hc_icount_in_ucast = -1;
282 static int hf_elink_hc_icount_in_mcast = -1;
283 static int hf_elink_hc_icount_in_broadcast = -1;
284 static int hf_elink_hc_icount_out_octets = -1;
285 static int hf_elink_hc_icount_out_ucast = -1;
286 static int hf_elink_hc_icount_out_mcast = -1;
287 static int hf_elink_hc_icount_out_broadcast = -1;
288 
289 static int hf_elink_hc_mcount_stats_align_errors = -1;
290 static int hf_elink_hc_mcount_stats_fcs_errors = -1;
291 static int hf_elink_hc_mcount_stats_internal_mac_transmit_errors = -1;
292 static int hf_elink_hc_mcount_stats_frame_too_long = -1;
293 static int hf_elink_hc_mcount_stats_internal_mac_receive_errors = -1;
294 static int hf_elink_hc_mcount_stats_symbol_errors = -1;
295 
296 static int hf_qos_8021q_enable = -1;
297 static int hf_qos_dscp_ptp_event = -1;
298 static int hf_qos_dscp_ptp_general = -1;
299 static int hf_qos_dscp_urgent = -1;
300 static int hf_qos_dscp_scheduled = -1;
301 static int hf_qos_dscp_high = -1;
302 static int hf_qos_dscp_low = -1;
303 static int hf_qos_dscp_explicit = -1;
304 
305 static int hf_dlr_network_topology = -1;
306 static int hf_dlr_network_status = -1;
307 static int hf_dlr_ring_supervisor_status = -1;
308 static int hf_dlr_rsc_ring_supervisor_enable = -1;
309 static int hf_dlr_rsc_ring_supervisor_precedence = -1;
310 static int hf_dlr_rsc_beacon_interval = -1;
311 static int hf_dlr_rsc_beacon_timeout = -1;
312 static int hf_dlr_rsc_dlr_vlan_id = -1;
313 static int hf_dlr_ring_faults_count = -1;
314 static int hf_dlr_lanp1_dev_ip_addr = -1;
315 static int hf_dlr_lanp1_dev_physical_address = -1;
316 static int hf_dlr_lanp2_dev_ip_addr = -1;
317 static int hf_dlr_lanp2_dev_physical_address = -1;
318 static int hf_dlr_ring_protocol_participants_count = -1;
319 static int hf_dlr_rppl_dev_ip_addr = -1;
320 static int hf_dlr_rppl_dev_physical_address = -1;
321 static int hf_dlr_asa_supervisor_ip_addr = -1;
322 static int hf_dlr_asa_supervisor_physical_address = -1;
323 static int hf_dlr_active_supervisor_precedence = -1;
324 static int hf_dlr_capability_flags = -1;
325 static int hf_dlr_capflags_announce_base_node = -1;
326 static int hf_dlr_capflags_beacon_base_node = -1;
327 static int hf_dlr_capflags_reserved1 = -1;
328 static int hf_dlr_capflags_supervisor_capable = -1;
329 static int hf_dlr_capflags_reserved2 = -1;
330 static int hf_dlr_capflags_redundant_gateway_capable = -1;
331 static int hf_dlr_capflags_flush_frame_capable = -1;
332 static int hf_dlr_rgc_red_gateway_enable = -1;
333 static int hf_dlr_rgc_gateway_precedence = -1;
334 static int hf_dlr_rgc_advertise_interval = -1;
335 static int hf_dlr_rgc_advertise_timeout = -1;
336 static int hf_dlr_rgc_learning_update_enable = -1;
337 static int hf_dlr_redundant_gateway_status = -1;
338 static int hf_dlr_aga_ip_addr = -1;
339 static int hf_dlr_aga_physical_address = -1;
340 static int hf_dlr_active_gateway_precedence = -1;
341 
342 static int hf_cip_security_state = -1;
343 static int hf_eip_security_state = -1;
344 static int hf_eip_security_verify_client_cert = -1;
345 static int hf_eip_security_send_cert_chain = -1;
346 static int hf_eip_security_check_expiration = -1;
347 static int hf_eip_security_capability_flags = -1;
348 static int hf_eip_security_capflags_secure_renegotiation = -1;
349 static int hf_eip_security_capflags_reserved = -1;
350 static int hf_eip_security_num_avail_cipher_suites = -1;
351 static int hf_eip_security_avail_cipher_suite = -1;
352 static int hf_eip_security_num_allow_cipher_suites = -1;
353 static int hf_eip_security_allow_cipher_suite = -1;
354 static int hf_eip_security_num_psk = -1;
355 static int hf_eip_security_psk_identity_size = -1;
356 static int hf_eip_security_psk_identity = -1;
357 static int hf_eip_security_psk_size = -1;
358 static int hf_eip_security_psk = -1;
359 static int hf_eip_security_num_active_certs = -1;
360 static int hf_eip_security_num_trusted_auths = -1;
361 static int hf_eip_cert_name = -1;
362 static int hf_eip_cert_state = -1;
363 static int hf_eip_cert_encoding = -1;
364 static int hf_eip_cert_device_cert_status = -1;
365 static int hf_eip_cert_ca_cert_status = -1;
366 static int hf_eip_cert_capflags_push = -1;
367 static int hf_eip_cert_capflags_reserved = -1;
368 static int hf_eip_cert_capability_flags = -1;
369 static int hf_eip_cert_num_certs = -1;
370 static int hf_eip_cert_cert_name = -1;
371 
372 /* Initialize the subtree pointers */
373 static gint ett_enip = -1;
374 static gint ett_cip_io_generic = -1;
375 static gint ett_path = -1;
376 static gint ett_count_tree = -1;
377 static gint ett_type_tree = -1;
378 static gint ett_command_tree = -1;
379 static gint ett_sockadd = -1;
380 static gint ett_lsrcf = -1;
381 static gint ett_tcpip_status = -1;
382 static gint ett_tcpip_admin_capability = -1;
383 static gint ett_tcpip_config_cap = -1;
384 static gint ett_tcpip_config_control = -1;
385 static gint ett_elink_interface_flags = -1;
386 static gint ett_elink_icontrol_bits = -1;
387 static gint ett_elink_icapability_bits = -1;
388 static gint ett_dlr_capability_flags = -1;
389 static gint ett_dlr_lnknbrstatus_flags = -1;
390 static gint ett_eip_security_capability_flags = -1;
391 static gint ett_eip_security_psk = -1;
392 static gint ett_eip_security_active_certs = -1;
393 static gint ett_eip_security_trusted_auths = -1;
394 static gint ett_eip_cert_capability_flags = -1;
395 static gint ett_eip_cert_num_certs = -1;
396 static gint ett_security_profiles = -1;
397 static gint ett_iana_port_state_flags = -1;
398 static gint ett_connection_info = -1;
399 static gint ett_connection_path_info = -1;
400 static gint ett_cmd_data = -1;
401 
402 static expert_field ei_mal_tcpip_status = EI_INIT;
403 static expert_field ei_mal_tcpip_config_cap = EI_INIT;
404 static expert_field ei_mal_tcpip_config_control = EI_INIT;
405 static expert_field ei_mal_tcpip_interface_config = EI_INIT;
406 static expert_field ei_mal_tcpip_mcast_config = EI_INIT;
407 static expert_field ei_mal_tcpip_last_conflict = EI_INIT;
408 static expert_field ei_mal_tcpip_snn = EI_INIT;
409 static expert_field ei_mal_elink_interface_flags = EI_INIT;
410 static expert_field ei_mal_elink_physical_address = EI_INIT;
411 static expert_field ei_mal_elink_interface_counters = EI_INIT;
412 static expert_field ei_mal_elink_media_counters = EI_INIT;
413 static expert_field ei_mal_elink_interface_control = EI_INIT;
414 static expert_field ei_mal_dlr_ring_supervisor_config = EI_INIT;
415 static expert_field ei_mal_dlr_last_active_node_on_port_1 = EI_INIT;
416 static expert_field ei_mal_dlr_last_active_node_on_port_2 = EI_INIT;
417 static expert_field ei_mal_dlr_ring_protocol_participants_list = EI_INIT;
418 static expert_field ei_mal_dlr_active_supervisor_address = EI_INIT;
419 static expert_field ei_mal_dlr_capability_flags = EI_INIT;
420 static expert_field ei_mal_dlr_redundant_gateway_config = EI_INIT;
421 static expert_field ei_mal_dlr_active_gateway_address = EI_INIT;
422 static expert_field ei_mal_eip_security_capability_flags = EI_INIT;
423 static expert_field ei_mal_eip_security_avail_cipher_suites = EI_INIT;
424 static expert_field ei_mal_eip_security_allow_cipher_suites = EI_INIT;
425 static expert_field ei_mal_eip_security_preshared_keys = EI_INIT;
426 static expert_field ei_mal_eip_security_active_certs = EI_INIT;
427 static expert_field ei_mal_eip_security_trusted_auths = EI_INIT;
428 static expert_field ei_mal_eip_cert_capability_flags = EI_INIT;
429 static expert_field ei_mal_cpf_item_length_mismatch = EI_INIT;
430 static expert_field ei_mal_cpf_item_minimum_size = EI_INIT;
431 
432 static dissector_table_t   subdissector_srrd_table;
433 static dissector_table_t   subdissector_io_table;
434 static dissector_table_t   subdissector_decode_as_io_table;
435 static dissector_table_t   subdissector_class_table;
436 static dissector_table_t   subdissector_cip_connection_table;
437 
438 static dissector_handle_t  arp_handle;
439 static dissector_handle_t  cipsafety_handle;
440 static dissector_handle_t  cip_io_generic_handle;
441 static dissector_handle_t  cip_implicit_handle;
442 static dissector_handle_t  cip_handle;
443 static dissector_handle_t  enip_tcp_handle;
444 static dissector_handle_t  cipio_handle;
445 static dissector_handle_t  cip_class1_handle;
446 
447 static gboolean enip_desegment  = TRUE;
448 static gboolean enip_OTrun_idle = TRUE;
449 static gboolean enip_TOrun_idle = FALSE;
450 
451 static int proto_dlr = -1;
452 
453 static int hf_dlr_ringsubtype = -1;
454 static int hf_dlr_ringprotoversion = -1;
455 static int hf_dlr_frametype = -1;
456 static int hf_dlr_sourceport = -1;
457 static int hf_dlr_sourceip = -1;
458 static int hf_dlr_sequenceid = -1;
459 
460 static int hf_dlr_ringstate = -1;
461 static int hf_dlr_supervisorprecedence = -1;
462 static int hf_dlr_beaconinterval = -1;
463 static int hf_dlr_beacontimeout = -1;
464 static int hf_dlr_beaconreserved = -1;
465 
466 static int hf_dlr_nreqreserved = -1;
467 
468 static int hf_dlr_nressourceport = -1;
469 static int hf_dlr_nresreserved = -1;
470 
471 static int hf_dlr_lnknbrstatus = -1;
472 static int hf_dlr_lnknbrstatus_port1 = -1;
473 static int hf_dlr_lnknbrstatus_port2 = -1;
474 static int hf_dlr_lnknbrstatus_reserved = -1;
475 static int hf_dlr_lnknbrstatus_frame_type = -1;
476 static int hf_dlr_lnknbrreserved = -1;
477 
478 static int hf_dlr_lfreserved = -1;
479 
480 static int hf_dlr_anreserved = -1;
481 
482 static int hf_dlr_sonumnodes = -1;
483 static int hf_dlr_somac = -1;
484 static int hf_dlr_soip = -1;
485 static int hf_dlr_soreserved = -1;
486 
487 static int hf_dlr_advgatewaystate = -1;
488 static int hf_dlr_advgatewayprecedence = -1;
489 static int hf_dlr_advadvertiseinterval = -1;
490 static int hf_dlr_advadvertisetimeout = -1;
491 static int hf_dlr_advlearningupdateenable = -1;
492 static int hf_dlr_advreserved = -1;
493 
494 static int hf_dlr_flushlearningupdateenable = -1;
495 static int hf_dlr_flushreserved = -1;
496 
497 static int hf_dlr_learnreserved  = -1;
498 
499 static gint ett_dlr = -1;
500 
501 /* Translate function to string - Encapsulation commands */
502 static const value_string encap_cmd_vals[] = {
503    { NOP,               "NOP"                },
504    { LIST_SERVICES,     "List Services"      },
505    { LIST_IDENTITY,     "List Identity"      },
506    { LIST_INTERFACES,   "List Interfaces"    },
507    { REGISTER_SESSION,  "Register Session"   },
508    { UNREGISTER_SESSION,"Unregister Session" },
509    { SEND_RR_DATA,      "Send RR Data"       },
510    { SEND_UNIT_DATA,    "Send Unit Data"     },
511    { START_DTLS,        "StartDTLS"          },
512 
513    { 0,                 NULL                 }
514 };
515 
516 /* Translate function to string - Encapsulation status */
517 static const value_string encap_status_vals[] = {
518    { SUCCESS,              "Success"                       },
519    { INVALID_CMD,          "Invalid Command"               },
520    { NO_RESOURCES,         "No Memory Resources"           },
521    { INCORRECT_DATA,       "Incorrect Data"                },
522    { INVALID_SESSION,      "Invalid Session Handle"        },
523    { INVALID_LENGTH,       "Invalid Length"                },
524    { UNSUPPORTED_PROT_REV, "Unsupported Protocol Revision" },
525    { ENCAP_HEADER_ERROR,   "Encapsulated CIP service not allowed on this port" },
526 
527    { 0,                    NULL }
528 };
529 
530 /* Translate function to Common packet format values */
531 static const value_string cpf_type_vals[] = {
532    { CPF_ITEM_NULL,                 "Null Address Item"        },
533    { CPF_ITEM_CIP_IDENTITY,         "CIP Identity"             },
534    { CPF_ITEM_CIP_SECURITY,         "CIP Security Information" },
535    { CPF_ITEM_ENIP_CAPABILITY,      "EtherNet/IP Capability"   },
536    { CPF_ITEM_ENIP_USAGE,           "EtherNet/IP Usage"        },
537    { CPF_ITEM_CONNECTED_ADDRESS,    "Connected Address Item"   },
538    { CPF_ITEM_CONNECTED_DATA,       "Connected Data Item"      },
539    { CPF_ITEM_UNCONNECTED_DATA,     "Unconnected Data Item"    },
540    { CPF_ITEM_LIST_SERVICES_RESP,   "List Services Response"   },
541    { CPF_ITEM_SOCK_ADR_INFO_OT,     "Socket Address Info O->T" },
542    { CPF_ITEM_SOCK_ADR_INFO_TO,     "Socket Address Info T->O" },
543    { CPF_ITEM_SEQUENCED_ADDRESS,    "Sequenced Address Item"   },
544    { CPF_ITEM_UNCONNECTED_MSG_DTLS, "Unconnected Message over UDP" },
545 
546    { 0,                    NULL }
547 };
548 
549 static const value_string unconn_msg_type_vals[] = {
550    { 0, "Reserved" },
551    { 1, "UCMM_NOACK" },
552 
553    { 0, NULL }
554 };
555 
556 static const value_string enip_tcpip_status_interface_config_vals[] = {
557    { 0,        "Not configured"    },
558    { 1,        "BOOTP/DHCP/NVS"    },
559    { 2,        "Hardware settings" },
560 
561    { 0,        NULL             }
562 };
563 
564 static const value_string enip_tcpip_status_acd_vals[] = {
565    { 0,  "No Address Conflict Detected" },
566    { 1,  "Address Conflict Detected"    },
567 
568    { 0,        NULL             }
569 };
570 
571 static const value_string enip_tcpip_config_control_config_vals[] = {
572    { 0,  "Static IP"   },
573    { 1,  "BOOTP"       },
574    { 2,  "DHCP"        },
575 
576    { 0,  NULL          }
577 };
578 
579 static const value_string enip_tcpip_mcast_alloc_vals[] = {
580    { 0,  "Use default multicast algorithm"      },
581    { 1,  "Use Num Mcast and Mcast Start Addr"   },
582 
583    { 0,  NULL                                   }
584 };
585 
586 static const value_string enip_tcpip_acd_activity_vals[] = {
587    { 0,  "No Conflict Detected" },
588    { 1,  "Probe IPv4 Address"   },
589    { 2,  "Ongoing Detection"    },
590    { 3,  "Semi Active Probe"    },
591 
592    { 0,        NULL             }
593 };
594 
595 static const value_string enip_elink_duplex_vals[] = {
596    { 0,  "Half Duplex"    },
597    { 1,  "Full Duplex"    },
598 
599    { 0,  NULL             }
600 };
601 
602 static const value_string enip_elink_iflags_neg_status_vals[] = {
603    { 0,  "Auto-negotiation in progress"                                 },
604    { 1,  "Auto-negotiation and speed detection failed"                  },
605    { 2,  "Auto-negotiation failed but detected speed"                   },
606    { 3,  "Successfully negotiated speed and duplex"                     },
607    { 4,  "Auto-negotiation not attempted.  Forced speed and duplex"     },
608 
609    { 0,  NULL                                                           }
610 };
611 
612 static const value_string enip_elink_iflags_reset_vals[] = {
613    { 0,  "Activate change automatically"             },
614    { 1,  "Device requires Reset service for change"  },
615 
616    { 0,  NULL              }
617 };
618 
619 static const value_string enip_elink_iflags_hw_fault_vals[] = {
620    { 0,  "No local hardware fault"        },
621    { 1,  "Local hardware fault detected"  },
622 
623    { 0,  NULL              }
624 };
625 
626 static const value_string enip_elink_interface_type_vals[] = {
627    { 0,  "Unknown type"    },
628    { 1,  "Internal"        },
629    { 2,  "Twisted-pair"    },
630    { 3,  "Optical fiber"   },
631 
632    { 0,  NULL              }
633 };
634 
635 static const value_string enip_elink_interface_state_vals[] = {
636    { 0,  "Unknown state"   },
637    { 1,  "Enabled"         },
638    { 2,  "Disabled"        },
639    { 3,  "Testing"         },
640 
641    { 0,  NULL              }
642 };
643 
644 static const value_string enip_elink_admin_state_vals[] = {
645    { 1,  "Enabled"         },
646    { 2,  "Disabled"        },
647 
648    { 0,  NULL              }
649 };
650 
651 static const value_string enip_dlr_network_topology_vals[] = {
652    { 0,  "Linear"    },
653    { 1,  "Ring"      },
654 
655    { 0,  NULL        }
656 };
657 
658 static const value_string enip_dlr_network_status_vals[] = {
659    { 0,  "Normal" },
660    { 1,  "Ring Fault" },
661    { 2,  "Unexpected Loop Detected" },
662    { 3,  "Partial Network Failure" },
663    { 4,  "Rapid Fault/Restore Cycle" },
664 
665    { 0,  NULL }
666 };
667 
668 static const value_string enip_dlr_ring_supervisor_status_vals[] = {
669    { 0,  "Backup Ring Supervisor" },
670    { 1,  "Active Ring Supervisor" },
671    { 2,  "Ring Node" },
672    { 3,  "Non-DLR Topology" },
673    { 4,  "Cannot Support Parameters" },
674 
675    { 0,  NULL }
676 };
677 
678 static const value_string enip_dlr_redundant_gateway_status_vals[] = {
679    { 0,  "Non-Gateway DLR node" },
680    { 1,  "Backup Gateway" },
681    { 2,  "Active Gateway" },
682    { 3,  "Gateway Fault" },
683    { 4,  "Cannot Support Parameters" },
684    { 5,  "Partial Network Fault" },
685 
686    { 0,  NULL }
687 };
688 
689 static const value_string cip_security_state_vals[] = {
690    { 0,  "Factory Default Configuration" },
691    { 1,  "Initial Commissioning In Progress" },
692    { 2,  "Configured" },
693    { 3,  "Incomplete Configuration" },
694 
695    { 0,  NULL }
696 };
697 
698 static const value_string eip_security_state_vals[] = {
699    { 0,  "Factory Default Configuration" },
700    { 1,  "Configuration In Progress" },
701    { 2,  "Configured" },
702 
703    { 0,  NULL }
704 };
705 
706 static const value_string eip_cert_state_vals[] = {
707    { 0,  "Created" },
708 
709    { 0,  NULL }
710 };
711 
712 static const value_string eip_cert_status_vals[] = {
713    { 0,  "Not Verified" },
714    { 1,  "Verified" },
715    { 2,  "Invalid" },
716 
717    { 0,  NULL }
718 };
719 
720 /* Translate interface handle to string */
721 static const value_string enip_interface_handle_vals[] = {
722    { 0,        "CIP" },
723 
724    { 0,        NULL  }
725 };
726 
727 /* Translate function to DLR Frame Type values */
728 static const value_string dlr_frame_type_vals[] = {
729    { DLR_FT_BEACON,           "Beacon"                        },
730    { DLR_FT_NEIGHBOR_REQ,     "Neighbor_Check_Request"        },
731    { DLR_FT_NEIGHBOR_RES,     "Neighbor_Check_Response"       },
732    { DLR_FT_LINK_STAT,        "Link_Status / Neighbor_Status" },
733    { DLR_FT_LOCATE_FLT,       "Locate_Fault"                  },
734    { DLR_FT_ANNOUNCE,         "Announce"                      },
735    { DLR_FT_SIGN_ON,          "Sign_On"                       },
736    { DLR_FT_ADVERTISE,        "Advertise"                     },
737    { DLR_FT_FLUSH_TABLES,     "Flush_Tables"                  },
738    { DLR_FT_LEARNING_UPDATE,  "Learning_Update"               },
739 
740    { 0,                    NULL }
741 };
742 
743 /* Translate function to DLR Source Port values */
744 static const value_string dlr_source_port_vals[] = {
745    { 0,     "Port 1 or Port 2" },
746    { 1,     "Port 1" },
747    { 2,     "Port 2" },
748 
749    { 0,                    NULL }
750 };
751 
752 /* Translate function to DLR Ring State values */
753 static const value_string dlr_ring_state_vals[] = {
754    { 1,     "RING_NORMAL_STATE" },
755    { 2,     "RING_FAULT_STATE" },
756 
757    { 0,                    NULL }
758 };
759 
760 /* Translate function to DLR Advertise State values */
761 static const value_string dlr_adv_state_vals[] = {
762    { 0x01,     "ACTIVE_LISTEN_STATE" },
763    { 0x02,     "ACTIVE_NORMAL_STATE" },
764    { 0x03,     "FAULT_STATE" },
765 
766    { 0,                    NULL }
767 };
768 
769 /* Translate function to DLR Learning Update values */
770 static const value_string dlr_adv_learning_update_vals[] = {
771    { 0,  "Disabled"        },
772    { 1,  "Enabled"         },
773 
774    { 0,  NULL              }
775 };
776 
777 /* Translate function to DLR Flush Learning Update values */
778 static const value_string dlr_flush_learning_update_vals[] = {
779    { 0,  "Disabled"        },
780    { 1,  "Enabled"         },
781 
782    { 0,  NULL              }
783 };
784 
785 static const true_false_string dlr_lnknbrstatus_frame_type_vals = {
786     "Neighbor_Status Frame",
787     "Link_Status Frame"
788 };
789 
enip_prompt(packet_info * pinfo _U_,gchar * result)790 static void enip_prompt(packet_info *pinfo _U_, gchar* result)
791 {
792    g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Dissect unidentified I/O traffic as");
793 }
794 
795 static wmem_map_t *enip_request_hashtable = NULL;
796 
797 /* Return codes of function classifying packets as query/response */
798 enum enip_packet_type {ENIP_REQUEST_PACKET, ENIP_RESPONSE_PACKET, ENIP_CANNOT_CLASSIFY};
799 enum enip_packet_data_type { EPDT_UNKNOWN, EPDT_CONNECTED_TRANSPORT, EPDT_UNCONNECTED };
800 
801 typedef struct enip_request_key {
802    guint32 session_handle;
803    enum enip_packet_type      requesttype;
804    enum enip_packet_data_type type;
805    guint64 sender_context;
806    guint32 conversation;
807    union {
808       struct {
809          guint32 connid;
810          guint16 sequence;
811       } connected_transport;
812    } data;
813 } enip_request_key_t;
814 
815 typedef struct enip_request_val {
816    wmem_tree_t *frames;
817 } enip_request_val_t;
818 
819 /*
820  * Hash Functions
821  */
822 static gboolean
enip_request_equal(gconstpointer v,gconstpointer w)823 enip_request_equal(gconstpointer v, gconstpointer w)
824 {
825    const enip_request_key_t *v1 = (const enip_request_key_t *)v;
826    const enip_request_key_t *v2 = (const enip_request_key_t *)w;
827 
828    if (  v1->conversation == v2->conversation
829          && v1->session_handle == v2->session_handle
830          && v1->type == v2->type
831          && ( (  v1->sender_context == v2->sender_context   /* heuristic approach */
832                  && v1->type == EPDT_UNCONNECTED
833                  )
834               ||
835               (  v1->data.connected_transport.connid == v2->data.connected_transport.connid
836                  && v1->data.connected_transport.sequence == v2->data.connected_transport.sequence
837                  && v1->type == EPDT_CONNECTED_TRANSPORT
838                  )
839             )
840       )
841       return TRUE;
842 
843    return FALSE;
844 }
845 
846 static void
enip_fmt_lir_revision(gchar * result,guint32 revision)847 enip_fmt_lir_revision( gchar *result, guint32 revision )
848 {
849    g_snprintf( result, ITEM_LABEL_LENGTH, "%d.%02d", (guint8)(( revision & 0xFF00 ) >> 8), (guint8)(revision & 0xFF) );
850 }
851 
852 static guint
enip_request_hash(gconstpointer v)853 enip_request_hash (gconstpointer v)
854 {
855    const enip_request_key_t *key = (const enip_request_key_t *)v;
856    guint val;
857 
858    val = (guint)(key->conversation * 37 + key->session_handle * 93 + key->type * 765);
859 
860    if (key->type == EPDT_UNCONNECTED)
861    {
862       val += ((guint)(key->sender_context * 23));
863    }
864    else if (key->type == EPDT_CONNECTED_TRANSPORT)
865    {
866       val += ((guint)(key->data.connected_transport.connid * 87 + key->data.connected_transport.sequence * 834));
867    }
868 
869    return val;
870 }
871 
872 static enip_request_info_t *
enip_match_request(packet_info * pinfo,proto_tree * tree,enip_request_key_t * prequest_key)873 enip_match_request( packet_info *pinfo, proto_tree *tree, enip_request_key_t *prequest_key )
874 {
875    enip_request_key_t  *new_request_key;
876    enip_request_val_t  *request_val;
877    enip_request_info_t *request_info;
878 
879    request_info = NULL;
880    request_val = (enip_request_val_t *)wmem_map_lookup( enip_request_hashtable, prequest_key );
881    if (!pinfo->fd->visited)
882    {
883       if ( prequest_key && prequest_key->requesttype == ENIP_REQUEST_PACKET )
884       {
885          if ( request_val == NULL )
886          {
887             new_request_key = (enip_request_key_t *)wmem_memdup(wmem_file_scope(), prequest_key, sizeof(enip_request_key_t));
888 
889             request_val = wmem_new(wmem_file_scope(), enip_request_val_t);
890             request_val->frames = wmem_tree_new(wmem_file_scope());
891 
892             wmem_map_insert(enip_request_hashtable, new_request_key, request_val );
893          }
894 
895          request_info = wmem_new(wmem_file_scope(), enip_request_info_t);
896          request_info->req_num = pinfo->num;
897          request_info->rep_num = 0;
898          request_info->req_time = pinfo->abs_ts;
899          request_info->cip_info = NULL;
900          wmem_tree_insert32(request_val->frames, pinfo->num, (void *)request_info);
901       }
902       if ( request_val && prequest_key && prequest_key->requesttype == ENIP_RESPONSE_PACKET )
903       {
904          request_info = (enip_request_info_t*)wmem_tree_lookup32_le( request_val->frames, pinfo->num );
905          if ( request_info )
906          {
907             request_info->rep_num = pinfo->num;
908          }
909       }
910    }
911    else
912    {
913       if ( request_val )
914          request_info = (enip_request_info_t *)wmem_tree_lookup32_le( request_val->frames, pinfo->num );
915    }
916 
917    if ( tree && request_info )
918    {
919       /* print state tracking in the tree */
920       if ( prequest_key && prequest_key->requesttype == ENIP_REQUEST_PACKET )
921       {
922          /* This is a request */
923          if (request_info->rep_num)
924          {
925             proto_item *it;
926 
927             it = proto_tree_add_uint(tree, hf_enip_response_in,
928                   NULL, 0, 0, request_info->rep_num);
929             proto_item_set_generated(it);
930          }
931       }
932       else
933       {
934          if ( prequest_key && prequest_key->requesttype == ENIP_RESPONSE_PACKET )
935          {
936             /* This is a reply */
937             if (request_info->req_num)
938             {
939                proto_item *it;
940                nstime_t    ns;
941 
942                it = proto_tree_add_uint(tree, hf_enip_response_to,
943                      NULL, 0, 0, request_info->req_num);
944                proto_item_set_generated(it);
945 
946                nstime_delta(&ns, &pinfo->abs_ts, &request_info->req_time);
947                it = proto_tree_add_time(tree, hf_enip_time, NULL, 0, 0, &ns);
948                proto_item_set_generated(it);
949             }
950          }
951       }
952    }
953    return request_info;
954 }
955 
956 typedef struct enip_conn_key {
957    cip_connection_triad_t triad;
958    guint32 O2TConnID;
959    guint32 T2OConnID;
960 } enip_conn_key_t;
961 
962 typedef struct _enip_conv_info_t {
963    wmem_tree_t *O2TConnIDs;
964    wmem_tree_t *T2OConnIDs;
965 } enip_conv_info_t;
966 
967 /*
968  * Conversation filter
969  */
970 static gboolean
enip_io_conv_valid(packet_info * pinfo)971 enip_io_conv_valid(packet_info *pinfo)
972 {
973    cip_conn_info_t* conn = (cip_conn_info_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO);
974 
975    if (conn == NULL)
976       return FALSE;
977 
978    return (((conn->TransportClass_trigger & CI_TRANSPORT_CLASS_MASK) == 0) ||
979            ((conn->TransportClass_trigger & CI_TRANSPORT_CLASS_MASK) == 1));
980 }
981 
982 static gchar *
enip_io_conv_filter(packet_info * pinfo)983 enip_io_conv_filter(packet_info *pinfo)
984 {
985    char      *buf;
986    cip_conn_info_t* conn = (cip_conn_info_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO);
987 
988    if (conn == NULL)
989       return NULL;
990 
991    if (conn->close_frame > 0)
992    {
993       buf = g_strdup_printf(
994           "((frame.number == %u) || ((frame.number >= %u) && (frame.number <= %u))) && "  /* Frames between ForwardOpen and ForwardClose reply */
995            "((enip.cpf.sai.connid == 0x%08x || enip.cpf.sai.connid == 0x%08x) || "                             /* O->T and T->O Connection IDs */
996            "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))",     /* Connection Triad */
997            conn->open_req_frame, conn->open_reply_frame, conn->close_frame,
998            conn->O2T.connID, conn->T2O.connID,
999            conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
1000    }
1001    else
1002    {
1003        /* If Forward Close isn't found, don't limit the (end) frame range */
1004       buf = g_strdup_printf(
1005           "((frame.number == %u) || (frame.number >= %u)) && "                                            /* Frames starting with ForwardOpen */
1006            "((enip.cpf.sai.connid == 0x%08x || enip.cpf.sai.connid == 0x%08x) || "                            /* O->T and T->O Connection IDs */
1007            "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))",    /* Connection Triad */
1008            conn->open_req_frame, conn->open_reply_frame,
1009            conn->O2T.connID, conn->T2O.connID,
1010            conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
1011    }
1012 
1013    return buf;
1014 }
1015 
1016 static gboolean
enip_exp_conv_valid(packet_info * pinfo)1017 enip_exp_conv_valid(packet_info *pinfo)
1018 {
1019    cip_conn_info_t* conn = (cip_conn_info_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO);
1020 
1021    if (conn == NULL)
1022       return FALSE;
1023 
1024    return (((conn->TransportClass_trigger & CI_TRANSPORT_CLASS_MASK) == 2) ||
1025            ((conn->TransportClass_trigger & CI_TRANSPORT_CLASS_MASK) == 3));
1026 }
1027 
1028 static gchar *
enip_exp_conv_filter(packet_info * pinfo)1029 enip_exp_conv_filter(packet_info *pinfo)
1030 {
1031    char      *buf;
1032    cip_conn_info_t* conn = (cip_conn_info_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO);
1033 
1034    if (conn == NULL)
1035       return NULL;
1036 
1037    if (conn->close_frame > 0)
1038    {
1039       buf = g_strdup_printf(
1040           "((frame.number == %u) || ((frame.number >= %u) && (frame.number <= %u))) && "  /* Frames between ForwardOpen and ForwardClose reply */
1041            "((enip.cpf.cai.connid == 0x%08x || enip.cpf.cai.connid == 0x%08x) || "                             /* O->T and T->O Connection IDs */
1042            "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))",     /* Connection Triad */
1043            conn->open_req_frame, conn->open_reply_frame, conn->close_frame,
1044            conn->O2T.connID, conn->T2O.connID,
1045            conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
1046    }
1047    else
1048    {
1049        /* If Forward Close isn't found, don't limit the (end) frame range */
1050       buf = g_strdup_printf(
1051           "((frame.number == %u) || (frame.number >= %u)) && "    /* Frames between ForwardOpen and ForwardClose */
1052            "((enip.cpf.cai.connid == 0x%08x || enip.cpf.cai.connid == 0x%08x) || "                          /* O->T and T->O Connection IDs */
1053            "((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x)))",  /* Connection Triad */
1054            conn->open_req_frame, conn->open_reply_frame,
1055            conn->O2T.connID, conn->T2O.connID,
1056            conn->triad.ConnSerialNumber, conn->triad.VendorID, conn->triad.DeviceSerialNumber);
1057    }
1058    return buf;
1059 }
1060 
cip_connection_conv_valid(packet_info * pinfo)1061 static gboolean cip_connection_conv_valid(packet_info *pinfo)
1062 {
1063    return enip_io_conv_valid(pinfo) || enip_exp_conv_valid(pinfo);
1064 }
1065 
cip_connection_conv_filter(packet_info * pinfo)1066 static gchar* cip_connection_conv_filter(packet_info *pinfo)
1067 {
1068    char* buf = NULL;
1069 
1070    if (enip_io_conv_valid(pinfo))
1071    {
1072       buf = enip_io_conv_filter(pinfo);
1073    }
1074    else if (enip_exp_conv_valid(pinfo))
1075    {
1076       buf = enip_exp_conv_filter(pinfo);
1077    }
1078 
1079    return buf;
1080 }
1081 
1082 /*
1083  * Connection management
1084  */
1085 
1086 // Key: (triad, connection IDs), Value: cip_conn_info_t
1087 static wmem_map_t *enip_conn_hashtable = NULL;
1088 static guint32 enip_unique_connid;
1089 
1090 static gboolean
enip_conn_equal(gconstpointer v,gconstpointer w)1091 enip_conn_equal(gconstpointer v, gconstpointer w)
1092 {
1093   const enip_conn_key_t *v1 = (const enip_conn_key_t *)v;
1094   const enip_conn_key_t *v2 = (const enip_conn_key_t *)w;
1095 
1096   if ((v1->triad.ConnSerialNumber == v2->triad.ConnSerialNumber) &&
1097       (v1->triad.VendorID == v2->triad.VendorID) &&
1098       (v1->triad.DeviceSerialNumber == v2->triad.DeviceSerialNumber) &&
1099       ((v1->O2TConnID == 0) || (v2->O2TConnID == 0) || (v1->O2TConnID == v2->O2TConnID)) &&
1100       ((v1->T2OConnID == 0) || (v2->T2OConnID == 0) || (v1->T2OConnID == v2->T2OConnID)))
1101     return TRUE;
1102 
1103   return FALSE;
1104 }
1105 
1106 static guint
enip_conn_hash(gconstpointer v)1107 enip_conn_hash (gconstpointer v)
1108 {
1109    const enip_conn_key_t *key = (const enip_conn_key_t *)v;
1110    guint val;
1111 
1112    val = (guint)( key->triad.ConnSerialNumber + key->triad.VendorID + key->triad.DeviceSerialNumber );
1113 
1114    return val;
1115 }
1116 
1117 // Create a list of connection IDs and attach it to the conversation.
create_connection_id_list(conversation_t * conversation)1118 static enip_conv_info_t* create_connection_id_list(conversation_t* conversation)
1119 {
1120    enip_conv_info_t* enip_info = wmem_new(wmem_file_scope(), enip_conv_info_t);
1121    enip_info->O2TConnIDs = wmem_tree_new(wmem_file_scope());
1122    enip_info->T2OConnIDs = wmem_tree_new(wmem_file_scope());
1123 
1124    conversation_add_proto_data(conversation, proto_enip, enip_info);
1125 
1126    return enip_info;
1127 }
1128 
1129 static
get_conversation_info_one_direction(packet_info * pinfo,address * src_address,address * dst_address,cip_connID_info_t * connid_info)1130 enip_conv_info_t* get_conversation_info_one_direction(packet_info* pinfo, address* src_address, address* dst_address, cip_connID_info_t* connid_info)
1131 {
1132    /* default some information if not included */
1133    if ((connid_info->port == 0) || (connid_info->type == CONN_TYPE_MULTICAST))
1134    {
1135       connid_info->port = ENIP_IO_PORT;
1136    }
1137 
1138    ws_in6_addr ipv6_zero = {0};
1139    if ((connid_info->ipaddress.type == AT_NONE) ||
1140        ((connid_info->ipaddress.type == AT_IPv4) && ((*(const guint32*)connid_info->ipaddress.data)) == 0) ||
1141        ((connid_info->ipaddress.type == AT_IPv6) && (memcmp(connid_info->ipaddress.data, &ipv6_zero, sizeof(ipv6_zero)) == 0)) ||
1142        (connid_info->type != CONN_TYPE_MULTICAST))
1143    {
1144       copy_address_wmem(wmem_file_scope(), &connid_info->ipaddress, dst_address);
1145    }
1146 
1147    address dest_address;
1148    if (connid_info->ipaddress.type == AT_IPv6)
1149    {
1150       dest_address.type = AT_IPv6;
1151       dest_address.len = 16;
1152    }
1153    else
1154    {
1155       dest_address.type = AT_IPv4;
1156       dest_address.len = 4;
1157    }
1158    dest_address.data = connid_info->ipaddress.data;
1159 
1160    // Similar logic to find_or_create_conversation(), but since I/O traffic
1161    //    is on UDP, the pinfo parameter doesn't have the correct information.
1162    conversation_t* conversation = find_conversation(pinfo->num, src_address, &dest_address,
1163       ENDPOINT_UDP, connid_info->port, 0, NO_PORT_B);
1164    if (conversation == NULL)
1165    {
1166       conversation = conversation_new(pinfo->num, src_address, &dest_address,
1167          ENDPOINT_UDP, connid_info->port, 0, NO_PORT2);
1168    }
1169 
1170    enip_conv_info_t* enip_info = (enip_conv_info_t*)conversation_get_proto_data(conversation, proto_enip);
1171    if (enip_info == NULL)
1172    {
1173       enip_info = create_connection_id_list(conversation);
1174    }
1175 
1176    return enip_info;
1177 }
1178 
1179 // connInfo - Connection Information that is known so far (from the Forward Open Request).
enip_open_cip_connection(packet_info * pinfo,cip_conn_info_t * connInfo)1180 static void enip_open_cip_connection( packet_info *pinfo, cip_conn_info_t* connInfo)
1181 {
1182    if (pinfo->fd->visited)
1183       return;
1184 
1185    // Don't create connections for Null Forward Opens.
1186    if (connInfo->T2O.type == CONN_TYPE_NULL && connInfo->O2T.type == CONN_TYPE_NULL)
1187    {
1188       return;
1189    }
1190 
1191    enip_conn_key_t* conn_key = wmem_new(wmem_file_scope(), enip_conn_key_t);
1192    conn_key->triad = connInfo->triad;
1193    conn_key->O2TConnID = connInfo->O2T.connID;
1194    conn_key->T2OConnID = connInfo->T2O.connID;
1195 
1196    cip_conn_info_t* conn_val = (cip_conn_info_t*)wmem_map_lookup( enip_conn_hashtable, conn_key );
1197    if ( conn_val == NULL )
1198    {
1199       conn_val = wmem_new0(wmem_file_scope(), cip_conn_info_t);
1200 
1201       // Copy initial connection data from the Forward Open Request.
1202       *conn_val = *connInfo;
1203 
1204       // These values are not copies from the Forward Open Request. Initialize these separately.
1205       conn_val->open_reply_frame = pinfo->num;
1206       conn_val->connid = enip_unique_connid++;
1207 
1208       wmem_map_insert(enip_conn_hashtable, conn_key, conn_val );
1209 
1210       /* I/O connection */
1211       if (((connInfo->TransportClass_trigger & CI_TRANSPORT_CLASS_MASK) == 0) ||
1212           ((connInfo->TransportClass_trigger & CI_TRANSPORT_CLASS_MASK) == 1))
1213       {
1214          /* check for O->T conversation */
1215          enip_conv_info_t* enip_info = get_conversation_info_one_direction(pinfo, &pinfo->dst, &pinfo->src, &(connInfo->O2T));
1216          wmem_tree_insert32(enip_info->O2TConnIDs, connInfo->O2T.connID, (void*)conn_val);
1217 
1218          /* Check if separate T->O conversation is necessary.  If either side is multicast
1219             or ports aren't equal, a separate conversation must be generated */
1220          enip_info = get_conversation_info_one_direction(pinfo, &pinfo->src, &pinfo->dst, &(connInfo->T2O));
1221          wmem_tree_insert32(enip_info->T2OConnIDs, connInfo->T2O.connID, (void *)conn_val);
1222       }
1223       else
1224       {
1225          /* explicit message connection */
1226          conversation_t* conversation = find_or_create_conversation(pinfo);
1227 
1228          enip_conv_info_t* enip_info = (enip_conv_info_t *)conversation_get_proto_data(conversation, proto_enip);
1229          if (!enip_info)
1230          {
1231             enip_info = create_connection_id_list(conversation);
1232          }
1233          wmem_tree_insert32(enip_info->O2TConnIDs, connInfo->O2T.connID, (void *)conn_val);
1234          wmem_tree_insert32(enip_info->T2OConnIDs, connInfo->T2O.connID, (void *)conn_val);
1235       }
1236    }
1237 
1238    /* Save the connection info for the conversation filter */
1239    p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO, conn_val);
1240 }
1241 
1242 void
enip_close_cip_connection(packet_info * pinfo,const cip_connection_triad_t * triad)1243 enip_close_cip_connection(packet_info *pinfo, const cip_connection_triad_t* triad)
1244 {
1245    if (pinfo->fd->visited)
1246       return;
1247 
1248    enip_conn_key_t conn_key;
1249    conn_key.triad              = *triad;
1250    conn_key.O2TConnID          = 0;
1251    conn_key.T2OConnID          = 0;
1252 
1253    cip_conn_info_t* conn_val = (cip_conn_info_t*)wmem_map_lookup( enip_conn_hashtable, &conn_key );
1254    if ( conn_val )
1255    {
1256       conn_val->close_frame = pinfo->num;
1257 
1258       /* Save the connection info for the conversation filter */
1259       p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO, conn_val);
1260    }
1261 }
1262 
1263 /* Save the connection info for the conversation filter */
enip_mark_connection_triad(packet_info * pinfo,const cip_connection_triad_t * triad)1264 void enip_mark_connection_triad(packet_info *pinfo, const cip_connection_triad_t* triad)
1265 {
1266    enip_conn_key_t conn_key;
1267    conn_key.triad              = *triad;
1268    conn_key.O2TConnID          = 0;
1269    conn_key.T2OConnID          = 0;
1270 
1271    cip_conn_info_t* conn_val = (cip_conn_info_t*)wmem_map_lookup( enip_conn_hashtable, &conn_key );
1272    if ( conn_val )
1273    {
1274       p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO, conn_val);
1275    }
1276 }
1277 
1278 static cip_conn_info_t*
enip_get_explicit_connid(packet_info * pinfo,enip_request_key_t * prequest_key,guint32 connid)1279 enip_get_explicit_connid(packet_info *pinfo, enip_request_key_t *prequest_key, guint32 connid)
1280 {
1281    conversation_t   *conversation;
1282    enip_conv_info_t *enip_info;
1283    enum enip_packet_type requesttype = ENIP_REQUEST_PACKET;
1284 
1285    if (prequest_key != NULL)
1286    {
1287        /* Sanity check */
1288        if ((prequest_key->requesttype != ENIP_REQUEST_PACKET) && (prequest_key->requesttype != ENIP_RESPONSE_PACKET ))
1289           return NULL;
1290 
1291        requesttype = prequest_key->requesttype;
1292    }
1293 
1294    /*
1295     * Do we have a conversation for this connection?
1296     */
1297    conversation = find_conversation_pinfo(pinfo, 0);
1298    if (conversation == NULL)
1299       return NULL;
1300 
1301    /*
1302     * Do we already have a state structure for this conv
1303     */
1304    enip_info = (enip_conv_info_t *)conversation_get_proto_data(conversation, proto_enip);
1305    if (!enip_info)
1306       return NULL;
1307 
1308    cip_conn_info_t* conn_val = NULL;
1309    switch (requesttype )
1310    {
1311        case ENIP_REQUEST_PACKET:
1312            conn_val = (cip_conn_info_t*)wmem_tree_lookup32( enip_info->O2TConnIDs, connid );
1313            if ( conn_val == NULL )
1314                conn_val = (cip_conn_info_t*)wmem_tree_lookup32( enip_info->T2OConnIDs, connid );
1315            break;
1316 
1317        case ENIP_RESPONSE_PACKET:
1318            conn_val = (cip_conn_info_t*)wmem_tree_lookup32( enip_info->T2OConnIDs, connid );
1319            if ( conn_val == NULL )
1320                conn_val = (cip_conn_info_t*)wmem_tree_lookup32( enip_info->O2TConnIDs, connid );
1321            break;
1322        case ENIP_CANNOT_CLASSIFY:
1323            /* ignore */
1324            break;
1325    }
1326 
1327    if ((conn_val == NULL ) || (conn_val->open_reply_frame > pinfo->num))
1328       return NULL;
1329 
1330    return conn_val;
1331 }
1332 
1333 static cip_conn_info_t*
enip_get_io_connid(packet_info * pinfo,guint32 connid,enum enip_connid_type * pconnid_type)1334 enip_get_io_connid(packet_info *pinfo, guint32 connid, enum enip_connid_type* pconnid_type)
1335 {
1336    conversation_t   *conversation;
1337    enip_conv_info_t *enip_info;
1338    cip_conn_info_t  *conn_val = NULL;
1339 
1340    *pconnid_type = ECIDT_UNKNOWN;
1341 
1342    /*
1343     * Do we have a conversation for this connection?
1344     */
1345    conversation = find_conversation(pinfo->num,
1346             &pinfo->src, &pinfo->dst,
1347             conversation_pt_to_endpoint_type(pinfo->ptype),
1348             pinfo->destport, 0, NO_PORT_B);
1349 
1350    if (conversation == NULL)
1351       return NULL;
1352 
1353    /*
1354     * Do we already have a state structure for this conv
1355     */
1356    if ((enip_info = (enip_conv_info_t *)conversation_get_proto_data(conversation, proto_enip)) == NULL)
1357       return NULL;
1358 
1359    if (enip_info->O2TConnIDs != NULL)
1360    {
1361       conn_val = (cip_conn_info_t*)wmem_tree_lookup32(enip_info->O2TConnIDs, connid);
1362       if (conn_val)
1363       {
1364          *pconnid_type = ECIDT_O2T;
1365       }
1366    }
1367 
1368    if ( conn_val == NULL )
1369    {
1370       if (enip_info->T2OConnIDs != NULL)
1371       {
1372          if ((conn_val = (cip_conn_info_t*)wmem_tree_lookup32( enip_info->T2OConnIDs, connid)) != NULL)
1373             *pconnid_type = ECIDT_T2O;
1374       }
1375    }
1376 
1377    if ((conn_val == NULL) || ( conn_val->open_reply_frame > pinfo->num ))
1378       return NULL;
1379 
1380    return conn_val;
1381 }
1382 
1383 static int
dissect_tcpip_status(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1384 dissect_tcpip_status(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1385                      int offset, int total_len)
1386 
1387 {
1388    static int * const status[] = {
1389       &hf_tcpip_status_interface_config,
1390       &hf_tcpip_status_mcast_pending,
1391       &hf_tcpip_status_interface_config_pending,
1392       &hf_tcpip_status_acd,
1393       &hf_tcpip_acd_fault,
1394       &hf_tcpip_status_iana_port_admin_change,
1395       &hf_tcpip_status_iana_protocol_admin_change,
1396       &hf_tcpip_status_reserved,
1397       NULL
1398    };
1399 
1400    if (total_len < 4)
1401    {
1402       expert_add_info(pinfo, item, &ei_mal_tcpip_status);
1403       return total_len;
1404    }
1405 
1406    proto_tree_add_bitmask(tree, tvb, offset, hf_tcpip_status, ett_tcpip_status, status, ENC_LITTLE_ENDIAN);
1407    return 4;
1408 }
1409 
1410 static int
dissect_tcpip_config_cap(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1411 dissect_tcpip_config_cap(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1412                          int offset, int total_len)
1413 
1414 {
1415    static int * const capabilities[] = {
1416       &hf_tcpip_config_cap_bootp,
1417       &hf_tcpip_config_cap_dns,
1418       &hf_tcpip_config_cap_dhcp,
1419       &hf_tcpip_config_cap_dhcp_dns_update,
1420       &hf_tcpip_config_cap_config_settable,
1421       &hf_tcpip_config_cap_hardware_config,
1422       &hf_tcpip_config_cap_interface_reset,
1423       &hf_tcpip_config_cap_acd,
1424       &hf_tcpip_config_cap_reserved,
1425       NULL
1426    };
1427 
1428    if (total_len < 4)
1429    {
1430       expert_add_info(pinfo, item, &ei_mal_tcpip_config_cap);
1431       return total_len;
1432    }
1433 
1434    proto_tree_add_bitmask(tree, tvb, offset, hf_tcpip_config_cap, ett_tcpip_config_cap, capabilities, ENC_LITTLE_ENDIAN);
1435    return 4;
1436 }
1437 
1438 static int
dissect_tcpip_config_control(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1439 dissect_tcpip_config_control(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1440                              int offset, int total_len)
1441 
1442 {
1443    static int * const control_bits[] = {
1444       &hf_tcpip_config_control_config,
1445       &hf_tcpip_config_control_dns,
1446       &hf_tcpip_config_control_reserved,
1447       NULL
1448    };
1449 
1450    if (total_len < 4)
1451    {
1452       expert_add_info(pinfo, item, &ei_mal_tcpip_config_control);
1453       return total_len;
1454    }
1455 
1456    proto_tree_add_bitmask(tree, tvb, offset, hf_tcpip_config_control, ett_tcpip_config_control, control_bits, ENC_LITTLE_ENDIAN);
1457    return 4;
1458 }
1459 
1460 static int
dissect_tcpip_physical_link(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1461 dissect_tcpip_physical_link(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1462                             int offset, int total_len)
1463 
1464 {
1465    return dissect_padded_epath_len_uint(pinfo, tree, item, tvb, offset, total_len);
1466 }
1467 
1468 static int
dissect_tcpip_interface_config(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1469 dissect_tcpip_interface_config(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1470                                int offset, int total_len)
1471 
1472 {
1473    guint16 domain_length;
1474 
1475    if (total_len < 22)
1476    {
1477       expert_add_info(pinfo, item, &ei_mal_tcpip_interface_config);
1478       return total_len;
1479    }
1480 
1481    proto_tree_add_item(tree, hf_tcpip_ic_ip_addr,      tvb, offset,    4, ENC_LITTLE_ENDIAN);
1482    proto_tree_add_item(tree, hf_tcpip_ic_subnet_mask,  tvb, offset+4,  4, ENC_LITTLE_ENDIAN);
1483    proto_tree_add_item(tree, hf_tcpip_ic_gateway,      tvb, offset+8,  4, ENC_LITTLE_ENDIAN);
1484    proto_tree_add_item(tree, hf_tcpip_ic_name_server,  tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
1485    proto_tree_add_item(tree, hf_tcpip_ic_name_server2, tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
1486 
1487    domain_length = tvb_get_letohs( tvb, offset+20);
1488    proto_tree_add_item(tree, hf_tcpip_ic_domain_name,  tvb, offset+22, domain_length, ENC_ASCII|ENC_NA);
1489 
1490    /* Add padding. */
1491    domain_length += domain_length % 2;
1492 
1493    return (22+domain_length);
1494 }
1495 
dissect_tcpip_hostname(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len _U_)1496 static int dissect_tcpip_hostname(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1497     int offset, int total_len _U_)
1498 {
1499     int parsed_len;
1500     parsed_len = dissect_cip_string_type(pinfo, tree, item, tvb, offset, hf_tcpip_hostname, CIP_STRING_TYPE);
1501 
1502     /* Add padding. */
1503     parsed_len += parsed_len % 2;
1504 
1505     return parsed_len;
1506 }
1507 
dissect_tcpip_snn(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1508 static int dissect_tcpip_snn(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1509                              int offset, int total_len)
1510 {
1511    if (total_len < 6)
1512    {
1513       expert_add_info(pinfo, item, &ei_mal_tcpip_snn);
1514       return total_len;
1515    }
1516 
1517    dissect_cipsafety_snn(tree, tvb, pinfo, offset, hf_tcpip_snn_timestamp, hf_tcpip_snn_date, hf_tcpip_snn_time);
1518    return 6;
1519 }
1520 
1521 static int
dissect_tcpip_mcast_config(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1522 dissect_tcpip_mcast_config(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1523                            int offset, int total_len)
1524 
1525 {
1526    if (total_len < 8)
1527    {
1528       expert_add_info(pinfo, item, &ei_mal_tcpip_mcast_config);
1529       return total_len;
1530    }
1531 
1532    proto_tree_add_item(tree, hf_tcpip_mcast_alloc,      tvb, offset,   1, ENC_LITTLE_ENDIAN);
1533    proto_tree_add_item(tree, hf_tcpip_mcast_reserved,   tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
1534    proto_tree_add_item(tree, hf_tcpip_mcast_num_mcast,  tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1535    proto_tree_add_item(tree, hf_tcpip_mcast_addr_start, tvb, offset+4, 4, ENC_LITTLE_ENDIAN);
1536    return 8;
1537 }
1538 
1539 static int
dissect_tcpip_last_conflict(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1540 dissect_tcpip_last_conflict(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1541                             int offset, int total_len)
1542 
1543 {
1544    tvbuff_t *next_tvb;
1545    gboolean  save_info;
1546 
1547    if (total_len < 35)
1548    {
1549       expert_add_info(pinfo, item, &ei_mal_tcpip_last_conflict);
1550       return total_len;
1551    }
1552 
1553    proto_tree_add_item(tree, hf_tcpip_lcd_acd_activity, tvb, offset,   1, ENC_LITTLE_ENDIAN);
1554    proto_tree_add_item(tree, hf_tcpip_lcd_remote_mac,   tvb, offset+1, 6, ENC_NA);
1555 
1556    if ( tvb_get_guint8(tvb, offset) == 0 )
1557       proto_tree_add_item(tree, hf_tcpip_lcd_arp_pdu, tvb, offset+7, 28, ENC_NA);
1558    else
1559    {
1560       /* Dissect ARP PDU, but don't have it change column info */
1561       save_info = col_get_writable(pinfo->cinfo, -1);
1562       col_set_writable(pinfo->cinfo, -1, FALSE);
1563 
1564       next_tvb = tvb_new_subset_length(tvb, offset+7, 28);
1565       call_dissector(arp_handle, next_tvb, pinfo, tree);
1566 
1567       col_set_writable(pinfo->cinfo, -1, save_info);
1568    }
1569 
1570    return 35;
1571 }
1572 
1573 static int
dissect_elink_interface_flags(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1574 dissect_elink_interface_flags(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1575                               int offset, int total_len)
1576 
1577 {
1578    static int * const flags[] = {
1579       &hf_elink_iflags_link_status,
1580       &hf_elink_iflags_duplex,
1581       &hf_elink_iflags_neg_status,
1582       &hf_elink_iflags_manual_reset,
1583       &hf_elink_iflags_local_hw_fault,
1584       &hf_elink_iflags_reserved,
1585       NULL
1586    };
1587 
1588    if (total_len < 4)
1589    {
1590       expert_add_info(pinfo, item, &ei_mal_elink_interface_flags);
1591       return total_len;
1592    }
1593 
1594    proto_tree_add_bitmask(tree, tvb, offset, hf_elink_interface_flags, ett_elink_interface_flags, flags, ENC_LITTLE_ENDIAN);
1595    return 4;
1596 }
1597 
1598 static int
dissect_elink_physical_address(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1599 dissect_elink_physical_address(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1600                                int offset, int total_len)
1601 
1602 {
1603    if (total_len < 6)
1604    {
1605       expert_add_info(pinfo, item, &ei_mal_elink_physical_address);
1606       return total_len;
1607    }
1608 
1609    proto_tree_add_item(tree, hf_elink_physical_address, tvb, offset, 6, ENC_NA);
1610    return 6;
1611 }
1612 
1613 
1614 static int
dissect_elink_interface_counters(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1615 dissect_elink_interface_counters(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1616                                  int offset, int total_len)
1617 
1618 {
1619    if (total_len < 44)
1620    {
1621       expert_add_info(pinfo, item, &ei_mal_elink_interface_counters);
1622       return total_len;
1623    }
1624 
1625    proto_tree_add_item(tree, hf_elink_icount_in_octets,         tvb, offset,    4, ENC_LITTLE_ENDIAN);
1626    proto_tree_add_item(tree, hf_elink_icount_in_ucast,          tvb, offset+4,  4, ENC_LITTLE_ENDIAN);
1627    proto_tree_add_item(tree, hf_elink_icount_in_nucast,         tvb, offset+8,  4, ENC_LITTLE_ENDIAN);
1628    proto_tree_add_item(tree, hf_elink_icount_in_discards,       tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
1629    proto_tree_add_item(tree, hf_elink_icount_in_errors,         tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
1630    proto_tree_add_item(tree, hf_elink_icount_in_unknown_protos, tvb, offset+20, 4, ENC_LITTLE_ENDIAN);
1631    proto_tree_add_item(tree, hf_elink_icount_out_octets,        tvb, offset+24, 4, ENC_LITTLE_ENDIAN);
1632    proto_tree_add_item(tree, hf_elink_icount_out_ucast,         tvb, offset+28, 4, ENC_LITTLE_ENDIAN);
1633    proto_tree_add_item(tree, hf_elink_icount_out_nucast,        tvb, offset+32, 4, ENC_LITTLE_ENDIAN);
1634    proto_tree_add_item(tree, hf_elink_icount_out_discards,      tvb, offset+36, 4, ENC_LITTLE_ENDIAN);
1635    proto_tree_add_item(tree, hf_elink_icount_out_errors,        tvb, offset+40, 4, ENC_LITTLE_ENDIAN);
1636    return 44;
1637 }
1638 
1639 static int
dissect_elink_media_counters(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1640 dissect_elink_media_counters(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1641                              int offset, int total_len)
1642 
1643 {
1644    if (total_len < 48)
1645    {
1646       expert_add_info(pinfo, item, &ei_mal_elink_media_counters);
1647       return total_len;
1648    }
1649 
1650    proto_tree_add_item(tree, hf_elink_mcount_alignment_errors,      tvb, offset,    4, ENC_LITTLE_ENDIAN);
1651    proto_tree_add_item(tree, hf_elink_mcount_fcs_errors,            tvb, offset+4,  4, ENC_LITTLE_ENDIAN);
1652    proto_tree_add_item(tree, hf_elink_mcount_single_collisions,     tvb, offset+8,  4, ENC_LITTLE_ENDIAN);
1653    proto_tree_add_item(tree, hf_elink_mcount_multiple_collisions,   tvb, offset+12, 4, ENC_LITTLE_ENDIAN);
1654    proto_tree_add_item(tree, hf_elink_mcount_sqe_test_errors,       tvb, offset+16, 4, ENC_LITTLE_ENDIAN);
1655    proto_tree_add_item(tree, hf_elink_mcount_deferred_transmission, tvb, offset+20, 4, ENC_LITTLE_ENDIAN);
1656    proto_tree_add_item(tree, hf_elink_mcount_late_collisions,       tvb, offset+24, 4, ENC_LITTLE_ENDIAN);
1657    proto_tree_add_item(tree, hf_elink_mcount_excessive_collisions,  tvb, offset+28, 4, ENC_LITTLE_ENDIAN);
1658    proto_tree_add_item(tree, hf_elink_mcount_mac_transmit_errors,   tvb, offset+32, 4, ENC_LITTLE_ENDIAN);
1659    proto_tree_add_item(tree, hf_elink_mcount_carrier_sense_errors,  tvb, offset+36, 4, ENC_LITTLE_ENDIAN);
1660    proto_tree_add_item(tree, hf_elink_mcount_frame_too_long,        tvb, offset+40, 4, ENC_LITTLE_ENDIAN);
1661    proto_tree_add_item(tree, hf_elink_mcount_mac_receive_errors,    tvb, offset+44, 4, ENC_LITTLE_ENDIAN);
1662    return 48;
1663 }
1664 
1665 static int
dissect_elink_interface_capability(packet_info * pinfo _U_,proto_tree * tree,proto_item * item _U_,tvbuff_t * tvb,int offset,int total_len _U_)1666 dissect_elink_interface_capability(packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, tvbuff_t *tvb,
1667    int offset, int total_len _U_)
1668 {
1669    static int * const bits[] = {
1670       &hf_elink_icapability_capability_bits_manual,
1671       &hf_elink_icapability_capability_bits_auto_neg,
1672       &hf_elink_icapability_capability_bits_auto_mdix,
1673       &hf_elink_icapability_capability_bits_manual_speed,
1674       NULL
1675    };
1676 
1677    proto_tree_add_bitmask(tree, tvb, offset, hf_elink_icapability_capability_bits, ett_elink_icapability_bits, bits, ENC_LITTLE_ENDIAN);
1678    offset += 4;
1679 
1680    guint32 array_count;
1681    proto_tree_add_item_ret_uint(tree, hf_elink_icapability_capability_speed_duplex_array_count, tvb, offset, 1, ENC_NA, &array_count);
1682    offset++;
1683 
1684    for (guint32 i = 0; i < array_count; i++)
1685    {
1686       proto_tree_add_item(tree, hf_elink_icapability_capability_speed, tvb, offset, 2, ENC_LITTLE_ENDIAN);
1687       offset += 2;
1688 
1689       proto_tree_add_item(tree, hf_elink_icapability_capability_duplex, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1690       offset++;
1691    }
1692 
1693    return 4 + 1 + array_count * 3;
1694 }
1695 
1696 static int
dissect_elink_hc_interface_counters(packet_info * pinfo _U_,proto_tree * tree,proto_item * item _U_,tvbuff_t * tvb,int offset,int total_len _U_)1697 dissect_elink_hc_interface_counters(packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, tvbuff_t *tvb,
1698    int offset, int total_len _U_)
1699 {
1700    proto_tree_add_item(tree, hf_elink_hc_icount_in_octets, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1701    proto_tree_add_item(tree, hf_elink_hc_icount_in_ucast, tvb, offset + 8, 8, ENC_LITTLE_ENDIAN);
1702    proto_tree_add_item(tree, hf_elink_hc_icount_in_mcast, tvb, offset + 16, 8, ENC_LITTLE_ENDIAN);
1703    proto_tree_add_item(tree, hf_elink_hc_icount_in_broadcast, tvb, offset + 24, 8, ENC_LITTLE_ENDIAN);
1704    proto_tree_add_item(tree, hf_elink_hc_icount_out_octets, tvb, offset + 32, 8, ENC_LITTLE_ENDIAN);
1705    proto_tree_add_item(tree, hf_elink_hc_icount_out_ucast, tvb, offset + 40, 8, ENC_LITTLE_ENDIAN);
1706    proto_tree_add_item(tree, hf_elink_hc_icount_out_mcast, tvb, offset + 48, 8, ENC_LITTLE_ENDIAN);
1707    proto_tree_add_item(tree, hf_elink_hc_icount_out_broadcast, tvb, offset + 56, 8, ENC_LITTLE_ENDIAN);
1708 
1709    return 8 * 8;
1710 }
1711 
1712 static int
dissect_elink_hc_media_counters(packet_info * pinfo _U_,proto_tree * tree,proto_item * item _U_,tvbuff_t * tvb,int offset,int total_len _U_)1713 dissect_elink_hc_media_counters(packet_info *pinfo _U_, proto_tree *tree, proto_item *item _U_, tvbuff_t *tvb,
1714    int offset, int total_len _U_)
1715 {
1716    proto_tree_add_item(tree, hf_elink_hc_mcount_stats_align_errors, tvb, offset, 8, ENC_LITTLE_ENDIAN);
1717    proto_tree_add_item(tree, hf_elink_hc_mcount_stats_fcs_errors, tvb, offset + 8, 8, ENC_LITTLE_ENDIAN);
1718    proto_tree_add_item(tree, hf_elink_hc_mcount_stats_internal_mac_transmit_errors, tvb, offset + 16, 8, ENC_LITTLE_ENDIAN);
1719    proto_tree_add_item(tree, hf_elink_hc_mcount_stats_frame_too_long, tvb, offset + 24, 8, ENC_LITTLE_ENDIAN);
1720    proto_tree_add_item(tree, hf_elink_hc_mcount_stats_internal_mac_receive_errors, tvb, offset + 32, 8, ENC_LITTLE_ENDIAN);
1721    proto_tree_add_item(tree, hf_elink_hc_mcount_stats_symbol_errors, tvb, offset + 40, 8, ENC_LITTLE_ENDIAN);
1722 
1723    return 8 * 6;
1724 }
1725 
1726 static int
dissect_elink_interface_control(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1727 dissect_elink_interface_control(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1728                                 int offset, int total_len)
1729 
1730 {
1731    static int * const control_bits[] = {
1732       &hf_elink_icontrol_control_bits_auto_neg,
1733       &hf_elink_icontrol_control_bits_forced_duplex,
1734       &hf_elink_icontrol_control_bits_reserved,
1735       NULL
1736    };
1737 
1738    if (total_len < 4)
1739    {
1740       expert_add_info(pinfo, item, &ei_mal_elink_interface_control);
1741       return total_len;
1742    }
1743 
1744    proto_tree_add_bitmask(tree, tvb, offset, hf_elink_icontrol_control_bits, ett_elink_icontrol_bits, control_bits, ENC_LITTLE_ENDIAN);
1745    proto_tree_add_item(tree, hf_elink_icontrol_forced_speed, tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1746    return 4;
1747 }
1748 
1749 static int
dissect_dlr_ring_supervisor_config(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1750 dissect_dlr_ring_supervisor_config(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1751                                    int offset, int total_len)
1752 
1753 {
1754    if (total_len < 12)
1755    {
1756       expert_add_info(pinfo, item, &ei_mal_dlr_ring_supervisor_config);
1757       return total_len;
1758    }
1759 
1760    proto_tree_add_item(tree, hf_dlr_rsc_ring_supervisor_enable,     tvb, offset,    1, ENC_LITTLE_ENDIAN);
1761    proto_tree_add_item(tree, hf_dlr_rsc_ring_supervisor_precedence, tvb, offset+1,  1, ENC_LITTLE_ENDIAN);
1762    proto_tree_add_item(tree, hf_dlr_rsc_beacon_interval,            tvb, offset+2,  4, ENC_LITTLE_ENDIAN);
1763    proto_tree_add_item(tree, hf_dlr_rsc_beacon_timeout,             tvb, offset+6,  4, ENC_LITTLE_ENDIAN);
1764    proto_tree_add_item(tree, hf_dlr_rsc_dlr_vlan_id,                tvb, offset+10, 2, ENC_LITTLE_ENDIAN);
1765    return 12;
1766 }
1767 
1768 static int
dissect_dlr_last_active_node_on_port_1(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1769 dissect_dlr_last_active_node_on_port_1(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1770                                        int offset, int total_len)
1771 
1772 {
1773    if (total_len < 10)
1774    {
1775       expert_add_info(pinfo, item, &ei_mal_dlr_last_active_node_on_port_1);
1776       return total_len;
1777    }
1778 
1779    proto_tree_add_item(tree, hf_dlr_lanp1_dev_ip_addr,          tvb, offset,   4, ENC_LITTLE_ENDIAN);
1780    proto_tree_add_item(tree, hf_dlr_lanp1_dev_physical_address, tvb, offset+4, 6, ENC_NA);
1781    return 10;
1782 }
1783 
1784 static int
dissect_dlr_last_active_node_on_port_2(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1785 dissect_dlr_last_active_node_on_port_2(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1786                                        int offset, int total_len)
1787 
1788 {
1789    if (total_len < 10)
1790    {
1791       expert_add_info(pinfo, item, &ei_mal_dlr_last_active_node_on_port_2);
1792       return total_len;
1793    }
1794 
1795    proto_tree_add_item(tree, hf_dlr_lanp2_dev_ip_addr,          tvb, offset,   4, ENC_LITTLE_ENDIAN);
1796    proto_tree_add_item(tree, hf_dlr_lanp2_dev_physical_address, tvb, offset+4, 6, ENC_NA);
1797    return 10;
1798 }
1799 
1800 static int
dissect_dlr_ring_protocol_participants_list(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1801 dissect_dlr_ring_protocol_participants_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1802                                             int offset, int total_len)
1803 
1804 {
1805    int pos;
1806 
1807    if (total_len % 10)
1808    {
1809       expert_add_info(pinfo, item, &ei_mal_dlr_ring_protocol_participants_list);
1810       return total_len;
1811    }
1812 
1813    pos = 0;
1814    while ( pos < total_len)
1815    {
1816       proto_tree_add_item(tree, hf_dlr_rppl_dev_ip_addr,          tvb, offset+pos,   4, ENC_LITTLE_ENDIAN);
1817       proto_tree_add_item(tree, hf_dlr_rppl_dev_physical_address, tvb, offset+pos+4, 6, ENC_NA);
1818       pos+=10;
1819    }
1820    return total_len;
1821 }
1822 
1823 static int
dissect_dlr_active_supervisor_address(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1824 dissect_dlr_active_supervisor_address(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1825                                       int offset, int total_len)
1826 
1827 {
1828    if (total_len < 10)
1829    {
1830       expert_add_info(pinfo, item, &ei_mal_dlr_active_supervisor_address);
1831       return total_len;
1832    }
1833 
1834    proto_tree_add_item(tree, hf_dlr_asa_supervisor_ip_addr,          tvb, offset,   4, ENC_LITTLE_ENDIAN);
1835    proto_tree_add_item(tree, hf_dlr_asa_supervisor_physical_address, tvb, offset+4, 6, ENC_NA);
1836    return 10;
1837 }
1838 
1839 static int
dissect_dlr_capability_flags(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1840 dissect_dlr_capability_flags(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1841                              int offset, int total_len)
1842 
1843 {
1844    static int * const capabilities[] = {
1845       &hf_dlr_capflags_announce_base_node,
1846       &hf_dlr_capflags_beacon_base_node,
1847       &hf_dlr_capflags_reserved1,
1848       &hf_dlr_capflags_supervisor_capable,
1849       &hf_dlr_capflags_redundant_gateway_capable,
1850       &hf_dlr_capflags_flush_frame_capable,
1851       &hf_dlr_capflags_reserved2,
1852       NULL
1853    };
1854 
1855    if (total_len < 4)
1856    {
1857       expert_add_info(pinfo, item, &ei_mal_dlr_capability_flags);
1858       return total_len;
1859    }
1860 
1861    proto_tree_add_bitmask(tree, tvb, offset, hf_dlr_capability_flags, ett_dlr_capability_flags, capabilities, ENC_LITTLE_ENDIAN);
1862    return 4;
1863 }
1864 
1865 static int
dissect_dlr_redundant_gateway_config(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1866 dissect_dlr_redundant_gateway_config(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1867                                      int offset, int total_len)
1868 
1869 {
1870    if (total_len < 11)
1871    {
1872       expert_add_info(pinfo, item, &ei_mal_dlr_redundant_gateway_config);
1873       return total_len;
1874    }
1875 
1876    proto_tree_add_item(tree, hf_dlr_rgc_red_gateway_enable,     tvb, offset,    1, ENC_LITTLE_ENDIAN);
1877    proto_tree_add_item(tree, hf_dlr_rgc_gateway_precedence,     tvb, offset+1,  1, ENC_LITTLE_ENDIAN);
1878    proto_tree_add_item(tree, hf_dlr_rgc_advertise_interval,     tvb, offset+2,  4, ENC_LITTLE_ENDIAN);
1879    proto_tree_add_item(tree, hf_dlr_rgc_advertise_timeout,      tvb, offset+6,  4, ENC_LITTLE_ENDIAN);
1880    proto_tree_add_item(tree, hf_dlr_rgc_learning_update_enable, tvb, offset+10, 1, ENC_LITTLE_ENDIAN);
1881    return 11;
1882 }
1883 
1884 static int
dissect_dlr_active_gateway_address(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1885 dissect_dlr_active_gateway_address(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1886                                    int offset, int total_len)
1887 
1888 {
1889    if (total_len < 10)
1890    {
1891       expert_add_info(pinfo, item, &ei_mal_dlr_active_gateway_address);
1892       return total_len;
1893    }
1894 
1895    proto_tree_add_item(tree, hf_dlr_aga_ip_addr,          tvb, offset,   4, ENC_LITTLE_ENDIAN);
1896    proto_tree_add_item(tree, hf_dlr_aga_physical_address, tvb, offset+4, 6, ENC_NA);
1897    return 10;
1898 }
1899 
dissect_cip_security_profiles(packet_info * pinfo _U_,proto_tree * tree,proto_item * item _U_,tvbuff_t * tvb,int offset,int total_len _U_)1900 static int dissect_cip_security_profiles(packet_info* pinfo _U_, proto_tree* tree, proto_item* item _U_, tvbuff_t* tvb,
1901    int offset, int total_len _U_)
1902 {
1903    static int* const security_profiles[] = {
1904       &hf_enip_security_profiles_eip_integrity,
1905       &hf_enip_security_profiles_eip_confidentiality,
1906       &hf_enip_security_profiles_cip_authorization,
1907       &hf_enip_security_profiles_cip_user_authentication,
1908       &hf_enip_security_profiles_resource_constrained,
1909       &hf_enip_security_profiles_reserved,
1910       NULL
1911    };
1912 
1913    proto_tree_add_bitmask(tree, tvb, offset, hf_enip_security_profiles, ett_security_profiles, security_profiles, ENC_LITTLE_ENDIAN);
1914 
1915    return 2;
1916 }
1917 
1918 static int
dissect_eip_security_cap(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1919 dissect_eip_security_cap(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1920                                    int offset, int total_len)
1921 
1922 {
1923    static int * const capabilities[] = {
1924       &hf_eip_security_capflags_secure_renegotiation,
1925       &hf_eip_security_capflags_reserved,
1926       NULL
1927    };
1928 
1929    if (total_len < 4)
1930    {
1931       expert_add_info(pinfo, item, &ei_mal_eip_security_capability_flags);
1932       return total_len;
1933    }
1934 
1935    proto_tree_add_bitmask(tree, tvb, offset, hf_eip_security_capability_flags, ett_eip_security_capability_flags, capabilities, ENC_LITTLE_ENDIAN);
1936    return 4;
1937 }
1938 
1939 static int
dissect_eip_security_avail_cipher_suites(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1940 dissect_eip_security_avail_cipher_suites(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1941                                    int offset, int total_len)
1942 
1943 {
1944    guint32 i, num_suites;
1945 
1946    if (total_len < 1)
1947    {
1948       expert_add_info(pinfo, item, &ei_mal_eip_security_avail_cipher_suites);
1949       return total_len;
1950    }
1951 
1952    proto_tree_add_item_ret_uint(tree, hf_eip_security_num_avail_cipher_suites, tvb, offset, 1, ENC_NA, &num_suites);
1953    offset++;
1954 
1955    for (i = 0; i < num_suites; i++)
1956    {
1957       proto_tree_add_item(tree, hf_eip_security_avail_cipher_suite, tvb, offset, 2, ENC_BIG_ENDIAN);
1958       offset += 2;
1959    }
1960 
1961    return ((num_suites*2)+1);
1962 }
1963 
1964 static int
dissect_eip_security_allow_cipher_suites(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1965 dissect_eip_security_allow_cipher_suites(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1966                                    int offset, int total_len)
1967 
1968 {
1969    guint32 i, num_suites;
1970 
1971    if (total_len < 1)
1972    {
1973       expert_add_info(pinfo, item, &ei_mal_eip_security_allow_cipher_suites);
1974       return total_len;
1975    }
1976 
1977    proto_tree_add_item_ret_uint(tree, hf_eip_security_num_allow_cipher_suites, tvb, offset, 1, ENC_NA, &num_suites);
1978    offset++;
1979 
1980    for (i = 0; i < num_suites; i++)
1981    {
1982       proto_tree_add_item(tree, hf_eip_security_allow_cipher_suite, tvb, offset, 2, ENC_BIG_ENDIAN);
1983       offset += 2;
1984    }
1985 
1986    return ((num_suites*2)+1);
1987 }
1988 
1989 static int
dissect_eip_security_preshared_keys(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)1990 dissect_eip_security_preshared_keys(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
1991                                    int offset, int total_len)
1992 
1993 {
1994    guint32 i, num, id_size, psk_size;
1995    proto_item* ti;
1996    proto_tree* psk_tree;
1997    int start_offset = offset;
1998 
1999    if (total_len < 1)
2000    {
2001       expert_add_info(pinfo, item, &ei_mal_eip_security_preshared_keys);
2002       return total_len;
2003    }
2004 
2005    ti = proto_tree_add_item_ret_uint(tree, hf_eip_security_num_psk, tvb, offset, 1, ENC_NA, &num);
2006    psk_tree = proto_item_add_subtree(ti, ett_eip_security_psk);
2007    offset++;
2008 
2009    for (i = 0; i < num; i++)
2010    {
2011       proto_tree_add_item_ret_uint(psk_tree, hf_eip_security_psk_identity_size, tvb, offset, 1, ENC_NA, &id_size);
2012       if (total_len < (int)(id_size+2))
2013       {
2014          expert_add_info(pinfo, item, &ei_mal_eip_security_preshared_keys);
2015          return total_len;
2016       }
2017       offset++;
2018       proto_tree_add_item(psk_tree, hf_eip_security_psk_identity, tvb, offset, id_size, ENC_NA);
2019       offset += id_size;
2020 
2021       proto_tree_add_item_ret_uint(psk_tree, hf_eip_security_psk_size, tvb, offset, 1, ENC_NA, &psk_size);
2022       offset++;
2023       if (total_len < (int)(id_size+psk_size+2))
2024       {
2025          expert_add_info(pinfo, item, &ei_mal_eip_security_preshared_keys);
2026          return total_len;
2027       }
2028       proto_tree_add_item(psk_tree, hf_eip_security_psk, tvb, offset, psk_size, ENC_NA);
2029       offset += psk_size;
2030    }
2031    proto_item_set_len(ti, offset-start_offset);
2032    return offset-start_offset;
2033 }
2034 
2035 static int
dissect_eip_security_active_certs(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)2036 dissect_eip_security_active_certs(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2037                                    int offset, int total_len)
2038 
2039 {
2040    guint32 i, num, path_size;
2041    proto_item *ti;
2042    proto_tree* cert_tree;
2043    int start_offset = offset;
2044 
2045    if (total_len < 1)
2046    {
2047       expert_add_info(pinfo, item, &ei_mal_eip_security_active_certs);
2048       return total_len;
2049    }
2050 
2051    ti = proto_tree_add_item_ret_uint(tree, hf_eip_security_num_active_certs, tvb, offset, 1, ENC_NA, &num);
2052    cert_tree = proto_item_add_subtree(ti, ett_eip_security_active_certs);
2053    offset++;
2054 
2055    for (i = 0; i < num; i++)
2056    {
2057       path_size = dissect_padded_epath_len_usint(pinfo, cert_tree, ti, tvb, offset, total_len);
2058       offset += path_size;
2059    }
2060    proto_item_set_len(ti, offset-start_offset);
2061    return offset-start_offset;
2062 }
2063 
2064 static int
dissect_eip_security_trusted_auths(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)2065 dissect_eip_security_trusted_auths(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2066                                    int offset, int total_len)
2067 
2068 {
2069    guint32 i, num, path_size;
2070    proto_item *ti;
2071    proto_tree* cert_tree;
2072    int start_offset = offset;
2073 
2074    if (total_len < 1)
2075    {
2076       expert_add_info(pinfo, item, &ei_mal_eip_security_trusted_auths);
2077       return total_len;
2078    }
2079 
2080    ti = proto_tree_add_item_ret_uint(tree, hf_eip_security_num_trusted_auths, tvb, offset, 1, ENC_NA, &num);
2081    cert_tree = proto_item_add_subtree(ti, ett_eip_security_trusted_auths);
2082    offset++;
2083 
2084    for (i = 0; i < num; i++)
2085    {
2086       path_size = dissect_padded_epath_len_usint(pinfo, cert_tree, ti, tvb, offset, total_len);
2087       offset += path_size;
2088    }
2089    proto_item_set_len(ti, offset-start_offset);
2090    return offset-start_offset;
2091 }
2092 
2093 static int
dissect_eip_security_cert_revocation_list(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)2094 dissect_eip_security_cert_revocation_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2095                                    int offset, int total_len)
2096 {
2097    return dissect_padded_epath_len_usint(pinfo, tree, item, tvb, offset, total_len);
2098 }
2099 
2100 static int
dissect_eip_cert_cap_flags(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)2101 dissect_eip_cert_cap_flags(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2102                                    int offset, int total_len)
2103 {
2104    static int * const capabilities[] = {
2105       &hf_eip_cert_capflags_push,
2106       &hf_eip_cert_capflags_reserved,
2107       NULL
2108    };
2109 
2110    if (total_len < 4)
2111    {
2112       expert_add_info(pinfo, item, &ei_mal_eip_cert_capability_flags);
2113       return total_len;
2114    }
2115 
2116    proto_tree_add_bitmask(tree, tvb, offset, hf_eip_cert_capability_flags, ett_eip_cert_capability_flags, capabilities, ENC_LITTLE_ENDIAN);
2117    return 4;
2118 }
2119 
2120 static int
dissect_eip_cert_cert_list(packet_info * pinfo,proto_tree * tree,proto_item * item _U_,tvbuff_t * tvb,int offset,int total_len)2121 dissect_eip_cert_cert_list(packet_info *pinfo, proto_tree *tree, proto_item *item _U_, tvbuff_t *tvb,
2122                                    int offset, int total_len)
2123 {
2124    guint32 i, num, path_size;
2125    proto_item *ti;
2126    proto_tree* cert_tree;
2127    int start_offset = offset;
2128 
2129    ti = proto_tree_add_item_ret_uint(tree, hf_eip_cert_num_certs, tvb, offset, 1, ENC_NA, &num);
2130    cert_tree = proto_item_add_subtree(ti, ett_eip_cert_num_certs);
2131    offset++;
2132 
2133    for (i = 0; i < num; i++)
2134    {
2135       path_size = tvb_get_guint8( tvb, offset );
2136       proto_tree_add_item(tree, hf_eip_cert_cert_name, tvb, offset+1, path_size, ENC_ASCII|ENC_NA);
2137       offset += (1+path_size);
2138 
2139       path_size = dissect_padded_epath_len_usint(pinfo, cert_tree, ti, tvb, offset, total_len);
2140       offset += path_size;
2141    }
2142    proto_item_set_len(ti, offset-start_offset);
2143    return offset-start_offset;
2144 }
2145 
2146 static int
dissect_eip_cert_device_cert(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)2147 dissect_eip_cert_device_cert(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2148                                    int offset, int total_len)
2149 {
2150    guint32 path_size;
2151 
2152    proto_tree_add_item(tree, hf_eip_cert_device_cert_status, tvb, offset, 1, ENC_NA);
2153    offset++;
2154 
2155    path_size = dissect_padded_epath_len_usint(pinfo, tree, item, tvb, offset, total_len);
2156 
2157    return path_size + 1;
2158 }
2159 
2160 static int
dissect_eip_cert_ca_cert(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len)2161 dissect_eip_cert_ca_cert(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2162                                    int offset, int total_len)
2163 {
2164    guint32 path_size;
2165 
2166    proto_tree_add_item(tree, hf_eip_cert_ca_cert_status, tvb, offset, 1, ENC_NA);
2167    offset++;
2168 
2169    path_size = dissect_padded_epath_len_usint(pinfo, tree, item, tvb, offset, total_len);
2170 
2171    return path_size + 1;
2172 }
2173 
dissect_tcpip_port_information(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset)2174 static int dissect_tcpip_port_information(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2175    int offset)
2176 {
2177    int start_offset = offset;
2178 
2179    guint32 port_count;
2180    proto_tree_add_item_ret_uint(tree, hf_tcpip_port_count, tvb, offset, 1, ENC_LITTLE_ENDIAN, &port_count);
2181    offset++;
2182 
2183    for (guint32 i = 0; i < port_count; ++i)
2184    {
2185       proto_item *port_item;
2186       proto_tree *port_tree = proto_tree_add_subtree(tree, tvb, offset, 0, ett_cmd_data, &port_item, "Port: ");
2187 
2188       offset += dissect_cip_string_type(pinfo, port_tree, item, tvb, offset, hf_tcpip_port_name, CIP_SHORT_STRING_TYPE);
2189 
2190       guint32 port_number;
2191       proto_tree_add_item_ret_uint(port_tree, hf_tcpip_port_number, tvb, offset, 2, ENC_LITTLE_ENDIAN, &port_number);
2192       offset += 2;
2193       proto_item_append_text(port_item, "Number: %d", port_number);
2194 
2195       proto_tree_add_item(port_tree, hf_tcpip_port_protocol, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2196       offset++;
2197 
2198       proto_tree_add_item(port_tree, hf_tcpip_port_admin_state, tvb, offset, 1, ENC_LITTLE_ENDIAN);
2199       offset++;
2200 
2201       static int* const capability[] = {
2202          &hf_tcpip_admin_capability_configurable,
2203          &hf_tcpip_admin_capability_reset_required,
2204          &hf_tcpip_admin_capability_reserved,
2205          NULL
2206       };
2207 
2208       proto_tree_add_bitmask(port_tree, tvb, offset, hf_tcpip_port_admin_capability, ett_tcpip_admin_capability, capability, ENC_LITTLE_ENDIAN);
2209       offset++;
2210    }
2211 
2212    return offset - start_offset;
2213 }
2214 
dissect_tcpip_port_admin(packet_info * pinfo,proto_tree * tree,proto_item * item,tvbuff_t * tvb,int offset,int total_len _U_)2215 static int dissect_tcpip_port_admin(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb,
2216    int offset, int total_len _U_)
2217 {
2218    return dissect_tcpip_port_information(pinfo, tree, item, tvb, offset);
2219 }
2220 
2221 attribute_info_t enip_attribute_vals[] = {
2222 
2223     /* TCP/IP Object (class attributes) */
2224    {0xF5, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
2225    {0xF5, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
2226    {0xF5, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
2227    {0xF5, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
2228    {0xF5, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
2229    {0xF5, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
2230    {0xF5, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
2231 
2232    /* TCP/IP object (instance attributes) */
2233    {0xF5, FALSE,  1, 0, "Status",                    cip_dissector_func,   NULL, dissect_tcpip_status},
2234    {0xF5, FALSE,  2, 1, "Configuration Capability",  cip_dissector_func,   NULL, dissect_tcpip_config_cap},
2235    {0xF5, FALSE,  3, 2, "Configuration Control",     cip_dissector_func,   NULL, dissect_tcpip_config_control},
2236    {0xF5, FALSE,  4, 3, "Physical Link Object",      cip_dissector_func,   NULL, dissect_tcpip_physical_link},
2237    {0xF5, FALSE,  5, 4, "Interface Configuration",   cip_dissector_func,   NULL, dissect_tcpip_interface_config},
2238    {0xF5, FALSE,  6, 5, "Host Name",                 cip_dissector_func,   NULL, dissect_tcpip_hostname},
2239    {0xF5, FALSE,  7, 6, "Safety Network Number", cip_dissector_func,   NULL, dissect_tcpip_snn},
2240    {0xF5, FALSE,  8, 7, "TTL Value", cip_usint,      &hf_tcpip_ttl_value,  NULL},
2241    {0xF5, FALSE,  9, 8, "Multicast Configuration",   cip_dissector_func,   NULL, dissect_tcpip_mcast_config},
2242    {0xF5, FALSE, 10, 9, "Select ACD", cip_bool,      &hf_tcpip_select_acd, NULL},
2243    {0xF5, FALSE, 11, 10, "Last Conflict Detected",    cip_dissector_func,   NULL, dissect_tcpip_last_conflict},
2244    {0xF5, FALSE, 12, 11, "EtherNet/IP Quick Connect", cip_bool,             &hf_tcpip_quick_connect, NULL},
2245    {0xF5, FALSE, 13, 12, "Encapsulation Inactivity Timeout", cip_uint,      &hf_tcpip_encap_inactivity, NULL},
2246    {0xF5, FALSE, 14, -1, "IANA Port Admin",           cip_dissector_func,   NULL, dissect_tcpip_port_admin },
2247 
2248     /* Ethernet Link Object (class attributes) */
2249    {0xF6, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
2250    {0xF6, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
2251    {0xF6, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
2252    {0xF6, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
2253    {0xF6, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
2254    {0xF6, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
2255    {0xF6, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
2256 
2257    /* Ethernet Link object (instance attributes) */
2258    {0xF6, FALSE,  1, 0, "Interface Speed",           cip_dword,            &hf_elink_interface_speed,  NULL},
2259    {0xF6, FALSE,  2, 1, "Interface Flags",           cip_dissector_func,   NULL, dissect_elink_interface_flags},
2260    {0xF6, FALSE,  3, 2, "Physical Address",          cip_dissector_func,   NULL, dissect_elink_physical_address },
2261    {0xF6, FALSE,  4, 3, "Interface Counters",        cip_dissector_func,   NULL, dissect_elink_interface_counters},
2262    {0xF6, FALSE,  5, 4, "Media Counters",            cip_dissector_func,   NULL, dissect_elink_media_counters},
2263    {0xF6, FALSE,  6, 5, "Interface Control",         cip_dissector_func,   NULL, dissect_elink_interface_control},
2264    {0xF6, FALSE,  7, 6, "Interface Type",            cip_usint,            &hf_elink_interface_type,  NULL},
2265    {0xF6, FALSE,  8, 7, "Interface State",           cip_usint,            &hf_elink_interface_state, NULL},
2266    {0xF6, FALSE,  9, 8, "Admin State",               cip_usint,            &hf_elink_admin_state,     NULL},
2267    {0xF6, FALSE, 10, 9, "Interface Label",           cip_short_string,     &hf_elink_interface_label, NULL},
2268    {0xF6, FALSE, 11, 10, "Interface Capability",     cip_dissector_func,   NULL, dissect_elink_interface_capability},
2269    {0xF6, FALSE, 12, 11, "HC Interface Counters",    cip_dissector_func,   NULL, dissect_elink_hc_interface_counters},
2270    {0xF6, FALSE, 13, 12, "HC Media Counters",        cip_dissector_func,   NULL, dissect_elink_hc_media_counters},
2271 
2272     /* QoS Object (class attributes) */
2273    {0x48, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
2274    {0x48, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
2275    {0x48, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
2276    {0x48, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
2277    {0x48, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
2278    {0x48, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
2279    {0x48, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
2280 
2281    /* QoS object (instance attributes) */
2282    {0x48, FALSE,  1, -1, "802.1Q Tag Enable",         cip_bool,             &hf_qos_8021q_enable,     NULL},
2283    {0x48, FALSE,  2, -1, "DSCP PTP Event",            cip_usint,            &hf_qos_dscp_ptp_event,   NULL},
2284    {0x48, FALSE,  3, -1, "DSCP PTP General",          cip_usint,            &hf_qos_dscp_ptp_general, NULL},
2285    {0x48, FALSE,  4, -1, "DSCP Urgent",               cip_usint,            &hf_qos_dscp_urgent,      NULL},
2286    {0x48, FALSE,  5, -1, "DSCP Scheduled",            cip_usint,            &hf_qos_dscp_scheduled,   NULL},
2287    {0x48, FALSE,  6, -1, "DSCP High",                 cip_usint,            &hf_qos_dscp_high,        NULL},
2288    {0x48, FALSE,  7, -1, "DSCP Low",                  cip_usint,            &hf_qos_dscp_low,         NULL},
2289    {0x48, FALSE,  8, -1, "DSCP Explicit",             cip_usint,            &hf_qos_dscp_explicit,    NULL},
2290 
2291     /* DLR Object (class attributes) */
2292    {0x47, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
2293    {0x47, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
2294    {0x47, TRUE, 3, 2, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
2295    {0x47, TRUE, 4, 3, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
2296    {0x47, TRUE, 5, 4, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
2297    {0x47, TRUE, 6, 5, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
2298    {0x47, TRUE, 7, 6, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
2299 
2300    /* DLR object (instance attributes) */
2301    /* Get Attributes All is not fully parsed here because there are multiple formats. */
2302    {0x47, FALSE, 1, 0, "Network Topology",                 cip_usint, &hf_dlr_network_topology, NULL},
2303    {0x47, FALSE, 2, 1, "Network Status",                   cip_usint, &hf_dlr_network_status, NULL},
2304    {0x47, FALSE, 3, -1, "Ring Supervisor Status",           cip_usint, &hf_dlr_ring_supervisor_status, NULL},
2305    {0x47, FALSE, 4, -1, "Ring Supervisor Config",           cip_dissector_func, NULL, dissect_dlr_ring_supervisor_config},
2306    {0x47, FALSE, 5, -1, "Ring Faults Count",                cip_uint,      &hf_dlr_ring_faults_count, NULL},
2307    {0x47, FALSE, 6, -1, "Last Active Node on Port 1",       cip_dissector_func, NULL, dissect_dlr_last_active_node_on_port_1},
2308    {0x47, FALSE, 7, -1, "Last Active Node on Port 2",       cip_dissector_func, NULL, dissect_dlr_last_active_node_on_port_2},
2309    {0x47, FALSE, 8, -1, "Ring Protocol Participants Count", cip_uint, &hf_dlr_ring_protocol_participants_count, NULL},
2310    {0x47, FALSE, 9, -1, "Ring Protocol Participants List",  cip_dissector_func, NULL, dissect_dlr_ring_protocol_participants_list},
2311    {0x47, FALSE, 10, -1, "Active Supervisor Address",       cip_dissector_func, NULL, dissect_dlr_active_supervisor_address},
2312    {0x47, FALSE, 11, -1, "Active Supervisor Precedence",    cip_usint, &hf_dlr_active_supervisor_precedence, NULL},
2313    {0x47, FALSE, 12, -1, "Capability Flags",                cip_dissector_func, NULL, dissect_dlr_capability_flags},
2314    {0x47, FALSE, 13, -1, "Redundant Gateway Config",        cip_dissector_func, NULL, dissect_dlr_redundant_gateway_config},
2315    {0x47, FALSE, 14, -1, "Redundant Gateway Status",        cip_usint, &hf_dlr_redundant_gateway_status, NULL},
2316    {0x47, FALSE, 15, -1, "Active Gateway Address",          cip_dissector_func, NULL, dissect_dlr_active_gateway_address},
2317    {0x47, FALSE, 16, -1, "Active Gateway Precedence",       cip_usint, &hf_dlr_active_gateway_precedence, NULL},
2318 
2319    /* CIP Security Object (instance attributes) */
2320    {0x5D, CIP_ATTR_INSTANCE, 1, 0, "State", cip_usint, &hf_cip_security_state, NULL},
2321    {0x5D, CIP_ATTR_INSTANCE, 2, 1, "Security Profiles", cip_dissector_func, NULL, dissect_cip_security_profiles },
2322 
2323    /* EtherNet/IP Security object (instance attributes) */
2324    {0x5E, FALSE, 1, 0, "State", cip_usint, &hf_eip_security_state, NULL},
2325    {0x5E, FALSE, 2, 1, "Capability Flags",  cip_dissector_func,   NULL, dissect_eip_security_cap},
2326    {0x5E, FALSE, 3, 2, "Available Cipher Suites",  cip_dissector_func,   NULL, dissect_eip_security_avail_cipher_suites},
2327    {0x5E, FALSE, 4, 3, "Allowed Cipher Suites",  cip_dissector_func,   NULL, dissect_eip_security_allow_cipher_suites},
2328    {0x5E, FALSE, 5, 4, "Pre-Shared Keys",  cip_dissector_func,   NULL, dissect_eip_security_preshared_keys},
2329    {0x5E, FALSE, 6, 5, "Active Device Certificates",  cip_dissector_func,   NULL, dissect_eip_security_active_certs},
2330    {0x5E, FALSE, 7, 6, "Trusted Authorities",  cip_dissector_func,   NULL, dissect_eip_security_trusted_auths},
2331    {0x5E, FALSE, 8, 7, "Certificate Revocation List",  cip_dissector_func,   NULL, dissect_eip_security_cert_revocation_list},
2332    {0x5E, FALSE, 9, 8, "Verify Client Certificate", cip_bool, &hf_eip_security_verify_client_cert, NULL},
2333    {0x5E, FALSE, 10, 9, "Send Certificate Chain", cip_bool, &hf_eip_security_send_cert_chain, NULL},
2334    {0x5E, FALSE, 11, 10, "Check Expiration", cip_bool, &hf_eip_security_check_expiration, NULL},
2335 
2336     /* Certificate Management Object (class attributes) */
2337    {0x5F, TRUE, 1, 0, CLASS_ATTRIBUTE_1_NAME, cip_uint, &hf_attr_class_revision, NULL },
2338    {0x5F, TRUE, 2, 1, CLASS_ATTRIBUTE_2_NAME, cip_uint, &hf_attr_class_max_instance, NULL },
2339    {0x5F, TRUE, 3, -1, CLASS_ATTRIBUTE_3_NAME, cip_uint, &hf_attr_class_num_instance, NULL },
2340    {0x5F, TRUE, 4, -1, CLASS_ATTRIBUTE_4_NAME, cip_dissector_func, NULL, dissect_optional_attr_list },
2341    {0x5F, TRUE, 5, -1, CLASS_ATTRIBUTE_5_NAME, cip_dissector_func, NULL, dissect_optional_service_list },
2342    {0x5F, TRUE, 6, 2, CLASS_ATTRIBUTE_6_NAME, cip_uint, &hf_attr_class_num_class_attr, NULL },
2343    {0x5F, TRUE, 7, 3, CLASS_ATTRIBUTE_7_NAME, cip_uint, &hf_attr_class_num_inst_attr, NULL },
2344    {0x5F, TRUE, 8, 4, "Capability Flags", cip_dissector_func,   NULL, dissect_eip_cert_cap_flags },
2345    {0x5F, TRUE, 9, 5, "Certificate List", cip_dissector_func,   NULL, dissect_eip_cert_cert_list },
2346 
2347    /* Certificate Management Object (instance attributes) */
2348    {0x5F, FALSE, 1, 0, "Name", cip_short_string, &hf_eip_cert_name, NULL},
2349    {0x5F, FALSE, 2, 1, "State", cip_usint, &hf_eip_cert_state, NULL},
2350    {0x5F, FALSE, 3, 2, "Device Certificate",  cip_dissector_func,   NULL, dissect_eip_cert_device_cert},
2351    {0x5F, FALSE, 4, 3, "CA Certificate",  cip_dissector_func,   NULL, dissect_eip_cert_ca_cert},
2352    {0x5F, FALSE, 5, 4, "Certificate Encoding", cip_usint, &hf_eip_cert_encoding, NULL },
2353 };
2354 
enip_init_protocol(void)2355 static void enip_init_protocol(void)
2356 {
2357    enip_unique_connid = 0;
2358 }
2359 
2360 // offset - Starts at the "Encapsulation Protocol Version" field.
dissect_item_list_identity(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * item_tree)2361 static void dissect_item_list_identity(packet_info* pinfo, tvbuff_t* tvb, int offset, proto_tree* item_tree)
2362 {
2363    /* Encapsulation version */
2364    proto_tree_add_item(item_tree, hf_enip_encapver, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2365 
2366    /* Socket Address */
2367    proto_tree* sockaddr_tree = proto_tree_add_subtree(item_tree, tvb, offset + 2, 16, ett_sockadd, NULL, "Socket Address");
2368 
2369    /* Socket address struct - sin_family */
2370    proto_tree_add_item(sockaddr_tree, hf_enip_sinfamily, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2371 
2372    /* Socket address struct - sin_port */
2373    proto_tree_add_item(sockaddr_tree, hf_enip_sinport, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
2374 
2375    /* Socket address struct - sin_address */
2376    proto_tree_add_item(sockaddr_tree, hf_enip_sinaddr, tvb, offset + 6, 4, ENC_BIG_ENDIAN);
2377 
2378    /* Socket address struct - sin_zero */
2379    proto_tree_add_item(sockaddr_tree, hf_enip_sinzero, tvb, offset + 10, 8, ENC_NA);
2380 
2381    /* Vendor ID */
2382    proto_tree_add_item(item_tree, hf_enip_lir_vendor, tvb, offset + 18, 2, ENC_LITTLE_ENDIAN);
2383 
2384    /* Device Type */
2385    proto_tree_add_item(item_tree, hf_enip_lir_devtype, tvb, offset + 20, 2, ENC_LITTLE_ENDIAN);
2386 
2387    /* Product Code */
2388    proto_tree_add_item(item_tree, hf_enip_lir_prodcode, tvb, offset + 22, 2, ENC_LITTLE_ENDIAN);
2389 
2390    /* Revision */
2391    proto_tree_add_item(item_tree, hf_enip_lir_revision, tvb, offset + 24, 2, ENC_BIG_ENDIAN);
2392 
2393    /* Status */
2394    proto_tree_add_item(item_tree, hf_enip_lir_status, tvb, offset + 26, 2, ENC_LITTLE_ENDIAN);
2395 
2396    /* Serial Number */
2397    proto_tree_add_item(item_tree, hf_enip_lir_serial, tvb, offset + 28, 4, ENC_LITTLE_ENDIAN);
2398 
2399    /* Product Name Length */
2400    guint32 name_length;
2401    proto_tree_add_item_ret_uint(item_tree, hf_enip_lir_namelen, tvb, offset + 32, 1, ENC_LITTLE_ENDIAN, &name_length);
2402 
2403    /* Product Name */
2404    proto_tree_add_item(item_tree, hf_enip_lir_name, tvb, offset + 33, name_length, ENC_ASCII | ENC_NA);
2405 
2406    /* Append product name to info column */
2407    col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", tvb_format_text(pinfo->pool, tvb, offset + 33, name_length));
2408 
2409    /* State */
2410    proto_tree_add_item(item_tree, hf_enip_lir_state, tvb, offset + name_length + 33, 1, ENC_LITTLE_ENDIAN);
2411 }
2412 
2413 // offset - Starts at the "Security Profiles" field.
dissect_item_cip_security_information(tvbuff_t * tvb,int offset,proto_tree * item_tree)2414 static void dissect_item_cip_security_information(tvbuff_t* tvb, int offset, proto_tree* item_tree)
2415 {
2416    static int * const iana_flags[] = {
2417       &hf_enip_iana_port_state_flags_tcp_44818,
2418       &hf_enip_iana_port_state_flags_udp_44818,
2419       &hf_enip_iana_port_state_flags_udp_2222,
2420       &hf_enip_iana_port_state_flags_tcp_2221,
2421       &hf_enip_iana_port_state_flags_udp_2221,
2422       &hf_enip_iana_port_state_flags_reserved,
2423       NULL
2424    };
2425 
2426    dissect_cip_security_profiles(NULL, item_tree, NULL, tvb, offset, tvb_reported_length_remaining(tvb, offset));
2427 
2428    /* CIP Security object state */
2429    proto_tree_add_item(item_tree, hf_enip_cip_security_state, tvb, offset + 2, 1, ENC_LITTLE_ENDIAN);
2430 
2431    /* ENIP Security object state  */
2432    proto_tree_add_item(item_tree, hf_enip_eip_security_state, tvb, offset + 3, 1, ENC_LITTLE_ENDIAN);
2433 
2434    /* IANA Port State flags */
2435    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);
2436 }
2437 
2438 // offset - Starts at the "Encapsulation Protocol Version" field.
dissect_item_list_services_response(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * item_tree)2439 static void dissect_item_list_services_response(packet_info* pinfo, tvbuff_t* tvb, int offset, proto_tree* item_tree)
2440 {
2441    /* Encapsulation version */
2442    proto_tree_add_item(item_tree, hf_enip_encapver, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2443 
2444    /* Capability flags */
2445    static int* const capability_bits[] = {
2446       &hf_enip_lsr_tcp,
2447       &hf_enip_lsr_udp,
2448       NULL
2449    };
2450    proto_tree_add_bitmask(item_tree, tvb, offset + 2, hf_enip_lsr_capaflags, ett_lsrcf, capability_bits, ENC_LITTLE_ENDIAN);
2451 
2452    /* Name of service */
2453    proto_tree_add_item(item_tree, hf_enip_lsr_servicename, tvb, offset + 4, 16, ENC_ASCII | ENC_NA);
2454 
2455    /* Append service name to info column */
2456    col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
2457       tvb_format_stringzpad(pinfo->pool, tvb, offset + 4, 16));
2458 }
2459 
display_fwd_open_connection_path(cip_conn_info_t * conn_info,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo)2460 static void display_fwd_open_connection_path(cip_conn_info_t* conn_info, proto_tree* tree, tvbuff_t* tvb, packet_info* pinfo)
2461 {
2462    if (!conn_info->pFwdOpenPathData)
2463    {
2464       return;
2465    }
2466 
2467    tvbuff_t* tvbIOI = tvb_new_real_data((const guint8*)conn_info->pFwdOpenPathData, conn_info->FwdOpenPathLenBytes, conn_info->FwdOpenPathLenBytes);
2468    if (tvbIOI)
2469    {
2470       proto_item* pi = NULL;
2471       proto_tree* epath_tree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_connection_path_info, &pi, "Forward Open Connection Path: ");
2472       proto_item_set_generated(pi);
2473 
2474       dissect_epath(tvbIOI, pinfo, epath_tree, pi, 0, conn_info->FwdOpenPathLenBytes, TRUE, FALSE, NULL, NULL, NO_DISPLAY, NULL, FALSE);
2475       tvb_free(tvbIOI);
2476    }
2477 }
2478 
display_connection_information(packet_info * pinfo,tvbuff_t * tvb,proto_tree * tree,cip_conn_info_t * conn_info,enum enip_connid_type connid_type)2479 static void display_connection_information(packet_info* pinfo, tvbuff_t* tvb, proto_tree* tree, cip_conn_info_t* conn_info, enum enip_connid_type connid_type)
2480 {
2481    proto_item* conn_info_item = NULL;
2482    proto_tree* conn_info_tree = proto_tree_add_subtree(tree, tvb, 0, 0, ett_connection_info, &conn_info_item, "Connection Information");
2483    proto_item_set_generated(conn_info_item);
2484 
2485    if (connid_type == ECIDT_O2T)
2486    {
2487        proto_item_append_text(conn_info_item, ": O->T");
2488    }
2489    else if (connid_type == ECIDT_T2O)
2490    {
2491        proto_item_append_text(conn_info_item, ": T->O");
2492    }
2493 
2494    display_fwd_open_connection_path(conn_info, conn_info_tree, tvb, pinfo);
2495 
2496    proto_item* pi = proto_tree_add_uint(conn_info_tree, hf_cip_cm_ot_api, tvb, 0, 0, conn_info->O2T.api);
2497    proto_item_set_generated(pi);
2498 
2499    pi = proto_tree_add_uint(conn_info_tree, hf_cip_cm_to_api, tvb, 0, 0, conn_info->T2O.api);
2500    proto_item_set_generated(pi);
2501 
2502    pi = proto_tree_add_uint(conn_info_tree, hf_cip_connection, tvb, 0, 0, conn_info->connid);
2503    proto_item_set_generated(pi);
2504 
2505    pi = proto_tree_add_uint(conn_info_tree, hf_enip_fwd_open_in, tvb, 0, 0, conn_info->open_req_frame);
2506    proto_item_set_generated(pi);
2507 }
2508 
2509 // This dissects Class 0 or Class 1 I/O.
2510 // offset - Starts at the field after the Item Length field.
dissect_cip_io_generic(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data)2511 static int dissect_cip_io_generic(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data)
2512 {
2513    cip_io_data_input* io_data_input = (cip_io_data_input*)data;
2514 
2515    int offset = 0;
2516 
2517    proto_item* ti = proto_tree_add_item(tree, proto_cipio, tvb, 0, -1, ENC_NA);
2518    proto_tree* io_tree = proto_item_add_subtree(ti, ett_cip_io_generic);
2519 
2520    if (io_data_input != NULL)
2521    {
2522       if ((io_data_input->conn_info->TransportClass_trigger & CI_TRANSPORT_CLASS_MASK) == 1)
2523       {
2524          proto_tree_add_item(io_tree, hf_cip_sequence_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2525          offset += 2;
2526       }
2527 
2528       if ((tvb_reported_length_remaining(tvb, offset) >= 4) &&
2529          (((io_data_input->connid_type == ECIDT_O2T) && enip_OTrun_idle) ||
2530          ((io_data_input->connid_type == ECIDT_T2O) && enip_TOrun_idle)))
2531       {
2532          dissect_cip_run_idle(tvb, offset, io_tree);
2533          offset += 4;
2534       }
2535    }
2536 
2537    proto_tree_add_item(io_tree, hf_cip_io_data, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA);
2538 
2539    return tvb_captured_length(tvb);
2540 }
2541 
2542 // Dissect the various kinds of CIP Class 0/1 I/O formats. This will determine the appropriate format and
2543 // call the appropriate related dissector.
2544 // offset - Starts at the field after the Item Length field.
dissect_cip_class01_io(packet_info * pinfo,tvbuff_t * tvb,int offset,int item_length,cip_conn_info_t * conn_info,enum enip_connid_type connid_type,proto_tree * dissector_tree)2545 static void dissect_cip_class01_io(packet_info* pinfo, tvbuff_t* tvb, int offset,
2546    int item_length, cip_conn_info_t* conn_info, enum enip_connid_type connid_type,
2547    proto_tree* dissector_tree)
2548 {
2549    if (tvb_reported_length_remaining(tvb, offset) <= 0)
2550    {
2551       return;
2552    }
2553 
2554    /* Display data */
2555    tvbuff_t* next_tvb = tvb_new_subset_length(tvb, offset, item_length);
2556    if (conn_info != NULL)
2557    {
2558       cip_io_data_input io_data_input;
2559       io_data_input.conn_info = conn_info;
2560       io_data_input.connid_type = connid_type;
2561 
2562       if (conn_info->safety.safety_seg == TRUE)
2563       {
2564          /* Add any possible safety related data */
2565          cip_safety_info_t      cip_safety;
2566          cip_safety.conn_type = connid_type;
2567          cip_safety.eip_conn_info = conn_info;
2568          cip_safety.compute_crc = TRUE;
2569 
2570          call_dissector_with_data(cipsafety_handle, next_tvb, pinfo, dissector_tree, &cip_safety);
2571       }
2572       else
2573       {
2574          dissector_handle_t dissector = dissector_get_uint_handle(subdissector_io_table, conn_info->ClassID);
2575          if (dissector)
2576          {
2577             call_dissector_with_data(dissector, next_tvb, pinfo, dissector_tree, &io_data_input);
2578          }
2579          else
2580          {
2581             call_dissector_with_data(cip_io_generic_handle, next_tvb, pinfo, dissector_tree, &io_data_input);
2582          }
2583       }
2584    }
2585    else
2586    {
2587       // This handles the Decode As options
2588       if (!dissector_try_payload(subdissector_decode_as_io_table, next_tvb, pinfo, dissector_tree))
2589       {
2590          call_dissector_with_data(cip_io_generic_handle, next_tvb, pinfo, dissector_tree, NULL);
2591       }
2592    }
2593 }
2594 
2595 // Dissect CIP Class 2/3 data. This will determine the appropriate format and call the appropriate related dissector.
2596 // offset - Starts at the field after the Item Length field.
dissect_cip_class23_data(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * tree,proto_tree * item_tree,guint32 item_length,enip_request_key_t * request_key,cip_conn_info_t * conn_info,proto_tree * dissector_tree)2597 static void dissect_cip_class23_data(packet_info* pinfo, tvbuff_t* tvb, int offset,
2598    proto_tree* tree, proto_tree* item_tree, guint32 item_length,
2599    enip_request_key_t* request_key, cip_conn_info_t* conn_info, proto_tree* dissector_tree)
2600 {
2601    enip_request_info_t* request_info = NULL;
2602 
2603    if (request_key)
2604    {
2605       request_key->type = EPDT_CONNECTED_TRANSPORT;
2606       request_key->data.connected_transport.sequence = tvb_get_letohs(tvb, offset);
2607       request_info = enip_match_request(pinfo, tree, request_key);
2608    }
2609 
2610    /* Add sequence count ( Transport Class 2,3 ) */
2611    proto_tree_add_item(item_tree, hf_cip_sequence_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2612 
2613    /* Call dissector for interface */
2614    tvbuff_t* next_tvb = tvb_new_subset_length(tvb, offset + 2, item_length - 2);
2615 
2616    p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO, request_info);
2617 
2618    if (conn_info != NULL)
2619    {
2620       dissector_handle_t dissector = dissector_get_uint_handle(subdissector_cip_connection_table, conn_info->ClassID);
2621       if (dissector)
2622       {
2623          call_dissector_with_data(dissector, next_tvb, pinfo, dissector_tree, GUINT_TO_POINTER(conn_info->ClassID));
2624       }
2625       else
2626       {
2627          call_dissector_with_data(cip_implicit_handle, next_tvb, pinfo, dissector_tree, GUINT_TO_POINTER(conn_info->ClassID));
2628       }
2629    }
2630    else
2631    {
2632       // Default to Message Router format, since this is the most common. Since we don't have the connection
2633       // info, at least ensure that the data can at least meet the minimum explicit message size.
2634       if (tvb_reported_length(next_tvb) >= 2)
2635       {
2636          call_dissector(cip_handle, next_tvb, pinfo, dissector_tree);
2637       }
2638    }
2639 
2640    p_remove_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO);
2641 }
2642 
2643 // offset - Starts at the sin_family field.
dissect_item_sockaddr_info(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * item_tree,guint32 item_type_id,gboolean is_fwd_open)2644 static void dissect_item_sockaddr_info(packet_info *pinfo, tvbuff_t* tvb, int offset, proto_tree* item_tree,
2645    guint32 item_type_id, gboolean is_fwd_open)
2646 {
2647    /* Socket address struct - sin_family */
2648    proto_tree_add_item(item_tree, hf_enip_sinfamily, tvb, offset, 2, ENC_BIG_ENDIAN);
2649 
2650    /* Socket address struct - sin_port */
2651    proto_tree_add_item(item_tree, hf_enip_sinport, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
2652 
2653    /* Socket address struct - sin_address */
2654    proto_tree_add_item(item_tree, hf_enip_sinaddr, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
2655 
2656    /* Socket address struct - sin_zero */
2657    proto_tree_add_item(item_tree, hf_enip_sinzero, tvb, offset + 8, 8, ENC_NA);
2658 
2659    if (is_fwd_open)
2660    {
2661       enip_request_info_t* request_info = (enip_request_info_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO);
2662       if (request_info != NULL)
2663       {
2664          if (item_type_id == CPF_ITEM_SOCK_ADR_INFO_OT)
2665          {
2666             request_info->cip_info->connInfo->O2T.port = tvb_get_ntohs(tvb, offset + 2);
2667             alloc_address_tvb(wmem_file_scope(), &request_info->cip_info->connInfo->O2T.ipaddress,
2668                AT_IPv4, sizeof(guint32), tvb, offset + 4);
2669          }
2670          else
2671          {
2672             request_info->cip_info->connInfo->T2O.port = tvb_get_ntohs(tvb, offset + 2);
2673             alloc_address_tvb(wmem_file_scope(), &request_info->cip_info->connInfo->T2O.ipaddress,
2674                AT_IPv4, sizeof(guint32), tvb, offset + 4);
2675          }
2676       }
2677    }
2678 }
2679 
2680 // offset - Starts at the Connection ID
2681 // Returns: connid_type, conn_info
dissect_item_sequenced_address(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * tree,enum enip_connid_type * connid_type,cip_conn_info_t ** conn_info)2682 static void dissect_item_sequenced_address(packet_info* pinfo, tvbuff_t* tvb, int offset,
2683    proto_tree* tree, enum enip_connid_type* connid_type, cip_conn_info_t** conn_info)
2684 {
2685    guint32 connection_id;
2686    proto_tree_add_item_ret_uint(tree, hf_enip_cpf_sai_connid, tvb, offset, 4, ENC_LITTLE_ENDIAN, &connection_id);
2687    proto_item* pi = proto_tree_add_item(tree, hf_cip_connid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2688    proto_item_set_hidden(pi);
2689 
2690    guint32 sequence_num;
2691    proto_tree_add_item_ret_uint(tree, hf_enip_cpf_sai_seqnum, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN, &sequence_num);
2692 
2693    *conn_info = enip_get_io_connid(pinfo, connection_id, connid_type);
2694 
2695    col_add_fstr(pinfo->cinfo, COL_INFO, "Connection: ID=0x%08X, SEQ=%010u", connection_id, sequence_num);
2696    if (*connid_type == ECIDT_O2T)
2697    {
2698        col_append_str(pinfo->cinfo, COL_INFO, ", O->T");
2699    }
2700    else if (*connid_type == ECIDT_T2O)
2701    {
2702        col_append_str(pinfo->cinfo, COL_INFO, ", T->O");
2703    }
2704 }
2705 
2706 // offset - Starts at the Connection ID
2707 // Returns: conn_info
dissect_item_connected_address(packet_info * pinfo,tvbuff_t * tvb,int offset,proto_tree * item_tree,proto_item * enip_item,enip_request_key_t * request_key,cip_conn_info_t ** conn_info)2708 static void dissect_item_connected_address(packet_info* pinfo, tvbuff_t* tvb, int offset,
2709    proto_tree* item_tree, proto_item* enip_item,
2710    enip_request_key_t* request_key, cip_conn_info_t** conn_info)
2711 {
2712    guint32 connection_id;
2713    proto_tree_add_item_ret_uint(item_tree, hf_enip_cpf_cai_connid, tvb, offset, 4, ENC_LITTLE_ENDIAN, &connection_id);
2714    proto_item* pi = proto_tree_add_item(item_tree, hf_cip_connid, tvb, offset, 4, ENC_LITTLE_ENDIAN);
2715    proto_item_set_hidden(pi);
2716 
2717    *conn_info = enip_get_explicit_connid(pinfo, request_key, connection_id);
2718    if (request_key)
2719    {
2720       request_key->type = EPDT_CONNECTED_TRANSPORT;
2721       request_key->data.connected_transport.connid = (*conn_info != NULL) ? (*conn_info)->connid : 0;
2722    }
2723 
2724    /* Add Connection ID to Info col and tree */
2725    col_append_fstr(pinfo->cinfo, COL_INFO, ", Connection: ID=0x%08X", connection_id);
2726 
2727    if (enip_item)
2728    {
2729       proto_item_append_text(enip_item, ", Connection ID: 0x%08X", connection_id);
2730    }
2731 }
2732 
2733 // offset - Starts at Unconn Msg Type
2734 // returns - input_request_key
2735 // Dissects the following parts of the Unconnected Message over UDP item: Unconn Msg Type, Transaction Number, Status.
2736 // The Unconnected Messge field is handled outside of this function.
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)2737 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)
2738 {
2739    guint32 ucmm_request;
2740    proto_tree_add_item_ret_uint(item_tree, hf_enip_cpf_ucmm_request, tvb, offset, 2, ENC_LITTLE_ENDIAN, &ucmm_request);
2741    proto_tree_add_item(item_tree, hf_enip_cpf_ucmm_msg_type, tvb, offset, 2, ENC_LITTLE_ENDIAN);
2742 
2743    guint32 trans_id;
2744    proto_tree_add_item_ret_uint(item_tree, hf_enip_cpf_ucmm_trans_id, tvb, offset + 2, 4, ENC_LITTLE_ENDIAN, &trans_id);
2745    proto_tree_add_item(item_tree, hf_enip_cpf_ucmm_status, tvb, offset + 6, 4, ENC_LITTLE_ENDIAN);
2746 
2747    if (*input_request_key == NULL)
2748    {
2749       /*
2750        * Under normal circumstances request_key should always be NULL here
2751        * Duplicating setting up a request (like is done with explicit messaging)
2752        */
2753       conversation_t* conversation = find_or_create_conversation(pinfo);
2754 
2755       /*
2756        * Attach that information to the conversation, and add
2757        * it to the list of information structures later before dissection.
2758        */
2759       enip_request_key_t* request_key = wmem_new0(pinfo->pool, enip_request_key_t);
2760       request_key->requesttype = ucmm_request ? ENIP_RESPONSE_PACKET : ENIP_REQUEST_PACKET;
2761       request_key->type = EPDT_UNKNOWN;
2762 
2763       /* UCMM over UDP doesn't have a session handle, so use conversation
2764        * pointer as "unique-ish ID"
2765        */
2766       request_key->session_handle = GPOINTER_TO_UINT(conversation);
2767       request_key->sender_context = trans_id;
2768       request_key->conversation = conversation->conv_index;
2769 
2770       // Return the new request key.
2771       *input_request_key = request_key;
2772    }
2773 }
2774 
is_forward_open(guint8 cip_service)2775 static gboolean is_forward_open(guint8 cip_service)
2776 {
2777    return (cip_service == SC_CM_FWD_OPEN
2778       || cip_service == SC_CM_LARGE_FWD_OPEN);
2779 }
2780 
2781 /* Dissect Common Packet Format */
2782 static void
dissect_cpf(enip_request_key_t * request_key,int command,tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * dissector_tree,proto_tree * enip_layer_tree,proto_item * enip_item,int offset,guint32 ifacehndl)2783 dissect_cpf(enip_request_key_t *request_key, int command, tvbuff_t *tvb,
2784             packet_info *pinfo, proto_tree *tree, proto_tree *dissector_tree, proto_tree *enip_layer_tree,
2785             proto_item *enip_item, int offset, guint32 ifacehndl)
2786 {
2787    proto_item            *count_item;
2788    proto_tree            *count_tree;
2789    int                    item_count;
2790 
2791    // The following variables are set in one pass of the loop, and read in a second pass.
2792    cip_conn_info_t*       conn_info    = NULL;
2793    gboolean               FwdOpenRequest = FALSE;
2794    gboolean               FwdOpenReply = FALSE;
2795    enum enip_connid_type  connid_type  = ECIDT_UNKNOWN;
2796 
2797    // Normal "Common Packet Format" configurations. See CIP Volume 2, Section 2-6.4.
2798    //    SendRRData (Unconnected):
2799    //       Item 1: CPF_ITEM_NULL
2800    //       Item 2: CPF_ITEM_UNCONNECTED_DATA
2801    //    SendUnitData (Connected, Class 3):
2802    //       Item 1: CPF_ITEM_CONNECTED_ADDRESS
2803    //       Item 2: CPF_ITEM_CONNECTED_DATA
2804    //       Item 3 (Optional): CPF_ITEM_SOCK_ADR_INFO_OT/CPF_ITEM_SOCK_ADR_INFO_TO
2805    //    Class 0/1 packet:
2806    //       Item 1: CPF_ITEM_SEQUENCED_ADDRESS
2807    //       Item 2: CPF_ITEM_CONNECTED_DATA
2808    //    Unconnected Message over UDP:
2809    //       Item 1: CPF_ITEM_UNCONNECTED_MSG_DTLS
2810 
2811    /* Create item count tree */
2812    item_count = tvb_get_letohs( tvb, offset );
2813    count_item = proto_tree_add_item( tree, hf_enip_cpf_itemcount, tvb, offset, 2, ENC_LITTLE_ENDIAN );
2814    count_tree = proto_item_add_subtree( count_item, ett_count_tree );
2815    offset += 2;
2816 
2817    while ( item_count-- )
2818    {
2819        // Verify that we have the minimum CPF Item size.
2820        if (tvb_reported_length_remaining(tvb, offset) < 4)
2821        {
2822            expert_add_info_format(pinfo, count_item, &ei_mal_cpf_item_minimum_size,
2823                "%s, but Remaining Data Length is %d",
2824                expert_get_summary(&ei_mal_cpf_item_minimum_size), tvb_reported_length_remaining(tvb, offset));
2825 
2826            break;
2827        }
2828 
2829       /* Add item type tree to item count tree*/
2830       guint32 item_type_id;
2831       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 );
2832       proto_tree* item_tree = proto_item_add_subtree( type_item, ett_type_tree );
2833       offset += 2;
2834 
2835       /* Add length field to item type tree */
2836       guint32 item_length;
2837       proto_tree_add_item_ret_uint( item_tree, hf_enip_cpf_length, tvb, offset, 2, ENC_LITTLE_ENDIAN, &item_length);
2838       offset += 2;
2839 
2840       // Check if the declared item length is more bytes than we have available. But, don't exit early
2841       //    so maybe it will be more obvious where the problem is.
2842       if ((int)item_length > tvb_reported_length_remaining(tvb, offset))
2843       {
2844           expert_add_info_format(pinfo, type_item, &ei_mal_cpf_item_length_mismatch,
2845               "%s: Item Length %d, Remaining Data Length: %d",
2846               expert_get_summary(&ei_mal_cpf_item_length_mismatch), item_length, tvb_reported_length_remaining(tvb, offset));
2847       }
2848 
2849       // offset now starts at the data field after the Item Length field. The name of this
2850       //    field varies depending on the item type.
2851       if ( item_length )
2852       {
2853           /* Add item data field */
2854 
2855           switch ( item_type_id )
2856           {
2857             case CPF_ITEM_CONNECTED_ADDRESS:  // 1st Item for: Class 3 Connected Messages
2858                conn_info = NULL;
2859                dissect_item_connected_address(pinfo, tvb, offset, item_tree, enip_item, request_key, &conn_info);
2860                break;
2861 
2862             case CPF_ITEM_UNCONNECTED_MSG_DTLS:  // Only item for: Unconnected messages over DTLS
2863             {
2864                ifacehndl = ENIP_CIP_INTERFACE;
2865 
2866                dissect_item_unconnected_message_over_udp(pinfo, tvb, offset, item_tree, &request_key);
2867 
2868                // Skip over the fields already parsed before falling through.
2869                offset += 10;
2870                item_length -= 10;
2871             }
2872 
2873             /* Intentionally fall through */
2874 
2875             case CPF_ITEM_UNCONNECTED_DATA:  // 2nd Item for: Unconnected Messages
2876             {
2877                enip_request_info_t* request_info = NULL;
2878                if ( request_key )
2879                {
2880                   request_key->type = EPDT_UNCONNECTED;
2881                   request_info = enip_match_request( pinfo, tree, request_key );
2882                }
2883 
2884                /* Call dissector for interface */
2885                tvbuff_t* next_tvb = tvb_new_subset_length( tvb, offset, item_length);
2886                p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO, request_info);
2887                if ( tvb_reported_length_remaining(next_tvb, 0) <= 0 || !dissector_try_uint(subdissector_srrd_table, ifacehndl, next_tvb, pinfo, dissector_tree) )
2888                {
2889                   /* Show the undissected payload */
2890                    if ( tvb_reported_length_remaining(tvb, offset) > 0 )
2891                      call_data_dissector(next_tvb, pinfo, dissector_tree);
2892                }
2893 
2894                /* Check if this is a ForwardOpen packet, because special handling is needed
2895                   to handle connection conversations */
2896                if ((request_info != NULL) && (request_info->cip_info != NULL) &&
2897                    (request_info->cip_info->connInfo != NULL) &&
2898                    (request_key != NULL) &&
2899                    is_forward_open(request_info->cip_info->bService & CIP_SC_MASK) &&
2900                    (request_info->cip_info->dissector == dissector_get_uint_handle(subdissector_class_table, CI_CLS_CM)))
2901                {
2902                   if (request_key->requesttype == ENIP_REQUEST_PACKET)
2903                   {
2904                      FwdOpenRequest = TRUE;
2905                   }
2906                   else
2907                   {
2908                      FwdOpenReply = TRUE;
2909                   }
2910                }
2911                else
2912                {
2913                   p_remove_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO);
2914                }
2915                break;
2916             }
2917 
2918             case CPF_ITEM_CONNECTED_DATA:  // 2nd item for: Connected messages (both Class 0/1 and Class 3)
2919                // Save the connection info for the conversation filter
2920                if (!pinfo->fd->visited && conn_info)
2921                {
2922                   p_add_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_CONNECTION_INFO, conn_info);
2923                }
2924 
2925                if (command == SEND_UNIT_DATA)  // Class 2/3 over TCP.
2926                {
2927                   dissect_cip_class23_data(pinfo, tvb, offset, tree, item_tree, item_length, request_key, conn_info, dissector_tree);
2928                }
2929                else  // No command. Send as CPF items only over UDP.
2930                {
2931                   dissect_cip_class01_io(pinfo, tvb, offset, item_length, conn_info, connid_type, dissector_tree);
2932                }
2933 
2934                if (conn_info)
2935                {
2936                   display_connection_information(pinfo, tvb, enip_layer_tree, conn_info, connid_type);
2937                }
2938 
2939                break;
2940 
2941             case CPF_ITEM_CIP_IDENTITY:
2942                dissect_item_list_identity(pinfo, tvb, offset, item_tree);
2943                break;
2944 
2945             case CPF_ITEM_CIP_SECURITY:
2946                dissect_item_cip_security_information(tvb, offset, item_tree);
2947                break;
2948 
2949             case CPF_ITEM_SOCK_ADR_INFO_OT:  // Optional 3rd item for: Unconnected Messages
2950             case CPF_ITEM_SOCK_ADR_INFO_TO:
2951             {
2952                gboolean is_fwd_open = (FwdOpenRequest == TRUE) || (FwdOpenReply == TRUE);
2953                dissect_item_sockaddr_info(pinfo, tvb, offset, item_tree, item_type_id, is_fwd_open);
2954                break;
2955             }
2956 
2957             case CPF_ITEM_SEQUENCED_ADDRESS:  // 1st item for: Class 0/1 connected data
2958                conn_info = NULL;
2959                dissect_item_sequenced_address(pinfo, tvb, offset, item_tree, &connid_type, &conn_info);
2960                break;
2961 
2962             case CPF_ITEM_LIST_SERVICES_RESP:
2963                dissect_item_list_services_response(pinfo, tvb, offset, item_tree);
2964                break;
2965 
2966             default:
2967                proto_tree_add_item(item_tree, hf_enip_cpf_data, tvb, offset, item_length, ENC_NA);
2968                break;
2969 
2970          } /* end of switch ( item type ) */
2971 
2972       } /* end of if ( item length ) */
2973 
2974       offset += item_length;
2975    } /* end of while ( item count ) */
2976 
2977    /* See if there is a CIP connection to establish */
2978    if (FwdOpenReply == TRUE)
2979    {
2980       enip_request_info_t* request_info = (enip_request_info_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO);
2981       if (request_info != NULL)
2982       {
2983          enip_open_cip_connection(pinfo, request_info->cip_info->connInfo);
2984       }
2985       p_remove_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO);
2986    }
2987    else if (FwdOpenRequest == TRUE)
2988    {
2989       p_remove_proto_data(wmem_file_scope(), pinfo, proto_enip, ENIP_REQUEST_INFO);
2990    }
2991 
2992 } /* end of dissect_cpf() */
2993 
2994 
2995 
2996 static enum enip_packet_type
classify_packet(packet_info * pinfo)2997 classify_packet(packet_info *pinfo)
2998 {
2999    /* see if nature of packets can be derived from src/dst ports */
3000    /* if so, return as found */
3001    if (((ENIP_ENCAP_PORT == pinfo->srcport && ENIP_ENCAP_PORT != pinfo->destport)) ||
3002        ((ENIP_SECURE_PORT == pinfo->srcport && ENIP_SECURE_PORT != pinfo->destport)))
3003    {
3004       return ENIP_RESPONSE_PACKET;
3005    }
3006    else if (((ENIP_ENCAP_PORT != pinfo->srcport && ENIP_ENCAP_PORT == pinfo->destport)) ||
3007             ((ENIP_SECURE_PORT != pinfo->srcport && ENIP_SECURE_PORT == pinfo->destport)))
3008    {
3009       return ENIP_REQUEST_PACKET;
3010    }
3011    else
3012    {
3013       return ENIP_CANNOT_CLASSIFY;
3014    }
3015 }
3016 
3017 static guint
get_enip_pdu_len(packet_info * pinfo _U_,tvbuff_t * tvb,int offset,void * data _U_)3018 get_enip_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
3019 {
3020    guint16 plen;
3021 
3022    /*
3023     * Get the length of the data from the encapsulation header.
3024     */
3025    plen = tvb_get_letohs(tvb, offset + 2);
3026 
3027    /*
3028     * That length doesn't include the encapsulation header itself;
3029     * add that in.
3030     */
3031    return plen + 24;
3032 }
3033 
3034 /* Code to actually dissect the packets */
3035 static int
dissect_enip_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3036 dissect_enip_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3037 {
3038    enum enip_packet_type packet_type;
3039    guint16             encap_cmd, encap_data_length;
3040    const char         *pkt_type_str = "";
3041    guint32             ifacehndl;
3042    conversation_t     *conversation;
3043 
3044    /* Set up structures needed to add the protocol subtree and manage it */
3045    proto_item *ti = NULL;
3046    proto_tree *enip_tree, *header_tree = NULL, *csftree;
3047 
3048    /* Make entries in Protocol column and Info column on summary display */
3049    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ENIP");
3050    col_clear(pinfo->cinfo, COL_INFO);
3051 
3052    encap_cmd = tvb_get_letohs( tvb, 0 );
3053 
3054    packet_type = classify_packet(pinfo);
3055 
3056    switch ( packet_type )
3057    {
3058       case ENIP_REQUEST_PACKET:
3059          pkt_type_str = "Req";
3060          break;
3061 
3062       case ENIP_RESPONSE_PACKET:
3063          pkt_type_str = "Rsp";
3064          break;
3065 
3066       case ENIP_CANNOT_CLASSIFY:
3067       default:
3068          pkt_type_str = "?";
3069    }
3070 
3071    /* Add encapsulation command to info column */
3072    col_append_sep_fstr(pinfo->cinfo, COL_INFO, " | ", "%s (%s)",
3073       val_to_str(encap_cmd, encap_cmd_vals, "Unknown Command (0x%04x)"),
3074       pkt_type_str );
3075 
3076    /*
3077     * We need to track some state for this protocol on a per conversation
3078     * basis so we can do neat things like request/response tracking
3079     */
3080    conversation = find_or_create_conversation(pinfo);
3081 
3082    /*
3083     * Attach that information to the conversation, and add
3084     * it to the list of information structures later before dissection.
3085     */
3086    enip_request_key_t  request_key = {0};
3087    request_key.requesttype    = packet_type;
3088    request_key.type           = EPDT_UNKNOWN;
3089    request_key.session_handle = tvb_get_letohl( tvb, 4 );
3090    request_key.sender_context = tvb_get_letoh64( tvb, 12 );
3091    request_key.conversation   = conversation->conv_index;
3092 
3093    /* create display subtree for the protocol */
3094    ti = proto_tree_add_item(tree, proto_enip, tvb, 0, -1, ENC_NA );
3095 
3096    enip_tree = proto_item_add_subtree(ti, ett_enip);
3097 
3098    /* Add encapsulation header tree */
3099    header_tree = proto_tree_add_subtree( enip_tree, tvb, 0, 24, ett_enip, NULL, "Encapsulation Header");
3100 
3101    /* Add EtherNet/IP encapsulation header */
3102    proto_tree_add_item( header_tree, hf_enip_command, tvb, 0, 2, ENC_LITTLE_ENDIAN );
3103 
3104    encap_data_length = tvb_get_letohs( tvb, 2 );
3105    proto_tree_add_item( header_tree, hf_enip_length, tvb, 2, 2, ENC_LITTLE_ENDIAN );
3106    proto_tree_add_item( header_tree, hf_enip_session, tvb, 4, 4, ENC_LITTLE_ENDIAN );
3107    proto_tree_add_item( header_tree, hf_enip_status, tvb, 8, 4, ENC_LITTLE_ENDIAN );
3108    if ((encap_cmd == LIST_IDENTITY) &&
3109       /* Length of 0 probably indicates a request */
3110       ((encap_data_length == 0) || (packet_type == ENIP_REQUEST_PACKET)))
3111    {
3112       proto_tree_add_item( header_tree, hf_enip_listid_delay, tvb, 12, 2, ENC_LITTLE_ENDIAN );
3113       proto_tree_add_item( header_tree, hf_enip_sendercontex, tvb, 14, 6, ENC_NA );
3114    }
3115    else
3116    {
3117       proto_tree_add_item( header_tree, hf_enip_sendercontex, tvb, 12, 8, ENC_NA );
3118    }
3119    proto_tree_add_item( header_tree, hf_enip_options, tvb, 20, 4, ENC_LITTLE_ENDIAN );
3120 
3121    /* Append session and command to the protocol tree */
3122    proto_item_append_text( ti, ", Session: 0x%08X, %s", tvb_get_letohl( tvb, 4 ),
3123       val_to_str( encap_cmd, encap_cmd_vals, "Unknown Command (0x%04x)" ) );
3124 
3125    /*
3126    ** For some commands we want to add some info to the info column
3127    */
3128    switch ( encap_cmd )
3129    {
3130        case REGISTER_SESSION:
3131        case UNREGISTER_SESSION:
3132            col_append_fstr( pinfo->cinfo, COL_INFO, ", Session: 0x%08X",
3133                             tvb_get_letohl( tvb, 4 ) );
3134            break;
3135    }
3136 
3137    /* Command specific data - create tree */
3138    if ( encap_data_length )
3139    {
3140       /* The packet have some command specific data, build a sub tree for it */
3141 
3142       csftree = proto_tree_add_subtree( enip_tree, tvb, 24, encap_data_length,
3143                                 ett_command_tree, NULL, "Command Specific Data");
3144 
3145       switch ( encap_cmd )
3146       {
3147          case NOP:
3148             break;
3149 
3150          case LIST_SERVICES:
3151             dissect_cpf( &request_key, encap_cmd, tvb, pinfo, csftree, tree, enip_tree, NULL, 24, 0 );
3152             break;
3153 
3154          case LIST_IDENTITY:
3155             dissect_cpf( &request_key, encap_cmd, tvb, pinfo, csftree, tree, enip_tree, NULL, 24, 0 );
3156             break;
3157 
3158          case LIST_INTERFACES:
3159             dissect_cpf( &request_key, encap_cmd, tvb, pinfo, csftree, tree, enip_tree, NULL, 24, 0 );
3160             break;
3161 
3162          case REGISTER_SESSION:
3163             proto_tree_add_item( csftree, hf_enip_rs_version,     tvb, 24, 2, ENC_LITTLE_ENDIAN );
3164             proto_tree_add_item( csftree, hf_enip_rs_optionflags, tvb, 26, 2, ENC_LITTLE_ENDIAN );
3165             break;
3166 
3167          case UNREGISTER_SESSION:
3168             break;
3169 
3170          case SEND_RR_DATA:
3171             proto_tree_add_item( csftree, hf_enip_srrd_ifacehnd,  tvb, 24, 4, ENC_LITTLE_ENDIAN );
3172             proto_tree_add_item( csftree, hf_enip_timeout,        tvb, 28, 2, ENC_LITTLE_ENDIAN );
3173 
3174             ifacehndl = tvb_get_letohl( tvb, 24 );
3175             dissect_cpf( &request_key, encap_cmd, tvb, pinfo, csftree, tree, enip_tree, NULL, 30, ifacehndl );
3176             break;
3177 
3178          case SEND_UNIT_DATA:
3179             proto_tree_add_item(csftree, hf_enip_sud_ifacehnd,    tvb, 24, 4, ENC_LITTLE_ENDIAN);
3180             proto_tree_add_item( csftree, hf_enip_timeout,        tvb, 28, 2, ENC_LITTLE_ENDIAN );
3181 
3182             ifacehndl = tvb_get_letohl( tvb, 24 );
3183             dissect_cpf( &request_key, encap_cmd, tvb, pinfo, csftree, tree, enip_tree, ti, 30, ifacehndl );
3184 
3185             break;
3186 
3187          default:
3188 
3189             /* Can not decode - Just show the data */
3190             proto_tree_add_item(header_tree, hf_enip_encap_data, tvb, 24, encap_data_length, ENC_NA);
3191             break;
3192 
3193       } /* end of switch () */
3194 
3195    } /* end of if ( encapsulated data ) */
3196 
3197    col_set_fence(pinfo->cinfo, COL_INFO);
3198 
3199    return tvb_captured_length(tvb);
3200 } /* end of dissect_enip_pdu() */
3201 
3202 static int
dissect_enip_udp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3203 dissect_enip_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3204 {
3205    /* An ENIP packet is at least 4 bytes long. */
3206    if (tvb_captured_length(tvb) < 4)
3207       return 0;
3208 
3209    return dissect_enip_pdu(tvb, pinfo, tree, data);
3210 }
3211 
3212 static int
dissect_enip_tcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)3213 dissect_enip_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3214 {
3215    // TCP connections for EtherNet/IP are typically open for extended periods of time.
3216    // This means that mostly likely, for real world traffic, a capture initiated for
3217    // EtherNet/IP traffic will start in the middle of a TCP connection. This check
3218    // ignores one byte TCP payloads because it is far more likely that a one byte TCP
3219    // payload is a TCP keep alive message, than a client actually sending real EtherNet/IP
3220    // messages in one byte chunks.
3221    if (tvb_captured_length(tvb) < 2)
3222       return 0;
3223 
3224    tcp_dissect_pdus(tvb, pinfo, tree, enip_desegment, 4, get_enip_pdu_len, dissect_enip_pdu, data);
3225    return tvb_captured_length(tvb);
3226 }
3227 
3228 /* Code to actually dissect the io packets*/
3229 static int
dissect_cipio(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3230 dissect_cipio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3231 {
3232    /* Set up structures needed to add the protocol subtree and manage it */
3233    proto_item *ti;
3234    proto_tree *enip_tree;
3235 
3236    /* Make entries in Protocol column and Info column on summary display */
3237    col_set_str(pinfo->cinfo, COL_PROTOCOL, "CIP I/O");
3238 
3239    /* create display subtree for the protocol */
3240    ti = proto_tree_add_item(tree, proto_enip, tvb, 0, -1, ENC_NA );
3241 
3242    enip_tree = proto_item_add_subtree(ti, ett_enip);
3243 
3244    dissect_cpf( NULL, 0xFFFF, tvb, pinfo, enip_tree, tree, enip_tree, NULL, 0, 0 );
3245 
3246    return tvb_captured_length(tvb);
3247 }
3248 
3249 
3250 static gboolean
dissect_dlr(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3251 dissect_dlr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
3252 {
3253    proto_item *ti;
3254    proto_tree *dlr_tree;
3255    guint8      dlr_subtype;
3256    guint8      dlr_protover;
3257    guint8      dlr_frametype;
3258 
3259    /* Make entries in Protocol column and Info column on summary display */
3260    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DLR");
3261 
3262    col_clear(pinfo->cinfo, COL_INFO);
3263 
3264    /* Create display subtree for the protocol */
3265    ti = proto_tree_add_item(tree, proto_dlr, tvb, 0, -1, ENC_NA );
3266    dlr_tree = proto_item_add_subtree( ti, ett_dlr );
3267 
3268    /* Get values for the Common Frame Header Format */
3269    dlr_subtype  = tvb_get_guint8(tvb, DLR_CFH_SUB_TYPE);
3270    dlr_protover = tvb_get_guint8(tvb, DLR_CFH_PROTO_VERSION);
3271 
3272    /* Dissect the Common Frame Header Format */
3273    proto_tree_add_uint( dlr_tree, hf_dlr_ringsubtype,      tvb, DLR_CFH_SUB_TYPE,      1, dlr_subtype );
3274    proto_tree_add_uint( dlr_tree, hf_dlr_ringprotoversion, tvb, DLR_CFH_PROTO_VERSION, 1, dlr_protover );
3275 
3276    /* Get values for the DLR Message Payload Fields */
3277    dlr_frametype  = tvb_get_guint8(tvb, DLR_MPF_FRAME_TYPE);
3278 
3279    /* Dissect the DLR Message Payload Fields */
3280    proto_tree_add_item( dlr_tree, hf_dlr_frametype,  tvb, DLR_MPF_FRAME_TYPE,  1, ENC_BIG_ENDIAN );
3281    proto_tree_add_item( dlr_tree, hf_dlr_sourceport, tvb, DLR_MPF_SOURCE_PORT, 1, ENC_BIG_ENDIAN );
3282    proto_tree_add_item( dlr_tree, hf_dlr_sourceip,   tvb, DLR_MPF_SOURCE_IP,   4, ENC_BIG_ENDIAN );
3283    proto_tree_add_item( dlr_tree, hf_dlr_sequenceid, tvb, DLR_MPF_SEQUENCE_ID, 4, ENC_BIG_ENDIAN );
3284 
3285    /* Add frame type to col info */
3286    col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
3287        val_to_str(dlr_frametype, dlr_frame_type_vals, "Unknown (0x%04x)") );
3288 
3289    if ( dlr_frametype == DLR_FT_BEACON )
3290    {
3291       /* Beacon */
3292       proto_tree_add_item( dlr_tree, hf_dlr_ringstate,            tvb, DLR_BE_RING_STATE,            1, ENC_BIG_ENDIAN );
3293       proto_tree_add_item( dlr_tree, hf_dlr_supervisorprecedence, tvb, DLR_BE_SUPERVISOR_PRECEDENCE, 1, ENC_BIG_ENDIAN );
3294       proto_tree_add_item( dlr_tree, hf_dlr_beaconinterval,       tvb, DLR_BE_BEACON_INTERVAL,       4, ENC_BIG_ENDIAN );
3295       proto_tree_add_item( dlr_tree, hf_dlr_beacontimeout,        tvb, DLR_BE_BEACON_TIMEOUT,        4, ENC_BIG_ENDIAN );
3296       proto_tree_add_item( dlr_tree, hf_dlr_beaconreserved,       tvb, DLR_BE_RESERVED,             20, ENC_NA );
3297    }
3298    else if ( dlr_frametype == DLR_FT_NEIGHBOR_REQ )
3299    {
3300       /* Neighbor_Check_Request */
3301       proto_tree_add_item( dlr_tree, hf_dlr_nreqreserved, tvb, DLR_NREQ_RESERVED, 30, ENC_NA );
3302    }
3303    else if ( dlr_frametype == DLR_FT_NEIGHBOR_RES )
3304    {
3305       /* Neighbor_Check_Response */
3306       proto_tree_add_item( dlr_tree, hf_dlr_nressourceport, tvb, DLR_NRES_SOURCE_PORT,  1, ENC_BIG_ENDIAN );
3307       proto_tree_add_item( dlr_tree, hf_dlr_nresreserved,   tvb, DLR_NRES_RESERVED,    29, ENC_NA );
3308    }
3309    else if ( dlr_frametype == DLR_FT_LINK_STAT )
3310    {
3311       /* Link_Status/Neighbor_Status */
3312       static int* const bits[] = {
3313          &hf_dlr_lnknbrstatus_port1,
3314          &hf_dlr_lnknbrstatus_port2,
3315          &hf_dlr_lnknbrstatus_reserved,
3316          &hf_dlr_lnknbrstatus_frame_type,
3317          NULL
3318       };
3319 
3320       proto_tree_add_bitmask(dlr_tree, tvb, DLR_LNS_SOURCE_PORT, hf_dlr_lnknbrstatus, ett_dlr_lnknbrstatus_flags, bits, ENC_LITTLE_ENDIAN);
3321 
3322       proto_tree_add_item( dlr_tree, hf_dlr_lnknbrreserved, tvb, DLR_LNS_RESERVED,    29, ENC_NA );
3323    }
3324    else if ( dlr_frametype == DLR_FT_LOCATE_FLT )
3325    {
3326       /* Locate_Fault */
3327       proto_tree_add_item( dlr_tree, hf_dlr_lfreserved, tvb, DLR_LF_RESERVED, 30, ENC_NA );
3328    }
3329    else if ( dlr_frametype == DLR_FT_ANNOUNCE )
3330    {
3331       /* Announce */
3332       proto_tree_add_item( dlr_tree, hf_dlr_ringstate,  tvb, DLR_AN_RING_STATE,  1, ENC_BIG_ENDIAN );
3333       proto_tree_add_item( dlr_tree, hf_dlr_anreserved, tvb, DLR_AN_RESERVED,   29, ENC_NA );
3334    }
3335    else if ( dlr_frametype == DLR_FT_SIGN_ON )
3336    {
3337       guint16  nCnt;
3338       guint16  nNumNodes;
3339       guint16  nOffset;
3340 
3341 
3342       /* Sign_On */
3343       nNumNodes = tvb_get_ntohs(tvb, DLR_SO_NUM_NODES);
3344 
3345       proto_tree_add_uint( dlr_tree, hf_dlr_sonumnodes, tvb, DLR_SO_NUM_NODES, 2, nNumNodes );
3346 
3347       /* Add each node in the list */
3348       for( nCnt = 0, nOffset = DLR_SO_NODE_1_MAC; nCnt < nNumNodes; nCnt++ )
3349       {
3350          proto_tree_add_item( dlr_tree, hf_dlr_somac, tvb, nOffset, 6, ENC_NA );
3351          nOffset += 6;
3352          proto_tree_add_item( dlr_tree, hf_dlr_soip, tvb, nOffset, 4, ENC_BIG_ENDIAN );
3353          nOffset += 4;
3354       }
3355 
3356       if ( nOffset < 42 )
3357       {
3358          proto_tree_add_item( dlr_tree, hf_dlr_soreserved, tvb, nOffset, 42 - nOffset, ENC_NA );
3359          /* nOffset += (42 - nOffset); */
3360       }
3361    }
3362    else if ( dlr_frametype == DLR_FT_ADVERTISE )
3363    {
3364       /* Advertise */
3365       proto_tree_add_item( dlr_tree, hf_dlr_advgatewaystate,         tvb, DLR_ADV_GATEWAY_STATE,           1, ENC_BIG_ENDIAN );
3366       proto_tree_add_item( dlr_tree, hf_dlr_advgatewayprecedence,    tvb, DLR_ADV_GATEWAY_PRECEDENCE,      1, ENC_BIG_ENDIAN );
3367       proto_tree_add_item( dlr_tree, hf_dlr_advadvertiseinterval,    tvb, DLR_ADV_ADVERTISE_INTERVAL,      4, ENC_BIG_ENDIAN );
3368       proto_tree_add_item( dlr_tree, hf_dlr_advadvertisetimeout,     tvb, DLR_ADV_ADVERTISE_TIMEOUT,       4, ENC_BIG_ENDIAN );
3369       proto_tree_add_item( dlr_tree, hf_dlr_advlearningupdateenable, tvb, DLR_ADV_LEARNING_UPDATE_ENABLE,  1, ENC_BIG_ENDIAN );
3370       proto_tree_add_item( dlr_tree, hf_dlr_advreserved,             tvb, DLR_ADV_RESERVED,               19, ENC_NA );
3371    }
3372    else if ( dlr_frametype == DLR_FT_FLUSH_TABLES )
3373    {
3374       proto_tree_add_item( dlr_tree, hf_dlr_flushlearningupdateenable, tvb, DLR_FLUSH_LEARNING_UPDATE_ENABLE,  1, ENC_BIG_ENDIAN );
3375       proto_tree_add_item( dlr_tree, hf_dlr_flushreserved,             tvb, DLR_FLUSH_RESERVED,               29, ENC_NA );
3376    }
3377    else if ( dlr_frametype == DLR_FT_LEARNING_UPDATE )
3378    {
3379       proto_tree_add_item( dlr_tree, hf_dlr_learnreserved,  tvb, DLR_LEARN_RESERVED, 34, ENC_NA );
3380    }
3381    else
3382    {
3383       /* Unknown Frame type */
3384    }
3385 
3386    return tvb_captured_length(tvb);
3387 
3388 } /* end of dissect_dlr() */
3389 
dissect_cip_class1(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3390 static int dissect_cip_class1(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* data _U_)
3391 {
3392    cip_conn_info_t conn_info;
3393    memset(&conn_info, 0, sizeof(conn_info));
3394    conn_info.TransportClass_trigger = 1;
3395 
3396    cip_io_data_input io_data_input;
3397    io_data_input.conn_info = &conn_info;
3398    io_data_input.connid_type = ECIDT_UNKNOWN;
3399 
3400    return dissect_cip_io_generic(tvb, pinfo, tree, &io_data_input);
3401 }
3402 
3403 /* Register the protocol with Wireshark */
3404 
3405 /* this format is require because a script is used to build the C function
3406    that calls all the protocol registration.
3407 */
3408 
3409 void
proto_register_enip(void)3410 proto_register_enip(void)
3411 {
3412    /* Setup list of header fields */
3413    static hf_register_info hf[] = {
3414       { &hf_enip_command,
3415         { "Command", "enip.command",
3416           FT_UINT16, BASE_HEX, VALS(encap_cmd_vals), 0,
3417           "Encapsulation command", HFILL }},
3418 
3419       { &hf_enip_length,
3420         { "Length", "enip.length",
3421           FT_UINT16, BASE_DEC, NULL, 0,
3422           "Encapsulation length", HFILL }},
3423 
3424       { &hf_enip_session,
3425         { "Session Handle", "enip.session",
3426           FT_UINT32, BASE_HEX, NULL, 0,
3427           "Session identification", HFILL }},
3428 
3429       { &hf_enip_status,
3430         { "Status", "enip.status",
3431           FT_UINT32, BASE_HEX, VALS(encap_status_vals), 0,
3432           "Status code", HFILL }},
3433 
3434       { &hf_enip_sendercontex,
3435         { "Sender Context", "enip.context",
3436           FT_BYTES, BASE_NONE, NULL, 0,
3437           "Information pertinent to the sender", HFILL }},
3438 
3439       { &hf_enip_listid_delay,
3440         { "Max Response Delay", "enip.listid_delay",
3441           FT_UINT16, BASE_DEC|BASE_UNIT_STRING, &units_milliseconds, 0,
3442           "Maximum random delay allowed by target", HFILL }},
3443 
3444       { &hf_enip_options,
3445         { "Options", "enip.options",
3446           FT_UINT32, BASE_HEX, NULL, 0,
3447           "Options flags", HFILL }},
3448 
3449       { &hf_enip_encapver,
3450         { "Encapsulation Protocol Version", "enip.encapver",
3451           FT_UINT16, BASE_DEC, NULL, 0,
3452           NULL, HFILL }},
3453 
3454       { &hf_enip_sinfamily,
3455         { "sin_family", "enip.sinfamily",
3456           FT_UINT16, BASE_DEC, NULL, 0,
3457           "Socket Address.Sin Family", HFILL }},
3458 
3459       { &hf_enip_sinport,
3460         { "sin_port", "enip.sinport",
3461           FT_UINT16, BASE_DEC, NULL, 0,
3462           "Socket Address.Sin Port", HFILL }},
3463 
3464       { &hf_enip_sinaddr,
3465         { "sin_addr", "enip.sinaddr",
3466           FT_IPv4, BASE_NONE, NULL, 0,
3467           "Socket Address.Sin Addr", HFILL }},
3468 
3469       { &hf_enip_sinzero,
3470         { "sin_zero", "enip.sinzero",
3471           FT_BYTES, BASE_NONE, NULL, 0,
3472           "Socket Address.Sin Zero", HFILL }},
3473 
3474       { &hf_enip_timeout,
3475         { "Timeout", "enip.timeout",
3476           FT_UINT16, BASE_DEC, NULL, 0,
3477           "Encapsulation Timeout", HFILL }},
3478 
3479       { &hf_enip_encap_data,
3480         { "Encap Data", "enip.encap_data",
3481           FT_BYTES, BASE_NONE, NULL, 0,
3482           "Encapsulation Data", HFILL }},
3483 
3484       /* List Services Reply */
3485       { &hf_enip_lsr_capaflags,
3486         { "Capability Flags", "enip.lsr.capaflags",
3487           FT_UINT16, BASE_HEX, NULL, 0,
3488           "ListServices Reply: Capability Flags", HFILL }},
3489 
3490       { &hf_enip_lsr_tcp,
3491         { "Supports CIP Encapsulation via TCP", "enip.lsr.capaflags.tcp",
3492           FT_BOOLEAN, 16, TFS(&tfs_true_false), 0x0020,
3493           "ListServices Reply: Supports CIP Encapsulation via TCP", HFILL }},
3494 
3495       { &hf_enip_lsr_udp,
3496         { "Supports CIP Class 0 or 1 via UDP", "enip.lsr.capaflags.udp",
3497           FT_BOOLEAN, 16, TFS(&tfs_true_false), 0x0100,
3498           "ListServices Reply: Supports CIP Class 0 or 1 via UDP", HFILL }},
3499 
3500       { &hf_enip_lsr_servicename,
3501         { "Name of Service", "enip.lsr.servicename",
3502           FT_STRING, BASE_NONE, NULL, 0,
3503           "ListServices Reply: Name of Service", HFILL }},
3504 
3505       /* Register Session */
3506       { &hf_enip_rs_version,
3507         { "Protocol Version", "enip.rs.version",
3508           FT_UINT16, BASE_DEC, NULL, 0,
3509           "Register Session: Protocol Version", HFILL }},
3510 
3511       { &hf_enip_rs_optionflags,
3512         { "Option Flags", "enip.rs.flags",
3513           FT_UINT16, BASE_HEX, NULL, 0,
3514           "Register Session: Option Flags", HFILL }},
3515 
3516       /* Send Request/Reply Data */
3517       { &hf_enip_srrd_ifacehnd,
3518         { "Interface Handle", "enip.srrd.iface",
3519           FT_UINT32, BASE_HEX, VALS(enip_interface_handle_vals), 0,
3520           "SendRRData: Interface handle", HFILL }},
3521 
3522       /* Send Unit Data */
3523       { &hf_enip_sud_ifacehnd,
3524         { "Interface Handle", "enip.sud.iface",
3525           FT_UINT32, BASE_HEX, VALS(enip_interface_handle_vals), 0,
3526           "SendUnitData: Interface handle", HFILL }},
3527 
3528       /* List identity reply */
3529       { &hf_enip_lir_vendor,
3530         { "Vendor ID", "enip.lir.vendor",
3531           FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_vendor_vals_ext, 0,
3532           "ListIdentity Reply: Vendor ID", HFILL }},
3533 
3534       { &hf_enip_lir_devtype,
3535         { "Device Type", "enip.lir.devtype",
3536           FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cip_devtype_vals_ext, 0,
3537           "ListIdentity Reply: Device Type", HFILL }},
3538 
3539       { &hf_enip_lir_prodcode,
3540         { "Product Code", "enip.lir.prodcode",
3541           FT_UINT16, BASE_DEC, NULL, 0,
3542           "ListIdentity Reply: Product Code", HFILL }},
3543 
3544       { &hf_enip_lir_revision,
3545         { "Revision", "enip.lir.revision",
3546           FT_UINT16, BASE_CUSTOM, CF_FUNC(enip_fmt_lir_revision), 0,
3547           "ListIdentity Reply: Revision", HFILL }},
3548 
3549       { &hf_enip_lir_status,
3550         { "Status", "enip.lir.status",
3551           FT_UINT16, BASE_HEX, NULL, 0,
3552           "ListIdentity Reply: Status", HFILL }},
3553 
3554       { &hf_enip_lir_serial,
3555         { "Serial Number", "enip.lir.serial",
3556           FT_UINT32, BASE_HEX, NULL, 0,
3557           "ListIdentity Reply: Serial Number", HFILL }},
3558 
3559       { &hf_enip_lir_namelen,
3560         { "Product Name Length", "enip.lir.namelen",
3561           FT_UINT8, BASE_DEC, NULL, 0,
3562           "ListIdentity Reply: Product Name Length", HFILL }},
3563 
3564       { &hf_enip_lir_name,
3565         { "Product Name", "enip.lir.name",
3566           FT_STRING, BASE_NONE, NULL, 0,
3567           "ListIdentity Reply: Product Name", HFILL }},
3568 
3569       { &hf_enip_lir_state,
3570         { "State", "enip.lir.state",
3571           FT_UINT8, BASE_HEX, NULL, 0,
3572           "ListIdentity Reply: State", HFILL }},
3573 
3574       { &hf_enip_security_profiles,
3575         { "Security Profiles", "enip.security_profiles",
3576           FT_UINT16, BASE_HEX, NULL, 0,
3577           NULL, HFILL }},
3578 
3579       { &hf_enip_security_profiles_eip_integrity,
3580         { "EtherNet/IP Integrity Profile", "enip.security_profiles.eip_integrity",
3581           FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0001,
3582           NULL, HFILL }},
3583 
3584       { &hf_enip_security_profiles_eip_confidentiality,
3585         { "EtherNet/IP Confidentiality Profile", "enip.security_profiles.eip_confidentiality",
3586           FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0002,
3587           NULL, HFILL }},
3588 
3589       { &hf_enip_security_profiles_cip_authorization,
3590         { "CIP Authorization Profile", "enip.security_profiles.cip_authorization",
3591           FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0004,
3592           NULL, HFILL }},
3593 
3594       { &hf_enip_security_profiles_cip_user_authentication,
3595         { "CIP User Authentication Profile", "enip.security_profiles.cip_user_authentication",
3596           FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0008,
3597           NULL, HFILL }},
3598 
3599       { &hf_enip_security_profiles_resource_constrained,
3600         { "Resource-Constrained CIP Security Profile", "enip.security_profiles.resource_constrained",
3601           FT_BOOLEAN, 16, TFS(&tfs_supported_not_supported), 0x0010,
3602           NULL, HFILL } },
3603 
3604       { &hf_enip_security_profiles_reserved,
3605         { "Reserved", "enip.security_profiles.reserved",
3606           FT_UINT16, BASE_HEX, NULL, 0xFFE0,
3607           NULL, HFILL }},
3608 
3609       { &hf_enip_cip_security_state,
3610         { "CIP Security State", "enip.cip_security_state",
3611           FT_UINT8, BASE_DEC, VALS(cip_security_state_vals), 0,
3612           NULL, HFILL }},
3613 
3614       { &hf_enip_eip_security_state,
3615         { "EIP Security State", "enip.eip_security_state",
3616           FT_UINT8, BASE_DEC, VALS(eip_security_state_vals), 0,
3617           NULL, HFILL }},
3618 
3619       { &hf_enip_iana_port_state_flags,
3620         { "IANA Port State", "enip.iana_port_state_flags",
3621           FT_UINT8, BASE_HEX, NULL, 0,
3622           NULL, HFILL }},
3623 
3624       { &hf_enip_iana_port_state_flags_tcp_44818,
3625         { "44818/tcp", "enip.security_profiles.iana_port_state_flags.tcp_44818",
3626           FT_BOOLEAN, 8, TFS(&tfs_open_closed), 0x01,
3627           NULL, HFILL }},
3628 
3629       { &hf_enip_iana_port_state_flags_udp_44818,
3630         { "44818/udp", "enip.security_profiles.iana_port_state_flags.udp_44818",
3631           FT_BOOLEAN, 8, TFS(&tfs_open_closed), 0x02,
3632           NULL, HFILL }},
3633 
3634       { &hf_enip_iana_port_state_flags_udp_2222,
3635         { "2222/udp", "enip.security_profiles.iana_port_state_flags.udp_2222",
3636           FT_BOOLEAN, 8, TFS(&tfs_open_closed), 0x04,
3637           NULL, HFILL }},
3638 
3639       { &hf_enip_iana_port_state_flags_tcp_2221,
3640         { "2221/tcp", "enip.security_profiles.iana_port_state_flags.tcp_2221",
3641           FT_BOOLEAN, 8, TFS(&tfs_open_closed), 0x08,
3642           NULL, HFILL }},
3643 
3644       { &hf_enip_iana_port_state_flags_udp_2221,
3645         { "2221/udp", "enip.security_profiles.iana_port_state_flags.udp_2221",
3646           FT_BOOLEAN, 8, TFS(&tfs_open_closed), 0x10,
3647           NULL, HFILL }},
3648 
3649       { &hf_enip_iana_port_state_flags_reserved,
3650         { "Reserved", "enip.iana_port_state_flags.reserved",
3651           FT_UINT8, BASE_HEX, NULL, 0xE0,
3652           NULL, HFILL }},
3653 
3654       /* Common Packet Format */
3655       { &hf_enip_cpf_itemcount,
3656         { "Item Count", "enip.cpf.itemcount",
3657           FT_UINT16, BASE_DEC, NULL, 0,
3658           "Common Packet Format: Item Count", HFILL }},
3659 
3660       { &hf_enip_cpf_typeid,
3661         { "Type ID", "enip.cpf.typeid",
3662           FT_UINT16, BASE_HEX, VALS(cpf_type_vals), 0,
3663           "Common Packet Format: Type of encapsulated item", HFILL }},
3664 
3665       { &hf_enip_cpf_length,
3666         { "Length", "enip.cpf.length",
3667           FT_UINT16, BASE_DEC, NULL, 0,
3668           "Common Packet Format: Length", HFILL }},
3669 
3670       /* Connected Data Item */
3671       { &hf_cip_sequence_count,
3672         { "CIP Sequence Count", "cip.seq",
3673           FT_UINT16, BASE_DEC, NULL, 0,
3674           NULL, HFILL }},
3675 
3676       /* Connection Address Item */
3677       { &hf_enip_cpf_cai_connid,
3678         { "Connection ID", "enip.cpf.cai.connid",
3679           FT_UINT32, BASE_HEX, NULL, 0,
3680           "Common Packet Format: Connection Address Item, Connection Identifier", HFILL }},
3681 
3682       { &hf_enip_cpf_ucmm_request,
3683         { "Request/Response", "enip.cpf.ucmm.request",
3684           FT_UINT16, BASE_DEC, VALS(cip_sc_rr), 0x8000,
3685           "Common Packet Format: UCMM Request/Response", HFILL }},
3686 
3687       { &hf_enip_cpf_ucmm_msg_type,
3688         { "Unconn Msg Type", "enip.cpf.ucmm.msg_type",
3689           FT_UINT16, BASE_DEC, VALS(unconn_msg_type_vals), 0x7FFF,
3690           "Common Packet Format: UCMM Transaction ID", HFILL }},
3691 
3692       { &hf_enip_cpf_ucmm_trans_id,
3693         { "Transaction ID", "enip.cpf.ucmm.trans_id",
3694           FT_UINT32, BASE_HEX, NULL, 0,
3695           "Common Packet Format: UCMM Transaction ID", HFILL }},
3696 
3697       { &hf_enip_cpf_ucmm_status,
3698         { "UCMM Status", "enip.cpf.ucmm.status",
3699           FT_UINT32, BASE_HEX, VALS(encap_status_vals), 0,
3700           "Common Packet Format: UCMM Status", HFILL }},
3701 
3702       /* Sequenced Address Type */
3703       { &hf_enip_cpf_sai_connid,
3704         { "Connection ID", "enip.cpf.sai.connid",
3705           FT_UINT32, BASE_HEX, NULL, 0,
3706           "Common Packet Format: Sequenced Address Item, Connection Identifier", HFILL }},
3707       { &hf_cip_connid, { "Connection ID", "cip.connid", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } },
3708 
3709       { &hf_enip_cpf_sai_seqnum,
3710         { "Encapsulation Sequence Number", "enip.cpf.sai.seq",
3711           FT_UINT32, BASE_DEC, NULL, 0,
3712           "Common Packet Format: Sequenced Address Item, Sequence Number", HFILL }},
3713 
3714       { &hf_enip_cpf_data,
3715         { "Data", "enip.cpf.data",
3716           FT_BYTES, BASE_NONE, NULL, 0,
3717           "Common Packet Format: Unknown Data", HFILL }},
3718 
3719       /* Request/Response Matching */
3720       { &hf_enip_response_in,
3721         { "Response In", "enip.response_in",
3722           FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0x0,
3723           "The response to this ENIP request is in this frame", HFILL }},
3724 
3725       { &hf_enip_response_to,
3726         { "Request In", "enip.response_to",
3727           FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0x0,
3728           "This is a response to the ENIP request in this frame", HFILL }},
3729 
3730       { &hf_enip_time,
3731         { "Time", "enip.time",
3732           FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3733           "The time between the Call and the Reply", HFILL }},
3734 
3735       { &hf_enip_fwd_open_in,
3736         { "Forward Open Request In", "enip.fwd_open_in",
3737         FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } },
3738 
3739       // Generated API data.
3740       { &hf_cip_cm_ot_api, { "O->T API", "cip.cm.otapi", FT_UINT32, BASE_CUSTOM, CF_FUNC(cip_rpi_api_fmt), 0, NULL, HFILL } },
3741       { &hf_cip_cm_to_api, { "T->O API", "cip.cm.toapi", FT_UINT32, BASE_CUSTOM, CF_FUNC(cip_rpi_api_fmt), 0, NULL, HFILL } },
3742 
3743       { &hf_cip_connection,
3744         { "CIP Connection Index", "cip.connection",
3745           FT_UINT32, BASE_DEC, NULL, 0x0,
3746           NULL, HFILL } },
3747 
3748       { &hf_cip_io_data,
3749         { "Data", "cipio.data",
3750           FT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0x0,
3751           NULL, HFILL }},
3752 
3753       { &hf_tcpip_status,
3754         { "Status", "cip.tcpip.status",
3755           FT_UINT32, BASE_HEX, NULL, 0,
3756           NULL, HFILL }},
3757 
3758       { &hf_tcpip_status_interface_config,
3759         { "Interface Configuration Status", "cip.tcpip.status.interface_config",
3760           FT_UINT32, BASE_DEC, VALS(enip_tcpip_status_interface_config_vals), 0x0000000F,
3761           NULL, HFILL }},
3762 
3763       { &hf_tcpip_status_mcast_pending,
3764         { "MCast Pending", "cip.tcpip.status.mcast_pending",
3765           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000010,
3766           NULL, HFILL }},
3767 
3768       { &hf_tcpip_status_interface_config_pending,
3769         { "Interface Configuration Pending", "cip.tcpip.status.interface_config_pending",
3770           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000020,
3771           NULL, HFILL }},
3772 
3773       { &hf_tcpip_status_acd,
3774         { "ACD Status", "cip.tcpip.status.acd",
3775           FT_UINT32, BASE_DEC, VALS(enip_tcpip_status_acd_vals), 0x00000040,
3776           NULL, HFILL }},
3777 
3778       { &hf_tcpip_acd_fault,
3779         { "ACD Fault", "cip.tcpip.status.acd_fault",
3780           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000080,
3781           NULL, HFILL }},
3782 
3783       { &hf_tcpip_status_iana_port_admin_change,
3784         { "IANA Port Admin Change Pending", "cip.tcpip.status.iana_port_admin",
3785           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000100,
3786           NULL, HFILL }},
3787 
3788       { &hf_tcpip_status_iana_protocol_admin_change,
3789         { "IANA Protocol Admin Change Pending", "cip.tcpip.status.iana_protocol_admin",
3790           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000200,
3791           NULL, HFILL }},
3792 
3793       { &hf_tcpip_status_reserved,
3794         { "Reserved", "cip.tcpip.status.reserved",
3795           FT_UINT32, BASE_HEX, NULL, 0xFFFFFC00,
3796           NULL, HFILL }},
3797 
3798       { &hf_tcpip_config_cap,
3799         { "Configuration Capability", "cip.tcpip.config_cap",
3800           FT_UINT32, BASE_HEX, NULL, 0,
3801           NULL, HFILL }},
3802 
3803       { &hf_tcpip_config_cap_bootp,
3804         { "BOOTP Client", "cip.tcpip.config_cap.bootp",
3805           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000001,
3806           NULL, HFILL }},
3807 
3808       { &hf_tcpip_config_cap_dns,
3809         { "DNS Client", "cip.tcpip.config_cap.dns",
3810           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000002,
3811           NULL, HFILL }},
3812 
3813       { &hf_tcpip_config_cap_dhcp,
3814         { "DHCP Client", "cip.tcpip.config_cap.dhcp",
3815           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000004,
3816           NULL, HFILL }},
3817 
3818       { &hf_tcpip_config_cap_dhcp_dns_update,
3819         { "DHCP-DNS Update", "cip.tcpip.config_cap.dhcp_dns_update",
3820           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000008,
3821           NULL, HFILL }},
3822 
3823       { &hf_tcpip_config_cap_config_settable,
3824         { "Configuration Settable", "cip.tcpip.config_cap.config_settable",
3825           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000010,
3826           NULL, HFILL }},
3827 
3828       { &hf_tcpip_config_cap_hardware_config,
3829         { "Hardware Configurable", "cip.tcpip.config_cap.hardware_config",
3830           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000020,
3831           NULL, HFILL }},
3832 
3833       { &hf_tcpip_config_cap_interface_reset,
3834         { "Interface Configuration Change Requires Reset", "cip.tcpip.config_cap.interface_reset",
3835           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000040,
3836           NULL, HFILL }},
3837 
3838       { &hf_tcpip_config_cap_acd,
3839         { "ACD Capable", "cip.tcpip.config_cap.acd",
3840           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000080,
3841           NULL, HFILL }},
3842 
3843       { &hf_tcpip_config_cap_reserved,
3844         { "Reserved", "cip.tcpip.config_cap.reserved",
3845           FT_UINT32, BASE_HEX, NULL, 0xFFFFFF00,
3846           NULL, HFILL }},
3847 
3848       { &hf_tcpip_config_control,
3849         { "Configuration Control", "cip.tcpip.config_control",
3850           FT_UINT32, BASE_HEX, NULL, 0,
3851           NULL, HFILL }},
3852 
3853       { &hf_tcpip_config_control_config,
3854         { "Configuration Method", "cip.tcpip.config_control.config",
3855           FT_UINT32, BASE_DEC, VALS(enip_tcpip_config_control_config_vals), 0x0000000F,
3856           NULL, HFILL }},
3857 
3858       { &hf_tcpip_config_control_dns,
3859         { "DNS Enable", "cip.tcpip.config_control.dns",
3860           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000010,
3861           NULL, HFILL }},
3862 
3863       { &hf_tcpip_config_control_reserved,
3864         { "Reserved", "cip.tcpip.config_control.reserved",
3865           FT_UINT32, BASE_HEX, NULL, 0xFFFFFFE0,
3866           NULL, HFILL }},
3867 
3868       { &hf_tcpip_ic_ip_addr,
3869         { "IP Address", "cip.tcpip.ip_addr",
3870           FT_IPv4, BASE_NONE, NULL, 0,
3871           NULL, HFILL }},
3872 
3873       { &hf_tcpip_ic_subnet_mask,
3874         { "Subnet Mask", "cip.tcpip.subnet_mask",
3875           FT_IPv4, BASE_NETMASK, NULL, 0,
3876           NULL, HFILL }},
3877 
3878       { &hf_tcpip_ic_gateway,
3879         { "Gateway", "cip.tcpip.gateway",
3880           FT_IPv4, BASE_NONE, NULL, 0,
3881           NULL, HFILL }},
3882 
3883       { &hf_tcpip_ic_name_server,
3884         { "Name Server", "cip.tcpip.name_server",
3885           FT_IPv4, BASE_NONE, NULL, 0,
3886           NULL, HFILL }},
3887 
3888       { &hf_tcpip_ic_name_server2,
3889         { "Name Server2", "cip.tcpip.name_server2",
3890           FT_IPv4, BASE_NONE, NULL, 0,
3891           NULL, HFILL }},
3892 
3893       { &hf_tcpip_ic_domain_name,
3894         { "Domain Name", "cip.tcpip.domain_name",
3895           FT_STRING, BASE_NONE, NULL, 0,
3896           NULL, HFILL }},
3897 
3898       { &hf_tcpip_hostname,
3899         { "Hostname", "cip.tcpip.hostname",
3900           FT_STRING, BASE_NONE, NULL, 0,
3901           NULL, HFILL }},
3902 
3903       { &hf_tcpip_snn_timestamp,
3904         { "Safety Network Number (Timestamp)", "cip.tcpip.snn.timestamp",
3905           FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
3906           NULL, HFILL }
3907       },
3908 
3909       { &hf_tcpip_snn_date,
3910         { "Safety Network Number (Manual) Date", "cip.tcpip.snn.date",
3911           FT_UINT16, BASE_HEX, VALS(cipsafety_snn_date_vals), 0,
3912           NULL, HFILL }
3913       },
3914 
3915       { &hf_tcpip_snn_time,
3916         { "Safety Network Number (Manual) Time", "cip.tcpip.snn.time",
3917           FT_UINT32, BASE_HEX, NULL, 0,
3918           NULL, HFILL }
3919       },
3920 
3921       { &hf_tcpip_ttl_value,
3922         { "TTL Value", "cip.tcpip.ttl_value",
3923           FT_UINT8, BASE_DEC, NULL, 0,
3924           NULL, HFILL }},
3925 
3926       { &hf_tcpip_mcast_alloc,
3927         { "Alloc Control", "cip.tcpip.mcast.alloc",
3928           FT_UINT8, BASE_DEC, VALS(enip_tcpip_mcast_alloc_vals), 0,
3929           NULL, HFILL }},
3930 
3931       { &hf_tcpip_mcast_reserved,
3932         { "Reserved", "cip.tcpip.mcast.reserved",
3933           FT_UINT8, BASE_HEX, NULL, 0,
3934           NULL, HFILL }},
3935 
3936       { &hf_tcpip_mcast_num_mcast,
3937         { "Num MCast", "cip.tcpip.mcast.num_mcast",
3938           FT_UINT16, BASE_DEC, NULL, 0,
3939           NULL, HFILL }},
3940 
3941       { &hf_tcpip_mcast_addr_start,
3942         { "MCast Start Addr", "cip.tcpip.mcast.addr_start",
3943           FT_IPv4, BASE_NONE, NULL, 0,
3944           NULL, HFILL }},
3945 
3946       { &hf_tcpip_select_acd,
3947         { "Select ACD", "cip.tcpip.select_acd",
3948           FT_BOOLEAN, BASE_NONE, TFS(&tfs_enabled_disabled), 0,
3949           NULL, HFILL }},
3950 
3951       { &hf_tcpip_lcd_acd_activity,
3952         { "ACD Activity", "cip.tcpip.last_conflict.acd_activity",
3953           FT_UINT8, BASE_DEC, VALS(enip_tcpip_acd_activity_vals), 0,
3954           NULL, HFILL }},
3955 
3956       { &hf_tcpip_lcd_remote_mac,
3957         { "RemoteMAC", "cip.tcpip.last_conflict.remote_mac",
3958           FT_ETHER, BASE_NONE, NULL, 0,
3959           NULL, HFILL }},
3960 
3961       { &hf_tcpip_lcd_arp_pdu,
3962         { "Arp PDU", "cip.tcpip.last_conflict.arp_pdu",
3963           FT_BYTES, BASE_NONE, NULL, 0,
3964           NULL, HFILL }},
3965 
3966       { &hf_tcpip_quick_connect,
3967         { "Ethernet/IP Quick Connection", "cip.tcpip.quick_connect",
3968           FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x1,
3969           NULL, HFILL }},
3970 
3971       { &hf_tcpip_encap_inactivity,
3972         { "Encapsulation Inactivity Timeout", "cip.tcpip.encap_inactivity",
3973           FT_UINT16, BASE_DEC, NULL, 0x0,
3974           NULL, HFILL }},
3975 
3976       { &hf_tcpip_port_count, { "Port Count", "cip.tcpip.port_count", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
3977       { &hf_tcpip_port_name, { "Port Name", "cip.tcpip.port_name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } },
3978       { &hf_tcpip_port_number, { "Port Number", "cip.tcpip.port_number", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
3979       { &hf_tcpip_port_protocol, { "Protocol", "cip.tcpip.protocol", FT_UINT8, BASE_DEC | BASE_EXT_STRING, &ipproto_val_ext, 0, NULL, HFILL } },
3980       { &hf_tcpip_port_admin_state, { "Admin State", "cip.tcpip.admin_state", FT_BOOLEAN, BASE_NONE, TFS(&tfs_open_closed), 0, NULL, HFILL } },
3981 
3982       { &hf_tcpip_port_admin_capability, { "Admin Capability", "cip.tcpip.admin_capability", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } },
3983       { &hf_tcpip_admin_capability_configurable, { "Configurable", "cip.tcpip.admin_capability.configurable", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x01, NULL, HFILL } },
3984       { &hf_tcpip_admin_capability_reset_required, { "Reset Required", "cip.tcpip.admin_capability.reset_required", FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x02, NULL, HFILL } },
3985       { &hf_tcpip_admin_capability_reserved, { "Reserved", "cip.tcpip.admin_capability", FT_UINT8, BASE_HEX, NULL, 0xFC, NULL, HFILL } },
3986 
3987       { &hf_elink_interface_speed,
3988         { "Interface Speed", "cip.elink.interface_speed",
3989           FT_UINT32, BASE_DEC, NULL, 0,
3990           NULL, HFILL }},
3991 
3992       { &hf_elink_interface_flags,
3993         { "Interface Flags", "cip.elink.iflags",
3994           FT_UINT32, BASE_HEX, NULL, 0,
3995           NULL, HFILL }},
3996 
3997       { &hf_elink_iflags_link_status,
3998         { "Link Status", "cip.elink.iflags.link_status",
3999           FT_BOOLEAN, 32, TFS(&tfs_active_inactive), 0x00000001,
4000           NULL, HFILL }},
4001 
4002       { &hf_elink_iflags_duplex,
4003         { "Duplex", "cip.elink.iflags.duplex",
4004           FT_UINT32, BASE_DEC, VALS(enip_elink_duplex_vals), 0x00000002,
4005           NULL, HFILL }},
4006 
4007       { &hf_elink_iflags_neg_status,
4008         { "Negotiation Status", "cip.elink.iflags.neg_status",
4009           FT_UINT32, BASE_DEC, VALS(enip_elink_iflags_neg_status_vals), 0x0000001C,
4010           NULL, HFILL }},
4011 
4012       { &hf_elink_iflags_manual_reset,
4013         { "Manual Reset Required", "cip.elink.iflags.manual_reset",
4014           FT_UINT32, BASE_DEC, VALS(enip_elink_iflags_reset_vals), 0x00000020,
4015           NULL, HFILL }},
4016 
4017       { &hf_elink_iflags_local_hw_fault,
4018         { "Local Hardware Fault", "cip.elink.iflags.local_hw_fault",
4019           FT_UINT32, BASE_DEC, VALS(enip_elink_iflags_hw_fault_vals), 0x00000040,
4020           NULL, HFILL }},
4021 
4022       { &hf_elink_iflags_reserved,
4023         { "Reserved", "cip.elink.iflags.reserved",
4024           FT_UINT32, BASE_HEX, NULL, 0xFFFFFF80,
4025           NULL, HFILL }},
4026 
4027       { &hf_elink_physical_address,
4028         { "Physical Address", "cip.elink.physical_address",
4029           FT_ETHER, BASE_NONE, NULL, 0,
4030           NULL, HFILL }},
4031 
4032       { &hf_elink_icount_in_octets,
4033         { "In Octets", "cip.elink.icount.in_octets",
4034           FT_UINT32, BASE_DEC, NULL, 0,
4035           NULL, HFILL }},
4036 
4037       { &hf_elink_icount_in_ucast,
4038         { "In Ucast Packets", "cip.elink.icount.in_ucast",
4039           FT_UINT32, BASE_DEC, NULL, 0,
4040           NULL, HFILL }},
4041 
4042       { &hf_elink_icount_in_nucast,
4043         { "In NUcast Packets", "cip.elink.icount.in_nucast",
4044           FT_UINT32, BASE_DEC, NULL, 0,
4045           NULL, HFILL }},
4046 
4047       { &hf_elink_icount_in_discards,
4048         { "In Discards", "cip.elink.icount.in_discards",
4049           FT_UINT32, BASE_DEC, NULL, 0,
4050           NULL, HFILL }},
4051 
4052       { &hf_elink_icount_in_errors,
4053         { "In Errors", "cip.elink.icount.in_errors",
4054           FT_UINT32, BASE_DEC, NULL, 0,
4055           NULL, HFILL }},
4056 
4057       { &hf_elink_icount_in_unknown_protos,
4058         { "In Unknown Protos", "cip.elink.icount.in_unknown_protos",
4059           FT_UINT32, BASE_DEC, NULL, 0,
4060           NULL, HFILL }},
4061 
4062       { &hf_elink_icount_out_octets,
4063         { "Out Octets", "cip.elink.icount.out_octets",
4064           FT_UINT32, BASE_DEC, NULL, 0,
4065           NULL, HFILL }},
4066 
4067       { &hf_elink_icount_out_ucast,
4068         { "Out Ucast Packets", "cip.elink.icount.out_ucast",
4069           FT_UINT32, BASE_DEC, NULL, 0,
4070           NULL, HFILL }},
4071 
4072       { &hf_elink_icount_out_nucast,
4073         { "Out NUcast Packets", "cip.elink.icount.out_nucast",
4074           FT_UINT32, BASE_DEC, NULL, 0,
4075           NULL, HFILL }},
4076 
4077       { &hf_elink_icount_out_discards,
4078         { "Out Discards", "cip.elink.icount.out_discards",
4079           FT_UINT32, BASE_DEC, NULL, 0,
4080           NULL, HFILL }},
4081 
4082       { &hf_elink_icount_out_errors,
4083         { "Out Errors", "cip.elink.icount.out_errors",
4084           FT_UINT32, BASE_DEC, NULL, 0,
4085           NULL, HFILL }},
4086 
4087       { &hf_elink_mcount_alignment_errors,
4088         { "Alignment Errors", "cip.elink.mcount.alignment_errors",
4089           FT_UINT32, BASE_DEC, NULL, 0,
4090           NULL, HFILL }},
4091 
4092       { &hf_elink_mcount_fcs_errors,
4093         { "FCS Errors", "cip.elink.mcount.fcs_errors",
4094           FT_UINT32, BASE_DEC, NULL, 0,
4095           NULL, HFILL }},
4096 
4097       { &hf_elink_mcount_single_collisions,
4098         { "Single Collisions", "cip.elink.mcount.single_collisions",
4099           FT_UINT32, BASE_DEC, NULL, 0,
4100           NULL, HFILL }},
4101 
4102       { &hf_elink_mcount_multiple_collisions,
4103         { "Multiple Collisions", "cip.elink.mcount.multiple_collisions",
4104           FT_UINT32, BASE_DEC, NULL, 0,
4105           NULL, HFILL }},
4106 
4107       { &hf_elink_mcount_sqe_test_errors,
4108         { "SQE Test Errors", "cip.elink.mcount.sqe_test_errors",
4109           FT_UINT32, BASE_DEC, NULL, 0,
4110           NULL, HFILL }},
4111 
4112       { &hf_elink_mcount_deferred_transmission,
4113         { "Deferred Transmission", "cip.elink.mcount.deferred_transmission",
4114           FT_UINT32, BASE_DEC, NULL, 0,
4115           NULL, HFILL }},
4116 
4117       { &hf_elink_mcount_late_collisions,
4118         { "Late Collisions", "cip.elink.mcount.late_collisions",
4119           FT_UINT32, BASE_DEC, NULL, 0,
4120           NULL, HFILL }},
4121 
4122       { &hf_elink_mcount_excessive_collisions,
4123         { "Excessive Collisions", "cip.elink.mcount.excessive_collisions",
4124           FT_UINT32, BASE_DEC, NULL, 0,
4125           NULL, HFILL }},
4126 
4127       { &hf_elink_mcount_mac_transmit_errors,
4128         { "MAC Transmit Errors", "cip.elink.mcount.mac_transmit_errors",
4129           FT_UINT32, BASE_DEC, NULL, 0,
4130           NULL, HFILL }},
4131 
4132       { &hf_elink_mcount_carrier_sense_errors,
4133         { "Carrier Sense Errors", "cip.elink.mcount.carrier_sense_errors",
4134           FT_UINT32, BASE_DEC, NULL, 0,
4135           NULL, HFILL }},
4136 
4137       { &hf_elink_mcount_frame_too_long,
4138         { "Frame Too Long", "cip.elink.mcount.frame_too_long",
4139           FT_UINT32, BASE_DEC, NULL, 0,
4140           NULL, HFILL }},
4141 
4142       { &hf_elink_mcount_mac_receive_errors,
4143         { "MAC Receive Errors", "cip.elink.mcount.mac_receive_errors",
4144           FT_UINT32, BASE_DEC, NULL, 0,
4145           NULL, HFILL }},
4146 
4147       { &hf_elink_icontrol_control_bits,
4148         { "Control Bits", "cip.elink.icontrol.control_bits",
4149           FT_UINT16, BASE_HEX, NULL, 0,
4150           NULL, HFILL }},
4151 
4152       { &hf_elink_icontrol_control_bits_auto_neg,
4153         { "Auto-negotiate", "cip.elink.icontrol.control_bits.auto_neg",
4154           FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), 0x0001,
4155           NULL, HFILL }},
4156 
4157       { &hf_elink_icontrol_control_bits_forced_duplex,
4158         { "Forced Duplex Mode", "cip.elink.icontrol.control_bits.forced_duplex",
4159           FT_UINT16, BASE_DEC, VALS(enip_elink_duplex_vals), 0x0002,
4160           NULL, HFILL }},
4161 
4162       { &hf_elink_icontrol_control_bits_reserved,
4163         { "Reserved", "cip.elink.icontrol.control_bits.reserved",
4164           FT_UINT16, BASE_HEX, NULL, 0xFFFC,
4165           NULL, HFILL }},
4166 
4167       { &hf_elink_icontrol_forced_speed,
4168         { "Forced Interface Speed", "cip.elink.icontrol.forced_speed",
4169           FT_UINT16, BASE_DEC, NULL, 0,
4170           NULL, HFILL }},
4171 
4172       { &hf_elink_icapability_capability_bits,
4173         { "Capability Bits", "cip.elink.icapability.capability_bits",
4174           FT_UINT32, BASE_HEX, NULL, 0,
4175           NULL, HFILL }},
4176 
4177       { &hf_elink_icapability_capability_bits_manual,
4178         { "Manual Setting Requires Reset", "cip.elink.icapability.capability_bits.manual",
4179           FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x0001,
4180           NULL, HFILL }},
4181 
4182       { &hf_elink_icapability_capability_bits_auto_neg,
4183         { "Auto-negotiate", "cip.elink.icapability.capability_bits.auto_neg",
4184           FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x0002,
4185           NULL, HFILL }},
4186 
4187       { &hf_elink_icapability_capability_bits_auto_mdix,
4188         { "Auto-MDIX", "cip.elink.icapability.capability_bits.auto_mdix",
4189           FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x0004,
4190           NULL, HFILL } },
4191 
4192       { &hf_elink_icapability_capability_bits_manual_speed,
4193         { "Manual Speed/Duplex", "cip.elink.icapability.capability_bits.manual_speed",
4194           FT_BOOLEAN, 32, TFS(&tfs_enabled_disabled), 0x0008,
4195           NULL, HFILL } },
4196 
4197       { &hf_elink_icapability_capability_speed_duplex_array_count,
4198         { "Speed/Duplex Array Count", "cip.elink.icapability.array_count",
4199           FT_UINT8, BASE_DEC, NULL, 0,
4200           NULL, HFILL } },
4201 
4202       { &hf_elink_icapability_capability_speed,
4203         { "Interface Speed", "cip.elink.icapability.speed",
4204           FT_UINT16, BASE_DEC, NULL, 0,
4205           NULL, HFILL } },
4206 
4207       { &hf_elink_icapability_capability_duplex,
4208         { "Interface Duplex Mode", "cip.elink.icapability.duplex",
4209           FT_UINT8, BASE_DEC, VALS(enip_elink_duplex_vals), 0,
4210           NULL, HFILL } },
4211 
4212       { &hf_elink_interface_type,
4213         { "Interface Type", "cip.elink.interface_type",
4214           FT_UINT8, BASE_DEC, VALS(enip_elink_interface_type_vals), 0,
4215           NULL, HFILL }},
4216 
4217       { &hf_elink_interface_state,
4218         { "Interface State", "cip.elink.interface_state",
4219           FT_UINT8, BASE_DEC, VALS(enip_elink_interface_state_vals), 0,
4220           NULL, HFILL }},
4221 
4222       { &hf_elink_admin_state,
4223         { "Admin State", "cip.elink.admin_state",
4224           FT_UINT8, BASE_DEC, VALS(enip_elink_admin_state_vals), 0,
4225           NULL, HFILL }},
4226 
4227       { &hf_elink_interface_label,
4228         { "Interface Label", "cip.elink.interface_label",
4229           FT_STRING, BASE_NONE, NULL, 0,
4230           NULL, HFILL }},
4231 
4232       { &hf_elink_hc_icount_in_octets,
4233         { "In Octets", "cip.elink.hc_icount.in_octets",
4234           FT_UINT64, BASE_DEC, NULL, 0,
4235           NULL, HFILL } },
4236 
4237       { &hf_elink_hc_icount_in_ucast,
4238         { "In Ucast Packets", "cip.elink.hc_icount.in_ucast",
4239           FT_UINT64, BASE_DEC, NULL, 0,
4240           NULL, HFILL } },
4241 
4242       { &hf_elink_hc_icount_in_mcast,
4243         { "In Multicast Packets", "cip.elink.hc_icount.in_mcast",
4244           FT_UINT64, BASE_DEC, NULL, 0,
4245           NULL, HFILL } },
4246 
4247       { &hf_elink_hc_icount_in_broadcast,
4248         { "In Broadcast", "cip.elink.hc_icount.in_broadcast",
4249           FT_UINT64, BASE_DEC, NULL, 0,
4250           NULL, HFILL } },
4251 
4252       { &hf_elink_hc_icount_out_octets,
4253         { "Out Octets", "cip.elink.hc_icount.out_octets",
4254           FT_UINT64, BASE_DEC, NULL, 0,
4255           NULL, HFILL } },
4256 
4257       { &hf_elink_hc_icount_out_ucast,
4258         { "Out Ucast Packets", "cip.elink.hc_icount.out_ucast",
4259           FT_UINT64, BASE_DEC, NULL, 0,
4260           NULL, HFILL } },
4261 
4262       { &hf_elink_hc_icount_out_mcast,
4263         { "Out Multicast Packets", "cip.elink.hc_icount.out_mcast",
4264           FT_UINT64, BASE_DEC, NULL, 0,
4265           NULL, HFILL } },
4266 
4267       { &hf_elink_hc_icount_out_broadcast,
4268         { "Out Broadcast Packets", "cip.elink.hc_icount.out_broadcast",
4269           FT_UINT64, BASE_DEC, NULL, 0,
4270           NULL, HFILL } },
4271 
4272       { &hf_elink_hc_mcount_stats_align_errors,
4273         { "Stats Alignment Errors", "cip.elink.hc_mcount.stats_align_errors",
4274           FT_UINT64, BASE_DEC, NULL, 0,
4275           NULL, HFILL } },
4276 
4277       { &hf_elink_hc_mcount_stats_fcs_errors,
4278         { "Stats FCS Errors", "cip.elink.hc_mcount.stats_fcs_errors",
4279           FT_UINT64, BASE_DEC, NULL, 0,
4280           NULL, HFILL } },
4281 
4282       { &hf_elink_hc_mcount_stats_internal_mac_transmit_errors,
4283         { "Stats Internal MAC Transmit Errors", "cip.elink.hc_mcount.internal_mac_transmit_errors",
4284           FT_UINT64, BASE_DEC, NULL, 0,
4285           NULL, HFILL } },
4286 
4287       { &hf_elink_hc_mcount_stats_frame_too_long,
4288         { "Stats Frame Too Long", "cip.elink.hc_mcount.stats_frame_too_long",
4289           FT_UINT64, BASE_DEC, NULL, 0,
4290           NULL, HFILL } },
4291 
4292       { &hf_elink_hc_mcount_stats_internal_mac_receive_errors,
4293         { "Stats Internal MAC Receive Errors", "cip.elink.hc_mcount.internal_mac_receive_errors",
4294           FT_UINT64, BASE_DEC, NULL, 0,
4295           NULL, HFILL } },
4296 
4297       { &hf_elink_hc_mcount_stats_symbol_errors,
4298         { "Stats Symbol Errors", "cip.elink.hc_mcount.stats_symbol_errors",
4299           FT_UINT64, BASE_DEC, NULL, 0,
4300           NULL, HFILL } },
4301 
4302       { &hf_qos_8021q_enable,
4303         { "802.1Q Tag Enable", "cip.qos.8021q_enable",
4304           FT_BOOLEAN, 8, TFS(&tfs_enabled_disabled), 0x1,
4305           NULL, HFILL }},
4306 
4307       { &hf_qos_dscp_ptp_event,
4308         { "DSCP PTP Event", "cip.qos.ptp_event",
4309           FT_UINT8, BASE_DEC, NULL, 0,
4310           NULL, HFILL }},
4311 
4312       { &hf_qos_dscp_ptp_general,
4313         { "DSCP PTP General", "cip.qos.ptp_general",
4314           FT_UINT8, BASE_DEC, NULL, 0,
4315           NULL, HFILL }},
4316 
4317       { &hf_qos_dscp_urgent,
4318         { "DSCP Urgent", "cip.qos.urgent",
4319           FT_UINT8, BASE_DEC, NULL, 0,
4320           NULL, HFILL }},
4321 
4322       { &hf_qos_dscp_scheduled,
4323         { "DSCP Scheduled", "cip.qos.scheduled",
4324           FT_UINT8, BASE_DEC, NULL, 0,
4325           NULL, HFILL }},
4326 
4327       { &hf_qos_dscp_high,
4328         { "DSCP High", "cip.qos.high",
4329           FT_UINT8, BASE_DEC, NULL, 0,
4330           NULL, HFILL }},
4331 
4332       { &hf_qos_dscp_low,
4333         { "DSCP Low", "cip.qos.low",
4334           FT_UINT8, BASE_DEC, NULL, 0,
4335           NULL, HFILL }},
4336 
4337       { &hf_qos_dscp_explicit,
4338         { "DSCP Explicit", "cip.qos.explicit",
4339           FT_UINT8, BASE_DEC, NULL, 0,
4340           NULL, HFILL }},
4341 
4342       { &hf_dlr_network_topology,
4343         { "Network Topology", "cip.dlr.network_topology",
4344           FT_UINT8, BASE_DEC, VALS(enip_dlr_network_topology_vals), 0,
4345           NULL, HFILL }},
4346 
4347       { &hf_dlr_network_status,
4348         { "Network Status", "cip.dlr.network_status",
4349           FT_UINT8, BASE_DEC, VALS(enip_dlr_network_status_vals), 0,
4350           NULL, HFILL }},
4351 
4352       { &hf_dlr_ring_supervisor_status,
4353         { "Ring Supervisor Status", "cip.dlr.ring_supervisor_status",
4354           FT_UINT8, BASE_DEC, VALS(enip_dlr_ring_supervisor_status_vals), 0,
4355           NULL, HFILL }},
4356 
4357       { &hf_dlr_rsc_ring_supervisor_enable,
4358         { "Ring Supervisor Enable", "cip.dlr.rscconfig.supervisor_enable",
4359           FT_BOOLEAN, 8, TFS(&tfs_true_false), 0,
4360           NULL, HFILL }},
4361 
4362       { &hf_dlr_rsc_ring_supervisor_precedence,
4363         { "Ring Supervisor Precedence", "cip.dlr.rscconfig.supervisor_precedence",
4364           FT_UINT8, BASE_DEC, NULL, 0,
4365           NULL, HFILL }},
4366 
4367       { &hf_dlr_rsc_beacon_interval,
4368         { "Beacon Interval", "cip.dlr.rscconfig.beacon_interval",
4369           FT_UINT32, BASE_DEC, NULL, 0,
4370           NULL, HFILL }},
4371 
4372       { &hf_dlr_rsc_beacon_timeout,
4373         { "Beacon Timeout", "cip.dlr.rscconfig.beacon_timeout",
4374           FT_UINT32, BASE_DEC, NULL, 0,
4375           NULL, HFILL }},
4376 
4377       { &hf_dlr_rsc_dlr_vlan_id,
4378         { "DLR VLAN ID", "cip.dlr.rscconfig.dlr_vlan_id",
4379           FT_UINT16, BASE_DEC, NULL, 0,
4380           NULL, HFILL }},
4381 
4382       { &hf_dlr_ring_faults_count,
4383         { "Ring Faults Count", "cip.dlr.ring_faults_count",
4384           FT_UINT16, BASE_DEC, NULL, 0,
4385           NULL, HFILL }},
4386 
4387       { &hf_dlr_lanp1_dev_ip_addr,
4388         { "Device IP Address", "cip.dlr.lanp1.ip_addr",
4389           FT_IPv4, BASE_NONE, NULL, 0,
4390           NULL, HFILL }},
4391 
4392       { &hf_dlr_lanp1_dev_physical_address,
4393         { "Device Physical Address", "cip.dlr.lanp1.physical_address",
4394           FT_ETHER, BASE_NONE, NULL, 0,
4395           NULL, HFILL }},
4396 
4397       { &hf_dlr_lanp2_dev_ip_addr,
4398         { "Device IP Address", "cip.dlr.lanp2.ip_addr",
4399           FT_IPv4, BASE_NONE, NULL, 0,
4400           NULL, HFILL }},
4401 
4402       { &hf_dlr_lanp2_dev_physical_address,
4403         { "Device Physical Address", "cip.dlr.lanp2.physical_address",
4404           FT_ETHER, BASE_NONE, NULL, 0,
4405           NULL, HFILL }},
4406 
4407       { &hf_dlr_ring_protocol_participants_count,
4408         { "Participants Count", "cip.dlr.participants_count",
4409           FT_UINT16, BASE_DEC, NULL, 0,
4410           NULL, HFILL }},
4411 
4412       { &hf_dlr_rppl_dev_ip_addr,
4413         { "Device IP Address", "cip.dlr.rppl.ip_addr",
4414           FT_IPv4, BASE_NONE, NULL, 0,
4415           NULL, HFILL }},
4416 
4417       { &hf_dlr_rppl_dev_physical_address,
4418         { "Device Physical Address", "cip.dlr.rppl.physical_address",
4419           FT_ETHER, BASE_NONE, NULL, 0,
4420           NULL, HFILL }},
4421 
4422       { &hf_dlr_asa_supervisor_ip_addr,
4423         { "Supervisor IP Address", "cip.dlr.asa.ip_addr",
4424           FT_IPv4, BASE_NONE, NULL, 0,
4425           NULL, HFILL }},
4426 
4427       { &hf_dlr_asa_supervisor_physical_address,
4428         { "Supervisor Physical Address", "cip.dlr.asa.physical_address",
4429           FT_ETHER, BASE_NONE, NULL, 0,
4430           NULL, HFILL }},
4431 
4432       { &hf_dlr_active_supervisor_precedence,
4433         { "Active Supervisor Precedence", "cip.dlr.supervisor_precedence",
4434           FT_UINT8, BASE_DEC, NULL, 0,
4435           NULL, HFILL }},
4436 
4437       { &hf_dlr_capability_flags,
4438         { "Capability Flags", "cip.dlr.capflags",
4439           FT_UINT32, BASE_HEX, NULL, 0,
4440           NULL, HFILL }},
4441 
4442       { &hf_dlr_capflags_announce_base_node,
4443         { "Announce-based Ring Node", "cip.dlr.capflags.announce_based",
4444           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000001,
4445           NULL, HFILL }},
4446 
4447       { &hf_dlr_capflags_beacon_base_node,
4448         { "Beacon-based Ring Node", "cip.dlr.capflags.beacon_based",
4449           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000002,
4450           NULL, HFILL }},
4451 
4452       { &hf_dlr_capflags_reserved1,
4453         { "Reserved", "cip.dlr.capflags.reserved1",
4454           FT_BOOLEAN, 32, NULL, 0x0000001C,
4455           NULL, HFILL }},
4456 
4457       { &hf_dlr_capflags_supervisor_capable,
4458         { "Supervisor Capable", "cip.dlr.capflags.supervisor_capable",
4459           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000020,
4460           NULL, HFILL }},
4461 
4462       { &hf_dlr_capflags_redundant_gateway_capable,
4463         { "Redundant Gateway Capable", "cip.dlr.capflags.redundant_gateway_capable",
4464           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000040,
4465           NULL, HFILL }},
4466 
4467       { &hf_dlr_capflags_flush_frame_capable,
4468         { "Flush_Table Frame Capable", "cip.dlr.capflags.flush_frame_capable",
4469           FT_BOOLEAN, 32, TFS(&tfs_true_false), 0x00000080,
4470           NULL, HFILL }},
4471 
4472       { &hf_dlr_capflags_reserved2,
4473         { "Reserved", "cip.dlr.capflags.reserved2",
4474           FT_BOOLEAN, 32, NULL, 0xFFFFFF00,
4475           NULL, HFILL }},
4476 
4477       { &hf_dlr_rgc_red_gateway_enable,
4478         { "Redundant Gateway Enable", "cip.dlr.rgc.gateway_enable",
4479           FT_BOOLEAN, 8, TFS(&tfs_true_false), 0,
4480           NULL, HFILL }},
4481 
4482       { &hf_dlr_rgc_gateway_precedence,
4483         { "Gateway Precedence", "cip.dlr.rgc.gateway_precedence",
4484           FT_UINT8, BASE_DEC, NULL, 0,
4485           NULL, HFILL }},
4486 
4487       { &hf_dlr_rgc_advertise_interval,
4488         { "Advertise Interval", "cip.dlr.rgc.advertise_interval",
4489           FT_UINT32, BASE_DEC, NULL, 0,
4490           NULL, HFILL }},
4491 
4492       { &hf_dlr_rgc_advertise_timeout,
4493         { "Advertise Timeout", "cip.dlr.rgc.advertise_timeout",
4494           FT_UINT32, BASE_DEC, NULL, 0,
4495           NULL, HFILL }},
4496 
4497       { &hf_dlr_rgc_learning_update_enable,
4498         { "Learning Update Enable", "cip.dlr.rgc.learning_update_enable",
4499           FT_BOOLEAN, 8, TFS(&tfs_true_false), 0,
4500           NULL, HFILL }},
4501 
4502       { &hf_dlr_redundant_gateway_status,
4503         { "Redundant Gateway Status", "cip.dlr.redundant_gateway_status",
4504           FT_UINT8, BASE_DEC, VALS(enip_dlr_redundant_gateway_status_vals), 0,
4505           NULL, HFILL }},
4506 
4507       { &hf_dlr_aga_ip_addr,
4508         { "Active Gateway IP Address", "cip.dlr.aga.ip_addr",
4509           FT_IPv4, BASE_NONE, NULL, 0,
4510           NULL, HFILL }},
4511 
4512       { &hf_dlr_aga_physical_address,
4513         { "Active Gateway Physical Address", "cip.dlr.aga.physical_address",
4514           FT_ETHER, BASE_NONE, NULL, 0,
4515           NULL, HFILL }},
4516 
4517       { &hf_dlr_active_gateway_precedence,
4518         { "Active Gateway Precedence", "cip.dlr.active_gateway_precedence",
4519           FT_UINT8, BASE_DEC, NULL, 0,
4520           NULL, HFILL }},
4521 
4522       { &hf_cip_security_state, { "State", "cip.security.state", FT_UINT8, BASE_DEC, VALS(cip_security_state_vals), 0, NULL, HFILL } },
4523 
4524       { &hf_eip_security_state,
4525         { "State", "cip.eip_security.state",
4526           FT_UINT8, BASE_DEC, VALS(eip_security_state_vals), 0,
4527           NULL, HFILL }},
4528 
4529       { &hf_eip_security_verify_client_cert,
4530         { "Verify Client Certificate", "cip.eip_security.verify_client_cert",
4531           FT_BOOLEAN, 8, NULL, 0,
4532           NULL, HFILL }},
4533 
4534       { &hf_eip_security_send_cert_chain,
4535         { "Send Certificate Chain", "cip.eip_security.send_cert_chain",
4536           FT_BOOLEAN, 8, NULL, 0,
4537           NULL, HFILL }},
4538 
4539       { &hf_eip_security_check_expiration,
4540         { "Check Expiration", "cip.eip_security.check_expiration",
4541           FT_BOOLEAN, 8, NULL, 0,
4542           NULL, HFILL }},
4543 
4544       { &hf_eip_security_capability_flags,
4545         { "Capability Flags", "cip.eip_security.capability_flags",
4546           FT_UINT32, BASE_HEX, NULL, 0,
4547           NULL, HFILL }},
4548 
4549       { &hf_eip_security_capflags_secure_renegotiation,
4550         { "Secure Renegotiation", "cip.eip_security.capability_flags.secure_renegotiation",
4551           FT_BOOLEAN, 32, TFS(&tfs_supported_not_supported), 0x00000001,
4552           NULL, HFILL }},
4553 
4554       { &hf_eip_security_capflags_reserved,
4555         { "Reserved", "cip.eip_security.capability_flags.reserved",
4556           FT_UINT32, BASE_HEX, NULL, 0xFFFFFFFE,
4557           NULL, HFILL }},
4558 
4559       { &hf_eip_security_num_avail_cipher_suites,
4560         { "Number of Available Cipher Suites", "cip.eip_security.num_avail_cipher_suites",
4561           FT_UINT8, BASE_DEC, NULL, 0,
4562           NULL, HFILL }},
4563 
4564       { &hf_eip_security_avail_cipher_suite,
4565         { "Available Cipher Suite", "cip.eip_security.avail_cipher_suite",
4566           FT_UINT16, BASE_HEX|BASE_EXT_STRING, &ssl_31_ciphersuite_ext, 0,
4567           NULL, HFILL }},
4568 
4569       { &hf_eip_security_num_allow_cipher_suites,
4570         { "Number of Allowed Cipher Suites", "cip.eip_security.num_allow_cipher_suites",
4571           FT_UINT8, BASE_DEC, NULL, 0,
4572           NULL, HFILL }},
4573 
4574       { &hf_eip_security_allow_cipher_suite,
4575         { "Allowed Cipher Suite", "cip.eip_security.allow_cipher_suite",
4576           FT_UINT16, BASE_HEX|BASE_EXT_STRING, &ssl_31_ciphersuite_ext, 0,
4577           NULL, HFILL }},
4578 
4579       { &hf_eip_security_num_psk,
4580         { "Number of PSKs", "cip.eip_security.num_psk",
4581           FT_UINT8, BASE_DEC, NULL, 0,
4582           NULL, HFILL }},
4583 
4584       { &hf_eip_security_psk_identity_size,
4585         { "PSK Identity Size", "cip.eip_security.psk_identity_size",
4586           FT_UINT8, BASE_DEC, NULL, 0,
4587           NULL, HFILL }},
4588 
4589       { &hf_eip_security_psk_identity,
4590         { "PSK Identity", "cip.eip_security.psk_identity",
4591           FT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0,
4592           NULL, HFILL }},
4593 
4594       { &hf_eip_security_psk_size,
4595         { "PSK Size", "cip.eip_security.psk_size",
4596           FT_UINT8, BASE_DEC, NULL, 0,
4597           NULL, HFILL }},
4598 
4599       { &hf_eip_security_psk,
4600         { "PSK", "cip.eip_security.psk",
4601           FT_BYTES, BASE_NONE|BASE_ALLOW_ZERO, NULL, 0,
4602           NULL, HFILL }},
4603 
4604       { &hf_eip_security_num_active_certs,
4605         { "Number of Active Certificates", "cip.eip_security.num_active_certs",
4606           FT_UINT8, BASE_DEC, NULL, 0,
4607           NULL, HFILL }},
4608 
4609       { &hf_eip_security_num_trusted_auths,
4610         { "Number of Trusted Authorities", "cip.eip_security.num_trusted_auths",
4611           FT_UINT8, BASE_DEC, NULL, 0,
4612           NULL, HFILL }},
4613 
4614       { &hf_eip_cert_name,
4615         { "Name", "cip.eip_cert.name",
4616           FT_STRING, BASE_NONE, NULL, 0,
4617           NULL, HFILL }},
4618 
4619       { &hf_eip_cert_state,
4620         { "State", "cip.eip_cert.state",
4621           FT_UINT8, BASE_DEC, VALS(eip_cert_state_vals), 0,
4622           NULL, HFILL }},
4623 
4624       { &hf_eip_cert_encoding,
4625         { "Certificate Encoding", "cip.eip_cert.encoding",
4626           FT_UINT8, BASE_DEC, NULL, 0,
4627           NULL, HFILL } },
4628 
4629       { &hf_eip_cert_device_cert_status,
4630         { "Certificate Status", "cip.eip_cert.device_cert.status",
4631           FT_UINT8, BASE_DEC, VALS(eip_cert_status_vals), 0,
4632           NULL, HFILL }},
4633 
4634       { &hf_eip_cert_ca_cert_status,
4635         { "Certificate Status", "cip.eip_cert.ca_cert.status",
4636           FT_UINT8, BASE_DEC, VALS(eip_cert_status_vals), 0,
4637           NULL, HFILL }},
4638 
4639       { &hf_eip_cert_capflags_push,
4640         { "Push", "cip.eip_cert.capflags.push",
4641           FT_BOOLEAN, 32, NULL, 0x00000001,
4642           NULL, HFILL }},
4643 
4644       { &hf_eip_cert_capflags_reserved,
4645         { "Reserved", "cip.eip_cert.capflags.reserved",
4646           FT_BOOLEAN, 32, NULL, 0xFFFFFFFE,
4647           NULL, HFILL }},
4648 
4649       { &hf_eip_cert_capability_flags,
4650         { "Capability flags", "cip.eip_cert.capflags",
4651           FT_UINT32, BASE_HEX, NULL, 0,
4652           NULL, HFILL }},
4653 
4654       { &hf_eip_cert_num_certs,
4655         { "Number of Certificates", "cip.eip_cert.num_certs",
4656           FT_UINT8, BASE_DEC, NULL, 0,
4657           NULL, HFILL }},
4658 
4659       { &hf_eip_cert_cert_name,
4660         { "Certificate name", "cip.eip_cert.cert_name",
4661           FT_STRING, BASE_NONE, NULL, 0,
4662           NULL, HFILL }},
4663    };
4664 
4665    /* Setup protocol subtree array */
4666    static gint *ett[] = {
4667       &ett_enip,
4668       &ett_cip_io_generic,
4669       &ett_path,
4670       &ett_count_tree,
4671       &ett_type_tree,
4672       &ett_command_tree,
4673       &ett_sockadd,
4674       &ett_lsrcf,
4675       &ett_tcpip_status,
4676       &ett_tcpip_admin_capability,
4677       &ett_tcpip_config_cap,
4678       &ett_tcpip_config_control,
4679       &ett_elink_interface_flags,
4680       &ett_elink_icontrol_bits,
4681       &ett_elink_icapability_bits,
4682       &ett_dlr_capability_flags,
4683       &ett_dlr_lnknbrstatus_flags,
4684       &ett_eip_security_capability_flags,
4685       &ett_eip_security_psk,
4686       &ett_eip_security_active_certs,
4687       &ett_eip_security_trusted_auths,
4688       &ett_eip_cert_capability_flags,
4689       &ett_eip_cert_num_certs,
4690       &ett_security_profiles,
4691       &ett_iana_port_state_flags,
4692       &ett_connection_info,
4693       &ett_connection_path_info,
4694       &ett_cmd_data
4695    };
4696 
4697    static ei_register_info ei[] = {
4698       { &ei_mal_tcpip_status, { "cip.malformed.tcpip.status", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Status", EXPFILL }},
4699       { &ei_mal_tcpip_config_cap, { "cip.malformed.tcpip.config_cap", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Configuration Capability", EXPFILL }},
4700       { &ei_mal_tcpip_config_control, { "cip.malformed.tcpip.config_control", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Configuration Control", EXPFILL }},
4701       { &ei_mal_tcpip_interface_config, { "cip.malformed.tcpip.interface_config", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Interface Configuration", EXPFILL }},
4702       { &ei_mal_tcpip_snn, { "cip.malformed.tcpip.snn", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Object Safety Network Number", EXPFILL }},
4703       { &ei_mal_tcpip_mcast_config, { "cip.malformed.tcpip.mcast_config", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Multicast Config", EXPFILL }},
4704       { &ei_mal_tcpip_last_conflict, { "cip.malformed.tcpip.last_conflict", PI_MALFORMED, PI_ERROR, "Malformed TCP/IP Last Conflict Detected", EXPFILL }},
4705       { &ei_mal_elink_interface_flags, { "cip.malformed.elink.interface_flags", PI_MALFORMED, PI_ERROR, "Malformed Ethernet Link Interface Flags", EXPFILL }},
4706       { &ei_mal_elink_physical_address, { "cip.malformed.elink.physical_address", PI_MALFORMED, PI_ERROR, "Malformed Ethernet Link Physical Address", EXPFILL } },
4707       { &ei_mal_elink_interface_counters, { "cip.malformed.elink.interface_counters", PI_MALFORMED, PI_ERROR, "Malformed Ethernet Link Interface Counters", EXPFILL }},
4708       { &ei_mal_elink_media_counters, { "cip.malformed.elink.media_counters", PI_MALFORMED, PI_ERROR, "Malformed Ethernet Link Media Counters", EXPFILL }},
4709       { &ei_mal_elink_interface_control, { "cip.malformed.elink.interface_control", PI_MALFORMED, PI_ERROR, "Malformed Ethernet Link Interface Control", EXPFILL }},
4710       { &ei_mal_dlr_ring_supervisor_config, { "cip.malformed.dlr.ring_supervisor_config", PI_MALFORMED, PI_ERROR, "Malformed DLR Ring Supervisor Config", EXPFILL }},
4711       { &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 }},
4712       { &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 }},
4713       { &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 }},
4714       { &ei_mal_dlr_active_supervisor_address, { "cip.malformed.dlr.active_supervisor_address", PI_MALFORMED, PI_ERROR, "Malformed DLR Active Supervisor Address", EXPFILL }},
4715       { &ei_mal_dlr_capability_flags, { "cip.malformed.dlr.capability_flags", PI_MALFORMED, PI_ERROR, "Malformed DLR Capability Flag", EXPFILL }},
4716       { &ei_mal_dlr_redundant_gateway_config, { "cip.malformed.dlr.redundant_gateway_config", PI_MALFORMED, PI_ERROR, "Malformed DLR Redundant Gateway Config", EXPFILL }},
4717       { &ei_mal_dlr_active_gateway_address, { "cip.malformed.dlr.active_gateway_address", PI_MALFORMED, PI_ERROR, "Malformed DLR Active Gateway Address", EXPFILL }},
4718       { &ei_mal_eip_security_capability_flags, { "cip.malformed.eip_security.capability_flags", PI_MALFORMED, PI_ERROR, "Malformed EIP Security Capability Flags", EXPFILL }},
4719       { &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 }},
4720       { &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 }},
4721       { &ei_mal_eip_security_preshared_keys, { "cip.malformed.eip_security.preshared_keys", PI_MALFORMED, PI_ERROR, "Malformed EIP Security Pre-Shared Keys", EXPFILL }},
4722       { &ei_mal_eip_security_active_certs, { "cip.malformed.eip_security.active_certs", PI_MALFORMED, PI_ERROR, "Malformed EIP Security Active Device Certificates", EXPFILL }},
4723       { &ei_mal_eip_security_trusted_auths, { "cip.malformed.eip_security.trusted_auths", PI_MALFORMED, PI_ERROR, "Malformed EIP Security Trusted Authorities", EXPFILL }},
4724       { &ei_mal_eip_cert_capability_flags, { "cip.malformed.eip_cert.capability_flags", PI_MALFORMED, PI_ERROR, "Malformed EIP Certificate Management Capability Flags", EXPFILL }},
4725       { &ei_mal_cpf_item_length_mismatch, { "enip.malformed.cpf_item_length_mismatch", PI_MALFORMED, PI_ERROR, "CPF Item Length Mismatch", EXPFILL } },
4726       { &ei_mal_cpf_item_minimum_size, { "enip.malformed.cpf_item_minimum_size", PI_MALFORMED, PI_ERROR, "CPF Item Minimum Size is 4", EXPFILL } },
4727    };
4728 
4729    /* Setup list of header fields for DLR  See Section 1.6.1 for details*/
4730    static hf_register_info hfdlr[] = {
4731       /* Ring Sub-type */
4732       { &hf_dlr_ringsubtype,
4733         { "Ring Sub-Type", "enip.dlr.ringsubtype",
4734           FT_UINT8, BASE_HEX, NULL, 0,
4735           NULL, HFILL }
4736       },
4737       /* Ring Protocol Version */
4738       { &hf_dlr_ringprotoversion,
4739         { "Ring Protocol Version", "enip.dlr.protversion",
4740           FT_UINT8, BASE_DEC, NULL, 0,
4741           NULL, HFILL }
4742       },
4743       /* Frame Type */
4744       { &hf_dlr_frametype,
4745         { "Frame Type", "enip.dlr.frametype",
4746           FT_UINT8, BASE_HEX, VALS(dlr_frame_type_vals), 0,
4747           NULL, HFILL }
4748       },
4749       /* Source Port */
4750       { &hf_dlr_sourceport,
4751         { "Source Port", "enip.dlr.sourceport",
4752           FT_UINT8, BASE_HEX, VALS(dlr_source_port_vals), 0,
4753           NULL, HFILL }
4754       },
4755       /* Source IP Address */
4756       { &hf_dlr_sourceip,
4757         { "Source IP", "enip.dlr.sourceip",
4758           FT_IPv4, BASE_NONE, NULL, 0,
4759           "Source IP Address", HFILL }
4760       },
4761       /* Sequence ID*/
4762       { &hf_dlr_sequenceid,
4763         { "Sequence Id", "enip.dlr.seqid",
4764           FT_UINT32, BASE_HEX, NULL, 0,
4765           NULL, HFILL }
4766       },
4767       /* Ring State */
4768       { &hf_dlr_ringstate,
4769         { "Ring State", "enip.dlr.state",
4770           FT_UINT8, BASE_HEX, VALS(dlr_ring_state_vals), 0,
4771           NULL, HFILL }
4772       },
4773       /* Supervisor Precedence */
4774       { &hf_dlr_supervisorprecedence,
4775         { "Supervisor Precedence", "enip.dlr.supervisorprecedence",
4776           FT_UINT8, BASE_DEC, NULL, 0,
4777           NULL, HFILL }
4778       },
4779       /* Beacon Interval */
4780       { &hf_dlr_beaconinterval,
4781         { "Beacon Interval", "enip.dlr.beaconinterval",
4782           FT_UINT32, BASE_DEC, NULL, 0,
4783           NULL, HFILL }
4784       },
4785       /* Beacon Timeout */
4786       { &hf_dlr_beacontimeout,
4787         { "Beacon Timeout", "enip.dlr.beacontimeout",
4788           FT_UINT32, BASE_DEC|BASE_UNIT_STRING, &units_microseconds, 0,
4789           NULL, HFILL }
4790       },
4791       /* Beacon Reserved */
4792       { &hf_dlr_beaconreserved,
4793         { "Reserved", "enip.dlr.beaconreserved",
4794           FT_BYTES, BASE_NONE, NULL, 0,
4795           "Beacon Reserved", HFILL }
4796       },
4797       /* Neighbor_Check_Request Reserved */
4798       { &hf_dlr_nreqreserved,
4799         { "Reserved", "enip.dlr.nreqreserved",
4800           FT_BYTES, BASE_NONE, NULL, 0,
4801           "Neighbor_Check_Request Reserved", HFILL }
4802       },
4803       /* Neighbor_Check_Response Source Port */
4804       { &hf_dlr_nressourceport,
4805         { "Request Source Port", "enip.dlr.nressourceport",
4806           FT_UINT8, BASE_HEX, VALS(dlr_source_port_vals), 0,
4807           "Neighbor_Check_Response Source Port", HFILL }
4808       },
4809       /* Neighbor_Check_Response Reserved */
4810       { &hf_dlr_nresreserved,
4811         { "Reserved", "enip.dlr.nresreserved",
4812           FT_BYTES, BASE_NONE, NULL, 0,
4813           "Neighbor_Check_Response Reserved", HFILL }
4814       },
4815       /* Link_Status/Neighbor_Status Status */
4816       { &hf_dlr_lnknbrstatus,
4817         { "Link/Neighbor Status", "enip.dlr.lnknbrstatus.status",
4818           FT_UINT8, BASE_HEX, NULL, 0,
4819           "Link_Status/Neighbor_Status Status", HFILL }
4820       },
4821       { &hf_dlr_lnknbrstatus_port1,
4822         { "Port 1 Active", "enip.dlr.lnknbrstatus.port1",
4823           FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x01,
4824           NULL, HFILL }
4825       },
4826       { &hf_dlr_lnknbrstatus_port2,
4827         { "Port 2 Active", "enip.dlr.lnknbrstatus.port2",
4828           FT_BOOLEAN, 8, TFS(&tfs_true_false), 0x02,
4829           NULL, HFILL }
4830       },
4831       { &hf_dlr_lnknbrstatus_reserved,
4832         { "Reserved", "enip.dlr.lnknbrstatus.reserved",
4833           FT_BOOLEAN, 8, NULL, 0x7C,
4834           NULL, HFILL }
4835       },
4836       { &hf_dlr_lnknbrstatus_frame_type,
4837         { "Link/Neighbor Status Frame Type", "enip.dlr.lnknbrstatus.frame_type",
4838           FT_BOOLEAN, 8, TFS(&dlr_lnknbrstatus_frame_type_vals), 0x80,
4839           NULL, HFILL }
4840       },
4841       /* Link_Status/Neighbor_Status Reserved */
4842       { &hf_dlr_lnknbrreserved,
4843         { "Reserved", "enip.dlr.lnknbrreserved",
4844           FT_BYTES, BASE_NONE, NULL, 0,
4845           "Link_Status/Neighbor_Status Reserved", HFILL }
4846       },
4847       /* Locate_Fault Reserved */
4848       { &hf_dlr_lfreserved,
4849         { "Reserved", "enip.dlr.lfreserved",
4850           FT_BYTES, BASE_NONE, NULL, 0,
4851           "Locate_Fault Reserved", HFILL }
4852       },
4853       /* Announce Reserved */
4854       { &hf_dlr_anreserved,
4855         { "Reserved", "enip.dlr.anreserved",
4856           FT_BYTES, BASE_NONE, NULL, 0,
4857           "Announce Reserved", HFILL }
4858       },
4859       /* Number of Nodes in List */
4860       { &hf_dlr_sonumnodes,
4861         { "Num nodes", "enip.dlr.sonumnodes",
4862           FT_UINT16, BASE_DEC, NULL, 0,
4863           "Number of Nodes in List", HFILL }
4864       },
4865       /* Sign_On Node # MAC Address */
4866       { &hf_dlr_somac,
4867         { "MAC Address", "enip.dlr.somac",
4868           FT_ETHER, BASE_NONE, NULL, 0,
4869           "Sign_On Node MAC Address", HFILL }
4870       },
4871       /*  Node # IP Address */
4872       { &hf_dlr_soip,
4873         { "IP Address", "enip.dlr.soip",
4874           FT_IPv4, BASE_NONE, NULL, 0,
4875           "Sign_On Node IP Address", HFILL }
4876       },
4877       /* Sign_On Reserved */
4878       { &hf_dlr_soreserved,
4879         { "Reserved", "enip.dlr.soreserved",
4880           FT_BYTES, BASE_NONE, NULL, 0,
4881           "Sign_On Reserved", HFILL }
4882       },
4883       /* Gateway State */
4884       { &hf_dlr_advgatewaystate,
4885         { "Gateway Status", "enip.dlr.advgatewaystate",
4886           FT_UINT8, BASE_HEX, VALS(dlr_adv_state_vals), 0,
4887           "Gateway State", HFILL }
4888       },
4889       /* Gateway Precedence */
4890       { &hf_dlr_advgatewayprecedence,
4891         { "Gateway Precedence", "enip.dlr.advgatewayprecedence",
4892           FT_UINT8, BASE_DEC, NULL, 0,
4893           NULL, HFILL }
4894       },
4895       /* Advertise Interval */
4896       { &hf_dlr_advadvertiseinterval,
4897         { "Advertise Interval", "enip.dlr.advadvertiseinterval",
4898           FT_UINT32, BASE_DEC, NULL, 0,
4899           NULL, HFILL }
4900       },
4901       /* Advertise Timeout */
4902       { &hf_dlr_advadvertisetimeout,
4903         { "Advertise Interval", "enip.dlr.advadvertisetimeout",
4904           FT_UINT32, BASE_DEC, NULL, 0,
4905           NULL, HFILL }
4906       },
4907       /* Learning Update Enable */
4908       { &hf_dlr_advlearningupdateenable,
4909         { "Learning Update Enable", "enip.dlr.advlearningupdateenable",
4910           FT_UINT8, BASE_HEX, VALS(dlr_adv_learning_update_vals), 0,
4911           "Advertise Learning Update Enable", HFILL }
4912       },
4913       /* Advertise Reserved */
4914       { &hf_dlr_advreserved,
4915         { "Reserved", "enip.dlr.advreserved",
4916           FT_BYTES, BASE_NONE, NULL, 0,
4917           "Advertise Reserved", HFILL }
4918       },
4919       /* Flush_Tables Learning Update Enable */
4920       { &hf_dlr_flushlearningupdateenable,
4921         { "Learning Update Enable", "enip.dlr.flushlearningupdateenable",
4922           FT_UINT8, BASE_HEX, VALS(dlr_flush_learning_update_vals), 0,
4923           "Flush_Tables Learning Update Enable", HFILL }
4924       },
4925       /* Flush Reserved */
4926       { &hf_dlr_flushreserved,
4927         { "Reserved", "enip.dlr.flushreserved",
4928           FT_BYTES, BASE_NONE, NULL, 0,
4929           "Flush_Tables Reserved", HFILL }
4930       },
4931       /* Learning_Update Reserved */
4932       { &hf_dlr_learnreserved,
4933         { "Reserved", "enip.dlr.learnreserved",
4934           FT_BYTES, BASE_NONE, NULL, 0,
4935           "Learning_Update Reserved", HFILL }
4936       }
4937    };
4938 
4939    /* Setup protocol subtree array for DLR */
4940    static gint *ettdlr[] = {
4941       &ett_dlr
4942    };
4943 
4944    module_t *enip_module;
4945    expert_module_t* expert_enip;
4946 
4947    /* Register the protocol name and description */
4948    proto_enip = proto_register_protocol("EtherNet/IP (Industrial Protocol)", "ENIP", "enip");
4949    proto_cipio = proto_register_protocol("Common Industrial Protocol, I/O", "CIP I/O", "cipio");
4950    proto_cip_class1 = proto_register_protocol_in_name_only(
4951       "Common Industrial Protocol, I/O Class 1",
4952       "CIP Class 1",
4953       "cipio1",
4954       proto_cipio,
4955       FT_PROTOCOL);
4956 
4957    enip_tcp_handle = register_dissector("enip", dissect_enip_tcp, proto_enip);
4958    cipio_handle = register_dissector("cipio", dissect_cipio, proto_cipio);
4959    cip_class1_handle = register_dissector("cipio_class1", dissect_cip_class1, proto_cip_class1);
4960    cip_io_generic_handle = register_dissector("cipgenericio", dissect_cip_io_generic, proto_cipio);
4961 
4962    /* Required function calls to register the header fields and subtrees used */
4963    proto_register_field_array(proto_enip, hf, array_length(hf));
4964    proto_register_subtree_array(ett, array_length(ett));
4965 
4966    expert_enip = expert_register_protocol(proto_enip);
4967    expert_register_field_array(expert_enip, ei, array_length(ei));
4968 
4969    enip_module = prefs_register_protocol(proto_enip, NULL);
4970    prefs_register_bool_preference(enip_module, "desegment",
4971                                   "Desegment all EtherNet/IP messages spanning multiple TCP segments",
4972                                   "Whether the EtherNet/IP dissector should desegment all messages spanning multiple TCP segments",
4973                                   &enip_desegment);
4974 
4975    prefs_register_bool_preference(enip_module, "o2t_run_idle",
4976                                   "Dissect 32-bit header in the O->T direction",
4977                                   "Determines whether all I/O connections will assume a 32-bit header in the O->T direction",
4978                                   &enip_OTrun_idle);
4979 
4980    prefs_register_bool_preference(enip_module, "t2o_run_idle",
4981                                   "Dissect 32-bit header in the T->O direction",
4982                                   "Determines whether all I/O connections will assume a 32-bit header in the T->O direction",
4983                                   &enip_TOrun_idle);
4984 
4985    prefs_register_obsolete_preference(enip_module, "default_io_dissector");
4986 
4987    subdissector_srrd_table = register_dissector_table("enip.srrd.iface",
4988                                                       "ENIP SendRequestReplyData.Interface Handle", proto_enip, FT_UINT32, BASE_HEX);
4989 
4990    subdissector_io_table = register_dissector_table("cip.io.iface",
4991       "CIP Class 0/1 Interface Handle", proto_cipio, FT_UINT32, BASE_HEX);
4992 
4993    subdissector_cip_connection_table = register_dissector_table("cip.connection.class",
4994       "CIP Class 2/3 Interface Handle", proto_enip, FT_UINT32, BASE_HEX);
4995 
4996    enip_request_hashtable = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), enip_request_hash, enip_request_equal);
4997    enip_conn_hashtable = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), enip_conn_hash, enip_conn_equal);
4998 
4999    register_init_routine(&enip_init_protocol);
5000 
5001    /* Register the protocol name and description */
5002    proto_dlr = proto_register_protocol("Device Level Ring", "DLR", "dlr");
5003 
5004    /* Required function calls to register the header fields and subtrees used */
5005    proto_register_field_array(proto_dlr, hfdlr, array_length(hfdlr));
5006    proto_register_subtree_array(ettdlr, array_length(ettdlr));
5007 
5008    register_conversation_filter("enip", "CIP Connection", cip_connection_conv_valid, cip_connection_conv_filter);
5009 
5010    subdissector_decode_as_io_table = register_decode_as_next_proto(proto_enip, "cip.io", "CIP I/O Payload", enip_prompt);
5011 } /* end of proto_register_enip() */
5012 
5013 
5014 void
proto_reg_handoff_enip(void)5015 proto_reg_handoff_enip(void)
5016 {
5017    dissector_handle_t enip_udp_handle;
5018    dissector_handle_t dlr_handle;
5019 
5020    /* Register for EtherNet/IP, using TCP */
5021    dissector_add_uint_with_preference("tcp.port", ENIP_ENCAP_PORT, enip_tcp_handle);
5022 
5023    /* Register for EtherNet/IP, using UDP */
5024    enip_udp_handle = create_dissector_handle(dissect_enip_udp, proto_enip);
5025    dissector_add_uint_with_preference("udp.port", ENIP_ENCAP_PORT, enip_udp_handle);
5026 
5027    /* Register for EtherNet/IP IO data (UDP) */
5028    dissector_add_uint_with_preference("udp.port", ENIP_IO_PORT, cipio_handle);
5029 
5030    /* Register for EtherNet/IP TLS */
5031    ssl_dissector_add(ENIP_SECURE_PORT, enip_tcp_handle);
5032    dtls_dissector_add(ENIP_SECURE_PORT, cipio_handle);
5033 
5034    /* Find ARP dissector for TCP/IP object */
5035    arp_handle = find_dissector_add_dependency("arp", proto_enip);
5036 
5037    /* I/O data dissectors */
5038    cipsafety_handle = find_dissector("cipsafety");
5039 
5040    /* Implicit data dissector */
5041    cip_implicit_handle = find_dissector_add_dependency("cip_implicit", proto_enip);
5042 
5043    cip_handle = find_dissector_add_dependency("cip", proto_enip);
5044 
5045    /* Register for EtherNet/IP Device Level Ring protocol */
5046    dlr_handle = create_dissector_handle(dissect_dlr, proto_dlr);
5047    dissector_add_uint("ethertype", ETHERTYPE_DLR, dlr_handle);
5048 
5049    subdissector_class_table = find_dissector_table("cip.class.iface");
5050 
5051    dissector_add_for_decode_as("cip.io", cip_class1_handle);
5052 } /* end of proto_reg_handoff_enip() */
5053 
5054 /*
5055 * Editor modelines - https://www.wireshark.org/tools/modelines.html
5056 *
5057 * Local variables:
5058 * c-basic-offset: 3
5059 * tab-width: 8
5060 * indent-tabs-mode: nil
5061 * End:
5062 *
5063 * ex: set shiftwidth=3 tabstop=8 expandtab:
5064 * :indentSize=3:tabSize=8:noTabs=true:
5065 */
5066