From 6dc8e11d8dd01e4392d83618df0ceed4db3629ae Mon Sep 17 00:00:00 2001 From: Dylan Ulis Date: Sun, 8 Jul 2018 21:20:56 -0400 Subject: [PATCH] CIP Motion: Update attribute service handling 1. Get/Set Axis Attribute List: Display the attribute name, and dissect where appropriate. 2. Minor: Cleanup exported functions/variables. Bug: 14958 Change-Id: I2ff6883e66068472ac5ded0172f51575f5e20a21 Reviewed-on: https://code.wireshark.org/review/28660 Petri-Dish: Roland Knall Tested-by: Petri Dish Buildbot Reviewed-by: Roland Knall --- epan/dissectors/packet-cip.c | 28 +++----- epan/dissectors/packet-cip.h | 62 ++++++++++------ epan/dissectors/packet-cipmotion.c | 109 +++++++++++++++++++++-------- 3 files changed, 131 insertions(+), 68 deletions(-) diff --git a/epan/dissectors/packet-cip.c b/epan/dissectors/packet-cip.c index 49b8a0302a..75e200aac5 100644 --- a/epan/dissectors/packet-cip.c +++ b/epan/dissectors/packet-cip.c @@ -45,12 +45,6 @@ #include "packet-cipsafety.h" #include "packet-mbtcp.h" -static void dissect_cip_data(proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info *pinfo, - cip_req_info_t *preq_info, proto_item* msp_item, gboolean is_msp_item); -static int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *path_tree, proto_item *epath_item, - gboolean generate, gboolean packed, cip_simple_request_info_t* req_data, cip_safety_epath_info_t* safety, int display_type, proto_item *msp_item, - gboolean is_msp_item); - void proto_register_cip(void); void proto_reg_handoff_cip(void); @@ -2790,7 +2784,7 @@ static const value_string cip_devtype_vals[] = { value_string_ext cip_devtype_vals_ext = VALUE_STRING_EXT_INIT(cip_devtype_vals); /* Translate class names */ -static const value_string cip_class_names_vals[] = { +const value_string cip_class_names_vals[] = { { 0x01, "Identity" }, { 0x02, "Message Router" }, { 0x03, "DeviceNet" }, @@ -4077,7 +4071,7 @@ dissect_cia(tvbuff_t *tvb, int offset, unsigned char segment_type, } /* Dissect Device ID structure */ -static void +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) @@ -4958,7 +4952,7 @@ static int dissect_segment_logical_service_id(packet_info* pinfo, tvbuff_t* tvb, return segment_len; } -static int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *path_tree, proto_item *epath_item, +int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *path_tree, proto_item *epath_item, gboolean generate, gboolean packed, cip_simple_request_info_t* req_data, cip_safety_epath_info_t* safety, int display_type, proto_item *msp_item, gboolean is_msp_item) @@ -5347,7 +5341,7 @@ static int dissect_cip_stringi(packet_info *pinfo, proto_tree *tree, proto_item return parsed_len; } -static int dissect_cip_attribute(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, +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 i, temp_data, temp_time, hour, min, sec, ms, @@ -5541,7 +5535,7 @@ dissect_cip_set_attribute_single_req(tvbuff_t *tvb, packet_info *pinfo, proto_tr return parsed_len; } -static int dissect_cip_get_attribute_list_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, +int 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; @@ -5583,7 +5577,7 @@ static int dissect_cip_get_attribute_list_req(tvbuff_t *tvb, packet_info *pinfo, return 2 + att_count * 2; } -static int +int 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) { @@ -5643,8 +5637,7 @@ dissect_cip_set_attribute_list_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree return 2 + (offset - start_offset); } -static int -dissect_cip_multiple_service_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, int offset, gboolean request) +int dissect_cip_multiple_service_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, int offset, gboolean request) { proto_tree *mult_serv_tree, *offset_tree; int i, num_services, serv_offset, prev_offset = 0; @@ -6028,7 +6021,7 @@ dissect_cip_get_attribute_list_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree return 2 + (offset - start_offset); } -static int +int 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) { @@ -6145,7 +6138,7 @@ void load_cip_request_data(packet_info *pinfo, cip_simple_request_info_t *req_da } } -static gboolean should_dissect_cip_response(tvbuff_t *tvb, int offset, guint8 gen_status) +gboolean should_dissect_cip_response(tvbuff_t *tvb, int offset, guint8 gen_status) { // Only parse the response if there is data left or it has a response status that allows additional data // to be returned. @@ -7773,8 +7766,7 @@ dissect_class_cco_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void * ************************************************/ -static void -dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info *pinfo, cip_req_info_t* preq_info, proto_item* msp_item, gboolean is_msp_item ) +void dissect_cip_data( proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info *pinfo, cip_req_info_t* preq_info, proto_item* msp_item, gboolean is_msp_item ) { proto_item *ti; proto_tree *cip_tree, *epath_tree; diff --git a/epan/dissectors/packet-cip.h b/epan/dissectors/packet-cip.h index 847f3491aa..0eb8a3d929 100644 --- a/epan/dissectors/packet-cip.h +++ b/epan/dissectors/packet-cip.h @@ -51,11 +51,12 @@ #define CIP_SC_RESPONSE_MASK 0x80 /* Classes that have class-specific dissectors */ -#define CI_CLS_MR 0x02 /* Message Router */ -#define CI_CLS_CM 0x06 /* Connection Manager */ -#define CI_CLS_PCCC 0x67 /* PCCC Class */ -#define CI_CLS_MB 0x44 /* Modbus Object */ -#define CI_CLS_CCO 0xF3 /* Connection Configuration Object */ +#define CI_CLS_MR 0x02 /* Message Router */ +#define CI_CLS_CM 0x06 /* Connection Manager */ +#define CI_CLS_PCCC 0x67 /* PCCC Class */ +#define CI_CLS_MOTION 0x42 /* Motion Device Axis Object */ +#define CI_CLS_MB 0x44 /* Modbus Object */ +#define CI_CLS_CCO 0xF3 /* Connection Configuration Object */ /* Class specific services */ /* Connection Manager */ @@ -518,20 +519,52 @@ enum cip_elem_data_types { CIP_SHORT_STRING_TYPE = 0xDA, CIP_STRING2_TYPE = 0xD5 }; -extern int dissect_cip_string_type(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, int offset, int hf_type, int string_type); -extern void dissect_cip_date_and_time(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_datetime); +extern void add_cip_service_to_info_column(packet_info *pinfo, guint8 service, const value_string* service_vals); extern attribute_info_t* cip_get_attribute(guint class_id, guint instance, guint attribute); -extern int dissect_cip_get_attribute_all_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + +extern 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); +extern void dissect_cip_data(proto_tree *item_tree, tvbuff_t *tvb, int offset, packet_info *pinfo, cip_req_info_t *preq_info, proto_item* msp_item, gboolean is_msp_item); +extern void dissect_cip_date_and_time(proto_tree *tree, tvbuff_t *tvb, int offset, int hf_datetime); +extern int 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); +extern int dissect_cip_multiple_service_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item * item, int offset, gboolean request); +extern int dissect_cip_response_status(proto_tree* tree, tvbuff_t* tvb, int offset, int hf_general_status, gboolean have_additional_status); +extern void dissect_cip_run_idle(tvbuff_t* tvb, int offset, proto_tree* item_tree); +extern int dissect_cip_segment_single(packet_info *pinfo, tvbuff_t *tvb, int offset, proto_tree *path_tree, proto_item *epath_item, + gboolean generate, gboolean packed, cip_simple_request_info_t* req_data, cip_safety_epath_info_t* safety, + int display_type, proto_item *msp_item, + gboolean is_msp_item); +extern int dissect_cip_string_type(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, int offset, int hf_type, int string_type); +extern int dissect_cip_get_attribute_all_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, cip_simple_request_info_t* req_data); +extern int 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); +extern int 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); +extern 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); +extern int dissect_optional_attr_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len); +extern int dissect_optional_service_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len); +extern int dissect_padded_epath_len_usint(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len); +extern int dissect_padded_epath_len_uint(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, + int offset, int total_len); + extern void load_cip_request_data(packet_info *pinfo, cip_simple_request_info_t *req_data); -void dissect_cip_run_idle(tvbuff_t* tvb, int offset, proto_tree* item_tree); +extern gboolean should_dissect_cip_response(tvbuff_t *tvb, int offset, guint8 gen_status); + /* ** Exported variables */ extern const value_string cip_sc_rr[]; extern const value_string cip_reset_type_vals[]; +extern const value_string cip_class_names_vals[]; +extern const value_string cip_port_number_vals[]; 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; @@ -557,17 +590,6 @@ extern int hf_attr_class_num_inst_attr; #define CLASS_ATTRIBUTE_6_NAME "Maximum ID Number Class Attributes" #define CLASS_ATTRIBUTE_7_NAME "Maximum ID Number Instance Attributes" -extern void add_cip_service_to_info_column(packet_info *pinfo, guint8 service, const value_string* service_vals); - -extern int dissect_optional_attr_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, - int offset, int total_len); -extern int dissect_optional_service_list(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, - int offset, int total_len); -extern int dissect_padded_epath_len_usint(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, - int offset, int total_len); -extern int dissect_padded_epath_len_uint(packet_info *pinfo, proto_tree *tree, proto_item *item, tvbuff_t *tvb, - int offset, int total_len); - /* * Editor modelines * diff --git a/epan/dissectors/packet-cipmotion.c b/epan/dissectors/packet-cipmotion.c index 6752fcb6d5..48dea8bcbb 100644 --- a/epan/dissectors/packet-cipmotion.c +++ b/epan/dissectors/packet-cipmotion.c @@ -617,13 +617,13 @@ static int dissect_node_status(packet_info *pinfo _U_, proto_tree *tree, proto_i } attribute_info_t cip_motion_attribute_vals[] = { - { 0x42, CIP_ATTR_CLASS, 14, -1, "Node Control", cip_dissector_func, NULL, dissect_node_control }, - { 0x42, CIP_ATTR_CLASS, 15, -1, "Node Status", cip_dissector_func, NULL, dissect_node_status }, - { 0x42, CIP_ATTR_INSTANCE, 40, -1, "Control Mode", cip_usint, &hf_cip_motor_cntrl, NULL }, - { 0x42, CIP_ATTR_INSTANCE, 60, -1, "Event Checking Control", cip_dissector_func, NULL, dissect_event_checking_control }, - { 0x42, CIP_ATTR_INSTANCE, 61, -1, "Event Checking Status", cip_dissector_func, NULL, dissect_event_checking_status }, - { 0x42, CIP_ATTR_INSTANCE, 92, -1, "Command Control", cip_dissector_func, NULL, dissect_command_control }, - { 0x42, CIP_ATTR_INSTANCE, 651, -1, "Axis Status", cip_dissector_func, NULL, dissect_axis_status }, + { CI_CLS_MOTION, CIP_ATTR_CLASS, 14, -1, "Node Control", cip_dissector_func, NULL, dissect_node_control }, + { CI_CLS_MOTION, CIP_ATTR_CLASS, 15, -1, "Node Status", cip_dissector_func, NULL, dissect_node_status }, + { CI_CLS_MOTION, CIP_ATTR_INSTANCE, 40, -1, "Control Mode", cip_usint, &hf_cip_motor_cntrl, NULL }, + { CI_CLS_MOTION, CIP_ATTR_INSTANCE, 60, -1, "Event Checking Control", cip_dissector_func, NULL, dissect_event_checking_control }, + { CI_CLS_MOTION, CIP_ATTR_INSTANCE, 61, -1, "Event Checking Status", cip_dissector_func, NULL, dissect_event_checking_status }, + { CI_CLS_MOTION, CIP_ATTR_INSTANCE, 92, -1, "Command Control", cip_dissector_func, NULL, dissect_command_control }, + { CI_CLS_MOTION, CIP_ATTR_INSTANCE, 651, -1, "Axis Status", cip_dissector_func, NULL, dissect_axis_status }, }; /* @@ -1205,7 +1205,7 @@ dissect_devce_event(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 siz * Returns: None */ static void -dissect_get_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size) +dissect_get_axis_attr_list_request(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size, guint32 instance_id) { proto_item *attr_item; proto_tree *header_tree, *attr_tree; @@ -1234,7 +1234,8 @@ dissect_get_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 off dimension = tvb_get_guint8(tvb, local_offset + 2); /* Create the tree for this attribute within the request */ - attr_item = proto_tree_add_item(header_tree, hf_get_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + guint32 attribute_id; + attr_item = proto_tree_add_item_ret_uint(header_tree, hf_get_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN, &attribute_id); attr_tree = proto_item_add_subtree(attr_item, ett_get_axis_attr_list); proto_tree_add_item(attr_tree, hf_get_axis_attr_list_dimension, tvb, local_offset + 2, 1, ENC_LITTLE_ENDIAN); @@ -1242,7 +1243,7 @@ dissect_get_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 off if (dimension == 1) { - /* Display the start index and start index from the request if this is an array request */ + /* Display the start index and start index from the request */ proto_tree_add_item(attr_tree, hf_get_axis_attr_list_start_index, tvb, local_offset + 4, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(attr_tree, hf_get_axis_attr_list_data_elements, tvb, local_offset + 6, 2, ENC_LITTLE_ENDIAN); @@ -1250,11 +1251,37 @@ dissect_get_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 off increment_size += 4; } + attribute_info_t* pattribute = cip_get_attribute(CI_CLS_MOTION, instance_id, attribute_id); + if (pattribute != NULL) + { + proto_item_append_text(attr_item, " (%s)", pattribute->text); + } + /* Move the local offset to the next attribute */ local_offset += increment_size; } } +static int dissect_motion_attribute(packet_info *pinfo, tvbuff_t* tvb, int offset, guint32 attribute_id, + guint32 instance_id, proto_item* attr_item, proto_tree* attr_tree, guint8 dimension, guint32 attribute_size) +{ + attribute_info_t* pattribute = cip_get_attribute(CI_CLS_MOTION, instance_id, attribute_id); + int parsed_len = 0; + + if (pattribute != NULL) + { + proto_item_append_text(attr_item, " (%s)", pattribute->text); + + // TODO: Handle more dimensions. Unsure about the format when there is more than 1 item. + if (dimension <= 1) + { + parsed_len = dissect_cip_attribute(pinfo, attr_tree, attr_item, tvb, pattribute, offset, attribute_size); + } + } + + return parsed_len; +} + /* * Function name: dissect_set_axis_attr_list_request * @@ -1263,7 +1290,7 @@ dissect_get_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 off * Returns: None */ static void -dissect_set_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size) +dissect_set_axis_attr_list_request(packet_info *pinfo, tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size, guint32 instance_id) { proto_item *attr_item; proto_tree *header_tree, *attr_tree; @@ -1307,7 +1334,8 @@ dissect_set_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 off } /* Create the tree for this attribute in the get axis attribute list request */ - attr_item = proto_tree_add_item(header_tree, hf_set_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + guint32 attribute_id; + attr_item = proto_tree_add_item_ret_uint(header_tree, hf_set_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN, &attribute_id); attr_tree = proto_item_add_subtree(attr_item, ett_set_axis_attr_list); proto_tree_add_item(attr_tree, hf_set_axis_attr_list_dimension, tvb, local_offset + 2, 1, ENC_LITTLE_ENDIAN); @@ -1320,8 +1348,14 @@ dissect_set_axis_attr_list_request (tvbuff_t* tvb, proto_tree* tree, guint32 off proto_tree_add_item(attr_tree, hf_set_axis_attr_list_data_elements, tvb, local_offset + 6, 2, ENC_LITTLE_ENDIAN); } - /* Display the value of this attribute */ - proto_tree_add_item(attr_tree, hf_cip_attribute_data, tvb, local_offset + attribute_start, attribute_size, ENC_NA); + int parsed_len = dissect_motion_attribute(pinfo, tvb, local_offset + attribute_start, attribute_id, + instance_id, attr_item, attr_tree, dimension, attribute_size); + + // Display any remaining unparsed attribute data. + if ((attribute_size - parsed_len) > 0) + { + proto_tree_add_item(attr_tree, hf_cip_attribute_data, tvb, local_offset + attribute_start + parsed_len, attribute_size - parsed_len, ENC_NA); + } /* Round the attribute size up so the next attribute lines up on a 32-bit boundary */ if (attribute_size % 4 != 0) @@ -1363,7 +1397,7 @@ dissect_group_sync_request (tvbuff_t* tvb, proto_tree* tree, guint32 offset, gui * as their starting offset */ static guint32 -dissect_cntr_service(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size) +dissect_cntr_service(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint32 offset, guint32 size, guint32 instance_id) { proto_tree *header_tree; guint32 service; @@ -1383,10 +1417,10 @@ dissect_cntr_service(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 si switch (service) { case SC_GET_AXIS_ATTRIBUTE_LIST: - dissect_get_axis_attr_list_request(tvb, header_tree, offset + 4, size - 4); + dissect_get_axis_attr_list_request(tvb, header_tree, offset + 4, size - 4, instance_id); break; case SC_SET_AXIS_ATTRIBUTE_LIST: - dissect_set_axis_attr_list_request(tvb, header_tree, offset + 4, size - 4); + dissect_set_axis_attr_list_request(pinfo, tvb, header_tree, offset + 4, size - 4, instance_id); break; case SC_GROUP_SYNC: dissect_group_sync_request(tvb, header_tree, offset + 4, size - 4); @@ -1408,7 +1442,7 @@ dissect_cntr_service(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 si * Returns: None */ static void -dissect_set_axis_attr_list_response (tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size) +dissect_set_axis_attr_list_response(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size, guint32 instance_id) { proto_item *attr_item; proto_tree *header_tree, *attr_tree; @@ -1429,12 +1463,19 @@ dissect_set_axis_attr_list_response (tvbuff_t* tvb, proto_tree* tree, guint32 of for (attribute = 0; attribute < attribute_cnt; attribute++) { /* Create the tree for the current attribute in the set axis attribute list response */ - attr_item = proto_tree_add_item(header_tree, hf_set_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + guint32 attribute_id; + attr_item = proto_tree_add_item_ret_uint(header_tree, hf_set_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN, &attribute_id); attr_tree = proto_item_add_subtree(attr_item, ett_get_axis_attr_list); /* Add the response status to the tree */ proto_tree_add_item(attr_tree, hf_cip_svc_set_axis_attr_sts, tvb, local_offset + 2, 1, ENC_LITTLE_ENDIAN); + attribute_info_t* pattribute = cip_get_attribute(CI_CLS_MOTION, instance_id, attribute_id); + if (pattribute != NULL) + { + proto_item_append_text(attr_item, " (%s)", pattribute->text); + } + /* Move the local offset to the next attribute */ local_offset += 4; } @@ -1448,7 +1489,7 @@ dissect_set_axis_attr_list_response (tvbuff_t* tvb, proto_tree* tree, guint32 of * Returns: None */ static void -dissect_get_axis_attr_list_response (tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size) +dissect_get_axis_attr_list_response(packet_info* pinfo, tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size, guint32 instance_id) { proto_item *attr_item; proto_tree *header_tree, *attr_tree; @@ -1473,7 +1514,7 @@ dissect_get_axis_attr_list_response (tvbuff_t* tvb, proto_tree* tree, guint32 of /* At a minimum the local offset needs to be incremented by 4 bytes to reach the next attribute */ increment_size = 4; - /* Pull the fields for this attribute from the payload, all fields are need to make some calculations before + /* Pull the fields for this attribute from the payload, all fields are needed to make some calculations before * properly displaying of the attribute is possible */ dimension = tvb_get_guint8(tvb, local_offset + 2); attribute_size = tvb_get_guint8(tvb, local_offset + 3); @@ -1492,7 +1533,8 @@ dissect_get_axis_attr_list_response (tvbuff_t* tvb, proto_tree* tree, guint32 of } /* Display the fields associated with the get axis attribute list response */ - attr_item = proto_tree_add_item(header_tree, hf_get_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN); + guint32 attribute_id; + attr_item = proto_tree_add_item_ret_uint(header_tree, hf_get_axis_attr_list_attribute_id, tvb, local_offset, 2, ENC_LITTLE_ENDIAN, &attribute_id); attr_tree = proto_item_add_subtree(attr_item, ett_get_axis_attr_list); if (dimension == 0xFF) @@ -1510,13 +1552,19 @@ dissect_get_axis_attr_list_response (tvbuff_t* tvb, proto_tree* tree, guint32 of if (dimension == 1) { - /* Display the start index and start indexfrom the request */ + /* Display the start index and start index from the request */ proto_tree_add_item(attr_tree, hf_get_axis_attr_list_start_index, tvb, local_offset + 4, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(attr_tree, hf_get_axis_attr_list_data_elements, tvb, local_offset + 6, 2, ENC_LITTLE_ENDIAN); } + int parsed_len = dissect_motion_attribute(pinfo, tvb, local_offset + attribute_start, attribute_id, + instance_id, attr_item, attr_tree, dimension, attribute_size); + /* Display the remainder of the service channel data */ - proto_tree_add_item(attr_tree, hf_cip_attribute_data, tvb, offset + attribute_start, attribute_size, ENC_NA); + if ((attribute_size - parsed_len) > 0) + { + proto_tree_add_item(attr_tree, hf_cip_attribute_data, tvb, local_offset + attribute_start + parsed_len, attribute_size - parsed_len, ENC_NA); + } /* Round the attribute size up so the next attribute lines up on a 32-bit boundary */ if (attribute_size % 4 != 0) @@ -1552,7 +1600,7 @@ dissect_group_sync_response (tvbuff_t* tvb, proto_tree* tree, guint32 offset, gu * as their starting offset */ static guint32 -dissect_devce_service(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 size) +dissect_devce_service(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, guint32 offset, guint32 size, guint32 instance_id) { proto_tree *header_tree; @@ -1578,10 +1626,10 @@ dissect_devce_service(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 s switch (service_code) { case SC_GET_AXIS_ATTRIBUTE_LIST: - dissect_get_axis_attr_list_response(tvb, header_tree, offset + 4, size - 4); + dissect_get_axis_attr_list_response(pinfo, tvb, header_tree, offset + 4, size - 4, instance_id); break; case SC_SET_AXIS_ATTRIBUTE_LIST: - dissect_set_axis_attr_list_response(tvb, header_tree, offset + 4, size - 4); + dissect_set_axis_attr_list_response(tvb, header_tree, offset + 4, size - 4, instance_id); break; case SC_GROUP_SYNC: dissect_group_sync_response(tvb, header_tree, offset + 4, size - 4); @@ -1589,6 +1637,7 @@ dissect_devce_service(tvbuff_t* tvb, proto_tree* tree, guint32 offset, guint32 s default: /* Display the remainder of the service channel data */ proto_tree_add_item(header_tree, hf_cip_svc_data, tvb, offset + 4, size - 4, ENC_NA); + break; } } @@ -1922,7 +1971,7 @@ dissect_cipmotion(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* dat if ( evnt_size > 0 ) offset = dissect_cntr_event(tvb, proto_tree_top, offset, evnt_size); if ( servc_size > 0 ) - offset = dissect_cntr_service(tvb, proto_tree_top, offset, servc_size); + offset = dissect_cntr_service(tvb, pinfo, proto_tree_top, offset, servc_size, instance); break; case FORMAT_VAR_DEVICE_TO_CONTROL: if ( cyc_size > 0 ) @@ -1932,7 +1981,7 @@ dissect_cipmotion(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree, void* dat if ( evnt_size > 0 ) offset = dissect_devce_event(tvb, proto_tree_top, offset, evnt_size); if ( servc_size > 0 ) - offset = dissect_devce_service(tvb, proto_tree_top, offset, servc_size); + offset = dissect_devce_service(tvb, pinfo, proto_tree_top, offset, servc_size, instance); break; } @@ -3049,7 +3098,7 @@ void proto_reg_handoff_cipmotion(void) dissector_add_for_decode_as("cip.io", cipmotion_handle); dissector_add_for_decode_as("cip.io", cipmotion3_handle); - dissector_add_uint("cip.io.iface", 0x42, cipmotion_handle); + dissector_add_uint("cip.io.iface", CI_CLS_MOTION, cipmotion_handle); } /*