aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>2010-08-16 05:48:40 +0000
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>2010-08-16 05:48:40 +0000
commit9d86c75240bd8a4756294dde2c0bd82dcf304ba4 (patch)
tree5ca76674dcd910b2c764139b4a9f6273ec8d93ec /epan/dissectors
parente01bcaed81403b7e1614bbf9b944930da5a8d8b2 (diff)
From Slava:
This patch adds to the Infiniband dissector the ability to dissect EoIB (Ethernet-over-Infiniband) traffic which uses Mellanox Technologies Ltd's standard for encapsulating Ethernet traffic inside Infiniband packets. This patch is submitted on behalf of Mellanox Technologies Ltd. https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=5061 git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@33808 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-infiniband.c99
-rw-r--r--epan/dissectors/packet-infiniband.h28
2 files changed, 126 insertions, 1 deletions
diff --git a/epan/dissectors/packet-infiniband.c b/epan/dissectors/packet-infiniband.c
index 3daf8dcbf5..660db0d9c4 100644
--- a/epan/dissectors/packet-infiniband.c
+++ b/epan/dissectors/packet-infiniband.c
@@ -303,6 +303,7 @@ skip_lrh:
* The find_next_header_sequence method could be used to automate this.
* We need to keep track of this so we know much data to mark as payload/ICRC/VCRC values. */
+ transport_type = (opCode & 0xE0) >> 5; /* save transport type for identifying EoIB payloads later... */
nextHeaderSequence = find_next_header_sequence((guint32) opCode);
/* find_next_header_sequence gives us the DEFINE value corresponding to the header order following */
@@ -968,7 +969,14 @@ static void parse_PAYLOAD(proto_tree *parentTree, packet_info *pinfo, tvbuff_t *
etype = tvb_get_ntohs(tvb, local_offset);
reserved = tvb_get_ntohs(tvb, local_offset + 2);
- if (pref_identify_iba_payload && reserved == 0) {
+ /* 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 &&
+ transport_type == TRANSPORT_UD &&
+ tvb_get_bits8(tvb, local_offset*8, 4) == 0xC) {
+ dissector_found = parse_EoIB(parentTree, tvb, local_offset, pinfo);
+ }
+ else if (pref_identify_iba_payload && reserved == 0) {
/* Get the captured length and reported length of the data
after the Ethernet type. */
@@ -1167,6 +1175,54 @@ static void parse_RWH(proto_tree *ah_tree, tvbuff_t *tvb, gint *offset, packet_i
proto_tree_add_item(ah_tree, hf_infiniband_variant_crc, tvb, *offset, 2, FALSE);
}
+/* Parse a Mellanox EoIB Encapsulation Header and the associated Ethernet frame
+* IN: parentTree to add the dissection to - in this code the all_headers_tree
+* IN: tvb - the data buffer from wireshark
+* IN: The current offset
+* IN: pinfo - packet info from wireshark */
+static gboolean parse_EoIB(proto_tree *tree, tvbuff_t *tvb, gint offset, packet_info *pinfo)
+{
+ 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;
+
+ if (encap_size < 4) {
+ /* not even large enough to contain the eoib encap header. error! */
+ return FALSE;
+ }
+
+ encap_tvb = tvb_new_subset(tvb, offset + 4, tvb_length_remaining(tvb, offset + 4), encap_size - 4);
+
+ header_item = proto_tree_add_item(tree, hf_infiniband_EOIB, tvb, offset, 4, FALSE);
+ header_subtree = proto_item_add_subtree(header_item, ett_eoib);
+
+ proto_tree_add_item(header_subtree, hf_infiniband_ver, tvb, offset, 2, FALSE);
+ proto_tree_add_item(header_subtree, hf_infiniband_tcp_chk, tvb, offset, 2, FALSE);
+ proto_tree_add_item(header_subtree, hf_infiniband_ip_chk, tvb, offset, 2, FALSE);
+ proto_tree_add_item(header_subtree, hf_infiniband_fcs, tvb, offset, 2, FALSE);
+
+ 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, FALSE);
+ proto_tree_add_item(header_subtree, hf_infiniband_seg_off, tvb, offset, 2, FALSE); offset += 2;
+ proto_tree_add_item(header_subtree, hf_infiniband_seg_id, tvb, offset, 2, FALSE); offset += 2;
+
+ if (seg_offset || ms) {
+ /* this is a fragment of an encapsulated Ethernet jumbo frame, parse as data */
+ call_dissector(data_handle, encap_tvb, pinfo, top_tree);
+ } else {
+ /* non-fragmented frames can be fully parsed */
+ call_dissector(eth_handle, encap_tvb, pinfo, top_tree);
+ }
+
+ return TRUE;
+}
+
/* Parse Subnet Management (LID Routed)
* IN: parentTree to add the dissection to
* IN: pinfo - packet info from wireshark
@@ -3853,6 +3909,40 @@ 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",
@@ -5217,6 +5307,7 @@ void proto_register_infiniband(void)
&ett_multipathrecord,
&ett_serviceassocrecord,
&ett_perfclass,
+ &ett_eoib
};
static hf_register_info hf_link[] = {
@@ -5261,6 +5352,11 @@ void proto_register_infiniband(void)
"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);
proto_infiniband_link = proto_register_protocol("InfiniBand Link", "InfiniBand Link", "infiniband_link");
register_dissector("infiniband_link", dissect_infiniband_link, proto_infiniband_link);
@@ -5277,6 +5373,7 @@ void proto_reg_handoff_infiniband(void)
ipv6_handle = find_dissector("ipv6");
data_handle = find_dissector("data");
+ eth_handle = find_dissector("eth");
ethertype_dissector_table = find_dissector_table("ethertype");
/* create and announce an anonymous RoCE dissector */
diff --git a/epan/dissectors/packet-infiniband.h b/epan/dissectors/packet-infiniband.h
index 817b3130f0..22770cdfdc 100644
--- a/epan/dissectors/packet-infiniband.h
+++ b/epan/dissectors/packet-infiniband.h
@@ -87,6 +87,7 @@ 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;
@@ -111,6 +112,7 @@ typedef struct {
/* Dissector Declarations */
static dissector_handle_t ipv6_handle;
static dissector_handle_t data_handle;
+static dissector_handle_t eth_handle;
static dissector_table_t ethertype_dissector_table;
static void dissect_roce(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
@@ -135,6 +137,7 @@ static void parse_DETH(proto_tree *, tvbuff_t *, gint *offset, gint* src_qp);
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 *);
+static gboolean parse_EoIB(proto_tree *, tvbuff_t *, gint offset, packet_info *);
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);
@@ -575,6 +578,15 @@ 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 hf_infiniband_ver = -1;
+static int hf_infiniband_tcp_chk = -1;
+static int hf_infiniband_ip_chk = -1;
+static int hf_infiniband_fcs = -1;
+static int hf_infiniband_ms = -1;
+static int hf_infiniband_seg_off = -1;
+static int hf_infiniband_seg_id = -1;
/* Attributes
* Additional Structures for individuala attribute decoding.
@@ -1252,6 +1264,16 @@ static const value_string OpCodeMap[] =
/* ___________________________________ */
+/* Infiniband transport services
+ These are an enumeration of the transport services over which an IB packet
+ might be sent. The values match the corresponding 3 bits of the opCode field
+ in the BTH */
+#define TRANSPORT_RC 0
+#define TRANSPORT_UC 1
+#define TRANSPORT_RD 2
+#define TRANSPORT_UD 3
+
+
/* Array of all availavle OpCodes to make matching a bit easier.
* The OpCodes dictate the header sequence following in the packet.
* These arrays tell the dissector which headers must be decoded for the given OpCode. */
@@ -1381,4 +1403,10 @@ static gchar *src_addr_str = NULL, /* the string to be displayed in the sour
/* settings to be set by the user via the preferences dialog */
static gboolean pref_identify_iba_payload = TRUE;
+static gint8 transport_type = -1; /* reflects the transport type of the packet being parsed.
+ only use one of the TRANSPORT_* values for this field */
+
+/* settings to be set by the user via the preferences dialog */
+static gboolean pref_dissect_eoib = TRUE;
+
#endif