+/* dissect a PROFIDrive parameter request */
+static int
+dissect_ProfiDriveParameterRequest(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint8 request_reference;
+ guint8 request_id;
+ guint8 do_id;
+ guint8 no_of_parameters;
+ guint8 addr_idx;
+ proto_item *profidrive_item;
+ proto_tree *profidrive_tree;
+
+ profidrive_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, FALSE);
+ profidrive_tree = proto_item_add_subtree(profidrive_item, ett_pn_io_profidrive_parameter_request);
+ proto_item_set_text(profidrive_item, "PROFIDrive Parameter Request: ");
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_request_reference, &request_reference);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_request_id, &request_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_do_id, &do_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_no_of_parameters, &no_of_parameters);
+
+ proto_item_append_text(profidrive_item, "ReqRef:0x%02x, ReqId:%s, DO:%u, NoOfParameters:%u",
+ request_reference, val_to_str(request_id, pn_io_profidrive_request_id_vals, "Unknown"),
+ do_id, no_of_parameters);
+
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "PROFIDrive Write Request, ReqRef:0x%02x, %s DO:%u",
+ request_reference,
+ request_id==0x01 ? "Read" :
+ request_id==0x02 ? "Change" :
+ "",
+ do_id);
+
+ /* Parameter address list */
+ for(addr_idx=0; addr_idx<no_of_parameters; addr_idx++) {
+ guint8 attribute;
+ guint8 no_of_elems;
+ guint16 parameter;
+ guint16 index;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_address);
+ proto_item_set_text(sub_item, "Parameter Address %u: ", addr_idx+1);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_attribute, &attribute);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_elems, &no_of_elems);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_number, ¶meter);
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_subindex, &index);
+
+ proto_item_append_text(sub_item, "Attr:%s, Elems:%u, Parameter:%u, Index:%u",
+ val_to_str(attribute, pn_io_profidrive_attribute_vals, "Unknown"), no_of_elems,
+ parameter, index);
+
+ if(no_of_elems>1) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", P%d[%d..%d]", parameter, index, index+no_of_elems-1);
+ }
+ else {
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", P%d[%d]", parameter, index);
+ }
+ }
+
+ /* in case of change request parameter value list */
+ if(request_id == 0x02) {
+ for(addr_idx=0; addr_idx<no_of_parameters; addr_idx++) {
+ guint8 format;
+ guint8 no_of_vals;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_value);
+ proto_item_set_text(sub_item, "Parameter Value %u: ", addr_idx+1);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_format, &format);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_values, &no_of_vals);
+
+ proto_item_append_text(sub_item, "Format:%s, NoOfVals:%u",
+ val_to_str(format, pn_io_profidrive_format_vals, "Unknown"), no_of_vals);
+
+ while(no_of_vals--) {
+ guint16 value;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_value, &value);
+
+ }
+ }
+ }
+
+ return offset;
+}
+
+static int
+dissect_ProfiDriveParameterResponse(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tree, guint8 *drep)
+{
+ guint8 request_reference;
+ guint8 response_id;
+ guint8 do_id;
+ guint8 no_of_parameters;
+ guint8 val_idx;
+ proto_item *profidrive_item;
+ proto_tree *profidrive_tree;
+
+ profidrive_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, FALSE);
+ profidrive_tree = proto_item_add_subtree(profidrive_item, ett_pn_io_profidrive_parameter_response);
+ proto_item_set_text(profidrive_item, "PROFIDrive Parameter Response: ");
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_request_reference, &request_reference);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_response_id, &response_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_do_id, &do_id);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, profidrive_tree, drep,
+ hf_pn_io_profidrive_no_of_parameters, &no_of_parameters);
+
+ proto_item_append_text(profidrive_item, "ReqRef:0x%02x, RspId:%s, DO:%u, NoOfParameters:%u",
+ request_reference, val_to_str(response_id, pn_io_profidrive_response_id_vals, "Unknown"),
+ do_id, no_of_parameters);
+
+ col_clear(pinfo->cinfo, COL_INFO);
+ col_append_fstr(pinfo->cinfo, COL_INFO, "PROFIDrive Read Response, ReqRef:0x%02x, RspId:%s",
+ request_reference,
+ val_to_str(response_id, pn_io_profidrive_response_id_vals, "Unknown response"));
+
+ val_idx = 1;
+ while(no_of_parameters--) {
+ guint8 format;
+ guint8 no_of_vals;
+ proto_item *sub_item;
+ proto_tree *sub_tree;
+
+ sub_item = proto_tree_add_item(profidrive_tree, hf_pn_io_block, tvb, offset, 0, FALSE);
+ sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_profidrive_parameter_value);
+ proto_item_set_text(sub_item, "Parameter Value %u: ", val_idx++);
+
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_format, &format);
+ offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_no_of_values, &no_of_vals);
+
+ proto_item_append_text(sub_item, "Format:%s, NoOfVals:%u",
+ val_to_str(format, pn_io_profidrive_format_vals, "Unknown"), no_of_vals);
+
+ while(no_of_vals--) {
+ guint16 value;
+
+ offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
+ hf_pn_io_profidrive_param_value, &value);
+ }
+ }
+
+ return offset;
+}