HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-iwarp-ddp-rdmap.c
blob0d12b6a6befb6e5d2085f42d7dc6dbb0ef2c5d22
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>
8 * $Id$
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
26 * Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
30 /* INCLUDES */
31 #include "config.h"
33 #include <glib.h>
35 #include <epan/packet.h>
37 /* DEFINES */
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
44 #define DDP_TO_LEN 8
45 #define DDP_UNTAGGED_HEADER_LEN 18
46 #define DDP_UNTAGGED_RSVDULP_LEN 5
47 #define DDP_QN_LEN 4
48 #define DDP_MSN_LEN 4
49 #define DDP_MO_LEN 4
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
63 /* RDMA messages */
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
73 /* bitmasks */
74 #define DDP_TAGGED_FLAG 0x80
75 #define DDP_LAST_FLAG 0x40
76 #define DDP_RSVD 0x3C
77 #define DDP_DV 0x03
78 #define RDMA_RV 0xC0
79 #define RDMA_RSV 0x30
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
96 /* GLOBALS */
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;
140 /* Control Field */
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" },
198 { 0, NULL }
201 static const value_string layer_names[] = {
202 { IWARP_LAYER_RDMA, "RDMA" },
203 { IWARP_LAYER_DDP, "DDP" },
204 { IWARP_LAYER_LLP, "LLP" },
205 { 0, NULL }
209 static const value_string rdma_etype_names[] = {
210 { 0x00, "Local Catastrophic Error" },
211 { 0x01, "Remote Protection Error" },
212 { 0x02, "Remote Operation Error" },
213 { 0, NULL }
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" },
221 { 0x04, "TO wrap" },
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" },
228 { 0, NULL }
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" },
236 { 0, NULL }
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" },
243 { 0x03, "TO wrap" },
244 { 0x04, "Invalid DDP version" },
245 { 0, NULL }
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" },
255 { 0, NULL }
258 /* update packet list pane in the GUI */
259 static void
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");
267 if (ddp_last_flag) {
268 ddp_fragment_state = "[last DDP segment]";
269 } else {
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 */
279 static void
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;
293 guint32 rdmardsz;
295 if (rdma_tree) {
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,
301 ett_iwarp_rdma);
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",
314 rdmardsz);
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,
329 ett_iwarp_rdma);
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);
342 switch (layer) {
343 case IWARP_LAYER_RDMA:
344 proto_tree_add_item(term_ctrl_field_tree,
345 hf_iwarp_rdma_term_etype_rdma, tvb, offset, 1,
346 ENC_BIG_ENDIAN);
347 offset += 1;
348 proto_tree_add_item(term_ctrl_field_tree,
349 hf_iwarp_rdma_term_errcode_rdma, tvb, offset, 1,
350 ENC_BIG_ENDIAN);
351 offset += 1;
352 break;
353 case IWARP_LAYER_DDP:
354 proto_tree_add_item(term_ctrl_field_tree,
355 hf_iwarp_rdma_term_etype_ddp, tvb, offset, 1,
356 ENC_BIG_ENDIAN);
357 offset += 1;
358 switch (etype) {
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);
363 offset += 1;
364 break;
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);
369 offset += 1;
370 break;
371 default:
372 proto_tree_add_item(term_ctrl_field_tree,
373 hf_iwarp_rdma_term_errcode, tvb, offset, 1,
374 ENC_BIG_ENDIAN);
375 offset += 1;
376 break;
378 break;
379 case IWARP_LAYER_LLP:
380 proto_tree_add_item(term_ctrl_field_tree,
381 hf_iwarp_rdma_term_etype_llp, tvb, offset, 1,
382 ENC_BIG_ENDIAN);
383 offset += 1;
384 proto_tree_add_item(term_ctrl_field_tree,
385 hf_iwarp_rdma_term_errcode_llp, tvb, offset, 1,
386 ENC_BIG_ENDIAN);
387 offset += 1;
388 break;
389 default:
390 proto_tree_add_item(term_ctrl_field_tree,
391 hf_iwarp_rdma_term_etype, tvb, offset, 1, ENC_BIG_ENDIAN);
392 offset += 1;
393 proto_tree_add_item(term_ctrl_field_tree,
394 hf_iwarp_rdma_term_errcode, tvb, offset, 1, ENC_BIG_ENDIAN);
395 offset += 1;
396 break;
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,
402 offset, 1, ENC_NA);
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);
417 offset += 2;
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;
433 } else {
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.
454 static void
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;
475 guint32 header_end;
476 guint32 offset = 0;
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);
485 if (tree) {
487 offset = 0;
489 /* determine header length */
490 if (is_tagged_buffer_model) {
491 header_end = DDP_TAGGED_HEADER_LEN;
492 } else {
493 header_end = DDP_UNTAGGED_HEADER_LEN;
496 if (rdma_msg_opcode == RDMA_READ_REQUEST
497 || rdma_msg_opcode == RDMA_TERMINATE) {
498 header_end = -1;
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,
517 ett_iwarp_ddp);
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;
539 } else {
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,
552 ett_iwarp_rdma);
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,
589 ett_iwarp_ddp);
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);
606 } else {
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,
613 ett_iwarp_ddp);
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 */
645 void
646 proto_register_iwarp_ddp_rdmap(void)
648 /* setup list of header fields */
649 static hf_register_info hf[] = {
651 /* DDP */
652 { &hf_iwarp_ddp, {
653 "DDP header", "iwarp_ddp",
654 FT_NONE, BASE_NONE, NULL, 0x0,
655 NULL, HFILL } },
656 { &hf_iwarp_ddp_control_field, {
657 "DDP control field", "iwarp_ddp.control_field",
658 FT_NONE, BASE_NONE, NULL, 0x0,
659 NULL, HFILL } },
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,
671 NULL, HFILL} },
672 { &hf_iwarp_ddp_l_flag, {
673 "Last flag", "iwarp_ddp.last_flag",
674 FT_BOOLEAN, 8, NULL, DDP_LAST_FLAG,
675 NULL, HFILL} },
676 { &hf_iwarp_ddp_rsvd, {
677 "Reserved", "iwarp_ddp.rsvd",
678 FT_UINT8, BASE_HEX, NULL, DDP_RSVD,
679 NULL, HFILL} },
680 { &hf_iwarp_ddp_dv, {
681 "DDP protocol version", "iwarp_ddp.dv",
682 FT_UINT8, BASE_DEC, NULL, DDP_DV,
683 NULL, HFILL} },
684 { &hf_iwarp_ddp_rsvdulp, {
685 "Reserved for use by the ULP", "iwarp_ddp.rsvdulp",
686 FT_BYTES, BASE_NONE, NULL, 0x0,
687 NULL, HFILL} },
688 { &hf_iwarp_ddp_stag, {
689 "(Data Sink) Steering Tag", "iwarp_ddp.stag",
690 FT_BYTES, BASE_NONE, NULL, 0x0,
691 NULL, HFILL} },
692 { &hf_iwarp_ddp_to, {
693 "(Data Sink) Tagged offset", "iwarp_ddp.tagged_offset",
694 FT_BYTES, BASE_NONE, NULL, 0x0,
695 NULL, HFILL} },
696 { &hf_iwarp_ddp_qn, {
697 "Queue number", "iwarp_ddp.qn",
698 FT_UINT32, BASE_DEC, NULL, 0x0,
699 NULL, HFILL} },
700 { &hf_iwarp_ddp_msn, {
701 "Message sequence number", "iwarp_ddp.msn",
702 FT_UINT32, BASE_DEC, NULL, 0x0,
703 NULL, HFILL} },
704 { &hf_iwarp_ddp_mo, {
705 "Message offset", "iwarp_ddp.mo",
706 FT_UINT32, BASE_DEC, NULL, 0x0,
707 NULL, HFILL}
710 /* RDMAP */
711 { &hf_iwarp_rdma, {
712 "RDMAP header", "iwarp_rdma",
713 FT_NONE, BASE_NONE, NULL, 0x0,
714 NULL, HFILL} },
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,
734 NULL, HFILL} },
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,
750 NULL, HFILL} },
751 { &hf_iwarp_rdma_sinkto, {
752 "Data Sink Tagged Offset", "iwarp_rdma.sinkto",
753 FT_UINT64, BASE_DEC, NULL, 0x0,
754 NULL, HFILL} },
755 { &hf_iwarp_rdma_rdmardsz, {
756 "RDMA Read Message Size", "iwarp_rdma.rdmardsz",
757 FT_UINT32, BASE_DEC, NULL, 0x0,
758 NULL, HFILL} },
759 { &hf_iwarp_rdma_srcstag, {
760 "Data Source STag", "iwarp_rdma.srcstag",
761 FT_UINT32, BASE_DEC, NULL, 0x0,
762 NULL, HFILL} },
763 { &hf_iwarp_rdma_srcto, {
764 "Data Source Tagged Offset", "iwarp_rdma.srcto",
765 FT_BYTES, BASE_NONE, NULL, 0x0,
766 NULL, HFILL} },
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",
813 HFILL} },
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,
833 NULL, HFILL} },
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,
837 NULL, HFILL} },
838 { &hf_iwarp_rdma_term_ddp_h, {
839 "Terminated DDP Header", "iwarp_rdma.term_ddp_h",
840 FT_BYTES, BASE_NONE, NULL, 0x0,
841 NULL, HFILL} },
842 { &hf_iwarp_rdma_term_rdma_h, {
843 "Terminated RDMA Header", "iwarp_rdma.term_rdma_h",
844 FT_BYTES, BASE_NONE, NULL, 0x0,
845 NULL, HFILL} }
848 /* setup protocol subtree array */
849 static gint *ett[] = {
851 &ett_iwarp_ddp_rdmap,
853 /* DDP */
854 &ett_iwarp_ddp,
856 &ett_iwarp_ddp_control_field,
857 &ett_iwarp_ddp_tagged_header,
858 &ett_iwarp_ddp_untagged_header,
860 /* RDMAP */
861 &ett_iwarp_rdma,
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",
873 "IWARP_DDP_RDMAP",
874 "iwarp_ddp_rdmap");
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);
884 void
885 proto_reg_handoff_iwarp_ddp_rdmap(void)
887 data_handle = find_dissector("data");