Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-smb-direct.c
bloba1e9e26eff53749ec51b4ca1a90f58cb6cddfc14
1 /*
2 * packet-smb-direct.c
4 * Routines for [MS-SMBD] the RDMA transport layer for SMB2/3
6 * Copyright 2012-2014 Stefan Metzmacher <metze@samba.org>
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 #include "config.h"
17 #include <epan/packet.h>
18 #include <epan/reassemble.h>
19 #include <epan/prefs.h>
20 #include <epan/proto_data.h>
21 #include "packet-windows-common.h"
22 #include "packet-iwarp-ddp-rdmap.h"
23 #include "packet-infiniband.h"
25 void proto_register_smb_direct(void);
26 void proto_reg_handoff_smb_direct(void);
28 static dissector_handle_t smb_direct_handle;
30 static int proto_smb_direct;
32 static int ett_smb_direct;
33 static int ett_smb_direct_hdr;
34 static int ett_smb_direct_flags;
35 static int ett_smb_direct_fragment;
36 static int ett_smb_direct_fragments;
38 static int hf_smb_direct_negotiate_request;
39 static int hf_smb_direct_negotiate_response;
40 static int hf_smb_direct_data_message;
41 static int hf_smb_direct_min_version;
42 static int hf_smb_direct_max_version;
43 static int hf_smb_direct_negotiated_version;
44 static int hf_smb_direct_credits_requested;
45 static int hf_smb_direct_credits_granted;
46 static int hf_smb_direct_status;
47 static int hf_smb_direct_max_read_write_size;
48 static int hf_smb_direct_preferred_send_size;
49 static int hf_smb_direct_max_receive_size;
50 static int hf_smb_direct_max_fragmented_size;
51 static int hf_smb_direct_flags;
52 static int hf_smb_direct_flags_response_requested;
53 static int hf_smb_direct_remaining_length;
54 static int hf_smb_direct_data_offset;
55 static int hf_smb_direct_data_length;
56 static int hf_smb_direct_fragments;
57 static int hf_smb_direct_fragment;
58 static int hf_smb_direct_fragment_overlap;
59 static int hf_smb_direct_fragment_overlap_conflict;
60 static int hf_smb_direct_fragment_multiple_tails;
61 static int hf_smb_direct_fragment_too_long_fragment;
62 static int hf_smb_direct_fragment_error;
63 static int hf_smb_direct_fragment_count;
64 static int hf_smb_direct_reassembled_in;
65 static int hf_smb_direct_reassembled_length;
66 static int hf_smb_direct_reassembled_data;
68 static const fragment_items smb_direct_frag_items = {
69 &ett_smb_direct_fragment,
70 &ett_smb_direct_fragments,
71 &hf_smb_direct_fragments,
72 &hf_smb_direct_fragment,
73 &hf_smb_direct_fragment_overlap,
74 &hf_smb_direct_fragment_overlap_conflict,
75 &hf_smb_direct_fragment_multiple_tails,
76 &hf_smb_direct_fragment_too_long_fragment,
77 &hf_smb_direct_fragment_error,
78 &hf_smb_direct_fragment_count,
79 &hf_smb_direct_reassembled_in,
80 &hf_smb_direct_reassembled_length,
81 &hf_smb_direct_reassembled_data,
82 "SMB Direct fragments"
85 enum SMB_DIRECT_HDR_TYPE {
86 SMB_DIRECT_HDR_UNKNOWN = -1,
87 SMB_DIRECT_HDR_NEG_REQ = 1,
88 SMB_DIRECT_HDR_NEG_REP = 2,
89 SMB_DIRECT_HDR_DATA = 3
92 #define SMB_DIRECT_RESPONSE_REQUESTED 0x0001
94 static heur_dissector_list_t smb_direct_heur_subdissector_list;
96 static bool smb_direct_reassemble = true;
97 static reassembly_table smb_direct_reassembly_table;
99 static void
100 dissect_smb_direct_payload(tvbuff_t *tvb, packet_info *pinfo,
101 proto_tree *tree, uint32_t remaining_length)
103 bool save_fragmented = pinfo->fragmented;
104 int save_visited = pinfo->fd->visited;
105 conversation_t *conversation = NULL;
106 fragment_head *fd_head = NULL;
107 tvbuff_t *payload_tvb = NULL;
108 bool more_frags = false;
109 bool fd_head_not_cached = false;
110 heur_dtbl_entry_t *hdtbl_entry;
112 if (!smb_direct_reassemble) {
113 payload_tvb = tvb;
114 goto dissect_payload;
117 conversation = find_or_create_conversation(pinfo);
119 if (remaining_length > 0) {
120 more_frags = true;
123 fd_head = (fragment_head *)p_get_proto_data(wmem_file_scope(), pinfo, proto_smb_direct, 0);
124 if (fd_head == NULL) {
125 fd_head_not_cached = true;
127 pinfo->fd->visited = 0;
128 fd_head = fragment_add_seq_next(&smb_direct_reassembly_table,
129 tvb, 0, pinfo,
130 conversation->conv_index,
131 NULL, tvb_captured_length(tvb),
132 more_frags);
135 if (fd_head == NULL) {
137 * We really want the fd_head and pass it to
138 * process_reassembled_data()
140 * So that individual fragments gets the
141 * reassembled in field.
143 fd_head = fragment_get_reassembled_id(&smb_direct_reassembly_table,
144 pinfo,
145 conversation->conv_index);
148 if (fd_head == NULL) {
150 * we need more data...
152 goto done;
155 if (fd_head_not_cached) {
156 p_add_proto_data(wmem_file_scope(), pinfo,
157 proto_smb_direct, 0, fd_head);
160 payload_tvb = process_reassembled_data(tvb, 0, pinfo,
161 "Reassembled SMB Direct",
162 fd_head,
163 &smb_direct_frag_items,
164 NULL, /* update_col_info*/
165 tree);
166 if (payload_tvb == NULL) {
168 * we need more data...
170 goto done;
173 dissect_payload:
174 pinfo->fragmented = false;
175 if (!dissector_try_heuristic(smb_direct_heur_subdissector_list,
176 payload_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
177 call_data_dissector(payload_tvb, pinfo, tree);
179 done:
180 pinfo->fragmented = save_fragmented;
181 pinfo->fd->visited = save_visited;
182 return;
185 static void
186 dissect_smb_direct(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
187 enum SMB_DIRECT_HDR_TYPE hdr_type)
190 proto_tree *tree = NULL;
191 proto_item *item = NULL;
192 proto_tree *neg_req_tree = NULL;
193 proto_tree *neg_rep_tree = NULL;
194 proto_tree *data_tree = NULL;
195 int offset = 0;
196 uint32_t status = 0;
197 uint32_t remaining_length = 0;
198 uint32_t data_offset = 0;
199 uint32_t data_length = 0;
200 unsigned rlen = tvb_reported_length(tvb);
201 int len = 0;
202 tvbuff_t *next_tvb = NULL;
203 static int * const flags[] = {
204 &hf_smb_direct_flags_response_requested,
205 NULL
208 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMBDirect");
209 col_clear(pinfo->cinfo, COL_INFO);
211 if (parent_tree != NULL) {
212 item = proto_tree_add_item(parent_tree, proto_smb_direct, tvb, 0, -1, ENC_NA);
213 tree = proto_item_add_subtree(item, ett_smb_direct);
216 switch (hdr_type) {
217 case SMB_DIRECT_HDR_UNKNOWN:
218 break;
220 case SMB_DIRECT_HDR_NEG_REQ:
221 col_append_str(pinfo->cinfo, COL_INFO, "NegotiateRequest");
223 if (tree == NULL) {
224 break;
227 item = proto_tree_add_item(tree, hf_smb_direct_negotiate_request, tvb, 0, -1, ENC_NA);
228 neg_req_tree = proto_item_add_subtree(item, ett_smb_direct_hdr);
230 proto_tree_add_item(neg_req_tree, hf_smb_direct_min_version,
231 tvb, offset, 2, ENC_LITTLE_ENDIAN);
232 offset += 2;
234 proto_tree_add_item(neg_req_tree, hf_smb_direct_max_version,
235 tvb, offset, 2, ENC_LITTLE_ENDIAN);
236 offset += 2;
238 /* 2 bytes reserved */
239 offset += 2;
241 proto_tree_add_item(neg_req_tree, hf_smb_direct_credits_requested,
242 tvb, offset, 2, ENC_LITTLE_ENDIAN);
243 offset += 2;
245 proto_tree_add_item(neg_req_tree, hf_smb_direct_preferred_send_size,
246 tvb, offset, 4, ENC_LITTLE_ENDIAN);
247 offset += 4;
249 proto_tree_add_item(neg_req_tree, hf_smb_direct_max_receive_size,
250 tvb, offset, 4, ENC_LITTLE_ENDIAN);
251 offset += 4;
253 proto_tree_add_item(neg_req_tree, hf_smb_direct_max_fragmented_size,
254 tvb, offset, 4, ENC_LITTLE_ENDIAN);
255 /* offset += 4; */
256 break;
258 case SMB_DIRECT_HDR_NEG_REP:
259 col_append_str(pinfo->cinfo, COL_INFO, "NegotiateResponse");
261 status = tvb_get_letohl(tvb, 12);
262 if (status != 0) {
263 col_append_fstr(
264 pinfo->cinfo, COL_INFO, ", Error: %s",
265 val_to_str_ext(status, &NT_errors_ext, "Unknown (0x%08X)"));
268 if (tree == NULL) {
269 break;
272 item = proto_tree_add_item(tree, hf_smb_direct_negotiate_response, tvb, 0, -1, ENC_NA);
273 neg_rep_tree = proto_item_add_subtree(item, ett_smb_direct_hdr);
275 proto_tree_add_item(neg_rep_tree, hf_smb_direct_min_version,
276 tvb, offset, 2, ENC_LITTLE_ENDIAN);
277 offset += 2;
279 proto_tree_add_item(neg_rep_tree, hf_smb_direct_max_version,
280 tvb, offset, 2, ENC_LITTLE_ENDIAN);
281 offset += 2;
283 proto_tree_add_item(neg_rep_tree, hf_smb_direct_negotiated_version,
284 tvb, offset, 2, ENC_LITTLE_ENDIAN);
285 offset += 2;
287 /* 2 bytes reserved */
288 offset += 2;
290 proto_tree_add_item(neg_rep_tree, hf_smb_direct_credits_requested,
291 tvb, offset, 2, ENC_LITTLE_ENDIAN);
292 offset += 2;
294 proto_tree_add_item(neg_rep_tree, hf_smb_direct_credits_granted,
295 tvb, offset, 2, ENC_LITTLE_ENDIAN);
296 offset += 2;
298 proto_tree_add_item(neg_rep_tree, hf_smb_direct_status,
299 tvb, offset, 4, ENC_LITTLE_ENDIAN);
300 offset += 4;
302 proto_tree_add_item(neg_rep_tree, hf_smb_direct_max_read_write_size,
303 tvb, offset, 4, ENC_LITTLE_ENDIAN);
304 offset += 4;
306 proto_tree_add_item(neg_rep_tree, hf_smb_direct_preferred_send_size,
307 tvb, offset, 4, ENC_LITTLE_ENDIAN);
308 offset += 4;
310 proto_tree_add_item(neg_rep_tree, hf_smb_direct_max_receive_size,
311 tvb, offset, 4, ENC_LITTLE_ENDIAN);
312 offset += 4;
314 proto_tree_add_item(neg_rep_tree, hf_smb_direct_max_fragmented_size,
315 tvb, offset, 4, ENC_LITTLE_ENDIAN);
316 /* offset += 4; */
317 break;
319 case SMB_DIRECT_HDR_DATA:
320 col_append_str(pinfo->cinfo, COL_INFO, "DataMessage");
322 rlen = MIN(rlen, 24);
324 item = proto_tree_add_item(tree, hf_smb_direct_data_message, tvb, 0, rlen, ENC_NA);
325 data_tree = proto_item_add_subtree(item, ett_smb_direct_hdr);
327 proto_tree_add_item(data_tree, hf_smb_direct_credits_requested,
328 tvb, offset, 2, ENC_LITTLE_ENDIAN);
329 offset += 2;
331 proto_tree_add_item(data_tree, hf_smb_direct_credits_granted,
332 tvb, offset, 2, ENC_LITTLE_ENDIAN);
333 offset += 2;
335 proto_tree_add_bitmask(data_tree, tvb, offset, hf_smb_direct_flags,
336 ett_smb_direct_flags, flags, ENC_LITTLE_ENDIAN);
337 offset += 2;
339 /* 2 bytes reserved */
340 offset += 2;
342 remaining_length = tvb_get_letohl(tvb, offset);
343 proto_tree_add_item(data_tree, hf_smb_direct_remaining_length,
344 tvb, offset, 4, ENC_LITTLE_ENDIAN);
345 offset += 4;
347 data_offset = tvb_get_letohl(tvb, offset);
348 proto_tree_add_item(data_tree, hf_smb_direct_data_offset,
349 tvb, offset, 4, ENC_LITTLE_ENDIAN);
350 offset += 4;
352 data_length = tvb_get_letohl(tvb, offset);
353 proto_tree_add_item(data_tree, hf_smb_direct_data_length,
354 tvb, offset, 4, ENC_LITTLE_ENDIAN);
355 offset += 4;
357 if (data_length > 0 && data_offset > (uint32_t)offset) {
358 len = tvb_reported_length_remaining(tvb, data_offset);
361 if (data_length <= (uint32_t)len) {
362 next_tvb = tvb_new_subset_length(tvb, data_offset,
363 data_length);
366 if (next_tvb != NULL) {
367 dissect_smb_direct_payload(next_tvb, pinfo,
368 parent_tree, remaining_length);
371 /* offset = data_offset + data_length; */
372 break;
375 return;
378 static enum SMB_DIRECT_HDR_TYPE
379 is_smb_direct(tvbuff_t *tvb, packet_info *pinfo _U_)
381 bool maybe_neg_req = false;
382 bool maybe_data = false;
383 unsigned len = tvb_reported_length(tvb);
385 if (len < 20) {
386 return SMB_DIRECT_HDR_UNKNOWN;
389 if (len == 32 &&
390 tvb_get_letohs(tvb, 0) == 0x0100 && /* min version */
391 tvb_get_letohs(tvb, 2) == 0x0100 && /* max version */
392 tvb_get_letohs(tvb, 4) == 0x0100 && /* negotiated version */
393 tvb_get_letohs(tvb, 6) == 0x0000) /* reserved */
395 /* Negotiate Response */
396 return SMB_DIRECT_HDR_NEG_REP;
399 if (tvb_get_letohs(tvb, 0) == 0x0100 && /* min version */
400 tvb_get_letohs(tvb, 2) == 0x0100 && /* max version */
401 tvb_get_letohs(tvb, 4) == 0x0000) /* reserved */
403 maybe_neg_req = true;
406 if (tvb_get_letohs(tvb, 0) <= 255 && /* credits up to 255 */
407 tvb_get_letohs(tvb, 2) <= 255 && /* credits up to 255 */
408 tvb_get_letohs(tvb, 4) <= 1 && /* flags 0 or 1 */
409 tvb_get_letohs(tvb, 6) == 0) /* reserved */
411 maybe_data = true;
414 if (len == 20) {
415 if (tvb_get_letohl(tvb, 8) != 0) { /* remaining */
416 maybe_data = false;
418 if (tvb_get_letohl(tvb, 12) != 0) { /* data offset */
419 maybe_data = false;
421 if (tvb_get_letohl(tvb, 16) != 0) { /* data length */
422 maybe_data = false;
425 if (maybe_neg_req && !maybe_data) {
426 /* Negotiate Request */
427 return SMB_DIRECT_HDR_NEG_REQ;
429 /* maybe_neg_req = false; */
430 if (maybe_data) {
431 /* Data Message */
432 return SMB_DIRECT_HDR_DATA;
436 if (len <= 24) {
437 return SMB_DIRECT_HDR_UNKNOWN;
440 if (tvb_get_letohl(tvb, 12) != 24) { /* data offset */
441 return SMB_DIRECT_HDR_UNKNOWN;
444 if (tvb_get_letohl(tvb, 16) == 0) { /* data length */
445 return SMB_DIRECT_HDR_UNKNOWN;
448 if (tvb_get_letohl(tvb, 20) != 0) { /* padding */
449 return SMB_DIRECT_HDR_UNKNOWN;
452 if (maybe_data) {
453 /* Data Message */
454 return SMB_DIRECT_HDR_DATA;
457 return SMB_DIRECT_HDR_UNKNOWN;
460 static bool
461 dissect_smb_direct_iwarp_heur(tvbuff_t *tvb, packet_info *pinfo,
462 proto_tree *parent_tree, void *data)
464 struct rdmapinfo *info = (struct rdmapinfo *)data;
465 enum SMB_DIRECT_HDR_TYPE hdr_type;
467 if (info == NULL) {
468 return false;
471 switch (info->opcode) {
472 case RDMA_SEND:
473 case RDMA_SEND_INVALIDATE:
474 case RDMA_SEND_SE:
475 case RDMA_SEND_SE_INVALIDATE:
476 break;
477 default:
478 return false;
481 hdr_type = is_smb_direct(tvb, pinfo);
482 if (hdr_type == SMB_DIRECT_HDR_UNKNOWN) {
483 return false;
486 dissect_smb_direct(tvb, pinfo, parent_tree, hdr_type);
487 return true;
490 static int
491 dissect_smb_direct_infiniband(tvbuff_t *tvb, packet_info *pinfo,
492 proto_tree *parent_tree, void *data)
494 struct infinibandinfo *info = (struct infinibandinfo *)data;
495 enum SMB_DIRECT_HDR_TYPE hdr_type;
497 if (info == NULL) {
498 return 0;
501 switch (info->opCode) {
502 case RC_SEND_FIRST:
503 case RC_SEND_MIDDLE:
504 case RC_SEND_LAST:
505 case RC_SEND_LAST_IMM:
506 case RC_SEND_ONLY:
507 case RC_SEND_ONLY_IMM:
508 case RC_SEND_LAST_INVAL:
509 case RC_SEND_ONLY_INVAL:
510 break;
511 default:
512 return 0;
515 hdr_type = is_smb_direct(tvb, pinfo);
516 if (hdr_type == SMB_DIRECT_HDR_UNKNOWN) {
517 return 0;
520 dissect_smb_direct(tvb, pinfo, parent_tree, hdr_type);
521 return tvb_captured_length(tvb);
524 static bool
525 dissect_smb_direct_infiniband_heur(tvbuff_t *tvb, packet_info *pinfo,
526 proto_tree *parent_tree, void *data)
528 return (dissect_smb_direct_infiniband(tvb, pinfo, parent_tree, data) > 0);
531 void proto_register_smb_direct(void)
533 static int *ett[] = {
534 &ett_smb_direct,
535 &ett_smb_direct_hdr,
536 &ett_smb_direct_flags,
537 &ett_smb_direct_fragment,
538 &ett_smb_direct_fragments,
541 static hf_register_info hf[] = {
542 { &hf_smb_direct_negotiate_request,
543 { "NegotiateRequest", "smb_direct.negotiate_request",
544 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
546 { &hf_smb_direct_negotiate_response,
547 { "NegotiateResponse", "smb_direct.negotiate_response",
548 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
550 { &hf_smb_direct_data_message,
551 { "DataMessage", "smb_direct.data_message",
552 FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
554 { &hf_smb_direct_min_version,
555 { "MinVersion", "smb_direct.version.min",
556 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
558 { &hf_smb_direct_max_version,
559 { "MaxVersion", "smb_direct.version.max",
560 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
562 { &hf_smb_direct_negotiated_version,
563 { "NegotiatedVersion", "smb_direct.version.negotiated",
564 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
566 { &hf_smb_direct_credits_requested,
567 { "CreditsRequested", "smb_direct.credits.requested",
568 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
570 { &hf_smb_direct_credits_granted,
571 { "CreditsGranted", "smb_direct.credits.granted",
572 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},
574 { &hf_smb_direct_status,
575 { "Status", "smb_direct.status",
576 FT_UINT32, BASE_HEX|BASE_EXT_STRING, &NT_errors_ext, 0,
577 "NT Status code", HFILL }},
579 { &hf_smb_direct_max_read_write_size,
580 { "MaxReadWriteSize", "smb_direct.max_read_write_size",
581 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
583 { &hf_smb_direct_preferred_send_size,
584 { "PreferredSendSize", "smb_direct.preferred_send_size",
585 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
587 { &hf_smb_direct_max_receive_size,
588 { "MaxReceiveSize", "smb_direct.max_receive_size",
589 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
591 { &hf_smb_direct_max_fragmented_size,
592 { "MaxFragmentedSize", "smb_direct.max_fragmented_size",
593 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
595 { &hf_smb_direct_flags,
596 { "Flags", "smb_direct.flags",
597 FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }},
599 { &hf_smb_direct_flags_response_requested,
600 { "ResponseRequested", "smb_direct.flags.response_requested",
601 FT_BOOLEAN, 16, NULL, SMB_DIRECT_RESPONSE_REQUESTED,
602 NULL, HFILL }},
604 { &hf_smb_direct_remaining_length,
605 { "RemainingLength", "smb_direct.remaining_length",
606 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
608 { &hf_smb_direct_data_offset,
609 { "DataOffset", "smb_direct.data_offset",
610 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
612 { &hf_smb_direct_data_length,
613 { "DataLength", "smb_direct.data_length",
614 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
616 { &hf_smb_direct_fragments,
617 { "Reassembled SMB Direct Fragments", "smb_direct.fragments",
618 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
620 { &hf_smb_direct_fragment,
621 { "SMB Direct Fragment", "smb_direct.fragment",
622 FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }},
623 { &hf_smb_direct_fragment_overlap,
624 { "Fragment overlap", "smb_direct.fragment.overlap",
625 FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }},
627 { &hf_smb_direct_fragment_overlap_conflict,
628 { "Conflicting data in fragment overlap", "smb_direct.fragment.overlap.conflict",
629 FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }},
631 { &hf_smb_direct_fragment_multiple_tails,
632 { "Multiple tail fragments found", "smb_direct.fragment.multipletails",
633 FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }},
635 { &hf_smb_direct_fragment_too_long_fragment,
636 { "Fragment too long", "smb_direct.fragment.toolongfragment",
637 FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }},
639 { &hf_smb_direct_fragment_error,
640 { "Defragmentation error", "smb_direct.fragment.error",
641 FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }},
643 { &hf_smb_direct_fragment_count,
644 { "Fragment count", "smb_direct.fragment.count",
645 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
647 { &hf_smb_direct_reassembled_in,
648 { "Reassembled PDU in frame", "smb_direct.reassembled_in",
649 FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }},
651 { &hf_smb_direct_reassembled_length,
652 { "Reassembled SMB Direct length", "smb_direct.reassembled.length",
653 FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
655 { &hf_smb_direct_reassembled_data,
656 { "Reassembled SMB Direct data", "smb_direct.reassembled.data",
657 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
660 module_t *smb_direct_module;
662 proto_smb_direct = proto_register_protocol("SMB-Direct (SMB RDMA Transport)",
663 "SMBDirect", "smb_direct");
664 proto_register_subtree_array(ett, array_length(ett));
665 proto_register_field_array(proto_smb_direct, hf, array_length(hf));
667 smb_direct_handle = register_dissector("smb_direct", dissect_smb_direct_infiniband, proto_smb_direct);
669 smb_direct_heur_subdissector_list = register_heur_dissector_list_with_description("smb_direct", "SMB-Direct payload", proto_smb_direct);
671 smb_direct_module = prefs_register_protocol(proto_smb_direct, NULL);
672 prefs_register_bool_preference(smb_direct_module,
673 "reassemble_smb_direct",
674 "Reassemble SMB Direct fragments",
675 "Whether the SMB Direct dissector should reassemble fragmented payloads",
676 &smb_direct_reassemble);
677 reassembly_table_register(&smb_direct_reassembly_table,
678 &addresses_ports_reassembly_table_functions);
681 void
682 proto_reg_handoff_smb_direct(void)
684 heur_dissector_add("iwarp_ddp_rdmap",
685 dissect_smb_direct_iwarp_heur,
686 "SMB Direct over iWARP", "smb_direct_iwarp",
687 proto_smb_direct, HEURISTIC_ENABLE);
688 heur_dissector_add("infiniband.payload",
689 dissect_smb_direct_infiniband_heur,
690 "SMB Direct Infiniband", "smb_direct_infiniband",
691 proto_smb_direct, HEURISTIC_ENABLE);
692 dissector_add_for_decode_as("infiniband", smb_direct_handle);
697 * Editor modelines - https://www.wireshark.org/tools/modelines.html
699 * Local variables:
700 * c-basic-offset: 8
701 * tab-width: 8
702 * indent-tabs-mode: t
703 * End:
705 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
706 * :indentSize=8:tabSize=8:noTabs=false: