1 /* packet-pn-rsi.c
2 * Routines for PN-RSI
3 * packet dissection.
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1999 Gerald Combs
8 *
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.
13 *
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.
18 *
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.
22 */
23
24 #include "config.h"
25
26 #include <string.h>
27
28 #include <glib.h>
29
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>
40
41 #include <wsutil/file_util.h>
42 #include <epan/prefs.h>
43
44 #include "packet-pn.h"
45
46 void proto_register_pn_rsi(void);
47 void proto_reg_handoff_pn_rsi(void);
48
49 static int proto_pn_rsi = -1;
50
51 static int hf_pn_rsi_dst_srv_access_point = -1;
52 static int hf_pn_rsi_src_srv_access_point = -1;
53
54 static int hf_pn_rsi_pdu_type = -1;
55 static int hf_pn_rsi_pdu_type_type = -1;
56 static int hf_pn_rsi_pdu_type_version = -1;
57
58 static int hf_pn_rsi_add_flags = -1;
59 static int hf_pn_rsi_add_flags_windowsize = -1;
60 static int hf_pn_rsi_add_flags_reserved1 = -1;
61 static int hf_pn_rsi_add_flags_tack = -1;
62 static int hf_pn_rsi_add_flags_morefrag = -1;
63 static int hf_pn_rsi_add_flags_notification = -1;
64 static int hf_pn_rsi_add_flags_reserved2 = -1;
65
66 static int hf_pn_rsi_send_seq_num = -1;
67 static int hf_pn_rsi_ack_seq_num = -1;
68 static int hf_pn_rsi_var_part_len = -1;
69
70 static int hf_pn_rsi_f_opnum_offset = -1;
71 static int hf_pn_rsi_f_opnum_offset_offset = -1;
72 static int hf_pn_rsi_f_opnum_offset_opnum = -1;
73 static int hf_pn_rsi_f_opnum_offset_callsequence = -1;
74
75 static int hf_pn_rsi_conn_block = -1;
76 static int hf_pn_rsi_rsp_max_length = -1;
77 static int hf_pn_rsi_vendor_id = -1;
78 static int hf_pn_rsi_device_id = -1;
79 static int hf_pn_rsi_instance_id = -1;
80 static int hf_pn_rsi_interface = -1;
81
82 static int hf_pn_rsi_svcs_block = -1;
83
84 static int hf_pn_rsi_number_of_entries = -1;
85 static int hf_pn_rsi_pd_rsi_instance = -1;
86 static int hf_pn_rsi_device_type = -1;
87 static int hf_pn_rsi_order_id = -1;
88 static int hf_pn_rsi_im_serial_number = -1;
89 static int hf_pn_rsi_hw_revision = -1;
90 static int hf_pn_rsi_sw_revision_prefix = -1;
91 static int hf_pn_rsi_sw_revision = -1;
92
93 static gint ett_pn_rsi = -1;
94 static gint ett_pn_rsi_pdu_type = -1;
95 static gint ett_pn_rsi_f_opnum_offset = -1;
96 static gint ett_pn_rsi_conn_block = -1;
97 static gint ett_pn_rsi_svcs_block = -1;
98 static gint ett_pn_rsi_add_flags = -1;
99 static gint ett_pn_rsi_rta = -1;
100 static gint ett_pn_io_pd_rsi_instance = -1;
101
102 static expert_field ei_pn_rsi_error = EI_INIT;
103
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 }
109 };
110
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 }
119 };
120
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 }
127 };
128
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 }
139 };
140
141 static const value_string pn_rsi_add_flags_tack[] = {
142 { 0x00, "No immediate acknowledge" },
143 { 0x01, "Immediate acknowledge" },
144 { 0, NULL }
145 };
146
147 static const value_string pn_rsi_add_flags_morefrag[] = {
148 { 0x00, "Last fragment" },
149 { 0x01, "More fragments follows" },
150 { 0, NULL }
151 };
152
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 }
157 };
158
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 }
165 };
166
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 }
172 };
173
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 }
179 };
180
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 }
200 };
201
202 static const range_string pn_rsi_f_opnum_offset_callsequence[] = {
203 { 0x00, 0x07, "Allowed values" },
204 { 0, 0, NULL }
205 };
206
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 }
212 };
213
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 }
221 };
222
223 static int
dissect_FOpnumOffset(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,guint8 * drep _U_,guint32 * u32FOpnumOffset)224 dissect_FOpnumOffset(tvbuff_t *tvb, int offset,
225 packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, guint32 *u32FOpnumOffset)
226 {
227 proto_item *sub_item;
228 proto_tree *sub_tree;
229
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);
238
239 return offset;
240 }
241
242 static int hf_pn_rsi_data_payload = -1;
243
244 static int hf_pn_rsi_segments = -1;
245 static int hf_pn_rsi_segment = -1;
246 //static int hf_pn_rsi_data = -1;
247 static int hf_pn_rsi_segment_overlap = -1;
248 static int hf_pn_rsi_segment_overlap_conflict = -1;
249 static int hf_pn_rsi_segment_multiple_tails = -1;
250 static int hf_pn_rsi_segment_too_long_segment = -1;
251 static int hf_pn_rsi_segment_error = -1;
252 static int hf_pn_rsi_segment_count = -1;
253 static int hf_pn_rsi_reassembled_in = -1;
254 static int hf_pn_rsi_reassembled_length = -1;
255
256 static reassembly_table pn_rsi_reassembly_table;
257
258 void
pn_rsi_reassemble_init(void)259 pn_rsi_reassemble_init(void)
260 {
261 reassembly_table_register(&pn_rsi_reassembly_table, &addresses_reassembly_table_functions);
262 }
263
264 static gint ett_pn_rsi_segments = -1;
265 static gint ett_pn_rsi_segment = -1;
266 //static gint ett_pn_rsi_data = -1;
267 static gint ett_pn_rsi_data_payload = -1;
268
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"
285 };
286
287 static int
dissect_pn_rta_remaining_user_data_bytes(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,guint8 * drep,guint32 length,guint8 u8MoreFrag,guint32 u32FOpnumOffsetOpnum,int type)288 dissect_pn_rta_remaining_user_data_bytes(tvbuff_t *tvb, int offset, packet_info *pinfo _U_,
289 proto_tree *tree, guint8 *drep, guint32 length, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOpnum, int type)
290 {
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 gboolean update_col_info = TRUE;
299
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, ENDPOINT_NONE,
303 pinfo->srcport, pinfo->destport, 0);
304 if (!conv) {
305 conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, ENDPOINT_NONE,
306 pinfo->srcport, pinfo->destport, 0);
307 }
308
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);
312 }
313 else {
314 /* plain COTP transport (without RFC1006/TCP), try reassembling */
315 conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, ENDPOINT_NONE,
316 pinfo->clnp_srcref, pinfo->clnp_dstref, 0);
317 if (!conv) {
318 conv = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, ENDPOINT_NONE,
319 pinfo->clnp_srcref, pinfo->clnp_dstref, 0);
320 }
321
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);
325 }
326
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;
332 }
333
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);
341
342 fd_reass = fragment_get_reassembled_id(&pn_rsi_reassembly_table, pinfo, conv->conv_index);
343 }
344
345 /* update display */
346 col_append_fstr(pinfo->cinfo, COL_INFO, " [%sPN IO RSI Segment]",
347 u8MoreFrag ? "" : "Last ");
348
349 /* reassembling completed? */
350 if (fd_reass != NULL) {
351 /* is this the packet to show the reassembed 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);
355
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);
359
360 offset = dissect_rsi_blocks(next_tvb, 0, pinfo, payload_tree, drep, u32FOpnumOffsetOpnum, type);
361
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);
365
366 }
367 else {
368 /* segment of a multiple segment payload */
369 proto_item *pi;
370
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);
375 }
376 }
377
378 return offset;
379 }
380
381 /* dissect a PN-IO RSI SVCS block (on top of PN-RT protocol) */
382 static int
dissect_RSI_SVCS_block(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 * drep,guint8 u8MoreFrag,guint32 u32FOpnumOffsetOffset,guint32 u32FOpnumOffsetOpnum)383 dissect_RSI_SVCS_block(tvbuff_t *tvb, int offset,
384 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
385 {
386 proto_item *sub_item;
387 proto_tree *sub_tree;
388
389 guint32 u32RspMaxLength;
390
391 sub_item = proto_tree_add_item(tree, hf_pn_rsi_svcs_block, tvb, offset, 0, ENC_NA);
392 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_svcs_block);
393 if (u32FOpnumOffsetOffset == 0)
394 {
395 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
396 hf_pn_rsi_rsp_max_length, &u32RspMaxLength);
397 }
398 else if (u8MoreFrag == 0)
399 {
400 proto_item_append_text(sub_item, ", RSI Header of SVCS is at first segment");
401 }
402
403 offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
404 tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
405 return offset;
406 }
407
408 /* dissect a PN-IO RSI CONN block (on top of PN-RT protocol) */
409 static int
dissect_RSI_CONN_block(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 * drep,guint8 u8MoreFrag,guint32 u32FOpnumOffsetOffset,guint32 u32FOpnumOffsetOpnum)410 dissect_RSI_CONN_block(tvbuff_t *tvb, int offset,
411 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
412 {
413 proto_item *sub_item;
414 proto_tree *sub_tree;
415
416 guint32 u32RspMaxLength;
417 guint16 u16VendorId;
418 guint16 u16DeviceId;
419 guint16 u16InstanceId;
420 guint8 u8RsiInterface;
421
422 sub_item = proto_tree_add_item(tree, hf_pn_rsi_conn_block, tvb, offset, 0, ENC_NA);
423 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_conn_block);
424
425 if (u32FOpnumOffsetOffset == 0) {
426
427 offset = dissect_dcerpc_uint32(tvb, offset, pinfo, sub_tree, drep,
428 hf_pn_rsi_rsp_max_length, &u32RspMaxLength);
429 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
430 hf_pn_rsi_vendor_id, &u16VendorId);
431 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
432 hf_pn_rsi_device_id, &u16DeviceId);
433 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
434 hf_pn_rsi_instance_id, &u16InstanceId);
435 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
436 hf_pn_rsi_interface, &u8RsiInterface);
437
438 offset = dissect_pn_padding(tvb, offset, pinfo, sub_tree, 1);
439 }
440 else if (u8MoreFrag == 0)
441 {
442 proto_item_append_text(sub_item, ", RSI Header of CONN is at first segment");
443 }
444
445 offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, sub_tree, drep,
446 tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_REQ);
447
448 return offset;
449 }
450
451 /* dissect a PN-IO RSI FREQ RTA PDU (on top of PN-RT protocol) */
452 static int
dissect_FREQ_RTA_block(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 * drep,guint8 u8MoreFrag)453 dissect_FREQ_RTA_block(tvbuff_t *tvb, int offset,
454 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint8 u8MoreFrag)
455 {
456 guint32 u32FOpnumOffset;
457 guint32 u32FOpnumOffsetOpnum;
458 guint32 u32FOpnumOffsetOffset;
459 offset = dissect_FOpnumOffset(tvb, offset, pinfo, tree, drep, &u32FOpnumOffset);
460 u32FOpnumOffsetOpnum = (u32FOpnumOffset & 0x1F000000) >> 24;
461 u32FOpnumOffsetOffset = u32FOpnumOffset & 0x00FFFFFF;
462 switch (u32FOpnumOffsetOpnum) {
463 case(0x0): /* RSI-CONN-PDU */
464 col_append_str(pinfo->cinfo, COL_INFO, "Connect request");
465 offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
466 break;
467 case(0x1): /* Reserved */
468 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
469 offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
470 break;
471 case(0x2): /* RSI-SVCS-PDU (Only valid with ARUUID<>0) */
472 col_append_str(pinfo->cinfo, COL_INFO, "Read request");
473 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
474 break;
475 case(0x3): /* RSI-SVCS-PDU */
476 col_append_str(pinfo->cinfo, COL_INFO, "Write request");
477 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
478 break;
479 case(0x4): /* RSI-SVCS-PDU */
480 col_append_str(pinfo->cinfo, COL_INFO, "Control request");
481 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
482 break;
483 case(0x5): /* RSI-CONN-PDU (Only valid with ARUUID=0) */
484 col_append_str(pinfo->cinfo, COL_INFO, "ReadImplicit request");
485 offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
486 break;
487 case(0x6): /* RSI-CONN-PDU (Only valid with ARUUID<>0) */
488 col_append_str(pinfo->cinfo, COL_INFO, "ReadConnectionless request");
489 offset = dissect_RSI_CONN_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
490 break;
491 case(0x7): /* RSI-SVCS-PDU */
492 col_append_str(pinfo->cinfo, COL_INFO, "ReadNotification request");
493 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
494 break;
495 case(0x8): /* RSI-SVCS-PDU */
496 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteMore request");
497 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
498 break;
499 case(0x9) : /* RSI-SVCS-PDU */
500 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteEnd request");
501 offset = dissect_RSI_SVCS_block(tvb, offset, pinfo, tree, drep, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
502 break;
503 default:
504 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
505 offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
506 break;
507 }
508 return offset;
509 }
510
511 /* dissect a PN-IO RSI RSP block (on top of PN-RT protocol) */
512 static int
dissect_RSI_RSP_block(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 * drep,guint16 u16VarPartLen,guint8 u8MoreFrag,guint32 u32FOpnumOffsetOffset,guint32 u32FOpnumOffsetOpnum)513 dissect_RSI_RSP_block(tvbuff_t *tvb, int offset,
514 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag, guint32 u32FOpnumOffsetOffset, guint32 u32FOpnumOffsetOpnum)
515 {
516 guint32 u32RsiHeaderSize = 4;
517
518 // PDU.FOpnumOffset.Offset + PDU.VarPartLen - 4 - RsiHeaderSize
519 gint32 length = u32FOpnumOffsetOffset + u16VarPartLen - 4 - u32RsiHeaderSize;
520
521 if (u32FOpnumOffsetOffset == 0)
522 {
523 offset = dissect_PNIO_status(tvb, offset, pinfo, tree, drep);
524 }
525
526 else if (u8MoreFrag == 0)
527 {
528 proto_item_append_text(tree, ", RSI Header of RSP is at first fragmented frame");
529 }
530
531 if (length > 0) {
532 offset = dissect_pn_rta_remaining_user_data_bytes(tvb, offset, pinfo, tree, drep,
533 tvb_captured_length_remaining(tvb, offset), u8MoreFrag, u32FOpnumOffsetOpnum, PDU_TYPE_RSP);
534 }
535
536 return offset;
537 }
538
539 /* dissect a PN-IO RSI FRSP RTA PDU (on top of PN-RT protocol) */
540 static int
dissect_FRSP_RTA_block(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 * drep,guint16 u16VarPartLen,guint8 u8MoreFrag)541 dissect_FRSP_RTA_block(tvbuff_t *tvb, int offset,
542 packet_info *pinfo, proto_tree *tree, guint8 *drep, guint16 u16VarPartLen, guint8 u8MoreFrag)
543 {
544 guint32 u32FOpnumOffset;
545 guint32 u32FOpnumOffsetOpnum;
546 guint32 u32FOpnumOffsetOffset;
547 offset = dissect_FOpnumOffset(tvb, offset, pinfo, tree, drep, &u32FOpnumOffset);
548 u32FOpnumOffsetOpnum = (u32FOpnumOffset & 0x1F000000) >> 24;
549 u32FOpnumOffsetOffset = u32FOpnumOffset & 0x00FFFFFF;
550 switch (u32FOpnumOffsetOpnum) {
551 case(0x0): /* Connect */
552 col_append_str(pinfo->cinfo, COL_INFO, "Connect response");
553 break;
554 case(0x1): /* Reserved */
555 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
556 break;
557 case(0x2): /* Read */
558 col_append_str(pinfo->cinfo, COL_INFO, "Read response");
559 break;
560 case(0x3): /* Write */
561 col_append_str(pinfo->cinfo, COL_INFO, "Write response");
562 break;
563 case(0x4): /* Control */
564 col_append_str(pinfo->cinfo, COL_INFO, "Control response");
565 break;
566 case(0x5): /* ReadImplicit */
567 col_append_str(pinfo->cinfo, COL_INFO, "ReadImplicit response");
568 break;
569 case(0x6): /* ReadConnectionless */
570 col_append_str(pinfo->cinfo, COL_INFO, "ReadConnectionless response");
571 break;
572 case(0x7): /* ReadNotification */
573 col_append_str(pinfo->cinfo, COL_INFO, "ReadNotification response");
574 break;
575 case(0x8): /* PrmWriteMore */
576 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteMore response");
577 break;
578 case(0x9) : /* PrmWriteEnd */
579 col_append_str(pinfo->cinfo, COL_INFO, "PrmWriteEnd response");
580 break;
581 default:
582 col_append_str(pinfo->cinfo, COL_INFO, "Reserved");
583 break;
584 }
585 offset = dissect_RSI_RSP_block(tvb, offset, pinfo, tree, drep, u16VarPartLen, u8MoreFrag, u32FOpnumOffsetOffset, u32FOpnumOffsetOpnum);
586 return offset;
587 }
588
589 static int
dissect_RSIAdditionalFlags(tvbuff_t * tvb,int offset,packet_info * pinfo _U_,proto_tree * tree,guint8 * drep _U_,guint8 * u8AddFlags)590 dissect_RSIAdditionalFlags(tvbuff_t *tvb, int offset,
591 packet_info *pinfo _U_, proto_tree *tree, guint8 *drep _U_, guint8 *u8AddFlags)
592 {
593 guint8 u8WindowSize;
594 guint8 u8Tack;
595 proto_item *sub_item;
596 proto_tree *sub_tree;
597
598 /* additional flags */
599 sub_item = proto_tree_add_item(tree, hf_pn_rsi_add_flags, tvb, offset, 1, ENC_NA);
600 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_add_flags);
601 /* Bit 0 - 2 : AddFlags.WindowSize */
602 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
603 hf_pn_rsi_add_flags_windowsize, u8AddFlags);
604 /* Bit 3: AddFlags.Reserved */
605 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
606 hf_pn_rsi_add_flags_reserved1, u8AddFlags);
607 /* Bit 4: AddFlags.TACK */
608 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
609 hf_pn_rsi_add_flags_tack, u8AddFlags);
610 /* Bit 5: AddFlags.MoreFrag */
611 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
612 hf_pn_rsi_add_flags_morefrag, u8AddFlags);
613 /* Bit 6: AddFlags.Notification */
614 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
615 hf_pn_rsi_add_flags_notification, u8AddFlags);
616 /* Bit 7: AddFlags.Reserved */
617 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
618 hf_pn_rsi_add_flags_reserved2, u8AddFlags);
619 u8WindowSize = *u8AddFlags & 0x03;
620 u8Tack = (*u8AddFlags & 0x10);
621 u8Tack = (u8Tack == 0x10) ? 1 : 0;
622
623 proto_item_append_text(sub_item, ", Window Size: %u, Tack: %u ",
624 u8WindowSize, u8Tack);
625 return offset;
626 }
627
628 /* dissect a PN-IO RTA RSI PDU (on top of PN-RT protocol) */
629 int
dissect_PNIO_RSI(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,guint8 * drep)630 dissect_PNIO_RSI(tvbuff_t *tvb, int offset,
631 packet_info *pinfo, proto_tree *tree, guint8 *drep)
632 {
633 guint16 u16DestinationServiceAccessPoint;
634 guint16 u16SourceServiceAccessPoint;
635 guint8 u8PDUType;
636 guint8 u8PDUVersion;
637 guint8 u8AddFlags;
638 guint8 u8MoreFrag;
639 guint16 u16SendSeqNum;
640 guint16 u16AckSeqNum;
641 guint16 u16VarPartLen;
642 int start_offset = offset;
643
644 proto_item *rta_item;
645 proto_tree *rta_tree;
646
647 proto_item *sub_item;
648 proto_tree *sub_tree;
649
650 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO-RSI");
651 rta_item = proto_tree_add_protocol_format(tree, proto_pn_rsi, tvb, offset, tvb_captured_length(tvb),
652 "PROFINET IO RSI");
653
654 rta_tree = proto_item_add_subtree(rta_item, ett_pn_rsi_rta);
655
656 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
657 hf_pn_rsi_dst_srv_access_point, &u16DestinationServiceAccessPoint);
658 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
659 hf_pn_rsi_src_srv_access_point, &u16SourceServiceAccessPoint);
660
661 //col_append_fstr(pinfo->cinfo, COL_INFO, ", Src: 0x%x, Dst: 0x%x",
662 // u16SourceServiceAccessPoint, u16DestinationServiceAccessPoint);
663
664 /* PDU type */
665 sub_item = proto_tree_add_item(rta_tree, hf_pn_rsi_pdu_type, tvb, offset, 1, ENC_NA);
666 sub_tree = proto_item_add_subtree(sub_item, ett_pn_rsi_pdu_type);
667
668 /* PDU type type - version of RTA 2*/
669 dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
670 hf_pn_rsi_pdu_type_type, &u8PDUType);
671 u8PDUType &= 0x0F;
672
673 /* PDU type version - version of RTA 2*/
674 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
675 hf_pn_rsi_pdu_type_version, &u8PDUVersion);
676 u8PDUVersion >>= 4;
677 //proto_item_append_text(sub_item, ", Type: %s, Version: %u",
678 // val_to_str(u8PDUType, pn_rsi_pdu_type_type, "Unknown"),
679 // u8PDUVersion);
680 offset = dissect_RSIAdditionalFlags(tvb, offset, pinfo, rta_tree, drep, &u8AddFlags);
681 u8MoreFrag = (u8AddFlags >> 5) & 0x1;
682 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
683 hf_pn_rsi_send_seq_num, &u16SendSeqNum);
684 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
685 hf_pn_rsi_ack_seq_num, &u16AckSeqNum);
686 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, rta_tree, drep,
687 hf_pn_rsi_var_part_len, &u16VarPartLen);
688
689 switch (u8PDUType & 0x0F) {
690 case(3): /* ACK-RTA */
691 col_append_str(pinfo->cinfo, COL_INFO, "ACK-RTA");
692
693 if (u8AddFlags & 0x40) {
694
695 col_append_str(pinfo->cinfo, COL_INFO, ", Application Ready Notification");
696 }
697 /* no additional data */
698 break;
699 case(4): /* ERR-RTA */
700 col_append_str(pinfo->cinfo, COL_INFO, "ERR-RTA");
701 offset = dissect_PNIO_status(tvb, offset, pinfo, rta_tree, drep);
702 break;
703 case(5): /* FREQ-RTA */
704 offset = dissect_FREQ_RTA_block(tvb, offset, pinfo, rta_tree, drep, u8MoreFrag);
705 break;
706 case(6): /* FRSP-RTA */
707 offset = dissect_FRSP_RTA_block(tvb, offset, pinfo, rta_tree, drep, u16VarPartLen, u8MoreFrag);
708 break;
709 default:
710 offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, tvb_captured_length(tvb));
711 break;
712 }
713
714 proto_item_set_len(rta_item, offset - start_offset);
715
716 return offset;
717 }
718
719 int
dissect_PDRsiInstances_block(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,proto_item * item _U_,guint8 * drep,guint8 u8BlockVersionHigh,guint8 u8BlockVersionLow)720 dissect_PDRsiInstances_block(tvbuff_t *tvb, int offset,
721 packet_info *pinfo, proto_tree *tree, proto_item *item _U_, guint8 *drep, guint8 u8BlockVersionHigh, guint8 u8BlockVersionLow)
722 {
723 proto_item *sub_item;
724 proto_tree *sub_tree;
725 guint16 u16NumberOfEntries;
726 guint16 u16VendorId;
727 guint16 u16DeviceId;
728 guint16 u16InstanceId;
729 guint8 u8RsiInterface;
730 const int deviceType_size = 25;
731 const int orderID_size = 20;
732 const int IMserialnumber_size = 16;
733 const int HWrevision_size = 5;
734 const int SWrevisionprefix_size = 1;
735 const int SWrevision_size = 9;
736 char *deviceType;
737 char *orderID;
738 char *IMserialnumber;
739 char *HWrevision;
740 char *SWrevisionprefix;
741 char *SWrevision;
742
743 if (u8BlockVersionHigh != 1 || u8BlockVersionLow != 0) {
744 expert_add_info_format(pinfo, item, &ei_pn_rsi_error,
745 "Block version %u.%u not implemented yet!", u8BlockVersionHigh, u8BlockVersionLow);
746 return offset;
747 }
748
749 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, tree, drep,
750 hf_pn_rsi_number_of_entries, &u16NumberOfEntries);
751
752 proto_item_append_text(item, ": NumberOfEntries:%u", u16NumberOfEntries);
753
754 while (u16NumberOfEntries > 0) {
755 u16NumberOfEntries--;
756
757 sub_item = proto_tree_add_item(tree, hf_pn_rsi_pd_rsi_instance, tvb, offset, 0, ENC_NA);
758 sub_tree = proto_item_add_subtree(sub_item, ett_pn_io_pd_rsi_instance);
759 /* VendorID */
760 /* DeviceID */
761 /* InstanceID */
762 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
763 hf_pn_rsi_vendor_id, &u16VendorId);
764 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
765 hf_pn_rsi_device_id, &u16DeviceId);
766 offset = dissect_dcerpc_uint16(tvb, offset, pinfo, sub_tree, drep,
767 hf_pn_rsi_instance_id, &u16InstanceId);
768
769 /* RSI Interface */
770 offset = dissect_dcerpc_uint8(tvb, offset, pinfo, sub_tree, drep,
771 hf_pn_rsi_interface, &u8RsiInterface);
772
773 proto_item_append_text(sub_item, ": VendorID:%u, DeviceID:%u, InstanceID:%u, RsiInterface:%u",
774 u16VendorId, u16DeviceId, u16InstanceId, u8RsiInterface);
775
776 /* Padding */
777 offset = dissect_pn_padding(tvb, offset, pinfo, sub_tree, 1);
778 }
779
780 /* SystemIdentification */
781 /* DeviceType */
782 deviceType = (char *)wmem_alloc(pinfo->pool, deviceType_size + 1);
783 tvb_memcpy(tvb, (guint8 *)deviceType, offset, 25);
784 deviceType[deviceType_size] = '\0';
785 proto_tree_add_string(tree, hf_pn_rsi_device_type, tvb, offset, deviceType_size, deviceType);
786 offset += deviceType_size + 1;
787
788 /* Blank */
789
790 /* OrderID */
791 orderID = (char *)wmem_alloc(pinfo->pool, orderID_size + 1);
792 tvb_memcpy(tvb, (guint8 *)orderID, offset, 20);
793 orderID[orderID_size] = '\0';
794 proto_tree_add_string(tree, hf_pn_rsi_order_id, tvb, offset, orderID_size, orderID);
795 offset += orderID_size + 1;
796
797 /* Blank */
798
799 /* IM_Serial_Number */
800 IMserialnumber = (char *)wmem_alloc(pinfo->pool, IMserialnumber_size + 1);
801 tvb_memcpy(tvb, (guint8 *)IMserialnumber, offset, 16);
802 IMserialnumber[IMserialnumber_size] = '\0';
803 proto_tree_add_string(tree, hf_pn_rsi_im_serial_number, tvb, offset, IMserialnumber_size, IMserialnumber);
804 offset += IMserialnumber_size + 1;
805
806 /* Blank */
807
808 /* HWRevision */
809 HWrevision = (char *)wmem_alloc(pinfo->pool, HWrevision_size + 1);
810 tvb_memcpy(tvb, (guint8 *)HWrevision, offset, 5);
811 HWrevision[HWrevision_size] = '\0';
812 proto_tree_add_string(tree, hf_pn_rsi_hw_revision, tvb, offset, HWrevision_size, HWrevision);
813 offset += HWrevision_size + 1;
814
815 /* Blank */
816
817 /* SWRevisionPrefix */
818 SWrevisionprefix = (char *)wmem_alloc(pinfo->pool, SWrevisionprefix_size + 1);
819 tvb_memcpy(tvb, (guint8 *)SWrevisionprefix, offset, 1);
820 SWrevisionprefix[SWrevisionprefix_size] = '\0';
821 proto_tree_add_string(tree, hf_pn_rsi_sw_revision_prefix, tvb, offset, SWrevisionprefix_size, SWrevisionprefix);
822 offset += SWrevisionprefix_size;
823
824 /* SWRevision */
825 SWrevision = (char *)wmem_alloc(pinfo->pool, SWrevision_size + 1);
826 tvb_memcpy(tvb, (guint8 *)SWrevision, offset, 9);
827 SWrevision[SWrevision_size] = '\0';
828 proto_tree_add_string(tree, hf_pn_rsi_sw_revision, tvb, offset, SWrevision_size, SWrevision);
829 offset += SWrevision_size;
830 return offset;
831 }
832
833 void
init_pn_rsi(int proto)834 init_pn_rsi(int proto)
835 {
836 static hf_register_info hf[] = {
837 { &hf_pn_rsi_dst_srv_access_point,
838 { "DestinationServiceAccessPoint", "pn_rsi.dst_srv_access_point",
839 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_alarm_endpoint), 0x0,
840 NULL, HFILL }
841 },
842 { &hf_pn_rsi_src_srv_access_point,
843 { "SourceServiceAccessPoint", "pn_rsi.src_srv_access_point",
844 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_alarm_endpoint), 0x0,
845 NULL, HFILL }
846 },
847 { &hf_pn_rsi_pdu_type,
848 { "PDUType", "pn_rsi.pdu_type",
849 FT_NONE, BASE_NONE, NULL, 0x0,
850 NULL, HFILL }
851 },
852 { &hf_pn_rsi_pdu_type_type,
853 { "Type", "pn_rsi.pdu_type.type",
854 FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_pdu_type_type), 0x0F,
855 NULL, HFILL }
856 },
857 { &hf_pn_rsi_pdu_type_version,
858 { "Version", "pn_rsi.pdu_type.version",
859 FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_pdu_type_version), 0xF0,
860 NULL, HFILL }
861 },
862 { &hf_pn_rsi_add_flags,
863 { "AddFlags", "pn_rsi.add_flags",
864 FT_NONE, BASE_NONE, NULL, 0x0,
865 NULL, HFILL }
866 },
867 { &hf_pn_rsi_add_flags_windowsize,
868 { "WindowSize", "pn_rsi.add_flags_windowsize",
869 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_windowsize), 0x07,
870 NULL, HFILL }
871 },
872 { &hf_pn_rsi_add_flags_reserved1,
873 { "Reserved", "pn_rsi.add_flags_reserved",
874 FT_UINT8, BASE_HEX, NULL, 0x08,
875 NULL, HFILL }
876 },
877 { &hf_pn_rsi_add_flags_tack,
878 { "TACK", "pn_rsi.add_flags_tack",
879 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_tack), 0x10,
880 NULL, HFILL }
881 },
882 { &hf_pn_rsi_add_flags_morefrag,
883 { "MoreFrag", "pn_rsi.add_flags_morefrag",
884 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_morefrag), 0x20,
885 NULL, HFILL }
886 },
887 { &hf_pn_rsi_add_flags_notification,
888 { "Notification", "pn_rsi.add_flags_notification",
889 FT_UINT8, BASE_HEX, VALS(pn_rsi_add_flags_notification), 0x40,
890 NULL, HFILL }
891 },
892 { &hf_pn_rsi_add_flags_reserved2,
893 { "Reserved", "pn_rsi.add_flags_reserved",
894 FT_UINT8, BASE_HEX, NULL, 0x80,
895 NULL, HFILL }
896 },
897 { &hf_pn_rsi_send_seq_num,
898 { "SendSeqNum", "pn_rsi.send_seq_num",
899 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_seq_num), 0x0,
900 NULL, HFILL }
901 },
902 { &hf_pn_rsi_ack_seq_num,
903 { "AckSeqNum", "pn_rsi.ack_seq_num",
904 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_seq_num), 0x0,
905 NULL, HFILL }
906 },
907 { &hf_pn_rsi_var_part_len,
908 { "VarPartLen", "pn_rsi.var_part_len",
909 FT_UINT16, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_var_part_len), 0x0,
910 NULL, HFILL }
911 },
912 { &hf_pn_rsi_f_opnum_offset,
913 { "FOpnumOffset", "pn_rsi.f_opnum_offset",
914 FT_UINT32, BASE_HEX, NULL, 0x0,
915 NULL, HFILL }
916 },
917 { &hf_pn_rsi_f_opnum_offset_offset,
918 { "FOpnumOffset.Offset", "pn_rsi.f_opnum_offset.offset",
919 FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_f_opnum_offset_offset), 0x00FFFFFF,
920 NULL, HFILL }
921 },
922 { &hf_pn_rsi_f_opnum_offset_opnum,
923 { "FOpnumOffset.Opnum", "pn_rsi.f_opnum_offset.opnum",
924 FT_UINT32, BASE_HEX, VALS(pn_rsi_f_opnum_offset_opnum), 0x1F000000,
925 NULL, HFILL }
926 },
927 { &hf_pn_rsi_f_opnum_offset_callsequence,
928 { "FOpnumOffset.CallSequence", "pn_rsi.f_opnum_offset.callsequence",
929 FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_f_opnum_offset_callsequence), 0xE0000000,
930 NULL, HFILL }
931 },
932 { &hf_pn_rsi_conn_block,
933 { "RSI CONN Block", "pn_rsi.conn_block",
934 FT_NONE, BASE_NONE, NULL, 0x0,
935 NULL, HFILL }
936 },
937 { &hf_pn_rsi_rsp_max_length,
938 { "RspMaxLength", "pn_rsi.rsp_max_length",
939 FT_UINT32, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_rsp_max_length), 0x0,
940 NULL, HFILL }
941 },
942 { &hf_pn_rsi_vendor_id,
943 { "VendorID", "pn_rsi.vendor_id",
944 FT_UINT16, BASE_HEX, NULL, 0x0,
945 NULL, HFILL }
946 },
947 { &hf_pn_rsi_device_id,
948 { "DeviceID", "pn_rsi.device_id",
949 FT_UINT16, BASE_HEX, NULL, 0x0,
950 NULL, HFILL }
951 },
952 { &hf_pn_rsi_instance_id,
953 { "InstanceID", "pn_rsi.instance_id",
954 FT_UINT16, BASE_HEX, NULL, 0x0,
955 NULL, HFILL }
956 },
957 { &hf_pn_rsi_interface,
958 { "RsiInterface", "pn_rsi.interface",
959 FT_UINT8, BASE_HEX|BASE_RANGE_STRING, RVALS(pn_rsi_interface), 0x0,
960 NULL, HFILL }
961 },
962 { &hf_pn_rsi_svcs_block,
963 { "RSI SVCS Block", "pn_rsi.svcs_block",
964 FT_NONE, BASE_NONE, NULL, 0x0,
965 NULL, HFILL }
966 },
967 { &hf_pn_rsi_number_of_entries,
968 { "NumberOfEntries", "pn_rsi.number_of_entries",
969 FT_UINT16, BASE_HEX, NULL, 0x0,
970 NULL, HFILL }
971 },
972 { &hf_pn_rsi_pd_rsi_instance,
973 { "PDRsiInstance", "pn_rsi.pd_rsi_instance",
974 FT_NONE, BASE_NONE, NULL, 0x0,
975 NULL, HFILL }
976 },
977 { &hf_pn_rsi_device_type,
978 { "DeviceType", "pn_rsi.device_type",
979 FT_STRING, BASE_NONE, NULL, 0x0,
980 NULL, HFILL }
981 },
982 { &hf_pn_rsi_order_id,
983 { "OrderID", "pn_rsi.order_id",
984 FT_STRING, BASE_NONE, NULL, 0x0,
985 NULL, HFILL }
986 },
987 { &hf_pn_rsi_im_serial_number,
988 { "IM_Serial_Number", "pn_rsi.im_serial_number",
989 FT_STRING, BASE_NONE, NULL, 0x0,
990 NULL, HFILL }
991 },
992 { &hf_pn_rsi_hw_revision,
993 { "HWRevision", "pn_rsi.hw_revision",
994 FT_STRING, BASE_NONE, NULL, 0x0,
995 NULL, HFILL }
996 },
997 { &hf_pn_rsi_sw_revision_prefix,
998 { "SWRevisionPrefix", "pn_rsi.sw_revision_prefix",
999 FT_STRING, BASE_NONE, NULL, 0x0,
1000 NULL, HFILL }
1001 },
1002 { &hf_pn_rsi_sw_revision,
1003 { "SWRevision", "pn_rsi.sw_revision",
1004 FT_STRING, BASE_NONE, NULL, 0x0,
1005 NULL, HFILL }
1006 },
1007 /*&hf_pn_rsi_segment_too_long_segment,
1008 &hf_pn_rsi_segment_error,
1009 &hf_pn_rsi_segment_count,
1010 &hf_pn_rsi_reassembled_in,
1011 &hf_pn_rsi_reassembled_length,*/
1012 { &hf_pn_rsi_segment,
1013 { "RSI Segment", "pn_rsi.segment",
1014 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1015 NULL, HFILL }
1016 },
1017 { &hf_pn_rsi_segments,
1018 { "PN RSI Segments", "pn_rsi.segments",
1019 FT_NONE, BASE_NONE, NULL, 0x0,
1020 NULL, HFILL }
1021 },
1022 { &hf_pn_rsi_segment_overlap,
1023 { "Segment overlap", "pn_rsi.segment.overlap",
1024 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1025 "Segment overlaps with other segments", HFILL }
1026 },
1027 { &hf_pn_rsi_segment_overlap_conflict,
1028 { "Conflicting data in segment overlap", "pn_rsi.segment.overlap.conflict",
1029 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1030 "Overlapping segments contained conflicting data", HFILL }
1031 },
1032 { &hf_pn_rsi_segment_multiple_tails,
1033 { "Multiple tail segments found", "pn_rsi.segment.multipletails",
1034 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1035 "Several tails were found when reassembling the packet", HFILL }
1036 },
1037 { &hf_pn_rsi_segment_too_long_segment,
1038 { "Segment too long", "pn_rsi.segment.toolongsegment",
1039 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1040 "Segment contained data past end of packet", HFILL }
1041 },
1042 { &hf_pn_rsi_segment_error,
1043 { "Reassembly error", "pn_rsi.segment.error",
1044 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1045 "Reassembly error due to illegal segments", HFILL }
1046 },
1047 { &hf_pn_rsi_segment_count,
1048 { "Segment count", "pn_rsi.segment.count",
1049 FT_UINT32, BASE_DEC, NULL, 0x0,
1050 NULL, HFILL }
1051 },
1052 { &hf_pn_rsi_reassembled_in,
1053 { "Reassembled pn_rsi in frame", "pn_rsi.reassembled_in",
1054 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1055 "This pn_rsi packet is reassembled in this frame", HFILL }
1056 },
1057 { &hf_pn_rsi_reassembled_length,
1058 { "Reassembled pn_rsi length", "pn_rsi.reassembled.length",
1059 FT_UINT32, BASE_DEC, NULL, 0x0,
1060 "The total length of the reassembled payload", HFILL }
1061 },
1062 { &hf_pn_rsi_data_payload,
1063 { "PN IO RSI Data Payload", "pn_rsi.data_payload",
1064 FT_NONE, BASE_NONE, NULL, 0x0,
1065 "", HFILL }
1066 }
1067 };
1068
1069 static gint *ett[] = {
1070 &ett_pn_rsi,
1071 &ett_pn_rsi_pdu_type,
1072 &ett_pn_rsi_f_opnum_offset,
1073 &ett_pn_rsi_conn_block,
1074 &ett_pn_rsi_svcs_block,
1075 &ett_pn_rsi_add_flags,
1076 &ett_pn_rsi_rta,
1077 &ett_pn_io_pd_rsi_instance,
1078 &ett_pn_rsi_segments,
1079 &ett_pn_rsi_segment,
1080 &ett_pn_rsi_data_payload
1081 };
1082
1083 static ei_register_info ei[] = {
1084 { &ei_pn_rsi_error, { "pn_rsi.ack_seq_num", PI_UNDECODED, PI_NOTE, "Block version not implemented yet!", EXPFILL } }
1085
1086 };
1087
1088 expert_module_t* expert_pn_rsi;
1089
1090 proto_pn_rsi = proto;
1091
1092 proto_register_field_array(proto, hf, array_length(hf));
1093 proto_register_subtree_array(ett, array_length(ett));
1094 expert_pn_rsi = expert_register_protocol(proto_pn_rsi);
1095 expert_register_field_array(expert_pn_rsi, ei, array_length(ei));
1096
1097 register_init_routine(pn_rsi_reassemble_init);
1098 }
1099