regen pidl all: rm epan/dissectors/pidl/*-stamp; pushd epan/dissectors/pidl/ && make...
[wireshark-sm.git] / plugins / epan / profinet / packet-pn-rsi.c
blob5456f456c800e961b3e9dd8b01bbfc56b43b8762
1 /* packet-pn-rsi.c
2 * Routines for PN-RSI
3 * packet dissection.
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1999 Gerald Combs
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 #include "config.h"
26 #include <string.h>
28 #include <glib.h>
30 #include <epan/packet.h>
31 #include <epan/exceptions.h>
32 #include <epan/to_str.h>
33 #include <epan/wmem_scopes.h>
34 #include <epan/dissectors/packet-dcerpc.h>
35 #include <epan/expert.h>
36 #include <epan/conversation_filter.h>
37 #include <epan/proto_data.h>
38 #include <epan/reassemble.h>
39 #include <epan/conversation.h>
41 #include <wsutil/file_util.h>
42 #include <epan/prefs.h>
44 #include "packet-pn.h"
46 void proto_register_pn_rsi(void);
47 void proto_reg_handoff_pn_rsi(void);
49 static int proto_pn_rsi;
51 static int hf_pn_rsi_dst_srv_access_point;
52 static int hf_pn_rsi_src_srv_access_point;
54 static int hf_pn_rsi_pdu_type;
55 static int hf_pn_rsi_pdu_type_type;
56 static int hf_pn_rsi_pdu_type_version;
58 static int hf_pn_rsi_add_flags;
59 static int hf_pn_rsi_add_flags_windowsize;
60 static int hf_pn_rsi_add_flags_reserved1;
61 static int hf_pn_rsi_add_flags_tack;
62 static int hf_pn_rsi_add_flags_morefrag;
63 static int hf_pn_rsi_add_flags_notification;
64 static int hf_pn_rsi_add_flags_reserved2;
66 static int hf_pn_rsi_send_seq_num;
67 static int hf_pn_rsi_ack_seq_num;
68 static int hf_pn_rsi_var_part_len;
70 static int hf_pn_rsi_f_opnum_offset;
71 static int hf_pn_rsi_f_opnum_offset_offset;
72 static int hf_pn_rsi_f_opnum_offset_opnum;
73 static int hf_pn_rsi_f_opnum_offset_callsequence;
75 static int hf_pn_rsi_conn_block;
76 static int hf_pn_rsi_rsp_max_length;
77 static int hf_pn_rsi_vendor_id;
78 static int hf_pn_rsi_device_id;
79 static int hf_pn_rsi_instance_id;
80 static int hf_pn_rsi_interface;
82 static int hf_pn_rsi_svcs_block;
84 static int hf_pn_rsi_number_of_entries;
85 static int hf_pn_rsi_pd_rsi_instance;
86 static int hf_pn_rsi_device_type;
87 static int hf_pn_rsi_order_id;
88 static int hf_pn_rsi_im_serial_number;
89 static int hf_pn_rsi_hw_revision;
90 static int hf_pn_rsi_sw_revision_prefix;
91 static int hf_pn_rsi_sw_revision;
93 static int ett_pn_rsi;
94 static int ett_pn_rsi_pdu_type;
95 static int ett_pn_rsi_f_opnum_offset;
96 static int ett_pn_rsi_conn_block;
97 static int ett_pn_rsi_svcs_block;
98 static int ett_pn_rsi_add_flags;
99 static int ett_pn_rsi_rta;
100 static int ett_pn_io_pd_rsi_instance;
102 static expert_field ei_pn_rsi_error;
104 static const range_string pn_rsi_alarm_endpoint[] = {
105 { 0x0000, 0x7FFF, "RSI Initiator Instance (ISAP) or RSI Responder Instance (RSAP)" },
106 { 0x8000, 0xFFFE, "Reserved" },
107 { 0xFFFF, 0xFFFF, "CON-SAP" },
108 { 0, 0, NULL }
111 static const range_string pn_rsi_pdu_type_type[] = {
112 { 0x00, 0x02, "Reserved" },
113 { 0x03, 0x03, "RTA_TYPE_ACK" },
114 { 0x04, 0x04, "RTA_TYPE_ERR" },
115 { 0x05, 0x05, "RTA_TYPE_FREQ" },
116 { 0x06, 0x06, "RTA_TYPE_FRSP" },
117 { 0x07, 0x0F, "Reserved" },
118 { 0, 0, NULL }
121 static const range_string pn_rsi_pdu_type_version[] = {
122 { 0x00, 0x00, "Reserved" },
123 { 0x01, 0x01, "Version 1 of the protocol" },
124 { 0x02, 0x02, "Version 2 of the protocol" },
125 { 0x03, 0X0F, "Reserved" },
126 { 0, 0, NULL }
129 static const value_string pn_rsi_add_flags_windowsize[] = {
130 { 0x00, "Reserved" },
131 { 0x01, "Unknown WindowSize" },
132 { 0x02, "Smallest WindowSize" },
133 { 0x03, "Optional usable WindowSize" },
134 { 0x04, "Optional usable WindowSize" },
135 { 0x05, "Optional usable WindowSize" },
136 { 0x06, "Optional usable WindowSize" },
137 { 0x07, "Optional usable WindowSize" },
138 { 0, NULL }
141 static const value_string pn_rsi_add_flags_tack[] = {
142 { 0x00, "No immediate acknowledge" },
143 { 0x01, "Immediate acknowledge" },
144 { 0, NULL }
147 static const value_string pn_rsi_add_flags_morefrag[] = {
148 { 0x00, "Last fragment" },
149 { 0x01, "More fragments follows" },
150 { 0, NULL }
153 static const value_string pn_rsi_add_flags_notification[] = {
154 { 0x00, "No action necessary" },
155 { 0x01, "The ApplicationReadyBlock is available for reading with the service ReadNotification" },
156 { 0, NULL }
159 static const range_string pn_rsi_seq_num[] = {
160 { 0x0000, 0x7FFF, "synchronization and transmission between initiator and responder" },
161 { 0x8000, 0xFFFD, "Reserved" },
162 { 0xFFFE, 0xFFFE, "synchronize initiator and responder for establishment of an AR" },
163 { 0xFFFF, 0xFFFF, "Reserved" },
164 { 0, 0, NULL }
167 static const range_string pn_rsi_var_part_len[] = {
168 { 0x0000, 0x0000, "No RTA-SDU or RSI-SDU exists" },
169 { 0x0001, 0x0598, "An RTA-SDU or RSI-PDU with VarPartLen octets exists" },
170 { 0x0599, 0xFFFF, "Reserved" },
171 { 0, 0, NULL }
174 static const range_string pn_rsi_f_opnum_offset_offset[] = {
175 { 0x00000000, 0x00000000, "First fragment" },
176 { 0x00000001, 0x00000003, "Reserved" },
177 { 0x00000004, 0x00FFFFFF, "Not first fragment" },
178 { 0, 0, NULL }
181 static const value_string pn_rsi_f_opnum_offset_opnum[] = {
182 { 0x00, "Connect" },
183 { 0x01, "Reserved" },
184 { 0x02, "Read" },
185 { 0x03, "Write" },
186 { 0x04, "Control" },
187 { 0x05, "ReadImplicit" },
188 { 0x06, "ReadConnectionless" },
189 { 0x07, "ReadNotification" },
190 { 0x08, "PrmWriteMore" },
191 { 0x09, "PrmWriteEnd" },
192 { 0x0A, "Reserved" },
193 { 0x0B, "Reserved" },
194 { 0x0C, "Reserved" },
195 { 0x0D, "Reserved" },
196 { 0x0E, "Reserved" },
197 { 0x0F, "Reserved" },
198 { 0x1F, "Reserved" },
199 { 0, NULL }
202 static const range_string pn_rsi_f_opnum_offset_callsequence[] = {
203 { 0x00, 0x07, "Allowed values" },
204 { 0, 0, NULL }
207 static const range_string pn_rsi_rsp_max_length[] = {
208 { 0x00000000, 0x00000003, "Reserved" },
209 { 0x00000004, 0x00FFFFFF, "Usable" },
210 { 0x01FFFFFF, 0xFFFFFFFF, "Reserved" },
211 { 0, 0, NULL }
214 static const range_string pn_rsi_interface[] = {
215 { 0x00, 0x00, "IO device interface" },
216 { 0x01, 0x01, "Read Implicit IO device interface" },
217 { 0x02, 0x02, "CIM device interface" },
218 { 0x03, 0x03, "Read Implicit CIM device interface" },
219 { 0x04, 0xFF, "Reserved" },
220 { 0, 0, NULL }
223 static int
224 dissect_FOpnumOffset(tvbuff_t *tvb, int offset,
225 packet_info *pinfo _U_, proto_tree *tree, uint8_t *drep _U_, uint32_t *u32FOpnumOffset)
227 proto_item *sub_item;
228 proto_tree *sub_tree;
230 sub_item = proto_tree_add_item(tree, hf_pn_rsi_f_opnum_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
231 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_f_opnum_offset);
232 dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
233 hf_pn_rsi_f_opnum_offset_offset, u32FOpnumOffset);
234 dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
235 hf_pn_rsi_f_opnum_offset_opnum, u32FOpnumOffset);
236 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
237 hf_pn_rsi_f_opnum_offset_callsequence, u32FOpnumOffset);
239 return offset;
242 static int hf_pn_rsi_data_payload;
244 static int hf_pn_rsi_segments;
245 static int hf_pn_rsi_segment;
246 //static int hf_pn_rsi_data;
247 static int hf_pn_rsi_segment_overlap;
248 static int hf_pn_rsi_segment_overlap_conflict;
249 static int hf_pn_rsi_segment_multiple_tails;
250 static int hf_pn_rsi_segment_too_long_segment;
251 static int hf_pn_rsi_segment_error;
252 static int hf_pn_rsi_segment_count;
253 static int hf_pn_rsi_reassembled_in;
254 static int hf_pn_rsi_reassembled_length;
256 static reassembly_table pn_rsi_reassembly_table;
258 void
259 pn_rsi_reassemble_init(void)
261 reassembly_table_register(&pn_rsi_reassembly_table, &addresses_reassembly_table_functions);
264 static int ett_pn_rsi_segments;
265 static int ett_pn_rsi_segment;
266 //static int ett_pn_rsi_data;
267 static int ett_pn_rsi_data_payload;
269 static const fragment_items pn_rsi_frag_items = {
270 &ett_pn_rsi_segment,
271 &ett_pn_rsi_segments,
272 &hf_pn_rsi_segments,
273 &hf_pn_rsi_segment,
274 &hf_pn_rsi_segment_overlap,
275 &hf_pn_rsi_segment_overlap_conflict,
276 &hf_pn_rsi_segment_multiple_tails,
277 &hf_pn_rsi_segment_too_long_segment,
278 &hf_pn_rsi_segment_error,
279 &hf_pn_rsi_segment_count,
280 &hf_pn_rsi_reassembled_in,
281 &hf_pn_rsi_reassembled_length,
282 /* Reassembled data field */
283 NULL,
284 "segments"
287 static int
288 dissect_pn_rta_remaining_user_data_bytes(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
289 proto_tree *tree, uint8_t *drep, uint32_t length, uint8_t u8MoreFrag, uint32_t u32FOpnumOffsetOpnum, int type)
291 fragment_head *fd_frag;
292 fragment_head *fd_reass;
293 conversation_t *conv;
294 tvbuff_t *next_tvb;
295 proto_item *pn_rsi_tree_item;
296 proto_item *payload_item = NULL;
297 proto_item *payload_tree = NULL;
298 bool update_col_info = true;
300 if (pinfo->srcport != 0 && pinfo->destport != 0) {
301 /* COTP over RFC1006/TCP, try reassembling */
302 conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
303 pinfo->srcport, pinfo->destport, 0);
304 if (!conv) {
305 conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
306 pinfo->srcport, pinfo->destport, 0);
309 /* XXX - don't know if this will work with multiple segmented Ack's in a single TCP stream */
310 fd_frag = fragment_get(&pn_rsi_reassembly_table, pinfo, conv->conv_index, NULL);
311 fd_reass = fragment_get_reassembled_id(&pn_rsi_reassembly_table, pinfo, conv->conv_index);
313 else {
314 /* plain COTP transport (without RFC1006/TCP), try reassembling */
315 conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
316 pinfo->clnp_srcref, pinfo->clnp_dstref, 0);
317 if (!conv) {
318 conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, CONVERSATION_NONE,
319 pinfo->clnp_srcref, pinfo->clnp_dstref, 0);
322 /* XXX - don't know if this will work with multiple segmented Ack's in a single TCP stream */
323 fd_frag = fragment_get(&pn_rsi_reassembly_table, pinfo, conv->conv_index, NULL);
324 fd_reass = fragment_get_reassembled_id(&pn_rsi_reassembly_table, pinfo, conv->conv_index);
327 /* is this packet containing a "standalone" segment? */
328 if (!u8MoreFrag && !fd_frag && !fd_reass) {
329 /* "standalone" segment, simply show payload and return */
330 offset = dissect_blocks(tvb, offset, pinfo, tree, drep);
331 return offset;
334 /* multiple segments */
335 if (!pinfo->fd->visited && conv != NULL) {
336 /* we haven't seen it before, add to list of segments */
337 fragment_add_seq_next(&pn_rsi_reassembly_table, tvb, offset, pinfo, conv->conv_index,
338 NULL /*Data comes from tvb as in packet-icmp-template.c */,
339 length,
340 u8MoreFrag);
342 fd_reass = fragment_get_reassembled_id(&pn_rsi_reassembly_table, pinfo, conv->conv_index);
345 /* update display */
346 col_append_fstr(pinfo->cinfo, COL_INFO, " [%sPN IO RSI Segment]",
347 u8MoreFrag ? "" : "Last ");
349 /* reassembling completed? */
350 if (fd_reass != NULL) {
351 /* is this the packet to show the reassembled payload in? */
352 if (pinfo->fd->num == fd_reass->reassembled_in) {
353 next_tvb = process_reassembled_data(tvb, 0, pinfo,
354 "Reassembled PN IO RSI packet", fd_reass, &pn_rsi_frag_items, &update_col_info, tree);
356 /* XXX - create new parent tree item "Reassembled Data Segments" */
357 payload_item = proto_tree_add_item(tree, hf_pn_rsi_data_payload, next_tvb, 0, tvb_captured_length(next_tvb), ENC_NA);
358 payload_tree = proto_item_add_subtree(payload_item, ett_pn_rsi_data_payload);
360 offset = dissect_rsi_blocks(next_tvb, 0, pinfo, payload_tree, drep, u32FOpnumOffsetOpnum, type);
362 /* the toplevel fragment subtree is now behind all desegmented data,
363 * move it right behind the DE2 tree item */
364 // pn_rsi_tree_item = proto_tree_get_parent(tree);
367 else {
368 /* segment of a multiple segment payload */
369 proto_item *pi;
371 pn_rsi_tree_item = proto_tree_get_parent(tree);
372 pi = proto_tree_add_uint(pn_rsi_tree_item, hf_pn_rsi_reassembled_in,
373 tvb, 0, 0, fd_reass->reassembled_in);
374 proto_item_set_generated(pi);
378 return offset;
381 /* dissect a PN-IO RSI SVCS block (on top of PN-RT protocol) */
382 static int
383 dissect_RSI_SVCS_block(tvbuff_t *tvb, int offset,
384 packet_info *pinfo, proto_tree *tree, uint8_t *drep, uint16_t u16VarPartLen, uint8_t u8MoreFrag, uint32_t u32FOpnumOffsetOffset, uint32_t u32FOpnumOffsetOpnum)
386 proto_item* sub_item;
387 proto_tree *sub_tree;
389 uint32_t u32RsiHeaderSize = 4;
390 uint32_t u32RspMaxLength;
392 // PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
393 int32_t length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
395 sub_item = proto_tree_add_item(tree, hf_pn_rsi_svcs_block, tvb, offset, 0, ENC_NA);
396 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_svcs_block);
398 if (u32FOpnumOffsetOffset == 0)
400 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
401 hf_pn_rsi_rsp_max_length, &u32RspMaxLength);
403 else if (u8MoreFrag == 0)
405 proto_item_append_text(sub_item, ", RSI Header of SVCS is at first segment");
408 if (length > 0) {
409 offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
410 tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
412 return offset;
415 /* dissect a PN-IO RSI CONN block (on top of PN-RT protocol) */
416 static int
417 dissect_RSI_CONN_block(tvbuff_t *tvb, int offset,
418 packet_info *pinfo, proto_tree *tree, uint8_t *drep, uint16_t u16VarPartLen, uint8_t u8MoreFrag, uint32_t u32FOpnumOffsetOffset, uint32_t u32FOpnumOffsetOpnum)
420 proto_item *sub_item;
421 proto_tree *sub_tree;
423 uint32_t u32RspMaxLength;
424 uint16_t u16VendorId;
425 uint16_t u16DeviceId;
426 uint16_t u16InstanceId;
427 uint8_t u8RsiInterface;
428 uint32_t u32RsiHeaderSize = 4;
430 // PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
431 int32_t length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
433 sub_item = proto_tree_add_item(tree, hf_pn_rsi_conn_block, tvb, offset, 0, ENC_NA);
434 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_conn_block);
436 if (u32FOpnumOffsetOffset == 0) {
438 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
439 hf_pn_rsi_rsp_max_length, &u32RspMaxLength);
440 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
441 hf_pn_rsi_vendor_id, &u16VendorId);
442 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
443 hf_pn_rsi_device_id, &u16DeviceId);
444 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
445 hf_pn_rsi_instance_id, &u16InstanceId);
446 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
447 hf_pn_rsi_interface, &u8RsiInterface);
449 offset = dissect_pn_padding(tvb, offset, pinfo, sub_tree, 1);
451 else if (u8MoreFrag == 0)
453 proto_item_append_text(sub_item, ", RSI Header of CONN is at first segment");
456 if (length > 0) {
457 offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
458 tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
461 return offset;
464 /* dissect a PN-IO RSI FREQ RTA PDU (on top of PN-RT protocol) */
465 static int
466 dissect_FREQ_RTA_block(tvbuff_t *tvb, int offset,
467 packet_info *pinfo, proto_tree *tree, uint8_t *drep, uint16_t u16VarPartLen, uint8_t u8MoreFrag)
469 uint32_t u32FOpnumOffset;
470 uint32_t u32FOpnumOffsetOpnum;
471 uint32_t u32FOpnumOffsetOffset;
472 offset = dissect_FOpnumOffset(tvb, offset, pinfo, tree, drep, &u32FOpnumOffset);
473 u32FOpnumOffsetOpnum = (u32FOpnumOffset & 0x1F000000) >> 24;
474 u32FOpnumOffsetOffset = u32FOpnumOffset & 0x00FFFFFF;
475 switch (u32FOpnumOffsetOpnum) {
476 case(0x0): /* RSI-CONN-PDU */
477 col_append_str(pinfo->cinfo, COL_INFO, "Connect request");
478 offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
479 break;
480 case(0x1): /* Reserved */
481 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
482 offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
483 break;
484 case(0x2): /* RSI-SVCS-PDU (Only valid with ARUUID<>0) */
485 col_append_str(pinfo->cinfo, COL_INFO, "Read request");
486 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
487 break;
488 case(0x3): /* RSI-SVCS-PDU */
489 col_append_str(pinfo->cinfo, COL_INFO, "Write request");
490 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
491 break;
492 case(0x4): /* RSI-SVCS-PDU */
493 col_append_str(pinfo->cinfo, COL_INFO, "Control request");
494 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
495 break;
496 case(0x5): /* RSI-CONN-PDU (Only valid with ARUUID=0) */
497 col_append_str(pinfo->cinfo, COL_INFO, "ReadImplicit request");
498 offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
499 break;
500 case(0x6): /* RSI-CONN-PDU (Only valid with ARUUID<>0) */
501 col_append_str(pinfo->cinfo, COL_INFO, "ReadConnectionless request");
502 offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
503 break;
504 case(0x7): /* RSI-SVCS-PDU */
505 col_append_str(pinfo->cinfo, COL_INFO, "ReadNotification request");
506 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
507 break;
508 case(0x8): /* RSI-SVCS-PDU */
509 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteMore request");
510 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
511 break;
512 case(0x9) : /* RSI-SVCS-PDU */
513 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteEnd request");
514 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
515 break;
516 default:
517 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
518 offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
519 break;
521 return offset;
524 /* dissect a PN-IO RSI RSP block (on top of PN-RT protocol) */
525 static int
526 dissect_RSI_RSP_block(tvbuff_t *tvb, int offset,
527 packet_info *pinfo, proto_tree *tree, uint8_t *drep, uint16_t u16VarPartLen, uint8_t u8MoreFrag, uint32_t u32FOpnumOffsetOffset, uint32_t u32FOpnumOffsetOpnum)
529 uint32_t u32RsiHeaderSize = 4;
531 // PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
532 int32_t length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
534 if (u32FOpnumOffsetOffset == 0)
536 offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
539 else if (u8MoreFrag == 0)
541 proto_item_append_text(tree, ", RSI Header of RSP is at first fragmented frame");
544 if (length > 0) {
545 offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, tree, drep,
546 tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_RSP);
549 return offset;
552 /* dissect a PN-IO RSI FRSP RTA PDU (on top of PN-RT protocol) */
553 static int
554 dissect_FRSP_RTA_block(tvbuff_t *tvb, int offset,
555 packet_info *pinfo, proto_tree *tree, uint8_t *drep, uint16_t u16VarPartLen, uint8_t u8MoreFrag)
557 uint32_t u32FOpnumOffset;
558 uint32_t u32FOpnumOffsetOpnum;
559 uint32_t u32FOpnumOffsetOffset;
560 offset = dissect_FOpnumOffset(tvb, offset, pinfo, tree, drep, &u32FOpnumOffset);
561 u32FOpnumOffsetOpnum = (u32FOpnumOffset & 0x1F000000) >> 24;
562 u32FOpnumOffsetOffset = u32FOpnumOffset & 0x00FFFFFF;
563 switch (u32FOpnumOffsetOpnum) {
564 case(0x0): /* Connect */
565 col_append_str(pinfo->cinfo, COL_INFO, "Connect response");
566 break;
567 case(0x1): /* Reserved */
568 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
569 break;
570 case(0x2): /* Read */
571 col_append_str(pinfo->cinfo, COL_INFO, "Read response");
572 break;
573 case(0x3): /* Write */
574 col_append_str(pinfo->cinfo, COL_INFO, "Write response");
575 break;
576 case(0x4): /* Control */
577 col_append_str(pinfo->cinfo, COL_INFO, "Control response");
578 break;
579 case(0x5): /* ReadImplicit */
580 col_append_str(pinfo->cinfo, COL_INFO, "ReadImplicit response");
581 break;
582 case(0x6): /* ReadConnectionless */
583 col_append_str(pinfo->cinfo, COL_INFO, "ReadConnectionless response");
584 break;
585 case(0x7): /* ReadNotification */
586 col_append_str(pinfo->cinfo, COL_INFO, "ReadNotification response");
587 break;
588 case(0x8): /* PrmWriteMore */
589 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteMore response");
590 break;
591 case(0x9) : /* PrmWriteEnd */
592 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteEnd response");
593 break;
594 default:
595 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
596 break;
598 offset = dissect_RSI_RSP_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
599 return offset;
602 static int
603 dissect_RSIAdditionalFlags(tvbuff_t *tvb, int offset,
604 packet_info *pinfo _U_, proto_tree *tree, uint8_t *drep _U_, uint8_t *u8AddFlags)
606 uint8_t u8WindowSize;
607 uint8_t u8Tack;
608 proto_item *sub_item;
609 proto_tree *sub_tree;
611 /* additional flags */
612 sub_item = proto_tree_add_item(tree, hf_pn_rsi_add_flags, tvb, offset, 1, ENC_NA);
613 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_add_flags);
614 /* Bit 0 - 2 : AddFlags.WindowSize */
615 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
616 hf_pn_rsi_add_flags_windowsize, u8AddFlags);
617 /* Bit 3: AddFlags.Reserved */
618 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
619 hf_pn_rsi_add_flags_reserved1, u8AddFlags);
620 /* Bit 4: AddFlags.TACK */
621 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
622 hf_pn_rsi_add_flags_tack, u8AddFlags);
623 /* Bit 5: AddFlags.MoreFrag */
624 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
625 hf_pn_rsi_add_flags_morefrag, u8AddFlags);
626 /* Bit 6: AddFlags.Notification */
627 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
628 hf_pn_rsi_add_flags_notification, u8AddFlags);
629 /* Bit 7: AddFlags.Reserved */
630 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
631 hf_pn_rsi_add_flags_reserved2, u8AddFlags);
632 u8WindowSize = *u8AddFlags & 0x03;
633 u8Tack = (*u8AddFlags & 0x10);
634 u8Tack = (u8Tack == 0x10) ? 1 : 0;
636 proto_item_append_text(sub_item, ", Window Size: %u, Tack: %u ",
637 u8WindowSize, u8Tack);
638 return offset;
641 /* dissect a PN-IO RTA RSI PDU (on top of PN-RT protocol) */
643 dissect_PNIO_RSI(tvbuff_t *tvb, int offset,
644 packet_info *pinfo, proto_tree *tree, uint8_t *drep)
646 uint16_t u16DestinationServiceAccessPoint;
647 uint16_t u16SourceServiceAccessPoint;
648 uint8_t u8PDUType;
649 uint8_t u8PDUVersion;
650 uint8_t u8AddFlags;
651 uint8_t u8MoreFrag;
652 uint16_t u16SendSeqNum;
653 uint16_t u16AckSeqNum;
654 uint16_t u16VarPartLen;
655 int start_offset = offset;
657 proto_item *rta_item;
658 proto_tree *rta_tree;
660 proto_item *sub_item;
661 proto_tree *sub_tree;
663 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-RSI");
664 rta_item = proto_tree_add_protocol_format(tree, proto_pn_rsi, tvb, offset, tvb_captured_length(tvb),
665 "PROFINET IO RSI");
667 rta_tree = proto_item_add_subtree(rta_item, ett_pn_rsi_rta);
669 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
670 hf_pn_rsi_dst_srv_access_point, &u16DestinationServiceAccessPoint);
671 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
672 hf_pn_rsi_src_srv_access_point, &u16SourceServiceAccessPoint);
674 //col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: 0x%x, Dst: 0x%x",
675 // u16SourceServiceAccessPoint, u16DestinationServiceAccessPoint);
677 /* PDU type */
678 sub_item = proto_tree_add_item(rta_tree, hf_pn_rsi_pdu_type, tvb, offset, 1, ENC_NA);
679 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_pdu_type);
681 /* PDU type type - version of RTA 2*/
682 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
683 hf_pn_rsi_pdu_type_type, &u8PDUType);
684 u8PDUType &= 0x0F;
686 /* PDU type version - version of RTA 2*/
687 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
688 hf_pn_rsi_pdu_type_version, &u8PDUVersion);
689 u8PDUVersion >>= 4;
690 //proto_item_append_text(sub_item, ", Type: %s, Version: %u",
691 // val_to_str(u8PDUType, pn_rsi_pdu_type_type, "Unknown"),
692 // u8PDUVersion);
693 offset = dissect_RSIAdditionalFlags(tvb, offset, pinfo, rta_tree, drep, &u8AddFlags);
694 u8MoreFrag = (u8AddFlags >> 5) & 0x1;
695 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
696 hf_pn_rsi_send_seq_num, &u16SendSeqNum);
697 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
698 hf_pn_rsi_ack_seq_num, &u16AckSeqNum);
699 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
700 hf_pn_rsi_var_part_len, &u16VarPartLen);
702 switch (u8PDUType & 0x0F) {
703 case(3): /* ACK-RTA */
704 col_append_str(pinfo->cinfo, COL_INFO, "ACK-RTA");
706 if (u8AddFlags & 0x40) {
708 col_append_str(pinfo->cinfo, COL_INFO, ", Application Ready Notification");
710 /* no additional data */
711 break;
712 case(4): /* ERR-RTA */
713 col_append_str(pinfo->cinfo, COL_INFO, "ERR-RTA");
714 offset = dissect_PNIO_status(tvb, offset, pinfo, rta_tree, drep);
715 break;
716 case(5): /* FREQ-RTA */
717 offset = dissect_FREQ_RTA_block(tvb, offset, pinfo, rta_tree, drep, u16VarPartLen, u8MoreFrag);
718 break;
719 case(6): /* FRSP-RTA */
720 offset = dissect_FRSP_RTA_block(tvb, offset, pinfo, rta_tree, drep, u16VarPartLen, u8MoreFrag);
721 break;
722 default:
723 offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
724 break;
727 proto_item_set_len(rta_item, offset - start_offset);
729 return offset;
733 dissect_PDRsiInstances_block(tvbuff_t *tvb, int offset,
734 packet_info *pinfo, proto_tree *tree, proto_item *item _U_, uint8_t *drep, uint8_t u8BlockVersionHigh, uint8_t u8BlockVersionLow)
736 proto_item *sub_item;
737 proto_tree *sub_tree;
738 uint16_t u16NumberOfEntries;
739 uint16_t u16VendorId;
740 uint16_t u16DeviceId;
741 uint16_t u16InstanceId;
742 uint8_t u8RsiInterface;
743 const int deviceType_size = 25;
744 const int orderID_size = 20;
745 const int IMserialnumber_size = 16;
746 const int HWrevision_size = 5;
747 const int SWrevisionprefix_size = 1;
748 const int SWrevision_size = 9;
750 if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
751 expert_add_info_format(pinfo, item, &ei_pn_rsi_error,
752 "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
753 return offset;
756 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
757 hf_pn_rsi_number_of_entries, &u16NumberOfEntries);
759 proto_item_append_text(item, ": NumberOfEntries:%u", u16NumberOfEntries);
761 while (u16NumberOfEntries > 0) {
762 u16NumberOfEntries--;
764 sub_item = proto_tree_add_item(tree, hf_pn_rsi_pd_rsi_instance, tvb, offset, 0, ENC_NA);
765 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pd_rsi_instance);
766 /* VendorID */
767 /* DeviceID */
768 /* InstanceID */
769 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
770 hf_pn_rsi_vendor_id, &u16VendorId);
771 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
772 hf_pn_rsi_device_id, &u16DeviceId);
773 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
774 hf_pn_rsi_instance_id, &u16InstanceId);
776 /* RSI Interface */
777 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
778 hf_pn_rsi_interface, &u8RsiInterface);
780 proto_item_append_text(sub_item, ": VendorID:%u, DeviceID:%u, InstanceID:%u, RsiInterface:%u",
781 u16VendorId, u16DeviceId, u16InstanceId, u8RsiInterface);
783 /* Padding */
784 offset = dissect_pn_padding(tvb, offset, pinfo, sub_tree, 1);
787 /* SystemIdentification */
788 /* DeviceType */
789 proto_tree_add_item(tree, hf_pn_rsi_device_type, tvb, offset, deviceType_size, ENC_UTF_8);
790 offset += deviceType_size + 1;
792 /* Blank */
794 /* OrderID */
795 proto_tree_add_item(tree, hf_pn_rsi_order_id, tvb, offset, orderID_size, ENC_UTF_8);
796 offset += orderID_size + 1;
798 /* Blank */
800 /* IM_Serial_Number */
801 proto_tree_add_item(tree, hf_pn_rsi_im_serial_number, tvb, offset, IMserialnumber_size, ENC_UTF_8);
802 offset += IMserialnumber_size + 1;
804 /* Blank */
806 /* HWRevision */
807 proto_tree_add_item(tree, hf_pn_rsi_hw_revision, tvb, offset, HWrevision_size, ENC_UTF_8);
808 offset += HWrevision_size + 1;
810 /* Blank */
812 /* SWRevisionPrefix */
813 proto_tree_add_item(tree, hf_pn_rsi_sw_revision_prefix, tvb, offset, SWrevisionprefix_size, ENC_UTF_8);
814 offset += SWrevisionprefix_size;
816 /* SWRevision */
817 proto_tree_add_item(tree, hf_pn_rsi_sw_revision, tvb, offset, SWrevision_size, ENC_UTF_8);
818 offset += SWrevision_size;
819 return offset;
822 void
823 init_pn_rsi(int proto)
825 static hf_register_info hf[] = {
826 { &hf_pn_rsi_dst_srv_access_point,
827 { "DestinationServiceAccessPoint", "pn_rsi.dst_srv_access_point",
828 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_alarm_endpoint), 0x0,
829 NULL, HFILL }
831 { &hf_pn_rsi_src_srv_access_point,
832 { "SourceServiceAccessPoint", "pn_rsi.src_srv_access_point",
833 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_alarm_endpoint), 0x0,
834 NULL, HFILL }
836 { &hf_pn_rsi_pdu_type,
837 { "PDUType", "pn_rsi.pdu_type",
838 FT_NONE, BASE_NONE, NULL, 0x0,
839 NULL, HFILL }
841 { &hf_pn_rsi_pdu_type_type,
842 { "Type", "pn_rsi.pdu_type.type",
843 FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_pdu_type_type), 0x0F,
844 NULL, HFILL }
846 { &hf_pn_rsi_pdu_type_version,
847 { "Version", "pn_rsi.pdu_type.version",
848 FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_pdu_type_version), 0xF0,
849 NULL, HFILL }
851 { &hf_pn_rsi_add_flags,
852 { "AddFlags", "pn_rsi.add_flags",
853 FT_NONE, BASE_NONE, NULL, 0x0,
854 NULL, HFILL }
856 { &hf_pn_rsi_add_flags_windowsize,
857 { "WindowSize", "pn_rsi.add_flags_windowsize",
858 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_windowsize), 0x07,
859 NULL, HFILL }
861 { &hf_pn_rsi_add_flags_reserved1,
862 { "Reserved", "pn_rsi.add_flags_reserved",
863 FT_UINT8, BASE_HEX, NULL, 0x08,
864 NULL, HFILL }
866 { &hf_pn_rsi_add_flags_tack,
867 { "TACK", "pn_rsi.add_flags_tack",
868 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_tack), 0x10,
869 NULL, HFILL }
871 { &hf_pn_rsi_add_flags_morefrag,
872 { "MoreFrag", "pn_rsi.add_flags_morefrag",
873 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_morefrag), 0x20,
874 NULL, HFILL }
876 { &hf_pn_rsi_add_flags_notification,
877 { "Notification", "pn_rsi.add_flags_notification",
878 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_notification), 0x40,
879 NULL, HFILL }
881 { &hf_pn_rsi_add_flags_reserved2,
882 { "Reserved", "pn_rsi.add_flags_reserved",
883 FT_UINT8, BASE_HEX, NULL, 0x80,
884 NULL, HFILL }
886 { &hf_pn_rsi_send_seq_num,
887 { "SendSeqNum", "pn_rsi.send_seq_num",
888 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_seq_num), 0x0,
889 NULL, HFILL }
891 { &hf_pn_rsi_ack_seq_num,
892 { "AckSeqNum", "pn_rsi.ack_seq_num",
893 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_seq_num), 0x0,
894 NULL, HFILL }
896 { &hf_pn_rsi_var_part_len,
897 { "VarPartLen", "pn_rsi.var_part_len",
898 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_var_part_len), 0x0,
899 NULL, HFILL }
901 { &hf_pn_rsi_f_opnum_offset,
902 { "FOpnumOffset", "pn_rsi.f_opnum_offset",
903 FT_UINT32, BASE_HEX, NULL, 0x0,
904 NULL, HFILL }
906 { &hf_pn_rsi_f_opnum_offset_offset,
907 { "FOpnumOffset.Offset", "pn_rsi.f_opnum_offset.offset",
908 FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_f_opnum_offset_offset), 0x00FFFFFF,
909 NULL, HFILL }
911 { &hf_pn_rsi_f_opnum_offset_opnum,
912 { "FOpnumOffset.Opnum", "pn_rsi.f_opnum_offset.opnum",
913 FT_UINT32, BASE_HEX, VALS(pn_rsi_f_opnum_offset_opnum), 0x1F000000,
914 NULL, HFILL }
916 { &hf_pn_rsi_f_opnum_offset_callsequence,
917 { "FOpnumOffset.CallSequence", "pn_rsi.f_opnum_offset.callsequence",
918 FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_f_opnum_offset_callsequence), 0xE0000000,
919 NULL, HFILL }
921 { &hf_pn_rsi_conn_block,
922 { "RSI CONN Block", "pn_rsi.conn_block",
923 FT_NONE, BASE_NONE, NULL, 0x0,
924 NULL, HFILL }
926 { &hf_pn_rsi_rsp_max_length,
927 { "RspMaxLength", "pn_rsi.rsp_max_length",
928 FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_rsp_max_length), 0x0,
929 NULL, HFILL }
931 { &hf_pn_rsi_vendor_id,
932 { "VendorID", "pn_rsi.vendor_id",
933 FT_UINT16, BASE_HEX, NULL, 0x0,
934 NULL, HFILL }
936 { &hf_pn_rsi_device_id,
937 { "DeviceID", "pn_rsi.device_id",
938 FT_UINT16, BASE_HEX, NULL, 0x0,
939 NULL, HFILL }
941 { &hf_pn_rsi_instance_id,
942 { "InstanceID", "pn_rsi.instance_id",
943 FT_UINT16, BASE_HEX, NULL, 0x0,
944 NULL, HFILL }
946 { &hf_pn_rsi_interface,
947 { "RsiInterface", "pn_rsi.interface",
948 FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_interface), 0x0,
949 NULL, HFILL }
951 { &hf_pn_rsi_svcs_block,
952 { "RSI SVCS Block", "pn_rsi.svcs_block",
953 FT_NONE, BASE_NONE, NULL, 0x0,
954 NULL, HFILL }
956 { &hf_pn_rsi_number_of_entries,
957 { "NumberOfEntries", "pn_rsi.number_of_entries",
958 FT_UINT16, BASE_HEX, NULL, 0x0,
959 NULL, HFILL }
961 { &hf_pn_rsi_pd_rsi_instance,
962 { "PDRsiInstance", "pn_rsi.pd_rsi_instance",
963 FT_NONE, BASE_NONE, NULL, 0x0,
964 NULL, HFILL }
966 { &hf_pn_rsi_device_type,
967 { "DeviceType", "pn_rsi.device_type",
968 FT_STRING, BASE_NONE, NULL, 0x0,
969 NULL, HFILL }
971 { &hf_pn_rsi_order_id,
972 { "OrderID", "pn_rsi.order_id",
973 FT_STRING, BASE_NONE, NULL, 0x0,
974 NULL, HFILL }
976 { &hf_pn_rsi_im_serial_number,
977 { "IM_Serial_Number", "pn_rsi.im_serial_number",
978 FT_STRING, BASE_NONE, NULL, 0x0,
979 NULL, HFILL }
981 { &hf_pn_rsi_hw_revision,
982 { "HWRevision", "pn_rsi.hw_revision",
983 FT_STRING, BASE_NONE, NULL, 0x0,
984 NULL, HFILL }
986 { &hf_pn_rsi_sw_revision_prefix,
987 { "SWRevisionPrefix", "pn_rsi.sw_revision_prefix",
988 FT_STRING, BASE_NONE, NULL, 0x0,
989 NULL, HFILL }
991 { &hf_pn_rsi_sw_revision,
992 { "SWRevision", "pn_rsi.sw_revision",
993 FT_STRING, BASE_NONE, NULL, 0x0,
994 NULL, HFILL }
996 /*&hf_pn_rsi_segment_too_long_segment,
997 &hf_pn_rsi_segment_error,
998 &hf_pn_rsi_segment_count,
999 &hf_pn_rsi_reassembled_in,
1000 &hf_pn_rsi_reassembled_length,*/
1001 { &hf_pn_rsi_segment,
1002 { "RSI Segment", "pn_rsi.segment",
1003 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1004 NULL, HFILL }
1006 { &hf_pn_rsi_segments,
1007 { "PN RSI Segments", "pn_rsi.segments",
1008 FT_NONE, BASE_NONE, NULL, 0x0,
1009 NULL, HFILL }
1011 { &hf_pn_rsi_segment_overlap,
1012 { "Segment overlap", "pn_rsi.segment.overlap",
1013 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1014 "Segment overlaps with other segments", HFILL }
1016 { &hf_pn_rsi_segment_overlap_conflict,
1017 { "Conflicting data in segment overlap", "pn_rsi.segment.overlap.conflict",
1018 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1019 "Overlapping segments contained conflicting data", HFILL }
1021 { &hf_pn_rsi_segment_multiple_tails,
1022 { "Multiple tail segments found", "pn_rsi.segment.multipletails",
1023 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1024 "Several tails were found when reassembling the packet", HFILL }
1026 { &hf_pn_rsi_segment_too_long_segment,
1027 { "Segment too long", "pn_rsi.segment.toolongsegment",
1028 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1029 "Segment contained data past end of packet", HFILL }
1031 { &hf_pn_rsi_segment_error,
1032 { "Reassembly error", "pn_rsi.segment.error",
1033 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1034 "Reassembly error due to illegal segments", HFILL }
1036 { &hf_pn_rsi_segment_count,
1037 { "Segment count", "pn_rsi.segment.count",
1038 FT_UINT32, BASE_DEC, NULL, 0x0,
1039 NULL, HFILL }
1041 { &hf_pn_rsi_reassembled_in,
1042 { "Reassembled pn_rsi in frame", "pn_rsi.reassembled_in",
1043 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1044 "This pn_rsi packet is reassembled in this frame", HFILL }
1046 { &hf_pn_rsi_reassembled_length,
1047 { "Reassembled pn_rsi length", "pn_rsi.reassembled.length",
1048 FT_UINT32, BASE_DEC, NULL, 0x0,
1049 "The total length of the reassembled payload", HFILL }
1051 { &hf_pn_rsi_data_payload,
1052 { "PN IO RSI Data Payload", "pn_rsi.data_payload",
1053 FT_NONE, BASE_NONE, NULL, 0x0,
1054 "", HFILL }
1058 static int *ett[] = {
1059 &ett_pn_rsi,
1060 &ett_pn_rsi_pdu_type,
1061 &ett_pn_rsi_f_opnum_offset,
1062 &ett_pn_rsi_conn_block,
1063 &ett_pn_rsi_svcs_block,
1064 &ett_pn_rsi_add_flags,
1065 &ett_pn_rsi_rta,
1066 &ett_pn_io_pd_rsi_instance,
1067 &ett_pn_rsi_segments,
1068 &ett_pn_rsi_segment,
1069 &ett_pn_rsi_data_payload
1072 static ei_register_info ei[] = {
1073 { &ei_pn_rsi_error, { "pn_rsi.error", PI_UNDECODED, PI_NOTE, "Block version not implemented yet!", EXPFILL } }
1077 expert_module_t* expert_pn_rsi;
1079 proto_pn_rsi = proto;
1081 proto_register_field_array(proto, hf, array_length(hf));
1082 proto_register_subtree_array(ett, array_length(ett));
1083 expert_pn_rsi = expert_register_protocol(proto_pn_rsi);
1084 expert_register_field_array(expert_pn_rsi, ei, array_length(ei));
1086 register_init_routine(pn_rsi_reassemble_init);