2003-08-16 01:53:41 +00:00
/* packet-enip.c
2003-06-11 22:36:18 +00:00
* Routines for EtherNet / IP ( Industrial Protocol ) dissection
2003-06-11 09:02:19 +00:00
* EtherNet / IP Home : www . odva . org
*
2004-02-04 20:34:53 +00:00
* Copyright 2003 - 2004
2003-06-11 09:02:19 +00:00
* Magnus Hansson < mah @ hms . se >
* Joakim Wiberg < jow @ hms . se >
*
2009-06-26 02:38:23 +00:00
* Conversation data support for CIP
* Jan Bartels , Siempelkamp Maschinen - und Anlagenbau GmbH & Co . KG
* Copyright 2007
*
2011-10-26 04:55:21 +00:00
* Ethernet / IP object support
* Michael Mann
* Copyright 2011
*
2006-05-21 04:49:01 +00:00
* Wireshark - Network traffic analyzer
* By Gerald Combs < gerald @ wireshark . org >
2003-06-11 09:02:19 +00:00
* Copyright 1998 Gerald Combs
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
2012-06-28 23:18:38 +00:00
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA .
2003-06-11 09:02:19 +00:00
*/
2012-09-20 02:03:38 +00:00
# include "config.h"
2003-06-11 09:02:19 +00:00
# include <glib.h>
# include <epan/packet.h>
2013-08-25 14:23:13 +00:00
# include <epan/wmem/wmem.h>
2009-06-26 02:38:23 +00:00
# include <epan/conversation.h>
2014-05-27 02:58:48 +00:00
# include <epan/dissector_filters.h>
2009-06-26 02:38:23 +00:00
# include <epan/prefs.h>
2009-07-09 20:44:28 +00:00
# include <epan/etypes.h>
2012-11-13 13:14:48 +00:00
# include <epan/ipv6-utils.h>
2011-10-26 04:55:21 +00:00
# include <epan/expert.h>
2004-01-27 04:43:35 +00:00
# include "packet-tcp.h"
2011-10-02 19:05:20 +00:00
# include "packet-cip.h"
2011-10-26 04:55:21 +00:00
# include "packet-enip.h"
2012-02-27 09:30:26 +00:00
# include "packet-cipsafety.h"
2003-06-11 09:02:19 +00:00
2013-12-15 23:44:12 +00:00
void proto_register_enip ( void ) ;
void proto_reg_handoff_enip ( void ) ;
2004-09-23 17:34:35 +00:00
/* Communication Ports */
2009-06-26 02:38:23 +00:00
# define ENIP_ENCAP_PORT 44818 /* EtherNet/IP located on port 44818 */
# define ENIP_IO_PORT 2222 /* EtherNet/IP IO located on port 2222 */
2003-06-11 09:02:19 +00:00
2004-09-23 17:34:35 +00:00
/* EtherNet/IP function codes */
2003-06-11 09:02:19 +00:00
# define NOP 0x0000
# define LIST_SERVICES 0x0004
# define LIST_IDENTITY 0x0063
# define LIST_INTERFACES 0x0064
# define REGISTER_SESSION 0x0065
# define UNREGISTER_SESSION 0x0066
# define SEND_RR_DATA 0x006F
# define SEND_UNIT_DATA 0x0070
# define INDICATE_STATUS 0x0072
# define CANCEL 0x0073
2004-09-23 17:34:35 +00:00
/* EtherNet/IP status codes */
2003-06-11 09:02:19 +00:00
# define SUCCESS 0x0000
# define INVALID_CMD 0x0001
# define NO_RESOURCES 0x0002
# define INCORRECT_DATA 0x0003
# define INVALID_SESSION 0x0064
# define INVALID_LENGTH 0x0065
# define UNSUPPORTED_PROT_REV 0x0069
2004-09-23 17:34:35 +00:00
/* EtherNet/IP Common Data Format Type IDs */
2003-06-11 09:02:19 +00:00
# define CDF_NULL 0x0000
# define LIST_IDENTITY_RESP 0x000C
# define CONNECTION_BASED 0x00A1
# define CONNECTION_TRANSPORT 0x00B1
# define UNCONNECTED_MSG 0x00B2
# define LIST_SERVICES_RESP 0x0100
# define SOCK_ADR_INFO_OT 0x8000
# define SOCK_ADR_INFO_TO 0x8001
# define SEQ_ADDRESS 0x8002
2012-07-18 19:40:56 +00:00
/* Decoded I/O traffic enumeration */
# define ENIP_IO_OFF 0
# define ENIP_IO_SAFETY 1
# define ENIP_IO_MOTION 2
2003-06-11 09:02:19 +00:00
2004-09-23 17:34:35 +00:00
/* Initialize the protocol and registered fields */
2012-04-26 16:47:37 +00:00
static int proto_enip = - 1 ;
static int proto_cipsafety = - 1 ;
static int hf_enip_command = - 1 ;
static int hf_enip_length = - 1 ;
static int hf_enip_options = - 1 ;
static int hf_enip_sendercontex = - 1 ;
2012-11-13 13:14:48 +00:00
static int hf_enip_listid_delay = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_enip_status = - 1 ;
static int hf_enip_session = - 1 ;
static int hf_enip_encapver = - 1 ;
static int hf_enip_sinfamily = - 1 ;
static int hf_enip_sinport = - 1 ;
static int hf_enip_sinaddr = - 1 ;
static int hf_enip_sinzero = - 1 ;
static int hf_enip_timeout = - 1 ;
static int hf_enip_encap_data = - 1 ;
static int hf_enip_lir_vendor = - 1 ;
static int hf_enip_lir_devtype = - 1 ;
static int hf_enip_lir_prodcode = - 1 ;
static int hf_enip_lir_revision = - 1 ;
static int hf_enip_lir_status = - 1 ;
static int hf_enip_lir_serial = - 1 ;
static int hf_enip_lir_namelen = - 1 ;
static int hf_enip_lir_name = - 1 ;
static int hf_enip_lir_state = - 1 ;
static int hf_enip_lsr_capaflags = - 1 ;
static int hf_enip_lsr_tcp = - 1 ;
static int hf_enip_lsr_udp = - 1 ;
2011-04-25 01:37:19 +00:00
static int hf_enip_lsr_servicename = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_enip_rs_version = - 1 ;
static int hf_enip_rs_optionflags = - 1 ;
2004-09-23 17:34:35 +00:00
2012-04-26 16:47:37 +00:00
static int hf_enip_srrd_ifacehnd = - 1 ;
2004-09-23 17:34:35 +00:00
2012-04-26 16:47:37 +00:00
static int hf_enip_sud_ifacehnd = - 1 ;
2003-06-11 09:02:19 +00:00
2012-04-26 16:47:37 +00:00
static int hf_enip_cpf_itemcount = - 1 ;
static int hf_enip_cpf_typeid = - 1 ;
static int hf_enip_cpf_length = - 1 ;
static int hf_enip_cpf_cdi_seqcnt = - 1 ;
2011-12-01 06:05:39 +00:00
static int hf_enip_cpf_cdi_32bitheader = - 1 ;
static int hf_enip_cpf_cdi_32bitheader_roo = - 1 ;
static int hf_enip_cpf_cdi_32bitheader_coo = - 1 ;
static int hf_enip_cpf_cdi_32bitheader_run_idle = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_enip_cpf_cai_connid = - 1 ;
static int hf_enip_cpf_sai_connid = - 1 ;
static int hf_enip_cpf_sai_seqnum = - 1 ;
2011-12-01 06:05:39 +00:00
2012-04-26 16:47:37 +00:00
static int hf_enip_cpf_data = - 1 ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
static int hf_enip_response_in = - 1 ;
static int hf_enip_response_to = - 1 ;
static int hf_enip_time = - 1 ;
2011-10-13 00:00:52 +00:00
static int hf_enip_connection_transport_data = - 1 ;
2009-06-26 02:38:23 +00:00
2011-10-26 04:55:21 +00:00
/* Parsed Attributes */
2012-04-26 16:47:37 +00:00
static int hf_tcpip_status = - 1 ;
static int hf_tcpip_status_interface_config = - 1 ;
static int hf_tcpip_status_mcast_pending = - 1 ;
static int hf_tcpip_status_interface_config_pending = - 1 ;
static int hf_tcpip_status_acd = - 1 ;
static int hf_tcpip_status_reserved = - 1 ;
static int hf_tcpip_config_cap = - 1 ;
static int hf_tcpip_config_cap_bootp = - 1 ;
static int hf_tcpip_config_cap_dns = - 1 ;
static int hf_tcpip_config_cap_dhcp = - 1 ;
static int hf_tcpip_config_cap_dhcp_dns_update = - 1 ;
static int hf_tcpip_config_cap_config_settable = - 1 ;
static int hf_tcpip_config_cap_hardware_config = - 1 ;
static int hf_tcpip_config_cap_interface_reset = - 1 ;
static int hf_tcpip_config_cap_acd = - 1 ;
static int hf_tcpip_config_cap_reserved = - 1 ;
static int hf_tcpip_config_control = - 1 ;
static int hf_tcpip_config_control_config = - 1 ;
static int hf_tcpip_config_control_dns = - 1 ;
static int hf_tcpip_config_control_reserved = - 1 ;
static int hf_tcpip_physical_link_size = - 1 ;
static int hf_tcpip_ic_ip_addr = - 1 ;
static int hf_tcpip_ic_subnet_mask = - 1 ;
static int hf_tcpip_ic_gateway = - 1 ;
static int hf_tcpip_ic_name_server = - 1 ;
static int hf_tcpip_ic_name_server2 = - 1 ;
static int hf_tcpip_ic_domain_name = - 1 ;
static int hf_tcpip_hostname = - 1 ;
static int hf_tcpip_ttl_value = - 1 ;
static int hf_tcpip_mcast_alloc = - 1 ;
static int hf_tcpip_mcast_reserved = - 1 ;
static int hf_tcpip_mcast_num_mcast = - 1 ;
static int hf_tcpip_mcast_addr_start = - 1 ;
static int hf_tcpip_lcd_acd_activity = - 1 ;
static int hf_tcpip_lcd_remote_mac = - 1 ;
static int hf_tcpip_lcd_arp_pdu = - 1 ;
static int hf_tcpip_select_acd = - 1 ;
static int hf_tcpip_quick_connect = - 1 ;
static int hf_elink_interface_flags = - 1 ;
static int hf_elink_iflags_link_status = - 1 ;
static int hf_elink_iflags_duplex = - 1 ;
static int hf_elink_iflags_neg_status = - 1 ;
static int hf_elink_iflags_manual_reset = - 1 ;
static int hf_elink_iflags_local_hw_fault = - 1 ;
static int hf_elink_iflags_reserved = - 1 ;
static int hf_elink_interface_speed = - 1 ;
static int hf_elink_physical_address = - 1 ;
static int hf_elink_icount_in_octets = - 1 ;
static int hf_elink_icount_in_ucast = - 1 ;
static int hf_elink_icount_in_nucast = - 1 ;
static int hf_elink_icount_in_discards = - 1 ;
static int hf_elink_icount_in_errors = - 1 ;
static int hf_elink_icount_in_unknown_protos = - 1 ;
static int hf_elink_icount_out_octets = - 1 ;
static int hf_elink_icount_out_ucast = - 1 ;
static int hf_elink_icount_out_nucast = - 1 ;
static int hf_elink_icount_out_discards = - 1 ;
static int hf_elink_icount_out_errors = - 1 ;
static int hf_elink_mcount_alignment_errors = - 1 ;
static int hf_elink_mcount_fcs_errors = - 1 ;
static int hf_elink_mcount_single_collisions = - 1 ;
static int hf_elink_mcount_multiple_collisions = - 1 ;
static int hf_elink_mcount_sqe_test_errors = - 1 ;
static int hf_elink_mcount_deferred_transmission = - 1 ;
static int hf_elink_mcount_late_collisions = - 1 ;
static int hf_elink_mcount_excessive_collisions = - 1 ;
static int hf_elink_mcount_mac_transmit_errors = - 1 ;
static int hf_elink_mcount_carrier_sense_errors = - 1 ;
static int hf_elink_mcount_frame_too_long = - 1 ;
static int hf_elink_mcount_mac_receive_errors = - 1 ;
static int hf_elink_icontrol_control_bits = - 1 ;
static int hf_elink_icontrol_control_bits_auto_neg = - 1 ;
2011-10-26 04:55:21 +00:00
static int hf_elink_icontrol_control_bits_forced_duplex = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_elink_icontrol_control_bits_reserved = - 1 ;
static int hf_elink_icontrol_forced_speed = - 1 ;
static int hf_elink_interface_type = - 1 ;
static int hf_elink_interface_state = - 1 ;
static int hf_elink_admin_state = - 1 ;
static int hf_elink_interface_label = - 1 ;
static int hf_qos_8021q_enable = - 1 ;
static int hf_qos_dscp_ptp_event = - 1 ;
static int hf_qos_dscp_ptp_general = - 1 ;
static int hf_qos_dscp_urgent = - 1 ;
static int hf_qos_dscp_scheduled = - 1 ;
static int hf_qos_dscp_high = - 1 ;
static int hf_qos_dscp_low = - 1 ;
static int hf_qos_dscp_explicit = - 1 ;
2011-10-26 04:55:21 +00:00
2012-08-09 16:47:15 +00:00
static int hf_dlr_network_topology = - 1 ;
static int hf_dlr_network_status = - 1 ;
static int hf_dlr_ring_supervisor_status = - 1 ;
static int hf_dlr_rsc_ring_supervisor_enable = - 1 ;
static int hf_dlr_rsc_ring_supervisor_precedence = - 1 ;
static int hf_dlr_rsc_beacon_interval = - 1 ;
static int hf_dlr_rsc_beacon_timeout = - 1 ;
static int hf_dlr_rsc_dlr_vlan_id = - 1 ;
static int hf_dlr_ring_faults_count = - 1 ;
static int hf_dlr_lanp1_dev_ip_addr = - 1 ;
static int hf_dlr_lanp1_dev_physical_address = - 1 ;
static int hf_dlr_lanp2_dev_ip_addr = - 1 ;
static int hf_dlr_lanp2_dev_physical_address = - 1 ;
static int hf_dlr_ring_protocol_participants_count = - 1 ;
static int hf_dlr_rppl_dev_ip_addr = - 1 ;
static int hf_dlr_rppl_dev_physical_address = - 1 ;
static int hf_dlr_asa_supervisor_ip_addr = - 1 ;
static int hf_dlr_asa_supervisor_physical_address = - 1 ;
static int hf_dlr_active_supervisor_precedence = - 1 ;
static int hf_dlr_capability_flags = - 1 ;
static int hf_dlr_capflags_announce_base_node = - 1 ;
static int hf_dlr_capflags_beacon_base_node = - 1 ;
static int hf_dlr_capflags_reserved1 = - 1 ;
static int hf_dlr_capflags_supervisor_capable = - 1 ;
static int hf_dlr_capflags_reserved2 = - 1 ;
2013-04-04 14:34:26 +00:00
static int hf_dlr_capflags_redundant_gateway_capable = - 1 ;
static int hf_dlr_capflags_flush_frame_capable = - 1 ;
static int hf_dlr_rgc_red_gateway_enable = - 1 ;
static int hf_dlr_rgc_gateway_precedence = - 1 ;
static int hf_dlr_rgc_advertise_interval = - 1 ;
static int hf_dlr_rgc_advertise_timeout = - 1 ;
static int hf_dlr_rgc_learning_update_enable = - 1 ;
static int hf_dlr_redundant_gateway_status = - 1 ;
static int hf_dlr_aga_ip_addr = - 1 ;
static int hf_dlr_aga_physical_address = - 1 ;
static int hf_dlr_active_gateway_precedence = - 1 ;
2012-07-18 19:40:56 +00:00
2003-06-11 09:02:19 +00:00
/* Initialize the subtree pointers */
2012-04-26 16:47:37 +00:00
static gint ett_enip = - 1 ;
static gint ett_count_tree = - 1 ;
static gint ett_type_tree = - 1 ;
static gint ett_command_tree = - 1 ;
static gint ett_sockadd = - 1 ;
2011-12-01 06:05:39 +00:00
static gint ett_32bitheader_tree = - 1 ;
2012-04-26 16:47:37 +00:00
static gint ett_lsrcf = - 1 ;
static gint ett_tcpip_status = - 1 ;
static gint ett_tcpip_config_cap = - 1 ;
static gint ett_tcpip_config_control = - 1 ;
2011-10-26 04:55:21 +00:00
static gint ett_elink_interface_flags = - 1 ;
static gint ett_elink_icontrol_bits = - 1 ;
2012-07-18 19:40:56 +00:00
static gint ett_dlr_capability_flags = - 1 ;
2013-04-04 14:34:26 +00:00
static gint ett_dlr_lnknbrstatus_flags = - 1 ;
2004-09-23 17:34:35 +00:00
2013-05-24 18:02:54 +00:00
static expert_field ei_mal_tcpip_status = EI_INIT ;
static expert_field ei_mal_tcpip_config_cap = EI_INIT ;
static expert_field ei_mal_tcpip_config_control = EI_INIT ;
static expert_field ei_mal_tcpip_physical_link_size = EI_INIT ;
static expert_field ei_mal_tcpip_interface_config = EI_INIT ;
static expert_field ei_mal_tcpip_mcast_config = EI_INIT ;
static expert_field ei_mal_tcpip_last_conflict = EI_INIT ;
static expert_field ei_mal_elink_interface_flags = EI_INIT ;
static expert_field ei_mal_elink_interface_counters = EI_INIT ;
static expert_field ei_mal_elink_media_counters = EI_INIT ;
static expert_field ei_mal_elink_interface_control = EI_INIT ;
static expert_field ei_mal_dlr_ring_supervisor_config = EI_INIT ;
static expert_field ei_mal_dlr_last_active_node_on_port_1 = EI_INIT ;
static expert_field ei_mal_dlr_last_active_node_on_port_2 = EI_INIT ;
static expert_field ei_mal_dlr_ring_protocol_participants_list = EI_INIT ;
static expert_field ei_mal_dlr_active_supervisor_address = EI_INIT ;
static expert_field ei_mal_dlr_capability_flags = EI_INIT ;
static expert_field ei_mal_dlr_redundant_gateway_config = EI_INIT ;
static expert_field ei_mal_dlr_active_gateway_address = EI_INIT ;
2004-09-23 17:34:35 +00:00
static dissector_table_t subdissector_srrd_table ;
static dissector_table_t subdissector_sud_table ;
static dissector_handle_t data_handle ;
2012-02-27 09:30:26 +00:00
static dissector_handle_t arp_handle ;
2012-03-02 03:39:16 +00:00
static dissector_handle_t cipsafety_handle ;
static dissector_handle_t cipmotion_handle ;
2004-09-23 17:34:35 +00:00
2012-04-26 16:47:37 +00:00
static gboolean enip_desegment = TRUE ;
2011-12-01 06:05:39 +00:00
static gboolean enip_OTrun_idle = TRUE ;
static gboolean enip_TOrun_idle = FALSE ;
2003-06-11 22:36:18 +00:00
2012-04-26 16:47:37 +00:00
static int proto_dlr = - 1 ;
2009-07-09 20:44:28 +00:00
2012-04-26 16:47:37 +00:00
static int hf_dlr_ringsubtype = - 1 ;
2009-07-09 20:44:28 +00:00
static int hf_dlr_ringprotoversion = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_dlr_frametype = - 1 ;
static int hf_dlr_sourceport = - 1 ;
static int hf_dlr_sourceip = - 1 ;
static int hf_dlr_sequenceid = - 1 ;
2009-07-09 20:44:28 +00:00
2012-04-26 16:47:37 +00:00
static int hf_dlr_ringstate = - 1 ;
2009-07-09 20:44:28 +00:00
static int hf_dlr_supervisorprecedence = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_dlr_beaconinterval = - 1 ;
static int hf_dlr_beacontimeout = - 1 ;
static int hf_dlr_beaconreserved = - 1 ;
2009-07-09 20:44:28 +00:00
2012-04-26 16:47:37 +00:00
static int hf_dlr_nreqreserved = - 1 ;
2009-07-09 20:44:28 +00:00
static int hf_dlr_nressourceport = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_dlr_nresreserved = - 1 ;
2009-07-09 20:44:28 +00:00
2012-04-26 16:47:37 +00:00
static int hf_dlr_lnknbrstatus = - 1 ;
2013-04-04 14:34:26 +00:00
static int hf_dlr_lnknbrstatus_port1 = - 1 ;
static int hf_dlr_lnknbrstatus_port2 = - 1 ;
static int hf_dlr_lnknbrstatus_reserved = - 1 ;
static int hf_dlr_lnknbrstatus_frame_type = - 1 ;
2009-07-09 20:44:28 +00:00
static int hf_dlr_lnknbrreserved = - 1 ;
static int hf_dlr_lfreserved = - 1 ;
static int hf_dlr_anreserved = - 1 ;
static int hf_dlr_sonumnodes = - 1 ;
2012-04-26 16:47:37 +00:00
static int hf_dlr_somac = - 1 ;
static int hf_dlr_soip = - 1 ;
2009-07-09 20:44:28 +00:00
static int hf_dlr_soreserved = - 1 ;
2013-04-04 14:34:26 +00:00
static int hf_dlr_advgatewaystate = - 1 ;
static int hf_dlr_advgatewayprecedence = - 1 ;
static int hf_dlr_advadvertiseinterval = - 1 ;
static int hf_dlr_advadvertisetimeout = - 1 ;
static int hf_dlr_advlearningupdateenable = - 1 ;
static int hf_dlr_advreserved = - 1 ;
static int hf_dlr_flushlearningupdateenable = - 1 ;
static int hf_dlr_flushreserved = - 1 ;
static int hf_dlr_learnreserved = - 1 ;
2009-07-09 20:44:28 +00:00
static gint ett_dlr = - 1 ;
2012-11-29 20:15:37 +00:00
static const enum_val_t enip_io_dissector_types [ ] = {
2012-08-09 16:47:15 +00:00
{ " Off " , " Regular Ethernet/IP I/O data " , ENIP_IO_OFF } ,
{ " CIP Safety " , " CIP Safety " , ENIP_IO_SAFETY } ,
{ " CIP Motion " , " CIP Motion " , ENIP_IO_MOTION } ,
2012-11-29 20:15:37 +00:00
{ NULL , NULL , 0 }
2012-07-18 19:40:56 +00:00
} ;
/* decode I/O traffic as this type if ForwardOpen isn't captured */
static gint default_io_dissector_type = ENIP_IO_OFF ;
2003-06-11 09:02:19 +00:00
/* Translate function to string - Encapsulation commands */
static const value_string encap_cmd_vals [ ] = {
2009-06-26 02:38:23 +00:00
{ NOP , " NOP " } ,
{ LIST_SERVICES , " List Services " } ,
{ LIST_IDENTITY , " List Identity " } ,
{ LIST_INTERFACES , " List Interfaces " } ,
{ REGISTER_SESSION , " Register Session " } ,
{ UNREGISTER_SESSION , " Unregister Session " } ,
{ SEND_RR_DATA , " Send RR Data " } ,
{ SEND_UNIT_DATA , " Send Unit Data " } ,
{ INDICATE_STATUS , " Indicate Status " } ,
{ CANCEL , " Cancel " } ,
{ 0 , NULL }
2003-06-11 09:02:19 +00:00
} ;
/* Translate function to string - Encapsulation status */
static const value_string encap_status_vals [ ] = {
2012-04-26 16:47:37 +00:00
{ SUCCESS , " Success " } ,
{ INVALID_CMD , " Invalid Command " } ,
{ NO_RESOURCES , " No Memory Resources " } ,
{ INCORRECT_DATA , " Incorrect Data " } ,
{ INVALID_SESSION , " Invalid Session Handle " } ,
{ INVALID_LENGTH , " Invalid Length " } ,
2009-06-26 02:38:23 +00:00
{ UNSUPPORTED_PROT_REV , " Unsupported Protocol Revision " } ,
{ 0 , NULL }
2003-06-11 09:02:19 +00:00
} ;
/* Translate function to Common data format values */
static const value_string cdf_type_vals [ ] = {
2012-04-26 16:47:37 +00:00
{ CDF_NULL , " Null Address Item " } ,
{ LIST_IDENTITY_RESP , " List Identity Response " } ,
{ CONNECTION_BASED , " Connected Address Item " } ,
{ CONNECTION_TRANSPORT , " Connected Data Item " } ,
{ UNCONNECTED_MSG , " Unconnected Data Item " } ,
{ LIST_SERVICES_RESP , " List Services Response " } ,
2009-06-26 02:38:23 +00:00
{ SOCK_ADR_INFO_OT , " Socket Address Info O->T " } ,
{ SOCK_ADR_INFO_TO , " Socket Address Info T->O " } ,
2012-04-26 16:47:37 +00:00
{ SEQ_ADDRESS , " Sequenced Address Item " } ,
2009-06-26 02:38:23 +00:00
{ 0 , NULL }
2003-06-11 09:02:19 +00:00
} ;
2011-12-01 06:05:39 +00:00
/* Translate function to string - Run/Idle */
static const value_string enip_run_idle_vals [ ] = {
{ 0 , " Idle " } ,
{ 1 , " Run " } ,
{ 0 , NULL }
} ;
2011-10-26 04:55:21 +00:00
static const value_string enip_tcpip_status_interface_config_vals [ ] = {
{ 0 , " Not configured " } ,
{ 1 , " BOOTP/DHCP/NVS " } ,
{ 2 , " Hardware settings " } ,
{ 0 , NULL }
} ;
static const value_string enip_tcpip_status_acd_vals [ ] = {
{ 0 , " No Address Conflict Detected " } ,
{ 1 , " Address Conflict Detected " } ,
{ 0 , NULL }
} ;
static const value_string enip_tcpip_config_control_config_vals [ ] = {
{ 0 , " Static IP " } ,
{ 1 , " BOOTP " } ,
{ 2 , " DHCP " } ,
{ 0 , NULL }
} ;
static const value_string enip_tcpip_mcast_alloc_vals [ ] = {
{ 0 , " Use default multicast algorithm " } ,
{ 1 , " Use Num Mcast and Mcast Start Addr " } ,
{ 0 , NULL }
} ;
static const value_string enip_tcpip_acd_activity_vals [ ] = {
{ 0 , " No Conflict Detected " } ,
{ 1 , " Probe IPv4 Address " } ,
{ 2 , " Ongoing Detection " } ,
{ 3 , " Semi Active Probe " } ,
{ 0 , NULL }
} ;
static const value_string enip_elink_duplex_vals [ ] = {
{ 0 , " Half Duplex " } ,
{ 1 , " Full Duplex " } ,
{ 0 , NULL }
} ;
static const value_string enip_elink_iflags_neg_status_vals [ ] = {
{ 0 , " Auto-negotiation in progress " } ,
{ 1 , " Auto-negotiation and speed detection failed " } ,
{ 2 , " Auto-negotiation failed but detected speed " } ,
2013-09-20 18:35:10 +00:00
{ 3 , " Successfully negotiatied speed and duplex " } ,
{ 4 , " Auto-negotiation not attempted. Forced speed and duplex " } ,
2011-10-26 04:55:21 +00:00
{ 0 , NULL }
} ;
static const value_string enip_elink_iflags_reset_vals [ ] = {
{ 0 , " Activate change automatically " } ,
{ 1 , " Device requires Reset service for change " } ,
{ 0 , NULL }
} ;
static const value_string enip_elink_iflags_hw_fault_vals [ ] = {
{ 0 , " No local hardware fault " } ,
{ 1 , " Local hardware fault detected " } ,
{ 0 , NULL }
} ;
static const value_string enip_elink_interface_type_vals [ ] = {
{ 0 , " Unknown type " } ,
{ 1 , " Internal " } ,
{ 2 , " Twisted-pair " } ,
{ 3 , " Optical fiber " } ,
{ 0 , NULL }
} ;
static const value_string enip_elink_interface_state_vals [ ] = {
{ 0 , " Unknown state " } ,
{ 1 , " Enabled " } ,
{ 2 , " Disabled " } ,
{ 3 , " Testing " } ,
{ 0 , NULL }
} ;
static const value_string enip_elink_admin_state_vals [ ] = {
{ 1 , " Enabled " } ,
{ 2 , " Disabled " } ,
{ 0 , NULL }
} ;
2012-07-18 19:40:56 +00:00
static const value_string enip_dlr_network_topology_vals [ ] = {
{ 0 , " Linear " } ,
{ 1 , " Ring " } ,
{ 0 , NULL }
} ;
static const value_string enip_dlr_network_status_vals [ ] = {
{ 0 , " Normal " } ,
{ 1 , " Ring Fault " } ,
{ 2 , " Unexpected Loop Detected " } ,
{ 3 , " Partial Network Failure " } ,
{ 4 , " Rapid Fault/Restore Cycle " } ,
{ 0 , NULL }
} ;
static const value_string enip_dlr_ring_supervisor_status_vals [ ] = {
{ 0 , " Backup Ring Supervisor " } ,
{ 1 , " Active Ring Supervisor " } ,
{ 2 , " Ring Node " } ,
{ 3 , " Non-DLR Topology " } ,
{ 4 , " Cannot Support Parameters " } ,
{ 0 , NULL }
} ;
2013-04-04 14:34:26 +00:00
static const value_string enip_dlr_redundant_gateway_status_vals [ ] = {
{ 0 , " Non-Gateway DLR node " } ,
{ 1 , " Backup Gateway " } ,
{ 2 , " Active Gateway " } ,
{ 3 , " Gateway Fault " } ,
{ 4 , " Cannot Support Parameters " } ,
{ 5 , " Partitial Network Fault " } ,
{ 0 , NULL }
} ;
2004-09-23 17:34:35 +00:00
/* Translate interface handle to string */
static const value_string enip_interface_handle_vals [ ] = {
2009-06-26 02:38:23 +00:00
{ 0 , " CIP " } ,
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
{ 0 , NULL }
2003-06-11 09:02:19 +00:00
} ;
2009-07-09 20:44:28 +00:00
/* Translate function to DLR Frame Type values */
static const value_string dlr_frame_type_vals [ ] = {
2012-04-26 16:47:37 +00:00
{ DLR_FT_BEACON , " Beacon " } ,
{ DLR_FT_NEIGHBOR_REQ , " Neighbor_Check_Request " } ,
{ DLR_FT_NEIGHBOR_RES , " Neighbor_Check_Response " } ,
2009-07-09 20:44:28 +00:00
{ DLR_FT_LINK_STAT , " Link_Status / Neighbor_Status " } ,
2012-04-26 16:47:37 +00:00
{ DLR_FT_LOCATE_FLT , " Locate_Fault " } ,
{ DLR_FT_ANNOUNCE , " Announce " } ,
{ DLR_FT_SIGN_ON , " Sign_On " } ,
2013-04-04 14:34:26 +00:00
{ DLR_FT_ADVERTISE , " Advertise " } ,
{ DLR_FT_FLUSH_TABLES , " Flush_Tables " } ,
{ DLR_FT_LEARNING_UPDATE , " Learning_Update " } ,
2009-07-09 20:44:28 +00:00
{ 0 , NULL }
} ;
/* Translate function to DLR Source Port values */
static const value_string dlr_source_port_vals [ ] = {
{ 0 , " Port 1 or Port 2 " } ,
{ 1 , " Port 1 " } ,
{ 2 , " Port 2 " } ,
{ 0 , NULL }
} ;
/* Translate function to DLR Ring State values */
static const value_string dlr_ring_state_vals [ ] = {
{ 1 , " RING_NORMAL_STATE " } ,
{ 2 , " RING_FAULT_STATE " } ,
{ 0 , NULL }
} ;
2013-04-04 14:34:26 +00:00
/* Translate function to DLR Advertise State values */
static const value_string dlr_adv_state_vals [ ] = {
{ 0x01 , " ACTIVE_LISTEN_STATE " } ,
{ 0x02 , " ACTIVE_NORMAL_STATE " } ,
{ 0x03 , " FAULT_STATE " } ,
2009-07-09 20:44:28 +00:00
{ 0 , NULL }
} ;
2013-04-04 14:34:26 +00:00
/* Translate function to DLR Learning Update values */
static const value_string dlr_adv_learning_update_vals [ ] = {
{ 0 , " Disabled " } ,
{ 1 , " Enabled " } ,
{ 0 , NULL }
} ;
/* Translate function to DLR Flush Learning Update values */
static const value_string dlr_flush_learning_update_vals [ ] = {
{ 0 , " Disabled " } ,
{ 1 , " Enabled " } ,
{ 0 , NULL }
} ;
static const true_false_string dlr_lnknbrstatus_frame_type_vals = {
2013-09-25 19:13:10 +00:00
" Neighbor_Status Frame " ,
" Link_Status Frame "
2013-04-04 14:34:26 +00:00
} ;
2009-06-26 02:38:23 +00:00
static GHashTable * enip_request_hashtable = NULL ;
/* Return codes of function classifying packets as query/response */
2011-12-01 06:05:39 +00:00
enum enip_packet_type { ENIP_REQUEST_PACKET , ENIP_RESPONSE_PACKET , ENIP_CANNOT_CLASSIFY } ;
2009-06-26 02:38:23 +00:00
enum enip_packet_data_type { EPDT_UNKNOWN , EPDT_CONNECTED_TRANSPORT , EPDT_UNCONNECTED } ;
typedef struct enip_request_key {
2012-04-26 16:47:37 +00:00
enum enip_packet_type requesttype ;
2009-06-26 02:38:23 +00:00
enum enip_packet_data_type type ;
guint32 session_handle ;
guint64 sender_context ;
guint32 conversation ;
union {
struct {
guint32 connid ;
guint16 sequence ;
} connected_transport ;
} data ;
} enip_request_key_t ;
typedef struct enip_request_val {
2013-08-25 14:23:13 +00:00
wmem_tree_t * frames ;
2009-06-26 02:38:23 +00:00
} enip_request_val_t ;
/*
* Hash Functions
*/
static gint
enip_request_equal ( gconstpointer v , gconstpointer w )
{
2011-10-13 00:00:52 +00:00
const enip_request_key_t * v1 = ( const enip_request_key_t * ) v ;
const enip_request_key_t * v2 = ( const enip_request_key_t * ) w ;
if ( v1 - > conversation = = v2 - > conversation
& & v1 - > session_handle = = v2 - > session_handle
& & v1 - > type = = v2 - > type
& & ( ( v1 - > sender_context = = v2 - > sender_context /* heuristic approach */
& & v1 - > type = = EPDT_UNCONNECTED
)
| |
( v1 - > data . connected_transport . connid = = v2 - > data . connected_transport . connid
& & v1 - > data . connected_transport . sequence = = v2 - > data . connected_transport . sequence
& & v1 - > type = = EPDT_CONNECTED_TRANSPORT
)
)
)
return 1 ;
2009-06-26 02:38:23 +00:00
2011-10-13 00:00:52 +00:00
return 0 ;
2009-06-26 02:38:23 +00:00
}
2011-04-25 01:37:19 +00:00
static void
enip_fmt_lir_revision ( gchar * result , guint32 revision )
{
2012-08-09 16:47:15 +00:00
g_snprintf ( result , ITEM_LABEL_LENGTH , " %d.%02d " , ( guint8 ) ( ( revision & 0xFF00 ) > > 8 ) , ( guint8 ) ( revision & 0xFF ) ) ;
2011-04-25 01:37:19 +00:00
}
2009-06-26 02:38:23 +00:00
static guint
enip_request_hash ( gconstpointer v )
{
const enip_request_key_t * key = ( const enip_request_key_t * ) v ;
guint val ;
2012-02-27 09:30:26 +00:00
val = ( guint ) ( key - > conversation * 37 + key - > session_handle * 93 + key - > type * 765 ) ;
if ( key - > type = = EPDT_UNCONNECTED )
{
val + = ( ( guint ) ( key - > sender_context * 23 ) ) ;
}
else if ( key - > type = = EPDT_CONNECTED_TRANSPORT )
{
val + = ( ( guint ) ( key - > data . connected_transport . connid * 87 + key - > data . connected_transport . sequence * 834 ) ) ;
}
2009-06-26 02:38:23 +00:00
return val ;
}
static enip_request_info_t *
enip_match_request ( packet_info * pinfo , proto_tree * tree , enip_request_key_t * prequest_key )
{
2012-04-26 16:47:37 +00:00
enip_request_key_t * new_request_key ;
enip_request_val_t * request_val ;
2012-08-09 16:47:15 +00:00
enip_request_info_t * request_info ;
2009-06-26 02:38:23 +00:00
request_info = NULL ;
2013-03-14 18:58:42 +00:00
request_val = ( enip_request_val_t * ) g_hash_table_lookup ( enip_request_hashtable , prequest_key ) ;
2013-11-21 18:37:26 +00:00
if ( ! pinfo - > fd - > flags . visited )
2009-06-26 02:38:23 +00:00
{
if ( prequest_key & & prequest_key - > requesttype = = ENIP_REQUEST_PACKET )
{
if ( request_val = = NULL )
{
2013-08-25 14:23:13 +00:00
new_request_key = ( enip_request_key_t * ) wmem_memdup ( wmem_file_scope ( ) , prequest_key , sizeof ( enip_request_key_t ) ) ;
2009-06-26 02:38:23 +00:00
2013-08-25 14:23:13 +00:00
request_val = wmem_new ( wmem_file_scope ( ) , enip_request_val_t ) ;
request_val - > frames = wmem_tree_new ( wmem_file_scope ( ) ) ;
2009-06-26 02:38:23 +00:00
g_hash_table_insert ( enip_request_hashtable , new_request_key , request_val ) ;
}
2013-08-25 14:23:13 +00:00
request_info = wmem_new ( wmem_file_scope ( ) , enip_request_info_t ) ;
2009-06-26 02:38:23 +00:00
request_info - > req_num = pinfo - > fd - > num ;
request_info - > rep_num = 0 ;
request_info - > req_time = pinfo - > fd - > abs_ts ;
request_info - > cip_info = NULL ;
2013-08-25 14:23:13 +00:00
wmem_tree_insert32 ( request_val - > frames , pinfo - > fd - > num , ( void * ) request_info ) ;
2009-06-26 02:38:23 +00:00
}
2013-11-21 18:37:26 +00:00
if ( request_val & & prequest_key & & prequest_key - > requesttype = = ENIP_RESPONSE_PACKET )
2009-06-26 02:38:23 +00:00
{
2013-08-25 14:23:13 +00:00
request_info = ( enip_request_info_t * ) wmem_tree_lookup32_le ( request_val - > frames , pinfo - > fd - > num ) ;
2009-06-26 02:38:23 +00:00
if ( request_info )
{
request_info - > rep_num = pinfo - > fd - > num ;
}
}
}
else
{
if ( request_val )
2013-11-21 18:37:26 +00:00
request_info = ( enip_request_info_t * ) wmem_tree_lookup32_le ( request_val - > frames , pinfo - > fd - > num ) ;
2009-06-26 02:38:23 +00:00
}
if ( tree & & request_info )
{
/* print state tracking in the tree */
if ( prequest_key & & prequest_key - > requesttype = = ENIP_REQUEST_PACKET )
{
/* This is a request */
if ( request_info - > rep_num )
{
proto_item * it ;
it = proto_tree_add_uint ( tree , hf_enip_response_in ,
NULL , 0 , 0 , request_info - > rep_num ) ;
PROTO_ITEM_SET_GENERATED ( it ) ;
}
}
else
{
if ( prequest_key & & prequest_key - > requesttype = = ENIP_RESPONSE_PACKET )
{
/* This is a reply */
if ( request_info - > req_num )
{
proto_item * it ;
2013-11-21 18:37:26 +00:00
nstime_t ns ;
2009-06-26 02:38:23 +00:00
it = proto_tree_add_uint ( tree , hf_enip_response_to ,
NULL , 0 , 0 , request_info - > req_num ) ;
PROTO_ITEM_SET_GENERATED ( it ) ;
nstime_delta ( & ns , & pinfo - > fd - > abs_ts , & request_info - > req_time ) ;
it = proto_tree_add_time ( tree , hf_enip_time , NULL , 0 , 0 , & ns ) ;
PROTO_ITEM_SET_GENERATED ( it ) ;
}
}
}
}
return request_info ;
}
typedef struct enip_conn_key {
guint16 ConnSerialNumber ;
guint16 VendorID ;
guint32 DeviceSerialNumber ;
2012-02-27 09:30:26 +00:00
guint32 O2TConnID ;
guint32 T2OConnID ;
2009-06-26 02:38:23 +00:00
} enip_conn_key_t ;
typedef struct enip_conn_val {
guint16 ConnSerialNumber ;
guint16 VendorID ;
guint32 DeviceSerialNumber ;
guint32 O2TConnID ;
guint32 T2OConnID ;
2012-02-27 09:30:26 +00:00
guint8 TransportClass_trigger ;
2014-05-27 02:58:48 +00:00
guint32 open_frame ;
guint32 open_reply_frame ;
guint32 close_frame ;
2009-06-26 02:38:23 +00:00
guint32 connid ;
2012-02-27 09:30:26 +00:00
cip_safety_epath_info_t safety ;
2012-03-02 03:39:16 +00:00
gboolean motion ;
2009-06-26 02:38:23 +00:00
} enip_conn_val_t ;
typedef struct _enip_conv_info_t {
2013-08-25 14:23:13 +00:00
wmem_tree_t * O2TConnIDs ;
wmem_tree_t * T2OConnIDs ;
2009-06-26 02:38:23 +00:00
} enip_conv_info_t ;
2014-05-27 02:58:48 +00:00
/*
* Conversation filter
*/
static gboolean
enip_io_conv_valid ( packet_info * pinfo )
{
enip_conn_val_t * conn = ( enip_conn_val_t * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO ) ;
if ( conn = = NULL )
return FALSE ;
return ( ( ( conn - > TransportClass_trigger & CI_TRANSPORT_CLASS_MASK ) = = 0 ) | |
( ( conn - > TransportClass_trigger & CI_TRANSPORT_CLASS_MASK ) = = 1 ) ) ;
}
static const gchar *
enip_io_conv_filter ( packet_info * pinfo )
{
char * buf ;
enip_conn_val_t * conn = ( enip_conn_val_t * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO ) ;
if ( conn = = NULL )
return NULL ;
2014-05-29 15:33:29 +00:00
if ( conn - > close_frame > 0 )
{
buf = g_strdup_printf (
" ((frame.number == %u) || ((frame.number >= %u) && (frame.number <= %u))) && " /* Frames between ForwardOpen and ForwardClose reply */
" ((enip.cpf.sai.connid == 0x%08x || enip.cpf.sai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
" ((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x))) " , /* Connection Triad */
conn - > open_frame , conn - > open_reply_frame , conn - > close_frame ,
conn - > O2TConnID , conn - > T2OConnID ,
conn - > ConnSerialNumber , conn - > VendorID , conn - > DeviceSerialNumber ) ;
}
else
{
/* If Forward Close isn't found, don't limit the (end) frame range */
buf = g_strdup_printf (
" ((frame.number == %u) || (frame.number >= %u)) && " /* Frames starting with ForwardOpen */
" ((enip.cpf.sai.connid == 0x%08x || enip.cpf.sai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
" ((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x))) " , /* Connection Triad */
conn - > open_frame , conn - > open_reply_frame ,
conn - > O2TConnID , conn - > T2OConnID ,
conn - > ConnSerialNumber , conn - > VendorID , conn - > DeviceSerialNumber ) ;
}
2014-05-27 02:58:48 +00:00
return buf ;
}
static gboolean
enip_exp_conv_valid ( packet_info * pinfo )
{
enip_conn_val_t * conn = ( enip_conn_val_t * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO ) ;
if ( conn = = NULL )
return FALSE ;
return ( ( ( conn - > TransportClass_trigger & CI_TRANSPORT_CLASS_MASK ) = = 2 ) | |
( ( conn - > TransportClass_trigger & CI_TRANSPORT_CLASS_MASK ) = = 3 ) ) ;
}
static const gchar *
enip_exp_conv_filter ( packet_info * pinfo )
{
char * buf ;
enip_conn_val_t * conn = ( enip_conn_val_t * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO ) ;
if ( conn = = NULL )
return NULL ;
2014-05-29 15:33:29 +00:00
if ( conn - > close_frame > 0 )
{
buf = g_strdup_printf (
" ((frame.number == %u) || ((frame.number >= %u) && (frame.number <= %u))) && " /* Frames between ForwardOpen and ForwardClose reply */
" ((enip.cpf.cai.connid == 0x%08x || enip.cpf.cai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
" ((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x))) " , /* Connection Triad */
conn - > open_frame , conn - > open_reply_frame , conn - > close_frame ,
conn - > O2TConnID , conn - > T2OConnID ,
conn - > ConnSerialNumber , conn - > VendorID , conn - > DeviceSerialNumber ) ;
}
else
{
/* If Forward Close isn't found, don't limit the (end) frame range */
buf = g_strdup_printf (
" ((frame.number == %u) || (frame.number >= %u)) && " /* Frames between ForwardOpen and ForwardClose */
" ((enip.cpf.cai.connid == 0x%08x || enip.cpf.cai.connid == 0x%08x) || " /* O->T and T->O Connection IDs */
" ((cip.cm.conn_serial_num == 0x%04x) && (cip.cm.vendor == 0x%04x) && (cip.cm.orig_serial_num == 0x%08x))) " , /* Connection Triad */
conn - > open_frame , conn - > open_reply_frame ,
conn - > O2TConnID , conn - > T2OConnID ,
conn - > ConnSerialNumber , conn - > VendorID , conn - > DeviceSerialNumber ) ;
}
2014-05-27 02:58:48 +00:00
return buf ;
}
/*
* Connection management
*/
2009-06-26 02:38:23 +00:00
static GHashTable * enip_conn_hashtable = NULL ;
static guint32 enip_unique_connid = 1 ;
static gint
enip_conn_equal ( gconstpointer v , gconstpointer w )
{
const enip_conn_key_t * v1 = ( const enip_conn_key_t * ) v ;
const enip_conn_key_t * v2 = ( const enip_conn_key_t * ) w ;
2012-03-02 03:39:16 +00:00
if ( ( v1 - > ConnSerialNumber = = v2 - > ConnSerialNumber ) & &
2012-02-27 09:30:26 +00:00
( v1 - > VendorID = = v2 - > VendorID ) & &
( v1 - > DeviceSerialNumber = = v2 - > DeviceSerialNumber ) & &
( ( v1 - > O2TConnID = = 0 ) | | ( v2 - > O2TConnID = = 0 ) | | ( v1 - > O2TConnID = = v2 - > O2TConnID ) ) & &
( ( v1 - > T2OConnID = = 0 ) | | ( v2 - > T2OConnID = = 0 ) | | ( v1 - > T2OConnID = = v2 - > T2OConnID ) ) )
2009-06-26 02:38:23 +00:00
return 1 ;
return 0 ;
}
static guint
enip_conn_hash ( gconstpointer v )
{
const enip_conn_key_t * key = ( const enip_conn_key_t * ) v ;
guint val ;
val = ( guint ) ( key - > ConnSerialNumber + key - > VendorID + key - > DeviceSerialNumber ) ;
return val ;
}
2013-12-16 06:03:17 +00:00
static void
2011-12-01 06:05:39 +00:00
enip_open_cip_connection ( packet_info * pinfo , cip_conn_info_t * connInfo )
2009-06-26 02:38:23 +00:00
{
2012-04-26 16:47:37 +00:00
enip_conn_key_t * conn_key ;
enip_conn_val_t * conn_val ;
conversation_t * conversation , * conversationTO ;
2011-04-25 01:37:19 +00:00
enip_conv_info_t * enip_info ;
2012-04-26 16:47:37 +00:00
address dest_address ;
2012-11-13 13:14:48 +00:00
struct e_in6_addr ipv6_zero ;
2009-06-26 02:38:23 +00:00
2011-04-25 01:37:19 +00:00
if ( pinfo - > fd - > flags . visited )
return ;
2009-06-26 02:38:23 +00:00
2013-08-25 14:23:13 +00:00
conn_key = wmem_new ( wmem_file_scope ( ) , enip_conn_key_t ) ;
2011-12-01 06:05:39 +00:00
conn_key - > ConnSerialNumber = connInfo - > ConnSerialNumber ;
conn_key - > VendorID = connInfo - > VendorID ;
conn_key - > DeviceSerialNumber = connInfo - > DeviceSerialNumber ;
2012-02-27 09:30:26 +00:00
conn_key - > O2TConnID = connInfo - > O2T . connID ;
conn_key - > T2OConnID = connInfo - > T2O . connID ;
2009-06-26 02:38:23 +00:00
2013-03-14 18:58:42 +00:00
conn_val = ( enip_conn_val_t * ) g_hash_table_lookup ( enip_conn_hashtable , conn_key ) ;
2009-06-26 02:38:23 +00:00
if ( conn_val = = NULL )
{
2013-08-25 14:23:13 +00:00
conn_val = wmem_new ( wmem_file_scope ( ) , enip_conn_val_t ) ;
2009-06-26 02:38:23 +00:00
2012-08-09 16:47:15 +00:00
conn_val - > ConnSerialNumber = connInfo - > ConnSerialNumber ;
conn_val - > VendorID = connInfo - > VendorID ;
conn_val - > DeviceSerialNumber = connInfo - > DeviceSerialNumber ;
conn_val - > O2TConnID = connInfo - > O2T . connID ;
conn_val - > T2OConnID = connInfo - > T2O . connID ;
2012-02-27 09:30:26 +00:00
conn_val - > TransportClass_trigger = connInfo - > TransportClass_trigger ;
2012-08-09 16:47:15 +00:00
conn_val - > safety = connInfo - > safety ;
conn_val - > motion = connInfo - > motion ;
2014-05-27 02:58:48 +00:00
conn_val - > open_frame = connInfo - > forward_open_frame ;
conn_val - > open_reply_frame = pinfo - > fd - > num ;
conn_val - > close_frame = 0 ;
2012-08-09 16:47:15 +00:00
conn_val - > connid = enip_unique_connid + + ;
2009-06-26 02:38:23 +00:00
g_hash_table_insert ( enip_conn_hashtable , conn_key , conn_val ) ;
2011-12-01 06:05:39 +00:00
/* I/O connection */
2012-02-27 09:30:26 +00:00
if ( ( ( connInfo - > TransportClass_trigger & CI_TRANSPORT_CLASS_MASK ) = = 0 ) | |
( ( connInfo - > TransportClass_trigger & CI_TRANSPORT_CLASS_MASK ) = = 1 ) )
2011-12-01 06:05:39 +00:00
{
2012-11-13 13:14:48 +00:00
/* zero out the ipv6 structure for comparison */
memset ( & ipv6_zero , 0 , sizeof ( ipv6_zero ) ) ;
2011-12-01 06:05:39 +00:00
/* default some information if not included */
if ( ( connInfo - > O2T . port = = 0 ) | | ( connInfo - > O2T . type = = CONN_TYPE_MULTICAST ) )
connInfo - > O2T . port = ENIP_IO_PORT ;
2012-11-13 13:14:48 +00:00
if ( ( connInfo - > O2T . ipaddress . type = = AT_NONE ) | |
2013-12-14 14:33:46 +00:00
( ( connInfo - > O2T . ipaddress . type = = AT_IPv4 ) & & ( ( * ( const guint32 * ) connInfo - > O2T . ipaddress . data ) ) = = 0 ) | |
2012-11-13 13:14:48 +00:00
( ( connInfo - > O2T . ipaddress . type = = AT_IPv6 ) & & ( memcmp ( connInfo - > O2T . ipaddress . data , & ipv6_zero , sizeof ( ipv6_zero ) ) = = 0 ) ) | |
( connInfo - > O2T . type ! = CONN_TYPE_MULTICAST ) )
connInfo - > O2T . ipaddress = pinfo - > src ;
2011-12-01 06:05:39 +00:00
if ( ( connInfo - > T2O . port = = 0 ) | | ( connInfo - > T2O . type = = CONN_TYPE_MULTICAST ) )
connInfo - > T2O . port = ENIP_IO_PORT ;
2012-11-13 13:14:48 +00:00
if ( ( connInfo - > T2O . ipaddress . type = = AT_NONE ) | |
2013-12-14 14:33:46 +00:00
( ( connInfo - > T2O . ipaddress . type = = AT_IPv4 ) & & ( ( * ( const guint32 * ) connInfo - > T2O . ipaddress . data ) ) = = 0 ) | |
2012-11-13 13:14:48 +00:00
( ( connInfo - > T2O . ipaddress . type = = AT_IPv6 ) & & ( memcmp ( connInfo - > T2O . ipaddress . data , & ipv6_zero , sizeof ( ipv6_zero ) ) = = 0 ) ) | |
( connInfo - > T2O . type ! = CONN_TYPE_MULTICAST ) )
connInfo - > T2O . ipaddress = pinfo - > dst ;
2011-12-01 06:05:39 +00:00
2012-11-13 13:14:48 +00:00
if ( connInfo - > O2T . ipaddress . type = = AT_IPv6 )
{
dest_address . type = AT_IPv6 ;
2013-11-21 18:37:26 +00:00
dest_address . len = 16 ;
2012-11-13 13:14:48 +00:00
}
else
{
dest_address . type = AT_IPv4 ;
2013-11-21 18:37:26 +00:00
dest_address . len = 4 ;
2012-11-13 13:14:48 +00:00
}
dest_address . data = connInfo - > O2T . ipaddress . data ;
2011-12-01 06:05:39 +00:00
/* check for O->T conversation */
/* similar logic to find_or_create_conversation(), but since I/O traffic
is on UDP , the pinfo parameter doesn ' t have the correct information */
2013-11-21 18:37:26 +00:00
if ( ( conversation = find_conversation ( pinfo - > fd - > num , & pinfo - > dst , & dest_address ,
2012-04-26 16:47:37 +00:00
PT_UDP , connInfo - > O2T . port , 0 , NO_PORT_B ) ) = = NULL ) {
2011-12-01 06:05:39 +00:00
2012-04-26 16:47:37 +00:00
conversation = conversation_new ( pinfo - > fd - > num , & pinfo - > dst , & dest_address ,
PT_UDP , connInfo - > O2T . port , 0 , NO_PORT2 ) ;
}
2011-12-01 06:05:39 +00:00
2013-03-14 18:58:42 +00:00
enip_info = ( enip_conv_info_t * ) conversation_get_proto_data ( conversation , proto_enip ) ;
2011-12-01 06:05:39 +00:00
if ( enip_info = = NULL )
{
2013-08-25 14:23:13 +00:00
enip_info = wmem_new ( wmem_file_scope ( ) , enip_conv_info_t ) ;
enip_info - > O2TConnIDs = wmem_tree_new ( wmem_file_scope ( ) ) ;
enip_info - > T2OConnIDs = wmem_tree_new ( wmem_file_scope ( ) ) ;
2010-05-13 18:28:34 +00:00
2011-12-01 06:05:39 +00:00
conversation_add_proto_data ( conversation , proto_enip , enip_info ) ;
}
2013-08-25 14:23:13 +00:00
wmem_tree_insert32 ( enip_info - > O2TConnIDs , connInfo - > O2T . connID , ( void * ) conn_val ) ;
2011-12-01 06:05:39 +00:00
/* Check if separate T->O conversation is necessary. If either side is multicast
or ports aren ' t equal , a separate conversation must be generated */
2014-05-27 02:58:48 +00:00
dest_address . data = connInfo - > T2O . ipaddress . data ;
2013-11-21 18:37:26 +00:00
if ( ( conversationTO = find_conversation ( pinfo - > fd - > num , & pinfo - > src , & dest_address ,
2012-04-26 16:47:37 +00:00
PT_UDP , connInfo - > T2O . port , 0 , NO_PORT_B ) ) = = NULL ) {
2011-12-01 06:05:39 +00:00
conversationTO = conversation_new ( pinfo - > fd - > num , & pinfo - > src ,
2012-04-26 16:47:37 +00:00
& dest_address , PT_UDP ,
connInfo - > T2O . port , 0 , NO_PORT2 ) ;
2011-12-01 06:05:39 +00:00
}
2013-03-14 18:58:42 +00:00
enip_info = ( enip_conv_info_t * ) conversation_get_proto_data ( conversationTO , proto_enip ) ;
2011-12-01 06:05:39 +00:00
if ( enip_info = = NULL )
{
2013-08-25 14:23:13 +00:00
enip_info = wmem_new ( wmem_file_scope ( ) , enip_conv_info_t ) ;
enip_info - > O2TConnIDs = wmem_tree_new ( wmem_file_scope ( ) ) ;
enip_info - > T2OConnIDs = wmem_tree_new ( wmem_file_scope ( ) ) ;
2011-12-01 06:05:39 +00:00
conversation_add_proto_data ( conversationTO , proto_enip , enip_info ) ;
}
2013-08-25 14:23:13 +00:00
wmem_tree_insert32 ( enip_info - > T2OConnIDs , connInfo - > T2O . connID , ( void * ) conn_val ) ;
2011-12-01 06:05:39 +00:00
}
else
2009-06-26 02:38:23 +00:00
{
2011-12-01 06:05:39 +00:00
/* explicit message connection */
conversation = find_or_create_conversation ( pinfo ) ;
/* Do we already have a state structure for this conv */
2013-03-14 18:58:42 +00:00
enip_info = ( enip_conv_info_t * ) conversation_get_proto_data ( conversation , proto_enip ) ;
2011-12-01 06:05:39 +00:00
if ( ! enip_info )
{
/*
* No . Attach that information to the conversation , and add
* it to the list of information structures .
*/
2013-08-25 14:23:13 +00:00
enip_info = wmem_new ( wmem_file_scope ( ) , enip_conv_info_t ) ;
enip_info - > O2TConnIDs = wmem_tree_new ( wmem_file_scope ( ) ) ;
enip_info - > T2OConnIDs = wmem_tree_new ( wmem_file_scope ( ) ) ;
2011-12-01 06:05:39 +00:00
conversation_add_proto_data ( conversation , proto_enip , enip_info ) ;
}
2013-08-25 14:23:13 +00:00
wmem_tree_insert32 ( enip_info - > O2TConnIDs , connInfo - > O2T . connID , ( void * ) conn_val ) ;
wmem_tree_insert32 ( enip_info - > T2OConnIDs , connInfo - > T2O . connID , ( void * ) conn_val ) ;
2009-06-26 02:38:23 +00:00
}
}
2014-05-27 02:58:48 +00:00
/* Save the connection info for the conversation filter */
if ( ! pinfo - > fd - > flags . visited )
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO , conn_val ) ;
2009-06-26 02:38:23 +00:00
}
2011-04-25 01:37:19 +00:00
void
enip_close_cip_connection ( packet_info * pinfo , guint16 ConnSerialNumber ,
guint16 VendorID , guint32 DeviceSerialNumber )
2009-06-26 02:38:23 +00:00
{
2012-04-26 16:47:37 +00:00
enip_conn_key_t conn_key ;
2011-04-25 01:37:19 +00:00
enip_conn_val_t * conn_val ;
2009-06-26 02:38:23 +00:00
2011-04-25 01:37:19 +00:00
if ( pinfo - > fd - > flags . visited )
return ;
2009-06-26 02:38:23 +00:00
2012-08-09 16:47:15 +00:00
conn_key . ConnSerialNumber = ConnSerialNumber ;
conn_key . VendorID = VendorID ;
2009-06-26 02:38:23 +00:00
conn_key . DeviceSerialNumber = DeviceSerialNumber ;
2012-08-09 16:47:15 +00:00
conn_key . O2TConnID = 0 ;
conn_key . T2OConnID = 0 ;
2009-06-26 02:38:23 +00:00
2013-03-14 18:58:42 +00:00
conn_val = ( enip_conn_val_t * ) g_hash_table_lookup ( enip_conn_hashtable , & conn_key ) ;
2009-06-26 02:38:23 +00:00
if ( conn_val )
{
2014-05-27 02:58:48 +00:00
conn_val - > close_frame = pinfo - > fd - > num ;
/* Save the connection info for the conversation filter */
if ( ! pinfo - > fd - > flags . visited )
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO , conn_val ) ;
}
}
/* Save the connection info for the conversation filter */
void enip_mark_connection_triad ( packet_info * pinfo , guint16 ConnSerialNumber , guint16 VendorID , guint32 DeviceSerialNumber )
{
enip_conn_key_t conn_key ;
enip_conn_val_t * conn_val ;
conn_key . ConnSerialNumber = ConnSerialNumber ;
conn_key . VendorID = VendorID ;
conn_key . DeviceSerialNumber = DeviceSerialNumber ;
conn_key . O2TConnID = 0 ;
conn_key . T2OConnID = 0 ;
conn_val = ( enip_conn_val_t * ) g_hash_table_lookup ( enip_conn_hashtable , & conn_key ) ;
if ( conn_val )
{
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO , conn_val ) ;
2009-06-26 02:38:23 +00:00
}
}
2014-05-29 15:33:29 +00:00
static enip_conn_val_t *
2011-12-01 06:05:39 +00:00
enip_get_explicit_connid ( packet_info * pinfo , enip_request_key_t * prequest_key , guint32 connid )
2009-06-26 02:38:23 +00:00
{
2012-04-26 16:47:37 +00:00
conversation_t * conversation ;
2011-04-25 01:37:19 +00:00
enip_conv_info_t * enip_info ;
2012-04-26 16:47:37 +00:00
enip_conn_val_t * conn_val ;
2014-05-29 15:33:29 +00:00
enum enip_packet_type requesttype = ENIP_REQUEST_PACKET ;
2009-06-26 02:38:23 +00:00
2014-05-29 15:33:29 +00:00
if ( prequest_key ! = NULL )
{
/* Sanity check */
if ( ( prequest_key - > requesttype ! = ENIP_REQUEST_PACKET ) & & ( prequest_key - > requesttype ! = ENIP_RESPONSE_PACKET ) )
return NULL ;
requesttype = prequest_key - > requesttype ;
}
2009-06-26 02:38:23 +00:00
/*
* Do we have a conversation for this connection ?
*/
conversation = find_conversation ( pinfo - > fd - > num ,
& pinfo - > src , & pinfo - > dst ,
pinfo - > ptype ,
pinfo - > srcport , pinfo - > destport , 0 ) ;
if ( conversation = = NULL )
2014-05-29 15:33:29 +00:00
return NULL ;
2009-06-26 02:38:23 +00:00
/*
* Do we already have a state structure for this conv
*/
2013-03-14 18:58:42 +00:00
enip_info = ( enip_conv_info_t * ) conversation_get_proto_data ( conversation , proto_enip ) ;
2009-06-26 02:38:23 +00:00
if ( ! enip_info )
2014-05-29 15:33:29 +00:00
return NULL ;
2009-06-26 02:38:23 +00:00
conn_val = NULL ;
2014-05-29 15:33:29 +00:00
switch ( requesttype )
2009-06-26 02:38:23 +00:00
{
2013-11-21 18:37:26 +00:00
case ENIP_REQUEST_PACKET :
conn_val = ( enip_conn_val_t * ) wmem_tree_lookup32 ( enip_info - > O2TConnIDs , connid ) ;
if ( conn_val = = NULL )
conn_val = ( enip_conn_val_t * ) wmem_tree_lookup32 ( enip_info - > T2OConnIDs , connid ) ;
break ;
case ENIP_RESPONSE_PACKET :
conn_val = ( enip_conn_val_t * ) wmem_tree_lookup32 ( enip_info - > T2OConnIDs , connid ) ;
if ( conn_val = = NULL )
conn_val = ( enip_conn_val_t * ) wmem_tree_lookup32 ( enip_info - > O2TConnIDs , connid ) ;
break ;
case ENIP_CANNOT_CLASSIFY :
/* ignore */
break ;
2009-06-26 02:38:23 +00:00
}
2014-05-27 02:58:48 +00:00
if ( ( conn_val = = NULL ) | | ( conn_val - > open_reply_frame > pinfo - > fd - > num ) )
2014-05-29 15:33:29 +00:00
return NULL ;
2009-06-26 02:38:23 +00:00
2014-05-29 15:33:29 +00:00
return conn_val ;
2009-06-26 02:38:23 +00:00
}
2013-11-21 18:37:26 +00:00
static enip_conn_val_t *
2011-12-01 06:05:39 +00:00
enip_get_io_connid ( packet_info * pinfo , guint32 connid , enum enip_connid_type * pconnid_type )
{
2012-04-26 16:47:37 +00:00
conversation_t * conversation ;
2011-12-01 06:05:39 +00:00
enip_conv_info_t * enip_info ;
2012-04-26 16:47:37 +00:00
enip_conn_val_t * conn_val = NULL ;
2011-12-01 06:05:39 +00:00
* pconnid_type = ECIDT_UNKNOWN ;
2012-02-27 09:30:26 +00:00
2011-12-01 06:05:39 +00:00
/*
* Do we have a conversation for this connection ?
*/
conversation = find_conversation ( pinfo - > fd - > num ,
& pinfo - > src , & pinfo - > dst ,
pinfo - > ptype ,
2012-02-27 09:30:26 +00:00
pinfo - > destport , 0 , NO_PORT_B ) ;
2011-12-01 06:05:39 +00:00
if ( conversation = = NULL )
return NULL ;
/*
* Do we already have a state structure for this conv
*/
2013-03-14 18:58:42 +00:00
if ( ( enip_info = ( enip_conv_info_t * ) conversation_get_proto_data ( conversation , proto_enip ) ) = = NULL )
2011-12-01 06:05:39 +00:00
return NULL ;
if ( enip_info - > O2TConnIDs ! = NULL )
2013-08-25 14:23:13 +00:00
conn_val = ( enip_conn_val_t * ) wmem_tree_lookup32 ( enip_info - > O2TConnIDs , connid ) ;
2011-12-01 06:05:39 +00:00
if ( conn_val = = NULL )
{
if ( enip_info - > T2OConnIDs ! = NULL )
{
2013-08-25 14:23:13 +00:00
if ( ( conn_val = ( enip_conn_val_t * ) wmem_tree_lookup32 ( enip_info - > T2OConnIDs , connid ) ) ! = NULL )
2011-12-01 06:05:39 +00:00
* pconnid_type = ECIDT_T2O ;
}
}
else
{
* pconnid_type = ECIDT_O2T ;
}
2014-05-27 02:58:48 +00:00
if ( ( conn_val = = NULL ) | | ( conn_val - > open_reply_frame > pinfo - > fd - > num ) )
2011-12-01 06:05:39 +00:00
return NULL ;
return conn_val ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_tcpip_status ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
2012-04-26 16:47:37 +00:00
proto_item * status_item ;
proto_tree * status_tree ;
2011-10-26 04:55:21 +00:00
if ( total_len < 4 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_tcpip_status ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
status_item = proto_tree_add_item ( tree , hf_tcpip_status , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
status_tree = proto_item_add_subtree ( status_item , ett_tcpip_status ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( status_tree , hf_tcpip_status_interface_config , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( status_tree , hf_tcpip_status_mcast_pending , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( status_tree , hf_tcpip_status_interface_config_pending , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( status_tree , hf_tcpip_status_acd , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( status_tree , hf_tcpip_status_reserved , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
return 4 ;
}
2013-12-18 06:51:09 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_tcpip_config_cap ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
2012-04-26 16:47:37 +00:00
proto_item * cap_item ;
proto_tree * cap_tree ;
2011-10-26 04:55:21 +00:00
if ( total_len < 4 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_tcpip_config_cap ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
cap_item = proto_tree_add_item ( tree , hf_tcpip_config_cap , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
cap_tree = proto_item_add_subtree ( cap_item , ett_tcpip_config_cap ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_bootp , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_dns , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_dhcp , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_dhcp_dns_update , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_config_settable , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_hardware_config , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_interface_reset , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_acd , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( cap_tree , hf_tcpip_config_cap_reserved , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
return 4 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_tcpip_config_control ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
2011-10-26 04:55:21 +00:00
int offset , int total_len )
{
2012-04-26 16:47:37 +00:00
proto_item * control_item ;
proto_tree * control_tree ;
2011-10-26 04:55:21 +00:00
if ( total_len < 4 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_tcpip_config_control ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
control_item = proto_tree_add_item ( tree , hf_tcpip_config_control , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
control_tree = proto_item_add_subtree ( control_item , ett_tcpip_config_control ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( control_tree , hf_tcpip_config_control_config , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( control_tree , hf_tcpip_config_control_dns , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( control_tree , hf_tcpip_config_control_reserved , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
return 4 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_tcpip_physical_link ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
2012-04-26 16:47:37 +00:00
guint16 path_size ;
proto_item * path_item ;
2011-10-26 04:55:21 +00:00
path_size = tvb_get_letohs ( tvb , offset ) * 2 ;
proto_tree_add_uint_format_value ( tree , hf_tcpip_physical_link_size , tvb , offset , 2 , path_size / 2 , " %d (words) " , path_size / 2 ) ;
if ( total_len < path_size + 2 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_tcpip_physical_link_size ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
path_item = proto_tree_add_text ( tree , tvb , offset + 2 , path_size , " Path: " ) ;
2012-02-27 09:30:26 +00:00
dissect_epath ( tvb , pinfo , path_item , offset + 2 , path_size , FALSE , FALSE , NULL , NULL ) ;
2011-10-26 04:55:21 +00:00
return path_size + 2 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_tcpip_interface_config ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
guint16 domain_length ;
if ( total_len < 22 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_tcpip_interface_config ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_tcpip_ic_ip_addr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_tcpip_ic_subnet_mask , tvb , offset + 4 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_tcpip_ic_gateway , tvb , offset + 8 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_tcpip_ic_name_server , tvb , offset + 12 , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( tree , hf_tcpip_ic_name_server2 , tvb , offset + 16 , 4 , ENC_LITTLE_ENDIAN ) ;
domain_length = tvb_get_letohs ( tvb , offset + 20 ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_tcpip_ic_domain_name , tvb , offset + 22 , domain_length , ENC_ASCII | ENC_NA ) ;
2011-10-26 04:55:21 +00:00
return ( 22 + domain_length ) ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_tcpip_mcast_config ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
if ( total_len < 8 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_tcpip_mcast_config ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_tcpip_mcast_alloc , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_tcpip_mcast_reserved , tvb , offset + 1 , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_tcpip_mcast_num_mcast , tvb , offset + 2 , 2 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( tree , hf_tcpip_mcast_addr_start , tvb , offset + 4 , 4 , ENC_LITTLE_ENDIAN ) ;
return 8 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_tcpip_last_conflict ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
2012-02-27 09:30:26 +00:00
tvbuff_t * next_tvb ;
2013-09-20 18:35:10 +00:00
gboolean save_info ;
2012-02-27 09:30:26 +00:00
2011-10-26 04:55:21 +00:00
if ( total_len < 35 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_tcpip_last_conflict ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_tcpip_lcd_acd_activity , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( tree , hf_tcpip_lcd_remote_mac , tvb , offset + 1 , 6 , ENC_NA ) ;
2012-03-02 03:39:16 +00:00
2013-11-21 18:37:26 +00:00
if ( tvb_get_guint8 ( tvb , offset ) = = 0 )
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( tree , hf_tcpip_lcd_arp_pdu , tvb , offset + 7 , 28 , ENC_NA ) ;
2012-02-27 09:30:26 +00:00
else
2013-10-13 19:56:52 +00:00
{
2013-09-20 18:35:10 +00:00
/* Dissect ARP PDU, but don't have it change column info */
save_info = col_get_writable ( pinfo - > cinfo ) ;
col_set_writable ( pinfo - > cinfo , FALSE ) ;
2014-06-06 14:35:50 +00:00
next_tvb = tvb_new_subset_length ( tvb , offset + 7 , 28 ) ;
2012-02-27 09:30:26 +00:00
call_dissector ( arp_handle , next_tvb , pinfo , tree ) ;
2013-09-20 18:35:10 +00:00
col_set_writable ( pinfo - > cinfo , save_info ) ;
2012-02-27 09:30:26 +00:00
}
2012-03-02 03:39:16 +00:00
2011-10-26 04:55:21 +00:00
return 35 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_elink_interface_flags ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
2012-04-26 16:47:37 +00:00
proto_item * flag_item ;
proto_tree * flag_tree ;
2011-10-26 04:55:21 +00:00
if ( total_len < 4 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_elink_interface_flags ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
flag_item = proto_tree_add_item ( tree , hf_elink_interface_flags , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
flag_tree = proto_item_add_subtree ( flag_item , ett_elink_interface_flags ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( flag_tree , hf_elink_iflags_link_status , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_elink_iflags_duplex , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_elink_iflags_neg_status , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_elink_iflags_manual_reset , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( flag_tree , hf_elink_iflags_local_hw_fault , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( flag_tree , hf_elink_iflags_reserved , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
return 4 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_elink_interface_counters ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
if ( total_len < 44 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_elink_interface_counters ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_elink_icount_in_octets , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_in_ucast , tvb , offset + 4 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_in_nucast , tvb , offset + 8 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_in_discards , tvb , offset + 12 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_in_errors , tvb , offset + 16 , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( tree , hf_elink_icount_in_unknown_protos , tvb , offset + 20 , 4 , ENC_LITTLE_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_elink_icount_out_octets , tvb , offset + 24 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_out_ucast , tvb , offset + 28 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_out_nucast , tvb , offset + 32 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_out_discards , tvb , offset + 36 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_icount_out_errors , tvb , offset + 40 , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
return 44 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_elink_media_counters ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
2011-10-26 04:55:21 +00:00
int offset , int total_len )
{
if ( total_len < 48 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_elink_media_counters ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_elink_mcount_alignment_errors , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_fcs_errors , tvb , offset + 4 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_single_collisions , tvb , offset + 8 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_multiple_collisions , tvb , offset + 12 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_sqe_test_errors , tvb , offset + 16 , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( tree , hf_elink_mcount_deferred_transmission , tvb , offset + 20 , 4 , ENC_LITTLE_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_elink_mcount_late_collisions , tvb , offset + 24 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_excessive_collisions , tvb , offset + 28 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_mac_transmit_errors , tvb , offset + 32 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_carrier_sense_errors , tvb , offset + 36 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_frame_too_long , tvb , offset + 40 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_elink_mcount_mac_receive_errors , tvb , offset + 44 , 4 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
return 48 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_elink_interface_control ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2011-10-26 04:55:21 +00:00
{
2012-04-26 16:47:37 +00:00
proto_item * control_item ;
proto_tree * control_tree ;
2011-10-26 04:55:21 +00:00
if ( total_len < 4 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_elink_interface_control ) ;
2011-10-26 04:55:21 +00:00
return total_len ;
}
control_item = proto_tree_add_item ( tree , hf_elink_icontrol_control_bits , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
control_tree = proto_item_add_subtree ( control_item , ett_elink_icontrol_bits ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( control_tree , hf_elink_icontrol_control_bits_auto_neg , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( control_tree , hf_elink_icontrol_control_bits_forced_duplex , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( control_tree , hf_elink_icontrol_control_bits_reserved , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_elink_icontrol_forced_speed , tvb , offset + 2 , 2 , ENC_LITTLE_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
return 4 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_dlr_ring_supervisor_config ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2012-07-18 19:40:56 +00:00
{
if ( total_len < 12 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_ring_supervisor_config ) ;
2012-07-18 19:40:56 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_dlr_rsc_ring_supervisor_enable , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rsc_ring_supervisor_precedence , tvb , offset + 1 , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rsc_beacon_interval , tvb , offset + 2 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rsc_beacon_timeout , tvb , offset + 6 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rsc_dlr_vlan_id , tvb , offset + 10 , 2 , ENC_LITTLE_ENDIAN ) ;
2012-07-18 19:40:56 +00:00
return 12 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
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 )
2012-07-18 19:40:56 +00:00
{
if ( total_len < 10 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_last_active_node_on_port_1 ) ;
2012-07-18 19:40:56 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_dlr_lanp1_dev_ip_addr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( tree , hf_dlr_lanp1_dev_physical_address , tvb , offset + 4 , 6 , ENC_NA ) ;
2012-07-18 19:40:56 +00:00
return 10 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
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 )
2012-07-18 19:40:56 +00:00
{
if ( total_len < 10 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_last_active_node_on_port_2 ) ;
2012-07-18 19:40:56 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_dlr_lanp2_dev_ip_addr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( tree , hf_dlr_lanp2_dev_physical_address , tvb , offset + 4 , 6 , ENC_NA ) ;
2012-07-18 19:40:56 +00:00
return 10 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_dlr_ring_protocol_participants_list ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2012-07-18 19:40:56 +00:00
{
int pos ;
if ( total_len % 10 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_ring_protocol_participants_list ) ;
2012-07-18 19:40:56 +00:00
return total_len ;
}
2013-11-21 18:37:26 +00:00
pos = 0 ;
while ( pos < total_len )
2012-07-18 19:40:56 +00:00
{
2013-02-01 16:16:05 +00:00
proto_tree_add_item ( tree , hf_dlr_rppl_dev_ip_addr , tvb , offset + pos , 4 , ENC_LITTLE_ENDIAN ) ;
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( tree , hf_dlr_rppl_dev_physical_address , tvb , offset + pos + 4 , 6 , ENC_NA ) ;
2012-08-09 16:47:15 +00:00
pos + = 10 ;
2012-07-18 19:40:56 +00:00
}
return total_len ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_dlr_active_supervisor_address ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2012-07-18 19:40:56 +00:00
{
if ( total_len < 10 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_active_supervisor_address ) ;
2012-07-18 19:40:56 +00:00
return total_len ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( tree , hf_dlr_asa_supervisor_ip_addr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( tree , hf_dlr_asa_supervisor_physical_address , tvb , offset + 4 , 6 , ENC_NA ) ;
2012-07-18 19:40:56 +00:00
return 10 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_dlr_capability_flags ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
2012-07-18 19:40:56 +00:00
int offset , int total_len )
{
proto_item * flag_item ;
proto_tree * flag_tree ;
if ( total_len < 4 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_capability_flags ) ;
2012-07-18 19:40:56 +00:00
return total_len ;
}
flag_item = proto_tree_add_item ( tree , hf_dlr_capability_flags , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
flag_tree = proto_item_add_subtree ( flag_item , ett_dlr_capability_flags ) ;
2013-04-04 14:34:26 +00:00
proto_tree_add_item ( flag_tree , hf_dlr_capflags_announce_base_node , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_capflags_beacon_base_node , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_capflags_reserved1 , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_capflags_supervisor_capable , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_capflags_redundant_gateway_capable , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_capflags_flush_frame_capable , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_capflags_reserved2 , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2012-07-18 19:40:56 +00:00
return 4 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_dlr_redundant_gateway_config ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2013-04-04 14:34:26 +00:00
{
if ( total_len < 11 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_redundant_gateway_config ) ;
2013-04-04 14:34:26 +00:00
return total_len ;
}
proto_tree_add_item ( tree , hf_dlr_rgc_red_gateway_enable , tvb , offset , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rgc_gateway_precedence , tvb , offset + 1 , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rgc_advertise_interval , tvb , offset + 2 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rgc_advertise_timeout , tvb , offset + 6 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( tree , hf_dlr_rgc_learning_update_enable , tvb , offset + 10 , 1 , ENC_LITTLE_ENDIAN ) ;
return 11 ;
}
2013-12-16 06:03:17 +00:00
static int
2013-11-21 18:37:26 +00:00
dissect_dlr_active_gateway_address ( packet_info * pinfo , proto_tree * tree , proto_item * item , tvbuff_t * tvb ,
int offset , int total_len )
2013-04-04 14:34:26 +00:00
{
if ( total_len < 10 )
{
2013-05-24 18:02:54 +00:00
expert_add_info ( pinfo , item , & ei_mal_dlr_active_gateway_address ) ;
2013-04-04 14:34:26 +00:00
return total_len ;
}
proto_tree_add_item ( tree , hf_dlr_aga_ip_addr , tvb , offset , 4 , ENC_LITTLE_ENDIAN ) ;
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( tree , hf_dlr_aga_physical_address , tvb , offset + 4 , 6 , ENC_NA ) ;
2013-04-04 14:34:26 +00:00
return 10 ;
}
attribute_info_t enip_attribute_vals [ 45 ] = {
2011-10-26 04:55:21 +00:00
2012-02-27 09:30:26 +00:00
/* TCP/IP object */
2012-08-09 16:47:15 +00:00
{ 0xF5 , FALSE , 1 , " Status " , cip_dissector_func , NULL , dissect_tcpip_status } ,
{ 0xF5 , FALSE , 2 , " Configuration Capability " , cip_dissector_func , NULL , dissect_tcpip_config_cap } ,
{ 0xF5 , FALSE , 3 , " Configuration Control " , cip_dissector_func , NULL , dissect_tcpip_config_control } ,
{ 0xF5 , FALSE , 4 , " Physical Link Object " , cip_dissector_func , NULL , dissect_tcpip_physical_link } ,
{ 0xF5 , FALSE , 5 , " Interface Configuration " , cip_dissector_func , NULL , dissect_tcpip_interface_config } ,
{ 0xF5 , FALSE , 6 , " Host Name " , cip_string , & hf_tcpip_hostname , NULL } ,
{ 0xF5 , FALSE , 8 , " TTL Value " , cip_usint , & hf_tcpip_ttl_value , NULL } ,
{ 0xF5 , FALSE , 9 , " Multicast Configuration " , cip_dissector_func , NULL , dissect_tcpip_mcast_config } ,
{ 0xF5 , FALSE , 10 , " Select ACD " , cip_bool , & hf_tcpip_select_acd , NULL } ,
{ 0xF5 , FALSE , 11 , " Last Conflict Detected " , cip_dissector_func , NULL , dissect_tcpip_last_conflict } ,
{ 0xF5 , FALSE , 12 , " EtherNet/IP Quick Connect " , cip_bool , & hf_tcpip_quick_connect , NULL } ,
2011-10-26 04:55:21 +00:00
2012-02-27 09:30:26 +00:00
/* Ethernet Link object */
2012-08-09 16:47:15 +00:00
{ 0xF6 , FALSE , 1 , " Interface Speed " , cip_dword , & hf_elink_interface_speed , NULL } ,
{ 0xF6 , FALSE , 2 , " Interface Flags " , cip_dissector_func , NULL , dissect_elink_interface_flags } ,
{ 0xF6 , FALSE , 3 , " Physical Address " , cip_byte_array , & hf_elink_physical_address , NULL } ,
{ 0xF6 , FALSE , 4 , " Interface Counters " , cip_dissector_func , NULL , dissect_elink_interface_counters } ,
{ 0xF6 , FALSE , 5 , " Media Counters " , cip_dissector_func , NULL , dissect_elink_media_counters } ,
{ 0xF6 , FALSE , 6 , " Interface Control " , cip_dissector_func , NULL , dissect_elink_interface_control } ,
{ 0xF6 , FALSE , 7 , " Interface Type " , cip_usint , & hf_elink_interface_type , NULL } ,
{ 0xF6 , FALSE , 8 , " Interface State " , cip_usint , & hf_elink_interface_state , NULL } ,
{ 0xF6 , FALSE , 9 , " Admin State " , cip_usint , & hf_elink_admin_state , NULL } ,
{ 0xF6 , FALSE , 10 , " Interface Label " , cip_short_string , & hf_elink_interface_label , NULL } ,
2011-10-26 04:55:21 +00:00
2012-02-27 09:30:26 +00:00
/* QoS object */
2012-08-09 16:47:15 +00:00
{ 0x48 , FALSE , 1 , " 802.1Q Tag Enable " , cip_bool , & hf_qos_8021q_enable , NULL } ,
{ 0x48 , FALSE , 2 , " DSCP PTP Event " , cip_usint , & hf_qos_dscp_ptp_event , NULL } ,
{ 0x48 , FALSE , 3 , " DSCP PTP General " , cip_usint , & hf_qos_dscp_ptp_general , NULL } ,
{ 0x48 , FALSE , 4 , " DSCP Urgent " , cip_usint , & hf_qos_dscp_urgent , NULL } ,
{ 0x48 , FALSE , 5 , " DSCP Scheduled " , cip_usint , & hf_qos_dscp_scheduled , NULL } ,
{ 0x48 , FALSE , 6 , " DSCP High " , cip_usint , & hf_qos_dscp_high , NULL } ,
{ 0x48 , FALSE , 7 , " DSCP Low " , cip_usint , & hf_qos_dscp_low , NULL } ,
{ 0x48 , FALSE , 8 , " DSCP Explicit " , cip_usint , & hf_qos_dscp_explicit , NULL } ,
2012-07-18 19:40:56 +00:00
/* DLR object */
2012-08-09 16:47:15 +00:00
{ 0x47 , FALSE , 1 , " Network Topology " , cip_usint , & hf_dlr_network_topology , NULL } ,
{ 0x47 , FALSE , 2 , " Network Status " , cip_usint , & hf_dlr_network_status , NULL } ,
{ 0x47 , FALSE , 3 , " Ring Supervisor Status " , cip_usint , & hf_dlr_ring_supervisor_status , NULL } ,
{ 0x47 , FALSE , 4 , " Ring Supervisor Config " , cip_dissector_func , NULL , dissect_dlr_ring_supervisor_config } ,
{ 0x47 , FALSE , 5 , " Ring Faults Count " , cip_uint , & hf_dlr_ring_faults_count , NULL } ,
{ 0x47 , FALSE , 6 , " Last Active Node on Port 1 " , cip_dissector_func , NULL , dissect_dlr_last_active_node_on_port_1 } ,
{ 0x47 , FALSE , 7 , " Last Active Node on Port 2 " , cip_dissector_func , NULL , dissect_dlr_last_active_node_on_port_2 } ,
2012-07-18 19:40:56 +00:00
{ 0x47 , FALSE , 8 , " Ring Protocol Participants Count " , cip_uint , & hf_dlr_ring_protocol_participants_count , NULL } ,
2012-08-09 16:47:15 +00:00
{ 0x47 , FALSE , 9 , " Ring Protocol Participants List " , cip_dissector_func , NULL , dissect_dlr_ring_protocol_participants_list } ,
{ 0x47 , FALSE , 10 , " Active Supervisor Address " , cip_dissector_func , NULL , dissect_dlr_active_supervisor_address } ,
{ 0x47 , FALSE , 11 , " Active Supervisor Precedence " , cip_usint , & hf_dlr_active_supervisor_precedence , NULL } ,
2013-04-04 14:34:26 +00:00
{ 0x47 , FALSE , 12 , " Capability Flags " , cip_dissector_func , NULL , dissect_dlr_capability_flags } ,
{ 0x47 , FALSE , 13 , " Redundant Gateway Config " , cip_dissector_func , NULL , dissect_dlr_redundant_gateway_config } ,
{ 0x47 , FALSE , 14 , " Redundant Gateway Status " , cip_usint , & hf_dlr_redundant_gateway_status , NULL } ,
{ 0x47 , FALSE , 15 , " Active Gateway Address " , cip_dissector_func , NULL , dissect_dlr_active_gateway_address } ,
{ 0x47 , FALSE , 16 , " Actice Gateway Precedence " , cip_usint , & hf_dlr_active_gateway_precedence , NULL } ,
2011-10-26 04:55:21 +00:00
} ;
2009-06-26 02:38:23 +00:00
/*
* Protocol initialization
*/
static void
enip_init_protocol ( void )
{
if ( enip_request_hashtable )
g_hash_table_destroy ( enip_request_hashtable ) ;
enip_request_hashtable = g_hash_table_new ( enip_request_hash , enip_request_equal ) ;
if ( enip_conn_hashtable )
g_hash_table_destroy ( enip_conn_hashtable ) ;
enip_conn_hashtable = g_hash_table_new ( enip_conn_hash , enip_conn_equal ) ;
}
2004-09-23 17:34:35 +00:00
/* Disssect Common Packet Format */
2003-06-11 09:02:19 +00:00
static void
2011-04-25 01:37:19 +00:00
dissect_cpf ( enip_request_key_t * request_key , int command , tvbuff_t * tvb ,
2011-12-01 06:05:39 +00:00
packet_info * pinfo , proto_tree * tree , proto_tree * dissector_tree , int offset , guint32 ifacehndl )
2003-06-11 09:02:19 +00:00
{
2014-06-26 02:59:50 +00:00
proto_item * temp_item , * count_item , * type_item , * io_item ;
2012-04-26 16:47:37 +00:00
proto_tree * temp_tree , * count_tree , * item_tree , * sockaddr_tree , * io_tree ;
int item_count , item_length , item , io_length ;
unsigned char name_length ;
tvbuff_t * next_tvb ;
enip_request_info_t * request_info ;
enip_conn_val_t * conn_info = NULL ;
gboolean FwdOpen = FALSE ;
gboolean FwdOpenReply = FALSE ;
enum enip_connid_type connid_type = ECIDT_UNKNOWN ;
cip_safety_info_t * cip_safety ;
2012-03-02 03:39:16 +00:00
2009-06-26 02:38:23 +00:00
/* Create item count tree */
item_count = tvb_get_letohs ( tvb , offset ) ;
2011-04-25 01:37:19 +00:00
count_item = proto_tree_add_item ( tree , hf_enip_cpf_itemcount , tvb , offset , 2 , ENC_LITTLE_ENDIAN ) ;
count_tree = proto_item_add_subtree ( count_item , ett_count_tree ) ;
2003-06-11 22:36:18 +00:00
2013-11-21 18:37:26 +00:00
while ( item_count - - )
2009-06-26 02:38:23 +00:00
{
/* Add item type tree to item count tree*/
2011-04-25 01:37:19 +00:00
type_item = proto_tree_add_item ( count_tree , hf_enip_cpf_typeid , tvb , offset + 2 , 2 , ENC_LITTLE_ENDIAN ) ;
2009-06-26 02:38:23 +00:00
item_tree = proto_item_add_subtree ( type_item , ett_type_tree ) ;
2004-02-04 20:34:53 +00:00
2011-04-25 01:37:19 +00:00
/* Add length field to item type tree */
proto_tree_add_item ( item_tree , hf_enip_cpf_length , tvb , offset + 4 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 22:36:18 +00:00
2009-06-26 02:38:23 +00:00
item = tvb_get_letohs ( tvb , offset + 2 ) ;
item_length = tvb_get_letohs ( tvb , offset + 4 ) ;
2003-06-11 09:02:19 +00:00
2013-11-21 18:37:26 +00:00
if ( item_length )
2009-06-26 02:38:23 +00:00
{
2011-10-13 00:00:52 +00:00
/* Add item data field */
2003-06-11 09:02:19 +00:00
2013-11-21 18:37:26 +00:00
switch ( item )
2011-10-13 00:00:52 +00:00
{
case CONNECTION_BASED :
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Add Connection identifier */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_cpf_cai_connid , tvb , offset + 6 , 4 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2014-05-29 15:33:29 +00:00
conn_info = enip_get_explicit_connid ( pinfo , request_key , tvb_get_letohl ( tvb , offset + 6 ) ) ;
if ( request_key )
{
request_key - > type = EPDT_CONNECTED_TRANSPORT ;
request_key - > data . connected_transport . connid = ( conn_info ! = NULL ) ? conn_info - > connid : 0 ;
}
2009-06-26 02:38:23 +00:00
/* Add Connection ID to Info col */
2012-11-13 13:14:48 +00:00
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , CONID: 0x%08X " , tvb_get_letohl ( tvb , offset + 6 ) ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case UNCONNECTED_MSG :
request_info = NULL ;
if ( request_key )
{
request_key - > type = EPDT_UNCONNECTED ;
request_info = enip_match_request ( pinfo , tree , request_key ) ;
}
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Call dissector for interface */
2014-06-06 14:35:50 +00:00
next_tvb = tvb_new_subset_length ( tvb , offset + 6 , item_length ) ;
2014-05-27 02:58:48 +00:00
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO , request_info ) ;
2014-06-19 17:18:16 +00:00
if ( tvb_length_remaining ( next_tvb , 0 ) < = 0 | | ! dissector_try_uint ( subdissector_srrd_table , ifacehndl , next_tvb , pinfo , dissector_tree ) )
2009-06-26 02:38:23 +00:00
{
/* Show the undissected payload */
2014-06-19 17:18:16 +00:00
if ( tvb_length_remaining ( tvb , offset ) > 0 )
2011-12-01 06:05:39 +00:00
call_dissector ( data_handle , next_tvb , pinfo , dissector_tree ) ;
2009-06-26 02:38:23 +00:00
}
2003-06-11 09:02:19 +00:00
2011-12-01 06:05:39 +00:00
/* Check if this is a ForwardOpen packet, because special handling is needed
to handle connection conversations */
if ( ( request_info ! = NULL ) & & ( request_info - > cip_info ! = NULL ) & &
2012-03-02 03:39:16 +00:00
( request_info - > cip_info - > connInfo ! = NULL ) & &
2011-12-01 06:05:39 +00:00
( request_key ! = NULL ) & &
2012-03-02 03:39:16 +00:00
( ( ( request_info - > cip_info - > bService & 0x7F ) = = SC_CM_FWD_OPEN ) | |
( ( request_info - > cip_info - > bService & 0x7F ) = = SC_CM_LARGE_FWD_OPEN ) ) & &
2011-12-01 06:05:39 +00:00
( request_info - > cip_info - > dissector = = dissector_get_uint_handle ( subdissector_class_table , CI_CLS_CM ) ) )
{
if ( request_key - > requesttype = = ENIP_REQUEST_PACKET )
{
FwdOpen = TRUE ;
}
else
{
FwdOpenReply = TRUE ;
}
}
else
{
2014-05-27 02:58:48 +00:00
p_remove_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO ) ;
2011-12-01 06:05:39 +00:00
}
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case CONNECTION_TRANSPORT :
2003-06-11 09:02:19 +00:00
2013-11-21 18:37:26 +00:00
if ( command = = SEND_UNIT_DATA )
2009-06-26 02:38:23 +00:00
{
request_info = NULL ;
if ( request_key )
{
request_key - > type = EPDT_CONNECTED_TRANSPORT ;
request_key - > data . connected_transport . sequence = tvb_get_letohs ( tvb , offset + 6 ) ;
request_info = enip_match_request ( pinfo , tree , request_key ) ;
}
2014-05-29 15:33:29 +00:00
/* Save the connection info for the conversation filter */
if ( ( ! pinfo - > fd - > flags . visited ) & & ( conn_info ! = NULL ) )
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO , conn_info ) ;
2009-06-26 02:38:23 +00:00
/*
* * If the encapsulation service is SendUnit Data , this is a
* * encapsulated connected message
*/
2011-04-25 01:37:19 +00:00
/* Add sequence count ( Transport Class 1,2,3 ) */
proto_tree_add_item ( item_tree , hf_enip_cpf_cdi_seqcnt , tvb , offset + 6 , 2 , ENC_LITTLE_ENDIAN ) ;
2009-06-26 02:38:23 +00:00
/* Call dissector for interface */
2014-06-06 14:35:50 +00:00
next_tvb = tvb_new_subset_length ( tvb , offset + 8 , item_length - 2 ) ;
2014-05-27 02:58:48 +00:00
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO , request_info ) ;
2014-06-19 17:18:16 +00:00
if ( tvb_length_remaining ( next_tvb , 0 ) < = 0 | | ! dissector_try_uint ( subdissector_sud_table , ifacehndl , next_tvb , pinfo , dissector_tree ) )
2009-06-26 02:38:23 +00:00
{
/* Show the undissected payload */
2014-06-19 17:18:16 +00:00
if ( tvb_length_remaining ( tvb , offset ) > 0 )
2011-12-01 06:05:39 +00:00
call_dissector ( data_handle , next_tvb , pinfo , dissector_tree ) ;
2009-06-26 02:38:23 +00:00
}
2014-05-27 02:58:48 +00:00
p_remove_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO ) ;
2009-06-26 02:38:23 +00:00
}
else
{
/* Display data */
2014-06-19 17:18:16 +00:00
if ( tvb_length_remaining ( tvb , offset + 6 ) > 0 )
2011-10-13 00:00:52 +00:00
{
2014-06-06 14:35:50 +00:00
next_tvb = tvb_new_subset_length ( tvb , offset + 6 , item_length ) ;
2012-03-02 03:39:16 +00:00
if ( conn_info ! = NULL )
2011-10-13 00:00:52 +00:00
{
2012-03-02 03:39:16 +00:00
if ( conn_info - > safety . safety_seg = = TRUE )
2011-12-01 06:05:39 +00:00
{
2012-03-02 03:39:16 +00:00
/* Add any possible safety related data */
2013-08-25 14:23:13 +00:00
cip_safety = wmem_new ( wmem_file_scope ( ) , cip_safety_info_t ) ;
2012-03-02 03:39:16 +00:00
cip_safety - > conn_type = connid_type ;
cip_safety - > server_dir = ( conn_info - > TransportClass_trigger & CI_PRODUCTION_DIR_MASK ) ? TRUE : FALSE ;
cip_safety - > format = conn_info - > safety . format ;
2013-11-23 02:20:13 +00:00
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_cipsafety , 0 , cip_safety ) ;
2012-03-02 03:39:16 +00:00
call_dissector ( cipsafety_handle , next_tvb , pinfo , dissector_tree ) ;
}
else if ( conn_info - > motion = = TRUE )
{
call_dissector ( cipmotion_handle , next_tvb , pinfo , dissector_tree ) ;
2011-12-01 06:05:39 +00:00
}
else
{
io_length = item_length ;
2012-02-27 09:30:26 +00:00
if ( ( conn_info - > TransportClass_trigger & CI_TRANSPORT_CLASS_MASK ) = = 1 )
2011-12-01 06:05:39 +00:00
{
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( item_tree , hf_enip_cpf_cdi_seqcnt ,
tvb , offset + 6 + ( item_length - io_length ) , 2 , ENC_LITTLE_ENDIAN ) ;
2011-12-01 06:05:39 +00:00
io_length - = 2 ;
}
if ( ( ( connid_type = = ECIDT_O2T ) & & enip_OTrun_idle ) | |
( ( connid_type = = ECIDT_T2O ) & & enip_TOrun_idle ) )
{
2012-08-09 16:47:15 +00:00
io_item = proto_tree_add_item ( item_tree , hf_enip_cpf_cdi_32bitheader ,
tvb , offset + 6 + ( item_length - io_length ) , 4 , ENC_LITTLE_ENDIAN ) ;
2011-12-01 06:05:39 +00:00
io_tree = proto_item_add_subtree ( io_item , ett_32bitheader_tree ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( io_tree , hf_enip_cpf_cdi_32bitheader_roo ,
tvb , offset + 6 + ( item_length - io_length ) , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( io_tree , hf_enip_cpf_cdi_32bitheader_coo ,
tvb , offset + 6 + ( item_length - io_length ) , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( io_tree , hf_enip_cpf_cdi_32bitheader_run_idle ,
tvb , offset + 6 + ( item_length - io_length ) , 4 , ENC_LITTLE_ENDIAN ) ;
2011-12-01 06:05:39 +00:00
io_length - = 4 ;
}
proto_tree_add_item ( item_tree , hf_enip_connection_transport_data , tvb , offset + 6 + ( item_length - io_length ) , io_length , ENC_NA ) ;
}
2014-05-27 02:58:48 +00:00
/* Save the connection info for the conversation filter */
if ( ! pinfo - > fd - > flags . visited )
p_add_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_CONNECTION_INFO , conn_info ) ;
2011-10-13 00:00:52 +00:00
}
2012-03-02 03:39:16 +00:00
else
{
2013-11-21 18:37:26 +00:00
switch ( default_io_dissector_type )
2012-07-18 19:40:56 +00:00
{
2013-11-21 18:37:26 +00:00
case ENIP_IO_SAFETY :
call_dissector ( cipsafety_handle , next_tvb , pinfo , dissector_tree ) ;
break ;
case ENIP_IO_MOTION :
call_dissector ( cipmotion_handle , next_tvb , pinfo , dissector_tree ) ;
break ;
default :
proto_tree_add_item ( item_tree , hf_enip_connection_transport_data , tvb , offset + 6 , item_length , ENC_NA ) ;
break ;
2012-07-18 19:40:56 +00:00
}
2012-03-02 03:39:16 +00:00
}
2011-10-13 00:00:52 +00:00
}
2009-06-26 02:38:23 +00:00
} /* End of if send unit data */
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case LIST_IDENTITY_RESP :
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Encapsulation version */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_encapver , tvb , offset + 6 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket Address */
2014-06-26 02:59:50 +00:00
sockaddr_tree = proto_tree_add_subtree ( item_tree , tvb , offset + 8 , 16 , ett_sockadd , NULL , " Socket Address " ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_family */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( sockaddr_tree , hf_enip_sinfamily ,
tvb , offset + 8 , 2 , ENC_BIG_ENDIAN ) ;
2004-06-02 06:30:15 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_port */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( sockaddr_tree , hf_enip_sinport ,
tvb , offset + 10 , 2 , ENC_BIG_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_address */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( sockaddr_tree , hf_enip_sinaddr ,
tvb , offset + 12 , 4 , ENC_BIG_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_zero */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( sockaddr_tree , hf_enip_sinzero ,
2011-10-04 22:44:31 +00:00
tvb , offset + 16 , 8 , ENC_NA ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Vendor ID */
proto_tree_add_item ( item_tree , hf_enip_lir_vendor ,
2011-04-25 01:37:19 +00:00
tvb , offset + 24 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Device Type */
proto_tree_add_item ( item_tree , hf_enip_lir_devtype ,
2011-04-25 01:37:19 +00:00
tvb , offset + 26 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Product Code */
proto_tree_add_item ( item_tree , hf_enip_lir_prodcode ,
2011-04-25 01:37:19 +00:00
tvb , offset + 28 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Revision */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_lir_revision ,
tvb , offset + 30 , 2 , ENC_NA ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Status */
proto_tree_add_item ( item_tree , hf_enip_lir_status ,
2011-04-25 01:37:19 +00:00
tvb , offset + 32 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Serial Number */
proto_tree_add_item ( item_tree , hf_enip_lir_serial ,
2011-04-25 01:37:19 +00:00
tvb , offset + 34 , 4 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Product Name Length */
name_length = tvb_get_guint8 ( tvb , offset + 38 ) ;
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_lir_namelen ,
2011-10-26 04:55:21 +00:00
tvb , offset + 38 , 1 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Product Name */
proto_tree_add_item ( item_tree , hf_enip_lir_name ,
2011-10-15 18:46:26 +00:00
tvb , offset + 39 , name_length , ENC_ASCII | ENC_NA ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Append product name to info column */
2012-11-13 13:14:48 +00:00
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , %s " , tvb_format_text ( tvb , offset + 39 , name_length ) ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* State */
proto_tree_add_item ( item_tree , hf_enip_lir_state ,
2011-10-26 04:55:21 +00:00
tvb , offset + name_length + 39 , 1 , ENC_LITTLE_ENDIAN ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case SOCK_ADR_INFO_OT :
case SOCK_ADR_INFO_TO :
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_family */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_sinfamily ,
tvb , offset + 6 , 2 , ENC_BIG_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_port */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_sinport ,
tvb , offset + 8 , 2 , ENC_BIG_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_address */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_sinaddr ,
tvb , offset + 10 , 4 , ENC_BIG_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Socket address struct - sin_zero */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_sinzero ,
2011-10-04 22:44:31 +00:00
tvb , offset + 14 , 8 , ENC_NA ) ;
2011-12-01 06:05:39 +00:00
if ( ( FwdOpen = = TRUE ) | | ( FwdOpenReply = = TRUE ) )
{
2014-05-27 02:58:48 +00:00
request_info = ( enip_request_info_t * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO ) ;
2011-12-01 06:05:39 +00:00
if ( request_info ! = NULL )
{
if ( item = = SOCK_ADR_INFO_OT )
{
request_info - > cip_info - > connInfo - > O2T . port = tvb_get_ntohs ( tvb , offset + 8 ) ;
2012-11-13 13:14:48 +00:00
request_info - > cip_info - > connInfo - > O2T . ipaddress . type = AT_IPv4 ;
2013-08-25 14:23:13 +00:00
request_info - > cip_info - > connInfo - > O2T . ipaddress . data = wmem_alloc ( wmem_file_scope ( ) , sizeof ( guint32 ) ) ;
2012-11-13 13:14:48 +00:00
* ( ( guint32 * ) request_info - > cip_info - > connInfo - > O2T . ipaddress . data ) = tvb_get_ipv4 ( tvb , offset + 10 ) ;
2011-12-01 06:05:39 +00:00
}
else
{
request_info - > cip_info - > connInfo - > T2O . port = tvb_get_ntohs ( tvb , offset + 8 ) ;
2012-11-13 13:14:48 +00:00
request_info - > cip_info - > connInfo - > T2O . ipaddress . type = AT_IPv4 ;
2013-08-25 14:23:13 +00:00
request_info - > cip_info - > connInfo - > T2O . ipaddress . data = wmem_alloc ( wmem_file_scope ( ) , sizeof ( guint32 ) ) ;
2012-11-13 13:14:48 +00:00
* ( ( guint32 * ) request_info - > cip_info - > connInfo - > T2O . ipaddress . data ) = tvb_get_ipv4 ( tvb , offset + 10 ) ;
2011-12-01 06:05:39 +00:00
}
}
}
2009-06-26 02:38:23 +00:00
break ;
case SEQ_ADDRESS :
2011-12-01 06:05:39 +00:00
conn_info = enip_get_io_connid ( pinfo , tvb_get_letohl ( tvb , offset + 6 ) , & connid_type ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( item_tree , hf_enip_cpf_sai_connid , tvb , offset + 6 , 4 , ENC_LITTLE_ENDIAN ) ;
2011-12-01 06:05:39 +00:00
proto_tree_add_item ( item_tree , hf_enip_cpf_sai_seqnum , tvb , offset + 10 , 4 , ENC_LITTLE_ENDIAN ) ;
2009-06-26 02:38:23 +00:00
/* Add info to column */
2012-11-13 13:14:48 +00:00
col_add_fstr ( pinfo - > cinfo , COL_INFO , " Connection: ID=0x%08X, SEQ=%010d " ,
2009-06-26 02:38:23 +00:00
tvb_get_letohl ( tvb , offset + 6 ) ,
tvb_get_letohl ( tvb , offset + 10 ) ) ;
break ;
2004-06-02 06:30:15 +00:00
2009-06-26 02:38:23 +00:00
case LIST_SERVICES_RESP :
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Encapsulation version */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( item_tree , hf_enip_encapver , tvb , offset + 6 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Capability flags */
2011-04-25 01:37:19 +00:00
temp_item = proto_tree_add_item ( item_tree , hf_enip_lsr_capaflags , tvb , offset + 8 , 2 , ENC_LITTLE_ENDIAN ) ;
temp_tree = proto_item_add_subtree ( temp_item , ett_lsrcf ) ;
2003-06-11 09:02:19 +00:00
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( temp_tree , hf_enip_lsr_tcp , tvb , offset + 8 , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( temp_tree , hf_enip_lsr_udp , tvb , offset + 8 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Name of service */
2011-10-15 18:46:26 +00:00
proto_tree_add_item ( item_tree , hf_enip_lsr_servicename , tvb , offset + 10 , 16 , ENC_ASCII | ENC_NA ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Append service name to info column */
2012-11-13 13:14:48 +00:00
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , %s " ,
tvb_format_stringzpad ( tvb , offset + 10 , 16 ) ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
default :
2011-10-13 00:00:52 +00:00
proto_tree_add_item ( item_tree , hf_enip_cpf_data , tvb , offset + 6 , item_length , ENC_NA ) ;
2009-06-26 02:38:23 +00:00
break ;
2013-11-21 18:37:26 +00:00
} /* end of switch ( item type ) */
2009-06-26 02:38:23 +00:00
2013-11-21 18:37:26 +00:00
} /* end of if ( item length ) */
2009-06-26 02:38:23 +00:00
offset = offset + item_length + 4 ;
2013-11-21 18:37:26 +00:00
} /* end of while ( item count ) */
2003-06-11 09:02:19 +00:00
2011-12-01 06:05:39 +00:00
/* See if there is a CIP connection to establish */
if ( FwdOpenReply = = TRUE )
{
2014-05-27 02:58:48 +00:00
request_info = ( enip_request_info_t * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO ) ;
2011-12-01 06:05:39 +00:00
if ( request_info ! = NULL )
{
enip_open_cip_connection ( pinfo , request_info - > cip_info - > connInfo ) ;
}
2014-05-27 02:58:48 +00:00
p_remove_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO ) ;
2011-12-01 06:05:39 +00:00
}
else if ( FwdOpen = = TRUE )
{
2014-05-27 02:58:48 +00:00
p_remove_proto_data ( wmem_file_scope ( ) , pinfo , proto_enip , ENIP_REQUEST_INFO ) ;
2011-12-01 06:05:39 +00:00
}
2004-09-23 17:34:35 +00:00
} /* end of dissect_cpf() */
2003-06-11 09:02:19 +00:00
2013-03-14 18:58:42 +00:00
static enum enip_packet_type
2003-06-11 09:02:19 +00:00
classify_packet ( packet_info * pinfo )
{
2009-06-26 02:38:23 +00:00
/* see if nature of packets can be derived from src/dst ports */
/* if so, return as found */
if ( ( ENIP_ENCAP_PORT = = pinfo - > srcport & & ENIP_ENCAP_PORT ! = pinfo - > destport ) | |
( ENIP_ENCAP_PORT ! = pinfo - > srcport & & ENIP_ENCAP_PORT = = pinfo - > destport ) ) {
if ( ENIP_ENCAP_PORT = = pinfo - > srcport )
return ENIP_RESPONSE_PACKET ;
else if ( ENIP_ENCAP_PORT = = pinfo - > destport )
return ENIP_REQUEST_PACKET ;
}
/* else, cannot classify */
return ENIP_CANNOT_CLASSIFY ;
2003-06-11 09:02:19 +00:00
}
2004-01-27 04:43:35 +00:00
static guint
2006-10-31 09:29:07 +00:00
get_enip_pdu_len ( packet_info * pinfo _U_ , tvbuff_t * tvb , int offset )
2004-01-27 04:43:35 +00:00
{
guint16 plen ;
/*
* Get the length of the data from the encapsulation header .
*/
plen = tvb_get_letohs ( tvb , offset + 2 ) ;
/*
* That length doesn ' t include the encapsulation header itself ;
* add that in .
*/
return plen + 24 ;
}
2003-06-11 09:02:19 +00:00
/* Code to actually dissect the packets */
2013-11-09 17:46:28 +00:00
static int
dissect_enip_pdu ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2003-06-11 09:02:19 +00:00
{
2013-03-14 18:58:42 +00:00
enum enip_packet_type packet_type ;
2012-04-26 16:47:37 +00:00
guint16 encap_cmd , encap_data_length ;
const char * pkt_type_str = " " ;
guint32 ifacehndl ;
enip_request_key_t request_key ;
conversation_t * conversation ;
2003-06-11 09:02:19 +00:00
/* Set up structures needed to add the protocol subtree and manage it */
2014-06-26 02:59:50 +00:00
proto_item * ti ;
2009-06-26 02:38:23 +00:00
proto_tree * enip_tree , * header_tree = NULL , * csftree ;
2003-06-11 09:02:19 +00:00
2003-10-01 21:51:59 +00:00
/* Make entries in Protocol column and Info column on summary display */
2009-08-09 06:26:46 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " ENIP " ) ;
2009-08-09 07:36:13 +00:00
col_clear ( pinfo - > cinfo , COL_INFO ) ;
2003-10-01 21:51:59 +00:00
2004-01-27 04:43:35 +00:00
encap_cmd = tvb_get_letohs ( tvb , 0 ) ;
2009-06-26 02:38:23 +00:00
packet_type = classify_packet ( pinfo ) ;
2004-02-04 20:34:53 +00:00
2012-11-13 13:14:48 +00:00
switch ( packet_type )
2003-10-01 21:51:59 +00:00
{
2012-11-13 13:14:48 +00:00
case ENIP_REQUEST_PACKET :
2013-11-21 18:37:26 +00:00
pkt_type_str = " Req " ;
2012-11-13 13:14:48 +00:00
break ;
2003-06-11 09:02:19 +00:00
2012-11-13 13:14:48 +00:00
case ENIP_RESPONSE_PACKET :
2013-11-21 18:37:26 +00:00
pkt_type_str = " Rsp " ;
2012-11-13 13:14:48 +00:00
break ;
2004-02-04 20:34:53 +00:00
2012-11-13 13:14:48 +00:00
case ENIP_CANNOT_CLASSIFY :
default :
2013-11-21 18:37:26 +00:00
pkt_type_str = " ? " ;
2012-11-13 13:14:48 +00:00
}
2003-06-11 09:02:19 +00:00
2012-11-13 13:14:48 +00:00
/* Add encapsulation command to info column */
col_append_sep_fstr ( pinfo - > cinfo , COL_INFO , " | " , " %s (%s) " ,
val_to_str ( encap_cmd , encap_cmd_vals , " Unknown (0x%04x) " ) ,
pkt_type_str ) ;
2009-06-26 02:38:23 +00:00
/*
* We need to track some state for this protocol on a per conversation
* basis so we can do neat things like request / response tracking
*/
2010-05-13 18:28:34 +00:00
conversation = find_or_create_conversation ( pinfo ) ;
2009-06-26 02:38:23 +00:00
/*
2010-05-13 18:28:34 +00:00
* Attach that information to the conversation , and add
2009-06-26 02:38:23 +00:00
* it to the list of information structures later before dissection .
*/
memset ( & request_key , 0 , sizeof ( enip_request_key_t ) ) ;
2012-08-09 16:47:15 +00:00
request_key . requesttype = packet_type ;
request_key . type = EPDT_UNKNOWN ;
2009-06-26 02:38:23 +00:00
request_key . session_handle = tvb_get_letohl ( tvb , 4 ) ;
request_key . sender_context = tvb_get_letoh64 ( tvb , 12 ) ;
2012-08-09 16:47:15 +00:00
request_key . conversation = conversation - > index ;
2009-06-26 02:38:23 +00:00
encap_data_length = tvb_get_letohs ( tvb , 2 ) ;
enip_tree = NULL ;
2012-08-09 16:47:15 +00:00
2003-10-01 21:51:59 +00:00
if ( tree ) {
2003-06-11 09:02:19 +00:00
/* create display subtree for the protocol */
2011-04-25 01:37:19 +00:00
ti = proto_tree_add_item ( tree , proto_enip , tvb , 0 , - 1 , ENC_NA ) ;
2003-06-11 09:02:19 +00:00
2004-09-23 17:34:35 +00:00
enip_tree = proto_item_add_subtree ( ti , ett_enip ) ;
2003-06-11 09:02:19 +00:00
/* Add encapsulation header tree */
2014-06-26 02:59:50 +00:00
header_tree = proto_tree_add_subtree ( enip_tree , tvb , 0 , 24 , ett_enip , NULL , " Encapsulation Header " ) ;
2003-06-11 09:02:19 +00:00
2004-09-23 17:34:35 +00:00
/* Add EtherNet/IP encapsulation header */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( header_tree , hf_enip_command , tvb , 0 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
encap_data_length = tvb_get_letohs ( tvb , 2 ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( header_tree , hf_enip_length , tvb , 2 , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( header_tree , hf_enip_session , tvb , 4 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( header_tree , hf_enip_status , tvb , 8 , 4 , ENC_LITTLE_ENDIAN ) ;
2012-11-29 20:15:37 +00:00
if ( ( encap_cmd = = LIST_IDENTITY ) & &
2012-11-13 13:14:48 +00:00
/* Length of 0 probably indicates a request */
( ( encap_data_length = = 0 ) | | ( packet_type = = ENIP_REQUEST_PACKET ) ) )
{
proto_tree_add_item ( header_tree , hf_enip_listid_delay , tvb , 12 , 2 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( header_tree , hf_enip_sendercontex , tvb , 14 , 6 , ENC_NA ) ;
}
else
{
proto_tree_add_item ( header_tree , hf_enip_sendercontex , tvb , 12 , 8 , ENC_NA ) ;
}
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( header_tree , hf_enip_options , tvb , 20 , 4 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2004-09-23 17:34:35 +00:00
/* Append session and command to the protocol tree */
proto_item_append_text ( ti , " , Session: 0x%08X, %s " , tvb_get_letohl ( tvb , 4 ) ,
val_to_str ( encap_cmd , encap_cmd_vals , " Unknown (0x%04x) " ) ) ;
2003-06-11 09:02:19 +00:00
2012-08-09 16:47:15 +00:00
} /* end of tree */
2004-02-04 20:34:53 +00:00
2012-08-09 16:47:15 +00:00
/*
* * For some commands we want to add some info to the info column
*/
2013-11-21 18:37:26 +00:00
switch ( encap_cmd )
2012-08-09 16:47:15 +00:00
{
2013-11-21 18:37:26 +00:00
case REGISTER_SESSION :
case UNREGISTER_SESSION :
col_append_fstr ( pinfo - > cinfo , COL_INFO , " , Session: 0x%08X " ,
tvb_get_letohl ( tvb , 4 ) ) ;
break ;
2012-11-13 13:14:48 +00:00
}
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Command specific data - create tree */
2013-11-21 18:37:26 +00:00
if ( encap_data_length )
2009-06-26 02:38:23 +00:00
{
/* The packet have some command specific data, buid a sub tree for it */
2003-06-11 09:02:19 +00:00
2014-06-26 02:59:50 +00:00
csftree = proto_tree_add_subtree ( enip_tree , tvb , 24 , encap_data_length ,
ett_command_tree , NULL , " Command Specific Data " ) ;
2003-06-11 09:02:19 +00:00
2013-11-21 18:37:26 +00:00
switch ( encap_cmd )
2009-06-26 02:38:23 +00:00
{
case NOP :
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case LIST_SERVICES :
2011-12-01 06:05:39 +00:00
dissect_cpf ( & request_key , encap_cmd , tvb , pinfo , csftree , tree , 24 , 0 ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case LIST_IDENTITY :
2011-12-01 06:05:39 +00:00
dissect_cpf ( & request_key , encap_cmd , tvb , pinfo , csftree , tree , 24 , 0 ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case LIST_INTERFACES :
2011-12-01 06:05:39 +00:00
dissect_cpf ( & request_key , encap_cmd , tvb , pinfo , csftree , tree , 24 , 0 ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case REGISTER_SESSION :
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( csftree , hf_enip_rs_version , tvb , 24 , 2 , ENC_LITTLE_ENDIAN ) ;
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( csftree , hf_enip_rs_optionflags , tvb , 26 , 2 , ENC_LITTLE_ENDIAN ) ;
2009-06-26 02:38:23 +00:00
break ;
2004-09-23 17:34:35 +00:00
2009-06-26 02:38:23 +00:00
case UNREGISTER_SESSION :
break ;
2004-09-23 17:34:35 +00:00
2009-06-26 02:38:23 +00:00
case SEND_RR_DATA :
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( csftree , hf_enip_srrd_ifacehnd , tvb , 24 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( csftree , hf_enip_timeout , tvb , 28 , 2 , ENC_LITTLE_ENDIAN ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
ifacehndl = tvb_get_letohl ( tvb , 24 ) ;
2011-12-01 06:05:39 +00:00
dissect_cpf ( & request_key , encap_cmd , tvb , pinfo , csftree , tree , 30 , ifacehndl ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case SEND_UNIT_DATA :
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( csftree , hf_enip_sud_ifacehnd , tvb , 24 , 4 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( csftree , hf_enip_timeout , tvb , 28 , 2 , ENC_LITTLE_ENDIAN ) ;
2009-06-19 05:45:40 +00:00
2009-06-26 02:38:23 +00:00
ifacehndl = tvb_get_letohl ( tvb , 24 ) ;
2011-12-01 06:05:39 +00:00
dissect_cpf ( & request_key , encap_cmd , tvb , pinfo , csftree , tree , 30 , ifacehndl ) ;
2009-06-26 02:38:23 +00:00
break ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
case INDICATE_STATUS :
case CANCEL :
default :
/* Can not decode - Just show the data */
2011-10-13 00:00:52 +00:00
proto_tree_add_item ( header_tree , hf_enip_encap_data , tvb , 24 , encap_data_length , ENC_NA ) ;
2009-06-26 02:38:23 +00:00
break ;
2009-06-19 06:15:52 +00:00
2013-11-21 18:37:26 +00:00
} /* end of switch () */
2003-06-11 09:02:19 +00:00
2013-11-21 18:37:26 +00:00
} /* end of if ( encapsulated data ) */
2013-11-09 17:46:28 +00:00
2014-06-19 17:18:16 +00:00
return tvb_length ( tvb ) ;
2004-09-23 17:34:35 +00:00
} /* end of dissect_enip_pdu() */
2004-01-27 04:43:35 +00:00
static int
2013-11-09 17:46:28 +00:00
dissect_enip_udp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data )
2004-01-27 04:43:35 +00:00
{
guint16 encap_cmd ;
/* An ENIP packet is at least 4 bytes long - we need the command type. */
2009-06-26 02:38:23 +00:00
if ( ! tvb_bytes_exist ( tvb , 0 , 4 ) )
2004-01-27 04:43:35 +00:00
return 0 ;
/* Get the command type and see if it's valid. */
encap_cmd = tvb_get_letohs ( tvb , 0 ) ;
2013-03-29 00:26:23 +00:00
if ( try_val_to_str ( encap_cmd , encap_cmd_vals ) = = NULL )
2009-06-26 02:38:23 +00:00
return 0 ; /* not a known command */
2003-08-16 01:53:41 +00:00
2013-11-09 17:46:28 +00:00
return dissect_enip_pdu ( tvb , pinfo , tree , data ) ;
2004-01-27 04:43:35 +00:00
}
static int
2013-11-09 17:46:28 +00:00
dissect_enip_tcp ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data )
2004-01-27 04:43:35 +00:00
{
guint16 encap_cmd ;
2003-06-11 09:02:19 +00:00
2004-01-27 04:43:35 +00:00
/* An ENIP packet is at least 4 bytes long - we need the command type. */
2009-06-26 02:38:23 +00:00
if ( ! tvb_bytes_exist ( tvb , 0 , 4 ) )
2004-01-27 04:43:35 +00:00
return 0 ;
/* Get the command type and see if it's valid. */
encap_cmd = tvb_get_letohs ( tvb , 0 ) ;
2013-03-29 00:26:23 +00:00
if ( try_val_to_str ( encap_cmd , encap_cmd_vals ) = = NULL )
2009-06-26 02:38:23 +00:00
return 0 ; /* not a known command */
2004-01-27 04:43:35 +00:00
2013-11-09 17:46:28 +00:00
tcp_dissect_pdus ( tvb , pinfo , tree , enip_desegment , 4 , get_enip_pdu_len , dissect_enip_pdu , data ) ;
2014-06-19 17:18:16 +00:00
return tvb_length ( tvb ) ;
2004-01-27 04:43:35 +00:00
}
2003-06-11 09:02:19 +00:00
/* Code to actually dissect the io packets*/
2009-06-26 02:38:23 +00:00
static void
2003-06-11 09:02:19 +00:00
dissect_enipio ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree )
{
/* Set up structures needed to add the protocol subtree and manage it */
2009-06-26 02:38:23 +00:00
proto_item * ti ;
proto_tree * enip_tree ;
2009-06-19 06:15:52 +00:00
2003-06-11 09:02:19 +00:00
/* Make entries in Protocol column and Info column on summary display */
2009-08-09 06:26:46 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " ENIP " ) ;
2003-06-11 09:02:19 +00:00
/* In the interest of speed, if "tree" is NULL, don't do any work not
necessary to generate protocol tree items . */
2012-08-09 16:47:15 +00:00
/* create display subtree for the protocol */
ti = proto_tree_add_item ( tree , proto_enip , tvb , 0 , - 1 , ENC_NA ) ;
2003-08-16 01:53:41 +00:00
2012-08-09 16:47:15 +00:00
enip_tree = proto_item_add_subtree ( ti , ett_enip ) ;
dissect_cpf ( NULL , 0xFFFF , tvb , pinfo , enip_tree , tree , 0 , 0 ) ;
2008-10-23 21:01:04 +00:00
2003-08-16 01:53:41 +00:00
} /* end of dissect_enipio() */
2003-06-11 09:02:19 +00:00
2009-07-09 20:44:28 +00:00
static gboolean
2012-09-10 21:40:21 +00:00
dissect_dlr ( tvbuff_t * tvb , packet_info * pinfo , proto_tree * tree , void * data _U_ )
2009-07-09 20:44:28 +00:00
{
proto_item * ti ;
2014-06-26 02:59:50 +00:00
proto_tree * dlr_tree ;
2009-07-09 20:44:28 +00:00
guint8 dlr_subtype ;
guint8 dlr_protover ;
guint8 dlr_frametype ;
/* Make entries in Protocol column and Info column on summary display */
2009-08-09 06:47:24 +00:00
col_set_str ( pinfo - > cinfo , COL_PROTOCOL , " DLR " ) ;
2009-07-09 20:44:28 +00:00
2009-08-09 07:36:13 +00:00
col_clear ( pinfo - > cinfo , COL_INFO ) ;
2009-07-09 20:44:28 +00:00
2014-06-26 02:59:50 +00:00
/* Create display subtree for the protocol */
ti = proto_tree_add_item ( tree , proto_dlr , tvb , 0 , - 1 , ENC_NA ) ;
dlr_tree = proto_item_add_subtree ( ti , ett_dlr ) ;
2009-07-09 20:44:28 +00:00
/* Get values for the Common Frame Header Format */
dlr_subtype = tvb_get_guint8 ( tvb , DLR_CFH_SUB_TYPE ) ;
dlr_protover = tvb_get_guint8 ( tvb , DLR_CFH_PROTO_VERSION ) ;
/* Dissect the Common Frame Header Format */
2012-08-09 16:47:15 +00:00
proto_tree_add_uint ( dlr_tree , hf_dlr_ringsubtype , tvb , DLR_CFH_SUB_TYPE , 1 , dlr_subtype ) ;
2009-07-09 20:44:28 +00:00
proto_tree_add_uint ( dlr_tree , hf_dlr_ringprotoversion , tvb , DLR_CFH_PROTO_VERSION , 1 , dlr_protover ) ;
/* Get values for the DLR Message Payload Fields */
dlr_frametype = tvb_get_guint8 ( tvb , DLR_MPF_FRAME_TYPE ) ;
/* Dissect the DLR Message Payload Fields */
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_frametype , tvb , DLR_MPF_FRAME_TYPE , 1 , ENC_BIG_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_sourceport , tvb , DLR_MPF_SOURCE_PORT , 1 , ENC_BIG_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_sourceip , tvb , DLR_MPF_SOURCE_IP , 4 , ENC_BIG_ENDIAN ) ;
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_sequenceid , tvb , DLR_MPF_SEQUENCE_ID , 4 , ENC_BIG_ENDIAN ) ;
2009-07-09 20:44:28 +00:00
/* Add frame type to col info */
2012-11-29 20:15:37 +00:00
col_add_fstr ( pinfo - > cinfo , COL_INFO , " %s " ,
2012-11-13 13:14:48 +00:00
val_to_str ( dlr_frametype , dlr_frame_type_vals , " Unknown (0x%04x) " ) ) ;
2009-07-09 20:44:28 +00:00
2013-11-21 18:37:26 +00:00
if ( dlr_frametype = = DLR_FT_BEACON )
2009-07-09 20:44:28 +00:00
{
/* Beacon */
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_ringstate , tvb , DLR_BE_RING_STATE , 1 , ENC_BIG_ENDIAN ) ;
2011-10-26 04:55:21 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_supervisorprecedence , tvb , DLR_BE_SUPERVISOR_PRECEDENCE , 1 , ENC_BIG_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_beaconinterval , tvb , DLR_BE_BEACON_INTERVAL , 4 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_beacontimeout , tvb , DLR_BE_BEACON_TIMEOUT , 4 , ENC_BIG_ENDIAN ) ;
2014-04-06 14:57:33 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_beaconreserved , tvb , DLR_BE_RESERVED , 20 , ENC_NA ) ;
2009-07-09 20:44:28 +00:00
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_NEIGHBOR_REQ )
2009-07-09 20:44:28 +00:00
{
/* Neighbor_Check_Request */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_nreqreserved , tvb , DLR_NREQ_RESERVED , 30 , ENC_NA ) ;
2009-07-09 20:44:28 +00:00
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_NEIGHBOR_RES )
2009-07-09 20:44:28 +00:00
{
/* Neighbor_Check_Response */
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_nressourceport , tvb , DLR_NRES_SOURCE_PORT , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_nresreserved , tvb , DLR_NRES_RESERVED , 29 , ENC_NA ) ;
2009-07-09 20:44:28 +00:00
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_LINK_STAT )
2009-07-09 20:44:28 +00:00
{
/* Link_Status/Neighbor_Status */
2013-04-04 14:34:26 +00:00
proto_item * flag_item ;
proto_tree * flag_tree ;
flag_item = proto_tree_add_item ( dlr_tree , hf_dlr_lnknbrstatus , tvb , DLR_LNS_SOURCE_PORT , 1 , ENC_BIG_ENDIAN ) ;
flag_tree = proto_item_add_subtree ( flag_item , ett_dlr_lnknbrstatus_flags ) ;
proto_tree_add_item ( flag_tree , hf_dlr_lnknbrstatus_port1 , tvb , DLR_LNS_SOURCE_PORT , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_lnknbrstatus_port2 , tvb , DLR_LNS_SOURCE_PORT , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_lnknbrstatus_reserved , tvb , DLR_LNS_SOURCE_PORT , 1 , ENC_LITTLE_ENDIAN ) ;
proto_tree_add_item ( flag_tree , hf_dlr_lnknbrstatus_frame_type , tvb , DLR_LNS_SOURCE_PORT , 1 , ENC_LITTLE_ENDIAN ) ;
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_lnknbrreserved , tvb , DLR_LNS_RESERVED , 29 , ENC_NA ) ;
2009-07-09 20:44:28 +00:00
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_LOCATE_FLT )
2009-07-09 20:44:28 +00:00
{
/* Locate_Fault */
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_lfreserved , tvb , DLR_LF_RESERVED , 30 , ENC_NA ) ;
2009-07-09 20:44:28 +00:00
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_ANNOUNCE )
2009-07-09 20:44:28 +00:00
{
/* Announce */
2012-08-09 16:47:15 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_ringstate , tvb , DLR_AN_RING_STATE , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_anreserved , tvb , DLR_AN_RESERVED , 29 , ENC_NA ) ;
2009-07-09 20:44:28 +00:00
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_SIGN_ON )
2009-07-09 20:44:28 +00:00
{
guint16 nCnt ;
guint16 nNumNodes ;
guint16 nOffset ;
/* Sign_On */
nNumNodes = tvb_get_ntohs ( tvb , DLR_SO_NUM_NODES ) ;
proto_tree_add_uint ( dlr_tree , hf_dlr_sonumnodes , tvb , DLR_SO_NUM_NODES , 2 , nNumNodes ) ;
/* Add each node in the list */
for ( nCnt = 0 , nOffset = DLR_SO_NODE_1_MAC ; nCnt < nNumNodes ; nCnt + + )
{
2011-10-20 14:07:54 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_somac , tvb , nOffset , 6 , ENC_NA ) ;
2009-07-09 20:44:28 +00:00
nOffset + = 6 ;
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_soip , tvb , nOffset , 4 , ENC_BIG_ENDIAN ) ;
2009-07-09 20:44:28 +00:00
nOffset + = 4 ;
}
2013-11-21 18:37:26 +00:00
if ( nOffset < 42 )
2009-07-09 20:44:28 +00:00
{
2011-04-25 01:37:19 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_soreserved , tvb , nOffset , 42 - nOffset , ENC_NA ) ;
2012-01-04 17:42:10 +00:00
/* nOffset += (42 - nOffset); */
2009-07-09 20:44:28 +00:00
}
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_ADVERTISE )
2013-04-04 14:34:26 +00:00
{
/* Advertise */
proto_tree_add_item ( dlr_tree , hf_dlr_advgatewaystate , tvb , DLR_ADV_GATEWAY_STATE , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_advgatewayprecedence , tvb , DLR_ADV_GATEWAY_PRECEDENCE , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_advadvertiseinterval , tvb , DLR_ADV_ADVERTISE_INTERVAL , 4 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_advadvertisetimeout , tvb , DLR_ADV_ADVERTISE_TIMEOUT , 4 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_advlearningupdateenable , tvb , DLR_ADV_LEARNING_UPDATE_ENABLE , 1 , ENC_BIG_ENDIAN ) ;
2013-09-12 20:34:19 +00:00
proto_tree_add_item ( dlr_tree , hf_dlr_advreserved , tvb , DLR_ADV_RESERVED , 19 , ENC_NA ) ;
2013-04-04 14:34:26 +00:00
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_FLUSH_TABLES )
2013-04-04 14:34:26 +00:00
{
proto_tree_add_item ( dlr_tree , hf_dlr_flushlearningupdateenable , tvb , DLR_FLUSH_LEARNING_UPDATE_ENABLE , 1 , ENC_BIG_ENDIAN ) ;
proto_tree_add_item ( dlr_tree , hf_dlr_flushreserved , tvb , DLR_FLUSH_RESERVED , 29 , ENC_NA ) ;
}
2013-11-21 18:37:26 +00:00
else if ( dlr_frametype = = DLR_FT_LEARNING_UPDATE )
2013-04-04 14:34:26 +00:00
{
proto_tree_add_item ( dlr_tree , hf_dlr_learnreserved , tvb , DLR_LEARN_RESERVED , 34 , ENC_NA ) ;
}
2009-07-09 20:44:28 +00:00
else
{
/* Unknown Frame type */
}
2014-06-19 17:18:16 +00:00
return tvb_length ( tvb ) ;
2009-07-09 20:44:28 +00:00
} /* end of dissect_dlr() */
2006-05-21 04:49:01 +00:00
/* Register the protocol with Wireshark */
2003-06-11 09:02:19 +00:00
/* this format is require because a script is used to build the C function
that calls all the protocol registration .
*/
void
2004-09-23 17:34:35 +00:00
proto_register_enip ( void )
2003-06-11 09:02:19 +00:00
{
2004-09-23 17:34:35 +00:00
/* Setup list of header fields */
2009-06-26 02:38:23 +00:00
static hf_register_info hf [ ] = {
2012-04-26 16:47:37 +00:00
{ & hf_enip_command ,
{ " Command " , " enip.command " ,
FT_UINT16 , BASE_HEX , VALS ( encap_cmd_vals ) , 0 ,
" Encapsulation command " , HFILL } } ,
{ & hf_enip_length ,
{ " Length " , " enip.length " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Encapsulation length " , HFILL } } ,
{ & hf_enip_session ,
{ " Session Handle " , " enip.session " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
" Session identification " , HFILL } } ,
{ & hf_enip_status ,
{ " Status " , " enip.status " ,
FT_UINT32 , BASE_HEX , VALS ( encap_status_vals ) , 0 ,
" Status code " , HFILL } } ,
{ & hf_enip_sendercontex ,
{ " Sender Context " , " enip.context " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
2012-08-09 16:47:15 +00:00
" Information pertinent to the sender " , HFILL } } ,
2012-04-26 16:47:37 +00:00
2012-11-13 13:14:48 +00:00
{ & hf_enip_listid_delay ,
{ " Max Response Delay " , " enip.listid_delay " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Maximum random delay allowed by target " , HFILL } } ,
2012-04-26 16:47:37 +00:00
{ & hf_enip_options ,
{ " Options " , " enip.options " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
" Options flags " , HFILL } } ,
{ & hf_enip_encapver ,
{ " Encapsulation Version " , " enip.encapver " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_enip_sinfamily ,
{ " sin_family " , " enip.sinfamily " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Socket Address.Sin Family " , HFILL } } ,
{ & hf_enip_sinport ,
{ " sin_port " , " enip.sinport " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Socket Address.Sin Port " , HFILL } } ,
{ & hf_enip_sinaddr ,
{ " sin_addr " , " enip.sinaddr " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
" Socket Address.Sin Addr " , HFILL } } ,
{ & hf_enip_sinzero ,
{ " sin_zero " , " enip.sinzero " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Socket Address.Sin Zero " , HFILL } } ,
{ & hf_enip_timeout ,
{ " Timeout " , " enip.timeout " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Encapsulation Timeout " , HFILL } } ,
{ & hf_enip_encap_data ,
{ " Encap Data " , " enip.encap_data " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Encapsulation Data " , HFILL } } ,
2011-04-25 01:37:19 +00:00
/* List Services Reply */
2012-04-26 16:47:37 +00:00
{ & hf_enip_lsr_capaflags ,
{ " Capability Flags " , " enip.lsr.capaflags " ,
FT_UINT16 , BASE_HEX , NULL , 0 ,
" ListServices Reply: Capability Flags " , HFILL } } ,
{ & hf_enip_lsr_tcp ,
{ " Supports CIP Encapsulation via TCP " , " enip.lsr.capaflags.tcp " ,
FT_BOOLEAN , 16 , TFS ( & tfs_true_false ) , 0x0020 ,
" ListServices Reply: Supports CIP Encapsulation via TCP " , HFILL } } ,
{ & hf_enip_lsr_udp ,
{ " Supports CIP Class 0 or 1 via UDP " , " enip.lsr.capaflags.udp " ,
FT_BOOLEAN , 16 , TFS ( & tfs_true_false ) , 0x0100 ,
" ListServices Reply: Supports CIP Class 0 or 1 via UDP " , HFILL } } ,
{ & hf_enip_lsr_servicename ,
{ " Name of Service " , " enip.lsr.servicename " ,
FT_STRING , BASE_NONE , NULL , 0 ,
" ListServices Reply: Name of Service " , HFILL } } ,
2011-04-25 01:37:19 +00:00
/* Register Session */
2012-04-26 16:47:37 +00:00
{ & hf_enip_rs_version ,
{ " Protocol Version " , " enip.rs.version " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Register Session: Protocol Version " , HFILL } } ,
{ & hf_enip_rs_optionflags ,
{ " Option Flags " , " enip.rs.flags " ,
FT_UINT16 , BASE_HEX , NULL , 0 ,
" Register Session: Option Flags " , HFILL } } ,
2009-06-26 02:38:23 +00:00
/* Send Request/Reply Data */
2012-04-26 16:47:37 +00:00
{ & hf_enip_srrd_ifacehnd ,
{ " Interface Handle " , " enip.srrd.iface " ,
FT_UINT32 , BASE_HEX , VALS ( enip_interface_handle_vals ) , 0 ,
" SendRRData: Interface handle " , HFILL } } ,
2009-06-26 02:38:23 +00:00
/* Send Unit Data */
2012-04-26 16:47:37 +00:00
{ & hf_enip_sud_ifacehnd ,
{ " Interface Handle " , " enip.sud.iface " ,
FT_UINT32 , BASE_HEX , VALS ( enip_interface_handle_vals ) , 0 ,
" SendUnitData: Interface handle " , HFILL } } ,
2009-06-26 02:38:23 +00:00
/* List identity reply */
2012-04-26 16:47:37 +00:00
{ & hf_enip_lir_vendor ,
{ " Vendor ID " , " enip.lir.vendor " ,
FT_UINT16 , BASE_HEX | BASE_EXT_STRING , & cip_vendor_vals_ext , 0 ,
" ListIdentity Reply: Vendor ID " , HFILL } } ,
{ & hf_enip_lir_devtype ,
{ " Device Type " , " enip.lir.devtype " ,
FT_UINT16 , BASE_DEC | BASE_EXT_STRING , & cip_devtype_vals_ext , 0 ,
" ListIdentity Reply: Device Type " , HFILL } } ,
{ & hf_enip_lir_prodcode ,
{ " Product Code " , " enip.lir.prodcode " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" ListIdentity Reply: Product Code " , HFILL } } ,
{ & hf_enip_lir_revision ,
{ " Revision " , " enip.lir.revision " ,
FT_UINT16 , BASE_CUSTOM , enip_fmt_lir_revision , 0 ,
" ListIdentity Reply: Revision " , HFILL } } ,
{ & hf_enip_lir_status ,
{ " Status " , " enip.lir.status " ,
FT_UINT16 , BASE_HEX , NULL , 0 ,
" ListIdentity Reply: Status " , HFILL } } ,
{ & hf_enip_lir_serial ,
{ " Serial Number " , " enip.lir.serial " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
" ListIdentity Reply: Serial Number " , HFILL } } ,
{ & hf_enip_lir_namelen ,
{ " Product Name Length " , " enip.lir.namelen " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
" ListIdentity Reply: Product Name Length " , HFILL } } ,
{ & hf_enip_lir_name ,
{ " Product Name " , " enip.lir.name " ,
FT_STRING , BASE_NONE , NULL , 0 ,
" ListIdentity Reply: Product Name " , HFILL } } ,
{ & hf_enip_lir_state ,
{ " State " , " enip.lir.state " ,
FT_UINT8 , BASE_HEX , NULL , 0 ,
" ListIdentity Reply: State " , HFILL } } ,
2009-06-26 02:38:23 +00:00
/* Common Packet Format */
2012-04-26 16:47:37 +00:00
{ & hf_enip_cpf_itemcount ,
{ " Item Count " , " enip.cpf.itemcount " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Common Packet Format: Item Count " , HFILL } } ,
{ & hf_enip_cpf_typeid ,
{ " Type ID " , " enip.cpf.typeid " ,
FT_UINT16 , BASE_HEX , VALS ( cdf_type_vals ) , 0 ,
" Common Packet Format: Type of encapsulated item " , HFILL } } ,
{ & hf_enip_cpf_length ,
{ " Length " , " enip.cpf.length " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Common Packet Format: Length " , HFILL } } ,
2011-04-25 01:37:19 +00:00
/* Connected Data Item */
2012-04-26 16:47:37 +00:00
{ & hf_enip_cpf_cdi_seqcnt ,
{ " Sequence Count " , " enip.cpf.cdi.seqcnt " ,
FT_UINT16 , BASE_HEX , NULL , 0 ,
" Common Packet Format: Connected Data Item, Sequence Count " , HFILL } } ,
{ & hf_enip_cpf_cdi_32bitheader ,
{ " 32-bit Header " , " enip.cpf.cdi.32bitheader " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
" Common Packet Format: Connected Data Item, 32-bit Header " , HFILL } } ,
{ & hf_enip_cpf_cdi_32bitheader_roo ,
{ " ROO " , " enip.cpf.cdi.roo " ,
FT_UINT32 , BASE_HEX , NULL , 0xC ,
" Common Packet Format: Connected Data Item, Ready for Ownership of Outputs " , HFILL } } ,
{ & hf_enip_cpf_cdi_32bitheader_coo ,
{ " COO " , " enip.cpf.cdi.coo " ,
FT_UINT32 , BASE_HEX , NULL , 0x2 ,
" Common Packet Format: Connected Data Item, Claim Output Ownership " , HFILL } } ,
{ & hf_enip_cpf_cdi_32bitheader_run_idle ,
{ " Run/Idle " , " enip.cpf.cdi.run_idle " ,
FT_UINT32 , BASE_HEX , VALS ( enip_run_idle_vals ) , 0x1 ,
" Common Packet Format: Connected Data Item, Run/Idle " , HFILL } } ,
2011-04-25 01:37:19 +00:00
/* Connection Address Item */
2012-04-26 16:47:37 +00:00
{ & hf_enip_cpf_cai_connid ,
{ " Connection ID " , " enip.cpf.cai.connid " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
" Common Packet Format: Connection Address Item, Connection Identifier " , HFILL } } ,
2009-06-26 02:38:23 +00:00
/* Sequenced Address Type */
2012-04-26 16:47:37 +00:00
{ & hf_enip_cpf_sai_connid ,
{ " Connection ID " , " enip.cpf.sai.connid " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
" Common Packet Format: Sequenced Address Item, Connection Identifier " , HFILL } } ,
{ & hf_enip_cpf_sai_seqnum ,
{ " Sequence Number " , " enip.cpf.sai.seq " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
" Common Packet Format: Sequenced Address Item, Sequence Number " , HFILL } } ,
{ & hf_enip_cpf_data ,
{ " Data " , " enip.cpf.data " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Common Packet Format: Unknown Data " , HFILL } } ,
2009-06-26 02:38:23 +00:00
/* Request/Response Matching */
2012-04-26 16:47:37 +00:00
{ & hf_enip_response_in ,
{ " Response In " , " enip.response_in " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x0 ,
" The response to this ENIP request is in this frame " , HFILL } } ,
{ & hf_enip_response_to ,
{ " Request In " , " enip.response_to " ,
FT_FRAMENUM , BASE_NONE , NULL , 0x0 ,
" This is a response to the ENIP request in this frame " , HFILL } } ,
{ & hf_enip_time ,
{ " Time " , " enip.time " ,
FT_RELATIVE_TIME , BASE_NONE , NULL , 0x0 ,
" The time between the Call and the Reply " , HFILL } } ,
{ & hf_enip_connection_transport_data ,
{ " Data " , " enip.connection_transport_data " ,
FT_BYTES , BASE_NONE , NULL , 0x0 ,
" Connection Transport Data " , HFILL } } ,
{ & hf_tcpip_status ,
{ " Status " , " cip.tcpip.status " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_status_interface_config ,
{ " Interface Configuration Status " , " cip.tcpip.status.interface_config " ,
2014-05-28 00:33:22 +00:00
FT_UINT32 , BASE_DEC , VALS ( enip_tcpip_status_interface_config_vals ) , 0x0000000F ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_tcpip_status_mcast_pending ,
{ " MCast Pending " , " cip.tcpip.status.mcast_pending " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000010 ,
NULL , HFILL } } ,
{ & hf_tcpip_status_interface_config_pending ,
{ " Interface Configuration Pending " , " cip.tcpip.status.interface_config_pending " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000020 ,
NULL , HFILL } } ,
{ & hf_tcpip_status_acd ,
{ " ACD Status " , " cip.tcpip.status.acd " ,
2014-05-28 00:33:22 +00:00
FT_UINT32 , BASE_DEC , VALS ( enip_tcpip_status_acd_vals ) , 0x00000040 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_tcpip_status_reserved ,
{ " Reserved " , " cip.tcpip.status.reserved " ,
FT_UINT32 , BASE_HEX , NULL , 0xFFFFFF80 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap ,
{ " Configuration Capability " , " cip.tcpip.config_cap " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_bootp ,
{ " BOOTP Client " , " cip.tcpip.config_cap.bootp " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000001 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_dns ,
{ " DNS Client " , " cip.tcpip.config_cap.dns " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000002 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_dhcp ,
{ " DHCP Client " , " cip.tcpip.config_cap.dhcp " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000004 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_dhcp_dns_update ,
{ " DHCP-DNS Update " , " cip.tcpip.config_cap.dhcp_dns_update " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000008 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_config_settable ,
{ " Configuration Settable " , " cip.tcpip.config_cap.config_settable " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000010 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_hardware_config ,
{ " Hardware Configurable " , " cip.tcpip.config_cap.hardware_config " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000020 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_interface_reset ,
{ " Interface Configuration Change Requires Reset " , " cip.tcpip.config_cap.interface_reset " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000040 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_acd ,
{ " ACD Capable " , " cip.tcpip.config_cap.acd " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000080 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_cap_reserved ,
{ " Reserved " , " cip.tcpip.config_cap.reserved " ,
FT_UINT32 , BASE_HEX , NULL , 0xFFFFFF00 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_control ,
{ " Configuration Control " , " cip.tcpip.config_control " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_control_config ,
{ " Configuration Method " , " cip.tcpip.config_control.config " ,
2014-05-28 00:33:22 +00:00
FT_UINT32 , BASE_DEC , VALS ( enip_tcpip_config_control_config_vals ) , 0x0000000F ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_tcpip_config_control_dns ,
{ " DNS Enable " , " cip.tcpip.config_control.dns " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000010 ,
NULL , HFILL } } ,
{ & hf_tcpip_config_control_reserved ,
{ " Reserved " , " cip.tcpip.config_control.reserved " ,
FT_UINT32 , BASE_HEX , NULL , 0xFFFFFFE0 ,
NULL , HFILL } } ,
{ & hf_tcpip_physical_link_size ,
{ " Size " , " cip.tcpip.physical_link_size " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_ic_ip_addr ,
{ " IP Address " , " cip.tcpip.ip_addr " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_ic_subnet_mask ,
{ " Subnet Mask " , " cip.tcpip.subnet_mask " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_ic_gateway ,
{ " Gateway " , " cip.tcpip.gateway " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_ic_name_server ,
{ " Name Server " , " cip.tcpip.name_server " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_ic_name_server2 ,
{ " Name Server2 " , " cip.tcpip.name_server2 " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_ic_domain_name ,
{ " Domain Name " , " cip.tcpip.domain_name " ,
FT_STRING , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_hostname ,
{ " Hostname " , " cip.tcpip.hostname " ,
FT_STRING , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_ttl_value ,
{ " TTL Value " , " cip.tcpip.ttl_value " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_mcast_alloc ,
{ " Alloc Control " , " cip.tcpip.mcast.alloc " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_tcpip_mcast_alloc_vals ) , 0 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_tcpip_mcast_reserved ,
{ " Reserved " , " cip.tcpip.mcast.reserved " ,
FT_UINT8 , BASE_HEX , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_mcast_num_mcast ,
{ " Num MCast " , " cip.tcpip.mcast.num_mcast " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_mcast_addr_start ,
{ " MCast Start Addr " , " cip.tcpip.mcast.addr_start " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_select_acd ,
{ " Select ACD " , " cip.tcpip.select_acd " ,
FT_BOOLEAN , BASE_NONE , TFS ( & tfs_enabled_disabled ) , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_lcd_acd_activity ,
{ " ACD Activity " , " cip.tcpip.last_conflict.acd_activity " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_tcpip_acd_activity_vals ) , 0 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_tcpip_lcd_remote_mac ,
{ " RemoteMAC " , " cip.tcpip.last_conflict.remote_mac " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_lcd_arp_pdu ,
{ " Arp PDU " , " cip.tcpip.last_conflict.arp_pdu " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_tcpip_quick_connect ,
{ " Ethernet/IP Quick Connection " , " cip.tcpip.quick_connect " ,
FT_BOOLEAN , 8 , TFS ( & tfs_enabled_disabled ) , 0x1 ,
NULL , HFILL } } ,
{ & hf_elink_interface_speed ,
{ " Interface Speed " , " cip.elink.interface_speed " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_interface_flags ,
{ " Interface Flags " , " cip.elink.iflags " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_iflags_link_status ,
{ " Link Status " , " cip.elink.iflags.link_status " ,
FT_BOOLEAN , 32 , TFS ( & tfs_active_inactive ) , 0x00000001 ,
NULL , HFILL } } ,
{ & hf_elink_iflags_duplex ,
{ " Duplex " , " cip.elink.iflags.duplex " ,
2014-05-28 00:33:22 +00:00
FT_UINT32 , BASE_DEC , VALS ( enip_elink_duplex_vals ) , 0x00000002 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_iflags_neg_status ,
{ " Negotiation Status " , " cip.elink.iflags.neg_status " ,
2014-05-28 00:33:22 +00:00
FT_UINT32 , BASE_DEC , VALS ( enip_elink_iflags_neg_status_vals ) , 0x0000001C ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_iflags_manual_reset ,
{ " Manual Reset Required " , " cip.elink.iflags.manual_reset " ,
2014-05-28 00:33:22 +00:00
FT_UINT32 , BASE_DEC , VALS ( enip_elink_iflags_reset_vals ) , 0x00000020 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_iflags_local_hw_fault ,
{ " Local Hardware Fault " , " cip.elink.iflags.local_hw_fault " ,
2014-05-28 00:33:22 +00:00
FT_UINT32 , BASE_DEC , VALS ( enip_elink_iflags_hw_fault_vals ) , 0x00000040 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_iflags_reserved ,
{ " Reserved " , " cip.elink.iflags.reserved " ,
FT_UINT32 , BASE_HEX , NULL , 0xFFFFFF80 ,
NULL , HFILL } } ,
{ & hf_elink_physical_address ,
{ " Physical Addresss " , " cip.elink.physical_address " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_in_octets ,
{ " In Octets " , " cip.elink.icount.in_octets " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_in_ucast ,
{ " In Ucast Packets " , " cip.elink.icount.in_ucast " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_in_nucast ,
{ " In NUcast Packets " , " cip.elink.icount.in_nucast " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_in_discards ,
{ " In Discards " , " cip.elink.icount.in_discards " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_in_errors ,
{ " In Errors " , " cip.elink.icount.in_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_in_unknown_protos ,
{ " In Unknown Protos " , " cip.elink.icount.in_unknown_protos " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_out_octets ,
{ " Out Octets " , " cip.elink.icount.out_octets " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_out_ucast ,
{ " Out Ucast Packets " , " cip.elink.icount.out_ucast " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_out_nucast ,
{ " Out NUcast Packets " , " cip.elink.icount.out_nucast " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_out_discards ,
{ " Out Discards " , " cip.elink.icount.out_discards " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icount_out_errors ,
{ " Out Errors " , " cip.elink.icount.out_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_alignment_errors ,
{ " Alignment Errors " , " cip.elink.mcount.alignment_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_fcs_errors ,
{ " FCS Errors " , " cip.elink.mcount.fcs_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_single_collisions ,
{ " Single Collisions " , " cip.elink.mcount.single_collisions " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_multiple_collisions ,
{ " Multiple Collisions " , " cip.elink.mcount.multiple_collisions " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_sqe_test_errors ,
{ " SQE Test Errors " , " cip.elink.mcount.sqe_test_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_deferred_transmission ,
{ " Deferred Transmission " , " cip.elink.mcount.deferred_transmission " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_late_collisions ,
{ " Late Collisions " , " cip.elink.mcount.late_collisions " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_excessive_collisions ,
{ " Excessive Collisions " , " cip.elink.mcount.excessive_collisions " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_mac_transmit_errors ,
{ " MAC Transmit Errors " , " cip.elink.mcount.mac_transmit_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_carrier_sense_errors ,
{ " Carrier Sense Errors " , " cip.elink.mcount.carrier_sense_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_frame_too_long ,
{ " Frame Too Long " , " cip.elink.mcount.frame_too_long " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_mcount_mac_receive_errors ,
{ " MAC Receive Errors " , " cip.elink.mcount.mac_receive_errors " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icontrol_control_bits ,
{ " Control Bits " , " cip.elink.icontrol.control_bits " ,
FT_UINT16 , BASE_HEX , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_icontrol_control_bits_auto_neg ,
{ " Auto-negotiate " , " cip.elink.icontrol.control_bits.auto_neg " ,
FT_BOOLEAN , 16 , TFS ( & tfs_enabled_disabled ) , 0x0001 ,
NULL , HFILL } } ,
{ & hf_elink_icontrol_control_bits_forced_duplex ,
{ " Forced Duplex Mode " , " cip.elink.icontrol.control_bits.forced_duplex " ,
2014-05-28 00:33:22 +00:00
FT_UINT16 , BASE_DEC , VALS ( enip_elink_duplex_vals ) , 0x0002 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_icontrol_control_bits_reserved ,
{ " Reserved " , " cip.elink.icontrol.control_bits.reserved " ,
FT_UINT16 , BASE_HEX , NULL , 0xFFFC ,
NULL , HFILL } } ,
{ & hf_elink_icontrol_forced_speed ,
{ " Forced Interface Speed " , " cip.elink.icontrol.forced_speed " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_elink_interface_type ,
{ " Interface Type " , " cip.elink.interface_type " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_elink_interface_type_vals ) , 0 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_interface_state ,
{ " Interface State " , " cip.elink.interface_state " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_elink_interface_state_vals ) , 0 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_admin_state ,
{ " Admin State " , " cip.elink.admin_state " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_elink_admin_state_vals ) , 0 ,
2012-04-26 16:47:37 +00:00
NULL , HFILL } } ,
{ & hf_elink_interface_label ,
{ " Interface Label " , " cip.elink.interface_label " ,
FT_STRING , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_qos_8021q_enable ,
{ " 802.1Q Tag Enable " , " cip.qos.8021q_enable " ,
FT_BOOLEAN , 8 , TFS ( & tfs_enabled_disabled ) , 0x1 ,
NULL , HFILL } } ,
{ & hf_qos_dscp_ptp_event ,
{ " DSCP PTP Event " , " cip.qos.ptp_event " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_qos_dscp_ptp_general ,
{ " DSCP PTP General " , " cip.qos.ptp_general " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_qos_dscp_urgent ,
{ " DSCP Urgent " , " cip.qos.urgent " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_qos_dscp_scheduled ,
{ " DSCP Scheduled " , " cip.qos.scheduled " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_qos_dscp_high ,
{ " DSCP High " , " cip.qos.high " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_qos_dscp_low ,
{ " DSCP Low " , " cip.qos.low " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_qos_dscp_explicit ,
{ " DSCP Explicit " , " cip.qos.explicit " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2012-07-18 19:40:56 +00:00
NULL , HFILL } } ,
{ & hf_dlr_network_topology ,
{ " Network Topology " , " cip.dlr.network_topology " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_dlr_network_topology_vals ) , 0 ,
2012-07-18 19:40:56 +00:00
NULL , HFILL } } ,
{ & hf_dlr_network_status ,
{ " Network Status " , " cip.dlr.network_status " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_dlr_network_status_vals ) , 0 ,
2012-07-18 19:40:56 +00:00
NULL , HFILL } } ,
{ & hf_dlr_ring_supervisor_status ,
{ " Ring Supervisor Status " , " cip.dlr.ring_supervisor_status " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_dlr_ring_supervisor_status_vals ) , 0 ,
2012-07-18 19:40:56 +00:00
NULL , HFILL } } ,
{ & hf_dlr_rsc_ring_supervisor_enable ,
{ " Ring Supervisor Enable " , " cip.dlr.rscconfig.supervisor_enable " ,
FT_BOOLEAN , 8 , TFS ( & tfs_true_false ) , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rsc_ring_supervisor_precedence ,
{ " Ring Supervisor Precedence " , " cip.dlr.rscconfig.supervisor_precedence " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rsc_beacon_interval ,
{ " Beacon Interval " , " cip.dlr.rscconfig.beacon_interval " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rsc_beacon_timeout ,
{ " Beacon Timeout " , " cip.dlr.rscconfig.beacon_timeout " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rsc_dlr_vlan_id ,
{ " DLR VLAN ID " , " cip.dlr.rscconfig.dlr_vlan_id " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_ring_faults_count ,
{ " Ring Faults Count " , " cip.dlr.ring_faults_count " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_lanp1_dev_ip_addr ,
{ " Device IP Address " , " cip.dlr.lanp1.ip_addr " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_lanp1_dev_physical_address ,
{ " Device Physical Address " , " cip.dlr.lanp1.physical_address " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_lanp2_dev_ip_addr ,
{ " Device IP Address " , " cip.dlr.lanp2.ip_addr " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
2011-10-13 00:00:52 +00:00
2012-07-18 19:40:56 +00:00
{ & hf_dlr_lanp2_dev_physical_address ,
{ " Device Physical Address " , " cip.dlr.lanp2.physical_address " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_ring_protocol_participants_count ,
{ " Participants Count " , " cip.dlr.participants_count " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rppl_dev_ip_addr ,
{ " Device IP Address " , " cip.dlr.rppl.ip_addr " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rppl_dev_physical_address ,
{ " Device Physical Address " , " cip.dlr.rppl.physical_address " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_asa_supervisor_ip_addr ,
{ " Supervisor IP Address " , " cip.dlr.asa.ip_addr " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_asa_supervisor_physical_address ,
{ " Supervisor Physical Address " , " cip.dlr.asa.physical_address " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_active_supervisor_precedence ,
{ " Active Supervisor Precedence " , " cip.dlr.supervisor_precedence " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_capability_flags ,
{ " Capability Flags " , " cip.dlr.capflags " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_capflags_announce_base_node ,
{ " Announce-based Ring Node " , " cip.dlr.capflags.announce_based " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000001 ,
NULL , HFILL } } ,
{ & hf_dlr_capflags_beacon_base_node ,
{ " Beacon-based Ring Node " , " cip.dlr.capflags.beacon_based " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000002 ,
NULL , HFILL } } ,
{ & hf_dlr_capflags_reserved1 ,
{ " Reserved " , " cip.dlr.capflags.reserved1 " ,
FT_BOOLEAN , 32 , NULL , 0x0000001C ,
NULL , HFILL } } ,
{ & hf_dlr_capflags_supervisor_capable ,
{ " Supervisor Capable " , " cip.dlr.capflags.supervisor_capable " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000020 ,
NULL , HFILL } } ,
2013-04-04 14:34:26 +00:00
{ & hf_dlr_capflags_redundant_gateway_capable ,
{ " Redundant Gatway Capable " , " cip.dlr.capflags.redundant_gateway_capable " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000040 ,
NULL , HFILL } } ,
{ & hf_dlr_capflags_flush_frame_capable ,
{ " Flush_Table Frame Capable " , " cip.dlr.capflags.flush_frame_capable " ,
FT_BOOLEAN , 32 , TFS ( & tfs_true_false ) , 0x00000080 ,
NULL , HFILL } } ,
2012-11-29 20:15:37 +00:00
{ & hf_dlr_capflags_reserved2 ,
2012-07-18 19:40:56 +00:00
{ " Reserved " , " cip.dlr.capflags.reserved2 " ,
2013-04-04 14:34:26 +00:00
FT_BOOLEAN , 32 , NULL , 0xFFFFFF00 ,
NULL , HFILL } } ,
{ & hf_dlr_rgc_red_gateway_enable ,
{ " Redundant Gateway Enable " , " cip.dlr.rgc.gateway_enable " ,
FT_BOOLEAN , 8 , TFS ( & tfs_true_false ) , 0 ,
2013-09-12 20:34:19 +00:00
NULL , HFILL } } ,
2013-04-04 14:34:26 +00:00
{ & hf_dlr_rgc_gateway_precedence ,
{ " Gateway Precedence " , " cip.dlr.rgc.gateway_precedence " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2013-09-12 20:34:19 +00:00
NULL , HFILL } } ,
2013-04-04 14:34:26 +00:00
{ & hf_dlr_rgc_advertise_interval ,
{ " Advertise Interval " , " cip.dlr.rgc.advertise_interval " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rgc_advertise_timeout ,
{ " Advertise Timeout " , " cip.dlr.rgc.advertise_timeout " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_rgc_learning_update_enable ,
{ " Learning Update Enable " , " cip.dlr.rgc.learning_update_enable " ,
FT_BOOLEAN , 8 , TFS ( & tfs_true_false ) , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_redundant_gateway_status ,
{ " Redundant Gateway Status " , " cip.dlr.redundant_gateway_status " ,
2014-05-28 00:33:22 +00:00
FT_UINT8 , BASE_DEC , VALS ( enip_dlr_redundant_gateway_status_vals ) , 0 ,
2013-04-04 14:34:26 +00:00
NULL , HFILL } } ,
{ & hf_dlr_aga_ip_addr ,
{ " Active Gateway IP Address " , " cip.dlr.aga.ip_addr " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
{ & hf_dlr_aga_physical_address ,
{ " Active Gateway Physical Address " , " cip.dlr.aga.physical_address " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
NULL , HFILL } } ,
2013-09-12 20:34:19 +00:00
2013-04-04 14:34:26 +00:00
{ & hf_dlr_active_gateway_precedence ,
{ " Active Gateway Precedence " , " cip.dlr.active_gateway_precedence " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2012-07-18 19:40:56 +00:00
NULL , HFILL } }
2003-06-11 09:02:19 +00:00
} ;
2009-07-15 19:33:48 +00:00
/* Setup protocol subtree array */
2009-06-26 02:38:23 +00:00
static gint * ett [ ] = {
& ett_enip ,
& ett_count_tree ,
& ett_type_tree ,
& ett_command_tree ,
& ett_sockadd ,
2011-12-01 06:05:39 +00:00
& ett_32bitheader_tree ,
2009-06-26 02:38:23 +00:00
& ett_lsrcf ,
2011-10-26 04:55:21 +00:00
& ett_tcpip_status ,
& ett_tcpip_config_cap ,
& ett_tcpip_config_control ,
& ett_elink_interface_flags ,
2012-07-18 19:40:56 +00:00
& ett_elink_icontrol_bits ,
2013-04-04 14:34:26 +00:00
& ett_dlr_capability_flags ,
& ett_dlr_lnknbrstatus_flags
2009-06-26 02:38:23 +00:00
} ;
2009-07-09 20:44:28 +00:00
2013-05-24 18:02:54 +00:00
static ei_register_info ei [ ] = {
2013-06-08 02:06:24 +00:00
{ & ei_mal_tcpip_status , { " cip.malformed.tcpip.status " , PI_MALFORMED , PI_ERROR , " Malformed TCP/IP Status " , EXPFILL } } ,
{ & ei_mal_tcpip_config_cap , { " cip.malformed.tcpip.config_cap " , PI_MALFORMED , PI_ERROR , " Malformed TCP/IP Configuration Capability " , EXPFILL } } ,
{ & ei_mal_tcpip_config_control , { " cip.malformed.tcpip.config_control " , PI_MALFORMED , PI_ERROR , " Malformed TCP/IP Configuration Control " , EXPFILL } } ,
{ & ei_mal_tcpip_physical_link_size , { " cip.malformed.tcpip.physical_link_size " , PI_MALFORMED , PI_ERROR , " Malformed TCP/IP Physical Link Object " , EXPFILL } } ,
{ & ei_mal_tcpip_interface_config , { " cip.malformed.tcpip.interface_config " , PI_MALFORMED , PI_ERROR , " Malformed TCP/IP Interface Configuration " , EXPFILL } } ,
{ & ei_mal_tcpip_mcast_config , { " cip.malformed.tcpip.mcast_config " , PI_MALFORMED , PI_ERROR , " Malformed TCP/IP Multicast Config " , EXPFILL } } ,
{ & ei_mal_tcpip_last_conflict , { " cip.malformed.tcpip.last_conflict " , PI_MALFORMED , PI_ERROR , " Malformed TCP/IP Last Conflict Detected " , EXPFILL } } ,
{ & ei_mal_elink_interface_flags , { " cip.malformed.elink.interface_flags " , PI_MALFORMED , PI_ERROR , " Malformed Ethernet Link Interface Flags " , EXPFILL } } ,
{ & ei_mal_elink_interface_counters , { " cip.malformed.elink.interface_counters " , PI_MALFORMED , PI_ERROR , " Malformed Ethernet Link Interface Counters " , EXPFILL } } ,
{ & ei_mal_elink_media_counters , { " cip.malformed.elink.media_counters " , PI_MALFORMED , PI_ERROR , " Malformed Ethernet Link Media Counters " , EXPFILL } } ,
{ & ei_mal_elink_interface_control , { " cip.malformed.elink.interface_control " , PI_MALFORMED , PI_ERROR , " Malformed Ethernet Link Interface Control " , EXPFILL } } ,
{ & ei_mal_dlr_ring_supervisor_config , { " cip.malformed.dlr.ring_supervisor_config " , PI_MALFORMED , PI_ERROR , " Malformed DLR Ring Supervisor Config " , EXPFILL } } ,
{ & 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 } } ,
{ & 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 } } ,
{ & 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 } } ,
{ & ei_mal_dlr_active_supervisor_address , { " cip.malformed.dlr.active_supervisor_address " , PI_MALFORMED , PI_ERROR , " Malformed DLR Active Supervisor Address " , EXPFILL } } ,
{ & ei_mal_dlr_capability_flags , { " cip.malformed.dlr.capability_flags " , PI_MALFORMED , PI_ERROR , " Malformed DLR Capability Flag " , EXPFILL } } ,
{ & ei_mal_dlr_redundant_gateway_config , { " cip.malformed.dlr.redundant_gateway_config " , PI_MALFORMED , PI_ERROR , " Malformed DLR Redundant Gateway Config " , EXPFILL } } ,
{ & ei_mal_dlr_active_gateway_address , { " cip.malformed.dlr.active_gateway_address " , PI_MALFORMED , PI_ERROR , " Malformed DLR Active Gateway Address " , EXPFILL } } ,
2013-05-24 18:02:54 +00:00
} ;
2009-07-09 20:44:28 +00:00
/* Setup list of header fields for DLR See Section 1.6.1 for details*/
2011-10-13 00:00:52 +00:00
static hf_register_info hfdlr [ ] = {
/* Ring Sub-type */
2009-07-09 20:44:28 +00:00
{ & hf_dlr_ringsubtype ,
2013-10-02 01:43:39 +00:00
{ " Ring Sub-Type " , " enip.dlr.ringsubtype " ,
2011-10-13 00:00:52 +00:00
FT_UINT8 , BASE_HEX , NULL , 0 ,
2013-10-02 01:43:39 +00:00
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Ring Protocol Version */
{ & hf_dlr_ringprotoversion ,
2013-10-02 01:43:39 +00:00
{ " Ring Protocol Version " , " enip.dlr.protversion " ,
2011-10-13 00:00:52 +00:00
FT_UINT8 , BASE_DEC , NULL , 0 ,
2013-10-02 01:43:39 +00:00
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Frame Type */
{ & hf_dlr_frametype ,
2013-10-02 01:43:39 +00:00
{ " Frame Type " , " enip.dlr.frametype " ,
2011-10-13 00:00:52 +00:00
FT_UINT8 , BASE_HEX , VALS ( dlr_frame_type_vals ) , 0 ,
2013-10-02 01:43:39 +00:00
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Source Port */
{ & hf_dlr_sourceport ,
2013-10-02 01:43:39 +00:00
{ " Source Port " , " enip.dlr.sourceport " ,
2011-10-13 00:00:52 +00:00
FT_UINT8 , BASE_HEX , VALS ( dlr_source_port_vals ) , 0 ,
2013-10-02 01:43:39 +00:00
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Source IP Address */
{ & hf_dlr_sourceip ,
2011-10-13 00:00:52 +00:00
{ " Source IP " , " enip.dlr.sourceip " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
" Source IP Address " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Sequence ID*/
{ & hf_dlr_sequenceid ,
2011-10-13 00:00:52 +00:00
{ " Sequence Id " , " enip.dlr.seqid " ,
FT_UINT32 , BASE_HEX , NULL , 0 ,
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Ring State */
{ & hf_dlr_ringstate ,
2011-10-13 00:00:52 +00:00
{ " Ring State " , " enip.dlr.state " ,
FT_UINT8 , BASE_HEX , VALS ( dlr_ring_state_vals ) , 0 ,
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Supervisor Precedence */
{ & hf_dlr_supervisorprecedence ,
2011-10-13 00:00:52 +00:00
{ " Supervisor Precedence " , " enip.dlr.supervisorprecedence " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Beacon Interval */
{ & hf_dlr_beaconinterval ,
2011-10-13 00:00:52 +00:00
{ " Beacon Interval " , " enip.dlr.beaconinterval " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Beacon Timeout */
{ & hf_dlr_beacontimeout ,
2011-10-13 00:00:52 +00:00
{ " Beacon Timeout " , " enip.dlr.beacontimeout " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
NULL , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Beacon Reserved */
{ & hf_dlr_beaconreserved ,
2011-10-13 00:00:52 +00:00
{ " Reserved " , " enip.dlr.beaconreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Beacon Reserved " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Neighbor_Check_Request Reserved */
{ & hf_dlr_nreqreserved ,
2011-10-13 00:00:52 +00:00
{ " Reserved " , " enip.dlr.nreqreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Neighbor_Check_Request Reserved " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Neighbor_Check_Response Source Port */
{ & hf_dlr_nressourceport ,
2013-10-02 01:43:39 +00:00
{ " Request Source Port " , " enip.dlr.nressourceport " ,
2011-10-13 00:00:52 +00:00
FT_UINT8 , BASE_HEX , VALS ( dlr_source_port_vals ) , 0 ,
" Neighbor_Check_Response Source Port " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Neighbor_Check_Response Reserved */
{ & hf_dlr_nresreserved ,
2011-10-13 00:00:52 +00:00
{ " Reserved " , " enip.dlr.nresreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Neighbor_Check_Response Reserved " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Link_Status/Neighbor_Status Status */
{ & hf_dlr_lnknbrstatus ,
2013-04-04 14:34:26 +00:00
{ " Link/Neighbor Status " , " enip.dlr.lnknbrstatus " ,
FT_UINT8 , BASE_HEX , NULL , 0 ,
2011-10-13 00:00:52 +00:00
" Link_Status/Neighbor_Status Status " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
2013-04-04 14:34:26 +00:00
{ & hf_dlr_lnknbrstatus_port1 ,
{ " Port 1 Active " , " enip.dlr.lnknbrstatus " ,
FT_BOOLEAN , 8 , TFS ( & tfs_true_false ) , 0x01 ,
NULL , HFILL }
} ,
{ & hf_dlr_lnknbrstatus_port2 ,
{ " Port 2 Active " , " enip.dlr.lnknbrstatus " ,
FT_BOOLEAN , 8 , TFS ( & tfs_true_false ) , 0x02 ,
NULL , HFILL }
} ,
{ & hf_dlr_lnknbrstatus_reserved ,
{ " Reserved " , " enip.dlr.lnknbrstatus.reserved " ,
FT_BOOLEAN , 8 , NULL , 0x7C ,
NULL , HFILL }
} ,
{ & hf_dlr_lnknbrstatus_frame_type ,
{ " Link/Neighbor Status Flag " , " enip.dlr.lnknbrstatus " ,
FT_BOOLEAN , 8 , TFS ( & dlr_lnknbrstatus_frame_type_vals ) , 0x80 ,
NULL , HFILL }
} ,
2009-07-09 20:44:28 +00:00
/* Link_Status/Neighbor_Status Reserved */
{ & hf_dlr_lnknbrreserved ,
2011-10-13 00:00:52 +00:00
{ " Reserved " , " enip.dlr.lnknbrreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Link_Status/Neighbor_Status Reserved " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Locate_Fault Reserved */
{ & hf_dlr_lfreserved ,
2011-10-13 00:00:52 +00:00
{ " Reserved " , " enip.dlr.lfreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Locate_Fault Reserved " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Announce Reserved */
{ & hf_dlr_anreserved ,
2011-10-13 00:00:52 +00:00
{ " Reserved " , " enip.dlr.anreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Announce Reserved " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Number of Nodes in List */
{ & hf_dlr_sonumnodes ,
2011-10-13 00:00:52 +00:00
{ " Num nodes " , " enip.dlr.sonumnodes " ,
FT_UINT16 , BASE_DEC , NULL , 0 ,
" Number of Nodes in List " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Sign_On Node # MAC Address */
{ & hf_dlr_somac ,
2011-10-13 00:00:52 +00:00
{ " MAC Address " , " enip.dlr.somac " ,
FT_ETHER , BASE_NONE , NULL , 0 ,
" Sign_On Node MAC Address " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Node # IP Address */
{ & hf_dlr_soip ,
2011-10-13 00:00:52 +00:00
{ " IP Address " , " enip.dlr.soip " ,
FT_IPv4 , BASE_NONE , NULL , 0 ,
" Sign_On Node IP Address " , HFILL }
2009-07-09 20:44:28 +00:00
} ,
/* Sign_On Reserved */
{ & hf_dlr_soreserved ,
2011-10-13 00:00:52 +00:00
{ " Reserved " , " enip.dlr.soreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Sign_On Reserved " , HFILL }
2013-04-04 14:34:26 +00:00
} ,
/* Gateway State */
{ & hf_dlr_advgatewaystate ,
{ " Gateway Status " , " enip.dlr.advgatewaystate " ,
FT_UINT8 , BASE_HEX , VALS ( dlr_adv_state_vals ) , 0 ,
" Gateway State " , HFILL }
} ,
/* Gateway Precedence */
{ & hf_dlr_advgatewayprecedence ,
{ " Gateway Precedence " , " enip.dlr.advgatewayprecedence " ,
FT_UINT8 , BASE_DEC , NULL , 0 ,
2013-04-04 15:00:27 +00:00
NULL , HFILL }
2013-04-04 14:34:26 +00:00
} ,
/* Advertise Interval */
{ & hf_dlr_advadvertiseinterval ,
{ " Advertise Interval " , " enip.dlr.advadvertiseinterval " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
2013-04-04 15:00:27 +00:00
NULL , HFILL }
2013-04-04 14:34:26 +00:00
} ,
/* Advertise Timeout */
{ & hf_dlr_advadvertisetimeout ,
{ " Advertise Interval " , " enip.dlr.advadvertisetimeout " ,
FT_UINT32 , BASE_DEC , NULL , 0 ,
2013-04-04 15:00:27 +00:00
NULL , HFILL }
2013-04-04 14:34:26 +00:00
} ,
/* Learning Update Enable */
{ & hf_dlr_advlearningupdateenable ,
{ " Learning Update Enable " , " enip.dlr.advlearningupdateenable " ,
FT_UINT8 , BASE_HEX , VALS ( dlr_adv_learning_update_vals ) , 0 ,
" Advertise Learning Update Enable " , HFILL }
} ,
/* Advertise Reserved */
{ & hf_dlr_advreserved ,
{ " Reserved " , " enip.dlr.advreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Advertise Reserved " , HFILL }
} ,
/* Flush_Tables Learning Update Enable */
{ & hf_dlr_flushlearningupdateenable ,
{ " Learning Update Enable " , " enip.dlr.flushlearningupdateenable " ,
FT_UINT8 , BASE_HEX , VALS ( dlr_flush_learning_update_vals ) , 0 ,
" Flush_Tables Learning Update Enable " , HFILL }
} ,
/* Flush Reserved */
{ & hf_dlr_flushreserved ,
{ " Reserved " , " enip.dlr.flushreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Flush_Tables Reserved " , HFILL }
} ,
/* Learning_Update Reserved */
{ & hf_dlr_learnreserved ,
{ " Reserved " , " enip.dlr.learnreserved " ,
FT_BYTES , BASE_NONE , NULL , 0 ,
" Learning_Update Reserved " , HFILL }
2009-07-09 20:44:28 +00:00
}
} ;
/* Setup protocol subtree array for DLR */
2011-04-25 01:37:19 +00:00
static gint * ettdlr [ ] = {
2011-10-13 00:00:52 +00:00
& ett_dlr
2011-04-25 01:37:19 +00:00
} ;
2009-07-09 20:44:28 +00:00
2009-06-26 02:38:23 +00:00
module_t * enip_module ;
2013-05-24 18:02:54 +00:00
expert_module_t * expert_enip ;
2003-06-11 09:02:19 +00:00
2009-07-15 19:33:48 +00:00
/* Register the protocol name and description */
2012-02-27 09:30:26 +00:00
proto_enip = proto_register_protocol ( " EtherNet/IP (Industrial Protocol) " , " ENIP " , " enip " ) ;
2003-06-11 09:02:19 +00:00
2009-07-15 19:33:48 +00:00
/* Required function calls to register the header fields and subtrees used */
2009-06-26 02:38:23 +00:00
proto_register_field_array ( proto_enip , hf , array_length ( hf ) ) ;
proto_register_subtree_array ( ett , array_length ( ett ) ) ;
2003-08-16 01:53:41 +00:00
2013-05-24 18:02:54 +00:00
expert_enip = expert_register_protocol ( proto_enip ) ;
expert_register_field_array ( expert_enip , ei , array_length ( ei ) ) ;
2009-06-26 02:38:23 +00:00
enip_module = prefs_register_protocol ( proto_enip , NULL ) ;
prefs_register_bool_preference ( enip_module , " desegment " ,
2011-10-13 00:00:52 +00:00
" Desegment all EtherNet/IP messages spanning multiple TCP segments " ,
" Whether the EtherNet/IP dissector should desegment all messages spanning multiple TCP segments " ,
& enip_desegment ) ;
2004-09-23 17:34:35 +00:00
2011-12-01 06:05:39 +00:00
prefs_register_bool_preference ( enip_module , " o2t_run_idle " ,
" Dissect 32-bit header in the O->T direction " ,
" Determines whether all I/O connections will assume a 32-bit header in the O->T direction " ,
& enip_OTrun_idle ) ;
prefs_register_bool_preference ( enip_module , " t2o_run_idle " ,
" Dissect 32-bit header in the T->O direction " ,
" Determines whether all I/O connections will assume a 32-bit header in the T->O direction " ,
& enip_TOrun_idle ) ;
2012-08-09 16:47:15 +00:00
prefs_register_enum_preference ( enip_module , " default_io_dissector " ,
" Dissect unidentified I/O traffic as " ,
" Decode all unidentified I/O traffic as this type " ,
& default_io_dissector_type ,
enip_io_dissector_types ,
FALSE ) ;
2012-07-18 19:40:56 +00:00
2009-06-26 02:38:23 +00:00
subdissector_sud_table = register_dissector_table ( " enip.sud.iface " ,
2013-09-12 20:34:19 +00:00
" ENIP SendUnitData.Interface Handle " , FT_UINT32 , BASE_HEX ) ;
2004-09-23 17:34:35 +00:00
2009-06-26 02:38:23 +00:00
subdissector_srrd_table = register_dissector_table ( " enip.srrd.iface " ,
2013-09-12 20:34:19 +00:00
" ENIP SendRequestReplyData.Interface Handle " , FT_UINT32 , BASE_HEX ) ;
2004-09-23 17:34:35 +00:00
2009-06-26 02:38:23 +00:00
register_init_routine ( & enip_init_protocol ) ;
2009-07-09 20:44:28 +00:00
/* Register the protocol name and description */
proto_dlr = proto_register_protocol ( " Device Level Ring " , " DLR " , " dlr " ) ;
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array ( proto_dlr , hfdlr , array_length ( hfdlr ) ) ;
proto_register_subtree_array ( ettdlr , array_length ( ettdlr ) ) ;
2014-05-27 02:58:48 +00:00
register_dissector_filter ( " ENIP IO " , enip_io_conv_valid , enip_io_conv_filter ) ;
register_dissector_filter ( " ENIP Explicit " , enip_exp_conv_valid , enip_exp_conv_filter ) ;
2004-09-23 17:34:35 +00:00
} /* end of proto_register_enip() */
2003-06-11 09:02:19 +00:00
void
2004-09-23 17:34:35 +00:00
proto_reg_handoff_enip ( void )
2003-06-11 09:02:19 +00:00
{
2009-06-26 02:38:23 +00:00
dissector_handle_t enip_udp_handle , enip_tcp_handle ;
dissector_handle_t enipio_handle ;
2009-07-09 20:44:28 +00:00
dissector_handle_t dlr_handle ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Register for EtherNet/IP, using TCP */
enip_tcp_handle = new_create_dissector_handle ( dissect_enip_tcp , proto_enip ) ;
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " tcp.port " , ENIP_ENCAP_PORT , enip_tcp_handle ) ;
2004-09-23 17:34:35 +00:00
2009-06-26 02:38:23 +00:00
/* Register for EtherNet/IP, using UDP */
enip_udp_handle = new_create_dissector_handle ( dissect_enip_udp , proto_enip ) ;
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " udp.port " , ENIP_ENCAP_PORT , enip_udp_handle ) ;
2003-06-11 09:02:19 +00:00
2009-06-26 02:38:23 +00:00
/* Register for EtherNet/IP IO data (UDP) */
enipio_handle = create_dissector_handle ( dissect_enipio , proto_enip ) ;
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " udp.port " , ENIP_IO_PORT , enipio_handle ) ;
2003-08-16 01:53:41 +00:00
2009-06-26 02:38:23 +00:00
/* Find dissector for data packet */
data_handle = find_dissector ( " data " ) ;
2004-09-23 17:34:35 +00:00
2012-02-27 09:30:26 +00:00
/* Find ARP dissector for TCP/IP object */
arp_handle = find_dissector ( " arp " ) ;
2012-03-02 03:39:16 +00:00
/* I/O data dissectors */
cipsafety_handle = find_dissector ( " cipsafety " ) ;
cipmotion_handle = find_dissector ( " cipmotion " ) ;
2009-07-09 20:44:28 +00:00
/* Register for EtherNet/IP Device Level Ring protocol */
dlr_handle = new_create_dissector_handle ( dissect_dlr , proto_dlr ) ;
2010-12-20 05:35:29 +00:00
dissector_add_uint ( " ethertype " , ETHERTYPE_DLR , dlr_handle ) ;
2009-07-09 20:44:28 +00:00
2012-08-09 16:47:15 +00:00
proto_cipsafety = proto_get_id_by_filter_name ( " cipsafety " ) ;
2004-09-23 17:34:35 +00:00
} /* end of proto_reg_handoff_enip() */
2011-10-13 00:00:52 +00:00
/*
* Editor modelines - http : //www.wireshark.org/tools/modelines.html
*
* Local variables :
* c - basic - offset : 3
* tab - width : 8
* indent - tabs - mode : nil
* End :
*
* ex : set shiftwidth = 3 tabstop = 8 expandtab :
* : indentSize = 3 : tabSize = 8 : noTabs = true :
*/