summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 ) );
}
/*