epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-smc.c
blobb89b662d536102870f28396122e88bd1c1ffea9e
1 /* packet-smc.c
2 * SMC dissector for wireshark
3 * By Joe Fowler <fowlerja@us.ibm.com>
4 * By Guvenc Gulce <guvenc@linux.ibm.com>
5 * By Karsten Graul <kgraul@linux.ibm.com>
6 * (c) Copyright IBM Corporation 2014,2022
7 * LICENSE: GNU General Public License, version 2, or (at your option) any
8 * version. http://opensource.org/licenses/gpl-2.0.php
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
16 * Please refer to the following specs for protocol:
17 * - ietf - draft-fox-tcpm-shared-memory-rdma-05
18 * - https://www.ibm.com/support/pages/node/6326337
21 #include "config.h"
23 #include <epan/packet.h>
25 #include "packet-tcp.h"
27 #define SMC_TCP_MIN_HEADER_LENGTH 7
28 #define CLC_MSG_START_OFFSET 5
29 #define LLC_MSG_START_OFFSET 3
30 #define RMBE_CTRL_START_OFFSET 2
31 #define MAC_ADDR_LEN 6
32 #define SMC_V2 2
33 #define GID_LEN 16
34 #define PEERID_LEN 8
35 #define DIAG_INFO_LEN 4
36 #define EID_LEN 32
37 #define ISM_GID_LEN 8
38 #define ISM_CHID_LEN 2
39 #define IPV4_SUBNET_MASK_LEN 4
40 #define IPV6_PREFIX_LEN 16
41 #define ONE_BYTE_RESERVED 1
42 #define TWO_BYTE_RESERVED 2
43 #define QP_LEN 3
44 #define RKEY_LEN 4
45 #define VIRTUAL_ADDR_LEN 8
46 #define FLAG_BYTE_LEN 1
47 #define LENGTH_BYTE_LEN 2
48 #define SEQNO_LEN 2
49 #define CURSOR_LEN 4
50 #define ALERT_TOKEN_LEN 4
51 #define DMB_TOKEN_LEN 8
52 #define PSN_LEN 3
53 #define CONN_INDEX_LEN 1
54 #define SMCR_MSG_BYTE_0 0
55 #define CLC_MSG_BYTE_0 0
56 #define CLC_MSG_BYTE_1 1
57 #define CLC_MSG_BYTE_2 2
58 #define CLC_MSG_BYTE_3 3
59 #define CLC_MSG_LEN_OFFSET 5
60 #define LLC_CMD_OFFSET 0
61 #define LLC_LEN_OFFSET 1
62 #define LLC_CMD_RSP_OFFSET 3
63 #define ACCEPT_CONFIRM_QP_OFFSET 38
64 #define SMCR_CLC_ID 0xe2d4c3d9 /*EBCDIC 'SMCR' */
65 #define SMCD_CLC_ID 0xe2d4c3c4 /*EBCDIC 'SMCD' */
66 #define SMC_CLC_V1 0x10
67 #define SMC_CLC_SMC_R 0x01
68 #define SMC_MAX_QP_NUM 6
69 #define SMCD_MAX_BUFSIZE_NUM 6
70 #define SMCR_MAX_BUFSIZE_NUM 5
72 #define LLC_FLAG_RESP 0x80
73 #define RMBE_CTRL 0xfe
74 #define LLC_MSG_LENGTH 0x2c
76 typedef enum {
77 SMC_CLC_PROPOSAL = 1,
78 SMC_CLC_ACCEPT = 2,
79 SMC_CLC_CONFIRMATION = 3,
80 SMC_CLC_DECLINE = 4
81 } clc_message;
83 typedef enum {
84 SMC_CLC_SMCR = 0,
85 SMC_CLC_SMCD = 1,
86 SMC_CLC_NONE = 2,
87 SMC_CLC_BOTH = 3,
88 } clc_type_message;
90 typedef enum {
91 SMC_CLC_OS_ZOS = 1,
92 SMC_CLC_OS_LINUX = 2,
93 SMC_CLC_OS_AIX = 3,
94 SMC_CLC_OS_UNKOWN = 15,
95 } clc_os_message;
97 typedef enum {
98 SMC_CLC_LG_INDIRECT = 0,
99 SMC_CLC_LG_DIRECT = 1,
100 } clc_v2_lg_message;
102 static const value_string smc_clc_os_message_txt[] = {
103 { SMC_CLC_OS_ZOS, "z/OS" },
104 { SMC_CLC_OS_LINUX, "Linux" },
105 { SMC_CLC_OS_AIX, "AIX" },
106 { SMC_CLC_OS_UNKOWN, "Unknown" },
107 { 0, NULL }
110 static const value_string smc_clc_v2_lg_message_txt[] = {
111 { SMC_CLC_LG_INDIRECT, "V2_INDIRECT" },
112 { SMC_CLC_LG_DIRECT, "V2_DIRECT" },
113 { 0, NULL }
116 static const value_string smc_clc_type_message_txt[] = {
117 { SMC_CLC_SMCR, "SMC-R" },
118 { SMC_CLC_SMCD, "SMC-D" },
119 { SMC_CLC_NONE, "NONE" },
120 { SMC_CLC_BOTH, "SMC-R/SMC-D" },
121 { 0, NULL }
125 static const value_string smcv2_clc_col_info_message_txt[] = {
126 { SMC_CLC_SMCR, "[SMC-Rv2-Proposal]" },
127 { SMC_CLC_SMCD, "[SMC-Dv2-Proposal]" },
128 { SMC_CLC_NONE, "[NONE]" },
129 { SMC_CLC_BOTH, "[SMC-Dv2/SMC-Rv2-Proposal]" },
130 { 0, NULL }
133 static const value_string smc_clc_col_info_message_txt[] = {
134 { SMC_CLC_SMCR, "[SMC-R-Proposal]" },
135 { SMC_CLC_SMCD, "[SMC-D-Proposal]" },
136 { SMC_CLC_NONE, "[NONE]" },
137 { SMC_CLC_BOTH, "[SMC-D/SMC-R-Proposal]" },
138 { 0, NULL }
141 static const value_string smcr_clc_message_txt[] = {
142 { SMC_CLC_PROPOSAL, "Proposal" },
143 { SMC_CLC_ACCEPT, "Accept" },
144 { SMC_CLC_CONFIRMATION, "Confirm" },
145 { SMC_CLC_DECLINE, "Decline" },
146 { 0, NULL }
149 typedef enum {
150 LLC_CONFIRM_LINK = 0x01,
151 LLC_ADD_LINK = 0x02,
152 LLC_ADD_LINK_CONT = 0x03,
153 LLC_DEL_LINK = 0x04,
154 LLC_CONFIRM_RKEY = 0x06,
155 LLC_CONFIRM_RKEY_CONT = 0x08,
156 LLC_DELETE_RKEY = 0x09,
157 LLC_TEST_LINK = 0x07,
158 /* SMC-Rv2 LLC message types */
159 LLC_CONFIRM_LINK_V2 = 0x21,
160 LLC_ADD_LINK_V2 = 0x22,
161 LLC_DEL_LINK_V2 = 0x24,
162 LLC_REQUEST_ADD_LINK_V2 = 0x25,
163 LLC_CONFIRM_RKEY_V2 = 0x26,
164 LLC_TEST_LINK_V2 = 0x27,
165 LLC_DELETE_RKEY_V2 = 0x29,
166 /* Common message types */
167 LLC_OPT_MSG_CTRL = 0x80,
168 LLC_NWM_DATA = 0x8A,
169 LLC_RMBE_CTRL = 0xFE
170 } llc_message;
172 static const value_string smcr_llc_message_txt[] = {
173 { LLC_CONFIRM_LINK, "Confirm Link" },
174 { LLC_ADD_LINK, "Add Link" },
175 { LLC_ADD_LINK_CONT, "Add Link Continuous" },
176 { LLC_DEL_LINK, "Delete Link" },
177 { LLC_CONFIRM_RKEY, "Confirm Rkey" },
178 { LLC_CONFIRM_RKEY_CONT, "Confirm Rkey Continuous" },
179 { LLC_DELETE_RKEY, "Delete Rkey" },
180 { LLC_TEST_LINK, "Test Link" },
181 /* SMC-Rv2 LLC message types */
182 { LLC_CONFIRM_LINK_V2, "Confirm Link (v2)" },
183 { LLC_ADD_LINK_V2, "Add Link (v2)" },
184 { LLC_DEL_LINK_V2, "Delete Link (v2)" },
185 { LLC_REQUEST_ADD_LINK_V2, "Request Add Link (v2)" },
186 { LLC_CONFIRM_RKEY_V2, "Confirm Rkey (v2)" },
187 { LLC_TEST_LINK_V2, "Test Link (v2)" },
188 { LLC_DELETE_RKEY_V2, "Delete Rkey (v2)" },
189 /* Common message types */
190 { LLC_OPT_MSG_CTRL, "OPT Message Control" },
191 { LLC_NWM_DATA, "NWM Data" },
192 { RMBE_CTRL, "CDC Message" },
193 { 0, NULL }
196 static int proto_smc;
197 static int ett_smcr;
198 static int hf_smcr_clc_msg;
199 static int hf_smcr_llc_msg;
201 /* SMC Proposal for both SMC-D and SMC-R */
202 static int ett_proposal_flag;
203 static int ett_proposal_ext_flag2;
204 static int hf_proposal_smc_version_release_number;
205 static int hf_proposal_smc_version_seid;
206 static int hf_proposal_smc_version;
207 static int hf_proposal_smc_type;
208 static int hf_proposal_smc_v2_type;
209 static int hf_smc_length;
210 static int hf_smc_proposal_smc_chid;
211 static int hf_smc_proposal_flags;
212 static int hf_smc_proposal_eid;
213 static int hf_smc_proposal_eid_count;
214 static int hf_smc_proposal_system_eid;
215 static int hf_smc_proposal_ext_flags;
216 static int hf_smc_proposal_client_peer_id;
217 static int hf_smc_proposal_ism_gid_count;
218 static int hf_smc_proposal_ism_gid;
219 static int hf_smc_proposal_client_preferred_gid;
220 static int hf_smc_proposal_client_preferred_mac;
221 static int hf_smc_proposal_smcv1_subnet_ext_offset;
222 static int hf_smc_proposal_smcv2_ext_offset;
223 static int hf_smc_proposal_outgoing_interface_subnet_mask;
224 static int hf_smc_proposal_smcdv2_ext_offset;
225 static int hf_smc_proposal_rocev2_gid_ipv4_addr;
226 static int hf_smc_proposal_rocev2_gid_ipv6_addr;
227 static int hf_smc_proposal_outgoing_subnet_mask_signifcant_bits;
228 static int hf_smc_proposal_ipv6_prefix_count;
229 static int hf_smc_proposal_ipv6_prefix;
230 static int hf_smc_proposal_ipv6_prefix_length;
232 static int hf_smc_reserved;
234 /* SMC-R Accept */
235 static int ett_accept_flag;
236 static int ett_accept_flag2;
237 static int ett_smcr_accept_fce_flag1;
238 static int hf_accept_v2_lg_type;
239 static int hf_accept_smc_version;
240 static int hf_accept_first_contact;
241 static int hf_accept_rmb_buffer_size;
242 static int hf_accept_qp_mtu_value;
243 static int hf_smcr_accept_flags;
244 static int hf_smcr_accept_flags2;
245 static int hf_smcr_accept_fce_flags;
246 static int hf_smcr_accept_server_peer_id;
247 static int hf_smcr_accept_server_preferred_gid;
248 static int hf_smcr_accept_server_preferred_mac;
249 static int hf_smcr_accept_server_qp_number;
250 static int hf_smcr_accept_server_rmb_rkey;
251 static int hf_smcr_accept_server_tcp_conn_index;
252 static int hf_smcr_accept_server_rmb_element_alert_token;
253 static int hf_smcr_accept_server_rmb_virtual_address;
254 static int hf_smcr_accept_initial_psn;
256 /* SMC-R Confirm */
257 static int ett_confirm_flag;
258 static int ett_confirm_flag2;
259 static int hf_smcr_confirm_flags;
260 static int hf_smcr_confirm_client_peer_id;
261 static int hf_smcr_confirm_client_gid;
262 static int hf_smcr_confirm_client_mac;
263 static int hf_smcr_confirm_client_qp_number;
264 static int hf_smcr_confirm_client_rmb_rkey;
265 static int hf_smcr_confirm_client_tcp_conn_index;
266 static int hf_smcr_confirm_client_rmb_element_alert_token;
267 static int hf_smcr_confirm_flags2;
268 static int hf_smcr_confirm_client_rmb_virtual_address;
269 static int hf_smcr_confirm_initial_psn;
270 static int hf_confirm_smc_version;
271 static int hf_confirm_rmb_buffer_size;
272 static int hf_confirm_qp_mtu_value;
274 /* SMC-D Accept */
275 static int hf_accept_smc_type;
276 static int ett_smcd_accept_flag;
277 static int ett_smc_accept_fce_flag;
278 static int ett_smcd_accept_flag2;
279 static int hf_smcd_accept_smc_version;
280 static int hf_accept_os_type;
281 static int hf_accept_smc_version_release_number;
282 static int hf_smcd_accept_first_contact;
283 static int hf_accept_dmb_buffer_size;
284 static int hf_smcd_accept_flags;
285 static int hf_smc_accept_fce_flags;
286 static int hf_smcd_accept_flags2;
287 static int hf_smcd_accept_server_peer_id;
288 static int hf_smcd_accept_dmbe_conn_index;
289 static int hf_smcd_accept_dmb_token;
290 static int hf_smcd_accept_server_link_id;
291 static int hf_smcd_accept_smc_chid;
292 static int hf_smc_accept_eid;
293 static int hf_smc_accept_peer_name;
295 /* SMC-D Confirm */
296 static int hf_confirm_smc_type;
297 static int ett_smcd_confirm_flag;
298 static int ett_smc_confirm_fce_flag;
299 static int ett_smcd_confirm_flag2;
300 static int hf_smcd_confirm_smc_version;
301 static int hf_confirm_os_type;
302 static int hf_smcd_confirm_flags;
303 static int hf_smcd_confirm_flags2;
304 static int hf_smc_confirm_first_contact;
305 static int hf_smcd_confirm_client_peer_id;
306 static int hf_smcd_confirm_dmb_token;
307 static int hf_smcd_confirm_dmbe_conn_index;
308 static int hf_smcd_confirm_client_link_id;
309 static int hf_confirm_smc_version_release_number;
310 static int hf_smcd_confirm_dmb_buffer_size;
311 static int hf_smcd_confirm_smc_chid;
312 static int hf_smc_confirm_eid;
313 static int hf_smc_confirm_peer_name;
314 static int hf_smc_confirm_gid_lst_len;
315 static int hf_smc_confirm_gid_list_entry;
317 /* SMC-R Decline */
318 static int ett_decline_flag;
319 static int ett_decline_flag2;
320 static int hf_smc_decline_flags;
321 static int hf_smc_decline_flags2;
322 static int hf_smc_decline_peer_id;
323 static int hf_smc_decline_diag_info;
324 static int hf_decline_os_type;
325 static int hf_decline_smc_version;
326 static int hf_decline_out_of_sync;
328 /* SMC-R Confirm Link*/
329 static int ett_confirm_link_flag;
330 static int hf_smcr_confirm_link_flags;
331 static int hf_smcr_confirm_link_mac;
332 static int hf_smcr_confirm_link_gid;
333 static int hf_smcr_confirm_link_qp_number;
334 static int hf_smcr_confirm_link_number;
335 static int hf_smcr_confirm_link_userid;
336 static int hf_smcr_confirm_link_max_links;
337 static int hf_smcr_confirm_link_response;
339 /* SMC-R Add Link */
340 static int ett_add_link_flag;
341 static int ett_add_link_flag2;
342 static int ett_add_link_flag3;
343 static int hf_smcr_add_link_flags;
344 static int hf_smcr_add_link_response;
345 static int hf_smcr_add_link_response_rejected;
346 static int hf_smcr_add_link_reject_reason;
347 static int hf_smcr_add_link_mac;
348 static int hf_smcr_add_link_gid;
349 static int hf_smcr_add_link_qp_number;
350 static int hf_smcr_add_link_number;
351 static int hf_smcr_add_link_initial_psn;
352 static int hf_smcr_add_link_flags2;
353 static int hf_smcr_add_link_qp_mtu_value;
354 static int hf_smcr_add_link_client_target_gid;
355 static int hf_smcr_add_link_rkey_count;
356 static int hf_smcr_add_link_rkey;
357 static int hf_smcr_add_link_rkey2;
358 static int hf_smcr_add_link_virt_addr;
359 static int hf_smcr_add_link_flags3;
360 static int hf_smcr_add_link_flag3_direct_link;
362 /* SMC-R Add Link Continue*/
363 static int ett_add_link_cont_flag;
364 static int hf_smcr_add_link_cont_flags;
365 static int hf_smcr_add_link_cont_response;
366 static int hf_smcr_add_link_cont_link_number;
367 static int hf_smcr_add_link_cont_number_of_rkeys;
368 static int hf_smcr_add_link_cont_p1_rkey;
369 static int hf_smcr_add_link_cont_p1_rkey2;
370 static int hf_smcr_add_link_cont_p1_virt_addr;
371 static int hf_smcr_add_link_cont_p2_rkey;
372 static int hf_smcr_add_link_cont_p2_rkey2;
373 static int hf_smcr_add_link_cont_p2_virt_addr;
375 /* SMC-Rv2 Request Add Link */
376 static int ett_request_add_link_flag;
377 static int hf_smcr_request_add_link_flags;
378 static int hf_smcr_request_add_link_response;
379 static int hf_smcr_request_add_link_response_rejected;
380 static int hf_smcr_request_add_link_reject_reason;
381 static int hf_smc_request_add_link_gid_lst_len;
382 static int hf_smc_request_add_link_gid_list_entry;
384 /* SMC-R Delete Link */
385 static int ett_delete_link_flag;
386 static int hf_smcr_delete_link_flags;
387 static int hf_smcr_delete_link_response;
388 static int hf_smcr_delete_link_all;
389 static int hf_smcr_delete_link_orderly;
390 static int hf_smcr_delete_link_number;
391 static int hf_smcr_delete_link_reason_code;
393 /* SMC-R Confirm Rkey */
394 static int ett_confirm_rkey_flag;
395 static int hf_smcr_confirm_rkey_response;
396 static int hf_smcr_confirm_rkey_flags;
397 static int hf_smcr_confirm_rkey_negative_response;
398 static int hf_smcr_confirm_rkey_retry_rkey_set;
399 static int hf_smcr_confirm_rkey_number;
400 static int hf_smcr_confirm_rkey_new_rkey;
401 static int hf_smcr_confirm_rkey_virtual_address;
402 static int hf_smcr_confirm_rkey_link_number;
404 /* SMC-R Delete Rkey */
405 static int ett_delete_rkey_flag;
406 static int hf_smcr_delete_rkey_flags;
407 static int hf_smcr_delete_rkey_response;
408 static int hf_smcr_delete_rkey_negative_response;
409 static int hf_smcr_delete_rkey_mask;
410 static int hf_smcr_delete_rkey_deleted;
411 static int hf_smcr_delete_rkey_count;
412 static int hf_smcr_delete_rkey_invalid_count;
414 /* SMC-R Test Link */
415 static int ett_test_link_flag;
416 static int hf_smcr_test_link_flags;
417 static int hf_smcr_test_link_response;
419 /* SMC-R RMBE Control */
420 static int ett_rmbe_ctrl_rw_status_flag;
421 static int ett_rmbe_ctrl_peer_conn_state_flag;
422 static int hf_smcr_rmbe_ctrl_seqno;
423 static int hf_smcr_rmbe_ctrl_alert_token;
424 static int hf_smcr_rmbe_ctrl_prod_wrap_seqno;
425 static int hf_smcr_rmbe_ctrl_peer_prod_curs;
426 static int hf_smcr_rmbe_ctrl_cons_wrap_seqno;
427 static int hf_smcr_rmbe_ctrl_peer_cons_curs;
428 static int hf_smcr_rmbe_ctrl_conn_rw_status_flags;
429 static int hf_smcr_rmbe_ctrl_write_blocked;
430 static int hf_smcr_rmbe_ctrl_urgent_pending;
431 static int hf_smcr_rmbe_ctrl_urgent_present;
432 static int hf_smcr_rmbe_ctrl_cons_update_requested;
433 static int hf_smcr_rmbe_ctrl_failover_validation;
434 static int hf_smcr_rmbe_ctrl_peer_conn_state_flags;
435 static int hf_smcr_rmbe_ctrl_peer_sending_done;
436 static int hf_smcr_rmbe_ctrl_peer_closed_conn;
437 static int hf_smcr_rmbe_ctrl_peer_abnormal_close;
439 void proto_register_smcr(void);
440 void proto_reg_handoff_smcr(void);
441 static dissector_handle_t smc_tcp_handle;
442 static dissector_handle_t smc_infiniband_handle;
444 static void
445 disect_smc_uncompress_size(proto_item* ti, unsigned size, unsigned max_valid)
447 if (size <= max_valid) {
448 proto_item_append_text(ti, " (Size: %dk)", 1 << (size + 4)); /* uncompressed size */
449 } else {
450 proto_item_append_text(ti, " (Size: invalid)");
454 static void
455 disect_smcr_translate_qp_mtu(proto_item* ti, unsigned qp_num)
457 if (qp_num > 0 && qp_num < SMC_MAX_QP_NUM) {
458 proto_item_append_text(ti, " (MTU: %d)", 1 << (7 + qp_num)); /* translated MTU size (1-5) */
459 } else {
460 proto_item_append_text(ti, " (MTU: invalid)");
464 static void
465 disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6)
467 unsigned offset;
468 uint16_t ip_subnet_ext_offset = 0, v2_ext_offset;
469 uint16_t v2_ext_pos = 0, smcd_v2_ext_offset = 0;
470 uint16_t smcd_v2_ext_pos = 0;
471 uint8_t ipv6_prefix_count, smc_version;
472 uint8_t smc_type, num_of_gids = 0, num_of_eids = 0;
473 uint8_t smc_type_v1 = 0, smc_type_v2 = 0;
474 bool is_smc_v2, is_smcdv1, is_smcdv2 = false, is_smcrv1, is_smcrv2 = false;
475 proto_item *proposal_flag_item;
476 proto_tree *proposal_flag_tree;
478 offset = CLC_MSG_START_OFFSET;
479 proto_tree_add_item(tree, hf_smc_length, tvb, offset, LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
480 offset += LENGTH_BYTE_LEN;
481 proposal_flag_item = proto_tree_add_item(tree, hf_smc_proposal_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
482 proposal_flag_tree = proto_item_add_subtree(proposal_flag_item, ett_proposal_flag);
483 proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
484 smc_version = tvb_get_uint8(tvb, offset);
485 smc_type = tvb_get_uint8(tvb, offset);
486 smc_version = ((smc_version >> 4) & 0x0F);
487 is_smc_v2 = (smc_version >= SMC_V2);
488 smc_type_v2 = ((smc_type >> 2) & 0x03);
489 smc_type_v1 = (smc_type & 0x03);
490 is_smcdv1 = ((smc_type_v1 == SMC_CLC_SMCD) || (smc_type_v1 == SMC_CLC_BOTH));
491 is_smcrv1 = ((smc_type_v1 == SMC_CLC_SMCR) || (smc_type_v1 == SMC_CLC_BOTH));
492 if (is_smc_v2) {
493 is_smcdv2 = ((smc_type_v2 == SMC_CLC_SMCD) || (smc_type_v2 == SMC_CLC_BOTH));
494 is_smcrv2 = ((smc_type_v2 == SMC_CLC_SMCR) || (smc_type_v2 == SMC_CLC_BOTH));
497 if (is_smc_v2) {
498 proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_v2_type, tvb,
499 offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
501 proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_type, tvb,
502 offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
503 offset += FLAG_BYTE_LEN;
504 if (is_smcrv1 || is_smcrv2) {
505 proto_tree_add_item(tree, hf_smc_proposal_client_peer_id, tvb, offset,
506 PEERID_LEN, ENC_BIG_ENDIAN);
507 } else {
508 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, PEERID_LEN, ENC_NA);
510 offset += PEERID_LEN;
511 if (is_smcrv1) {
512 proto_tree_add_item(tree, hf_smc_proposal_client_preferred_gid, tvb,
513 offset, GID_LEN, ENC_NA);
514 offset += GID_LEN;
515 proto_tree_add_item(tree, hf_smc_proposal_client_preferred_mac, tvb,
516 offset, MAC_ADDR_LEN, ENC_NA);
517 offset += MAC_ADDR_LEN;
518 } else {
519 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, GID_LEN + MAC_ADDR_LEN, ENC_NA);
520 offset += GID_LEN + MAC_ADDR_LEN;
522 if (is_smcrv1 || is_smcdv1) {
523 ip_subnet_ext_offset = tvb_get_ntohs(tvb, offset);
524 proto_tree_add_item(tree, hf_smc_proposal_smcv1_subnet_ext_offset, tvb,
525 offset, 2, ENC_BIG_ENDIAN);
526 offset += 2;
527 } else {
528 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 2, ENC_NA);
529 offset += 2;
531 if (is_smcdv1 || is_smcdv2) {
532 proto_tree_add_item(tree, hf_smc_proposal_ism_gid, tvb,
533 offset, ISM_GID_LEN, ENC_NA);
535 offset += ISM_GID_LEN;
536 if (is_smcdv2) {
537 proto_tree_add_item(tree, hf_smc_proposal_smc_chid, tvb, offset,
538 LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
539 } else {
540 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, LENGTH_BYTE_LEN, ENC_NA);
542 offset += LENGTH_BYTE_LEN;
543 if (is_smc_v2) {
544 v2_ext_offset = tvb_get_ntohs(tvb, offset);
545 v2_ext_pos = offset + 2 + v2_ext_offset;
546 proto_tree_add_item(tree, hf_smc_proposal_smcv2_ext_offset, tvb,
547 offset, 2, ENC_BIG_ENDIAN);
548 } else {
549 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 2, ENC_NA);
551 offset += 2;
553 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 28, ENC_NA);
554 offset += 28; /* reserved */
556 if (ip_subnet_ext_offset) {
557 proto_tree_add_item(tree, hf_smc_proposal_outgoing_interface_subnet_mask, tvb,
558 offset, IPV4_SUBNET_MASK_LEN, ENC_BIG_ENDIAN);
559 offset += IPV4_SUBNET_MASK_LEN;
560 proto_tree_add_item(tree, hf_smc_proposal_outgoing_subnet_mask_signifcant_bits, tvb,
561 offset, 1, ENC_BIG_ENDIAN);
562 offset += 1;
563 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
564 offset += TWO_BYTE_RESERVED; /* reserved */
565 ipv6_prefix_count = tvb_get_uint8(tvb, offset);
566 proto_tree_add_item(tree, hf_smc_proposal_ipv6_prefix_count, tvb,
567 offset, 1, ENC_BIG_ENDIAN);
568 offset += 1;
570 while (ipv6_prefix_count != 0) {
571 proto_tree_add_item(tree, hf_smc_proposal_ipv6_prefix, tvb,
572 offset, IPV6_PREFIX_LEN, ENC_NA);
573 offset += IPV6_PREFIX_LEN;
574 proto_tree_add_item(tree, hf_smc_proposal_ipv6_prefix_length, tvb,
575 offset, 1, ENC_BIG_ENDIAN);
576 offset += 1;
577 ipv6_prefix_count--;
581 if (v2_ext_pos >= offset) {
582 offset = v2_ext_pos;
583 num_of_eids = tvb_get_uint8(tvb, offset);
584 proto_tree_add_item(tree, hf_smc_proposal_eid_count, tvb,
585 offset, 1, ENC_BIG_ENDIAN);
586 offset += FLAG_BYTE_LEN;
587 num_of_gids = tvb_get_uint8(tvb, offset);
588 proto_tree_add_item(tree, hf_smc_proposal_ism_gid_count, tvb,
589 offset, 1, ENC_BIG_ENDIAN);
590 offset += FLAG_BYTE_LEN;
591 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, ONE_BYTE_RESERVED, ENC_NA);
592 offset += ONE_BYTE_RESERVED; /* reserved */
593 proposal_flag_item = proto_tree_add_item(tree, hf_smc_proposal_ext_flags, tvb,
594 offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
595 proposal_flag_tree = proto_item_add_subtree(proposal_flag_item, ett_proposal_ext_flag2);
596 proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_version_release_number,
597 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
598 proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_version_seid, tvb,
599 offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
600 offset += FLAG_BYTE_LEN;
601 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
602 offset += TWO_BYTE_RESERVED; /* reserved */
603 smcd_v2_ext_offset = tvb_get_ntohs(tvb, offset);
604 proto_tree_add_item(tree, hf_smc_proposal_smcdv2_ext_offset, tvb,
605 offset, 2, ENC_BIG_ENDIAN);
606 offset += 2;
607 smcd_v2_ext_pos = offset + smcd_v2_ext_offset;
608 if (is_smcrv2) {
609 if (is_ipv6) {
610 proto_tree_add_item(tree, hf_smc_proposal_rocev2_gid_ipv6_addr, tvb,
611 offset, GID_LEN, ENC_NA);
612 offset += GID_LEN;
613 } else {
614 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 12, ENC_NA);
615 offset += 12; /* reserved */
616 proto_tree_add_item(tree, hf_smc_proposal_rocev2_gid_ipv4_addr, tvb,
617 offset, IPV4_SUBNET_MASK_LEN, ENC_BIG_ENDIAN);
618 offset += IPV4_SUBNET_MASK_LEN;
620 } else {
621 offset += GID_LEN;
623 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 16, ENC_NA);
624 offset += 16; /* reserved */
625 while (num_of_eids != 0) {
626 proto_tree_add_item(tree, hf_smc_proposal_eid, tvb,
627 offset, EID_LEN, ENC_ASCII | ENC_NA);
628 offset += EID_LEN;
629 num_of_eids--;
631 if (smcd_v2_ext_pos >= offset) {
632 offset = smcd_v2_ext_pos;
633 proto_tree_add_item(tree, hf_smc_proposal_system_eid, tvb,
634 offset, EID_LEN, ENC_ASCII | ENC_NA);
635 offset += EID_LEN;
636 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 16, ENC_NA);
637 offset += 16; /* reserved */
638 while (num_of_gids != 0) {
639 proto_tree_add_item(tree, hf_smc_proposal_ism_gid, tvb,
640 offset, ISM_GID_LEN, ENC_NA);
641 offset += ISM_GID_LEN;
642 proto_tree_add_item(tree, hf_smc_proposal_smc_chid, tvb, offset,
643 ISM_CHID_LEN, ENC_BIG_ENDIAN);
644 offset += ISM_CHID_LEN;
645 num_of_gids--;
651 static void
652 disect_smcd_accept(tvbuff_t* tvb, proto_tree* tree)
654 unsigned offset, dmbe_size;
655 proto_item* accept_flag_item;
656 proto_tree* accept_flag_tree;
657 proto_item* accept_flag2_item;
658 proto_tree* accept_flag2_tree;
659 proto_item* ti;
660 uint8_t smc_version, first_contact = 0;
662 offset = CLC_MSG_START_OFFSET;
663 proto_tree_add_item(tree, hf_smc_length, tvb, offset,
664 LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
665 offset += LENGTH_BYTE_LEN;
666 accept_flag_item = proto_tree_add_item(tree, hf_smcd_accept_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
667 accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_smcd_accept_flag);
668 proto_tree_add_item(accept_flag_tree, hf_smcd_accept_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
669 proto_tree_add_item(accept_flag_tree, hf_smcd_accept_first_contact, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
670 proto_tree_add_item(accept_flag_tree, hf_accept_smc_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
671 smc_version = tvb_get_uint8(tvb, offset);
672 first_contact = tvb_get_uint8(tvb, offset);
673 smc_version = ((smc_version >> 4) & 0x0F);
674 first_contact = ((first_contact >> 3) & 0x01);
675 offset += FLAG_BYTE_LEN;
676 proto_tree_add_item(tree, hf_smcd_accept_server_peer_id, tvb, offset,
677 PEERID_LEN, ENC_BIG_ENDIAN);
678 offset += PEERID_LEN;
680 proto_tree_add_item(tree, hf_smcd_accept_dmb_token, tvb,
681 offset, DMB_TOKEN_LEN, ENC_NA);
682 offset += DMB_TOKEN_LEN;
684 proto_tree_add_item(tree, hf_smcd_accept_dmbe_conn_index, tvb,
685 offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN);
686 offset += CONN_INDEX_LEN;
688 accept_flag2_item = proto_tree_add_item(tree, hf_smcd_accept_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
689 accept_flag2_tree = proto_item_add_subtree(accept_flag2_item, ett_smcd_accept_flag2);
690 ti = proto_tree_add_item(accept_flag2_tree, hf_accept_dmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
691 dmbe_size = tvb_get_int8(tvb, offset) >> 4;
692 disect_smc_uncompress_size(ti, dmbe_size, SMCD_MAX_BUFSIZE_NUM);
693 offset += FLAG_BYTE_LEN;
694 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
695 offset += TWO_BYTE_RESERVED; /* reserved */
696 proto_tree_add_item(tree, hf_smcd_accept_server_link_id, tvb,
697 offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN);
698 offset += ALERT_TOKEN_LEN;
700 if (smc_version >= SMC_V2) {
701 proto_tree_add_item(tree, hf_smcd_accept_smc_chid, tvb, offset, LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
702 offset += LENGTH_BYTE_LEN;
704 proto_tree_add_item(tree, hf_smc_accept_eid, tvb, offset, 32, ENC_ASCII | ENC_NA);
705 offset += 32;
706 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 8, ENC_NA);
707 offset += 8; /* reserved */
709 if (first_contact) {
710 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, ONE_BYTE_RESERVED, ENC_NA);
711 offset += ONE_BYTE_RESERVED; /* reserved */
712 accept_flag_item = proto_tree_add_item(tree, hf_smc_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
713 accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_smc_accept_fce_flag);
714 proto_tree_add_item(accept_flag_tree, hf_accept_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
715 proto_tree_add_item(accept_flag_tree, hf_accept_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
716 offset += FLAG_BYTE_LEN;
717 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
718 offset += TWO_BYTE_RESERVED; /* reserved */
719 proto_tree_add_item(tree, hf_smc_accept_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA);
720 offset += 32;
721 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 16, ENC_NA);
722 /* offset += 16; */ /* reserved */
727 static void
728 disect_smcd_confirm(tvbuff_t* tvb, proto_tree* tree)
730 unsigned offset, dmbe_size;
731 proto_item* confirm_flag_item;
732 proto_tree* confirm_flag_tree;
733 proto_item* confirm_flag2_item;
734 proto_tree* confirm_flag2_tree;
735 proto_item* ti;
736 uint8_t smc_version, first_contact = 0;
738 offset = CLC_MSG_START_OFFSET;
739 proto_tree_add_item(tree, hf_smc_length, tvb, offset,
740 LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
741 offset += LENGTH_BYTE_LEN;
742 confirm_flag_item = proto_tree_add_item(tree, hf_smcd_confirm_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
743 confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_smcd_confirm_flag);
744 proto_tree_add_item(confirm_flag_tree, hf_smcd_confirm_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
745 proto_tree_add_item(confirm_flag_tree, hf_smc_confirm_first_contact, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
746 proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
747 smc_version = tvb_get_uint8(tvb, offset);
748 first_contact = tvb_get_uint8(tvb, offset);
749 smc_version = ((smc_version >> 4) & 0x0F);
750 first_contact = ((first_contact >> 3) & 0x01);
751 offset += FLAG_BYTE_LEN;
752 proto_tree_add_item(tree, hf_smcd_confirm_client_peer_id, tvb, offset,
753 PEERID_LEN, ENC_BIG_ENDIAN);
754 offset += PEERID_LEN;
756 proto_tree_add_item(tree, hf_smcd_confirm_dmb_token, tvb,
757 offset, DMB_TOKEN_LEN, ENC_NA);
758 offset += DMB_TOKEN_LEN;
760 proto_tree_add_item(tree, hf_smcd_confirm_dmbe_conn_index, tvb,
761 offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN);
762 offset += CONN_INDEX_LEN;
764 confirm_flag2_item = proto_tree_add_item(tree, hf_smcd_confirm_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
765 confirm_flag2_tree = proto_item_add_subtree(confirm_flag2_item, ett_smcd_confirm_flag2);
766 ti = proto_tree_add_item(confirm_flag2_tree, hf_smcd_confirm_dmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
767 dmbe_size = tvb_get_int8(tvb, offset) >> 4;
768 disect_smc_uncompress_size(ti, dmbe_size, SMCD_MAX_BUFSIZE_NUM);
769 offset += FLAG_BYTE_LEN;
770 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
771 offset += TWO_BYTE_RESERVED; /* reserved */
772 proto_tree_add_item(tree, hf_smcd_confirm_client_link_id, tvb,
773 offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN);
774 offset += ALERT_TOKEN_LEN;
776 if (smc_version >= SMC_V2) {
777 proto_tree_add_item(tree, hf_smcd_confirm_smc_chid, tvb, offset,
778 LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
779 offset += LENGTH_BYTE_LEN;
781 proto_tree_add_item(tree, hf_smc_confirm_eid, tvb, offset, 32, ENC_ASCII | ENC_NA);
782 offset += 32;
783 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 8, ENC_NA);
784 offset += 8; /* reserved */
786 if (first_contact) {
787 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, ONE_BYTE_RESERVED, ENC_NA);
788 offset += ONE_BYTE_RESERVED; /* reserved */
789 confirm_flag_item = proto_tree_add_item(tree, hf_smc_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
790 confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_smc_confirm_fce_flag);
791 proto_tree_add_item(confirm_flag_tree, hf_confirm_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
792 proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
793 offset += FLAG_BYTE_LEN;
794 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
795 offset += TWO_BYTE_RESERVED; /* reserved */
796 proto_tree_add_item(tree, hf_smc_confirm_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA);
801 static void
802 disect_smcr_accept(tvbuff_t *tvb, proto_tree *tree)
804 unsigned offset, qp_num, rmbe_size;
805 proto_item *accept_flag_item;
806 proto_tree *accept_flag_tree;
807 proto_item *accept_flag2_item;
808 proto_tree *accept_flag2_tree;
809 proto_item *ti;
810 uint8_t smc_version, first_contact = 0;
812 offset = CLC_MSG_START_OFFSET;
813 proto_tree_add_item(tree, hf_smc_length, tvb, offset,
814 LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
815 offset += LENGTH_BYTE_LEN;
816 accept_flag_item = proto_tree_add_item(tree, hf_smcr_accept_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
817 accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_accept_flag);
818 proto_tree_add_item(accept_flag_tree, hf_accept_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
819 proto_tree_add_item(accept_flag_tree, hf_accept_first_contact, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
820 smc_version = tvb_get_uint8(tvb, offset);
821 first_contact = tvb_get_uint8(tvb, offset);
822 smc_version = ((smc_version >> 4) & 0x0F);
823 first_contact = ((first_contact >> 3) & 0x01);
824 offset += FLAG_BYTE_LEN;
825 proto_tree_add_item(tree, hf_smcr_accept_server_peer_id, tvb, offset,
826 PEERID_LEN, ENC_BIG_ENDIAN);
827 offset += PEERID_LEN;
828 proto_tree_add_item(tree, hf_smcr_accept_server_preferred_gid, tvb,
829 offset, GID_LEN, ENC_NA);
830 offset += GID_LEN;
831 proto_tree_add_item(tree, hf_smcr_accept_server_preferred_mac, tvb,
832 offset, MAC_ADDR_LEN, ENC_NA);
833 offset += MAC_ADDR_LEN;
834 proto_tree_add_item(tree, hf_smcr_accept_server_qp_number, tvb,
835 offset, QP_LEN, ENC_BIG_ENDIAN);
836 offset += QP_LEN;
837 proto_tree_add_item(tree, hf_smcr_accept_server_rmb_rkey, tvb,
838 offset, RKEY_LEN, ENC_BIG_ENDIAN);
839 offset += RKEY_LEN;
840 proto_tree_add_item(tree, hf_smcr_accept_server_tcp_conn_index, tvb,
841 offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN);
842 offset += CONN_INDEX_LEN;
843 proto_tree_add_item(tree, hf_smcr_accept_server_rmb_element_alert_token, tvb,
844 offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN);
845 offset += ALERT_TOKEN_LEN;
846 accept_flag2_item = proto_tree_add_item(tree, hf_smcr_accept_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
847 accept_flag2_tree = proto_item_add_subtree(accept_flag2_item, ett_accept_flag2);
848 ti = proto_tree_add_item(accept_flag2_tree, hf_accept_rmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
849 rmbe_size = tvb_get_int8(tvb, offset) >> 4;
850 disect_smc_uncompress_size(ti, rmbe_size, SMCR_MAX_BUFSIZE_NUM);
851 ti = proto_tree_add_item(accept_flag2_tree, hf_accept_qp_mtu_value, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
852 qp_num = tvb_get_int8(tvb, offset) & 0x0F;
853 disect_smcr_translate_qp_mtu(ti, qp_num);
854 offset += FLAG_BYTE_LEN;
855 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, ONE_BYTE_RESERVED, ENC_NA);
856 offset += ONE_BYTE_RESERVED; /* reserved */
857 proto_tree_add_item(tree, hf_smcr_accept_server_rmb_virtual_address, tvb,
858 offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
859 offset += VIRTUAL_ADDR_LEN;
860 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, ONE_BYTE_RESERVED, ENC_NA);
861 offset += ONE_BYTE_RESERVED; /* reserved */
862 proto_tree_add_item(tree, hf_smcr_accept_initial_psn, tvb,
863 offset, PSN_LEN, ENC_BIG_ENDIAN);
864 offset += PSN_LEN;
866 if (smc_version >= SMC_V2) {
867 proto_tree_add_item(tree, hf_smc_accept_eid, tvb, offset, 32, ENC_ASCII | ENC_NA);
868 offset += 32;
869 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 8, ENC_NA);
870 offset += 8; /* reserved */
872 if (first_contact) {
873 accept_flag_item = proto_tree_add_item(tree, hf_smcr_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
874 accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_smcr_accept_fce_flag1);
875 proto_tree_add_item(accept_flag_tree, hf_accept_v2_lg_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
876 offset += FLAG_BYTE_LEN;
877 accept_flag_item = proto_tree_add_item(tree, hf_smc_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
878 accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_smc_accept_fce_flag);
879 proto_tree_add_item(accept_flag_tree, hf_accept_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
880 proto_tree_add_item(accept_flag_tree, hf_accept_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
881 offset += FLAG_BYTE_LEN;
882 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
883 offset += TWO_BYTE_RESERVED; /* reserved */
884 proto_tree_add_item(tree, hf_smc_accept_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA);
885 offset += 32;
886 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 16, ENC_NA);
887 /* offset += 16; */ /* reserved */
892 static void
893 disect_smcr_confirm(tvbuff_t *tvb, proto_tree *tree)
895 unsigned offset, qp_num, rmbe_size;
896 proto_item *confirm_flag_item;
897 proto_tree *confirm_flag_tree;
898 proto_item *confirm_flag2_item;
899 proto_tree *confirm_flag2_tree;
900 proto_item *ti;
901 uint8_t smc_version, first_contact = 0;
902 uint8_t gid_list_len;
904 offset = CLC_MSG_START_OFFSET;
905 proto_tree_add_item(tree, hf_smc_length, tvb, offset,
906 LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
907 offset += LENGTH_BYTE_LEN;
908 confirm_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
909 confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_confirm_flag);
910 proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
911 proto_tree_add_item(confirm_flag_tree, hf_smc_confirm_first_contact, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
912 proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
913 smc_version = tvb_get_uint8(tvb, offset);
914 first_contact = tvb_get_uint8(tvb, offset);
915 smc_version = ((smc_version >> 4) & 0x0F);
916 first_contact = ((first_contact >> 3) & 0x01);
917 offset += FLAG_BYTE_LEN;
918 proto_tree_add_item(tree, hf_smcr_confirm_client_peer_id, tvb, offset,
919 PEERID_LEN, ENC_BIG_ENDIAN);
920 offset += PEERID_LEN;
921 proto_tree_add_item(tree, hf_smcr_confirm_client_gid, tvb,
922 offset, GID_LEN, ENC_NA);
923 offset += GID_LEN;
924 proto_tree_add_item(tree, hf_smcr_confirm_client_mac, tvb,
925 offset, MAC_ADDR_LEN, ENC_NA);
926 offset += MAC_ADDR_LEN;
927 proto_tree_add_item(tree, hf_smcr_confirm_client_qp_number, tvb,
928 offset, QP_LEN, ENC_BIG_ENDIAN);
929 offset += QP_LEN;
930 proto_tree_add_item(tree, hf_smcr_confirm_client_rmb_rkey, tvb,
931 offset, RKEY_LEN, ENC_BIG_ENDIAN);
932 offset += RKEY_LEN;
933 proto_tree_add_item(tree, hf_smcr_confirm_client_tcp_conn_index, tvb,
934 offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN);
935 offset += CONN_INDEX_LEN;
936 proto_tree_add_item(tree, hf_smcr_confirm_client_rmb_element_alert_token, tvb,
937 offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN);
938 offset += ALERT_TOKEN_LEN;
939 confirm_flag2_item = proto_tree_add_item(tree, hf_smcr_confirm_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
940 confirm_flag2_tree = proto_item_add_subtree(confirm_flag2_item, ett_confirm_flag2);
941 ti = proto_tree_add_item(confirm_flag2_tree, hf_confirm_rmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
942 rmbe_size = tvb_get_int8(tvb, offset) >> 4;
943 disect_smc_uncompress_size(ti, rmbe_size, SMCR_MAX_BUFSIZE_NUM);
944 ti = proto_tree_add_item(confirm_flag2_tree, hf_confirm_qp_mtu_value, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
945 qp_num = tvb_get_int8(tvb, offset) & 0x0F;
946 disect_smcr_translate_qp_mtu(ti, qp_num);
947 offset += FLAG_BYTE_LEN;
948 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, ONE_BYTE_RESERVED, ENC_NA);
949 offset += ONE_BYTE_RESERVED; /* reserved */
950 proto_tree_add_item(tree, hf_smcr_confirm_client_rmb_virtual_address, tvb,
951 offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
952 offset += VIRTUAL_ADDR_LEN;
953 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, ONE_BYTE_RESERVED, ENC_NA);
954 offset += ONE_BYTE_RESERVED; /* reserved */
955 proto_tree_add_item(tree, hf_smcr_confirm_initial_psn, tvb,
956 offset, PSN_LEN, ENC_BIG_ENDIAN);
958 if (smc_version >= SMC_V2) {
959 offset += PSN_LEN;
960 proto_tree_add_item(tree, hf_smc_confirm_eid, tvb, offset, 32, ENC_ASCII | ENC_NA);
961 offset += 32;
962 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 8, ENC_NA);
963 offset += 8; /* reserved */
965 if (first_contact) {
966 confirm_flag_item = proto_tree_add_item(tree, hf_smcr_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
967 confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_smcr_accept_fce_flag1);
968 proto_tree_add_item(confirm_flag_tree, hf_accept_v2_lg_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
969 offset += FLAG_BYTE_LEN;
970 confirm_flag_item = proto_tree_add_item(tree, hf_smc_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
971 confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_smc_confirm_fce_flag);
972 proto_tree_add_item(confirm_flag_tree, hf_confirm_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
973 proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
974 offset += FLAG_BYTE_LEN;
975 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
976 offset += TWO_BYTE_RESERVED; /* reserved */
977 proto_tree_add_item(tree, hf_smc_confirm_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA);
978 offset += 32;
979 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 16, ENC_NA);
980 offset += 16; /* reserved */
981 gid_list_len = tvb_get_uint8(tvb, offset);
982 proto_tree_add_item(tree, hf_smc_confirm_gid_lst_len, tvb, offset, 1, ENC_BIG_ENDIAN);
983 offset += 1;
984 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 3, ENC_NA);
985 offset += 3; /* reserved */
986 while (gid_list_len > 0) {
987 proto_tree_add_item(tree, hf_smc_confirm_gid_list_entry, tvb, offset, GID_LEN, ENC_NA);
988 offset += GID_LEN;
989 gid_list_len--;
995 static void
996 disect_smc_decline(tvbuff_t *tvb, proto_tree *tree)
998 proto_item* decline_flag_item;
999 proto_tree* decline_flag_tree;
1000 proto_item* decline_flag2_item;
1001 proto_tree* decline_flag2_tree;
1002 unsigned offset, smc_version, smc_length, num_of_diag;
1004 offset = CLC_MSG_START_OFFSET;
1005 proto_tree_add_item(tree, hf_smc_length, tvb, offset,
1006 LENGTH_BYTE_LEN, ENC_BIG_ENDIAN);
1007 smc_length = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1008 offset += LENGTH_BYTE_LEN;
1010 decline_flag_item = proto_tree_add_item(tree, hf_smc_decline_flags, tvb, offset,
1011 FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1012 decline_flag_tree = proto_item_add_subtree(decline_flag_item, ett_decline_flag);
1013 proto_tree_add_item(decline_flag_tree, hf_decline_smc_version, tvb, offset,
1014 FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1015 proto_tree_add_item(decline_flag_tree, hf_decline_out_of_sync, tvb, offset,
1016 FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1017 smc_version = tvb_get_uint8(tvb, offset);
1018 smc_version = ((smc_version >> 4) & 0x0F);
1020 offset += FLAG_BYTE_LEN;
1021 proto_tree_add_item(tree, hf_smc_decline_peer_id, tvb, offset,
1022 PEERID_LEN, ENC_BIG_ENDIAN);
1023 offset += PEERID_LEN;
1024 proto_tree_add_item(tree, hf_smc_decline_diag_info, tvb, offset,
1025 DIAG_INFO_LEN, ENC_BIG_ENDIAN);
1026 offset += DIAG_INFO_LEN;
1027 if (smc_version >= SMC_V2) {
1028 decline_flag2_item = proto_tree_add_item(tree, hf_smc_decline_flags2, tvb, offset,
1029 FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1030 decline_flag2_tree = proto_item_add_subtree(decline_flag2_item, ett_decline_flag2);
1031 proto_tree_add_item(decline_flag2_tree, hf_decline_os_type, tvb, offset,
1032 FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1033 offset += FLAG_BYTE_LEN;
1034 offset += 3;
1035 if (smc_length >= offset + 16) {
1036 for (num_of_diag = 0; num_of_diag < 4; num_of_diag++) {
1037 proto_tree_add_item(tree, hf_smc_decline_diag_info, tvb, offset,
1038 DIAG_INFO_LEN, ENC_BIG_ENDIAN);
1039 offset += DIAG_INFO_LEN;
1045 static void
1046 disect_smcr_confirm_link(tvbuff_t *tvb, proto_tree *tree)
1048 unsigned offset;
1049 proto_item *confirm_flag_item;
1050 proto_tree *confirm_flag_tree;
1052 offset = LLC_MSG_START_OFFSET;
1053 confirm_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1054 confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_confirm_link_flag);
1055 proto_tree_add_item(confirm_flag_tree, hf_smcr_confirm_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1057 offset += FLAG_BYTE_LEN;
1058 proto_tree_add_item(tree, hf_smcr_confirm_link_mac, tvb,
1059 offset, MAC_ADDR_LEN, ENC_NA);
1060 offset += MAC_ADDR_LEN;
1061 proto_tree_add_item(tree, hf_smcr_confirm_link_gid, tvb,
1062 offset, GID_LEN, ENC_NA);
1063 offset += GID_LEN;
1064 proto_tree_add_item(tree, hf_smcr_confirm_link_qp_number, tvb,
1065 offset, QP_LEN, ENC_BIG_ENDIAN);
1066 offset += QP_LEN;
1067 proto_tree_add_item(tree, hf_smcr_confirm_link_number, tvb,
1068 offset, 1, ENC_BIG_ENDIAN);
1069 offset += 1;
1070 proto_tree_add_item(tree, hf_smcr_confirm_link_userid, tvb,
1071 offset, 4, ENC_BIG_ENDIAN);
1072 offset += 4;
1073 proto_tree_add_item(tree, hf_smcr_confirm_link_max_links, tvb,
1074 offset, 1, ENC_BIG_ENDIAN);
1077 static void
1078 disect_smcr_add_link(tvbuff_t *tvb, proto_tree *tree, bool is_smc_v2)
1080 unsigned offset, rkey_count, qp_num;
1081 proto_item *add_link_flag_item;
1082 proto_tree *add_link_flag_tree;
1083 proto_item *add_link_flag2_item;
1084 proto_tree *add_link_flag2_tree;
1085 proto_item *add_link_flag3_item;
1086 proto_tree *add_link_flag3_tree;
1087 proto_item *ti;
1088 bool is_response = tvb_get_uint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP;
1090 offset = LLC_MSG_START_OFFSET;
1091 add_link_flag_item = proto_tree_add_item(tree, hf_smcr_add_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1092 add_link_flag_tree = proto_item_add_subtree(add_link_flag_item, ett_add_link_flag);
1093 proto_tree_add_item(add_link_flag_tree, hf_smcr_add_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1094 proto_tree_add_item(add_link_flag_tree, hf_smcr_add_link_response_rejected, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1095 if (is_smc_v2 && is_response) {
1096 proto_tree_add_item(add_link_flag_tree, hf_smcr_add_link_reject_reason, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1098 offset += FLAG_BYTE_LEN;
1099 proto_tree_add_item(tree, hf_smcr_add_link_mac, tvb,
1100 offset, MAC_ADDR_LEN, ENC_NA);
1101 offset += MAC_ADDR_LEN;
1102 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
1103 offset += TWO_BYTE_RESERVED; /* reserved */
1104 proto_tree_add_item(tree, hf_smcr_add_link_gid, tvb,
1105 offset, GID_LEN, ENC_NA);
1106 offset += GID_LEN;
1107 proto_tree_add_item(tree, hf_smcr_add_link_qp_number, tvb,
1108 offset, QP_LEN, ENC_BIG_ENDIAN);
1109 offset += QP_LEN;
1110 proto_tree_add_item(tree, hf_smcr_add_link_number, tvb,
1111 offset, 1, ENC_BIG_ENDIAN);
1112 offset += 1;
1113 add_link_flag2_item = proto_tree_add_item(tree, hf_smcr_add_link_flags2, tvb, offset, 1, ENC_BIG_ENDIAN);
1114 add_link_flag2_tree = proto_item_add_subtree(add_link_flag2_item, ett_add_link_flag2);
1115 ti = proto_tree_add_item(add_link_flag2_tree, hf_smcr_add_link_qp_mtu_value, tvb, offset, 1, ENC_BIG_ENDIAN);
1116 qp_num = tvb_get_int8(tvb, offset) & 0x0F;
1117 disect_smcr_translate_qp_mtu(ti, qp_num);
1118 offset += 1;
1119 proto_tree_add_item(tree, hf_smcr_add_link_initial_psn, tvb,
1120 offset, PSN_LEN, ENC_BIG_ENDIAN);
1121 offset += PSN_LEN;
1122 if (!is_smc_v2 || is_response)
1123 return;
1125 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 8, ENC_NA);
1126 offset += 8; /* reserved */
1127 add_link_flag3_item = proto_tree_add_item(tree, hf_smcr_add_link_flags3, tvb, offset, 1, ENC_BIG_ENDIAN);
1128 add_link_flag3_tree = proto_item_add_subtree(add_link_flag3_item, ett_add_link_flag3);
1129 proto_tree_add_item(add_link_flag3_tree, hf_smcr_add_link_flag3_direct_link, tvb, offset, 1, ENC_BIG_ENDIAN);
1130 offset += 1;
1131 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 1, ENC_NA);
1132 offset += 1; /* reserved */
1133 proto_tree_add_item(tree, hf_smcr_add_link_client_target_gid, tvb, offset, GID_LEN, ENC_NA);
1134 offset += GID_LEN;
1135 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 8, ENC_NA);
1136 offset += 8; /* reserved */
1137 proto_tree_add_item(tree, hf_smcr_add_link_rkey_count, tvb, offset, 2, ENC_BIG_ENDIAN);
1138 rkey_count = tvb_get_uint16(tvb, offset, ENC_BIG_ENDIAN);
1139 offset += 2;
1140 while (rkey_count > 0) {
1141 proto_tree_add_item(tree, hf_smcr_add_link_rkey, tvb, offset, RKEY_LEN, ENC_BIG_ENDIAN);
1142 offset += RKEY_LEN;
1143 proto_tree_add_item(tree, hf_smcr_add_link_rkey2, tvb, offset, RKEY_LEN, ENC_BIG_ENDIAN);
1144 offset += RKEY_LEN;
1145 proto_tree_add_item(tree, hf_smcr_add_link_virt_addr, tvb, offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
1146 offset += VIRTUAL_ADDR_LEN;
1147 rkey_count--;
1151 static void
1152 disect_smcr_add_continuation(tvbuff_t *tvb, proto_tree *tree)
1154 unsigned offset;
1155 uint8_t num_of_keys;
1156 proto_item *add_link_flag_item;
1157 proto_tree *add_link_flag_tree;
1159 offset = LLC_MSG_START_OFFSET;
1160 add_link_flag_item = proto_tree_add_item(tree, hf_smcr_add_link_cont_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1161 add_link_flag_tree = proto_item_add_subtree(add_link_flag_item, ett_add_link_cont_flag);
1162 proto_tree_add_item(add_link_flag_tree, hf_smcr_add_link_cont_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1163 offset += FLAG_BYTE_LEN;
1164 proto_tree_add_item(tree, hf_smcr_add_link_cont_link_number, tvb,
1165 offset, 1, ENC_BIG_ENDIAN);
1166 offset += 1;
1167 proto_tree_add_item(tree, hf_smcr_add_link_cont_number_of_rkeys, tvb,
1168 offset, 1, ENC_BIG_ENDIAN);
1169 num_of_keys = tvb_get_uint8(tvb,offset);
1170 offset += 1;
1172 if (num_of_keys >= 1) {
1173 proto_tree_add_item(tree, hf_smcr_add_link_cont_p1_rkey, tvb,
1174 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1175 offset += RKEY_LEN;
1176 proto_tree_add_item(tree, hf_smcr_add_link_cont_p1_rkey2, tvb,
1177 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1178 offset += RKEY_LEN;
1179 proto_tree_add_item(tree, hf_smcr_add_link_cont_p1_virt_addr, tvb,
1180 offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
1182 if (num_of_keys >= 2) {
1183 offset += VIRTUAL_ADDR_LEN;
1184 proto_tree_add_item(tree, hf_smcr_add_link_cont_p2_rkey, tvb,
1185 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1186 offset += RKEY_LEN;
1187 proto_tree_add_item(tree, hf_smcr_add_link_cont_p2_rkey2, tvb,
1188 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1189 offset += RKEY_LEN;
1190 proto_tree_add_item(tree, hf_smcr_add_link_cont_p2_virt_addr, tvb,
1191 offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
1196 static void
1197 disect_smcr_request_add_link(tvbuff_t* tvb, proto_tree* tree)
1199 bool is_response = tvb_get_uint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP;
1200 proto_item* add_link_flag_item;
1201 proto_tree* add_link_flag_tree;
1202 unsigned offset, gid_list_len;
1204 offset = LLC_MSG_START_OFFSET;
1205 add_link_flag_item = proto_tree_add_item(tree, hf_smcr_request_add_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1206 add_link_flag_tree = proto_item_add_subtree(add_link_flag_item, ett_request_add_link_flag);
1207 proto_tree_add_item(add_link_flag_tree, hf_smcr_request_add_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1208 proto_tree_add_item(add_link_flag_tree, hf_smcr_request_add_link_response_rejected, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1209 if (is_response) {
1210 proto_tree_add_item(add_link_flag_tree, hf_smcr_request_add_link_reject_reason, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1212 offset += FLAG_BYTE_LEN;
1213 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 20, ENC_NA);
1214 offset += 20; /* reserved */
1215 gid_list_len = tvb_get_uint8(tvb, offset);
1216 proto_tree_add_item(tree, hf_smc_request_add_link_gid_lst_len, tvb, offset, 1, ENC_BIG_ENDIAN);
1217 offset += 1;
1218 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 3, ENC_NA);
1219 offset += 3; /* reserved */
1220 while (gid_list_len > 0) {
1221 proto_tree_add_item(tree, hf_smc_request_add_link_gid_list_entry, tvb, offset, GID_LEN, ENC_NA);
1222 offset += GID_LEN;
1223 gid_list_len--;
1227 static void
1228 disect_smcr_delete_link(tvbuff_t *tvb, proto_tree *tree)
1230 unsigned offset;
1231 proto_item *delete_link_flag_item;
1232 proto_tree *delete_link_flag_tree;
1234 offset = LLC_MSG_START_OFFSET;
1235 delete_link_flag_item = proto_tree_add_item(tree, hf_smcr_delete_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1236 delete_link_flag_tree = proto_item_add_subtree(delete_link_flag_item, ett_delete_link_flag);
1237 proto_tree_add_item(delete_link_flag_tree, hf_smcr_delete_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1238 proto_tree_add_item(delete_link_flag_tree, hf_smcr_delete_link_all, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1239 proto_tree_add_item(delete_link_flag_tree, hf_smcr_delete_link_orderly, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1240 offset += FLAG_BYTE_LEN;
1241 proto_tree_add_item(tree, hf_smcr_delete_link_number, tvb,
1242 offset, 1, ENC_BIG_ENDIAN);
1243 offset += 1;
1244 proto_tree_add_item(tree, hf_smcr_delete_link_reason_code, tvb,
1245 offset, 4, ENC_BIG_ENDIAN);
1248 static void
1249 disect_smcr_confirm_rkey(tvbuff_t *tvb, proto_tree *tree)
1251 unsigned offset;
1252 uint8_t num_entries;
1253 proto_item *confirm_rkey_flag_item;
1254 proto_tree *confirm_rkey_flag_tree;
1256 offset = LLC_MSG_START_OFFSET;
1257 confirm_rkey_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_rkey_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1258 confirm_rkey_flag_tree = proto_item_add_subtree(confirm_rkey_flag_item, ett_confirm_rkey_flag);
1259 proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1260 proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_negative_response,
1261 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1262 proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_retry_rkey_set,
1263 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1264 offset += FLAG_BYTE_LEN;
1265 proto_tree_add_item(tree, hf_smcr_confirm_rkey_number, tvb,
1266 offset, 1, ENC_BIG_ENDIAN);
1267 num_entries = tvb_get_uint8(tvb,offset);
1269 if (num_entries > 2)
1270 num_entries = 2;
1272 offset += 1;
1273 proto_tree_add_item(tree, hf_smcr_confirm_rkey_new_rkey, tvb,
1274 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1275 offset += RKEY_LEN;
1276 proto_tree_add_item(tree, hf_smcr_confirm_rkey_virtual_address, tvb,
1277 offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
1279 for (; num_entries > 0; num_entries--) {
1280 offset += VIRTUAL_ADDR_LEN;
1281 proto_tree_add_item(tree, hf_smcr_confirm_rkey_link_number, tvb,
1282 offset, 1, ENC_BIG_ENDIAN);
1283 offset += 1;
1284 proto_tree_add_item(tree, hf_smcr_confirm_rkey_new_rkey, tvb,
1285 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1286 offset += RKEY_LEN;
1287 proto_tree_add_item(tree, hf_smcr_confirm_rkey_virtual_address, tvb,
1288 offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
1292 static void
1293 disect_smcr_confirm_rkey_cont(tvbuff_t *tvb, proto_tree *tree)
1295 unsigned offset;
1296 proto_item *confirm_rkey_flag_item;
1297 proto_tree *confirm_rkey_flag_tree;
1298 uint8_t num_entries;
1300 offset = LLC_MSG_START_OFFSET;
1301 confirm_rkey_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_rkey_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1302 confirm_rkey_flag_tree = proto_item_add_subtree(confirm_rkey_flag_item, ett_confirm_rkey_flag);
1303 proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1304 proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_negative_response,
1305 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1306 proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_retry_rkey_set,
1307 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1308 offset += FLAG_BYTE_LEN;
1309 proto_tree_add_item(tree, hf_smcr_confirm_rkey_number, tvb,
1310 offset, 1, ENC_BIG_ENDIAN);
1311 num_entries = tvb_get_uint8(tvb,offset);
1312 if (num_entries > 3)
1313 num_entries = 3;
1315 offset += 1;
1316 for (; num_entries > 0; num_entries--) {
1317 proto_tree_add_item(tree, hf_smcr_confirm_rkey_link_number, tvb,
1318 offset, 1, ENC_BIG_ENDIAN);
1319 offset += 1;
1320 proto_tree_add_item(tree, hf_smcr_confirm_rkey_new_rkey, tvb,
1321 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1322 offset += RKEY_LEN;
1323 proto_tree_add_item(tree, hf_smcr_confirm_rkey_virtual_address, tvb,
1324 offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN);
1325 offset += VIRTUAL_ADDR_LEN;
1329 static void
1330 disect_smcr_delete_rkey(tvbuff_t *tvb, proto_tree *tree, bool is_smc_v2)
1332 unsigned offset;
1333 uint8_t count;
1334 proto_item *delete_rkey_flag_item;
1335 proto_tree *delete_rkey_flag_tree;
1337 offset = LLC_MSG_START_OFFSET;
1338 delete_rkey_flag_item = proto_tree_add_item(tree, hf_smcr_delete_rkey_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1339 delete_rkey_flag_tree = proto_item_add_subtree(delete_rkey_flag_item, ett_delete_rkey_flag);
1340 proto_tree_add_item(delete_rkey_flag_tree, hf_smcr_delete_rkey_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1341 proto_tree_add_item(delete_rkey_flag_tree, hf_smcr_delete_rkey_negative_response,
1342 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1343 offset += FLAG_BYTE_LEN;
1344 count = tvb_get_uint8(tvb, offset);
1345 proto_tree_add_item(tree, hf_smcr_delete_rkey_count, tvb, offset, 1, ENC_NA);
1346 offset += 1;
1347 if (!is_smc_v2) {
1348 proto_tree_add_item(tree, hf_smcr_delete_rkey_mask, tvb, offset, 1, ENC_BIG_ENDIAN);
1349 } else {
1350 bool is_response = tvb_get_uint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP;
1351 if (is_response) {
1352 proto_tree_add_item(tree, hf_smcr_delete_rkey_invalid_count, tvb, offset, 1, ENC_NA);
1353 count = tvb_get_uint8(tvb, offset);
1354 if (count > 8)
1355 count = 8; /* show a maximum of 8 invalid rkeys in response */
1358 offset += 1;
1359 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, 2, ENC_NA);
1360 offset += 2; /* reserved */
1361 while (count > 0) {
1362 proto_tree_add_item(tree, hf_smcr_delete_rkey_deleted, tvb,
1363 offset, RKEY_LEN, ENC_BIG_ENDIAN);
1364 offset += RKEY_LEN;
1365 count--;
1369 static void
1370 disect_smcr_test_link(tvbuff_t *tvb, proto_tree *tree)
1372 unsigned offset;
1373 proto_item *test_link_flag_item;
1374 proto_tree *test_link_flag_tree;
1376 offset = LLC_MSG_START_OFFSET;
1377 test_link_flag_item = proto_tree_add_item(tree, hf_smcr_test_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1378 test_link_flag_tree = proto_item_add_subtree(test_link_flag_item, ett_test_link_flag);
1379 proto_tree_add_item(test_link_flag_tree, hf_smcr_test_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1382 static void
1383 disect_smcr_rmbe_ctrl(tvbuff_t *tvb, proto_tree *tree)
1385 int offset;
1386 proto_item *rmbe_ctrl_rw_status_flag_item;
1387 proto_tree *rmbe_ctrl_rw_status_flag_tree;
1388 proto_item *rmbe_ctrl_peer_conn_state_flag_item;
1389 proto_tree *rmbe_ctrl_peer_conn_state_flag_tree;
1391 offset = RMBE_CTRL_START_OFFSET;
1392 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_seqno, tvb, offset, SEQNO_LEN, ENC_BIG_ENDIAN);
1393 offset += SEQNO_LEN;
1394 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_alert_token, tvb, offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN);
1395 offset += ALERT_TOKEN_LEN;
1396 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
1397 offset += TWO_BYTE_RESERVED; /* reserved */
1398 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_prod_wrap_seqno, tvb, offset, SEQNO_LEN, ENC_BIG_ENDIAN);
1399 offset += SEQNO_LEN;
1400 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_peer_prod_curs, tvb, offset, CURSOR_LEN, ENC_BIG_ENDIAN);
1401 offset += CURSOR_LEN;
1402 proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA);
1403 offset += TWO_BYTE_RESERVED; /* reserved */
1404 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_cons_wrap_seqno, tvb, offset, SEQNO_LEN, ENC_BIG_ENDIAN);
1405 offset += SEQNO_LEN;
1406 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_peer_cons_curs, tvb, offset, CURSOR_LEN, ENC_BIG_ENDIAN);
1407 offset += CURSOR_LEN;
1408 rmbe_ctrl_rw_status_flag_item =
1409 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_conn_rw_status_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1410 rmbe_ctrl_rw_status_flag_tree =
1411 proto_item_add_subtree(rmbe_ctrl_rw_status_flag_item, ett_rmbe_ctrl_rw_status_flag);
1412 proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_write_blocked,
1413 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1414 proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_urgent_pending,
1415 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1416 proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_urgent_present,
1417 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1418 proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_cons_update_requested,
1419 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1420 proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_failover_validation,
1421 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1422 offset += FLAG_BYTE_LEN;
1423 rmbe_ctrl_peer_conn_state_flag_item =
1424 proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_peer_conn_state_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1425 rmbe_ctrl_peer_conn_state_flag_tree =
1426 proto_item_add_subtree(rmbe_ctrl_peer_conn_state_flag_item, ett_rmbe_ctrl_peer_conn_state_flag);
1427 proto_tree_add_item(rmbe_ctrl_peer_conn_state_flag_tree, hf_smcr_rmbe_ctrl_peer_sending_done,
1428 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1429 proto_tree_add_item(rmbe_ctrl_peer_conn_state_flag_tree, hf_smcr_rmbe_ctrl_peer_closed_conn,
1430 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1431 proto_tree_add_item(rmbe_ctrl_peer_conn_state_flag_tree, hf_smcr_rmbe_ctrl_peer_abnormal_close,
1432 tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN);
1435 static uint8_t get_mixed_type(uint8_t v1_type, uint8_t v2_type)
1437 if (v1_type == SMC_CLC_BOTH)
1438 return v1_type;
1440 if (v1_type == SMC_CLC_NONE)
1441 return v2_type;
1443 if (((v2_type == SMC_CLC_SMCD) && (v1_type == SMC_CLC_SMCR)) ||
1444 ((v2_type == SMC_CLC_SMCR) && (v1_type == SMC_CLC_SMCD)))
1445 return SMC_CLC_BOTH;
1447 return v2_type;
1450 static int
1451 dissect_smc_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1452 void *data _U_)
1454 int offset;
1455 uint16_t msg_len;
1456 uint8_t smc_type, smc_v2_type = 0, smc_v1_type = 0, smc_version = 0;
1457 uint8_t mixed_type;
1458 clc_message clc_msgid;
1459 proto_item *ti;
1460 proto_tree *smc_tree;
1461 bool is_ipv6, is_smc_v2, is_smcd = false;
1463 msg_len = tvb_get_ntohs(tvb, CLC_MSG_LEN_OFFSET);
1464 offset = 4;
1465 clc_msgid = (clc_message)tvb_get_uint8(tvb, offset);
1467 smc_version = tvb_get_uint8(tvb, offset + 3);
1468 smc_version = ((smc_version >> 4) & 0x0F);
1469 smc_type = tvb_get_uint8(tvb, offset + 3);
1470 is_smc_v2 = (smc_version >= SMC_V2);
1472 if (is_smc_v2 && (clc_msgid == SMC_CLC_PROPOSAL)) {
1473 smc_v1_type = (smc_type & 0x03);
1474 smc_v2_type = ((smc_type >> 2) & 0x03);
1476 else if (clc_msgid != SMC_CLC_DECLINE) {
1477 smc_v2_type = (smc_type & 0x03);
1478 smc_v1_type = (smc_type & 0x03);
1481 is_ipv6 = (pinfo->src.type == AT_IPv6);
1483 if (is_smc_v2)
1484 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMCv2");
1485 else
1486 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMC");
1488 if (clc_msgid == SMC_CLC_PROPOSAL) {
1489 if (is_smc_v2 && (smc_v2_type != SMC_CLC_NONE)) {
1490 mixed_type = get_mixed_type(smc_v1_type, smc_v2_type);
1491 col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s,",
1492 val_to_str_const((uint32_t)mixed_type,
1493 smcv2_clc_col_info_message_txt, "Unknown Command"));
1494 } else {
1495 col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s,",
1496 val_to_str_const((uint32_t)smc_v1_type,
1497 smc_clc_col_info_message_txt, "Unknown Command"));
1499 } else if ((smc_v2_type == SMC_CLC_SMCR) && ((clc_msgid == SMC_CLC_ACCEPT) ||
1500 (clc_msgid == SMC_CLC_CONFIRMATION))) {
1501 if (is_smc_v2)
1502 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-Rv2-%s],",
1503 val_to_str_const((uint32_t)clc_msgid,
1504 smcr_clc_message_txt, "Unknown Command"));
1505 else
1506 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-R-%s],",
1507 val_to_str_const((uint32_t)clc_msgid,
1508 smcr_clc_message_txt, "Unknown Command"));
1510 col_append_fstr(pinfo->cinfo, COL_INFO, " QP=0x%06x",
1511 tvb_get_ntoh24(tvb, ACCEPT_CONFIRM_QP_OFFSET));
1513 else if ((smc_v2_type == SMC_CLC_SMCD) && ((clc_msgid == SMC_CLC_ACCEPT) ||
1514 (clc_msgid == SMC_CLC_CONFIRMATION))) {
1515 is_smcd = true;
1516 if (is_smc_v2)
1517 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-Dv2-%s],",
1518 val_to_str_const((uint32_t)clc_msgid,
1519 smcr_clc_message_txt, "Unknown Command"));
1520 else
1521 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-D-%s],",
1522 val_to_str_const((uint32_t)clc_msgid,
1523 smcr_clc_message_txt, "Unknown Command"));
1525 else {
1526 if (is_smc_v2)
1527 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMCv2-%s],",
1528 val_to_str_const((uint32_t)clc_msgid,
1529 smcr_clc_message_txt, "Unknown Command"));
1530 else
1531 col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-%s],",
1532 val_to_str_const((uint32_t)clc_msgid,
1533 smcr_clc_message_txt, "Unknown Command"));
1536 if (!tree)
1537 return tvb_reported_length(tvb);
1539 ti = proto_tree_add_item(tree, proto_smc, tvb, 0, msg_len, ENC_NA);
1540 smc_tree = proto_item_add_subtree(ti, ett_smcr);
1541 proto_tree_add_item(smc_tree, hf_smcr_clc_msg, tvb, offset, 1,
1542 ENC_BIG_ENDIAN);
1543 switch (clc_msgid) {
1544 case SMC_CLC_PROPOSAL:
1545 disect_smc_proposal(tvb, smc_tree, is_ipv6);
1546 break;
1547 case SMC_CLC_ACCEPT:
1548 if (is_smcd)
1549 disect_smcd_accept(tvb, smc_tree);
1550 else
1551 disect_smcr_accept(tvb, smc_tree);
1552 break;
1553 case SMC_CLC_CONFIRMATION:
1554 if (is_smcd)
1555 disect_smcd_confirm(tvb, smc_tree);
1556 else
1557 disect_smcr_confirm(tvb, smc_tree);
1558 break;
1559 case SMC_CLC_DECLINE:
1560 disect_smc_decline(tvb, smc_tree);
1561 break;
1562 default:
1563 /* Unknown Command */
1564 break;
1566 return tvb_reported_length(tvb);
1569 static int
1570 dissect_smcr_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1572 uint16_t msg_len;
1573 llc_message llc_msgid;
1574 proto_item *ti;
1575 proto_tree *smcr_tree;
1576 int smc_version;
1577 bool is_smc_v2;
1579 llc_msgid = (llc_message) tvb_get_uint8(tvb, LLC_CMD_OFFSET);
1580 smc_version = ((llc_msgid >> 4) & 0x0F);
1581 is_smc_v2 = (smc_version == SMC_V2);
1583 if (!is_smc_v2) {
1584 msg_len = tvb_get_uint8(tvb, LLC_LEN_OFFSET);
1585 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMC-R");
1586 col_append_str(pinfo->cinfo, COL_INFO, "[SMC-R] ");
1587 } else {
1588 msg_len = tvb_get_uint16(tvb, LLC_LEN_OFFSET, ENC_BIG_ENDIAN);
1589 col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMC-Rv2");
1590 col_append_str(pinfo->cinfo, COL_INFO, "[SMC-Rv2] ");
1592 col_append_str(pinfo->cinfo, COL_INFO,
1593 val_to_str_const((uint32_t)llc_msgid,
1594 smcr_llc_message_txt, "Unknown Command"));
1596 if ((llc_msgid != RMBE_CTRL) &&
1597 (tvb_get_uint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP))
1598 col_append_str(pinfo->cinfo, COL_INFO, "(Resp)");
1600 ti = proto_tree_add_item(tree, proto_smc, tvb, 0, msg_len, ENC_NA);
1601 smcr_tree = proto_item_add_subtree(ti, ett_smcr);
1602 ti = proto_tree_add_item(smcr_tree, hf_smcr_llc_msg, tvb, 0, 1, ENC_BIG_ENDIAN);
1603 if ((llc_msgid != RMBE_CTRL) &&
1604 (tvb_get_uint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP))
1605 proto_item_append_text(ti, " (Resp)");
1607 proto_tree_add_item(smcr_tree, hf_smc_length, tvb, LLC_LEN_OFFSET, (!is_smc_v2?1:2), ENC_BIG_ENDIAN);
1609 switch (llc_msgid) {
1610 case LLC_CONFIRM_LINK:
1611 case LLC_CONFIRM_LINK_V2:
1612 disect_smcr_confirm_link(tvb, smcr_tree);
1613 break;
1615 case LLC_ADD_LINK:
1616 case LLC_ADD_LINK_V2:
1617 disect_smcr_add_link(tvb, smcr_tree, is_smc_v2);
1618 break;
1620 case LLC_ADD_LINK_CONT:
1621 disect_smcr_add_continuation(tvb, smcr_tree);
1622 break;
1624 case LLC_DEL_LINK:
1625 case LLC_DEL_LINK_V2:
1626 disect_smcr_delete_link(tvb, smcr_tree);
1627 break;
1629 case LLC_CONFIRM_RKEY:
1630 case LLC_CONFIRM_RKEY_V2:
1631 disect_smcr_confirm_rkey(tvb, smcr_tree);
1632 break;
1634 case LLC_CONFIRM_RKEY_CONT:
1635 disect_smcr_confirm_rkey_cont(tvb, smcr_tree);
1636 break;
1638 case LLC_DELETE_RKEY:
1639 case LLC_DELETE_RKEY_V2:
1640 disect_smcr_delete_rkey(tvb, smcr_tree, is_smc_v2);
1641 break;
1643 case LLC_TEST_LINK:
1644 case LLC_TEST_LINK_V2:
1645 disect_smcr_test_link(tvb, smcr_tree);
1646 break;
1648 case LLC_REQUEST_ADD_LINK_V2:
1649 disect_smcr_request_add_link(tvb, smcr_tree);
1650 break;
1652 case RMBE_CTRL:
1653 disect_smcr_rmbe_ctrl(tvb, smcr_tree);
1654 break;
1656 default:
1657 /* Unknown Command */
1658 break;
1661 return tvb_captured_length(tvb);
1664 static unsigned
1665 get_smcr_pdu_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *data _U_)
1667 uint32_t length;
1668 length = tvb_get_ntohs(tvb, offset+CLC_MSG_LEN_OFFSET);
1669 return length;
1672 static int
1673 dissect_smc_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1674 void *data)
1676 tcp_dissect_pdus(tvb, pinfo, tree, true, SMC_TCP_MIN_HEADER_LENGTH,
1677 get_smcr_pdu_length, dissect_smc_tcp_pdu, data);
1678 return tvb_reported_length(tvb);
1681 static bool
1682 dissect_smc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1683 void *data)
1685 if (tvb_captured_length(tvb) < 4) {
1686 return false;
1689 if ((tvb_get_ntohl(tvb, CLC_MSG_BYTE_0) != SMCR_CLC_ID) &&
1690 (tvb_get_ntohl(tvb, CLC_MSG_BYTE_0) != SMCD_CLC_ID))
1691 return false;
1693 dissect_smc_tcp(tvb, pinfo, tree, data);
1694 return true;
1697 static bool
1698 dissect_smcr_infiniband_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1699 void *data _U_)
1701 uint16_t msg_len;
1702 llc_message msg_byte0;
1703 uint8_t msg_byte1;
1704 bool v1_check = true, v2_check = true;
1706 if (tvb_captured_length_remaining(tvb, SMCR_MSG_BYTE_0) < 2) /* need at least 2 bytes */
1707 return false;
1709 /* Grab the first two bytes of the message, as they are needed */
1710 /* for validity checking of both CLC and LLC messages */
1711 msg_byte0 = (llc_message) tvb_get_uint8(tvb,CLC_MSG_BYTE_0);
1712 msg_byte1 = tvb_get_uint8(tvb,CLC_MSG_BYTE_1);
1715 /* Check for possible LLC Messages */
1717 if (!((msg_byte1 == LLC_MSG_LENGTH) &&
1718 (((msg_byte0 >= LLC_CONFIRM_LINK) &&
1719 (msg_byte0 <= LLC_DELETE_RKEY)) ||
1720 (msg_byte0 == LLC_RMBE_CTRL))))
1721 v1_check = false;
1722 if (!(((msg_byte0 >= LLC_CONFIRM_LINK_V2) &&
1723 (msg_byte0 <= LLC_ADD_LINK_V2)) ||
1724 ((msg_byte0 >= LLC_DEL_LINK_V2) &&
1725 (msg_byte0 <= LLC_TEST_LINK_V2)) ||
1726 (msg_byte0 == LLC_DELETE_RKEY_V2)))
1727 v2_check = false;
1729 if ((!v1_check && !v2_check) || (v1_check && v2_check))
1730 return false;
1732 if (v1_check)
1733 msg_len = tvb_get_uint8(tvb, LLC_LEN_OFFSET);
1734 else
1735 msg_len = tvb_get_uint16(tvb, LLC_LEN_OFFSET, ENC_BIG_ENDIAN);
1736 if (msg_len != tvb_reported_length_remaining(tvb, LLC_CMD_OFFSET))
1737 return false;
1739 dissect_smcr_infiniband(tvb, pinfo, tree, data);
1740 return true;
1743 void
1744 proto_register_smcr(void)
1746 /* Setup list of header fields */
1747 static hf_register_info hf[] = {
1748 { &hf_smcr_clc_msg, {
1749 "CLC Message", "smc.clc_msg",
1750 FT_UINT8, BASE_DEC, VALS(smcr_clc_message_txt), 0x0,
1751 NULL, HFILL}},
1753 { &hf_smcr_llc_msg, {
1754 "LLC Message", "smc.llc_msg",
1755 FT_UINT8, BASE_HEX, VALS(smcr_llc_message_txt), 0x0,
1756 NULL, HFILL}},
1758 { &hf_proposal_smc_version_release_number, {
1759 "SMC Version Release Number", "smc.proposal.smc.version.relnum",
1760 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
1762 { &hf_proposal_smc_version_seid, {
1763 "SEID Indicator", "smc.proposal.smc.seid",
1764 FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } },
1766 { &hf_proposal_smc_version, {
1767 "SMC Version", "smc.proposal.smc.version",
1768 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}},
1770 { &hf_proposal_smc_type, {
1771 "SMC(v1) Type", "smc.proposal.smc.type",
1772 FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt),
1773 0x03, NULL, HFILL}},
1775 { &hf_accept_smc_type, {
1776 "SMC Type", "smc.accept.smc.type",
1777 FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt),
1778 0x03, NULL, HFILL}},
1780 { &hf_confirm_smc_type, {
1781 "SMC Type", "smc.confirm.smc.type",
1782 FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt),
1783 0x03, NULL, HFILL}},
1785 { &hf_proposal_smc_v2_type, {
1786 "SMC(v2) Type", "smc.proposal.smcv2.type",
1787 FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt),
1788 0x0C, NULL, HFILL}},
1790 { &hf_smc_proposal_smc_chid, {
1791 "ISMv2 CHID", "smc.proposal.smc.chid",
1792 FT_UINT16, BASE_HEX, NULL, 0x00, NULL, HFILL}},
1794 { &hf_smc_length, {
1795 "SMC Length", "smc.length",
1796 FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL}},
1798 { &hf_accept_smc_version, {
1799 "SMC Version", "smc.proposal.smc.version",
1800 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}},
1802 { &hf_smcd_accept_smc_version, {
1803 "SMC Version", "smc.proposal.smc.version",
1804 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}},
1806 { &hf_smcd_confirm_smc_version, {
1807 "SMC Version", "smc.proposal.smc.version",
1808 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}},
1810 { &hf_accept_first_contact, {
1811 "First Contact", "smc.proposal.first.contact",
1812 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}},
1814 { &hf_confirm_smc_version, {
1815 "SMC Version", "smc.proposal.smc.version",
1816 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}},
1818 { &hf_accept_rmb_buffer_size, {
1819 "Server RMB Buffers Size (Compressed Notation)",
1820 "smc.accept.rmb.buffer.size",
1821 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}},
1823 { &hf_accept_qp_mtu_value, {
1824 "QP MTU Value (enumerated value)",
1825 "smc.accept.qp.mtu.value",
1826 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}},
1828 { &hf_confirm_rmb_buffer_size, {
1829 "Client RMB Buffers Size (Compressed Notation)",
1830 "smc.confirm.rmb.buffer.size",
1831 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}},
1833 { &hf_confirm_qp_mtu_value, {
1834 "QP MTU Value (enumerated value)",
1835 "smc.confirm.qp.mtu.value",
1836 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}},
1838 { &hf_smc_proposal_flags, {
1839 "Flags", "smc.proposal.flags",
1840 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1842 { &hf_smc_proposal_ext_flags, {
1843 "Flag 2", "smc.proposal.extflags.2",
1844 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1846 { &hf_smcr_accept_flags, {
1847 "Flags", "smc.accept.flags",
1848 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1850 { &hf_smcr_accept_flags2, {
1851 "Flags 2", "smc.accept.flags.2",
1852 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1854 { &hf_smcr_confirm_flags, {
1855 "Flags", "smc.confirm.flags",
1856 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1858 { &hf_decline_smc_version, {
1859 "SMC Version", "smc.decline.smc.version",
1860 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL} },
1862 { &hf_decline_out_of_sync, {
1863 "Out of Sync", "smc.decline.osync",
1864 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL} },
1866 { &hf_smc_decline_flags2, {
1867 "Flags 2", "smc.decline.flags2",
1868 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1870 { &hf_smc_decline_flags, {
1871 "Flags", "smc.decline.flags",
1872 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
1874 { &hf_smcr_confirm_flags2, {
1875 "Flags 2", "smc.confirm.flags.2",
1876 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1878 { &hf_smc_proposal_client_peer_id, {
1879 "Sender (Client) Peer ID", "smc.proposal.sender.client.peer.id",
1880 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1882 { &hf_smc_proposal_ism_gid_count, {
1883 "ISMv2 GID Count", "smc.proposal.ismv2_gid_count",
1884 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
1886 { &hf_smc_proposal_ism_gid, {
1887 "ISM GID", "smc.proposal.ism.gid",
1888 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1890 { &hf_smc_proposal_client_preferred_gid, {
1891 "Client Preferred GID", "smc.proposal.client.preferred.gid",
1892 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1894 { &hf_smc_proposal_client_preferred_mac, {
1895 "Client Preferred MAC Address",
1896 "smc.proposal.client.preferred.mac",
1897 FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1899 { &hf_smcr_accept_server_peer_id, {
1900 "Sender (Server) Peer ID", "smc.accept.sender.server.peer.id",
1901 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1903 { &hf_smcr_accept_server_preferred_gid, {
1904 "Server Preferred GID", "smc.accept.server.preferred.gid",
1905 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1907 { &hf_smcr_accept_server_preferred_mac, {
1908 "Server Preferred MAC Address",
1909 "smc.accept.server.preferred.mac",
1910 FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1912 { &hf_smc_proposal_smcv1_subnet_ext_offset, {
1913 "SMCv1 IP Subnet Extension Offset","smc.proposal.smcv1_subnet_ext_offset",
1914 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} },
1916 { &hf_smc_proposal_smcv2_ext_offset, {
1917 "SMCv2 Extension Offset","smc.proposal.smcv2_ext_offset",
1918 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} },
1920 { &hf_smc_proposal_smcdv2_ext_offset, {
1921 "SMC-Dv2 Extension Offset","smc.proposal.smcdv2_ext_offset",
1922 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL} },
1924 { &hf_smc_proposal_rocev2_gid_ipv6_addr, {
1925 "RoCEv2 GID IPv6 Address",
1926 "smc.proposal.rocev2.gid.ipv6",
1927 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL} },
1929 { &hf_smc_proposal_rocev2_gid_ipv4_addr, {
1930 "RoCEv2 GID IPv4 Address",
1931 "smc.proposal.rocev2.gid.ipv4",
1932 FT_IPv4, BASE_NETMASK, NULL, 0x0, NULL, HFILL}},
1934 { &hf_smc_proposal_outgoing_interface_subnet_mask, {
1935 "Outgoing Interface Subnet Mask",
1936 "smc.outgoing.interface.subnet.mask",
1937 FT_IPv4, BASE_NETMASK, NULL, 0x0, NULL, HFILL}},
1939 { &hf_smc_proposal_outgoing_subnet_mask_signifcant_bits, {
1940 "Outgoing Interface Subnet Mask Number of Significant Bits",
1941 "smc.outgoing.interface.subnet.mask.number.of.significant.bits",
1942 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1944 { &hf_smc_proposal_ipv6_prefix_count, {
1945 "IPv6 Prefix Count","smc.proposal.ipv6.prefix.count",
1946 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
1948 { &hf_smc_proposal_ipv6_prefix, {
1949 "IPv6 Prefix Value","smc.proposal.ipv6.prefix.value",
1950 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1952 { &hf_smc_proposal_ipv6_prefix_length, {
1953 "IPv6 Prefix Length", "smc.proposal.ipv6.prefix.length",
1954 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1956 { &hf_smcr_accept_server_qp_number, {
1957 "Server QP Number","smc.accept.server.qp.number",
1958 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1960 { &hf_smcr_accept_server_rmb_rkey, {
1961 "Server RMB Rkey","smc.accept.server.rmb.rkey",
1962 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1964 { &hf_smcr_accept_server_tcp_conn_index, {
1965 "Server TCP Connection Index",
1966 "smc.accept.server.tcp.conn.index",
1967 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
1969 { &hf_smcr_accept_server_rmb_element_alert_token, {
1970 "Server RMB Element Alert Token",
1971 "smc.accept.server.rmb.element.alert.token",
1972 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1974 { &hf_smcr_accept_server_rmb_virtual_address, {
1975 "Server's RMB Virtual Address",
1976 "smc.accept.server.rmb.virtual.address",
1977 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1979 { &hf_smcr_accept_initial_psn, {
1980 "Initial PSN","smc.accept.initial.psn",
1981 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1983 { &hf_smcr_confirm_client_peer_id, {
1984 "Sender (Client) Peer ID",
1985 "smc.confirm.sender.client.peer.id",
1986 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
1988 { &hf_smcr_confirm_client_gid, {
1989 "Client GID", "smc.client.gid",
1990 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1992 { &hf_smcr_confirm_client_mac, {
1993 "Client MAC Address", "smc.confirm.client.mac",
1994 FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
1996 { &hf_smcr_confirm_client_qp_number, {
1997 "Client QP Number","smc.confirm.client.qp.number",
1998 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2000 { &hf_smcr_confirm_client_rmb_rkey, {
2001 "Client RMB Rkey","smc.confirm.client.rmb.rkey",
2002 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2004 { &hf_smcr_confirm_client_tcp_conn_index, {
2005 "Client TCP Connection Index",
2006 "smc.confirm.client.tcp.conn.index",
2007 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2009 { &hf_smcr_confirm_client_rmb_element_alert_token, {
2010 "Client RMB Element Alert Token",
2011 "smc.client.rmb.element.alert.token",
2012 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2014 { &hf_smcr_confirm_client_rmb_virtual_address, {
2015 "Client's RMB Virtual Address",
2016 "smc.client.rmb.virtual.address",
2017 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2019 { &hf_smcr_confirm_initial_psn, {
2020 "Initial PSN","smc.initial.psn",
2021 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2023 { &hf_smc_decline_peer_id, {
2024 "Sender Peer ID", "smc.sender.peer.id",
2025 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2027 { &hf_smc_decline_diag_info, {
2028 "Peer Diagnosis Information", "smc.peer.diag.info",
2029 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2031 { &hf_decline_os_type, {
2032 "OS Type", "smc.decline.os.type",
2033 FT_UINT8, BASE_DEC, VALS(smc_clc_os_message_txt), 0xF0, NULL, HFILL} },
2035 { &hf_smcr_confirm_link_gid, {
2036 "Sender GID", "smc.sender.gid",
2037 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2039 { &hf_smcr_confirm_link_mac, {
2040 "Sender MAC Address", "smc.confirm.link.sender.mac",
2041 FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2043 { &hf_smcr_confirm_link_qp_number, {
2044 "Sender QP Number","smc.confirm.link.sender.qp.number",
2045 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2047 { &hf_smcr_confirm_link_number, {
2048 "Link Number", "smc.confirm.link.number",
2049 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2051 { &hf_smcr_confirm_link_userid, {
2052 "Sender Link User ID",
2053 "smc.confirm.link.sender.link.userid",
2054 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2056 { &hf_smcr_confirm_link_max_links, {
2057 "Max Links","smc.confirm.link.max.links",
2058 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2060 { &hf_smcr_confirm_link_flags, {
2061 "Flags", "smc.confirm.link.flags",
2062 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2064 { &hf_smcr_confirm_link_response, {
2065 "Response", "smc.confirm.link.response",
2066 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2068 { &hf_smcr_add_link_gid, {
2069 "Sender GID", "smc.add.link.sender.gid",
2070 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2072 { &hf_smcr_add_link_mac, {
2073 "Sender MAC Address", "smc.add.link.sender.mac",
2074 FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2076 { &hf_smcr_add_link_qp_number, {
2077 "Sender QP Number","smc.add.link.sender.qp.number",
2078 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2080 { &hf_smcr_add_link_number, {
2081 "Link Number", "smc.add.link.link.number",
2082 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2084 { &hf_smcr_add_link_initial_psn, {
2085 "Initial PSN", "smc.add.link.initial.psn",
2086 FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2088 { &hf_smcr_add_link_flags, {
2089 "Flags", "smc.add.link.flags",
2090 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2092 { &hf_smcr_add_link_response, {
2093 "Add Link Response", "smc.add.link.response",
2094 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2096 { &hf_smcr_add_link_response_rejected, {
2097 "Add Link Rejected", "smc.add.link.response.rejected",
2098 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}},
2100 { &hf_smcr_add_link_reject_reason, {
2101 "Reject Reason", "smc.add.link.response.reject_reason",
2102 FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL}},
2104 { &hf_smcr_add_link_flags2, {
2105 "Flags", "smc.add.link.flags2",
2106 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2108 { &hf_smcr_add_link_qp_mtu_value, {
2109 "QP MTU Value (enumerated value)", "smc.add.link.qp.mtu.value",
2110 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}},
2112 { &hf_smcr_add_link_flags3, {
2113 "V2 Flags", "smc.add.link.flags3",
2114 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2116 { &hf_smcr_add_link_flag3_direct_link, {
2117 "Direct link attachment to peer", "smc.add.link.direct_link",
2118 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2120 { &hf_smcr_add_link_client_target_gid, {
2121 "Client Target GID", "smc.add.link.client_target_gid",
2122 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2124 { &hf_smcr_add_link_rkey_count, {
2125 "Number of Rkeys", "smc.add.link.rkey_count",
2126 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2128 { &hf_smcr_add_link_rkey, {
2129 "RMB RToken Pair - Rkey as known on this SMC Link",
2130 "smc.add.link.rmb.RTok.Rkey1",
2131 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2133 { &hf_smcr_add_link_rkey2, {
2134 "RMB RToken Pair - Equivalent Rkey for the new SMC Link",
2135 "smc.add.link.rmb.RTok.Rkey2",
2136 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2138 { &hf_smcr_add_link_virt_addr, {
2139 "RMB RToken Pair - Virtual Address for the new SMC Link",
2140 "smc.add.link.rmb.RTok.virt",
2141 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2143 { &hf_smcr_add_link_cont_flags, {
2144 "Flags", "smc.add.link.cont.flags",
2145 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2147 { &hf_smcr_add_link_cont_response, {
2148 "Response", "smc.add.link.cont.response",
2149 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2151 { &hf_smcr_add_link_cont_link_number, {
2152 "Link Number", "smc.add.link.cont.link.number",
2153 FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}},
2155 { &hf_smcr_add_link_cont_number_of_rkeys, {
2156 "Number of Rkeys", "smc.add.link.cont.rkey.number",
2157 FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL}},
2159 { &hf_smcr_add_link_cont_p1_rkey, {
2160 "RMB RToken Pair 1 - Rkey as known on this SMC Link",
2161 "smc.add.link.cont.rmb.RTok1.Rkey1",
2162 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2164 { &hf_smcr_add_link_cont_p1_rkey2, {
2165 "RMB RToken Pair 1 - Equivalent Rkey for the new SMC Link",
2166 "smc.add.link.cont.rmb.RTok1.Rkey2",
2167 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2169 { &hf_smcr_add_link_cont_p1_virt_addr, {
2170 "RMB RToken Pair 1 Virtual Address for the new SMC Link",
2171 "smc.add.link.cont.rmb.RTok1.virt",
2172 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2174 { &hf_smcr_add_link_cont_p2_rkey, {
2175 "RMB RToken Pair 2 - Rkey as known on this SMC Link",
2176 "smc.add.link.cont.rmb.RTok2.Rkey1",
2177 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2179 { &hf_smcr_add_link_cont_p2_rkey2, {
2180 "RMB RToken Pair 2 - Equivalent Rkey for the new SMC Link",
2181 "smc.add.link.cont.rmb.RTok2.Rkey2",
2182 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2184 { &hf_smcr_add_link_cont_p2_virt_addr, {
2185 "RMB RToken Pair 2 Virtual Address for the new SMC Link",
2186 "smc.add.link.cont.rmb.RTok2.virt",
2187 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2189 { &hf_smcr_request_add_link_flags, {
2190 "Flags", "smc.add.link.flags",
2191 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2193 { &hf_smcr_request_add_link_response, {
2194 "Request Add Link Response", "smc.request.add.link.response",
2195 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL} },
2197 { &hf_smcr_request_add_link_response_rejected, {
2198 "Request Add Link Rejected", "smc.request.add.link.response.rejected",
2199 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL} },
2201 { &hf_smcr_request_add_link_reject_reason, {
2202 "Reject Reason", "smc.request.add.link.response.reject_reason",
2203 FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL} },
2205 { &hf_smc_request_add_link_gid_lst_len, {
2206 "GID List Entry Count", "smc.request.add.link.gid.list.entry_count",
2207 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
2209 { &hf_smc_request_add_link_gid_list_entry, {
2210 "RoCEv2 GID List Entry", "smc.request.add.link.gid.list.entry",
2211 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2213 { &hf_smcr_delete_link_flags, {
2214 "Flags", "smc.delete.link.flags",
2215 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2217 { &hf_smcr_delete_link_response, {
2218 "Response", "smc.delete.link.response",
2219 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2221 { &hf_smcr_delete_link_all, {
2222 "Terminate All Links In The Link Group",
2223 "smc.delete.link.all",
2224 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}},
2226 { &hf_smcr_delete_link_orderly, {
2227 "Terminate Links Orderly", "smc.delete.link.orderly",
2228 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
2230 { &hf_smcr_delete_link_number, {
2231 "Link Number For The Failed Link", "smc.delete.link.number",
2232 FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}},
2234 { &hf_smcr_delete_link_reason_code, {
2235 "Reason Code", "smc.delete.link.reason.code",
2236 FT_UINT32, BASE_HEX, NULL, 0x00, NULL, HFILL}},
2238 { &hf_smcr_confirm_rkey_flags, {
2239 "Flags", "smc.confirm.rkey.flags",
2240 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2242 { &hf_smcr_confirm_rkey_response, {
2243 "Response", "smc.confirm.rkey.response",
2244 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2246 { &hf_smcr_confirm_rkey_negative_response, {
2247 "Negative Response", "smc.confirm.rkey.negative.response",
2248 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
2250 { &hf_smcr_confirm_rkey_retry_rkey_set, {
2251 "Retry Rkey Set", "smc.confirm.rkey.retry.rkey.set",
2252 FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}},
2254 { &hf_smcr_confirm_rkey_number, {
2255 "Number of other QP", "smc.confirm.rkey.number.qp",
2256 FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL}},
2258 { &hf_smcr_confirm_rkey_new_rkey, {
2259 "New Rkey for this link","smc.confirm.rkey.new.rkey",
2260 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2262 { &hf_smcr_confirm_rkey_virtual_address, {
2263 "New RMB virtual address for this link",
2264 "smc.confirm.rkey.new.virt",
2265 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2267 { &hf_smcr_confirm_rkey_link_number, {
2268 "Link Number", "smc.confirm.rkey.link.number",
2269 FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}},
2271 { &hf_smcr_delete_rkey_flags, {
2272 "Flags", "smc.delete.rkey.flags",
2273 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2275 { &hf_smcr_delete_rkey_response, {
2276 "Response", "smc.delete.rkey.response",
2277 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2279 { &hf_smcr_delete_rkey_negative_response, {
2280 "Negative Response", "smc.delete.rkey.negative.response",
2281 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
2283 { &hf_smcr_delete_rkey_mask, {
2284 "Error Mask", "smc.delete.rkey.error.mask",
2285 FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}},
2287 { &hf_smcr_delete_rkey_deleted, {
2288 "RMB Rkey to be deleted", "smc.delete.rkey.deleted",
2289 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2291 { &hf_smcr_delete_rkey_count, {
2292 "Rkey Count", "smc.delete.rkey.count",
2293 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2295 { &hf_smcr_delete_rkey_invalid_count, {
2296 "Invalid Rkey Count", "smc.delete.rkey.count.invalid",
2297 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2299 { &hf_smcr_test_link_flags, {
2300 "Flags", "smc.test.link.flags",
2301 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2303 { &hf_smcr_test_link_response, {
2304 "Response", "smc.test.link.response",
2305 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2307 { &hf_smcr_rmbe_ctrl_seqno, {
2308 "Sequence Number", "smc.rmbe.ctrl.seqno",
2309 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2311 { &hf_smcr_rmbe_ctrl_alert_token, {
2312 "Alert Token", "smc.rmbe.ctrl.alert.token",
2313 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2315 { &hf_smc_proposal_eid_count, {
2316 "EID Count", "smc.proposal.eid.count",
2317 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
2319 { &hf_smc_proposal_eid, {
2320 "EID", "smc.proposal.eid",
2321 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2323 { &hf_smc_proposal_system_eid, {
2324 "SEID", "smc.proposal.system.eid",
2325 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2327 { &hf_smcr_rmbe_ctrl_prod_wrap_seqno, {
2328 "Producer window wrap sequence number",
2329 "smc.rmbe.ctrl.prod.wrap.seq",
2330 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2332 { &hf_smcr_rmbe_ctrl_peer_prod_curs, {
2333 "Peer Producer Cursor", "smc.rmbe.ctrl.peer.prod.curs",
2334 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2336 { &hf_smcr_rmbe_ctrl_cons_wrap_seqno, {
2337 "Consumer window wrap sequence number",
2338 "smc.rmbe.ctrl.cons.wrap.seq",
2339 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2341 { &hf_smcr_rmbe_ctrl_peer_cons_curs, {
2342 "Peer Consumer Cursor", "smc.rmbe.ctrl.peer.cons.curs",
2343 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2345 { &hf_smcr_rmbe_ctrl_conn_rw_status_flags, {
2346 "Connection read/write status flags",
2347 "smc.rmbe.ctrl.conn.rw.status.flags",
2348 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2350 { &hf_smcr_rmbe_ctrl_write_blocked, {
2351 "Write Blocked", "smc.rmbe.ctrl.write.blocked",
2352 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2354 { &hf_smcr_rmbe_ctrl_urgent_pending, {
2355 "Urgent Data Pending", "smc.rmbe.ctrl.urgent.pending",
2356 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}},
2358 { &hf_smcr_rmbe_ctrl_urgent_present, {
2359 "Urgent Data Present", "smc.rmbe.ctrl.urgent.present",
2360 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
2362 { &hf_smcr_rmbe_ctrl_cons_update_requested, {
2363 "Consumer Cursor Update Requested",
2364 "smc.rmbe.ctrl.cons.update.requested",
2365 FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}},
2367 { &hf_smcr_rmbe_ctrl_failover_validation, {
2368 "Failover Validation Indicator",
2369 "smc.rmbe.ctrl.failover.validation",
2370 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}},
2372 { &hf_smcr_rmbe_ctrl_peer_conn_state_flags, {
2373 "Peer Connection State Flags",
2374 "smc.rmbe.ctrl.peer.conn.state.flags",
2375 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}},
2377 { &hf_smcr_rmbe_ctrl_peer_sending_done, {
2378 "Peer Sending Done", "smc.rmbe.ctrl.peer.sending.done",
2379 FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}},
2381 { &hf_smcr_rmbe_ctrl_peer_closed_conn, {
2382 "Peer Closed Connection", "smc.rmbe.ctrl.peer.closed.conn",
2383 FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}},
2385 { &hf_smcr_rmbe_ctrl_peer_abnormal_close, {
2386 "Peer Abnormal Close", "smc.rmbe.ctrl.peer.abnormal.close",
2387 FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}},
2389 { &hf_smc_accept_eid, {
2390 "Negotiated EID", "smc.accept.eid",
2391 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2393 { &hf_smc_confirm_eid, {
2394 "Negotiated EID", "smc.confirm.eid",
2395 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2397 { &hf_smc_accept_peer_name, {
2398 "Peer Host Name", "smc.accept.peer.host.name",
2399 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2401 { &hf_smc_confirm_peer_name, {
2402 "Peer Host Name", "smc.confirm.peer.host.name",
2403 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2405 { &hf_smc_confirm_gid_lst_len, {
2406 "GID List Entry Count", "smc.confirm.gid.list.entry_count",
2407 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
2409 { &hf_smc_confirm_gid_list_entry, {
2410 "RoCEv2 GID List Entry", "smc.confirm.gid.list.entry",
2411 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL} },
2413 { &hf_smcd_accept_first_contact, {
2414 "First Contact", "smc.accept.first.contact",
2415 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL} },
2417 { &hf_smc_confirm_first_contact, {
2418 "First Contact", "smc.confirm.first.contact",
2419 FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL} },
2421 { &hf_accept_smc_version_release_number, {
2422 "SMC Version Release Number", "smc.accept.smc.version.relnum",
2423 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL } },
2425 { &hf_confirm_smc_version_release_number, {
2426 "SMC Version Release Number", "smc.confirm.smc.version.relnum",
2427 FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL } },
2429 { &hf_accept_os_type, {
2430 "OS Type", "smc.accept.os.type",
2431 FT_UINT8, BASE_DEC, VALS(smc_clc_os_message_txt), 0xF0, NULL, HFILL} },
2433 { &hf_accept_v2_lg_type, {
2434 "V2 LG Type", "smc.accept.v2_lg.type",
2435 FT_UINT8, BASE_DEC, VALS(smc_clc_v2_lg_message_txt), 0x80, NULL, HFILL} },
2437 { &hf_confirm_os_type, {
2438 "OS Type", "smc.confirm.os.type",
2439 FT_UINT8, BASE_DEC, VALS(smc_clc_os_message_txt), 0xF0, NULL, HFILL} },
2441 { &hf_smcd_accept_dmb_token, {
2442 "DMB Token", "smc.accept.dmb.token",
2443 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2445 { &hf_smcd_confirm_dmb_token, {
2446 "DMB Token", "smc.confirm.dmb.token",
2447 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2449 { &hf_accept_dmb_buffer_size, {
2450 "Server DMBE Buffers Size (Compressed Notation)",
2451 "smc.accept.dmbe.buffer.size",
2452 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL} },
2454 { &hf_smcd_confirm_dmb_buffer_size, {
2455 "Client DMBE Buffers Size (Compressed Notation)",
2456 "smc.confirm.dmbe.buffer.size",
2457 FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL} },
2459 { &hf_smcd_accept_smc_chid, {
2460 "ISMv2 CHID", "smc.accept.smc.chid",
2461 FT_UINT16, BASE_HEX, NULL, 0x00, NULL, HFILL} },
2463 { &hf_smcd_confirm_smc_chid, {
2464 "ISMv2 CHID", "smc.confirm.smc.chid",
2465 FT_UINT16, BASE_HEX, NULL, 0x00, NULL, HFILL} },
2467 { &hf_smcd_accept_server_peer_id, {
2468 "Sender (Server) ISM GID", "smc.accept.sender.server.ism.gid",
2469 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2471 { &hf_smcd_confirm_client_peer_id, {
2472 "Sender (Client) ISM GID", "smc.confirm.sender.client.ism.gid",
2473 FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2475 { &hf_smcd_accept_dmbe_conn_index, {
2476 "DMBE Connection Index",
2477 "smc.accept.dmbe.conn.index",
2478 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
2480 { &hf_smcd_accept_server_link_id, {
2481 "Server Link ID",
2482 "smc.accept.server.linkid",
2483 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2485 { &hf_smcd_confirm_dmbe_conn_index, {
2486 "DMBE Connection Index",
2487 "smc.confirm.dmbe.conn.index",
2488 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL} },
2490 { &hf_smcd_confirm_client_link_id, {
2491 "Client Link ID",
2492 "smc.confirm.client.linkid",
2493 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2495 { &hf_smcd_accept_flags, {
2496 "Flags", "smc.accept.flags",
2497 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2499 { &hf_smcd_confirm_flags, {
2500 "Flags", "smc.confirm.flags",
2501 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2503 { &hf_smcd_accept_flags2, {
2504 "DMBE Size", "smc.accept.dmbe.size",
2505 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2507 { &hf_smcd_confirm_flags2, {
2508 "DMBE Size", "smc.confirm.dmbe.size",
2509 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2511 { &hf_smc_accept_fce_flags, {
2512 "Flags", "smc.accept.fce.flags",
2513 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2515 { &hf_smcr_accept_fce_flags, {
2516 "Flags", "smc.accept.fce1.flags",
2517 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} },
2519 { &hf_smc_reserved, {
2520 "Reserved", "smc.reserved",
2521 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} }
2524 /* Setup protocol subtree arrays */
2525 static int* ett[] = {
2526 &ett_smcr,
2527 &ett_proposal_flag,
2528 &ett_proposal_ext_flag2,
2529 &ett_accept_flag,
2530 &ett_accept_flag2,
2531 &ett_smcr_accept_fce_flag1,
2532 &ett_smcd_accept_flag,
2533 &ett_smcd_accept_flag2,
2534 &ett_smc_accept_fce_flag,
2535 &ett_smcd_confirm_flag,
2536 &ett_smc_confirm_fce_flag,
2537 &ett_smcd_confirm_flag2,
2538 &ett_confirm_flag,
2539 &ett_confirm_flag2,
2540 &ett_confirm_link_flag,
2541 &ett_decline_flag,
2542 &ett_decline_flag2,
2543 &ett_add_link_flag,
2544 &ett_add_link_flag2,
2545 &ett_add_link_flag3,
2546 &ett_add_link_cont_flag,
2547 &ett_request_add_link_flag,
2548 &ett_delete_link_flag,
2549 &ett_confirm_rkey_flag,
2550 &ett_delete_rkey_flag,
2551 &ett_test_link_flag,
2552 &ett_rmbe_ctrl_rw_status_flag,
2553 &ett_rmbe_ctrl_peer_conn_state_flag
2556 proto_smc = proto_register_protocol("Shared Memory Communications",
2557 "SMC", "smc");
2559 proto_register_field_array(proto_smc, hf, array_length(hf));
2560 proto_register_subtree_array(ett, array_length(ett));
2562 smc_tcp_handle = register_dissector("smc", dissect_smc_tcp, proto_smc);
2563 smc_infiniband_handle = register_dissector("smc.infiniband", dissect_smcr_infiniband, proto_smc);
2566 void
2567 proto_reg_handoff_smcr(void)
2569 heur_dissector_add("tcp", dissect_smc_tcp_heur, "Shared Memory Communications over TCP", "smc_tcp", proto_smc, HEURISTIC_ENABLE);
2570 heur_dissector_add("infiniband.payload", dissect_smcr_infiniband_heur, "Shared Memory Communications Infiniband", "smcr_infiniband", proto_smc, HEURISTIC_ENABLE);
2571 dissector_add_for_decode_as("infiniband", smc_infiniband_handle);
2575 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2577 * Local variables:
2578 * c-basic-offset: 8
2579 * tab-width: 8
2580 * indent-tabs-mode: t
2581 * End:
2583 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
2584 * :indentSize=8:tabSize=8:noTabs=false: