1 /* packet-dcerpc-pn-io.c
2 * Routines for PROFINET IO dissection.
6 * Ethereal - Network traffic analyzer
7 * By Gerald Combs <gerald@ethereal.com>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 * The PN-IO protocol is a field bus protocol related to decentralized
27 * periphery and is developed by the PROFIBUS Nutzerorganisation e.V. (PNO),
28 * see: www.profibus.com
31 * PN-IO is based on the common DCE-RPC and the "lightweight" PN-RT
32 * (ethernet type 0x8892) protocols.
34 * The context manager (CM) part is handling context information
35 * (like establishing, ...) and is using DCE-RPC as it's underlying
38 * The actual cyclic data transfer and acyclic notification uses the
39 * "lightweight" PN-RT protocol.
41 * There are some other related PROFINET protocols (e.g. PN-DCP, which is
42 * handling addressing topics).
44 * Please note: the PROFINET CBA protocol is independant of the PN-IO protocol!
53 #ifdef HAVE_SYS_TYPES_H
54 #include <sys/types.h>
60 #include <epan/packet.h>
61 #include <epan/dissectors/packet-dcerpc.h>
65 static int proto_pn_io = -1;
67 static int hf_pn_io_opnum = -1;
68 static int hf_pn_io_reserved16 = -1;
70 static int hf_pn_io_array = -1;
71 static int hf_pn_io_status = -1;
72 static int hf_pn_io_args_max = -1;
73 static int hf_pn_io_args_len = -1;
74 static int hf_pn_io_array_max_count = -1;
75 static int hf_pn_io_array_offset = -1;
76 static int hf_pn_io_array_act_count = -1;
78 static int hf_pn_io_data = -1;
80 static int hf_pn_io_ar_type = -1;
81 static int hf_pn_io_cminitiator_macadd = -1;
82 static int hf_pn_io_cminitiator_objectuuid = -1;
83 static int hf_pn_io_ar_properties = -1;
84 static int hf_pn_io_cminitiator_activitytimeoutfactor = -1;
85 static int hf_pn_io_cminitiator_udprtport = -1;
86 static int hf_pn_io_station_name_length = -1;
87 static int hf_pn_io_cminitiator_station_name = -1;
89 static int hf_pn_io_cmresponder_macadd = -1;
90 static int hf_pn_io_cmresponder_udprtport = -1;
92 static int hf_pn_io_iocr_type = -1;
93 static int hf_pn_io_iocr_reference = -1;
94 static int hf_pn_io_lt = -1;
95 static int hf_pn_io_iocr_properties = -1;
96 static int hf_pn_io_data_length = -1;
97 static int hf_pn_io_frame_id = -1;
98 static int hf_pn_io_send_clock_factor = -1;
99 static int hf_pn_io_reduction_ratio = -1;
100 static int hf_pn_io_phase = -1;
101 static int hf_pn_io_sequence = -1;
102 static int hf_pn_io_frame_send_offset = -1;
103 static int hf_pn_io_watchdog_factor = -1;
104 static int hf_pn_io_data_hold_factor = -1;
105 static int hf_pn_io_iocr_tag_header = -1;
106 static int hf_pn_io_iocr_multicast_mac_add = -1;
107 static int hf_pn_io_number_of_apis = -1;
108 static int hf_pn_io_number_of_io_data_objects = -1;
109 static int hf_pn_io_io_data_object_frame_offset = -1;
110 static int hf_pn_io_number_of_iocs = -1;
111 static int hf_pn_io_iocs_frame_offset = -1;
113 static int hf_pn_io_alarmcr_type = -1;
114 static int hf_pn_io_alarmcr_properties = -1;
115 static int hf_pn_io_rta_timeoutfactor = -1;
116 static int hf_pn_io_rta_retries = -1;
117 static int hf_pn_io_localalarmref = -1;
118 static int hf_pn_io_maxalarmdatalength = -1;
119 static int hf_pn_io_alarmcr_tagheaderhigh = -1;
120 static int hf_pn_io_alarmcr_tagheaderlow = -1;
122 static int hf_pn_io_ar_uuid = -1;
123 static int hf_pn_io_api_tree = -1;
124 static int hf_pn_io_module_tree = -1;
125 static int hf_pn_io_submodule_tree = -1;
126 static int hf_pn_io_io_data_object = -1;
127 static int hf_pn_io_io_cs = -1;
128 static int hf_pn_io_api = -1;
129 static int hf_pn_io_slot_nr = -1;
130 static int hf_pn_io_subslot_nr = -1;
131 static int hf_pn_io_index = -1;
132 static int hf_pn_io_seq_number = -1;
133 static int hf_pn_io_record_data_length = -1;
134 static int hf_pn_io_padding = -1;
135 static int hf_pn_io_add_val1 = -1;
136 static int hf_pn_io_add_val2 = -1;
138 static int hf_pn_io_block = -1;
139 static int hf_pn_io_block_header = -1;
140 static int hf_pn_io_block_type = -1;
141 static int hf_pn_io_block_length = -1;
142 static int hf_pn_io_block_version_high = -1;
143 static int hf_pn_io_block_version_low = -1;
145 static int hf_pn_io_sessionkey = -1;
146 static int hf_pn_io_control_command = -1;
147 static int hf_pn_io_control_command_prmend = -1;
148 static int hf_pn_io_control_command_applready = -1;
149 static int hf_pn_io_control_command_release = -1;
150 static int hf_pn_io_control_command_done = -1;
151 static int hf_pn_io_control_block_properties = -1;
153 static int hf_pn_io_error_code = -1;
154 static int hf_pn_io_error_decode = -1;
155 static int hf_pn_io_error_code1 = -1;
156 static int hf_pn_io_error_code2 = -1;
157 static int hf_pn_io_error_code1_pniorw = -1;
158 static int hf_pn_io_error_code1_pnio = -1;
160 static int hf_pn_io_alarm_type = -1;
161 static int hf_pn_io_alarm_specifier = -1;
162 static int hf_pn_io_alarm_specifier_sequence = -1;
163 static int hf_pn_io_alarm_specifier_channel = -1;
164 static int hf_pn_io_alarm_specifier_manufacturer = -1;
165 static int hf_pn_io_alarm_specifier_submodule = -1;
166 static int hf_pn_io_alarm_specifier_ardiagnosis = -1;
168 static int hf_pn_io_alarm_dst_endpoint = -1;
169 static int hf_pn_io_alarm_src_endpoint = -1;
170 static int hf_pn_io_pdu_type = -1;
171 static int hf_pn_io_pdu_type_type = -1;
172 static int hf_pn_io_pdu_type_version = -1;
173 static int hf_pn_io_add_flags = -1;
174 static int hf_pn_io_window_size = -1;
175 static int hf_pn_io_tack = -1;
176 static int hf_pn_io_send_seq_num = -1;
177 static int hf_pn_io_ack_seq_num = -1;
178 static int hf_pn_io_var_part_len = -1;
180 static int hf_pn_io_number_of_modules = -1;
181 static int hf_pn_io_module_ident_number = -1;
182 static int hf_pn_io_module_properties = -1;
183 static int hf_pn_io_module_state = -1;
184 static int hf_pn_io_number_of_submodules = -1;
185 static int hf_pn_io_submodule_ident_number = -1;
186 static int hf_pn_io_submodule_properties = -1;
187 static int hf_pn_io_submodule_state = -1;
188 static int hf_pn_io_data_description_tree = -1;
189 static int hf_pn_io_data_description = -1;
190 static int hf_pn_io_submodule_data_length = -1;
191 static int hf_pn_io_length_iocs = -1;
192 static int hf_pn_io_length_iops = -1;
194 static int hf_pn_io_ioxs = -1;
195 static int hf_pn_io_ioxs_extension = -1;
196 static int hf_pn_io_ioxs_res14 = -1;
197 static int hf_pn_io_ioxs_instance = -1;
198 static int hf_pn_io_ioxs_datastate = -1;
200 static int hf_pn_io_address_resolution_properties = -1;
201 static int hf_pn_io_mci_timeout_factor = -1;
202 static int hf_pn_io_provider_station_name = -1;
205 static gint ett_pn_io = -1;
206 static gint ett_pn_io_block = -1;
207 static gint ett_pn_io_block_header = -1;
208 static gint ett_pn_io_status = -1;
209 static gint ett_pn_io_rtc = -1;
210 static gint ett_pn_io_rta = -1;
211 static gint ett_pn_io_pdu_type = -1;
212 static gint ett_pn_io_add_flags = -1;
213 static gint ett_pn_io_control_command = -1;
214 static gint ett_pn_io_ioxs = -1;
215 static gint ett_pn_io_api = -1;
216 static gint ett_pn_io_data_description = -1;
217 static gint ett_pn_io_module = -1;
218 static gint ett_pn_io_submodule = -1;
219 static gint ett_pn_io_io_data_object = -1;
220 static gint ett_pn_io_io_cs = -1;
222 static e_uuid_t uuid_pn_io_device = { 0xDEA00001, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
223 static guint16 ver_pn_io_device = 1;
225 static e_uuid_t uuid_pn_io_controller = { 0xDEA00002, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
226 static guint16 ver_pn_io_controller = 1;
228 static e_uuid_t uuid_pn_io_supervisor = { 0xDEA00003, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
229 static guint16 ver_pn_io_supervisor = 1;
231 static e_uuid_t uuid_pn_io_parameterserver = { 0xDEA00004, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } };
232 static guint16 ver_pn_io_parameterserver = 1;
235 static const value_string pn_io_block_type[] = {
236 { 0x0000, "Reserved" },
237 { 0x0001, "Alarm Notification High"},
238 { 0x0002, "Alarm Notification Low"},
239 { 0x0008, "WriteRecordReq"},
240 { 0x8008, "WriteRecordRes"},
241 { 0x0009, "ReadRecordReq"},
242 { 0x8009, "ReadRecordRes"},
243 { 0x0010, "ManufacturerSpecificDiagnosisBlock"},
244 { 0x0011, "ChannelDiagnosisBlock"},
245 { 0x0012, "ExpectedIdentificationDataBlock"},
246 { 0x0014, "SubstituteValue RecordDataRead"},
247 { 0x0015, "RecordInputDataObjectElement"},
248 { 0x0016, "RecordOutputDataObjectElement"},
249 { 0x0017, "RecordOutputDataSubstituteObjectElement"},
251 { 0x0019, "LogData"},
252 { 0x001A, "APIData"},
258 { 0x8001, "Alarm Ack High"},
259 { 0x8002, "Alarm Ack Low"},
260 { 0x0101, "ARBlockReq"},
261 { 0x8101, "ARBlockRes"},
262 { 0x0102, "IOCRBlockReq"},
263 { 0x8102, "IOCRBlockRes"},
264 { 0x0103, "AlarmCRBlockReq"},
265 { 0x8103, "AlarmCRBlockRes"},
266 { 0x0104, "ExpectedSubmoduleBlockReq"},
267 { 0x8104, "ModuleDiffBlock"},
268 { 0x0105, "PrmServerBlockReq"},
269 { 0x8105, "PrmServerBlockRes"},
270 { 0x0106, "MCRBlockReq"},
271 { 0x0110, "IODBlockReq"},
272 { 0x8110, "IODBlockRes"},
273 { 0x0111, "IODBlockReq"},
274 { 0x8111, "IODBlockRes"},
275 { 0x0112, "IOXBlockReq"},
276 { 0x8112, "IOXBlockRes"},
277 { 0x0113, "IOXBlockReq"},
278 { 0x8113, "IOXBlockRes"},
279 { 0x0114, "ReleaseBlockReq"},
280 { 0x8114, "ReleaseBlockRes"},
284 static const value_string pn_io_alarm_type[] = {
285 { 0x0000, "Reserved" },
286 { 0x0001, "Diagnosis" },
287 { 0x0002, "Process" },
290 { 0x0005, "Status" },
291 { 0x0006, "Update" },
292 { 0x0007, "Redundancy" },
293 { 0x0008, "Controlled by supervisor" },
294 { 0x0009, "Released by supervisor" },
295 { 0x000A, "Plug wrong submodule" },
296 { 0x000B, "Return of submodule" },
297 /* 0x000C - 0x001F reserved */
298 /* 0x0020 - 0x007F manufacturer specific */
299 /* 0x0080 - 0x00FF reserved for profiles */
300 /* 0x0100 - 0xFFFF reserved */
304 static const value_string pn_io_pdu_type[] = {
305 { 0x01, "Data-RTA-PDU" },
306 { 0x02, "NACK-RTA-PDU" },
307 { 0x03, "ACK-RTA-PDU" },
308 { 0x04, "ERR-RTA-PDU" },
312 static const value_string pn_io_error_code[] = {
315 { 0xCF, "RTA error" },
316 { 0xDA, "AlarmAck" },
317 { 0xDB, "IODConnectRes" },
318 { 0xDC, "IODReleaseRes" },
319 { 0xDD, "IODControlRes" },
320 { 0xDE, "IODReadRes" },
321 { 0xDF, "IODWriteRes" },
325 static const value_string pn_io_error_decode[] = {
333 XXX: the next 2 are dependant on error_code and error_decode
336 error_code .. see above
346 7 RPC_ERR_PNIO_OUT_ARGS
347 8 Application Timeout
350 /* XXX: add some more error codes here */
351 static const value_string pn_io_error_code1[] = {
356 /* XXX: add some more error codes here */
357 static const value_string pn_io_error_code2[] = {
362 static const value_string pn_io_error_code1_pniorw[] = {
363 { 0x0a /* 10*/, "application" },
364 { 0x0b /* 11*/, "access" },
365 { 0x0c /* 12*/, "resource" },
366 { 0x0d /* 13*/, "user specific(13)" },
367 { 0x0e /* 14*/, "user specific(14)" },
368 { 0x0f /* 15*/, "user specific(15)" },
372 static const value_string pn_io_error_code1_pnio[] = {
373 { 0x00 /* 0*/, "Reserved" },
374 { 0x01 /* 1*/, "Connect: Faulty ARBlockReq" },
375 { 0x02 /* 2*/, "Connect: Faulty IOCRBlockReq" },
376 { 0x03 /* 3*/, "Connect: Faulty ExpectedSubmoduleBlockReq" },
377 { 0x04 /* 4*/, "Connect: Faulty AlarmCRBlockReq" },
378 { 0x05 /* 5*/, "Connect: Faulty PrmServerBlockReq" },
380 { 0x14 /* 20*/, "IODControl: Faulty ControlBlockConnect" },
381 { 0x15 /* 21*/, "IODControl: Faulty ControlBlockPlug" },
382 { 0x16 /* 22*/, "IOXControl: Faulty ControlBlock after a connect est." },
383 { 0x17 /* 23*/, "IOXControl: Faulty ControlBlock a plug alarm" },
385 { 0x28 /* 40*/, "Release: Faulty ReleaseBlock" },
387 { 0x3c /* 60*/, "AlarmAck Error Codes" },
388 { 0x3d /* 61*/, "CMDEV" },
389 { 0x3e /* 62*/, "CMCTL" },
390 { 0x3f /* 63*/, "NRPM" },
391 { 0x40 /* 64*/, "RMPM" },
392 { 0x41 /* 65*/, "ALPMI" },
393 { 0x42 /* 66*/, "ALPMR" },
394 { 0x43 /* 67*/, "LMPM" },
395 { 0x44 /* 68*/, "MMAC" },
396 { 0x45 /* 69*/, "RPC" },
397 { 0x46 /* 70*/, "APMR" },
398 { 0x47 /* 71*/, "APMS" },
399 { 0x48 /* 72*/, "CPM" },
400 { 0x49 /* 73*/, "PPM" },
401 { 0x4a /* 74*/, "DCPUCS" },
402 { 0x4b /* 75*/, "DCPUCR" },
403 { 0x4c /* 76*/, "DCPMCS" },
404 { 0x4d /* 77*/, "DCPMCR" },
405 { 0x4e /* 78*/, "FSPM" },
406 { 0xfd /*253*/, "RTA_ERR_CLS_PROTOCOL" },
410 static const value_string pn_io_ioxs[] = {
411 { 0x00 /* 0*/, "detected by subslot" },
412 { 0x01 /* 1*/, "detected by slot" },
413 { 0x02 /* 2*/, "detected by IO device" },
414 { 0x03 /* 3*/, "detected by IO controller" },
419 static const value_string pn_io_ar_type[] = {
420 { 0x0000, "reserved" },
421 { 0x0001, "IOCARSingle" },
422 { 0x0002, "reserved" },
423 { 0x0003, "IOCARCIR" },
424 { 0x0004, "IOCAR_IOControllerRedundant" },
425 { 0x0005, "IOCAR_IODeviceRedundant" },
427 /*0x0007 - 0xFFFF reserved */
431 static const value_string pn_io_iocr_type[] = {
432 { 0x0000, "reserved" },
433 { 0x0001, "Input CR" },
434 { 0x0002, "Output CR" },
435 { 0x0003, "Multicast Provider CR" },
436 { 0x0004, "Multicast Consumer CR" },
437 /*0x0005 - 0xFFFF reserved */
442 static const value_string pn_io_data_description[] = {
443 { 0x0000, "reserved" },
445 { 0x0002, "Output" },
446 { 0x0003, "reserved" },
447 /*0x0004 - 0xFFFF reserved */
453 static const value_string pn_io_module_state[] = {
454 { 0x0000, "no module" },
455 { 0x0001, "wrong module" },
456 { 0x0002, "proper module" },
457 { 0x0003, "substitute" },
458 /*0x0004 - 0xFFFF reserved */
467 /* dissect a 6 byte MAC address */
469 dissect_MAC(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
470 proto_tree *tree, int hfindex, guint8 *pdata)
474 tvb_memcpy(tvb, data, offset, 6);
476 proto_tree_add_ether(tree, hfindex, tvb, offset, 6, data);
479 memcpy(pdata, data, 6);
488 /* dissect the four status (error) fields */
490 dissect_PNIO_status(tvbuff_t *tvb, int offset,
491 packet_info *pinfo, proto_tree *tree, guint8 *drep)
494 guint8 u8ErrorDecode;
498 proto_item *sub_item;
499 proto_tree *sub_tree;
501 int bytemask = (drep[0] & 0x10) ? 3 : 0;
502 const value_string *error_code1_vals;
507 sub_item = proto_tree_add_item(tree, hf_pn_io_status, tvb, offset, 0, FALSE);
508 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_status);
509 u32SubStart = offset;
511 /* the PNIOStatus field is existing in both the RPC and the application data,
512 * depending on the current PDU.
513 * As the byte representation of these layers are different, this has to be handled
514 * in a somewhat different way than elsewhere. */
516 dissect_dcerpc_uint8(tvb, offset+(0^bytemask), pinfo, sub_tree, drep,
517 hf_pn_io_error_code, &u8ErrorCode);
518 dissect_dcerpc_uint8(tvb, offset+(1^bytemask), pinfo, sub_tree, drep,
519 hf_pn_io_error_decode, &u8ErrorDecode);
521 switch(u8ErrorDecode) {
522 case(0x80): /* PNIORW */
523 dissect_dcerpc_uint8(tvb, offset+(2^bytemask), pinfo, sub_tree, drep,
524 hf_pn_io_error_code1_pniorw, &u8ErrorCode1);
525 error_code1_vals = pn_io_error_code1_pniorw;
527 case(0x81): /* PNIO */
528 dissect_dcerpc_uint8(tvb, offset+(2^bytemask), pinfo, sub_tree, drep,
529 hf_pn_io_error_code1_pnio, &u8ErrorCode1);
530 error_code1_vals = pn_io_error_code1_pnio;
533 dissect_dcerpc_uint8(tvb, offset+(2^bytemask), pinfo, sub_tree, drep,
534 hf_pn_io_error_code1, &u8ErrorCode1);
535 error_code1_vals = pn_io_error_code1;
538 /* XXX - this has to be decode specific too */
539 dissect_dcerpc_uint8(tvb, offset+(3^bytemask), pinfo, sub_tree, drep,
540 hf_pn_io_error_code2, &u8ErrorCode2);
544 if(u8ErrorCode == 0 && u8ErrorDecode == 0 && u8ErrorCode1 == 0 && u8ErrorCode2 == 0) {
545 proto_item_append_text(sub_item, ": OK");
546 if (check_col(pinfo->cinfo, COL_INFO))
547 col_append_str(pinfo->cinfo, COL_INFO, ", OK");
549 proto_item_append_text(sub_item, ": Error Code: \"%s\", Decode: \"%s\", Code1: \"%s\" Code2: 0x%x",
550 val_to_str(u8ErrorCode, pn_io_error_code, "(0x%x)"),
551 val_to_str(u8ErrorDecode, pn_io_error_decode, "(0x%x)"),
552 val_to_str(u8ErrorCode1, error_code1_vals, "(0x%x)"),
554 if (check_col(pinfo->cinfo, COL_INFO))
555 col_append_fstr(pinfo->cinfo, COL_INFO, ", Error Code: %s, Decode: %s, Code1: 0x%x Code2: 0x%x",
556 val_to_str(u8ErrorCode, pn_io_error_code, "(0x%x)"),
557 val_to_str(u8ErrorDecode, pn_io_error_decode, "(0x%x)"),
561 proto_item_set_len(sub_item, offset - u32SubStart);
567 /* dissect the alarm specifier */
569 dissect_Alarm_specifier(tvbuff_t *tvb, int offset,
570 packet_info *pinfo, proto_tree *tree, guint8 *drep)
572 guint16 u16AlarmSpecifierSequence;
573 guint16 u16AlarmSpecifierChannel;
574 guint16 u16AlarmSpecifierManufacturer;
575 guint16 u16AlarmSpecifierSubmodule;
576 guint16 u16AlarmSpecifierAR;
577 proto_item *sub_item;
578 proto_tree *sub_tree;
580 /* alarm specifier */
581 sub_item = proto_tree_add_item(tree, hf_pn_io_alarm_specifier, tvb, offset, 2, FALSE);
582 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pdu_type);
584 dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
585 hf_pn_io_alarm_specifier_sequence, &u16AlarmSpecifierSequence);
586 u16AlarmSpecifierSequence &= 0x07FF;
587 dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
588 hf_pn_io_alarm_specifier_channel, &u16AlarmSpecifierChannel);
589 u16AlarmSpecifierChannel = (u16AlarmSpecifierChannel &0x0800) >> 11;
590 dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
591 hf_pn_io_alarm_specifier_manufacturer, &u16AlarmSpecifierManufacturer);
592 u16AlarmSpecifierManufacturer = (u16AlarmSpecifierManufacturer &0x1000) >> 12;
593 dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
594 hf_pn_io_alarm_specifier_submodule, &u16AlarmSpecifierSubmodule);
595 u16AlarmSpecifierSubmodule = (u16AlarmSpecifierSubmodule & 0x2000) >> 13;
596 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
597 hf_pn_io_alarm_specifier_ardiagnosis, &u16AlarmSpecifierAR);
598 u16AlarmSpecifierAR = (u16AlarmSpecifierAR & 0x8000) >> 15;
601 proto_item_append_text(sub_item, ", Sequence: %u, Channel: %u, Manuf: %u, Submodule: %u AR: %u",
602 u16AlarmSpecifierSequence, u16AlarmSpecifierChannel,
603 u16AlarmSpecifierManufacturer, u16AlarmSpecifierSubmodule, u16AlarmSpecifierAR);
609 /* dissect the alarm header */
611 dissect_Alarm_header(tvbuff_t *tvb, int offset,
612 packet_info *pinfo, proto_tree *tree, guint8 *drep)
614 guint16 u16AlarmType;
617 guint16 u16SubslotNr;
619 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
620 hf_pn_io_alarm_type, &u16AlarmType);
621 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
622 hf_pn_io_api, &u32Api);
623 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
624 hf_pn_io_slot_nr, &u16SlotNr);
625 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
626 hf_pn_io_subslot_nr, &u16SubslotNr);
628 if (check_col(pinfo->cinfo, COL_INFO))
629 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s, Slot: 0x%x/0x%x",
630 val_to_str(u16AlarmType, pn_io_alarm_type, "Unknown"),
631 u16SlotNr, u16SubslotNr);
637 /* dissect the alarm note block */
639 dissect_Alarm_note_block(tvbuff_t *tvb, int offset,
640 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 body_length)
642 guint32 u32ModuleIdentNumber;
643 guint32 u32SubmoduleIdentNumber;
645 if (check_col(pinfo->cinfo, COL_INFO))
646 col_append_str(pinfo->cinfo, COL_INFO, ", Alarm Notification");
648 offset = dissect_Alarm_header(tvb, offset, pinfo, tree, drep);
650 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
651 hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
652 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
653 hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
655 offset = dissect_Alarm_specifier(tvb, offset, pinfo, tree, drep);
657 /* XXX - dissect AlarmItem */
659 proto_tree_add_string_format(tree, hf_pn_io_data, tvb, offset, body_length, "data",
660 "Alarm Item Data: %u bytes", body_length);
661 offset += body_length;
667 /* dissect the alarm acknowledge block */
669 dissect_Alarm_ack_block(tvbuff_t *tvb, int offset,
670 packet_info *pinfo, proto_tree *tree, guint8 *drep)
672 if (check_col(pinfo->cinfo, COL_INFO))
673 col_append_str(pinfo->cinfo, COL_INFO, ", Alarm Ack");
675 offset = dissect_Alarm_header(tvb, offset, pinfo, tree, drep);
677 offset = dissect_Alarm_specifier(tvb, offset, pinfo, tree, drep);
679 offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
685 /* dissect the read/write header */
687 dissect_ReadWrite_header(tvbuff_t *tvb, int offset,
688 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index)
693 guint16 u16SubslotNr;
696 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
697 hf_pn_io_seq_number, &u16SeqNr);
699 offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
700 hf_pn_io_ar_uuid, &uuid);
702 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
703 hf_pn_io_api, &u32Api);
704 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
705 hf_pn_io_slot_nr, &u16SlotNr);
706 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
707 hf_pn_io_subslot_nr, &u16SubslotNr);
708 proto_tree_add_string_format(tree, hf_pn_io_padding, tvb, offset, 2, "padding", "Padding: 2 bytes");
710 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
711 hf_pn_io_index, u16Index);
713 if (check_col(pinfo->cinfo, COL_INFO))
714 col_append_fstr(pinfo->cinfo, COL_INFO, ", Api: 0x%x, Slot: 0x%x/0x%x",
715 u32Api, u16SlotNr, u16SubslotNr);
721 /* dissect the read/write request block */
723 dissect_ReadWrite_rqst_block(tvbuff_t *tvb, int offset,
724 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen)
727 offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, drep, u16Index);
729 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
730 hf_pn_io_record_data_length, u32RecDataLen);
731 /* XXX: don't know how to handle the optional TargetARUUID */
733 if (check_col(pinfo->cinfo, COL_INFO))
734 col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
741 /* dissect the read/write response block */
743 dissect_ReadWrite_resp_block(tvbuff_t *tvb, int offset,
744 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index)
746 guint32 u32RecDataLen;
751 offset = dissect_ReadWrite_header(tvb, offset, pinfo, tree, drep, u16Index);
753 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
754 hf_pn_io_record_data_length, &u32RecDataLen);
756 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
757 hf_pn_io_add_val1, &u16AddVal1);
759 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
760 hf_pn_io_add_val2, &u16AddVal2);
762 if (check_col(pinfo->cinfo, COL_INFO))
763 col_append_fstr(pinfo->cinfo, COL_INFO, ", %u bytes",
770 /* dissect the control/connect block */
772 dissect_ControlConnect_block(tvbuff_t *tvb, int offset,
773 packet_info *pinfo, proto_tree *tree, guint8 *drep)
776 proto_item *sub_item;
777 proto_tree *sub_tree;
779 guint16 u16ApplReady;
784 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
785 hf_pn_io_reserved16, NULL);
787 offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
788 hf_pn_io_ar_uuid, &ar_uuid);
790 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
791 hf_pn_io_sessionkey, NULL);
793 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
794 hf_pn_io_reserved16, NULL);
796 sub_item = proto_tree_add_item(tree, hf_pn_io_control_command, tvb, offset, 2, FALSE);
797 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_control_command);
799 dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
800 hf_pn_io_control_command_prmend, &u16PrmEnd);
801 if(u16PrmEnd & 0x0001) {
802 proto_item_append_text(sub_item, ", Parameter End");
803 if (check_col(pinfo->cinfo, COL_INFO))
804 col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Parameter End\"");
806 dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
807 hf_pn_io_control_command_applready, &u16ApplReady);
808 if((u16ApplReady >> 1) & 0x0001) {
809 proto_item_append_text(sub_item, ", Application Ready");
810 if (check_col(pinfo->cinfo, COL_INFO))
811 col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Application Ready\"");
813 dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
814 hf_pn_io_control_command_release, &u16Release);
815 if((u16Release >> 2) & 0x0001) {
816 proto_item_append_text(sub_item, ", Release");
817 if (check_col(pinfo->cinfo, COL_INFO))
818 col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Release\"");
820 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
821 hf_pn_io_control_command_done, &u16CmdDone);
822 if((u16CmdDone >> 3) & 0x0001) {
823 proto_item_append_text(sub_item, ", Done");
824 if (check_col(pinfo->cinfo, COL_INFO))
825 col_append_fstr(pinfo->cinfo, COL_INFO, ", Command: \"Done\"");
828 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
829 hf_pn_io_control_block_properties, NULL);
835 /* dissect the ARBlockReq */
837 dissect_ARBlockReq(tvbuff_t *tvb, int offset,
838 packet_info *pinfo, proto_tree *tree, guint8 *drep)
842 guint16 u16SessionKey;
844 guint32 u32ARProperties;
845 guint16 u16TimeoutFactor;
846 guint16 u16UDPRTPort;
847 guint16 u16NameLength;
848 guint8 *pu8StationName;
851 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
852 hf_pn_io_ar_type, &u16ARType);
853 offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
854 hf_pn_io_ar_uuid, &uuid);
855 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
856 hf_pn_io_sessionkey, &u16SessionKey);
857 offset = dissect_MAC(tvb, offset, pinfo, tree,
858 hf_pn_io_cminitiator_macadd, mac);
859 offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
860 hf_pn_io_cminitiator_objectuuid, &uuid);
861 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
862 hf_pn_io_ar_properties, &u32ARProperties);
863 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
864 hf_pn_io_cminitiator_activitytimeoutfactor, &u16TimeoutFactor); /* XXX - special values */
865 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
866 hf_pn_io_cminitiator_udprtport, &u16UDPRTPort); /* XXX - special values */
867 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
868 hf_pn_io_station_name_length, &u16NameLength);
870 pu8StationName = ep_alloc(u16NameLength+1);
871 tvb_memcpy(tvb, pu8StationName, offset, u16NameLength);
872 pu8StationName[u16NameLength] = '\0';
873 proto_tree_add_string (tree, hf_pn_io_cminitiator_station_name, tvb, offset, u16NameLength, pu8StationName);
874 offset += u16NameLength;
876 /*if (check_col(pinfo->cinfo, COL_INFO))
877 col_append_fstr(pinfo->cinfo, COL_INFO, ", Api: %u, Slot: %u/%u",
878 u32Api, u16SlotNr, u16SubslotNr);*/
884 /* dissect the ARBlockRes */
886 dissect_ARBlockRes(tvbuff_t *tvb, int offset,
887 packet_info *pinfo, proto_tree *tree, guint8 *drep)
891 guint16 u16SessionKey;
893 guint16 u16UDPRTPort;
896 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
897 hf_pn_io_ar_type, &u16ARType);
898 offset = dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep,
899 hf_pn_io_ar_uuid, &uuid);
900 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
901 hf_pn_io_sessionkey, &u16SessionKey);
902 offset = dissect_MAC(tvb, offset, pinfo, tree,
903 hf_pn_io_cmresponder_macadd, mac);
904 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
905 hf_pn_io_cmresponder_udprtport, &u16UDPRTPort); /* XXX - special values */
907 /*if (check_col(pinfo->cinfo, COL_INFO))
908 col_append_fstr(pinfo->cinfo, COL_INFO, ", Api: %u, Slot: %u/%u",
909 u32Api, u16SlotNr, u16SubslotNr);*/
915 /* dissect the IOCRBlockReq */
917 dissect_IOCRBlockReq(tvbuff_t *tvb, int offset,
918 packet_info *pinfo, proto_tree *tree, guint8 *drep)
921 guint16 u16IOCRReference;
923 guint32 u32IOCRProperties;
924 guint16 u16DataLength;
926 guint16 u16SendClockFactor;
927 guint16 u16ReductionRatio;
930 guint32 u32FrameSendOffset;
931 guint16 u16WatchdogFactor;
932 guint16 u16DataHoldFactor;
933 guint16 u16IOCRTagHeader;
935 guint16 u16NumberOfAPIs;
937 guint16 u16NumberOfIODataObjects;
939 guint16 u16SubslotNr;
940 guint16 u16IODataObjectFrameOffset;
941 guint16 u16NumberOfIOCS;
942 guint16 u16IOCSFrameOffset;
943 proto_item *api_item;
944 proto_tree *api_tree;
947 proto_item *sub_item;
948 proto_tree *sub_tree;
952 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
953 hf_pn_io_iocr_type, &u16IOCRType);
954 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
955 hf_pn_io_iocr_reference, &u16IOCRReference);
956 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
957 hf_pn_io_lt, &u16LT);
958 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
959 hf_pn_io_iocr_properties, &u32IOCRProperties);
960 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
961 hf_pn_io_data_length, &u16DataLength);
962 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
963 hf_pn_io_frame_id, &u16FrameID);
964 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
965 hf_pn_io_send_clock_factor, &u16SendClockFactor);
966 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
967 hf_pn_io_reduction_ratio, &u16ReductionRatio);
968 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
969 hf_pn_io_phase, &u16Phase);
970 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
971 hf_pn_io_sequence, &u16Sequence);
972 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
973 hf_pn_io_frame_send_offset, &u32FrameSendOffset);
974 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
975 hf_pn_io_watchdog_factor, &u16WatchdogFactor);
976 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
977 hf_pn_io_data_hold_factor, &u16DataHoldFactor);
978 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
979 hf_pn_io_iocr_tag_header, &u16IOCRTagHeader);
980 offset = dissect_MAC(tvb, offset, pinfo, tree,
981 hf_pn_io_iocr_multicast_mac_add, mac);
983 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
984 hf_pn_io_number_of_apis, &u16NumberOfAPIs);
985 while(u16NumberOfAPIs--) {
986 api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, FALSE);
987 api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
988 u32ApiStart = offset;
991 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
992 hf_pn_io_api, &u32Api);
993 /* NumberOfIODataObjects */
994 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
995 hf_pn_io_number_of_io_data_objects, &u16NumberOfIODataObjects);
997 u16Tmp = u16NumberOfIODataObjects;
999 sub_item = proto_tree_add_item(api_tree, hf_pn_io_io_data_object, tvb, offset, 0, FALSE);
1000 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_io_data_object);
1001 u32SubStart = offset;
1004 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1005 hf_pn_io_slot_nr, &u16SlotNr);
1007 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1008 hf_pn_io_subslot_nr, &u16SubslotNr);
1009 /* IODataObjectFrameOffset */
1010 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1011 hf_pn_io_io_data_object_frame_offset, &u16IODataObjectFrameOffset);
1013 proto_item_append_text(sub_item, ": Slot: 0x%x, Subslot: 0x%x FrameOffset: %u",
1014 u16SlotNr, u16SubslotNr, u16IODataObjectFrameOffset);
1016 proto_item_set_len(sub_item, offset - u32SubStart);
1019 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
1020 hf_pn_io_number_of_iocs, &u16NumberOfIOCS);
1022 u16Tmp = u16NumberOfIOCS;
1024 sub_item = proto_tree_add_item(api_tree, hf_pn_io_io_cs, tvb, offset, 0, FALSE);
1025 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_io_cs);
1026 u32SubStart = offset;
1029 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1030 hf_pn_io_slot_nr, &u16SlotNr);
1032 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1033 hf_pn_io_subslot_nr, &u16SubslotNr);
1034 /* IOCSFrameOffset */
1035 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1036 hf_pn_io_iocs_frame_offset, &u16IOCSFrameOffset);
1038 proto_item_append_text(sub_item, ": Slot: 0x%x, Subslot: 0x%x FrameOffset: %u",
1039 u16SlotNr, u16SubslotNr, u16IOCSFrameOffset);
1041 proto_item_set_len(sub_item, offset - u32SubStart);
1044 proto_item_append_text(api_item, ": %u, NumberOfIODataObjects: %u NumberOfIOCS: %u",
1045 u32Api, u16NumberOfIODataObjects, u16NumberOfIOCS);
1047 proto_item_set_len(api_item, offset - u32ApiStart);
1054 /* dissect the AlarmCRBlockReq */
1056 dissect_AlarmCRBlockReq(tvbuff_t *tvb, int offset,
1057 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1059 guint16 u16AlarmCRType;
1061 guint32 u32AlarmCRProperties;
1062 guint16 u16RTATimeoutFactor;
1063 guint16 u16RTARetries;
1064 guint16 u16LocalAlarmReference;
1065 guint16 u16MaxAlarmDataLength;
1066 guint16 u16AlarmCRTagHeaderHigh;
1067 guint16 u16AlarmCRTagHeaderLow;
1070 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1071 hf_pn_io_alarmcr_type, &u16AlarmCRType);
1072 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1073 hf_pn_io_lt, &u16LT);
1074 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
1075 hf_pn_io_alarmcr_properties, &u32AlarmCRProperties);
1076 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1077 hf_pn_io_rta_timeoutfactor, &u16RTATimeoutFactor);
1078 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1079 hf_pn_io_rta_retries, &u16RTARetries);
1080 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1081 hf_pn_io_localalarmref, &u16LocalAlarmReference);
1082 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1083 hf_pn_io_maxalarmdatalength, &u16MaxAlarmDataLength);
1084 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1085 hf_pn_io_alarmcr_tagheaderhigh, &u16AlarmCRTagHeaderHigh);
1086 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1087 hf_pn_io_alarmcr_tagheaderlow, &u16AlarmCRTagHeaderLow);
1093 /* dissect the AlarmCRBlockRes */
1095 dissect_AlarmCRBlockRes(tvbuff_t *tvb, int offset,
1096 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1098 guint16 u16AlarmCRType;
1099 guint16 u16LocalAlarmReference;
1100 guint16 u16MaxAlarmDataLength;
1103 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1104 hf_pn_io_alarmcr_type, &u16AlarmCRType);
1105 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1106 hf_pn_io_localalarmref, &u16LocalAlarmReference);
1107 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1108 hf_pn_io_maxalarmdatalength, &u16MaxAlarmDataLength);
1115 /* dissect the IOCRBlockRes */
1117 dissect_IOCRBlockRes(tvbuff_t *tvb, int offset,
1118 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1120 guint16 u16IOCRType;
1121 guint16 u16IOCRReference;
1125 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1126 hf_pn_io_iocr_type, &u16IOCRType);
1127 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1128 hf_pn_io_iocr_reference, &u16IOCRReference);
1129 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1130 hf_pn_io_frame_id, &u16FrameID);
1137 /* dissect the MCRBlockReq */
1139 dissect_MCRBlockReq(tvbuff_t *tvb, int offset,
1140 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1142 guint16 u16IOCRReference;
1143 guint32 u32AddressResolutionProperties;
1144 guint16 u16MCITimeoutFactor;
1145 guint16 u16NameLength;
1146 guint8 *pu8StationName;
1149 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1150 hf_pn_io_iocr_reference, &u16IOCRReference);
1151 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, tree, drep,
1152 hf_pn_io_address_resolution_properties, &u32AddressResolutionProperties);
1153 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1154 hf_pn_io_mci_timeout_factor, &u16MCITimeoutFactor);
1156 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1157 hf_pn_io_station_name_length, &u16NameLength);
1159 pu8StationName = ep_alloc(u16NameLength+1);
1160 tvb_memcpy(tvb, pu8StationName, offset, u16NameLength);
1161 pu8StationName[u16NameLength] = '\0';
1162 proto_tree_add_string (tree, hf_pn_io_provider_station_name, tvb, offset, u16NameLength, pu8StationName);
1163 offset += u16NameLength;
1170 /* dissect the DataDescription */
1172 dissect_DataDescription(tvbuff_t *tvb, int offset,
1173 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1175 guint16 u16DataDescription;
1176 guint16 u16SubmoduleDataLength;
1177 guint8 u8LengthIOCS;
1178 guint8 u8LengthIOPS;
1179 proto_item *sub_item;
1180 proto_tree *sub_tree;
1181 guint32 u32SubStart;
1184 sub_item = proto_tree_add_item(tree, hf_pn_io_data_description_tree, tvb, offset, 0, FALSE);
1185 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_data_description);
1186 u32SubStart = offset;
1188 /* DataDescription */
1189 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1190 hf_pn_io_data_description, &u16DataDescription);
1191 /* SubmoduleDataLength */
1192 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1193 hf_pn_io_submodule_data_length, &u16SubmoduleDataLength);
1195 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
1196 hf_pn_io_length_iocs, &u8LengthIOCS);
1198 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
1199 hf_pn_io_length_iops, &u8LengthIOPS);
1201 proto_item_append_text(sub_item, ": %s, SubmoduleDataLength: %u, LengthIOCS: %u, u8LengthIOPS: %u",
1202 val_to_str(u16DataDescription, pn_io_data_description, "(0x%x)"),
1203 u16SubmoduleDataLength, u8LengthIOCS, u8LengthIOPS);
1204 proto_item_set_len(sub_item, offset - u32SubStart);
1210 /* dissect the ExpectedSubmoduleBlockReq */
1212 dissect_ExpectedSubmoduleBlockReq(tvbuff_t *tvb, int offset,
1213 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1215 guint16 u16NumberOfAPIs;
1218 guint32 u32ModuleIdentNumber;
1219 guint16 u16ModuleProperties;
1220 guint16 u16NumberOfSubmodules;
1221 guint16 u16SubslotNr;
1222 guint32 u32SubmoduleIdentNumber;
1223 guint16 u16SubmoduleProperties;
1224 proto_item *api_item;
1225 proto_tree *api_tree;
1226 guint32 u32ApiStart;
1227 proto_item *sub_item;
1228 proto_tree *sub_tree;
1229 guint32 u32SubStart;
1232 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1233 hf_pn_io_number_of_apis, &u16NumberOfAPIs);
1234 while(u16NumberOfAPIs--) {
1235 api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, FALSE);
1236 api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
1237 u32ApiStart = offset;
1240 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
1241 hf_pn_io_api, &u32Api);
1243 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
1244 hf_pn_io_slot_nr, &u16SlotNr);
1245 /* ModuleIdentNumber */
1246 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
1247 hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
1248 /* ModuleProperties */
1249 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
1250 hf_pn_io_module_properties, &u16ModuleProperties);
1251 /* NumberOfSubmodules */
1252 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
1253 hf_pn_io_number_of_submodules, &u16NumberOfSubmodules);
1255 proto_item_append_text(api_item, ": %u, Slot: 0x%x, ModuleIdentNumber: 0x%x ModuleProperties: 0x%x NumberOfSubmodules: %u",
1256 u32Api, u16SlotNr, u32ModuleIdentNumber, u16ModuleProperties, u16NumberOfSubmodules);
1258 while(u16NumberOfSubmodules--) {
1259 sub_item = proto_tree_add_item(api_tree, hf_pn_io_submodule_tree, tvb, offset, 0, FALSE);
1260 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_submodule);
1261 u32SubStart = offset;
1264 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1265 hf_pn_io_subslot_nr, &u16SubslotNr);
1266 /* SubmoduleIdentNumber */
1267 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
1268 hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
1269 /* SubmoduleProperties */
1270 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1271 hf_pn_io_submodule_properties, &u16SubmoduleProperties);
1273 switch(u16SubmoduleProperties & 0x03) {
1274 case(0x00): /* no input and no output data (one Input DataDescription Block follows) */
1275 offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep);
1277 case(0x01): /* input data (one Input DataDescription Block follows) */
1278 offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep);
1280 case(0x02): /* output data (one Output DataDescription Block follows) */
1281 offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep);
1283 case(0x03): /* input and output data (one Input and one Output DataDescription Block follows) */
1284 offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep);
1285 offset = dissect_DataDescription(tvb, offset, pinfo, sub_tree, drep);
1289 proto_item_append_text(sub_item, ": Subslot: 0x%x, SubmoduleIdent: 0x%x SubmoduleProperties: 0x%x",
1290 u16SubslotNr, u32SubmoduleIdentNumber, u16SubmoduleProperties);
1291 proto_item_set_len(sub_item, offset - u32SubStart);
1294 proto_item_set_len(api_item, offset - u32ApiStart);
1301 /* dissect the ModuleDiffBlock */
1303 dissect_ModuleDiffBlock(tvbuff_t *tvb, int offset,
1304 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1306 guint16 u16NumberOfAPIs;
1308 guint16 u16NumberOfModules;
1310 guint32 u32ModuleIdentNumber;
1311 guint16 u16ModuleState;
1312 guint16 u16NumberOfSubmodules;
1313 guint16 u16SubslotNr;
1314 guint32 u32SubmoduleIdentNumber;
1315 guint16 u16SubmoduleState;
1316 proto_item *api_item;
1317 proto_tree *api_tree;
1318 guint32 u32ApiStart;
1319 proto_item *module_item;
1320 proto_tree *module_tree;
1321 guint32 u32ModuleStart;
1322 proto_item *sub_item;
1323 proto_tree *sub_tree;
1324 guint32 u32SubStart;
1328 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
1329 hf_pn_io_number_of_apis, &u16NumberOfAPIs);
1330 while(u16NumberOfAPIs--) {
1331 api_item = proto_tree_add_item(tree, hf_pn_io_api_tree, tvb, offset, 0, FALSE);
1332 api_tree = proto_item_add_subtree(api_item, ett_pn_io_api);
1333 u32ApiStart = offset;
1336 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, api_tree, drep,
1337 hf_pn_io_api, &u32Api);
1338 /* NumberOfModules */
1339 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, api_tree, drep,
1340 hf_pn_io_number_of_modules, &u16NumberOfModules);
1342 proto_item_append_text(api_item, ": %u, NumberOfModules: %u",
1343 u32Api, u16NumberOfModules);
1345 while(u16NumberOfModules--) {
1346 module_item = proto_tree_add_item(api_tree, hf_pn_io_module_tree, tvb, offset, 0, FALSE);
1347 module_tree = proto_item_add_subtree(module_item, ett_pn_io_module);
1348 u32ModuleStart = offset;
1351 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
1352 hf_pn_io_slot_nr, &u16SlotNr);
1353 /* ModuleIdentNumber */
1354 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, module_tree, drep,
1355 hf_pn_io_module_ident_number, &u32ModuleIdentNumber);
1357 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
1358 hf_pn_io_module_state, &u16ModuleState);
1359 /* NumberOfSubmodules */
1360 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, module_tree, drep,
1361 hf_pn_io_number_of_submodules, &u16NumberOfSubmodules);
1363 proto_item_append_text(module_item, ": Slot 0x%x, ModuleIdent: 0x%x ModuleState: %s NumberOfSubmodules: %u",
1364 u16SlotNr, u32ModuleIdentNumber,
1365 val_to_str(u16ModuleState, pn_io_module_state, "(0x%x)"),
1366 u16NumberOfSubmodules);
1368 while(u16NumberOfSubmodules--) {
1369 sub_item = proto_tree_add_item(module_tree, hf_pn_io_submodule_tree, tvb, offset, 0, FALSE);
1370 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_submodule);
1371 u32SubStart = offset;
1374 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1375 hf_pn_io_subslot_nr, &u16SubslotNr);
1376 /* SubmoduleIdentNumber */
1377 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
1378 hf_pn_io_submodule_ident_number, &u32SubmoduleIdentNumber);
1379 /* SubmoduleState */
1380 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
1381 hf_pn_io_submodule_state, &u16SubmoduleState);
1383 proto_item_append_text(sub_item, ": Subslot 0x%x, SubmoduleIdentNumber: 0x%x, SubmoduleState: 0x%x",
1384 u16SubslotNr, u32SubmoduleIdentNumber, u16SubmoduleState);
1386 proto_item_set_len(sub_item, offset - u32SubStart);
1387 } /* NumberOfSubmodules */
1389 proto_item_set_len(module_item, offset - u32ModuleStart);
1392 proto_item_set_len(api_item, offset - u32ApiStart);
1399 /* dissect one PN-IO block (depending on the block type) */
1401 dissect_block(tvbuff_t *tvb, int offset,
1402 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 *u16Index, guint32 *u32RecDataLen)
1404 guint16 u16BlockType;
1405 guint16 u16BlockLength;
1406 guint8 u8BlockVersionHigh;
1407 guint8 u8BlockVersionLow;
1408 proto_item *sub_item;
1409 proto_tree *sub_tree;
1410 guint32 u32SubStart;
1411 guint16 u16BodyLength;
1412 proto_item *header_item;
1413 proto_tree *header_tree;
1416 /* from here, we only have big endian (network byte ordering)!!! */
1419 sub_item = proto_tree_add_item(tree, hf_pn_io_block, tvb, offset, 0, FALSE);
1420 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_block);
1421 u32SubStart = offset;
1423 header_item = proto_tree_add_item(sub_tree, hf_pn_io_block_header, tvb, offset, 6, FALSE);
1424 header_tree = proto_item_add_subtree(header_item, ett_pn_io_block_header);
1426 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, header_tree, drep,
1427 hf_pn_io_block_type, &u16BlockType);
1428 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, header_tree, drep,
1429 hf_pn_io_block_length, &u16BlockLength);
1430 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, header_tree, drep,
1431 hf_pn_io_block_version_high, &u8BlockVersionHigh);
1432 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, header_tree, drep,
1433 hf_pn_io_block_version_low, &u8BlockVersionLow);
1435 /* XXX - append block_header data to header_item */
1437 /* block length is without type and length fields, but with version field */
1438 /* as it's already dissected, remove it */
1439 u16BodyLength = u16BlockLength - 2;
1440 tvb_ensure_bytes_exist(tvb, offset, u16BodyLength);
1442 switch(u16BlockType) {
1445 dissect_Alarm_note_block(tvb, offset, pinfo, sub_tree, drep, u16BodyLength);
1448 dissect_ARBlockReq(tvb, offset, pinfo, sub_tree, drep);
1451 dissect_IOCRBlockReq(tvb, offset, pinfo, sub_tree, drep);
1454 dissect_AlarmCRBlockReq(tvb, offset, pinfo, sub_tree, drep);
1457 dissect_ExpectedSubmoduleBlockReq(tvb, offset, pinfo, sub_tree, drep);
1460 dissect_MCRBlockReq(tvb, offset, pinfo, sub_tree, drep);
1465 if (check_col(pinfo->cinfo, COL_INFO))
1466 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1467 val_to_str(u16BlockType, pn_io_block_type, "Unknown"));
1468 dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, drep);
1472 dissect_ReadWrite_rqst_block(tvb, offset, pinfo, sub_tree, drep, u16Index, u32RecDataLen);
1476 dissect_Alarm_ack_block(tvb, offset, pinfo, sub_tree, drep);
1480 dissect_ReadWrite_resp_block(tvb, offset, pinfo, sub_tree, drep, u16Index);
1483 dissect_ARBlockRes(tvb, offset, pinfo, sub_tree, drep);
1486 dissect_IOCRBlockRes(tvb, offset, pinfo, sub_tree, drep);
1489 dissect_AlarmCRBlockRes(tvb, offset, pinfo, sub_tree, drep);
1492 dissect_ModuleDiffBlock(tvb, offset, pinfo, sub_tree, drep);
1497 if (check_col(pinfo->cinfo, COL_INFO))
1498 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1499 val_to_str(u16BlockType, pn_io_block_type, "Unknown"));
1500 dissect_ControlConnect_block(tvb, offset, pinfo, sub_tree, drep);
1503 if (check_col(pinfo->cinfo, COL_INFO) && *u16Index < 3)
1504 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1505 val_to_str(u16BlockType, pn_io_block_type, "Unknown"));
1506 proto_tree_add_string_format(sub_tree, hf_pn_io_data, tvb, offset, u16BodyLength, "undecoded", "Undecoded Data: %d bytes", u16BodyLength);
1508 offset += u16BodyLength;
1510 proto_item_append_text(sub_item, "[%u]: Type=\"%s\" (0x%04x), Length=%u(+4), Version=%u.%u",
1511 *u16Index, val_to_str(u16BlockType, pn_io_block_type, "Unknown"), u16BlockType,
1512 u16BlockLength, u8BlockVersionHigh, u8BlockVersionLow);
1513 proto_item_set_len(sub_item, offset - u32SubStart);
1519 /* dissect any number of PN-IO blocks */
1521 dissect_blocks(tvbuff_t *tvb, int offset,
1522 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1524 guint16 u16Index = 0;
1525 guint32 u32RecDataLen;
1528 while(tvb_length(tvb) > (guint) offset) {
1529 offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
1533 /* we don't want to have too many blocks in the info column */
1535 if (check_col(pinfo->cinfo, COL_INFO))
1536 col_append_fstr(pinfo->cinfo, COL_INFO, ", ... (%u blocks)",
1543 /* dissect a PN-IO (DCE-RPC) request header */
1545 dissect_IPNIO_rqst_header(tvbuff_t *tvb, int offset,
1546 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1550 guint32 u32MaxCount;
1552 guint32 u32ArraySize;
1554 proto_item *sub_item;
1555 proto_tree *sub_tree;
1556 guint32 u32SubStart;
1559 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1560 col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-CM");
1563 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1564 hf_pn_io_args_max, &u32ArgsMax);
1566 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1567 hf_pn_io_args_len, &u32ArgsLen);
1569 sub_item = proto_tree_add_item(tree, hf_pn_io_array, tvb, offset, 0, FALSE);
1570 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io);
1571 u32SubStart = offset;
1573 /* RPC array header */
1574 offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
1575 hf_pn_io_array_max_count, &u32MaxCount);
1576 offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
1577 hf_pn_io_array_offset, &u32Offset);
1578 offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
1579 hf_pn_io_array_act_count, &u32ArraySize);
1581 proto_item_append_text(sub_item, ": Max: %u, Offset: %u, Size: %u",
1582 u32MaxCount, u32Offset, u32ArraySize);
1583 proto_item_set_len(sub_item, offset - u32SubStart);
1589 /* dissect a PN-IO (DCE-RPC) response header */
1591 dissect_IPNIO_resp_header(tvbuff_t *tvb, int offset,
1592 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1595 guint32 u32MaxCount;
1597 guint32 u32ArraySize;
1599 proto_item *sub_item;
1600 proto_tree *sub_tree;
1601 guint32 u32SubStart;
1604 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1605 col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-CM");
1607 offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
1610 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep,
1611 hf_pn_io_args_len, &u32ArgsLen);
1613 sub_item = proto_tree_add_item(tree, hf_pn_io_array, tvb, offset, 0, FALSE);
1614 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io);
1615 u32SubStart = offset;
1617 /* RPC array header */
1618 offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
1619 hf_pn_io_array_max_count, &u32MaxCount);
1620 offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
1621 hf_pn_io_array_offset, &u32Offset);
1622 offset = dissect_ndr_uint32(tvb, offset, pinfo, sub_tree, drep,
1623 hf_pn_io_array_act_count, &u32ArraySize);
1625 proto_item_append_text(sub_item, ": Max: %u, Offset: %u, Size: %u",
1626 u32MaxCount, u32Offset, u32ArraySize);
1627 proto_item_set_len(sub_item, offset - u32SubStart);
1633 /* dissect a PN-IO connect request */
1635 dissect_IPNIO_Connect_rqst(tvbuff_t *tvb, int offset,
1636 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1639 offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
1642 offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
1648 /* dissect a PN-IO connect response */
1650 dissect_IPNIO_Connect_resp(tvbuff_t *tvb, int offset,
1651 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1654 offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
1657 offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
1663 /* dissect a PN-IO release request */
1665 dissect_IPNIO_Release_rqst(tvbuff_t *tvb, int offset,
1666 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1669 offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
1672 offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
1678 /* dissect a PN-IO release response */
1680 dissect_IPNIO_Release_resp(tvbuff_t *tvb, int offset,
1681 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1684 offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
1687 offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
1693 /* dissect a PN-IO control request */
1695 dissect_IPNIO_Control_rqst(tvbuff_t *tvb, int offset,
1696 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1699 offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
1702 offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
1708 /* dissect a PN-IO control response */
1710 dissect_IPNIO_Control_resp(tvbuff_t *tvb, int offset,
1711 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1714 offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
1717 offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
1723 /* dissect a PN-IO read request */
1725 dissect_IPNIO_Read_rqst(tvbuff_t *tvb, int offset,
1726 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1728 guint16 u16Index = 0;
1729 guint32 u32RecDataLen;
1731 offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
1734 offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
1740 /* dissect a PN-IO read response */
1742 dissect_IPNIO_Read_resp(tvbuff_t *tvb, int offset,
1743 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1746 guint16 u16Index = 0;
1747 guint32 u32RecDataLen;
1749 offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
1752 offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
1754 /* XXX - RecordDataRead: dissection not yet implemented */
1755 remain = tvb_length_remaining(tvb, offset);
1756 proto_tree_add_string_format(tree, hf_pn_io_data, tvb, offset, remain, "data", "User Data: %d bytes", remain);
1764 dissect_IODWriteReq(tvbuff_t *tvb, int offset,
1765 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1768 guint16 u16Index = 0;
1769 guint32 u32RecDataLen;
1772 /* IODWriteHeader */
1773 offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
1776 /* IODWriteMultipleReq? */
1777 if(u16Index == 0xe040) {
1778 while((remain = tvb_length_remaining(tvb, offset)) > 0) {
1779 offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep);
1782 /* RecordDataWrite */
1783 /* XXX - dissection not yet implemented */
1784 proto_tree_add_string_format(tree, hf_pn_io_data, tvb, offset, u32RecDataLen, "data", "RecordDataWrite: %d bytes", u32RecDataLen);
1785 offset += u32RecDataLen;
1787 /* XXX - add padding (required with IODWriteMultipleReq) */
1788 switch(offset % 4) {
1804 /* dissect a PN-IO write request */
1806 dissect_IPNIO_Write_rqst(tvbuff_t *tvb, int offset,
1807 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1809 offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, drep);
1811 offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep);
1819 dissect_IODWriteRes(tvbuff_t *tvb, int offset,
1820 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1823 guint16 u16Index = 0;
1824 guint32 u32RecDataLen;
1827 /* IODWriteResHeader */
1828 offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen);
1830 /* IODWriteMultipleRes? */
1831 if(u16Index == 0xe040) {
1832 while((remain = tvb_length_remaining(tvb, offset)) > 0) {
1833 offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
1841 /* dissect a PN-IO write response */
1843 dissect_IPNIO_Write_resp(tvbuff_t *tvb, int offset,
1844 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1846 guint16 u16Index = 0;
1848 offset = dissect_IPNIO_resp_header(tvb, offset, pinfo, tree, drep);
1850 offset = dissect_IODWriteRes(tvb, offset, pinfo, tree, drep);
1856 /* dissect the IOxS (IOCS, IOPS) field */
1858 dissect_PNIO_IOxS(tvbuff_t *tvb, int offset,
1859 packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_)
1862 proto_item *ioxs_item = NULL;
1863 proto_tree *ioxs_tree = NULL;
1866 u8IOxS = tvb_get_guint8(tvb, offset);
1868 /* add ioxs subtree */
1869 ioxs_item = proto_tree_add_uint_format(tree, hf_pn_io_ioxs,
1870 tvb, offset, 1, u8IOxS,
1871 "IOxS: 0x%02x (%s%s)",
1873 (u8IOxS & 0x01) ? "another IOxS follows " : "",
1874 (u8IOxS & 0x80) ? "good" : "bad");
1875 ioxs_tree = proto_item_add_subtree(ioxs_item, ett_pn_io_ioxs);
1877 proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_extension, tvb, offset, 1, u8IOxS);
1878 proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_res14, tvb, offset, 1, u8IOxS);
1879 proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_instance, tvb, offset, 1, u8IOxS);
1880 proto_tree_add_uint(ioxs_tree, hf_pn_io_ioxs_datastate, tvb, offset, 1, u8IOxS);
1886 /* dissect a PN-IO Cyclic Service Data Unit (on top of PN-RT protocol) */
1888 dissect_PNIO_C_SDU(tvbuff_t *tvb, int offset,
1889 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1891 proto_item *data_item;
1892 proto_tree *data_tree;
1895 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1896 col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO");
1899 data_item = proto_tree_add_protocol_format(tree, proto_pn_io, tvb, offset, tvb_length(tvb),
1900 "PROFINET IO Cyclic Service Data Unit: %u bytes", tvb_length(tvb));
1901 data_tree = proto_item_add_subtree(data_item, ett_pn_io_rtc);
1903 offset = dissect_PNIO_IOxS(tvb, offset, pinfo, data_tree, drep);
1905 /* XXX - dissect the remaining data */
1906 /* this will be one or more DataItems followed by an optional GAP and RTCPadding */
1907 /* as we don't have the required context information to dissect the specific DataItems, this will be tricky :-( */
1908 data_item = proto_tree_add_protocol_format(data_tree, proto_pn_io, tvb, offset, tvb_length_remaining(tvb, offset),
1909 "Data: %u bytes (including GAP and RTCPadding)", tvb_length_remaining(tvb, offset));
1916 /* dissect a PN-IO RTA PDU (on top of PN-RT protocol) */
1918 dissect_PNIO_RTA(tvbuff_t *tvb, int offset,
1919 packet_info *pinfo, proto_tree *tree, guint8 *drep)
1921 guint16 u16AlarmDstEndpoint;
1922 guint16 u16AlarmSrcEndpoint;
1924 guint8 u8PDUVersion;
1925 guint8 u8WindowSize;
1927 guint16 u16SendSeqNum;
1928 guint16 u16AckSeqNum;
1929 guint16 u16VarPartLen;
1930 int start_offset = offset;
1931 guint16 u16Index = 0;
1932 guint32 u32RecDataLen;
1935 proto_item *rta_item;
1936 proto_tree *rta_tree;
1938 proto_item *sub_item;
1939 proto_tree *sub_tree;
1942 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1943 col_add_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-AL");
1945 rta_item = proto_tree_add_protocol_format(tree, proto_pn_io, tvb, offset, tvb_length(tvb),
1946 "PROFINET IO Alarm");
1947 rta_tree = proto_item_add_subtree(rta_item, ett_pn_io_rta);
1949 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
1950 hf_pn_io_alarm_dst_endpoint, &u16AlarmDstEndpoint);
1951 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
1952 hf_pn_io_alarm_src_endpoint, &u16AlarmSrcEndpoint);
1954 if (check_col(pinfo->cinfo, COL_INFO))
1955 col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: 0x%x, Dst: 0x%x",
1956 u16AlarmSrcEndpoint, u16AlarmDstEndpoint);
1959 sub_item = proto_tree_add_item(rta_tree, hf_pn_io_pdu_type, tvb, offset, 1, FALSE);
1960 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pdu_type);
1961 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
1962 hf_pn_io_pdu_type_type, &u8PDUType);
1964 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
1965 hf_pn_io_pdu_type_version, &u8PDUVersion);
1967 proto_item_append_text(sub_item, ", Type: %s, Version: %u",
1968 val_to_str(u8PDUType, pn_io_pdu_type, "Unknown"),
1971 /* additional flags */
1972 sub_item = proto_tree_add_item(rta_tree, hf_pn_io_add_flags, tvb, offset, 1, FALSE);
1973 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_add_flags);
1974 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
1975 hf_pn_io_window_size, &u8WindowSize);
1976 u8WindowSize &= 0x0F;
1977 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
1978 hf_pn_io_tack, &u8Tack);
1980 proto_item_append_text(sub_item, ", Window Size: %u, Tack: %u",
1981 u8WindowSize, u8Tack);
1983 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
1984 hf_pn_io_send_seq_num, &u16SendSeqNum);
1985 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
1986 hf_pn_io_ack_seq_num, &u16AckSeqNum);
1987 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
1988 hf_pn_io_var_part_len, &u16VarPartLen);
1990 switch(u8PDUType & 0x0F) {
1991 case(1): /* Data-RTA */
1992 if (check_col(pinfo->cinfo, COL_INFO))
1993 col_append_str(pinfo->cinfo, COL_INFO, ", Data-RTA");
1994 offset = dissect_block(tvb, offset, pinfo, rta_tree, drep, &u16Index, &u32RecDataLen);
1996 case(2): /* NACK-RTA */
1997 if (check_col(pinfo->cinfo, COL_INFO))
1998 col_append_str(pinfo->cinfo, COL_INFO, ", NACK-RTA");
1999 /* no additional data */
2001 case(3): /* ACK-RTA */
2002 if (check_col(pinfo->cinfo, COL_INFO))
2003 col_append_str(pinfo->cinfo, COL_INFO, ", ACK-RTA");
2004 /* no additional data */
2006 case(4): /* ERR-RTA */
2007 if (check_col(pinfo->cinfo, COL_INFO))
2008 col_append_str(pinfo->cinfo, COL_INFO, ", ERR-RTA");
2009 offset = dissect_PNIO_status(tvb, offset, pinfo, rta_tree, drep);
2012 proto_tree_add_string_format(tree, hf_pn_io_data, tvb, 0, tvb_length(tvb), "data",
2013 "PN-IO Alarm: unknown PDU type 0x%x", u8PDUType);
2016 proto_item_set_len(rta_item, offset - start_offset);
2022 /* possibly dissect a PN-IO related PN-RT packet */
2024 dissect_PNIO_heur(tvbuff_t *tvb,
2025 packet_info *pinfo, proto_tree *tree)
2027 guint8 drep_data = 0;
2028 guint8 *drep = &drep_data;
2029 guint8 u8CBAVersion;
2033 /* the sub tvb will NOT contain the frame_id here! */
2034 u16FrameID = GPOINTER_TO_UINT(pinfo->private_data);
2036 u8CBAVersion = tvb_get_guint8 (tvb, 0);
2038 /* is this a PNIO class 2 data packet? */
2039 /* frame id must be in valid range (cyclic Real-Time, class=2) */
2040 if (u16FrameID >= 0x8000 && u16FrameID < 0xbf00) {
2041 dissect_PNIO_C_SDU(tvb, 0, pinfo, tree, drep);
2045 /* is this a PNIO class 1 data packet? */
2046 /* frame id must be in valid range (cyclic Real-Time, class=1) and
2047 * first byte (CBA version field) has to be != 0x11 */
2048 if (u16FrameID >= 0xc000 && u16FrameID < 0xfb00 && u8CBAVersion != 0x11) {
2049 dissect_PNIO_C_SDU(tvb, 0, pinfo, tree, drep);
2053 /* is this a PNIO high priority alarm packet? */
2054 if(u16FrameID == 0xfc01) {
2055 if (check_col(pinfo->cinfo, COL_INFO))
2056 col_add_str(pinfo->cinfo, COL_INFO, "Alarm High");
2058 dissect_PNIO_RTA(tvb, 0, pinfo, tree, drep);
2062 /* is this a PNIO low priority alarm packet? */
2063 if(u16FrameID == 0xfe01) {
2064 if (check_col(pinfo->cinfo, COL_INFO))
2065 col_add_str(pinfo->cinfo, COL_INFO, "Alarm Low");
2067 dissect_PNIO_RTA(tvb, 0, pinfo, tree, drep);
2071 /* this PN-RT packet doesn't seem to be PNIO specific */
2076 /* the PNIO dcerpc interface table */
2077 static dcerpc_sub_dissector pn_io_dissectors[] = {
2078 { 0, "Connect", dissect_IPNIO_Connect_rqst, dissect_IPNIO_Connect_resp },
2079 { 1, "Release", dissect_IPNIO_Release_rqst, dissect_IPNIO_Release_resp },
2080 { 2, "Read", dissect_IPNIO_Read_rqst, dissect_IPNIO_Read_resp },
2081 { 3, "Write", dissect_IPNIO_Write_rqst, dissect_IPNIO_Write_resp },
2082 { 4, "Control", dissect_IPNIO_Control_rqst, dissect_IPNIO_Control_resp },
2083 { 0, NULL, NULL, NULL }
2088 proto_register_pn_io (void)
2090 static hf_register_info hf[] = {
2092 { "Operation", "pn_io.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2093 { &hf_pn_io_reserved16,
2094 { "Reserved", "pn_io.reserved16", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2096 { "Array", "pn_io.array", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2098 { "Status", "pn_io.status", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2099 { &hf_pn_io_args_max,
2100 { "ArgsMaximum", "pn_io.args_max", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2101 { &hf_pn_io_args_len,
2102 { "ArgsLength", "pn_io.args_len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2103 { &hf_pn_io_array_max_count,
2104 { "MaximumCount", "pn_io.array_max_count", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2105 { &hf_pn_io_array_offset,
2106 { "Offset", "pn_io.array_offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2107 { &hf_pn_io_array_act_count,
2108 { "ActualCount", "pn_io.array_act_count", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2110 { &hf_pn_io_ar_type,
2111 { "ARType", "pn_io.ar_type", FT_UINT16, BASE_HEX, VALS(pn_io_ar_type), 0x0, "", HFILL }},
2112 { &hf_pn_io_cminitiator_macadd,
2113 { "CMInitiatorMacAdd", "pn_io.cminitiator_mac_add", FT_ETHER, BASE_HEX, 0x0, 0x0, "", HFILL }},
2114 { &hf_pn_io_cminitiator_objectuuid,
2115 { "CMInitiatorObjectUUID", "pn_io.cminitiator_uuid", FT_STRING, BASE_DEC, 0x0, 0x0, "", HFILL }},
2116 { &hf_pn_io_ar_properties,
2117 { "ARProperties", "pn_io.ar_properties", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - 32 bitfield! */
2118 { &hf_pn_io_cminitiator_activitytimeoutfactor,
2119 { "CMInitiatorActivityTimeoutFactor", "pn_io.cminitiator_activitytimeoutfactor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, /* XXX - special values */
2120 { &hf_pn_io_cminitiator_udprtport,
2121 { "CMInitiatorUDPRTPort", "pn_io.cminitiator_udprtport", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - special values */
2122 { &hf_pn_io_station_name_length,
2123 { "StationNameLength", "pn_io.station_name_length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2124 { &hf_pn_io_cminitiator_station_name,
2125 { "CMInitiatorStationName", "pn_io.cminitiator_station_name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
2127 { &hf_pn_io_cmresponder_macadd,
2128 { "CMResponderMacAdd", "pn_io.cmresponder_macadd", FT_ETHER, BASE_HEX, 0x0, 0x0, "", HFILL }},
2129 { &hf_pn_io_cmresponder_udprtport,
2130 { "CMResponderUDPRTPort", "pn_io.cmresponder_udprtport", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - special values */
2132 { &hf_pn_io_iocr_type,
2133 { "IOCRType", "pn_io.iocr_type", FT_UINT16, BASE_HEX, VALS(pn_io_iocr_type), 0x0, "", HFILL }},
2134 { &hf_pn_io_iocr_reference,
2135 { "IOCRReference", "pn_io.iocr_reference", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2137 { "LT", "pn_io.lt", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2138 { &hf_pn_io_iocr_properties,
2139 { "IOCRProperties", "pn_io.iocr_properties", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - 32 bitfield! */
2140 { &hf_pn_io_data_length,
2141 { "DataLength", "pn_io.data_length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2142 { &hf_pn_io_frame_id,
2143 { "FrameID", "pn_io.frame_id", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2144 { &hf_pn_io_send_clock_factor,
2145 { "SendClockFactor", "pn_io.send_clock_factor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, /* XXX - special values */
2146 { &hf_pn_io_reduction_ratio,
2147 { "ReductionRatio", "pn_io.reduction_ratio", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, /* XXX - special values */
2149 { "Phase", "pn_io.phase", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2150 { &hf_pn_io_sequence,
2151 { "Sequence", "pn_io.sequence", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2152 { &hf_pn_io_frame_send_offset,
2153 { "FrameSendOffset", "pn_io.frame_send_offset", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2154 { &hf_pn_io_watchdog_factor,
2155 { "WatchdogFactor", "pn_io.watchdog_factor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2156 { &hf_pn_io_data_hold_factor,
2157 { "DataHoldFactor", "pn_io.data_hold_factor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2158 { &hf_pn_io_iocr_tag_header,
2159 { "IOCRTagHeader", "pn_io.iocr_tag_header", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2160 { &hf_pn_io_iocr_multicast_mac_add,
2161 { "IOCRMulticastMACAdd", "pn_io.iocr_multicast_mac_add", FT_ETHER, BASE_HEX, NULL, 0x0, "", HFILL }},
2162 { &hf_pn_io_number_of_apis,
2163 { "NumberOfAPIs", "pn_io.number_of_apis", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2164 { &hf_pn_io_number_of_io_data_objects,
2165 { "NumberOfIODataObjects", "pn_io.number_of_io_data_objects", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2166 { &hf_pn_io_io_data_object_frame_offset,
2167 { "IODataObjectFrameOffset", "pn_io.io_data_object_frame_offset", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2168 { &hf_pn_io_number_of_iocs,
2169 { "NumberOfIOCS", "pn_io.number_of_iocs", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2170 { &hf_pn_io_iocs_frame_offset,
2171 { "IOCSFrameOffset", "pn_io.iocs_frame_offset", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2173 { &hf_pn_io_alarmcr_type,
2174 { "AlarmCRType", "pn_io.alarmcr_type", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2175 { &hf_pn_io_alarmcr_properties,
2176 { "AlarmCRProperties", "pn_io.alarmcr_properties", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - 32 bitfield! */
2177 { &hf_pn_io_rta_timeoutfactor,
2178 { "RTATimeoutFactor", "pn_io.rta_timeoutfactor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, /* XXX - special values */
2179 { &hf_pn_io_rta_retries,
2180 { "RTARetries", "pn_io.rta_retries", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, /* XXX - only values 3 - 15 allowed */
2181 { &hf_pn_io_localalarmref,
2182 { "LocalAlarmReference", "pn_io.localalarmref", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - special values */
2183 { &hf_pn_io_maxalarmdatalength,
2184 { "MaxAlarmDataLength", "pn_io.maxalarmdatalength", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, /* XXX - only values 200 - 1432 allowed */
2185 { &hf_pn_io_alarmcr_tagheaderhigh,
2186 { "AlarmCRTagHeaderHigh", "pn_io.alarmcr_tagheaderhigh", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - 16 bitfield! */
2187 { &hf_pn_io_alarmcr_tagheaderlow,
2188 { "AlarmCRTagHeaderLow", "pn_io.alarmcr_tagheaderlow", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, /* XXX - 16 bitfield!*/
2190 { &hf_pn_io_api_tree,
2191 { "API", "pn_io.api", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2192 { &hf_pn_io_module_tree,
2193 { "Module", "pn_io.module", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2194 { &hf_pn_io_submodule_tree,
2195 { "Submodule", "pn_io.submodule", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2196 { &hf_pn_io_io_data_object,
2197 { "IODataObject", "pn_io.io_data_object", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2199 { "IOCS", "pn_io.io_cs", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2201 { &hf_pn_io_ar_uuid,
2202 { "ARUUID", "pn_io.ar_uuid", FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }},
2204 { "API", "pn_io.api", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2205 { &hf_pn_io_slot_nr,
2206 { "SlotNumber", "pn_io.slot_nr", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2207 { &hf_pn_io_subslot_nr,
2208 { "SubslotNumber", "pn_io.subslot_nr", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2210 { "Index", "pn_io.index", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2211 { &hf_pn_io_seq_number,
2212 { "SeqNumber", "pn_io.seq_number", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2213 { &hf_pn_io_record_data_length,
2214 { "RecordDataLength", "pn_io.record_data_length", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2215 { &hf_pn_io_padding,
2216 { "Padding", "pn_io.padding", FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }},
2217 { &hf_pn_io_add_val1,
2218 { "AdditionalValue1", "pn_io.add_val1", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2219 { &hf_pn_io_add_val2,
2220 { "AdditionalValue2", "pn_io.add_val2", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2221 { &hf_pn_io_block_header,
2222 { "BlockHeader", "pn_io.block_header", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2223 { &hf_pn_io_block_type,
2224 { "BlockType", "pn_io.block_type", FT_UINT16, BASE_HEX, VALS(pn_io_block_type), 0x0, "", HFILL }},
2225 { &hf_pn_io_block_length,
2226 { "BlockLength", "pn_io.block_length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2227 { &hf_pn_io_block_version_high,
2228 { "BlockVersionHigh", "pn_io.block_version_high", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
2229 { &hf_pn_io_block_version_low,
2230 { "BlockVersionLow", "pn_io.block_version_low", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }},
2231 { &hf_pn_io_sessionkey,
2232 { "SessionKey", "pn_io.session_key", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2233 { &hf_pn_io_control_command,
2234 { "ControlCommand", "pn_io.control_command", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2235 { &hf_pn_io_control_command_prmend,
2236 { "PrmEnd", "pn_io.control_command.prmend", FT_UINT16, BASE_DEC, NULL, 0x0001, "", HFILL }},
2237 { &hf_pn_io_control_command_applready,
2238 { "ApplicationReady", "pn_io.control_command.applready", FT_UINT16, BASE_DEC, NULL, 0x0002, "", HFILL }},
2239 { &hf_pn_io_control_command_release,
2240 { "Release", "pn_io.control_command.release", FT_UINT16, BASE_DEC, NULL, 0x0004, "", HFILL }},
2241 { &hf_pn_io_control_command_done,
2242 { "Done", "pn_io.control_command.done", FT_UINT16, BASE_DEC, NULL, 0x0008, "", HFILL }},
2243 { &hf_pn_io_control_block_properties,
2244 { "ControlBlockProperties", "pn_io.control_block_properties", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2246 { &hf_pn_io_error_code,
2247 { "ErrorCode", "pn_io.error_code", FT_UINT8, BASE_HEX, VALS(pn_io_error_code), 0x0, "", HFILL }},
2248 { &hf_pn_io_error_decode,
2249 { "ErrorDecode", "pn_io.error_decode", FT_UINT8, BASE_HEX, VALS(pn_io_error_decode), 0x0, "", HFILL }},
2250 { &hf_pn_io_error_code1,
2251 { "ErrorCode1", "pn_io.error_code1", FT_UINT8, BASE_HEX, VALS(pn_io_error_code1), 0x0, "", HFILL }},
2252 { &hf_pn_io_error_code2,
2253 { "ErrorCode2", "pn_io.error_code2", FT_UINT8, BASE_HEX, VALS(pn_io_error_code2), 0x0, "", HFILL }},
2254 { &hf_pn_io_error_code1_pniorw,
2255 { "ErrorCode1 (PNIORW)", "pn_io.error_code1", FT_UINT8, BASE_HEX, VALS(pn_io_error_code1_pniorw), 0x0, "", HFILL }},
2256 { &hf_pn_io_error_code1_pnio,
2257 { "ErrorCode1 (PNIO)", "pn_io.error_code1", FT_UINT8, BASE_HEX, VALS(pn_io_error_code1_pnio), 0x0, "", HFILL }},
2259 { "Block", "pn_io.block", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2261 { "Undecoded Data", "pn_io.data", FT_STRING, BASE_DEC, NULL, 0x0, "", HFILL }},
2263 { &hf_pn_io_alarm_type,
2264 { "AlarmType", "pn_io.alarm_type", FT_UINT16, BASE_HEX, VALS(pn_io_alarm_type), 0x0, "", HFILL }},
2266 { &hf_pn_io_alarm_specifier,
2267 { "AlarmSpecifier", "pn_io.alarm_specifier", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2268 { &hf_pn_io_alarm_specifier_sequence,
2269 { "SequenceNumber", "pn_io.alarm_specifier.sequence", FT_UINT16, BASE_HEX, NULL, 0x07FF, "", HFILL }},
2270 { &hf_pn_io_alarm_specifier_channel,
2271 { "ChannelDiagnosis", "pn_io.alarm_specifier.channel", FT_UINT16, BASE_HEX, NULL, 0x0800, "", HFILL }},
2272 { &hf_pn_io_alarm_specifier_manufacturer,
2273 { "ManufacturerSpecificDiagnosis", "pn_io.alarm_specifier.manufacturer", FT_UINT16, BASE_HEX, NULL, 0x1000, "", HFILL }},
2274 { &hf_pn_io_alarm_specifier_submodule,
2275 { "SubmoduleDiagnosisState", "pn_io.alarm_specifier.submodule", FT_UINT16, BASE_HEX, NULL, 0x2000, "", HFILL }},
2276 { &hf_pn_io_alarm_specifier_ardiagnosis,
2277 { "ARDiagnosisState", "pn_io.alarm_specifier.ardiagnosis", FT_UINT16, BASE_HEX, NULL, 0x8000, "", HFILL }},
2279 { &hf_pn_io_alarm_dst_endpoint,
2280 { "AlarmDstEndpoint", "pn_io.alarm_dst_endpoint", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2281 { &hf_pn_io_alarm_src_endpoint,
2282 { "AlarmSrcEndpoint", "pn_io.alarm_src_endpoint", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2283 { &hf_pn_io_pdu_type,
2284 { "PDUType", "pn_io.pdu_type", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2285 { &hf_pn_io_pdu_type_type,
2286 { "Type", "pn_io.pdu_type.type", FT_UINT8, BASE_HEX, VALS(pn_io_pdu_type), 0x0F, "", HFILL }},
2287 { &hf_pn_io_pdu_type_version,
2288 { "Version", "pn_io.pdu_type.version", FT_UINT8, BASE_HEX, NULL, 0xF0, "", HFILL }},
2289 { &hf_pn_io_add_flags,
2290 { "AddFlags", "pn_io.add_flags", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2291 { &hf_pn_io_window_size,
2292 { "WindowSize", "pn_io.window_size", FT_UINT8, BASE_DEC, NULL, 0x0F, "", HFILL }},
2294 { "TACK", "pn_io.tack", FT_UINT8, BASE_HEX, NULL, 0xF0, "", HFILL }},
2295 { &hf_pn_io_send_seq_num,
2296 { "SendSeqNum", "pn_io.send_seq_num", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2297 { &hf_pn_io_ack_seq_num,
2298 { "AckSeqNum", "pn_io.ack_seq_num", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2299 { &hf_pn_io_var_part_len,
2300 { "VarPartLen", "pn_io.var_part_len", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2301 { &hf_pn_io_module_ident_number,
2302 { "ModuleIdentNumber", "pn_io.module_ident_number", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2303 { &hf_pn_io_submodule_ident_number,
2304 { "SubmoduleIdentNumber", "pn_io.submodule_ident_number", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2306 { &hf_pn_io_number_of_modules,
2307 { "NumberOfModules", "pn_io.number_of_modules", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2308 { &hf_pn_io_module_properties,
2309 { "ModuleProperties", "pn_io.module_properties", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2310 { &hf_pn_io_module_state,
2311 { "ModuleState", "pn_io.module_state", FT_UINT16, BASE_HEX, VALS(pn_io_module_state), 0x0, "", HFILL }},
2312 { &hf_pn_io_number_of_submodules,
2313 { "NumberOfSubmodules", "pn_io.number_of_submodules", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2314 { &hf_pn_io_submodule_properties,
2315 { "SubmoduleProperties", "pn_io.submodule_properties", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2316 { &hf_pn_io_submodule_state,
2317 { "SubmoduleState", "pn_io.submodule_state", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }},
2319 { &hf_pn_io_data_description_tree,
2320 { "DataDescription", "pn_io.data_description", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
2321 { &hf_pn_io_data_description,
2322 { "DataDescription", "pn_io.data_description", FT_UINT16, BASE_HEX, VALS(pn_io_data_description), 0x0, "", HFILL }},
2323 { &hf_pn_io_submodule_data_length,
2324 { "SubmoduleDataLength", "pn_io.submodule_data_length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2325 { &hf_pn_io_length_iocs,
2326 { "LengthIOCS", "pn_io.length_iocs", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2327 { &hf_pn_io_length_iops,
2328 { "LengthIOPS", "pn_io.length_iops", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2331 { "IOxS", "pn_io.ioxs", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }},
2332 { &hf_pn_io_ioxs_extension,
2333 { "Extension (1:another IOxS follows/0:no IOxS follows)", "pn_io.ioxs.extension", FT_UINT8, BASE_HEX, NULL, 0x01, "", HFILL }},
2334 { &hf_pn_io_ioxs_res14,
2335 { "Reserved (should be zero)", "pn_io.ioxs.res14", FT_UINT8, BASE_HEX, NULL, 0x1E, "", HFILL }},
2336 { &hf_pn_io_ioxs_instance,
2337 { "Instance (only valid, if DataState is bad)", "pn_io.ioxs.instance", FT_UINT8, BASE_HEX, VALS(pn_io_ioxs), 0x60, "", HFILL }},
2338 { &hf_pn_io_ioxs_datastate,
2339 { "DataState (1:good/0:bad)", "pn_io.ioxs.datastate", FT_UINT8, BASE_HEX, NULL, 0x80, "", HFILL }},
2341 { &hf_pn_io_address_resolution_properties,
2342 { "AddressResolutionProperties", "pn_io.address_resolution_properties", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2343 { &hf_pn_io_mci_timeout_factor,
2344 { "MCITimeoutFactor", "pn_io.mci_timeout_factor", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
2345 { &hf_pn_io_provider_station_name,
2346 { "ProviderStationName", "pn_io.provider_station_name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }}
2350 static gint *ett[] = {
2353 &ett_pn_io_block_header,
2357 &ett_pn_io_pdu_type,
2358 &ett_pn_io_add_flags,
2359 &ett_pn_io_control_command,
2362 &ett_pn_io_data_description,
2364 &ett_pn_io_submodule,
2365 &ett_pn_io_io_data_object,
2369 proto_pn_io = proto_register_protocol ("PROFINET IO", "PNIO", "pn_io");
2370 proto_register_field_array (proto_pn_io, hf, array_length (hf));
2371 proto_register_subtree_array (ett, array_length (ett));
2375 proto_reg_handoff_pn_io (void)
2377 /* Register the protocols as dcerpc */
2378 dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_device, ver_pn_io_device, pn_io_dissectors, hf_pn_io_opnum);
2379 dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_controller, ver_pn_io_controller, pn_io_dissectors, hf_pn_io_opnum);
2380 dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_supervisor, ver_pn_io_supervisor, pn_io_dissectors, hf_pn_io_opnum);
2381 dcerpc_init_uuid (proto_pn_io, ett_pn_io, &uuid_pn_io_parameterserver, ver_pn_io_parameterserver, pn_io_dissectors, hf_pn_io_opnum);
2383 heur_dissector_add("pn_rt", dissect_PNIO_heur, proto_pn_io);