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.
38 #include <epan/packet.h>
42 /* header field byte lengths */
43 #define DDP_CONTROL_FIELD_LEN 1
44 #define DDP_TAGGED_HEADER_LEN 14
45 #define DDP_TAGGED_RSVDULP_LEN 4
46 #define DDP_STAG_LEN 4
48 #define DDP_UNTAGGED_HEADER_LEN 18
49 #define DDP_UNTAGGED_RSVDULP_LEN 5
53 #define DDP_BUFFER_MODEL_LEN 12
55 #define RDMA_CONTROL_FIELD_LEN 1
56 #define RDMA_RESERVED_FIELD_LEN 4
57 #define RDMA_INVAL_STAG_LEN 4
58 #define RDMA_SINKSTAG_LEN 4
59 #define RDMA_SINKTO_LEN 8
60 #define RDMA_RDMARDSZ_LEN 4
61 #define RDMA_SRCSTAG_LEN 4
62 #define RDMA_SRCTO_LEN 8
63 #define RDMA_DDP_SEGLEN_LEN 2
64 #define RDMA_TERMINATED_RDMA_LEN 28
67 #define RDMA_WRITE 0x00
68 #define RDMA_READ_REQUEST 0x01
69 #define RDMA_READ_RESPONSE 0x02
70 #define RDMA_SEND 0x03
71 #define RDMA_SEND_INVALIDATE 0x04
72 #define RDMA_SEND_SE 0x05
73 #define RDMA_SEND_SE_INVALIDATE 0x06
74 #define RDMA_TERMINATE 0x07
77 #define DDP_TAGGED_FLAG 0x80
78 #define DDP_LAST_FLAG 0x40
83 #define RDMA_OPCODE 0x0F
85 #define IWARP_LAYER 0xF0
86 #define IWARP_ETYPE 0x0F
87 #define IWARP_HDRCT 0xE0
88 #define IWARP_HDRCT_M 0x80
89 #define IWARP_HDRCT_D 0x40
90 #define IWARP_HDRCT_R 0x20
91 #define IWARP_TERM_RES 0x1FFF
93 #define IWARP_LAYER_RDMA 0x00
94 #define IWARP_LAYER_DDP 0x10
95 #define IWARP_LAYER_LLP 0x20
96 #define IWARP_ETYPE_DDP_TAGGED 0x01
97 #define IWARP_ETYPE_DDP_UNTAGGED 0x02
100 static gint proto_iwarp_ddp_rdmap = -1;
101 static gint ett_iwarp_ddp_rdmap = -1;
103 static dissector_handle_t data_handle;
106 * DDP: initialize the protocol and registered fields
108 static gint hf_iwarp_ddp = -1;
110 /* DDP Control Field */
111 static gint hf_iwarp_ddp_control_field = -1;
112 static gint hf_iwarp_ddp_t_flag = -1;
113 static gint hf_iwarp_ddp_l_flag = -1;
114 static gint hf_iwarp_ddp_rsvd = -1;
115 static gint hf_iwarp_ddp_dv = -1;
117 /* DDP rsvdULP[8:39] field */
118 static gint hf_iwarp_ddp_rsvdulp = -1;
120 /* Tagged Buffer Model Header */
121 static gint hf_iwarp_ddp_tagged_header = -1;
122 static gint hf_iwarp_ddp_stag = -1;
123 static gint hf_iwarp_ddp_to = -1;
125 /* Untagged Buffer Model Header */
126 static gint hf_iwarp_ddp_untagged_header = -1;
127 static gint hf_iwarp_ddp_qn= -1;
128 static gint hf_iwarp_ddp_msn = -1;
129 static gint hf_iwarp_ddp_mo = -1;
131 /* initialize the subtree pointers */
132 static gint ett_iwarp_ddp = -1;
134 static gint ett_iwarp_ddp_control_field = -1;
135 static gint ett_iwarp_ddp_tagged_header = -1;
136 static gint ett_iwarp_ddp_untagged_header = -1;
139 * RDMAP: initialize the protocol and registered fields
141 static gint hf_iwarp_rdma = -1;
144 static gint hf_iwarp_rdma_control_field = -1;
145 static gint hf_iwarp_rdma_version = -1;
146 static gint hf_iwarp_rdma_rsvd = -1;
147 static gint hf_iwarp_rdma_opcode = -1;
149 /* DDP rsvdULP[8:39] RDMA interpretations */
150 static gint hf_iwarp_rdma_reserved = -1;
151 static gint hf_iwarp_rdma_inval_stag = -1;
153 /* Read Request Header */
154 static gint hf_iwarp_rdma_rr_header = -1;
155 static gint hf_iwarp_rdma_sinkstag = -1;
156 static gint hf_iwarp_rdma_sinkto = -1;
157 static gint hf_iwarp_rdma_rdmardsz = -1;
158 static gint hf_iwarp_rdma_srcstag = -1;
159 static gint hf_iwarp_rdma_srcto = -1;
161 /* Terminate Header */
162 static gint hf_iwarp_rdma_terminate_header = -1;
163 static gint hf_iwarp_rdma_term_ctrl = -1;
164 static gint hf_iwarp_rdma_term_layer = -1;
165 static gint hf_iwarp_rdma_term_etype = -1;
166 static gint hf_iwarp_rdma_term_etype_rdma = -1;
167 static gint hf_iwarp_rdma_term_etype_ddp = -1;
168 static gint hf_iwarp_rdma_term_etype_llp = -1;
169 static gint hf_iwarp_rdma_term_errcode = -1;
170 static gint hf_iwarp_rdma_term_errcode_rdma = -1;
171 static gint hf_iwarp_rdma_term_errcode_ddp_untagged = -1;
172 static gint hf_iwarp_rdma_term_errcode_ddp_tagged = -1;
173 static gint hf_iwarp_rdma_term_errcode_llp = -1;
174 static gint hf_iwarp_rdma_term_hdrct = -1;
175 static gint hf_iwarp_rdma_term_hdrct_m = -1;
176 static gint hf_iwarp_rdma_term_hdrct_d = -1;
177 static gint hf_iwarp_rdma_term_hdrct_r = -1;
178 static gint hf_iwarp_rdma_term_rsvd = -1;
179 static gint hf_iwarp_rdma_term_ddp_seg_len = -1;
180 static gint hf_iwarp_rdma_term_ddp_h = -1;
181 static gint hf_iwarp_rdma_term_rdma_h = -1;
183 /* initialize the subtree pointers */
184 static gint ett_iwarp_rdma = -1;
186 static gint ett_iwarp_rdma_control_field = -1;
187 static gint ett_iwarp_rdma_rr_header = -1;
188 static gint ett_iwarp_rdma_terminate_header = -1;
189 static gint ett_iwarp_rdma_term_ctrl = -1;
190 static gint ett_iwarp_rdma_term_hdrct = -1;
192 static const value_string rdmap_messages[] = {
193 { RDMA_WRITE, "Write" },
194 { RDMA_READ_REQUEST, "Read Request" },
195 { RDMA_READ_RESPONSE, "Read Response" },
196 { RDMA_SEND, "Send" },
197 { RDMA_SEND_INVALIDATE, "Send with Invalidate" },
198 { RDMA_SEND_SE, "Send with SE" },
199 { RDMA_SEND_SE_INVALIDATE, "Send with SE and Invalidate" },
200 { RDMA_TERMINATE, "Terminate" },
204 static const value_string layer_names[] = {
205 { IWARP_LAYER_RDMA, "RDMA" },
206 { IWARP_LAYER_DDP, "DDP" },
207 { IWARP_LAYER_LLP, "LLP" },
212 static const value_string rdma_etype_names[] = {
213 { 0x00, "Local Catastrophic Error" },
214 { 0x01, "Remote Protection Error" },
215 { 0x02, "Remote Operation Error" },
219 static const value_string rdma_errcode_names[] = {
220 { 0x00, "Invalid STag" },
221 { 0x01, "Base or bounds violation" },
222 { 0x02, "Access rights violation" },
223 { 0x03, "STag not associated with RDMAP Stream" },
225 { 0x05, "Invalid RDMAP version" },
226 { 0x06, "Unexpected OpCode" },
227 { 0x07, "Catastrophic error, localized to RDMAP Stream" },
228 { 0x08, "Catastrophic error, global" },
229 { 0x09, "STag cannot be Invalidated" },
230 { 0xFF, "Unspecific Error" },
234 static const value_string ddp_etype_names[] = {
235 { 0x00, "Local Catastrophic Error" },
236 { 0x01, "Tagged Buffer Error" },
237 { 0x02, "Untagged Buffer Error" },
238 { 0x03, "Reserved for the use by the LLP" },
242 static const value_string ddp_errcode_tagged_names[] = {
243 { 0x00, "Invalid STag" },
244 { 0x01, "Base or bounds violation" },
245 { 0x02, "STag not associated with DDP Stream" },
247 { 0x04, "Invalid DDP version" },
251 static const value_string ddp_errcode_untagged_names[] = {
252 { 0x01, "Invalid QN" },
253 { 0x02, "Invalid MSN - no buffer available" },
254 { 0x03, "Invalid MSN - MSN range is not valid" },
255 { 0x04, "Invalid MO" },
256 { 0x05, "DDP Message too long for available buffer" },
257 { 0x06, "Invalid DDP version" },
261 /* update packet list pane in the GUI */
263 ddp_rdma_packetlist(packet_info *pinfo, gboolean ddp_last_flag,
264 guint8 rdma_msg_opcode)
266 const gchar *ddp_fragment_state;
268 if (check_col(pinfo->cinfo, COL_PROTOCOL)) {
269 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP/RDMA");
273 ddp_fragment_state = "[last DDP segment]";
275 ddp_fragment_state = "[more DDP segments]";
278 if (check_col(pinfo->cinfo, COL_INFO)) {
279 col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d %s %s", pinfo->srcport,
280 pinfo->destport, val_to_str(rdma_msg_opcode, rdmap_messages,
281 "Unknown %d"), ddp_fragment_state);
285 /* dissects RDMA Read Request and Terminate message header */
287 dissect_iwarp_rdmap(tvbuff_t *tvb, proto_tree *rdma_tree, guint32 offset,
288 guint8 rdma_msg_opcode)
290 proto_tree *rdma_header_tree = NULL;
291 proto_tree *term_ctrl_field_tree = NULL;
292 proto_tree *header_ctrl_field_tree = NULL;
294 proto_item *rdma_header_subitem = NULL;
295 proto_item *term_ctrl_field_subitem = NULL;
296 proto_item *header_ctrl_field_subitem = NULL;
298 guint8 layer, etype, hdrct;
304 if (rdma_msg_opcode == RDMA_READ_REQUEST) {
305 rdma_header_subitem = proto_tree_add_item(rdma_tree,
306 hf_iwarp_rdma_rr_header, tvb, offset, -1, FALSE);
307 rdma_header_tree = proto_item_add_subtree(rdma_header_subitem,
310 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_sinkstag, tvb,
311 offset, RDMA_SINKSTAG_LEN, FALSE);
312 offset += RDMA_SINKSTAG_LEN;
313 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_sinkto, tvb,
314 offset, RDMA_SINKTO_LEN, FALSE);
315 offset += RDMA_SINKTO_LEN;
317 rdmardsz = (guint32) tvb_get_ntohl(tvb, offset);
318 proto_tree_add_uint_format_value(rdma_header_tree,
319 hf_iwarp_rdma_rdmardsz, tvb, offset,
320 RDMA_RDMARDSZ_LEN, rdmardsz, "%u bytes",
323 offset += RDMA_RDMARDSZ_LEN;
324 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_srcstag, tvb,
325 offset, RDMA_SRCSTAG_LEN, FALSE);
326 offset += RDMA_SRCSTAG_LEN;
327 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_srcto, tvb,
328 offset, RDMA_SRCTO_LEN, FALSE);
329 offset += RDMA_SRCTO_LEN;
332 if (rdma_msg_opcode == RDMA_TERMINATE) {
333 rdma_header_subitem = proto_tree_add_item(rdma_tree,
334 hf_iwarp_rdma_terminate_header, tvb, offset, -1, FALSE);
335 rdma_header_tree = proto_item_add_subtree(rdma_header_subitem,
338 /* Terminate Control Field */
339 layer = tvb_get_guint8(tvb, offset) & IWARP_LAYER;
340 etype = tvb_get_guint8(tvb, offset) & IWARP_ETYPE;
342 term_ctrl_field_subitem = proto_tree_add_item(rdma_tree,
343 hf_iwarp_rdma_term_ctrl, tvb, offset, 3, FALSE);
344 term_ctrl_field_tree = proto_item_add_subtree(
345 term_ctrl_field_subitem, ett_iwarp_rdma);
346 proto_tree_add_item(term_ctrl_field_tree, hf_iwarp_rdma_term_layer,
347 tvb, offset, 1, FALSE);
350 case IWARP_LAYER_RDMA:
351 proto_tree_add_item(term_ctrl_field_tree,
352 hf_iwarp_rdma_term_etype_rdma, tvb, offset, 1,
355 proto_tree_add_item(term_ctrl_field_tree,
356 hf_iwarp_rdma_term_errcode_rdma, tvb, offset, 1,
360 case IWARP_LAYER_DDP:
361 proto_tree_add_item(term_ctrl_field_tree,
362 hf_iwarp_rdma_term_etype_ddp, tvb, offset, 1,
366 case IWARP_ETYPE_DDP_TAGGED:
367 proto_tree_add_item(term_ctrl_field_tree,
368 hf_iwarp_rdma_term_errcode_ddp_tagged, tvb,
372 case IWARP_ETYPE_DDP_UNTAGGED:
373 proto_tree_add_item(term_ctrl_field_tree,
374 hf_iwarp_rdma_term_errcode_ddp_untagged, tvb,
379 proto_tree_add_item(term_ctrl_field_tree,
380 hf_iwarp_rdma_term_errcode, tvb, offset, 1,
386 case IWARP_LAYER_LLP:
387 proto_tree_add_item(term_ctrl_field_tree,
388 hf_iwarp_rdma_term_etype_llp, tvb, offset, 1,
391 proto_tree_add_item(term_ctrl_field_tree,
392 hf_iwarp_rdma_term_errcode_llp, tvb, offset, 1,
397 proto_tree_add_item(term_ctrl_field_tree,
398 hf_iwarp_rdma_term_etype, tvb, offset, 1, FALSE);
400 proto_tree_add_item(term_ctrl_field_tree,
401 hf_iwarp_rdma_term_errcode, tvb, offset, 1, FALSE);
406 /* header control bits (hdctr), part of Terminate Control Field */
407 header_ctrl_field_subitem = proto_tree_add_item(
408 term_ctrl_field_tree, hf_iwarp_rdma_term_hdrct, tvb,
410 header_ctrl_field_tree = proto_item_add_subtree(
411 header_ctrl_field_subitem, ett_iwarp_rdma);
413 hdrct = tvb_get_guint8(tvb, offset) & IWARP_HDRCT;
415 proto_tree_add_item(header_ctrl_field_tree,
416 hf_iwarp_rdma_term_hdrct_m, tvb, offset, 1, FALSE);
417 proto_tree_add_item(header_ctrl_field_tree,
418 hf_iwarp_rdma_term_hdrct_d, tvb, offset, 1, FALSE);
419 proto_tree_add_item(header_ctrl_field_tree,
420 hf_iwarp_rdma_term_hdrct_r, tvb, offset, 1, FALSE);
422 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_term_rsvd, tvb,
427 if (hdrct & IWARP_HDRCT_D) {
428 /* DDP Segment Length (if any) */
429 proto_tree_add_item(rdma_header_tree,
430 hf_iwarp_rdma_term_ddp_seg_len, tvb,
431 offset, RDMA_DDP_SEGLEN_LEN, FALSE);
432 offset += RDMA_DDP_SEGLEN_LEN;
434 /* Terminated DDP Header (if any), tagged or untagged */
435 if (etype == IWARP_ETYPE_DDP_TAGGED) {
436 proto_tree_add_item(rdma_header_tree,
437 hf_iwarp_rdma_term_ddp_h, tvb,
438 offset, DDP_TAGGED_HEADER_LEN, FALSE);
439 offset += DDP_TAGGED_HEADER_LEN;
441 proto_tree_add_item(rdma_header_tree,
442 hf_iwarp_rdma_term_ddp_h, tvb,
443 offset, DDP_UNTAGGED_HEADER_LEN, FALSE);
444 offset += DDP_UNTAGGED_HEADER_LEN;
448 /* Terminated RDMA Header (if any) */
449 if (hdrct & IWARP_HDRCT_R) {
450 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_term_rdma_h,
451 tvb, offset, RDMA_TERMINATED_RDMA_LEN, FALSE);
458 * Main dissection routine which dissects a DDP segment and interprets the
459 * header field rsvdULP according to RDMAP.
462 dissect_iwarp_ddp_rdmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
464 proto_tree *ddp_rdma_tree = NULL;
465 proto_tree *ddp_tree = NULL;
466 proto_tree *ddp_ctrl_field_tree = NULL;
467 proto_tree *ddp_buffer_model_tree = NULL;
468 proto_tree *rdma_tree = NULL;
469 proto_tree *rdma_ctrl_field_tree = NULL;
471 proto_item *ddp_rdma_item = NULL;
472 proto_item *ddp_item = NULL;
473 proto_item *ddp_ctrl_field_item = NULL;
474 proto_item *ddp_buffer_model_item = NULL;
475 proto_item *rdma_item = NULL;
476 proto_item *rdma_ctrl_field_item = NULL;
478 tvbuff_t *next_tvb = NULL;
480 gboolean is_tagged_buffer_model;
481 guint8 ddp_ctrl_field, rdma_ctrl_field, rdma_msg_opcode;
485 ddp_ctrl_field = tvb_get_guint8(tvb, 0);
486 rdma_ctrl_field = tvb_get_guint8(tvb, 1);
487 rdma_msg_opcode = rdma_ctrl_field & RDMA_OPCODE;
488 is_tagged_buffer_model = ddp_ctrl_field & DDP_TAGGED_FLAG;
490 ddp_rdma_packetlist(pinfo, ddp_ctrl_field & DDP_LAST_FLAG, rdma_msg_opcode);
496 /* determine header length */
497 if (is_tagged_buffer_model) {
498 header_end = DDP_TAGGED_HEADER_LEN;
500 header_end = DDP_UNTAGGED_HEADER_LEN;
503 if (rdma_msg_opcode == RDMA_READ_REQUEST
504 || rdma_msg_opcode == RDMA_TERMINATE) {
508 /* DDP/RDMA protocol tree */
509 ddp_rdma_item = proto_tree_add_item(tree, proto_iwarp_ddp_rdmap,
510 tvb, offset, header_end, FALSE);
511 ddp_rdma_tree = proto_item_add_subtree(ddp_rdma_item,
512 ett_iwarp_ddp_rdmap);
514 /* DDP protocol header subtree */
515 ddp_item = proto_tree_add_item(ddp_rdma_tree, hf_iwarp_ddp, tvb,
516 offset, header_end, FALSE);
517 ddp_tree = proto_item_add_subtree(ddp_item, ett_iwarp_ddp);
519 /* DDP control field */
520 ddp_ctrl_field_item = proto_tree_add_item(ddp_tree,
521 hf_iwarp_ddp_control_field, tvb, offset,
522 DDP_CONTROL_FIELD_LEN, FALSE);
523 ddp_ctrl_field_tree = proto_item_add_subtree(ddp_ctrl_field_item,
526 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_t_flag, tvb,
527 offset, DDP_CONTROL_FIELD_LEN, FALSE);
528 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_l_flag, tvb,
529 offset, DDP_CONTROL_FIELD_LEN, FALSE);
530 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_rsvd, tvb,
531 offset, DDP_CONTROL_FIELD_LEN, FALSE);
532 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_dv, tvb, offset,
533 DDP_CONTROL_FIELD_LEN, FALSE);
534 offset += DDP_CONTROL_FIELD_LEN;
537 /* DDP header field RsvdULP */
538 if (!is_tagged_buffer_model) {
539 proto_tree_add_item(ddp_tree, hf_iwarp_ddp_rsvdulp, tvb,
540 offset, DDP_UNTAGGED_RSVDULP_LEN, FALSE);
543 /* RDMA protocol header subtree */
544 if (is_tagged_buffer_model) {
545 header_end = RDMA_CONTROL_FIELD_LEN;
547 header_end = RDMA_CONTROL_FIELD_LEN + RDMA_RESERVED_FIELD_LEN;
550 rdma_item = proto_tree_add_item(ddp_rdma_tree, hf_iwarp_rdma, tvb,
551 offset, header_end, FALSE);
552 rdma_tree = proto_item_add_subtree(rdma_item, ett_iwarp_rdma);
554 /* RDMA Control Field */
555 rdma_ctrl_field_item = proto_tree_add_item(rdma_tree,
556 hf_iwarp_rdma_control_field, tvb, offset,
557 RDMA_CONTROL_FIELD_LEN, FALSE);
558 rdma_ctrl_field_tree = proto_item_add_subtree(rdma_ctrl_field_item,
561 proto_tree_add_item(rdma_ctrl_field_tree, hf_iwarp_rdma_version, tvb,
562 offset, RDMA_CONTROL_FIELD_LEN, FALSE);
563 proto_tree_add_item(rdma_ctrl_field_tree, hf_iwarp_rdma_rsvd, tvb,
564 offset, RDMA_CONTROL_FIELD_LEN, FALSE);
565 proto_tree_add_item(rdma_ctrl_field_tree, hf_iwarp_rdma_opcode, tvb,
566 offset, RDMA_CONTROL_FIELD_LEN, FALSE);
567 offset += RDMA_CONTROL_FIELD_LEN;
569 /* dissection of DDP rsvdULP[8:39] with respect to RDMAP */
570 if (rdma_msg_opcode == RDMA_READ_REQUEST
571 || rdma_msg_opcode == RDMA_SEND
572 || rdma_msg_opcode == RDMA_SEND_SE
573 || rdma_msg_opcode == RDMA_TERMINATE) {
574 proto_tree_add_item(rdma_tree, hf_iwarp_rdma_reserved,
575 tvb, offset, RDMA_RESERVED_FIELD_LEN, FALSE);
578 if (rdma_msg_opcode == RDMA_SEND_INVALIDATE
579 || rdma_msg_opcode == RDMA_SEND_SE_INVALIDATE) {
580 proto_tree_add_item(rdma_tree, hf_iwarp_rdma_inval_stag,
581 tvb, offset, RDMA_INVAL_STAG_LEN, FALSE);
584 if (!is_tagged_buffer_model) {
585 offset += RDMA_RESERVED_FIELD_LEN;
588 /* DDP Buffer Model dissection */
589 if (is_tagged_buffer_model) {
591 /* Tagged Buffer Model Case */
592 ddp_buffer_model_item = proto_tree_add_item(ddp_tree,
593 hf_iwarp_ddp_tagged_header, tvb, offset,
594 DDP_BUFFER_MODEL_LEN, FALSE);
595 ddp_buffer_model_tree = proto_item_add_subtree(ddp_buffer_model_item,
598 proto_tree_add_item(ddp_buffer_model_tree, hf_iwarp_ddp_stag, tvb,
599 offset, DDP_STAG_LEN, FALSE);
600 offset += DDP_STAG_LEN;
601 proto_tree_add_item(ddp_buffer_model_tree, hf_iwarp_ddp_to, tvb,
602 offset, DDP_TO_LEN, FALSE);
603 offset += DDP_TO_LEN;
605 if( rdma_msg_opcode == RDMA_READ_RESPONSE
606 || rdma_msg_opcode == RDMA_WRITE) {
608 /* display the payload */
609 next_tvb = tvb_new_subset(tvb, DDP_TAGGED_HEADER_LEN, -1, -1);
610 call_dissector(data_handle, next_tvb, pinfo, tree);
615 /* Untagged Buffer Model Case */
616 ddp_buffer_model_item = proto_tree_add_item(ddp_tree,
617 hf_iwarp_ddp_untagged_header, tvb, offset,
618 DDP_BUFFER_MODEL_LEN, FALSE);
619 ddp_buffer_model_tree = proto_item_add_subtree(ddp_buffer_model_item,
622 proto_tree_add_item(ddp_buffer_model_tree, hf_iwarp_ddp_qn, tvb,
623 offset, DDP_QN_LEN, FALSE);
624 offset += DDP_QN_LEN;
625 proto_tree_add_item(ddp_buffer_model_tree, hf_iwarp_ddp_msn, tvb,
626 offset, DDP_MSN_LEN, FALSE);
627 offset += DDP_MSN_LEN;
628 proto_tree_add_item(ddp_buffer_model_tree, hf_iwarp_ddp_mo, tvb,
629 offset, DDP_MO_LEN, FALSE);
630 offset += DDP_MO_LEN;
632 if (rdma_msg_opcode == RDMA_SEND
633 || rdma_msg_opcode == RDMA_SEND_INVALIDATE
634 || rdma_msg_opcode == RDMA_SEND_SE
635 || rdma_msg_opcode == RDMA_SEND_SE_INVALIDATE) {
637 /* display the payload */
638 next_tvb = tvb_new_subset(tvb, DDP_UNTAGGED_HEADER_LEN, -1, -1);
639 call_dissector(data_handle, next_tvb, pinfo, tree);
644 /* do further dissection for RDMA messages RDMA Read Request & Terminate */
645 if (rdma_msg_opcode == RDMA_READ_REQUEST
646 || rdma_msg_opcode == RDMA_TERMINATE) {
647 dissect_iwarp_rdmap(tvb, rdma_tree, offset, rdma_msg_opcode);
651 /* register the protocol with Wireshark */
653 proto_register_iwarp_ddp_rdmap(void)
655 /* setup list of header fields */
656 static hf_register_info hf[] = {
660 "DDP header", "iwarp_ddp",
661 FT_NONE, BASE_NONE, NULL, 0x0,
663 { &hf_iwarp_ddp_control_field, {
664 "DDP control field", "iwarp_ddp.control_field",
665 FT_NONE, BASE_NONE, NULL, 0x0,
666 "DDP Control Field", HFILL } },
667 { &hf_iwarp_ddp_tagged_header, {
668 "Tagged buffer model", "iwarp_ddp.tagged",
669 FT_NONE, BASE_NONE, NULL, 0x0,
670 "DDP Tagged Buffer Model Header", HFILL} },
671 { &hf_iwarp_ddp_untagged_header, {
672 "Untagged buffer model", "iwarp_ddp.untagged",
673 FT_NONE, BASE_NONE, NULL, 0x0,
674 "DDP Untagged Buffer Model Header", HFILL} },
675 { &hf_iwarp_ddp_t_flag, {
676 "Tagged flag", "iwarp_ddp.tagged_flag",
677 FT_BOOLEAN, 8, NULL, DDP_TAGGED_FLAG,
679 { &hf_iwarp_ddp_l_flag, {
680 "Last flag", "iwarp_ddp.last_flag",
681 FT_BOOLEAN, 8, NULL, DDP_LAST_FLAG,
683 { &hf_iwarp_ddp_rsvd, {
684 "Reserved", "iwarp_ddp.rsvd",
685 FT_UINT8, BASE_HEX, NULL, DDP_RSVD,
687 { &hf_iwarp_ddp_dv, {
688 "DDP protocol version", "iwarp_ddp.dv",
689 FT_UINT8, BASE_DEC, NULL, DDP_DV,
691 { &hf_iwarp_ddp_rsvdulp, {
692 "Reserved for use by the ULP", "iwarp_ddp.rsvdulp",
693 FT_BYTES, BASE_NONE, NULL, 0x0,
695 { &hf_iwarp_ddp_stag, {
696 "(Data Sink) Steering Tag", "iwarp_ddp.stag",
697 FT_BYTES, BASE_NONE, NULL, 0x0,
699 { &hf_iwarp_ddp_to, {
700 "(Data Sink) Tagged offset", "iwarp_ddp.tagged_offset",
701 FT_BYTES, BASE_NONE, NULL, 0x0,
703 { &hf_iwarp_ddp_qn, {
704 "Queue number", "iwarp_ddp.qn",
705 FT_UINT32, BASE_DEC, NULL, 0x0,
707 { &hf_iwarp_ddp_msn, {
708 "Message sequence number", "iwarp_ddp.msn",
709 FT_UINT32, BASE_DEC, NULL, 0x0,
711 { &hf_iwarp_ddp_mo, {
712 "Message offset", "iwarp_ddp.mo",
713 FT_UINT32, BASE_DEC, NULL, 0x0,
719 "RDMAP header", "iwarp_rdma",
720 FT_NONE, BASE_NONE, NULL, 0x0,
722 { &hf_iwarp_rdma_control_field, {
723 "RDMAP control field", "iwarp_rdma.control_field",
724 FT_NONE, BASE_NONE, NULL, 0x0,
725 "RDMA Control Field", HFILL} },
726 { &hf_iwarp_rdma_version, {
727 "Version", "iwarp_rdma.version",
728 FT_UINT8, BASE_DEC, NULL, RDMA_RV,
729 "RDMA Version Field", HFILL} },
730 { &hf_iwarp_rdma_rsvd, {
731 "Reserved", "iwarp_rdma.rsv",
732 FT_UINT8, BASE_HEX, NULL, RDMA_RSV,
733 "RDMA Control Field Reserved", HFILL} },
734 { &hf_iwarp_rdma_opcode, {
735 "OpCode", "iwarp_rdma.opcode",
736 FT_UINT8, BASE_HEX, VALS(rdmap_messages), RDMA_OPCODE,
737 "RDMA OpCode Field", HFILL} },
738 { &hf_iwarp_rdma_reserved, {
739 "Reserved", "iwarp_rdma.reserved",
740 FT_BYTES, BASE_NONE, NULL, 0x0,
742 { &hf_iwarp_rdma_inval_stag, {
743 "Invalidate STag", "iwarp_rdma.inval_stag",
744 FT_UINT32, BASE_DEC, NULL, 0x0,
745 "RDMA Invalidate STag", HFILL} },
746 { &hf_iwarp_rdma_rr_header, {
747 "Read request", "iwarp_rdma.rr",
748 FT_NONE, BASE_NONE, NULL, 0x0,
749 "RDMA Read Request Header", HFILL} },
750 { &hf_iwarp_rdma_terminate_header, {
751 "Terminate", "iwarp_rdma.terminate",
752 FT_NONE, BASE_NONE, NULL, 0x0,
753 "RDMA Terminate Header", HFILL} },
754 { &hf_iwarp_rdma_sinkstag, {
755 "Data Sink STag", "iwarp_rdma.sinkstag",
756 FT_UINT32, BASE_DEC, NULL, 0x0,
758 { &hf_iwarp_rdma_sinkto, {
759 "Data Sink Tagged Offset", "iwarp_rdma.sinkto",
760 FT_UINT64, BASE_DEC, NULL, 0x0,
762 { &hf_iwarp_rdma_rdmardsz, {
763 "RDMA Read Message Size", "iwarp_rdma.rdmardsz",
764 FT_UINT32, BASE_DEC, NULL, 0x0,
766 { &hf_iwarp_rdma_srcstag, {
767 "Data Source STag", "iwarp_rdma.srcstag",
768 FT_UINT32, BASE_DEC, NULL, 0x0,
770 { &hf_iwarp_rdma_srcto, {
771 "Data Source Tagged Offset", "iwarp_rdma.srcto",
772 FT_BYTES, BASE_NONE, NULL, 0x0,
774 { &hf_iwarp_rdma_term_ctrl, {
775 "Terminate Control", "iwarp_rdma.term_ctrl",
776 FT_NONE, BASE_NONE, NULL, 0x0,
777 "RDMA Terminate Control Field", HFILL} },
778 { &hf_iwarp_rdma_term_layer, {
779 "Layer", "iwarp_rdma.term_layer",
780 FT_UINT8, BASE_HEX, VALS(layer_names), IWARP_LAYER,
781 "Terminate Control Field: Layer", HFILL} },
782 { &hf_iwarp_rdma_term_etype_rdma, {
783 "Error Types for RDMA layer", "iwarp_rdma.term_etype_rdma",
784 FT_UINT8, BASE_HEX, VALS(rdma_etype_names), IWARP_ETYPE,
785 "Terminate Control Field: Error Type", HFILL} },
786 { &hf_iwarp_rdma_term_etype_ddp, {
787 "Error Types for DDP layer", "iwarp_rdma.term_etype_ddp",
788 FT_UINT8, BASE_HEX, VALS(ddp_etype_names), IWARP_ETYPE,
789 "Terminate Control Field: Error Type", HFILL} },
790 { &hf_iwarp_rdma_term_etype_llp, {
791 "Error Types for LLP layer", "iwarp_rdma.term_etype_llp",
792 FT_UINT8, BASE_HEX, NULL, IWARP_ETYPE,
793 "Terminate Control Field: Error Type", HFILL} },
794 { &hf_iwarp_rdma_term_etype, {
795 "Error Types", "iwarp_rdma.term_etype",
796 FT_UINT8, BASE_HEX, NULL, IWARP_ETYPE,
797 "Terminate Control Field: Error Type", HFILL} },
798 { &hf_iwarp_rdma_term_errcode_rdma, {
799 "Error Code for RDMA layer", "iwarp_rdma.term_errcode_rdma",
800 FT_UINT8, BASE_HEX, VALS(rdma_errcode_names), 0x0,
801 "Terminate Control Field: Error Code", HFILL} },
802 { &hf_iwarp_rdma_term_errcode_ddp_tagged, {
803 "Error Code for DDP Tagged Buffer",
804 "iwarp_rdma.term_errcode_ddp_tagged",
805 FT_UINT8, BASE_HEX, VALS(ddp_errcode_tagged_names), 0x0,
806 "Terminate Control Field: Error Code", HFILL} },
807 { &hf_iwarp_rdma_term_errcode_ddp_untagged, {
808 "Error Code for DDP Untagged Buffer",
809 "iwarp_rdma.term_errcode_ddp_untagged",
810 FT_UINT8, BASE_HEX, VALS(ddp_errcode_untagged_names), 0x0,
811 "Terminate Control Field: Error Code", HFILL} },
812 { &hf_iwarp_rdma_term_errcode, {
813 "Error Code", "iwarp_rdma.term_errcode",
814 FT_UINT8, BASE_HEX, NULL, 0x0,
815 "Terminate Control Field: Error Code", HFILL} },
816 { &hf_iwarp_rdma_term_errcode_llp, {
817 "Error Code for LLP layer", "iwarp_rdma.term_errcode_llp",
818 FT_UINT8, BASE_HEX, NULL, 0x0,
819 "Terminate Control Field: Lower Layer Protocol Error Code",
821 { &hf_iwarp_rdma_term_hdrct, {
822 "Header control bits", "iwarp_rdma.term_hdrct",
823 FT_NONE, BASE_NONE, NULL, IWARP_HDRCT,
824 "Terminate Control Field: Header control bits", HFILL} },
825 { &hf_iwarp_rdma_term_hdrct_m, {
826 "M bit", "iwarp_rdma.term_hdrct_m",
827 FT_UINT8, BASE_HEX, NULL, IWARP_HDRCT_M,
828 "Header control bit m: DDP Segment Length valid", HFILL} },
829 { &hf_iwarp_rdma_term_hdrct_d, {
830 "D bit", "iwarp_rdma.hdrct_d",
831 FT_UINT8, BASE_HEX, NULL, IWARP_HDRCT_D,
832 "Header control bit d: DDP Header Included", HFILL} },
833 { &hf_iwarp_rdma_term_hdrct_r, {
834 "R bit", "iwarp_rdma.hdrct_r",
835 FT_UINT8, BASE_HEX, NULL, IWARP_HDRCT_R,
836 "Header control bit r: RDMAP Header Included", HFILL} },
837 { &hf_iwarp_rdma_term_rsvd, {
838 "Reserved", "iwarp_rdma.term_rsvd",
839 FT_UINT16, BASE_HEX, NULL, IWARP_TERM_RES,
841 { &hf_iwarp_rdma_term_ddp_seg_len, {
842 "DDP Segment Length", "iwarp_rdma.term_ddp_seg_len",
843 FT_BYTES, BASE_NONE, NULL, 0x0,
845 { &hf_iwarp_rdma_term_ddp_h, {
846 "Terminated DDP Header", "iwarp_rdma.term_ddp_h",
847 FT_BYTES, BASE_NONE, NULL, 0x0,
849 { &hf_iwarp_rdma_term_rdma_h, {
850 "Terminated RDMA Header", "iwarp_rdma.term_rdma_h",
851 FT_BYTES, BASE_NONE, NULL, 0x0,
855 /* setup protocol subtree array */
856 static gint *ett[] = {
858 &ett_iwarp_ddp_rdmap,
863 &ett_iwarp_ddp_control_field,
864 &ett_iwarp_ddp_tagged_header,
865 &ett_iwarp_ddp_untagged_header,
870 &ett_iwarp_rdma_control_field,
871 &ett_iwarp_rdma_rr_header,
872 &ett_iwarp_rdma_terminate_header,
873 &ett_iwarp_rdma_term_ctrl,
874 &ett_iwarp_rdma_term_hdrct
877 /* register the protocol name and description */
878 proto_iwarp_ddp_rdmap = proto_register_protocol(
879 "iWARP Direct Data Placement and Remote Direct Memory Access Protocol",
883 /* required function calls to register the header fields and subtrees */
884 proto_register_field_array(proto_iwarp_ddp_rdmap, hf, array_length(hf));
885 proto_register_subtree_array(ett, array_length(ett));
887 register_dissector("iwarp_ddp_rdmap", dissect_iwarp_ddp_rdmap,
888 proto_iwarp_ddp_rdmap);
892 proto_reg_handoff_iwarp_ddp_rdmap(void)
894 data_handle = find_dissector("data");