diff options
author | Anders Broman <anders.broman@ericsson.com> | 2011-10-02 16:35:10 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2011-10-02 16:35:10 +0000 |
commit | 8bb88d9efcdfaaaeb04d8ced2ab34670c230dd11 (patch) | |
tree | 15b6b1d02322495364d0cacb17320bbff376c10b /epan | |
parent | 64c2355b675f0c38e1f1d313fe88ded3270cd1dd (diff) |
From Michael Mann :
General improvements to CIP and ENIP dissectors.
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6416
svn path=/trunk/; revision=39222
Diffstat (limited to 'epan')
-rw-r--r-- | epan/dissectors/packet-cip.c | 5589 | ||||
-rw-r--r-- | epan/dissectors/packet-cip.h | 1202 | ||||
-rw-r--r-- | epan/dissectors/packet-enip.c | 625 | ||||
-rw-r--r-- | epan/dissectors/packet-enip.h | 3 |
4 files changed, 4122 insertions, 3297 deletions
diff --git a/epan/dissectors/packet-cip.c b/epan/dissectors/packet-cip.c index 90107fa832..deb6acabaa 100644 --- a/epan/dissectors/packet-cip.c +++ b/epan/dissectors/packet-cip.c @@ -14,6 +14,7 @@ * Copyright 2007 * * Improved support for CoCo and CM objects + * Heuristic object support for common services * Michael Mann * Copyright 2011 * * $Id$ @@ -61,8 +62,9 @@ #include <glib.h> #include <epan/packet.h> -#include "packet-enip.h" +#include <epan/expert.h> #include "packet-cip.h" +#include "packet-enip.h" #define ENIP_CIP_INTERFACE 0 @@ -72,67 +74,162 @@ typedef struct cip_req_info { guint IOILen; void *pIOI; void *pData; + cip_simple_request_info_t* ciaData; } cip_req_info_t; -typedef struct cip_simple_request_info { - guint32 iClass; - guint32 iInstance; - guint32 iAttribute; - guint32 iMember; -} cip_simple_request_info_t; +typedef struct mr_mult_req_info { + guint8 service; + int num_services; + cip_req_info_t *requests; +} mr_mult_req_info_t; static dissector_handle_t cip_handle; static dissector_handle_t cip_class_generic_handle; static dissector_handle_t cip_class_cm_handle; -static dissector_handle_t cip_class_mr_handle; static dissector_handle_t cip_class_cco_handle; +static heur_dissector_list_t heur_subdissector_service; /* Initialize the protocol and registered fields */ static int proto_cip = -1; static int proto_cip_class_generic = -1; static int proto_cip_class_cm = -1; -static int proto_cip_class_mr = -1; static int proto_cip_class_cco = -1; static int proto_enip = -1; -static int hf_cip_sc = -1; -static int hf_cip_rr = -1; -static int hf_cip_epath = -1; -static int hf_cip_genstat = -1; - -static int hf_cip_fwo_comp = -1; -static int hf_cip_fwo_mrev = -1; - -static int hf_cip_cm_ot_connid = -1; -static int hf_cip_cm_to_connid = -1; -static int hf_cip_cm_conn_serial_num = -1; -static int hf_cip_cm_orig_serial_num = -1; -static int hf_cip_cm_fwo_con_size = -1; -static int hf_cip_cm_lfwo_con_size = -1; -static int hf_cip_cm_fwo_fixed_var = -1; -static int hf_cip_cm_lfwo_fixed_var = -1; -static int hf_cip_cm_fwo_prio = -1; -static int hf_cip_cm_lfwo_prio = -1; -static int hf_cip_cm_fwo_typ = -1; -static int hf_cip_cm_lfwo_typ = -1; -static int hf_cip_cm_fwo_own = -1; -static int hf_cip_cm_lfwo_own = -1; -static int hf_cip_cm_fwo_dir = -1; -static int hf_cip_cm_fwo_trigg = -1; -static int hf_cip_cm_fwo_class = -1; -static int hf_cip_cm_gco_conn = -1; -static int hf_cip_cm_gco_coo_conn = -1; -static int hf_cip_cm_gco_roo_conn = -1; -static int hf_cip_cm_gco_la = -1; -static int hf_cip_cco_con_type = -1; -static int hf_cip_cco_ot_rtf = -1; -static int hf_cip_cco_to_rtf = -1; +static int hf_cip_data = -1; +static int hf_cip_service = -1; +static int hf_cip_service_code = -1; +static int hf_cip_reqrsp = -1; +static int hf_cip_epath = -1; +static int hf_cip_genstat = -1; +static int hf_cip_addstat_size = -1; +static int hf_cip_add_stat = -1; +static int hf_cip_request_path_size = -1; + +static int hf_cip_cm_sc = -1; +static int hf_cip_cm_genstat = -1; +static int hf_cip_cm_addstat_size = -1; +static int hf_cip_cm_add_status = -1; +static int hf_cip_cm_ext_status = -1; +static int hf_cip_cm_priority = -1; +static int hf_cip_cm_tick_time = -1; +static int hf_cip_cm_timeout_tick = -1; +static int hf_cip_cm_timeout = -1; +static int hf_cip_cm_ot_connid = -1; +static int hf_cip_cm_to_connid = -1; +static int hf_cip_cm_conn_serial_num = -1; +static int hf_cip_cm_orig_serial_num = -1; +static int hf_cip_cm_vendor = -1; +static int hf_cip_cm_timeout_multiplier = -1; +static int hf_cip_cm_ot_rpi = -1; +static int hf_cip_cm_ot_net_params32 = -1; +static int hf_cip_cm_ot_net_params16 = -1; +static int hf_cip_cm_to_rpi = -1; +static int hf_cip_cm_to_net_params32 = -1; +static int hf_cip_cm_to_net_params16 = -1; +static int hf_cip_cm_transport_type_trigger = -1; +static int hf_cip_cm_conn_path_size = -1; +static int hf_cip_cm_ot_api = -1; +static int hf_cip_cm_to_api = -1; +static int hf_cip_cm_app_reply_size = -1; +static int hf_cip_cm_app_reply_data = -1; +static int hf_cip_cm_remain_path_size = -1; +static int hf_cip_cm_msg_req_size = -1; +static int hf_cip_cm_route_path_size = -1; +static int hf_cip_cm_fwo_con_size = -1; +static int hf_cip_cm_lfwo_con_size = -1; +static int hf_cip_cm_fwo_fixed_var = -1; +static int hf_cip_cm_lfwo_fixed_var = -1; +static int hf_cip_cm_fwo_prio = -1; +static int hf_cip_cm_lfwo_prio = -1; +static int hf_cip_cm_fwo_typ = -1; +static int hf_cip_cm_lfwo_typ = -1; +static int hf_cip_cm_fwo_own = -1; +static int hf_cip_cm_lfwo_own = -1; +static int hf_cip_cm_fwo_dir = -1; +static int hf_cip_cm_fwo_trigg = -1; +static int hf_cip_cm_fwo_class = -1; +static int hf_cip_cm_gco_conn = -1; +static int hf_cip_cm_gco_coo_conn = -1; +static int hf_cip_cm_gco_roo_conn = -1; +static int hf_cip_cm_gco_last_action = -1; +static int hf_cip_cm_ext112_ot_rpi_type = -1; +static int hf_cip_cm_ext112_to_rpi_type = -1; +static int hf_cip_cm_ext112_ot_rpi = -1; +static int hf_cip_cm_ext112_to_rpi = -1; +static int hf_cip_cm_ext126_size = -1; +static int hf_cip_cm_ext127_size = -1; +static int hf_cip_cm_ext128_size = -1; + + +static int hf_cip_cco_con_type = -1; +static int hf_cip_cco_ot_rtf = -1; +static int hf_cip_cco_to_rtf = -1; +static int hf_cip_cco_sc = -1; +static int hf_cip_cco_format_number = -1; +static int hf_cip_cco_edit_signature = -1; +static int hf_cip_cco_con_flags = -1; +static int hf_cip_cco_tdi_vendor = -1; +static int hf_cip_cco_tdi_devtype = -1; +static int hf_cip_cco_tdi_prodcode = -1; +static int hf_cip_cco_tdi_compatibility = -1; +static int hf_cip_cco_tdi_comp_bit = -1; +static int hf_cip_cco_tdi_majorrev = -1; +static int hf_cip_cco_tdi_minorrev = -1; +static int hf_cip_cco_pdi_vendor = -1; +static int hf_cip_cco_pdi_devtype = -1; +static int hf_cip_cco_pdi_prodcode = -1; +static int hf_cip_cco_pdi_compatibility = -1; +static int hf_cip_cco_pdi_comp_bit = -1; +static int hf_cip_cco_pdi_majorrev = -1; +static int hf_cip_cco_pdi_minorrev = -1; +static int hf_cip_cco_cs_data_index = -1; +static int hf_cip_cco_ot_rpi = -1; +static int hf_cip_cco_to_rpi = -1; +static int hf_cip_cco_ot_net_param16 = -1; +static int hf_cip_cco_to_net_param16 = -1; +static int hf_cip_cco_fwo_own = -1; +static int hf_cip_cco_fwo_typ = -1; +static int hf_cip_cco_fwo_prio = -1; +static int hf_cip_cco_fwo_fixed_var = -1; +static int hf_cip_cco_fwo_con_size = -1; +static int hf_cip_cco_ot_net_param32 = -1; +static int hf_cip_cco_to_net_param32 = -1; +static int hf_cip_cco_lfwo_own = -1; +static int hf_cip_cco_lfwo_typ = -1; +static int hf_cip_cco_lfwo_prio = -1; +static int hf_cip_cco_lfwo_fixed_var = -1; +static int hf_cip_cco_lfwo_con_size = -1; +static int hf_cip_cco_conn_path_size = -1; +static int hf_cip_cco_proxy_config_size = -1; +static int hf_cip_cco_target_config_size = -1; +static int hf_cip_cco_iomap_format_number = -1; +static int hf_cip_cco_iomap_size = -1; +static int hf_cip_cco_connection_disable = -1; +static int hf_cip_cco_net_conn_param_attr = -1; +static int hf_cip_cco_timeout_multiplier = -1; +static int hf_cip_cco_transport_type_trigger = -1; +static int hf_cip_cco_fwo_dir = -1; +static int hf_cip_cco_fwo_trigger = -1; +static int hf_cip_cco_fwo_class = -1; +static int hf_cip_cco_proxy_config_data = -1; +static int hf_cip_cco_target_config_data = -1; +static int hf_cip_cco_iomap_attribute = -1; +static int hf_cip_cco_safety = -1; +static int hf_cip_cco_change_type = -1; static int hf_cip_vendor = -1; static int hf_cip_devtype = -1; +static int hf_cip_path_segment = -1; +static int hf_cip_path_segment_type = -1; +static int hf_cip_port_segment = -1; +static int hf_cip_port_ex_link_addr = -1; static int hf_cip_port = -1; +static int hf_cip_link_address_size = -1; static int hf_cip_link_address_byte = -1; static int hf_cip_link_address_string = -1; +static int hf_cip_logical_seg_type = -1; +static int hf_cip_logical_seg_format = -1; static int hf_cip_class8 = -1; static int hf_cip_class16 = -1; static int hf_cip_class32 = -1; @@ -148,46 +245,134 @@ static int hf_cip_attribute32 = -1; static int hf_cip_conpoint8 = -1; static int hf_cip_conpoint16 = -1; static int hf_cip_conpoint32 = -1; +static int hf_cip_ekey = -1; +static int hf_cip_ekey_format = -1; +static int hf_cip_ekey_vendor = -1; +static int hf_cip_ekey_devtype = -1; +static int hf_cip_ekey_prodcode = -1; +static int hf_cip_ekey_compatibility = -1; +static int hf_cip_ekey_comp_bit = -1; +static int hf_cip_ekey_majorrev = -1; +static int hf_cip_ekey_minorrev = -1; +static int hf_cip_data_seg_type = -1; +static int hf_cip_data_seg_size = -1; +static int hf_cip_data_seg_item = -1; static int hf_cip_symbol = -1; +static int hf_cip_network_seg_type = -1; +static int hf_cip_seg_schedule = -1; +static int hf_cip_seg_fixed_tag = -1; +static int hf_cip_seg_prod_inhibit_time = -1; static int hf_cip_class_rev = -1; static int hf_cip_class_max_inst32 = -1; static int hf_cip_class_num_inst32 = -1; static int hf_cip_reserved8 = -1; +static int hf_cip_reserved16 = -1; +static int hf_cip_reserved24 = -1; +static int hf_cip_pad8 = -1; + +static int hf_cip_sc_get_attr_list_attr_count = -1; +static int hf_cip_sc_get_attr_list_attr_item = -1; +static int hf_cip_sc_get_attr_list_attr_status = -1; +static int hf_cip_sc_get_attr_list_attr_data = -1; +static int hf_cip_sc_set_attr_list_attr_count = -1; +static int hf_cip_sc_set_attr_list_attr_item = -1; +static int hf_cip_sc_set_attr_list_attr_status = -1; +static int hf_cip_sc_set_attr_list_attr_data = -1; +static int hf_cip_sc_reset_param = -1; +static int hf_cip_sc_get_attribute_all_data = -1; +static int hf_cip_sc_set_attribute_all_data = -1; +static int hf_cip_sc_reset_data = -1; +static int hf_cip_sc_start_data = -1; +static int hf_cip_sc_stop_data = -1; +static int hf_cip_sc_create_instance = -1; +static int hf_cip_sc_create_data = -1; +static int hf_cip_sc_delete_data = -1; +static int hf_cip_sc_mult_serv_pack_num_services = -1; +static int hf_cip_sc_mult_serv_pack_offset = -1; +static int hf_cip_sc_mult_serv_pack_num_replies = -1; +static int hf_cip_sc_apply_attributes_data = -1; +static int hf_cip_sc_set_attr_single_data = -1; +static int hf_cip_sc_get_attr_single_data = -1; +static int hf_cip_find_next_object_max_instance = -1; +static int hf_cip_find_next_object_num_instances = -1; +static int hf_cip_find_next_object_instance_item = -1; +static int hf_cip_sc_restore_data = -1; +static int hf_cip_sc_save_data = -1; +static int hf_cip_sc_noop_data = -1; +static int hf_cip_sc_get_member_data = -1; +static int hf_cip_sc_set_member_data = -1; +static int hf_cip_sc_insert_member_data = -1; +static int hf_cip_sc_remove_member_data = -1; +static int hf_cip_sc_group_sync_is_sync = -1; +static int hf_cip_sc_group_sync_data = -1; + +/* Parsed Attributes */ +static int hf_id_vendor_id = -1; +static int hf_id_device_type = -1; +static int hf_id_produce_code = -1; +static int hf_id_major_rev = -1; +static int hf_id_minor_rev = -1; +static int hf_id_status = -1; +static int hf_id_serial_number = -1; +static int hf_id_product_name = -1; +static int hf_msg_rout_num_classes = -1; +static int hf_msg_rout_classes = -1; +static int hf_msg_rout_num_available = -1; +static int hf_msg_rout_num_active = -1; +static int hf_msg_rout_active_connections = -1; +static int hf_conn_mgr_open_requests = -1; +static int hf_conn_mgr_open_format_rejects = -1; +static int hf_conn_mgr_open_resource_rejects = -1; +static int hf_conn_mgr_other_open_rejects = -1; +static int hf_conn_mgr_close_requests = -1; +static int hf_conn_close_format_requests = -1; +static int hf_conn_mgr_close_other_requests = -1; +static int hf_conn_mgr_conn_timouts = -1; + /* Initialize the subtree pointers */ static gint ett_cip = -1; static gint ett_cip_class_generic = -1; -static gint ett_cip_class_mr = -1; static gint ett_cip_class_cm = -1; static gint ett_cip_class_cco = -1; -static gint ett_path = -1; -static gint ett_ekey_path = -1; -static gint ett_mcsc = -1; -static gint ett_cia_path = -1; -static gint ett_data_seg = -1; -static gint ett_port_path = -1; - -static gint ett_rrsc = -1; -static gint ett_status_item = -1; -static gint ett_cmd_data = -1; +static gint ett_path = -1; +static gint ett_path_seg = -1; +static gint ett_ekey_path = -1; +static gint ett_mcsc = -1; +static gint ett_cia_path = -1; +static gint ett_data_seg = -1; +static gint ett_data_seg_data = -1; +static gint ett_port_path = -1; +static gint ett_network_seg = -1; + +static gint ett_rrsc = -1; +static gint ett_status_item = -1; +static gint ett_add_status_item = -1; +static gint ett_cmd_data = -1; + +static gint ett_cip_get_attribute_list = -1; +static gint ett_cip_get_attribute_list_item = -1; +static gint ett_cip_set_attribute_list = -1; +static gint ett_cip_set_attribute_list_item = -1; +static gint ett_cip_mult_service_packet = -1; static gint ett_cm_rrsc = -1; static gint ett_cm_ncp = -1; static gint ett_cm_mes_req = -1; static gint ett_cm_cmd_data = -1; - -static gint ett_mr_rrsc = -1; -static gint ett_mr_mult_ser = -1; -static gint ett_mr_cmd_data = -1; +static gint ett_cm_ttt = -1; +static gint ett_cm_add_status_item = -1; static gint ett_cco_iomap = -1; static gint ett_cco_con_status = -1; static gint ett_cco_con_flag = -1; static gint ett_cco_tdi = -1; +static gint ett_cco_pdi = -1; static gint ett_cco_ncp = -1; static gint ett_cco_rrsc = -1; static gint ett_cco_cmd_data = -1; +static gint ett_cco_ttt = -1; static dissector_table_t subdissector_class_table; static dissector_table_t subdissector_symbol_table; @@ -246,6 +431,14 @@ static const value_string cip_com_bit_vals[] = { { 0, NULL } }; +static const value_string cip_reset_type_vals[] = { + { 0, "Cycle Power" }, + { 1, "Factory Default" }, + { 2, "Keep Communication Parameters" }, + + { 0, NULL } +}; + /* Translate function to string - Connection priority */ static const value_string cip_con_prio_vals[] = { { 0, "Low Priority" }, @@ -360,6 +553,94 @@ static const value_string cip_cco_change_type_vals[] = { { 0, NULL } }; +static const value_string cip_path_seg_vals[] = { + { ((CI_PORT_SEGMENT>>5)&7), "Port Segment" }, + { ((CI_LOGICAL_SEGMENT>>5)&7), "Logical Segment" }, + { ((CI_NETWORK_SEGMENT>>5)&7), "Network Segment" }, + { ((CI_SYMBOLIC_SEGMENT>>5)&7), "Symbolic Segment" }, + { ((CI_DATA_SEGMENT>>5)&7), "Data Segment" }, + { 5, "Constructed Data Type" }, + { 6, "Elementary Data Type" }, + { 7, "Reserved" }, + + { 0, NULL } +}; + +static const value_string cip_logical_segment_type_vals[] = { + { ((CI_LOGICAL_SEG_CLASS_ID>>2)&7), "Class ID" }, + { ((CI_LOGICAL_SEG_INST_ID>>2)&7), "Instance ID" }, + { ((CI_LOGICAL_SEG_MBR_ID>>2)&7), "Member ID" }, + { ((CI_LOGICAL_SEG_CON_POINT>>2)&7), "Connection Point" }, + { ((CI_LOGICAL_SEG_ATTR_ID>>2)&7), "Attribute ID" }, + { ((CI_LOGICAL_SEG_SPECIAL>>2)&7), "Special" }, + { ((CI_LOGICAL_SEG_SERV_ID>>2)&7), "Service ID" }, + { ((CI_LOGICAL_SEG_RES_1>>2)&7), "Reserved" }, + + { 0, NULL } +}; + +static const value_string cip_logical_segment_format_vals[] = { + { CI_LOGICAL_SEG_8_BIT, "8-bit Logical Segment" }, + { CI_LOGICAL_SEG_16_BIT, "16-bit Logical Segment" }, + { CI_LOGICAL_SEG_32_BIT, "32-bit Logical Segment" }, + { CI_LOGICAL_SEG_RES_2, "Reserved" }, + + { 0, NULL } +}; + +static const value_string cip_logical_seg_vals[] = { + {((CI_LOGICAL_SEG_CLASS_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_8_BIT), "8-Bit Class Segment"}, + {((CI_LOGICAL_SEG_CLASS_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_16_BIT), "16-Bit Class Segment"}, + {((CI_LOGICAL_SEG_CLASS_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_32_BIT), "32-Bit Class Segment"}, + + {((CI_LOGICAL_SEG_INST_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_8_BIT), "8-Bit Instance Segment"}, + {((CI_LOGICAL_SEG_INST_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_16_BIT), "16-Bit Instance Segment"}, + {((CI_LOGICAL_SEG_INST_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_32_BIT), "32-Bit Instance Segment"}, + + {((CI_LOGICAL_SEG_MBR_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_8_BIT), "8-Bit Member Segment"}, + {((CI_LOGICAL_SEG_MBR_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_16_BIT), "16-Bit Member Segment"}, + {((CI_LOGICAL_SEG_MBR_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_32_BIT), "32-Bit Member Segment"}, + + {((CI_LOGICAL_SEG_CON_POINT & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_8_BIT), "8-Bit Connection Point Segment"}, + {((CI_LOGICAL_SEG_CON_POINT & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_16_BIT), "16-Bit Connection Point Segment"}, + {((CI_LOGICAL_SEG_CON_POINT & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_32_BIT), "32-Bit Connection Point Segment"}, + + {((CI_LOGICAL_SEG_ATTR_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_8_BIT), "8-Bit Attribute Segment"}, + {((CI_LOGICAL_SEG_ATTR_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_16_BIT), "16-Bit Attribute Segment"}, + {((CI_LOGICAL_SEG_ATTR_ID & CI_LOGICAL_SEG_TYPE_MASK)|CI_LOGICAL_SEG_32_BIT), "32-Bit Attribute Segment"}, + + {CI_LOGICAL_SEG_SPECIAL, "Electronic Key Segment"}, + + { 0, NULL } +}; + +static const value_string cip_data_segment_type_vals[] = { + {CI_DATA_SEG_SIMPLE, "Simple Data Segment"}, + {CI_DATA_SEG_SYMBOL, "ANSI Extended Symbol Segment"}, + + { 0, NULL } +}; + +static const value_string cip_network_segment_type_vals[] = { + {CI_NETWORK_SEG_SCHEDULE, "Schedule Segment"}, + {CI_NETWORK_SEG_FIXED_TAG, "Fixed Tag Segment"}, + {CI_NETWORK_SEG_PROD_INHI, "Production Inhibit Time"}, + {CI_NETWORK_SEG_SAFETY, "Safety Segment"}, + {CI_NETWORK_SEG_EXTENDED, "Extended Network Segment"}, + + { 0, NULL } +}; + +static const value_string cip_cm_rpi_type_vals[] = { + {0, "RPI acceptable"}, + {1, "Unspecified"}, + {2, "Minimum acceptable RPI"}, + {3, "Maximum acceptable RPI"}, + {4, "Required RPI to correct mismatch"}, + + { 0, NULL } +}; + /* Translate function to string - CIP General Status codes */ static const value_string cip_gs_vals[] = { { CI_GRC_SUCCESS, "Success" }, @@ -406,19 +687,1396 @@ static const value_string cip_gs_vals[] = { { CI_GRC_MEMBER_NOT_SETTABLE, "Member not settable" }, { CI_GRC_G2_SERVER_FAILURE, "Group 2 only server general failure" }, { CI_GRC_UNKNOWN_MB_ERROR, "Unknown Modbus error" }, + { CI_GRC_ATTRIBUTE_NOT_GET, "Attribute not gettable" }, { 0, NULL } }; -/* Translate Vendor ID:s */ -const value_string cip_vendor_vals[] = { - VENDOR_ID_LIST +value_string_ext cip_gs_vals_ext = VALUE_STRING_EXT_INIT(cip_gs_vals); + +/* Connection Manager Extended Status codes */ +#define CM_ES_DUP_FWD_OPEN 0x100 +#define CM_ES_CLASS_AND_TRIGGER 0x103 +#define CM_ES_OWNERSHIP_CONFLICT 0x106 +#define CM_ES_TARGET_CONN_NOT_FOUND 0x107 +#define CM_ES_INVALID_NET_CONN_PARAM 0x108 +#define CM_ES_INVALID_CONNECTION_SIZE 0x109 +#define CM_ES_TARGET_CONNECTION_NOT_CONFIGURED 0x110 +#define CM_ES_RPI_NOT_SUPPORTED 0x111 +#define CM_ES_RPI_NOT_ACCEPTABLE 0x112 +#define CM_ES_OUT_OF_CONNECTIONS 0x113 +#define CM_ES_VENDOR_ID_OR_PRODUCT_CODE_MISMATCH 0x114 +#define CM_ES_DEVICE_TYPE_MISMATCH 0x115 +#define CM_ES_REVISION_MISMATCH 0x116 +#define CM_ES_INVALID_PROD_CONS_APP_PATH 0x117 +#define CM_ES_INVALID_OR_INCONSISTENT_CONF_APP_PATH 0x118 +#define CM_ES_NON_LISTEN_ONLY_CONN_NOT_OPENED 0x119 +#define CM_ES_TARGET_OBJECT_OUT_OF_CONNECTIONS 0x11A +#define CM_ES_RPI_SMALLER_THAN_PROD_INHIBIT_TIME 0x11B +#define CM_ES_TRANSPORT_CLASS_NOT_SUPPORTED 0x11C +#define CM_ES_PRODUCTION_TRIGGER_NOT_SUPPORTED 0x11D +#define CM_ES_DIRECTION_NOT_SUPPORTED 0x11E +#define CM_ES_INVALID_OT_NET_CONN_FIX_VAR 0x11F +#define CM_ES_INVALID_TO_NET_CONN_FIX_VAR 0x120 +#define CM_ES_INVALID_OT_NET_CONN_PRIORITY 0x121 +#define CM_ES_INVALID_TO_NET_CONN_PRIORITY 0x122 +#define CM_ES_INVALID_OT_NET_CONN_TYPE 0x123 +#define CM_ES_INVALID_TO_NET_CONN_TYPE 0x124 +#define CM_ES_INVALID_OT_NET_CONN_REDUNDANT_OWNER 0x125 +#define CM_ES_INVALID_CONFIGURATION_SIZE 0x126 +#define CM_ES_INVALID_OT_SIZE 0x127 +#define CM_ES_INVALID_TO_SIZE 0x128 +#define CM_ES_INVALID_CONFIGURATION_APP_PATH 0x129 +#define CM_ES_INVALID_CONSUMING_APP_PATH 0x12A +#define CM_ES_INVALID_PRODUCING_APP_PATH 0x12B +#define CM_ES_CONFIGURATION_SYMBOL_NOT_EXIST 0x12C +#define CM_ES_CONSUMING_SYMBOL_NOT_EXIST 0x12D +#define CM_ES_PRODUCING_SYMBOL_NOT_EXIST 0x12E +#define CM_ES_INCONSISTENT_APP_PATH_COMBO 0x12F +#define CM_ES_INCONSISTENT_CONSUME_DATA_FORMAT 0x130 +#define CM_ES_INCONSISTENT_PRODUCE_DATA_FORMAT 0x131 +#define CM_ES_NULL_FORWARD_OPEN_NOT_SUPPORTED 0x132 +#define CM_ES_CONNECTION_TIMED_OUT 0x203 +#define CM_ES_UNCONNECTED_REQUEST_TIMED_OUT 0x204 +#define CM_ES_PARAMETER_ERROR_IN_UNCONNECTED_REQUEST 0x205 +#define CM_ES_MESSAGE_TOO_LARGE_FOR_UNCONNECTED_SEND 0x206 +#define CM_ES_UNCONNECTED_ACK_WITHOUT_REPLY 0x207 +#define CM_ES_NO_BUFFER_MEMORY_AVAILABLE 0x301 +#define CM_ES_NETWORK_BANDWIDTH_NOT_AVAIL_FOR_DATA 0x302 +#define CM_ES_NO_CONSUMED_CONN_ID_FILTER_AVAILABLE 0x303 +#define CM_ES_NOT_CONFIGURED_TO_SEND_SCHEDULED_DATA 0x304 +#define CM_ES_SCHEDULE_SIGNATURE_MISMATCH 0x305 +#define CM_ES_SCHEDULE_SIGNATURE_VALIDATION_NOT_POSS 0x306 +#define CM_ES_PORT_NOT_AVAILABLE 0x311 +#define CM_ES_LINK_ADDRESS_NOT_VALID 0x312 +#define CM_ES_INVALID_SEGMENT_IN_CONN_PATH 0x315 +#define CM_ES_FWD_CLOSE_CONN_PATH_MISMATCH 0x316 +#define CM_ES_SCHEDULING_NOT_SPECIFIED 0x317 +#define CM_ES_LINK_ADDRESS_TO_SELF_INVALID 0x318 +#define CM_ES_SECONDARY_RESOURCES_UNAVAILABLE 0x319 +#define CM_ES_RACK_CONNECTION_ALREADY_ESTABLISHED 0x31A +#define CM_ES_MODULE_CONNECTION_ALREADY_ESTABLISHED 0x31B +#define CM_ES_MISCELLANEOUS 0x31C +#define CM_ES_REDUNDANT_CONNECTION_MISMATCH 0x31D +#define CM_ES_NO_CONSUMER_RES_AVAIL_IN_PROD_MODULE 0x31E +#define CM_ES_NO_CONSUMER_RES_CONF_IN_PROD_MODULE 0x31F +#define CM_ES_NETWORK_LINK_OFFLINE 0x800 +#define CM_ES_NO_TARGET_APP_DATA_AVAILABLE 0x810 +#define CM_ES_NO_ORIG_APP_DATA_AVAILABLE 0x811 +#define CM_ES_NODE_ADDRESS_CHANGED_AFTER_SCHEDULED 0x812 +#define CM_ES_NOT_CONFIGURED_MULTICAST 0x813 +#define CM_ES_INVALID_PROD_CONS_DATA_FORMAT 0x814 + +/* Translate function to string - CIP General Status codes */ +static const value_string cip_cm_ext_st_vals[] = { + { CM_ES_DUP_FWD_OPEN, "Connection in use or duplicate Forward Open" }, + { CM_ES_CLASS_AND_TRIGGER, "Transport class and trigger combination not supported" }, + { CM_ES_OWNERSHIP_CONFLICT, "Ownership conflict" }, + { CM_ES_TARGET_CONN_NOT_FOUND, "Target connection not found" }, + { CM_ES_INVALID_NET_CONN_PARAM, "Invalid network connection parameter" }, + { CM_ES_INVALID_CONNECTION_SIZE, "Invalid connection size" }, + { CM_ES_TARGET_CONNECTION_NOT_CONFIGURED, "Target for connection not configured" }, + { CM_ES_RPI_NOT_SUPPORTED, "RPI not supported" }, + { CM_ES_RPI_NOT_ACCEPTABLE, "RPI value(s) not acceptable" }, + { CM_ES_OUT_OF_CONNECTIONS, "Out of connections" }, + { CM_ES_VENDOR_ID_OR_PRODUCT_CODE_MISMATCH, "Vendor ID or product code mismatch" }, + { CM_ES_DEVICE_TYPE_MISMATCH, "Device type mismatch" }, + { CM_ES_REVISION_MISMATCH, "Revision mismatch" }, + { CM_ES_INVALID_PROD_CONS_APP_PATH, "Invalid produced or consumed application path" }, + { CM_ES_INVALID_OR_INCONSISTENT_CONF_APP_PATH, "Invalid or inconsistent configuration application path" }, + { CM_ES_NON_LISTEN_ONLY_CONN_NOT_OPENED, "Non-listen only connection not opened" }, + { CM_ES_TARGET_OBJECT_OUT_OF_CONNECTIONS, "Target object out of connections" }, + { CM_ES_RPI_SMALLER_THAN_PROD_INHIBIT_TIME, "RPI is smaller than the production inhibit time" }, + { CM_ES_TRANSPORT_CLASS_NOT_SUPPORTED, "Transport class not supported" }, + { CM_ES_PRODUCTION_TRIGGER_NOT_SUPPORTED, "Production trigger not supported" }, + { CM_ES_DIRECTION_NOT_SUPPORTED, "Direction not supported" }, + { CM_ES_INVALID_OT_NET_CONN_FIX_VAR, "Invalid O->T Fixed/Variable" }, + { CM_ES_INVALID_TO_NET_CONN_FIX_VAR, "Invalid T->O Fixed/Variable" }, + { CM_ES_INVALID_OT_NET_CONN_PRIORITY, "Invalid O->T Priority" }, + { CM_ES_INVALID_TO_NET_CONN_PRIORITY, "Invalid T->O Priority" }, + { CM_ES_INVALID_OT_NET_CONN_TYPE, "Invalid O->T connection type" }, + { CM_ES_INVALID_TO_NET_CONN_TYPE, "Invalid T->O connection type" }, + { CM_ES_INVALID_OT_NET_CONN_REDUNDANT_OWNER, "Invalid O->T redundant owner" }, + { CM_ES_INVALID_CONFIGURATION_SIZE, "Invalid configuration size" }, + { CM_ES_INVALID_OT_SIZE, "Invalid O->T size" }, + { CM_ES_INVALID_TO_SIZE, "Invalid T->O size" }, + { CM_ES_INVALID_CONFIGURATION_APP_PATH, "Invalid configuration application path" }, + { CM_ES_INVALID_CONSUMING_APP_PATH, "Invalid consuming application path" }, + { CM_ES_INVALID_PRODUCING_APP_PATH, "Invalid producing application path" }, + { CM_ES_CONFIGURATION_SYMBOL_NOT_EXIST, "Configuration symbol does not exist" }, + { CM_ES_CONSUMING_SYMBOL_NOT_EXIST, "Consuming symbol does not exist" }, + { CM_ES_PRODUCING_SYMBOL_NOT_EXIST, "Producing symbol does not exist" }, + { CM_ES_INCONSISTENT_APP_PATH_COMBO, "Inconsistent application path combination" }, + { CM_ES_INCONSISTENT_CONSUME_DATA_FORMAT, "Inconsistent consume data format" }, + { CM_ES_INCONSISTENT_PRODUCE_DATA_FORMAT, "Inconsistent produce data format" }, + { CM_ES_NULL_FORWARD_OPEN_NOT_SUPPORTED, "NULL ForwardOpen not supported" }, + { CM_ES_CONNECTION_TIMED_OUT, "Connection timed out" }, + { CM_ES_UNCONNECTED_REQUEST_TIMED_OUT, "Unconnected request timed out" }, + { CM_ES_PARAMETER_ERROR_IN_UNCONNECTED_REQUEST, "Parameter error in unconnected request" }, + { CM_ES_MESSAGE_TOO_LARGE_FOR_UNCONNECTED_SEND, "Message too large for UnconnectedSend" }, + { CM_ES_UNCONNECTED_ACK_WITHOUT_REPLY, "Unconnected acknowledged without reply" }, + { CM_ES_NO_BUFFER_MEMORY_AVAILABLE, "No buffer memory available" }, + { CM_ES_NETWORK_BANDWIDTH_NOT_AVAIL_FOR_DATA, "Network bandwidth not available for data" }, + { CM_ES_NO_CONSUMED_CONN_ID_FILTER_AVAILABLE, "No consumed connection ID filter available" }, + { CM_ES_NOT_CONFIGURED_TO_SEND_SCHEDULED_DATA, "Not confgured to send scheduled priority data" }, + { CM_ES_SCHEDULE_SIGNATURE_MISMATCH, "Schedule signature mismatch" }, + { CM_ES_SCHEDULE_SIGNATURE_VALIDATION_NOT_POSS, "Schedule signature validation not possible" }, + { CM_ES_PORT_NOT_AVAILABLE, "Port not available" }, + { CM_ES_LINK_ADDRESS_NOT_VALID, "Link address not valid" }, + { CM_ES_INVALID_SEGMENT_IN_CONN_PATH, "Invalid segment in connection path" }, + { CM_ES_FWD_CLOSE_CONN_PATH_MISMATCH, "ForwardClose connection path mismatch" }, + { CM_ES_SCHEDULING_NOT_SPECIFIED, "Scheduling not specified" }, + { CM_ES_LINK_ADDRESS_TO_SELF_INVALID, "Link address to self invalid" }, + { CM_ES_SECONDARY_RESOURCES_UNAVAILABLE, "Secondary resources unavailable" }, + { CM_ES_RACK_CONNECTION_ALREADY_ESTABLISHED, "Rack connection already established" }, + { CM_ES_MODULE_CONNECTION_ALREADY_ESTABLISHED, "Module connection already established" }, + { CM_ES_MISCELLANEOUS, "Miscellaneous" }, + { CM_ES_REDUNDANT_CONNECTION_MISMATCH, "Redundant connection mismatch" }, + { CM_ES_NO_CONSUMER_RES_AVAIL_IN_PROD_MODULE, "No more user configurable link consumer resources available in the producing module" }, + { CM_ES_NO_CONSUMER_RES_CONF_IN_PROD_MODULE, "No more user configurable link consumer resources configured in the producing module" }, + { CM_ES_NETWORK_LINK_OFFLINE, "Network link offline" }, + { CM_ES_NO_TARGET_APP_DATA_AVAILABLE, "No target application data available" }, + { CM_ES_NO_ORIG_APP_DATA_AVAILABLE, "No originator application data available" }, + { CM_ES_NODE_ADDRESS_CHANGED_AFTER_SCHEDULED, "Node address has changed since the network was scheduled" }, + { CM_ES_NOT_CONFIGURED_MULTICAST, "Not configured for off-subnet multicast" }, + { CM_ES_INVALID_PROD_CONS_DATA_FORMAT, "Invalid produce/consume data format" }, + + { 0, NULL } +}; + +value_string_ext cip_cm_ext_st_vals_ext = VALUE_STRING_EXT_INIT(cip_cm_ext_st_vals); + +/* Translate Vendor IDs */ +static const value_string cip_vendor_vals[] = { + { 0, "Reserved" }, + { 1, "Rockwell Automation/Allen-Bradley" }, + { 2, "Namco Controls Corp." }, + { 3, "Honeywell Inc." }, + { 4, "Parker Hannifin Corp. (Veriflo Division)" }, + { 5, "Rockwell Automation/Reliance Elec." }, + { 6, "Reserved" }, + { 7, "SMC Corporation" }, + { 8, "Molex Incorporated" }, + { 9, "Western Reserve Controls Corp." }, + { 10, "Advanced Micro Controls Inc. (AMCI)" }, + { 11, "ASCO Pneumatic Controls" }, + { 12, "Banner Engineering Corp." }, + { 13, "Belden Wire & Cable Company" }, + { 14, "Cooper Interconnect" }, + { 15, "Reserved" }, + { 16, "Daniel Woodhead Co. (Woodhead Connectivity)" }, + { 17, "Dearborn Group Inc." }, + { 18, "Reserved" }, + { 19, "Helm Instrument Company" }, + { 20, "Huron Net Works" }, + { 21, "Lumberg, Inc." }, + { 22, "Online Development Inc.(Automation Value)" }, + { 23, "Vorne Industries, Inc." }, + { 24, "ODVA Special Reserve" }, + { 25, "Reserved" }, + { 26, "Festo Corporation" }, + { 27, "Reserved" }, + { 28, "Reserved" }, + { 29, "Reserved" }, + { 30, "Unico, Inc." }, + { 31, "Ross Controls" }, + { 32, "Reserved" }, + { 33, "Reserved" }, + { 34, "Hohner Corp." }, + { 35, "Micro Mo Electronics, Inc." }, + { 36, "MKS Instruments, Inc." }, + { 37, "Yaskawa Electric America formerly Magnetek Drives" }, + { 38, "Reserved" }, + { 39, "AVG Automation (Uticor)" }, + { 40, "Wago Corporation" }, + { 41, "Kinetics (Unit Instruments)" }, + { 42, "IMI Norgren Limited" }, + { 43, "BALLUFF, Inc." }, + { 44, "Yaskawa Electric America, Inc." }, + { 45, "Eurotherm Controls Inc" }, + { 46, "ABB Industrial Systems" }, + { 47, "Omron Corporation" }, + { 48, "TURCk, Inc." }, + { 49, "Grayhill Inc." }, + { 50, "Real Time Automation (C&ID)" }, + { 51, "Reserved" }, + { 52, "Numatics, Inc." }, + { 53, "Lutze, Inc." }, + { 54, "Reserved" }, + { 55, "Reserved" }, + { 56, "Softing GmbH" }, + { 57, "Pepperl + Fuchs" }, + { 58, "Spectrum Controls, Inc." }, + { 59, "D.I.P. Inc. MKS Inst." }, + { 60, "Applied Motion Products, Inc." }, + { 61, "Sencon Inc." }, + { 62, "High Country Tek" }, + { 63, "SWAC Automation Consult GmbH" }, + { 64, "Clippard Instrument Laboratory" }, + { 65, "Reserved" }, + { 66, "Reserved" }, + { 67, "Reserved" }, + { 68, "Eaton Electrical" }, + { 69, "Reserved" }, + { 70, "Reserved" }, + { 71, "Toshiba International Corp." }, + { 72, "Control Technology Incorporated" }, + { 73, "TCS (NZ) Ltd." }, + { 74, "Hitachi, Ltd." }, + { 75, "ABB Robotics Products AB" }, + { 76, "NKE Corporation" }, + { 77, "Rockwell Software, Inc." }, + { 78, "Escort Memory Systems (A Datalogic Group Co.)" }, + { 79, "Reserved" }, + { 80, "Industrial Devices Corporation" }, + { 81, "IXXAT Automation GmbH" }, + { 82, "Mitsubishi Electric Automation, Inc." }, + { 83, "OPTO-22" }, + { 84, "Reserved" }, + { 85, "Reserved" }, + { 86, "Horner Electric" }, + { 87, "Burkert Werke GmbH & Co. KG" }, + { 88, "Reserved" }, + { 89, "Industrial Indexing Systems, Inc." }, + { 90, "HMS Industrial Networks AB" }, + { 91, "Robicon" }, + { 92, "Helix Technology (Granville-Phillips)" }, + { 93, "Arlington Laboratory" }, + { 94, "Advantech Co. Ltd." }, + { 95, "Square D Company" }, + { 96, "Digital Electronics Corp." }, + { 97, "Danfoss" }, + { 98, "Reserved" }, + { 99, "Reserved" }, + { 100, "Bosch Rexroth Corporation, Pneumatics" }, + { 101, "Applied Materials, Inc." }, + { 102, "Showa Electric Wire & Cable Co." }, + { 103, "Pacific Scientific (API Controls Inc.)" }, + { 104, "Sharp Manufacturing Systems Corp." }, + { 105, "Olflex Wire & Cable, Inc." }, + { 106, "Reserved" }, + { 107, "Unitrode" }, + { 108, "Beckhoff Automation GmbH" }, + { 109, "National Instruments" }, + { 110, "Mykrolis Corporations (Millipore)" }, + { 111, "International Motion Controls Corp." }, + { 112, "Reserved" }, + { 113, "SEG Kempen GmbH" }, + { 114, "Reserved" }, + { 115, "Reserved" }, + { 116, "MTS Systems Corp." }, + { 117, "Krones, Inc" }, + { 118, "Reserved" }, + { 119, "EXOR Electronic R & D" }, + { 120, "SIEI S.p.A." }, + { 121, "KUKA Roboter GmbH" }, + { 122, "Reserved" }, + { 123, "SEC (Samsung Electronics Co., Ltd)" }, + { 124, "Binary Electronics Ltd" }, + { 125, "Flexible Machine Controls" }, + { 126, "Reserved" }, + { 127, "ABB Inc. (Entrelec)" }, + { 128, "MAC Valves, Inc." }, + { 129, "Auma Actuators Inc" }, + { 130, "Toyoda Machine Works, Ltd" }, + { 131, "Reserved" }, + { 132, "Reserved" }, + { 133, "Balogh T.A.G., Corporation" }, + { 134, "TR Systemtechnik GmbH" }, + { 135, "UNIPULSE Corporation" }, + { 136, "Reserved" }, + { 137, "Reserved" }, + { 138, "Conxall Corporation Inc." }, + { 139, "Reserved" }, + { 140, "Reserved" }, + { 141, "Kuramo Electric Co., Ltd." }, + { 142, "Creative Micro Designs" }, + { 143, "GE Industrial Systems" }, + { 144, "Leybold Vacuum GmbH" }, + { 145, "Siemens Energy & Automation/Drives" }, + { 146, "Kodensha Ltd" }, + { 147, "Motion Engineering, Inc." }, + { 148, "Honda Engineering Co., Ltd" }, + { 149, "EIM Valve Controls" }, + { 150, "Melec Inc." }, + { 151, "Sony Manufacturing Systems Corporation" }, + { 152, "North American Mfg." }, + { 153, "WATLOW" }, + { 154, "Japan Radio Co., Ltd" }, + { 155, "NADEX Co., Ltd" }, + { 156, "Ametek Automation & Process Technologies" }, + { 157, "Reserved" }, + { 158, "KVASER AB" }, + { 159, "IDEC IZUMI Corporation" }, + { 160, "Mitsubishi Heavy Industries Ltd" }, + { 161, "Mitsubishi Electric Corporation" }, + { 162, "Horiba-STEC Inc." }, + { 163, "esd electronic system design gmbh" }, + { 164, "DAIHEN Corporation" }, + { 165, "Tyco Valves & Controls/Keystone" }, + { 166, "EBARA Corporation" }, + { 167, "Reserved" }, + { 168, "Reserved" }, + { 169, "Hokuyo Electric Co. Ltd" }, + { 170, "Pyramid Solutions, Inc." }, + { 171, "Denso Wave Incorporated" }, + { 172, "HLS Hard-Line Solutions Inc" }, + { 173, "Caterpillar, Inc." }, + { 174, "PDL Electronics Ltd." }, + { 175, "Reserved" }, + { 176, "Red Lion Controls" }, + { 177, "ANELVA Corporation" }, + { 178, "Toyo Denki Seizo KK" }, + { 179, "Sanyo Denki Co., Ltd" }, + { 180, "Advanced Energy Japan K.K. (Aera Japan)" }, + { 181, "Pilz GmbH & Co" }, + { 182, "Marsh Bellofram-Bellofram PCD Division" }, + { 183, "Reserved" }, + { 184, "M-SYSTEM Co. Ltd" }, + { 185, "Nissin Electric Co., Ltd" }, + { 186, "Hitachi Metals Ltd." }, + { 187, "Oriental Motor Company" }, + { 188, "A&D Co., Ltd" }, + { 189, "Phasetronics, Inc." }, + { 190, "Cummins Engine Company" }, + { 191, "Deltron Inc." }, + { 192, "Geneer Corporation" }, + { 193, "Anatol Automation, Inc." }, + { 194, "Reserved" }, + { 195, "Reserved" }, + { 196, "Medar, Inc." }, + { 197, "Comdel Inc." }, + { 198, "Advanced Energy Industries, Inc" }, + { 199, "Reserved" }, + { 200, "DAIDEN Co., Ltd" }, + { 201, "CKD Corporation" }, + { 202, "Toyo Electric Corporation" }, + { 203, "Reserved" }, + { 204, "AuCom Electronics Ltd" }, + { 205, "Shinko Electric Co., Ltd" }, + { 206, "Vector Informatik GmbH" }, + { 207, "Reserved" }, + { 208, "Moog Inc." }, + { 209, "Contemporary Controls" }, + { 210, "Tokyo Sokki Kenkyujo Co., Ltd" }, + { 211, "Schenck-AccuRate, Inc." }, + { 212, "The Oilgear Company" }, + { 213, "Reserved" }, + { 214, "ASM Japan K.K." }, + { 215, "HIRATA Corp." }, + { 216, "SUNX Limited" }, + { 217, "Meidensha Corp." }, + { 218, "NIDEC SANKYO CORPORATION (Sankyo Seiki Mfg. Co., Ltd)" }, + { 219, "KAMRO Corp." }, + { 220, "Nippon System Development Co., Ltd" }, + { 221, "EBARA Technologies Inc." }, + { 222, "Reserved" }, + { 223, "Reserved" }, + { 224, "SG Co., Ltd" }, + { 225, "Vaasa Institute of Technology" }, + { 226, "MKS Instruments (ENI Technology)" }, + { 227, "Tateyama System Laboratory Co., Ltd." }, + { 228, "QLOG Corporation" }, + { 229, "Matric Limited Inc." }, + { 230, "NSD Corporation" }, + { 231, "Reserved" }, + { 232, "Sumitomo Wiring Systems, Ltd" }, + { 233, "Group 3 Technology Ltd" }, + { 234, "CTI Cryogenics" }, + { 235, "POLSYS CORP" }, + { 236, "Ampere Inc." }, + { 237, "Reserved" }, + { 238, "Simplatroll Ltd" }, + { 239, "Reserved" }, + { 240, "Reserved" }, + { 241, "Leading Edge Design" }, + { 242, "Humphrey Products" }, + { 243, "Schneider Automation, Inc." }, + { 244, "Westlock Controls Corp." }, + { 245, "Nihon Weidmuller Co., Ltd" }, + { 246, "Brooks Instrument (Div. of Emerson)" }, + { 247, "Reserved" }, + { 248, " Moeller GmbH" }, + { 249, "Varian Vacuum Products" }, + { 250, "Yokogawa Electric Corporation" }, + { 251, "Electrical Design Daiyu Co., Ltd" }, + { 252, "Omron Software Co., Ltd" }, + { 253, "BOC Edwards" }, + { 254, "Control Technology Corporation" }, + { 255, "Bosch Rexroth" }, + { 256, "Turck" }, + { 257, "Control Techniques PLC" }, + { 258, "Hardy Instruments, Inc." }, + { 259, "LS Industrial Systems" }, + { 260, "E.O.A. Systems Inc." }, + { 261, "Reserved" }, + { 262, "New Cosmos Electric Co., Ltd." }, + { 263, "Sense Eletronica LTDA" }, + { 264, "Xycom, Inc." }, + { 265, "Baldor Electric" }, + { 266, "Reserved" }, + { 267, "Patlite Corporation" }, + { 268, "Reserved" }, + { 269, "Mogami Wire & Cable Corporation" }, + { 270, "Welding Technology Corporation (WTC)" }, + { 271, "Reserved" }, + { 272, "Deutschmann Automation GmbH" }, + { 273, "ICP Panel-Tec Inc." }, + { 274, "Bray Controls USA" }, + { 275, "Reserved" }, + { 276, "Status Technologies" }, + { 277, "Trio Motion Technology Ltd" }, + { 278, "Sherrex Systems Ltd" }, + { 279, "Adept Technology, Inc." }, + { 280, "Spang Power Electronics" }, + { 281, "Reserved" }, + { 282, "Acrosser Technology Co., Ltd" }, + { 283, "Hilscher GmbH" }, + { 284, "IMAX Corporation" }, + { 285, "Electronic Innovation, Inc. (Falter Engineering)" }, + { 286, "Netlogic Inc." }, + { 287, "Bosch Rexroth Corporation, Indramat" }, + { 288, "Reserved" }, + { 289, "Reserved" }, + { 290, "Murata Machinery Ltd." }, + { 291, "MTT Company Ltd." }, + { 292, "Kanematsu Semiconductor Corp." }, + { 293, "Takebishi Electric Sales Co." }, + { 294, "Tokyo Electron Device Ltd" }, + { 295, "PFU Limited" }, + { 296, "Hakko Automation Co., Ltd." }, + { 297, "Advanet Inc." }, + { 298, "Tokyo Electron Software Technologies Ltd." }, + { 299, "Reserved" }, + { 300, "Shinagawa Electric Wire Co., Ltd." }, + { 301, "Yokogawa M&C Corporation" }, + { 302, "KONAN Electric Co., Ltd." }, + { 303, "Binar Elektronik AB" }, + { 304, "Furukawa Electric Co." }, + { 305, "Cooper Energy Services" }, + { 306, "Schleicher GmbH & Co." }, + { 307, "Hirose Electric Co., Ltd" }, + { 308, "Western Servo Design Inc." }, + { 309, "Prosoft Technology" }, + { 310, "Reserved" }, + { 311, "Towa Shoko Co., Ltd" }, + { 312, "Kyopal Co., Ltd" }, + { 313, "Extron Co." }, + { 314, "Wieland Electric GmbH" }, + { 315, "SEW Eurodrive GmbH" }, + { 316, "Aera Corporation" }, + { 317, "STA Reutlingen" }, + { 318, "Reserved" }, + { 319, "Fuji Electric Co., Ltd." }, + { 320, "Reserved" }, + { 321, "Reserved" }, + { 322, "ifm efector, inc." }, + { 323, "Reserved" }, + { 324, "IDEACOD-Hohner Automation S.A." }, + { 325, "CommScope Inc." }, + { 326, "GE Fanuc Automation North America, Inc." }, + { 327, "Matsushita Electric Industrial Co., Ltd" }, + { 328, "Okaya Electronics Corporation" }, + { 329, "KASHIYAMA Industries, Ltd" }, + { 330, "JVC" }, + { 331, "Interface Corporation" }, + { 332, "Grape Systems Inc." }, + { 333, "Reserved" }, + { 344, "Reserved" }, + { 335, "Toshiba IT & Control Systems Corporation" }, + { 336, "Sanyo Machine Works, Ltd." }, + { 337, "Vansco Electronics Ltd." }, + { 338, "Dart Container Corp." }, + { 339, "Livingston & Co., Inc." }, + { 340, "Alfa Laval LKM as" }, + { 341, "BF ENTRON Ltd. (British Federal)" }, + { 342, "Bekaert Engineering NV" }, + { 343, "Ferran Scientific Inc." }, + { 344, "KEBA AG" }, + { 345, "Endress + Hauser" }, + { 346, "Reserved" }, + { 347, "ABB ALSTOM Power UK Ltd. (EGT)" }, + { 348, "Berger Lahr GmbH" }, + { 349, "Reserved" }, + { 350, "Federal Signal Corp." }, + { 351, "Kawasaki Robotics (USA), Inc." }, + { 352, "Bently Nevada Corporation" }, + { 353, "Reserved" }, + { 354, "FRABA Posital GmbH" }, + { 355, "Elsag Bailey, Inc." }, + { 356, "Fanuc Robotics America" }, + { 357, "Reserved" }, + { 358, "Surface Combustion, Inc." }, + { 359, "Reserved" }, + { 360, "AILES Electronics Ind. Co., Ltd." }, + { 361, "Wonderware Corporation" }, + { 362, "Particle Measuring Systems, Inc." }, + { 363, "Reserved" }, + { 364, "Reserved" }, + { 365, "BITS Co., Ltd" }, + { 366, "Japan Aviation Electronics Industry Ltd" }, + { 367, "Keyence Corporation" }, + { 368, "Kuroda Precision Industries Ltd." }, + { 369, "Mitsubishi Electric Semiconductor Application" }, + { 370, "Nippon Seisen Cable, Ltd." }, + { 371, "Omron ASO Co., Ltd" }, + { 372, "Seiko Seiki Co., Ltd." }, + { 373, "Sumitomo Heavy Industries, Ltd." }, + { 374, "Tango Computer Service Corporation" }, + { 375, "Technology Service, Inc." }, + { 376, "Toshiba Information Systems (Japan) Corporation" }, + { 377, "TOSHIBA Schneider Inverter Corporation" }, + { 378, "Toyooki Kogyo Co., Ltd." }, + { 379, "XEBEC" }, + { 380, "Madison Cable Corporation" }, + { 381, "Hitati Engineering & Services Co., Ltd" }, + { 382, "TEM-TECH Lab Co., Ltd" }, + { 383, "International Laboratory Corporation" }, + { 384, "Dyadic Systems Co., Ltd." }, + { 385, "SETO Electronics Industry Co., Ltd" }, + { 386, "Tokyo Electron Kyushu Limited" }, + { 387, "KEI System Co., Ltd" }, + { 388, "Reserved" }, + { 389, "Asahi Engineering Co., Ltd" }, + { 390, "Contrex Inc." }, + { 391, "Paradigm Controls Ltd." }, + { 392, "Reserved" }, + { 393, "Ohm Electric Co., Ltd." }, + { 394, "RKC Instrument Inc." }, + { 395, "Suzuki Motor Corporation" }, + { 396, "Custom Servo Motors Inc." }, + { 397, "PACE Control Systems" }, + { 398, "Reserved" }, + { 399, "Reserved" }, + { 400, "LINTEC Co., Ltd." }, + { 401, "Hitachi Cable Ltd." }, + { 402, "BUSWARE Direct" }, + { 403, "Eaton Electric B.V. (former Holec Holland N.V.)" }, + { 404, "VAT Vakuumventile AG" }, + { 405, "Scientific Technologies Incorporated" }, + { 406, "Alfa Instrumentos Eletronicos Ltda" }, + { 407, "TWK Elektronik GmbH" }, + { 408, "ABB Welding Systems AB" }, + { 409, "BYSTRONIC Maschinen AG" }, + { 410, "Kimura Electric Co., Ltd" }, + { 411, "Nissei Plastic Industrial Co., Ltd" }, + { 412, "Reserved" }, + { 413, "Kistler-Morse Corporation" }, + { 414, "Proteous Industries Inc." }, + { 415, "IDC Corporation" }, + { 416, "Nordson Corporation" }, + { 417, "Rapistan Systems" }, + { 418, "LP-Elektronik GmbH" }, + { 419, "GERBI & FASE S.p.A.(Fase Saldatura)" }, + { 420, "Phoenix Digital Corporation" }, + { 421, "Z-World Engineering" }, + { 422, "Honda R&D Co., Ltd." }, + { 423, "Bionics Instrument Co., Ltd." }, + { 424, "Teknic, Inc." }, + { 425, "R.Stahl, Inc." }, + { 426, "Reserved" }, + { 427, "Ryco Graphic Manufacturing Inc." }, + { 428, "Giddings & Lewis, Inc." }, + { 429, "Koganei Corporation" }, + { 430, "Reserved" }, + { 431, "Nichigoh Communication Electric Wire Co., Ltd." }, + { 432, "Reserved" }, + { 433, "Fujikura Ltd." }, + { 434, "AD Link Technology Inc." }, + { 435, "StoneL Corporation" }, + { 436, "Computer Optical Products, Inc." }, + { 437, "CONOS Inc." }, + { 438, "Erhardt + Leimer GmbH" }, + { 439, "UNIQUE Co. Ltd" }, + { 440, "Roboticsware, Inc." }, + { 441, "Nachi Fujikoshi Corporation" }, + { 442, "Hengstler GmbH" }, + { 443, "Reserved" }, + { 444, "SUNNY GIKEN Inc." }, + { 445, "Lenze Drive Systems GmbH" }, + { 446, "CD Systems B.V." }, + { 447, "FMT/Aircraft Gate Support Systems AB" }, + { 448, "Axiomatic Technologies Corp" }, + { 449, "Embedded System Products, Inc." }, + { 450, "Reserved" }, + { 451, "Mencom Corporation" }, + { 452, "Reserved" }, + { 453, "Matsushita Welding Systems Co., Ltd." }, + { 454, "Dengensha Mfg. Co. Ltd." }, + { 455, "Quinn Systems Ltd." }, + { 456, "Tellima Technology Ltd" }, + { 457, "MDT, Software" }, + { 458, "Taiwan Keiso Co., Ltd" }, + { 459, "Pinnacle Systems" }, + { 460, "Ascom Hasler Mailing Sys" }, + { 461, "INSTRUMAR Limited" }, + { 462, "Reserved" }, + { 463, "Navistar International Transportation Corp" }, + { 464, "Huettinger Elektronik GmbH + Co. KG" }, + { 465, "OCM Technology Inc." }, + { 466, "Professional Supply Inc." }, + { 467, "Control Solutions" }, + { 468, "Baumer IVO GmbH & Co. KG" }, + { 469, "Worcester Controls Corporation" }, + { 470, "Pyramid Technical Consultants, Inc." }, + { 471, "Reserved" }, + { 472, "Apollo Fire Detectors Limited" }, + { 473, "Avtron Manufacturing, Inc." }, + { 474, "Reserved" }, + { 475, "Tokyo Keiso Co., Ltd." }, + { 476, "Daishowa Swiki Co., Ltd." }, + { 477, "Kojima Instruments Inc." }, + { 478, "Shimadzu Corporation" }, + { 479, "Tatsuta Electric Wire & Cable Co., Ltd." }, + { 480, "MECS Corporation" }, + { 481, "Tahara Electric" }, + { 482, "Koyo Electronics" }, + { 483, "Clever Devices" }, + { 484, "GCD Hardware & Software GmbH" }, + { 485, "Reserved" }, + { 486, "Miller Electric Mfg Co." }, + { 487, "GEA Tuchenhagen GmbH" }, + { 488, "Riken Keiki Co., LTD" }, + { 489, "Keisokugiken Corporation" }, + { 490, "Fuji Machine Mfg. Co., Ltd" }, + { 491, "Reserved" }, + { 492, "Nidec-Shimpo Corp." }, + { 493, "UTEC Corporation" }, + { 494, "Sanyo Electric Co. Ltd." }, + { 495, "Reserved" }, + { 496, "Reserved" }, + { 497, "Okano Electric Wire Co. Ltd" }, + { 498, "Shimaden Co. Ltd." }, + { 499, "Teddington Controls Ltd" }, + { 500, "Reserved" }, + { 501, "VIPA GmbH" }, + { 502, "Warwick Manufacturing Group" }, + { 503, "Danaher Controls" }, + { 504, "Reserved" }, + { 505, "Reserved" }, + { 506, "American Science & Engineering" }, + { 507, "Accutron Controls International Inc." }, + { 508, "Norcott Technologies Ltd" }, + { 509, "TB Woods, Inc" }, + { 510, "Proportion-Air, Inc." }, + { 511, "SICK Stegmann GmbH" }, + { 512, "Reserved" }, + { 513, "Edwards Signaling" }, + { 514, "Sumitomo Metal Industries, Ltd" }, + { 515, "Cosmo Instruments Co., Ltd." }, + { 516, "Denshosha Co., Ltd." }, + { 517, "Kaijo Corp." }, + { 518, "Michiproducts Co., Ltd." }, + { 519, "Miura Corporation" }, + { 520, "TG Information Network Co., Ltd." }, + { 521, "Fujikin , Inc." }, + { 522, "Estic Corp." }, + { 523, "GS Hydraulic Sales" }, + { 524, "Reserved" }, + { 525, "MTE Limited" }, + { 526, "Hyde Park Electronics, Inc." }, + { 527, "Pfeiffer Vacuum GmbH" }, + { 528, "Cyberlogic Technologies" }, + { 529, "OKUMA Corporation FA Systems Division" }, + { 530, "Reserved" }, + { 531, "Hitachi Kokusai Electric Co., Ltd." }, + { 532, "SHINKO TECHNOS Co., Ltd." }, + { 533, "Itoh Electric Co., Ltd." }, + { 534, "Colorado Flow Tech Inc." }, + { 535, "Love Controls Division/Dwyer Inst." }, + { 536, "Alstom Drives and Controls" }, + { 537, "The Foxboro Company" }, + { 538, "Tescom Corporation" }, + { 539, "Reserved" }, + { 540, "Atlas Copco Controls UK" }, + { 541, "Reserved" }, + { 542, "Autojet Technologies" }, + { 543, "Prima Electronics S.p.A." }, + { 544, "PMA GmbH" }, + { 545, "Shimafuji Electric Co., Ltd" }, + { 546, "Oki Electric Industry Co., Ltd" }, + { 547, "Kyushu Matsushita Electric Co., Ltd" }, + { 548, "Nihon Electric Wire & Cable Co., Ltd" }, + { 549, "Tsuken Electric Ind Co., Ltd" }, + { 550, "Tamadic Co." }, + { 551, "MAATEL SA" }, + { 552, "OKUMA America" }, + { 553, "Control Techniques PLC-NA" }, + { 554, "TPC Wire & Cable" }, + { 555, "ATI Industrial Automation" }, + { 556, "Microcontrol (Australia) Pty Ltd" }, + { 557, "Serra Soldadura, S.A." }, + { 558, "Southwest Research Institute" }, + { 559, "Cabinplant International" }, + { 560, "Sartorius Mechatronics T&H GmbH" }, + { 561, "Comau S.p.A. Robotics & Final Assembly Division" }, + { 562, "Phoenix Contact" }, + { 563, "Yokogawa MAT Corporation" }, + { 564, "asahi sangyo co., ltd." }, + { 565, "Reserved" }, + { 566, "Akita Myotoku Ltd." }, + { 567, "OBARA Corp." }, + { 568, "Suetron Electronic GmbH" }, + { 569, "Reserved" }, + { 570, "Serck Controls Limited" }, + { 571, "Fairchild Industrial Products Company" }, + { 572, "ARO S.A." }, + { 573, "M2C GmbH" }, + { 574, "Shin Caterpillar Mitsubishi Ltd." }, + { 575, "Santest Co., Ltd." }, + { 576, "Cosmotechs Co., Ltd." }, + { 577, "Hitachi Electric Systems" }, + { 578, "Smartscan Ltd" }, + { 579, "Woodhead Software & Electronics France" }, + { 580, "Athena Controls, Inc." }, + { 581, "Syron Engineering & Manufacturing, Inc." }, + { 582, "Asahi Optical Co., Ltd." }, + { 583, "Sansha Electric Mfg. Co., Ltd." }, + { 584, "Nikki Denso Co., Ltd." }, + { 585, "Star Micronics, Co., Ltd." }, + { 586, "Ecotecnia Socirtat Corp." }, + { 587, "AC Technology Corp." }, + { 588, "West Instruments Limited" }, + { 589, "NTI Limited" }, + { 590, "Delta Computer Systems, Inc." }, + { 591, "FANUC Ltd." }, + { 592, "Hearn-Gu Lee" }, + { 593, "ABB Automation Products" }, + { 594, "Orion Machinery Co., Ltd." }, + { 595, "Reserved" }, + { 596, "Wire-Pro, Inc." }, + { 597, "Beijing Huakong Technology Co. Ltd." }, + { 598, "Yokoyama Shokai Co., Ltd." }, + { 599, "Toyogiken Co., Ltd." }, + { 600, "Coester Equipamentos Eletronicos Ltda." }, + { 601, "Reserved" }, + { 602, "Electroplating Engineers of Japan Ltd." }, + { 603, "ROBOX S.p.A." }, + { 604, "Spraying Systems Company" }, + { 605, "Benshaw Inc." }, + { 606, "ZPA-DP A.S." }, + { 607, "Wired Rite Systems" }, + { 608, "Tandis Research, Inc." }, + { 609, "SSD Drives GmbH" }, + { 610, "ULVAC Japan Ltd." }, + { 611, "DYNAX Corporation" }, + { 612, "Nor-Cal Products, Inc." }, + { 613, "Aros Electronics AB" }, + { 614, "Jun-Tech Co., Ltd." }, + { 615, "HAN-MI Co. Ltd." }, + { 616, "uniNtech (formerly SungGi Internet)" }, + { 617, "Hae Pyung Electronics Reserch Institute" }, + { 618, "Milwaukee Electronics" }, + { 619, "OBERG Industries" }, + { 620, "Parker Hannifin/Compumotor Division" }, + { 621, "TECHNO DIGITAL CORPORATION" }, + { 622, "Network Supply Co., Ltd." }, + { 623, "Union Electronics Co., Ltd." }, + { 624, "Tritronics Services PM Ltd." }, + { 625, "Rockwell Automation-Sprecher+Schuh" }, + { 626, "Matsushita Electric Industrial Co., Ltd/Motor Co." }, + { 627, "Rolls-Royce Energy Systems, Inc." }, + { 628, "JEONGIL INTERCOM CO., LTD" }, + { 629, "Interroll Corp." }, + { 630, "Hubbell Wiring Device-Kellems (Delaware)" }, + { 631, "Intelligent Motion Systems" }, + { 632, "Reserved" }, + { 633, "INFICON AG" }, + { 634, "Hirschmann, Inc." }, + { 635, "The Siemon Company" }, + { 636, "YAMAHA Motor Co. Ltd." }, + { 637, "aska corporation" }, + { 638, "Woodhead Connectivity" }, + { 639, "Trimble AB" }, + { 640, "Murrelektronik GmbH" }, + { 641, "Creatrix Labs, Inc." }, + { 642, "TopWorx" }, + { 643, "Kumho Industrial Co., Ltd." }, + { 644, "Wind River Systems, Inc." }, + { 645, "Bihl & Wiedemann GmbH" }, + { 646, "Harmonic Drive Systems Inc." }, + { 647, "Rikei Corporation" }, + { 648, "BL Autotec, Ltd." }, + { 649, "Hana Information & Technology Co., Ltd." }, + { 650, "Seoil Electric Co., Ltd." }, + { 651, "Fife Corporation" }, + { 652, "Shanghai Electrical Apparatus Research Institute" }, + { 653, "Reserved" }, + { 654, "Parasense Development Centre" }, + { 655, "Reserved" }, + { 656, "Reserved" }, + { 657, "Six Tau S.p.A." }, + { 658, "Aucos GmbH" }, + { 659, "Rotork Controls" }, + { 660, "Automationdirect.com" }, + { 661, "Thermo BLH" }, + { 662, "System Controls, Ltd." }, + { 663, "Univer S.p.A." }, + { 664, "MKS-Tenta Technology" }, + { 665, "Lika Electronic SNC" }, + { 666, "Mettler-Toledo, Inc." }, + { 667, "DXL USA Inc." }, + { 668, "Rockwell Automation/Entek IRD Intl." }, + { 669, "Nippon Otis Elevator Company" }, + { 670, "Sinano Electric, Co., Ltd." }, + { 671, "Sony Manufacturing Systems" }, + { 672, "Reserved" }, + { 673, "Contec Co., Ltd." }, + { 674, "Automated Solutions" }, + { 675, "Controlweigh" }, + { 676, "Reserved" }, + { 677, "Fincor Electronics" }, + { 678, "Cognex Corporation" }, + { 679, "Qualiflow" }, + { 680, "Weidmuller, Inc." }, + { 681, "Morinaga Milk Industry Co., Ltd." }, + { 682, "Takagi Industrial Co., Ltd." }, + { 683, "Wittenstein AG" }, + { 684, "Sena Technologies, Inc." }, + { 685, "Reserved" }, + { 686, "APV Products Unna" }, + { 687, "Creator Teknisk Utvedkling AB" }, + { 688, "Reserved" }, + { 689, "Mibu Denki Industrial Co., Ltd." }, + { 690, "Takamastsu Machineer Section" }, + { 691, "Startco Engineering Ltd." }, + { 692, "Reserved" }, + { 693, "Holjeron" }, + { 694, "ALCATEL High Vacuum Technology" }, + { 695, "Taesan LCD Co., Ltd." }, + { 696, "POSCON" }, + { 697, "VMIC" }, + { 698, "Matsushita Electric Works, Ltd." }, + { 699, "IAI Corporation" }, + { 700, "Horst GmbH" }, + { 701, "MicroControl GmbH & Co." }, + { 702, "Leine & Linde AB" }, + { 703, "Reserved" }, + { 704, "EC Elettronica Srl" }, + { 705, "VIT Software HB" }, + { 706, "Bronkhorst High-Tech B.V." }, + { 707, "Optex Co., Ltd." }, + { 708, "Yosio Electronic Co." }, + { 709, "Terasaki Electric Co., Ltd." }, + { 710, "Sodick Co., Ltd." }, + { 711, "MTS Systems Corporation-Automation Division" }, + { 712, "Mesa Systemtechnik" }, + { 713, "SHIN HO SYSTEM Co., Ltd." }, + { 714, "Goyo Electronics Co, Ltd." }, + { 715, "Loreme" }, + { 716, "SAB Brockskes GmbH & Co. KG" }, + { 717, "Trumpf Laser GmbH + Co. KG" }, + { 718, "Niigata Electronic Instruments Co., Ltd." }, + { 719, "Yokogawa Digital Computer Corporation" }, + { 720, "O.N. Electronic Co., Ltd." }, + { 721, "Industrial Control Communication, Inc." }, + { 722, "ABB, Inc." }, + { 723, "ElectroWave USA, Inc." }, + { 724, "Industrial Network Controls, LLC" }, + { 725, "KDT Systems Co., Ltd." }, + { 726, "SEFA Technology Inc." }, + { 727, "Nippon POP Rivets and Fasteners Ltd." }, + { 728, "Yamato Scale Co., Ltd." }, + { 729, "Zener Electric" }, + { 730, "GSE Scale Systems" }, + { 731, "ISAS (Integrated Switchgear & Sys. Pty Ltd)" }, + { 732, "Beta LaserMike Limited" }, + { 733, "TOEI Electric Co., Ltd." }, + { 734, "Hakko Electronics Co., Ltd" }, + { 735, "Reserved" }, + { 736, "RFID, Inc." }, + { 737, "Adwin Corporation" }, + { 738, "Osaka Vacuum, Ltd." }, + { 739, "A-Kyung Motion, Inc." }, + { 740, "Camozzi S.P. A." }, + { 741, "Crevis Co., LTD" }, + { 742, "Rice Lake Weighing Systems" }, + { 743, "Linux Network Services" }, + { 744, "KEB Antriebstechnik GmbH" }, + { 745, "Hagiwara Electric Co., Ltd." }, + { 746, "Glass Inc. International" }, + { 747, "Reserved" }, + { 748, "DVT Corporation" }, + { 749, "Woodward Governor" }, + { 750, "Mosaic Systems, Inc." }, + { 751, "Laserline GmbH" }, + { 752, "COM-TEC, Inc." }, + { 753, "Weed Instrument" }, + { 754, "Prof-face European Technology Center" }, + { 755, "Fuji Automation Co., Ltd." }, + { 756, "Matsutame Co., Ltd." }, + { 757, "Hitachi Via Mechanics, Ltd." }, + { 758, "Dainippon Screen Mfg. Co. Ltd." }, + { 759, "FLS Automation A/S" }, + { 760, "ABB Stotz Kontakt GmbH" }, + { 761, "Technical Marine Service" }, + { 762, "Advanced Automation Associates, Inc." }, + { 763, "Baumer Ident GmbH" }, + { 764, "Tsubakimoto Chain Co." }, + { 765, "Reserved" }, + { 766, "Furukawa Co., Ltd." }, + { 767, "Active Power" }, + { 768, "CSIRO Mining Automation" }, + { 769, "Matrix Integrated Systems" }, + { 770, "Digitronic Automationsanlagen GmbH" }, + { 771, "SICK STEGMANN Inc." }, + { 772, "TAE-Antriebstechnik GmbH" }, + { 773, "Electronic Solutions" }, + { 774, "Rocon L.L.C." }, + { 775, "Dijitized Communications Inc." }, + { 776, "Asahi Organic Chemicals Industry Co., Ltd." }, + { 777, "Hodensha" }, + { 778, "Harting, Inc. NA" }, + { 779, "Kubler GmbH" }, + { 780, "Yamatake Corporation" }, + { 781, "JEOL" }, + { 782, "Yamatake Industrial Systems Co., Ltd." }, + { 783, "HAEHNE Elektronische Messgerate GmbH" }, + { 784, "Ci Technologies Pty Ltd (for Pelamos Industries)" }, + { 785, "N. SCHLUMBERGER & CIE" }, + { 786, "Teijin Seiki Co., Ltd." }, + { 787, "DAIKIN Industries, Ltd" }, + { 788, "RyuSyo Industrial Co., Ltd." }, + { 789, "SAGINOMIYA SEISAKUSHO, INC." }, + { 790, "Seishin Engineering Co., Ltd." }, + { 791, "Japan Support System Ltd." }, + { 792, "Decsys" }, + { 793, "Metronix Messgerate u. Elektronik GmbH" }, + { 794, "Reserved" }, + { 795, "Vaccon Company, Inc." }, + { 796, "Siemens Energy & Automation, Inc." }, + { 797, "Ten X Technology, Inc." }, + { 798, "Tyco Electronics" }, + { 799, "Delta Power Electronics Center" }, + { 800, "Denker" }, + { 801, "Autonics Corporation" }, + { 802, "JFE Electronic Engineering Pty. Ltd." }, + { 803, "Reserved" }, + { 804, "Electro-Sensors, Inc." }, + { 805, "Digi International, Inc." }, + { 806, "Texas Instruments" }, + { 807, "ADTEC Plasma Technology Co., Ltd" }, + { 808, "SICK AG" }, + { 809, "Ethernet Peripherals, Inc." }, + { 810, "Animatics Corporation" }, + { 811, "Reserved" }, + { 812, "Process Control Corporation" }, + { 813, "SystemV. Inc." }, + { 814, "Danaher Motion SRL" }, + { 815, "SHINKAWA Sensor Technology, Inc." }, + { 816, "Tesch GmbH & Co. KG" }, + { 817, "Reserved" }, + { 818, "Trend Controls Systems Ltd." }, + { 819, "Guangzhou ZHIYUAN Electronic Co., Ltd." }, + { 820, "Mykrolis Corporation" }, + { 821, "Bethlehem Steel Corporation" }, + { 822, "KK ICP" }, + { 823, "Takemoto Denki Corporation" }, + { 824, "The Montalvo Corporation" }, + { 825, "Reserved" }, + { 826, "LEONI Special Cables GmbH" }, + { 827, "Reserved" }, + { 828, "ONO SOKKI CO.,LTD." }, + { 829, "Rockwell Samsung Automation" }, + { 830, "SHINDENGEN ELECTRIC MFG. CO. LTD" }, + { 831, "Origin Electric Co. Ltd." }, + { 832, "Quest Technical Solutions, Inc." }, + { 833, "LS Cable, Ltd." }, + { 834, "Enercon-Nord Electronic GmbH" }, + { 835, "Northwire Inc." }, + { 836, "Engel Elektroantriebe GmbH" }, + { 837, "The Stanley Works" }, + { 838, "Celesco Transducer Products, Inc." }, + { 839, "Chugoku Electric Wire and Cable Co." }, + { 840, "Kongsberg Simrad AS" }, + { 841, "Panduit Corporation" }, + { 842, "Spellman High Voltage Electronics Corp." }, + { 843, "Kokusai Electric Alpha Co., Ltd." }, + { 844, "Brooks Automation, Inc." }, + { 845, "ANYWIRE CORPORATION" }, + { 846, "Honda Electronics Co. Ltd" }, + { 847, "REO Elektronik AG" }, + { 848, "Fusion UV Systems, Inc." }, + { 849, "ASI Advanced Semiconductor Instruments GmbH" }, + { 850, "Datalogic, Inc." }, + { 851, "SoftPLC Corporation" }, + { 852, "Dynisco Instruments LLC" }, + { 853, "WEG Industrias SA" }, + { 854, "Frontline Test Equipment, Inc." }, + { 855, "Tamagawa Seiki Co., Ltd." }, + { 856, "Multi Computing Co., Ltd." }, + { 857, "RVSI" }, + { 858, "Commercial Timesharing Inc." }, + { 859, "Tennessee Rand Automation LLC" }, + { 860, "Wacogiken Co., Ltd" }, + { 861, "Reflex Integration Inc." }, + { 862, "Siemens AG, A&D PI Flow Instruments" }, + { 863, "G. Bachmann Electronic GmbH" }, + { 864, "NT International" }, + { 865, "Schweitzer Engineering Laboratories" }, + { 866, "ATR Industrie-Elektronik GmbH Co." }, + { 867, "PLASMATECH Co., Ltd" }, + { 868, "Reserved" }, + { 869, "GEMU GmbH & Co. KG" }, + { 870, "Alcorn McBride Inc." }, + { 871, "MORI SEIKI CO., LTD" }, + { 872, "NodeTech Systems Ltd" }, + { 873, "Emhart Teknologies" }, + { 874, "Cervis, Inc." }, + { 875, "FieldServer Technologies (Div Sierra Monitor Corp)" }, + { 876, "NEDAP Power Supplies" }, + { 877, "Nippon Sanso Corporation" }, + { 878, "Mitomi Giken Co., Ltd." }, + { 879, "PULS GmbH" }, + { 880, "Reserved" }, + { 881, "Japan Control Engineering Ltd" }, + { 882, "Embedded Systems Korea (Former Zues Emtek Co Ltd.)" }, + { 883, "Automa SRL" }, + { 884, "Harms+Wende GmbH & Co KG" }, + { 885, "SAE-STAHL GmbH" }, + { 886, "Microwave Data Systems" }, + { 887, "Bernecker + Rainer Industrie-Elektronik GmbH" }, + { 888, "Hiprom Technologies" }, + { 889, "Reserved" }, + { 890, "Nitta Corporation" }, + { 891, "Kontron Modular Computers GmbH" }, + { 892, "Marlin Controls" }, + { 893, "ELCIS s.r.l." }, + { 894, "Acromag, Inc." }, + { 895, "Avery Weigh-Tronix" }, + { 896, "Reserved" }, + { 897, "Reserved" }, + { 898, "Reserved" }, + { 899, "Practicon Ltd" }, + { 900, "Schunk GmbH & Co. KG" }, + { 901, "MYNAH Technologies" }, + { 902, "Defontaine Groupe" }, + { 903, "Emerson Process Management Power & Water Solutions" }, + { 904, "F.A. Elec" }, + { 905, "Hottinger Baldwin Messtechnik GmbH" }, + { 906, "Coreco Imaging, Inc." }, + { 907, "London Electronics Ltd." }, + { 908, "HSD SpA" }, + { 909, "Comtrol Corporation" }, + { 910, "TEAM, S.A. (Tecnica Electronica de Automatismo Y Medida)" }, + { 911, "MAN B&W Diesel Ltd. Regulateurs Europa" }, + { 912, "Reserved" }, + { 913, "Reserved" }, + { 914, "Micro Motion, Inc." }, + { 915, "Eckelmann AG" }, + { 916, "Hanyoung Nux" }, + { 917, "Ransburg Industrial Finishing KK" }, + { 918, "Kun Hung Electric Co. Ltd." }, + { 919, "Brimos wegbebakening b.v." }, + { 920, "Nitto Seiki Co., Ltd" }, + { 921, "PPT Vision, Inc." }, + { 922, "Yamazaki Machinery Works" }, + { 923, "SCHMIDT Technology GmbH" }, + { 924, "Parker Hannifin SpA (SBC Division)" }, + { 925, "HIMA Paul Hildebrandt GmbH" }, + { 926, "RivaTek, Inc." }, + { 927, "Misumi Corporation" }, + { 928, "GE Multilin" }, + { 929, "Measurement Computing Corporation" }, + { 930, "Jetter AG" }, + { 931, "Tokyo Electronics Systems Corporation" }, + { 932, "Togami Electric Mfg. Co., Ltd." }, + { 933, "HK Systems" }, + { 934, "CDA Systems Ltd." }, + { 935, "Aerotech Inc." }, + { 936, "JVL Industrie Elektronik A/S" }, + { 937, "NovaTech Process Solutions LLC" }, + { 938, "Reserved" }, + { 939, "Cisco Systems" }, + { 940, "Grid Connect" }, + { 941, "ITW Automotive Finishing" }, + { 942, "HanYang System" }, + { 943, "ABB K.K. Technical Center" }, + { 944, "Taiyo Electric Wire & Cable Co., Ltd." }, + { 945, "Reserved" }, + { 946, "SEREN IPS INC" }, + { 947, "Belden CDT Electronics Division" }, + { 948, "ControlNet International" }, + { 949, "Gefran S.P.A." }, + { 950, "Jokab Safety AB" }, + { 951, "SUMITA OPTICAL GLASS, INC." }, + { 952, "Biffi Italia srl" }, + { 953, "Beck IPC GmbH" }, + { 954, "Copley Controls Corporation" }, + { 955, "Fagor Automation S. Coop." }, + { 956, "DARCOM" }, + { 957, "Frick Controls (div. of York International)" }, + { 958, "SymCom, Inc." }, + { 959, "Infranor" }, + { 960, "Kyosan Cable, Ltd." }, + { 961, "Varian Vacuum Technologies" }, + { 962, "Messung Systems" }, + { 963, "Xantrex Technology, Inc." }, + { 964, "StarThis Inc." }, + { 965, "Chiyoda Co., Ltd." }, + { 966, "Flowserve Corporation" }, + { 967, "Spyder Controls Corp." }, + { 968, "IBA AG" }, + { 969, "SHIMOHIRA ELECTRIC MFG.CO.,LTD" }, + { 970, "Reserved" }, + { 971, "Siemens L&A" }, + { 972, "Micro Innovations AG" }, + { 973, "Switchgear & Instrumentation" }, + { 974, "PRE-TECH CO., LTD." }, + { 975, "National Semiconductor" }, + { 976, "Invensys Process Systems" }, + { 977, "Ametek HDR Power Systems" }, + { 978, "Reserved" }, + { 979, "TETRA-K Corporation" }, + { 980, "C & M Corporation" }, + { 981, "Siempelkamp Maschinen" }, + { 982, "Reserved" }, + { 983, "Daifuku America Corporation" }, + { 984, "Electro-Matic Products Inc." }, + { 985, "BUSSAN MICROELECTRONICS CORP." }, + { 986, "ELAU AG" }, + { 987, "Hetronic USA" }, + { 988, "NIIGATA POWER SYSTEMS Co., Ltd." }, + { 989, "Software Horizons Inc." }, + { 990, "B3 Systems, Inc." }, + { 991, "Moxa Networking Co., Ltd." }, + { 992, "Reserved" }, + { 993, "S4 Integration" }, + { 994, "Elettro Stemi S.R.L." }, + { 995, "AquaSensors" }, + { 996, "Ifak System GmbH" }, + { 997, "SANKEI MANUFACTURING Co.,LTD." }, + { 998, "Emerson Network Power Co., Ltd." }, + { 999, "Fairmount Automation, Inc." }, + { 1000, "Bird Electronic Corporation" }, + { 1001, "Nabtesco Corporation" }, + { 1002, "AGM Electronics, Inc." }, + { 1003, "ARCX Inc." }, + { 1004, "DELTA I/O Co." }, + { 1005, "Chun IL Electric Ind. Co." }, + { 1006, "N-Tron" }, + { 1007, "Nippon Pneumatics/Fludics System CO.,LTD." }, + { 1008, "DDK Ltd." }, + { 1009, "Seiko Epson Corporation" }, + { 1010, "Halstrup-Walcher GmbH" }, + { 1011, "ITT" }, + { 1012, "Ground Fault Systems bv" }, + { 1013, "Scolari Engineering S.p.A." }, + { 1014, "Vialis Traffic bv" }, + { 1015, "Weidmueller Interface GmbH & Co. KG" }, + { 1016, "Shanghai Sibotech Automation Co. Ltd" }, + { 1017, "AEG Power Supply Systems GmbH" }, + { 1018, "Komatsu Electronics Inc." }, + { 1019, "Souriau" }, + { 1020, "Baumuller Chicago Corp." }, + { 1021, "J. Schmalz GmbH" }, + { 1022, "SEN Corporation" }, + { 1023, "Korenix Technology Co. Ltd" }, + { 1024, "Cooper Power Tools" }, + { 1025, "INNOBIS" }, + { 1026, "Shinho System" }, + { 1027, "Xm Services Ltd." }, + { 1028, "KVC Co., Ltd." }, + { 1029, "Sanyu Seiki Co., Ltd." }, + { 1030, "TuxPLC" }, + { 1031, "Northern Network Solutions" }, + { 1032, "Converteam GmbH" }, + { 1033, "Symbol Technologies" }, + { 1034, "S-TEAM Lab" }, + { 1035, "Maguire Products, Inc." }, + { 1036, "AC&T" }, + { 1037, "MITSUBISHI HEAVY INDUSTRIES, LTD. KOBE SHIPYARD & MACHINERY WORKS" }, + { 1038, "Hurletron Inc." }, + { 1039, "Chunichi Denshi Co., Ltd" }, + { 1040, "Cardinal Scale Mfg. Co." }, + { 1041, "BTR NETCOM via RIA Connect, Inc." }, + { 1042, "Base2" }, + { 1043, "ASRC Aerospace" }, + { 1044, "Beijing Stone Automation" }, + { 1045, "Changshu Switchgear Manufacture Ltd." }, + { 1046, "METRONIX Corp." }, + { 1047, "WIT" }, + { 1048, "ORMEC Systems Corp." }, + { 1049, "ASATech (China) Inc." }, + { 1050, "Controlled Systems Limited" }, + { 1051, "Mitsubishi Heavy Ind. Digital System Co., Ltd. (M.H.I.)" }, + { 1052, "Electrogrip" }, + { 1053, "TDS Automation" }, + { 1054, "T&C Power Conversion, Inc." }, + { 1055, "Robostar Co., Ltd" }, + { 1056, "Scancon A/S" }, + { 1057, "Haas Automation, Inc." }, + { 1058, "Eshed Technology" }, + { 1059, "Delta Electronic Inc." }, + { 1060, "Innovasic Semiconductor" }, + { 1061, "SoftDEL Systems Limited" }, + { 1062, "FiberFin, Inc." }, + { 1063, "Nicollet Technologies Corp." }, + { 1064, "B.F. Systems" }, + { 1065, "Empire Wire and Supply LLC" }, + { 1066, "Reserved" }, + { 1067, "Elmo Motion Control LTD" }, + { 1068, "Reserved" }, + { 1069, "Asahi Keiki Co., Ltd." }, + { 1070, "Joy Mining Machinery" }, + { 1071, "MPM Engineering Ltd" }, + { 1072, "Wolke Inks & Printers GmbH" }, + { 1073, "Mitsubishi Electric Engineering Co., Ltd." }, + { 1074, "COMET AG" }, + { 1075, "Real Time Objects & Systems, LLC" }, + { 1076, "MISCO Refractometer" }, + { 1077, "JT Engineering Inc." }, + { 1078, "Automated Packing Systems" }, + { 1079, "Niobrara R&D Corp." }, + { 1080, "Garmin Ltd." }, + { 1081, "Japan Mobile Platform Co., Ltd" }, + { 1082, "Advosol Inc." }, + { 1083, "ABB Global Services Limited" }, + { 1084, "Sciemetric Instruments Inc." }, + { 1085, "Tata Elxsi Ltd." }, + { 1086, "TPC Mechatronics, Co., Ltd." }, + { 1087, "Cooper Bussmann" }, + { 1088, "Trinite Automatisering B.V." }, + { 1089, "Peek Traffic B.V." }, + { 1090, "Acrison, Inc" }, + { 1091, "Applied Robotics, Inc." }, + { 1092, "FireBus Systems, Inc." }, + { 1093, "Beijing Sevenstar Huachuang Electronics" }, + { 1094, "Magnetek" }, + { 1095, "Microscan" }, + { 1096, "Air Water Inc." }, + { 1097, "Sensopart Industriesensorik GmbH" }, + { 1098, "Tiefenbach Control Systems GmbH" }, + { 1099, "INOXPA S.A" }, + { 1100, "Zurich University of Applied Sciences" }, + { 1101, "Ethernet Direct" }, + { 1102, "GSI-Micro-E Systems" }, + { 1103, "S-Net Automation Co., Ltd." }, + { 1104, "Power Electronics S.L." }, + { 1105, "Renesas Technology Corp." }, + { 1106, "NSWCCD-SSES" }, + { 1107, "Porter Engineering Ltd." }, + { 1108, "Meggitt Airdynamics, Inc." }, + { 1109, "Inductive Automation" }, + { 1110, "Neural ID" }, + { 1111, "EEPod LLC" }, + { 1112, "Hitachi Industrial Equipment Systems Co., Ltd." }, + { 1113, "Salem Automation" }, + { 1114, "port GmbH" }, + { 1115, "B & PLUS" }, + { 1116, "Graco Inc." }, + { 1117, "Altera Corporation" }, + { 1118, "Technology Brewing Corporation" }, + { 1121, "CSE Servelec" }, + { 1124, "Fluke Networks" }, + { 1125, "Tetra Pak Packaging Solutions SPA" }, + { 1126, "Racine Federated, Inc." }, + { 1127, "Pureron Japan Co., Ltd." }, + { 1130, "Brother Industries, Ltd." }, + { 1132, "Leroy Automation" }, + { 1134, "THK CO., LTD." }, + { 1137, "TR-Electronic GmbH" }, + { 1138, "ASCON S.p.A." }, + { 1139, "Toledo do Brasil Industria de Balancas Ltda." }, + { 1140, "Bucyrus DBT Europe GmbH" }, + { 1141, "Emerson Process Management Valve Automation" }, + { 1142, "Alstom Transport" }, + { 1144, "Matrox Electronic Systems" }, + { 1145, "Littelfuse" }, + { 1146, "PLASMART, Inc." }, + { 1147, "Miyachi Corporation" }, + { 1150, "Promess Incorporated" }, + { 1151, "COPA-DATA GmbH" }, + { 1152, "Precision Engine Controls Corporation" }, + { 1153, "Alga Automacao e controle LTDA" }, + { 1154, "U.I. Lapp GmbH" }, + { 1155, "ICES" }, + { 1156, "Philips Lighting bv" }, + { 1157, "Aseptomag AG" }, + { 1158, "ARC Informatique" }, + { 1159, "Hesmor GmbH" }, + { 1160, "Kobe Steel, Ltd." }, + { 1161, "FLIR Systems" }, + { 1162, "Simcon A/S" }, + { 1163, "COPALP" }, + { 1164, "Zypcom, Inc." }, + { 1165, "Swagelok" }, + { 1166, "Elspec" }, + { 1167, "ITT Water & Wastewater AB" }, + { 1168, "Kunbus GmbH Industrial Communication" }, + { 1170, "Performance Controls, Inc." }, + { 1171, "ACS Motion Control, Ltd." }, + { 1173, "IStar Technology Limited" }, + { 1174, "Alicat Scientific, Inc." }, + { 1176, "ADFweb.com SRL" }, + { 1177, "Tata Consultancy Services Limited" }, + { 1178, "CXR Ltd." }, + { 1179, "Vishay Nobel AB" }, + { 1181, "SolaHD" }, + { 1182, "Endress+Hauser" }, + { 1183, "Bartec GmbH" }, + { 1185, "AccuSentry, Inc." }, + { 1186, "Exlar Corporation" }, + { 1187, "ILS Technology" }, + { 1188, "Control Concepts Inc." }, + { 1190, "Procon Engineering Limited" }, + { 1191, "Hermary Opto Electronics Inc." }, + { 1192, "Q-Lambda" }, + { 1194, "VAMP Ltd" }, + { 1195, "FlexLink" }, + { 1196, "Office FA.com Co., Ltd." }, + { 1197, "SPMC (Changzhou) Co. Ltd." }, + { 1198, "Anton Paar GmbH" }, + { 1199, "Zhuzhou CSR Times Electric Co., Ltd." }, + { 1200, "DeStaCo" }, + { 1201, "Synrad, Inc" }, + { 1202, "Bonfiglioli Vectron GmbH" }, + { 1203, "Pivotal Systems" }, + { 1204, "TKSCT" }, + { 1205, "Randy Nuernberger" }, + { 1206, "CENTRALP" }, + { 1207, "Tengen Group" }, + { 1208, "OES, Inc." }, + { 1209, "Actel Corporation" }, + { 1210, "Monaghan Engineering, Inc." }, + { 1211, "wenglor sensoric gmbh" }, + { 1212, "HSA Systems" }, + { 1213, "MK Precision Co., Ltd." }, + { 1214, "Tappan Wire and Cable" }, + { 1215, "Heinzmann GmbH & Co. KG" }, + { 1216, "Process Automation International Ltd." }, + { 1217, "Secure Crossing" }, + { 1218, "SMA Railway Technology GmbH" }, + { 1219, "FMS Force Measuring Systems AG" }, + { 1220, "ABT Endustri Enerji Sistemleri Sanayi Tic. Ltd. Sti." }, + { 1221, "MagneMotion Inc." }, + { 1222, "STS Co., Ltd." }, + { 1223, "MERAK SIC, SA" }, + { 1224, "ABOUNDI, Inc." }, + { 1225, "Rosemount Inc." }, + { 1226, "GEA FES, Inc." }, + { 1227, "TMG Technologie und Engineering GmbH" }, + { 1228, "embeX GmbH" }, + { 1229, "GH Electrotermia, S.A." }, + { 1230, "Tolomatic" }, + { 1231, "Dukane" }, + { 1232, "Elco (Tian Jin) Electronics Co., Ltd." }, + { 1233, "Jacobs Automation" }, + { 1234, "Noda Radio Frequency Technologies Co., Ltd." }, + { 1235, "MSC Tuttlingen GmbH" }, + { 1236, "Hitachi Cable Manchester" }, + { 1237, "ACOREL SAS" }, + { 1238, "Global Engineering Solutions Co., Ltd." }, + { 1239, "ALTE Transportation, S.L." }, + { 1240, "Penko Engineering B.V." }, { 0, NULL } }; +value_string_ext cip_vendor_vals_ext = VALUE_STRING_EXT_INIT(cip_vendor_vals); + /* Translate Device Profile:s */ -const value_string cip_devtype_vals[] = { +static const value_string cip_devtype_vals[] = { { DP_GEN_DEV, "Generic Device" }, { DP_AC_DRIVE, "AC Drive" }, { DP_MOTOR_OVERLOAD, "Motor Overload" }, @@ -441,6 +2099,8 @@ const value_string cip_devtype_vals[] = { { 0, NULL } }; +value_string_ext cip_devtype_vals_ext = VALUE_STRING_EXT_INIT(cip_devtype_vals); + #define CI_CLS_MR 0x02 /* Message Router */ #define CI_CLS_CM 0x06 /* Connection Manager */ #define CI_CLS_CCO 0xF3 /* Connection Configuration Object */ @@ -517,90 +2177,317 @@ static const value_string cip_class_names_vals[] = { { 0, NULL } }; +value_string_ext cip_class_names_vals_ext = VALUE_STRING_EXT_INIT(cip_class_names_vals); + + +int dissect_id_revision(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) +{ + proto_tree_add_item( tree, hf_id_major_rev, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item( tree, hf_id_minor_rev, tvb, offset+1, 1, ENC_LITTLE_ENDIAN); + return 2; +} + +int dissect_msg_rout_num_classes(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) +{ + guint16 i, num_classes; + + num_classes = tvb_get_letohs( tvb, offset); + proto_tree_add_item( tree, hf_msg_rout_num_classes, tvb, offset, 2, ENC_LITTLE_ENDIAN); + for (i = 0; i < num_classes; i++) + proto_tree_add_item( tree, hf_msg_rout_classes, tvb, offset+2+(i*2), 2, ENC_LITTLE_ENDIAN); + + return (2+(num_classes*2)); +} + +static attribute_info_t cip_attribute_vals[] = { + + {0x01, FALSE, 1, "Vendor ID", cip_uint, &hf_id_vendor_id, NULL}, + {0x01, FALSE, 2, "Device Type", cip_uint, &hf_id_device_type, NULL}, + {0x01, FALSE, 3, "Product Code", cip_uint, &hf_id_produce_code, NULL}, + {0x01, FALSE, 4, "Revision", cip_dissector_func, NULL, dissect_id_revision}, + {0x01, FALSE, 5, "Status", cip_word, &hf_id_status, NULL}, + {0x01, FALSE, 6, "Serial Number", cip_udint, &hf_id_serial_number, NULL}, + {0x01, FALSE, 7, "Product Name", cip_short_string, &hf_id_product_name, NULL}, + + {0x02, FALSE, 1, "Object List", cip_dissector_func, NULL, dissect_msg_rout_num_classes}, + {0x02, FALSE, 2, "Number Available", cip_uint, &hf_msg_rout_num_available, NULL}, + {0x02, FALSE, 3, "Number Active", cip_uint, &hf_msg_rout_num_active, NULL}, + {0x02, FALSE, 4, "Active Connections", cip_uint_array, &hf_msg_rout_active_connections, NULL}, + + {0x06, FALSE, 1, "Open Requests", cip_uint, &hf_conn_mgr_open_requests, NULL}, + {0x06, FALSE, 2, "Open Format Rejects", cip_uint, &hf_conn_mgr_open_format_rejects, NULL}, + {0x06, FALSE, 3, "Open Resource Rejects", cip_uint, &hf_conn_mgr_open_resource_rejects, NULL}, + {0x06, FALSE, 4, "Other Open Rejects", cip_uint, &hf_conn_mgr_other_open_rejects, NULL}, + {0x06, FALSE, 5, "Close Requests", cip_uint, &hf_conn_mgr_close_requests, NULL}, + {0x06, FALSE, 6, "Close Format Requests", cip_uint, &hf_conn_close_format_requests, NULL}, + {0x06, FALSE, 7, "Close Other Requests", cip_uint, &hf_conn_mgr_close_other_requests, NULL}, + {0x06, FALSE, 8, "Connection Timeouts", cip_uint, &hf_conn_mgr_conn_timouts, NULL}, +}; + +typedef struct attribute_val_array { + gint size; + attribute_info_t* attrs; +} attribute_val_array_t; + +static attribute_val_array_t all_attribute_vals[] = { + {sizeof(cip_attribute_vals)/sizeof(attribute_info_t), cip_attribute_vals}, + {sizeof(enip_attribute_vals)/sizeof(attribute_info_t), enip_attribute_vals} +}; + static void dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info *pinfo, cip_req_info_t *preq_info ); -static proto_item* -add_byte_array_text_to_proto_tree( proto_tree *tree, tvbuff_t *tvb, gint start, gint length, const char* str ) +static attribute_info_t* cip_get_attribute(guint class_id, guint instance, guint attribute) { - const guint8 *tmp; - char *tmp2, *tmp2start; - proto_item *pi; - int i,tmp_length,tmp2_length; - guint32 octet; - /* At least one version of Apple's C compiler/linker is buggy, causing - a complaint from the linker about the "literal C string section" - not ending with '\0' if we initialize a 16-element "char" array with - a 16-character string, the fact that initializing such an array with - such a string is perfectly legitimate ANSI C nonwithstanding, the 17th - '\0' byte in the string nonwithstanding. */ - static const char my_hex_digits[16] = - { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - - - if( ( length * 2 ) > 32 ) + gint i, j; + attribute_val_array_t* att_array; + attribute_info_t* pattr; + + for (i = 0; i < sizeof(all_attribute_vals)/sizeof(attribute_val_array_t); i++) { - tmp_length = 16; - tmp2_length = 36; - } - else - { - tmp_length = length; - tmp2_length = ( length * 2 ) + 1; + att_array = &all_attribute_vals[i]; + for (j = 0; j < att_array->size; j++) + { + pattr = &att_array->attrs[j]; + if ((pattr->class_id == class_id) && + (instance != (guint)-1) && + (((instance == 0) && (pattr->class_instance == TRUE)) || ((instance != 0) && (pattr->class_instance == FALSE))) && + (pattr->attribute == attribute)) + { + return pattr; + } + } } - tmp = tvb_get_ptr( tvb, start, tmp_length ); - tmp2 = (char*)ep_alloc( tmp2_length ); + return NULL; +} - tmp2start = tmp2; +static void +dissect_cia(tvbuff_t *tvb, int offset, int* pathpos, unsigned char segment_type, + gboolean generate, packet_info *pinfo, proto_item *epath_item, + proto_item *item, proto_tree *tree, proto_item *path_item, proto_item ** ret_item, + const char* segment_name, const value_string* vals, int* value, + int hf8, int hf16, int hf32) +{ + int temp_data; + emem_strbuf_t *strbuf; - for( i = 0; i < tmp_length; i++ ) + switch (segment_type) { - octet = tmp[i]; - octet >>= 4; - *tmp2++ = my_hex_digits[octet&0xF]; - octet = tmp[i]; - *tmp2++ = my_hex_digits[octet&0xF]; - } + case CI_LOGICAL_SEG_8_BIT: + temp_data = tvb_get_guint8( tvb, offset + *pathpos + 1 ); - if( tmp_length != length ) - { - *tmp2++ = '.'; - *tmp2++ = '.'; - *tmp2++ = '.'; + if ( generate ) + { + *ret_item = proto_tree_add_uint(item, hf8, NULL, 0, 0, temp_data ); + PROTO_ITEM_SET_GENERATED(*ret_item); + } + else + { + *ret_item = proto_tree_add_item(tree, hf8, tvb, offset + *pathpos + 1, 1, ENC_LITTLE_ENDIAN); + } + + if (vals == NULL) + { + proto_item_append_text( epath_item, "%s: 0x%02X", segment_name, temp_data); + } + else + { + strbuf = ep_strbuf_new(segment_name); + ep_strbuf_append(strbuf, ": 0x%02X"); + + proto_item_append_text( epath_item, "%s", val_to_str( temp_data, vals , strbuf->str) ); + } + + if (value != NULL) + *value = temp_data; + + proto_item_set_len( item, 2); + proto_item_set_len( path_item, 2); + (*pathpos) += 2; + break; + case CI_LOGICAL_SEG_16_BIT: + temp_data = tvb_get_letohs( tvb, offset + *pathpos + 2 ); + + if ( generate ) + { + *ret_item = proto_tree_add_uint(tree, hf16, NULL, 0, 0, temp_data ); + PROTO_ITEM_SET_GENERATED(*ret_item); + } + else + { + *ret_item = proto_tree_add_item( tree, hf16, tvb, offset + *pathpos + 2, 2, ENC_LITTLE_ENDIAN); + } + if (vals == NULL) + { + proto_item_append_text( epath_item, "%s: 0x%04X", segment_name, temp_data); + } + else + { + strbuf = ep_strbuf_new(segment_name); + ep_strbuf_append(strbuf, ": 0x%04X"); + + proto_item_append_text( epath_item, "%s", val_to_str( temp_data, vals , strbuf->str) ); + } + + if (value != NULL) + *value = temp_data; + + proto_item_set_len( item, 4); + proto_item_set_len( path_item, 4); + (*pathpos) += 4; + break; + case CI_LOGICAL_SEG_32_BIT: + temp_data = tvb_get_letohl( tvb, offset + *pathpos + 2 ); + + if ( generate ) + { + *ret_item = proto_tree_add_uint(tree, hf32, NULL, 0, 0, temp_data ); + PROTO_ITEM_SET_GENERATED(*ret_item); + } + else + { + *ret_item = proto_tree_add_item( tree, hf32, tvb, offset + *pathpos + 2, 4, ENC_LITTLE_ENDIAN); + } + + if (vals == NULL) + { + proto_item_append_text( epath_item, "%s: 0x%08X", segment_name, temp_data); + } + else + { + strbuf = ep_strbuf_new(segment_name); + ep_strbuf_append(strbuf, ": 0x%08X"); + + proto_item_append_text( epath_item, "%s", val_to_str( temp_data, vals , strbuf->str) ); + } + + if (value != NULL) + *value = temp_data; + + proto_item_set_len( item, 6); + proto_item_set_len( path_item, 6); + (*pathpos) += 6; + break; + default: + expert_add_info_format(pinfo, epath_item, PI_PROTOCOL, PI_ERROR, "Unsupported Logical Segment Format"); + return; } - *tmp2 = 0; +} + +/* Dissect Device ID structure */ +static void +dissect_deviceid(tvbuff_t *tvb, int offset, proto_tree *tree, + int hf_vendor, int hf_devtype, int hf_prodcode, + int hf_compatibility, int hf_comp_bit, int hf_majrev, int hf_minrev) +{ + guint compatibility; + proto_item *compatibility_item; + proto_item *compatibility_tree; + + proto_tree_add_item(tree, hf_vendor, tvb, offset, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_devtype, tvb, offset+2, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_prodcode, tvb, offset+4, 2, ENC_LITTLE_ENDIAN); + + /* Major revision/Compatibility */ + compatibility = tvb_get_guint8( tvb, offset+6); + + /* Add Major revision/Compatibility tree */ + compatibility_item = proto_tree_add_uint_format_value(tree, hf_compatibility, + tvb, offset+6, 1, compatibility, "%s, Major Revision: %d", + val_to_str( ( compatibility & 0x80 )>>7, cip_com_bit_vals , "" ), + compatibility & 0x7F); + compatibility_tree = proto_item_add_subtree(compatibility_item, ett_mcsc); + + proto_tree_add_item(compatibility_tree, hf_comp_bit, tvb, offset+6, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(compatibility_tree, hf_majrev, tvb, offset+6, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(tree, hf_minrev, tvb, offset+7, 1, ENC_LITTLE_ENDIAN ); +} + +static void +dissect_net_param16(tvbuff_t *tvb, int offset, proto_tree *tree, + int hf_net_param16, int hf_owner, int hf_type, + int hf_priority, int hf_fixed_var, int hf_con_size, gint ncp_ett) +{ + proto_item *net_param_item; + proto_tree *net_param_tree; + + net_param_item = proto_tree_add_item(tree, hf_net_param16, tvb, offset, 2, ENC_LITTLE_ENDIAN ); + net_param_tree = proto_item_add_subtree(net_param_item, ncp_ett); - pi = proto_tree_add_text( tree, tvb, start, length, "%s%s", str, tmp2start ); + /* Add the data to the tree */ + proto_tree_add_item(net_param_tree, hf_owner, tvb, offset, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_type, tvb, offset, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_priority, tvb, offset, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_fixed_var, tvb, offset, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_con_size, tvb, offset, 2, ENC_LITTLE_ENDIAN ); +} + +static void +dissect_net_param32(tvbuff_t *tvb, int offset, proto_tree *tree, + int hf_net_param16, int hf_owner, int hf_type, + int hf_priority, int hf_fixed_var, int hf_con_size, gint ncp_ett) +{ + proto_item *net_param_item; + proto_tree *net_param_tree; + + net_param_item = proto_tree_add_item(tree, hf_net_param16, tvb, offset, 4, ENC_LITTLE_ENDIAN ); + net_param_tree = proto_item_add_subtree(net_param_item, ncp_ett); - return( pi ); + /* Add the data to the tree */ + proto_tree_add_item(net_param_tree, hf_owner, tvb, offset, 4, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_type, tvb, offset, 4, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_priority, tvb, offset, 4, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_fixed_var, tvb, offset, 4, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(net_param_tree, hf_con_size, tvb, offset, 4, ENC_LITTLE_ENDIAN ); +} -} /* end of add_byte_array_text_to_proto_tree() */ +static void +dissect_transport_type_trigger(tvbuff_t *tvb, int offset, proto_tree *tree, + int hf_ttt, int hf_direction, int hf_trigger, int hf_class, gint ett) +{ + proto_item *ttt_item; + proto_tree *ttt_tree; + ttt_item = proto_tree_add_item(tree, hf_ttt, tvb, offset, 1, ENC_LITTLE_ENDIAN ); + ttt_tree = proto_item_add_subtree(ttt_item, ett); + + proto_tree_add_item(ttt_tree, hf_direction, tvb, offset, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(ttt_tree, hf_trigger, tvb, offset, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(ttt_tree, hf_class, tvb, offset, 1, ENC_LITTLE_ENDIAN ); +} /* Dissect EPATH */ -static void -dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_length, gboolean generate ) +void dissect_epath( tvbuff_t *tvb, packet_info *pinfo, proto_item *epath_item, int offset, int path_length, gboolean generate, cip_simple_request_info_t* req_data) { - int pathpos, temp_data, temp_data2, seg_size, i, temp_word; + int pathpos, temp_data, temp_data2, seg_size, i; unsigned char segment_type, opt_link_size; proto_tree *path_tree, *port_tree, *net_tree; - proto_item *qi, *cia_item, *ds_item; - proto_tree *e_key_tree, *cia_tree, *ds_tree; - proto_item *mcpi, *port_item, *net_item; - proto_tree *mc_tree; - proto_item *it; - proto_item *hidden_item; + proto_tree *cia_tree, *ds_tree, *ds_data_tree, *path_seg_tree; + proto_item *it, *cia_item, *cia_ret_item, *port_item, *ds_item, *ds_data_item; + proto_item *net_item, *hidden_item, *path_seg_item; + + attribute_info_t* att_info; /* Create a sub tree for the epath */ path_tree = proto_item_add_subtree( epath_item, ett_path ); + /* can't populate req_data unless its there */ + if (req_data != NULL) + { + req_data->iClass = (guint32)-1; + req_data->iInstance = (guint32)-1; + req_data->iAttribute = (guint32)-1; + req_data->iMember = (guint32)-1; + } + if ( !generate ) { hidden_item = proto_tree_add_item(path_tree, hf_cip_epath, - tvb, offset, path_length, TRUE ); + tvb, offset, path_length, ENC_LITTLE_ENDIAN ); PROTO_ITEM_SET_HIDDEN(hidden_item); } @@ -608,91 +2495,93 @@ dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_lengt while( pathpos < path_length ) { + if (tvb_length_remaining(tvb, offset + pathpos) <= 0) + { + expert_add_info_format(pinfo, epath_item, PI_MALFORMED, PI_ERROR, "Incomplete EPATH"); + return; + } + /* Get segement type */ segment_type = tvb_get_guint8( tvb, offset + pathpos ); + if ( generate ) + { + path_seg_item = proto_tree_add_uint(path_tree, hf_cip_path_segment, NULL, 0, 0, segment_type ); + PROTO_ITEM_SET_GENERATED(path_seg_item); + path_seg_tree = proto_item_add_subtree( path_seg_item, ett_path_seg ); + it = proto_tree_add_uint(path_seg_tree, hf_cip_path_segment_type, NULL, 0, 0, segment_type&CI_SEGMENT_TYPE_MASK); + PROTO_ITEM_SET_GENERATED(it); + } + else + { + path_seg_item = proto_tree_add_item(path_tree, hf_cip_path_segment, tvb, offset + pathpos, 1, ENC_LITTLE_ENDIAN); + path_seg_tree = proto_item_add_subtree( path_seg_item, ett_path_seg ); + proto_tree_add_item(path_seg_tree, hf_cip_path_segment_type, tvb, offset + pathpos, 1, ENC_LITTLE_ENDIAN); + } + /* Determine the segment type */ switch( segment_type & CI_SEGMENT_TYPE_MASK ) { case CI_PORT_SEGMENT: - - port_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 0, "Port Segment" ); + /* Add Extended Link Address flag & Port Identifier*/ if ( generate ) { - port_item = proto_tree_add_text( path_tree, NULL, 0, 0, "Port Segment" ); + it = proto_tree_add_boolean(path_seg_tree, hf_cip_port_ex_link_addr, NULL, 0, 0, segment_type & CI_PORT_SEG_EX_LINK_ADDRESS); + PROTO_ITEM_SET_GENERATED(it); + it = proto_tree_add_uint(path_seg_tree, hf_cip_port, NULL, 0, 0, ( segment_type & 0x0F ) ); + PROTO_ITEM_SET_GENERATED(it); + port_item = proto_tree_add_text(path_seg_tree, NULL, 0, 0, "Port Segment"); PROTO_ITEM_SET_GENERATED(port_item); } else - port_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 0, "Port Segment" ); - port_tree = proto_item_add_subtree( port_item, ett_port_path ); - - /* Add port number */ - if ( generate ) { - it = proto_tree_add_uint(port_tree, hf_cip_port, NULL, 0, 0, ( segment_type & 0x0F ) ); - PROTO_ITEM_SET_GENERATED(it); + proto_tree_add_item(path_seg_tree, hf_cip_port_ex_link_addr, tvb, offset+pathpos, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(path_seg_tree, hf_cip_port, tvb, offset + pathpos, 1, ENC_LITTLE_ENDIAN); + port_item = proto_tree_add_text(path_seg_tree, tvb, offset + pathpos, 1, "Port Segment"); } - else - proto_tree_add_item( port_tree, hf_cip_port, tvb, offset + pathpos, 1, TRUE ); - proto_item_append_text( epath_item, "Port: %d", ( segment_type & 0x0F ) ); - proto_item_append_text( port_item, ": Port: %d", ( segment_type & 0x0F ) ); - if( segment_type & 0x10 ) - { - /* Add Extended Link Address flag */ - if ( generate ) - { - it = proto_tree_add_text( port_tree, NULL, 0, 0, "Extended Link Address: TRUE" ); - PROTO_ITEM_SET_GENERATED(it); - } - else - it = proto_tree_add_text( port_tree, tvb, offset+pathpos, 1, "Extended Link Address: TRUE" ); + proto_item_append_text( path_seg_item, " (Port Segment)"); + proto_item_append_text( epath_item, "Port: %d", ( segment_type & CI_PORT_SEG_PORT_ID_MASK ) ); + port_tree = proto_item_add_subtree( port_item, ett_port_path ); - /* Add size of extended link address */ + if( segment_type & CI_PORT_SEG_EX_LINK_ADDRESS ) + { opt_link_size = tvb_get_guint8( tvb, offset + pathpos + 1 ); - if ( generate ) - { - it = proto_tree_add_text( port_tree, NULL, 0, 0, "Link Address Size: %d", opt_link_size ); - PROTO_ITEM_SET_GENERATED(it); - } - else - it = proto_tree_add_text( port_tree, tvb, offset+pathpos+1, 1, "Link Address Size: %d", opt_link_size ); - /* Add extended link address */ if ( generate ) { + /* Add size of extended link address */ + it = proto_tree_add_uint(port_tree, hf_cip_link_address_size, NULL, 0, 0, opt_link_size); + PROTO_ITEM_SET_GENERATED(it); + /* Add extended link address */ it = proto_tree_add_string(port_tree, hf_cip_link_address_string, NULL, 0, 0, tvb_format_text(tvb, offset+pathpos+2, opt_link_size) ); PROTO_ITEM_SET_GENERATED(it); } else - proto_tree_add_item( port_tree, hf_cip_link_address_string, tvb, offset+pathpos+2, opt_link_size, FALSE ); + { + proto_tree_add_item( port_tree, hf_cip_link_address_size, tvb, offset+pathpos+1, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item( port_tree, hf_cip_link_address_string, tvb, offset+pathpos+2, opt_link_size, ENC_LITTLE_ENDIAN ); + } + proto_item_append_text( epath_item, ", Address: %s", tvb_format_text(tvb, offset+pathpos+2, opt_link_size) ); - proto_item_append_text( port_item, ", Address: %s", tvb_format_text(tvb, offset+pathpos+2, opt_link_size) ); /* Pad byte */ if( opt_link_size % 2 ) { proto_item_set_len( port_item, 3 + opt_link_size ); - pathpos = pathpos + 3 + opt_link_size; + proto_item_set_len( path_seg_item, 3 + opt_link_size ); + pathpos += (3 + opt_link_size); } else { proto_item_set_len( port_item, 2 + opt_link_size ); - pathpos = pathpos + 2 + opt_link_size; + proto_item_set_len( path_seg_item, 2 + opt_link_size ); + pathpos += (2 + opt_link_size); } } else { - /* Add Extended Link Address flag */ - if ( generate ) - { - it = proto_tree_add_text( port_tree, NULL, 0, 0, "Extended Link Address: FALSE" ); - PROTO_ITEM_SET_GENERATED(it); - } - else - it = proto_tree_add_text( port_tree, tvb, offset+pathpos, 1, "Extended Link Address: FALSE" ); - /* Add Link Address */ if ( generate ) { @@ -700,11 +2589,14 @@ dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_lengt PROTO_ITEM_SET_GENERATED(it); } else - proto_tree_add_item( port_tree, hf_cip_link_address_byte, tvb, offset+pathpos+1, 1, FALSE ); + { + proto_tree_add_item(port_tree, hf_cip_link_address_byte, tvb, offset+pathpos+1, 1, ENC_LITTLE_ENDIAN ); + } + proto_item_append_text( epath_item, ", Address: %d",tvb_get_guint8( tvb, offset + pathpos + 1 ) ); - proto_item_append_text( port_item, ", Address: %d",tvb_get_guint8( tvb, offset + pathpos + 1 ) ); proto_item_set_len( port_item, 2 ); + proto_item_set_len( path_seg_item, 2); pathpos += 2; } @@ -712,448 +2604,81 @@ dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_lengt case CI_LOGICAL_SEGMENT: - /* Logical segment, determin the logical type */ + /* Logical segment, determine the logical type */ + if ( generate ) + { + it = proto_tree_add_uint(path_seg_tree, hf_cip_logical_seg_type, NULL, 0, 0, segment_type & CI_LOGICAL_SEG_TYPE_MASK); + PROTO_ITEM_SET_GENERATED(it); + if ((segment_type & CI_LOGICAL_SEG_TYPE_MASK) <= CI_LOGICAL_SEG_ATTR_ID) + { + it = proto_tree_add_uint(path_seg_tree, hf_cip_logical_seg_format, NULL, 0, 0, segment_type & CI_LOGICAL_SEG_FORMAT_MASK); + PROTO_ITEM_SET_GENERATED(it); + } + cia_item = proto_tree_add_text(path_seg_tree, NULL, 0, 0, "%s", val_to_str( ((segment_type & (CI_LOGICAL_SEG_TYPE_MASK|CI_LOGICAL_SEG_FORMAT_MASK))), cip_logical_seg_vals, "Reserved")); + PROTO_ITEM_SET_GENERATED(cia_item); + } + else + { + proto_tree_add_item(path_seg_tree, hf_cip_logical_seg_type, tvb, offset+pathpos, 1, ENC_LITTLE_ENDIAN ); + if ((segment_type & CI_LOGICAL_SEG_TYPE_MASK) <= CI_LOGICAL_SEG_ATTR_ID) + proto_tree_add_item(path_seg_tree, hf_cip_logical_seg_format, tvb, offset + pathpos, 1, ENC_LITTLE_ENDIAN); + cia_item = proto_tree_add_text(path_seg_tree, tvb, offset + pathpos, 1, "%s", val_to_str( ((segment_type & (CI_LOGICAL_SEG_TYPE_MASK|CI_LOGICAL_SEG_FORMAT_MASK))), cip_logical_seg_vals, "Reserved")); + } + + proto_item_append_text( path_seg_item, " (%s)", val_to_str( ((segment_type & (CI_LOGICAL_SEG_TYPE_MASK|CI_LOGICAL_SEG_FORMAT_MASK))), cip_logical_seg_vals, "Reserved")); + cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); switch( segment_type & CI_LOGICAL_SEG_TYPE_MASK ) { case CI_LOGICAL_SEG_CLASS_ID: - - /* Logical Class ID, do a format check */ - - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - temp_data = tvb_get_guint8( tvb, offset + pathpos + 1 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "8-Bit Logical Class Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "8-Bit Logical Class Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the class */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 8-bit class number */ - if ( generate ) - { - it = proto_tree_add_uint(cia_tree, hf_cip_class8, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_class8, tvb, offset + pathpos + 1, 1, TRUE ); - proto_item_append_text( epath_item, "%s", val_to_str( temp_data, cip_class_names_vals , "Class: 0x%02X" ) ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - temp_data = tvb_get_letohs( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "16-Bit Logical Class Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 4, "16-Bit Logical Class Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the class */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 16-bit class number */ - if ( generate ) - { - it = proto_tree_add_uint(cia_tree, hf_cip_class16, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_class16, tvb, offset + pathpos + 2, 2, TRUE ); - proto_item_append_text( epath_item, "%s", val_to_str( temp_data, cip_class_names_vals , "Class: 0x%04X" ) ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - temp_data = tvb_get_letohl( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "32-Bit Logical Instance Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 6, "32-Bit Logical Instance Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the class */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 32-bit class number */ - if ( generate ) - { - it = proto_tree_add_uint(cia_tree, hf_cip_class32, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_class32, tvb, offset + pathpos + 2, 4, TRUE ); - proto_item_append_text( epath_item, "%s", val_to_str( temp_data, cip_class_names_vals , "Class: 0x%08X" ) ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Logical Segment Format" ); - return; - } + dissect_cia(tvb, offset, &pathpos, segment_type & CI_LOGICAL_SEG_FORMAT_MASK, generate, pinfo, + epath_item, cia_item, cia_tree, path_seg_item, &cia_ret_item, + "Class", cip_class_names_vals, (req_data == NULL) ? NULL : &req_data->iClass, + hf_cip_class8, hf_cip_class16, hf_cip_class32); break; - case CI_LOGICAL_SEG_INST_ID: - - /* Logical Instance ID, do a format check */ - - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - temp_data = tvb_get_guint8( tvb, offset + pathpos + 1 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "8-Bit Logical Instance Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "8-Bit Logical Instance Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the instance */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 8-bit instance number */ - if ( generate ) - { - it = proto_tree_add_uint(cia_tree, hf_cip_instance8, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_instance8, tvb, offset + pathpos + 1, 1, TRUE ); - proto_item_append_text( epath_item, "Instance: 0x%02X", temp_data ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - temp_data = tvb_get_letohs( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "16-Bit Logical Instance Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 4, "16-Bit Logical Instance Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the instance */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 16-bit instance number */ - if ( generate ) - { - it = proto_tree_add_uint(cia_tree, hf_cip_instance16, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_instance16, tvb, offset + pathpos + 2, 2, TRUE ); - proto_item_append_text( epath_item, "Instance: 0x%04X", temp_data ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - temp_data = tvb_get_letohl( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "32-Bit Logical Instance Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 6, "32-Bit Logical Instance Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the instance */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 32-bit instance number */ - if ( generate ) - { - it = proto_tree_add_uint(cia_tree, hf_cip_instance32, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_instance32, tvb, offset + pathpos + 2, 4, TRUE ); - proto_item_append_text( epath_item, "Instance: 0x%08X", temp_data ); - - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Logical Segment Format" ); - return; - } + dissect_cia(tvb, offset, &pathpos, segment_type & CI_LOGICAL_SEG_FORMAT_MASK, generate, pinfo, + epath_item, cia_item, cia_tree, path_seg_item, &cia_ret_item, + "Instance", NULL, (req_data == NULL) ? NULL : &req_data->iInstance, + hf_cip_instance8, hf_cip_instance16, hf_cip_instance32); break; - case CI_LOGICAL_SEG_MBR_ID: - - /* Logical Member ID, do a format check */ - - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - temp_data = tvb_get_guint8( tvb, offset + pathpos + 1 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "8-Bit Logical Member Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "8-Bit Logical Member Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the attribute */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 8-bit attribute number */ - if ( generate ) - { - it = proto_tree_add_uint( cia_tree, hf_cip_member8, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_member8, tvb, offset + pathpos + 1, 1, TRUE ); - proto_item_append_text( epath_item, "Member: 0x%02X", temp_data ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - temp_data = tvb_get_letohs( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "16-Bit Logical Member Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 4, "16-Bit Logical Member Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the attribute */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 16-bit attribute number */ - if ( generate ) - { - it = proto_tree_add_uint( cia_tree, hf_cip_member16, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_member16, tvb, offset + pathpos + 2, 2, TRUE ); - proto_item_append_text( epath_item, "Member: 0x%04X", temp_data ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - temp_data = tvb_get_letohl( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "32-Bit Logical Member Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 6, "32-Bit Logical Member Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the attribute */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 32-bit attribute number */ - if ( generate ) - { - it = proto_tree_add_uint( cia_tree, hf_cip_member32, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_member32, tvb, offset + pathpos + 2, 4, TRUE ); - proto_item_append_text( epath_item, "Member: 0x%08X", temp_data ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Logical Segment Format" ); - return; - } + dissect_cia(tvb, offset, &pathpos, segment_type & CI_LOGICAL_SEG_FORMAT_MASK, generate, pinfo, + epath_item, cia_item, cia_tree, path_seg_item, &cia_ret_item, + "Member", NULL, (req_data == NULL) ? NULL : &req_data->iMember, + hf_cip_member8, hf_cip_member16, hf_cip_member32); break; case CI_LOGICAL_SEG_ATTR_ID: + dissect_cia(tvb, offset, &pathpos, segment_type & CI_LOGICAL_SEG_FORMAT_MASK, generate, pinfo, + epath_item, cia_item, cia_tree, path_seg_item, &cia_ret_item, + "Attribute", NULL, (req_data == NULL) ? NULL : &req_data->iAttribute, + hf_cip_attribute8, hf_cip_attribute16, hf_cip_attribute32); - /* Logical Attribute ID, do a format check */ - - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - temp_data = tvb_get_guint8( tvb, offset + pathpos + 1 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "8-Bit Logical Attribute Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "8-Bit Logical Attribute Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the attribute */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 8-bit attribute number */ - if ( generate ) - { - it = proto_tree_add_uint( cia_tree, hf_cip_attribute8, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_attribute8, tvb, offset + pathpos + 1, 1, TRUE ); - proto_item_append_text( epath_item, "Attribute: 0x%02X", temp_data ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - temp_data = tvb_get_letohs( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "16-Bit Logical Attribute Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 4, "16-Bit Logical Attribute Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the attribute */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 16-bit attribute number */ - if ( generate ) - { - it = proto_tree_add_uint( cia_tree, hf_cip_attribute16, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); - } - else - proto_tree_add_item( cia_tree, hf_cip_attribute16, tvb, offset + pathpos + 2, 2, TRUE ); - proto_item_append_text( epath_item, "Attribute: 0x%04X", temp_data ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) + if (req_data != NULL) { - temp_data = tvb_get_letohl( tvb, offset + pathpos + 2 ); - if ( generate ) - { - cia_item = proto_tree_add_text( path_tree, NULL, 0, 0, "32-Bit Logical Attribute Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(cia_item); - } - else - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 6, "32-Bit Logical Attribute Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the attribute */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 32-bit attribute number */ - if ( generate ) + att_info = cip_get_attribute(req_data->iClass, req_data->iInstance, + req_data->iAttribute); + if (att_info != NULL) { - it = proto_tree_add_uint( cia_tree, hf_cip_attribute32, NULL, 0, 0, temp_data ); - PROTO_ITEM_SET_GENERATED(it); + proto_item_append_text(cia_ret_item, " (%s)", att_info->text); + proto_item_append_text(epath_item, " (%s)", att_info->text); } - else - proto_tree_add_item( cia_tree, hf_cip_attribute32, tvb, offset + pathpos + 2, 4, TRUE ); - proto_item_append_text( epath_item, "Attribute: 0x%08X", temp_data ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Logical Segment Format" ); - return; } break; - case CI_LOGICAL_SEG_CON_POINT: - - /* Logical Connection point , do a format check */ - - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - temp_data = tvb_get_guint8( tvb, offset + pathpos + 1 ); - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "8-Bit Logical Connection Point Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the connection point */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 8-bit connection point number */ - proto_tree_add_item( cia_tree, hf_cip_conpoint8, tvb, offset + pathpos + 1, 1, TRUE ); - proto_item_append_text( epath_item, "Connection Point: 0x%02X", temp_data ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - temp_data = tvb_get_letohs( tvb, offset + pathpos + 2 ); - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 4, "16-Bit Logical Connection Point Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the connection point */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 16-bit connection point number */ - proto_tree_add_item( cia_tree, hf_cip_conpoint16, tvb, offset + pathpos + 2, 2, TRUE ); - proto_item_append_text( epath_item, "Connection Point: 0x%04X", temp_data ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - temp_data = tvb_get_letohl( tvb, offset + pathpos + 2 ); - cia_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 6, "32-Bit Logical Connection Point Segment (0x%02X)", segment_type ); - - /* Create a sub tree for the connection point */ - cia_tree = proto_item_add_subtree( cia_item, ett_cia_path ); - - /* Display the 32-bit connection point number */ - proto_tree_add_item( cia_tree, hf_cip_conpoint32, tvb, offset + pathpos + 2, 4, TRUE ); - proto_item_append_text( epath_item, "Connection Point: 0x%08X", temp_data ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Logical Segment Format" ); - return; - } + dissect_cia(tvb, offset, &pathpos, segment_type & CI_LOGICAL_SEG_FORMAT_MASK, generate, pinfo, + epath_item, cia_item, cia_tree, path_seg_item, &cia_ret_item, + "Connection Point", NULL, NULL, + hf_cip_conpoint8, hf_cip_conpoint16, hf_cip_conpoint32); break; - case CI_LOGICAL_SEG_SPECIAL: - /* Logical Special ID, the only logical format sepcifyed is electronic key */ - + /* Logical Special ID, the only logical format specified is electronic key */ if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_E_KEY ) { /* Get the Key Format */ @@ -1161,188 +2686,138 @@ dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_lengt if( temp_data == CI_E_KEY_FORMAT_VAL ) { - qi = proto_tree_add_text( path_tree, tvb, offset + pathpos, 10, "Electronic Key Segment (0x%02X): ",segment_type ); - - /* Create a sub tree for the IOI */ - e_key_tree = proto_item_add_subtree( qi, ett_ekey_path ); + proto_item_set_len(path_seg_item, 10); + proto_item_set_len(cia_item, 10); + proto_tree_add_item( cia_tree, hf_cip_ekey_format, tvb, offset + pathpos+1, 1, ENC_LITTLE_ENDIAN); - /* Print the key type */ - proto_tree_add_text( e_key_tree, tvb, offset + pathpos + 1, 1, "Key Format: 0x%02X", temp_data ); + /* dissect the device ID */ + dissect_deviceid(tvb, offset + pathpos + 2, cia_tree, + hf_cip_ekey_vendor, hf_cip_ekey_devtype, hf_cip_ekey_prodcode, + hf_cip_ekey_compatibility, hf_cip_ekey_comp_bit, hf_cip_ekey_majorrev, hf_cip_ekey_minorrev); - /* Get the Vendor ID */ + /* Add "summary" information to parent item */ temp_data = tvb_get_letohs( tvb, offset + pathpos + 2 ); - proto_tree_add_item( e_key_tree, hf_cip_vendor, tvb, offset + pathpos + 2, 2, ENC_LITTLE_ENDIAN); - proto_item_append_text( qi, "VendorID: 0x%04X", temp_data ); - - /* Get Device Type */ + proto_item_append_text( cia_tree, " (VendorID: 0x%04X", temp_data ); temp_data = tvb_get_letohs( tvb, offset + pathpos + 4 ); - proto_tree_add_item( e_key_tree, hf_cip_devtype, tvb, offset + pathpos + 4, 2, ENC_LITTLE_ENDIAN); - proto_item_append_text( qi, ", DevTyp: 0x%04X", temp_data ); - - /* Product Code */ - temp_data = tvb_get_letohs( tvb, offset + pathpos + 6 ); - proto_tree_add_text( e_key_tree, tvb, offset + pathpos + 6, 2, "Product Code: 0x%04X", temp_data ); - - /* Major revision/Compatibility */ + proto_item_append_text( cia_tree, ", DevTyp: 0x%04X", temp_data ); temp_data = tvb_get_guint8( tvb, offset + pathpos + 8 ); - - /* Add Major revision/Compatibility tree */ - mcpi = proto_tree_add_text(e_key_tree, tvb, offset + pathpos + 8, 1, "Compatibility "); - mc_tree = proto_item_add_subtree(mcpi, ett_mcsc); - - /* Add Compatibility bit info */ - proto_tree_add_item(mc_tree, hf_cip_fwo_comp, - tvb, offset + pathpos + 8, 1, TRUE ); - - proto_item_append_text( mcpi, "%s, Major Revision: %d", - val_to_str( ( temp_data & 0x80 )>>7, cip_com_bit_vals , "" ), - temp_data & 0x7F ); - - /* Major revision */ - proto_tree_add_item(mc_tree, hf_cip_fwo_mrev, - tvb, offset + pathpos + 8, 1, TRUE ); - - /* Minor revision */ temp_data2 = tvb_get_guint8( tvb, offset + pathpos + 9 ); - proto_tree_add_text( e_key_tree, tvb, offset + pathpos + 9, 1, "Minor Revision: %d", temp_data2 ); - - proto_item_append_text( qi, ", %d.%d", ( temp_data & 0x7F ), temp_data2 ); + proto_item_append_text(cia_tree, ", %d.%d)", ( temp_data & 0x7F ), temp_data2 ); proto_item_append_text(epath_item, "[Key]" ); - /* Increment the path pointer */ pathpos += 10; } else { - /* Unsupported electronic key format */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Electronic Key Format" ); + expert_add_info_format(pinfo, epath_item, PI_PROTOCOL, PI_ERROR, "Unsupported Electronic Key Format"); return; } } else { - /* Unsupported special segment format */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Special Segment Format" ); + expert_add_info_format(pinfo, epath_item, PI_PROTOCOL, PI_ERROR, "Unsupported Special Segment Format"); return; } break; default: - - /* Unsupported logical segment type */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Logical Segment Type" ); + expert_add_info_format(pinfo, epath_item, PI_PROTOCOL, PI_ERROR, "Unsupported Logical Segment Type"); return; } /* end of switch( segment_type & CI_LOGICAL_SEG_TYPE_MASK ) */ break; - case CI_DATA_SEGMENT: - /* Data segment, determin the logical type */ - - switch( segment_type ) + /* Data segment, determine the logical type */ + if ( generate ) { - case CI_DATA_SEG_SIMPLE: - - /* Simple data segment */ - if ( generate ) - { - ds_item = proto_tree_add_text( path_tree, NULL, 0, 0, "Simple Data Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(ds_item); - } - else - ds_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 1, "Simple Data Segment (0x%02X)", segment_type ); + it = proto_tree_add_uint(path_seg_tree, hf_cip_data_seg_type, NULL, 0, 0, segment_type & CI_DATA_SEG_TYPE_MASK); + PROTO_ITEM_SET_GENERATED(it); + ds_item = proto_tree_add_text(path_seg_tree, NULL, 0, 0, "%s", val_to_str( (segment_type & CI_DATA_SEG_TYPE_MASK), cip_data_segment_type_vals, "Reserved")); + PROTO_ITEM_SET_GENERATED(ds_item); + } + else + { + proto_tree_add_item(path_seg_tree, hf_cip_data_seg_type, tvb, offset+pathpos, 1, ENC_LITTLE_ENDIAN ); + ds_item = proto_tree_add_text(path_seg_tree, tvb, offset + pathpos, 1, "%s", val_to_str( (segment_type & CI_DATA_SEG_TYPE_MASK), cip_data_segment_type_vals, "Reserved")); + } - /* Create a sub tree */ - ds_tree = proto_item_add_subtree( ds_item, ett_data_seg ); + proto_item_append_text( path_seg_item, " (%s)", val_to_str( (segment_type & CI_DATA_SEG_TYPE_MASK), cip_data_segment_type_vals, "Reserved")); + ds_tree = proto_item_add_subtree( ds_item, ett_data_seg ); + switch( segment_type & CI_DATA_SEG_TYPE_MASK) + { + case CI_DATA_SEG_SIMPLE: /* Segment size */ seg_size = tvb_get_guint8( tvb, offset + pathpos+1 )*2; - proto_tree_add_text( ds_tree, tvb, offset + pathpos+1, 1, "Data Size: %d (words)", seg_size/2 ); + + proto_tree_add_uint_format_value(ds_tree, hf_cip_data_seg_size, + tvb, offset + pathpos+1, 1, seg_size, "%d (words)", seg_size/2); /* Segment data */ if( seg_size != 0 ) { - qi = proto_tree_add_text( ds_tree, tvb, offset + pathpos+2, 0, "Data: " ); + ds_data_item = proto_tree_add_text( ds_tree, tvb, offset + pathpos+2, 0, "Data" ); + ds_data_tree = proto_item_add_subtree( ds_data_item, ett_data_seg_data ); for( i=0; i < seg_size/2; i ++ ) - { - temp_word = tvb_get_letohs( tvb, offset + pathpos+2+(i*2) ); - proto_item_append_text(qi, " 0x%04X", temp_word ); - } + proto_tree_add_item(ds_data_tree, hf_cip_data_seg_item, tvb, offset + pathpos+2+(i*2), 2, ENC_LITTLE_ENDIAN ); - proto_item_set_len(qi, seg_size); + proto_item_set_len(ds_data_item, seg_size); } proto_item_set_len( ds_item, 2 + seg_size ); - pathpos = pathpos + 2 + seg_size; + proto_item_set_len( path_seg_item, 2 + seg_size ); + pathpos += (2 + seg_size); proto_item_append_text(epath_item, "[Data]" ); - break; case CI_DATA_SEG_SYMBOL: /* ANSI extended symbol segment */ - if ( generate ) - { - ds_item = proto_tree_add_text( path_tree, NULL, 0, 0, "Extended Symbol Segment (0x%02X)", segment_type ); - PROTO_ITEM_SET_GENERATED(ds_item); - } - else - ds_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 1, "Extended Symbol Segment (0x%02X)", segment_type ); - - /* Create a sub tree */ - ds_tree = proto_item_add_subtree( ds_item, ett_data_seg ); /* Segment size */ seg_size = tvb_get_guint8( tvb, offset + pathpos+1 ); if ( generate ) { - it = proto_tree_add_text( ds_tree, NULL, 0, 0, "Data Size: %d", seg_size ); + it = proto_tree_add_uint(ds_tree, hf_cip_data_seg_type, NULL, 0, 0, seg_size); PROTO_ITEM_SET_GENERATED(it); } else - proto_tree_add_text( ds_tree, tvb, offset + pathpos+1, 1, "Data Size: %d", seg_size ); + proto_tree_add_item(ds_tree, hf_cip_data_seg_size, tvb, offset + pathpos+1, 1, ENC_LITTLE_ENDIAN ); /* Segment data */ if( seg_size != 0 ) { if ( generate ) { - qi = proto_tree_add_text( ds_tree, NULL, 0, 0, "Data: %s", - tvb_format_text(tvb, offset + pathpos + 2, seg_size ) ); - PROTO_ITEM_SET_GENERATED(qi); + it = proto_tree_add_string(ds_tree, hf_cip_symbol, NULL, 0, 0, tvb_format_text(tvb, offset + pathpos + 2, seg_size)); + PROTO_ITEM_SET_GENERATED(it); } else - qi = proto_tree_add_text( ds_tree, tvb, offset + pathpos + 2, seg_size, "Data: %s", - tvb_format_text(tvb, offset + pathpos + 2, seg_size ) ); - - proto_item_append_text(epath_item, "%s", tvb_format_text(tvb, offset + pathpos + 2, seg_size ) ); - - hidden_item = proto_tree_add_item( ds_tree, hf_cip_symbol, tvb, offset + pathpos + 2, seg_size, FALSE ); - PROTO_ITEM_SET_HIDDEN(hidden_item); + proto_tree_add_item( ds_tree, hf_cip_symbol, tvb, offset + pathpos + 2, seg_size, ENC_LITTLE_ENDIAN ); - if( seg_size %2 ) - { - /* We have a PAD BYTE */ - if ( !generate ) - proto_tree_add_text( ds_tree, tvb, offset + pathpos + 2 + seg_size, 1, "Pad Byte (0x%02X)", - tvb_get_guint8( tvb, offset + pathpos + 2 + seg_size ) ); - seg_size++; - } + proto_item_append_text(epath_item, "%s", tvb_format_text(tvb, offset + pathpos + 2, seg_size)); } + /* Check for pad byte */ + if( seg_size %2 ) + seg_size++; + if ( !generate ) + { proto_item_set_len( ds_item, 2 + seg_size ); - pathpos = pathpos + 2 + seg_size; + proto_item_set_len( path_seg_item, 2 + seg_size ); + } + pathpos += (2 + seg_size); break; default: - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Sub-Segment Type" ); + expert_add_info_format(pinfo, epath_item, PI_PROTOCOL, PI_ERROR, "Unsupported Sub-Segment Type"); return; } /* End of switch sub-type */ @@ -1352,41 +2827,53 @@ dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_lengt case CI_NETWORK_SEGMENT: /* Network segment -Determine the segment sub-type */ + if ( generate ) + { + it = proto_tree_add_uint(path_seg_tree, hf_cip_network_seg_type, NULL, 0, 0, segment_type & CI_NETWORK_SEG_TYPE_MASK); + PROTO_ITEM_SET_GENERATED(it); + net_item = proto_tree_add_text(path_seg_tree, NULL, 0, 0, "%s", val_to_str( (segment_type & CI_NETWORK_SEG_TYPE_MASK), cip_network_segment_type_vals, "Reserved")); + PROTO_ITEM_SET_GENERATED(net_item); + } + else + { + proto_tree_add_item(path_seg_tree, hf_cip_network_seg_type, tvb, offset+pathpos, 1, ENC_LITTLE_ENDIAN ); + net_item = proto_tree_add_text(path_seg_tree, tvb, offset + pathpos, 1, "%s", val_to_str( (segment_type & CI_NETWORK_SEG_TYPE_MASK), cip_network_segment_type_vals, "Reserved")); + } + + proto_item_append_text( path_seg_item, " (%s)", val_to_str( (segment_type & CI_NETWORK_SEG_TYPE_MASK), cip_network_segment_type_vals, "Reserved")); + net_tree = proto_item_add_subtree( net_item, ett_network_seg ); switch( segment_type & CI_NETWORK_SEG_TYPE_MASK ) { case CI_NETWORK_SEG_SCHEDULE: - net_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "Network Segment - Schedule" ); - net_tree = proto_item_add_subtree( net_item, ett_port_path ); + proto_tree_add_item(net_tree, hf_cip_seg_schedule, tvb, offset+pathpos+1, 1, ENC_LITTLE_ENDIAN ); - proto_tree_add_text( net_tree, tvb, offset + pathpos + 1, 1, "Multiplier/Phase: %02X", tvb_get_guint8( tvb, offset + pathpos + 1 ) ); - - /* 2 bytes of path used */ + proto_item_set_len( net_item, 2 + seg_size ); + proto_item_set_len( path_seg_item, 2 + seg_size ); pathpos += 2; break; case CI_NETWORK_SEG_FIXED_TAG: - net_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "Network Segment - Fixed Tag" ); - net_tree = proto_item_add_subtree( net_item, ett_port_path ); - - proto_tree_add_text( net_tree, tvb, offset + pathpos + 1, 1, "Fixed Tag: %02X", tvb_get_guint8( tvb, offset + pathpos + 1 ) ); + proto_tree_add_item(net_tree, hf_cip_seg_fixed_tag, tvb, offset+pathpos+1, 1, ENC_LITTLE_ENDIAN ); - /* 2 bytes of path used */ + proto_item_set_len( net_item, 2 + seg_size ); + proto_item_set_len( path_seg_item, 2 + seg_size ); pathpos += 2; break; case CI_NETWORK_SEG_PROD_INHI: - net_item = proto_tree_add_text( path_tree, tvb, offset + pathpos, 2, "Network Segment - Production Inhibit" ); - net_tree = proto_item_add_subtree( net_item, ett_port_path ); - proto_tree_add_text( net_tree, tvb, offset + pathpos + 1, 1, "Production Inhibit Time: %dms", tvb_get_guint8( tvb, offset + pathpos + 1 ) ); + temp_data = tvb_get_guint8( tvb, offset + pathpos + 1 ); + proto_tree_add_uint_format_value(net_tree, hf_cip_seg_prod_inhibit_time, + tvb, offset + pathpos+1, 1, temp_data, "%dms", temp_data); - /* 2 bytes of path used */ + proto_item_set_len( net_item, 2 + seg_size ); + proto_item_set_len( path_seg_item, 2 + seg_size ); pathpos += 2; break; default: - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Sub-Segment Type" ); + expert_add_info_format(pinfo, epath_item, PI_PROTOCOL, PI_ERROR, "Unsupported Sub-Segment Type"); return; } /* End of switch sub-type */ @@ -1394,9 +2881,7 @@ dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_lengt break; default: - - /* Unsupported segment type */ - proto_tree_add_text( path_tree, tvb, 0, 0, "Unsupported Segment Type" ); + expert_add_info_format(pinfo, epath_item, PI_PROTOCOL, PI_ERROR, "Unsupported Segment Type"); return; } /* end of switch( segment_type & CI_SEGMENT_TYPE_MASK ) */ @@ -1409,322 +2894,81 @@ dissect_epath( tvbuff_t *tvb, proto_item *epath_item, int offset, int path_lengt } /* end of dissect_epath() */ -/* Dissect EPATH for class, instance, attribute, and/or member without creating a tree */ -static void -dissect_epath_request( tvbuff_t *tvb, cip_simple_request_info_t* req_data, int path_length) +static int +dissect_cip_attribute(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + attribute_info_t* attr, int offset, int total_len) { - int pathpos, offset, temp_data, seg_size; - unsigned char segment_type, opt_link_size; - - /* can't populate req_data unless its there */ - if (req_data == NULL) - return; - - req_data->iClass = (guint32)-1; - req_data->iInstance = (guint32)-1; - req_data->iAttribute = (guint32)-1; - req_data->iMember = (guint32)-1; - - pathpos = 0; - offset = 0; + int i, temp_data, + consumed = 0; - while( pathpos < path_length ) + /* sanity check */ + if (((attr->datatype == cip_dissector_func) && (attr->pdissect == NULL)) || + ((attr->datatype != cip_dissector_func) && (attr->phf == NULL))) { - /* Get segement type */ - segment_type = tvb_get_guint8( tvb, offset + pathpos ); - - /* Determine the segment type */ - switch( segment_type & CI_SEGMENT_TYPE_MASK ) - { - case CI_PORT_SEGMENT: - if( segment_type & 0x10 ) - { - /* Add size of extended link address */ - opt_link_size = tvb_get_guint8( tvb, offset + pathpos + 1 ); - - /* Pad byte */ - if( opt_link_size % 2 ) - { - pathpos = pathpos + 3 + opt_link_size; - } - else - { - pathpos = pathpos + 2 + opt_link_size; - } - } - else - { - pathpos += 2; - } - break; - - case CI_LOGICAL_SEGMENT: - - /* Logical segment, determin the logical type */ - switch( segment_type & CI_LOGICAL_SEG_TYPE_MASK ) - { - case CI_LOGICAL_SEG_CLASS_ID: - - /* Logical Class ID, do a format check */ - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - req_data->iClass = tvb_get_guint8( tvb, offset + pathpos + 1 ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - req_data->iClass = tvb_get_letohs( tvb, offset + pathpos + 2 ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - req_data->iClass = tvb_get_letohl( tvb, offset + pathpos + 2 ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - return; - } - break; - - case CI_LOGICAL_SEG_INST_ID: - - /* Logical Instance ID, do a format check */ - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - req_data->iInstance = tvb_get_guint8( tvb, offset + pathpos + 1 ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - req_data->iInstance = tvb_get_letohs( tvb, offset + pathpos + 2 ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - req_data->iInstance = tvb_get_letohl( tvb, offset + pathpos + 2 ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - return; - } - break; - - - case CI_LOGICAL_SEG_MBR_ID: - - /* Logical Member ID, do a format check */ - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - req_data->iMember = tvb_get_guint8( tvb, offset + pathpos + 1 ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - req_data->iMember = tvb_get_letohs( tvb, offset + pathpos + 2 ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - req_data->iMember = tvb_get_letohl( tvb, offset + pathpos + 2 ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - return; - } - break; - - case CI_LOGICAL_SEG_ATTR_ID: - - /* Logical Attribute ID, do a format check */ - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - req_data->iAttribute = tvb_get_guint8( tvb, offset + pathpos + 1 ); - - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - req_data->iAttribute = tvb_get_letohs( tvb, offset + pathpos + 2 ); - - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - req_data->iAttribute = tvb_get_letohl( tvb, offset + pathpos + 2 ); - - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - return; - } - break; - - - case CI_LOGICAL_SEG_CON_POINT: - - /* Logical Connection point , do a format check */ - - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_8_BIT ) - { - /* 2 bytes of path used */ - pathpos += 2; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_16_BIT ) - { - /* 4 bytes of path used */ - pathpos += 4; - } - else if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_32_BIT ) - { - /* 6 bytes of path used */ - pathpos += 6; - } - else - { - /* Unsupported logical segment format */ - return; - } - break; - - - case CI_LOGICAL_SEG_SPECIAL: - - /* Logical Special ID, the only logical format specified is electronic key */ - if( ( segment_type & CI_LOGICAL_SEG_FORMAT_MASK ) == CI_LOGICAL_SEG_E_KEY ) - { - /* Get the Key Format */ - temp_data = tvb_get_guint8( tvb, offset + pathpos + 1 ); - if( temp_data == CI_E_KEY_FORMAT_VAL ) - { - /* Increment the path pointer */ - pathpos += 10; - } - else - { - /* Unsupported electronic key format */ - return; - } - } - else - { - /* Unsupported special segment format */ - return; - } - break; - - default: - - /* Unsupported logical segment type */ - return; - - } /* end of switch( segment_type & CI_LOGICAL_SEG_TYPE_MASK ) */ - break; - - - case CI_DATA_SEGMENT: - - /* Data segment, determin the logical type */ - switch( segment_type ) - { - case CI_DATA_SEG_SIMPLE: - - /* Simple data segment */ - - /* Segment size */ - seg_size = tvb_get_guint8( tvb, offset + pathpos+1 )*2; - pathpos = pathpos + 2 + seg_size; - break; - - case CI_DATA_SEG_SYMBOL: - - /* Segment size */ - seg_size = tvb_get_guint8( tvb, offset + pathpos+1 ); - - /* Segment data */ - if( seg_size != 0 ) - { - if( seg_size %2 ) - { - /* We have a PAD BYTE */ - seg_size++; - } - } - - pathpos = pathpos + 2 + seg_size; - break; - - default: - return; - - } /* End of switch sub-type */ - break; - - case CI_NETWORK_SEGMENT: - - /* Network segment -Determine the segment sub-type */ - switch( segment_type & CI_NETWORK_SEG_TYPE_MASK ) - { - case CI_NETWORK_SEG_SCHEDULE: - /* 2 bytes of path used */ - pathpos += 2; - break; - - case CI_NETWORK_SEG_FIXED_TAG: - /* 2 bytes of path used */ - pathpos += 2; - break; - - case CI_NETWORK_SEG_PROD_INHI: - /* 2 bytes of path used */ - pathpos += 2; - break; - - default: - return; - - } /* End of switch sub-type */ + expert_add_info_format(pinfo, item, PI_UNDECODED, PI_ERROR, "PROGRAMMING ERROR: Attribute table set up incorrectly"); + return total_len; + } + switch (attr->datatype) + { + case cip_bool: + case cip_usint: + case cip_sint: + case cip_byte: + proto_tree_add_item(tree, *(attr->phf), tvb, offset, 1, ENC_LITTLE_ENDIAN); + consumed = 1; break; + case cip_uint: + case cip_int: + case cip_word: + case cip_itime: + proto_tree_add_item(tree, *(attr->phf), tvb, offset, 2, ENC_LITTLE_ENDIAN); + consumed = 2; + break; + case cip_usint_array: + proto_tree_add_item(tree, *(attr->phf), tvb, offset, total_len, ENC_LITTLE_ENDIAN); + consumed = total_len; + break; + case cip_uint_array: + for (i = 0; i < total_len; i+=2) + proto_tree_add_item(tree, *(attr->phf), tvb, offset+i, 2, ENC_LITTLE_ENDIAN); - default: - - /* Unsupported segment type */ - return; - - } /* end of switch( segment_type & CI_SEGMENT_TYPE_MASK ) */ - - } /* end of while( pathpos < path_length ) */ + consumed = i; + break; + case cip_udint: + case cip_dint: + case cip_dword: + case cip_real: + case cip_time: + case cip_ftime: + proto_tree_add_item(tree, *(attr->phf), tvb, offset, 4, ENC_LITTLE_ENDIAN); + consumed = 4; + break; + case cip_ulint: + case cip_lint: + case cip_lword: + case cip_lreal: + case cip_ltime: + proto_tree_add_item(tree, *(attr->phf), tvb, offset, 8, ENC_LITTLE_ENDIAN); + consumed = 8; + break; + case cip_short_string: + temp_data = tvb_get_guint8( tvb, offset ); + proto_tree_add_item(tree, *(attr->phf), tvb, offset+1, temp_data, ENC_LITTLE_ENDIAN); + consumed = 1+temp_data; + break; + case cip_string: + temp_data = tvb_get_letohs( tvb, offset ); + proto_tree_add_item(tree, *(attr->phf), tvb, offset+2, temp_data, ENC_LITTLE_ENDIAN); + consumed = 2+temp_data; + break; + case cip_dissector_func: + consumed = attr->pdissect(pinfo, tree, item, tvb, offset, total_len); + break; + } -} /* end of dissect_epath_request() */ + return consumed; +} /************************************************ * @@ -1735,12 +2979,10 @@ dissect_epath_request( tvbuff_t *tvb, cip_simple_request_info_t* req_data, int p static void dissect_cip_generic_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_length, packet_info *pinfo, proto_item *ti ) { - proto_item *pi, *temp_item; + proto_item *pi; proto_tree *cmd_data_tree; int req_path_size; unsigned char add_stat_size; - unsigned char i; - if( tvb_get_guint8( tvb, offset ) & 0x80 ) { @@ -1754,7 +2996,7 @@ dissect_cip_generic_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int cmd_data_tree = proto_item_add_subtree( pi, ett_cmd_data ); /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, ENC_LITTLE_ENDIAN); } else { @@ -1776,40 +3018,10 @@ dissect_cip_generic_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int /* If there is any command specific data creat a sub-tree for it */ if( (item_length-req_path_size-2) != 0 ) { - pi = proto_tree_add_text( item_tree, tvb, offset+2+req_path_size, item_length-req_path_size-2, "Command Specific Data" ); cmd_data_tree = proto_item_add_subtree( pi, ett_cmd_data ); - /* Check what service code that recived */ - - if( tvb_get_guint8( tvb, offset ) == SC_GET_ATT_LIST ) - { - /* Get attribute list request */ - - int att_count; - - /* Add number of services */ - att_count = tvb_get_letohs( tvb, offset+2+req_path_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Attribute Count: %d", att_count ); - - /* Add Attribute List */ - temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, att_count*2, "Attribute List: " ); - - for( i=0; i < att_count; i++ ) - { - if( i == (att_count-1) ) - proto_item_append_text(temp_item, "%d",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - else - proto_item_append_text(temp_item, "%d, ",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - } - - } /* End of Get attribute list request */ - else - { - /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+2+req_path_size, item_length-req_path_size-2, "Data: " ); - } /* End of check service code */ - + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+2+req_path_size, item_length-req_path_size-2, ENC_LITTLE_ENDIAN); } else { @@ -1829,7 +3041,7 @@ dissect_cip_class_generic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if( tree ) { /* Create display subtree for the protocol */ - ti = proto_tree_add_item(tree, proto_cip_class_generic, tvb, 0, -1, ENC_BIG_ENDIAN); + ti = proto_tree_add_item(tree, proto_cip_class_generic, tvb, 0, -1, ENC_LITTLE_ENDIAN); class_tree = proto_item_add_subtree( ti, ett_cip_class_generic ); dissect_cip_generic_data( class_tree, tvb, 0, tvb_length(tvb), pinfo, ti ); @@ -1838,314 +3050,666 @@ dissect_cip_class_generic(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return tvb_length(tvb); } -/************************************************ - * - * Dissector for CIP Message Router - * - ************************************************/ +static void +dissect_cip_set_attribute_single_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) +{ + attribute_info_t* attr; + + attr = cip_get_attribute(req_data->iClass, req_data->iInstance, req_data->iAttribute); + if (attr != NULL) + { + dissect_cip_attribute(pinfo, tree, item, tvb, attr, offset, tvb_length_remaining(tvb, offset)); + } + else + { + proto_tree_add_item(tree, hf_cip_sc_set_attr_single_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + } +} static void -dissect_cip_mr_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_length, packet_info *pinfo ) +dissect_cip_get_attribute_list_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) { + int i, att_count, att_value; + attribute_info_t* pattribute; + proto_item *att_list, *att_item; + proto_tree* att_tree; -typedef struct mr_mult_req_info { - guint8 service; - int num_services; - cip_req_info_t *requests; -} mr_mult_req_info_t; + /* Get attribute list request */ + if (tvb_length_remaining(tvb, offset) < 2) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Malformed Get Attribute List service"); + return; + } - proto_item *pi, *rrsc_item, *temp_item, *temp_item2; - proto_tree *temp_tree, *rrsc_tree, *cmd_data_tree; - int req_path_size; - int i; - unsigned char gen_status; - unsigned char add_stat_size; - int num_services, serv_offset; - unsigned char service; - mr_mult_req_info_t *mr_mult_req_info; - cip_req_info_t *mr_single_req_info; - cip_req_info_t *cip_req_info; + /* Add number of attributes */ + att_count = tvb_get_letohs( tvb, offset); + proto_tree_add_item(tree, hf_cip_sc_get_attr_list_attr_count, tvb, offset, 2, ENC_LITTLE_ENDIAN); - col_set_str(pinfo->cinfo, COL_PROTOCOL, "CIP MR"); + /* Add Attribute List */ + att_list = proto_tree_add_text(tree, tvb, offset+2, att_count*2, "Attribute List" ); + att_tree = proto_item_add_subtree( att_list, ett_cip_get_attribute_list); - /* Add Service code & Request/Response tree */ - rrsc_item = proto_tree_add_text( item_tree, tvb, offset, 1, "Service: " ); - rrsc_tree = proto_item_add_subtree( rrsc_item, ett_mr_rrsc ); + for( i=0; i < att_count; i++ ) + { + att_value = tvb_get_letohs( tvb, offset+2); + att_item = proto_tree_add_item(att_tree, hf_cip_sc_get_attr_list_attr_item, tvb, offset+2, 2, ENC_LITTLE_ENDIAN); + pattribute = cip_get_attribute(req_data->iClass, req_data->iInstance, att_value); + if (pattribute != NULL) + proto_item_append_text(att_item, " (%s)", pattribute->text); + + offset += 2; + if ((tvb_length_remaining(tvb, offset+2) < 2) && (i < att_count-1)) + { + expert_add_info_format(pinfo, att_list, PI_MALFORMED, PI_ERROR, "Get Attribute List attribute list count greater than packet size"); + break; + } + } +} - /* Add Request/Response */ - proto_tree_add_item( rrsc_tree, hf_cip_rr, tvb, offset, 1, TRUE ); +static void +dissect_cip_set_attribute_list_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) +{ + int i, start_offset, att_count, + att_value, att_size; + attribute_info_t* attr; + proto_item *att_list, *att_item; + proto_tree *att_tree, *att_list_tree; + + /* Get attribute list request */ + if (tvb_length_remaining(tvb, offset) < 2) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Malformed Set Attribute List service"); + return; + } - /* watch for service collisions */ - service = tvb_get_guint8( tvb, offset ); + /* Add number of attributes */ + att_count = tvb_get_letohs( tvb, offset); + proto_tree_add_item(tree, hf_cip_sc_set_attr_list_attr_count, tvb, offset, 2, ENC_LITTLE_ENDIAN); - proto_item_append_text( rrsc_item, "%s (%s)", - val_to_str( ( service & 0x7F ), - cip_sc_vals, "Unknown Service (0x%02x)"), - val_to_str( ( service & 0x80 )>>7, - cip_sc_rr, "") ); + /* Add Attribute List */ + att_list = proto_tree_add_text(tree, tvb, offset+2, att_count*4, "Attribute List" ); + att_list_tree = proto_item_add_subtree( att_list, ett_cip_set_attribute_list); + offset += 2; + start_offset = offset; - /* Add Service code */ - proto_tree_add_item(rrsc_tree, hf_cip_sc, tvb, offset, 1, TRUE ); + for( i=0; i < att_count; i++ ) + { + att_value = tvb_get_letohs( tvb, offset); + att_item = proto_tree_add_item(att_list_tree, hf_cip_sc_set_attr_list_attr_item, tvb, offset, 2, ENC_LITTLE_ENDIAN); + att_tree = proto_item_add_subtree( att_item, ett_cip_set_attribute_list_item); + offset += 2; - if( tvb_get_guint8( tvb, offset ) & 0x80 ) + attr = cip_get_attribute(req_data->iClass, req_data->iInstance, att_value); + if (attr != NULL) + { + proto_item_append_text(att_item, " (%s)", attr->text); + /* provide attribute data */ + att_size = dissect_cip_attribute(pinfo, att_tree, att_item, tvb, attr, offset, tvb_length_remaining(tvb, offset)); + offset += att_size; + proto_item_set_len(att_item, att_size+4); + } + else + { + /* Can't find the attribute, treat the rest of the request as raw data */ + proto_tree_add_item(att_tree, hf_cip_sc_set_attr_list_attr_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + } + + if ((tvb_length_remaining(tvb, offset) < 2) && (i < att_count-1)) + { + expert_add_info_format(pinfo, att_list, PI_MALFORMED, PI_ERROR, "Set Attribute List attribute list count greater than packet size"); + break; + } + } + + proto_item_set_len(att_list, offset-start_offset ); +} + +static void +dissect_cip_multiple_service_packet_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) +{ + proto_item *mult_serv_item; + proto_tree *mult_serv_tree; + int i, num_services, serv_offset; + cip_req_info_t *cip_req_info, *mr_single_req_info; + mr_mult_req_info_t *mr_mult_req_info = NULL; + + /* Add number of services */ + num_services = tvb_get_letohs( tvb, offset); + proto_tree_add_item(tree, hf_cip_sc_mult_serv_pack_num_services, tvb, offset, 2, ENC_LITTLE_ENDIAN); + + /* Add services */ + cip_req_info = (cip_req_info_t*)p_get_proto_data( pinfo->fd, proto_cip ); + if ( cip_req_info ) { - gen_status = tvb_get_guint8( tvb, offset+2 ); - add_stat_size = tvb_get_guint8( tvb, offset+3 ) * 2; + if ( cip_req_info->pData == NULL ) + { + mr_mult_req_info = se_alloc(sizeof(mr_mult_req_info_t)); + mr_mult_req_info->service = SC_MULT_SERV_PACK; + mr_mult_req_info->num_services = num_services; + mr_mult_req_info->requests = se_alloc(sizeof(cip_req_info_t)*num_services); + cip_req_info->pData = mr_mult_req_info; + } + else + { + mr_mult_req_info = (mr_mult_req_info_t*)cip_req_info->pData; + if ( mr_mult_req_info && mr_mult_req_info->num_services != num_services ) + mr_mult_req_info = NULL; + } + } - /* If there is any command specific data create a sub-tree for it */ - if( ( item_length-4-add_stat_size ) != 0 ) + for( i=0; i < num_services; i++ ) + { + int serv_length; + tvbuff_t *next_tvb; + + serv_offset = tvb_get_letohs( tvb, offset+2+(i*2) ); + + if( i == (num_services-1) ) { - pi = proto_tree_add_text( item_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Command Specific Data" ); - cmd_data_tree = proto_item_add_subtree( pi, ett_mr_cmd_data ); + /* Last service to add */ + serv_length = tvb_length_remaining(tvb, offset)-serv_offset; + } + else + { + serv_length = tvb_get_letohs( tvb, offset+2+((i+1)*2) ) - serv_offset; + } - if( gen_status == CI_GRC_SUCCESS || gen_status == CI_GRC_SERVICE_ERROR ) - { - /* Success responses */ + mult_serv_item = proto_tree_add_text(tree, tvb, offset+serv_offset, serv_length, "Service Packet #%d", i+1 ); + mult_serv_tree = proto_item_add_subtree(mult_serv_item, ett_cip_mult_service_packet ); + proto_tree_add_item(mult_serv_tree, hf_cip_sc_mult_serv_pack_offset, tvb, offset+2+(i*2) , 2, ENC_LITTLE_ENDIAN); - if( ( tvb_get_guint8( tvb, offset ) & 0x7F ) == SC_MULT_SERV_PACK ) - { - /* Multiple Service Reply (Success)*/ + /* + ** We call our selves again to disect embedded packet + */ - /* Add number of replies */ - num_services = tvb_get_letohs( tvb, offset+4+add_stat_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size, 2, "Number of Replies: %d", num_services ); + col_append_str( pinfo->cinfo, COL_INFO, ", "); - /* Add replies */ - temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+add_stat_size+4, num_services*2, "Offsets: " ); + next_tvb = tvb_new_subset(tvb, offset+serv_offset, serv_length, serv_length); - cip_req_info = (cip_req_info_t*)p_get_proto_data( pinfo->fd, proto_cip ); - mr_mult_req_info = NULL; - if ( cip_req_info ) - { - mr_mult_req_info = (mr_mult_req_info_t*)cip_req_info->pData; - - if ( mr_mult_req_info - && ( mr_mult_req_info->service != SC_MULT_SERV_PACK - || mr_mult_req_info->num_services != num_services - ) - ) - mr_mult_req_info = NULL; - } + if ( mr_mult_req_info ) + { + mr_single_req_info = mr_mult_req_info->requests + i; + mr_single_req_info->bService = 0; + mr_single_req_info->dissector = NULL; + mr_single_req_info->IOILen = 0; + mr_single_req_info->pIOI = NULL; + mr_single_req_info->pData = NULL; + + dissect_cip_data(mult_serv_tree, next_tvb, 0, pinfo, mr_single_req_info ); + } + else + { + dissect_cip_data(mult_serv_tree, next_tvb, 0, pinfo, NULL ); + } + } - for( i=0; i < num_services; i++ ) - { - int serv_length; - tvbuff_t *next_tvb; +} - serv_offset = tvb_get_letohs( tvb, offset+6+add_stat_size+(i*2) ); +static int +dissect_cip_generic_service_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item *cmd_data_item; + int req_path_size, + offset = 0; + proto_tree *cmd_data_tree; + cip_simple_request_info_t req_data; + guint8 service = tvb_get_guint8( tvb, offset ) & 0x7F; - if( i == (num_services-1) ) - { - /* Last service to add */ - proto_item_append_text(temp_item, "%d", serv_offset ); - serv_length = item_length-add_stat_size-serv_offset-4; - } - else - { - proto_item_append_text(temp_item, "%d, ", serv_offset ); - serv_length = tvb_get_letohs( tvb, offset+6+add_stat_size+((i+1)*2) ) - serv_offset; - } + /* Add service to info column */ + col_append_str( pinfo->cinfo, COL_INFO, + val_to_str(service, cip_sc_vals , "Unknown Service (0x%02x)") ); - temp_item2 = proto_tree_add_text( cmd_data_tree, tvb, offset+serv_offset+4, serv_length, "Service Reply #%d", i+1 ); - temp_tree = proto_item_add_subtree( temp_item2, ett_mr_mult_ser ); + /* Create service tree */ + cmd_data_item = proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), + val_to_str(service, cip_sc_vals , "Unknown Service (0x%02x)")); + proto_item_append_text(cmd_data_item, " (Request)"); + cmd_data_tree = proto_item_add_subtree( cmd_data_item, ett_cmd_data ); - /* - ** We call our selves again to disect embedded packet - */ + req_path_size = tvb_get_guint8( tvb, offset+1); + offset += ((req_path_size*2)+2); + if (tvb_length_remaining(tvb, offset) <= 0) + return tvb_length(tvb); - col_append_str( pinfo->cinfo, COL_INFO, ", "); + switch(service) + { + case SC_GET_ATT_ALL: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_get_attribute_all_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_SET_ATT_ALL: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_set_attribute_all_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_GET_ATT_LIST: + dissect_cip_get_attribute_list_req(tvb, pinfo, cmd_data_tree, cmd_data_item, offset, &req_data); + break; + case SC_SET_ATT_LIST: + dissect_cip_set_attribute_list_req(tvb, pinfo, cmd_data_tree, cmd_data_item, offset, &req_data); + break; + case SC_RESET: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_reset_param, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(cmd_data_tree, hf_cip_sc_reset_data, tvb, offset+1, tvb_length_remaining(tvb, offset+1), ENC_LITTLE_ENDIAN); + break; + case SC_START: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_start_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_STOP: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_stop_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_CREATE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_create_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_DELETE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_delete_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_MULT_SERV_PACK: + dissect_cip_multiple_service_packet_req(tvb, pinfo, cmd_data_tree, cmd_data_item, offset, &req_data); + break; + case SC_APPLY_ATTRIBUTES: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_apply_attributes_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_GET_ATT_SINGLE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_get_attr_single_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_SET_ATT_SINGLE: + dissect_cip_set_attribute_single_req(tvb, pinfo, cmd_data_tree, cmd_data_item, offset, &req_data); + break; + case SC_FIND_NEXT_OBJ_INST: + proto_tree_add_item(cmd_data_tree, hf_cip_find_next_object_max_instance, tvb, offset, 1, ENC_LITTLE_ENDIAN); + break; + case SC_RESTOR: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_restore_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_SAVE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_save_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_NO_OP: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_noop_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_GET_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_get_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_SET_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_set_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_INSERT_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_insert_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_REMOVE_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_remove_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_GROUP_SYNC: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_group_sync_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + } - next_tvb = tvb_new_subset(tvb, offset+serv_offset+4, serv_length, serv_length); - if ( mr_mult_req_info ) - { - mr_single_req_info = mr_mult_req_info->requests + i; - dissect_cip_data( temp_tree, next_tvb, 0, pinfo, mr_single_req_info ); - } - else - { - dissect_cip_data( temp_tree, next_tvb, 0, pinfo, NULL ); - } - } - } /* End if Multiple service Packet */ - else if( ( tvb_get_guint8( tvb, offset ) & 0x7F ) == SC_GET_ATT_LIST ) - { - /* Get Attribute List Reply (Success)*/ + return tvb_length(tvb); +} + +static void +dissect_cip_get_attribute_list_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) +{ + int i, start_offset, att_count, + att_value, att_status; + guint att_size; + attribute_info_t* attr; + proto_item *att_list, *att_item; + proto_tree *att_tree, *att_list_tree; + + /* Get attribute list request */ + if (tvb_length_remaining(tvb, offset) < 2) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Malformed Get Attribute List service"); + return; + } + + /* Add number of attributes */ + att_count = tvb_get_letohs( tvb, offset); + proto_tree_add_item(tree, hf_cip_sc_get_attr_list_attr_count, tvb, offset, 2, ENC_LITTLE_ENDIAN); - int att_count; + /* Add Attribute List */ + att_list = proto_tree_add_text(tree, tvb, offset+2, att_count*4, "Attribute List" ); + att_list_tree = proto_item_add_subtree( att_list, ett_cip_get_attribute_list); + offset += 2; + start_offset = offset; - /* Add Attribute Count */ - att_count = tvb_get_letohs( tvb, offset+4+add_stat_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size, 2, "Attribute Count: %d", att_count ); + for( i=0; i < att_count; i++ ) + { + att_value = tvb_get_letohs( tvb, offset); + att_item = proto_tree_add_item(att_list_tree, hf_cip_sc_get_attr_list_attr_item, tvb, offset, 2, ENC_LITTLE_ENDIAN); + att_tree = proto_item_add_subtree( att_item, ett_cip_get_attribute_list_item); - /* Add the data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+6+add_stat_size, item_length-6-add_stat_size, "Data: " ); + att_status = tvb_get_letohs( tvb, offset+2); + proto_tree_add_item(att_tree, hf_cip_sc_get_attr_list_attr_status, tvb, offset+2, 2, ENC_LITTLE_ENDIAN); - } /* End if GetAttrList */ - else - { - /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); - } /* end of check service code */ + attr = cip_get_attribute(req_data->iClass, req_data->iInstance, att_value); + if (attr != NULL) + proto_item_append_text(att_item, " (%s)", attr->text); + offset += 4; + if (att_status == 0) + { + if (attr != NULL) + { + /* provide attribute data */ + att_size = dissect_cip_attribute(pinfo, att_tree, att_item, tvb, attr, offset, tvb_length_remaining(tvb, offset)); + offset += att_size; + proto_item_set_len(att_item, att_size+4); } else { - /* Error responses */ + /* Can't find the attribute, treat the rest of the response as raw data */ + proto_tree_add_item(att_tree, hf_cip_sc_get_attr_list_attr_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + } + } - /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); + if ((tvb_length_remaining(tvb, offset) < 4) && (i < att_count-1)) + { + expert_add_info_format(pinfo, att_list, PI_MALFORMED, PI_ERROR, "Get Attribute List attribute list count greater than packet size"); + break; + } + } - } /* end of if-else( CI_CRC_SUCCESS ) */ + proto_item_set_len(att_list, offset-start_offset ); +} - } /* End of if command-specific data present */ +static void +dissect_cip_set_attribute_list_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) +{ + int i, start_offset, att_count, + att_value, att_status; + attribute_info_t* attr; + proto_item *att_list, *att_item; + proto_tree *att_tree, *att_list_tree; + + /* Get attribute list request */ + if (tvb_length_remaining(tvb, offset) < 2) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Malformed Set Attribute List service"); + return; + } - } /* End of if reply */ - else + /* Add number of attributes */ + att_count = tvb_get_letohs( tvb, offset); + proto_tree_add_item(tree, hf_cip_sc_set_attr_list_attr_count, tvb, offset, 2, ENC_LITTLE_ENDIAN); + + /* Add Attribute List */ + att_list = proto_tree_add_text(tree, tvb, offset+2, att_count*4, "Attribute List" ); + att_list_tree = proto_item_add_subtree( att_list, ett_cip_get_attribute_list); + offset += 2; + start_offset = offset; + + for( i=0; i < att_count; i++ ) { - /* Request message */ + att_value = tvb_get_letohs( tvb, offset); + att_item = proto_tree_add_item(att_list_tree, hf_cip_sc_set_attr_list_attr_item, tvb, offset, 2, ENC_LITTLE_ENDIAN); + att_tree = proto_item_add_subtree( att_item, ett_cip_set_attribute_list_item); - /* Add service to info column */ - col_append_str( pinfo->cinfo, COL_INFO, - val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x7F ), - cip_sc_vals, "Unknown Service (0x%02x)") ); + att_status = tvb_get_letohs( tvb, offset+2); + proto_tree_add_item(att_tree, hf_cip_sc_set_attr_list_attr_status, tvb, offset+2, 2, ENC_LITTLE_ENDIAN); - /* Add path size to tree */ - req_path_size = tvb_get_guint8( tvb, offset+1 )*2; + attr = cip_get_attribute(req_data->iClass, req_data->iInstance, att_value); + if (attr != NULL) + proto_item_append_text(att_item, " (%s)", attr->text); - /* If there is any command specific data creat a sub-tree for it */ - if( (item_length-req_path_size-2) != 0 ) + offset += 4; + if ((tvb_length_remaining(tvb, offset) < 4) && (i < att_count-1)) { + expert_add_info_format(pinfo, att_list, PI_MALFORMED, PI_ERROR, "Set Attribute List attribute list count greater than packet size"); + break; + } + } - pi = proto_tree_add_text( item_tree, tvb, offset+2+req_path_size, item_length-req_path_size-2, "Command Specific Data" ); - cmd_data_tree = proto_item_add_subtree( pi, ett_mr_cmd_data ); + proto_item_set_len(att_list, offset-start_offset ); +} - /* Check what service code that recived */ +static void +dissect_cip_get_attribute_single_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) +{ + attribute_info_t* attr; - if( tvb_get_guint8( tvb, offset ) == SC_MULT_SERV_PACK ) - { - /* Multiple service packet */ + attr = cip_get_attribute(req_data->iClass, req_data->iInstance, req_data->iAttribute); + if (attr != NULL) + { + proto_item_append_text(item, " (%s)", attr->text); + dissect_cip_attribute(pinfo, tree, item, tvb, attr, offset, tvb_length_remaining(tvb, offset)); + } + else + { + /* Can't find the attribute, treat the rest of the response as raw data */ + proto_tree_add_item(tree, hf_cip_sc_get_attr_single_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + } +} - /* Add number of services */ - num_services = tvb_get_letohs( tvb, offset+2+req_path_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Number of Services: %d", num_services ); +static void +dissect_cip_multiple_service_packet_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, + int offset, cip_simple_request_info_t* req_data) +{ + proto_item *mult_serv_item; + proto_tree *mult_serv_tree; + int i, num_services, serv_offset; + cip_req_info_t *cip_req_info, *mr_single_req_info; + mr_mult_req_info_t *mr_mult_req_info = NULL; - /* Add services */ - temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, num_services*2, "Offsets: " ); + if (tvb_length_remaining(tvb, offset) < 2) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Multiple Service Packet service missing Number of Services field"); + return; + } - cip_req_info = (cip_req_info_t*)p_get_proto_data( pinfo->fd, proto_cip ); + num_services = tvb_get_letohs( tvb, offset); + proto_tree_add_item(tree, hf_cip_sc_mult_serv_pack_num_replies, tvb, offset, 2, ENC_LITTLE_ENDIAN); - mr_mult_req_info = NULL; - if ( cip_req_info ) - { - if ( cip_req_info->pData == NULL ) - { - mr_mult_req_info = se_alloc(sizeof(mr_mult_req_info_t)); - mr_mult_req_info->service = SC_MULT_SERV_PACK; - mr_mult_req_info->num_services = num_services; - mr_mult_req_info->requests = se_alloc(sizeof(cip_req_info_t)*num_services); - cip_req_info->pData = mr_mult_req_info; - } - else - { - mr_mult_req_info = (mr_mult_req_info_t*)cip_req_info->pData; - if ( mr_mult_req_info && mr_mult_req_info->num_services != num_services ) - mr_mult_req_info = NULL; - } - } - for( i=0; i < num_services; i++ ) - { - int serv_length; - tvbuff_t *next_tvb; + if (tvb_length_remaining(tvb, offset+((num_services+1)*2)) <= 0) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Multiple Service Packet service too many response offsets for packet size"); + return; + } - serv_offset = tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ); + cip_req_info = (cip_req_info_t*)p_get_proto_data( pinfo->fd, proto_cip ); + if ( cip_req_info ) + { + mr_mult_req_info = (mr_mult_req_info_t*)cip_req_info->pData; - if( i == (num_services-1) ) - { - /* Last service to add */ - serv_length = item_length-2-req_path_size-serv_offset; - proto_item_append_text(temp_item, "%d", serv_offset ); - } - else - { - serv_length = tvb_get_letohs( tvb, offset+4+req_path_size+((i+1)*2) ) - serv_offset; - proto_item_append_text(temp_item, "%d, ", serv_offset ); - } + if ( mr_mult_req_info + && ( mr_mult_req_info->service != SC_MULT_SERV_PACK + || mr_mult_req_info->num_services != num_services + ) + ) + mr_mult_req_info = NULL; + } - temp_item2 = proto_tree_add_text( cmd_data_tree, tvb, offset+serv_offset+6, serv_length, "Service Packet #%d", i+1 ); - temp_tree = proto_item_add_subtree( temp_item2, ett_mr_mult_ser ); + /* Add number of replies */ + for( i=0; i < num_services; i++ ) + { + int serv_length; + tvbuff_t *next_tvb; - /* - ** We call our selves again to disect embedded packet - */ + serv_offset = tvb_get_letohs( tvb, offset+2+(i*2) ); - col_append_str( pinfo->cinfo, COL_INFO, ", "); + if (tvb_length_remaining(tvb, serv_offset) <= 0) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Multiple Service Packet service invalid offset"); + continue; + } - next_tvb = tvb_new_subset(tvb, offset+serv_offset+6, serv_length, serv_length); + if( i == (num_services-1) ) + { + /* Last service to add */ + serv_length = tvb_length_remaining(tvb, offset)-serv_offset; + } + else + { + serv_length = tvb_get_letohs( tvb, offset+2+((i+1)*2) ) - serv_offset; + } - if ( mr_mult_req_info ) - { - mr_single_req_info = mr_mult_req_info->requests + i; - mr_single_req_info->bService = 0; - mr_single_req_info->dissector = NULL; - mr_single_req_info->IOILen = 0; - mr_single_req_info->pIOI = NULL; - mr_single_req_info->pData = NULL; - - dissect_cip_data( temp_tree, next_tvb, 0, pinfo, mr_single_req_info ); - } - else - { - dissect_cip_data( temp_tree, next_tvb, 0, pinfo, NULL ); - } - } - } /* End if Multiple service Packet */ - else if( tvb_get_guint8( tvb, offset ) == SC_GET_ATT_LIST ) - { - /* Get attribute list request */ + mult_serv_item = proto_tree_add_text( tree, tvb, offset+serv_offset, serv_length, "Service Reply #%d", i+1 ); + mult_serv_tree = proto_item_add_subtree( mult_serv_item, ett_cip_mult_service_packet ); + proto_tree_add_item(mult_serv_tree, hf_cip_sc_mult_serv_pack_offset, tvb, offset+2+(i*2) , 2, ENC_LITTLE_ENDIAN); - int att_count; + /* + ** We call our selves again to disect embedded packet + */ - /* Add number of services */ - att_count = tvb_get_letohs( tvb, offset+2+req_path_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Attribute Count: %d", att_count ); + col_append_str( pinfo->cinfo, COL_INFO, ", "); - /* Add Attribute List */ - temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, att_count*2, "Attribute List: " ); + next_tvb = tvb_new_subset(tvb, offset+serv_offset, serv_length, serv_length); + if ( mr_mult_req_info ) + { + mr_single_req_info = mr_mult_req_info->requests + i; + dissect_cip_data( mult_serv_tree, next_tvb, 0, pinfo, mr_single_req_info ); + } + else + { + dissect_cip_data( mult_serv_tree, next_tvb, 0, pinfo, NULL ); + } + } - for( i=0; i < att_count; i++ ) - { - if( i == (att_count-1) ) - proto_item_append_text(temp_item, "%d",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - else - proto_item_append_text(temp_item, "%d, ",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - } +} - } /* End of Get attribute list request */ - else - { - /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+2+req_path_size, item_length-req_path_size-2, "Data: " ); - } /* End of check service code */ +static void +dissect_cip_find_next_object_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, int offset) +{ + guint8 i, num_instances; - } /* End of if command-specific data present */ + if (tvb_length_remaining(tvb, offset) < 1) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Find Next Object service missing Number of List Members field"); + return; + } - } /* End of if-else( request ) */ + num_instances = tvb_get_guint8( tvb, offset); + proto_tree_add_item(tree, hf_cip_find_next_object_num_instances, tvb, offset, 1, ENC_LITTLE_ENDIAN); + offset += 1; + for (i = 0; i < num_instances; i++) + { + proto_tree_add_item(tree, hf_cip_find_next_object_instance_item, tvb, offset, 2, ENC_LITTLE_ENDIAN); + offset += 2; -} /* End of dissect_cip_mr() */ + if ((tvb_length_remaining(tvb, offset) < 2) && (i < num_instances-1)) + { + expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "Find Next Object instance list count greater than packet size"); + break; + } + } +} static int -dissect_cip_class_mr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +dissect_cip_generic_service_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - proto_item *ti; - proto_tree *class_tree; + proto_item *cmd_data_item; + proto_tree *cmd_data_tree; + cip_req_info_t* preq_info; + cip_simple_request_info_t req_data; + int offset = 0, + item_length = tvb_length(tvb); + guint8 service = tvb_get_guint8( tvb, offset ) & 0x7F, + add_stat_size = tvb_get_guint8( tvb, offset+3 ) * 2; - if( tree ) + /* If there is any command specific data create a sub-tree for it */ + if( (item_length-4-add_stat_size ) != 0 ) { - /* Create display subtree for the protocol */ - ti = proto_tree_add_item(tree, proto_cip_class_mr, tvb, 0, -1, ENC_BIG_ENDIAN); - class_tree = proto_item_add_subtree( ti, ett_cip_class_mr ); + cmd_data_item = proto_tree_add_text(tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, + val_to_str(service, cip_sc_vals , "Unknown Service (0x%02x)")); + proto_item_append_text(cmd_data_item, " (Response)"); + cmd_data_tree = proto_item_add_subtree( cmd_data_item, ett_cmd_data ); + } + else + { +/* PROTO_ITEM_SET_HIDDEN( ti ); */ + return tvb_length(tvb); + } - dissect_cip_mr_data( class_tree, tvb, 0, tvb_length(tvb), pinfo ); + preq_info = (cip_req_info_t*)p_get_proto_data(pinfo->fd, proto_cip); + if ((preq_info != NULL) && + (preq_info->ciaData != NULL)) + { + memcpy(&req_data, preq_info->ciaData, sizeof(cip_simple_request_info_t)); + } + else + { + req_data.iClass = (guint32)-1; + req_data.iInstance = (guint32)-1; + req_data.iAttribute = (guint32)-1; + req_data.iMember = (guint32)-1; + } + + switch(service) + { + case SC_GET_ATT_ALL: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_get_attribute_all_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_SET_ATT_ALL: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_set_attribute_all_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_GET_ATT_LIST: + dissect_cip_get_attribute_list_rsp(tvb, pinfo, cmd_data_tree, cmd_data_item, offset+4+add_stat_size, &req_data); + break; + case SC_SET_ATT_LIST: + dissect_cip_set_attribute_list_rsp(tvb, pinfo, cmd_data_tree, cmd_data_item, offset+4+add_stat_size, &req_data); + break; + case SC_RESET: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_reset_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_START: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_start_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_STOP: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_stop_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_CREATE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_create_instance, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + proto_tree_add_item(cmd_data_tree, hf_cip_sc_create_data, tvb, offset+4+add_stat_size+2, tvb_length_remaining(tvb, offset+4+add_stat_size+2), ENC_LITTLE_ENDIAN); + break; + case SC_DELETE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_delete_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_MULT_SERV_PACK: + dissect_cip_multiple_service_packet_rsp(tvb, pinfo, cmd_data_tree, cmd_data_item, offset+4+add_stat_size, &req_data); + break; + case SC_APPLY_ATTRIBUTES: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_apply_attributes_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_GET_ATT_SINGLE: + dissect_cip_get_attribute_single_rsp(tvb, pinfo, cmd_data_tree, cmd_data_item, offset+4+add_stat_size, &req_data); + break; + case SC_SET_ATT_SINGLE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_set_attr_single_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_FIND_NEXT_OBJ_INST: + dissect_cip_find_next_object_rsp(tvb, pinfo, cmd_data_tree, cmd_data_item, offset+4+add_stat_size); + break; + case SC_RESTOR: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_restore_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_SAVE: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_save_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_NO_OP: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_noop_data, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + break; + case SC_GET_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_get_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_SET_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_set_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_INSERT_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_insert_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_REMOVE_MEMBER: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_remove_member_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_LITTLE_ENDIAN); + break; + case SC_GROUP_SYNC: + proto_tree_add_item(cmd_data_tree, hf_cip_sc_group_sync_is_sync, tvb, offset+4+add_stat_size, tvb_length_remaining(tvb, offset+4+add_stat_size), ENC_LITTLE_ENDIAN); + proto_tree_add_item(cmd_data_tree, hf_cip_sc_group_sync_data, tvb, offset+4+add_stat_size+1, tvb_length_remaining(tvb, offset+4+add_stat_size+1), ENC_LITTLE_ENDIAN); + break; } return tvb_length(tvb); @@ -2160,155 +3724,104 @@ dissect_cip_class_mr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) static void dissect_cip_cm_timeout(proto_tree *cmd_tree, tvbuff_t *tvb, int offset) { - unsigned char temp_byte; - int temp_data; + guint8 tick, timeout_tick; + int timeout; /* Display the priority/tick timer */ - temp_byte = tvb_get_guint8( tvb, offset); - proto_tree_add_text( cmd_tree, tvb, offset, 1, "Priority/Time_tick: 0x%02X", temp_byte ); + tick = tvb_get_guint8( tvb, offset) & 0x0F; + proto_tree_add_item( cmd_tree, hf_cip_cm_priority, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item( cmd_tree, hf_cip_cm_tick_time, tvb, offset, 1, ENC_LITTLE_ENDIAN); /* Display the time-out ticks */ - temp_data = tvb_get_guint8( tvb, offset+1 ); - proto_tree_add_text( cmd_tree, tvb, offset+1, 1, "Time-out_ticks: %d", temp_data ); + timeout_tick = tvb_get_guint8( tvb, offset+1 ); + proto_tree_add_item( cmd_tree, hf_cip_cm_timeout_tick, tvb, offset+1, 1, ENC_LITTLE_ENDIAN); /* Display the actual time out */ - temp_data = ( 1 << ( temp_byte & 0x0F ) ) * temp_data; - proto_tree_add_text( cmd_tree, tvb, offset, 2, "Actual Time Out: %dms", temp_data ); + timeout = ( 1 << tick ) * timeout_tick; + proto_tree_add_uint_format_value(cmd_tree, hf_cip_cm_timeout, tvb, offset, 2, timeout, "%dms", timeout); } static void -dissect_cip_cm_fwd_open_req(proto_tree *cmd_tree, tvbuff_t *tvb, int offset, gboolean large_fwd_open) +dissect_cip_cm_fwd_open_req(proto_tree *cmd_tree, tvbuff_t *tvb, int offset, gboolean large_fwd_open, packet_info *pinfo) { - proto_item *pi, *ncppi; - proto_tree *ncp_tree; - int conn_path_size, temp_data, net_param_offset = 0; + proto_item *pi; + int conn_path_size, rpi, net_param_offset = 0; - /* Display timeout fields */ dissect_cip_cm_timeout(cmd_tree, tvb, offset); - - /* Display originator to taget connection ID */ proto_tree_add_item( cmd_tree, hf_cip_cm_ot_connid, tvb, offset+2, 4, ENC_LITTLE_ENDIAN); - - /* Display target to originator connection ID */ proto_tree_add_item( cmd_tree, hf_cip_cm_to_connid, tvb, offset+6, 4, ENC_LITTLE_ENDIAN); - - /* Display connection serial number */ proto_tree_add_item( cmd_tree, hf_cip_cm_conn_serial_num, tvb, offset+10, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator vendor id */ - proto_tree_add_item( cmd_tree, hf_cip_vendor, tvb, offset+12, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator serial number */ + proto_tree_add_item( cmd_tree, hf_cip_cm_vendor, tvb, offset+12, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item( cmd_tree, hf_cip_cm_orig_serial_num, tvb, offset+14, 4, ENC_LITTLE_ENDIAN); - - /* Display the timeout multiplier */ - temp_data = tvb_get_guint8( tvb, offset+18 ); - proto_tree_add_text( cmd_tree, tvb, offset+18, 1, "Connection Timeout Multiplier: %s (%d)", val_to_str( temp_data, cip_con_time_mult_vals , "Reserved" ), temp_data ); - - /* Put out an indicator for the reserved bytes */ - proto_tree_add_text( cmd_tree, tvb, offset+19, 3, "Reserved Data" ); + proto_tree_add_item( cmd_tree, hf_cip_cm_timeout_multiplier, tvb, offset+18, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item( cmd_tree, hf_cip_reserved24, tvb, offset+19, 3, ENC_LITTLE_ENDIAN); /* Display originator to target requested packet interval */ - temp_data = tvb_get_letohl( tvb, offset+22 ); - proto_tree_add_text( cmd_tree, tvb, offset+22, 4, "O->T RPI: %dms (0x%08X)", temp_data / 1000, temp_data ); + rpi = tvb_get_letohl( tvb, offset+22 ); + proto_tree_add_uint_format_value(cmd_tree, hf_cip_cm_ot_rpi, tvb, offset+22, 4, rpi, "%dms (0x%08X)", rpi / 1000, rpi); - /* Display originator to target network connection parameters, in a tree */ + /* Display originator to target network connection parameters as a tree */ if (large_fwd_open) { - temp_data = tvb_get_letohl( tvb, offset+26 ); - ncppi = proto_tree_add_text(cmd_tree, tvb, offset+26, 4, "O->T Network Connection Parameters: 0x%08X", temp_data ); - ncp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); - - /* Add the data to the tree */ - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_own, tvb, offset+26, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_typ, tvb, offset+26, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_prio, tvb, offset+26, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_fixed_var, tvb, offset+26, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_con_size, tvb, offset+26, 4, TRUE ); + dissect_net_param32(tvb, offset+26, cmd_tree, + hf_cip_cm_ot_net_params32, hf_cip_cm_lfwo_own, hf_cip_cm_lfwo_typ, + hf_cip_cm_lfwo_prio, hf_cip_cm_lfwo_fixed_var, hf_cip_cm_lfwo_con_size, ett_cm_ncp); net_param_offset = 4; } else { - temp_data = tvb_get_letohs( tvb, offset+26 ); - ncppi = proto_tree_add_text(cmd_tree, tvb, offset+26, 2, "O->T Network Connection Parameters: 0x%04X", temp_data ); - ncp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); - - /* Add the data to the tree */ - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_own, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_typ, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_prio, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_fixed_var, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_con_size, tvb, offset+26, 2, TRUE ); + dissect_net_param16(tvb, offset+26, cmd_tree, + hf_cip_cm_ot_net_params16, hf_cip_cm_fwo_own, hf_cip_cm_fwo_typ, + hf_cip_cm_fwo_prio, hf_cip_cm_fwo_fixed_var, hf_cip_cm_fwo_con_size, ett_cm_ncp); + net_param_offset = 2; } /* Display target to originator requested packet interval */ - temp_data = tvb_get_letohl( tvb, offset+26+net_param_offset ); - proto_tree_add_text( cmd_tree, tvb, offset+26+net_param_offset, 4, "T->O RPI: %dms (0x%08X)", temp_data / 1000, temp_data ); + rpi = tvb_get_letohl( tvb, offset+26+net_param_offset ); + proto_tree_add_uint_format_value(cmd_tree, hf_cip_cm_to_rpi, tvb, offset+26+net_param_offset, 4, rpi, "%dms (0x%08X)", rpi / 1000, rpi); - /* Display target to originator network connection parameters, in a tree */ + /* Display target to originator network connection parameters as a tree */ if (large_fwd_open) { - temp_data = tvb_get_letohl( tvb, offset+26+net_param_offset+4 ); - ncppi = proto_tree_add_text(cmd_tree, tvb, offset+26+net_param_offset+4, 4, "T->O Network Connection Parameters: 0x%04X", temp_data ); - ncp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); - - /* Add the data to the tree */ - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_own, tvb, offset+26+net_param_offset+4, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_typ, tvb, offset+26+net_param_offset+4, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_prio, tvb, offset+26+net_param_offset+4, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_fixed_var, tvb, offset+26+net_param_offset+4, 4, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_lfwo_con_size, tvb, offset+26+net_param_offset+4, 4, TRUE ); + dissect_net_param32(tvb, offset+26+net_param_offset+4, cmd_tree, + hf_cip_cm_to_net_params32, hf_cip_cm_lfwo_own, hf_cip_cm_lfwo_typ, + hf_cip_cm_lfwo_prio, hf_cip_cm_lfwo_fixed_var, hf_cip_cm_lfwo_con_size, ett_cm_ncp); net_param_offset += 4; } else { - temp_data = tvb_get_letohs( tvb, offset+26+net_param_offset+4 ); - ncppi = proto_tree_add_text(cmd_tree, tvb, offset+26+net_param_offset+4, 2, "T->O Network Connection Parameters: 0x%04X", temp_data ); - ncp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); - - /* Add the data to the tree */ - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_own, tvb, offset+26+net_param_offset+4, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_typ, tvb, offset+26+net_param_offset+4, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_prio, tvb, offset+26+net_param_offset+4, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_fixed_var, tvb, offset+26+net_param_offset+4, 2, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_con_size, tvb, offset+26+net_param_offset+4, 2, TRUE ); + dissect_net_param16(tvb, offset+26+net_param_offset+4, cmd_tree, + hf_cip_cm_to_net_params16, hf_cip_cm_fwo_own, hf_cip_cm_fwo_typ, + hf_cip_cm_fwo_prio, hf_cip_cm_fwo_fixed_var, hf_cip_cm_fwo_con_size, ett_cm_ncp); + net_param_offset += 2; } - /* Transport type/trigger in tree */ - temp_data = tvb_get_guint8( tvb, offset+26+net_param_offset+4 ); - - ncppi = proto_tree_add_text(cmd_tree, tvb, offset+26+net_param_offset+4, 1, "Transport Type/Trigger: 0x%02X", temp_data ); - ncp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); - - /* Add the data to the tree */ - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_dir, tvb, offset+26+net_param_offset+4, 1, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_trigg, tvb, offset+26+net_param_offset+4, 1, TRUE ); - proto_tree_add_item(ncp_tree, hf_cip_cm_fwo_class, tvb, offset+26+net_param_offset+4, 1, TRUE ); + dissect_transport_type_trigger(tvb, offset+26+net_param_offset+4, cmd_tree, hf_cip_cm_transport_type_trigger, + hf_cip_cm_fwo_dir, hf_cip_cm_fwo_trigg, hf_cip_cm_fwo_class, ett_cm_ttt); /* Add path size */ conn_path_size = tvb_get_guint8( tvb, offset+26+net_param_offset+5 )*2; - proto_tree_add_text( cmd_tree, tvb, offset+26+net_param_offset+5, 1, "Connection Path Size: %d (words)", conn_path_size / 2 ); + proto_tree_add_uint_format_value(cmd_tree, hf_cip_cm_conn_path_size, tvb, offset+26+net_param_offset+5, 1, conn_path_size/2, "%d (words)", conn_path_size/2); /* Add the epath */ pi = proto_tree_add_text(cmd_tree, tvb, offset+26+net_param_offset+6, conn_path_size, "Connection Path: "); - dissect_epath( tvb, pi, offset+26+net_param_offset+6, conn_path_size, FALSE ); + dissect_epath( tvb, pinfo, pi, offset+26+net_param_offset+6, conn_path_size, FALSE, NULL); } static void dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_length, packet_info *pinfo ) { - proto_item *pi, *rrsc_item, *ar_item, *temp_item; - proto_tree *temp_tree, *rrsc_tree, *cmd_data_tree; + proto_item *pi, *rrsc_item, *status_item, *add_status_item, *temp_item; + proto_tree *rrsc_tree, *cmd_data_tree, *status_tree, *add_status_tree, *temp_tree; int req_path_size, conn_path_size, temp_data; unsigned char service, gen_status, add_stat_size; unsigned short add_status; - unsigned char temp_byte, route_path_size; - unsigned char app_rep_size, i; - int msg_req_siz; + unsigned char app_rep_size, route_path_size; + int i, msg_req_siz; cip_req_info_t *preq_info; cip_req_info_t *pembedded_req_info; @@ -2329,9 +3842,12 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ add_status = 0; if( gen_status == 0 /* success response ) */ || ( ( service & 0x7F ) != SC_CM_UNCON_SEND ) - || !( ( gen_status == 0x01 && ( add_status == 0x0204 || add_status == 0x0311 || add_status == 0x0312 || add_status == 0x0315 ) ) - || gen_status == 0x02 - || gen_status == 0x04 + || !( ( gen_status == CI_GRC_FAILURE && (add_status == CM_ES_UNCONNECTED_REQUEST_TIMED_OUT || + add_status == CM_ES_PORT_NOT_AVAILABLE || + add_status == CM_ES_LINK_ADDRESS_NOT_VALID || + add_status == CM_ES_INVALID_SEGMENT_IN_CONN_PATH) ) + || gen_status == CI_GRC_NO_RESOURCE + || gen_status == CI_GRC_BAD_PATH ) ) { @@ -2367,7 +3883,7 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ rrsc_tree = proto_item_add_subtree( rrsc_item, ett_cm_rrsc ); /* Add Request/Response */ - proto_tree_add_item( rrsc_tree, hf_cip_rr, tvb, offset, 1, TRUE ); + proto_tree_add_item( rrsc_tree, hf_cip_reqrsp, tvb, offset, 1, ENC_LITTLE_ENDIAN ); /* watch for service collisions */ proto_item_append_text( rrsc_item, "%s (%s)", @@ -2377,7 +3893,7 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ cip_sc_rr, "") ); /* Add Service code */ - proto_tree_add_item(rrsc_tree, hf_cip_sc, tvb, offset, 1, TRUE ); + proto_tree_add_item(rrsc_tree, hf_cip_cm_sc, tvb, offset, 1, ENC_LITTLE_ENDIAN ); if( service & 0x80 ) { @@ -2385,6 +3901,89 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ gen_status = tvb_get_guint8( tvb, offset+2 ); add_stat_size = tvb_get_guint8( tvb, offset+3 ) * 2; + if (gen_status == CI_GRC_FAILURE) + { + /* Dissect object specific error codes */ + status_item = proto_tree_add_text(item_tree, tvb, offset+2, 1, "Status: " ); + status_tree = proto_item_add_subtree( status_item, ett_status_item ); + + /* Add general status */ + proto_tree_add_item(status_tree, hf_cip_cm_genstat, tvb, offset+2, 1, ENC_LITTLE_ENDIAN ); + proto_item_append_text( status_item, "%s", val_to_str_ext( gen_status, + &cip_gs_vals_ext , "Unknown Response (%x)") ); + + /* Add additional status size */ + add_stat_size = tvb_get_guint8( tvb, offset+3 ); + proto_tree_add_uint_format_value(status_tree, hf_cip_cm_addstat_size, + tvb, offset+3, 1, add_stat_size, "%d (words)", add_stat_size); + + if( add_stat_size ) + { + add_status = tvb_get_letohs( tvb, offset + 4 ); + proto_tree_add_item(status_tree, hf_cip_cm_ext_status, tvb, offset+4, 2, ENC_LITTLE_ENDIAN ); + proto_item_append_text(status_item, ", Extended: %s", val_to_str_ext(add_status, &cip_cm_ext_st_vals_ext, "Reserved (0x%04x)")); + + switch(add_status) + { + case CM_ES_RPI_NOT_ACCEPTABLE: + if (add_stat_size < 6) + { + expert_add_info_format(pinfo, status_item, PI_MALFORMED, PI_WARN, "RPI not acceptable - missing extended data"); + } + else + { + proto_tree_add_item(status_tree, hf_cip_cm_ext112_ot_rpi_type, tvb, offset+6, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(status_tree, hf_cip_cm_ext112_to_rpi_type, tvb, offset+7, 1, ENC_LITTLE_ENDIAN ); + temp_data = tvb_get_letohl( tvb, offset+8); + proto_tree_add_uint_format_value(status_tree, hf_cip_cm_ext112_ot_rpi, tvb, offset+8, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); + temp_data = tvb_get_letohl( tvb, offset+12); + proto_tree_add_uint_format_value(status_tree, hf_cip_cm_ext112_to_rpi, tvb, offset+12, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); + } + break; + case CM_ES_INVALID_CONFIGURATION_SIZE: + if (add_stat_size < 2) + { + expert_add_info_format(pinfo, status_item, PI_MALFORMED, PI_WARN, "Invalid configuration size - missing size field"); + } + else + { + proto_tree_add_item(status_tree, hf_cip_cm_ext126_size, tvb, offset+6, 2, ENC_LITTLE_ENDIAN ); + } + break; + case CM_ES_INVALID_OT_SIZE: + if (add_stat_size < 2) + { + expert_add_info_format(pinfo, status_item, PI_MALFORMED, PI_WARN, "Invalid O->T size - missing size field"); + } + else + { + proto_tree_add_item(status_tree, hf_cip_cm_ext127_size, tvb, offset+6, 2, ENC_LITTLE_ENDIAN ); + } + break; + case CM_ES_INVALID_TO_SIZE: + if (add_stat_size < 2) + { + expert_add_info_format(pinfo, status_item, PI_MALFORMED, PI_WARN, "Invalid T->O size - missing size field"); + } + else + { + proto_tree_add_item(status_tree, hf_cip_cm_ext128_size, tvb, offset+6, 2, ENC_LITTLE_ENDIAN ); + } + break; + default: + /* Add additional status */ + if (add_stat_size > 1) + { + add_status_item = proto_tree_add_text( status_tree, tvb, offset+4, add_stat_size*2, "Additional Status" ); + add_status_tree = proto_item_add_subtree( add_status_item, ett_cm_add_status_item ); + + for( i=0; i < add_stat_size-1; i ++ ) + proto_tree_add_item(add_status_tree, hf_cip_cm_add_status, tvb, offset+4+(i*2), 2, ENC_LITTLE_ENDIAN ); + } + } + } + } + /* If there is any command specific data create a sub-tree for it */ if( ( item_length-4-add_stat_size ) != 0 ) { @@ -2420,7 +4019,7 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ /* Display the originator vendor id */ VendorID = tvb_get_letohs( tvb, offset+4+add_stat_size+10 ); - proto_tree_add_item( cmd_data_tree, hf_cip_vendor, tvb, offset+4+add_stat_size+10, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+4+add_stat_size+10, 2, ENC_LITTLE_ENDIAN); /* Display the originator serial number */ DeviceSerialNumber = tvb_get_letohl( tvb, offset+4+add_stat_size+12 ); @@ -2428,31 +4027,19 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ /* Display originator to target actual packet interval */ temp_data = tvb_get_letohl( tvb, offset+4+add_stat_size+16 ); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+16, 4, "O->T API: %dms (0x%08X)", temp_data / 1000, temp_data ); + proto_tree_add_uint_format_value(cmd_data_tree, hf_cip_cm_ot_api, tvb, offset+4+add_stat_size+16, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); /* Display originator to target actual packet interval */ temp_data = tvb_get_letohl( tvb, offset+4+add_stat_size+20 ); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+20, 4, "T->O API: %dms (0x%08X)", temp_data / 1000, temp_data ); + proto_tree_add_uint_format_value(cmd_data_tree, hf_cip_cm_to_api, tvb, offset+4+add_stat_size+20, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); /* Display the application reply size */ app_rep_size = tvb_get_guint8( tvb, offset+4+add_stat_size+24 ) * 2; - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+24, 1, "Application Reply Size: %d (words)", app_rep_size / 2 ); + proto_tree_add_uint_format_value(cmd_data_tree, hf_cip_cm_app_reply_size, tvb, offset+4+add_stat_size+24, 1, app_rep_size / 2, "%d (words)", app_rep_size / 2); - /* Display the Reserved byte */ - proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+4+add_stat_size+25, 1, TRUE ); - - if( app_rep_size != 0 ) - { - /* Display application Reply data */ - ar_item = proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+26, app_rep_size, "Application Reply:" ); - - for( i=0; i < app_rep_size; i++ ) - { - temp_byte = tvb_get_guint8( tvb, offset+4+add_stat_size+26+i ); - proto_item_append_text(ar_item, " 0x%02X", temp_byte ); - } - - } /* End of if reply data */ + proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+4+add_stat_size+25, 1, ENC_LITTLE_ENDIAN ); + if (app_rep_size > 0) + proto_tree_add_item(cmd_data_tree, hf_cip_cm_app_reply_data, tvb, offset+4+add_stat_size+26, app_rep_size, ENC_LITTLE_ENDIAN ); enip_open_cip_connection( pinfo, ConnSerialNumber, VendorID, DeviceSerialNumber, O2TConnID, T2OConnID ); @@ -2471,7 +4058,7 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ /* Display the originator vendor id */ VendorID = tvb_get_letohs( tvb, offset+4+add_stat_size+2 ); - proto_tree_add_item( cmd_data_tree, hf_cip_vendor, tvb, offset+4+add_stat_size+2, 2, ENC_LITTLE_ENDIAN); + proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+4+add_stat_size+2, 2, ENC_LITTLE_ENDIAN); /* Display the originator serial number */ DeviceSerialNumber = tvb_get_letohl( tvb, offset+4+add_stat_size+4 ); @@ -2479,23 +4066,11 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ /* Display the application reply size */ app_rep_size = tvb_get_guint8( tvb, offset+4+add_stat_size+8 ) * 2; - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+8, 1, "Application Reply Size: %d (words)", app_rep_size / 2 ); + proto_tree_add_uint_format_value(cmd_data_tree, hf_cip_cm_app_reply_size, tvb, offset+4+add_stat_size+8, 1, app_rep_size / 2, "%d (words)", app_rep_size / 2); - /* Display the Reserved byte */ - proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+4+add_stat_size+9, 1, TRUE ); - - if( app_rep_size != 0 ) - { - /* Display application Reply data */ - ar_item = proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+10, app_rep_size, "Application Reply:" ); - - for( i=0; i < app_rep_size; i ++ ) - { - temp_byte = tvb_get_guint8( tvb, offset+4+add_stat_size+10+i ); - proto_item_append_text(ar_item, " 0x%02X", temp_byte ); - } - - } /* End of if reply data */ + proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+4+add_stat_size+9, 1, ENC_LITTLE_ENDIAN); + if (app_rep_size > 0) + proto_tree_add_item(cmd_data_tree, hf_cip_cm_app_reply_data, tvb, offset+4+add_stat_size+10, app_rep_size, ENC_LITTLE_ENDIAN); enip_close_cip_connection( pinfo, ConnSerialNumber, VendorID, DeviceSerialNumber ); @@ -2506,53 +4081,25 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ /* Unconnected send response (Success) */ /* Display service response data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, ENC_LITTLE_ENDIAN); } break; case SC_CM_GET_CONN_OWNER: { /* Get Connection owner response (Success) */ - /* Display number of connections */ proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_conn, tvb, offset+4+add_stat_size, 1, ENC_LITTLE_ENDIAN); - - /* Display number of COO connections */ proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_coo_conn, tvb, offset+4+add_stat_size+1, 1, ENC_LITTLE_ENDIAN); - - /* Display number of ROO connections */ proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_roo_conn, tvb, offset+4+add_stat_size+2, 1, ENC_LITTLE_ENDIAN); - - /* Display Last Action */ - proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_la, tvb, offset+4+add_stat_size+3, 1, ENC_LITTLE_ENDIAN); - - /* Display connection serial number */ + proto_tree_add_item( cmd_data_tree, hf_cip_cm_gco_last_action, tvb, offset+4+add_stat_size+3, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item( cmd_data_tree, hf_cip_cm_conn_serial_num, tvb, offset+4+add_stat_size+4, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator vendor id */ - proto_tree_add_item( cmd_data_tree, hf_cip_vendor, tvb, offset+4+add_stat_size+6, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator serial number */ + proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+4+add_stat_size+6, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item( cmd_data_tree, hf_cip_cm_orig_serial_num, tvb, offset+4+add_stat_size+8, 4, ENC_LITTLE_ENDIAN); } break; - case SC_GET_ATT_LIST: - { - /* Get Attribute List Reply (Success)*/ - - int att_count; - - /* Add Attribute Count */ - att_count = tvb_get_letohs( tvb, offset+4+add_stat_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size, 2, "Attribute Count: %d", att_count ); - - /* Add the data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+6+add_stat_size, item_length-6-add_stat_size, "Data: " ); - - } /* Get Attribute List Reply */ - break; default: /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, ENC_LITTLE_ENDIAN); break; } } @@ -2565,33 +4112,19 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ case SC_CM_LARGE_FWD_OPEN: case SC_CM_FWD_CLOSE: /* Forward open and forward close error response look the same */ - - /* Display connection serial number */ proto_tree_add_item( cmd_data_tree, hf_cip_cm_conn_serial_num, tvb, offset+4+add_stat_size, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator vendor id */ - proto_tree_add_item( cmd_data_tree, hf_cip_vendor, tvb, offset+4+add_stat_size+2, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator serial number */ + proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+4+add_stat_size+2, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item( cmd_data_tree, hf_cip_cm_orig_serial_num, tvb, offset+4+add_stat_size+4, 4, ENC_LITTLE_ENDIAN); - - /* Display remaining path size */ - temp_data = tvb_get_guint8( tvb, offset+4+add_stat_size+8 ); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+8, 1, "Remaining Path Size: %d", temp_data ); - - /* Display the Reserved byte */ - proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+4+add_stat_size+9, 1, TRUE ); + proto_tree_add_item(cmd_data_tree, hf_cip_cm_remain_path_size, tvb, offset+4+add_stat_size+8, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+4+add_stat_size+9, 1, ENC_LITTLE_ENDIAN); break; case SC_CM_UNCON_SEND: /* Unconnected send response (Unsuccess) */ - - /* Display remaining path size */ - temp_data = tvb_get_guint8( tvb, offset+4+add_stat_size); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size, 1, "Remaining Path Size: %d", temp_data ); + proto_tree_add_item(cmd_data_tree, hf_cip_cm_remain_path_size, tvb, offset+4+add_stat_size, 1, ENC_LITTLE_ENDIAN); break; default: /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, ENC_LITTLE_ENDIAN); break; } } /* end of if-else( CI_CRC_SUCCESS ) */ @@ -2607,6 +4140,7 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ col_append_str( pinfo->cinfo, COL_INFO, val_to_str( ( tvb_get_guint8( tvb, offset ) & 0x7F ), cip_sc_vals_cm , "Unknown Service (0x%02x)") ); + req_path_size = tvb_get_guint8( tvb, offset+1 )*2; /* If there is any command specific data creat a sub-tree for it */ @@ -2621,37 +4155,30 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ { case SC_CM_FWD_OPEN: /* Forward open Request*/ - dissect_cip_cm_fwd_open_req(cmd_data_tree, tvb, offset+2+req_path_size, ENC_BIG_ENDIAN); + dissect_cip_cm_fwd_open_req(cmd_data_tree, tvb, offset+2+req_path_size, FALSE, pinfo); break; case SC_CM_LARGE_FWD_OPEN: /* Large Forward open Request*/ - dissect_cip_cm_fwd_open_req(cmd_data_tree, tvb, offset+2+req_path_size, ENC_LITTLE_ENDIAN); + dissect_cip_cm_fwd_open_req(cmd_data_tree, tvb, offset+2+req_path_size, TRUE, pinfo); break; case SC_CM_FWD_CLOSE: /* Forward Close Request */ - /* Display timeout fields */ dissect_cip_cm_timeout( cmd_data_tree, tvb, offset+2+req_path_size); - - /* Display connection serial number */ proto_tree_add_item( cmd_data_tree, hf_cip_cm_conn_serial_num, tvb, offset+2+req_path_size+2, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator vendor id */ - proto_tree_add_item( cmd_data_tree, hf_cip_vendor, tvb, offset+2+req_path_size+4, 2, ENC_LITTLE_ENDIAN); - - /* Display the originator serial number */ + proto_tree_add_item( cmd_data_tree, hf_cip_cm_vendor, tvb, offset+2+req_path_size+4, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item( cmd_data_tree, hf_cip_cm_orig_serial_num, tvb, offset+2+req_path_size+6, 4, ENC_LITTLE_ENDIAN); /* Add the path size */ conn_path_size = tvb_get_guint8( tvb, offset+2+req_path_size+10 )*2; - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+10, 1, "Connection Path Size: %d (words)", conn_path_size / 2 ); + proto_tree_add_uint_format_value(cmd_data_tree, hf_cip_cm_conn_path_size, tvb, offset+2+req_path_size+10, 1, conn_path_size/2, "%d (words)", conn_path_size/2); /* Display the Reserved byte */ - proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+2+req_path_size+11, 1, TRUE ); + proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+2+req_path_size+11, 1, ENC_LITTLE_ENDIAN); /* Add the EPATH */ pi = proto_tree_add_text(cmd_data_tree, tvb, offset+2+req_path_size+12, conn_path_size, "Connection Path: "); - dissect_epath( tvb, pi, offset+2+req_path_size+12, conn_path_size, FALSE ); + dissect_epath( tvb, pinfo, pi, offset+2+req_path_size+12, conn_path_size, FALSE, NULL ); break; case SC_CM_UNCON_SEND: { @@ -2663,7 +4190,7 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ /* Message request size */ msg_req_siz = tvb_get_letohs( tvb, offset+2+req_path_size+2 ); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, 2, "Message Request Size: 0x%04X", msg_req_siz ); + proto_tree_add_item(cmd_data_tree, hf_cip_cm_msg_req_size, tvb, offset+2+req_path_size+2, 2, ENC_LITTLE_ENDIAN); /* Message Request */ temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4, msg_req_siz, "Message Request" ); @@ -2688,6 +4215,7 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ pembedded_req_info->IOILen = 0; pembedded_req_info->pIOI = NULL; pembedded_req_info->pData = NULL; + pembedded_req_info->ciaData = NULL; preq_info->pData = pembedded_req_info; } else @@ -2700,63 +4228,38 @@ dissect_cip_cm_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_ if( msg_req_siz % 2 ) { /* Pad byte */ - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4+msg_req_siz, 1, "Pad Byte (0x%02X)", - tvb_get_guint8( tvb, offset+2+req_path_size+4+msg_req_siz ) ); + proto_tree_add_item(cmd_data_tree, hf_cip_pad8, tvb, offset+2+req_path_size+4+msg_req_siz, 1, ENC_LITTLE_ENDIAN); msg_req_siz++; /* include the padding */ } /* Route Path Size */ route_path_size = tvb_get_guint8( tvb, offset+2+req_path_size+4+msg_req_siz )*2; - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+4+msg_req_siz, 1, "Route Path Size: %d (words)", route_path_size/2 ); + proto_tree_add_uint_format_value(cmd_data_tree, hf_cip_cm_route_path_size, tvb, offset+2+req_path_size+4+msg_req_siz, 1, route_path_size / 2, "%d (words)", route_path_size / 2); /* Display the Reserved byte */ - proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+2+req_path_size+5+msg_req_siz, 1, TRUE ); + proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+2+req_path_size+5+msg_req_siz, 1, ENC_LITTLE_ENDIAN); /* Route Path */ temp_item = proto_tree_add_text(cmd_data_tree, tvb, offset+2+req_path_size+6+msg_req_siz, route_path_size, "Route Path: "); - dissect_epath( tvb, temp_item, offset+2+req_path_size+6+msg_req_siz, route_path_size, FALSE ); + dissect_epath( tvb, pinfo, temp_item, offset+2+req_path_size+6+msg_req_siz, route_path_size, FALSE, NULL ); } break; case SC_CM_GET_CONN_OWNER: /* Get Connection Owner Request */ - /* Display the Reserved byte */ - proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+2+req_path_size, 1, TRUE ); + proto_tree_add_item(cmd_data_tree, hf_cip_reserved8, tvb, offset+2+req_path_size, 1, ENC_LITTLE_ENDIAN); /* Add path size */ conn_path_size = tvb_get_guint8( tvb, offset+2+req_path_size+1 )*2; - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+1, 1, "Connection Path Size: %d (words)", conn_path_size / 2 ); + proto_tree_add_uint_format_value(cmd_data_tree, hf_cip_cm_conn_path_size, tvb, offset+2+req_path_size+1, 1, conn_path_size/2, "%d (words)", conn_path_size/2); /* Add the epath */ pi = proto_tree_add_text(cmd_data_tree, tvb, offset+2+req_path_size+2, conn_path_size, "Connection Path: "); - dissect_epath( tvb, pi, offset+2+req_path_size+2, conn_path_size, FALSE ); + dissect_epath( tvb, pinfo, pi, offset+2+req_path_size+2, conn_path_size, FALSE, NULL ); break; - case SC_GET_ATT_LIST: - { - /* Get attribute list request */ - - int att_count; - - /* Add number of services */ - att_count = tvb_get_letohs( tvb, offset+2+req_path_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Attribute Count: %d", att_count ); - - /* Add Attribute List */ - temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, att_count*2, "Attribute List: " ); - - for( i=0; i < att_count; i++ ) - { - if( i == (att_count-1) ) - proto_item_append_text(temp_item, "%d",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - else - proto_item_append_text(temp_item, "%d, ",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - } - - } /* End of Get attribute list request */ - break; default: /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+2+req_path_size, item_length-req_path_size-2, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+2+req_path_size, item_length-req_path_size-2, ENC_LITTLE_ENDIAN); } } /* End of if command-specific data present */ @@ -2774,7 +4277,7 @@ dissect_cip_class_cm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if( tree ) { /* Create display subtree for the protocol */ - ti = proto_tree_add_item(tree, proto_cip_class_cm, tvb, 0, -1, ENC_BIG_ENDIAN); + ti = proto_tree_add_item(tree, proto_cip_class_cm, tvb, 0, -1, FALSE); class_tree = proto_item_add_subtree( ti, ett_cip_class_cm ); dissect_cip_cm_data( class_tree, tvb, 0, tvb_length(tvb), pinfo ); @@ -2789,132 +4292,96 @@ dissect_cip_class_cm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) * ************************************************/ static void -dissect_cip_cco_all_attribute_common( proto_tree *cmd_tree, tvbuff_t *tvb, int offset, int item_length) +dissect_cip_cco_all_attribute_common( proto_tree *cmd_tree, tvbuff_t *tvb, int offset, int item_length, packet_info *pinfo) { - proto_item *pi, *tdii, *ncpi, *ncppi, *iomapi, *confgi; + proto_item *pi, *tdii, *ncpi, *iomapi, *confgi; proto_tree *tdi_tree, *iomap_tree; - proto_tree *ncp_tree, *ncpp_tree, *confg_tree; + proto_tree *ncp_tree, *confg_tree; int conn_path_size, variable_data_size = 0, config_data_size; int connection_name_size, iomap_size, ot_rtf, to_rtf; - int temp_data, temp_data2; + int temp_data; char* str_connection_name; /* Connection flags */ temp_data = tvb_get_letohs( tvb, offset); ot_rtf = (temp_data >> 1) & 7; to_rtf = (temp_data >> 4) & 7; - confgi = proto_tree_add_text( cmd_tree, tvb, offset, 2, "Connection Flags: 0x%04X", temp_data ); + confgi = proto_tree_add_item(cmd_tree, hf_cip_cco_con_flags, tvb, offset, 2, ENC_LITTLE_ENDIAN ); confg_tree = proto_item_add_subtree(confgi, ett_cco_con_flag); - /* Add the data to the tree */ - proto_tree_add_item(confg_tree, hf_cip_cco_con_type, tvb, offset, 2, TRUE ); - proto_tree_add_item(confg_tree, hf_cip_cco_ot_rtf, tvb, offset, 2, TRUE ); - proto_tree_add_item(confg_tree, hf_cip_cco_to_rtf, tvb, offset, 2, TRUE ); + proto_tree_add_item(confg_tree, hf_cip_cco_con_type, tvb, offset, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(confg_tree, hf_cip_cco_ot_rtf, tvb, offset, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(confg_tree, hf_cip_cco_to_rtf, tvb, offset, 2, ENC_LITTLE_ENDIAN ); /* Target device id */ tdii = proto_tree_add_text( cmd_tree, tvb, offset+2, 10, "Target Device ID"); tdi_tree = proto_item_add_subtree(tdii, ett_cco_tdi); - /* Target Vendor ID */ - proto_tree_add_item(tdi_tree, hf_cip_vendor, tvb, offset+2, 2, ENC_LITTLE_ENDIAN); - - /* Target Device Type */ - proto_tree_add_item(tdi_tree, hf_cip_devtype, tvb, offset+4, 2, ENC_LITTLE_ENDIAN); - - /* Target Product Code */ - temp_data = tvb_get_letohs( tvb, offset+6); - proto_tree_add_text(tdi_tree, tvb, offset+6, 2, "Product Code: 0x%04X", temp_data ); - - /* Target Major/Minor revision*/ - temp_data = tvb_get_guint8( tvb, offset+8); - temp_data2 = tvb_get_guint8( tvb, offset+9); - proto_tree_add_text(tdi_tree, tvb, offset+8, 2, "Revision %d.%d", temp_data, temp_data2); + dissect_deviceid(tvb, offset+2, tdi_tree, + hf_cip_cco_tdi_vendor, hf_cip_cco_tdi_devtype, hf_cip_cco_tdi_prodcode, + hf_cip_cco_tdi_compatibility, hf_cip_cco_tdi_comp_bit, hf_cip_cco_tdi_majorrev, hf_cip_cco_tdi_minorrev); /* CS Data Index Number */ - temp_data = tvb_get_letohl( tvb, offset+10); - proto_tree_add_text( cmd_tree, tvb, offset+10, 4, "CS Data Index Number: 0x%08X", temp_data ); + proto_tree_add_item(cmd_tree, hf_cip_cco_cs_data_index, tvb, offset+10, 4, ENC_LITTLE_ENDIAN ); /* Net Connection Parameters */ ncpi = proto_tree_add_text( cmd_tree, tvb, offset+14, 14, "Net Connection Parameters"); ncp_tree = proto_item_add_subtree(ncpi, ett_cco_ncp); /* Timeout multiplier */ - temp_data = tvb_get_guint8( tvb, offset+14); - proto_tree_add_text(ncp_tree, tvb, offset+14, 1, "Connection Timeout Multiplier: %s (%d)", val_to_str( temp_data, cip_con_time_mult_vals , "Reserved" ), temp_data ); - - /* Transport type/trigger in tree*/ - temp_data = tvb_get_guint8( tvb, offset+15 ); - - ncppi = proto_tree_add_text(ncp_tree, tvb, offset+15, 1, "Transport Type/Trigger: 0x%02X", temp_data ); - ncpp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); + proto_tree_add_item(ncp_tree, hf_cip_cco_timeout_multiplier, tvb, offset+14, 1, ENC_LITTLE_ENDIAN ); - /* Add the data to the tree */ - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_dir, tvb, offset+15, 1, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_trigg, tvb, offset+15, 1, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_class, tvb, offset+15, 1, TRUE ); + dissect_transport_type_trigger(tvb, offset+15, ncp_tree, hf_cip_cco_transport_type_trigger, + hf_cip_cco_fwo_dir, hf_cip_cco_fwo_trigger, hf_cip_cco_fwo_class, ett_cco_ttt); temp_data = tvb_get_letohl( tvb, offset+16); - proto_tree_add_text(ncp_tree, tvb, offset+16, 4, "O->T RPI: %dms (0x%08X)", temp_data / 1000, temp_data ); + proto_tree_add_uint_format_value(ncp_tree, hf_cip_cco_ot_rpi, tvb, offset+16, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); - /* Display originator to target network connection patameterts, in a tree */ - temp_data = tvb_get_letohs( tvb, offset+20 ); - ncppi = proto_tree_add_text(ncp_tree, tvb, offset+20, 2, "O->T Network Connection Parameters: 0x%04X", temp_data ); - ncpp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); - - /* Add the data to the tree */ - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_own, tvb, offset+20, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_typ, tvb, offset+20, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_prio, tvb, offset+20, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_fixed_var, tvb, offset+20, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_con_size, tvb, offset+20, 2, TRUE ); + /* Display O->T network connection parameters */ + dissect_net_param16(tvb, offset+20, ncp_tree, + hf_cip_cco_ot_net_param16, hf_cip_cco_fwo_own, hf_cip_cco_fwo_typ, + hf_cip_cco_fwo_prio, hf_cip_cco_fwo_fixed_var, hf_cip_cco_fwo_con_size, ett_cco_ncp); temp_data = tvb_get_letohl( tvb, offset+22); - proto_tree_add_text(ncp_tree, tvb, offset+22, 4, "T->O RPI: %dms (0x%08X)", temp_data / 1000, temp_data ); - - /* Display target to originator network connection patameters, in a tree */ - temp_data = tvb_get_letohs( tvb, offset+26); - ncppi = proto_tree_add_text(ncp_tree, tvb, offset+26, 2, "T->O Network Connection Parameters: 0x%04X", temp_data ); - ncpp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); + proto_tree_add_uint_format_value(ncp_tree, hf_cip_cco_to_rpi, tvb, offset+16, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); - /* Add the data to the tree */ - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_own, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_typ, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_prio, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_fixed_var, tvb, offset+26, 2, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_con_size, tvb, offset+26, 2, TRUE ); + /* Display T->O network connection parameters */ + dissect_net_param16(tvb, offset+26, ncp_tree, + hf_cip_cco_to_net_param16, hf_cip_cco_fwo_own, hf_cip_cco_fwo_typ, + hf_cip_cco_fwo_prio, hf_cip_cco_fwo_fixed_var, hf_cip_cco_fwo_con_size, ett_cco_ncp); /* Connection Path */ conn_path_size = tvb_get_guint8( tvb, offset+28 )*2; - proto_tree_add_text( cmd_tree, tvb, offset+28, 1, "Connection Path Size: %d (words)", conn_path_size / 2 ); + proto_tree_add_uint_format_value(cmd_tree, hf_cip_cco_conn_path_size, tvb, offset+28, 1, conn_path_size/2, "%d (words)", conn_path_size/2); /* Display the Reserved byte */ - proto_tree_add_item(cmd_tree, hf_cip_reserved8, tvb, offset+29, 1, TRUE ); + proto_tree_add_item(cmd_tree, hf_cip_reserved8, tvb, offset+29, 1, ENC_LITTLE_ENDIAN ); /* Add the epath */ pi = proto_tree_add_text(cmd_tree, tvb, offset+30, conn_path_size, "Connection Path: "); - dissect_epath( tvb, pi, offset+30, conn_path_size, FALSE ); + dissect_epath( tvb, pinfo, pi, offset+30, conn_path_size, FALSE, NULL ); variable_data_size += (conn_path_size+30); /* Config #1 Data */ - config_data_size = tvb_get_letohs( tvb, offset+variable_data_size); - proto_tree_add_text( cmd_tree, tvb, offset+variable_data_size, 2, "Proxy Config Data Size %d", config_data_size); + config_data_size = tvb_get_letohs( tvb, offset+variable_data_size); + proto_tree_add_item(cmd_tree, hf_cip_cco_proxy_config_size, tvb, offset+variable_data_size, 2, ENC_LITTLE_ENDIAN ); if (config_data_size > 0) - add_byte_array_text_to_proto_tree( cmd_tree, tvb, offset+variable_data_size+2, config_data_size, "Proxy Config Data: " ); + proto_tree_add_item(cmd_tree, hf_cip_cco_proxy_config_data, tvb, offset+variable_data_size+2, config_data_size, ENC_LITTLE_ENDIAN); variable_data_size += (config_data_size+2); /* Config #2 Data */ - config_data_size = tvb_get_letohs( tvb, offset+variable_data_size); - proto_tree_add_text( cmd_tree, tvb, offset+variable_data_size, 2, "Target Config Data Size %d", config_data_size); + config_data_size = tvb_get_letohs( tvb, offset+variable_data_size); + proto_tree_add_item(cmd_tree, hf_cip_cco_target_config_size, tvb, offset+variable_data_size, 2, ENC_LITTLE_ENDIAN ); if (config_data_size > 0) - add_byte_array_text_to_proto_tree( cmd_tree, tvb, offset+variable_data_size+2, config_data_size, "Target Config Data: " ); + proto_tree_add_item(cmd_tree, hf_cip_cco_target_config_data, tvb, offset+variable_data_size+2, config_data_size, ENC_LITTLE_ENDIAN); variable_data_size += (config_data_size+2); /* Connection Name */ connection_name_size = tvb_get_guint8( tvb, offset+variable_data_size); - str_connection_name = tvb_get_ephemeral_faked_unicode(tvb, offset+variable_data_size+2, connection_name_size, ENC_LITTLE_ENDIAN); + str_connection_name = tvb_get_ephemeral_faked_unicode(tvb, offset+variable_data_size+2, connection_name_size, TRUE); proto_tree_add_text(cmd_tree, tvb, offset+variable_data_size, connection_name_size+2, "Connection Name: %s", str_connection_name); variable_data_size += ((connection_name_size*2)+2); @@ -2925,39 +4392,22 @@ dissect_cip_cco_all_attribute_common( proto_tree *cmd_tree, tvbuff_t *tvb, int o iomapi = proto_tree_add_text( cmd_tree, tvb, offset+variable_data_size, iomap_size+2, "I/O Mapping"); iomap_tree = proto_item_add_subtree(iomapi, ett_cco_iomap); - /* Format number */ - temp_data = tvb_get_guint8( tvb, offset+variable_data_size); - proto_tree_add_text(iomap_tree, tvb, offset+variable_data_size, 2, "Format number: %d", temp_data ); - - /* Attribute size */ - proto_tree_add_text(iomap_tree, tvb, offset+variable_data_size+2, 2, "Attribute size: %d (bytes)", iomap_size); + proto_tree_add_item(iomap_tree, hf_cip_cco_iomap_format_number, tvb, offset+variable_data_size, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_uint_format_value(iomap_tree, hf_cip_cco_iomap_size, tvb, offset+variable_data_size+2, 2, iomap_size, "%d (bytes)", iomap_size); /* Attribute data */ if (iomap_size > 0) - add_byte_array_text_to_proto_tree( iomap_tree, tvb, offset+variable_data_size+4, iomap_size, "Attribute Data: " ); + proto_tree_add_item(iomap_tree, hf_cip_cco_iomap_attribute, tvb, offset+variable_data_size+4, iomap_size, ENC_LITTLE_ENDIAN); variable_data_size += (iomap_size+4); /* Proxy device id */ tdii = proto_tree_add_text( cmd_tree, tvb, offset+variable_data_size, 10, "Proxy Device ID"); - tdi_tree = proto_item_add_subtree(tdii, ett_cco_tdi); - - /* Proxy Vendor ID */ - temp_data = tvb_get_letohs( tvb, offset+variable_data_size); - proto_tree_add_item(tdi_tree, hf_cip_vendor, tvb, offset+variable_data_size, 2, ENC_LITTLE_ENDIAN); - - /* Proxy Device Type */ - temp_data = tvb_get_letohs( tvb, offset+variable_data_size+2); - proto_tree_add_item(tdi_tree, hf_cip_devtype, tvb, offset+variable_data_size+2, 2, ENC_LITTLE_ENDIAN); - - /* Proxy Product Code */ - temp_data = tvb_get_letohs( tvb, offset+variable_data_size+4); - proto_tree_add_text(tdi_tree, tvb, offset+variable_data_size+4, 2, "Product Code: 0x%04X", temp_data ); + tdi_tree = proto_item_add_subtree(tdii, ett_cco_pdi); - /* Proxy Major/Minor revision*/ - temp_data = tvb_get_guint8( tvb, offset+variable_data_size+6); - temp_data2 = tvb_get_guint8( tvb, offset+variable_data_size+7); - proto_tree_add_text(tdi_tree, tvb, offset+variable_data_size+6, 2, "Revision %d.%d", temp_data, temp_data2); + dissect_deviceid(tvb, offset+variable_data_size, tdi_tree, + hf_cip_cco_pdi_vendor, hf_cip_cco_pdi_devtype, hf_cip_cco_pdi_prodcode, + hf_cip_cco_pdi_compatibility, hf_cip_cco_pdi_comp_bit, hf_cip_cco_pdi_majorrev, hf_cip_cco_pdi_minorrev); /* Add in proxy device id size */ variable_data_size += 8; @@ -2966,26 +4416,19 @@ dissect_cip_cco_all_attribute_common( proto_tree *cmd_tree, tvbuff_t *tvb, int o ((ot_rtf == 5) || (to_rtf == 5))) { /* Safety parameters */ - add_byte_array_text_to_proto_tree( cmd_tree, tvb, offset+variable_data_size, 55, "Safety Parameters: " ); - + proto_tree_add_item(cmd_tree, hf_cip_cco_safety, tvb, offset+variable_data_size, 55, ENC_LITTLE_ENDIAN); variable_data_size += 55; } if (offset+variable_data_size < item_length) { - /* Connection disable */ - temp_data = tvb_get_guint8( tvb, offset+variable_data_size) & 1; - proto_tree_add_text( cmd_tree, tvb, offset+variable_data_size, 1, "Connection Disable: %d", temp_data ); - + proto_tree_add_item(cmd_tree, hf_cip_cco_connection_disable, tvb, offset+variable_data_size, 1, ENC_LITTLE_ENDIAN ); variable_data_size++; } if (offset+variable_data_size < item_length) { - /* Net Connection Parameter Attribute Selection */ - temp_data = tvb_get_guint8( tvb, offset+variable_data_size); - proto_tree_add_text( cmd_tree, tvb, offset+variable_data_size, 1, "Net Connection Parameter Attribute Selection: %d", temp_data ); - + proto_tree_add_item(cmd_tree, hf_cip_cco_net_conn_param_attr, tvb, offset+variable_data_size, 1, ENC_LITTLE_ENDIAN ); variable_data_size++; } @@ -2995,50 +4438,27 @@ dissect_cip_cco_all_attribute_common( proto_tree *cmd_tree, tvbuff_t *tvb, int o ncpi = proto_tree_add_text( cmd_tree, tvb, offset+variable_data_size, 18, "Large Net Connection Parameters"); ncp_tree = proto_item_add_subtree(ncpi, ett_cco_ncp); - /* Timeout multiplier */ - temp_data = tvb_get_guint8( tvb, offset+variable_data_size); - proto_tree_add_text(ncp_tree, tvb, offset+variable_data_size, 1, "Connection Timeout Multiplier: %s (%d)", val_to_str( temp_data, cip_con_time_mult_vals , "Reserved" ), temp_data ); - - /* Transport type/trigger in tree*/ - temp_data = tvb_get_guint8( tvb, offset+variable_data_size+1); - - ncppi = proto_tree_add_text(ncp_tree, tvb, offset+variable_data_size+1, 1, "Transport Type/Trigger: 0x%02X", temp_data ); - ncpp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); - - /* Add the data to the tree */ - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_dir, tvb, offset+variable_data_size+1, 1, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_trigg, tvb, offset+variable_data_size+1, 1, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_fwo_class, tvb, offset+variable_data_size+1, 1, TRUE ); + proto_tree_add_item(ncp_tree, hf_cip_cco_timeout_multiplier, tvb, offset+variable_data_size, 1, ENC_LITTLE_ENDIAN ); + dissect_transport_type_trigger(tvb, offset+variable_data_size+1, ncp_tree, hf_cip_cco_transport_type_trigger, + hf_cip_cco_fwo_dir, hf_cip_cco_fwo_trigger, hf_cip_cco_fwo_class, ett_cco_ttt); temp_data = tvb_get_letohl( tvb, offset+variable_data_size+2); - proto_tree_add_text(ncp_tree, tvb, offset+variable_data_size+2, 4, "O->T RPI: %dms (0x%08X)", temp_data / 1000, temp_data ); + proto_tree_add_uint_format_value(ncp_tree, hf_cip_cco_ot_rpi, tvb, offset+variable_data_size+2, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); - /* Display originator to target network connection patameterts, in a tree */ - temp_data = tvb_get_letohl(tvb, offset+variable_data_size+6); - ncppi = proto_tree_add_text(ncp_tree, tvb, offset+variable_data_size+6, 4, "O->T Network Connection Parameters: 0x%08X", temp_data ); - ncpp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); + /* Display O->T network connection parameters */ + dissect_net_param32(tvb, offset+variable_data_size+6, ncp_tree, + hf_cip_cco_ot_net_param32, hf_cip_cco_lfwo_own, hf_cip_cco_lfwo_typ, + hf_cip_cco_lfwo_prio, hf_cip_cco_lfwo_fixed_var, hf_cip_cco_lfwo_con_size, ett_cco_ncp); - /* Add the data to the tree */ - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_own, tvb, offset+variable_data_size+6, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_typ, tvb, offset+variable_data_size+6, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_prio, tvb, offset+variable_data_size+6, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_fixed_var, tvb, offset+variable_data_size+6, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_con_size, tvb, offset+variable_data_size+6, 4, TRUE ); temp_data = tvb_get_letohl( tvb, offset+variable_data_size+10); - proto_tree_add_text(ncp_tree, tvb, offset+variable_data_size+10, 4, "T->O RPI: %dms (0x%08X)", temp_data / 1000, temp_data ); + proto_tree_add_uint_format_value(ncp_tree, hf_cip_cco_to_rpi, tvb, offset+variable_data_size+2, 4, temp_data, "%dms (0x%08X)", temp_data / 1000, temp_data); - /* Display target to originator network connection patameterts, in a tree */ - temp_data = tvb_get_letohl(tvb, offset+variable_data_size+14); - ncppi = proto_tree_add_text(ncp_tree, tvb, offset+variable_data_size+14, 4, "T->0 Network Connection Parameters: 0x%08X", temp_data ); - ncpp_tree = proto_item_add_subtree(ncppi, ett_cm_ncp); + /* Display T->O network connection parameters */ + dissect_net_param32(tvb, offset+variable_data_size+14, ncp_tree, + hf_cip_cco_to_net_param32, hf_cip_cco_lfwo_own, hf_cip_cco_lfwo_typ, + hf_cip_cco_lfwo_prio, hf_cip_cco_lfwo_fixed_var, hf_cip_cco_lfwo_con_size, ett_cco_ncp); - /* Add the data to the tree */ - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_own, tvb, offset+variable_data_size+14, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_typ, tvb, offset+variable_data_size+14, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_prio, tvb, offset+variable_data_size+14, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_fixed_var, tvb, offset+variable_data_size+14, 4, TRUE ); - proto_tree_add_item(ncpp_tree, hf_cip_cm_lfwo_con_size, tvb, offset+variable_data_size+14, 4, TRUE ); variable_data_size += 18; } @@ -3047,14 +4467,11 @@ dissect_cip_cco_all_attribute_common( proto_tree *cmd_tree, tvbuff_t *tvb, int o static void dissect_cip_cco_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item_length, packet_info *pinfo ) { - proto_item *pi, *rrsc_item, *temp_item, *con_sti; + proto_item *pi, *rrsc_item, *con_sti; proto_tree *rrsc_tree, *cmd_data_tree, *con_st_tree; int req_path_size; int temp_data; - guint8 service; - unsigned char gen_status; - unsigned char add_stat_size; - unsigned char i; + guint8 service, gen_status, add_stat_size; cip_req_info_t* preq_info; cip_simple_request_info_t req_data; @@ -3066,7 +4483,7 @@ dissect_cip_cco_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item rrsc_tree = proto_item_add_subtree( rrsc_item, ett_cco_rrsc ); /* Add Request/Response */ - proto_tree_add_item( rrsc_tree, hf_cip_rr, tvb, offset, 1, TRUE ); + proto_tree_add_item( rrsc_tree, hf_cip_reqrsp, tvb, offset, 1, ENC_LITTLE_ENDIAN ); proto_item_append_text( rrsc_item, "%s (%s)", val_to_str( ( service & 0x7F ), @@ -3075,28 +4492,20 @@ dissect_cip_cco_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item cip_sc_rr, "") ); /* Add Service code */ - proto_tree_add_item(rrsc_tree, hf_cip_sc, tvb, offset, 1, TRUE ); - - /* Get path information for further dissection */ - req_data.iClass = (guint32)-1; - req_data.iInstance = (guint32)-1; - req_data.iAttribute = (guint32)-1; - req_data.iMember = (guint32)-1; + proto_tree_add_item(rrsc_tree, hf_cip_cco_sc, tvb, offset, 1, ENC_LITTLE_ENDIAN ); - preq_info = p_get_proto_data(pinfo->fd, proto_cip); - if ( preq_info ) + preq_info = (cip_req_info_t*)p_get_proto_data(pinfo->fd, proto_cip); + if ((preq_info != NULL) && + (preq_info->ciaData != NULL)) { - if ( preq_info->IOILen && preq_info->pIOI ) - { - tvbuff_t* tvbIOI; - - tvbIOI = tvb_new_real_data( preq_info->pIOI, preq_info->IOILen * 2, preq_info->IOILen * 2); - if ( tvbIOI ) - { - dissect_epath_request(tvbIOI, &req_data, preq_info->IOILen*2); - tvb_free(tvbIOI); - } - } + memcpy(&req_data, preq_info->ciaData, sizeof(cip_simple_request_info_t)); + } + else + { + req_data.iClass = (guint32)-1; + req_data.iInstance = (guint32)-1; + req_data.iAttribute = (guint32)-1; + req_data.iMember = (guint32)-1; } if(service & 0x80 ) @@ -3123,22 +4532,11 @@ dissect_cip_cco_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item { /* Get Attribute All (class) request */ - /* Revision */ - proto_tree_add_item(cmd_data_tree, hf_cip_class_rev, tvb, offset+4+add_stat_size, 2, TRUE ); - - /* Max Instance */ - proto_tree_add_item(cmd_data_tree, hf_cip_class_max_inst32, tvb, offset+4+add_stat_size+2, 4, TRUE ); - - /* Num Instance */ - proto_tree_add_item(cmd_data_tree, hf_cip_class_num_inst32, tvb, offset+4+add_stat_size+6, 4, TRUE ); - - /* Format Number */ - temp_data = tvb_get_letohl( tvb, offset+4+add_stat_size+8); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+8, 2, "Format Number: %d", temp_data ); - - /* Edit Signature */ - temp_data = tvb_get_letohl( tvb, offset+4+add_stat_size+10); - proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size+10, 4, "Edit Signature: 0x%08X", temp_data ); + proto_tree_add_item(cmd_data_tree, hf_cip_class_rev, tvb, offset+4+add_stat_size, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(cmd_data_tree, hf_cip_class_max_inst32, tvb, offset+4+add_stat_size+2, 4, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(cmd_data_tree, hf_cip_class_num_inst32, tvb, offset+4+add_stat_size+6, 4, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(cmd_data_tree, hf_cip_cco_format_number, tvb, offset+4+add_stat_size+8, 2, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(cmd_data_tree, hf_cip_cco_edit_signature, tvb, offset+4+add_stat_size+10, 4, ENC_LITTLE_ENDIAN ); } else { @@ -3148,24 +4546,20 @@ dissect_cip_cco_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item con_sti = proto_tree_add_text( cmd_data_tree, tvb, offset+4+add_stat_size, 4, "Connection Status"); con_st_tree = proto_item_add_subtree(con_sti, ett_cco_con_status); - /* General Status */ - proto_tree_add_item(con_st_tree, hf_cip_genstat, tvb, offset+4+add_stat_size, 1, TRUE ); + proto_tree_add_item(con_st_tree, hf_cip_genstat, tvb, offset+4+add_stat_size, 1, ENC_LITTLE_ENDIAN ); + proto_tree_add_item(con_st_tree, hf_cip_pad8, tvb, offset+4+add_stat_size+1, 1, ENC_LITTLE_ENDIAN); - /* Pad */ - temp_data = tvb_get_guint8( tvb, offset+4+add_stat_size+1); - proto_tree_add_text(con_st_tree, tvb, offset+4+add_stat_size+1, 1, "Pad: %d", temp_data ); + /* Extended Status */ + temp_data = tvb_get_letohs( tvb, offset+4+add_stat_size+2); + proto_tree_add_text(con_st_tree, tvb, offset+4+add_stat_size+2, 2, "Extended Status: 0x%04X", temp_data ); - /* Extended Status */ - temp_data = tvb_get_letohs( tvb, offset+4+add_stat_size+2); - proto_tree_add_text(con_st_tree, tvb, offset+4+add_stat_size+2, 2, "Extended Status: 0x%04X", temp_data ); - - dissect_cip_cco_all_attribute_common( cmd_data_tree, tvb, offset+4+add_stat_size+4, item_length); + dissect_cip_cco_all_attribute_common( cmd_data_tree, tvb, offset+4+add_stat_size+4, item_length, pinfo); } } else { /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, ENC_LITTLE_ENDIAN); } } else @@ -3173,7 +4567,7 @@ dissect_cip_cco_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item /* Error responses */ /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+4+add_stat_size, item_length-4-add_stat_size, ENC_LITTLE_ENDIAN); } /* end of if-else( CI_CRC_SUCCESS ) */ } /* End of if command-specific data present */ @@ -3201,56 +4595,27 @@ dissect_cip_cco_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, int item switch (service) { case SC_CCO_AUDIT_CHANGE: - /* Audit Change */ - temp_data = tvb_get_letohs( tvb, offset+2+req_path_size); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Change Type: %s (%d)", val_to_str( temp_data, cip_cco_change_type_vals , "Reserved" ), temp_data ); + proto_tree_add_item(cmd_data_tree, hf_cip_cco_change_type, tvb, offset+2+req_path_size, 2, ENC_LITTLE_ENDIAN ); break; - - case SC_GET_ATT_LIST: - { - /* Get attribute list request */ - - int att_count; - - /* Add number of services */ - att_count = tvb_get_letohs( tvb, offset+2+req_path_size ); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Attribute Count: %d", att_count ); - - /* Add Attribute List */ - temp_item = proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size+2, att_count*2, "Attribute List: " ); - - for( i=0; i < att_count; i++ ) - { - if( i == (att_count-1) ) - proto_item_append_text(temp_item, "%d",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - else - proto_item_append_text(temp_item, "%d, ",tvb_get_letohs( tvb, offset+4+req_path_size+(i*2) ) ); - } - - } - break; case SC_CCO_CHANGE_COMPLETE: - /* Change complete request */ - - temp_data = tvb_get_letohs( tvb, offset+2+req_path_size); - proto_tree_add_text( cmd_data_tree, tvb, offset+2+req_path_size, 2, "Change Type: %s (%d)", val_to_str( temp_data, cip_cco_change_type_vals , "Reserved" ), temp_data ); + proto_tree_add_item(cmd_data_tree, hf_cip_cco_change_type, tvb, offset+2+req_path_size, 2, ENC_LITTLE_ENDIAN ); break; case SC_SET_ATT_ALL: if ((req_data.iInstance == 0) || - (req_data.iInstance != (guint32)-1)) + (req_data.iInstance == (guint32)-1)) { /* Just add raw data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+2+req_path_size, item_length-req_path_size-2, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+2+req_path_size, item_length-req_path_size-2, ENC_LITTLE_ENDIAN); break; } /* Set Attribute All (instance) request */ - dissect_cip_cco_all_attribute_common(cmd_data_tree, tvb, offset+2+req_path_size, item_length); + dissect_cip_cco_all_attribute_common(cmd_data_tree, tvb, offset+2+req_path_size, item_length, pinfo); break; default: /* Add data */ - add_byte_array_text_to_proto_tree( cmd_data_tree, tvb, offset+2+req_path_size, item_length-req_path_size-2, "Data: " ); + proto_tree_add_item(cmd_data_tree, hf_cip_data, tvb, offset+2+req_path_size, item_length-req_path_size-2, ENC_LITTLE_ENDIAN); } /* End of check service code */ } /* End of if command-specific data present */ @@ -3268,7 +4633,7 @@ dissect_cip_class_cco(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) if( tree ) { /* Create display subtree for the protocol */ - ti = proto_tree_add_item(tree, proto_cip_class_cco, tvb, 0, -1, ENC_BIG_ENDIAN); + ti = proto_tree_add_item(tree, proto_cip_class_cco, tvb, 0, -1, ENC_NA); class_tree = proto_item_add_subtree( ti, ett_cip_class_cco ); dissect_cip_cco_data( class_tree, tvb, 0, tvb_length(tvb), pinfo ); @@ -3277,6 +4642,72 @@ dissect_cip_class_cco(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) return tvb_length(tvb); } +static gboolean +dissect_class_cco_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + unsigned char service, service_code, ioilen, segment; + cip_req_info_t* preq_info; + guint32 classid = 0; + int offset = 0; + + service = tvb_get_guint8( tvb, offset ); + service_code = service & 0x7F; + + /* Handle GetAttributeAll and SetAttributeAll in CCO class */ + if ((service_code == SC_GET_ATT_ALL) || + (service_code == SC_SET_ATT_ALL)) + { + if (service & 0x80) + { + /* Service response */ + preq_info = (cip_req_info_t*)p_get_proto_data(pinfo->fd, proto_cip); + if ((preq_info != NULL) && + (preq_info->dissector == dissector_get_uint_handle( subdissector_class_table, CI_CLS_CCO))) + { + call_dissector(preq_info->dissector, tvb, pinfo, tree); + return TRUE; + } + } + else + { + /* Service request */ + ioilen = tvb_get_guint8( tvb, offset + 1 ); + if (ioilen > 1) + { + segment = tvb_get_guint8( tvb, offset + 2 ); + if (((segment & CI_SEGMENT_TYPE_MASK) == CI_LOGICAL_SEGMENT) && + ((segment & CI_LOGICAL_SEG_TYPE_MASK) == CI_LOGICAL_SEG_CLASS_ID)) + { + /* Logical Class ID, do a format check */ + switch ( segment & CI_LOGICAL_SEG_FORMAT_MASK ) + { + case CI_LOGICAL_SEG_8_BIT: + classid = tvb_get_guint8( tvb, offset + 3 ); + break; + case CI_LOGICAL_SEG_16_BIT: + if ( ioilen >= 2 ) + classid = tvb_get_letohs( tvb, offset + 4 ); + break; + case CI_LOGICAL_SEG_32_BIT: + if ( ioilen >= 3 ) + classid = tvb_get_letohl( tvb, offset + 4 ); + break; + } + } + } + + if (classid == CI_CLS_CCO) + { + call_dissector(cip_class_cco_handle, tvb, pinfo, tree ); + return TRUE; + } + + } + } + + return FALSE; +} + /************************************************ * * Dissector for CIP Request/Response @@ -3290,8 +4721,8 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info { proto_item *ti; proto_tree *cip_tree; - proto_item *pi, *rrsc_item, *status_item; - proto_tree *rrsc_tree, *status_tree; + proto_item *pi, *rrsc_item, *status_item, *add_status_item; + proto_tree *rrsc_tree, *status_tree, *add_status_tree; int req_path_size; unsigned char gen_status; unsigned char add_stat_size; @@ -3300,32 +4731,29 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info unsigned char service,ioilen,segment; void *p_save_proto_data; dissector_handle_t dissector; + gint service_index; p_save_proto_data = p_get_proto_data(pinfo->fd, proto_cip); p_remove_proto_data(pinfo->fd, proto_cip); p_add_proto_data(pinfo->fd, proto_cip, preq_info); /* Create display subtree for the protocol */ - ti = proto_tree_add_item(item_tree, proto_cip, tvb, 0, -1, ENC_BIG_ENDIAN); + ti = proto_tree_add_item(item_tree, proto_cip, tvb, 0, -1, ENC_NA); cip_tree = proto_item_add_subtree( ti, ett_cip ); + service = tvb_get_guint8( tvb, offset ); + /* Add Service code & Request/Response tree */ - rrsc_item = proto_tree_add_text( cip_tree, tvb, offset, 1, "Service: " ); - rrsc_tree = proto_item_add_subtree( rrsc_item, ett_rrsc ); + rrsc_item = proto_tree_add_uint_format_value(cip_tree, hf_cip_service, + tvb, offset, 1, service, "%s (%s)", + val_to_str( ( service & 0x7F ), cip_sc_vals , "Unknown Service (0x%02x)"), + val_to_str( ( service & 0x80 )>>7, cip_sc_rr, "")); - /* Add Request/Response */ - proto_tree_add_item( rrsc_tree, hf_cip_rr, tvb, offset, 1, TRUE ); - /* watch for service collisions */ - service = tvb_get_guint8( tvb, offset ); - proto_item_append_text( rrsc_item, "%s (%s)", - val_to_str( ( service & 0x7F ), - cip_sc_vals , "Unknown Service (0x%02x)"), - val_to_str( ( service & 0x80 )>>7, - cip_sc_rr, "") ); + rrsc_tree = proto_item_add_subtree( rrsc_item, ett_rrsc ); - /* Add Service code */ - proto_tree_add_item(rrsc_tree, hf_cip_sc, tvb, offset, 1, TRUE ); + proto_tree_add_item( rrsc_tree, hf_cip_reqrsp, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(rrsc_tree, hf_cip_service_code, tvb, offset, 1, ENC_LITTLE_ENDIAN); if( service & 0x80 ) { @@ -3335,36 +4763,30 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info /* Add general status */ gen_status = tvb_get_guint8( tvb, offset+2 ); - proto_tree_add_item(status_tree, hf_cip_genstat, tvb, offset+2, 1, TRUE ); - proto_item_append_text( status_item, "%s", val_to_str( gen_status, - cip_gs_vals , "Unknown Response (%x)") ); + proto_tree_add_item(status_tree, hf_cip_genstat, tvb, offset+2, 1, ENC_LITTLE_ENDIAN ); + proto_item_append_text( status_item, "%s", val_to_str_ext( gen_status, + &cip_gs_vals_ext , "Unknown Response (%x)") ); /* Add reply status to info column */ col_append_str( pinfo->cinfo, COL_INFO, - val_to_str( ( tvb_get_guint8( tvb, offset+2 ) ), - cip_gs_vals , "Unknown Response (%x)") ); + val_to_str_ext( gen_status, &cip_gs_vals_ext, "Unknown Response (%x)") ); /* Add additional status size */ - proto_tree_add_text( status_tree, tvb, offset+3, 1, "Additional Status Size: %d (word)", - tvb_get_guint8( tvb, offset+3 ) ); - - add_stat_size = tvb_get_guint8( tvb, offset+3 ) * 2; + add_stat_size = tvb_get_guint8( tvb, offset+3 ); + proto_tree_add_uint_format_value(status_tree, hf_cip_addstat_size, + tvb, offset+3, 1, add_stat_size, "%d (words)", add_stat_size); if( add_stat_size ) { - proto_item_append_text( status_item, ", Extended:" ); - /* Add additional status */ - pi = proto_tree_add_text( status_tree, tvb, offset+4, add_stat_size, "Additional Status:" ); + add_status_item = proto_tree_add_text( status_tree, tvb, offset+4, add_stat_size*2, "Additional Status" ); + add_status_tree = proto_item_add_subtree( add_status_item, ett_add_status_item ); - for( i=0; i < add_stat_size/2; i ++ ) - { - proto_item_append_text( pi, " 0x%04X", tvb_get_letohs( tvb, offset+4+(i*2) ) ); - proto_item_append_text( status_item, " 0x%04X", tvb_get_letohs( tvb, offset+4+(i*2) ) ); - } + for( i=0; i < add_stat_size; i ++ ) + proto_tree_add_item(add_status_tree, hf_cip_add_stat, tvb, offset+4+(i*2), 2, ENC_LITTLE_ENDIAN ); } - proto_item_set_len( status_item, 2 + add_stat_size ); + proto_item_set_len( status_item, 2 + add_stat_size*2); if( preq_info @@ -3383,24 +4805,31 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info tvbIOI = tvb_new_real_data( preq_info->pIOI, preq_info->IOILen * 2, preq_info->IOILen * 2); if ( tvbIOI ) { -#if 0 - pi = add_byte_array_text_to_proto_tree( cip_tree, tvbIOI, 0, req_path_size+1, "IOI: " ); - PROTO_ITEM_SET_GENERATED(pi); -#endif - pi = proto_tree_add_text( cip_tree, NULL, 0, 0, "Request Path Size: %d (words)", preq_info->IOILen ); PROTO_ITEM_SET_GENERATED(pi); /* Add the epath */ pi = proto_tree_add_text(cip_tree, NULL, 0, 0, "Request Path: "); PROTO_ITEM_SET_GENERATED(pi); - dissect_epath( tvbIOI, pi, 0, preq_info->IOILen*2, TRUE ); + + preq_info->ciaData = se_alloc(sizeof(cip_simple_request_info_t)); + dissect_epath( tvbIOI, pinfo, pi, 0, preq_info->IOILen*2, TRUE, preq_info->ciaData); tvb_free(tvbIOI); } } } - if ( preq_info && preq_info->dissector ) + /* Check to see if service is 'generic' */ + match_strval_idx((service & 0x7F), cip_sc_vals, &service_index); + if (service_index >= 0) + { + /* See if object dissector wants to override generic service handling */ + if(!dissector_try_heuristic(heur_subdissector_service, tvb, pinfo, item_tree)) + { + dissect_cip_generic_service_rsp(tvb, pinfo, cip_tree); + } + } + else if ( preq_info && preq_info->dissector ) { call_dissector( preq_info->dissector, tvb, pinfo, item_tree ); } @@ -3414,14 +4843,23 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info /* Request message */ /* Add path size to tree */ - req_path_size = tvb_get_guint8( tvb, offset+1 )*2; - proto_tree_add_text( cip_tree, tvb, offset+1, 1, "Request Path Size: %d (words)", req_path_size/2 ); + req_path_size = tvb_get_guint8( tvb, offset+1); + proto_tree_add_uint_format_value(cip_tree, hf_cip_request_path_size, + tvb, offset+1, 1, req_path_size, "%d (words)", req_path_size); /* Add the epath */ - pi = proto_tree_add_text(cip_tree, tvb, offset+2, req_path_size, "Request Path: "); - dissect_epath( tvb, pi, offset+2, req_path_size, FALSE ); + pi = proto_tree_add_text(cip_tree, tvb, offset+2, req_path_size*2, "Request Path: "); + if (preq_info) + { + preq_info->ciaData = se_alloc(sizeof(cip_simple_request_info_t)); + dissect_epath( tvb, pinfo, pi, offset+2, req_path_size*2, FALSE, preq_info->ciaData); + } + else + { + dissect_epath( tvb, pinfo, pi, offset+2, req_path_size*2, FALSE, NULL); + } - /* parse IOI; extract class ID */ + /* Take a sneak peak through the IOI to extract the class ID */ ioilen = tvb_get_guint8( tvb, offset + 1 ); if ( preq_info ) preq_info->dissector = NULL; @@ -3478,7 +4916,17 @@ dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info if( preq_info ) preq_info->bService = service; - if ( dissector ) + /* Check to see if service is 'generic' */ + match_strval_idx((service & 0x7F), cip_sc_vals, &service_index); + if (service_index >= 0) + { + /* See if object dissector wants to override generic service handling */ + if(!dissector_try_heuristic(heur_subdissector_service, tvb, pinfo, item_tree)) + { + dissect_cip_generic_service_req(tvb, pinfo, cip_tree); + } + } + else if ( dissector ) { call_dissector( dissector, tvb, pinfo, item_tree ); } @@ -3519,6 +4967,7 @@ dissect_cip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) preq_info->IOILen = 0; preq_info->pIOI = NULL; preq_info->pData = NULL; + preq_info->ciaData = NULL; enip_info->cip_info = preq_info; } dissect_cip_data( tree, tvb, 0, pinfo, enip_info->cip_info ); @@ -3547,288 +4996,244 @@ proto_register_cip(void) /* Setup list of header fields */ static hf_register_info hf[] = { - { &hf_cip_rr, - { "Request/Response", "cip.rr", - FT_UINT8, BASE_HEX, VALS(cip_sc_rr), 0x80, - "Request or Response message", HFILL } - }, - { &hf_cip_sc, - { "Service", "cip.sc", - FT_UINT8, BASE_HEX, VALS(cip_sc_vals), 0x7F, - "Service Code", HFILL } - }, - { &hf_cip_epath, - { "EPath", "cip.epath", - FT_BYTES, BASE_NONE, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_genstat, - { "General Status", "cip.genstat", - FT_UINT8, BASE_HEX, VALS(cip_gs_vals), 0, - NULL, HFILL } - }, - { &hf_cip_port, - { "Port", "cip.port", - FT_UINT8, BASE_DEC, NULL, 0, - "Port Identifier", HFILL } - }, - { &hf_cip_link_address_byte, - { "Link Address", "cip.linkaddress", - FT_UINT8, BASE_DEC, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_link_address_string, - { "Link Address", "cip.linkaddress", - FT_STRING, BASE_NONE, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_class8, - { "Class", "cip.class", - FT_UINT8, BASE_HEX, VALS(cip_class_names_vals), 0, - NULL, HFILL } - }, - { &hf_cip_class16, - { "Class", "cip.class", - FT_UINT16, BASE_HEX, VALS(cip_class_names_vals), 0, - NULL, HFILL } - }, - { &hf_cip_class32, - { "Class", "cip.class", - FT_UINT32, BASE_HEX, VALS(cip_class_names_vals), 0, - NULL, HFILL } - }, - { &hf_cip_instance8, - { "Instance", "cip.instance", - FT_UINT8, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_instance16, - { "Instance", "cip.instance", - FT_UINT16, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_instance32, - { "Instance", "cip.instance", - FT_UINT32, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_member8, - { "Member", "cip.member", - FT_UINT8, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_member16, - { "Member", "cip.member", - FT_UINT16, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_member32, - { "Member", "cip.member", - FT_UINT32, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_attribute8, - { "Attribute", "cip.attribute", - FT_UINT8, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_attribute16, - { "Attribute", "cip.attribute", - FT_UINT16, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_attribute32, - { "Attribute", "cip.attribute", - FT_UINT32, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_conpoint8, - { "Connection Point", "cip.connpoint", - FT_UINT8, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_conpoint16, - { "Connection Point", "cip.connpoint", - FT_UINT16, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_conpoint32, - { "Connection Point", "cip.connpoint", - FT_UINT16, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_symbol, - { "Symbol", "cip.symbol", - FT_STRING, BASE_NONE, NULL, 0, - "ANSI Extended Symbol Segment", HFILL } - }, - { &hf_cip_vendor, - { "Vendor ID", "cip.vendor", - FT_UINT16, BASE_HEX, VALS(cip_vendor_vals), 0, - NULL, HFILL } - }, - { &hf_cip_devtype, - { "Device Type", "cip.devtype", - FT_UINT16, BASE_DEC, VALS(cip_devtype_vals), 0, - NULL, HFILL } - }, - { &hf_cip_class_rev, - { "Class Revision", "cip.class.rev", - FT_UINT16, BASE_DEC, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_class_max_inst32, - { "Max Instance", "cip.class.max_inst", - FT_UINT32, BASE_DEC, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_class_num_inst32, - { "Number of Instances", "cip.class.num_inst", - FT_UINT32, BASE_DEC, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_reserved8, - { "Reserved", "cip.reserved", - FT_UINT8, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_fwo_comp, - { "Compatibility", "cip.fwo.cmp", - FT_UINT8, BASE_HEX, VALS(cip_com_bit_vals), 0x80, - "EKey: Compatibility bit", HFILL } - }, - { &hf_cip_fwo_mrev, - { "Major Revision", "cip.fwo.major", - FT_UINT8, BASE_DEC, NULL, 0x7F, - "EKey: Major Revision", HFILL } - } + { &hf_cip_service, { "Service", "cip.service", FT_UINT8, BASE_HEX, NULL, 0, "Service Code + Request/Response", HFILL }}, + { &hf_cip_reqrsp, { "Request/Response", "cip.rr", FT_UINT8, BASE_HEX, VALS(cip_sc_rr), 0x80, "Request or Response message", HFILL }}, + { &hf_cip_service_code, { "Service", "cip.sc", FT_UINT8, BASE_HEX, VALS(cip_sc_vals), 0x7F, "Service Code", HFILL }}, + { &hf_cip_epath, { "EPath", "cip.epath", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_genstat, { "General Status", "cip.genstat", FT_UINT8, BASE_HEX|BASE_EXT_STRING, &cip_gs_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_addstat_size, { "Additional Status Size", "cip.addstat_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_add_stat, { "Additional Status", "cip.addstat", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_request_path_size, { "Request Path Size", "cip.request_path_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + + { &hf_cip_path_segment, { "Path Segment", "cip.path_segment", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_path_segment_type, { "Path Segment Type", "cip.path_segment.type", FT_UINT8, BASE_DEC, VALS(cip_path_seg_vals), CI_SEGMENT_TYPE_MASK, NULL, HFILL }}, + { &hf_cip_port_segment, { "Port Segment", "cip.port_segment", FT_UINT8, BASE_HEX, NULL, CI_SEGMENT_TYPE_MASK, NULL, HFILL }}, + { &hf_cip_port_ex_link_addr, { "Extended Link Address", "cip.ex_linkaddress", FT_BOOLEAN, BASE_DEC, TFS(&tfs_true_false), CI_PORT_SEG_EX_LINK_ADDRESS, NULL, HFILL }}, + { &hf_cip_port, { "Port", "cip.port", FT_UINT8, BASE_DEC, NULL, CI_PORT_SEG_PORT_ID_MASK, "Port Identifier", HFILL }}, + { &hf_cip_link_address_byte, { "Link Address", "cip.linkaddress", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_link_address_size, { "Link Address Size", "cip.linkaddress_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_link_address_string, { "Link Address", "cip.linkaddress", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_logical_seg_type, { "Logical Segment Type", "cip.logical_segment.type", FT_UINT8, BASE_DEC, VALS(cip_logical_segment_type_vals), CI_LOGICAL_SEG_TYPE_MASK, NULL, HFILL }}, + { &hf_cip_logical_seg_format, { "Logical Segment Format", "cip.logical_segment.format", FT_UINT8, BASE_DEC, VALS(cip_logical_segment_format_vals), CI_LOGICAL_SEG_FORMAT_MASK, NULL, HFILL }}, + { &hf_cip_class8, { "Class", "cip.class", FT_UINT8, BASE_HEX|BASE_EXT_STRING, &cip_class_names_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_class16, { "Class", "cip.class", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_class_names_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_class32, { "Class", "cip.class", FT_UINT32, BASE_HEX|BASE_EXT_STRING, &cip_class_names_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_instance8, { "Instance", "cip.instance", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_instance16, { "Instance", "cip.instance", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_instance32, { "Instance", "cip.instance", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_member8, { "Member", "cip.member", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_member16, { "Member", "cip.member", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_member32, { "Member", "cip.member", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_attribute8, { "Attribute", "cip.attribute", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_attribute16, { "Attribute", "cip.attribute", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_attribute32, { "Attribute", "cip.attribute", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_conpoint8, { "Connection Point", "cip.connpoint", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_conpoint16, { "Connection Point", "cip.connpoint", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_conpoint32, { "Connection Point", "cip.connpoint", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_ekey, { "Electronic Key Segment", "cip.ekey", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_ekey_format, { "Key Format", "cip.ekey.format", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_ekey_vendor, { "Vendor ID", "cip.ekey.vendor", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_vendor_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_ekey_devtype, { "Device Type", "cip.ekey.devtype", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cip_devtype_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_ekey_prodcode, { "Product Code", "cip.ekey.product_code", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_ekey_compatibility, { "Compatibility", "cip.ekey.compatibility", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_ekey_comp_bit, { "Compatibility", "cip.ekey.comp_bit", FT_UINT8, BASE_HEX, VALS(cip_com_bit_vals), 0x80, "EKey: Compatibility bit", HFILL }}, + { &hf_cip_ekey_majorrev, { "Major Revision", "cip.ekey.major_rev", FT_UINT8, BASE_DEC, NULL, 0x7F, "EKey: Major Revision", HFILL }}, + { &hf_cip_ekey_minorrev, { "Minor Revision", "cip.ekey.minor_rev", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_data_seg_type, { "Data Segment Type", "cip.data_segment.type", FT_UINT8, BASE_DEC, VALS(cip_data_segment_type_vals), CI_DATA_SEG_TYPE_MASK, NULL, HFILL }}, + { &hf_cip_data_seg_size, { "Data Size", "cip.data_segment.size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_data_seg_item, { "Data", "cip.cip.data_segment.data", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_symbol, { "Symbol", "cip.symbol", FT_STRING, BASE_NONE, NULL, 0, "ANSI Extended Symbol Segment", HFILL }}, + { &hf_cip_network_seg_type, { "Network Segment Type", "cip.network_segment.type", FT_UINT8, BASE_DEC, VALS(cip_network_segment_type_vals), CI_NETWORK_SEG_TYPE_MASK, NULL, HFILL }}, + { &hf_cip_seg_schedule, { "Multiplier/Phase", "cip.network_segment.schedule", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_seg_fixed_tag, { "Fixed Tag", "cip.network_segment.fixed_tag", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_seg_prod_inhibit_time, { "Production Inhibit Time", "cip.network_segment.prod_inhibit", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + + { &hf_cip_vendor, { "Vendor ID", "cip.vendor", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_vendor_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_devtype, { "Device Type", "cip.devtype", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cip_devtype_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_class_rev, { "Class Revision", "cip.class.rev", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_class_max_inst32, { "Max Instance", "cip.class.max_inst", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_class_num_inst32, { "Number of Instances", "cip.class.num_inst", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_reserved8, { "Reserved", "cip.reserved", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_reserved16, { "Reserved", "cip.reserved", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_reserved24, { "Reserved", "cip.reserved", FT_UINT24, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_pad8, { "Pad Byte", "cip.pad", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + + { &hf_cip_sc_get_attr_list_attr_count, { "Attribute Count", "cip.getlist.attr_count", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_get_attr_list_attr_item, { "Attribute", "cip.getlist.attr_item", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_get_attr_list_attr_status, { "General Status", "cip.getlist.attr_status", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_gs_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_sc_get_attr_list_attr_data, { "Data", "cip.getlist.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_set_attr_list_attr_count, { "Attribute Count", "cip.setlist.attr_count", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_set_attr_list_attr_item, { "Attribute", "cip.setlist.attr_item", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_set_attr_list_attr_status, { "General Status", "cip.setlist.attr_status", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_gs_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_sc_set_attr_list_attr_data, { "Data", "cip.setlist.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + + { &hf_cip_sc_get_attribute_all_data, { "Data", "cip.getall.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_set_attribute_all_data, { "Data", "cip.setall.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_reset_param, { "Reset type", "cip.reset.type", FT_UINT8, BASE_DEC, VALS(cip_reset_type_vals), 0, NULL, HFILL }}, + { &hf_cip_sc_reset_data, { "Data", "cip.reset.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_start_data, { "Data", "cip.start.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_stop_data, { "Data", "cip.stop.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_create_instance, { "Instance", "cip.create.instance", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_create_data, { "Data", "cip.create.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_mult_serv_pack_num_services, { "Number of Services", "cip.msp.num_services", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_mult_serv_pack_offset, { "Offset", "cip.msp.offset", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_mult_serv_pack_num_replies, { "Number of Replies", "cip.msp.num_replies", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_delete_data, { "Data", "cip.delete.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_apply_attributes_data, { "Data", "cip.apply_attributes.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_get_attr_single_data, { "Data", "cip.getsingle.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_set_attr_single_data, { "Data", "cip.setsingle.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_find_next_object_max_instance, { "Maximum ID", "cip.find_next_object.max_instance", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_find_next_object_num_instances, { "Number of Instances:", "cip.find_next_object.num_instances", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_find_next_object_instance_item, { "Instance", "cip.find_next_object.instance", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_restore_data, { "Data", "cip.restore.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_save_data, { "Data", "cip.save.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_noop_data, { "Data", "cip.noop.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_get_member_data, { "Data", "cip.getmember.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_set_member_data, { "Data", "cip.setmember.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_insert_member_data, { "Data", "cip.insertmember.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_remove_member_data, { "Data", "cip.removemember.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_group_sync_is_sync, { "IsSynchronized", "cip.group_sync.data", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_sc_group_sync_data, { "Data", "cip.group_sync.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_data, { "Data", "cip.data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + + { &hf_id_vendor_id, { "Vendor ID", "cip.id.vendor_id", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_id_device_type, { "Device Type", "cip.id.device_type", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_id_produce_code, { "Product Code", "cip.id.produce_code", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_id_major_rev, { "Major Revision", "cip.id.major_rev", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_id_minor_rev, { "Minor Revision", "cip.id.minor_rev", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_id_status, { "Status", "cip.id.status", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_id_serial_number, { "Serial Number", "cip.id.serial_number", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_id_product_name, { "Product Name", "cip.id.product_name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, + + { &hf_msg_rout_num_classes, { "Number of Classes", "cip.mr.num_classes", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_msg_rout_classes, { "Class", "cip.mr.class", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_class_names_vals_ext, 0, NULL, HFILL }}, + { &hf_msg_rout_num_available, { "Number Available", "cip.mr.num_available", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_msg_rout_num_active, { "Number Active", "cip.mr.num_active", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_msg_rout_active_connections, { "Active Connection", "cip.mr.active_connections", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + + { &hf_conn_mgr_open_requests, { "Open Requests", "cip.cm.open_requests", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_conn_mgr_open_format_rejects, { "Open Format Rejects", "cip.cm.open_format_rejects", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_conn_mgr_open_resource_rejects, { "Open Resource Rejects", "cip.cm.open_resource_rejects", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_conn_mgr_other_open_rejects, { "Other Open Rejects", "cip.cm.other_open_rejects", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_conn_mgr_close_requests, { "Close Requests", "cip.cm.close_requests", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_conn_close_format_requests, { "Close Format Requests", "cip.cm.close_format_requests", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_conn_mgr_close_other_requests, { "Close Other Requests", "cip.cm.close_other_requests", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_conn_mgr_conn_timouts, { "Connection Timeouts", "cip.cm.conn_timouts", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, }; static hf_register_info hf_cm[] = { - - { &hf_cip_cm_ot_connid, - { "O->T Network Connection ID", "cip.cm.ot_connid", - FT_UINT32, BASE_HEX, NULL, 0, - "O->T Network Connection ID", HFILL } - }, - { &hf_cip_cm_to_connid, - { "T->O Network Connection ID", "cip.cm.to_connid", - FT_UINT32, BASE_HEX, NULL, 0, - "T->O Network Connection ID", HFILL } - }, - { &hf_cip_cm_conn_serial_num, - { "Connection Serial Number", "cip.cm.conn_serial_num", - FT_UINT16, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_cm_orig_serial_num, - { "Originator Serial Number", "cip.cm.orig_serial_num", - FT_UINT32, BASE_HEX, NULL, 0, - NULL, HFILL } - }, - { &hf_cip_cm_fwo_con_size, - { "Connection Size", "cip.cm.fwo.consize", - FT_UINT16, BASE_DEC, NULL, 0x01FF, - "Fwd Open: Connection size", HFILL } - }, - { &hf_cip_cm_lfwo_con_size, - { "Connection Size", "cip.cm.fwo.consize", - FT_UINT32, BASE_DEC, NULL, 0xFFFF, - "Large Fwd Open: Connection size", HFILL } - }, - { &hf_cip_cm_fwo_fixed_var, - { "Connection Size Type", "cip.cm.fwo.f_v", - FT_UINT16, BASE_DEC, VALS(cip_con_fw_vals), 0x0200, - "Fwd Open: Fixed or variable connection size", HFILL } - }, - { &hf_cip_cm_lfwo_fixed_var, - { "Connection Size Type", "cip.cm.fwo.f_v", - FT_UINT32, BASE_DEC, VALS(cip_con_fw_vals), 0x02000000, - "Large Fwd Open: Fixed or variable connection size", HFILL } - }, - { &hf_cip_cm_fwo_prio, - { "Priority", "cip.cm.fwo.prio", - FT_UINT16, BASE_DEC, VALS(cip_con_prio_vals), 0x0C00, - "Fwd Open: Connection priority", HFILL } - }, - { &hf_cip_cm_lfwo_prio, - { "Priority", "cip.cm.fwo.prio", - FT_UINT32, BASE_DEC, VALS(cip_con_prio_vals), 0x0C000000, - "Large Fwd Open: Connection priority", HFILL } - }, - { &hf_cip_cm_fwo_typ, - { "Connection Type", "cip.cm.fwo.type", - FT_UINT16, BASE_DEC, VALS(cip_con_type_vals), 0x6000, - "Fwd Open: Connection type", HFILL } - }, - { &hf_cip_cm_lfwo_typ, - { "Connection Type", "cip.cm.fwo.type", - FT_UINT32, BASE_DEC, VALS(cip_con_type_vals), 0x60000000, - "Large Fwd Open: Connection type", HFILL } - }, - { &hf_cip_cm_fwo_own, - { "Owner", "cip.cm.fwo.owner", - FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, - "Fwd Open: Redundant owner bit", HFILL } - }, - { &hf_cip_cm_lfwo_own, - { "Owner", "cip.cm.fwo.owner", - FT_UINT32, BASE_DEC, VALS(cip_con_owner_vals), 0x80000000, - "Large Fwd Open: Redundant owner bit", HFILL } - }, - { &hf_cip_cm_fwo_dir, - { "Direction", "cip.cm.fwo.dir", - FT_UINT8, BASE_DEC, VALS(cip_con_dir_vals), 0x80, - "Fwd Open: Direction", HFILL } - }, - { &hf_cip_cm_fwo_trigg, - { "Trigger", "cip.cm.fwo.trigger", - FT_UINT8, BASE_DEC, VALS(cip_con_trigg_vals), 0x70, - "Fwd Open: Production trigger", HFILL } - }, - { &hf_cip_cm_fwo_class, - { "Class", "cip.cm.fwo.transport", - FT_UINT8, BASE_DEC, VALS(cip_con_class_vals), 0x0F, - "Fwd Open: Transport Class", HFILL } - }, - { &hf_cip_cm_gco_conn, - { "Number of Connections", "cip.cm.gco.conn", - FT_UINT8, BASE_DEC, NULL, 0, - "GetConnOwner: Number of Connections", HFILL } - }, - { &hf_cip_cm_gco_coo_conn, - { "COO Connections", "cip.cm.gco.coo_conn", - FT_UINT8, BASE_DEC, NULL, 0, - "GetConnOwner: COO Connections", HFILL } - }, - { &hf_cip_cm_gco_roo_conn, - { "ROO Connections", "cip.cm.gco.roo_conn", - FT_UINT8, BASE_DEC, NULL, 0, - "GetConnOwner: ROO Connections", HFILL } - }, - { &hf_cip_cm_gco_la, - { "Last Action", "cip.cm.gco.la", - FT_UINT8, BASE_DEC, VALS(cip_con_last_action_vals), 0, - "GetConnOwner: Last Action", HFILL } - } + { &hf_cip_cm_sc, { "Service", "cip.cm.sc", FT_UINT8, BASE_HEX, VALS(cip_sc_vals_cm), 0x7F, NULL, HFILL }}, + { &hf_cip_cm_genstat, { "General Status", "cip.cm.genstat", FT_UINT8, BASE_HEX|BASE_EXT_STRING, &cip_gs_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_cm_addstat_size, { "Additional Status Size", "cip.cm.addstat_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ext_status, { "Extended Status", "cip.cm.ext_status", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_cm_ext_st_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_cm_add_status, { "Additional Status", "cip.cm.addstat", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_priority, { "Priority", "cip.cm.priority", FT_UINT8, BASE_DEC, NULL, 0x10, NULL, HFILL }}, + { &hf_cip_cm_tick_time, { "Tick time", "cip.cm.tick_time", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL }}, + { &hf_cip_cm_timeout_tick, { "Time-out ticks", "cip.cm.timeout_tick", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_timeout, { "Actual Time Out", "cip.cm.timeout", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ot_connid, { "O->T Network Connection ID", "cip.cm.ot_connid", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_to_connid, { "T->O Network Connection ID", "cip.cm.to_connid", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_conn_serial_num, { "Connection Serial Number", "cip.cm.conn_serial_num", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_vendor, { "Vendor ID", "cip.cm.vendor", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_vendor_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_cm_timeout_multiplier, { "Connection Timeout Multiplier", "cip.cm.timeout_multiplier", FT_UINT8, BASE_DEC, VALS(cip_con_time_mult_vals), 0, NULL, HFILL }}, + { &hf_cip_cm_ot_rpi, { "O->T RPI", "cip.cm.otrpi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ot_net_params32, { "O->T Network Connection Parameters", "cip.cm.ot_net_params", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ot_net_params16, { "O->T Network Connection Parameters", "cip.cm.ot_net_params", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_to_rpi, { "T->O RPI", "cip.cm.torpi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_to_net_params32, { "T->O Network Connection Parameters", "cip.cm.to_net_params", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_to_net_params16, { "T->O Network Connection Parameters", "cip.cm.to_net_params", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_transport_type_trigger, { "Transport Type/Trigger", "cip.cm.transport_type_trigger", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_conn_path_size, { "Connection Path Size", "cip.cm.connpath_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ot_api, { "O->T API", "cip.cm.otapi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_to_api, { "T->O API", "cip.cm.toapi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_app_reply_size, { "Application Reply Size", "cip.cm.app_reply_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_app_reply_data , { "Application Reply", "cip.cm.app_reply_data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_remain_path_size, { "Remaining Path Size", "cip.cm.remain_path_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_msg_req_size, { "Message Request Size", "cip.cm.msg_req_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_route_path_size, { "Route Path Size", "cip.cm.route_path_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_orig_serial_num, { "Originator Serial Number", "cip.cm.orig_serial_num", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_fwo_con_size, { "Connection Size", "cip.cm.fwo.consize", FT_UINT16, BASE_DEC, NULL, 0x01FF, "Fwd Open: Connection size", HFILL }}, + { &hf_cip_cm_lfwo_con_size, { "Connection Size", "cip.cm.fwo.consize", FT_UINT32, BASE_DEC, NULL, 0xFFFF, "Large Fwd Open: Connection size", HFILL }}, + { &hf_cip_cm_fwo_fixed_var, { "Connection Size Type", "cip.cm.fwo.f_v", FT_UINT16, BASE_DEC, VALS(cip_con_fw_vals), 0x0200, "Fwd Open: Fixed or variable connection size", HFILL }}, + { &hf_cip_cm_lfwo_fixed_var, { "Connection Size Type", "cip.cm.fwo.f_v", FT_UINT32, BASE_DEC, VALS(cip_con_fw_vals), 0x02000000, "Large Fwd Open: Fixed or variable connection size", HFILL }}, + { &hf_cip_cm_fwo_prio, { "Priority", "cip.cm.fwo.prio", FT_UINT16, BASE_DEC, VALS(cip_con_prio_vals), 0x0C00, "Fwd Open: Connection priority", HFILL }}, + { &hf_cip_cm_lfwo_prio, { "Priority", "cip.cm.fwo.prio", FT_UINT32, BASE_DEC, VALS(cip_con_prio_vals), 0x0C000000, "Large Fwd Open: Connection priority", HFILL }}, + { &hf_cip_cm_fwo_typ, { "Connection Type", "cip.cm.fwo.type", FT_UINT16, BASE_DEC, VALS(cip_con_type_vals), 0x6000, "Fwd Open: Connection type", HFILL }}, + { &hf_cip_cm_lfwo_typ, { "Connection Type", "cip.cm.fwo.type", FT_UINT32, BASE_DEC, VALS(cip_con_type_vals), 0x60000000, "Large Fwd Open: Connection type", HFILL }}, + { &hf_cip_cm_fwo_own, { "Owner", "cip.cm.fwo.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, "Fwd Open: Redundant owner bit", HFILL }}, + { &hf_cip_cm_lfwo_own, { "Owner", "cip.cm.fwo.owner", FT_UINT32, BASE_DEC, VALS(cip_con_owner_vals), 0x80000000, "Large Fwd Open: Redundant owner bit", HFILL }}, + { &hf_cip_cm_fwo_dir, { "Direction", "cip.cm.fwo.dir", FT_UINT8, BASE_DEC, VALS(cip_con_dir_vals), 0x80, "Fwd Open: Direction", HFILL }}, + { &hf_cip_cm_fwo_trigg, { "Trigger", "cip.cm.fwo.trigger", FT_UINT8, BASE_DEC, VALS(cip_con_trigg_vals), 0x70, "Fwd Open: Production trigger", HFILL }}, + { &hf_cip_cm_fwo_class, { "Class", "cip.cm.fwo.transport", FT_UINT8, BASE_DEC, VALS(cip_con_class_vals), 0x0F, "Fwd Open: Transport Class", HFILL }}, + { &hf_cip_cm_gco_conn, { "Number of Connections", "cip.cm.gco.conn", FT_UINT8, BASE_DEC, NULL, 0, "GetConnOwner: Number of Connections", HFILL }}, + { &hf_cip_cm_gco_coo_conn, { "COO Connections", "cip.cm.gco.coo_conn", FT_UINT8, BASE_DEC, NULL, 0, "GetConnOwner: COO Connections", HFILL }}, + { &hf_cip_cm_gco_roo_conn, { "ROO Connections", "cip.cm.gco.roo_conn", FT_UINT8, BASE_DEC, NULL, 0, "GetConnOwner: ROO Connections", HFILL }}, + { &hf_cip_cm_gco_last_action, { "Last Action", "cip.cm.gco.la", FT_UINT8, BASE_DEC, VALS(cip_con_last_action_vals), 0, "GetConnOwner: Last Action", HFILL }}, + { &hf_cip_cm_ext112_ot_rpi_type, { "Trigger", "cip.cm.ext112otrpi_type", FT_UINT8, BASE_DEC, VALS(cip_cm_rpi_type_vals), 0, NULL, HFILL }}, + { &hf_cip_cm_ext112_to_rpi_type, { "Trigger", "cip.cm.ext112torpi_type", FT_UINT8, BASE_DEC, VALS(cip_cm_rpi_type_vals), 0, NULL, HFILL }}, + { &hf_cip_cm_ext112_ot_rpi, { "Acceptable O->T RPI", "cip.cm.ext112otrpi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ext112_to_rpi, { "Acceptable T->O RPI", "cip.cm.ext112torpi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ext126_size, { "Maximum Size", "cip.cm.ext126_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ext127_size, { "Maximum Size", "cip.cm.ext127_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cm_ext128_size, { "Maximum Size", "cip.cm.ext128_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }} }; static hf_register_info hf_cco[] = { - { &hf_cip_cco_con_type, - { "Connection O_T", "cip.cco.con", - FT_UINT16, BASE_DEC, VALS(cip_con_vals), 0x001, - "Connection", HFILL } - }, - { &hf_cip_cco_ot_rtf, - { "O->T real time transfer format", "cip.cco.otrtf", - FT_UINT16, BASE_DEC, VALS(cip_con_rtf_vals), 0x000E, - "O->T real time transfer", HFILL } - }, - { &hf_cip_cco_to_rtf, - { "T->O real time transfer format", "cip.cco.tortf", - FT_UINT16, BASE_DEC, VALS(cip_con_rtf_vals), 0x0070, - "T->O real time transfer", HFILL } - }, + { &hf_cip_cco_sc, { "Service", "cip.cco.sc", FT_UINT8, BASE_HEX, VALS(cip_sc_vals_cco), 0x7F, NULL, HFILL }}, + { &hf_cip_cco_format_number, { "Format Number", "cip.cco.format_number", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_edit_signature, { "Edit Signature", "cip.cco.edit_signature", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_con_flags, { "Connection Flags", "cip.cco.connflags", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_con_type, { "Connection O_T", "cip.cco.con", FT_UINT16, BASE_DEC, VALS(cip_con_vals), 0x001, NULL, HFILL }}, + { &hf_cip_cco_ot_rtf, { "O->T real time transfer format", "cip.cco.otrtf", FT_UINT16, BASE_DEC, VALS(cip_con_rtf_vals), 0x000E, NULL, HFILL }}, + { &hf_cip_cco_to_rtf, { "T->O real time transfer format", "cip.cco.tortf", FT_UINT16, BASE_DEC, VALS(cip_con_rtf_vals), 0x0070, NULL, HFILL }}, + { &hf_cip_cco_tdi_vendor, { "Vendor ID", "cip.cco.tdi.vendor", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_vendor_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_cco_tdi_devtype, { "Device Type", "cip.cco.tdi.devtype", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cip_devtype_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_cco_tdi_prodcode, { "Product Code", "cip.cco.tdi.product_code", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_tdi_compatibility, { "Compatibility", "cip.cco.tdi.compatibility", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_tdi_comp_bit, { "Compatibility", "cip.cco.tdi.comp_bit", FT_UINT8, BASE_HEX, VALS(cip_com_bit_vals), 0x80, NULL, HFILL }}, + { &hf_cip_cco_tdi_majorrev, { "Major Revision", "cip.cco.tdi.major_rev", FT_UINT8, BASE_DEC, NULL, 0x7F, NULL, HFILL }}, + { &hf_cip_cco_tdi_minorrev, { "Minor Revision", "cip.cco.tdi.minor_rev", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_pdi_vendor, { "Vendor ID", "cip.cco.pdi.vendor", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &cip_vendor_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_cco_pdi_devtype, { "Device Type", "cip.cco.pdi.devtype", FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cip_devtype_vals_ext, 0, NULL, HFILL }}, + { &hf_cip_cco_pdi_prodcode, { "Product Code", "cip.cco.pdi.product_code", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_pdi_compatibility, { "Compatibility", "cip.cco.pdi.compatibility", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_pdi_comp_bit, { "Compatibility", "cip.cco.pdi.comp_bit", FT_UINT8, BASE_HEX, VALS(cip_com_bit_vals), 0x80, NULL, HFILL }}, + { &hf_cip_cco_pdi_majorrev, { "Major Revision", "cip.cco.pdi.major_rev", FT_UINT8, BASE_DEC, NULL, 0x7F, NULL, HFILL }}, + { &hf_cip_cco_pdi_minorrev, { "Minor Revision", "cip.cco.pdi.minor_rev", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_cs_data_index, { "CS Data Index Number", "cip.cco.cs_data_index", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_timeout_multiplier, { "Connection Timeout Multiplier", "cip.cco.timeout_multiplier", FT_UINT8, BASE_DEC, VALS(cip_con_time_mult_vals), 0, NULL, HFILL }}, + { &hf_cip_cco_ot_rpi, { "O->T RPI", "cip.cco.otrpi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_ot_net_param32, { "O->T Network Connection Parameters", "cip.cco.ot_net_params", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_ot_net_param16, { "O->T Network Connection Parameters", "cip.cco.ot_net_params", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_to_rpi, { "T->O RPI", "cip.cco.torpi", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_to_net_param16, { "T->O Network Connection Parameters", "cip.cco.to_net_params", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_to_net_param32, { "T->O Network Connection Parameters", "cip.cco.to_net_params", FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_transport_type_trigger, { "Transport Type/Trigger", "cip.cco.transport_type_trigger", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_fwo_con_size, { "Connection Size", "cip.cco.consize", FT_UINT16, BASE_DEC, NULL, 0x01FF, NULL, HFILL }}, + { &hf_cip_cco_lfwo_con_size, { "Connection Size", "cip.cco.consize", FT_UINT32, BASE_DEC, NULL, 0xFFFF, NULL, HFILL }}, + { &hf_cip_cco_fwo_fixed_var, { "Connection Size Type", "cip.cco.f_v", FT_UINT16, BASE_DEC, VALS(cip_con_fw_vals), 0x0200, NULL, HFILL }}, + { &hf_cip_cco_lfwo_fixed_var, { "Connection Size Type", "cip.cco.f_v", FT_UINT32, BASE_DEC, VALS(cip_con_fw_vals), 0x02000000, NULL, HFILL }}, + { &hf_cip_cco_fwo_prio, { "Priority", "cip.cco.prio", FT_UINT16, BASE_DEC, VALS(cip_con_prio_vals), 0x0C00, NULL, HFILL }}, + { &hf_cip_cco_lfwo_prio, { "Priority", "cip.cco.prio", FT_UINT32, BASE_DEC, VALS(cip_con_prio_vals), 0x0C000000, NULL, HFILL }}, + { &hf_cip_cco_fwo_typ, { "Connection Type", "cip.cco.type", FT_UINT16, BASE_DEC, VALS(cip_con_type_vals), 0x6000, NULL, HFILL }}, + { &hf_cip_cco_lfwo_typ, { "Connection Type", "cip.cco.type", FT_UINT32, BASE_DEC, VALS(cip_con_type_vals), 0x60000000, NULL, HFILL }}, + { &hf_cip_cco_fwo_own, { "Owner", "cip.cco.owner", FT_UINT16, BASE_DEC, VALS(cip_con_owner_vals), 0x8000, NULL, HFILL }}, + { &hf_cip_cco_lfwo_own, { "Owner", "cip.cco.owner", FT_UINT32, BASE_DEC, VALS(cip_con_owner_vals), 0x80000000, NULL, HFILL }}, + { &hf_cip_cco_fwo_dir, { "Direction", "cip.cco.dir", FT_UINT8, BASE_DEC, VALS(cip_con_dir_vals), 0x80, NULL, HFILL }}, + { &hf_cip_cco_fwo_trigger, { "Trigger", "cip.cco.trigger", FT_UINT8, BASE_DEC, VALS(cip_con_trigg_vals), 0x70, NULL, HFILL }}, + { &hf_cip_cco_fwo_class, { "Class", "cip.cco.transport", FT_UINT8, BASE_DEC, VALS(cip_con_class_vals), 0x0F, NULL, HFILL }}, + { &hf_cip_cco_conn_path_size, { "Connection Path Size", "cip.cco.connpath_size", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_proxy_config_size, { "Proxy Config Data Size", "cip.cco.proxy_config_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_target_config_size, { "Target Config Data Size", "cip.cco.proxy_config_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_iomap_format_number, { "Format number", "cip.cco.iomap_format_number", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_iomap_size, { "Attribute size", "cip.cco.iomap_size", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_connection_disable, { "Connection Disable", "cip.cco.connection_disable", FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL }}, + { &hf_cip_cco_net_conn_param_attr, { "Net Connection Parameter Attribute Selection", "cip.cco.net_conn_param_attr", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_proxy_config_data, { "Proxy Config Data", "cip.cco.proxy_config_data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_target_config_data, { "Target Config Data", "cip.cco.target_config_data", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_iomap_attribute, { "Attribute Data", "cip.cco.iomap", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_safety, { "Safety Parameters", "cip.cco.safety", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_cip_cco_change_type, { "Change Type", "cip.cco.change_type", FT_UINT16, BASE_DEC, cip_cco_change_type_vals, 0, NULL, HFILL }}, }; /* Setup protocol subtree array */ @@ -3836,21 +5241,23 @@ proto_register_cip(void) &ett_cip_class_generic, &ett_cip, &ett_path, + &ett_path_seg, &ett_ekey_path, &ett_rrsc, &ett_mcsc, &ett_cia_path, &ett_data_seg, + &ett_data_seg_data, &ett_cmd_data, &ett_port_path, - &ett_status_item - }; - - static gint *ett_mr[] = { - &ett_cip_class_mr, - &ett_mr_rrsc, - &ett_mr_mult_ser, - &ett_mr_cmd_data + &ett_network_seg, + &ett_status_item, + &ett_add_status_item, + &ett_cip_get_attribute_list, + &ett_cip_get_attribute_list_item, + &ett_cip_set_attribute_list, + &ett_cip_set_attribute_list_item, + &ett_cip_mult_service_packet }; static gint *ett_cm[] = { @@ -3858,7 +5265,9 @@ proto_register_cip(void) &ett_cm_rrsc, &ett_cm_mes_req, &ett_cm_ncp, - &ett_cm_cmd_data + &ett_cm_cmd_data, + &ett_cm_ttt, + &ett_cm_add_status_item }; static gint *ett_cco[] = { @@ -3867,9 +5276,11 @@ proto_register_cip(void) &ett_cco_con_status, &ett_cco_con_flag, &ett_cco_tdi, + &ett_cco_pdi, &ett_cco_ncp, &ett_cco_rrsc, - &ett_cco_cmd_data + &ett_cco_cmd_data, + &ett_cco_ttt }; /* Register the protocol name and description */ @@ -3889,10 +5300,6 @@ proto_register_cip(void) "CIPCLS", "cipcls"); /* Register the protocol name and description */ - proto_cip_class_mr = proto_register_protocol("CIP Message Router", - "CIPMR", "cipmr"); - proto_register_subtree_array(ett_mr, array_length(ett_mr)); - proto_cip_class_cm = proto_register_protocol("CIP Connection Manager", "CIPCM", "cipcm"); proto_register_field_array(proto_cip_class_cm, hf_cm, array_length(hf_cm)); @@ -3904,6 +5311,11 @@ proto_register_cip(void) proto_register_subtree_array(ett_cco, array_length(ett_cco)); register_init_routine(&cip_init_protocol); + + /* Register a heuristic dissector on the service of the message so objects + * can override the dissector for common services */ + register_heur_dissector_list("cip.sc", &heur_subdissector_service); + } /* end of proto_register_cip() */ @@ -3921,10 +5333,6 @@ proto_reg_handoff_cip(void) cip_class_generic_handle = new_create_dissector_handle( dissect_cip_class_generic, proto_cip_class_generic ); dissector_add_uint( "cip.class.iface", 0, cip_class_generic_handle ); - /* Create and register dissector handle for Message Router */ - cip_class_mr_handle = new_create_dissector_handle( dissect_cip_class_mr, proto_cip_class_mr ); - dissector_add_uint( "cip.class.iface", CI_CLS_MR, cip_class_mr_handle ); - /* Create and register dissector handle for Connection Manager */ cip_class_cm_handle = new_create_dissector_handle( dissect_cip_class_cm, proto_cip_class_cm ); dissector_add_uint( "cip.class.iface", CI_CLS_CM, cip_class_cm_handle ); @@ -3932,6 +5340,7 @@ proto_reg_handoff_cip(void) /* Create and register dissector handle for Connection Configuration Object */ cip_class_cco_handle = new_create_dissector_handle( dissect_cip_class_cco, proto_cip_class_cco ); dissector_add_uint( "cip.class.iface", CI_CLS_CCO, cip_class_cco_handle ); + heur_dissector_add("cip.sc", dissect_class_cco_heur, proto_cip_class_cco); } /* end of proto_reg_handoff_cip() */ diff --git a/epan/dissectors/packet-cip.h b/epan/dissectors/packet-cip.h index ebb9f894a0..b821f58d9b 100644 --- a/epan/dissectors/packet-cip.h +++ b/epan/dissectors/packet-cip.h @@ -116,6 +116,7 @@ #define CI_GRC_MEMBER_NOT_SETTABLE 0x29 #define CI_GRC_G2_SERVER_FAILURE 0x2A #define CI_GRC_UNKNOWN_MB_ERROR 0x2B +#define CI_GRC_ATTRIBUTE_NOT_GET 0x2C #define CI_GRC_STILL_PROCESSING 0xFF @@ -129,6 +130,9 @@ #define CI_SYMBOLIC_SEGMENT 0x60 #define CI_DATA_SEGMENT 0x80 +#define CI_PORT_SEG_EX_LINK_ADDRESS 0x10 +#define CI_PORT_SEG_PORT_ID_MASK 0x0F + #define CI_LOGICAL_SEG_TYPE_MASK 0x1C #define CI_LOGICAL_SEG_CLASS_ID 0x00 #define CI_LOGICAL_SEG_INST_ID 0x04 @@ -148,15 +152,18 @@ #define CI_E_KEY_FORMAT_VAL 0x04 -#define CI_DATA_SEG_SIMPLE 0x80 -#define CI_DATA_SEG_SYMBOL 0x91 +#define CI_DATA_SEG_TYPE_MASK 0x1F +#define CI_DATA_SEG_SIMPLE 0x00 +#define CI_DATA_SEG_SYMBOL 0x11 -#define CI_NETWORK_SEG_TYPE_MASK 0x07 +#define CI_NETWORK_SEG_TYPE_MASK 0x1F #define CI_NETWORK_SEG_SCHEDULE 0x01 #define CI_NETWORK_SEG_FIXED_TAG 0x02 #define CI_NETWORK_SEG_PROD_INHI 0x03 +#define CI_NETWORK_SEG_SAFETY 0x10 +#define CI_NETWORK_SEG_EXTENDED 0x1F -/* Device Profile:s */ +/* Device Profiles */ #define DP_GEN_DEV 0x00 #define DP_AC_DRIVE 0x02 #define DP_MOTOR_OVERLOAD 0x03 @@ -201,1132 +208,71 @@ { SC_REMOVE_MEMBER, "Remove Member" }, \ { SC_GROUP_SYNC, "Group Sync" }, \ -/* Define vendor IDs (ControlNet + DeviceNet + EtherNet/IP) */ -#define VENDOR_ID_LIST \ - { 0, "Reserved" }, \ - { 1, "Rockwell Automation/Allen-Bradley" }, \ - { 2, "Namco Controls Corp." }, \ - { 3, "Honeywell Inc." }, \ - { 4, "Parker Hannifin Corp. (Veriflo Division)" }, \ - { 5, "Rockwell Automation/Reliance Elec." }, \ - { 6, "Reserved" }, \ - { 7, "SMC Corporation" }, \ - { 8, "Molex Incorporated" }, \ - { 9, "Western Reserve Controls Corp." }, \ - { 10, "Advanced Micro Controls Inc. (AMCI)" }, \ - { 11, "ASCO Pneumatic Controls" }, \ - { 12, "Banner Engineering Corp." }, \ - { 13, "Belden Wire & Cable Company" }, \ - { 14, "Cooper Interconnect" }, \ - { 15, "Reserved" }, \ - { 16, "Daniel Woodhead Co. (Woodhead Connectivity)" }, \ - { 17, "Dearborn Group Inc." }, \ - { 18, "Reserved" }, \ - { 19, "Helm Instrument Company" }, \ - { 20, "Huron Net Works" }, \ - { 21, "Lumberg, Inc." }, \ - { 22, "Online Development Inc.(Automation Value)" }, \ - { 23, "Vorne Industries, Inc." }, \ - { 24, "ODVA Special Reserve" }, \ - { 25, "Reserved" }, \ - { 26, "Festo Corporation" }, \ - { 27, "Reserved" }, \ - { 28, "Reserved" }, \ - { 29, "Reserved" }, \ - { 30, "Unico, Inc." }, \ - { 31, "Ross Controls" }, \ - { 32, "Reserved" }, \ - { 33, "Reserved" }, \ - { 34, "Hohner Corp." }, \ - { 35, "Micro Mo Electronics, Inc." }, \ - { 36, "MKS Instruments, Inc." }, \ - { 37, "Yaskawa Electric America formerly Magnetek Drives" }, \ - { 38, "Reserved" }, \ - { 39, "AVG Automation (Uticor)" }, \ - { 40, "Wago Corporation" }, \ - { 41, "Kinetics (Unit Instruments)" }, \ - { 42, "IMI Norgren Limited" }, \ - { 43, "BALLUFF, Inc." }, \ - { 44, "Yaskawa Electric America, Inc." }, \ - { 45, "Eurotherm Controls Inc" }, \ - { 46, "ABB Industrial Systems" }, \ - { 47, "Omron Corporation" }, \ - { 48, "TURCk, Inc." }, \ - { 49, "Grayhill Inc." }, \ - { 50, "Real Time Automation (C&ID)" }, \ - { 51, "Reserved" }, \ - { 52, "Numatics, Inc." }, \ - { 53, "Lutze, Inc." }, \ - { 54, "Reserved" }, \ - { 55, "Reserved" }, \ - { 56, "Softing GmbH" }, \ - { 57, "Pepperl + Fuchs" }, \ - { 58, "Spectrum Controls, Inc." }, \ - { 59, "D.I.P. Inc. MKS Inst." }, \ - { 60, "Applied Motion Products, Inc." }, \ - { 61, "Sencon Inc." }, \ - { 62, "High Country Tek" }, \ - { 63, "SWAC Automation Consult GmbH" }, \ - { 64, "Clippard Instrument Laboratory" }, \ - { 65, "Reserved" }, \ - { 66, "Reserved" }, \ - { 67, "Reserved" }, \ - { 68, "Eaton Electrical" }, \ - { 69, "Reserved" }, \ - { 70, "Reserved" }, \ - { 71, "Toshiba International Corp." }, \ - { 72, "Control Technology Incorporated" }, \ - { 73, "TCS (NZ) Ltd." }, \ - { 74, "Hitachi, Ltd." }, \ - { 75, "ABB Robotics Products AB" }, \ - { 76, "NKE Corporation" }, \ - { 77, "Rockwell Software, Inc." }, \ - { 78, "Escort Memory Systems (A Datalogic Group Co.)" }, \ - { 79, "Reserved" }, \ - { 80, "Industrial Devices Corporation" }, \ - { 81, "IXXAT Automation GmbH" }, \ - { 82, "Mitsubishi Electric Automation, Inc." }, \ - { 83, "OPTO-22" }, \ - { 84, "Reserved" }, \ - { 85, "Reserved" }, \ - { 86, "Horner Electric" }, \ - { 87, "Burkert Werke GmbH & Co. KG" }, \ - { 88, "Reserved" }, \ - { 89, "Industrial Indexing Systems, Inc." }, \ - { 90, "HMS Industrial Networks AB" }, \ - { 91, "Robicon" }, \ - { 92, "Helix Technology (Granville-Phillips)" }, \ - { 93, "Arlington Laboratory" }, \ - { 94, "Advantech Co. Ltd." }, \ - { 95, "Square D Company" }, \ - { 96, "Digital Electronics Corp." }, \ - { 97, "Danfoss" }, \ - { 98, "Reserved" }, \ - { 99, "Reserved" }, \ - { 100, "Bosch Rexroth Corporation, Pneumatics" }, \ - { 101, "Applied Materials, Inc." }, \ - { 102, "Showa Electric Wire & Cable Co." }, \ - { 103, "Pacific Scientific (API Controls Inc.)" }, \ - { 104, "Sharp Manufacturing Systems Corp." }, \ - { 105, "Olflex Wire & Cable, Inc." }, \ - { 106, "Reserved" }, \ - { 107, "Unitrode" }, \ - { 108, "Beckhoff Automation GmbH" }, \ - { 109, "National Instruments" }, \ - { 110, "Mykrolis Corporations (Millipore)" }, \ - { 111, "International Motion Controls Corp." }, \ - { 112, "Reserved" }, \ - { 113, "SEG Kempen GmbH" }, \ - { 114, "Reserved" }, \ - { 115, "Reserved" }, \ - { 116, "MTS Systems Corp." }, \ - { 117, "Krones, Inc" }, \ - { 118, "Reserved" }, \ - { 119, "EXOR Electronic R & D" }, \ - { 120, "SIEI S.p.A." }, \ - { 121, "KUKA Roboter GmbH" }, \ - { 122, "Reserved" }, \ - { 123, "SEC (Samsung Electronics Co., Ltd)" }, \ - { 124, "Binary Electronics Ltd" }, \ - { 125, "Flexible Machine Controls" }, \ - { 126, "Reserved" }, \ - { 127, "ABB Inc. (Entrelec)" }, \ - { 128, "MAC Valves, Inc." }, \ - { 129, "Auma Actuators Inc" }, \ - { 130, "Toyoda Machine Works, Ltd" }, \ - { 131, "Reserved" }, \ - { 132, "Reserved" }, \ - { 133, "Balogh T.A.G., Corporation" }, \ - { 134, "TR Systemtechnik GmbH" }, \ - { 135, "UNIPULSE Corporation" }, \ - { 136, "Reserved" }, \ - { 137, "Reserved" }, \ - { 138, "Conxall Corporation Inc." }, \ - { 139, "Reserved" }, \ - { 140, "Reserved" }, \ - { 141, "Kuramo Electric Co., Ltd." }, \ - { 142, "Creative Micro Designs" }, \ - { 143, "GE Industrial Systems" }, \ - { 144, "Leybold Vacuum GmbH" }, \ - { 145, "Siemens Energy & Automation/Drives" }, \ - { 146, "Kodensha Ltd" }, \ - { 147, "Motion Engineering, Inc." }, \ - { 148, "Honda Engineering Co., Ltd" }, \ - { 149, "EIM Valve Controls" }, \ - { 150, "Melec Inc." }, \ - { 151, "Sony Manufacturing Systems Corporation" }, \ - { 152, "North American Mfg." }, \ - { 153, "WATLOW" }, \ - { 154, "Japan Radio Co., Ltd" }, \ - { 155, "NADEX Co., Ltd" }, \ - { 156, "Ametek Automation & Process Technologies" }, \ - { 157, "Reserved" }, \ - { 158, "KVASER AB" }, \ - { 159, "IDEC IZUMI Corporation" }, \ - { 160, "Mitsubishi Heavy Industries Ltd" }, \ - { 161, "Mitsubishi Electric Corporation" }, \ - { 162, "Horiba-STEC Inc." }, \ - { 163, "esd electronic system design gmbh" }, \ - { 164, "DAIHEN Corporation" }, \ - { 165, "Tyco Valves & Controls/Keystone" }, \ - { 166, "EBARA Corporation" }, \ - { 167, "Reserved" }, \ - { 168, "Reserved" }, \ - { 169, "Hokuyo Electric Co. Ltd" }, \ - { 170, "Pyramid Solutions, Inc." }, \ - { 171, "Denso Wave Incorporated" }, \ - { 172, "HLS Hard-Line Solutions Inc" }, \ - { 173, "Caterpillar, Inc." }, \ - { 174, "PDL Electronics Ltd." }, \ - { 175, "Reserved" }, \ - { 176, "Red Lion Controls" }, \ - { 177, "ANELVA Corporation" }, \ - { 178, "Toyo Denki Seizo KK" }, \ - { 179, "Sanyo Denki Co., Ltd" }, \ - { 180, "Advanced Energy Japan K.K. (Aera Japan)" }, \ - { 181, "Pilz GmbH & Co" }, \ - { 182, "Marsh Bellofram-Bellofram PCD Division" }, \ - { 183, "Reserved" }, \ - { 184, "M-SYSTEM Co. Ltd" }, \ - { 185, "Nissin Electric Co., Ltd" }, \ - { 186, "Hitachi Metals Ltd." }, \ - { 187, "Oriental Motor Company" }, \ - { 188, "A&D Co., Ltd" }, \ - { 189, "Phasetronics, Inc." }, \ - { 190, "Cummins Engine Company" }, \ - { 191, "Deltron Inc." }, \ - { 192, "Geneer Corporation" }, \ - { 193, "Anatol Automation, Inc." }, \ - { 194, "Reserved" }, \ - { 195, "Reserved" }, \ - { 196, "Medar, Inc." }, \ - { 197, "Comdel Inc." }, \ - { 198, "Advanced Energy Industries, Inc" }, \ - { 199, "Reserved" }, \ - { 200, "DAIDEN Co., Ltd" }, \ - { 201, "CKD Corporation" }, \ - { 202, "Toyo Electric Corporation" }, \ - { 203, "Reserved" }, \ - { 204, "AuCom Electronics Ltd" }, \ - { 205, "Shinko Electric Co., Ltd" }, \ - { 206, "Vector Informatik GmbH" }, \ - { 207, "Reserved" }, \ - { 208, "Moog Inc." }, \ - { 209, "Contemporary Controls" }, \ - { 210, "Tokyo Sokki Kenkyujo Co., Ltd" }, \ - { 211, "Schenck-AccuRate, Inc." }, \ - { 212, "The Oilgear Company" }, \ - { 213, "Reserved" }, \ - { 214, "ASM Japan K.K." }, \ - { 215, "HIRATA Corp." }, \ - { 216, "SUNX Limited" }, \ - { 217, "Meidensha Corp." }, \ - { 218, "NIDEC SANKYO CORPORATION (Sankyo Seiki Mfg. Co., Ltd)" }, \ - { 219, "KAMRO Corp." }, \ - { 220, "Nippon System Development Co., Ltd" }, \ - { 221, "EBARA Technologies Inc." }, \ - { 222, "Reserved" }, \ - { 223, "Reserved" }, \ - { 224, "SG Co., Ltd" }, \ - { 225, "Vaasa Institute of Technology" }, \ - { 226, "MKS Instruments (ENI Technology)" }, \ - { 227, "Tateyama System Laboratory Co., Ltd." }, \ - { 228, "QLOG Corporation" }, \ - { 229, "Matric Limited Inc." }, \ - { 230, "NSD Corporation" }, \ - { 231, "Reserved" }, \ - { 232, "Sumitomo Wiring Systems, Ltd" }, \ - { 233, "Group 3 Technology Ltd" }, \ - { 234, "CTI Cryogenics" }, \ - { 235, "POLSYS CORP" }, \ - { 236, "Ampere Inc." }, \ - { 237, "Reserved" }, \ - { 238, "Simplatroll Ltd" }, \ - { 239, "Reserved" }, \ - { 240, "Reserved" }, \ - { 241, "Leading Edge Design" }, \ - { 242, "Humphrey Products" }, \ - { 243, "Schneider Automation, Inc." }, \ - { 244, "Westlock Controls Corp." }, \ - { 245, "Nihon Weidmuller Co., Ltd" }, \ - { 246, "Brooks Instrument (Div. of Emerson)" }, \ - { 247, "Reserved" }, \ - { 248, " Moeller GmbH" }, \ - { 249, "Varian Vacuum Products" }, \ - { 250, "Yokogawa Electric Corporation" }, \ - { 251, "Electrical Design Daiyu Co., Ltd" }, \ - { 252, "Omron Software Co., Ltd" }, \ - { 253, "BOC Edwards" }, \ - { 254, "Control Technology Corporation" }, \ - { 255, "Bosch Rexroth" }, \ - { 256, "Turck" }, \ - { 257, "Control Techniques PLC" }, \ - { 258, "Hardy Instruments, Inc." }, \ - { 259, "LS Industrial Systems" }, \ - { 260, "E.O.A. Systems Inc." }, \ - { 261, "Reserved" }, \ - { 262, "New Cosmos Electric Co., Ltd." }, \ - { 263, "Sense Eletronica LTDA" }, \ - { 264, "Xycom, Inc." }, \ - { 265, "Baldor Electric" }, \ - { 266, "Reserved" }, \ - { 267, "Patlite Corporation" }, \ - { 268, "Reserved" }, \ - { 269, "Mogami Wire & Cable Corporation" }, \ - { 270, "Welding Technology Corporation (WTC)" }, \ - { 271, "Reserved" }, \ - { 272, "Deutschmann Automation GmbH" }, \ - { 273, "ICP Panel-Tec Inc." }, \ - { 274, "Bray Controls USA" }, \ - { 275, "Reserved" }, \ - { 276, "Status Technologies" }, \ - { 277, "Trio Motion Technology Ltd" }, \ - { 278, "Sherrex Systems Ltd" }, \ - { 279, "Adept Technology, Inc." }, \ - { 280, "Spang Power Electronics" }, \ - { 281, "Reserved" }, \ - { 282, "Acrosser Technology Co., Ltd" }, \ - { 283, "Hilscher GmbH" }, \ - { 284, "IMAX Corporation" }, \ - { 285, "Electronic Innovation, Inc. (Falter Engineering)" }, \ - { 286, "Netlogic Inc." }, \ - { 287, "Bosch Rexroth Corporation, Indramat" }, \ - { 288, "Reserved" }, \ - { 289, "Reserved" }, \ - { 290, "Murata Machinery Ltd." }, \ - { 291, "MTT Company Ltd." }, \ - { 292, "Kanematsu Semiconductor Corp." }, \ - { 293, "Takebishi Electric Sales Co." }, \ - { 294, "Tokyo Electron Device Ltd" }, \ - { 295, "PFU Limited" }, \ - { 296, "Hakko Automation Co., Ltd." }, \ - { 297, "Advanet Inc." }, \ - { 298, "Tokyo Electron Software Technologies Ltd." }, \ - { 299, "Reserved" }, \ - { 300, "Shinagawa Electric Wire Co., Ltd." }, \ - { 301, "Yokogawa M&C Corporation" }, \ - { 302, "KONAN Electric Co., Ltd." }, \ - { 303, "Binar Elektronik AB" }, \ - { 304, "Furukawa Electric Co." }, \ - { 305, "Cooper Energy Services" }, \ - { 306, "Schleicher GmbH & Co." }, \ - { 307, "Hirose Electric Co., Ltd" }, \ - { 308, "Western Servo Design Inc." }, \ - { 309, "Prosoft Technology" }, \ - { 310, "Reserved" }, \ - { 311, "Towa Shoko Co., Ltd" }, \ - { 312, "Kyopal Co., Ltd" }, \ - { 313, "Extron Co." }, \ - { 314, "Wieland Electric GmbH" }, \ - { 315, "SEW Eurodrive GmbH" }, \ - { 316, "Aera Corporation" }, \ - { 317, "STA Reutlingen" }, \ - { 318, "Reserved" }, \ - { 319, "Fuji Electric Co., Ltd." }, \ - { 320, "Reserved" }, \ - { 321, "Reserved" }, \ - { 322, "ifm efector, inc." }, \ - { 323, "Reserved" }, \ - { 324, "IDEACOD-Hohner Automation S.A." }, \ - { 325, "CommScope Inc." }, \ - { 326, "GE Fanuc Automation North America, Inc." }, \ - { 327, "Matsushita Electric Industrial Co., Ltd" }, \ - { 328, "Okaya Electronics Corporation" }, \ - { 329, "KASHIYAMA Industries, Ltd" }, \ - { 330, "JVC" }, \ - { 331, "Interface Corporation" }, \ - { 332, "Grape Systems Inc." }, \ - { 333, "Reserved" }, \ - { 344, "Reserved" }, \ - { 335, "Toshiba IT & Control Systems Corporation" }, \ - { 336, "Sanyo Machine Works, Ltd." }, \ - { 337, "Vansco Electronics Ltd." }, \ - { 338, "Dart Container Corp." }, \ - { 339, "Livingston & Co., Inc." }, \ - { 340, "Alfa Laval LKM as" }, \ - { 341, "BF ENTRON Ltd. (British Federal)" }, \ - { 342, "Bekaert Engineering NV" }, \ - { 343, "Ferran Scientific Inc." }, \ - { 344, "KEBA AG" }, \ - { 345, "Endress + Hauser" }, \ - { 346, "Reserved" }, \ - { 347, "ABB ALSTOM Power UK Ltd. (EGT)" }, \ - { 348, "Berger Lahr GmbH" }, \ - { 349, "Reserved" }, \ - { 350, "Federal Signal Corp." }, \ - { 351, "Kawasaki Robotics (USA), Inc." }, \ - { 352, "Bently Nevada Corporation" }, \ - { 353, "Reserved" }, \ - { 354, "FRABA Posital GmbH" }, \ - { 355, "Elsag Bailey, Inc." }, \ - { 356, "Fanuc Robotics America" }, \ - { 357, "Reserved" }, \ - { 358, "Surface Combustion, Inc." }, \ - { 359, "Reserved" }, \ - { 360, "AILES Electronics Ind. Co., Ltd." }, \ - { 361, "Wonderware Corporation" }, \ - { 362, "Particle Measuring Systems, Inc." }, \ - { 363, "Reserved" }, \ - { 364, "Reserved" }, \ - { 365, "BITS Co., Ltd" }, \ - { 366, "Japan Aviation Electronics Industry Ltd" }, \ - { 367, "Keyence Corporation" }, \ - { 368, "Kuroda Precision Industries Ltd." }, \ - { 369, "Mitsubishi Electric Semiconductor Application" }, \ - { 370, "Nippon Seisen Cable, Ltd." }, \ - { 371, "Omron ASO Co., Ltd" }, \ - { 372, "Seiko Seiki Co., Ltd." }, \ - { 373, "Sumitomo Heavy Industries, Ltd." }, \ - { 374, "Tango Computer Service Corporation" }, \ - { 375, "Technology Service, Inc." }, \ - { 376, "Toshiba Information Systems (Japan) Corporation" }, \ - { 377, "TOSHIBA Schneider Inverter Corporation" }, \ - { 378, "Toyooki Kogyo Co., Ltd." }, \ - { 379, "XEBEC" }, \ - { 380, "Madison Cable Corporation" }, \ - { 381, "Hitati Engineering & Services Co., Ltd" }, \ - { 382, "TEM-TECH Lab Co., Ltd" }, \ - { 383, "International Laboratory Corporation" }, \ - { 384, "Dyadic Systems Co., Ltd." }, \ - { 385, "SETO Electronics Industry Co., Ltd" }, \ - { 386, "Tokyo Electron Kyushu Limited" }, \ - { 387, "KEI System Co., Ltd" }, \ - { 388, "Reserved" }, \ - { 389, "Asahi Engineering Co., Ltd" }, \ - { 390, "Contrex Inc." }, \ - { 391, "Paradigm Controls Ltd." }, \ - { 392, "Reserved" }, \ - { 393, "Ohm Electric Co., Ltd." }, \ - { 394, "RKC Instrument Inc." }, \ - { 395, "Suzuki Motor Corporation" }, \ - { 396, "Custom Servo Motors Inc." }, \ - { 397, "PACE Control Systems" }, \ - { 398, "Reserved" }, \ - { 399, "Reserved" }, \ - { 400, "LINTEC Co., Ltd." }, \ - { 401, "Hitachi Cable Ltd." }, \ - { 402, "BUSWARE Direct" }, \ - { 403, "Eaton Electric B.V. (former Holec Holland N.V.)" }, \ - { 404, "VAT Vakuumventile AG" }, \ - { 405, "Scientific Technologies Incorporated" }, \ - { 406, "Alfa Instrumentos Eletronicos Ltda" }, \ - { 407, "TWK Elektronik GmbH" }, \ - { 408, "ABB Welding Systems AB" }, \ - { 409, "BYSTRONIC Maschinen AG" }, \ - { 410, "Kimura Electric Co., Ltd" }, \ - { 411, "Nissei Plastic Industrial Co., Ltd" }, \ - { 412, "Reserved" }, \ - { 413, "Kistler-Morse Corporation" }, \ - { 414, "Proteous Industries Inc." }, \ - { 415, "IDC Corporation" }, \ - { 416, "Nordson Corporation" }, \ - { 417, "Rapistan Systems" }, \ - { 418, "LP-Elektronik GmbH" }, \ - { 419, "GERBI & FASE S.p.A.(Fase Saldatura)" }, \ - { 420, "Phoenix Digital Corporation" }, \ - { 421, "Z-World Engineering" }, \ - { 422, "Honda R&D Co., Ltd." }, \ - { 423, "Bionics Instrument Co., Ltd." }, \ - { 424, "Teknic, Inc." }, \ - { 425, "R.Stahl, Inc." }, \ - { 426, "Reserved" }, \ - { 427, "Ryco Graphic Manufacturing Inc." }, \ - { 428, "Giddings & Lewis, Inc." }, \ - { 429, "Koganei Corporation" }, \ - { 430, "Reserved" }, \ - { 431, "Nichigoh Communication Electric Wire Co., Ltd." }, \ - { 432, "Reserved" }, \ - { 433, "Fujikura Ltd." }, \ - { 434, "AD Link Technology Inc." }, \ - { 435, "StoneL Corporation" }, \ - { 436, "Computer Optical Products, Inc." }, \ - { 437, "CONOS Inc." }, \ - { 438, "Erhardt + Leimer GmbH" }, \ - { 439, "UNIQUE Co. Ltd" }, \ - { 440, "Roboticsware, Inc." }, \ - { 441, "Nachi Fujikoshi Corporation" }, \ - { 442, "Hengstler GmbH" }, \ - { 443, "Reserved" }, \ - { 444, "SUNNY GIKEN Inc." }, \ - { 445, "Lenze Drive Systems GmbH" }, \ - { 446, "CD Systems B.V." }, \ - { 447, "FMT/Aircraft Gate Support Systems AB" }, \ - { 448, "Axiomatic Technologies Corp" }, \ - { 449, "Embedded System Products, Inc." }, \ - { 450, "Reserved" }, \ - { 451, "Mencom Corporation" }, \ - { 452, "Reserved" }, \ - { 453, "Matsushita Welding Systems Co., Ltd." }, \ - { 454, "Dengensha Mfg. Co. Ltd." }, \ - { 455, "Quinn Systems Ltd." }, \ - { 456, "Tellima Technology Ltd" }, \ - { 457, "MDT, Software" }, \ - { 458, "Taiwan Keiso Co., Ltd" }, \ - { 459, "Pinnacle Systems" }, \ - { 460, "Ascom Hasler Mailing Sys" }, \ - { 461, "INSTRUMAR Limited" }, \ - { 462, "Reserved" }, \ - { 463, "Navistar International Transportation Corp" }, \ - { 464, "Huettinger Elektronik GmbH + Co. KG" }, \ - { 465, "OCM Technology Inc." }, \ - { 466, "Professional Supply Inc." }, \ - { 467, "Control Solutions" }, \ - { 468, "Baumer IVO GmbH & Co. KG" }, \ - { 469, "Worcester Controls Corporation" }, \ - { 470, "Pyramid Technical Consultants, Inc." }, \ - { 471, "Reserved" }, \ - { 472, "Apollo Fire Detectors Limited" }, \ - { 473, "Avtron Manufacturing, Inc." }, \ - { 474, "Reserved" }, \ - { 475, "Tokyo Keiso Co., Ltd." }, \ - { 476, "Daishowa Swiki Co., Ltd." }, \ - { 477, "Kojima Instruments Inc." }, \ - { 478, "Shimadzu Corporation" }, \ - { 479, "Tatsuta Electric Wire & Cable Co., Ltd." }, \ - { 480, "MECS Corporation" }, \ - { 481, "Tahara Electric" }, \ - { 482, "Koyo Electronics" }, \ - { 483, "Clever Devices" }, \ - { 484, "GCD Hardware & Software GmbH" }, \ - { 485, "Reserved" }, \ - { 486, "Miller Electric Mfg Co." }, \ - { 487, "GEA Tuchenhagen GmbH" }, \ - { 488, "Riken Keiki Co., LTD" }, \ - { 489, "Keisokugiken Corporation" }, \ - { 490, "Fuji Machine Mfg. Co., Ltd" }, \ - { 491, "Reserved" }, \ - { 492, "Nidec-Shimpo Corp." }, \ - { 493, "UTEC Corporation" }, \ - { 494, "Sanyo Electric Co. Ltd." }, \ - { 495, "Reserved" }, \ - { 496, "Reserved" }, \ - { 497, "Okano Electric Wire Co. Ltd" }, \ - { 498, "Shimaden Co. Ltd." }, \ - { 499, "Teddington Controls Ltd" }, \ - { 500, "Reserved" }, \ - { 501, "VIPA GmbH" }, \ - { 502, "Warwick Manufacturing Group" }, \ - { 503, "Danaher Controls" }, \ - { 504, "Reserved" }, \ - { 505, "Reserved" }, \ - { 506, "American Science & Engineering" }, \ - { 507, "Accutron Controls International Inc." }, \ - { 508, "Norcott Technologies Ltd" }, \ - { 509, "TB Woods, Inc" }, \ - { 510, "Proportion-Air, Inc." }, \ - { 511, "SICK Stegmann GmbH" }, \ - { 512, "Reserved" }, \ - { 513, "Edwards Signaling" }, \ - { 514, "Sumitomo Metal Industries, Ltd" }, \ - { 515, "Cosmo Instruments Co., Ltd." }, \ - { 516, "Denshosha Co., Ltd." }, \ - { 517, "Kaijo Corp." }, \ - { 518, "Michiproducts Co., Ltd." }, \ - { 519, "Miura Corporation" }, \ - { 520, "TG Information Network Co., Ltd." }, \ - { 521, "Fujikin , Inc." }, \ - { 522, "Estic Corp." }, \ - { 523, "GS Hydraulic Sales" }, \ - { 524, "Reserved" }, \ - { 525, "MTE Limited" }, \ - { 526, "Hyde Park Electronics, Inc." }, \ - { 527, "Pfeiffer Vacuum GmbH" }, \ - { 528, "Cyberlogic Technologies" }, \ - { 529, "OKUMA Corporation FA Systems Division" }, \ - { 530, "Reserved" }, \ - { 531, "Hitachi Kokusai Electric Co., Ltd." }, \ - { 532, "SHINKO TECHNOS Co., Ltd." }, \ - { 533, "Itoh Electric Co., Ltd." }, \ - { 534, "Colorado Flow Tech Inc." }, \ - { 535, "Love Controls Division/Dwyer Inst." }, \ - { 536, "Alstom Drives and Controls" }, \ - { 537, "The Foxboro Company" }, \ - { 538, "Tescom Corporation" }, \ - { 539, "Reserved" }, \ - { 540, "Atlas Copco Controls UK" }, \ - { 541, "Reserved" }, \ - { 542, "Autojet Technologies" }, \ - { 543, "Prima Electronics S.p.A." }, \ - { 544, "PMA GmbH" }, \ - { 545, "Shimafuji Electric Co., Ltd" }, \ - { 546, "Oki Electric Industry Co., Ltd" }, \ - { 547, "Kyushu Matsushita Electric Co., Ltd" }, \ - { 548, "Nihon Electric Wire & Cable Co., Ltd" }, \ - { 549, "Tsuken Electric Ind Co., Ltd" }, \ - { 550, "Tamadic Co." }, \ - { 551, "MAATEL SA" }, \ - { 552, "OKUMA America" }, \ - { 553, "Control Techniques PLC-NA" }, \ - { 554, "TPC Wire & Cable" }, \ - { 555, "ATI Industrial Automation" }, \ - { 556, "Microcontrol (Australia) Pty Ltd" }, \ - { 557, "Serra Soldadura, S.A." }, \ - { 558, "Southwest Research Institute" }, \ - { 559, "Cabinplant International" }, \ - { 560, "Sartorius Mechatronics T&H GmbH" }, \ - { 561, "Comau S.p.A. Robotics & Final Assembly Division" }, \ - { 562, "Phoenix Contact" }, \ - { 563, "Yokogawa MAT Corporation" }, \ - { 564, "asahi sangyo co., ltd." }, \ - { 565, "Reserved" }, \ - { 566, "Akita Myotoku Ltd." }, \ - { 567, "OBARA Corp." }, \ - { 568, "Suetron Electronic GmbH" }, \ - { 569, "Reserved" }, \ - { 570, "Serck Controls Limited" }, \ - { 571, "Fairchild Industrial Products Company" }, \ - { 572, "ARO S.A." }, \ - { 573, "M2C GmbH" }, \ - { 574, "Shin Caterpillar Mitsubishi Ltd." }, \ - { 575, "Santest Co., Ltd." }, \ - { 576, "Cosmotechs Co., Ltd." }, \ - { 577, "Hitachi Electric Systems" }, \ - { 578, "Smartscan Ltd" }, \ - { 579, "Woodhead Software & Electronics France" }, \ - { 580, "Athena Controls, Inc." }, \ - { 581, "Syron Engineering & Manufacturing, Inc." }, \ - { 582, "Asahi Optical Co., Ltd." }, \ - { 583, "Sansha Electric Mfg. Co., Ltd." }, \ - { 584, "Nikki Denso Co., Ltd." }, \ - { 585, "Star Micronics, Co., Ltd." }, \ - { 586, "Ecotecnia Socirtat Corp." }, \ - { 587, "AC Technology Corp." }, \ - { 588, "West Instruments Limited" }, \ - { 589, "NTI Limited" }, \ - { 590, "Delta Computer Systems, Inc." }, \ - { 591, "FANUC Ltd." }, \ - { 592, "Hearn-Gu Lee" }, \ - { 593, "ABB Automation Products" }, \ - { 594, "Orion Machinery Co., Ltd." }, \ - { 595, "Reserved" }, \ - { 596, "Wire-Pro, Inc." }, \ - { 597, "Beijing Huakong Technology Co. Ltd." }, \ - { 598, "Yokoyama Shokai Co., Ltd." }, \ - { 599, "Toyogiken Co., Ltd." }, \ - { 600, "Coester Equipamentos Eletronicos Ltda." }, \ - { 601, "Reserved" }, \ - { 602, "Electroplating Engineers of Japan Ltd." }, \ - { 603, "ROBOX S.p.A." }, \ - { 604, "Spraying Systems Company" }, \ - { 605, "Benshaw Inc." }, \ - { 606, "ZPA-DP A.S." }, \ - { 607, "Wired Rite Systems" }, \ - { 608, "Tandis Research, Inc." }, \ - { 609, "SSD Drives GmbH" }, \ - { 610, "ULVAC Japan Ltd." }, \ - { 611, "DYNAX Corporation" }, \ - { 612, "Nor-Cal Products, Inc." }, \ - { 613, "Aros Electronics AB" }, \ - { 614, "Jun-Tech Co., Ltd." }, \ - { 615, "HAN-MI Co. Ltd." }, \ - { 616, "uniNtech (formerly SungGi Internet)" }, \ - { 617, "Hae Pyung Electronics Reserch Institute" }, \ - { 618, "Milwaukee Electronics" }, \ - { 619, "OBERG Industries" }, \ - { 620, "Parker Hannifin/Compumotor Division" }, \ - { 621, "TECHNO DIGITAL CORPORATION" }, \ - { 622, "Network Supply Co., Ltd." }, \ - { 623, "Union Electronics Co., Ltd." }, \ - { 624, "Tritronics Services PM Ltd." }, \ - { 625, "Rockwell Automation-Sprecher+Schuh" }, \ - { 626, "Matsushita Electric Industrial Co., Ltd/Motor Co." }, \ - { 627, "Rolls-Royce Energy Systems, Inc." }, \ - { 628, "JEONGIL INTERCOM CO., LTD" }, \ - { 629, "Interroll Corp." }, \ - { 630, "Hubbell Wiring Device-Kellems (Delaware)" }, \ - { 631, "Intelligent Motion Systems" }, \ - { 632, "Reserved" }, \ - { 633, "INFICON AG" }, \ - { 634, "Hirschmann, Inc." }, \ - { 635, "The Siemon Company" }, \ - { 636, "YAMAHA Motor Co. Ltd." }, \ - { 637, "aska corporation" }, \ - { 638, "Woodhead Connectivity" }, \ - { 639, "Trimble AB" }, \ - { 640, "Murrelektronik GmbH" }, \ - { 641, "Creatrix Labs, Inc." }, \ - { 642, "TopWorx" }, \ - { 643, "Kumho Industrial Co., Ltd." }, \ - { 644, "Wind River Systems, Inc." }, \ - { 645, "Bihl & Wiedemann GmbH" }, \ - { 646, "Harmonic Drive Systems Inc." }, \ - { 647, "Rikei Corporation" }, \ - { 648, "BL Autotec, Ltd." }, \ - { 649, "Hana Information & Technology Co., Ltd." }, \ - { 650, "Seoil Electric Co., Ltd." }, \ - { 651, "Fife Corporation" }, \ - { 652, "Shanghai Electrical Apparatus Research Institute" }, \ - { 653, "Reserved" }, \ - { 654, "Parasense Development Centre" }, \ - { 655, "Reserved" }, \ - { 656, "Reserved" }, \ - { 657, "Six Tau S.p.A." }, \ - { 658, "Aucos GmbH" }, \ - { 659, "Rotork Controls" }, \ - { 660, "Automationdirect.com" }, \ - { 661, "Thermo BLH" }, \ - { 662, "System Controls, Ltd." }, \ - { 663, "Univer S.p.A." }, \ - { 664, "MKS-Tenta Technology" }, \ - { 665, "Lika Electronic SNC" }, \ - { 666, "Mettler-Toledo, Inc." }, \ - { 667, "DXL USA Inc." }, \ - { 668, "Rockwell Automation/Entek IRD Intl." }, \ - { 669, "Nippon Otis Elevator Company" }, \ - { 670, "Sinano Electric, Co., Ltd." }, \ - { 671, "Sony Manufacturing Systems" }, \ - { 672, "Reserved" }, \ - { 673, "Contec Co., Ltd." }, \ - { 674, "Automated Solutions" }, \ - { 675, "Controlweigh" }, \ - { 676, "Reserved" }, \ - { 677, "Fincor Electronics" }, \ - { 678, "Cognex Corporation" }, \ - { 679, "Qualiflow" }, \ - { 680, "Weidmuller, Inc." }, \ - { 681, "Morinaga Milk Industry Co., Ltd." }, \ - { 682, "Takagi Industrial Co., Ltd." }, \ - { 683, "Wittenstein AG" }, \ - { 684, "Sena Technologies, Inc." }, \ - { 685, "Reserved" }, \ - { 686, "APV Products Unna" }, \ - { 687, "Creator Teknisk Utvedkling AB" }, \ - { 688, "Reserved" }, \ - { 689, "Mibu Denki Industrial Co., Ltd." }, \ - { 690, "Takamastsu Machineer Section" }, \ - { 691, "Startco Engineering Ltd." }, \ - { 692, "Reserved" }, \ - { 693, "Holjeron" }, \ - { 694, "ALCATEL High Vacuum Technology" }, \ - { 695, "Taesan LCD Co., Ltd." }, \ - { 696, "POSCON" }, \ - { 697, "VMIC" }, \ - { 698, "Matsushita Electric Works, Ltd." }, \ - { 699, "IAI Corporation" }, \ - { 700, "Horst GmbH" }, \ - { 701, "MicroControl GmbH & Co." }, \ - { 702, "Leine & Linde AB" }, \ - { 703, "Reserved" }, \ - { 704, "EC Elettronica Srl" }, \ - { 705, "VIT Software HB" }, \ - { 706, "Bronkhorst High-Tech B.V." }, \ - { 707, "Optex Co., Ltd." }, \ - { 708, "Yosio Electronic Co." }, \ - { 709, "Terasaki Electric Co., Ltd." }, \ - { 710, "Sodick Co., Ltd." }, \ - { 711, "MTS Systems Corporation-Automation Division" }, \ - { 712, "Mesa Systemtechnik" }, \ - { 713, "SHIN HO SYSTEM Co., Ltd." }, \ - { 714, "Goyo Electronics Co, Ltd." }, \ - { 715, "Loreme" }, \ - { 716, "SAB Brockskes GmbH & Co. KG" }, \ - { 717, "Trumpf Laser GmbH + Co. KG" }, \ - { 718, "Niigata Electronic Instruments Co., Ltd." }, \ - { 719, "Yokogawa Digital Computer Corporation" }, \ - { 720, "O.N. Electronic Co., Ltd." }, \ - { 721, "Industrial Control Communication, Inc." }, \ - { 722, "ABB, Inc." }, \ - { 723, "ElectroWave USA, Inc." }, \ - { 724, "Industrial Network Controls, LLC" }, \ - { 725, "KDT Systems Co., Ltd." }, \ - { 726, "SEFA Technology Inc." }, \ - { 727, "Nippon POP Rivets and Fasteners Ltd." }, \ - { 728, "Yamato Scale Co., Ltd." }, \ - { 729, "Zener Electric" }, \ - { 730, "GSE Scale Systems" }, \ - { 731, "ISAS (Integrated Switchgear & Sys. Pty Ltd)" }, \ - { 732, "Beta LaserMike Limited" }, \ - { 733, "TOEI Electric Co., Ltd." }, \ - { 734, "Hakko Electronics Co., Ltd" }, \ - { 735, "Reserved" }, \ - { 736, "RFID, Inc." }, \ - { 737, "Adwin Corporation" }, \ - { 738, "Osaka Vacuum, Ltd." }, \ - { 739, "A-Kyung Motion, Inc." }, \ - { 740, "Camozzi S.P. A." }, \ - { 741, "Crevis Co., LTD" }, \ - { 742, "Rice Lake Weighing Systems" }, \ - { 743, "Linux Network Services" }, \ - { 744, "KEB Antriebstechnik GmbH" }, \ - { 745, "Hagiwara Electric Co., Ltd." }, \ - { 746, "Glass Inc. International" }, \ - { 747, "Reserved" }, \ - { 748, "DVT Corporation" }, \ - { 749, "Woodward Governor" }, \ - { 750, "Mosaic Systems, Inc." }, \ - { 751, "Laserline GmbH" }, \ - { 752, "COM-TEC, Inc." }, \ - { 753, "Weed Instrument" }, \ - { 754, "Prof-face European Technology Center" }, \ - { 755, "Fuji Automation Co., Ltd." }, \ - { 756, "Matsutame Co., Ltd." }, \ - { 757, "Hitachi Via Mechanics, Ltd." }, \ - { 758, "Dainippon Screen Mfg. Co. Ltd." }, \ - { 759, "FLS Automation A/S" }, \ - { 760, "ABB Stotz Kontakt GmbH" }, \ - { 761, "Technical Marine Service" }, \ - { 762, "Advanced Automation Associates, Inc." }, \ - { 763, "Baumer Ident GmbH" }, \ - { 764, "Tsubakimoto Chain Co." }, \ - { 765, "Reserved" }, \ - { 766, "Furukawa Co., Ltd." }, \ - { 767, "Active Power" }, \ - { 768, "CSIRO Mining Automation" }, \ - { 769, "Matrix Integrated Systems" }, \ - { 770, "Digitronic Automationsanlagen GmbH" }, \ - { 771, "SICK STEGMANN Inc." }, \ - { 772, "TAE-Antriebstechnik GmbH" }, \ - { 773, "Electronic Solutions" }, \ - { 774, "Rocon L.L.C." }, \ - { 775, "Dijitized Communications Inc." }, \ - { 776, "Asahi Organic Chemicals Industry Co., Ltd." }, \ - { 777, "Hodensha" }, \ - { 778, "Harting, Inc. NA" }, \ - { 779, "Kubler GmbH" }, \ - { 780, "Yamatake Corporation" }, \ - { 781, "JEOL" }, \ - { 782, "Yamatake Industrial Systems Co., Ltd." }, \ - { 783, "HAEHNE Elektronische Messgerate GmbH" }, \ - { 784, "Ci Technologies Pty Ltd (for Pelamos Industries)" }, \ - { 785, "N. SCHLUMBERGER & CIE" }, \ - { 786, "Teijin Seiki Co., Ltd." }, \ - { 787, "DAIKIN Industries, Ltd" }, \ - { 788, "RyuSyo Industrial Co., Ltd." }, \ - { 789, "SAGINOMIYA SEISAKUSHO, INC." }, \ - { 790, "Seishin Engineering Co., Ltd." }, \ - { 791, "Japan Support System Ltd." }, \ - { 792, "Decsys" }, \ - { 793, "Metronix Messgerate u. Elektronik GmbH" }, \ - { 794, "Reserved" }, \ - { 795, "Vaccon Company, Inc." }, \ - { 796, "Siemens Energy & Automation, Inc." }, \ - { 797, "Ten X Technology, Inc." }, \ - { 798, "Tyco Electronics" }, \ - { 799, "Delta Power Electronics Center" }, \ - { 800, "Denker" }, \ - { 801, "Autonics Corporation" }, \ - { 802, "JFE Electronic Engineering Pty. Ltd." }, \ - { 803, "Reserved" }, \ - { 804, "Electro-Sensors, Inc." }, \ - { 805, "Digi International, Inc." }, \ - { 806, "Texas Instruments" }, \ - { 807, "ADTEC Plasma Technology Co., Ltd" }, \ - { 808, "SICK AG" }, \ - { 809, "Ethernet Peripherals, Inc." }, \ - { 810, "Animatics Corporation" }, \ - { 811, "Reserved" }, \ - { 812, "Process Control Corporation" }, \ - { 813, "SystemV. Inc." }, \ - { 814, "Danaher Motion SRL" }, \ - { 815, "SHINKAWA Sensor Technology, Inc." }, \ - { 816, "Tesch GmbH & Co. KG" }, \ - { 817, "Reserved" }, \ - { 818, "Trend Controls Systems Ltd." }, \ - { 819, "Guangzhou ZHIYUAN Electronic Co., Ltd." }, \ - { 820, "Mykrolis Corporation" }, \ - { 821, "Bethlehem Steel Corporation" }, \ - { 822, "KK ICP" }, \ - { 823, "Takemoto Denki Corporation" }, \ - { 824, "The Montalvo Corporation" }, \ - { 825, "Reserved" }, \ - { 826, "LEONI Special Cables GmbH" }, \ - { 827, "Reserved" }, \ - { 828, "ONO SOKKI CO.,LTD." }, \ - { 829, "Rockwell Samsung Automation" }, \ - { 830, "SHINDENGEN ELECTRIC MFG. CO. LTD" }, \ - { 831, "Origin Electric Co. Ltd." }, \ - { 832, "Quest Technical Solutions, Inc." }, \ - { 833, "LS Cable, Ltd." }, \ - { 834, "Enercon-Nord Electronic GmbH" }, \ - { 835, "Northwire Inc." }, \ - { 836, "Engel Elektroantriebe GmbH" }, \ - { 837, "The Stanley Works" }, \ - { 838, "Celesco Transducer Products, Inc." }, \ - { 839, "Chugoku Electric Wire and Cable Co." }, \ - { 840, "Kongsberg Simrad AS" }, \ - { 841, "Panduit Corporation" }, \ - { 842, "Spellman High Voltage Electronics Corp." }, \ - { 843, "Kokusai Electric Alpha Co., Ltd." }, \ - { 844, "Brooks Automation, Inc." }, \ - { 845, "ANYWIRE CORPORATION" }, \ - { 846, "Honda Electronics Co. Ltd" }, \ - { 847, "REO Elektronik AG" }, \ - { 848, "Fusion UV Systems, Inc." }, \ - { 849, "ASI Advanced Semiconductor Instruments GmbH" }, \ - { 850, "Datalogic, Inc." }, \ - { 851, "SoftPLC Corporation" }, \ - { 852, "Dynisco Instruments LLC" }, \ - { 853, "WEG Industrias SA" }, \ - { 854, "Frontline Test Equipment, Inc." }, \ - { 855, "Tamagawa Seiki Co., Ltd." }, \ - { 856, "Multi Computing Co., Ltd." }, \ - { 857, "RVSI" }, \ - { 858, "Commercial Timesharing Inc." }, \ - { 859, "Tennessee Rand Automation LLC" }, \ - { 860, "Wacogiken Co., Ltd" }, \ - { 861, "Reflex Integration Inc." }, \ - { 862, "Siemens AG, A&D PI Flow Instruments" }, \ - { 863, "G. Bachmann Electronic GmbH" }, \ - { 864, "NT International" }, \ - { 865, "Schweitzer Engineering Laboratories" }, \ - { 866, "ATR Industrie-Elektronik GmbH Co." }, \ - { 867, "PLASMATECH Co., Ltd" }, \ - { 868, "Reserved" }, \ - { 869, "GEMU GmbH & Co. KG" }, \ - { 870, "Alcorn McBride Inc." }, \ - { 871, "MORI SEIKI CO., LTD" }, \ - { 872, "NodeTech Systems Ltd" }, \ - { 873, "Emhart Teknologies" }, \ - { 874, "Cervis, Inc." }, \ - { 875, "FieldServer Technologies (Div Sierra Monitor Corp)" }, \ - { 876, "NEDAP Power Supplies" }, \ - { 877, "Nippon Sanso Corporation" }, \ - { 878, "Mitomi Giken Co., Ltd." }, \ - { 879, "PULS GmbH" }, \ - { 880, "Reserved" }, \ - { 881, "Japan Control Engineering Ltd" }, \ - { 882, "Embedded Systems Korea (Former Zues Emtek Co Ltd.)" }, \ - { 883, "Automa SRL" }, \ - { 884, "Harms+Wende GmbH & Co KG" }, \ - { 885, "SAE-STAHL GmbH" }, \ - { 886, "Microwave Data Systems" }, \ - { 887, "Bernecker + Rainer Industrie-Elektronik GmbH" }, \ - { 888, "Hiprom Technologies" }, \ - { 889, "Reserved" }, \ - { 890, "Nitta Corporation" }, \ - { 891, "Kontron Modular Computers GmbH" }, \ - { 892, "Marlin Controls" }, \ - { 893, "ELCIS s.r.l." }, \ - { 894, "Acromag, Inc." }, \ - { 895, "Avery Weigh-Tronix" }, \ - { 896, "Reserved" }, \ - { 897, "Reserved" }, \ - { 898, "Reserved" }, \ - { 899, "Practicon Ltd" }, \ - { 900, "Schunk GmbH & Co. KG" }, \ - { 901, "MYNAH Technologies" }, \ - { 902, "Defontaine Groupe" }, \ - { 903, "Emerson Process Management Power & Water Solutions" }, \ - { 904, "F.A. Elec" }, \ - { 905, "Hottinger Baldwin Messtechnik GmbH" }, \ - { 906, "Coreco Imaging, Inc." }, \ - { 907, "London Electronics Ltd." }, \ - { 908, "HSD SpA" }, \ - { 909, "Comtrol Corporation" }, \ - { 910, "TEAM, S.A. (Tecnica Electronica de Automatismo Y Medida)" }, \ - { 911, "MAN B&W Diesel Ltd. Regulateurs Europa" }, \ - { 912, "Reserved" }, \ - { 913, "Reserved" }, \ - { 914, "Micro Motion, Inc." }, \ - { 915, "Eckelmann AG" }, \ - { 916, "Hanyoung Nux" }, \ - { 917, "Ransburg Industrial Finishing KK" }, \ - { 918, "Kun Hung Electric Co. Ltd." }, \ - { 919, "Brimos wegbebakening b.v." }, \ - { 920, "Nitto Seiki Co., Ltd" }, \ - { 921, "PPT Vision, Inc." }, \ - { 922, "Yamazaki Machinery Works" }, \ - { 923, "SCHMIDT Technology GmbH" }, \ - { 924, "Parker Hannifin SpA (SBC Division)" }, \ - { 925, "HIMA Paul Hildebrandt GmbH" }, \ - { 926, "RivaTek, Inc." }, \ - { 927, "Misumi Corporation" }, \ - { 928, "GE Multilin" }, \ - { 929, "Measurement Computing Corporation" }, \ - { 930, "Jetter AG" }, \ - { 931, "Tokyo Electronics Systems Corporation" }, \ - { 932, "Togami Electric Mfg. Co., Ltd." }, \ - { 933, "HK Systems" }, \ - { 934, "CDA Systems Ltd." }, \ - { 935, "Aerotech Inc." }, \ - { 936, "JVL Industrie Elektronik A/S" }, \ - { 937, "NovaTech Process Solutions LLC" }, \ - { 938, "Reserved" }, \ - { 939, "Cisco Systems" }, \ - { 940, "Grid Connect" }, \ - { 941, "ITW Automotive Finishing" }, \ - { 942, "HanYang System" }, \ - { 943, "ABB K.K. Technical Center" }, \ - { 944, "Taiyo Electric Wire & Cable Co., Ltd." }, \ - { 945, "Reserved" }, \ - { 946, "SEREN IPS INC" }, \ - { 947, "Belden CDT Electronics Division" }, \ - { 948, "ControlNet International" }, \ - { 949, "Gefran S.P.A." }, \ - { 950, "Jokab Safety AB" }, \ - { 951, "SUMITA OPTICAL GLASS, INC." }, \ - { 952, "Biffi Italia srl" }, \ - { 953, "Beck IPC GmbH" }, \ - { 954, "Copley Controls Corporation" }, \ - { 955, "Fagor Automation S. Coop." }, \ - { 956, "DARCOM" }, \ - { 957, "Frick Controls (div. of York International)" }, \ - { 958, "SymCom, Inc." }, \ - { 959, "Infranor" }, \ - { 960, "Kyosan Cable, Ltd." }, \ - { 961, "Varian Vacuum Technologies" }, \ - { 962, "Messung Systems" }, \ - { 963, "Xantrex Technology, Inc." }, \ - { 964, "StarThis Inc." }, \ - { 965, "Chiyoda Co., Ltd." }, \ - { 966, "Flowserve Corporation" }, \ - { 967, "Spyder Controls Corp." }, \ - { 968, "IBA AG" }, \ - { 969, "SHIMOHIRA ELECTRIC MFG.CO.,LTD" }, \ - { 970, "Reserved" }, \ - { 971, "Siemens L&A" }, \ - { 972, "Micro Innovations AG" }, \ - { 973, "Switchgear & Instrumentation" }, \ - { 974, "PRE-TECH CO., LTD." }, \ - { 975, "National Semiconductor" }, \ - { 976, "Invensys Process Systems" }, \ - { 977, "Ametek HDR Power Systems" }, \ - { 978, "Reserved" }, \ - { 979, "TETRA-K Corporation" }, \ - { 980, "C & M Corporation" }, \ - { 981, "Siempelkamp Maschinen" }, \ - { 982, "Reserved" }, \ - { 983, "Daifuku America Corporation" }, \ - { 984, "Electro-Matic Products Inc." }, \ - { 985, "BUSSAN MICROELECTRONICS CORP." }, \ - { 986, "ELAU AG" }, \ - { 987, "Hetronic USA" }, \ - { 988, "NIIGATA POWER SYSTEMS Co., Ltd." }, \ - { 989, "Software Horizons Inc." }, \ - { 990, "B3 Systems, Inc." }, \ - { 991, "Moxa Networking Co., Ltd." }, \ - { 992, "Reserved" }, \ - { 993, "S4 Integration" }, \ - { 994, "Elettro Stemi S.R.L." }, \ - { 995, "AquaSensors" }, \ - { 996, "Ifak System GmbH" }, \ - { 997, "SANKEI MANUFACTURING Co.,LTD." }, \ - { 998, "Emerson Network Power Co., Ltd." }, \ - { 999, "Fairmount Automation, Inc." }, \ - { 1000, "Bird Electronic Corporation" }, \ - { 1001, "Nabtesco Corporation" }, \ - { 1002, "AGM Electronics, Inc." }, \ - { 1003, "ARCX Inc." }, \ - { 1004, "DELTA I/O Co." }, \ - { 1005, "Chun IL Electric Ind. Co." }, \ - { 1006, "N-Tron" }, \ - { 1007, "Nippon Pneumatics/Fludics System CO.,LTD." }, \ - { 1008, "DDK Ltd." }, \ - { 1009, "Seiko Epson Corporation" }, \ - { 1010, "Halstrup-Walcher GmbH" }, \ - { 1011, "ITT" }, \ - { 1012, "Ground Fault Systems bv" }, \ - { 1013, "Scolari Engineering S.p.A." }, \ - { 1014, "Vialis Traffic bv" }, \ - { 1015, "Weidmueller Interface GmbH & Co. KG" }, \ - { 1016, "Shanghai Sibotech Automation Co. Ltd" }, \ - { 1017, "AEG Power Supply Systems GmbH" }, \ - { 1018, "Komatsu Electronics Inc." }, \ - { 1019, "Souriau" }, \ - { 1020, "Baumuller Chicago Corp." }, \ - { 1021, "J. Schmalz GmbH" }, \ - { 1022, "SEN Corporation" }, \ - { 1023, "Korenix Technology Co. Ltd" }, \ - { 1024, "Cooper Power Tools" }, \ - { 1025, "INNOBIS" }, \ - { 1026, "Shinho System" }, \ - { 1027, "Xm Services Ltd." }, \ - { 1028, "KVC Co., Ltd." }, \ - { 1029, "Sanyu Seiki Co., Ltd." }, \ - { 1030, "TuxPLC" }, \ - { 1031, "Northern Network Solutions" }, \ - { 1032, "Converteam GmbH" }, \ - { 1033, "Symbol Technologies" }, \ - { 1034, "S-TEAM Lab" }, \ - { 1035, "Maguire Products, Inc." }, \ - { 1036, "AC&T" }, \ - { 1037, "MITSUBISHI HEAVY INDUSTRIES, LTD. KOBE SHIPYARD & MACHINERY WORKS" }, \ - { 1038, "Hurletron Inc." }, \ - { 1039, "Chunichi Denshi Co., Ltd" }, \ - { 1040, "Cardinal Scale Mfg. Co." }, \ - { 1041, "BTR NETCOM via RIA Connect, Inc." }, \ - { 1042, "Base2" }, \ - { 1043, "ASRC Aerospace" }, \ - { 1044, "Beijing Stone Automation" }, \ - { 1045, "Changshu Switchgear Manufacture Ltd." }, \ - { 1046, "METRONIX Corp." }, \ - { 1047, "WIT" }, \ - { 1048, "ORMEC Systems Corp." }, \ - { 1049, "ASATech (China) Inc." }, \ - { 1050, "Controlled Systems Limited" }, \ - { 1051, "Mitsubishi Heavy Ind. Digital System Co., Ltd. (M.H.I.)" }, \ - { 1052, "Electrogrip" }, \ - { 1053, "TDS Automation" }, \ - { 1054, "T&C Power Conversion, Inc." }, \ - { 1055, "Robostar Co., Ltd" }, \ - { 1056, "Scancon A/S" }, \ - { 1057, "Haas Automation, Inc." }, \ - { 1058, "Eshed Technology" }, \ - { 1059, "Delta Electronic Inc." }, \ - { 1060, "Innovasic Semiconductor" }, \ - { 1061, "SoftDEL Systems Limited" }, \ - { 1062, "FiberFin, Inc." }, \ - { 1063, "Nicollet Technologies Corp." }, \ - { 1064, "B.F. Systems" }, \ - { 1065, "Empire Wire and Supply LLC" }, \ - { 1066, "Reserved" }, \ - { 1067, "Elmo Motion Control LTD" }, \ - { 1068, "Reserved" }, \ - { 1069, "Asahi Keiki Co., Ltd." }, \ - { 1070, "Joy Mining Machinery" }, \ - { 1071, "MPM Engineering Ltd" }, \ - { 1072, "Wolke Inks & Printers GmbH" }, \ - { 1073, "Mitsubishi Electric Engineering Co., Ltd." }, \ - { 1074, "COMET AG" }, \ - { 1075, "Real Time Objects & Systems, LLC" }, \ - { 1076, "MISCO Refractometer" }, \ - { 1077, "JT Engineering Inc." }, \ - { 1078, "Automated Packing Systems" }, \ - { 1079, "Niobrara R&D Corp." }, \ - { 1080, "Garmin Ltd." }, \ - { 1081, "Japan Mobile Platform Co., Ltd" }, \ - { 1082, "Advosol Inc." }, \ - { 1083, "ABB Global Services Limited" }, \ - { 1084, "Sciemetric Instruments Inc." }, \ - { 1085, "Tata Elxsi Ltd." }, \ - { 1086, "TPC Mechatronics, Co., Ltd." }, \ - { 1087, "Cooper Bussmann" }, \ - { 1088, "Trinite Automatisering B.V." }, \ - { 1089, "Peek Traffic B.V." }, \ - { 1090, "Acrison, Inc" }, \ - { 1091, "Applied Robotics, Inc." }, \ - { 1092, "FireBus Systems, Inc." }, \ - { 1093, "Beijing Sevenstar Huachuang Electronics" }, \ - { 1094, "Magnetek" }, \ - { 1095, "Microscan" }, \ - { 1096, "Air Water Inc." }, \ - { 1097, "Sensopart Industriesensorik GmbH" }, \ - { 1098, "Tiefenbach Control Systems GmbH" }, \ - { 1099, "INOXPA S.A" }, \ - { 1100, "Zurich University of Applied Sciences" }, \ - { 1101, "Ethernet Direct" }, \ - { 1102, "GSI-Micro-E Systems" }, \ - { 1103, "S-Net Automation Co., Ltd." }, \ - { 1104, "Power Electronics S.L." }, \ - { 1105, "Renesas Technology Corp." }, \ - { 1106, "NSWCCD-SSES" }, \ - { 1107, "Porter Engineering Ltd." }, \ - { 1108, "Meggitt Airdynamics, Inc." }, \ - { 1109, "Inductive Automation" }, \ - { 1110, "Neural ID" }, \ - { 1111, "EEPod LLC" }, \ - { 1112, "Hitachi Industrial Equipment Systems Co., Ltd." }, \ - { 1113, "Salem Automation" }, \ - { 1114, "port GmbH" }, \ - { 1115, "B & PLUS" }, \ - { 1116, "Graco Inc." }, \ - { 1117, "Altera Corporation" }, \ - { 1118, "Technology Brewing Corporation" }, +typedef struct cip_simple_request_info { + guint32 iClass; + guint32 iInstance; + guint32 iAttribute; + guint32 iMember; +} cip_simple_request_info_t; + +enum cip_datatype { + cip_bool, + cip_sint, + cip_int, + cip_dint, + cip_lint, + cip_usint, + cip_usint_array, + cip_uint, + cip_uint_array, + cip_udint, + cip_ulint, + cip_real, + cip_lreal, + cip_itime, + cip_time, + cip_ftime, + cip_ltime, + cip_short_string, + cip_string, + cip_byte, + cip_word, + cip_dword, + cip_lword, + cip_dissector_func, + + /* Currently not supported */ + cip_date, + cip_time_of_day, + cip_date_and_time, + cip_string2, + cip_stringN, + cip_stringi, +}; + +typedef int attribute_dissector_func(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len); +typedef struct attribute_info { + guint class_id; + gboolean class_instance; + guint attribute; + const char *text; + enum cip_datatype datatype; + int* phf; + attribute_dissector_func* pdissect; +} attribute_info_t; /* -** Exported variables +** Exported functions */ +extern void dissect_epath( tvbuff_t *tvb, packet_info *pinfo, proto_item *epath_item, int offset, int path_length, gboolean generate, cip_simple_request_info_t* req_data); -extern const value_string cip_devtype_vals[]; -extern const value_string cip_vendor_vals[]; +/* +** Exported variables +*/ +extern value_string_ext cip_gs_vals_ext; +extern value_string_ext cip_cm_ext_st_vals_ext; +extern value_string_ext cip_vendor_vals_ext; +extern value_string_ext cip_devtype_vals_ext; +extern value_string_ext cip_class_names_vals_ext; diff --git a/epan/dissectors/packet-enip.c b/epan/dissectors/packet-enip.c index 9a81c630fb..6f69031129 100644 --- a/epan/dissectors/packet-enip.c +++ b/epan/dissectors/packet-enip.c @@ -10,6 +10,10 @@ * Jan Bartels, Siempelkamp Maschinen- und Anlagenbau GmbH & Co. KG * Copyright 2007 * + * Ethernet/IP object support + * Michael Mann + * Copyright 2011 + * * $Id$ * * Wireshark - Network traffic analyzer @@ -35,9 +39,6 @@ # include "config.h" #endif -#include <stdlib.h> -#include <string.h> - #include <glib.h> #include <epan/packet.h> @@ -46,8 +47,8 @@ #include <epan/prefs.h> #include <epan/etypes.h> #include "packet-tcp.h" -#include "packet-enip.h" #include "packet-cip.h" +#include "packet-enip.h" /* Communication Ports */ #define ENIP_ENCAP_PORT 44818 /* EtherNet/IP located on port 44818 */ @@ -101,6 +102,7 @@ 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; @@ -131,10 +133,103 @@ static int hf_enip_cpf_cdi_seqcnt = -1; static int hf_enip_cpf_cai_connid = -1; static int hf_enip_cpf_sai_connid = -1; static int hf_enip_cpf_sai_seqnum = -1; +static int hf_enip_cpf_data = -1; static int hf_enip_response_in = -1; static int hf_enip_response_to = -1; static int hf_enip_time = -1; +static int hf_enip_connection_transport_data = -1; + +/* Parsed Attributes */ +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; +static int hf_elink_icontrol_control_bits_forced_duplex = -1; +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; /* Initialize the subtree pointers */ static gint ett_enip = -1; @@ -143,11 +238,17 @@ static gint ett_type_tree = -1; static gint ett_command_tree = -1; static gint ett_sockadd = -1; 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; +static gint ett_elink_interface_flags = -1; +static gint ett_elink_icontrol_bits = -1; static proto_tree *g_tree; static dissector_table_t subdissector_srrd_table; static dissector_table_t subdissector_sud_table; static dissector_handle_t data_handle; +static heur_dissector_list_t heur_subdissector_conndata_table; static gboolean enip_desegment = TRUE; @@ -229,15 +330,99 @@ static const value_string cdf_type_vals[] = { { 0, NULL } }; +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" }, -/* Translate function to string - True/False */ -static const value_string enip_true_false_vals[] = { - { 0, "False" }, - { 1, "True" }, + { 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" }, + { 3, "Auto-negotiation not attempted. Forced speed and duplex." }, + + { 0, NULL } +}; + +static const value_string enip_elink_iflags_reset_vals[] = { + { 0, "Activate change automatically" }, + { 1, "Device requires Reset service for change" }, - { 0, NULL } + { 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 } +}; /* Translate interface handle to string */ static const value_string enip_interface_handle_vals[] = { @@ -632,6 +817,228 @@ enip_get_connid(packet_info *pinfo, enip_request_key_t *prequest_key, guint32 co return conn_val->connid; } +int dissect_tcpip_status(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + proto_item* status_item; + proto_tree* status_tree; + + 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); + + 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); + proto_tree_add_item(status_tree, hf_tcpip_status_interface_config_pending, tvb, offset, 4, ENC_LITTLE_ENDIAN); + 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); + return 4; +} + +int dissect_tcpip_config_cap(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + proto_item* cap_item; + proto_tree* cap_tree; + + 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); + + 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); + 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); + 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); + return 4; +} + +int dissect_tcpip_config_control(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + proto_item* control_item; + proto_tree* control_tree; + + 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); + + 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); + proto_tree_add_item(control_tree, hf_tcpip_config_control_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN); + return 4; +} + +int dissect_tcpip_physical_link(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + guint16 path_size; + proto_item* path_item; + + 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); + + path_item = proto_tree_add_text(tree, tvb, offset+2, path_size, "Path: "); + dissect_epath( tvb, pinfo, path_item, offset+2, path_size, FALSE, NULL); + + return path_size+2; +} + +int dissect_tcpip_interface_config(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + guint16 domain_length; + + 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); + 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); + proto_tree_add_item(tree, hf_tcpip_ic_domain_name, tvb, offset+22, domain_length, ENC_LITTLE_ENDIAN); + + return (22+domain_length); +} + +int dissect_tcpip_mcast_config(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + 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); + proto_tree_add_item(tree, hf_tcpip_mcast_addr_start, tvb, offset+4, 4, ENC_LITTLE_ENDIAN); + return 8; +} + +int dissect_tcpip_last_conflict(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + proto_tree_add_item(tree, hf_tcpip_lcd_acd_activity, tvb, offset, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(tree, hf_tcpip_lcd_remote_mac, tvb, offset+1, 6, ENC_LITTLE_ENDIAN); + /* Call ARP dissector? */ + proto_tree_add_item(tree, hf_tcpip_lcd_arp_pdu, tvb, offset+7, 28, ENC_LITTLE_ENDIAN); + return 35; +} + +int dissect_elink_interface_flags(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + proto_item* flag_item; + proto_tree* flag_tree; + + 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); + + 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); + proto_tree_add_item(flag_tree, hf_elink_iflags_local_hw_fault, tvb, offset, 4, ENC_LITTLE_ENDIAN); + proto_tree_add_item(flag_tree, hf_elink_iflags_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN); + return 4; +} + +int dissect_elink_interface_counters(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + 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); + proto_tree_add_item(tree, hf_elink_icount_in_unknown_protos, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); + 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); + return 44; +} + +int dissect_elink_media_counters(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + 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); + proto_tree_add_item(tree, hf_elink_mcount_deferred_transmission, tvb, offset+20, 4, ENC_LITTLE_ENDIAN); + 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); + return 48; +} + +int dissect_elink_interface_control(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len) + +{ + proto_item* control_item; + proto_tree* control_tree; + + 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); + 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); + + proto_tree_add_item(tree, hf_elink_icontrol_forced_speed, tvb, offset+2, 2, ENC_LITTLE_ENDIAN); + return 4; +} + +attribute_info_t enip_attribute_vals[29] = { + + {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}, + + {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_usint_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}, + + {0x48, FALSE, 1, "802.1Q Tag Enable", cip_usint, &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} + +}; + + /* * Protocol initialization */ @@ -647,67 +1054,6 @@ enip_init_protocol(void) enip_conn_hashtable = g_hash_table_new(enip_conn_hash, enip_conn_equal); } -static proto_item * -add_byte_array_text_to_proto_tree(proto_tree *tree, tvbuff_t *tvb, gint start, - gint length, const char* str, gboolean printall ) -{ - const char *tmp; - char *tmp2, *tmp2start; - proto_item *pi; - int i,tmp_length,tmp2_length; - guint32 octet; - /* At least one version of Apple's C compiler/linker is buggy, causing - a complaint from the linker about the "literal C string section" - not ending with '\0' if we initialize a 16-element "char" array with - a 16-character string, the fact that initializing such an array with - such a string is perfectly legitimate ANSI C nonwithstanding, the 17th - '\0' byte in the string nonwithstanding. */ - static const char my_hex_digits[16] = - { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; - - - if( !printall && - ( ( length * 2 ) > 32 ) ) - { - tmp_length = 16; - tmp2_length = 36; - } - else - { - tmp_length = length; - tmp2_length = ( length * 2 ) + 1; - } - - tmp = (const char *)tvb_get_ptr( tvb, start, tmp_length ); - tmp2 = (char *)ep_alloc( tmp2_length ); - - tmp2start = tmp2; - - for( i = 0; i < tmp_length; i++ ) - { - octet = tmp[i]; - octet >>= 4; - *tmp2++ = my_hex_digits[octet&0xF]; - octet = tmp[i]; - *tmp2++ = my_hex_digits[octet&0xF]; - } - - if( tmp_length != length ) - { - *tmp2++ = '.'; - *tmp2++ = '.'; - *tmp2++ = '.'; - } - - *tmp2 = '\0'; - - pi = proto_tree_add_text( tree, tvb, start, length, "%s%s", str, tmp2start ); - - return( pi ); - -} /* end of add_byte_array_text_to_proto_tree() */ - /* Disssect Common Packet Format */ static void dissect_cpf(enip_request_key_t *request_key, int command, tvbuff_t *tvb, @@ -819,8 +1165,14 @@ dissect_cpf(enip_request_key_t *request_key, int command, tvbuff_t *tvb, else { /* Display data */ - add_byte_array_text_to_proto_tree( item_tree, tvb, offset+6, item_length, "Data: ", TRUE ); - + if (tvb_length_remaining(tvb, offset+6) > 0) + { + next_tvb = tvb_new_subset(tvb, offset+6, item_length, item_length); + if(!dissector_try_heuristic(heur_subdissector_conndata_table, next_tvb, pinfo, g_tree)) + { + proto_tree_add_item(item_tree, hf_enip_connection_transport_data, tvb, offset+6, item_length, ENC_LITTLE_ENDIAN); + } + } } /* End of if send unit data */ break; @@ -966,7 +1318,7 @@ dissect_cpf(enip_request_key_t *request_key, int command, tvbuff_t *tvb, default: - add_byte_array_text_to_proto_tree( item_tree, tvb, offset+6, item_length, "Data: ", FALSE ); + proto_tree_add_item(item_tree, hf_enip_cpf_data, tvb, offset+6, item_length, ENC_LITTLE_ENDIAN); break; } /* end of switch( item type ) */ @@ -1183,7 +1535,7 @@ dissect_enip_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) default: /* Can not decode - Just show the data */ - add_byte_array_text_to_proto_tree( header_tree, tvb, 24, encap_data_length, "Encap Data: ", FALSE ); + proto_tree_add_item(header_tree, hf_enip_encap_data, tvb, 24, encap_data_length, ENC_LITTLE_ENDIAN); break; } /* end of switch() */ @@ -1450,6 +1802,11 @@ proto_register_enip(void) 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 } + }, /* List Services Reply */ { &hf_enip_lsr_capaflags, { "Capability Flags", "enip.lsr.capaflags", @@ -1458,12 +1815,12 @@ proto_register_enip(void) }, { &hf_enip_lsr_tcp, { "Supports CIP Encapsulation via TCP", "enip.lsr.capaflags.tcp", - FT_UINT16, BASE_DEC, VALS(enip_true_false_vals), 0x0020, + FT_UINT16, BASE_DEC, 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_UINT16, BASE_DEC, VALS(enip_true_false_vals), 0x0100, + FT_UINT16, BASE_DEC, TFS(&tfs_true_false), 0x0100, "ListServices Reply: Supports CIP Class 0 or 1 via UDP", HFILL } }, { &hf_enip_lsr_servicename, @@ -1497,12 +1854,12 @@ proto_register_enip(void) /* List identity reply */ { &hf_enip_lir_vendor, { "Vendor ID", "enip.lir.vendor", - FT_UINT16, BASE_HEX, VALS(cip_vendor_vals), 0, + 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, VALS(cip_devtype_vals), 0, + FT_UINT16, BASE_DEC|BASE_EXT_STRING, &cip_devtype_vals_ext, 0, "ListIdentity Reply: Device Type", HFILL } }, { &hf_enip_lir_prodcode, @@ -1579,6 +1936,12 @@ proto_register_enip(void) 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 } + }, + /* Request/Response Matching */ { &hf_enip_response_in, { "Response In", "enip.response_in", @@ -1594,7 +1957,102 @@ proto_register_enip(void) { "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", FT_UINT32, BASE_DEC, enip_tcpip_status_interface_config_vals, 0x0000000F, NULL, HFILL }}, + { &hf_tcpip_status_mcast_pending, { "MCast Pending", "cip.tcpip.status.mcast_pending", FT_UINT32, BASE_DEC, TFS(&tfs_true_false), 0x00000010, NULL, HFILL }}, + { &hf_tcpip_status_interface_config_pending, { "Interface Configuration Pending", "cip.tcpip.status.interface_config_pending", FT_UINT32, BASE_DEC, TFS(&tfs_true_false), 0x00000020, NULL, HFILL }}, + { &hf_tcpip_status_acd, { "ACD Status", "cip.tcpip.status.acd", FT_UINT32, BASE_DEC, enip_tcpip_status_acd_vals, 0x00000040, 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_UINT32, BASE_DEC, TFS(&tfs_true_false), 0x00000001, NULL, HFILL }}, + { &hf_tcpip_config_cap_dns, { "DNS Client", "cip.tcpip.config_cap.dns", FT_UINT32, BASE_DEC, TFS(&tfs_true_false), 0x00000002, NULL, HFILL }}, + { &hf_tcpip_config_cap_dhcp, { "DHCP Client", "cip.tcpip.config_cap.dhcp", FT_UINT32, BASE_DEC, 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_UINT32, BASE_DEC, TFS(&tfs_true_false), 0x00000008, NULL, HFILL }}, + { &hf_tcpip_config_cap_config_settable, { "Configuration Settable", "cip.tcpip.config_cap.config_settable", FT_UINT32, BASE_DEC, TFS(&tfs_true_false), 0x00000010, NULL, HFILL }}, + { &hf_tcpip_config_cap_hardware_config, { "Hardware Configurable", "cip.tcpip.config_cap.hardware_config", FT_UINT32, BASE_DEC, 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_UINT32, BASE_DEC, TFS(&tfs_true_false), 0x00000040, NULL, HFILL }}, + { &hf_tcpip_config_cap_acd, { "ACD Capable", "cip.tcpip.config_cap.acd", FT_UINT32, BASE_DEC, 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", FT_UINT32, BASE_DEC, enip_tcpip_config_control_config_vals, 0x0000000F, NULL, HFILL }}, + { &hf_tcpip_config_control_dns, { "DNS Enable", "cip.tcpip.config_control.dns", FT_UINT32, BASE_DEC, 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", FT_UINT8, BASE_DEC, enip_tcpip_mcast_alloc_vals, 0, 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_UINT8, BASE_DEC, TFS(&tfs_enabled_disabled), 0, NULL, HFILL }}, + { &hf_tcpip_lcd_acd_activity, { "ACD Activity", "cip.tcpip.last_conflict.acd_activity", FT_UINT8, BASE_DEC, enip_tcpip_acd_activity_vals, 0, 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, BASE_DEC, 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_UINT32, BASE_DEC, TFS(&tfs_active_inactive), 0x00000001, NULL, HFILL }}, + { &hf_elink_iflags_duplex, { "Duplex", "cip.elink.iflags.duplex", FT_UINT32, BASE_DEC, enip_elink_duplex_vals, 0x00000002, NULL, HFILL }}, + { &hf_elink_iflags_neg_status, { "Negotiation Status", "cip.elink.iflags.neg_status", FT_UINT32, BASE_DEC, enip_elink_iflags_neg_status_vals, 0x0000001C, NULL, HFILL }}, + { &hf_elink_iflags_manual_reset, { "Manual Reset Required", "cip.elink.iflags.manual_reset", FT_UINT32, BASE_DEC, enip_elink_iflags_reset_vals, 0x00000020, NULL, HFILL }}, + { &hf_elink_iflags_local_hw_fault, { "Local Hardware Fault", "cip.elink.iflags.local_hw_fault", FT_UINT32, BASE_DEC, enip_elink_iflags_hw_fault_vals, 0x00000040, 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_UINT16, BASE_DEC, TFS(&tfs_enabled_disabled), 0x0001, NULL, HFILL }}, + { &hf_elink_icontrol_control_bits_forced_duplex, { "Forced Duplex Mode", "cip.elink.icontrol.control_bits.forced_duplex", FT_UINT16, BASE_DEC, enip_elink_duplex_vals, 0x0002, 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", FT_UINT8, BASE_DEC, enip_elink_interface_type_vals, 0, NULL, HFILL }}, + { &hf_elink_interface_state, { "Interface State", "cip.elink.interface_state", FT_UINT8, BASE_DEC, enip_elink_interface_state_vals, 0, NULL, HFILL }}, + { &hf_elink_admin_state, { "Admin State", "cip.elink.admin_state", FT_UINT8, BASE_DEC, enip_elink_admin_state_vals, 0, 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, BASE_DEC, 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, NULL, HFILL }} }; @@ -1606,6 +2064,11 @@ proto_register_enip(void) &ett_command_tree, &ett_sockadd, &ett_lsrcf, + &ett_tcpip_status, + &ett_tcpip_config_cap, + &ett_tcpip_config_control, + &ett_elink_interface_flags, + &ett_elink_icontrol_bits }; /* Setup list of header fields for DLR See Section 1.6.1 for details*/ @@ -1780,6 +2243,10 @@ proto_register_enip(void) proto_register_field_array(proto_dlr, hfdlr, array_length(hfdlr)); proto_register_subtree_array(ettdlr, array_length(ettdlr)); + /* Register a heuristic dissector on the data in the message so encapsulated protocols + * can dissect the data without modifying this file */ + register_heur_dissector_list("enip.cpf.conndata", &heur_subdissector_conndata_table); + } /* end of proto_register_enip() */ diff --git a/epan/dissectors/packet-enip.h b/epan/dissectors/packet-enip.h index a16cda9821..f07544239d 100644 --- a/epan/dissectors/packet-enip.h +++ b/epan/dissectors/packet-enip.h @@ -89,3 +89,6 @@ void enip_open_cip_connection( packet_info *pinfo, guint32 O2TConnID, guint32 T2OConnID ); void enip_close_cip_connection( packet_info *pinfo, guint16 ConnSerialNumber, guint16 VendorID, guint32 DeviceSerialNumber ); + + +extern attribute_info_t enip_attribute_vals[29]; |