aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-infiniband.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-infiniband.c')
-rw-r--r--epan/dissectors/packet-infiniband.c318
1 files changed, 161 insertions, 157 deletions
diff --git a/epan/dissectors/packet-infiniband.c b/epan/dissectors/packet-infiniband.c
index a007d6a231..f775864638 100644
--- a/epan/dissectors/packet-infiniband.c
+++ b/epan/dissectors/packet-infiniband.c
@@ -105,7 +105,6 @@ static gint ett_tracerecord = -1;
static gint ett_multipathrecord = -1;
static gint ett_serviceassocrecord = -1;
static gint ett_perfclass = -1;
-static gint ett_eoib = -1;
static gint ett_link = -1;
/* Dissector Declaration */
@@ -160,7 +159,6 @@ static void parse_RDETH(proto_tree *, tvbuff_t *, gint *offset);
static void parse_IPvSix(proto_tree *, tvbuff_t *, gint *offset, packet_info *);
static void parse_RWH(proto_tree *, tvbuff_t *, gint *offset, packet_info *, proto_tree *);
static void parse_DCCETH(proto_tree *parentTree, tvbuff_t *tvb, gint *offset);
-static gboolean parse_EoIB(proto_tree *, tvbuff_t *, gint offset, packet_info *, proto_tree *);
static void parse_SUBN_LID_ROUTED(proto_tree *, packet_info *, tvbuff_t *, gint *offset);
static void parse_SUBN_DIRECTED_ROUTE(proto_tree *, packet_info *, tvbuff_t *, gint *offset);
@@ -728,8 +726,9 @@ static int hf_infiniband_sm_key = -1;
static int hf_infiniband_attribute_offset = -1;
static int hf_infiniband_component_mask = -1;
static int hf_infiniband_subnet_admin_data = -1;
+
/* Mellanox EoIB encapsulation header */
-static int hf_infiniband_EOIB = -1;
+static int proto_mellanox_eoib = -1;
static int hf_infiniband_ver = -1;
static int hf_infiniband_tcp_chk = -1;
static int hf_infiniband_ip_chk = -1;
@@ -738,6 +737,15 @@ static int hf_infiniband_ms = -1;
static int hf_infiniband_seg_off = -1;
static int hf_infiniband_seg_id = -1;
+static gint ett_eoib = -1;
+
+#define MELLANOX_VERSION_FLAG 0x3000
+#define MELLANOX_TCP_CHECKSUM_FLAG 0x0C00
+#define MELLANOX_IP_CHECKSUM_FLAG 0x0300
+#define MELLANOX_FCS_PRESENT_FLAG 0x0040
+#define MELLANOX_MORE_SEGMENT_FLAG 0x0020
+#define MELLANOX_SEGMENT_FLAG 0x001F
+
/* Attributes
* Additional Structures for individuala attribute decoding.
* Since they are not headers the naming convention is slightly modified
@@ -1495,8 +1503,6 @@ static guint32 opCode_PAYLD[] = {
* }; */
/* settings to be set by the user via the preferences dialog */
-static gboolean pref_dissect_eoib = TRUE;
-static gboolean pref_identify_iba_payload = TRUE;
static guint pref_rroce_udp_port = DEFAULT_RROCE_UDP_PORT;
/* saves information about connections that have been/are in the process of being
@@ -1591,7 +1597,7 @@ dissect_infiniband_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
/* General Variables */
gboolean bthFollows = FALSE; /* Tracks if we are parsing a BTH. This is a significant decision point */
- struct infinibandinfo info = { 0, FALSE, 0};
+ struct infinibandinfo info = { 0, FALSE, 0, NULL};
gint32 nextHeaderSequence = -1; /* defined by this dissector. #define which indicates the upcoming header sequence from OpCode */
guint8 nxtHdr = 0; /* Keyed off for header dissection order */
guint16 packetLength = 0; /* Packet Length. We track this as tvb_length - offset. */
@@ -2403,9 +2409,6 @@ static void parse_PAYLOAD(proto_tree *parentTree,
guint8 management_class;
tvbuff_t *volatile next_tvb;
gint reported_length;
- guint16 etype, reserved;
- const char *saved_proto;
- volatile gboolean dissector_found = FALSE;
heur_dtbl_entry_t *hdtbl_entry;
if (!tvb_bytes_exist(tvb, *offset, length)) /* previously consumed bytes + offset was all the data - none or corrupt payload */
@@ -2486,104 +2489,25 @@ static void parse_PAYLOAD(proto_tree *parentTree,
*/
update_sport(pinfo);
+ info->payload_tree = parentTree;
+
/* Calculation for Payload:
* (tvb_length) Length of entire packet - (local_offset) Starting byte of Payload Data
* offset addition is more complex for the payload.
* We need the total length of the packet, - length of previous headers, + offset where payload started.
* We also need to reserve 6 bytes for the CRCs which are not actually part of the payload. */
-
- etype = tvb_get_ntohs(tvb, local_offset);
- reserved = tvb_get_ntohs(tvb, local_offset + 2);
-
- /* try to recognize whether or not this is a Mellanox EoIB packet by the
- transport type and the 4 first bits of the payload */
- if (pref_dissect_eoib &&
- (((info->opCode & 0xE0) >> 5) == TRANSPORT_UD) &&
- (tvb_get_bits8(tvb, local_offset*8, 4) == 0xC)) {
- dissector_found = parse_EoIB(parentTree, tvb, local_offset, pinfo, top_tree);
- }
-
- /* IBA packet data could be anything in principle, however it is common
- * practice to carry non-IBA data encapsulated with an EtherType header,
- * similar to the RWH header. There is no way to identify these frames
- * positively.
- *
- * If the appropriate option is set in protocol preferences,
- * We see if the first few bytes look like an EtherType header, and if so
- * call the appropriate dissector. If not we call the "data" dissector.
- */
- if (!dissector_found && pref_identify_iba_payload && (reserved == 0)) {
- next_tvb = tvb_new_subset_remaining(tvb, local_offset+4);
-
- /* Look for sub-dissector, and call it if found.
- Catch exceptions, so that if the reported length of "next_tvb"
- was reduced by some dissector before an exception was thrown,
- we can still put in an item for the trailer. */
- saved_proto = pinfo->current_proto;
-
- TRY {
- dissector_found = dissector_try_uint(ethertype_dissector_table,
- etype, next_tvb, pinfo, top_tree);
- }
- CATCH_NONFATAL_ERRORS {
- /* Somebody threw an exception that means that there
- was a problem dissecting the payload; that means
- that a dissector was found, so we don't need to
- dissect the payload as data or update the protocol
- or info columns.
-
- Just show the exception and then drive on to show
- the trailer, after noting that a dissector was found
- and restoring the protocol value that was in effect
- before we called the subdissector.
- */
-
- show_exception(next_tvb, pinfo, top_tree, EXCEPT_CODE, GET_MESSAGE);
- dissector_found = TRUE;
- pinfo->current_proto = saved_proto;
- }
- ENDTRY;
-
- if (dissector_found) {
- proto_item *PAYLOAD_header_item;
- proto_tree *PAYLOAD_header_tree;
- /* now create payload entry to show Ethertype */
- PAYLOAD_header_item = proto_tree_add_item(parentTree, hf_infiniband_payload, tvb, local_offset, tvb_reported_length_remaining(tvb, local_offset)-6, ENC_NA);
- proto_item_set_text(PAYLOAD_header_item, "%s", "IBA Payload - appears to be EtherType encapsulated");
- PAYLOAD_header_tree = proto_item_add_subtree(PAYLOAD_header_item, ett_payload);
- proto_tree_add_uint(PAYLOAD_header_tree, hf_infiniband_etype, tvb,
- local_offset, 2, tvb_get_ntohs(tvb, local_offset));
-
- local_offset += 2;
-
- proto_tree_add_uint(PAYLOAD_header_tree, hf_infiniband_reserved16_RWH, tvb,
- local_offset, 2, tvb_get_ntohs(tvb, local_offset));
-
- }
-
- }
-
- reported_length = tvb_reported_length_remaining(tvb,
- local_offset);
-
+ reported_length = tvb_reported_length_remaining(tvb, local_offset);
if (reported_length >= crclen)
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_found) {
- dissector_found = dissector_try_heuristic(heur_dissectors_payload, next_tvb, pinfo, parentTree, &hdtbl_entry, info);
- }
-
- if (!dissector_found) {
+ if (!dissector_try_heuristic(heur_dissectors_payload, next_tvb, pinfo, top_tree, &hdtbl_entry, info)) {
/* No sub-dissector found.
Label rest of packet as "Data" */
call_data_dissector(next_tvb, pinfo, top_tree);
-
}
- /*parse_RWH(parentTree, tvb, &local_offset, pinfo, top_tree);*/
-
/* Will contain ICRC <and maybe VCRC> = 4 or 4+2 (crclen) */
local_offset = tvb_reported_length(tvb) - crclen;
}
@@ -2687,49 +2611,126 @@ static void parse_RWH(proto_tree *ah_tree, tvbuff_t *tvb, gint *offset, packet_i
* IN: The current offset
* IN: pinfo - packet info from wireshark
* IN: top_tree - parent tree of Infiniband dissector */
-static gboolean parse_EoIB(proto_tree *tree, tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *top_tree)
+static gboolean dissect_mellanox_eoib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
proto_item *header_item;
proto_tree *header_subtree;
- gboolean ms;
- gint8 seg_offset;
tvbuff_t *encap_tvb;
- /* the encapsulated eoib size (including the header!) is remaining length-6 bytes of CRC */
- int encap_size = tvb_reported_length_remaining(tvb, offset) - 6;
+ int offset = 0;
+ gboolean more_segments;
+ struct infinibandinfo *info = (struct infinibandinfo *)data;
- if (encap_size < 4) {
+ if (((info->opCode & 0xE0) >> 5) != TRANSPORT_UD)
+ return FALSE;
+
+ if ((tvb_get_guint8(tvb, offset) & 0xF0) != 0xC0)
+ return FALSE;
+
+ if (tvb_reported_length(tvb) < 4) {
/* not even large enough to contain the eoib encap header. error! */
return FALSE;
}
- encap_tvb = tvb_new_subset_length(tvb, offset + 4, encap_size - 4);
-
- header_item = proto_tree_add_item(tree, hf_infiniband_EOIB, tvb, offset, 4, ENC_NA);
+ header_item = proto_tree_add_item(tree, proto_mellanox_eoib, tvb, offset, 4, ENC_NA);
header_subtree = proto_item_add_subtree(header_item, ett_eoib);
proto_tree_add_item(header_subtree, hf_infiniband_ver, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(header_subtree, hf_infiniband_tcp_chk, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(header_subtree, hf_infiniband_ip_chk, tvb, offset, 2, ENC_BIG_ENDIAN);
proto_tree_add_item(header_subtree, hf_infiniband_fcs, tvb, offset, 2, ENC_BIG_ENDIAN);
-
- ms = tvb_get_bits8(tvb, (offset + 1)*8 + 2, 1);
- seg_offset = tvb_get_bits8(tvb, (offset + 1)*8 + 3, 5);
-
proto_tree_add_item(header_subtree, hf_infiniband_ms, tvb, offset, 2, ENC_BIG_ENDIAN);
- proto_tree_add_item(header_subtree, hf_infiniband_seg_off, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2;
+ proto_tree_add_item(header_subtree, hf_infiniband_seg_off, tvb, offset, 2, ENC_BIG_ENDIAN);
+ more_segments = tvb_get_ntohs(tvb, offset) & (MELLANOX_MORE_SEGMENT_FLAG | MELLANOX_SEGMENT_FLAG);
+ offset += 2;
proto_tree_add_item(header_subtree, hf_infiniband_seg_id, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
- if (seg_offset || ms) {
+ encap_tvb = tvb_new_subset_remaining(tvb, offset);
+
+ if (more_segments) {
/* this is a fragment of an encapsulated Ethernet jumbo frame, parse as data */
- call_data_dissector(encap_tvb, pinfo, top_tree);
+ call_data_dissector(encap_tvb, pinfo, tree);
} else {
/* non-fragmented frames can be fully parsed */
- call_dissector(eth_handle, encap_tvb, pinfo, top_tree);
+ call_dissector(eth_handle, encap_tvb, pinfo, tree);
}
return TRUE;
}
+/* IBA packet data could be anything in principle, however it is common
+ * practice to carry non-IBA data encapsulated with an EtherType header,
+ * similar to the RWH header. There is no way to identify these frames
+ * positively.
+ */
+static gboolean dissect_eth_over_ib(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
+{
+ guint16 etype, reserved;
+ const char *saved_proto;
+ int offset = 0;
+ tvbuff_t *next_tvb;
+ struct infinibandinfo *info = (struct infinibandinfo *)data;
+ volatile gboolean dissector_found = FALSE;
+
+ if (tvb_reported_length(tvb) < 4) {
+ /* not even large enough to contain the eoib encap header. error! */
+ return FALSE;
+ }
+
+ etype = tvb_get_ntohs(tvb, offset);
+ reserved = tvb_get_ntohs(tvb, offset + 2);
+
+ if (reserved != 0)
+ return FALSE;
+
+ next_tvb = tvb_new_subset_remaining(tvb, offset+4);
+
+ /* Look for sub-dissector, and call it if found.
+ Catch exceptions, so that if the reported length of "next_tvb"
+ was reduced by some dissector before an exception was thrown,
+ we can still put in an item for the trailer. */
+ saved_proto = pinfo->current_proto;
+
+ TRY {
+ dissector_found = dissector_try_uint(ethertype_dissector_table,
+ etype, next_tvb, pinfo, tree);
+ }
+ CATCH_NONFATAL_ERRORS {
+ /* Somebody threw an exception that means that there
+ was a problem dissecting the payload; that means
+ that a dissector was found, so we don't need to
+ dissect the payload as data or update the protocol
+ or info columns.
+
+ Just show the exception and then drive on to show
+ the trailer, after noting that a dissector was found
+ and restoring the protocol value that was in effect
+ before we called the subdissector.
+ */
+
+ show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
+ dissector_found = TRUE;
+ pinfo->current_proto = saved_proto;
+ }
+ ENDTRY;
+
+ if (dissector_found) {
+ proto_item *PAYLOAD_header_item;
+ proto_tree *PAYLOAD_header_tree;
+
+ /* now create payload entry to show Ethertype */
+ PAYLOAD_header_item = proto_tree_add_item(info->payload_tree, hf_infiniband_payload, tvb, offset, tvb_reported_length_remaining(tvb, offset)-6, ENC_NA);
+ proto_item_set_text(PAYLOAD_header_item, "%s", "IBA Payload - appears to be EtherType encapsulated");
+ PAYLOAD_header_tree = proto_item_add_subtree(PAYLOAD_header_item, ett_payload);
+
+ proto_tree_add_item(PAYLOAD_header_tree, hf_infiniband_etype, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(PAYLOAD_header_tree, hf_infiniband_reserved16_RWH, tvb, offset, 2, ENC_BIG_ENDIAN);
+
+ }
+
+ return dissector_found;
+}
/* Parse Subnet Management (LID Routed)
* IN: parentTree to add the dissection to
@@ -3473,7 +3474,7 @@ static void parse_CM_DRsp(proto_tree *parentTree, packet_info *pinfo, tvbuff_t *
static void parse_COM_MGT(proto_tree *parentTree, packet_info *pinfo, tvbuff_t *tvb, gint *offset)
{
MAD_Data MadData;
- struct infinibandinfo info = { 0, FALSE, 0};
+ struct infinibandinfo info = { 0, FALSE, 0, NULL};
gint local_offset;
const char *label;
proto_item *CM_header_item;
@@ -5280,7 +5281,7 @@ static void dissect_general_info(tvbuff_t *tvb, gint offset, packet_info *pinfo,
MAD_Data MadData;
/* BTH - Base Trasport Header */
- struct infinibandinfo info = { 0, FALSE, 0};
+ struct infinibandinfo info = { 0, FALSE, 0, NULL};
gint bthSize = 12;
void *src_addr, /* the address to be displayed in the source/destination columns */
*dst_addr; /* (lid/gid number) will be stored here */
@@ -6443,40 +6444,6 @@ void proto_register_infiniband(void)
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL}
},
- /* Mellanox EoIB encapsulation header */
- { &hf_infiniband_EOIB, {
- "Mellanox EoIB Encapsulation Header", "infiniband.eoib",
- FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}
- },
- { &hf_infiniband_ver, {
- "Version", "infiniband.eoib.version",
- FT_UINT16, BASE_HEX, NULL, 0x3000, NULL, HFILL}
- },
- { &hf_infiniband_tcp_chk, {
- "TCP Checksum", "infiniband.eoib.tcp_chk",
- FT_UINT16, BASE_HEX, NULL, 0x0c00, NULL, HFILL}
- },
- { &hf_infiniband_ip_chk, {
- "IP Checksum", "infiniband.eoib.ip_chk",
- FT_UINT16, BASE_HEX, NULL, 0x0300, NULL, HFILL}
- },
- { &hf_infiniband_fcs, {
- "FCS Field Present", "infiniband.eoib.fcs",
- FT_BOOLEAN, 16, NULL, 0x0040, NULL, HFILL}
- },
- { &hf_infiniband_ms, {
- "More Segments to Follow", "infiniband.eoib.ms",
- FT_BOOLEAN, 16, NULL, 0x0020, NULL, HFILL}
- },
- { &hf_infiniband_seg_off, {
- "Segment Offset", "infiniband.eoib.ip_seg_offset",
- FT_UINT16, BASE_DEC, NULL, 0x001f, NULL, HFILL}
- },
- { &hf_infiniband_seg_id, {
- "Segment ID", "infiniband.eoib.ip_seg_id",
- FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
- },
-
/* NodeDescription */
{ &hf_infiniband_NodeDescription_NodeString, {
"NodeString", "infiniband.nodedescription.nodestring",
@@ -7881,7 +7848,6 @@ void proto_register_infiniband(void)
&ett_multipathrecord,
&ett_serviceassocrecord,
&ett_perfclass,
- &ett_eoib
};
static hf_register_info hf_link[] = {
@@ -7907,11 +7873,46 @@ void proto_register_infiniband(void)
}
};
-
static gint *ett_link_array[] = {
&ett_link
};
+ static hf_register_info hf_eoib[] = {
+ /* Mellanox EoIB encapsulation header */
+ { &hf_infiniband_ver, {
+ "Version", "infiniband.eoib.version",
+ FT_UINT16, BASE_HEX, NULL, MELLANOX_VERSION_FLAG, NULL, HFILL}
+ },
+ { &hf_infiniband_tcp_chk, {
+ "TCP Checksum", "infiniband.eoib.tcp_chk",
+ FT_UINT16, BASE_HEX, NULL, MELLANOX_TCP_CHECKSUM_FLAG, NULL, HFILL}
+ },
+ { &hf_infiniband_ip_chk, {
+ "IP Checksum", "infiniband.eoib.ip_chk",
+ FT_UINT16, BASE_HEX, NULL, MELLANOX_IP_CHECKSUM_FLAG, NULL, HFILL}
+ },
+ { &hf_infiniband_fcs, {
+ "FCS Field Present", "infiniband.eoib.fcs",
+ FT_BOOLEAN, 16, NULL, MELLANOX_FCS_PRESENT_FLAG, NULL, HFILL}
+ },
+ { &hf_infiniband_ms, {
+ "More Segments to Follow", "infiniband.eoib.ms",
+ FT_BOOLEAN, 16, NULL, MELLANOX_MORE_SEGMENT_FLAG, NULL, HFILL}
+ },
+ { &hf_infiniband_seg_off, {
+ "Segment Offset", "infiniband.eoib.ip_seg_offset",
+ FT_UINT16, BASE_DEC, NULL, MELLANOX_SEGMENT_FLAG, NULL, HFILL}
+ },
+ { &hf_infiniband_seg_id, {
+ "Segment ID", "infiniband.eoib.ip_seg_id",
+ FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ };
+
+ static gint *ett_eoib_array[] = {
+ &ett_eoib
+ };
+
proto_infiniband = proto_register_protocol("InfiniBand", "IB", "infiniband");
ib_handle = register_dissector("infiniband", dissect_infiniband, proto_infiniband);
@@ -7925,16 +7926,8 @@ void proto_register_infiniband(void)
/* register dissection preferences */
infiniband_module = prefs_register_protocol(proto_infiniband, proto_reg_handoff_infiniband);
- prefs_register_bool_preference(infiniband_module, "identify_payload",
- "Attempt to identify and parse encapsulated IBA payloads",
- "When set, dissector will attempt to identify unknown IBA payloads "
- "as containing an encapsulated ethertype, and parse them accordingly",
- &pref_identify_iba_payload);
- prefs_register_bool_preference(infiniband_module, "dissect_eoib",
- "Attempt to identify and parse Mellanox EoIB packets",
- "When set, dissector will attempt to identify and parse "
- "Mellanox Ethernet-over-InfiniBand packets",
- &pref_dissect_eoib);
+ prefs_register_obsolete_preference(infiniband_module, "identify_payload");
+ prefs_register_obsolete_preference(infiniband_module, "dissect_eoib");
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);
@@ -7945,6 +7938,10 @@ void proto_register_infiniband(void)
proto_register_field_array(proto_infiniband_link, hf_link, array_length(hf_link));
proto_register_subtree_array(ett_link_array, array_length(ett_link_array));
+ proto_mellanox_eoib = proto_register_protocol("Mellanox EoIB Encapsulation Header", "Mellanox EoIB", "infiniband.eoib");
+ proto_register_field_array(proto_infiniband, hf_eoib, array_length(hf_eoib));
+ proto_register_subtree_array(ett_eoib_array, array_length(ett_eoib_array));
+
/* initialize the hash table */
CM_context_table = g_hash_table_new_full(g_int64_hash, g_int64_equal,
table_destroy_notify, table_destroy_notify);
@@ -7956,6 +7953,7 @@ void proto_reg_handoff_infiniband(void)
static gboolean initialized = FALSE;
static guint prev_rroce_udp_port;
dissector_handle_t roce_handle, rroce_handle;
+ int proto_ethertype;
ipv6_handle = find_dissector_add_dependency("ipv6", proto_infiniband);
@@ -8006,6 +8004,12 @@ void proto_reg_handoff_infiniband(void)
dissector_add_uint("udp.port", pref_rroce_udp_port, rroce_handle);
dissector_add_uint("wtap_encap", WTAP_ENCAP_INFINIBAND, ib_handle);
+ heur_dissector_add("infiniband.payload", dissect_mellanox_eoib, "Mellanox EoIB", "mellanox_eoib", proto_mellanox_eoib, HEURISTIC_ENABLE);
+
+ /* This could be put in the ethernet dissector file, but since there are a few Infiniband fields in the encapsulation,
+ keep the dissector here, but associate it with ethernet */
+ proto_ethertype = proto_get_id_by_filter_name( "ethertype" );
+ heur_dissector_add("infiniband.payload", dissect_eth_over_ib, "Ethernet over IB", "eth_over_ib", proto_ethertype, HEURISTIC_ENABLE);
}
/*