diff options
author | Joe Fowler <fowlerja@us.ibm.com> | 2014-11-18 13:13:46 -0500 |
---|---|---|
committer | Bill Meier <wmeier@newsguy.com> | 2014-11-25 04:48:27 +0000 |
commit | 392dae58db55c1db9e18f4ceefbd25355f6b793e (patch) | |
tree | 7cabe37b0f9179aa3e5f4f4281801a0bd44abd08 | |
parent | 363b87a4befcfbdd61ed7656283022a31afb2ab5 (diff) |
Add new dissector for Shared Memory Communications over RDMA protocol (SMC-R)
RFC draft http://www.ietf.org/id/draft-fox-tcpm-shared-memory-rdma-05.txt
used as reference for packet dissection.
A small change was made to packet-infiniband, to add the Queue Number to the
info column. This allows for easy indentification of session traffic for a
particular QP.
Also: infiniband: tvb_length() --> tvb_captured_length()
Bug: 10715
Change-Id: I774ceffaa5c271cb6a28ab4ed21e53cd42f2547b
Reviewed-on: https://code.wireshark.org/review/5386
Petri-Dish: Bill Meier <wmeier@newsguy.com>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Bill Meier <wmeier@newsguy.com>
-rw-r--r-- | AUTHORS | 9 | ||||
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | docbook/release-notes.asciidoc | 1 | ||||
-rw-r--r-- | epan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | epan/dissectors/Makefile.common | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-infiniband.c | 29 | ||||
-rw-r--r-- | epan/dissectors/packet-smcr.c | 1439 |
7 files changed, 1469 insertions, 14 deletions
@@ -3627,15 +3627,20 @@ Raphaƫl Doursenaud <rdoursenaud[AT]free.fr> { Harman Pro HiQnet dissector } -Ryan Doyle <ryan[AT]doylenet.net> { +Ryan Doyle <ryan[AT]doylenet.net> { Dissector for Elasticsearch Dissector for Performance Co-Pilot } -Jesse Gross <jesse[AT]nicira.com> { +Jesse Gross <jesse[AT]nicira.com> { Dissector for Geneve } +Joe Fowler <fowlerja[AT]us.ibm.com> { + Dissector for Shared Memory Communication over RDMA (SMC-R) +} + + and by: Georgi Guninski <guninski[AT]guninski.com> @@ -57,7 +57,8 @@ What's New Couchbase, CP "Cooper" 2179, Dynamic Source Routing (RFC 4728), Generic Network Virtualization Encapsulation (Geneve), GVSP, IPMI Trace, iSER, KNXnetIP, MCPE (Minecraft Pocket Edition), OptoMMP, RakNet games - library, S7 Communication, Stateless Transport Tunneling and Elasticsearch + library, S7 Communication, Stateless Transport Tunneling and Elasticsearch, + Shared Memory Communications - RDMA Updated Protocol Support diff --git a/docbook/release-notes.asciidoc b/docbook/release-notes.asciidoc index 7f4f415d93..0d65abd695 100644 --- a/docbook/release-notes.asciidoc +++ b/docbook/release-notes.asciidoc @@ -87,6 +87,7 @@ Couchbase AllJoyn Reliable Datagram Protocol HiQnet Elasticsearch +Shared Memory Communications - RDMA --sort-and-group-- === Updated Protocol Support diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 2560f21b78..0040a2205b 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -1248,6 +1248,7 @@ set(DISSECTOR_SRC dissectors/packet-smb-direct.c dissectors/packet-smb.c dissectors/packet-smb2.c + dissectors/packet-smcr.c dissectors/packet-sml.c dissectors/packet-smpp.c dissectors/packet-smtp.c diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index f2ec44a3da..35b87f8ea3 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -1160,6 +1160,7 @@ DISSECTOR_SRC = \ packet-smb-direct.c \ packet-smb.c \ packet-smb2.c \ + packet-smcr.c \ packet-sml.c \ packet-smpp.c \ packet-smtp.c \ diff --git a/epan/dissectors/packet-infiniband.c b/epan/dissectors/packet-infiniband.c index 6154e3c0a2..7602f9e5b4 100644 --- a/epan/dissectors/packet-infiniband.c +++ b/epan/dissectors/packet-infiniband.c @@ -1756,14 +1756,21 @@ skip_lrh: proto_tree_add_item(base_transport_header_tree, hf_infiniband_solicited_event, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(base_transport_header_tree, hf_infiniband_migreq, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(base_transport_header_tree, hf_infiniband_pad_count, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(base_transport_header_tree, hf_infiniband_transport_header_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; - proto_tree_add_item(base_transport_header_tree, hf_infiniband_partition_key, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; - proto_tree_add_item(base_transport_header_tree, hf_infiniband_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; + proto_tree_add_item(base_transport_header_tree, hf_infiniband_transport_header_version, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(base_transport_header_tree, hf_infiniband_partition_key, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; + proto_tree_add_item(base_transport_header_tree, hf_infiniband_reserved8, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; proto_tree_add_item(base_transport_header_tree, hf_infiniband_destination_qp, tvb, offset, 3, ENC_BIG_ENDIAN); - pinfo->destport = tvb_get_ntoh24(tvb, offset); offset += 3; + pinfo->destport = tvb_get_ntoh24(tvb, offset); + col_append_fstr(pinfo->cinfo, COL_INFO, "QP=0x%06x ", pinfo->destport); + offset += 3; proto_tree_add_item(base_transport_header_tree, hf_infiniband_acknowledge_request, tvb, offset, 1, ENC_BIG_ENDIAN); - proto_tree_add_item(base_transport_header_tree, hf_infiniband_reserved7, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; - proto_tree_add_item(base_transport_header_tree, hf_infiniband_packet_sequence_number, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; + proto_tree_add_item(base_transport_header_tree, hf_infiniband_reserved7, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(base_transport_header_tree, hf_infiniband_packet_sequence_number, tvb, offset, 3, ENC_BIG_ENDIAN); + offset += 3; offset += bthSize - 12; packetLength -= bthSize; /* Shave bthSize for Base Transport Header */ } @@ -2487,7 +2494,7 @@ static void parse_PAYLOAD(proto_tree *parentTree, /* Get the captured length and reported length of the data after the Ethernet type. */ - captured_length = tvb_length_remaining(tvb, local_offset+4); + captured_length = tvb_captured_length_remaining(tvb, local_offset+4); reported_length = tvb_reported_length_remaining(tvb, local_offset+4); next_tvb = tvb_new_subset(tvb, local_offset+4, captured_length, reported_length); @@ -2545,7 +2552,7 @@ static void parse_PAYLOAD(proto_tree *parentTree, } - captured_length = tvb_length_remaining(tvb, local_offset); + captured_length = tvb_captured_length_remaining(tvb, local_offset); reported_length = tvb_reported_length_remaining(tvb, local_offset); @@ -2608,7 +2615,7 @@ static void parse_IPvSix(proto_tree *parentTree, tvbuff_t *tvb, gint *offset, pa /* (- 2) for VCRC which lives at the end of the packet */ ipv6_tvb = tvb_new_subset(tvb, *offset, - tvb_length_remaining(tvb, *offset) - 2, + tvb_captured_length_remaining(tvb, *offset) - 2, tvb_reported_length_remaining(tvb, *offset) - 2); call_dissector(ipv6_handle, ipv6_tvb, pinfo, parentTree); *offset = tvb_reported_length(tvb) - 2; @@ -2650,7 +2657,7 @@ static void parse_RWH(proto_tree *ah_tree, tvbuff_t *tvb, gint *offset, packet_i /* Get the captured length and reported length of the data * after the Ethernet type. */ - captured_length = tvb_length_remaining(tvb, *offset); + captured_length = tvb_captured_length_remaining(tvb, *offset); reported_length = tvb_reported_length_remaining(tvb, *offset); /* Construct a tvbuff for the payload after the Ethernet type, @@ -2694,7 +2701,7 @@ static gboolean parse_EoIB(proto_tree *tree, tvbuff_t *tvb, gint offset, packet_ return FALSE; } - encap_tvb = tvb_new_subset(tvb, offset + 4, tvb_length_remaining(tvb, offset + 4), encap_size - 4); + encap_tvb = tvb_new_subset(tvb, offset + 4, tvb_captured_length_remaining(tvb, offset + 4), encap_size - 4); header_item = proto_tree_add_item(tree, hf_infiniband_EOIB, tvb, offset, 4, ENC_NA); header_subtree = proto_item_add_subtree(header_item, ett_eoib); diff --git a/epan/dissectors/packet-smcr.c b/epan/dissectors/packet-smcr.c new file mode 100644 index 0000000000..98debe280c --- /dev/null +++ b/epan/dissectors/packet-smcr.c @@ -0,0 +1,1439 @@ +/* packet-smcr.c + * SMC-R dissector for wireshark + * By Joe Fowler <fowlerja@us.ibm.com> + * (c) Copyright IBM Corporation 2014 + * LICENSE: GNU General Public License, version 2, or (at your option) any + * version. http://opensource.org/licenses/gpl-2.0.php + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please refer to the following specs for protocol: + * - ietf - draft-fox-tcpm-shared-memory-rdma-05 + */ + +#include "config.h" + +#include <glib.h> + +#include <epan/packet.h> +#include <epan/etypes.h> +#include <epan/conversation.h> + +#include "packet-tcp.h" + +#define SMCR_TCP_MIN_HEADER_LENGTH 7 +#define CLC_MSG_START_OFFSET 7 +#define LLC_MSG_START_OFFSET 3 +#define RMBE_CTRL_START_OFFSET 2 +#define MAC_ADDR_LEN 6 +#define GID_LEN 16 +#define PEERID_LEN 8 +#define IPV4_SUBNET_MASK_LEN 4 +#define IPV6_PREFIX_LEN 4 +#define ONE_BYTE_RESERVED 1 +#define TWO_BYTE_RESERVED 2 +#define QP_LEN 3 +#define RKEY_LEN 4 +#define VIRTUAL_ADDR_LEN 8 +#define FLAG_BYTE_LEN 1 +#define SEQNO_LEN 2 +#define CURSOR_LEN 4 +#define ALERT_TOKEN_LEN 4 +#define PSN_LEN 3 +#define CONN_INDEX_LEN 1 +#define SMCR_MSG_BYTE_0 0 +#define CLC_MSG_BYTE_0 0 +#define CLC_MSG_BYTE_1 1 +#define CLC_MSG_BYTE_2 2 +#define CLC_MSG_BYTE_3 3 +#define CLC_MSG_LEN_OFFSET 5 +#define LLC_CMD_OFFSET 0 +#define LLC_LEN_OFFSET 1 +#define LLC_CMD_RSP_OFFSET 3 +#define ACCEPT_CONFIRM_QP_OFFSET 38 +#define SMCR_CLC_ID "\xe2\xd4\xc3\xd9" /* EBCDIC 'SMCR' */ +#define SMC_CLC_V1 0x10 +#define SMC_CLC_SMC_R 0x01 + +#define LLC_FLAG_RESP 0x80 +#define RMBE_CTRL 0xfe +#define LLC_MSG_LENGTH 0x2c + +typedef enum { + SMC_CLC_PROPOSAL = 1, + SMC_CLC_ACCEPT = 2, + SMC_CLC_CONFIRMATION = 3, + SMC_CLC_DECLINE = 4 +} clc_message; + + +static const value_string smcr_clc_message_txt[] = { + { SMC_CLC_PROPOSAL, "Proposal" }, + { SMC_CLC_ACCEPT, "Accept" }, + { SMC_CLC_CONFIRMATION, "Confirm" }, + { SMC_CLC_DECLINE, "Decline" }, + { 0, NULL } +}; + +typedef enum { + LLC_CONFIRM_LINK = 0x01, + LLC_ADD_LINK = 0x02, + LLC_ADD_LINK_CONT = 0x03, + LLC_DEL_LINK = 0x04, + LLC_CONFIRM_RKEY = 0x06, + LLC_CONFIRM_RKEY_CONT = 0x08, + LLC_DELETE_RKEY = 0x09, + LLC_TEST_LINK = 0x07, + LLC_OPT_MSG_CTRL = 0x80, + LLC_NWM_DATA = 0x8A, + LLC_RMBE_CTRL = 0xFE +} llc_message; + +static const value_string smcr_llc_message_txt[] = { + { LLC_CONFIRM_LINK, "Confirm Link" }, + { LLC_ADD_LINK, "Add Link" }, + { LLC_ADD_LINK_CONT, "Add Link Continuous" }, + { LLC_DEL_LINK, "Delete Link" }, + { LLC_CONFIRM_RKEY, "Confirm Rkey" }, + { LLC_CONFIRM_RKEY_CONT, "Confirm Rkey Continuous" }, + { LLC_DELETE_RKEY, "Delete Rkey" }, + { LLC_TEST_LINK, "Test Link" }, + { LLC_OPT_MSG_CTRL, "OPT Message Control" }, + { LLC_NWM_DATA, "NWM Data" }, + { RMBE_CTRL, "CDC Message" }, + { 0, NULL } +}; + +static int proto_smcr = -1; +static int ett_smcr = -1; +static int hf_smcr_clc_msg = -1; +static int hf_smcr_llc_msg = -1; + +/* SMC-R Proposal */ +static int ett_proposal_flag = -1; +static int hf_proposal_smc_version = -1; +static int hf_smcr_proposal_flags = -1; +static int hf_smcr_proposal_client_peer_id = -1; +static int hf_smcr_proposal_client_preferred_gid = -1; +static int hf_smcr_proposal_client_preferred_mac = -1; +static int hf_smcr_proposal_outgoing_interface_subnet_mask = -1; +static int hf_smcr_proposal_outgoing_subnet_mask_signifcant_bits = -1; +static int hf_smcr_proposal_ipv6_prefix = -1; +static int hf_smcr_proposal_ipv6_prefix_length = -1; + +/* SMC-R Accept */ +static int ett_accept_flag = -1; +static int ett_accept_flag2 = -1; +static int hf_accept_smc_version = -1; +static int hf_accept_first_contact = -1; +static int hf_accept_rmb_buffer_size = -1; +static int hf_accept_qp_mtu_value = -1; +static int hf_smcr_accept_flags = -1; +static int hf_smcr_accept_flags2 = -1; +static int hf_smcr_accept_server_peer_id = -1; +static int hf_smcr_accept_server_preferred_gid = -1; +static int hf_smcr_accept_server_preferred_mac = -1; +static int hf_smcr_accept_server_qp_number = -1; +static int hf_smcr_accept_server_rmb_rkey = -1; +static int hf_smcr_accept_server_tcp_conn_index = -1; +static int hf_smcr_accept_server_rmb_element_alert_token = -1; +static int hf_smcr_accept_server_rmb_virtual_address = -1; +static int hf_smcr_accept_initial_psn = -1; + +/* SMC-R Confirm */ +static int ett_confirm_flag = -1; +static int ett_confirm_flag2 = -1; +static int hf_smcr_confirm_flags = -1; +static int hf_smcr_confirm_client_peer_id = -1; +static int hf_smcr_confirm_client_gid = -1; +static int hf_smcr_confirm_client_mac = -1; +static int hf_smcr_confirm_client_qp_number = -1; +static int hf_smcr_confirm_client_rmb_rkey = -1; +static int hf_smcr_confirm_client_tcp_conn_index = -1; +static int hf_smcr_confirm_client_rmb_element_alert_token = -1; +static int hf_smcr_confirm_flags2 = -1; +static int hf_smcr_confirm_client_rmb_virtual_address = -1; +static int hf_smcr_confirm_initial_psn = -1; +static int hf_confirm_smc_version = -1; +static int hf_confirm_rmb_buffer_size = -1; +static int hf_confirm_qp_mtu_value = -1; + +/* SMC-R Decline */ +static int hf_smcr_decline_flags = -1; +static int hf_smcr_decline_peer_id = -1; +static int hf_smcr_decline_diag_info = -1; + +/* SMC-R Confirm Link*/ +static int ett_confirm_link_flag = -1; +static int hf_smcr_confirm_link_flags = -1; +static int hf_smcr_confirm_link_mac = -1; +static int hf_smcr_confirm_link_gid = -1; +static int hf_smcr_confirm_link_qp_number = -1; +static int hf_smcr_confirm_link_number = -1; +static int hf_smcr_confirm_link_userid = -1; +static int hf_smcr_confirm_link_max_links = -1; +static int hf_smcr_confirm_link_response = -1; + +/* SMC-R Add Link */ +static int ett_add_link_flag = -1; +static int ett_add_link_flag2 = -1; +static int hf_smcr_add_link_flags = -1; +static int hf_smcr_add_link_response = -1; +static int hf_smcr_add_link_response_rejected = -1; +static int hf_smcr_add_link_mac = -1; +static int hf_smcr_add_link_gid = -1; +static int hf_smcr_add_link_qp_number = -1; +static int hf_smcr_add_link_number = -1; +static int hf_smcr_add_link_initial_psn = -1; +static int hf_smcr_add_link_flags2 = -1; +static int hf_smcr_add_link_qp_mtu_value = -1; + +/* SMC-R Add Link Continue*/ +static int ett_add_link_cont_flag = -1; +static int hf_smcr_add_link_cont_flags = -1; +static int hf_smcr_add_link_cont_response = -1; +static int hf_smcr_add_link_cont_link_number = -1; +static int hf_smcr_add_link_cont_number_of_rkeys = -1; +static int hf_smcr_add_link_cont_p1_rkey = -1; +static int hf_smcr_add_link_cont_p1_rkey2 = -1; +static int hf_smcr_add_link_cont_p1_virt_addr = -1; +static int hf_smcr_add_link_cont_p2_rkey = -1; +static int hf_smcr_add_link_cont_p2_rkey2 = -1; +static int hf_smcr_add_link_cont_p2_virt_addr = -1; + +/* SMC-R Delete Link */ +static int ett_delete_link_flag = -1; +static int hf_smcr_delete_link_flags = -1; +static int hf_smcr_delete_link_response = -1; +static int hf_smcr_delete_link_all = -1; +static int hf_smcr_delete_link_orderly = -1; +static int hf_smcr_delete_link_number = -1; +static int hf_smcr_delete_link_reason_code = -1; + +/* SMC-R Confirm Rkey */ +static int ett_confirm_rkey_flag = -1; +static int hf_smcr_confirm_rkey_response = -1; +static int hf_smcr_confirm_rkey_flags = -1; +static int hf_smcr_confirm_rkey_negative_response = -1; +static int hf_smcr_confirm_rkey_retry_rkey_set = -1; +static int hf_smcr_confirm_rkey_number = -1; +static int hf_smcr_confirm_rkey_new_rkey = -1; +static int hf_smcr_confirm_rkey_virtual_address = -1; +static int hf_smcr_confirm_rkey_link_number = -1; + +/* SMC-R Delete Rkey */ +static int ett_delete_rkey_flag = -1; +static int hf_smcr_delete_rkey_flags = -1; +static int hf_smcr_delete_rkey_response = -1; +static int hf_smcr_delete_rkey_negative_response = -1; +static int hf_smcr_delete_rkey_mask = -1; +static int hf_smcr_delete_rkey_deleted = -1; + +/* SMC-R Test Link */ +static int ett_test_link_flag = -1; +static int hf_smcr_test_link_flags = -1; +static int hf_smcr_test_link_response = -1; + +/* SMC-R RMBE Control */ +static int ett_rmbe_ctrl_rw_status_flag = -1; +static int ett_rmbe_ctrl_peer_conn_state_flag = -1; +static int hf_smcr_rmbe_ctrl_seqno = -1; +static int hf_smcr_rmbe_ctrl_alert_token = -1; +static int hf_smcr_rmbe_ctrl_prod_wrap_seqno = -1; +static int hf_smcr_rmbe_ctrl_peer_prod_curs = -1; +static int hf_smcr_rmbe_ctrl_cons_wrap_seqno = -1; +static int hf_smcr_rmbe_ctrl_peer_cons_curs = -1; +static int hf_smcr_rmbe_ctrl_conn_rw_status_flags = -1; +static int hf_smcr_rmbe_ctrl_write_blocked = -1; +static int hf_smcr_rmbe_ctrl_urgent_pending = -1; +static int hf_smcr_rmbe_ctrl_urgent_present = -1; +static int hf_smcr_rmbe_ctrl_cons_update_requested = -1; +static int hf_smcr_rmbe_ctrl_peer_conn_state_flags = -1; +static int hf_smcr_rmbe_ctrl_peer_sending_done = -1; +static int hf_smcr_rmbe_ctrl_peer_closed_conn = -1; +static int hf_smcr_rmbe_ctrl_peer_abnormal_close = -1; + +void proto_register_smcr(void); +void proto_reg_handoff_smcr(void); +static dissector_handle_t smcr_tcp_handle; + +static void +disect_smcr_proposal(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + guint16 mask_offset; + guint8 ipv6_prefix_count; + proto_item *proposal_flag_item; + proto_tree *proposal_flag_tree; + + offset = CLC_MSG_START_OFFSET; + proposal_flag_item = proto_tree_add_item(tree, hf_smcr_proposal_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + proposal_flag_tree = proto_item_add_subtree(proposal_flag_item, ett_proposal_flag); + proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_proposal_client_peer_id, tvb, offset, + PEERID_LEN, ENC_BIG_ENDIAN); + offset += PEERID_LEN; + proto_tree_add_item(tree, hf_smcr_proposal_client_preferred_gid, tvb, + offset, GID_LEN, ENC_NA); + offset += GID_LEN; + proto_tree_add_item(tree, hf_smcr_proposal_client_preferred_mac, tvb, + offset, MAC_ADDR_LEN, ENC_NA); + offset += MAC_ADDR_LEN; + mask_offset = tvb_get_ntohs(tvb, offset); + offset += 2 + mask_offset; + proto_tree_add_item(tree, hf_smcr_proposal_outgoing_interface_subnet_mask, tvb, + offset, IPV4_SUBNET_MASK_LEN, ENC_BIG_ENDIAN); + offset += IPV4_SUBNET_MASK_LEN; + proto_tree_add_item(tree, hf_smcr_proposal_outgoing_subnet_mask_signifcant_bits, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + /* Bump past reserved bytes */ + offset += TWO_BYTE_RESERVED; + ipv6_prefix_count = tvb_get_guint8(tvb, offset); + offset += 2; + + while (ipv6_prefix_count != 0) { + proto_tree_add_item(tree, hf_smcr_proposal_ipv6_prefix, tvb, + offset, IPV6_PREFIX_LEN, ENC_NA); + offset += IPV6_PREFIX_LEN; + proto_tree_add_item(tree, hf_smcr_proposal_ipv6_prefix_length, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + ipv6_prefix_count--; + } +} + +static void +disect_smcr_accept(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + proto_item *accept_flag_item; + proto_tree *accept_flag_tree; + proto_item *accept_flag2_item; + proto_tree *accept_flag2_tree; + + offset = CLC_MSG_START_OFFSET; + accept_flag_item = proto_tree_add_item(tree, hf_smcr_accept_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_accept_flag); + proto_tree_add_item(accept_flag_tree, hf_accept_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(accept_flag_tree, hf_accept_first_contact, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_accept_server_peer_id, tvb, offset, + PEERID_LEN, ENC_BIG_ENDIAN); + offset += PEERID_LEN; + proto_tree_add_item(tree, hf_smcr_accept_server_preferred_gid, tvb, + offset, GID_LEN, ENC_NA); + offset += GID_LEN; + proto_tree_add_item(tree, hf_smcr_accept_server_preferred_mac, tvb, + offset, MAC_ADDR_LEN, ENC_NA); + offset += MAC_ADDR_LEN; + proto_tree_add_item(tree, hf_smcr_accept_server_qp_number, tvb, + offset, QP_LEN, ENC_BIG_ENDIAN); + offset += QP_LEN; + proto_tree_add_item(tree, hf_smcr_accept_server_rmb_rkey, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_accept_server_tcp_conn_index, tvb, + offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN); + offset += CONN_INDEX_LEN; + proto_tree_add_item(tree, hf_smcr_accept_server_rmb_element_alert_token, tvb, + offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN); + offset += ALERT_TOKEN_LEN; + accept_flag2_item = proto_tree_add_item(tree, hf_smcr_accept_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + accept_flag2_tree = proto_item_add_subtree(accept_flag2_item, ett_accept_flag2); + proto_tree_add_item(accept_flag2_tree, hf_accept_rmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(accept_flag2_tree, hf_accept_qp_mtu_value, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + /* Bump past reserved byte */ + offset += ONE_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_accept_server_rmb_virtual_address, tvb, + offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN); + offset += VIRTUAL_ADDR_LEN; + /* Bump past reserved byte */ + offset += ONE_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_accept_initial_psn, tvb, + offset, PSN_LEN, ENC_BIG_ENDIAN); +} + +static void +disect_smcr_confirm(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + proto_item *confirm_flag_item; + proto_tree *confirm_flag_tree; + proto_item *confirm_flag2_item; + proto_tree *confirm_flag2_tree; + + offset = CLC_MSG_START_OFFSET; + confirm_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_confirm_flag); + proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_client_peer_id, tvb, offset, + PEERID_LEN, ENC_BIG_ENDIAN); + offset += PEERID_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_client_gid, tvb, + offset, GID_LEN, ENC_NA); + offset += GID_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_client_mac, tvb, + offset, MAC_ADDR_LEN, ENC_NA); + offset += MAC_ADDR_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_client_qp_number, tvb, + offset, QP_LEN, ENC_BIG_ENDIAN); + offset += QP_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_client_rmb_rkey, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_client_tcp_conn_index, tvb, + offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN); + offset += CONN_INDEX_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_client_rmb_element_alert_token, tvb, + offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN); + offset += ALERT_TOKEN_LEN; + confirm_flag2_item = proto_tree_add_item(tree, hf_smcr_confirm_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + confirm_flag2_tree = proto_item_add_subtree(confirm_flag2_item, ett_confirm_flag2); + proto_tree_add_item(confirm_flag2_tree, hf_confirm_rmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(confirm_flag2_tree, hf_confirm_qp_mtu_value, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + /* Bump past reserved byte */ + offset += ONE_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_confirm_client_rmb_virtual_address, tvb, + offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN); + offset += VIRTUAL_ADDR_LEN; + /* Bump past reserved byte */ + offset += ONE_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_confirm_initial_psn, tvb, + offset, PSN_LEN, ENC_BIG_ENDIAN); +} + +static void +disect_smcr_decline(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + + offset = CLC_MSG_START_OFFSET; + proto_tree_add_item(tree, hf_smcr_decline_flags, tvb, offset, + FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_decline_peer_id, tvb, offset, + PEERID_LEN, ENC_BIG_ENDIAN); + offset += PEERID_LEN; + proto_tree_add_item(tree, hf_smcr_decline_diag_info, tvb, offset, + 4, ENC_BIG_ENDIAN); +} + +static void +disect_smcr_confirm_link(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + proto_item *confirm_flag_item; + proto_tree *confirm_flag_tree; + + offset = LLC_MSG_START_OFFSET; + confirm_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_confirm_link_flag); + proto_tree_add_item(confirm_flag_tree, hf_smcr_confirm_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_link_mac, tvb, + offset, MAC_ADDR_LEN, ENC_NA); + offset += MAC_ADDR_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_link_gid, tvb, + offset, GID_LEN, ENC_NA); + offset += GID_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_link_qp_number, tvb, + offset, QP_LEN, ENC_BIG_ENDIAN); + offset += QP_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_link_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_smcr_confirm_link_userid, tvb, + offset, 4, ENC_BIG_ENDIAN); + offset += 4; + proto_tree_add_item(tree, hf_smcr_confirm_link_max_links, tvb, + offset, 1, ENC_BIG_ENDIAN); +} + +static void +disect_smcr_add_link(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + proto_item *add_link_flag_item; + proto_tree *add_link_flag_tree; + proto_item *add_link_flag2_item; + proto_tree *add_link_flag2_tree; + + offset = LLC_MSG_START_OFFSET; + add_link_flag_item = proto_tree_add_item(tree, hf_smcr_add_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + add_link_flag_tree = proto_item_add_subtree(add_link_flag_item, ett_add_link_flag); + proto_tree_add_item(add_link_flag_tree, hf_smcr_add_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(add_link_flag_tree, hf_smcr_add_link_response_rejected, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_mac, tvb, + offset, MAC_ADDR_LEN, ENC_NA); + offset += MAC_ADDR_LEN; + /* Bump past reserved bytes */ + offset += TWO_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_add_link_gid, tvb, + offset, GID_LEN, ENC_NA); + offset += GID_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_qp_number, tvb, + offset, QP_LEN, ENC_BIG_ENDIAN); + offset += QP_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + add_link_flag2_item = proto_tree_add_item(tree, hf_smcr_add_link_flags2, tvb, offset, 1, ENC_NA); + add_link_flag2_tree = proto_item_add_subtree(add_link_flag2_item, ett_add_link_flag2); + proto_tree_add_item(add_link_flag2_tree, hf_smcr_add_link_qp_mtu_value, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_smcr_add_link_initial_psn, tvb, + offset, PSN_LEN, ENC_BIG_ENDIAN); +} + +static void +disect_smcr_add_continuation(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + guint8 num_of_keys; + proto_item *add_link_flag_item; + proto_tree *add_link_flag_tree; + + offset = LLC_MSG_START_OFFSET; + add_link_flag_item = proto_tree_add_item(tree, hf_smcr_add_link_cont_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + add_link_flag_tree = proto_item_add_subtree(add_link_flag_item, ett_add_link_cont_flag); + proto_tree_add_item(add_link_flag_tree, hf_smcr_add_link_cont_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_cont_link_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_smcr_add_link_cont_number_of_rkeys, tvb, + offset, 1, ENC_BIG_ENDIAN); + num_of_keys = tvb_get_guint8(tvb,offset); + offset += 1; + + if (num_of_keys >= 1) { + proto_tree_add_item(tree, hf_smcr_add_link_cont_p1_rkey, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_cont_p1_rkey2, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_cont_p1_virt_addr, tvb, + offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN); + + if (num_of_keys >= 2) { + offset += VIRTUAL_ADDR_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_cont_p2_rkey, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_cont_p2_rkey2, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_add_link_cont_p2_virt_addr, tvb, + offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN); + } + } +} + +static void +disect_smcr_delete_link(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + proto_item *delete_link_flag_item; + proto_tree *delete_link_flag_tree; + + offset = LLC_MSG_START_OFFSET; + delete_link_flag_item = proto_tree_add_item(tree, hf_smcr_delete_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + delete_link_flag_tree = proto_item_add_subtree(delete_link_flag_item, ett_delete_link_flag); + proto_tree_add_item(delete_link_flag_tree, hf_smcr_delete_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(delete_link_flag_tree, hf_smcr_delete_link_all, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(delete_link_flag_tree, hf_smcr_delete_link_orderly, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_delete_link_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_smcr_delete_link_reason_code, tvb, + offset, 4, ENC_BIG_ENDIAN); +} + +static void +disect_smcr_confirm_rkey(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + guint8 num_entries; + proto_item *confirm_rkey_flag_item; + proto_tree *confirm_rkey_flag_tree; + + offset = LLC_MSG_START_OFFSET; + confirm_rkey_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_rkey_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + confirm_rkey_flag_tree = proto_item_add_subtree(confirm_rkey_flag_item, ett_confirm_rkey_flag); + proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_negative_response, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_retry_rkey_set, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + num_entries = tvb_get_guint8(tvb,offset); + + if (num_entries > 2) + num_entries = 2; + + offset += 1; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_new_rkey, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_virtual_address, tvb, + offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN); + + for (; num_entries > 0; num_entries--) { + offset += VIRTUAL_ADDR_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_link_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_new_rkey, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_virtual_address, tvb, + offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN); + } +} + +static void +disect_smcr_confirm_rkey_cont(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + proto_item *confirm_rkey_flag_item; + proto_tree *confirm_rkey_flag_tree; + guint8 num_entries; + + offset = LLC_MSG_START_OFFSET; + confirm_rkey_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_rkey_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + confirm_rkey_flag_tree = proto_item_add_subtree(confirm_rkey_flag_item, ett_confirm_rkey_flag); + proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_negative_response, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(confirm_rkey_flag_tree, hf_smcr_confirm_rkey_retry_rkey_set, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + num_entries = tvb_get_guint8(tvb,offset); + if (num_entries > 3) + num_entries = 3; + + offset += 1; + for (; num_entries > 0; num_entries--) { + proto_tree_add_item(tree, hf_smcr_confirm_rkey_link_number, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_new_rkey, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + proto_tree_add_item(tree, hf_smcr_confirm_rkey_virtual_address, tvb, + offset, VIRTUAL_ADDR_LEN, ENC_BIG_ENDIAN); + offset += VIRTUAL_ADDR_LEN; + } +} + +static void +disect_smcr_delete_rkey(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + guint8 count; + proto_item *delete_rkey_flag_item; + proto_tree *delete_rkey_flag_tree; + + offset = LLC_MSG_START_OFFSET; + delete_rkey_flag_item = proto_tree_add_item(tree, hf_smcr_delete_rkey_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + delete_rkey_flag_tree = proto_item_add_subtree(delete_rkey_flag_item, ett_delete_rkey_flag); + proto_tree_add_item(delete_rkey_flag_tree, hf_smcr_delete_rkey_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(delete_rkey_flag_tree, hf_smcr_delete_rkey_negative_response, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + proto_tree_add_item(tree, hf_smcr_delete_rkey_mask, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + for (count=0; count < 8; count++) { + proto_tree_add_item(tree, hf_smcr_delete_rkey_deleted, tvb, + offset, RKEY_LEN, ENC_BIG_ENDIAN); + offset += RKEY_LEN; + } +} + +static void +disect_smcr_test_link(tvbuff_t *tvb, proto_tree *tree) +{ + guint offset; + proto_item *test_link_flag_item; + proto_tree *test_link_flag_tree; + + offset = LLC_MSG_START_OFFSET; + test_link_flag_item = proto_tree_add_item(tree, hf_smcr_test_link_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + test_link_flag_tree = proto_item_add_subtree(test_link_flag_item, ett_test_link_flag); + proto_tree_add_item(test_link_flag_tree, hf_smcr_test_link_response, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); +} + +static void +disect_smcr_rmbe_ctrl(tvbuff_t *tvb, proto_tree *tree) +{ + gint offset; + proto_item *rmbe_ctrl_rw_status_flag_item; + proto_tree *rmbe_ctrl_rw_status_flag_tree; + proto_item *rmbe_ctrl_peer_conn_state_flag_item; + proto_tree *rmbe_ctrl_peer_conn_state_flag_tree; + + offset = RMBE_CTRL_START_OFFSET; + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_seqno, tvb, offset, SEQNO_LEN, ENC_BIG_ENDIAN); + offset += SEQNO_LEN; + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_alert_token, tvb, offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN); + offset += ALERT_TOKEN_LEN; + offset += TWO_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_prod_wrap_seqno, tvb, offset, SEQNO_LEN, ENC_BIG_ENDIAN); + offset += SEQNO_LEN; + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_peer_prod_curs, tvb, offset, CURSOR_LEN, ENC_BIG_ENDIAN); + offset += CURSOR_LEN; + /* Bump past reserved bytes */ + offset += TWO_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_cons_wrap_seqno, tvb, offset, SEQNO_LEN, ENC_BIG_ENDIAN); + offset += SEQNO_LEN; + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_peer_cons_curs, tvb, offset, CURSOR_LEN, ENC_BIG_ENDIAN); + offset += CURSOR_LEN; + rmbe_ctrl_rw_status_flag_item = + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_conn_rw_status_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + rmbe_ctrl_rw_status_flag_tree = + proto_item_add_subtree(rmbe_ctrl_rw_status_flag_item, ett_rmbe_ctrl_rw_status_flag); + proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_write_blocked, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_urgent_pending, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_urgent_present, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(rmbe_ctrl_rw_status_flag_tree, hf_smcr_rmbe_ctrl_cons_update_requested, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; + rmbe_ctrl_peer_conn_state_flag_item = + proto_tree_add_item(tree, hf_smcr_rmbe_ctrl_peer_conn_state_flags, tvb, offset, FLAG_BYTE_LEN, ENC_NA); + rmbe_ctrl_peer_conn_state_flag_tree = + proto_item_add_subtree(rmbe_ctrl_peer_conn_state_flag_item, ett_rmbe_ctrl_peer_conn_state_flag); + proto_tree_add_item(rmbe_ctrl_peer_conn_state_flag_tree, hf_smcr_rmbe_ctrl_peer_sending_done, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(rmbe_ctrl_peer_conn_state_flag_tree, hf_smcr_rmbe_ctrl_peer_closed_conn, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(rmbe_ctrl_peer_conn_state_flag_tree, hf_smcr_rmbe_ctrl_peer_abnormal_close, + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); +} + +static int +dissect_smcr_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data _U_) +{ + gint offset; + guint16 msg_len; + clc_message clc_msgid; + proto_item *ti; + proto_tree *smcr_tree; + + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMC-R"); + msg_len = tvb_get_ntohs(tvb, CLC_MSG_LEN_OFFSET); + offset = 4; + clc_msgid = (clc_message) tvb_get_guint8(tvb, offset); + col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-R-%s],", + val_to_str_const((guint32)clc_msgid, + smcr_clc_message_txt, "Unknown Command")); + + if ((clc_msgid == SMC_CLC_ACCEPT) || + (clc_msgid == SMC_CLC_CONFIRMATION)) { + col_append_fstr(pinfo->cinfo, COL_INFO, " QP=0x%06x", + tvb_get_ntoh24(tvb, ACCEPT_CONFIRM_QP_OFFSET)); + } + + if (!tree) + return tvb_reported_length(tvb); + + ti = proto_tree_add_item(tree, proto_smcr, tvb, 0, msg_len, ENC_NA); + smcr_tree = proto_item_add_subtree(ti, ett_smcr); + proto_tree_add_item(smcr_tree, hf_smcr_clc_msg, tvb, offset, 1, + ENC_BIG_ENDIAN); + + switch (clc_msgid) { + case SMC_CLC_PROPOSAL: + disect_smcr_proposal(tvb, smcr_tree); + break; + case SMC_CLC_ACCEPT: + disect_smcr_accept(tvb, smcr_tree); + break; + case SMC_CLC_CONFIRMATION: + disect_smcr_confirm(tvb, smcr_tree); + break; + case SMC_CLC_DECLINE: + disect_smcr_decline(tvb, smcr_tree); + break; + default: + /* Unknown Command */ + break; + } + return tvb_reported_length(tvb); +} + +static void +dissect_smcr_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + guint16 msg_len; + llc_message llc_msgid; + proto_item *ti; + proto_tree *smcr_tree; + + msg_len = tvb_get_guint8(tvb, LLC_LEN_OFFSET); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMC-R"); + llc_msgid = (llc_message) tvb_get_guint8(tvb, LLC_CMD_OFFSET); + col_append_str(pinfo->cinfo, COL_INFO, "[SMC-R] "); + col_append_str(pinfo->cinfo, COL_INFO, + val_to_str_const((guint32)llc_msgid, + smcr_llc_message_txt, "Unknown Command")); + + if ((llc_msgid != RMBE_CTRL) && + (tvb_get_guint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP)) + col_append_str(pinfo->cinfo, COL_INFO, "(Resp)"); + + if (!tree) + return; + + ti = proto_tree_add_item(tree, proto_smcr, tvb, 0, msg_len, ENC_NA); + smcr_tree = proto_item_add_subtree(ti, ett_smcr); + proto_tree_add_item(smcr_tree, hf_smcr_llc_msg, tvb, 0, 1, + ENC_BIG_ENDIAN); + + switch (llc_msgid) { + case LLC_CONFIRM_LINK: + disect_smcr_confirm_link(tvb, smcr_tree); + break; + + case LLC_ADD_LINK: + disect_smcr_add_link(tvb, smcr_tree); + break; + + case LLC_ADD_LINK_CONT: + disect_smcr_add_continuation(tvb, smcr_tree); + break; + + case LLC_DEL_LINK: + disect_smcr_delete_link(tvb, smcr_tree); + break; + + case LLC_CONFIRM_RKEY: + disect_smcr_confirm_rkey(tvb, smcr_tree); + break; + + case LLC_CONFIRM_RKEY_CONT: + disect_smcr_confirm_rkey_cont(tvb, smcr_tree); + break; + + case LLC_DELETE_RKEY: + disect_smcr_delete_rkey(tvb, smcr_tree); + break; + + case LLC_TEST_LINK: + disect_smcr_test_link(tvb, smcr_tree); + break; + + case RMBE_CTRL: + disect_smcr_rmbe_ctrl(tvb, smcr_tree); + break; + + default: + /* Unknown Command */ + break; + } + return; +} + +static guint +get_smcr_pdu_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) +{ + guint32 length; + length = tvb_get_ntohs(tvb, offset+CLC_MSG_LEN_OFFSET); + return length; +} + +static int +dissect_smcr_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data) +{ + tcp_dissect_pdus(tvb, pinfo, tree, TRUE, SMCR_TCP_MIN_HEADER_LENGTH, + get_smcr_pdu_length, dissect_smcr_tcp_pdu, data); + return tvb_reported_length(tvb); +} + +static gboolean +dissect_smcr_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data) +{ + if (tvb_memeql(tvb, CLC_MSG_BYTE_0, SMCR_CLC_ID, sizeof(SMCR_CLC_ID) != 0)) return FALSE; + dissect_smcr_tcp(tvb, pinfo, tree, data); + return TRUE; +} + +static gboolean +dissect_smcr_infiniband_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data _U_) +{ + guint16 msg_len; + llc_message msg_byte0; + guint8 msg_byte1; + + if (tvb_captured_length_remaining(tvb, SMCR_MSG_BYTE_0) < 2) /* need at least 2 bytes */ + return FALSE; + + /* Grab the first two bytes of the message, as they are needed */ + /* for validity checking of both CLC and LLC messages */ + msg_byte0 = (llc_message) tvb_get_guint8(tvb,CLC_MSG_BYTE_0); + msg_byte1 = tvb_get_guint8(tvb,CLC_MSG_BYTE_1); + + + /* Check for possible LLC Messages */ + + if (!((msg_byte1 == LLC_MSG_LENGTH) && + (((msg_byte0 >= LLC_CONFIRM_LINK) && + (msg_byte0 <= LLC_DELETE_RKEY)) || + (msg_byte0 == LLC_RMBE_CTRL)))) + return FALSE; + + msg_len = tvb_get_guint8(tvb, LLC_LEN_OFFSET); + if (msg_len != tvb_reported_length_remaining(tvb, LLC_CMD_OFFSET)) + return FALSE; + + dissect_smcr_infiniband(tvb, pinfo, tree); + return TRUE; +} + +void +proto_register_smcr(void) +{ + /* Setup list of header fields */ + static hf_register_info hf[] = { + { &hf_smcr_clc_msg, { + "CLC Message", "smcr.clc_msg", + FT_UINT8, BASE_DEC, VALS(smcr_clc_message_txt), 0x0, + NULL, HFILL}}, + + { &hf_smcr_llc_msg, { + "LLC Message", "smcr.llc_msg", + FT_UINT8, BASE_DEC, VALS(smcr_llc_message_txt), 0x0, + NULL, HFILL}}, + + { &hf_proposal_smc_version, { + "SMC Version", "smcr.proposal.smc.version", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, + + { &hf_accept_smc_version, { + "SMC Version", "smcr.proposal.smc.version", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, + + { &hf_accept_first_contact, { + "First Contact", "smcr.proposal.first.contact", + FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}}, + + { &hf_confirm_smc_version, { + "SMC Version", "smcr.proposal.smc.version", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, + + { &hf_accept_rmb_buffer_size, { + "Server RMB Buffers Size (Compressed Notation)", + "smcr.accept.rmb.buffer.size", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, + + { &hf_accept_qp_mtu_value, { + "QP MTU Value (enumerated value)", + "smcr.accept.qp.mtu.value", + FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}}, + + { &hf_confirm_rmb_buffer_size, { + "Client RMB Buffers Size (Compressed Notation)", + "smcr.confirm.rmb.buffer.size", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, + + { &hf_confirm_qp_mtu_value, { + "QP MTU Value (enumerated value)", + "smcr.confirm.qp.mtu.value", + FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}}, + + { &hf_smcr_proposal_flags, { + "Flags", "smcr.proposal.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_flags, { + "Flags", "smcr.accept.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_flags2, { + "Flags 2", "smcr.accept.flags.2", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_flags, { + "Flags", "smcr.confirm.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_decline_flags, { + "Flags", "smcr.decline.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_flags2, { + "Flags 2", "smcr.confirm.flags.2", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_proposal_client_peer_id, { + "Sender (Client) Peer ID", "smcr.proposal.sender.client.peer.id", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_proposal_client_preferred_gid, { + "Client Preferred GID", "smcr.proposal.client.preferred.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_proposal_client_preferred_mac, { + "Client Preferred MAC Address", + "smcr.proposal.client.preferred.mac", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_peer_id, { + "Sender (Server) Peer ID", "smcr.accept.sender.server.peer.id", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_preferred_gid, { + "Server Preferred GID", "smcr.accept.server.preferred.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_preferred_mac, { + "Server Preferred MAC Address", + "smcr.accept.server.preferred.mac", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_proposal_outgoing_interface_subnet_mask, { + "Outgoing Interface Subnet Mask", + "smcr.outgoing.interface.subnet.mask", + FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_proposal_outgoing_subnet_mask_signifcant_bits, { + "Outgoing Interface Subnet Mask Number of Significant Bits", + "smcr.outgoing.interface.subnet.mask.number.of.significant.bits", + FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_proposal_ipv6_prefix, { + "IPv6 Prefix Value","smcr.proposal.ipv6.prefix.value", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_proposal_ipv6_prefix_length, { + "IPv6 Prefix Length", "smcr.proposal.ipv6.prefix.length", + FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_qp_number, { + "Server QP Number","smcr.accept.server.qp.number", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_rmb_rkey, { + "Server RMB Rkey","smcr.accept.server.rmb.rkey", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_tcp_conn_index, { + "Server TCP Connection Index", + "smcr.accept.server.tcp.conn.index", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_rmb_element_alert_token, { + "Server RMB Element Alert Token", + "smcr.accept.server.rmb.element.alert.token", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_rmb_virtual_address, { + "Server's RMB Vitual Address", + "smcr.accept.server.rmb.virtual.address", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_initial_psn, { + "Initial PSN","smcr.accept.initial.psn", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_peer_id, { + "Sender (Client) Peer ID", + "smcr.confirm.sender.client.peer.id", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_gid, { + "Client GID", "smcr.client.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_mac, { + "Client MAC Address", "smcr.confirm.client.mac", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_qp_number, { + "Client QP Number","smcr.confirm.client.qp.number", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_rmb_rkey, { + "Client RMB Rkey","smcr.confirm.client.rmb.rkey", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_tcp_conn_index, { + "Client TCP Connection Index", + "smcr.confirm.client.tcp.conn.index", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_rmb_element_alert_token, { + "Client RMB Element Alert Token", + "smcr.client.rmb.element.alert.token", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_rmb_virtual_address, { + "Client's RMB Vitual Address", + "smcr.client.rmb.virtual.address", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_initial_psn, { + "Initial PSN","smcr.initial.psn", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_decline_peer_id, { + "Sender Peer ID", "smcr.sender.peer.id", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_decline_diag_info, { + "Peer Diagnosis Information", "smcr.peer.diag.info", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_gid, { + "Sender GID", "smcr.sender.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_mac, { + "Sender MAC Address", "smcr.confirm.link.sender.mac", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_qp_number, { + "Sender QP Number","smcr.confirm.link.sender.qp.number", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_number, { + "Link Number", "smcr.confirm.link.number", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_userid, { + "Sender Link User ID", + "smcr.confirm.link.sender.link.userid", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_max_links, { + "Max Links","smcr.confirm.link.max.links", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_flags, { + "Flags", "smcr.confirm.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_response, { + "Response", "smcr.confirm.link.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_add_link_gid, { + "Sender GID", "smcr.add.link.sender.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_mac, { + "Sender MAC Address", "smcr.add.link.sender.mac", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_qp_number, { + "Sender QP Number","smcr.add.link.sender.qp.number", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_number, { + "Link Number", "smcr.add.link.link.number", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_initial_psn, { + "Initial PSN", "smcr.add.link.initial.psn", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_flags, { + "Flags", "smcr.add.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_response, { + "Add Link Response", "smcr.add.link.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_add_link_response_rejected, { + "Add Link Rejected", "smcr.add.link.response.rejected", + FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}}, + + { &hf_smcr_add_link_flags2, { + "Flags", "smcr.add.link.flags2", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + + { &hf_smcr_add_link_qp_mtu_value, { + "QP MTU Value", "smcr.add.link.qp.mtu.value", + FT_UINT8, BASE_HEX, NULL, 0x0F, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_flags, { + "Flags", "smcr.add.link.cont.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_response, { + "Response", "smcr.add.link.cont.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_link_number, { + "Link Number", "smcr.add.link.cont.link.number", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_number_of_rkeys, { + "Number of Rkeys", "smcr.add.link.cont.rkey.number", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_p1_rkey, { + "RMB RToken Pair 1 - Rkey as known on this SMC Link", + "smcr.add.link.cont.rmb.RTok1.Rkey1", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_p1_rkey2, { + "RMB RToken Pair 1 - Equivalent Rkey for the new SMC Link", + "smcr.add.link.cont.rmb.RTok1.Rkey2", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_p1_virt_addr, { + "RMB RToken Pair 1 Virtual Address for the new SMC Link", + "smcr.add.link.cont.rmb.RTok1.virt", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_p2_rkey, { + "RMB RToken Pair 2 - Rkey as known on this SMC Link", + "smcr.add.link.cont.rmb.RTok2.Rkey1", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_p2_rkey2, { + "RMB RToken Pair 2 - Equivalent Rkey for the new SMC Link", + "smcr.add.link.cont.rmb.RTok2.Rkey2", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_p2_virt_addr, { + "RMB RToken Pair 2 Virtual Address for the new SMC Link", + "smcr.add.link.cont.rmb.RTok1.virt", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_delete_link_flags, { + "Flags", "smcr.delete.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_delete_link_response, { + "Response", "smcr.delete.link.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_delete_link_all, { + "Terminate All Links In The Link Group", + "smcr.delete.link.all", + FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}}, + + { &hf_smcr_delete_link_orderly, { + "Terminate Links Orderly", "smcr.delete.link.orderly", + FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}}, + + { &hf_smcr_delete_link_number, { + "Link Number For The Failed Link", "smcr.delete.link.number", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_delete_link_reason_code, { + "Reason Code", "smcr.delete.link.reason.code", + FT_UINT32, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_flags, { + "Flags", "smcr.confirm.rkey.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_response, { + "Response", "smcr.confirm.rkey.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_negative_response, { + "Negative Response", "smcr.confirm.rkey.negative.response", + FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_retry_rkey_set, { + "Retry Rkey Set", "smcr.confirm.rkey.retry.rkey.set", + FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_number, { + "Number of other QP", "smcr.confirm.rkey.number.qp", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_new_rkey, { + "New Rkey for this link","smcr.confirm.rkey.new.rkey", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_virtual_address, { + "New RMB virtual address for this link", + "smcr.confirm.rkey.new.virt", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_link_number, { + "Link Number", "smcr.confirm.rkey.link.number", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_flags, { + "Flags", "smcr.delete.rkey.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_response, { + "Response", "smcr.delete.rkey.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_negative_response, { + "Negative Response", "smcr.delete.rkey.negative.response", + FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_mask, { + "Error Mask", "smcr.delete.rkey.error.mask", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_deleted, { + "RMB Rkey to be deleted", "smcr.delete.rkey.deleted", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_test_link_flags, { + "Flags", "smcr.test.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_test_link_response, { + "Response", "smcr.test.link.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_seqno, { + "Sequence Number", "smcr.rmbe.ctrl.seqno", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_alert_token, { + "Alert Token", "smcr.rmbe.ctrl.alert.token", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_prod_wrap_seqno, { + "Producer window wrap sequence number", + "smcr.rmbe.ctrl.prod.wrap.seq", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_peer_prod_curs, { + "Peer Producer Cursor", "smcr.rmbe.ctrl.peer.prod.curs", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }}, + + { &hf_smcr_rmbe_ctrl_cons_wrap_seqno, { + "Consumer window wrap sequence number", + "smcr.rmbe.ctrl.prod.wrap.seq", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_peer_cons_curs, { + "Peer Consumer Cursor", "smcr.rmbe.ctrl.peer.prod.curs", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_conn_rw_status_flags, { + "Connection read/write status flags", + "smcr.rmbe.ctrl.conn.rw.status.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_write_blocked, { + "Write Blocked", "smcr.rmbe.ctrl.write.blocked", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_urgent_pending, { + "Urgent Data Pending", "smcr.rmbe.ctrl.urgent.pending", + FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_urgent_present, { + "Urgent Data Present", "smcr.rmbe.ctrl.urgent.present", + FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_cons_update_requested, { + "Consumer Cursor Update Requested", + "smcr.rmbe.ctrl.cons.update.requested", + FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_peer_conn_state_flags, { + "Peer Connection State Flags", + "smcr.rmbe.ctrl.peer.conn.state.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_peer_sending_done, { + "Peer Sending Done", "smcr.rmbe.ctrl.peer.sending.done", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_peer_closed_conn, { + "Peer Closed Connection", "smcr.rmbe.ctrl.peer.closed.conn", + FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_peer_abnormal_close, { + "Peer Abnormal Close", "smcr.rmbe.ctrl.peer.abnormal.close", + FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}} + }; + + /* Setup protocol subtree arrays */ + static gint *ett[] = { + &ett_smcr, + &ett_proposal_flag, + &ett_accept_flag, + &ett_accept_flag2, + &ett_confirm_flag, + &ett_confirm_flag2, + &ett_confirm_link_flag, + &ett_add_link_flag, + &ett_add_link_flag2, + &ett_add_link_cont_flag, + &ett_delete_link_flag, + &ett_confirm_rkey_flag, + &ett_delete_rkey_flag, + &ett_test_link_flag, + &ett_rmbe_ctrl_rw_status_flag, + &ett_rmbe_ctrl_peer_conn_state_flag + }; + + proto_register_field_array(proto_smcr, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + proto_smcr = proto_register_protocol("Shared Memory Communications - RDMA", + "SMCR", "smcr"); + smcr_tcp_handle = new_register_dissector("smcr", dissect_smcr_tcp, proto_smcr); +} + +void +proto_reg_handoff_smcr(void) +{ + heur_dissector_add("tcp", dissect_smcr_tcp_heur, proto_smcr); + heur_dissector_add("infiniband.payload", dissect_smcr_infiniband_heur, proto_smcr); +} + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + * + * vi: set shiftwidth=8 tabstop=8 noexpandtab: + * :indentSize=8:tabSize=8:noTabs=false: + */ |