1 /* packet-iwarp-ddp-rdmap.c
2 * Routines for Direct Data Placement (DDP) and
3 * Remote Direct Memory Access Protocol (RDMAP) dissection
4 * According to IETF RFC 5041 and RFC 5040
5 * Copyright 2008, Yves Geissbuehler <yves.geissbuehler@gmx.net>
6 * Copyright 2008, Philip Frey <frey.philip@gmail.com>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
35 #include <epan/packet.h>
39 /* header field byte lengths */
40 #define DDP_CONTROL_FIELD_LEN 1
41 #define DDP_TAGGED_HEADER_LEN 14
42 #define DDP_TAGGED_RSVDULP_LEN 4
43 #define DDP_STAG_LEN 4
45 #define DDP_UNTAGGED_HEADER_LEN 18
46 #define DDP_UNTAGGED_RSVDULP_LEN 5
50 #define DDP_BUFFER_MODEL_LEN 12
52 #define RDMA_CONTROL_FIELD_LEN 1
53 #define RDMA_RESERVED_FIELD_LEN 4
54 #define RDMA_INVAL_STAG_LEN 4
55 #define RDMA_SINKSTAG_LEN 4
56 #define RDMA_SINKTO_LEN 8
57 #define RDMA_RDMARDSZ_LEN 4
58 #define RDMA_SRCSTAG_LEN 4
59 #define RDMA_SRCTO_LEN 8
60 #define RDMA_DDP_SEGLEN_LEN 2
61 #define RDMA_TERMINATED_RDMA_LEN 28
64 #define RDMA_WRITE 0x00
65 #define RDMA_READ_REQUEST 0x01
66 #define RDMA_READ_RESPONSE 0x02
67 #define RDMA_SEND 0x03
68 #define RDMA_SEND_INVALIDATE 0x04
69 #define RDMA_SEND_SE 0x05
70 #define RDMA_SEND_SE_INVALIDATE 0x06
71 #define RDMA_TERMINATE 0x07
74 #define DDP_TAGGED_FLAG 0x80
75 #define DDP_LAST_FLAG 0x40
80 #define RDMA_OPCODE 0x0F
82 #define IWARP_LAYER 0xF0
83 #define IWARP_ETYPE 0x0F
84 #define IWARP_HDRCT 0xE0
85 #define IWARP_HDRCT_M 0x80
86 #define IWARP_HDRCT_D 0x40
87 #define IWARP_HDRCT_R 0x20
88 #define IWARP_TERM_RES 0x1FFF
90 #define IWARP_LAYER_RDMA 0x00
91 #define IWARP_LAYER_DDP 0x10
92 #define IWARP_LAYER_LLP 0x20
93 #define IWARP_ETYPE_DDP_TAGGED 0x01
94 #define IWARP_ETYPE_DDP_UNTAGGED 0x02
97 static gint proto_iwarp_ddp_rdmap
= -1;
98 static gint ett_iwarp_ddp_rdmap
= -1;
100 static dissector_handle_t data_handle
;
103 * DDP: initialize the protocol and registered fields
105 static gint hf_iwarp_ddp
= -1;
107 /* DDP Control Field */
108 static gint hf_iwarp_ddp_control_field
= -1;
109 static gint hf_iwarp_ddp_t_flag
= -1;
110 static gint hf_iwarp_ddp_l_flag
= -1;
111 static gint hf_iwarp_ddp_rsvd
= -1;
112 static gint hf_iwarp_ddp_dv
= -1;
114 /* DDP rsvdULP[8:39] field */
115 static gint hf_iwarp_ddp_rsvdulp
= -1;
117 /* Tagged Buffer Model Header */
118 static gint hf_iwarp_ddp_tagged_header
= -1;
119 static gint hf_iwarp_ddp_stag
= -1;
120 static gint hf_iwarp_ddp_to
= -1;
122 /* Untagged Buffer Model Header */
123 static gint hf_iwarp_ddp_untagged_header
= -1;
124 static gint hf_iwarp_ddp_qn
= -1;
125 static gint hf_iwarp_ddp_msn
= -1;
126 static gint hf_iwarp_ddp_mo
= -1;
128 /* initialize the subtree pointers */
129 static gint ett_iwarp_ddp
= -1;
131 static gint ett_iwarp_ddp_control_field
= -1;
132 static gint ett_iwarp_ddp_tagged_header
= -1;
133 static gint ett_iwarp_ddp_untagged_header
= -1;
136 * RDMAP: initialize the protocol and registered fields
138 static gint hf_iwarp_rdma
= -1;
141 static gint hf_iwarp_rdma_control_field
= -1;
142 static gint hf_iwarp_rdma_version
= -1;
143 static gint hf_iwarp_rdma_rsvd
= -1;
144 static gint hf_iwarp_rdma_opcode
= -1;
146 /* DDP rsvdULP[8:39] RDMA interpretations */
147 static gint hf_iwarp_rdma_reserved
= -1;
148 static gint hf_iwarp_rdma_inval_stag
= -1;
150 /* Read Request Header */
151 static gint hf_iwarp_rdma_rr_header
= -1;
152 static gint hf_iwarp_rdma_sinkstag
= -1;
153 static gint hf_iwarp_rdma_sinkto
= -1;
154 static gint hf_iwarp_rdma_rdmardsz
= -1;
155 static gint hf_iwarp_rdma_srcstag
= -1;
156 static gint hf_iwarp_rdma_srcto
= -1;
158 /* Terminate Header */
159 static gint hf_iwarp_rdma_terminate_header
= -1;
160 static gint hf_iwarp_rdma_term_ctrl
= -1;
161 static gint hf_iwarp_rdma_term_layer
= -1;
162 static gint hf_iwarp_rdma_term_etype
= -1;
163 static gint hf_iwarp_rdma_term_etype_rdma
= -1;
164 static gint hf_iwarp_rdma_term_etype_ddp
= -1;
165 static gint hf_iwarp_rdma_term_etype_llp
= -1;
166 static gint hf_iwarp_rdma_term_errcode
= -1;
167 static gint hf_iwarp_rdma_term_errcode_rdma
= -1;
168 static gint hf_iwarp_rdma_term_errcode_ddp_untagged
= -1;
169 static gint hf_iwarp_rdma_term_errcode_ddp_tagged
= -1;
170 static gint hf_iwarp_rdma_term_errcode_llp
= -1;
171 static gint hf_iwarp_rdma_term_hdrct
= -1;
172 static gint hf_iwarp_rdma_term_hdrct_m
= -1;
173 static gint hf_iwarp_rdma_term_hdrct_d
= -1;
174 static gint hf_iwarp_rdma_term_hdrct_r
= -1;
175 static gint hf_iwarp_rdma_term_rsvd
= -1;
176 static gint hf_iwarp_rdma_term_ddp_seg_len
= -1;
177 static gint hf_iwarp_rdma_term_ddp_h
= -1;
178 static gint hf_iwarp_rdma_term_rdma_h
= -1;
180 /* initialize the subtree pointers */
181 static gint ett_iwarp_rdma
= -1;
183 static gint ett_iwarp_rdma_control_field
= -1;
184 static gint ett_iwarp_rdma_rr_header
= -1;
185 static gint ett_iwarp_rdma_terminate_header
= -1;
186 static gint ett_iwarp_rdma_term_ctrl
= -1;
187 static gint ett_iwarp_rdma_term_hdrct
= -1;
189 static const value_string rdmap_messages
[] = {
190 { RDMA_WRITE
, "Write" },
191 { RDMA_READ_REQUEST
, "Read Request" },
192 { RDMA_READ_RESPONSE
, "Read Response" },
193 { RDMA_SEND
, "Send" },
194 { RDMA_SEND_INVALIDATE
, "Send with Invalidate" },
195 { RDMA_SEND_SE
, "Send with SE" },
196 { RDMA_SEND_SE_INVALIDATE
, "Send with SE and Invalidate" },
197 { RDMA_TERMINATE
, "Terminate" },
201 static const value_string layer_names
[] = {
202 { IWARP_LAYER_RDMA
, "RDMA" },
203 { IWARP_LAYER_DDP
, "DDP" },
204 { IWARP_LAYER_LLP
, "LLP" },
209 static const value_string rdma_etype_names
[] = {
210 { 0x00, "Local Catastrophic Error" },
211 { 0x01, "Remote Protection Error" },
212 { 0x02, "Remote Operation Error" },
216 static const value_string rdma_errcode_names
[] = {
217 { 0x00, "Invalid STag" },
218 { 0x01, "Base or bounds violation" },
219 { 0x02, "Access rights violation" },
220 { 0x03, "STag not associated with RDMAP Stream" },
222 { 0x05, "Invalid RDMAP version" },
223 { 0x06, "Unexpected OpCode" },
224 { 0x07, "Catastrophic error, localized to RDMAP Stream" },
225 { 0x08, "Catastrophic error, global" },
226 { 0x09, "STag cannot be Invalidated" },
227 { 0xFF, "Unspecific Error" },
231 static const value_string ddp_etype_names
[] = {
232 { 0x00, "Local Catastrophic Error" },
233 { 0x01, "Tagged Buffer Error" },
234 { 0x02, "Untagged Buffer Error" },
235 { 0x03, "Reserved for the use by the LLP" },
239 static const value_string ddp_errcode_tagged_names
[] = {
240 { 0x00, "Invalid STag" },
241 { 0x01, "Base or bounds violation" },
242 { 0x02, "STag not associated with DDP Stream" },
244 { 0x04, "Invalid DDP version" },
248 static const value_string ddp_errcode_untagged_names
[] = {
249 { 0x01, "Invalid QN" },
250 { 0x02, "Invalid MSN - no buffer available" },
251 { 0x03, "Invalid MSN - MSN range is not valid" },
252 { 0x04, "Invalid MO" },
253 { 0x05, "DDP Message too long for available buffer" },
254 { 0x06, "Invalid DDP version" },
258 /* update packet list pane in the GUI */
260 ddp_rdma_packetlist(packet_info
*pinfo
, gboolean ddp_last_flag
,
261 guint8 rdma_msg_opcode
)
263 const gchar
*ddp_fragment_state
;
265 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DDP/RDMA");
268 ddp_fragment_state
= "[last DDP segment]";
270 ddp_fragment_state
= "[more DDP segments]";
273 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "%d > %d %s %s", pinfo
->srcport
,
274 pinfo
->destport
, val_to_str(rdma_msg_opcode
, rdmap_messages
,
275 "Unknown %d"), ddp_fragment_state
);
278 /* dissects RDMA Read Request and Terminate message header */
280 dissect_iwarp_rdmap(tvbuff_t
*tvb
, proto_tree
*rdma_tree
, guint32 offset
,
281 guint8 rdma_msg_opcode
)
283 proto_tree
*rdma_header_tree
= NULL
;
284 proto_tree
*term_ctrl_field_tree
= NULL
;
285 proto_tree
*header_ctrl_field_tree
= NULL
;
287 proto_item
*rdma_header_subitem
= NULL
;
288 proto_item
*term_ctrl_field_subitem
= NULL
;
289 proto_item
*header_ctrl_field_subitem
= NULL
;
291 guint8 layer
, etype
, hdrct
;
297 if (rdma_msg_opcode
== RDMA_READ_REQUEST
) {
298 rdma_header_subitem
= proto_tree_add_item(rdma_tree
,
299 hf_iwarp_rdma_rr_header
, tvb
, offset
, -1, ENC_NA
);
300 rdma_header_tree
= proto_item_add_subtree(rdma_header_subitem
,
303 proto_tree_add_item(rdma_header_tree
, hf_iwarp_rdma_sinkstag
, tvb
,
304 offset
, RDMA_SINKSTAG_LEN
, ENC_BIG_ENDIAN
);
305 offset
+= RDMA_SINKSTAG_LEN
;
306 proto_tree_add_item(rdma_header_tree
, hf_iwarp_rdma_sinkto
, tvb
,
307 offset
, RDMA_SINKTO_LEN
, ENC_BIG_ENDIAN
);
308 offset
+= RDMA_SINKTO_LEN
;
310 rdmardsz
= (guint32
) tvb_get_ntohl(tvb
, offset
);
311 proto_tree_add_uint_format_value(rdma_header_tree
,
312 hf_iwarp_rdma_rdmardsz
, tvb
, offset
,
313 RDMA_RDMARDSZ_LEN
, rdmardsz
, "%u bytes",
316 offset
+= RDMA_RDMARDSZ_LEN
;
317 proto_tree_add_item(rdma_header_tree
, hf_iwarp_rdma_srcstag
, tvb
,
318 offset
, RDMA_SRCSTAG_LEN
, ENC_BIG_ENDIAN
);
319 offset
+= RDMA_SRCSTAG_LEN
;
320 proto_tree_add_item(rdma_header_tree
, hf_iwarp_rdma_srcto
, tvb
,
321 offset
, RDMA_SRCTO_LEN
, ENC_NA
);
322 offset
+= RDMA_SRCTO_LEN
;
325 if (rdma_msg_opcode
== RDMA_TERMINATE
) {
326 rdma_header_subitem
= proto_tree_add_item(rdma_tree
,
327 hf_iwarp_rdma_terminate_header
, tvb
, offset
, -1, ENC_NA
);
328 rdma_header_tree
= proto_item_add_subtree(rdma_header_subitem
,
331 /* Terminate Control Field */
332 layer
= tvb_get_guint8(tvb
, offset
) & IWARP_LAYER
;
333 etype
= tvb_get_guint8(tvb
, offset
) & IWARP_ETYPE
;
335 term_ctrl_field_subitem
= proto_tree_add_item(rdma_tree
,
336 hf_iwarp_rdma_term_ctrl
, tvb
, offset
, 3, ENC_NA
);
337 term_ctrl_field_tree
= proto_item_add_subtree(
338 term_ctrl_field_subitem
, ett_iwarp_rdma
);
339 proto_tree_add_item(term_ctrl_field_tree
, hf_iwarp_rdma_term_layer
,
340 tvb
, offset
, 1, ENC_BIG_ENDIAN
);
343 case IWARP_LAYER_RDMA
:
344 proto_tree_add_item(term_ctrl_field_tree
,
345 hf_iwarp_rdma_term_etype_rdma
, tvb
, offset
, 1,
348 proto_tree_add_item(term_ctrl_field_tree
,
349 hf_iwarp_rdma_term_errcode_rdma
, tvb
, offset
, 1,
353 case IWARP_LAYER_DDP
:
354 proto_tree_add_item(term_ctrl_field_tree
,
355 hf_iwarp_rdma_term_etype_ddp
, tvb
, offset
, 1,
359 case IWARP_ETYPE_DDP_TAGGED
:
360 proto_tree_add_item(term_ctrl_field_tree
,
361 hf_iwarp_rdma_term_errcode_ddp_tagged
, tvb
,
362 offset
, 1, ENC_BIG_ENDIAN
);
365 case IWARP_ETYPE_DDP_UNTAGGED
:
366 proto_tree_add_item(term_ctrl_field_tree
,
367 hf_iwarp_rdma_term_errcode_ddp_untagged
, tvb
,
368 offset
, 1, ENC_BIG_ENDIAN
);
372 proto_tree_add_item(term_ctrl_field_tree
,
373 hf_iwarp_rdma_term_errcode
, tvb
, offset
, 1,
379 case IWARP_LAYER_LLP
:
380 proto_tree_add_item(term_ctrl_field_tree
,
381 hf_iwarp_rdma_term_etype_llp
, tvb
, offset
, 1,
384 proto_tree_add_item(term_ctrl_field_tree
,
385 hf_iwarp_rdma_term_errcode_llp
, tvb
, offset
, 1,
390 proto_tree_add_item(term_ctrl_field_tree
,
391 hf_iwarp_rdma_term_etype
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
393 proto_tree_add_item(term_ctrl_field_tree
,
394 hf_iwarp_rdma_term_errcode
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
399 /* header control bits (hdctr), part of Terminate Control Field */
400 header_ctrl_field_subitem
= proto_tree_add_item(
401 term_ctrl_field_tree
, hf_iwarp_rdma_term_hdrct
, tvb
,
403 header_ctrl_field_tree
= proto_item_add_subtree(
404 header_ctrl_field_subitem
, ett_iwarp_rdma
);
406 hdrct
= tvb_get_guint8(tvb
, offset
) & IWARP_HDRCT
;
408 proto_tree_add_item(header_ctrl_field_tree
,
409 hf_iwarp_rdma_term_hdrct_m
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
410 proto_tree_add_item(header_ctrl_field_tree
,
411 hf_iwarp_rdma_term_hdrct_d
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
412 proto_tree_add_item(header_ctrl_field_tree
,
413 hf_iwarp_rdma_term_hdrct_r
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
415 proto_tree_add_item(rdma_header_tree
, hf_iwarp_rdma_term_rsvd
, tvb
,
416 offset
, 2, ENC_BIG_ENDIAN
);
420 if (hdrct
& IWARP_HDRCT_D
) {
421 /* DDP Segment Length (if any) */
422 proto_tree_add_item(rdma_header_tree
,
423 hf_iwarp_rdma_term_ddp_seg_len
, tvb
,
424 offset
, RDMA_DDP_SEGLEN_LEN
, ENC_NA
);
425 offset
+= RDMA_DDP_SEGLEN_LEN
;
427 /* Terminated DDP Header (if any), tagged or untagged */
428 if (etype
== IWARP_ETYPE_DDP_TAGGED
) {
429 proto_tree_add_item(rdma_header_tree
,
430 hf_iwarp_rdma_term_ddp_h
, tvb
,
431 offset
, DDP_TAGGED_HEADER_LEN
, ENC_NA
);
432 offset
+= DDP_TAGGED_HEADER_LEN
;
434 proto_tree_add_item(rdma_header_tree
,
435 hf_iwarp_rdma_term_ddp_h
, tvb
,
436 offset
, DDP_UNTAGGED_HEADER_LEN
, ENC_NA
);
437 offset
+= DDP_UNTAGGED_HEADER_LEN
;
441 /* Terminated RDMA Header (if any) */
442 if (hdrct
& IWARP_HDRCT_R
) {
443 proto_tree_add_item(rdma_header_tree
, hf_iwarp_rdma_term_rdma_h
,
444 tvb
, offset
, RDMA_TERMINATED_RDMA_LEN
, ENC_NA
);
451 * Main dissection routine which dissects a DDP segment and interprets the
452 * header field rsvdULP according to RDMAP.
455 dissect_iwarp_ddp_rdmap(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
457 proto_tree
*ddp_rdma_tree
= NULL
;
458 proto_tree
*ddp_tree
= NULL
;
459 proto_tree
*ddp_ctrl_field_tree
= NULL
;
460 proto_tree
*ddp_buffer_model_tree
= NULL
;
461 proto_tree
*rdma_tree
= NULL
;
462 proto_tree
*rdma_ctrl_field_tree
= NULL
;
464 proto_item
*ddp_rdma_item
= NULL
;
465 proto_item
*ddp_item
= NULL
;
466 proto_item
*ddp_ctrl_field_item
= NULL
;
467 proto_item
*ddp_buffer_model_item
= NULL
;
468 proto_item
*rdma_item
= NULL
;
469 proto_item
*rdma_ctrl_field_item
= NULL
;
471 tvbuff_t
*next_tvb
= NULL
;
473 gboolean is_tagged_buffer_model
;
474 guint8 ddp_ctrl_field
, rdma_ctrl_field
, rdma_msg_opcode
;
478 ddp_ctrl_field
= tvb_get_guint8(tvb
, 0);
479 rdma_ctrl_field
= tvb_get_guint8(tvb
, 1);
480 rdma_msg_opcode
= rdma_ctrl_field
& RDMA_OPCODE
;
481 is_tagged_buffer_model
= ddp_ctrl_field
& DDP_TAGGED_FLAG
;
483 ddp_rdma_packetlist(pinfo
, ddp_ctrl_field
& DDP_LAST_FLAG
, rdma_msg_opcode
);
489 /* determine header length */
490 if (is_tagged_buffer_model
) {
491 header_end
= DDP_TAGGED_HEADER_LEN
;
493 header_end
= DDP_UNTAGGED_HEADER_LEN
;
496 if (rdma_msg_opcode
== RDMA_READ_REQUEST
497 || rdma_msg_opcode
== RDMA_TERMINATE
) {
501 /* DDP/RDMA protocol tree */
502 ddp_rdma_item
= proto_tree_add_item(tree
, proto_iwarp_ddp_rdmap
,
503 tvb
, offset
, header_end
, ENC_NA
);
504 ddp_rdma_tree
= proto_item_add_subtree(ddp_rdma_item
,
505 ett_iwarp_ddp_rdmap
);
507 /* DDP protocol header subtree */
508 ddp_item
= proto_tree_add_item(ddp_rdma_tree
, hf_iwarp_ddp
, tvb
,
509 offset
, header_end
, ENC_NA
);
510 ddp_tree
= proto_item_add_subtree(ddp_item
, ett_iwarp_ddp
);
512 /* DDP control field */
513 ddp_ctrl_field_item
= proto_tree_add_item(ddp_tree
,
514 hf_iwarp_ddp_control_field
, tvb
, offset
,
515 DDP_CONTROL_FIELD_LEN
, ENC_NA
);
516 ddp_ctrl_field_tree
= proto_item_add_subtree(ddp_ctrl_field_item
,
519 proto_tree_add_item(ddp_ctrl_field_tree
, hf_iwarp_ddp_t_flag
, tvb
,
520 offset
, DDP_CONTROL_FIELD_LEN
, ENC_BIG_ENDIAN
);
521 proto_tree_add_item(ddp_ctrl_field_tree
, hf_iwarp_ddp_l_flag
, tvb
,
522 offset
, DDP_CONTROL_FIELD_LEN
, ENC_BIG_ENDIAN
);
523 proto_tree_add_item(ddp_ctrl_field_tree
, hf_iwarp_ddp_rsvd
, tvb
,
524 offset
, DDP_CONTROL_FIELD_LEN
, ENC_BIG_ENDIAN
);
525 proto_tree_add_item(ddp_ctrl_field_tree
, hf_iwarp_ddp_dv
, tvb
, offset
,
526 DDP_CONTROL_FIELD_LEN
, ENC_BIG_ENDIAN
);
527 offset
+= DDP_CONTROL_FIELD_LEN
;
530 /* DDP header field RsvdULP */
531 if (!is_tagged_buffer_model
) {
532 proto_tree_add_item(ddp_tree
, hf_iwarp_ddp_rsvdulp
, tvb
,
533 offset
, DDP_UNTAGGED_RSVDULP_LEN
, ENC_NA
);
536 /* RDMA protocol header subtree */
537 if (is_tagged_buffer_model
) {
538 header_end
= RDMA_CONTROL_FIELD_LEN
;
540 header_end
= RDMA_CONTROL_FIELD_LEN
+ RDMA_RESERVED_FIELD_LEN
;
543 rdma_item
= proto_tree_add_item(ddp_rdma_tree
, hf_iwarp_rdma
, tvb
,
544 offset
, header_end
, ENC_NA
);
545 rdma_tree
= proto_item_add_subtree(rdma_item
, ett_iwarp_rdma
);
547 /* RDMA Control Field */
548 rdma_ctrl_field_item
= proto_tree_add_item(rdma_tree
,
549 hf_iwarp_rdma_control_field
, tvb
, offset
,
550 RDMA_CONTROL_FIELD_LEN
, ENC_NA
);
551 rdma_ctrl_field_tree
= proto_item_add_subtree(rdma_ctrl_field_item
,
554 proto_tree_add_item(rdma_ctrl_field_tree
, hf_iwarp_rdma_version
, tvb
,
555 offset
, RDMA_CONTROL_FIELD_LEN
, ENC_BIG_ENDIAN
);
556 proto_tree_add_item(rdma_ctrl_field_tree
, hf_iwarp_rdma_rsvd
, tvb
,
557 offset
, RDMA_CONTROL_FIELD_LEN
, ENC_BIG_ENDIAN
);
558 proto_tree_add_item(rdma_ctrl_field_tree
, hf_iwarp_rdma_opcode
, tvb
,
559 offset
, RDMA_CONTROL_FIELD_LEN
, ENC_BIG_ENDIAN
);
560 offset
+= RDMA_CONTROL_FIELD_LEN
;
562 /* dissection of DDP rsvdULP[8:39] with respect to RDMAP */
563 if (rdma_msg_opcode
== RDMA_READ_REQUEST
564 || rdma_msg_opcode
== RDMA_SEND
565 || rdma_msg_opcode
== RDMA_SEND_SE
566 || rdma_msg_opcode
== RDMA_TERMINATE
) {
567 proto_tree_add_item(rdma_tree
, hf_iwarp_rdma_reserved
,
568 tvb
, offset
, RDMA_RESERVED_FIELD_LEN
, ENC_NA
);
571 if (rdma_msg_opcode
== RDMA_SEND_INVALIDATE
572 || rdma_msg_opcode
== RDMA_SEND_SE_INVALIDATE
) {
573 proto_tree_add_item(rdma_tree
, hf_iwarp_rdma_inval_stag
,
574 tvb
, offset
, RDMA_INVAL_STAG_LEN
, ENC_BIG_ENDIAN
);
577 if (!is_tagged_buffer_model
) {
578 offset
+= RDMA_RESERVED_FIELD_LEN
;
581 /* DDP Buffer Model dissection */
582 if (is_tagged_buffer_model
) {
584 /* Tagged Buffer Model Case */
585 ddp_buffer_model_item
= proto_tree_add_item(ddp_tree
,
586 hf_iwarp_ddp_tagged_header
, tvb
, offset
,
587 DDP_BUFFER_MODEL_LEN
, ENC_NA
);
588 ddp_buffer_model_tree
= proto_item_add_subtree(ddp_buffer_model_item
,
591 proto_tree_add_item(ddp_buffer_model_tree
, hf_iwarp_ddp_stag
, tvb
,
592 offset
, DDP_STAG_LEN
, ENC_NA
);
593 offset
+= DDP_STAG_LEN
;
594 proto_tree_add_item(ddp_buffer_model_tree
, hf_iwarp_ddp_to
, tvb
,
595 offset
, DDP_TO_LEN
, ENC_NA
);
596 offset
+= DDP_TO_LEN
;
598 if( rdma_msg_opcode
== RDMA_READ_RESPONSE
599 || rdma_msg_opcode
== RDMA_WRITE
) {
601 /* display the payload */
602 next_tvb
= tvb_new_subset_remaining(tvb
, DDP_TAGGED_HEADER_LEN
);
603 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
608 /* Untagged Buffer Model Case */
609 ddp_buffer_model_item
= proto_tree_add_item(ddp_tree
,
610 hf_iwarp_ddp_untagged_header
, tvb
, offset
,
611 DDP_BUFFER_MODEL_LEN
, ENC_NA
);
612 ddp_buffer_model_tree
= proto_item_add_subtree(ddp_buffer_model_item
,
615 proto_tree_add_item(ddp_buffer_model_tree
, hf_iwarp_ddp_qn
, tvb
,
616 offset
, DDP_QN_LEN
, ENC_BIG_ENDIAN
);
617 offset
+= DDP_QN_LEN
;
618 proto_tree_add_item(ddp_buffer_model_tree
, hf_iwarp_ddp_msn
, tvb
,
619 offset
, DDP_MSN_LEN
, ENC_BIG_ENDIAN
);
620 offset
+= DDP_MSN_LEN
;
621 proto_tree_add_item(ddp_buffer_model_tree
, hf_iwarp_ddp_mo
, tvb
,
622 offset
, DDP_MO_LEN
, ENC_BIG_ENDIAN
);
623 offset
+= DDP_MO_LEN
;
625 if (rdma_msg_opcode
== RDMA_SEND
626 || rdma_msg_opcode
== RDMA_SEND_INVALIDATE
627 || rdma_msg_opcode
== RDMA_SEND_SE
628 || rdma_msg_opcode
== RDMA_SEND_SE_INVALIDATE
) {
630 /* display the payload */
631 next_tvb
= tvb_new_subset_remaining(tvb
, DDP_UNTAGGED_HEADER_LEN
);
632 call_dissector(data_handle
, next_tvb
, pinfo
, tree
);
637 /* do further dissection for RDMA messages RDMA Read Request & Terminate */
638 if (rdma_msg_opcode
== RDMA_READ_REQUEST
639 || rdma_msg_opcode
== RDMA_TERMINATE
) {
640 dissect_iwarp_rdmap(tvb
, rdma_tree
, offset
, rdma_msg_opcode
);
644 /* register the protocol with Wireshark */
646 proto_register_iwarp_ddp_rdmap(void)
648 /* setup list of header fields */
649 static hf_register_info hf
[] = {
653 "DDP header", "iwarp_ddp",
654 FT_NONE
, BASE_NONE
, NULL
, 0x0,
656 { &hf_iwarp_ddp_control_field
, {
657 "DDP control field", "iwarp_ddp.control_field",
658 FT_NONE
, BASE_NONE
, NULL
, 0x0,
660 { &hf_iwarp_ddp_tagged_header
, {
661 "Tagged buffer model", "iwarp_ddp.tagged",
662 FT_NONE
, BASE_NONE
, NULL
, 0x0,
663 "DDP Tagged Buffer Model Header", HFILL
} },
664 { &hf_iwarp_ddp_untagged_header
, {
665 "Untagged buffer model", "iwarp_ddp.untagged",
666 FT_NONE
, BASE_NONE
, NULL
, 0x0,
667 "DDP Untagged Buffer Model Header", HFILL
} },
668 { &hf_iwarp_ddp_t_flag
, {
669 "Tagged flag", "iwarp_ddp.tagged_flag",
670 FT_BOOLEAN
, 8, NULL
, DDP_TAGGED_FLAG
,
672 { &hf_iwarp_ddp_l_flag
, {
673 "Last flag", "iwarp_ddp.last_flag",
674 FT_BOOLEAN
, 8, NULL
, DDP_LAST_FLAG
,
676 { &hf_iwarp_ddp_rsvd
, {
677 "Reserved", "iwarp_ddp.rsvd",
678 FT_UINT8
, BASE_HEX
, NULL
, DDP_RSVD
,
680 { &hf_iwarp_ddp_dv
, {
681 "DDP protocol version", "iwarp_ddp.dv",
682 FT_UINT8
, BASE_DEC
, NULL
, DDP_DV
,
684 { &hf_iwarp_ddp_rsvdulp
, {
685 "Reserved for use by the ULP", "iwarp_ddp.rsvdulp",
686 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
688 { &hf_iwarp_ddp_stag
, {
689 "(Data Sink) Steering Tag", "iwarp_ddp.stag",
690 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
692 { &hf_iwarp_ddp_to
, {
693 "(Data Sink) Tagged offset", "iwarp_ddp.tagged_offset",
694 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
696 { &hf_iwarp_ddp_qn
, {
697 "Queue number", "iwarp_ddp.qn",
698 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
700 { &hf_iwarp_ddp_msn
, {
701 "Message sequence number", "iwarp_ddp.msn",
702 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
704 { &hf_iwarp_ddp_mo
, {
705 "Message offset", "iwarp_ddp.mo",
706 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
712 "RDMAP header", "iwarp_rdma",
713 FT_NONE
, BASE_NONE
, NULL
, 0x0,
715 { &hf_iwarp_rdma_control_field
, {
716 "RDMAP control field", "iwarp_rdma.control_field",
717 FT_NONE
, BASE_NONE
, NULL
, 0x0,
718 "RDMA Control Field", HFILL
} },
719 { &hf_iwarp_rdma_version
, {
720 "Version", "iwarp_rdma.version",
721 FT_UINT8
, BASE_DEC
, NULL
, RDMA_RV
,
722 "RDMA Version Field", HFILL
} },
723 { &hf_iwarp_rdma_rsvd
, {
724 "Reserved", "iwarp_rdma.rsv",
725 FT_UINT8
, BASE_HEX
, NULL
, RDMA_RSV
,
726 "RDMA Control Field Reserved", HFILL
} },
727 { &hf_iwarp_rdma_opcode
, {
728 "OpCode", "iwarp_rdma.opcode",
729 FT_UINT8
, BASE_HEX
, VALS(rdmap_messages
), RDMA_OPCODE
,
730 "RDMA OpCode Field", HFILL
} },
731 { &hf_iwarp_rdma_reserved
, {
732 "Reserved", "iwarp_rdma.reserved",
733 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
735 { &hf_iwarp_rdma_inval_stag
, {
736 "Invalidate STag", "iwarp_rdma.inval_stag",
737 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
738 "RDMA Invalidate STag", HFILL
} },
739 { &hf_iwarp_rdma_rr_header
, {
740 "Read request", "iwarp_rdma.rr",
741 FT_NONE
, BASE_NONE
, NULL
, 0x0,
742 "RDMA Read Request Header", HFILL
} },
743 { &hf_iwarp_rdma_terminate_header
, {
744 "Terminate", "iwarp_rdma.terminate",
745 FT_NONE
, BASE_NONE
, NULL
, 0x0,
746 "RDMA Terminate Header", HFILL
} },
747 { &hf_iwarp_rdma_sinkstag
, {
748 "Data Sink STag", "iwarp_rdma.sinkstag",
749 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
751 { &hf_iwarp_rdma_sinkto
, {
752 "Data Sink Tagged Offset", "iwarp_rdma.sinkto",
753 FT_UINT64
, BASE_DEC
, NULL
, 0x0,
755 { &hf_iwarp_rdma_rdmardsz
, {
756 "RDMA Read Message Size", "iwarp_rdma.rdmardsz",
757 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
759 { &hf_iwarp_rdma_srcstag
, {
760 "Data Source STag", "iwarp_rdma.srcstag",
761 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
763 { &hf_iwarp_rdma_srcto
, {
764 "Data Source Tagged Offset", "iwarp_rdma.srcto",
765 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
767 { &hf_iwarp_rdma_term_ctrl
, {
768 "Terminate Control", "iwarp_rdma.term_ctrl",
769 FT_NONE
, BASE_NONE
, NULL
, 0x0,
770 "RDMA Terminate Control Field", HFILL
} },
771 { &hf_iwarp_rdma_term_layer
, {
772 "Layer", "iwarp_rdma.term_layer",
773 FT_UINT8
, BASE_HEX
, VALS(layer_names
), IWARP_LAYER
,
774 "Terminate Control Field: Layer", HFILL
} },
775 { &hf_iwarp_rdma_term_etype_rdma
, {
776 "Error Types for RDMA layer", "iwarp_rdma.term_etype_rdma",
777 FT_UINT8
, BASE_HEX
, VALS(rdma_etype_names
), IWARP_ETYPE
,
778 "Terminate Control Field: Error Type", HFILL
} },
779 { &hf_iwarp_rdma_term_etype_ddp
, {
780 "Error Types for DDP layer", "iwarp_rdma.term_etype_ddp",
781 FT_UINT8
, BASE_HEX
, VALS(ddp_etype_names
), IWARP_ETYPE
,
782 "Terminate Control Field: Error Type", HFILL
} },
783 { &hf_iwarp_rdma_term_etype_llp
, {
784 "Error Types for LLP layer", "iwarp_rdma.term_etype_llp",
785 FT_UINT8
, BASE_HEX
, NULL
, IWARP_ETYPE
,
786 "Terminate Control Field: Error Type", HFILL
} },
787 { &hf_iwarp_rdma_term_etype
, {
788 "Error Types", "iwarp_rdma.term_etype",
789 FT_UINT8
, BASE_HEX
, NULL
, IWARP_ETYPE
,
790 "Terminate Control Field: Error Type", HFILL
} },
791 { &hf_iwarp_rdma_term_errcode_rdma
, {
792 "Error Code for RDMA layer", "iwarp_rdma.term_errcode_rdma",
793 FT_UINT8
, BASE_HEX
, VALS(rdma_errcode_names
), 0x0,
794 "Terminate Control Field: Error Code", HFILL
} },
795 { &hf_iwarp_rdma_term_errcode_ddp_tagged
, {
796 "Error Code for DDP Tagged Buffer",
797 "iwarp_rdma.term_errcode_ddp_tagged",
798 FT_UINT8
, BASE_HEX
, VALS(ddp_errcode_tagged_names
), 0x0,
799 "Terminate Control Field: Error Code", HFILL
} },
800 { &hf_iwarp_rdma_term_errcode_ddp_untagged
, {
801 "Error Code for DDP Untagged Buffer",
802 "iwarp_rdma.term_errcode_ddp_untagged",
803 FT_UINT8
, BASE_HEX
, VALS(ddp_errcode_untagged_names
), 0x0,
804 "Terminate Control Field: Error Code", HFILL
} },
805 { &hf_iwarp_rdma_term_errcode
, {
806 "Error Code", "iwarp_rdma.term_errcode",
807 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
808 "Terminate Control Field: Error Code", HFILL
} },
809 { &hf_iwarp_rdma_term_errcode_llp
, {
810 "Error Code for LLP layer", "iwarp_rdma.term_errcode_llp",
811 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
812 "Terminate Control Field: Lower Layer Protocol Error Code",
814 { &hf_iwarp_rdma_term_hdrct
, {
815 "Header control bits", "iwarp_rdma.term_hdrct",
816 FT_NONE
, BASE_NONE
, NULL
, 0x0,
817 "Terminate Control Field: Header control bits", HFILL
} },
818 { &hf_iwarp_rdma_term_hdrct_m
, {
819 "M bit", "iwarp_rdma.term_hdrct_m",
820 FT_UINT8
, BASE_HEX
, NULL
, IWARP_HDRCT_M
,
821 "Header control bit m: DDP Segment Length valid", HFILL
} },
822 { &hf_iwarp_rdma_term_hdrct_d
, {
823 "D bit", "iwarp_rdma.hdrct_d",
824 FT_UINT8
, BASE_HEX
, NULL
, IWARP_HDRCT_D
,
825 "Header control bit d: DDP Header Included", HFILL
} },
826 { &hf_iwarp_rdma_term_hdrct_r
, {
827 "R bit", "iwarp_rdma.hdrct_r",
828 FT_UINT8
, BASE_HEX
, NULL
, IWARP_HDRCT_R
,
829 "Header control bit r: RDMAP Header Included", HFILL
} },
830 { &hf_iwarp_rdma_term_rsvd
, {
831 "Reserved", "iwarp_rdma.term_rsvd",
832 FT_UINT16
, BASE_HEX
, NULL
, IWARP_TERM_RES
,
834 { &hf_iwarp_rdma_term_ddp_seg_len
, {
835 "DDP Segment Length", "iwarp_rdma.term_ddp_seg_len",
836 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
838 { &hf_iwarp_rdma_term_ddp_h
, {
839 "Terminated DDP Header", "iwarp_rdma.term_ddp_h",
840 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
842 { &hf_iwarp_rdma_term_rdma_h
, {
843 "Terminated RDMA Header", "iwarp_rdma.term_rdma_h",
844 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
848 /* setup protocol subtree array */
849 static gint
*ett
[] = {
851 &ett_iwarp_ddp_rdmap
,
856 &ett_iwarp_ddp_control_field
,
857 &ett_iwarp_ddp_tagged_header
,
858 &ett_iwarp_ddp_untagged_header
,
863 &ett_iwarp_rdma_control_field
,
864 &ett_iwarp_rdma_rr_header
,
865 &ett_iwarp_rdma_terminate_header
,
866 &ett_iwarp_rdma_term_ctrl
,
867 &ett_iwarp_rdma_term_hdrct
870 /* register the protocol name and description */
871 proto_iwarp_ddp_rdmap
= proto_register_protocol(
872 "iWARP Direct Data Placement and Remote Direct Memory Access Protocol",
876 /* required function calls to register the header fields and subtrees */
877 proto_register_field_array(proto_iwarp_ddp_rdmap
, hf
, array_length(hf
));
878 proto_register_subtree_array(ett
, array_length(ett
));
880 register_dissector("iwarp_ddp_rdmap", dissect_iwarp_ddp_rdmap
,
881 proto_iwarp_ddp_rdmap
);
885 proto_reg_handoff_iwarp_ddp_rdmap(void)
887 data_handle
= find_dissector("data");