diff --git a/SOURCES/wireshark-0026-mptcp.patch b/SOURCES/wireshark-0026-mptcp.patch new file mode 100644 index 0000000..ebb0cbb --- /dev/null +++ b/SOURCES/wireshark-0026-mptcp.patch @@ -0,0 +1,875 @@ +diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c +index 36e8afb2a3..73f4a2647a 100644 +--- a/epan/dissectors/packet-tcp.c ++++ b/epan/dissectors/packet-tcp.c +@@ -285,7 +285,9 @@ static int hf_mptcp_analysis_subflows_stream_id = -1; + static int hf_mptcp_analysis_subflows = -1; + static int hf_mptcp_number_of_removed_addresses = -1; + static int hf_mptcp_related_mapping = -1; +-static int hf_mptcp_duplicated_data = -1; ++static int hf_mptcp_reinjection_of = -1; ++static int hf_mptcp_reinjected_in = -1; ++ + + static int hf_tcp_option_fast_open_cookie_request = -1; + static int hf_tcp_option_fast_open_cookie = -1; +@@ -1455,8 +1457,8 @@ mptcp_init_subflow(tcp_flow_t *flow) + + DISSECTOR_ASSERT(flow->mptcp_subflow == 0); + flow->mptcp_subflow = sf; +- sf->mappings = wmem_itree_new(wmem_file_scope()); +- sf->dsn_map = wmem_itree_new(wmem_file_scope()); ++ sf->ssn2dsn_mappings = wmem_itree_new(wmem_file_scope()); ++ sf->dsn2packet_map = wmem_itree_new(wmem_file_scope()); + } + + +@@ -2607,13 +2609,13 @@ guint64 rawdsn64low, guint64 rawdsn64high + mptcp_dsn2packet_mapping_t *packet = NULL; + proto_item *item = NULL; + +- results = wmem_itree_find_intervals(subflow->mappings, ++ results = wmem_itree_find_intervals(subflow->dsn2packet_map, + wmem_packet_scope(), + rawdsn64low, + rawdsn64high + ); + +- for(packet_it=wmem_list_head(results); ++ for(packet_it = wmem_list_head(results); + packet_it != NULL; + packet_it = wmem_list_frame_next(packet_it)) + { +@@ -2621,43 +2623,18 @@ guint64 rawdsn64low, guint64 rawdsn64high + packet = (mptcp_dsn2packet_mapping_t *) wmem_list_frame_data(packet_it); + DISSECTOR_ASSERT(packet); + +- item = proto_tree_add_uint(tree, hf_mptcp_duplicated_data, tvb, 0, 0, packet->frame); ++ if(pinfo->num > packet->frame) { ++ item = proto_tree_add_uint(tree, hf_mptcp_reinjection_of, tvb, 0, 0, packet->frame); ++ } ++ else { ++ item = proto_tree_add_uint(tree, hf_mptcp_reinjected_in, tvb, 0, 0, packet->frame); ++ } + PROTO_ITEM_SET_GENERATED(item); + } + + return packet; + } + +-/* Finds mappings that cover the sent data */ +-static mptcp_dss_mapping_t * +-mptcp_add_matching_dss_on_subflow(packet_info *pinfo _U_, proto_tree *tree, tvbuff_t *tvb, struct mptcp_subflow *subflow, +-guint32 relseq, guint32 seglen +-) +-{ +- wmem_list_t *results = NULL; +- wmem_list_frame_t *dss_it = NULL; +- mptcp_dss_mapping_t *mapping = NULL; +- proto_item *item = NULL; +- +- results = wmem_itree_find_intervals(subflow->mappings, +- wmem_packet_scope(), +- relseq, +- (seglen) ? relseq + seglen - 1 : relseq +- ); +- +- for(dss_it=wmem_list_head(results); +- dss_it!= NULL; +- dss_it= wmem_list_frame_next(dss_it)) +- { +- mapping = (mptcp_dss_mapping_t *) wmem_list_frame_data(dss_it); +- DISSECTOR_ASSERT(mapping); +- +- item = proto_tree_add_uint(tree, hf_mptcp_related_mapping, tvb, 0, 0, mapping->frame); +- PROTO_ITEM_SET_GENERATED(item); +- } +- +- return mapping; +-} + + /* Lookup mappings that describe the packet and then converts the tcp seq number + * into the MPTCP Data Sequence Number (DSN) +@@ -2698,13 +2675,29 @@ mptcp_analysis_dsn_lookup(packet_info *pinfo , tvbuff_t *tvb, + rawdsn = tcpd->fwd->mptcp_subflow->meta->base_dsn; + convert = DSN_CONV_NONE; + } ++ /* if it's a non-syn packet without data (just used to convey TCP options) ++ * then there would be no mappings */ ++ else if(relseq == 1 && tcph->th_seglen == 0) { ++ rawdsn = tcpd->fwd->mptcp_subflow->meta->base_dsn + 1; ++ convert = DSN_CONV_NONE; ++ } + else { +- /* display packets that conveyed the mappings covering the data range */ +- mapping = mptcp_add_matching_dss_on_subflow(pinfo, parent_tree, tvb, +- tcpd->fwd->mptcp_subflow, relseq, +- (tcph->th_have_seglen) ? tcph->th_seglen : 0 +- ); +- if(mapping == NULL) { ++ ++ wmem_list_frame_t *dss_it = NULL; ++ wmem_list_t *results = NULL; ++ guint32 ssn_low = relseq; ++ guint32 seglen = tcph->th_seglen; ++ ++ results = wmem_itree_find_intervals(tcpd->fwd->mptcp_subflow->ssn2dsn_mappings, ++ wmem_packet_scope(), ++ ssn_low, ++ (seglen) ? ssn_low + seglen - 1 : ssn_low ++ ); ++ dss_it = wmem_list_head(results); /* assume it's always ok */ ++ if(dss_it) { ++ mapping = (mptcp_dss_mapping_t *) wmem_list_frame_data(dss_it); ++ } ++ if(dss_it == NULL || mapping == NULL) { + expert_add_info(pinfo, parent_tree, &ei_mptcp_mapping_missing); + return; + } +@@ -2713,6 +2706,19 @@ mptcp_analysis_dsn_lookup(packet_info *pinfo , tvbuff_t *tvb, + } + + DISSECTOR_ASSERT(mapping); ++ if(seglen) { ++ /* Finds mappings that cover the sent data and adds them to the dissection tree */ ++ for(dss_it = wmem_list_head(results); ++ dss_it != NULL; ++ dss_it = wmem_list_frame_next(dss_it)) ++ { ++ mapping = (mptcp_dss_mapping_t *) wmem_list_frame_data(dss_it); ++ DISSECTOR_ASSERT(mapping); ++ ++ item = proto_tree_add_uint(parent_tree, hf_mptcp_related_mapping, tvb, 0, 0, mapping->frame); ++ PROTO_ITEM_SET_GENERATED(item); ++ } ++ } + + convert = (mapping->extended_dsn) ? DSN_CONV_NONE : DSN_CONV_32_TO_64; + DISSECTOR_ASSERT(mptcp_map_relssn_to_rawdsn(mapping, relseq, &rawdsn)); +@@ -2732,39 +2738,40 @@ mptcp_analysis_dsn_lookup(packet_info *pinfo , tvbuff_t *tvb, + proto_item_append_text(item, " (Relative)"); + } + +- /* register */ +- if (!PINFO_FD_VISITED(pinfo)) +- { +- mptcp_dsn2packet_mapping_t *packet; +- packet = wmem_new0(wmem_file_scope(), mptcp_dsn2packet_mapping_t); +- packet->frame = pinfo->fd->num; +- packet->subflow = tcpd; +- +- /* tcph->th_mptcp->mh_rawdsn64 */ +- if (tcph->th_have_seglen) { +- wmem_itree_insert(tcpd->fwd->mptcp_subflow->dsn_map, ++ /* register dsn->packet mapping */ ++ if(mptcp_intersubflows_retransmission ++ && !PINFO_FD_VISITED(pinfo) ++ && tcph->th_seglen > 0 ++ ) { ++ mptcp_dsn2packet_mapping_t *packet = 0; ++ packet = wmem_new0(wmem_file_scope(), mptcp_dsn2packet_mapping_t); ++ packet->frame = pinfo->fd->num; ++ packet->subflow = tcpd; ++ ++ wmem_itree_insert(tcpd->fwd->mptcp_subflow->dsn2packet_map, + tcph->th_mptcp->mh_rawdsn64, + tcph->th_mptcp->mh_rawdsn64 + (tcph->th_seglen - 1 ), + packet + ); +- } + } + PROTO_ITEM_SET_GENERATED(item); + + /* We can do this only if rawdsn64 is valid ! + if enabled, look for overlapping mappings on other subflows */ +- if(mptcp_intersubflows_retransmission) { ++ if(mptcp_intersubflows_retransmission ++ && tcph->th_have_seglen ++ && tcph->th_seglen) { + + wmem_list_frame_t *subflow_it = NULL; + +- /* results should be some kind of in case 2 DSS are needed to cover this packet */ ++ /* results should be some kind of list in case 2 DSS are needed to cover this packet */ + for(subflow_it = wmem_list_head(mptcpd->subflows); subflow_it != NULL; subflow_it = wmem_list_frame_next(subflow_it)) { + struct tcp_analysis *sf_tcpd = (struct tcp_analysis *)wmem_list_frame_data(subflow_it); + struct mptcp_subflow *sf = mptcp_select_subflow_from_meta(sf_tcpd, tcpd->fwd->mptcp_subflow->meta); + + /* for current subflow */ + if (sf == tcpd->fwd->mptcp_subflow) { +- /* skip, was done just before */ ++ /* skip, this is the current subflow */ + } + /* in case there were retransmissions on other subflows */ + else { +@@ -2776,7 +2783,7 @@ mptcp_analysis_dsn_lookup(packet_info *pinfo , tvbuff_t *tvb, + } + } + else { +- /* ignore and continue */ ++ /* could not get the rawdsn64, ignore and continue */ + } + + } +@@ -4590,7 +4597,6 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + + if (!PINFO_FD_VISITED(pinfo)) + { +- + /* register SSN range described by the mapping into a subflow interval_tree */ + mptcp_dss_mapping_t *mapping = NULL; + mapping = wmem_new0(wmem_file_scope(), mptcp_dss_mapping_t); +@@ -4601,7 +4607,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + mapping->ssn_low = mph->mh_dss_ssn; + mapping->ssn_high = mph->mh_dss_ssn + mph->mh_dss_length-1; + +- wmem_itree_insert(tcpd->fwd->mptcp_subflow->mappings, ++ wmem_itree_insert(tcpd->fwd->mptcp_subflow->ssn2dsn_mappings, + mph->mh_dss_ssn, + mapping->ssn_high, + mapping +@@ -7564,15 +7570,19 @@ proto_register_tcp(void) + "This frame has some of the MPTCP analysis shown", HFILL }}, + + { &hf_mptcp_related_mapping, +- { "Related mapping", "mptcp.related_mapping", FT_FRAMENUM , BASE_NONE, NULL, 0x0, +- "Packet in which mapping describing current packet was sent", HFILL }}, ++ { "Related mapping", "mptcp.related_mapping", FT_FRAMENUM , BASE_NONE, NULL, 0x0, ++ "Packet in which current packet DSS mapping was sent", HFILL }}, ++ ++ { &hf_mptcp_reinjection_of, ++ { "Reinjection of", "mptcp.reinjection_of", FT_FRAMENUM , BASE_NONE, NULL, 0x0, ++ "This is a retransmission of data sent on another subflow", HFILL }}, + +- { &hf_mptcp_duplicated_data, +- { "Was data duplicated", "mptcp.duplicated_dsn", FT_FRAMENUM , BASE_NONE, NULL, 0x0, ++ { &hf_mptcp_reinjected_in, ++ { "Data reinjected in", "mptcp.reinjected_in", FT_FRAMENUM , BASE_NONE, NULL, 0x0, + "This was retransmitted on another subflow", HFILL }}, + + { &hf_mptcp_analysis_subflows, +- { "TCP subflow stream id(s):", "mptcp.analysis.subflows", FT_NONE, BASE_NONE, NULL, 0x0, ++ { "TCP subflow stream id(s):", "mptcp.analysis.subflows", FT_NONE, BASE_NONE, NULL, 0x0, + "List all TCP connections mapped to this MPTCP connection", HFILL }}, + + { &hf_mptcp_stream, +@@ -7752,13 +7762,16 @@ proto_register_tcp(void) + &mptcp_relative_seq); + + prefs_register_bool_preference(mptcp_module, "analyze_mappings", +- "In depth analysis of Data Sequence Signal (DSS) mappings.", ++ "Deeper analysis of Data Sequence Signal (DSS)", ++ "Scales logarithmically with the number of packets" + "You need to capture the handshake for this to work." + "\"Map TCP subflows to their respective MPTCP connections\"", + &mptcp_analyze_mappings); + + prefs_register_bool_preference(mptcp_module, "intersubflows_retransmission", + "Check for data duplication across subflows", ++ "(Greedy algorithm: Scales linearly with number of subflows and" ++ " logarithmic scaling with number of packets)" + "You need to enable DSS mapping analysis for this option to work", + &mptcp_intersubflows_retransmission); + +diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h +index 7f84351ade..c1811fa049 100644 +--- a/epan/dissectors/packet-tcp.h ++++ b/epan/dissectors/packet-tcp.h +@@ -257,15 +257,16 @@ struct mptcp_subflow { + guint8 address_id; /* sent during an MP_JOIN */ + + +- /* Attempt to map DSN to packets +- * Ideally this was to generate application latency +- * each node contains a GSList * ? +- * this should be done in tap or 3rd party tools ++ /* map DSN to packets ++ * Used when looking for reinjections across subflows + */ +- wmem_itree_t *dsn_map; ++ wmem_itree_t *dsn2packet_map; + +- /* Map SSN to a DSS mappings, each node registers a mptcp_dss_mapping_t */ +- wmem_itree_t *mappings; ++ /* Map SSN to a DSS mappings ++ * a DSS can map DSN to SSNs possibily over several packets, ++ * hence some packets may have been mapped by previous DSS, ++ * whence the necessity to be able to look for SSN -> DSN */ ++ wmem_itree_t *ssn2dsn_mappings; + /* meta flow to which it is attached. Helps setting forward and backward meta flow */ + mptcp_meta_flow_t *meta; + }; +diff --git a/epan/wmem/wmem_interval_tree.c b/epan/wmem/wmem_interval_tree.c +index d52267de18..48888996b7 100644 +--- a/epan/wmem/wmem_interval_tree.c ++++ b/epan/wmem/wmem_interval_tree.c +@@ -121,7 +121,7 @@ wmem_itree_insert(wmem_itree_t *tree, const guint64 low, const guint64 high, voi + node = wmem_tree_insert(tree, range, data, (compare_func)wmem_tree_compare_ranges); + + /* Even If no rotations, still a need to update max_edge */ +- update_max_edge(node); ++ update_max_edge(node->parent); + } + + +diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c +index 74e9b6b10c..efcfa005af 100644 +--- a/epan/dissectors/packet-tcp.c ++++ b/epan/dissectors/packet-tcp.c +@@ -4361,6 +4361,35 @@ get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint6 + return mptcpd; + } + ++/* record this mapping */ ++static ++void analyze_mapping(struct tcp_analysis *tcpd, packet_info *pinfo, guint16 len, guint64 dsn, gboolean extended, guint32 ssn) { ++ ++ /* store mapping only if analysis is enabled and mapping is not unlimited */ ++ if (!mptcp_analyze_mappings || !len) { ++ return; ++ } ++ ++ if (PINFO_FD_VISITED(pinfo)) { ++ return; ++ } ++ ++ /* register SSN range described by the mapping into a subflow interval_tree */ ++ mptcp_dss_mapping_t *mapping = NULL; ++ mapping = wmem_new0(wmem_file_scope(), mptcp_dss_mapping_t); ++ ++ mapping->rawdsn = dsn; ++ mapping->extended_dsn = extended; ++ mapping->frame = pinfo->fd->num; ++ mapping->ssn_low = ssn; ++ mapping->ssn_high = ssn + len - 1; ++ ++ wmem_itree_insert(tcpd->fwd->mptcp_subflow->ssn2dsn_mappings, ++ mapping->ssn_low, ++ mapping->ssn_high, ++ mapping ++ ); ++} + + /* + * The TCP Extensions for Multipath Operation with Multiple Addresses +@@ -4449,8 +4478,11 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + } + offset += 1; + +- /* optlen == 12 => SYN or SYN/ACK; optlen == 20 => ACK */ +- if (optlen == 12 || optlen == 20) { ++ /* optlen == 12 => SYN or SYN/ACK; optlen == 20 => ACK; ++ * optlen == 22 => ACK + data (v1 only); ++ * optlen == 24 => ACK + data + csum (v1 only) ++ */ ++ if (optlen == 12 || optlen == 20 || optlen == 22 || optlen == 24) { + + mph->mh_key = tvb_get_ntoh64(tvb,offset); + proto_tree_add_uint64(mptcp_tree, hf_tcp_option_mptcp_sender_key, tvb, offset, 8, mph->mh_key); +@@ -4468,9 +4500,10 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + PROTO_ITEM_SET_GENERATED(item); + + /* last ACK of 3WHS, repeats both keys */ +- if (optlen == 20) { ++ if (optlen >= 20) { + guint64 recv_key = tvb_get_ntoh64(tvb,offset); + proto_tree_add_uint64(mptcp_tree, hf_tcp_option_mptcp_recv_key, tvb, offset, 8, recv_key); ++ offset += 8; + + if(tcpd->rev->mptcp_subflow->meta + && (tcpd->rev->mptcp_subflow->meta->static_flags & MPTCP_META_HAS_KEY)) { +@@ -4484,6 +4517,26 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->rev, recv_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK); + } + } ++ ++ /* MPTCP v1 ACK + data, contains data_len and optional checksum */ ++ if (optlen >= 22) { ++ proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_data_lvl_len, tvb, offset, 2, ENC_BIG_ENDIAN); ++ mph->mh_dss_length = tvb_get_ntohs(tvb,offset); ++ offset += 2; ++ ++ if (mph->mh_dss_length == 0) { ++ expert_add_info(pinfo, mptcp_tree, &ei_mptcp_infinite_mapping); ++ } ++ ++ /* when data len is present, this MP_CAPABLE also carries an implicit mapping ... */ ++ analyze_mapping(tcpd, pinfo, mph->mh_dss_length, tcpd->fwd->mptcp_subflow->meta->base_dsn + 1, TRUE, tcph->th_seq); ++ ++ /* ... with optional checksum */ ++ if (optlen == 24) ++ { ++ proto_tree_add_checksum(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS); ++ } ++ } + } + break; + +@@ -4650,29 +4703,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + /* ignore and continue */ + } + +- /* if mapping analysis enabled and not a */ +- if(mptcp_analyze_mappings && mph->mh_dss_length) +- { +- +- if (!PINFO_FD_VISITED(pinfo)) +- { +- /* register SSN range described by the mapping into a subflow interval_tree */ +- mptcp_dss_mapping_t *mapping = NULL; +- mapping = wmem_new0(wmem_file_scope(), mptcp_dss_mapping_t); +- +- mapping->rawdsn = mph->mh_dss_rawdsn; +- mapping->extended_dsn = (mph->mh_dss_flags & MPTCP_DSS_FLAG_DATA_ACK_8BYTES); +- mapping->frame = pinfo->fd->num; +- mapping->ssn_low = mph->mh_dss_ssn; +- mapping->ssn_high = mph->mh_dss_ssn + mph->mh_dss_length-1; +- +- wmem_itree_insert(tcpd->fwd->mptcp_subflow->ssn2dsn_mappings, +- mph->mh_dss_ssn, +- mapping->ssn_high, +- mapping +- ); +- } +- } ++ analyze_mapping(tcpd, pinfo, mph->mh_dss_length, mph->mh_dss_rawdsn, mph->mh_dss_flags & MPTCP_DSS_FLAG_DATA_ACK_8BYTES, mph->mh_dss_ssn); + + if ((int)optlen >= offset-start_offset+4) + { +diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c +index efcfa005af..238b592927 100644 +--- a/epan/dissectors/packet-tcp.c ++++ b/epan/dissectors/packet-tcp.c +@@ -246,7 +246,8 @@ static int hf_tcp_option_mptcp_flags = -1; + static int hf_tcp_option_mptcp_backup_flag = -1; + static int hf_tcp_option_mptcp_checksum_flag = -1; + static int hf_tcp_option_mptcp_B_flag = -1; +-static int hf_tcp_option_mptcp_H_flag = -1; ++static int hf_tcp_option_mptcp_H_v0_flag = -1; ++static int hf_tcp_option_mptcp_H_v1_flag = -1; + static int hf_tcp_option_mptcp_F_flag = -1; + static int hf_tcp_option_mptcp_m_flag = -1; + static int hf_tcp_option_mptcp_M_flag = -1; +@@ -593,10 +594,18 @@ static guint32 mptcp_stream_count; + */ + static wmem_tree_t *mptcp_tokens = NULL; + +-static const int *tcp_option_mptcp_capable_flags[] = { ++static const int *tcp_option_mptcp_capable_v0_flags[] = { + &hf_tcp_option_mptcp_checksum_flag, + &hf_tcp_option_mptcp_B_flag, +- &hf_tcp_option_mptcp_H_flag, ++ &hf_tcp_option_mptcp_H_v0_flag, ++ &hf_tcp_option_mptcp_reserved_flag, ++ NULL ++}; ++ ++static const int *tcp_option_mptcp_capable_v1_flags[] = { ++ &hf_tcp_option_mptcp_checksum_flag, ++ &hf_tcp_option_mptcp_B_flag, ++ &hf_tcp_option_mptcp_H_v1_flag, + &hf_tcp_option_mptcp_reserved_flag, + NULL + }; +@@ -2574,6 +2583,24 @@ mptcp_cryptodata_sha1(const guint64 key, guint32 *token, guint64 *idsn) + *idsn = GUINT64_FROM_BE(_isdn); + } + ++/* Generate the initial data sequence number and MPTCP connection token from the key. */ ++static void ++mptcp_cryptodata_sha256(const guint64 key, guint32 *token, guint64 *idsn) ++{ ++ guint8 digest_buf[HASH_SHA2_256_LENGTH]; ++ guint64 pseudokey = GUINT64_TO_BE(key); ++ guint32 _token; ++ guint64 _isdn; ++ ++ gcry_md_hash_buffer(GCRY_MD_SHA256, digest_buf, (const guint8 *)&pseudokey, 8); ++ ++ /* memcpy to prevent -Wstrict-aliasing errors with GCC 4 */ ++ memcpy(&_token, digest_buf, sizeof(_token)); ++ *token = GUINT32_FROM_BE(_token); ++ memcpy(&_isdn, digest_buf + HASH_SHA2_256_LENGTH - sizeof(_isdn), sizeof(_isdn)); ++ *idsn = GUINT64_FROM_BE(_isdn); ++} ++ + + /* Print formatted list of tcp stream ids that are part of the connection */ + static void +@@ -4338,7 +4365,7 @@ mptcp_get_meta_from_token(struct tcp_analysis* tcpd, tcp_flow_t *tcp_flow, guint + /* setup from_key */ + static + struct mptcp_analysis* +-get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint64 key, guint8 hmac_algo _U_) { ++get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint8 version, guint64 key, guint8 hmac_algo _U_) { + + guint32 token = 0; + guint64 expected_idsn= 0; +@@ -4348,8 +4375,11 @@ get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint6 + return mptcpd; + } + +- /* MPTCP only standardizes SHA1 for now. */ +- mptcp_cryptodata_sha1(key, &token, &expected_idsn); ++ /* MPTCP v0 only standardizes SHA1, and v1 SHA256. */ ++ if (version == 0) ++ mptcp_cryptodata_sha1(key, &token, &expected_idsn); ++ else if (version == 1) ++ mptcp_cryptodata_sha256(key, &token, &expected_idsn); + + mptcpd = mptcp_get_meta_from_token(tcpd, fwd, token); + +@@ -4409,6 +4439,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + proto_item *item,*main_item; + proto_tree *mptcp_tree; + ++ guint32 version; + guint8 subtype; + guint8 ipver; + int offset = 0; +@@ -4462,18 +4493,19 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + case TCPOPT_MPTCP_MP_CAPABLE: + mph->mh_mpc = TRUE; + +- proto_tree_add_item(mptcp_tree, hf_tcp_option_mptcp_version, tvb, +- offset, 1, ENC_BIG_ENDIAN); ++ proto_tree_add_item_ret_uint(mptcp_tree, hf_tcp_option_mptcp_version, tvb, ++ offset, 1, ENC_BIG_ENDIAN, &version); + offset += 1; + + item = proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags, +- ett_tcp_option_mptcp, tcp_option_mptcp_capable_flags, ++ ett_tcp_option_mptcp, ++ version == 1 ? tcp_option_mptcp_capable_v1_flags : tcp_option_mptcp_capable_v0_flags, + ENC_BIG_ENDIAN); + mph->mh_capable_flags = tvb_get_guint8(tvb, offset); + if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) == 0) { + expert_add_info(pinfo, item, &ei_mptcp_analysis_missing_algorithm); + } +- if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) != MPTCP_HMAC_SHA1) { ++ if ((mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK) != MPTCP_HMAC_SHA) { + expert_add_info(pinfo, item, &ei_mptcp_analysis_unsupported_algorithm); + } + offset += 1; +@@ -4488,7 +4520,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + proto_tree_add_uint64(mptcp_tree, hf_tcp_option_mptcp_sender_key, tvb, offset, 8, mph->mh_key); + offset += 8; + +- mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->fwd, mph->mh_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK); ++ mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->fwd, version, mph->mh_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK); + mptcpd->master = tcpd; + + item = proto_tree_add_uint(mptcp_tree, +@@ -4514,7 +4546,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + } + } + else { +- mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->rev, recv_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK); ++ mptcpd = get_or_create_mptcpd_from_key(tcpd, tcpd->rev, version, recv_key, mph->mh_capable_flags & MPTCP_CAPABLE_CRYPTO_MASK); + } + } + +@@ -7147,10 +7179,14 @@ proto_register_tcp(void) + { "Extensibility", "tcp.options.mptcp.extensibility.flag", FT_UINT8, + BASE_DEC, NULL, 0x40, NULL, HFILL}}, + +- { &hf_tcp_option_mptcp_H_flag, ++ { &hf_tcp_option_mptcp_H_v0_flag, + { "Use HMAC-SHA1", "tcp.options.mptcp.sha1.flag", FT_UINT8, + BASE_DEC, NULL, 0x01, NULL, HFILL}}, + ++ { &hf_tcp_option_mptcp_H_v1_flag, ++ { "Use HMAC-SHA256", "tcp.options.mptcp.sha256.flag", FT_UINT8, ++ BASE_DEC, NULL, 0x01, NULL, HFILL}}, ++ + { &hf_tcp_option_mptcp_F_flag, + { "DATA_FIN", "tcp.options.mptcp.datafin.flag", FT_UINT8, + BASE_DEC, NULL, MPTCP_DSS_FLAG_DATA_FIN_PRESENT, NULL, HFILL}}, +diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h +index dfee9cdeb4..38630d3a51 100644 +--- a/epan/dissectors/packet-tcp.h ++++ b/epan/dissectors/packet-tcp.h +@@ -277,7 +277,8 @@ struct mptcp_subflow { + + typedef enum { + MPTCP_HMAC_NOT_SET = 0, +- MPTCP_HMAC_SHA1 = 1, ++ /* this is either SHA1 for MPTCP v0 or sha256 for MPTCP v1 */ ++ MPTCP_HMAC_SHA = 1, + MPTCP_HMAC_LAST + } mptcp_hmac_algorithm_t; + +diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c +index c4a9a6eb15..ca284604ed 100644 +--- a/epan/dissectors/packet-tcp.c ++++ b/epan/dissectors/packet-tcp.c +@@ -271,6 +271,7 @@ static int hf_tcp_option_mptcp_subflow_seq_no = -1; + static int hf_tcp_option_mptcp_data_lvl_len = -1; + static int hf_tcp_option_mptcp_checksum = -1; + static int hf_tcp_option_mptcp_ipver = -1; ++static int hf_tcp_option_mptcp_echo = -1; + static int hf_tcp_option_mptcp_ipv4 = -1; + static int hf_tcp_option_mptcp_ipv6 = -1; + static int hf_tcp_option_mptcp_port = -1; +@@ -4776,33 +4777,32 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + break; + + case TCPOPT_MPTCP_ADD_ADDR: +- proto_tree_add_item(mptcp_tree, +- hf_tcp_option_mptcp_ipver, tvb, offset, 1, ENC_BIG_ENDIAN); + ipver = tvb_get_guint8(tvb, offset) & 0x0F; ++ if (ipver == 4 || ipver == 6) ++ proto_tree_add_item(mptcp_tree, ++ hf_tcp_option_mptcp_ipver, tvb, offset, 1, ENC_BIG_ENDIAN); ++ else ++ proto_tree_add_item(mptcp_tree, ++ hf_tcp_option_mptcp_echo, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + + proto_tree_add_item(mptcp_tree, + hf_tcp_option_mptcp_address_id, tvb, offset, 1, ENC_BIG_ENDIAN); + offset += 1; + +- switch (ipver) { +- case 4: +- proto_tree_add_item(mptcp_tree, ++ if (optlen == 8 || optlen == 10 || optlen == 16 || optlen == 18) { ++ proto_tree_add_item(mptcp_tree, + hf_tcp_option_mptcp_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN); +- offset += 4; +- break; ++ offset += 4; ++ } + +- case 6: +- proto_tree_add_item(mptcp_tree, ++ if (optlen == 20 || optlen == 22 || optlen == 28 || optlen == 30) { ++ proto_tree_add_item(mptcp_tree, + hf_tcp_option_mptcp_ipv6, tvb, offset, 16, ENC_NA); +- offset += 16; +- break; +- +- default: +- break; ++ offset += 16; + } + +- if (optlen % 4 == 2) { ++ if (optlen == 10 || optlen == 18 || optlen == 22 || optlen == 30) { + proto_tree_add_item(mptcp_tree, + hf_tcp_option_mptcp_port, tvb, offset, 2, ENC_BIG_ENDIAN); + offset += 2; +@@ -7303,6 +7303,10 @@ proto_register_tcp(void) + { "IP version", "tcp.options.mptcp.ipver", FT_UINT8, + BASE_DEC, NULL, 0x0F, NULL, HFILL}}, + ++ { &hf_tcp_option_mptcp_echo, ++ { "Echo", "tcp.options.mptcp.echo", FT_UINT8, ++ BASE_DEC, NULL, 0x01, NULL, HFILL}}, ++ + { &hf_tcp_option_mptcp_ipv4, + { "Advertised IPv4 Address", "tcp.options.mptcp.ipv4", FT_IPv4, + BASE_NONE, NULL, 0x0, NULL, HFILL}}, +diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c +index 6bc1915e82..b0ed652215 100644 +--- a/epan/dissectors/packet-tcp.c ++++ b/epan/dissectors/packet-tcp.c +@@ -2152,13 +2152,19 @@ tcp_analyze_sequence_number(packet_info *pinfo, guint32 seq, guint32 ack, guint3 + && seq==tcpd->fwd->tcp_analyze_seq_info->nextseq + && ack==tcpd->fwd->tcp_analyze_seq_info->lastack + && (flags&(TH_SYN|TH_FIN|TH_RST))==0 ) { +- tcpd->fwd->tcp_analyze_seq_info->dupacknum++; +- if(!tcpd->ta) { +- tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd); +- } +- tcpd->ta->flags|=TCP_A_DUPLICATE_ACK; +- tcpd->ta->dupack_num=tcpd->fwd->tcp_analyze_seq_info->dupacknum; +- tcpd->ta->dupack_frame=tcpd->fwd->tcp_analyze_seq_info->lastnondupack; ++ ++ /* MPTCP tolerates duplicate acks in some circumstances, see RFC 8684 4. */ ++ if(tcpd->mptcp_analysis && (tcpd->mptcp_analysis->mp_operations!=tcpd->fwd->mp_operations)) { ++ /* just ignore this DUPLICATE ACK */ ++ } else { ++ tcpd->fwd->tcp_analyze_seq_info->dupacknum++; ++ if(!tcpd->ta) { ++ tcp_analyze_get_acked_struct(pinfo->num, seq, ack, TRUE, tcpd); ++ } ++ tcpd->ta->flags|=TCP_A_DUPLICATE_ACK; ++ tcpd->ta->dupack_num=tcpd->fwd->tcp_analyze_seq_info->dupacknum; ++ tcpd->ta->dupack_frame=tcpd->fwd->tcp_analyze_seq_info->lastnondupack; ++ } + } + + +@@ -2343,6 +2349,10 @@ finished_checking_retransmission_type: + tcpd->fwd->tcp_analyze_seq_info->lastacktime.secs=pinfo->abs_ts.secs; + tcpd->fwd->tcp_analyze_seq_info->lastacktime.nsecs=pinfo->abs_ts.nsecs; + ++ /* remember the MPTCP operations if any */ ++ if( tcpd->mptcp_analysis ) { ++ tcpd->fwd->mp_operations=tcpd->mptcp_analysis->mp_operations; ++ } + + /* if there were any flags set for this segment we need to remember them + * we only remember the flags for the very last segment though. +@@ -2702,24 +2712,17 @@ mptcp_analysis_add_subflows(packet_info *pinfo _U_, tvbuff_t *tvb, + proto_tree *parent_tree, struct mptcp_analysis* mptcpd) + { + wmem_list_frame_t *it; +- proto_tree *tree; + proto_item *item; + +- item=proto_tree_add_item(parent_tree, hf_mptcp_analysis_subflows, tvb, 0, 0, ENC_NA); +- PROTO_ITEM_SET_GENERATED(item); +- +- tree=proto_item_add_subtree(item, ett_mptcp_analysis_subflows); ++ wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), ""); + + /* for the analysis, we set each subflow tcp stream id */ + for(it = wmem_list_head(mptcpd->subflows); it != NULL; it = wmem_list_frame_next(it)) { + struct tcp_analysis *sf = (struct tcp_analysis *)wmem_list_frame_data(it); +- proto_item *subflow_item; +- subflow_item=proto_tree_add_uint(tree, hf_mptcp_analysis_subflows_stream_id, tvb, 0, 0, sf->stream); +- PROTO_ITEM_SET_HIDDEN(subflow_item); +- +- proto_item_append_text(item, " %d", sf->stream); ++ wmem_strbuf_append_printf(val, "%u ", sf->stream); + } + ++ item = proto_tree_add_string(parent_tree, hf_mptcp_analysis_subflows, tvb, 0, 0, wmem_strbuf_get_str(val)); + PROTO_ITEM_SET_GENERATED(item); + } + +@@ -2962,6 +2965,42 @@ mptcp_add_analysis_subtree(packet_info *pinfo, tvbuff_t *tvb, proto_tree *parent + + PROTO_ITEM_SET_GENERATED(item); + ++ /* store the TCP Options related to MPTCP then we will avoid false DUP ACKs later */ ++ guint8 nbOptionsChanged = 0; ++ if((tcpd->mptcp_analysis->mp_operations&(0x01))!=tcph->th_mptcp->mh_mpc) { ++ tcpd->mptcp_analysis->mp_operations |= 0x01; ++ nbOptionsChanged++; ++ } ++ if((tcpd->mptcp_analysis->mp_operations&(0x02))!=tcph->th_mptcp->mh_join) { ++ tcpd->mptcp_analysis->mp_operations |= 0x02; ++ nbOptionsChanged++; ++ } ++ if((tcpd->mptcp_analysis->mp_operations&(0x04))!=tcph->th_mptcp->mh_dss) { ++ tcpd->mptcp_analysis->mp_operations |= 0x04; ++ nbOptionsChanged++; ++ } ++ if((tcpd->mptcp_analysis->mp_operations&(0x08))!=tcph->th_mptcp->mh_add) { ++ tcpd->mptcp_analysis->mp_operations |= 0x08; ++ nbOptionsChanged++; ++ } ++ if((tcpd->mptcp_analysis->mp_operations&(0x10))!=tcph->th_mptcp->mh_remove) { ++ tcpd->mptcp_analysis->mp_operations |= 0x10; ++ nbOptionsChanged++; ++ } ++ if((tcpd->mptcp_analysis->mp_operations&(0x20))!=tcph->th_mptcp->mh_prio) { ++ tcpd->mptcp_analysis->mp_operations |= 0x20; ++ nbOptionsChanged++; ++ } ++ if((tcpd->mptcp_analysis->mp_operations&(0x40))!=tcph->th_mptcp->mh_fail) { ++ tcpd->mptcp_analysis->mp_operations |= 0x40; ++ nbOptionsChanged++; ++ } ++ if((tcpd->mptcp_analysis->mp_operations&(0x80))!=tcph->th_mptcp->mh_fastclose) { ++ tcpd->mptcp_analysis->mp_operations |= 0x80; ++ nbOptionsChanged++; ++ } ++ /* we could track MPTCP option changes here, with nbOptionsChanged */ ++ + item = proto_tree_add_uint(tree, hf_mptcp_stream, tvb, 0, 0, mptcpd->stream); + PROTO_ITEM_SET_GENERATED(item); + +@@ -4537,6 +4576,7 @@ get_or_create_mptcpd_from_key(struct tcp_analysis* tcpd, tcp_flow_t *fwd, guint8 + + DISSECTOR_ASSERT(fwd->mptcp_subflow->meta); + ++ fwd->mptcp_subflow->meta->version = version; + fwd->mptcp_subflow->meta->key = key; + fwd->mptcp_subflow->meta->static_flags |= MPTCP_META_HAS_KEY; + fwd->mptcp_subflow->meta->base_dsn = expected_idsn; +@@ -4747,6 +4787,13 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + offset += 4; + + mptcpd = mptcp_get_meta_from_token(tcpd, tcpd->rev, mph->mh_token); ++ if (tcpd->fwd->mptcp_subflow->meta->version == 1) { ++ mptcp_meta_flow_t *tmp = tcpd->fwd->mptcp_subflow->meta; ++ ++ /* if the negotiated version is v1 the first key was exchanged on SYN/ACK packet: we must swap the meta */ ++ tcpd->fwd->mptcp_subflow->meta = tcpd->rev->mptcp_subflow->meta; ++ tcpd->rev->mptcp_subflow->meta = tmp; ++ } + + proto_tree_add_item_ret_uint(mptcp_tree, hf_tcp_option_mptcp_sender_rand, tvb, offset, + 4, ENC_BIG_ENDIAN, &tcpd->fwd->mptcp_subflow->nonce); +@@ -4897,6 +4944,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + break; + + case TCPOPT_MPTCP_ADD_ADDR: ++ mph->mh_add = TRUE; + ipver = tvb_get_guint8(tvb, offset) & 0x0F; + if (ipver == 4 || ipver == 6) + proto_tree_add_item(mptcp_tree, +@@ -4935,6 +4983,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + break; + + case TCPOPT_MPTCP_REMOVE_ADDR: ++ mph->mh_remove = TRUE; + item = proto_tree_add_uint(mptcp_tree, hf_mptcp_number_of_removed_addresses, tvb, start_offset+2, + 1, optlen - 3); + PROTO_ITEM_SET_GENERATED(item); +@@ -4947,6 +4996,7 @@ dissect_tcpopt_mptcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* + break; + + case TCPOPT_MPTCP_MP_PRIO: ++ mph->mh_prio = TRUE; + proto_tree_add_bitmask(mptcp_tree, tvb, offset, hf_tcp_option_mptcp_flags, + ett_tcp_option_mptcp, tcp_option_mptcp_join_flags, + ENC_BIG_ENDIAN); +@@ -8040,7 +8090,7 @@ proto_register_tcp(void) + "This was retransmitted on another subflow", HFILL }}, + + { &hf_mptcp_analysis_subflows, +- { "TCP subflow stream id(s):", "mptcp.analysis.subflows", FT_NONE, BASE_NONE, NULL, 0x0, ++ { "TCP subflow stream id(s)", "mptcp.analysis.subflows", FT_STRING, BASE_NONE, NULL, 0x0, + "List all TCP connections mapped to this MPTCP connection", HFILL }}, + + { &hf_mptcp_stream, +diff --git a/epan/dissectors/packet-tcp.h b/epan/dissectors/packet-tcp.h +index ac250d948e..21e6a61086 100644 +--- a/epan/dissectors/packet-tcp.h ++++ b/epan/dissectors/packet-tcp.h +@@ -49,8 +49,11 @@ struct mptcpheader { + gboolean mh_mpc; /* true if seen an mp_capable option */ + gboolean mh_join; /* true if seen an mp_join option */ + gboolean mh_dss; /* true if seen a dss */ +- gboolean mh_fastclose; /* true if seen a fastclose */ ++ gboolean mh_add; /* true if seen an MP_ADD */ ++ gboolean mh_remove; /* true if seen an MP_REMOVE */ ++ gboolean mh_prio; /* true if seen an MP_PRIO */ + gboolean mh_fail; /* true if seen an MP_FAIL */ ++ gboolean mh_fastclose; /* true if seen a fastclose */ + + guint8 mh_capable_flags; /* to get hmac version for instance */ + guint8 mh_dss_flags; /* data sequence signal flag */ +@@ -332,6 +335,7 @@ typedef struct _tcp_flow_t { + gboolean valid_bif; /* if lost pkts, disable BiF until ACK is recvd */ + guint32 push_bytes_sent; /* bytes since the last PSH flag */ + gboolean push_set_last; /* tracking last time PSH flag was set */ ++ guint8 mp_operations; /* tracking of the MPTCP operations */ + + tcp_analyze_seq_flow_info_t* tcp_analyze_seq_info; + +@@ -378,6 +382,9 @@ struct mptcp_analysis { + + /* identifier of the tcp stream that saw the initial 3WHS with MP_CAPABLE option */ + struct tcp_analysis *master; ++ ++ /* Keep track of the last TCP operations seen in order to avoid false DUP ACKs */ ++ guint8 mp_operations; + }; + + struct tcp_analysis { diff --git a/SOURCES/wireshark-0027-ibm-smc.patch b/SOURCES/wireshark-0027-ibm-smc.patch new file mode 100644 index 0000000..2df4d08 --- /dev/null +++ b/SOURCES/wireshark-0027-ibm-smc.patch @@ -0,0 +1,1871 @@ +diff --git a/epan/dissectors/CMakeLists.txt b/epan/dissectors/CMakeLists.txt +index 11d2c89cd0..3c313d2c5e 100644 +--- a/epan/dissectors/CMakeLists.txt ++++ b/epan/dissectors/CMakeLists.txt +@@ -1745,7 +1745,7 @@ set(DISSECTOR_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/packet-smb-direct.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-smb.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-smb2.c +- ${CMAKE_CURRENT_SOURCE_DIR}/packet-smcr.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/packet-smc.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-sml.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-smp.c + ${CMAKE_CURRENT_SOURCE_DIR}/packet-smpp.c +diff --git a/epan/dissectors/packet-smcr.c b/epan/dissectors/packet-smc.c +similarity index 56% +rename from epan/dissectors/packet-smcr.c +rename to epan/dissectors/packet-smc.c +index 7096d1b0b0..bbfa9c07ef 100644 +--- a/epan/dissectors/packet-smcr.c ++++ b/epan/dissectors/packet-smc.c +@@ -1,7 +1,8 @@ +-/* packet-smcr.c +- * SMC-R dissector for wireshark ++/* packet-smc.c ++ * SMC dissector for wireshark + * By Joe Fowler +- * (c) Copyright IBM Corporation 2014 ++ * By Guvenc Gulce ++ * (c) Copyright IBM Corporation 2014,2020 + * LICENSE: GNU General Public License, version 2, or (at your option) any + * version. http://opensource.org/licenses/gpl-2.0.php + * +@@ -13,6 +14,7 @@ + * + * Please refer to the following specs for protocol: + * - ietf - draft-fox-tcpm-shared-memory-rdma-05 ++ * - https://www.ibm.com/support/pages/node/6326337 + */ + + #include "config.h" +@@ -20,25 +22,33 @@ + #include + + #include "packet-tcp.h" ++#include + +-#define SMCR_TCP_MIN_HEADER_LENGTH 7 +-#define CLC_MSG_START_OFFSET 7 ++#define SMC_TCP_MIN_HEADER_LENGTH 7 ++#define CLC_MSG_START_OFFSET 5 + #define LLC_MSG_START_OFFSET 3 + #define RMBE_CTRL_START_OFFSET 2 + #define MAC_ADDR_LEN 6 ++#define SMC_V2 2 + #define GID_LEN 16 + #define PEERID_LEN 8 ++#define DIAG_INFO_LEN 4 ++#define EID_LEN 32 ++#define ISM_GID_LEN 8 ++#define ISM_CHID_LEN 2 + #define IPV4_SUBNET_MASK_LEN 4 +-#define IPV6_PREFIX_LEN 4 ++#define IPV6_PREFIX_LEN 16 + #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 LENGTH_BYTE_LEN 2 + #define SEQNO_LEN 2 + #define CURSOR_LEN 4 + #define ALERT_TOKEN_LEN 4 ++#define DMB_TOKEN_LEN 8 + #define PSN_LEN 3 + #define CONN_INDEX_LEN 1 + #define SMCR_MSG_BYTE_0 0 +@@ -52,6 +62,7 @@ + #define LLC_CMD_RSP_OFFSET 3 + #define ACCEPT_CONFIRM_QP_OFFSET 38 + #define SMCR_CLC_ID 0xe2d4c3d9 /*EBCDIC 'SMCR' */ ++#define SMCD_CLC_ID 0xe2d4c3c4 /*EBCDIC 'SMCD' */ + #define SMC_CLC_V1 0x10 + #define SMC_CLC_SMC_R 0x01 + +@@ -66,6 +77,52 @@ typedef enum { + SMC_CLC_DECLINE = 4 + } clc_message; + ++typedef enum { ++ SMC_CLC_SMCR = 0, ++ SMC_CLC_SMCD = 1, ++ SMC_CLC_NONE = 2, ++ SMC_CLC_BOTH = 3, ++} clc_type_message; ++ ++typedef enum { ++ SMC_CLC_OS_ZOS = 1, ++ SMC_CLC_OS_LINUX = 2, ++ SMC_CLC_OS_AIX = 3, ++ SMC_CLC_OS_UNKOWN = 15, ++} clc_os_message; ++ ++static const value_string smc_clc_os_message_txt[] = { ++ { SMC_CLC_OS_ZOS, "z/OS" }, ++ { SMC_CLC_OS_LINUX, "Linux" }, ++ { SMC_CLC_OS_AIX, "AIX" }, ++ { SMC_CLC_OS_UNKOWN, "Unknown" }, ++ { 0, NULL } ++}; ++ ++static const value_string smc_clc_type_message_txt[] = { ++ { SMC_CLC_SMCR, "SMC-R" }, ++ { SMC_CLC_SMCD, "SMC-D" }, ++ { SMC_CLC_NONE, "NONE" }, ++ { SMC_CLC_BOTH, "SMC-R/SMC-D" }, ++ { 0, NULL } ++}; ++ ++ ++static const value_string smcv2_clc_col_info_message_txt[] = { ++ { SMC_CLC_SMCR, "[SMC-R-Proposal]" }, ++ { SMC_CLC_SMCD, "[SMC-Dv2-Proposal]" }, ++ { SMC_CLC_NONE, "[NONE]" }, ++ { SMC_CLC_BOTH, "[SMC-Dv2/SMC-R-Proposal]" }, ++ { 0, NULL } ++}; ++ ++static const value_string smc_clc_col_info_message_txt[] = { ++ { SMC_CLC_SMCR, "[SMC-R-Proposal]" }, ++ { SMC_CLC_SMCD, "[SMC-D-Proposal]" }, ++ { SMC_CLC_NONE, "[NONE]" }, ++ { SMC_CLC_BOTH, "[SMC-D/SMC-R-Proposal]" }, ++ { 0, NULL } ++}; + + static const value_string smcr_clc_message_txt[] = { + { SMC_CLC_PROPOSAL, "Proposal" }, +@@ -104,22 +161,35 @@ static const value_string smcr_llc_message_txt[] = { + { 0, NULL } + }; + +-static int proto_smcr = -1; ++static int proto_smc = -1; + static int ett_smcr = -1; + static int hf_smcr_clc_msg = -1; + static int hf_smcr_llc_msg = -1; + +-/* SMC-R Proposal */ ++/* SMC Proposal for both SMC-D and SMC-R */ + static int ett_proposal_flag = -1; ++static int ett_proposal_ext_flag2 = -1; ++static int hf_proposal_smc_version_release_number = -1; ++static int hf_proposal_smc_version_seid = -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; ++static int hf_proposal_smc_type = -1; ++static int hf_proposal_smc_v2_type = -1; ++static int hf_smc_length = -1; ++static int hf_smc_proposal_smc_chid = -1; ++static int hf_smc_proposal_flags = -1; ++static int hf_smc_proposal_eid = -1; ++static int hf_smc_proposal_system_eid = -1; ++static int hf_smc_proposal_ext_flags = -1; ++static int hf_smc_proposal_client_peer_id = -1; ++static int hf_smc_proposal_ism_gid = -1; ++static int hf_smc_proposal_client_preferred_gid = -1; ++static int hf_smc_proposal_client_preferred_mac = -1; ++static int hf_smc_proposal_outgoing_interface_subnet_mask = -1; ++static int hf_smc_proposal_rocev2_gid_ipv4_addr = -1; ++static int hf_smc_proposal_rocev2_gid_ipv6_addr = -1; ++static int hf_smc_proposal_outgoing_subnet_mask_signifcant_bits = -1; ++static int hf_smc_proposal_ipv6_prefix = -1; ++static int hf_smc_proposal_ipv6_prefix_length = -1; + + /* SMC-R Accept */ + static int ett_accept_flag = -1; +@@ -158,10 +228,57 @@ static int hf_confirm_smc_version = -1; + static int hf_confirm_rmb_buffer_size = -1; + static int hf_confirm_qp_mtu_value = -1; + ++/* SMC-D Accept */ ++static int hf_accept_smc_type = -1; ++static int ett_smcd_accept_flag = -1; ++static int ett_smcd_accept_fce_flag = -1; ++static int ett_smcd_accept_flag2 = -1; ++static int hf_smcd_accept_smc_version = -1; ++static int hf_accept_os_type = -1; ++static int hf_accept_smc_version_release_number = -1; ++static int hf_smcd_accept_first_contact = -1; ++static int hf_accept_dmb_buffer_size = -1; ++static int hf_smcd_accept_flags = -1; ++static int hf_smcd_accept_fce_flags = -1; ++static int hf_smcd_accept_flags2 = -1; ++static int hf_smcd_accept_server_peer_id = -1; ++static int hf_smcd_accept_dmbe_conn_index = -1; ++static int hf_smcd_accept_dmb_token = -1; ++static int hf_smcd_accept_server_link_id = -1; ++static int hf_smcd_accept_smc_chid = -1; ++static int hf_smcd_accept_eid = -1; ++static int hf_smcd_accept_peer_name = -1; ++ ++/* SMC-D Confirm */ ++static int hf_confirm_smc_type = -1; ++static int ett_smcd_confirm_flag = -1; ++static int ett_smcd_confirm_fce_flag = -1; ++static int ett_smcd_confirm_flag2 = -1; ++static int hf_smcd_confirm_smc_version = -1; ++static int hf_confirm_os_type = -1; ++static int hf_smcd_confirm_flags = -1; ++static int hf_smcd_confirm_flags2 = -1; ++static int hf_smcd_confirm_first_contact = -1; ++static int hf_smcd_confirm_client_peer_id = -1; ++static int hf_smcd_confirm_dmb_token = -1; ++static int hf_smcd_confirm_dmbe_conn_index = -1; ++static int hf_smcd_confirm_client_link_id = -1; ++static int hf_confirm_smc_version_release_number = -1; ++static int hf_smcd_confirm_dmb_buffer_size = -1; ++static int hf_smcd_confirm_smc_chid = -1; ++static int hf_smcd_confirm_eid = -1; ++static int hf_smcd_confirm_peer_name = -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; ++static int ett_decline_flag = -1; ++static int ett_decline_flag2 = -1; ++static int hf_smc_decline_flags = -1; ++static int hf_smc_decline_flags2 = -1; ++static int hf_smc_decline_peer_id = -1; ++static int hf_smc_decline_diag_info = -1; ++static int hf_decline_os_type = -1; ++static int hf_decline_smc_version = -1; ++static int hf_decline_out_of_sync = -1; + + /* SMC-R Confirm Link*/ + static int ett_confirm_link_flag = -1; +@@ -256,55 +373,300 @@ 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 dissector_handle_t smc_tcp_handle; + + static void +-disect_smcr_proposal(tvbuff_t *tvb, proto_tree *tree) ++disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + { +- guint offset; +- guint16 mask_offset; +- guint8 ipv6_prefix_count; ++ guint offset, suboffset; ++ guint16 mask_offset, v2_ext_offset; ++ guint16 v2_ext_pos = 0, smcd_v2_ext_offset = 0; ++ guint16 smcd_v2_ext_pos = 0; ++ guint8 ipv6_prefix_count, smc_version; ++ guint8 smc_type, num_of_gids = 0, num_of_eids = 0; ++ guint8 smc_type_v1 = 0, smc_type_v2 = 0; ++ bool is_smc_v2, is_smcdv1, is_smcdv2; + 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_BIG_ENDIAN); ++ proto_tree_add_item(tree, hf_smc_length, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; ++ proposal_flag_item = proto_tree_add_item(tree, hf_smc_proposal_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + 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); ++ smc_version = tvb_get_guint8(tvb, offset); ++ smc_type = tvb_get_guint8(tvb, offset); ++ smc_version = ((smc_version >> 4) & 0x0F); ++ is_smc_v2 = (smc_version >= SMC_V2); ++ smc_type_v2 = ((smc_type >> 2) & 0x03); ++ smc_type_v1 = (smc_type & 0x03); ++ is_smcdv1 = ((smc_type_v1 == SMC_CLC_SMCD) || (smc_type_v1 == SMC_CLC_BOTH)); ++ is_smcdv2 = ((smc_type_v2 == SMC_CLC_SMCD) || (smc_type_v2 == SMC_CLC_BOTH)); ++ ++ if (is_smc_v2) ++ proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_v2_type, tvb, ++ offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ ++ proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_type, 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, ++ proto_tree_add_item(tree, hf_smc_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, ++ proto_tree_add_item(tree, hf_smc_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, ++ proto_tree_add_item(tree, hf_smc_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); ++ ++ if (mask_offset != 0) { ++ suboffset = offset; ++ suboffset += TWO_BYTE_RESERVED; ++ if (is_smcdv1 || is_smcdv2) { ++ proto_tree_add_item(tree, hf_smc_proposal_ism_gid, tvb, ++ suboffset, ISM_GID_LEN, ENC_NA); ++ } ++ suboffset += ISM_GID_LEN; ++ if (is_smc_v2) { ++ if (is_smcdv2) { ++ proto_tree_add_item(tree, hf_smc_proposal_smc_chid, tvb, suboffset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ } ++ suboffset += LENGTH_BYTE_LEN; ++ v2_ext_offset = tvb_get_ntohs(tvb, suboffset); ++ v2_ext_pos = suboffset + TWO_BYTE_RESERVED + v2_ext_offset; ++ } ++ } ++ offset += TWO_BYTE_RESERVED + mask_offset; ++ ++ proto_tree_add_item(tree, hf_smc_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); ++ proto_tree_add_item(tree, hf_smc_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; ++ offset += 1; + + while (ipv6_prefix_count != 0) { +- proto_tree_add_item(tree, hf_smcr_proposal_ipv6_prefix, tvb, ++ proto_tree_add_item(tree, hf_smc_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, ++ proto_tree_add_item(tree, hf_smc_proposal_ipv6_prefix_length, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; + ipv6_prefix_count--; + } ++ ++ if (v2_ext_pos >= offset) { ++ offset = v2_ext_pos; ++ num_of_eids = tvb_get_guint8(tvb, offset); ++ offset += FLAG_BYTE_LEN; ++ num_of_gids = tvb_get_guint8(tvb, offset); ++ offset += FLAG_BYTE_LEN; ++ /*Skip reserved flag 1*/ ++ offset += 1; ++ proposal_flag_item = proto_tree_add_item(tree, hf_smc_proposal_ext_flags, tvb, ++ offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proposal_flag_tree = proto_item_add_subtree(proposal_flag_item, ett_proposal_ext_flag2); ++ proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_version_release_number, ++ tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_version_seid, tvb, ++ offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += FLAG_BYTE_LEN; ++ /*Skip not used 2 bytes*/ ++ offset += 2; ++ smcd_v2_ext_offset = tvb_get_ntohs(tvb, offset); ++ offset += 2; ++ smcd_v2_ext_pos = offset + smcd_v2_ext_offset; ++ ++ if (is_ipv6) { ++ proto_tree_add_item(tree, hf_smc_proposal_rocev2_gid_ipv6_addr, tvb, ++ offset, GID_LEN, ENC_NA); ++ offset += GID_LEN; ++ } ++ else { ++ offset += 12; ++ proto_tree_add_item(tree, hf_smc_proposal_rocev2_gid_ipv4_addr, tvb, ++ offset, IPV4_SUBNET_MASK_LEN, ENC_BIG_ENDIAN); ++ offset += IPV4_SUBNET_MASK_LEN; ++ } ++ /*Skip reserved 16 bytes*/ ++ offset += 16; ++ while (num_of_eids != 0) { ++ proto_tree_add_item(tree, hf_smc_proposal_eid, tvb, ++ offset, EID_LEN, ENC_ASCII | ENC_NA); ++ offset += EID_LEN; ++ num_of_eids--; ++ } ++ if (smcd_v2_ext_pos >= offset) { ++ offset = smcd_v2_ext_pos; ++ proto_tree_add_item(tree, hf_smc_proposal_system_eid, tvb, ++ offset, EID_LEN, ENC_ASCII | ENC_NA); ++ offset += EID_LEN; ++ /*Skip reserved 16 bytes*/ ++ offset += 16; ++ while (num_of_gids != 0) { ++ proto_tree_add_item(tree, hf_smc_proposal_ism_gid, tvb, ++ offset, ISM_GID_LEN, ENC_NA); ++ offset += ISM_GID_LEN; ++ proto_tree_add_item(tree, hf_smc_proposal_smc_chid, tvb, offset, ++ ISM_CHID_LEN, ENC_BIG_ENDIAN); ++ offset += ISM_CHID_LEN; ++ num_of_gids--; ++ } ++ } ++ ++ } ++} ++ ++static void ++disect_smcd_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; ++ guint8 smc_version, first_contact = 0; ++ ++ offset = CLC_MSG_START_OFFSET; ++ proto_tree_add_item(tree, hf_smc_length, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; ++ accept_flag_item = proto_tree_add_item(tree, hf_smcd_accept_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_smcd_accept_flag); ++ proto_tree_add_item(accept_flag_tree, hf_smcd_accept_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(accept_flag_tree, hf_smcd_accept_first_contact, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(accept_flag_tree, hf_accept_smc_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ smc_version = tvb_get_guint8(tvb, offset); ++ first_contact = tvb_get_guint8(tvb, offset); ++ smc_version = ((smc_version >> 4) & 0x0F); ++ first_contact = ((first_contact >> 3) & 0x01); ++ offset += FLAG_BYTE_LEN; ++ proto_tree_add_item(tree, hf_smcd_accept_server_peer_id, tvb, offset, ++ PEERID_LEN, ENC_BIG_ENDIAN); ++ offset += PEERID_LEN; ++ ++ proto_tree_add_item(tree, hf_smcd_accept_dmb_token, tvb, ++ offset, DMB_TOKEN_LEN, ENC_NA); ++ offset += DMB_TOKEN_LEN; ++ ++ proto_tree_add_item(tree, hf_smcd_accept_dmbe_conn_index, tvb, ++ offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN); ++ offset += CONN_INDEX_LEN; ++ ++ accept_flag2_item = proto_tree_add_item(tree, hf_smcd_accept_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ accept_flag2_tree = proto_item_add_subtree(accept_flag2_item, ett_smcd_accept_flag2); ++ proto_tree_add_item(accept_flag2_tree, hf_accept_dmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += FLAG_BYTE_LEN; ++ offset += TWO_BYTE_RESERVED; ++ proto_tree_add_item(tree, hf_smcd_accept_server_link_id, tvb, ++ offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN); ++ offset += ALERT_TOKEN_LEN; ++ ++ if (smc_version >= SMC_V2) { ++ proto_tree_add_item(tree, hf_smcd_accept_smc_chid, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; ++ ++ proto_tree_add_item(tree, hf_smcd_accept_eid, tvb, offset, 32, ENC_ASCII | ENC_NA); ++ offset += 32; ++ /* Reserved bytes */ ++ offset += 8; ++ ++ if (first_contact) { ++ offset += ONE_BYTE_RESERVED; ++ accept_flag_item = proto_tree_add_item(tree, hf_smcd_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_smcd_accept_fce_flag); ++ proto_tree_add_item(accept_flag_tree, hf_accept_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(accept_flag_tree, hf_accept_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += FLAG_BYTE_LEN; ++ offset += TWO_BYTE_RESERVED; ++ proto_tree_add_item(tree, hf_smcd_accept_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA); ++ /* offset += 32; */ ++ } ++ } ++} ++ ++static void ++disect_smcd_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; ++ guint8 smc_version, first_contact = 0; ++ ++ offset = CLC_MSG_START_OFFSET; ++ proto_tree_add_item(tree, hf_smc_length, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; ++ confirm_flag_item = proto_tree_add_item(tree, hf_smcd_confirm_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_smcd_confirm_flag); ++ proto_tree_add_item(confirm_flag_tree, hf_smcd_confirm_smc_version, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(confirm_flag_tree, hf_smcd_confirm_first_contact, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ smc_version = tvb_get_guint8(tvb, offset); ++ first_contact = tvb_get_guint8(tvb, offset); ++ smc_version = ((smc_version >> 4) & 0x0F); ++ first_contact = ((first_contact >> 3) & 0x01); ++ offset += FLAG_BYTE_LEN; ++ proto_tree_add_item(tree, hf_smcd_confirm_client_peer_id, tvb, offset, ++ PEERID_LEN, ENC_BIG_ENDIAN); ++ offset += PEERID_LEN; ++ ++ proto_tree_add_item(tree, hf_smcd_confirm_dmb_token, tvb, ++ offset, DMB_TOKEN_LEN, ENC_NA); ++ offset += DMB_TOKEN_LEN; ++ ++ proto_tree_add_item(tree, hf_smcd_confirm_dmbe_conn_index, tvb, ++ offset, CONN_INDEX_LEN, ENC_BIG_ENDIAN); ++ offset += CONN_INDEX_LEN; ++ ++ confirm_flag2_item = proto_tree_add_item(tree, hf_smcd_confirm_flags2, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ confirm_flag2_tree = proto_item_add_subtree(confirm_flag2_item, ett_smcd_confirm_flag2); ++ proto_tree_add_item(confirm_flag2_tree, hf_smcd_confirm_dmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += FLAG_BYTE_LEN; ++ offset += TWO_BYTE_RESERVED; ++ proto_tree_add_item(tree, hf_smcd_confirm_client_link_id, tvb, ++ offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN); ++ offset += ALERT_TOKEN_LEN; ++ ++ if (smc_version >= SMC_V2) { ++ proto_tree_add_item(tree, hf_smcd_confirm_smc_chid, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; ++ ++ proto_tree_add_item(tree, hf_smcd_confirm_eid, tvb, offset, 32, ENC_ASCII | ENC_NA); ++ offset += 32; ++ /* Reserved bytes */ ++ offset += 8; ++ ++ if (first_contact) { ++ offset += ONE_BYTE_RESERVED; ++ confirm_flag_item = proto_tree_add_item(tree, hf_smcd_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_smcd_confirm_fce_flag); ++ proto_tree_add_item(confirm_flag_tree, hf_confirm_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += FLAG_BYTE_LEN; ++ offset += TWO_BYTE_RESERVED; ++ proto_tree_add_item(tree, hf_smcd_confirm_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA); ++ /* offset += 32; */ ++ } ++ } + } + ++ + static void + disect_smcr_accept(tvbuff_t *tvb, proto_tree *tree) + { +@@ -315,6 +677,9 @@ disect_smcr_accept(tvbuff_t *tvb, proto_tree *tree) + proto_tree *accept_flag2_tree; + + offset = CLC_MSG_START_OFFSET; ++ proto_tree_add_item(tree, hf_smc_length, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; + accept_flag_item = proto_tree_add_item(tree, hf_smcr_accept_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + 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); +@@ -367,6 +732,9 @@ disect_smcr_confirm(tvbuff_t *tvb, proto_tree *tree) + proto_tree *confirm_flag2_tree; + + offset = CLC_MSG_START_OFFSET; ++ proto_tree_add_item(tree, hf_smc_length, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; + confirm_flag_item = proto_tree_add_item(tree, hf_smcr_confirm_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + 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); +@@ -411,17 +779,41 @@ disect_smcr_confirm(tvbuff_t *tvb, proto_tree *tree) + static void + disect_smcr_decline(tvbuff_t *tvb, proto_tree *tree) + { +- guint offset; ++ proto_item* decline_flag_item; ++ proto_tree* decline_flag_tree; ++ proto_item* decline_flag2_item; ++ proto_tree* decline_flag2_tree; ++ guint offset, smc_version; + + offset = CLC_MSG_START_OFFSET; +- proto_tree_add_item(tree, hf_smcr_decline_flags, tvb, offset, ++ proto_tree_add_item(tree, hf_smc_length, tvb, offset, ++ LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); ++ offset += LENGTH_BYTE_LEN; ++ ++ decline_flag_item = proto_tree_add_item(tree, hf_smc_decline_flags, tvb, offset, ++ FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ decline_flag_tree = proto_item_add_subtree(decline_flag_item, ett_decline_flag); ++ proto_tree_add_item(decline_flag_tree, hf_decline_smc_version, tvb, offset, ++ FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ proto_tree_add_item(decline_flag_tree, hf_decline_out_of_sync, tvb, offset, + FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ smc_version = tvb_get_guint8(tvb, offset); ++ smc_version = ((smc_version >> 4) & 0x0F); ++ + offset += FLAG_BYTE_LEN; +- proto_tree_add_item(tree, hf_smcr_decline_peer_id, tvb, offset, ++ proto_tree_add_item(tree, hf_smc_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); ++ proto_tree_add_item(tree, hf_smc_decline_diag_info, tvb, offset, ++ DIAG_INFO_LEN, ENC_BIG_ENDIAN); ++ offset += DIAG_INFO_LEN; ++ if (smc_version >= SMC_V2) { ++ decline_flag2_item = proto_tree_add_item(tree, hf_smc_decline_flags2, tvb, offset, ++ FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ decline_flag2_tree = proto_item_add_subtree(decline_flag2_item, ett_decline_flag2); ++ proto_tree_add_item(decline_flag2_tree, hf_decline_os_type, tvb, offset, ++ FLAG_BYTE_LEN, ENC_BIG_ENDIAN); ++ } + } + + static void +@@ -730,50 +1122,126 @@ disect_smcr_rmbe_ctrl(tvbuff_t *tvb, proto_tree *tree) + tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + } + ++static guint8 get_mixed_type(guint8 v1_type, guint8 v2_type) ++{ ++ if (v1_type == SMC_CLC_BOTH) ++ return v1_type; ++ ++ if (v1_type == SMC_CLC_NONE) ++ return v2_type; ++ ++ if (((v2_type == SMC_CLC_SMCD) && (v1_type == SMC_CLC_SMCR)) || ++ ((v2_type == SMC_CLC_SMCR) && (v1_type == SMC_CLC_SMCD))) ++ return SMC_CLC_BOTH; ++ ++ return v2_type; ++} ++ + static int +-dissect_smcr_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ++dissect_smc_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data _U_) + { + gint offset; + guint16 msg_len; ++ guint8 smc_type, smc_v2_type = 0, smc_v1_type = 0, smc_version = 0; ++ guint8 mixed_type; + clc_message clc_msgid; + proto_item *ti; +- proto_tree *smcr_tree; ++ proto_tree *smc_tree; ++ bool is_ipv6, is_smc_v2, is_smcd = false; + +- 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")); ++ clc_msgid = (clc_message)tvb_get_guint8(tvb, offset); + +- if ((clc_msgid == SMC_CLC_ACCEPT) || +- (clc_msgid == SMC_CLC_CONFIRMATION)) { ++ smc_version = tvb_get_guint8(tvb, offset + 3); ++ smc_version = ((smc_version >> 4) & 0x0F); ++ smc_type = tvb_get_guint8(tvb, offset + 3); ++ is_smc_v2 = (smc_version >= SMC_V2); ++ ++ if (is_smc_v2 && (clc_msgid == SMC_CLC_PROPOSAL)) { ++ smc_v1_type = (smc_type & 0x03); ++ smc_v2_type = ((smc_type >> 2) & 0x03); ++ } ++ else if (clc_msgid != SMC_CLC_DECLINE) { ++ smc_v2_type = (smc_type & 0x03); ++ smc_v1_type = (smc_type & 0x03); ++ } ++ ++ is_ipv6 = (pinfo->src.type == AT_IPv6); ++ ++ if (is_smc_v2) ++ col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMCv2"); ++ else ++ col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMC"); ++ ++ if (clc_msgid == SMC_CLC_PROPOSAL) { ++ if (is_smc_v2 && (smc_v2_type != SMC_CLC_NONE)) { ++ mixed_type = get_mixed_type(smc_v1_type, smc_v2_type); ++ col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s,", ++ val_to_str_const((guint32)mixed_type, ++ smcv2_clc_col_info_message_txt, "Unknown Command")); ++ } else { ++ col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s,", ++ val_to_str_const((guint32)smc_v1_type, ++ smc_clc_col_info_message_txt, "Unknown Command")); ++ } ++ } else if ((smc_v2_type == SMC_CLC_SMCR) && ((clc_msgid == SMC_CLC_ACCEPT) || ++ (clc_msgid == SMC_CLC_CONFIRMATION))) { ++ col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-R-%s],", ++ val_to_str_const((guint32)clc_msgid, ++ smcr_clc_message_txt, "Unknown Command")); + col_append_fstr(pinfo->cinfo, COL_INFO, " QP=0x%06x", + tvb_get_ntoh24(tvb, ACCEPT_CONFIRM_QP_OFFSET)); + } ++ else if ((smc_v2_type == SMC_CLC_SMCD) && ((clc_msgid == SMC_CLC_ACCEPT) || ++ (clc_msgid == SMC_CLC_CONFIRMATION))) { ++ is_smcd = true; ++ if (is_smc_v2) ++ col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-Dv2-%s],", ++ val_to_str_const((guint32)clc_msgid, ++ smcr_clc_message_txt, "Unknown Command")); ++ else ++ col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-D-%s],", ++ val_to_str_const((guint32)clc_msgid, ++ smcr_clc_message_txt, "Unknown Command")); ++ } ++ else { ++ if (is_smc_v2) ++ col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMCv2-%s],", ++ val_to_str_const((guint32)clc_msgid, ++ smcr_clc_message_txt, "Unknown Command")); ++ else ++ col_prepend_fstr(pinfo->cinfo, COL_INFO, "[SMC-%s],", ++ val_to_str_const((guint32)clc_msgid, ++ smcr_clc_message_txt, "Unknown Command")); ++ } + + 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, ++ ti = proto_tree_add_item(tree, proto_smc, tvb, 0, msg_len, ENC_NA); ++ smc_tree = proto_item_add_subtree(ti, ett_smcr); ++ proto_tree_add_item(smc_tree, hf_smcr_clc_msg, tvb, offset, 1, + ENC_BIG_ENDIAN); +- + switch (clc_msgid) { + case SMC_CLC_PROPOSAL: +- disect_smcr_proposal(tvb, smcr_tree); ++ disect_smc_proposal(tvb, smc_tree, is_ipv6); + break; + case SMC_CLC_ACCEPT: +- disect_smcr_accept(tvb, smcr_tree); ++ if (is_smcd) ++ disect_smcd_accept(tvb, smc_tree); ++ else ++ disect_smcr_accept(tvb, smc_tree); + break; + case SMC_CLC_CONFIRMATION: +- disect_smcr_confirm(tvb, smcr_tree); ++ if (is_smcd) ++ disect_smcd_confirm(tvb, smc_tree); ++ else ++ disect_smcr_confirm(tvb, smc_tree); + break; + case SMC_CLC_DECLINE: +- disect_smcr_decline(tvb, smcr_tree); ++ disect_smcr_decline(tvb, smc_tree); + break; + default: + /* Unknown Command */ +@@ -802,7 +1270,7 @@ dissect_smcr_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi + (tvb_get_guint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP)) + col_append_str(pinfo->cinfo, COL_INFO, "(Resp)"); + +- ti = proto_tree_add_item(tree, proto_smcr, tvb, 0, msg_len, ENC_NA); ++ ti = proto_tree_add_item(tree, proto_smc, 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); +@@ -861,24 +1329,27 @@ get_smcr_pdu_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset, void *dat + } + + static int +-dissect_smcr_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ++dissect_smc_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); ++ tcp_dissect_pdus(tvb, pinfo, tree, TRUE, SMC_TCP_MIN_HEADER_LENGTH, ++ get_smcr_pdu_length, dissect_smc_tcp_pdu, data); + return tvb_reported_length(tvb); + } + + static gboolean +-dissect_smcr_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, ++dissect_smc_tcp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + void *data) + { + if (tvb_captured_length(tvb) < 4) { + return FALSE; + } + +- if (tvb_get_ntohl(tvb, CLC_MSG_BYTE_0) != SMCR_CLC_ID) return FALSE; +- dissect_smcr_tcp(tvb, pinfo, tree, data); ++ if ((tvb_get_ntohl(tvb, CLC_MSG_BYTE_0) != SMCR_CLC_ID) && ++ (tvb_get_ntohl(tvb, CLC_MSG_BYTE_0) != SMCD_CLC_ID)) ++ return FALSE; ++ ++ dissect_smc_tcp(tvb, pinfo, tree, data); + return TRUE; + } + +@@ -921,479 +1392,688 @@ proto_register_smcr(void) + /* Setup list of header fields */ + static hf_register_info hf[] = { + { &hf_smcr_clc_msg, { +- "CLC Message", "smcr.clc_msg", ++ "CLC Message", "smc.clc_msg", + FT_UINT8, BASE_DEC, VALS(smcr_clc_message_txt), 0x0, + NULL, HFILL}}, + + { &hf_smcr_llc_msg, { +- "LLC Message", "smcr.llc_msg", ++ "LLC Message", "smc.llc_msg", + FT_UINT8, BASE_DEC, VALS(smcr_llc_message_txt), 0x0, + NULL, HFILL}}, + ++ { &hf_proposal_smc_version_release_number, { ++ "SMC Version Release Number", "smc.proposal.smc.version.relnum", ++ FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }}, ++ ++ { &hf_proposal_smc_version_seid, { ++ "SEID Indicator", "smc.proposal.smc.seid", ++ FT_BOOLEAN, 8, NULL, 0x01, NULL, HFILL } }, ++ + { &hf_proposal_smc_version, { +- "SMC Version", "smcr.proposal.smc.version", ++ "SMC Version", "smc.proposal.smc.version", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, + ++ { &hf_proposal_smc_type, { ++ "SMC(v1) Type", "smc.proposal.smc.type", ++ FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt), ++ 0x03, NULL, HFILL}}, ++ ++ { &hf_accept_smc_type, { ++ "SMC Type", "smc.accept.smc.type", ++ FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt), ++ 0x03, NULL, HFILL}}, ++ ++ { &hf_confirm_smc_type, { ++ "SMC Type", "smc.confirm.smc.type", ++ FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt), ++ 0x03, NULL, HFILL}}, ++ ++ { &hf_proposal_smc_v2_type, { ++ "SMC(v2) Type", "smc.proposal.smcv2.type", ++ FT_UINT8, BASE_DEC, VALS(smc_clc_type_message_txt), ++ 0x0C, NULL, HFILL}}, ++ ++ { &hf_smc_proposal_smc_chid, { ++ "ISM CHID", "smc.proposal.smc.chid", ++ FT_UINT16, BASE_HEX, NULL, 0x00, NULL, HFILL}}, ++ ++ { &hf_smc_length, { ++ "SMC Length", "smc.length", ++ FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL}}, ++ + { &hf_accept_smc_version, { +- "SMC Version", "smcr.proposal.smc.version", ++ "SMC Version", "smc.proposal.smc.version", ++ FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, ++ ++ { &hf_smcd_accept_smc_version, { ++ "SMC Version", "smc.proposal.smc.version", ++ FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, ++ ++ { &hf_smcd_confirm_smc_version, { ++ "SMC Version", "smc.proposal.smc.version", + FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}}, + + { &hf_accept_first_contact, { +- "First Contact", "smcr.proposal.first.contact", ++ "First Contact", "smc.proposal.first.contact", + FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}}, + + { &hf_confirm_smc_version, { +- "SMC Version", "smcr.proposal.smc.version", ++ "SMC Version", "smc.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", ++ "smc.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", ++ "smc.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", ++ "smc.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", ++ "smc.confirm.qp.mtu.value", + FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}}, + +- { &hf_smcr_proposal_flags, { +- "Flags", "smcr.proposal.flags", ++ { &hf_smc_proposal_flags, { ++ "Flags", "smc.proposal.flags", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, ++ ++ { &hf_smc_proposal_ext_flags, { ++ "Flag 2", "smc.proposal.extflags.2", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_flags, { +- "Flags", "smcr.accept.flags", ++ "Flags", "smc.accept.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_flags2, { +- "Flags 2", "smcr.accept.flags.2", ++ "Flags 2", "smc.accept.flags.2", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_flags, { +- "Flags", "smcr.confirm.flags", ++ "Flags", "smc.confirm.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + +- { &hf_smcr_decline_flags, { +- "Flags", "smcr.decline.flags", ++ { &hf_decline_smc_version, { ++ "SMC Version", "smc.decline.smc.version", ++ FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL} }, ++ ++ { &hf_decline_out_of_sync, { ++ "Out of Sync", "smc.decline.osync", ++ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL} }, ++ ++ { &hf_smc_decline_flags2, { ++ "Flags 2", "smc.decline.flags2", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + ++ { &hf_smc_decline_flags, { ++ "Flags", "smc.decline.flags", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ + { &hf_smcr_confirm_flags2, { +- "Flags 2", "smcr.confirm.flags.2", ++ "Flags 2", "smc.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", ++ { &hf_smc_proposal_client_peer_id, { ++ "Sender (Client) Peer ID", "smc.proposal.sender.client.peer.id", ++ FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, ++ ++ { &hf_smc_proposal_ism_gid, { ++ "ISM GID", "smc.proposal.ism.gid", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + +- { &hf_smcr_proposal_client_preferred_gid, { +- "Client Preferred GID", "smcr.proposal.client.preferred.gid", ++ { &hf_smc_proposal_client_preferred_gid, { ++ "Client Preferred GID", "smc.proposal.client.preferred.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + +- { &hf_smcr_proposal_client_preferred_mac, { ++ { &hf_smc_proposal_client_preferred_mac, { + "Client Preferred MAC Address", +- "smcr.proposal.client.preferred.mac", ++ "smc.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", ++ "Sender (Server) Peer ID", "smc.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", ++ "Server Preferred GID", "smc.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", ++ "smc.accept.server.preferred.mac", + FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + +- { &hf_smcr_proposal_outgoing_interface_subnet_mask, { ++ { &hf_smc_proposal_rocev2_gid_ipv6_addr, { ++ "RoCEv2 GID IPv6 Address", ++ "smc.proposal.rocev2.gid.ipv6", ++ FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smc_proposal_rocev2_gid_ipv4_addr, { ++ "RoCEv2 GID IPv4 Address", ++ "smc.proposal.rocev2.gid.ipv4", ++ FT_IPv4, BASE_NETMASK, NULL, 0x0, NULL, HFILL}}, ++ ++ { &hf_smc_proposal_outgoing_interface_subnet_mask, { + "Outgoing Interface Subnet Mask", +- "smcr.outgoing.interface.subnet.mask", ++ "smc.outgoing.interface.subnet.mask", + FT_IPv4, BASE_NETMASK, NULL, 0x0, NULL, HFILL}}, + +- { &hf_smcr_proposal_outgoing_subnet_mask_signifcant_bits, { ++ { &hf_smc_proposal_outgoing_subnet_mask_signifcant_bits, { + "Outgoing Interface Subnet Mask Number of Significant Bits", +- "smcr.outgoing.interface.subnet.mask.number.of.significant.bits", ++ "smc.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", ++ { &hf_smc_proposal_ipv6_prefix, { ++ "IPv6 Prefix Value","smc.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", ++ { &hf_smc_proposal_ipv6_prefix_length, { ++ "IPv6 Prefix Length", "smc.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", ++ "Server QP Number","smc.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", ++ "Server RMB Rkey","smc.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", ++ "smc.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", ++ "smc.accept.server.rmb.element.alert.token", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_server_rmb_virtual_address, { + "Server's RMB Virtual Address", +- "smcr.accept.server.rmb.virtual.address", ++ "smc.accept.server.rmb.virtual.address", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_accept_initial_psn, { +- "Initial PSN","smcr.accept.initial.psn", ++ "Initial PSN","smc.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", ++ "smc.confirm.sender.client.peer.id", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_gid, { +- "Client GID", "smcr.client.gid", ++ "Client GID", "smc.client.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_mac, { +- "Client MAC Address", "smcr.confirm.client.mac", ++ "Client MAC Address", "smc.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", ++ "Client QP Number","smc.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", ++ "Client RMB Rkey","smc.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", ++ "smc.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", ++ "smc.client.rmb.element.alert.token", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_client_rmb_virtual_address, { + "Client's RMB Virtual Address", +- "smcr.client.rmb.virtual.address", ++ "smc.client.rmb.virtual.address", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_initial_psn, { +- "Initial PSN","smcr.initial.psn", ++ "Initial PSN","smc.initial.psn", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + +- { &hf_smcr_decline_peer_id, { +- "Sender Peer ID", "smcr.sender.peer.id", ++ { &hf_smc_decline_peer_id, { ++ "Sender Peer ID", "smc.sender.peer.id", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + +- { &hf_smcr_decline_diag_info, { +- "Peer Diagnosis Information", "smcr.peer.diag.info", ++ { &hf_smc_decline_diag_info, { ++ "Peer Diagnosis Information", "smc.peer.diag.info", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + ++ { &hf_decline_os_type, { ++ "OS Type", "smc.decline.os.type", ++ FT_UINT8, BASE_DEC, VALS(smc_clc_os_message_txt), 0xF0, NULL, HFILL} }, ++ + { &hf_smcr_confirm_link_gid, { +- "Sender GID", "smcr.sender.gid", ++ "Sender GID", "smc.sender.gid", + FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_mac, { +- "Sender MAC Address", "smcr.confirm.link.sender.mac", ++ "Sender MAC Address", "smc.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", ++ "Sender QP Number","smc.confirm.link.sender.qp.number", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_number, { +- "Link Number", "smcr.confirm.link.number", ++ "Link Number", "smc.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", ++ "smc.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", ++ "Max Links","smc.confirm.link.max.links", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_flags, { +- "Flags", "smcr.confirm.link.flags", ++ "Flags", "smc.confirm.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_link_response, { +- "Response", "smcr.confirm.link.response", ++ "Response", "smc.confirm.link.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_add_link_gid, { +- "Sender GID", "smcr.add.link.sender.gid", ++ "Sender GID", "smc.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", ++ "Sender MAC Address", "smc.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", ++ "Sender QP Number","smc.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", ++ "Link Number", "smc.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", ++ "Initial PSN", "smc.add.link.initial.psn", + FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_flags, { +- "Flags", "smcr.add.link.flags", ++ "Flags", "smc.add.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_response, { +- "Add Link Response", "smcr.add.link.response", ++ "Add Link Response", "smc.add.link.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_add_link_response_rejected, { +- "Add Link Rejected", "smcr.add.link.response.rejected", ++ "Add Link Rejected", "smc.add.link.response.rejected", + FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}}, + + { &hf_smcr_add_link_flags2, { +- "Flags", "smcr.add.link.flags2", ++ "Flags", "smc.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", ++ "QP MTU Value", "smc.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", ++ "Flags", "smc.add.link.cont.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_add_link_cont_response, { +- "Response", "smcr.add.link.cont.response", ++ "Response", "smc.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", ++ "Link Number", "smc.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", ++ "Number of Rkeys", "smc.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", ++ "smc.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", ++ "smc.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", ++ "smc.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", ++ "smc.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", ++ "smc.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", ++ "smc.add.link.cont.rmb.RTok1.virt", + FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_delete_link_flags, { +- "Flags", "smcr.delete.link.flags", ++ "Flags", "smc.delete.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_delete_link_response, { +- "Response", "smcr.delete.link.response", ++ "Response", "smc.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", ++ "smc.delete.link.all", + FT_BOOLEAN, 8, NULL, 0x40, NULL, HFILL}}, + + { &hf_smcr_delete_link_orderly, { +- "Terminate Links Orderly", "smcr.delete.link.orderly", ++ "Terminate Links Orderly", "smc.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", ++ "Link Number For The Failed Link", "smc.delete.link.number", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_delete_link_reason_code, { +- "Reason Code", "smcr.delete.link.reason.code", ++ "Reason Code", "smc.delete.link.reason.code", + FT_UINT32, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_flags, { +- "Flags", "smcr.confirm.rkey.flags", ++ "Flags", "smc.confirm.rkey.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_response, { +- "Response", "smcr.confirm.rkey.response", ++ "Response", "smc.confirm.rkey.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_confirm_rkey_negative_response, { +- "Negative Response", "smcr.confirm.rkey.negative.response", ++ "Negative Response", "smc.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", ++ "Retry Rkey Set", "smc.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", ++ "Number of other QP", "smc.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", ++ "New Rkey for this link","smc.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", ++ "smc.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", ++ "Link Number", "smc.confirm.rkey.link.number", + FT_UINT8, BASE_HEX, NULL, 0x00, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_flags, { +- "Flags", "smcr.delete.rkey.flags", ++ "Flags", "smc.delete.rkey.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_response, { +- "Response", "smcr.delete.rkey.response", ++ "Response", "smc.delete.rkey.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_negative_response, { +- "Negative Response", "smcr.delete.rkey.negative.response", ++ "Negative Response", "smc.delete.rkey.negative.response", + FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}}, + + { &hf_smcr_delete_rkey_mask, { +- "Error Mask", "smcr.delete.rkey.error.mask", ++ "Error Mask", "smc.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", ++ "RMB Rkey to be deleted", "smc.delete.rkey.deleted", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_test_link_flags, { +- "Flags", "smcr.test.link.flags", ++ "Flags", "smc.test.link.flags", + FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_test_link_response, { +- "Response", "smcr.test.link.response", ++ "Response", "smc.test.link.response", + FT_BOOLEAN, 8, NULL, 0x80, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_seqno, { +- "Sequence Number", "smcr.rmbe.ctrl.seqno", ++ "Sequence Number", "smc.rmbe.ctrl.seqno", + FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_alert_token, { +- "Alert Token", "smcr.rmbe.ctrl.alert.token", ++ "Alert Token", "smc.rmbe.ctrl.alert.token", + FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}}, + ++ { &hf_smc_proposal_eid, { ++ "EID", "smc.proposal.eid", ++ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smc_proposal_system_eid, { ++ "SEID", "smc.proposal.system.eid", ++ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} }, ++ + { &hf_smcr_rmbe_ctrl_prod_wrap_seqno, { + "Producer window wrap sequence number", +- "smcr.rmbe.ctrl.prod.wrap.seq", ++ "smc.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", ++ "Peer Producer Cursor", "smc.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", ++ "smc.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", ++ "Peer Consumer Cursor", "smc.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", ++ "smc.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", ++ "Write Blocked", "smc.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", ++ "Urgent Data Pending", "smc.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", ++ "Urgent Data Present", "smc.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", ++ "smc.rmbe.ctrl.cons.update.requested", + FT_BOOLEAN, 8, NULL, 0x10, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_failover_validation, { + "Failover Validation Indicator", +- "smcr.rmbe.ctrl.failover.validation", ++ "smc.rmbe.ctrl.failover.validation", + FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL}}, + + { &hf_smcr_rmbe_ctrl_peer_conn_state_flags, { + "Peer Connection State Flags", +- "smcr.rmbe.ctrl.peer.conn.state.flags", ++ "smc.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", ++ "Peer Sending Done", "smc.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", ++ "Peer Closed Connection", "smc.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}} ++ "Peer Abnormal Close", "smc.rmbe.ctrl.peer.abnormal.close", ++ FT_BOOLEAN, 8, NULL, 0x20, NULL, HFILL}}, ++ ++ { &hf_smcd_accept_eid, { ++ "EID", "smc.accept.eid", ++ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_eid, { ++ "EID", "smc.confirm.eid", ++ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_peer_name, { ++ "Peer Host Name", "smc.accept.peer.host.name", ++ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_peer_name, { ++ "Peer Host Name", "smc.confirm.peer.host.name", ++ FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_first_contact, { ++ "First Contact", "smc.accept.first.contact", ++ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_first_contact, { ++ "First Contact", "smc.confirm.first.contact", ++ FT_BOOLEAN, 8, NULL, 0x08, NULL, HFILL} }, ++ ++ { &hf_accept_smc_version_release_number, { ++ "SMC Version Release Number", "smc.accept.smc.version.relnum", ++ FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL } }, ++ ++ { &hf_confirm_smc_version_release_number, { ++ "SMC Version Release Number", "smc.confirm.smc.version.relnum", ++ FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL } }, ++ ++ { &hf_accept_os_type, { ++ "OS Type", "smc.accept.os.type", ++ FT_UINT8, BASE_DEC, VALS(smc_clc_os_message_txt), 0xF0, NULL, HFILL} }, ++ ++ { &hf_confirm_os_type, { ++ "OS Type", "smc.confirm.os.type", ++ FT_UINT8, BASE_DEC, VALS(smc_clc_os_message_txt), 0xF0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_dmb_token, { ++ "DMB Token", "smc.accept.dmb.token", ++ FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_dmb_token, { ++ "DMB Token", "smc.confirm.dmb.token", ++ FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_accept_dmb_buffer_size, { ++ "Server DMBE Buffers Size (Compressed Notation)", ++ "smc.accept.dmbe.buffer.size", ++ FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_dmb_buffer_size, { ++ "Client DMBE Buffers Size (Compressed Notation)", ++ "smc.confirm.dmbe.buffer.size", ++ FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_smc_chid, { ++ "ISM CHID", "smc.accept.smc.chid", ++ FT_UINT16, BASE_HEX, NULL, 0x00, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_smc_chid, { ++ "ISM CHID", "smc.confirm.smc.chid", ++ FT_UINT16, BASE_HEX, NULL, 0x00, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_server_peer_id, { ++ "Sender (Server) ISM GID", "smc.accept.sender.server.ism.gid", ++ FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_client_peer_id, { ++ "Sender (Client) ISM GID", "smc.confirm.sender.client.ism.gid", ++ FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_dmbe_conn_index, { ++ "DMBE Connection Index", ++ "smc.accept.dmbe.conn.index", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_server_link_id, { ++ "Server Link ID", ++ "smc.accept.server.linkid", ++ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_dmbe_conn_index, { ++ "DMBE Connection Index", ++ "smc.confirm.dmbe.conn.index", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_client_link_id, { ++ "Client Link ID", ++ "smc.confirm.client.linkid", ++ FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_flags, { ++ "Flags", "smc.accept.flags", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_flags, { ++ "Flags", "smc.confirm.flags", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_flags2, { ++ "DMBE Size", "smc.accept.dmbe.size", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_confirm_flags2, { ++ "DMBE Size", "smc.confirm.dmbe.size", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smcd_accept_fce_flags, { ++ "Flags", "smc.accept.fce.flags", ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} } + }; + + /* Setup protocol subtree arrays */ +- static gint *ett[] = { ++ static gint* ett[] = { + &ett_smcr, + &ett_proposal_flag, ++ &ett_proposal_ext_flag2, + &ett_accept_flag, + &ett_accept_flag2, ++ &ett_smcd_accept_flag, ++ &ett_smcd_accept_flag2, ++ &ett_smcd_accept_fce_flag, ++ &ett_smcd_confirm_flag, ++ &ett_smcd_confirm_fce_flag, ++ &ett_smcd_confirm_flag2, + &ett_confirm_flag, + &ett_confirm_flag2, + &ett_confirm_link_flag, ++ &ett_decline_flag, ++ &ett_decline_flag2, + &ett_add_link_flag, + &ett_add_link_flag2, + &ett_add_link_cont_flag, +@@ -1405,21 +2085,21 @@ proto_register_smcr(void) + &ett_rmbe_ctrl_peer_conn_state_flag + }; + +- proto_smcr = proto_register_protocol("Shared Memory Communications - RDMA", +- "SMCR", "smcr"); ++ proto_smc = proto_register_protocol("Shared Memory Communications", ++ "SMC", "smc"); + +- proto_register_field_array(proto_smcr, hf, array_length(hf)); ++ proto_register_field_array(proto_smc, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + +- smcr_tcp_handle = register_dissector("smcr", dissect_smcr_tcp, proto_smcr); ++ smc_tcp_handle = register_dissector("smc", dissect_smc_tcp, proto_smc); + } + + void + proto_reg_handoff_smcr(void) + { +- heur_dissector_add("tcp", dissect_smcr_tcp_heur, "Shared Memory Communications over TCP", "smcr_tcp", proto_smcr, HEURISTIC_ENABLE); +- heur_dissector_add("infiniband.payload", dissect_smcr_infiniband_heur, "Shared Memory Communications Infiniband", "smcr_infiniband", proto_smcr, HEURISTIC_ENABLE); +- dissector_add_for_decode_as("infiniband", create_dissector_handle( dissect_smcr_infiniband, proto_smcr ) ); ++ heur_dissector_add("tcp", dissect_smc_tcp_heur, "Shared Memory Communications over TCP", "smc_tcp", proto_smc, HEURISTIC_ENABLE); ++ heur_dissector_add("infiniband.payload", dissect_smcr_infiniband_heur, "Shared Memory Communications Infiniband", "smcr_infiniband", proto_smc, HEURISTIC_ENABLE); ++ dissector_add_for_decode_as("infiniband", create_dissector_handle( dissect_smcr_infiniband, proto_smc ) ); + } + + /* +diff --git a/epan/dissectors/packet-smc.c b/epan/dissectors/packet-smc.c +index 0a4e96e055..6ede4690db 100644 +--- a/epan/dissectors/packet-smc.c ++++ b/epan/dissectors/packet-smc.c +@@ -1,3 +1,6 @@ ++ ++ ++ + /* packet-smc.c + * SMC dissector for wireshark + * By Joe Fowler +@@ -191,6 +194,8 @@ static int hf_smc_proposal_outgoing_subnet_mask_signifcant_bits = -1; + static int hf_smc_proposal_ipv6_prefix = -1; + static int hf_smc_proposal_ipv6_prefix_length = -1; + ++static int hf_smc_reserved = -1; ++ + /* SMC-R Accept */ + static int ett_accept_flag = -1; + static int ett_accept_flag2 = -1; +@@ -427,6 +432,8 @@ disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + + if (mask_offset != 0) { + suboffset = offset; ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ suboffset, TWO_BYTE_RESERVED, ENC_NA); + suboffset += TWO_BYTE_RESERVED; + if (is_smcdv1 || is_smcdv2) { + proto_tree_add_item(tree, hf_smc_proposal_ism_gid, tvb, +@@ -439,6 +446,8 @@ disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + LENGTH_BYTE_LEN, ENC_BIG_ENDIAN); + } + suboffset += LENGTH_BYTE_LEN; ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ suboffset, TWO_BYTE_RESERVED, ENC_NA); + v2_ext_offset = tvb_get_ntohs(tvb, suboffset); + v2_ext_pos = suboffset + TWO_BYTE_RESERVED + v2_ext_offset; + } +@@ -451,7 +460,8 @@ disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + proto_tree_add_item(tree, hf_smc_proposal_outgoing_subnet_mask_signifcant_bits, tvb, + offset, 1, ENC_BIG_ENDIAN); + offset += 1; +- /* Bump past reserved bytes */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, TWO_BYTE_RESERVED, ENC_NA); + offset += TWO_BYTE_RESERVED; + ipv6_prefix_count = tvb_get_guint8(tvb, offset); + offset += 1; +@@ -472,7 +482,8 @@ disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + offset += FLAG_BYTE_LEN; + num_of_gids = tvb_get_guint8(tvb, offset); + offset += FLAG_BYTE_LEN; +- /*Skip reserved flag 1*/ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, 1, ENC_NA); + offset += 1; + proposal_flag_item = proto_tree_add_item(tree, hf_smc_proposal_ext_flags, tvb, + offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); +@@ -482,7 +493,8 @@ disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + proto_tree_add_item(proposal_flag_tree, hf_proposal_smc_version_seid, tvb, + offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; +- /*Skip not used 2 bytes*/ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, 2, ENC_NA); + offset += 2; + smcd_v2_ext_offset = tvb_get_ntohs(tvb, offset); + offset += 2; +@@ -499,7 +511,8 @@ disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + offset, IPV4_SUBNET_MASK_LEN, ENC_BIG_ENDIAN); + offset += IPV4_SUBNET_MASK_LEN; + } +- /*Skip reserved 16 bytes*/ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, 16, ENC_NA); + offset += 16; + while (num_of_eids != 0) { + proto_tree_add_item(tree, hf_smc_proposal_eid, tvb, +@@ -512,7 +525,8 @@ disect_smc_proposal(tvbuff_t *tvb, proto_tree *tree, bool is_ipv6) + proto_tree_add_item(tree, hf_smc_proposal_system_eid, tvb, + offset, EID_LEN, ENC_ASCII | ENC_NA); + offset += EID_LEN; +- /*Skip reserved 16 bytes*/ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, 16, ENC_NA); + offset += 16; + while (num_of_gids != 0) { + proto_tree_add_item(tree, hf_smc_proposal_ism_gid, tvb, +@@ -580,16 +594,21 @@ disect_smcd_accept(tvbuff_t* tvb, proto_tree* tree) + + proto_tree_add_item(tree, hf_smcd_accept_eid, tvb, offset, 32, ENC_ASCII | ENC_NA); + offset += 32; +- /* Reserved bytes */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, 8, ENC_NA); + offset += 8; + + if (first_contact) { ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, ONE_BYTE_RESERVED, ENC_NA); + offset += ONE_BYTE_RESERVED; + accept_flag_item = proto_tree_add_item(tree, hf_smcd_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + accept_flag_tree = proto_item_add_subtree(accept_flag_item, ett_smcd_accept_fce_flag); + proto_tree_add_item(accept_flag_tree, hf_accept_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(accept_flag_tree, hf_accept_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, TWO_BYTE_RESERVED, ENC_NA); + offset += TWO_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcd_accept_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA); + /* offset += 32; */ +@@ -637,6 +656,8 @@ disect_smcd_confirm(tvbuff_t* tvb, proto_tree* tree) + confirm_flag2_tree = proto_item_add_subtree(confirm_flag2_item, ett_smcd_confirm_flag2); + proto_tree_add_item(confirm_flag2_tree, hf_smcd_confirm_dmb_buffer_size, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, ONE_BYTE_RESERVED, ENC_NA); + offset += TWO_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcd_confirm_client_link_id, tvb, + offset, ALERT_TOKEN_LEN, ENC_BIG_ENDIAN); +@@ -649,16 +670,21 @@ disect_smcd_confirm(tvbuff_t* tvb, proto_tree* tree) + + proto_tree_add_item(tree, hf_smcd_confirm_eid, tvb, offset, 32, ENC_ASCII | ENC_NA); + offset += 32; +- /* Reserved bytes */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, 8, ENC_NA); + offset += 8; + + if (first_contact) { ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, ONE_BYTE_RESERVED, ENC_NA); + offset += ONE_BYTE_RESERVED; + confirm_flag_item = proto_tree_add_item(tree, hf_smcd_accept_fce_flags, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + confirm_flag_tree = proto_item_add_subtree(confirm_flag_item, ett_smcd_confirm_fce_flag); + proto_tree_add_item(confirm_flag_tree, hf_confirm_os_type, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + proto_tree_add_item(confirm_flag_tree, hf_confirm_smc_version_release_number, tvb, offset, FLAG_BYTE_LEN, ENC_BIG_ENDIAN); + offset += FLAG_BYTE_LEN; ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, TWO_BYTE_RESERVED, ENC_NA); + offset += TWO_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcd_confirm_peer_name, tvb, offset, 32, ENC_ASCII | ENC_NA); + /* offset += 32; */ +@@ -711,12 +737,14 @@ disect_smcr_accept(tvbuff_t *tvb, proto_tree *tree) + 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 */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, ONE_BYTE_RESERVED, ENC_NA); + 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 */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, ONE_BYTE_RESERVED, ENC_NA); + offset += ONE_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_accept_initial_psn, tvb, + offset, PSN_LEN, ENC_BIG_ENDIAN); +@@ -765,12 +793,14 @@ disect_smcr_confirm(tvbuff_t *tvb, proto_tree *tree) + 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 */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, ONE_BYTE_RESERVED, ENC_NA); + 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 */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, ONE_BYTE_RESERVED, ENC_NA); + offset += ONE_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_confirm_initial_psn, tvb, + offset, PSN_LEN, ENC_BIG_ENDIAN); +@@ -866,7 +896,8 @@ disect_smcr_add_link(tvbuff_t *tvb, proto_tree *tree) + 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 */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, ++ offset, TWO_BYTE_RESERVED, ENC_NA); + offset += TWO_BYTE_RESERVED; + proto_tree_add_item(tree, hf_smcr_add_link_gid, tvb, + offset, GID_LEN, ENC_NA); +@@ -1084,12 +1115,13 @@ disect_smcr_rmbe_ctrl(tvbuff_t *tvb, proto_tree *tree) + 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; ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA); + 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 */ ++ proto_tree_add_item(tree, hf_smc_reserved, tvb, offset, TWO_BYTE_RESERVED, ENC_NA); + 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; +@@ -2053,7 +2085,11 @@ proto_register_smcr(void) + + { &hf_smcd_accept_fce_flags, { + "Flags", "smc.accept.fce.flags", +- FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} } ++ FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL} }, ++ ++ { &hf_smc_reserved, { ++ "Reserved", "smc.reserved", ++ FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL} } + }; + + /* Setup protocol subtree arrays */ diff --git a/SPECS/wireshark.spec b/SPECS/wireshark.spec index 50544c7..2f362ae 100644 --- a/SPECS/wireshark.spec +++ b/SPECS/wireshark.spec @@ -6,7 +6,7 @@ Summary: Network traffic analyzer Name: wireshark Version: 2.6.2 -Release: 12%{?dist} +Release: 14%{?dist} Epoch: 1 License: GPL+ Url: http://www.wireshark.org/ @@ -58,6 +58,8 @@ Patch23: wireshark-0023-desktop-file.patch Patch24: wireshark-0024-covscan.patch Patch25: wireshark-0025-drop-count.patch +Patch26: wireshark-0026-mptcp.patch +Patch27: wireshark-0027-ibm-smc.patch #install tshark together with wireshark GUI Requires: %{name}-cli = %{epoch}:%{version}-%{release} @@ -306,6 +308,12 @@ getent group usbmon >/dev/null || groupadd -r usbmon %{_libdir}/pkgconfig/%{name}.pc %changelog +* Mon Apr 19 2021 Michal Ruprich - 1:2.6.2-14 +- Resolves: #1851465 - [IBM 8.5 FEAT] wireshark: Update to include SMC support + +* Tue Apr 13 2021 Michal Ruprich - 1:2.6.2-13 +- Resolves: #1934617 - [RFE] better MPTCP dissection support + * Tue Oct 29 2019 Michal Ruprich - 1:2.6.2-12 - Resolves: #1609737 - wiretap does not write "drop_count" in pcapng format