aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-12-20 08:58:49 -0500
committerMichael Mann <mmann78@netscape.net>2016-12-20 22:15:56 +0000
commit4c50e4b5c4d794de3944c05bd8ce3ed778a13443 (patch)
treeec28f762587eaa271956de1ff98eb69137ecce74 /epan
parentcaadaaf62317a88f99373d9095b827102999e4e3 (diff)
Improve Infiniband heuristic subdissection.
Add preference in Infiniband dissector to distinguish between heuristic and non-heuristic dissection (that uses Decode As). Remove all of the preferences in the Infiniband subdissectors that tried to put in "manual" heuristics and direct users to just use Decode As. Most subdissectors still kept some basic heuristics in their heuristic functions, but now also register with the Infiniband dissector table for "manually" forcing dissection with Decode As. Ping-Bug: 13259 Change-Id: I20d56eee38887664b439e52ec5f5b8f962c45ef1 Reviewed-on: https://code.wireshark.org/review/19362 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-fcoib.c198
-rw-r--r--epan/dissectors/packet-infiniband.c55
-rw-r--r--epan/dissectors/packet-infiniband_sdp.c208
-rw-r--r--epan/dissectors/packet-iser.c142
-rw-r--r--epan/dissectors/packet-rpcrdma.c27
-rw-r--r--epan/dissectors/packet-smb-direct.c32
-rw-r--r--epan/dissectors/packet-smcr.c13
7 files changed, 257 insertions, 418 deletions
diff --git a/epan/dissectors/packet-fcoib.c b/epan/dissectors/packet-fcoib.c
index 81a6bca433..849b43001a 100644
--- a/epan/dissectors/packet-fcoib.c
+++ b/epan/dissectors/packet-fcoib.c
@@ -34,7 +34,6 @@
#include <epan/crc32-tvb.h>
#include <epan/expert.h>
#include <epan/addr_resolv.h>
-#include "packet-infiniband.h"
#include "packet-fc.h"
void proto_register_fcoib(void);
@@ -104,44 +103,7 @@ static expert_field ei_fcoib_crc = EI_INIT;
static dissector_handle_t fc_handle;
-/* global preferences */
-static gboolean gPREF_HEUR_EN = TRUE;
-static gboolean gPREF_MAN_EN = FALSE;
-static gint gPREF_TYPE[2] = {0};
-static const char *gPREF_ID[2] = {NULL};
-static guint gPREF_QP[2] = {0};
-
-/* source/destination addresses from preferences menu (parsed from gPREF_TYPE[?], gPREF_ID[?]) */
-static address manual_addr[2];
-static void *manual_addr_data[2];
-
-static const enum_val_t pref_address_types[] = {
- {"lid", "LID", 0},
- {"gid", "GID", 1},
- {NULL, NULL, -1}
-};
-
-/* checks if a packet matches the source/destination manually-configured in preferences */
-static gboolean
-manual_addr_match(packet_info *pinfo) {
- if (gPREF_MAN_EN) {
- /* If the manual settings are enabled see if this fits - in which case we can skip
- the following checks entirely and go straight to dissecting */
- if ( (addresses_equal(&pinfo->src, &manual_addr[0]) &&
- addresses_equal(&pinfo->dst, &manual_addr[1]) &&
- (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[0]) &&
- (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[1])) ||
- (addresses_equal(&pinfo->src, &manual_addr[1]) &&
- addresses_equal(&pinfo->dst, &manual_addr[0]) &&
- (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[1]) &&
- (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[0])) )
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gboolean
+static int
dissect_fcoib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
gint crc_offset;
@@ -164,7 +126,6 @@ dissect_fcoib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
gboolean crc_exists;
guint32 crc_computed = 0;
guint32 crc = 0;
- gboolean packet_match_manual;
fc_data_t fc_data;
frame_len = tvb_reported_length_remaining(tvb, 0) -
@@ -174,33 +135,7 @@ dissect_fcoib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
sof_offset = FCOIB_HEADER_LEN - 1;
if (frame_len <= 0)
- return FALSE; /* this packet isn't even long enough to contain the header+trailer w/o FC payload! */
-
- packet_match_manual = manual_addr_match(pinfo);
-
- if (!packet_match_manual && !gPREF_HEUR_EN)
- return FALSE; /* user doesn't want us trying to automatically identify FCoIB packets */
-
- /* we start off with some basic heuristics checks to make sure this could be a FCoIB packet */
-
- if (tvb_bytes_exist(tvb, 0, 1))
- sig = tvb_get_guint8(tvb, 0) >> 6;
- if (tvb_bytes_exist(tvb, eof_offset, 1))
- eof = tvb_get_guint8(tvb, eof_offset);
- if (tvb_bytes_exist(tvb, sof_offset, 1))
- sof = tvb_get_guint8(tvb, sof_offset);
-
- if (!packet_match_manual) {
- if (sig != 1)
- return FALSE; /* the sig field in the FCoIB Encap. header MUST be 2'b01*/
- if (!tvb_bytes_exist(tvb, eof_offset + 1, 3) || tvb_get_ntoh24(tvb, eof_offset + 1) != 0)
- return FALSE; /* 3 bytes of RESERVED field immediately after eEOF MUST be 0 */
- if (!try_val_to_str(sof, fcoib_sof_vals))
- return FALSE; /* invalid value for SOF */
- if (!try_val_to_str(eof, fcoib_eof_vals))
- return FALSE; /* invalid value for EOF */
- }
-
+ return 0; /* this packet isn't even long enough to contain the header+trailer w/o FC payload! */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "FCoIB");
bytes_remaining = tvb_captured_length_remaining(tvb, FCOIB_HEADER_LEN);
@@ -299,6 +234,48 @@ dissect_fcoib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U
call_data_dissector(next_tvb, pinfo, tree);
}
+ return tvb_captured_length(tvb);
+}
+
+static gboolean
+dissect_fcoib_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ gint crc_offset;
+ gint eof_offset;
+ gint sof_offset;
+ gint frame_len;
+ guint8 sof = 0;
+ guint8 eof = 0;
+ guint8 sig = 0;
+
+ frame_len = tvb_reported_length_remaining(tvb, 0) -
+ FCOIB_HEADER_LEN - FCOIB_TRAILER_LEN;
+ crc_offset = FCOIB_HEADER_LEN + frame_len;
+ eof_offset = crc_offset + 4;
+ sof_offset = FCOIB_HEADER_LEN - 1;
+
+ if (frame_len <= 0)
+ return FALSE; /* this packet isn't even long enough to contain the header+trailer w/o FC payload! */
+
+ /* we start off with some basic heuristics checks to make sure this could be a FCoIB packet */
+
+ if (tvb_bytes_exist(tvb, 0, 1))
+ sig = tvb_get_guint8(tvb, 0) >> 6;
+ if (tvb_bytes_exist(tvb, eof_offset, 1))
+ eof = tvb_get_guint8(tvb, eof_offset);
+ if (tvb_bytes_exist(tvb, sof_offset, 1))
+ sof = tvb_get_guint8(tvb, sof_offset);
+
+ if (sig != 1)
+ return FALSE; /* the sig field in the FCoIB Encap. header MUST be 2'b01*/
+ if (!tvb_bytes_exist(tvb, eof_offset + 1, 3) || tvb_get_ntoh24(tvb, eof_offset + 1) != 0)
+ return FALSE; /* 3 bytes of RESERVED field immediately after eEOF MUST be 0 */
+ if (!try_val_to_str(sof, fcoib_sof_vals))
+ return FALSE; /* invalid value for SOF */
+ if (!try_val_to_str(eof, fcoib_eof_vals))
+ return FALSE; /* invalid value for EOF */
+
+ dissect_fcoib(tvb, pinfo, tree, data);
return TRUE;
}
@@ -348,80 +325,33 @@ proto_register_fcoib(void)
fcoib_module = prefs_register_protocol(proto_fcoib, proto_reg_handoff_fcoib);
- prefs_register_bool_preference(fcoib_module, "heur_en", "Enable heuristic identification of FCoIB packets",
- "When this option is enabled Wireshark will attempt to identify FCoIB packets automatically "
- "based on some common features (may generate false positives)",
- &gPREF_HEUR_EN);
-
- prefs_register_bool_preference(fcoib_module, "manual_en", "Enable manual settings",
- "Enables dissecting packets between the manually configured source/destination as FCoIB traffic",
- &gPREF_MAN_EN);
-
- prefs_register_static_text_preference(fcoib_module, "addr_a", "Address A",
- "Side A of the manually-configured connection");
- prefs_register_enum_preference(fcoib_module, "addr_a_type", "Address Type",
- "Type of address specified", &gPREF_TYPE[0], pref_address_types, FALSE);
- prefs_register_string_preference(fcoib_module, "addr_a_id", "ID",
- "LID/GID of address A", &gPREF_ID[0]);
- prefs_register_uint_preference(fcoib_module, "addr_a_qp", "QP Number",
- "QP Number for address A", 10, &gPREF_QP[0]);
-
- prefs_register_static_text_preference(fcoib_module, "addr_b", "Address B",
- "Side B of the manually-configured connection");
- prefs_register_enum_preference(fcoib_module, "addr_b_type", "Address Type",
- "Type of address specified", &gPREF_TYPE[1], pref_address_types, FALSE);
- prefs_register_string_preference(fcoib_module, "addr_b_id", "ID",
- "LID/GID of address B", &gPREF_ID[1]);
- prefs_register_uint_preference(fcoib_module, "addr_b_qp", "QP Number",
- "QP Number for address B", 10, &gPREF_QP[1]);
+ prefs_register_static_text_preference(fcoib_module, "use_decode_as",
+ "Heuristic matching preferences removed. Use Infiniband protocol preferences or Decode As.",
+ "Simple heuristics can still be enable (may generate false positives) through Infiniband protocol preferences."
+ "To force FCoIB dissection use Decode As");
+
+ prefs_register_obsolete_preference(fcoib_module, "heur_en");
+ prefs_register_obsolete_preference(fcoib_module, "manual_en");
+
+ prefs_register_obsolete_preference(fcoib_module, "addr_a");
+ prefs_register_obsolete_preference(fcoib_module, "addr_a_type");
+ prefs_register_obsolete_preference(fcoib_module, "addr_a_id");
+ prefs_register_obsolete_preference(fcoib_module, "addr_a_qp");
+
+ prefs_register_obsolete_preference(fcoib_module, "addr_b");
+ prefs_register_obsolete_preference(fcoib_module, "addr_b_type");
+ prefs_register_obsolete_preference(fcoib_module, "addr_b_id");
+ prefs_register_obsolete_preference(fcoib_module, "addr_b_qp");
}
void
proto_reg_handoff_fcoib(void)
{
- static gboolean initialized = FALSE;
-
- if (!initialized) {
- heur_dissector_add("infiniband.payload", dissect_fcoib, "Fibre Channel over Infiniband", "fc_infiniband", proto_fcoib, HEURISTIC_ENABLE);
+ heur_dissector_add("infiniband.payload", dissect_fcoib_heur, "Fibre Channel over Infiniband", "fc_infiniband", proto_fcoib, HEURISTIC_ENABLE);
- fc_handle = find_dissector_add_dependency("fc", proto_fcoib);
-
- initialized = TRUE;
- }
+ dissector_add_for_decode_as("infiniband", create_dissector_handle( dissect_fcoib, proto_fcoib ) );
- if (gPREF_MAN_EN) {
- /* the manual setting is enabled, so parse the settings into the address type */
- gboolean error_occured = FALSE;
- char *not_parsed;
- int i;
-
- for (i = 0; i < 2; i++) {
- if (gPREF_ID[i][0] == '\0') {
- error_occured = TRUE;
- } else if (gPREF_TYPE[i] == 0) { /* LID */
- errno = 0; /* reset any previous error indicators */
- *((guint16*)manual_addr_data[i]) = (guint16)strtoul(gPREF_ID[i], &not_parsed, 0);
- if (errno || *not_parsed != '\0') {
- error_occured = TRUE;
- } else {
- set_address(&manual_addr[i], AT_IB, sizeof(guint16), manual_addr_data[i]);
- }
- } else { /* GID */
- if (!str_to_ip6( gPREF_ID[i], manual_addr_data[i])) {
- error_occured = TRUE;
- } else {
- set_address(&manual_addr[i], AT_IB, GID_SIZE, manual_addr_data[i]);
- }
- }
-
- if (error_occured) {
- /* an invalid id was specified - disable manual settings until it's fixed */
- gPREF_MAN_EN = FALSE;
- break;
- }
- }
-
- }
+ fc_handle = find_dissector_add_dependency("fc", proto_fcoib);
}
/*
diff --git a/epan/dissectors/packet-infiniband.c b/epan/dissectors/packet-infiniband.c
index f775864638..70038a8ed4 100644
--- a/epan/dissectors/packet-infiniband.c
+++ b/epan/dissectors/packet-infiniband.c
@@ -31,6 +31,7 @@
#include <epan/prefs.h>
#include <epan/etypes.h>
#include <epan/show_exception.h>
+#include <epan/decode_as.h>
#include <wiretap/erf.h>
#include "packet-infiniband.h"
@@ -116,6 +117,8 @@ static dissector_handle_t ipv6_handle;
static dissector_handle_t eth_handle;
static dissector_table_t ethertype_dissector_table;
+static dissector_table_t subdissector_table;
+
/* MAD_Data
* Structure to hold information from the common MAD header.
* This is necessary because the MAD header contains information which significantly changes the dissection algorithm. */
@@ -1504,6 +1507,7 @@ static guint32 opCode_PAYLD[] = {
/* settings to be set by the user via the preferences dialog */
static guint pref_rroce_udp_port = DEFAULT_RROCE_UDP_PORT;
+static gboolean try_heuristic_first = TRUE;
/* saves information about connections that have been/are in the process of being
negotiated via ConnectionManagement packets */
@@ -1527,6 +1531,15 @@ static heur_dissector_list_t heur_dissectors_payload;
static heur_dissector_list_t heur_dissectors_cm_private;
/* ----- This sections contains various utility functions indirectly related to Infiniband dissection ---- */
+static void infiniband_payload_prompt(packet_info *pinfo _U_, gchar* result)
+{
+ g_snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Dissect Infiniband payload as");
+}
+
+static gpointer infiniband_payload_value(packet_info *pinfo _U_)
+{
+ return 0;
+}
static void table_destroy_notify(gpointer data) {
g_free(data);
@@ -2410,6 +2423,7 @@ static void parse_PAYLOAD(proto_tree *parentTree,
tvbuff_t *volatile next_tvb;
gint reported_length;
heur_dtbl_entry_t *hdtbl_entry;
+ gboolean dissector_found = FALSE;
if (!tvb_bytes_exist(tvb, *offset, length)) /* previously consumed bytes + offset was all the data - none or corrupt payload */
{
@@ -2501,8 +2515,32 @@ static void parse_PAYLOAD(proto_tree *parentTree,
reported_length -= crclen;
next_tvb = tvb_new_subset_length(tvb, local_offset, reported_length);
- /* Try any heuristic dissectors that requested a chance to try and dissect IB payloads */
- if (!dissector_try_heuristic(heur_dissectors_payload, next_tvb, pinfo, top_tree, &hdtbl_entry, info)) {
+ if (try_heuristic_first)
+ {
+ if (dissector_try_heuristic(heur_dissectors_payload, next_tvb, pinfo, top_tree, &hdtbl_entry, info))
+ dissector_found = TRUE;
+ }
+
+ if (dissector_found == FALSE)
+ {
+ /* Functionality for choosing subdissector is controlled through Decode As as there
+ isn't a unique identifier to determine subdissector */
+ if (dissector_try_uint_new(subdissector_table, 0, next_tvb, pinfo, top_tree, TRUE, info))
+ {
+ dissector_found = TRUE;
+ }
+ else
+ {
+ if (!try_heuristic_first)
+ {
+ if (dissector_try_heuristic(heur_dissectors_payload, next_tvb, pinfo, top_tree, &hdtbl_entry, info))
+ dissector_found = TRUE;
+ }
+ }
+ }
+
+ if (dissector_found == FALSE)
+ {
/* No sub-dissector found.
Label rest of packet as "Data" */
call_data_dissector(next_tvb, pinfo, top_tree);
@@ -7913,6 +7951,12 @@ void proto_register_infiniband(void)
&ett_eoib
};
+ /* Decode As handling */
+ static build_valid_func infiniband_payload_da_build_value[1] = {infiniband_payload_value};
+ static decode_as_value_t infiniband_payload_da_values = {infiniband_payload_prompt, 1, infiniband_payload_da_build_value};
+ static decode_as_t infiniband_payload_da = {"infiniband", "Network", "infiniband", 1, 0, &infiniband_payload_da_values, NULL, NULL,
+ decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL};
+
proto_infiniband = proto_register_protocol("InfiniBand", "IB", "infiniband");
ib_handle = register_dissector("infiniband", dissect_infiniband, proto_infiniband);
@@ -7922,6 +7966,7 @@ void proto_register_infiniband(void)
/* register the subdissector tables */
heur_dissectors_payload = register_heur_dissector_list("infiniband.payload", proto_infiniband);
heur_dissectors_cm_private = register_heur_dissector_list("infiniband.mad.cm.private", proto_infiniband);
+ subdissector_table = register_dissector_table("infiniband", "Infiniband Payload", proto_infiniband, FT_UINT16, BASE_DEC);
/* register dissection preferences */
infiniband_module = prefs_register_protocol(proto_infiniband, proto_reg_handoff_infiniband);
@@ -7931,6 +7976,10 @@ void proto_register_infiniband(void)
prefs_register_uint_preference(infiniband_module, "rroce.port", "RRoce UDP Port(Default 1021)", "when set "
"the Analyser will consider this as RRoce UDP Port and parse it accordingly",
10, &pref_rroce_udp_port);
+ prefs_register_bool_preference(infiniband_module, "try_heuristic_first",
+ "Try heuristic sub-dissectors first",
+ "Try to decode a packet using an heuristic sub-dissector before using Decode As",
+ &try_heuristic_first);
proto_infiniband_link = proto_register_protocol("InfiniBand Link", "InfiniBand Link", "infiniband_link");
ib_link_handle = register_dissector("infiniband_link", dissect_infiniband_link, proto_infiniband_link);
@@ -7945,6 +7994,8 @@ void proto_register_infiniband(void)
/* initialize the hash table */
CM_context_table = g_hash_table_new_full(g_int64_hash, g_int64_equal,
table_destroy_notify, table_destroy_notify);
+
+ register_decode_as(&infiniband_payload_da);
}
/* Reg Handoff. Register dissectors we'll need for IPoIB and RoCE */
diff --git a/epan/dissectors/packet-infiniband_sdp.c b/epan/dissectors/packet-infiniband_sdp.c
index ecf6018894..426c82776f 100644
--- a/epan/dissectors/packet-infiniband_sdp.c
+++ b/epan/dissectors/packet-infiniband_sdp.c
@@ -41,7 +41,7 @@ void proto_reg_handoff_ib_sdp(void);
this is SDP traffic */
#define SERVICE_ID_MASK 0x0000000000010000
-static int proto_infiniband = -1; /* we'll need the Infiniband protocol index sometimes, so keep it here */
+static int proto_infiniband = -1; /* we'll need the Infiniband protocol index for conversation data */
/* Initialize the protocol and registered fields... */
static int proto_ib_sdp = -1;
@@ -90,22 +90,6 @@ static gint ett_ib_sdp = -1;
static gint ett_ib_sdp_bsdh = -1;
static gint ett_ib_sdp_hh = -1;
-/* global preferences */
-static gboolean gPREF_MAN_EN = FALSE;
-static gint gPREF_TYPE[2] = {0};
-static const char *gPREF_ID[2] = {NULL};
-static guint gPREF_QP[2] = {0};
-
-/* source/destination addresses from preferences menu (parsed from gPREF_TYPE[?], gPREF_ID[?]) */
-address manual_addr[2];
-void *manual_addr_data[2];
-
-static const enum_val_t pref_address_types[] = {
- {"lid", "LID", 0},
- {"gid", "GID", 1},
- {NULL, NULL, -1}
-};
-
typedef enum {
Hello = 0x0,
HelloAck,
@@ -157,67 +141,17 @@ static int
dissect_ib_sdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
{
int local_offset = 0;
- proto_item *SDP_header_item = NULL;
- proto_tree *SDP_header_tree = NULL;
- proto_item *SDP_BSDH_header_item = NULL;
- proto_tree *SDP_BSDH_header_tree = NULL;
- proto_item *SDP_EH_header_item = NULL;
- proto_tree *SDP_EH_header_tree = NULL;
+ proto_item *SDP_header_item;
+ proto_tree *SDP_header_tree;
+ proto_item *SDP_BSDH_header_item;
+ proto_tree *SDP_BSDH_header_tree;
+ proto_item *SDP_EH_header_item;
+ proto_tree *SDP_EH_header_tree;
guint8 mid;
- conversation_t *conv;
- conversation_infiniband_data *convo_data = NULL;
- dissector_handle_t infiniband_handle;
if (tvb_captured_length(tvb) < 16) /* check this has at least enough bytes for the BSDH */
return 0;
- if (gPREF_MAN_EN) {
- /* If the manual settings are enabled see if this fits - in which case we can skip
- the following checks entirely and go straight to dissecting */
- if ( (addresses_equal(&pinfo->src, &manual_addr[0]) &&
- addresses_equal(&pinfo->dst, &manual_addr[1]) &&
- (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[0]) &&
- (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[1])) ||
- (addresses_equal(&pinfo->src, &manual_addr[1]) &&
- addresses_equal(&pinfo->dst, &manual_addr[0]) &&
- (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[1]) &&
- (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[0])) )
- goto manual_override;
- }
-
- /* first try to find a conversation between the two current hosts. in most cases this
- will not work since we do not have the source QP. this WILL succeed when we're still
- in the process of CM negotiations */
- conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
- PT_IBQP, pinfo->srcport, pinfo->destport, 0);
-
- if (!conv) {
- /* if not, try to find an established RC channel. recall Infiniband conversations are
- registered with one side of the channel. since the packet is only guaranteed to
- contain the qpn of the destination, we'll use this */
- conv = find_conversation(pinfo->num, &pinfo->dst, &pinfo->dst,
- PT_IBQP, pinfo->destport, pinfo->destport, NO_ADDR_B|NO_PORT_B);
-
- if (!conv)
- return 0; /* nothing to do with no conversation context */
- }
-
- if (proto_infiniband < 0) { /* first time - get the infiniband protocol index*/
- infiniband_handle = find_dissector("infiniband");
- if (!infiniband_handle)
- return 0; /* no infiniband handle? can't get our proto-data; sorry, can't help you without this */
- proto_infiniband = dissector_handle_get_protocol_index(infiniband_handle);
- }
- convo_data = (conversation_infiniband_data *)conversation_get_proto_data(conv, proto_infiniband);
-
- if (!convo_data)
- return 0;
-
- if (!(convo_data->service_id & SERVICE_ID_MASK))
- return 0; /* the service id doesn't match that of SDP - nothing for us to do here */
-
-manual_override:
-
col_set_str(pinfo->cinfo, COL_PROTOCOL, "SDP");
SDP_header_item = proto_tree_add_item(tree, proto_ib_sdp, tvb, local_offset, -1, ENC_NA);
@@ -229,6 +163,9 @@ manual_override:
mid = tvb_get_guint8(tvb, local_offset);
proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_mid, tvb, local_offset, 1, ENC_BIG_ENDIAN); local_offset += 1;
+ col_append_fstr(pinfo->cinfo, COL_INFO, "(SDP %s)",
+ rval_to_str(mid, mid_meanings, "Unknown"));
+
proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_flags, tvb, local_offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_flags_oobpres, tvb, local_offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(SDP_BSDH_header_tree, hf_ib_sdp_flags_oob_pend, tvb, local_offset, 4, ENC_BIG_ENDIAN);
@@ -308,12 +245,47 @@ manual_override:
break;
}
- col_append_fstr(pinfo->cinfo, COL_INFO, "(SDP %s)",
- rval_to_str(mid, mid_meanings, "Unknown"));
-
return tvb_captured_length(tvb);
}
+static gboolean
+dissect_ib_sdp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ conversation_t *conv;
+ conversation_infiniband_data *convo_data = NULL;
+
+ if (tvb_captured_length(tvb) < 16) /* check this has at least enough bytes for the BSDH */
+ return FALSE;
+
+ /* first try to find a conversation between the two current hosts. in most cases this
+ will not work since we do not have the source QP. this WILL succeed when we're still
+ in the process of CM negotiations */
+ conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst,
+ PT_IBQP, pinfo->srcport, pinfo->destport, 0);
+
+ if (!conv) {
+ /* if not, try to find an established RC channel. recall Infiniband conversations are
+ registered with one side of the channel. since the packet is only guaranteed to
+ contain the qpn of the destination, we'll use this */
+ conv = find_conversation(pinfo->num, &pinfo->dst, &pinfo->dst,
+ PT_IBQP, pinfo->destport, pinfo->destport, NO_ADDR_B|NO_PORT_B);
+
+ if (!conv)
+ return FALSE; /* nothing to do with no conversation context */
+ }
+
+ convo_data = (conversation_infiniband_data *)conversation_get_proto_data(conv, proto_infiniband);
+
+ if (!convo_data)
+ return FALSE;
+
+ if (!(convo_data->service_id & SERVICE_ID_MASK))
+ return FALSE; /* the service id doesn't match that of SDP - nothing for us to do here */
+
+ dissect_ib_sdp(tvb, pinfo, tree, data);
+ return TRUE;
+}
+
void
proto_register_ib_sdp(void)
{
@@ -478,77 +450,33 @@ proto_register_ib_sdp(void)
/* Register preferences */
ib_sdp_module = prefs_register_protocol(proto_ib_sdp, proto_reg_handoff_ib_sdp);
- prefs_register_bool_preference(ib_sdp_module, "manual_en", "Enable manual settings",
- "Check to treat all traffic between the configured source/destination as SDP",
- &gPREF_MAN_EN);
-
- prefs_register_static_text_preference(ib_sdp_module, "addr_a", "Address A",
- "Side A of the manually-configured connection");
- prefs_register_enum_preference(ib_sdp_module, "addr_a_type", "Address Type",
- "Type of address specified", &gPREF_TYPE[0], pref_address_types, FALSE);
- prefs_register_string_preference(ib_sdp_module, "addr_a_id", "ID",
- "LID/GID of address A", &gPREF_ID[0]);
- prefs_register_uint_preference(ib_sdp_module, "addr_a_qp", "QP Number",
- "QP Number for address A", 10, &gPREF_QP[0]);
-
- prefs_register_static_text_preference(ib_sdp_module, "addr_b", "Address B",
- "Side B of the manually-configured connection");
- prefs_register_enum_preference(ib_sdp_module, "addr_b_type", "Address Type",
- "Type of address specified", &gPREF_TYPE[1], pref_address_types, FALSE);
- prefs_register_string_preference(ib_sdp_module, "addr_b_id", "ID",
- "LID/GID of address B", &gPREF_ID[1]);
- prefs_register_uint_preference(ib_sdp_module, "addr_b_qp", "QP Number",
- "QP Number for address B", 10, &gPREF_QP[1]);
+ prefs_register_static_text_preference(ib_sdp_module, "use_decode_as",
+ "Heuristic matching preferences removed. Use Infiniband protocol preferences or Decode As.",
+ "Simple heuristics can still be enable (may generate false positives) through Infiniband protocol preferences."
+ "To force Infiniband SDP dissection use Decode As");
+
+ prefs_register_obsolete_preference(ib_sdp_module, "manual_en");
+
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_a");
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_a_type");
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_a_id");
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_a_qp");
+
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_b");
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_b_type");
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_b_id");
+ prefs_register_obsolete_preference(ib_sdp_module, "addr_b_qp");
}
void
proto_reg_handoff_ib_sdp(void)
{
- static gboolean initialized = FALSE;
-
- if (!initialized) {
- heur_dissector_add("infiniband.payload", dissect_ib_sdp, "Infiniband SDP", "sdp_infiniband", proto_ib_sdp, HEURISTIC_ENABLE);
- heur_dissector_add("infiniband.mad.cm.private", dissect_ib_sdp, "Infiniband SDP in PrivateData of CM packets", "sdp_ib_private", proto_ib_sdp, HEURISTIC_ENABLE);
+ heur_dissector_add("infiniband.payload", dissect_ib_sdp_heur, "Infiniband SDP", "sdp_infiniband", proto_ib_sdp, HEURISTIC_ENABLE);
+ heur_dissector_add("infiniband.mad.cm.private", dissect_ib_sdp_heur, "Infiniband SDP in PrivateData of CM packets", "sdp_ib_private", proto_ib_sdp, HEURISTIC_ENABLE);
- /* allocate enough space in the addresses to store the largest address (a GID) */
- manual_addr_data[0] = wmem_alloc(wmem_epan_scope(), GID_SIZE);
- manual_addr_data[1] = wmem_alloc(wmem_epan_scope(), GID_SIZE);
+ dissector_add_for_decode_as("infiniband", create_dissector_handle( dissect_ib_sdp, proto_ib_sdp ) );
- initialized = TRUE;
- }
-
- if (gPREF_MAN_EN) {
- /* the manual setting is enabled, so parse the settings into the address type */
- gboolean error_occured = FALSE;
- char *not_parsed;
- int i;
-
- for (i = 0; i < 2; i++) {
- if (gPREF_ID[i][0] == '\0') {
- error_occured = TRUE;
- } else if (gPREF_TYPE[i] == 0) { /* LID */
- errno = 0; /* reset any previous error indicators */
- *((guint16*)manual_addr_data[i]) = (guint16)strtoul(gPREF_ID[i], &not_parsed, 0);
- if (errno || *not_parsed != '\0') {
- error_occured = TRUE;
- } else {
- set_address(&manual_addr[i], AT_IB, sizeof(guint16), manual_addr_data[i]);
- }
- } else { /* GID */
- if (!str_to_ip6(gPREF_ID[i], manual_addr_data[i])) {
- error_occured = TRUE;
- } else {
- set_address(&manual_addr[i], AT_IB, GID_SIZE, manual_addr_data[i]);
- }
- }
-
- if (error_occured) {
- /* an invalid id was specified - disable manual settings until it's fixed */
- gPREF_MAN_EN = FALSE;
- break;
- }
- }
- }
+ proto_infiniband = proto_get_id_by_filter_name( "infiniband" );
}
/*
diff --git a/epan/dissectors/packet-iser.c b/epan/dissectors/packet-iser.c
index 511926e121..f5edbebb7d 100644
--- a/epan/dissectors/packet-iser.c
+++ b/epan/dissectors/packet-iser.c
@@ -66,7 +66,7 @@ void proto_register_iser(void);
static int proto_iser = -1;
static dissector_handle_t iscsi_handler;
-static dissector_handle_t ib_handler;
+
static int proto_ib = -1;
/* iSER Header */
@@ -87,22 +87,8 @@ static gint ett_iser = -1;
static gint ett_iser_flags = -1;
/* global preferences */
-static gboolean gPREF_MAN_EN = FALSE;
-static gint gPREF_TYPE[2] = {0};
-static const char *gPREF_ID[2] = {NULL};
-static guint gPREF_QP[2] = {0};
static range_t *gPORT_RANGE;
-/* source/destination addresses from preferences menu (parsed from gPREF_TYPE[?], gPREF_ID[?]) */
-static address manual_addr[2];
-static void *manual_addr_data[2];
-
-static const enum_val_t pref_address_types[] = {
- {"lid", "LID", 0},
- {"gid", "GID", 1},
- {NULL, NULL, -1}
-};
-
static const value_string iser_flags_opcode[] = {
{ ISER_ISCSI_CTRL >> 4, "iSCSI Control-Type PDU"},
{ ISER_HELLO >> 4, "Hello Message"},
@@ -126,16 +112,20 @@ static const int *hellorply_flags_fields[] = {
NULL
};
-static int dissect_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int dissect_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
tvbuff_t *next_tvb;
/* Set up structures needed to add the protocol subtree and manage it */
proto_item *ti;
proto_tree *iser_tree;
guint offset = 0;
- guint8 flags = tvb_get_guint8(tvb, 0);
- guint8 vers;
- guint8 opcode = flags & ISER_OPCODE_MASK;
+ guint8 flags, vers, opcode;
+
+ if (tvb_reported_length(tvb) < ISER_ISCSI_HDR_SZ)
+ return 0;
+
+ flags = tvb_get_guint8(tvb, 0);
+ opcode = flags & ISER_OPCODE_MASK;
/* Check if the opcode is valid */
switch (opcode) {
@@ -238,21 +228,7 @@ dissect_iser(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
conversation_infiniband_data *convo_data = NULL;
if (tvb_reported_length(tvb) < ISER_ISCSI_HDR_SZ)
- return 0;
-
- if (gPREF_MAN_EN) {
- /* If the manual settings are enabled see if this fits - in which case we can skip
- the following checks entirely and go straight to dissecting */
- if ( (addresses_equal(&pinfo->src, &manual_addr[0]) &&
- addresses_equal(&pinfo->dst, &manual_addr[1]) &&
- (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[0]) &&
- (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[1])) ||
- (addresses_equal(&pinfo->src, &manual_addr[1]) &&
- addresses_equal(&pinfo->dst, &manual_addr[0]) &&
- (pinfo->srcport == 0xffffffff /* is unknown */ || pinfo->srcport == gPREF_QP[1]) &&
- (pinfo->destport == 0xffffffff /* is unknown */ || pinfo->destport == gPREF_QP[0])) )
- return dissect_packet(tvb, pinfo, tree);
- }
+ return FALSE;
/* first try to find a conversation between the two current hosts. in most cases this
will not work since we do not have the source QP. this WILL succeed when we're still
@@ -268,21 +244,22 @@ dissect_iser(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
PT_IBQP, pinfo->destport, pinfo->destport, NO_ADDR_B|NO_PORT_B);
if (!conv)
- return 0; /* nothing to do with no conversation context */
+ return FALSE; /* nothing to do with no conversation context */
}
convo_data = (conversation_infiniband_data *)conversation_get_proto_data(conv, proto_ib);
if (!convo_data)
- return 0;
+ return FALSE;
if ((convo_data->service_id & SID_MASK) != SID_ULP_TCP)
- return 0; /* the service id doesn't match that of TCP ULP - nothing for us to do here */
+ return FALSE; /* the service id doesn't match that of TCP ULP - nothing for us to do here */
if (!(value_is_in_range(gPORT_RANGE, (guint32)(convo_data->service_id & SID_PORT_MASK))))
- return 0; /* the port doesn't match that of iSER - nothing for us to do here */
+ return FALSE; /* the port doesn't match that of iSER - nothing for us to do here */
- return dissect_packet(tvb, pinfo, tree);
+ dissect_packet(tvb, pinfo, tree, data);
+ return TRUE;
}
void
@@ -354,27 +331,22 @@ proto_register_iser(void)
/* Register preferences */
iser_module = prefs_register_protocol(proto_iser, proto_reg_handoff_iser);
- prefs_register_bool_preference(iser_module, "manual_en", "Enable manual settings",
- "Check to treat all traffic between the configured source/destination as iSER",
- &gPREF_MAN_EN);
-
- prefs_register_static_text_preference(iser_module, "addr_a", "Address A",
- "Side A of the manually-configured connection");
- prefs_register_enum_preference(iser_module, "addr_a_type", "Address Type",
- "Type of address specified", &gPREF_TYPE[0], pref_address_types, FALSE);
- prefs_register_string_preference(iser_module, "addr_a_id", "ID",
- "LID/GID of address A", &gPREF_ID[0]);
- prefs_register_uint_preference(iser_module, "addr_a_qp", "QP Number",
- "QP Number for address A", 10, &gPREF_QP[0]);
-
- prefs_register_static_text_preference(iser_module, "addr_b", "Address B",
- "Side B of the manually-configured connection");
- prefs_register_enum_preference(iser_module, "addr_b_type", "Address Type",
- "Type of address specified", &gPREF_TYPE[1], pref_address_types, FALSE);
- prefs_register_string_preference(iser_module, "addr_b_id", "ID",
- "LID/GID of address B", &gPREF_ID[1]);
- prefs_register_uint_preference(iser_module, "addr_b_qp", "QP Number",
- "QP Number for address B", 10, &gPREF_QP[1]);
+ prefs_register_static_text_preference(iser_module, "use_decode_as",
+ "Heuristic matching preferences removed. Use Infiniband protocol preferences or Decode As.",
+ "Simple heuristics can still be enable (may generate false positives) through Infiniband protocol preferences."
+ "To force iSER dissection use Decode As");
+
+ prefs_register_obsolete_preference(iser_module, "manual_en");
+
+ prefs_register_obsolete_preference(iser_module, "addr_a");
+ prefs_register_obsolete_preference(iser_module, "addr_a_type");
+ prefs_register_obsolete_preference(iser_module, "addr_a_id");
+ prefs_register_obsolete_preference(iser_module, "addr_a_qp");
+
+ prefs_register_obsolete_preference(iser_module, "addr_b");
+ prefs_register_obsolete_preference(iser_module, "addr_b_type");
+ prefs_register_obsolete_preference(iser_module, "addr_b_id");
+ prefs_register_obsolete_preference(iser_module, "addr_b_qp");
range_convert_str(&gPORT_RANGE, TCP_PORT_ISER_RANGE, MAX_TCP_PORT);
prefs_register_range_preference(iser_module,
@@ -388,53 +360,13 @@ proto_register_iser(void)
void
proto_reg_handoff_iser(void)
{
- static gboolean initialized = FALSE;
-
- if (!initialized) {
- heur_dissector_add("infiniband.payload", dissect_iser, "iSER Infiniband", "iser_infiniband", proto_iser, HEURISTIC_ENABLE);
- heur_dissector_add("infiniband.mad.cm.private", dissect_iser, "iSER in PrivateData of CM packets", "iser_ib_private", proto_iser, HEURISTIC_ENABLE);
+ heur_dissector_add("infiniband.payload", dissect_iser, "iSER Infiniband", "iser_infiniband", proto_iser, HEURISTIC_ENABLE);
+ heur_dissector_add("infiniband.mad.cm.private", dissect_iser, "iSER in PrivateData of CM packets", "iser_ib_private", proto_iser, HEURISTIC_ENABLE);
- /* allocate enough space in the addresses to store the largest address (a GID) */
- manual_addr_data[0] = wmem_alloc(wmem_epan_scope(), GID_SIZE);
- manual_addr_data[1] = wmem_alloc(wmem_epan_scope(), GID_SIZE);
+ dissector_add_for_decode_as("infiniband", create_dissector_handle( dissect_packet, proto_iser ) );
- iscsi_handler = find_dissector_add_dependency("iscsi", proto_iser);
- ib_handler = find_dissector_add_dependency("infiniband", proto_iser);
- proto_ib = dissector_handle_get_protocol_index(ib_handler);
-
- initialized = TRUE;
- }
-
- if (gPREF_MAN_EN) {
- /* the manual setting is enabled, so parse the settings into the address type */
- gboolean error_occured = FALSE;
- char *not_parsed;
- int i;
-
- for (i = 0; i < 2; i++) {
- if (gPREF_TYPE[i] == 0) { /* LID */
- errno = 0; /* reset any previous error indicators */
- *((guint16*)manual_addr_data[i]) = (guint16)strtoul(gPREF_ID[i], &not_parsed, 0);
- if (errno || *not_parsed != '\0') {
- error_occured = TRUE;
- } else {
- set_address(&manual_addr[i], AT_IB, sizeof(guint16), manual_addr_data[i]);
- }
- } else { /* GID */
- if (!str_to_ip6(gPREF_ID[i], manual_addr_data[i]) ) {
- error_occured = TRUE;
- } else {
- set_address(&manual_addr[i], AT_IB, GID_SIZE, manual_addr_data[i]);
- }
- }
-
- if (error_occured) {
- /* an invalid id was specified - disable manual settings until it's fixed */
- gPREF_MAN_EN = FALSE;
- break;
- }
- }
- }
+ iscsi_handler = find_dissector_add_dependency("iscsi", proto_iser);
+ proto_ib = proto_get_id_by_filter_name( "infiniband" );
}
/*
diff --git a/epan/dissectors/packet-rpcrdma.c b/epan/dissectors/packet-rpcrdma.c
index 12346ee7a7..826604cc92 100644
--- a/epan/dissectors/packet-rpcrdma.c
+++ b/epan/dissectors/packet-rpcrdma.c
@@ -475,7 +475,7 @@ packet_is_rpcordma(tvbuff_t *tvb)
}
static int
-dissect_rpcrdma(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_rpcrdma(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
tvbuff_t *next_tvb;
proto_item *ti;
@@ -599,7 +599,7 @@ dissect_rpcrdma_ib_heur(tvbuff_t *tvb, packet_info *pinfo,
if (!packet_is_rpcordma(tvb))
return FALSE;
- dissect_rpcrdma(tvb, pinfo, tree);
+ dissect_rpcrdma(tvb, pinfo, tree, NULL);
return TRUE;
}
@@ -623,7 +623,7 @@ dissect_rpcrdma_iwarp_heur(tvbuff_t *tvb, packet_info *pinfo,
if (!packet_is_rpcordma(tvb))
return FALSE;
- dissect_rpcrdma(tvb, pinfo, tree);
+ dissect_rpcrdma(tvb, pinfo, tree, NULL);
return TRUE;
}
@@ -757,23 +757,14 @@ proto_register_rpcordma(void)
void
proto_reg_handoff_rpcordma(void)
{
- static gboolean initialized = FALSE;
+ heur_dissector_add("infiniband.payload", dissect_rpcrdma_ib_heur, "RPC-over-RDMA on Infiniband",
+ "rpcrdma_infiniband", proto_rpcordma, HEURISTIC_ENABLE);
+ dissector_add_for_decode_as("infiniband", create_dissector_handle( dissect_rpcrdma, proto_rpcordma ) );
- if (!initialized) {
- heur_dissector_add("infiniband.payload", dissect_rpcrdma_ib_heur, "RPC-over-RDMA on Infiniband",
- "rpcrdma_infiniband", proto_rpcordma, HEURISTIC_ENABLE);
- heur_dissector_add("iwarp_ddp_rdmap", dissect_rpcrdma_iwarp_heur, "RPC-over-RDMA on iWARP",
- "rpcrdma_iwarp", proto_rpcordma, HEURISTIC_ENABLE);
+ heur_dissector_add("iwarp_ddp_rdmap", dissect_rpcrdma_iwarp_heur, "RPC-over-RDMA on iWARP",
+ "rpcrdma_iwarp", proto_rpcordma, HEURISTIC_ENABLE);
- /* The following is never used: there are no known implementations, and no specification */
- heur_dissector_add("infiniband.mad.cm.private", dissect_rpcrdma_ib_heur,
- "RPC over RDMA in PrivateData of CM packets",
- "rpcordma_ib_private", proto_rpcordma, HEURISTIC_ENABLE);
-
- rpc_handler = find_dissector_add_dependency("rpc", proto_rpcordma);
-
- initialized = TRUE;
- }
+ rpc_handler = find_dissector_add_dependency("rpc", proto_rpcordma);
}
/*
diff --git a/epan/dissectors/packet-smb-direct.c b/epan/dissectors/packet-smb-direct.c
index 5344835587..29ccbdd9d6 100644
--- a/epan/dissectors/packet-smb-direct.c
+++ b/epan/dissectors/packet-smb-direct.c
@@ -514,15 +514,15 @@ dissect_smb_direct_iwarp_heur(tvbuff_t *tvb, packet_info *pinfo,
return TRUE;
}
-static gboolean
-dissect_smb_direct_infiniband_heur(tvbuff_t *tvb, packet_info *pinfo,
+static int
+dissect_smb_direct_infiniband(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *parent_tree, void *data)
{
struct infinibandinfo *info = (struct infinibandinfo *)data;
enum SMB_DIRECT_HDR_TYPE hdr_type;
if (info == NULL) {
- return FALSE;
+ return 0;
}
switch (info->opCode) {
@@ -536,16 +536,23 @@ dissect_smb_direct_infiniband_heur(tvbuff_t *tvb, packet_info *pinfo,
case RC_SEND_ONLY_INVAL:
break;
default:
- return FALSE;
+ return 0;
}
hdr_type = is_smb_direct(tvb, pinfo);
if (hdr_type == SMB_DIRECT_HDR_UNKNOWN) {
- return FALSE;
+ return 0;
}
dissect_smb_direct(tvb, pinfo, parent_tree, hdr_type);
- return TRUE;
+ return tvb_captured_length(tvb);
+}
+
+static gboolean
+dissect_smb_direct_infiniband_heur(tvbuff_t *tvb, packet_info *pinfo,
+ proto_tree *parent_tree, void *data)
+{
+ return (dissect_smb_direct_infiniband(tvb, pinfo, parent_tree, data) > 0);
}
void proto_register_smb_direct(void)
@@ -700,13 +707,14 @@ void
proto_reg_handoff_smb_direct(void)
{
heur_dissector_add("iwarp_ddp_rdmap",
- dissect_smb_direct_iwarp_heur,
- "SMB Direct over iWARP", "smb_direct_iwarp",
- proto_smb_direct, HEURISTIC_ENABLE);
+ dissect_smb_direct_iwarp_heur,
+ "SMB Direct over iWARP", "smb_direct_iwarp",
+ proto_smb_direct, HEURISTIC_ENABLE);
heur_dissector_add("infiniband.payload",
- dissect_smb_direct_infiniband_heur,
- "SMB Direct Infiniband", "smb_direct_infiniband",
- proto_smb_direct, HEURISTIC_ENABLE);
+ dissect_smb_direct_infiniband_heur,
+ "SMB Direct Infiniband", "smb_direct_infiniband",
+ proto_smb_direct, HEURISTIC_ENABLE);
+ dissector_add_for_decode_as("infiniband", create_dissector_handle( dissect_smb_direct_infiniband, proto_smb_direct ) );
}
diff --git a/epan/dissectors/packet-smcr.c b/epan/dissectors/packet-smcr.c
index f92910786f..bbdf7ad0c9 100644
--- a/epan/dissectors/packet-smcr.c
+++ b/epan/dissectors/packet-smcr.c
@@ -794,8 +794,8 @@ dissect_smcr_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
return tvb_reported_length(tvb);
}
-static void
-dissect_smcr_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_smcr_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
guint16 msg_len;
llc_message llc_msgid;
@@ -814,9 +814,6 @@ dissect_smcr_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
(tvb_get_guint8(tvb, LLC_CMD_RSP_OFFSET) & LLC_FLAG_RESP))
col_append_str(pinfo->cinfo, COL_INFO, "(Resp)");
- if (!tree)
- return;
-
ti = proto_tree_add_item(tree, proto_smcr, tvb, 0, msg_len, ENC_NA);
smcr_tree = proto_item_add_subtree(ti, ett_smcr);
proto_tree_add_item(smcr_tree, hf_smcr_llc_msg, tvb, 0, 1,
@@ -863,7 +860,8 @@ dissect_smcr_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
/* Unknown Command */
break;
}
- return;
+
+ return tvb_captured_length(tvb);
}
static guint
@@ -925,7 +923,7 @@ dissect_smcr_infiniband_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
if (msg_len != tvb_reported_length_remaining(tvb, LLC_CMD_OFFSET))
return FALSE;
- dissect_smcr_infiniband(tvb, pinfo, tree);
+ dissect_smcr_infiniband(tvb, pinfo, tree, data);
return TRUE;
}
@@ -1433,6 +1431,7 @@ 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 ) );
}
/*