Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-iwarp-ddp-rdmap.c
blob09766a1ca87abed92b738a3ee5160a226ba6da69
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 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * SPDX-License-Identifier: GPL-2.0-or-later
15 /* INCLUDES */
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/reassemble.h>
20 #include <epan/conversation.h>
21 #include <epan/proto_data.h>
22 #include <epan/tfs.h>
23 #include <epan/unit_strings.h>
25 #include "packet-iwarp-ddp-rdmap.h"
27 void proto_register_iwarp_ddp_rdmap(void);
29 /* DEFINES */
31 /* header field byte lengths */
32 #define DDP_CONTROL_FIELD_LEN 1
33 #define DDP_TAGGED_HEADER_LEN 14
34 #define DDP_TAGGED_RSVDULP_LEN 4
35 #define DDP_STAG_LEN 4
36 #define DDP_TO_LEN 8
37 #define DDP_UNTAGGED_HEADER_LEN 18
38 #define DDP_UNTAGGED_RSVDULP_LEN 5
39 #define DDP_QN_LEN 4
40 #define DDP_MSN_LEN 4
41 #define DDP_MO_LEN 4
42 #define DDP_BUFFER_MODEL_LEN 12
44 #define RDMA_CONTROL_FIELD_LEN 1
45 #define RDMA_RESERVED_FIELD_LEN 4
46 #define RDMA_INVAL_STAG_LEN 4
47 #define RDMA_SINKSTAG_LEN 4
48 #define RDMA_SINKTO_LEN 8
49 #define RDMA_RDMARDSZ_LEN 4
50 #define RDMA_SRCSTAG_LEN 4
51 #define RDMA_SRCTO_LEN 8
52 #define RDMA_DDP_SEGLEN_LEN 2
53 #define RDMA_TERMINATED_RDMA_LEN 28
55 /* RDMA messages */
56 #define RDMA_WRITE 0x00
57 #define RDMA_READ_REQUEST 0x01
58 #define RDMA_READ_RESPONSE 0x02
59 #define RDMA_SEND 0x03
60 #define RDMA_SEND_INVALIDATE 0x04
61 #define RDMA_SEND_SE 0x05
62 #define RDMA_SEND_SE_INVALIDATE 0x06
63 #define RDMA_TERMINATE 0x07
64 #define RDMA_ATOMIC_REQUEST 0x0A
65 #define RDMA_ATOMIC_RESPONSE 0x0B
67 /* bitmasks */
68 #define DDP_TAGGED_FLAG 0x80
69 #define DDP_LAST_FLAG 0x40
70 #define DDP_RSVD 0x3C
71 #define DDP_DV 0x03
72 #define RDMA_RV 0xC0
73 #define RDMA_RSV 0x30
74 #define RDMA_OPCODE 0x0F
76 #define IWARP_LAYER 0xF0
77 #define IWARP_ETYPE 0x0F
78 #define IWARP_HDRCT 0xE0
79 #define IWARP_HDRCT_M 0x80
80 #define IWARP_HDRCT_D 0x40
81 #define IWARP_HDRCT_R 0x20
82 #define IWARP_TERM_RES 0x1FFF
84 #define IWARP_LAYER_RDMA 0x00
85 #define IWARP_LAYER_DDP 0x01
86 #define IWARP_LAYER_LLP 0x02
88 #define IWARP_ETYPE_DDP_TAGGED 0x01
89 #define IWARP_ETYPE_DDP_UNTAGGED 0x02
91 /* GLOBALS */
92 static int proto_iwarp_ddp_rdmap;
93 static int ett_iwarp_ddp_rdmap;
96 * DDP: initialize the protocol and registered fields
98 static int hf_iwarp_ddp;
100 /* DDP Control Field */
101 static int hf_iwarp_ddp_control_field;
102 static int hf_iwarp_ddp_t_flag;
103 static int hf_iwarp_ddp_l_flag;
104 static int hf_iwarp_ddp_rsvd;
105 static int hf_iwarp_ddp_dv;
107 /* DDP rsvdULP[8:39] field */
108 static int hf_iwarp_ddp_rsvdulp;
110 /* Tagged Buffer Model Header */
111 static int hf_iwarp_ddp_tagged_header;
112 static int hf_iwarp_ddp_stag;
113 static int hf_iwarp_ddp_to;
115 /* Untagged Buffer Model Header */
116 static int hf_iwarp_ddp_untagged_header;
117 static int hf_iwarp_ddp_qn;
118 static int hf_iwarp_ddp_msn;
119 static int hf_iwarp_ddp_mo;
121 /* initialize the subtree pointers */
122 static int ett_iwarp_ddp;
124 static int ett_iwarp_ddp_control_field;
125 static int ett_iwarp_ddp_tagged_header;
126 static int ett_iwarp_ddp_untagged_header;
129 * RDMAP: initialize the protocol and registered fields
131 static int hf_iwarp_rdma;
133 /* Control Field */
134 static int hf_iwarp_rdma_control_field;
135 static int hf_iwarp_rdma_version;
136 static int hf_iwarp_rdma_rsvd;
137 static int hf_iwarp_rdma_opcode;
139 /* DDP rsvdULP[8:39] RDMA interpretations */
140 static int hf_iwarp_rdma_reserved;
141 static int hf_iwarp_rdma_inval_stag;
143 /* Read Request Header */
144 static int hf_iwarp_rdma_rr_header;
145 static int hf_iwarp_rdma_sinkstag;
146 static int hf_iwarp_rdma_sinkto;
147 static int hf_iwarp_rdma_rdmardsz;
148 static int hf_iwarp_rdma_srcstag;
149 static int hf_iwarp_rdma_srcto;
151 /* Terminate Header */
152 static int hf_iwarp_rdma_terminate_header;
153 static int hf_iwarp_rdma_term_ctrl;
154 static int hf_iwarp_rdma_term_layer;
155 static int hf_iwarp_rdma_term_etype;
156 static int hf_iwarp_rdma_term_etype_rdma;
157 static int hf_iwarp_rdma_term_etype_ddp;
158 static int hf_iwarp_rdma_term_etype_llp;
159 static int hf_iwarp_rdma_term_errcode;
160 static int hf_iwarp_rdma_term_errcode_rdma;
161 static int hf_iwarp_rdma_term_errcode_ddp_untagged;
162 static int hf_iwarp_rdma_term_errcode_ddp_tagged;
163 static int hf_iwarp_rdma_term_errcode_llp;
164 static int hf_iwarp_rdma_term_hdrct;
165 static int hf_iwarp_rdma_term_hdrct_m;
166 static int hf_iwarp_rdma_term_hdrct_d;
167 static int hf_iwarp_rdma_term_hdrct_r;
168 static int hf_iwarp_rdma_term_rsvd;
169 static int hf_iwarp_rdma_term_ddp_seg_len;
170 static int hf_iwarp_rdma_term_ddp_h;
171 static int hf_iwarp_rdma_term_rdma_h;
173 /* Atomic */
174 static int hf_iwarp_rdma_atomic_reserved;
175 static int hf_iwarp_rdma_atomic_opcode;
176 static int hf_iwarp_rdma_atomic_request_identifier;
177 static int hf_iwarp_rdma_atomic_remote_stag;
178 static int hf_iwarp_rdma_atomic_remote_tagged_offset;
179 static int hf_iwarp_rdma_atomic_add_data;
180 static int hf_iwarp_rdma_atomic_add_mask;
181 static int hf_iwarp_rdma_atomic_swap_data;
182 static int hf_iwarp_rdma_atomic_swap_mask;
183 static int hf_iwarp_rdma_atomic_compare_data;
184 static int hf_iwarp_rdma_atomic_compare_mask;
185 static int hf_iwarp_rdma_atomic_original_request_identifier;
186 static int hf_iwarp_rdma_atomic_original_remote_data_value;
188 static int hf_iwarp_rdma_send_fragments;
189 static int hf_iwarp_rdma_send_fragment;
190 static int hf_iwarp_rdma_send_fragment_overlap;
191 static int hf_iwarp_rdma_send_fragment_overlap_conflict;
192 static int hf_iwarp_rdma_send_fragment_multiple_tails;
193 static int hf_iwarp_rdma_send_fragment_too_long_fragment;
194 static int hf_iwarp_rdma_send_fragment_error;
195 static int hf_iwarp_rdma_send_fragment_count;
196 static int hf_iwarp_rdma_send_reassembled_in;
197 static int hf_iwarp_rdma_send_reassembled_length;
198 static int hf_iwarp_rdma_send_reassembled_data;
200 /* initialize the subtree pointers */
201 static int ett_iwarp_rdma;
203 static int ett_iwarp_rdma_control_field;
204 static int ett_iwarp_rdma_rr_header;
205 static int ett_iwarp_rdma_terminate_header;
206 static int ett_iwarp_rdma_term_ctrl;
207 static int ett_iwarp_rdma_term_hdrct;
209 static int ett_iwarp_rdma_send_fragment;
210 static int ett_iwarp_rdma_send_fragments;
212 static const fragment_items iwarp_rdma_send_frag_items = {
213 &ett_iwarp_rdma_send_fragment,
214 &ett_iwarp_rdma_send_fragments,
215 &hf_iwarp_rdma_send_fragments,
216 &hf_iwarp_rdma_send_fragment,
217 &hf_iwarp_rdma_send_fragment_overlap,
218 &hf_iwarp_rdma_send_fragment_overlap_conflict,
219 &hf_iwarp_rdma_send_fragment_multiple_tails,
220 &hf_iwarp_rdma_send_fragment_too_long_fragment,
221 &hf_iwarp_rdma_send_fragment_error,
222 &hf_iwarp_rdma_send_fragment_count,
223 &hf_iwarp_rdma_send_reassembled_in,
224 &hf_iwarp_rdma_send_reassembled_length,
225 &hf_iwarp_rdma_send_reassembled_data,
226 "iWarp RDMA Send fragments"
229 static const value_string rdmap_messages[] = {
230 { RDMA_WRITE, "Write" },
231 { RDMA_READ_REQUEST, "Read Request" },
232 { RDMA_READ_RESPONSE, "Read Response" },
233 { RDMA_SEND, "Send" },
234 { RDMA_SEND_INVALIDATE, "Send with Invalidate" },
235 { RDMA_SEND_SE, "Send with SE" },
236 { RDMA_SEND_SE_INVALIDATE, "Send with SE and Invalidate" },
237 { RDMA_TERMINATE, "Terminate" },
238 { RDMA_ATOMIC_REQUEST, "Atomic Request" },
239 { RDMA_ATOMIC_RESPONSE, "Atomic Response" },
240 { 0, NULL }
243 static const value_string layer_names[] = {
244 { IWARP_LAYER_RDMA, "RDMA" },
245 { IWARP_LAYER_DDP, "DDP" },
246 { IWARP_LAYER_LLP, "LLP" },
247 { 0, NULL }
251 static const value_string rdma_etype_names[] = {
252 { 0x00, "Local Catastrophic Error" },
253 { 0x01, "Remote Protection Error" },
254 { 0x02, "Remote Operation Error" },
255 { 0, NULL }
258 static const value_string rdma_errcode_names[] = {
259 { 0x00, "Invalid STag" },
260 { 0x01, "Base or bounds violation" },
261 { 0x02, "Access rights violation" },
262 { 0x03, "STag not associated with RDMAP Stream" },
263 { 0x04, "TO wrap" },
264 { 0x05, "Invalid RDMAP version" },
265 { 0x06, "Unexpected OpCode" },
266 { 0x07, "Catastrophic error, localized to RDMAP Stream" },
267 { 0x08, "Catastrophic error, global" },
268 { 0x09, "STag cannot be Invalidated" },
269 { 0xFF, "Unspecific Error" },
270 { 0, NULL }
273 static const value_string ddp_etype_names[] = {
274 { 0x00, "Local Catastrophic Error" },
275 { 0x01, "Tagged Buffer Error" },
276 { 0x02, "Untagged Buffer Error" },
277 { 0x03, "Reserved for the use by the LLP" },
278 { 0, NULL }
281 static const value_string ddp_errcode_tagged_names[] = {
282 { 0x00, "Invalid STag" },
283 { 0x01, "Base or bounds violation" },
284 { 0x02, "STag not associated with DDP Stream" },
285 { 0x03, "TO wrap" },
286 { 0x04, "Invalid DDP version" },
287 { 0, NULL }
290 static const value_string ddp_errcode_untagged_names[] = {
291 { 0x01, "Invalid QN" },
292 { 0x02, "Invalid MSN - no buffer available" },
293 { 0x03, "Invalid MSN - MSN range is not valid" },
294 { 0x04, "Invalid MO" },
295 { 0x05, "DDP Message too long for available buffer" },
296 { 0x06, "Invalid DDP version" },
297 { 0, NULL }
300 static const value_string mpa_etype_names[] = {
301 { 0x00, "MPA Error" },
302 { 0, NULL }
305 static const value_string mpa_errcode_names[] = {
306 { 0x01, "TCP connection closed, terminated or lost" },
307 { 0x02, "MPA CRC Error" },
308 { 0x03, "MPA Marker and ULPDU Length field mismatch" },
309 { 0x04, "Invalid MPA Request Frame or MPA Response Frame" },
310 { 0x05, "Local Catastrophic Error" },
311 { 0x06, "Insufficient IRD Resources" },
312 { 0x07, "No Matching RTR Option" },
313 { 0, NULL }
316 static const value_string rdma_atomic_opcode_names[] = {
317 { 0x00, "FetchAdd" },
318 { 0x02, "CmpSwap" },
319 { 0, NULL }
323 static heur_dissector_list_t rdmap_heur_subdissector_list;
325 static bool iwarp_rdma_send_reassemble = true;
326 static reassembly_table iwarp_rdma_send_reassembly_table;
328 static void
329 dissect_rdmap_payload(tvbuff_t *tvb, packet_info *pinfo,
330 proto_tree *tree, rdmap_info_t *info)
332 bool save_fragmented = pinfo->fragmented;
333 int save_visited = pinfo->fd->visited;
334 conversation_t *conversation = NULL;
335 fragment_head *fd_head = NULL;
336 bool more_frags = false;
337 bool fd_head_not_cached = false;
338 heur_dtbl_entry_t *hdtbl_entry;
340 switch (info->opcode) {
341 case RDMA_SEND:
342 case RDMA_SEND_INVALIDATE:
343 case RDMA_SEND_SE:
344 case RDMA_SEND_SE_INVALIDATE:
345 if (iwarp_rdma_send_reassemble) {
346 break;
348 /* FALLTHRU */
349 default:
350 goto dissect_payload;
353 conversation = find_or_create_conversation(pinfo);
355 if (!info->last_flag) {
356 more_frags = true;
359 fd_head = (fragment_head *)p_get_proto_data(wmem_file_scope(), pinfo, proto_iwarp_ddp_rdmap, 0);
360 if (fd_head == NULL) {
361 fd_head_not_cached = true;
363 pinfo->fd->visited = 0;
364 fd_head = fragment_add_seq_next(&iwarp_rdma_send_reassembly_table,
365 tvb, 0, pinfo,
366 conversation->conv_index,
367 NULL, tvb_captured_length(tvb),
368 more_frags);
371 if (fd_head == NULL) {
373 * We really want the fd_head and pass it to
374 * process_reassembled_data()
376 * So that individual fragments gets the
377 * reassembled in field.
379 fd_head = fragment_get_reassembled_id(&iwarp_rdma_send_reassembly_table,
380 pinfo,
381 conversation->conv_index);
384 if (fd_head == NULL) {
386 * we need more data...
388 goto done;
391 if (fd_head_not_cached) {
392 p_add_proto_data(wmem_file_scope(), pinfo,
393 proto_iwarp_ddp_rdmap, 0, fd_head);
396 tvb = process_reassembled_data(tvb, 0, pinfo,
397 "Reassembled iWarp RDMA Send",
398 fd_head,
399 &iwarp_rdma_send_frag_items,
400 NULL, /* update_col_info*/
401 tree);
402 if (tvb == NULL) {
404 * we need more data...
406 goto done;
409 dissect_payload:
410 pinfo->fragmented = false;
411 if (!dissector_try_heuristic(rdmap_heur_subdissector_list,
412 tvb, pinfo, tree, &hdtbl_entry, info)) {
413 call_data_dissector(tvb, pinfo, tree);
415 done:
416 pinfo->fragmented = save_fragmented;
417 pinfo->fd->visited = save_visited;
418 return;
421 /* update packet list pane in the GUI */
422 static void
423 ddp_rdma_packetlist(packet_info *pinfo, bool ddp_last_flag,
424 uint8_t rdma_msg_opcode)
426 const char *ddp_fragment_state;
428 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP/RDMA");
430 if (ddp_last_flag) {
431 ddp_fragment_state = "[last DDP segment]";
432 } else {
433 ddp_fragment_state = "[more DDP segments]";
436 col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d %s %s", pinfo->srcport,
437 pinfo->destport, val_to_str(rdma_msg_opcode, rdmap_messages,
438 "Unknown %d"), ddp_fragment_state);
441 /* dissects RDMA Read Request and Terminate message header */
442 static int
443 dissect_iwarp_rdmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *rdma_tree, uint32_t offset,
444 rdmap_info_t *info)
446 proto_tree *rdma_header_tree = NULL;
447 proto_tree *term_ctrl_field_tree = NULL;
448 proto_tree *header_ctrl_field_tree = NULL;
450 proto_item *rdma_header_subitem = NULL;
451 proto_item *term_ctrl_field_subitem = NULL;
452 proto_item *header_ctrl_field_subitem = NULL;
454 uint8_t layer, etype, hdrct;
456 if (info->opcode == RDMA_READ_REQUEST) {
457 info->read_request = wmem_new(pinfo->pool, rdmap_request_t);
459 rdma_header_subitem = proto_tree_add_item(rdma_tree,
460 hf_iwarp_rdma_rr_header, tvb, offset, -1, ENC_NA);
461 rdma_header_tree = proto_item_add_subtree(rdma_header_subitem,
462 ett_iwarp_rdma);
464 proto_tree_add_item_ret_uint(rdma_header_tree, hf_iwarp_rdma_sinkstag, tvb,
465 offset, RDMA_SINKSTAG_LEN, ENC_BIG_ENDIAN,
466 &info->read_request->sink_stag);
467 offset += RDMA_SINKSTAG_LEN;
468 proto_tree_add_item_ret_uint64(rdma_header_tree, hf_iwarp_rdma_sinkto, tvb,
469 offset, RDMA_SINKTO_LEN, ENC_BIG_ENDIAN,
470 &info->read_request->sink_toffset);
471 offset += RDMA_SINKTO_LEN;
473 proto_tree_add_item_ret_uint(rdma_header_tree,
474 hf_iwarp_rdma_rdmardsz, tvb, offset,
475 RDMA_RDMARDSZ_LEN, ENC_BIG_ENDIAN,
476 &info->read_request->message_size);
478 offset += RDMA_RDMARDSZ_LEN;
479 proto_tree_add_item_ret_uint(rdma_header_tree, hf_iwarp_rdma_srcstag, tvb,
480 offset, RDMA_SRCSTAG_LEN, ENC_BIG_ENDIAN,
481 &info->read_request->source_stag);
482 offset += RDMA_SRCSTAG_LEN;
483 proto_tree_add_item_ret_uint64(rdma_header_tree, hf_iwarp_rdma_srcto, tvb,
484 offset, RDMA_SRCTO_LEN, ENC_BIG_ENDIAN,
485 &info->read_request->source_toffset);
486 offset += RDMA_SRCTO_LEN;
489 if (rdma_tree) {
490 if (info->opcode == RDMA_TERMINATE) {
491 rdma_header_subitem = proto_tree_add_item(rdma_tree,
492 hf_iwarp_rdma_terminate_header, tvb, offset, -1, ENC_NA);
493 rdma_header_tree = proto_item_add_subtree(rdma_header_subitem,
494 ett_iwarp_rdma);
496 /* Terminate Control Field */
497 layer = tvb_get_uint8(tvb, offset) & IWARP_LAYER;
498 etype = tvb_get_uint8(tvb, offset) & IWARP_ETYPE;
500 term_ctrl_field_subitem = proto_tree_add_item(rdma_header_tree,
501 hf_iwarp_rdma_term_ctrl, tvb, offset, 3, ENC_NA);
502 term_ctrl_field_tree = proto_item_add_subtree(
503 term_ctrl_field_subitem, ett_iwarp_rdma);
504 proto_tree_add_item(term_ctrl_field_tree, hf_iwarp_rdma_term_layer,
505 tvb, offset, 1, ENC_BIG_ENDIAN);
507 switch (layer >> 4) {
508 case IWARP_LAYER_RDMA:
509 proto_tree_add_item(term_ctrl_field_tree,
510 hf_iwarp_rdma_term_etype_rdma, tvb, offset, 1,
511 ENC_BIG_ENDIAN);
512 offset += 1;
513 proto_tree_add_item(term_ctrl_field_tree,
514 etype ? hf_iwarp_rdma_term_errcode_rdma : hf_iwarp_rdma_term_errcode,
515 tvb, offset, 1, ENC_BIG_ENDIAN);
516 offset += 1;
517 break;
518 case IWARP_LAYER_DDP:
519 proto_tree_add_item(term_ctrl_field_tree,
520 hf_iwarp_rdma_term_etype_ddp, tvb, offset, 1,
521 ENC_BIG_ENDIAN);
522 offset += 1;
523 switch (etype) {
524 case IWARP_ETYPE_DDP_TAGGED:
525 proto_tree_add_item(term_ctrl_field_tree,
526 hf_iwarp_rdma_term_errcode_ddp_tagged, tvb,
527 offset, 1, ENC_BIG_ENDIAN);
528 offset += 1;
529 break;
530 case IWARP_ETYPE_DDP_UNTAGGED:
531 proto_tree_add_item(term_ctrl_field_tree,
532 hf_iwarp_rdma_term_errcode_ddp_untagged, tvb,
533 offset, 1, ENC_BIG_ENDIAN);
534 offset += 1;
535 break;
536 default:
537 proto_tree_add_item(term_ctrl_field_tree,
538 hf_iwarp_rdma_term_errcode, tvb, offset, 1,
539 ENC_BIG_ENDIAN);
540 offset += 1;
541 break;
543 break;
544 case IWARP_LAYER_LLP:
545 proto_tree_add_item(term_ctrl_field_tree,
546 hf_iwarp_rdma_term_etype_llp, tvb, offset, 1,
547 ENC_BIG_ENDIAN);
548 offset += 1;
549 proto_tree_add_item(term_ctrl_field_tree,
550 etype ? hf_iwarp_rdma_term_errcode : hf_iwarp_rdma_term_errcode_llp,
551 tvb, offset, 1, ENC_BIG_ENDIAN);
552 offset += 1;
553 break;
554 default:
555 proto_tree_add_item(term_ctrl_field_tree,
556 hf_iwarp_rdma_term_etype, tvb, offset, 1, ENC_BIG_ENDIAN);
557 offset += 1;
558 proto_tree_add_item(term_ctrl_field_tree,
559 hf_iwarp_rdma_term_errcode, tvb, offset, 1, ENC_BIG_ENDIAN);
560 offset += 1;
561 break;
564 /* header control bits (hdctr), part of Terminate Control Field */
565 header_ctrl_field_subitem = proto_tree_add_item(
566 term_ctrl_field_tree, hf_iwarp_rdma_term_hdrct, tvb,
567 offset, 1, ENC_NA);
568 header_ctrl_field_tree = proto_item_add_subtree(
569 header_ctrl_field_subitem, ett_iwarp_rdma);
571 hdrct = tvb_get_uint8(tvb, offset) & IWARP_HDRCT;
573 proto_tree_add_item(header_ctrl_field_tree,
574 hf_iwarp_rdma_term_hdrct_m, tvb, offset, 1, ENC_BIG_ENDIAN);
575 proto_tree_add_item(header_ctrl_field_tree,
576 hf_iwarp_rdma_term_hdrct_d, tvb, offset, 1, ENC_BIG_ENDIAN);
577 proto_tree_add_item(header_ctrl_field_tree,
578 hf_iwarp_rdma_term_hdrct_r, tvb, offset, 1, ENC_BIG_ENDIAN);
580 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_term_rsvd, tvb,
581 offset, 2, ENC_BIG_ENDIAN);
582 offset += 2;
585 if (hdrct & IWARP_HDRCT_D) {
586 /* DDP Segment Length (if any) */
587 proto_tree_add_item(rdma_header_tree,
588 hf_iwarp_rdma_term_ddp_seg_len, tvb,
589 offset, RDMA_DDP_SEGLEN_LEN, ENC_NA);
590 offset += RDMA_DDP_SEGLEN_LEN;
592 /* Terminated DDP Header (if any), tagged or untagged */
593 if (etype == IWARP_ETYPE_DDP_TAGGED) {
594 proto_tree_add_item(rdma_header_tree,
595 hf_iwarp_rdma_term_ddp_h, tvb,
596 offset, DDP_TAGGED_HEADER_LEN, ENC_NA);
597 offset += DDP_TAGGED_HEADER_LEN;
598 } else {
599 proto_tree_add_item(rdma_header_tree,
600 hf_iwarp_rdma_term_ddp_h, tvb,
601 offset, DDP_UNTAGGED_HEADER_LEN, ENC_NA);
602 offset += DDP_UNTAGGED_HEADER_LEN;
606 /* Terminated RDMA Header (if any) */
607 if (hdrct & IWARP_HDRCT_R) {
608 proto_tree_add_item(rdma_header_tree, hf_iwarp_rdma_term_rdma_h,
609 tvb, offset, RDMA_TERMINATED_RDMA_LEN, ENC_NA);
613 return offset;
616 /* dissects RDMA Atomic Request and Terminate message header */
617 static int
618 dissect_iwarp_atomic(tvbuff_t *tvb, proto_tree *atomic_tree, uint32_t offset,
619 uint8_t rdma_msg_opcode)
621 switch(rdma_msg_opcode){
622 case RDMA_ATOMIC_REQUEST:{
623 uint32_t atomic_opcode;
624 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
625 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_opcode, tvb, offset, 4, ENC_BIG_ENDIAN);
626 atomic_opcode = tvb_get_ntohl(tvb, offset);
627 offset += 4;
628 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_request_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
629 offset += 4;
630 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_remote_stag, tvb, offset, 4, ENC_BIG_ENDIAN);
631 offset += 4;
632 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_remote_tagged_offset, tvb, offset, 8, ENC_BIG_ENDIAN);
633 offset += 8;
634 switch(atomic_opcode){
635 case 0: /* Add */
636 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_add_data, tvb, offset, 8, ENC_BIG_ENDIAN);
637 offset += 8;
638 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_add_mask, tvb, offset, 8, ENC_BIG_ENDIAN);
639 offset += 8;
640 break;
641 case 2: /* Swap */
642 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_swap_data, tvb, offset, 8, ENC_BIG_ENDIAN);
643 offset += 8;
644 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_swap_mask, tvb, offset, 8, ENC_BIG_ENDIAN);
645 offset += 8;
646 break;
648 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_compare_data, tvb, offset, 8, ENC_BIG_ENDIAN);
649 offset += 8;
650 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_compare_mask, tvb, offset, 8, ENC_BIG_ENDIAN);
651 offset += 8;
653 break;
654 case RDMA_ATOMIC_RESPONSE:
655 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_original_request_identifier, tvb, offset, 4, ENC_BIG_ENDIAN);
656 offset += 4;
657 proto_tree_add_item(atomic_tree, hf_iwarp_rdma_atomic_original_remote_data_value, tvb, offset, 8, ENC_BIG_ENDIAN);
658 offset += 4;
659 break;
661 return offset;
665 * Main dissection routine which dissects a DDP segment and interprets the
666 * header field rsvdULP according to RDMAP.
668 static int
669 dissect_iwarp_ddp_rdmap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
671 proto_tree *ddp_rdma_tree = NULL;
672 proto_tree *ddp_tree = NULL;
673 proto_tree *ddp_ctrl_field_tree = NULL;
674 proto_tree *ddp_buffer_model_tree = NULL;
675 proto_tree *rdma_tree = NULL;
676 proto_tree *rdma_ctrl_field_tree = NULL;
678 proto_item *ddp_rdma_item = NULL;
679 proto_item *ddp_item = NULL;
680 proto_item *ddp_ctrl_field_item = NULL;
681 proto_item *ddp_buffer_model_item = NULL;
682 proto_item *rdma_item = NULL;
683 proto_item *rdma_ctrl_field_item = NULL;
685 tvbuff_t *next_tvb = NULL;
687 uint8_t ddp_ctrl_field, rdma_ctrl_field;
688 rdmap_info_t info = { 0, 0, 0, {{0, 0}}, NULL };
689 uint32_t header_end;
690 uint32_t offset = 0;
692 ddp_ctrl_field = tvb_get_uint8(tvb, 0);
693 rdma_ctrl_field = tvb_get_uint8(tvb, 1);
694 info.opcode = rdma_ctrl_field & RDMA_OPCODE;
695 info.is_tagged = (ddp_ctrl_field & DDP_TAGGED_FLAG) ? true : false;
696 info.last_flag = (ddp_ctrl_field & DDP_LAST_FLAG) ? true : false;
698 ddp_rdma_packetlist(pinfo, info.last_flag, info.opcode);
700 offset = 0;
702 /* determine header length */
703 if (info.is_tagged) {
704 header_end = DDP_TAGGED_HEADER_LEN;
705 } else {
706 header_end = DDP_UNTAGGED_HEADER_LEN;
709 if (info.opcode == RDMA_READ_REQUEST
710 || info.opcode == RDMA_TERMINATE) {
711 header_end = -1;
714 /* DDP/RDMA protocol tree */
715 ddp_rdma_item = proto_tree_add_item(tree, proto_iwarp_ddp_rdmap,
716 tvb, offset, header_end, ENC_NA);
717 ddp_rdma_tree = proto_item_add_subtree(ddp_rdma_item,
718 ett_iwarp_ddp_rdmap);
720 /* DDP protocol header subtree */
721 ddp_item = proto_tree_add_item(ddp_rdma_tree, hf_iwarp_ddp, tvb,
722 offset, header_end, ENC_NA);
723 ddp_tree = proto_item_add_subtree(ddp_item, ett_iwarp_ddp);
725 /* DDP control field */
726 ddp_ctrl_field_item = proto_tree_add_item(ddp_tree,
727 hf_iwarp_ddp_control_field, tvb, offset,
728 DDP_CONTROL_FIELD_LEN, ENC_NA);
729 ddp_ctrl_field_tree = proto_item_add_subtree(ddp_ctrl_field_item,
730 ett_iwarp_ddp);
732 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_t_flag, tvb,
733 offset, DDP_CONTROL_FIELD_LEN, ENC_BIG_ENDIAN);
734 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_l_flag, tvb,
735 offset, DDP_CONTROL_FIELD_LEN, ENC_BIG_ENDIAN);
736 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_rsvd, tvb,
737 offset, DDP_CONTROL_FIELD_LEN, ENC_BIG_ENDIAN);
738 proto_tree_add_item(ddp_ctrl_field_tree, hf_iwarp_ddp_dv, tvb, offset,
739 DDP_CONTROL_FIELD_LEN, ENC_BIG_ENDIAN);
740 offset += DDP_CONTROL_FIELD_LEN;
743 /* DDP header field RsvdULP */
744 if (!info.is_tagged) {
745 proto_tree_add_item(ddp_tree, hf_iwarp_ddp_rsvdulp, tvb,
746 offset, DDP_UNTAGGED_RSVDULP_LEN, ENC_NA);
749 /* RDMA protocol header subtree */
750 if (info.is_tagged) {
751 header_end = RDMA_CONTROL_FIELD_LEN;
752 } else {
753 header_end = RDMA_CONTROL_FIELD_LEN + RDMA_RESERVED_FIELD_LEN;
756 rdma_item = proto_tree_add_item(ddp_rdma_tree, hf_iwarp_rdma, tvb,
757 offset, header_end, ENC_NA);
758 rdma_tree = proto_item_add_subtree(rdma_item, ett_iwarp_rdma);
760 /* RDMA Control Field */
761 rdma_ctrl_field_item = proto_tree_add_item(rdma_tree,
762 hf_iwarp_rdma_control_field, tvb, offset,
763 RDMA_CONTROL_FIELD_LEN, ENC_NA);
764 rdma_ctrl_field_tree = proto_item_add_subtree(rdma_ctrl_field_item,
765 ett_iwarp_rdma);
767 proto_tree_add_item(rdma_ctrl_field_tree, hf_iwarp_rdma_version, tvb,
768 offset, RDMA_CONTROL_FIELD_LEN, ENC_BIG_ENDIAN);
769 proto_tree_add_item(rdma_ctrl_field_tree, hf_iwarp_rdma_rsvd, tvb,
770 offset, RDMA_CONTROL_FIELD_LEN, ENC_BIG_ENDIAN);
771 proto_tree_add_item(rdma_ctrl_field_tree, hf_iwarp_rdma_opcode, tvb,
772 offset, RDMA_CONTROL_FIELD_LEN, ENC_BIG_ENDIAN);
773 offset += RDMA_CONTROL_FIELD_LEN;
775 /* dissection of DDP rsvdULP[8:39] with respect to RDMAP */
776 if (info.opcode == RDMA_READ_REQUEST
777 || info.opcode == RDMA_SEND
778 || info.opcode == RDMA_SEND_SE
779 || info.opcode == RDMA_TERMINATE) {
780 proto_tree_add_item(rdma_tree, hf_iwarp_rdma_reserved,
781 tvb, offset, RDMA_RESERVED_FIELD_LEN, ENC_NA);
784 if (info.opcode == RDMA_SEND_INVALIDATE
785 || info.opcode == RDMA_SEND_SE_INVALIDATE) {
786 proto_tree_add_item(rdma_tree, hf_iwarp_rdma_inval_stag,
787 tvb, offset, RDMA_INVAL_STAG_LEN, ENC_BIG_ENDIAN);
790 if (!info.is_tagged) {
791 offset += RDMA_RESERVED_FIELD_LEN;
794 /* DDP Buffer Model dissection */
795 if (info.is_tagged) {
797 /* Tagged Buffer Model Case */
798 ddp_buffer_model_item = proto_tree_add_item(ddp_tree,
799 hf_iwarp_ddp_tagged_header, tvb, offset,
800 DDP_BUFFER_MODEL_LEN, ENC_NA);
801 ddp_buffer_model_tree = proto_item_add_subtree(ddp_buffer_model_item,
802 ett_iwarp_ddp);
804 proto_tree_add_item_ret_uint(ddp_buffer_model_tree, hf_iwarp_ddp_stag, tvb,
805 offset, DDP_STAG_LEN, ENC_BIG_ENDIAN, &info.steering_tag);
806 offset += DDP_STAG_LEN;
807 proto_tree_add_item_ret_uint64(ddp_buffer_model_tree, hf_iwarp_ddp_to, tvb,
808 offset, DDP_TO_LEN, ENC_BIG_ENDIAN, &info.tagged_offset);
809 offset += DDP_TO_LEN;
811 if( info.opcode == RDMA_READ_RESPONSE
812 || info.opcode == RDMA_WRITE) {
814 /* display the payload */
815 next_tvb = tvb_new_subset_remaining(tvb, DDP_TAGGED_HEADER_LEN);
816 dissect_rdmap_payload(next_tvb, pinfo, tree, &info);
819 } else {
821 /* Untagged Buffer Model Case */
822 ddp_buffer_model_item = proto_tree_add_item(ddp_tree,
823 hf_iwarp_ddp_untagged_header, tvb, offset,
824 DDP_BUFFER_MODEL_LEN, ENC_NA);
825 ddp_buffer_model_tree = proto_item_add_subtree(ddp_buffer_model_item,
826 ett_iwarp_ddp);
828 proto_tree_add_item_ret_uint(ddp_buffer_model_tree, hf_iwarp_ddp_qn, tvb,
829 offset, DDP_QN_LEN, ENC_BIG_ENDIAN, &info.queue_number);
830 offset += DDP_QN_LEN;
831 proto_tree_add_item_ret_uint(ddp_buffer_model_tree, hf_iwarp_ddp_msn, tvb,
832 offset, DDP_MSN_LEN, ENC_BIG_ENDIAN, &info.message_seq_num);
833 offset += DDP_MSN_LEN;
834 proto_tree_add_item_ret_uint(ddp_buffer_model_tree, hf_iwarp_ddp_mo, tvb,
835 offset, DDP_MO_LEN, ENC_BIG_ENDIAN, &info.message_offset);
836 offset += DDP_MO_LEN;
838 if (info.opcode == RDMA_SEND
839 || info.opcode == RDMA_SEND_INVALIDATE
840 || info.opcode == RDMA_SEND_SE
841 || info.opcode == RDMA_SEND_SE_INVALIDATE) {
843 /* display the payload */
844 next_tvb = tvb_new_subset_remaining(tvb, DDP_UNTAGGED_HEADER_LEN);
845 dissect_rdmap_payload(next_tvb, pinfo, tree, &info);
849 /* do further dissection for RDMA messages RDMA Read Request & Terminate */
850 if (info.opcode == RDMA_READ_REQUEST) {
851 offset = dissect_iwarp_rdmap(tvb, pinfo, rdma_tree, offset, &info);
852 /* Call upper layer dissector for message reassembly */
853 next_tvb = tvb_new_subset_remaining(tvb, offset);
854 dissect_rdmap_payload(next_tvb, pinfo, tree, &info);
855 } else if (info.opcode == RDMA_TERMINATE) {
856 dissect_iwarp_rdmap(tvb, pinfo, rdma_tree, offset, &info);
859 /* do further dissection for RDMA messages RDMA Atomic Request & Response */
860 if (info.opcode == RDMA_ATOMIC_REQUEST
861 || info.opcode == RDMA_ATOMIC_RESPONSE) {
862 dissect_iwarp_atomic(tvb, rdma_tree, offset, info.opcode);
865 return tvb_captured_length(tvb);
868 /* register the protocol with Wireshark */
869 void
870 proto_register_iwarp_ddp_rdmap(void)
872 /* setup list of header fields */
873 static hf_register_info hf[] = {
875 /* DDP */
876 { &hf_iwarp_ddp, {
877 "DDP header", "iwarp_ddp",
878 FT_NONE, BASE_NONE, NULL, 0x0,
879 NULL, HFILL } },
880 { &hf_iwarp_ddp_control_field, {
881 "DDP control field", "iwarp_ddp.control_field",
882 FT_NONE, BASE_NONE, NULL, 0x0,
883 NULL, HFILL } },
884 { &hf_iwarp_ddp_tagged_header, {
885 "Tagged buffer model", "iwarp_ddp.tagged",
886 FT_NONE, BASE_NONE, NULL, 0x0,
887 "DDP Tagged Buffer Model Header", HFILL} },
888 { &hf_iwarp_ddp_untagged_header, {
889 "Untagged buffer model", "iwarp_ddp.untagged",
890 FT_NONE, BASE_NONE, NULL, 0x0,
891 "DDP Untagged Buffer Model Header", HFILL} },
892 { &hf_iwarp_ddp_t_flag, {
893 "Tagged flag", "iwarp_ddp.tagged_flag",
894 FT_BOOLEAN, 8, NULL, DDP_TAGGED_FLAG,
895 NULL, HFILL} },
896 { &hf_iwarp_ddp_l_flag, {
897 "Last flag", "iwarp_ddp.last_flag",
898 FT_BOOLEAN, 8, NULL, DDP_LAST_FLAG,
899 NULL, HFILL} },
900 { &hf_iwarp_ddp_rsvd, {
901 "Reserved", "iwarp_ddp.rsvd",
902 FT_UINT8, BASE_HEX, NULL, DDP_RSVD,
903 NULL, HFILL} },
904 { &hf_iwarp_ddp_dv, {
905 "DDP protocol version", "iwarp_ddp.dv",
906 FT_UINT8, BASE_DEC, NULL, DDP_DV,
907 NULL, HFILL} },
908 { &hf_iwarp_ddp_rsvdulp, {
909 "Reserved for use by the ULP", "iwarp_ddp.rsvdulp",
910 FT_BYTES, BASE_NONE, NULL, 0x0,
911 NULL, HFILL} },
912 { &hf_iwarp_ddp_stag, {
913 "(Data Sink) Steering Tag", "iwarp_ddp.stag",
914 FT_UINT32, BASE_HEX, NULL, 0x0,
915 NULL, HFILL} },
916 { &hf_iwarp_ddp_to, {
917 "(Data Sink) Tagged offset", "iwarp_ddp.tagged_offset",
918 FT_UINT64, BASE_HEX, NULL, 0x0,
919 NULL, HFILL} },
920 { &hf_iwarp_ddp_qn, {
921 "Queue number", "iwarp_ddp.qn",
922 FT_UINT32, BASE_DEC, NULL, 0x0,
923 NULL, HFILL} },
924 { &hf_iwarp_ddp_msn, {
925 "Message sequence number", "iwarp_ddp.msn",
926 FT_UINT32, BASE_DEC, NULL, 0x0,
927 NULL, HFILL} },
928 { &hf_iwarp_ddp_mo, {
929 "Message offset", "iwarp_ddp.mo",
930 FT_UINT32, BASE_DEC, NULL, 0x0,
931 NULL, HFILL}
934 /* RDMAP */
935 { &hf_iwarp_rdma, {
936 "RDMAP header", "iwarp_rdma",
937 FT_NONE, BASE_NONE, NULL, 0x0,
938 NULL, HFILL} },
939 { &hf_iwarp_rdma_control_field, {
940 "RDMAP control field", "iwarp_rdma.control_field",
941 FT_NONE, BASE_NONE, NULL, 0x0,
942 "RDMA Control Field", HFILL} },
943 { &hf_iwarp_rdma_version, {
944 "Version", "iwarp_rdma.version",
945 FT_UINT8, BASE_DEC, NULL, RDMA_RV,
946 "RDMA Version Field", HFILL} },
947 { &hf_iwarp_rdma_rsvd, {
948 "Reserved", "iwarp_rdma.rsv",
949 FT_UINT8, BASE_HEX, NULL, RDMA_RSV,
950 "RDMA Control Field Reserved", HFILL} },
951 { &hf_iwarp_rdma_opcode, {
952 "OpCode", "iwarp_rdma.opcode",
953 FT_UINT8, BASE_HEX, VALS(rdmap_messages), RDMA_OPCODE,
954 "RDMA OpCode Field", HFILL} },
955 { &hf_iwarp_rdma_reserved, {
956 "Reserved", "iwarp_rdma.reserved",
957 FT_BYTES, BASE_NONE, NULL, 0x0,
958 NULL, HFILL} },
959 { &hf_iwarp_rdma_inval_stag, {
960 "Invalidate STag", "iwarp_rdma.inval_stag",
961 FT_UINT32, BASE_DEC, NULL, 0x0,
962 "RDMA Invalidate STag", HFILL} },
963 { &hf_iwarp_rdma_rr_header, {
964 "Read request", "iwarp_rdma.rr",
965 FT_NONE, BASE_NONE, NULL, 0x0,
966 "RDMA Read Request Header", HFILL} },
967 { &hf_iwarp_rdma_terminate_header, {
968 "Terminate", "iwarp_rdma.terminate",
969 FT_NONE, BASE_NONE, NULL, 0x0,
970 "RDMA Terminate Header", HFILL} },
971 { &hf_iwarp_rdma_sinkstag, {
972 "Data Sink STag", "iwarp_rdma.sinkstag",
973 FT_UINT32, BASE_HEX, NULL, 0x0,
974 NULL, HFILL} },
975 { &hf_iwarp_rdma_sinkto, {
976 "Data Sink Tagged Offset", "iwarp_rdma.sinkto",
977 FT_UINT64, BASE_HEX, NULL, 0x0,
978 NULL, HFILL} },
979 { &hf_iwarp_rdma_rdmardsz, {
980 "RDMA Read Message Size", "iwarp_rdma.rdmardsz",
981 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, UNS(&units_byte_bytes), 0x0,
982 NULL, HFILL} },
983 { &hf_iwarp_rdma_srcstag, {
984 "Data Source STag", "iwarp_rdma.srcstag",
985 FT_UINT32, BASE_HEX, NULL, 0x0,
986 NULL, HFILL} },
987 { &hf_iwarp_rdma_srcto, {
988 "Data Source Tagged Offset", "iwarp_rdma.srcto",
989 FT_UINT64, BASE_HEX, NULL, 0x0,
990 NULL, HFILL} },
991 { &hf_iwarp_rdma_term_ctrl, {
992 "Terminate Control", "iwarp_rdma.term_ctrl",
993 FT_NONE, BASE_NONE, NULL, 0x0,
994 "RDMA Terminate Control Field", HFILL} },
995 { &hf_iwarp_rdma_term_layer, {
996 "Layer", "iwarp_rdma.term_layer",
997 FT_UINT8, BASE_HEX, VALS(layer_names), IWARP_LAYER,
998 "Terminate Control Field: Layer", HFILL} },
999 { &hf_iwarp_rdma_term_etype_rdma, {
1000 "Error Types for RDMA layer", "iwarp_rdma.term_etype_rdma",
1001 FT_UINT8, BASE_HEX, VALS(rdma_etype_names), IWARP_ETYPE,
1002 "Terminate Control Field: Error Type", HFILL} },
1003 { &hf_iwarp_rdma_term_etype_ddp, {
1004 "Error Types for DDP layer", "iwarp_rdma.term_etype_ddp",
1005 FT_UINT8, BASE_HEX, VALS(ddp_etype_names), IWARP_ETYPE,
1006 "Terminate Control Field: Error Type", HFILL} },
1007 { &hf_iwarp_rdma_term_etype_llp, {
1008 "Error Types for LLP layer", "iwarp_rdma.term_etype_llp",
1009 FT_UINT8, BASE_HEX, VALS(mpa_etype_names), IWARP_ETYPE,
1010 "Terminate Control Field: Error Type", HFILL} },
1011 { &hf_iwarp_rdma_term_etype, {
1012 "Error Types", "iwarp_rdma.term_etype",
1013 FT_UINT8, BASE_HEX, NULL, IWARP_ETYPE,
1014 "Terminate Control Field: Error Type", HFILL} },
1015 { &hf_iwarp_rdma_term_errcode_rdma, {
1016 "Error Code for RDMA layer", "iwarp_rdma.term_errcode_rdma",
1017 FT_UINT8, BASE_HEX, VALS(rdma_errcode_names), 0x0,
1018 "Terminate Control Field: Error Code", HFILL} },
1019 { &hf_iwarp_rdma_term_errcode_ddp_tagged, {
1020 "Error Code for DDP Tagged Buffer",
1021 "iwarp_rdma.term_errcode_ddp_tagged",
1022 FT_UINT8, BASE_HEX, VALS(ddp_errcode_tagged_names), 0x0,
1023 "Terminate Control Field: Error Code", HFILL} },
1024 { &hf_iwarp_rdma_term_errcode_ddp_untagged, {
1025 "Error Code for DDP Untagged Buffer",
1026 "iwarp_rdma.term_errcode_ddp_untagged",
1027 FT_UINT8, BASE_HEX, VALS(ddp_errcode_untagged_names), 0x0,
1028 "Terminate Control Field: Error Code", HFILL} },
1029 { &hf_iwarp_rdma_term_errcode, {
1030 "Error Code", "iwarp_rdma.term_errcode",
1031 FT_UINT8, BASE_HEX, NULL, 0x0,
1032 "Terminate Control Field: Error Code", HFILL} },
1033 { &hf_iwarp_rdma_term_errcode_llp, {
1034 "Error Code for LLP layer", "iwarp_rdma.term_errcode_llp",
1035 FT_UINT8, BASE_HEX, VALS(mpa_errcode_names), 0x0,
1036 "Terminate Control Field: Lower Layer Protocol Error Code",
1037 HFILL} },
1038 { &hf_iwarp_rdma_term_hdrct, {
1039 "Header control bits", "iwarp_rdma.term_hdrct",
1040 FT_NONE, BASE_NONE, NULL, 0x0,
1041 "Terminate Control Field: Header control bits", HFILL} },
1042 { &hf_iwarp_rdma_term_hdrct_m, {
1043 "M bit", "iwarp_rdma.term_hdrct_m",
1044 FT_BOOLEAN, 8, TFS(&tfs_set_notset), IWARP_HDRCT_M,
1045 "Header control bit m: DDP Segment Length valid", HFILL} },
1046 { &hf_iwarp_rdma_term_hdrct_d, {
1047 "D bit", "iwarp_rdma.hdrct_d",
1048 FT_BOOLEAN, 8, TFS(&tfs_set_notset), IWARP_HDRCT_D,
1049 "Header control bit d: DDP Header Included", HFILL} },
1050 { &hf_iwarp_rdma_term_hdrct_r, {
1051 "R bit", "iwarp_rdma.hdrct_r",
1052 FT_BOOLEAN, 8, TFS(&tfs_set_notset), IWARP_HDRCT_R,
1053 "Header control bit r: RDMAP Header Included", HFILL} },
1054 { &hf_iwarp_rdma_term_rsvd, {
1055 "Reserved", "iwarp_rdma.term_rsvd",
1056 FT_UINT16, BASE_HEX, NULL, IWARP_TERM_RES,
1057 NULL, HFILL} },
1058 { &hf_iwarp_rdma_term_ddp_seg_len, {
1059 "DDP Segment Length", "iwarp_rdma.term_ddp_seg_len",
1060 FT_BYTES, BASE_NONE, NULL, 0x0,
1061 NULL, HFILL} },
1062 { &hf_iwarp_rdma_term_ddp_h, {
1063 "Terminated DDP Header", "iwarp_rdma.term_ddp_h",
1064 FT_BYTES, BASE_NONE, NULL, 0x0,
1065 NULL, HFILL} },
1066 { &hf_iwarp_rdma_term_rdma_h, {
1067 "Terminated RDMA Header", "iwarp_rdma.term_rdma_h",
1068 FT_BYTES, BASE_NONE, NULL, 0x0,
1069 NULL, HFILL} },
1071 /* Atomic */
1072 { &hf_iwarp_rdma_atomic_reserved, {
1073 "Reserved", "iwarp_rdma.atomic.reserved",
1074 FT_UINT32, BASE_DEC, NULL, 0xFFFFFFF0,
1075 NULL, HFILL} },
1076 { &hf_iwarp_rdma_atomic_opcode, {
1077 "OpCode", "iwarp_rdma.atomic.opcode",
1078 FT_UINT32, BASE_DEC, VALS(rdma_atomic_opcode_names), 0x0000000F,
1079 NULL, HFILL} },
1080 { &hf_iwarp_rdma_atomic_request_identifier, {
1081 "Request Identifier", "iwarp_rdma.atomic.request_identifier",
1082 FT_UINT32, BASE_DEC, NULL, 0x0,
1083 NULL, HFILL} },
1084 { &hf_iwarp_rdma_atomic_remote_stag, {
1085 "Remote STag", "iwarp_rdma.atomic.remote_stag",
1086 FT_UINT32, BASE_DEC, NULL, 0x0,
1087 NULL, HFILL} },
1088 { &hf_iwarp_rdma_atomic_remote_tagged_offset, {
1089 "Remote Tagged Offset", "iwarp_rdma.atomic.remote_tagged_offset",
1090 FT_UINT64, BASE_DEC, NULL, 0x0,
1091 NULL, HFILL} },
1092 { &hf_iwarp_rdma_atomic_add_data, {
1093 "Add Data", "iwarp_rdma.atomic.add_data",
1094 FT_UINT64, BASE_DEC, NULL, 0x0,
1095 NULL, HFILL} },
1096 { &hf_iwarp_rdma_atomic_add_mask, {
1097 "Add Mask", "iwarp_rdma.atomic.add_mask",
1098 FT_UINT64, BASE_HEX, NULL, 0x0,
1099 NULL, HFILL} },
1100 { &hf_iwarp_rdma_atomic_swap_data, {
1101 "Swap Data", "iwarp_rdma.atomic.swap_data",
1102 FT_UINT64, BASE_DEC, NULL, 0x0,
1103 NULL, HFILL} },
1104 { &hf_iwarp_rdma_atomic_swap_mask, {
1105 "Swap Mask", "iwarp_rdma.atomic.swap_mask",
1106 FT_UINT64, BASE_HEX, NULL, 0x0,
1107 NULL, HFILL} },
1108 { &hf_iwarp_rdma_atomic_compare_data, {
1109 "Compare Data", "iwarp_rdma.atomic.compare_data",
1110 FT_UINT64, BASE_DEC, NULL, 0x0,
1111 NULL, HFILL} },
1112 { &hf_iwarp_rdma_atomic_compare_mask, {
1113 "Compare Mask", "iwarp_rdma.atomic.compare_mask",
1114 FT_UINT64, BASE_HEX, NULL, 0x0,
1115 NULL, HFILL} },
1116 { &hf_iwarp_rdma_atomic_original_request_identifier, {
1117 "Original Request Identifier", "iwarp_rdma.atomic.original_request_identifier",
1118 FT_UINT32, BASE_DEC, NULL, 0x0,
1119 NULL, HFILL} },
1120 { &hf_iwarp_rdma_atomic_original_remote_data_value, {
1121 "Original Request Identifier", "iwarp_rdma.atomic.original_remote_data_value",
1122 FT_UINT64, BASE_DEC, NULL, 0x0,
1123 NULL, HFILL} },
1125 { &hf_iwarp_rdma_send_fragments, {
1126 "Reassembled iWarp RDMA Send Fragments", "iwarp_rdma.send.fragments",
1127 FT_NONE, BASE_NONE, NULL, 0,
1128 NULL, HFILL} },
1129 { &hf_iwarp_rdma_send_fragment, {
1130 "iWarp RDMA Send Fragment", "iwarp_rdma.send.fragment",
1131 FT_FRAMENUM, BASE_NONE, NULL, 0,
1132 NULL, HFILL} },
1133 { &hf_iwarp_rdma_send_fragment_overlap, {
1134 "Fragment overlap", "iwarp_rdma.send.fragment.overlap",
1135 FT_BOOLEAN, BASE_NONE, NULL, 0,
1136 NULL, HFILL} },
1137 { &hf_iwarp_rdma_send_fragment_overlap_conflict, {
1138 "Conflicting data in fragment overlap", "iwarp_rdma.send.fragment.overlap.conflict",
1139 FT_BOOLEAN, BASE_NONE, NULL, 0,
1140 NULL, HFILL} },
1141 { &hf_iwarp_rdma_send_fragment_multiple_tails, {
1142 "Multiple tail fragments found", "iwarp_rdma.send.fragment.multipletails",
1143 FT_BOOLEAN, BASE_NONE, NULL, 0,
1144 NULL, HFILL} },
1145 { &hf_iwarp_rdma_send_fragment_too_long_fragment, {
1146 "Fragment too long", "iwarp_rdma.send.fragment.toolongfragment",
1147 FT_BOOLEAN, BASE_NONE, NULL, 0,
1148 NULL, HFILL} },
1149 { &hf_iwarp_rdma_send_fragment_error, {
1150 "Defragmentation error", "iwarp_rdma.send.fragment.error",
1151 FT_FRAMENUM, BASE_NONE, NULL, 0,
1152 NULL, HFILL} },
1153 { &hf_iwarp_rdma_send_fragment_count, {
1154 "Fragment count", "iwarp_rdma.send.fragment.count",
1155 FT_UINT32, BASE_DEC, NULL, 0x0,
1156 NULL, HFILL} },
1157 { &hf_iwarp_rdma_send_reassembled_in, {
1158 "Reassembled PDU in frame", "iwarp_rdma.send.reassembled_in",
1159 FT_FRAMENUM, BASE_NONE, NULL, 0,
1160 NULL, HFILL} },
1161 { &hf_iwarp_rdma_send_reassembled_length, {
1162 "Reassembled iWarp RDMA Send length", "iwarp_rdma.send.reassembled.length",
1163 FT_UINT32, BASE_DEC, NULL, 0,
1164 NULL, HFILL} },
1165 { &hf_iwarp_rdma_send_reassembled_data, {
1166 "Reassembled iWarp RDMA Send data", "iwarp_rdma.send.reassembled.data",
1167 FT_BYTES, BASE_NONE, NULL, 0,
1168 NULL, HFILL} },
1171 /* setup protocol subtree array */
1172 static int *ett[] = {
1174 &ett_iwarp_ddp_rdmap,
1176 /* DDP */
1177 &ett_iwarp_ddp,
1179 &ett_iwarp_ddp_control_field,
1180 &ett_iwarp_ddp_tagged_header,
1181 &ett_iwarp_ddp_untagged_header,
1183 /* RDMAP */
1184 &ett_iwarp_rdma,
1186 &ett_iwarp_rdma_control_field,
1187 &ett_iwarp_rdma_rr_header,
1188 &ett_iwarp_rdma_terminate_header,
1189 &ett_iwarp_rdma_term_ctrl,
1190 &ett_iwarp_rdma_term_hdrct,
1192 &ett_iwarp_rdma_send_fragment,
1193 &ett_iwarp_rdma_send_fragments,
1195 module_t *iwarp_dep_rdmap_module;
1197 /* register the protocol name and description */
1198 proto_iwarp_ddp_rdmap = proto_register_protocol("iWARP Direct Data Placement and Remote Direct Memory Access Protocol", "IWARP_DDP_RDMAP", "iwarp_ddp_rdmap");
1200 /* required function calls to register the header fields and subtrees */
1201 proto_register_field_array(proto_iwarp_ddp_rdmap, hf, array_length(hf));
1202 proto_register_subtree_array(ett, array_length(ett));
1204 rdmap_heur_subdissector_list = register_heur_dissector_list_with_description("iwarp_ddp_rdmap", "iWARP RDMAP payload", proto_iwarp_ddp_rdmap);
1206 register_dissector("iwarp_ddp_rdmap", dissect_iwarp_ddp_rdmap,
1207 proto_iwarp_ddp_rdmap);
1209 iwarp_dep_rdmap_module = prefs_register_protocol(proto_iwarp_ddp_rdmap, NULL);
1210 prefs_register_bool_preference(iwarp_dep_rdmap_module,
1211 "reassemble_iwarp_rdma_send",
1212 "Reassemble iWarp RDMA Send fragments",
1213 "Whether the iWarp RDMA dissector should reassemble Send fragmented payloads",
1214 &iwarp_rdma_send_reassemble);
1215 reassembly_table_register(&iwarp_rdma_send_reassembly_table,
1216 &addresses_ports_reassembly_table_functions);
1220 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1222 * Local variables:
1223 * c-basic-offset: 8
1224 * tab-width: 8
1225 * indent-tabs-mode: t
1226 * End:
1228 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1229 * :indentSize=8:tabSize=8:noTabs=false: