aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2008-03-14 17:47:53 +0000
committerGerald Combs <gerald@wireshark.org>2008-03-14 17:47:53 +0000
commit68d23708bc686821b0df3c3ffaaf233cca6e4eee (patch)
tree73c5653c388e74ea09b7f70042a978dc23b9f2f2
parent14e0b8f79233987dde0b88aec2667cf9244c9585 (diff)
From Stephen Donnelly via bug 2235:
This plugin implements a dissector for Infiniband. It is released under the GPL v2. Rather than using say libpcap to capture raw (unframed) IP packets from near the top of an IPoIB stack, this plugin dissects link level Infiniband frames. Infiniband trace files can be read from Endace ERF format trace files, or from libpcap DLT_ERF files containing ERF TYPE_INFINIBAND records. There is currently no native DLT_INFINIBAND in libpcap. Each record contains a hardware timestamp, capture metadata such as port Id, and a complete link level Infiniband frame starting from the Local Route Header. svn path=/trunk/; revision=24628
-rw-r--r--AUTHORS4
-rw-r--r--Makefile.am1
-rw-r--r--configure.in1
-rw-r--r--epan/dissectors/packet-erf.c27
-rw-r--r--plugins/Makefile.am1
-rw-r--r--plugins/Makefile.nmake4
-rw-r--r--plugins/infiniband/Makefile.am119
-rw-r--r--plugins/infiniband/Makefile.common26
-rw-r--r--plugins/infiniband/Makefile.nmake96
-rw-r--r--plugins/infiniband/moduleinfo.h18
-rw-r--r--plugins/infiniband/moduleinfo.nmake28
-rw-r--r--plugins/infiniband/packet-infiniband.c857
-rw-r--r--plugins/infiniband/packet-infiniband.h686
-rw-r--r--plugins/infiniband/plugin.rc.in34
-rw-r--r--wiretap/erf.c11
-rw-r--r--wiretap/erf.h1
16 files changed, 1912 insertions, 2 deletions
diff --git a/AUTHORS b/AUTHORS
index 47b3ed31bc..b798301682 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -2732,6 +2732,10 @@ Hannes Kälber <hannes.kaelber--wireshark [AT] x2e.de> {
Automotive DLTs
}
+Stephen Donnelly <stephen [AT] endace.com> {
+ Infiniband support
+}
+
and by:
Pavel Roskin <proski [AT] gnu.org>
diff --git a/Makefile.am b/Makefile.am
index a94c6c8d07..f4097da423 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -246,6 +246,7 @@ plugin_ldadd = \
-dlopen plugins/giop/cosnaming.la \
-dlopen plugins/giop/coseventcomm.la \
-dlopen plugins/gryphon/gryphon.la \
+ -dlopen plugins/infiniband/infiniband.la \
-dlopen plugins/irda/irda.la \
-dlopen plugins/lwres/lwres.la \
-dlopen plugins/m2m/m2m.la \
diff --git a/configure.in b/configure.in
index 6085949e93..de8e5f82c1 100644
--- a/configure.in
+++ b/configure.in
@@ -1685,6 +1685,7 @@ AC_OUTPUT(
plugins/ethercat/Makefile
plugins/giop/Makefile
plugins/gryphon/Makefile
+ plugins/infiniband/Makefile
plugins/irda/Makefile
plugins/lwres/Makefile
plugins/m2m/Makefile
diff --git a/epan/dissectors/packet-erf.c b/epan/dissectors/packet-erf.c
index 69a01b9202..10bd8ff597 100644
--- a/epan/dissectors/packet-erf.c
+++ b/epan/dissectors/packet-erf.c
@@ -143,6 +143,11 @@ static gint ett_erf_eth = -1;
/* Default subdissector, display raw hex data */
static dissector_handle_t data_handle;
+// Possible there will be more in the future
+#define ERF_INFINIBAND 1
+gint erf_infiniband_default = ERF_INFINIBAND;
+static dissector_handle_t erf_infiniband_dissector[ERF_INFINIBAND];
+
typedef enum {
ERF_HDLC_CHDLC = 1,
ERF_HDLC_PPP = 2,
@@ -267,6 +272,7 @@ static const value_string erf_type_vals[] = {
{ ERF_TYPE_COLOR_MC_HDLC_POS,"COLOR_MC_HDLC_POS"},
{ ERF_TYPE_AAL2,"AAL2"},
{ ERF_TYPE_PAD,"PAD"},
+ { ERF_TYPE_INFINIBAND, "INFINIBAND"},
{0, NULL}
};
/* Copy of atm_guess_traffic_type from atm.c in /wiretap */
@@ -608,6 +614,10 @@ dissect_erf_header(tvbuff_t *erf_tvb, packet_info *pinfo, proto_tree *erf_tree,
switch(erf_type) {
+ case ERF_TYPE_INFINIBAND:
+ //if(data_handle) // no infiniband header but there might be later on
+ // call_dissector(data_handle, tvb, pinfo, tree);
+ break;
case ERF_TYPE_LEGACY:
case ERF_TYPE_IP_COUNTER:
case ERF_TYPE_TCP_FLOW_COUNTER:
@@ -756,6 +766,8 @@ dissect_erf_header(tvbuff_t *erf_tvb, packet_info *pinfo, proto_tree *erf_tree,
static void
dissect_erf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
+ guint8 erf_type = 0;
+ dissector_handle_t infiniband_dissector = NULL;
proto_item *erf_item = NULL;
proto_tree *erf_tree = NULL;
@@ -768,6 +780,17 @@ dissect_erf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
};
dissect_erf_header(tvb, pinfo, erf_tree, tree);
+
+ if (pinfo->pseudo_header)
+ {
+ erf_type = pinfo->pseudo_header->erf.phdr.type;
+ }
+ if(erf_type == ERF_TYPE_INFINIBAND)
+ {
+ infiniband_dissector = find_dissector("infiniband");
+ call_dissector(infiniband_dissector, tvb, pinfo, erf_tree);
+ }
+
}
void
@@ -933,6 +956,10 @@ proto_reg_handoff_erf(void)
/* Dissector called to dump raw data, or unknown protocol */
data_handle = find_dissector("data");
+
+ /* Create ERF_INFINIBAND dissectors */
+ erf_infiniband_dissector[ERF_INFINIBAND] = find_dissector("infiniband");
+
/* Create ERF_HDLC dissectors table */
erf_hdlc_dissector[ERF_HDLC_CHDLC] = find_dissector("chdlc");
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 32aa95b6c5..a1acbe35c0 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -32,6 +32,7 @@ SUBDIRS = \
giop \
gryphon \
irda \
+ infiniband \
lwres \
m2m \
mate \
diff --git a/plugins/Makefile.nmake b/plugins/Makefile.nmake
index e80dfa0de6..71e5e36e3e 100644
--- a/plugins/Makefile.nmake
+++ b/plugins/Makefile.nmake
@@ -56,6 +56,9 @@ process-plugins:
cd gryphon
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake $(PLUGIN_TARGET)
cd ..
+ cd infiniband
+ $(MAKE) /$(MAKEFLAGS) -f Makefile.nmake $(PLUGIN_TARGET)
+ cd ..
cd irda
$(MAKE) /$(MAKEFLAGS) -f Makefile.nmake $(PLUGIN_TARGET)
cd ..
@@ -127,6 +130,7 @@ install-plugins:
xcopy ethercat\*.dll $(VERSION) /d
xcopy giop\*.dll $(VERSION) /d
xcopy gryphon\*.dll $(VERSION) /d
+ xcopy infiniband\*.dll $(VERSION) /d
xcopy irda\*.dll $(VERSION) /d
xcopy lwres\*.dll $(VERSION) /d
xcopy m2m\*.dll $(VERSION) /d
diff --git a/plugins/infiniband/Makefile.am b/plugins/infiniband/Makefile.am
new file mode 100644
index 0000000000..f3eb08be3d
--- /dev/null
+++ b/plugins/infiniband/Makefile.am
@@ -0,0 +1,119 @@
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+INCLUDES = -I$(top_srcdir) -I$(includedir)
+
+include Makefile.common
+
+if HAVE_WARNINGS_AS_ERRORS
+AM_CFLAGS = -Werror
+endif
+
+plugindir = @plugindir@
+
+plugin_LTLIBRARIES = infiniband.la
+infiniband_la_SOURCES = \
+ plugin.c \
+ moduleinfo.h \
+ $(DISSECTOR_SRC)
+infiniband_la_LDFLAGS = -module -avoid-version
+infiniband_la_LIBADD = @PLUGIN_LIBS@
+
+# Libs must be cleared, or else libtool won't create a shared module.
+# If your module needs to be linked against any particular libraries,
+# add them here.
+LIBS =
+
+#
+# Build plugin.c, which contains the plugin version[] string, a
+# function plugin_register() that calls the register routines for all
+# protocols, and a function plugin_reg_handoff() that calls the handoff
+# registration routines for all protocols.
+#
+# We do this by scanning sources. If that turns out to be too slow,
+# maybe we could just require every .o file to have an register routine
+# of a given name (packet-aarp.o -> proto_register_aarp, etc.).
+#
+# Formatting conventions: The name of the proto_register_* routines an
+# proto_reg_handoff_* routines must start in column zero, or must be
+# preceded only by "void " starting in column zero, and must not be
+# inside #if.
+#
+# DISSECTOR_SRC is assumed to have all the files that need to be scanned.
+#
+# For some unknown reason, having a big "for" loop in the Makefile
+# to scan all the files doesn't work with some "make"s; they seem to
+# pass only the first few names in the list to the shell, for some
+# reason.
+#
+# Therefore, we have a script to generate the plugin.c file.
+# The shell script runs slowly, as multiple greps and seds are run
+# for each input file; this is especially slow on Windows. Therefore,
+# if Python is present (as indicated by PYTHON being defined), we run
+# a faster Python script to do that work instead.
+#
+# The first argument is the directory in which the source files live.
+# The second argument is "plugin", to indicate that we should build
+# a plugin.c file for a plugin.
+# All subsequent arguments are the files to scan.
+#
+plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \
+ $(top_srcdir)/tools/make-dissector-reg.py
+ @if test -n $(PYTHON); then \
+ echo Making plugin.c with python ; \
+ $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \
+ plugin $(DISSECTOR_SRC) ; \
+ else \
+ echo Making plugin.c with shell script ; \
+ $(top_srcdir)/tools/make-dissector-reg $(srcdir) \
+ $(plugin_src) plugin $(DISSECTOR_SRC) ; \
+ fi
+
+#
+# Currently plugin.c can be included in the distribution because
+# we always build all protocol dissectors. We used to have to check
+# whether or not to build the snmp dissector. If we again need to
+# variably build something, making plugin.c non-portable, uncomment
+# the dist-hook line below.
+#
+# Oh, yuk. We don't want to include "plugin.c" in the distribution, as
+# its contents depend on the configuration, and therefore we want it
+# to be built when the first "make" is done; however, Automake insists
+# on putting *all* source into the distribution.
+#
+# We work around this by having a "dist-hook" rule that deletes
+# "plugin.c", so that "dist" won't pick it up.
+#
+#dist-hook:
+# @rm -f $(distdir)/plugin.c
+
+CLEANFILES = \
+ infiniband \
+ *~
+
+MAINTAINERCLEANFILES = \
+ Makefile.in \
+ plugin.c
+
+EXTRA_DIST = \
+ Makefile.common \
+ Makefile.nmake \
+ moduleinfo.nmake \
+ plugin.rc.in
diff --git a/plugins/infiniband/Makefile.common b/plugins/infiniband/Makefile.common
new file mode 100644
index 0000000000..e179814048
--- /dev/null
+++ b/plugins/infiniband/Makefile.common
@@ -0,0 +1,26 @@
+#
+# Wireshark - Network traffic analyzer
+# By Gerald Combs <gerald@wireshark.org>
+# Copyright 1998 Gerald Combs
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# the name of the plugin
+PLUGIN_NAME = infiniband
+
+# the dissector sources (without any helpers)
+DISSECTOR_SRC = \
+ packet-infiniband.c
+
diff --git a/plugins/infiniband/Makefile.nmake b/plugins/infiniband/Makefile.nmake
new file mode 100644
index 0000000000..6f0cfe4b1e
--- /dev/null
+++ b/plugins/infiniband/Makefile.nmake
@@ -0,0 +1,96 @@
+# Makefile.nmake
+# nmake file for Wireshark plugin
+#
+# $Id: Makefile.nmake 21963 2007-05-27 18:56:39Z guy $
+#
+
+include ..\..\config.nmake
+include moduleinfo.nmake
+
+include Makefile.common
+
+CFLAGS=/WX /DHAVE_CONFIG_H /I../.. /I../../wiretap $(GLIB_CFLAGS) \
+ /I$(PCAP_DIR)\include -D_U_="" $(LOCAL_CFLAGS)
+
+LDFLAGS = $(PLUGIN_LDFLAGS)
+
+!IFDEF ENABLE_LIBWIRESHARK
+LINK_PLUGIN_WITH=..\..\epan\libwireshark.lib
+CFLAGS=/DHAVE_WIN32_LIBWIRESHARK_LIB /D_NEED_VAR_IMPORT_ $(CFLAGS)
+
+DISSECTOR_OBJECTS = $(DISSECTOR_SRC:.c=.obj)
+
+DISSECTOR_SUPPORT_OBJECTS = $(DISSECTOR_SUPPORT_SRC:.c=.obj)
+
+OBJECTS = $(DISSECTOR_OBJECTS) $(DISSECTOR_SUPPORT_OBJECTS) plugin.obj
+
+RESOURCE=$(PLUGIN_NAME).res
+
+all: $(PLUGIN_NAME).dll
+
+$(PLUGIN_NAME).rc : moduleinfo.nmake
+ sed -e s/@PLUGIN_NAME@/$(PLUGIN_NAME)/ \
+ -e s/@RC_MODULE_VERSION@/$(RC_MODULE_VERSION)/ \
+ -e s/@RC_VERSION@/$(RC_VERSION)/ \
+ -e s/@MODULE_VERSION@/$(MODULE_VERSION)/ \
+ -e s/@PACKAGE@/$(PACKAGE)/ \
+ -e s/@VERSION@/$(VERSION)/ \
+ -e s/@MSVC_VARIANT@/$(MSVC_VARIANT)/ \
+ < plugin.rc.in > $@
+
+$(PLUGIN_NAME).dll $(PLUGIN_NAME).exp $(PLUGIN_NAME).lib : $(OBJECTS) $(LINK_PLUGIN_WITH) $(RESOURCE)
+ link -dll /out:$(PLUGIN_NAME).dll $(LDFLAGS) $(OBJECTS) $(LINK_PLUGIN_WITH) \
+ $(GLIB_LIBS) $(RESOURCE)
+
+#
+# Build plugin.c, which contains the plugin version[] string, a
+# function plugin_register() that calls the register routines for all
+# protocols, and a function plugin_reg_handoff() that calls the handoff
+# registration routines for all protocols.
+#
+# We do this by scanning sources. If that turns out to be too slow,
+# maybe we could just require every .o file to have an register routine
+# of a given name (packet-aarp.o -> proto_register_aarp, etc.).
+#
+# Formatting conventions: The name of the proto_register_* routines an
+# proto_reg_handoff_* routines must start in column zero, or must be
+# preceded only by "void " starting in column zero, and must not be
+# inside #if.
+#
+# DISSECTOR_SRC is assumed to have all the files that need to be scanned.
+#
+# For some unknown reason, having a big "for" loop in the Makefile
+# to scan all the files doesn't work with some "make"s; they seem to
+# pass only the first few names in the list to the shell, for some
+# reason.
+#
+# Therefore, we have a script to generate the plugin.c file.
+# The shell script runs slowly, as multiple greps and seds are run
+# for each input file; this is especially slow on Windows. Therefore,
+# if Python is present (as indicated by PYTHON being defined), we run
+# a faster Python script to do that work instead.
+#
+# The first argument is the directory in which the source files live.
+# The second argument is "plugin", to indicate that we should build
+# a plugin.c file for a plugin.
+# All subsequent arguments are the files to scan.
+#
+plugin.c: $(DISSECTOR_SRC) ../../tools/make-dissector-reg.py ../../tools/make-dissector-reg
+!IFDEF PYTHON
+ @echo Making plugin.c (using python)
+ @$(PYTHON) "../../tools/make-dissector-reg.py" . plugin $(DISSECTOR_SRC)
+!ELSE
+ @echo Making plugin.c (using sh)
+ @$(SH) ../../tools/make-dissector-reg . plugin $(DISSECTOR_SRC)
+!ENDIF
+
+!ENDIF
+
+clean:
+ rm -f $(OBJECTS) $(RESOURCE) plugin.c *.pdb \
+ $(PLUGIN_NAME).dll $(PLUGIN_NAME).dll.manifest $(PLUGIN_NAME).lib \
+ $(PLUGIN_NAME).exp $(PLUGIN_NAME).rc
+
+distclean: clean
+
+maintainer-clean: distclean
diff --git a/plugins/infiniband/moduleinfo.h b/plugins/infiniband/moduleinfo.h
new file mode 100644
index 0000000000..2c7ded04d2
--- /dev/null
+++ b/plugins/infiniband/moduleinfo.h
@@ -0,0 +1,18 @@
+/* Included *after* config.h, in order to re-define these macros */
+
+#ifdef PACKAGE
+#undef PACKAGE
+#endif
+
+/* Name of package */
+#define PACKAGE "infiniband"
+
+
+#ifdef VERSION
+#undef VERSION
+#endif
+
+/* Version number of package */
+#define VERSION "1.0.1.0"
+
+
diff --git a/plugins/infiniband/moduleinfo.nmake b/plugins/infiniband/moduleinfo.nmake
new file mode 100644
index 0000000000..659350a62c
--- /dev/null
+++ b/plugins/infiniband/moduleinfo.nmake
@@ -0,0 +1,28 @@
+#
+# $Id: moduleinfo.nmake 20036 2006-12-04 23:12:04Z jake $
+#
+
+# The name
+PACKAGE=infiniband
+
+# The version
+MODULE_VERSION_MAJOR=1
+MODULE_VERSION_MINOR=0
+MODULE_VERSION_MICRO=1
+MODULE_VERSION_EXTRA=0
+
+#
+# The RC_VERSION should be comma-separated, not dot-separated,
+# as per Graham Bloice's message in
+#
+# http://www.ethereal.com/lists/ethereal-dev/200303/msg00283.html
+#
+# "The RC_VERSION variable in config.nmake should be comma separated.
+# This allows the resources to be built correctly and the version
+# number to be correctly displayed in the explorer properties dialog
+# for the executables, and XP's tooltip, rather than 0.0.0.0."
+#
+
+MODULE_VERSION=$(MODULE_VERSION_MAJOR).$(MODULE_VERSION_MINOR).$(MODULE_VERSION_MICRO).$(MODULE_VERSION_EXTRA)
+RC_MODULE_VERSION=$(MODULE_VERSION_MAJOR),$(MODULE_VERSION_MINOR),$(MODULE_VERSION_MICRO),$(MODULE_VERSION_EXTRA)
+
diff --git a/plugins/infiniband/packet-infiniband.c b/plugins/infiniband/packet-infiniband.c
new file mode 100644
index 0000000000..2fd0cc4dac
--- /dev/null
+++ b/plugins/infiniband/packet-infiniband.c
@@ -0,0 +1,857 @@
+/* packet-infiniband.c
+ * Routines for Infiniband/ERF Dissection
+ *
+ * Copyright 2008 Endace Technology Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/prefs.h>
+#include <epan/proto.h>
+#include <string.h>
+#include "packet-infiniband.h"
+
+void proto_register_infiniband(void)
+{
+ if(proto_infiniband == -1)
+ {
+ proto_infiniband = proto_register_protocol("InfiniBand", "InfiniBand", "infiniband");
+ register_dissector("infiniband", dissect_infiniband, proto_infiniband);
+ }
+
+ proto_register_field_array(proto_infiniband, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+}
+
+void proto_reg_handoff_infiniband(void)
+{
+ static int initialized=FALSE;
+ if(!initialized)
+ {
+ infiniband_handle = create_dissector_handle(dissect_infiniband, proto_infiniband);
+ }
+}
+
+
+static void
+dissect_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ /* Top Level Item */
+ proto_item *infiniband_packet = NULL;
+
+ /* The Headers Subtree */
+ proto_tree *all_headers_tree = NULL;
+
+ /* LRH - Local Route Header */
+ proto_tree *local_route_header_tree = NULL;
+ proto_item *local_route_header_item = NULL;
+
+ /* GRH - Global Route Header */
+ proto_tree *global_route_header_tree = NULL;
+ proto_item *global_route_header_item = NULL;
+
+ /* BTH - Base Transport header */
+ proto_tree *base_transport_header_tree = NULL;
+ proto_item *base_transport_header_item = NULL;
+
+ /* Raw Data - no decoding. */
+ proto_item *raw_ipv6 = NULL;
+ proto_item *raw_RWH_Ethertype;
+
+ gboolean bthFollows = 0; /* Tracks if we are parsing a BTH. This is a significant decision point */
+ guint8 lnh_val = 0; /* Link Next Header Value */
+ gint offset = 0; /* Current Offset */
+ guint8 opCode = 0; /* OpCode from BTH header. */
+ gint32 nextHeaderSequence = -1; /* defined by this dissector. #define which indicates the upcoming header sequence from OpCode */
+ guint16 payloadLength = 0; /* Payload Length should it exist */
+ guint8 nxtHdr = 0; /* */
+ guint16 packetLength = 0; /* Packet Length. We track this as tvb->length - offset. It provides the parsing methods a known size */
+ /* that must be available for that header. */
+ e_guid_t SRCguid;
+ e_guid_t DSTguid;
+
+ /* Mark the Packet type as Infiniband in the wireshark UI */
+ /* Clear other columns */
+ if(pinfo->cinfo)
+ {
+ if(check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "InfiniBand");
+ if(check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+ }
+
+ /* Get the parent tree from the ERF dissector */
+ if(tree && tree->parent)
+ {
+ tree = tree->parent;
+ }
+
+ if(tree)
+ {
+ /* proto_tree* proto_item_add_subtree(proto_item *ti, gint idx); */
+
+ /* Top Level Packet */
+ infiniband_packet = proto_tree_add_item(tree, proto_infiniband, tvb, offset, -1, FALSE);
+
+ /* Headers Level Tree */
+ all_headers_tree = proto_item_add_subtree(infiniband_packet, ett_infiniband);
+
+ /* Local Route Header Subtree */
+ local_route_header_item = proto_tree_add_bytes(all_headers_tree, hf_infiniband_LRH, tvb, offset, 8, tvb->real_data);
+ proto_item_set_text(local_route_header_item, "%s", "Local Route Header");
+ local_route_header_tree = proto_item_add_subtree(local_route_header_item, ett_infiniband);
+
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_virtual_lane, tvb, offset, 1, FALSE);
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_link_version, tvb, offset, 1, FALSE); offset+=1;
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_service_level, tvb, offset, 1, FALSE);
+
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_reserved2, tvb, offset, 1, FALSE);
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_link_next_header, tvb, offset, 1, FALSE);
+ }
+ else
+ {
+ offset+=1;
+ }
+
+ /* Save Link Next Header... This tells us what the next header is. */
+ lnh_val = tvb_get_guint8(tvb, offset);
+ lnh_val = lnh_val & 0x03;
+ offset+=1;
+
+ if(tree)
+ {
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_destination_local_id, tvb, offset, 2, FALSE);
+ }
+
+ /* Set destination in packet view. */
+ if (check_col(pinfo->cinfo, COL_DEF_DST))
+ {
+ col_set_str(pinfo->cinfo, COL_DEF_DST, "DLID: ");
+ col_set_fence(pinfo->cinfo, COL_DEF_DST);
+ col_set_str(pinfo->cinfo, COL_DEF_DST, tvb_bytes_to_str(tvb, offset, 2));
+ }
+ offset+=2;
+
+ if(tree)
+ {
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_reserved5, tvb, offset, 2, FALSE);
+ }
+
+ packetLength = tvb_get_ntohs(tvb, offset); /* Get the Packet Length. This will determine payload size later on. */
+ packetLength = packetLength & 0x07FF; /* Mask off top 5 bits, they are reserved */
+ packetLength = packetLength * 4; /* Multiply by 4 to get true byte length. This is by specification. PktLen is size in 4 byte words (byteSize /4). */
+
+ if(tree)
+ {
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_packet_length, tvb, offset, 2, FALSE); offset+=2;
+ proto_tree_add_item(local_route_header_tree, hf_infiniband_source_local_id, tvb, offset, 2, FALSE);
+ }
+ else
+ {
+ offset+=2;
+ }
+
+ /* Set Source in packet view. */
+ if (check_col(pinfo->cinfo, COL_DEF_SRC))
+ {
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, "SLID: ");
+ col_set_fence(pinfo->cinfo, COL_DEF_SRC);
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, tvb_bytes_to_str(tvb, offset, 2));
+ }
+ offset+=2;
+ packetLength -= 8; /* Shave 8 bytes for the LRH. */
+
+ switch(lnh_val)
+ {
+ case IBA_GLOBAL:
+ payloadLength = tvb_get_ntohs(tvb, offset + 4);
+ nxtHdr = tvb_get_guint8(tvb, offset + 6);
+ if(tree)
+ {
+ global_route_header_item = proto_tree_add_item(all_headers_tree, hf_infiniband_GRH, tvb, offset, 40, FALSE);
+ proto_item_set_text(global_route_header_item, "%s", "Global Route Header");
+ global_route_header_tree = proto_item_add_subtree(global_route_header_item, ett_infiniband);
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_ip_version, tvb, offset, 1, FALSE);
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_traffic_class, tvb, offset, 2, FALSE);
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_flow_label, tvb, offset, 4, FALSE); offset += 4;
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_payload_length, tvb, offset, 2, FALSE); offset += 2;
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_next_header, tvb, offset, 1, FALSE); offset +=1;
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_hop_limit, tvb, offset, 1, FALSE); offset +=1;
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_source_gid, tvb, offset, 16, FALSE);
+ }
+ else
+ {
+ offset+=8;
+ }
+
+ tvb_get_ntohguid(tvb, offset,&SRCguid);
+ if (check_col(pinfo->cinfo, COL_DEF_SRC))
+ {
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, "SGID: ");
+ col_set_fence(pinfo->cinfo, COL_DEF_SRC);
+ col_set_str(pinfo->cinfo, COL_DEF_SRC, guid_to_str(&SRCguid));
+ }
+ offset += 16;
+
+ if(tree)
+ {
+ proto_tree_add_item(global_route_header_tree, hf_infiniband_destination_gid, tvb, offset, 16, FALSE); offset +=16;
+ }
+ else
+ {
+ offset+=16;
+ }
+
+ tvb_get_ntohguid(tvb, offset, &DSTguid);
+ if (check_col(pinfo->cinfo, COL_DEF_DST))
+ {
+ col_set_str(pinfo->cinfo, COL_DEF_DST, "DGID: ");
+ col_set_fence(pinfo->cinfo, COL_DEF_DST);
+ col_set_str(pinfo->cinfo, COL_DEF_DST, guid_to_str(&DSTguid));
+ }
+ offset += 16;
+
+
+
+ packetLength -= 40; /* Shave 40 bytes for GRH */
+ if(nxtHdr != 0x1B)
+ {
+ if(tree)
+ {
+ /* Some kind of packet being transported globally with IBA, but locally it is not IBA - no BTH following. */
+ proto_tree *RAWDATA_header_tree = NULL;
+ proto_item *RAWDATA_header_item = NULL;
+ RAWDATA_header_item = proto_tree_add_item(all_headers_tree, hf_infiniband_raw_data, tvb, offset, -1, FALSE);
+ proto_item_set_text(RAWDATA_header_item, "%s", "Raw Data - Non IBA local transport");
+ RAWDATA_header_tree = proto_item_add_subtree(RAWDATA_header_item, ett_infiniband);
+ }
+ break;
+ }
+
+ /* otherwise fall through and start parsing BTH */
+
+ case IBA_LOCAL:
+ bthFollows = TRUE;
+
+ if(tree)
+ {
+ base_transport_header_item = proto_tree_add_item(all_headers_tree, hf_infiniband_BTH, tvb, offset, 12, FALSE);
+ proto_item_set_text(base_transport_header_item, "%s", "Base Transport Header");
+ base_transport_header_tree = proto_item_add_subtree(base_transport_header_item, ett_infiniband);
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_opcode, tvb, offset, 1, FALSE);
+ }
+ /* Get the OpCode - this tells us what headers are following */
+ opCode = tvb_get_guint8(tvb, offset);
+ if (check_col(pinfo->cinfo, COL_INFO))
+ {
+ col_set_str(pinfo->cinfo, COL_INFO, " ");
+ col_set_fence(pinfo->cinfo, COL_INFO);
+ col_set_str(pinfo->cinfo, COL_INFO, val_to_str((guint32)opCode, OpCodeMap, "Unknown OpCode"));
+ }
+ offset +=1;
+ if(tree)
+ {
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_solicited_event, tvb, offset, 1, FALSE);
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_migreq, tvb, offset, 1, FALSE);
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_pad_count, tvb, offset, 1, FALSE);
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_transport_header_version, tvb, offset, 1, FALSE); offset +=1;
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_partition_key, tvb, offset, 2, FALSE); offset +=2;
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_reserved8, tvb, offset, 1, FALSE); offset +=1;
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_destination_qp, tvb, offset, 3, FALSE); offset +=3;
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_acknowledge_request, tvb, offset, 1, FALSE);
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_reserved7, tvb, offset, 1, FALSE); offset +=1;
+ proto_tree_add_item(base_transport_header_tree, hf_infiniband_packet_sequence_number, tvb, offset, 3, FALSE); offset +=3;
+ }
+ else
+ {
+ offset+=11;
+ }
+
+ packetLength -= 12; /* Shave 12 for Base Transport Header */
+
+ break;
+ case IP_NON_IBA:
+ if(!tree)
+ {
+ break;
+ }
+
+ /* Raw IPv6 Packet */
+ raw_ipv6 = proto_tree_add_item(all_headers_tree, hf_infiniband_raw_data, tvb, offset, -1, FALSE);
+ proto_item_set_text(raw_ipv6, "%s", "Raw (non-IBA Transport) IPv6 Packet");
+ break;
+ case RAW:
+ if(!tree)
+ {
+ break;
+ }
+
+ /* Raw (any other) Packet */
+ raw_RWH_Ethertype = proto_tree_add_item(all_headers_tree, hf_infiniband_raw_data, tvb, offset, -1, FALSE);
+ proto_item_set_text(raw_RWH_Ethertype, "%s", "Raw (non-IBA Transport) Packet");
+
+ break;
+ default:
+ if(!tree)
+ {
+ break;
+ }
+
+ /* Unknown Packet */
+ raw_ipv6 = proto_tree_add_item(all_headers_tree, hf_infiniband_raw_data, tvb, offset, -1, FALSE);
+ proto_item_set_text(raw_ipv6, "%s", "Unknown (non-IBA Transport) Raw Data Packet");
+ break;
+ }
+
+ if(bthFollows && tree)
+ {
+ /* Find our next header sequence based on the Opcode */
+ /* Each case decrements the packetLength by the amount of bytes consumed by each header. */
+ /* 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. */
+ nextHeaderSequence = find_next_header_sequence((guint32) opCode);
+ switch(nextHeaderSequence)
+ {
+ case RDETH_DETH_PAYLD:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_DETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 8; /* DETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RDETH_DETH_RETH_PAYLD:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_DETH(all_headers_tree, tvb, &offset);
+ parse_RETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 8; /* DETH */
+ packetLength -= 16; /* RETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RDETH_DETH_IMMDT_PAYLD:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_DETH(all_headers_tree, tvb, &offset);
+ parse_IMMDT(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 8; /* DETH */
+ packetLength -= 4; /* IMMDT */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RDETH_DETH_RETH_IMMDT_PAYLD:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_DETH(all_headers_tree, tvb, &offset);
+ parse_RETH(all_headers_tree, tvb, &offset);
+ parse_IMMDT(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 8; /* DETH */
+ packetLength -= 16; /* RETH */
+ packetLength -= 4; /* IMMDT */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RDETH_DETH_RETH:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_DETH(all_headers_tree, tvb, &offset);
+ parse_RETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 8; /* DETH */
+ packetLength -= 16; /* RETH */
+
+ break;
+ case RDETH_AETH_PAYLD:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_AETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 4; /* AETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RDETH_PAYLD:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RDETH_AETH:
+ parse_AETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 4; /* AETH */
+
+
+ break;
+ case RDETH_AETH_ATOMICACKETH:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_AETH(all_headers_tree, tvb, &offset);
+ parse_ATOMICACKETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 4; /* AETH */
+ packetLength -= 8; /* AtomicAckETH */
+
+
+ break;
+ case RDETH_DETH_ATOMICETH:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_DETH(all_headers_tree, tvb, &offset);
+ parse_ATOMICETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 8; /* DETH */
+ packetLength -= 28; /* AtomicETH */
+
+ break;
+ case RDETH_DETH:
+ parse_RDETH(all_headers_tree, tvb, &offset);
+ parse_DETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* RDETH */
+ packetLength -= 8; /* DETH */
+
+ break;
+ case DETH_PAYLD:
+ parse_DETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 8; /* DETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case PAYLD:
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case IMMDT_PAYLD:
+ parse_IMMDT(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* IMMDT */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RETH_PAYLD:
+ parse_RETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 16; /* RETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case RETH:
+ parse_RETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 16; /* RETH */
+
+ break;
+ case AETH_PAYLD:
+ parse_AETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* AETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case AETH:
+ parse_AETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* AETH */
+
+ break;
+ case AETH_ATOMICACKETH:
+ parse_AETH(all_headers_tree, tvb, &offset);
+ parse_ATOMICACKETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* AETH */
+ packetLength -= 8; /* AtomicAckETH */
+
+ break;
+ case ATOMICETH:
+ parse_ATOMICETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 28; /* AtomicETH */
+
+ break;
+ case IETH_PAYLD:
+ parse_IETH(all_headers_tree, tvb, &offset);
+
+ packetLength -= 4; /* IETH */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ case DETH_IMMDT_PAYLD:
+ parse_DETH(all_headers_tree, tvb, &offset);
+ parse_IMMDT(all_headers_tree, tvb, &offset);
+
+ packetLength -= 8; /* DETH */
+ packetLength -= 4; /* IMMDT */
+
+ parse_PAYLOAD(all_headers_tree, tvb, &offset, packetLength);
+ break;
+ default:
+ parse_VENDOR(all_headers_tree, tvb, &offset);
+ break;
+ }
+ }
+}
+
+
+/* Description: Finds the header sequence that follows the Base Transport Header. */
+/* Somwhat inefficient (should be using a single key,value pair data structure) */
+/* But uses pure probablity to take a stab at better efficiency. */
+/* Searches largest header sequence groups first, and then finally resorts to single matches for unique header sequences */
+/* IN: OpCode: The OpCode from the Base Transport Header. */
+/* OUT: The Header Sequence enumeration. See Declarations for #defines from (0-22) */
+static gint32
+find_next_header_sequence(guint32 OpCode)
+{
+ if(contains(OpCode, &opCode_PAYLD[0], (gint32)sizeof(opCode_PAYLD)))
+ return PAYLD;
+
+ if(contains(OpCode, &opCode_IMMDT_PAYLD[0], (gint32)sizeof(opCode_IMMDT_PAYLD)))
+ return IMMDT_PAYLD;
+
+ if(contains(OpCode, &opCode_RDETH_DETH_PAYLD[0], (gint32)sizeof(opCode_RDETH_DETH_PAYLD)))
+ return RDETH_DETH_PAYLD;
+
+ if(contains(OpCode, &opCode_RETH_PAYLD[0], (gint32)sizeof(opCode_RETH_PAYLD)))
+ return RETH_PAYLD;
+
+ if(contains(OpCode, &opCode_RDETH_AETH_PAYLD[0], (gint32)sizeof(opCode_RDETH_AETH_PAYLD)))
+ return RDETH_AETH_PAYLD;
+
+ if(contains(OpCode, &opCode_AETH_PAYLD[0], (gint32)sizeof(opCode_AETH_PAYLD)))
+ return AETH_PAYLD;
+
+ if(contains(OpCode, &opCode_RDETH_DETH_IMMDT_PAYLD[0], (gint32)sizeof(opCode_RDETH_DETH_IMMDT_PAYLD)))
+ return RDETH_DETH_IMMDT_PAYLD;
+
+ if(contains(OpCode, &opCode_RETH_IMMDT_PAYLD[0], (gint32)sizeof(opCode_RETH_IMMDT_PAYLD)))
+ return RETH_IMMDT_PAYLD;
+
+ if(contains(OpCode, &opCode_RDETH_DETH_RETH_PAYLD[0], (gint32)sizeof(opCode_RDETH_DETH_RETH_PAYLD)))
+ return RDETH_DETH_RETH_PAYLD;
+
+ if(contains(OpCode, &opCode_ATOMICETH[0], (gint32)sizeof(opCode_ATOMICETH)))
+ return ATOMICETH;
+
+ if(contains(OpCode, &opCode_IETH_PAYLD[0], (gint32)sizeof(opCode_IETH_PAYLD)))
+ return IETH_PAYLD;
+
+ if(contains(OpCode, &opCode_RDETH_DETH_ATOMICETH[0], (gint32)sizeof(opCode_RDETH_DETH_ATOMICETH)))
+ return RDETH_DETH_ATOMICETH;
+
+ if((OpCode ^ RC_ACKNOWLEDGE) == 0)
+ return AETH;
+
+ if((OpCode ^ RC_RDMA_READ_REQUEST) == 0)
+ return RETH;
+
+ if((OpCode ^ RC_ATOMIC_ACKNOWLEDGE) == 0)
+ return AETH_ATOMICACKETH;
+
+ if((OpCode ^ RD_RDMA_READ_RESPONSE_MIDDLE) == 0)
+ return RDETH_PAYLD;
+
+ if((OpCode ^ RD_ACKNOWLEDGE) == 0)
+ return RDETH_AETH;
+
+ if((OpCode ^ RD_ATOMIC_ACKNOWLEDGE) == 0)
+ return RDETH_AETH_ATOMICACKETH;
+
+ if((OpCode ^ RD_RDMA_WRITE_ONLY_IMM) == 0)
+ return RDETH_DETH_RETH_IMMDT_PAYLD;
+
+ if((OpCode ^ RD_RDMA_READ_REQUEST) == 0)
+ return RDETH_DETH_RETH;
+
+ if((OpCode ^ RD_RESYNC) == 0)
+ return RDETH_DETH;
+
+ if((OpCode ^ UD_SEND_ONLY) == 0)
+ return DETH_PAYLD;
+
+ if((OpCode ^ UD_SEND_ONLY_IMM) == 0)
+ return DETH_IMMDT_PAYLD;
+
+ return -1;
+}
+
+/* Description: Finds if a given value is present in an array. This is probably in a standard library somewhere, */
+/* But I'd rather define my own. */
+/* IN: OpCode: The OpCode you are looking for */
+/* IN: Codes: The organized array of OpCodes to look through */
+/* IN: Array length, because we're in C... */
+/* OUT: Boolean indicating if that OpCode was found in OpCodes */
+static gboolean
+contains(guint32 OpCode, guint32* Codes, gint32 length)
+{
+ gint32 i;
+ for(i = 0; i < length; i++)
+ {
+ if((OpCode ^ Codes[i]) == 0)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Parse RDETH - Reliable Datagram Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_RDETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* RDETH - Reliable Datagram Extended Transport Header */
+ proto_tree *RDETH_header_tree = NULL;
+ proto_item *RDETH_header_item = NULL;
+
+ RDETH_header_item = proto_tree_add_item(parentTree, hf_infiniband_RDETH, tvb, local_offset, 4, FALSE);
+ proto_item_set_text(RDETH_header_item, "%s", "RDETH - Reliable Datagram Extended Transport Header");
+ RDETH_header_tree = proto_item_add_subtree(RDETH_header_item, ett_infiniband);
+
+ proto_tree_add_item(RDETH_header_tree, hf_infiniband_reserved8_RDETH, tvb, local_offset, 1, FALSE); local_offset+=1;
+ proto_tree_add_item(RDETH_header_tree, hf_infiniband_ee_context, tvb, local_offset, 3, FALSE); local_offset+=3;
+
+ *offset = local_offset;
+}
+
+/* Parse DETH - Datagram Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_DETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* DETH - Datagram Extended Transport Header */
+ proto_tree *DETH_header_tree = NULL;
+ proto_item *DETH_header_item = NULL;
+
+ DETH_header_item = proto_tree_add_item(parentTree, hf_infiniband_DETH, tvb, local_offset, 8, FALSE);
+ proto_item_set_text(DETH_header_item, "%s", "DETH - Datagram Extended Transport Header");
+ DETH_header_tree = proto_item_add_subtree(DETH_header_item, ett_infiniband);
+
+ proto_tree_add_item(DETH_header_tree, hf_infiniband_queue_key, tvb, local_offset, 4, FALSE); local_offset+=4;
+ proto_tree_add_item(DETH_header_tree, hf_infiniband_reserved8_DETH, tvb, local_offset, 1, FALSE); local_offset+=1;
+ proto_tree_add_item(DETH_header_tree, hf_infiniband_source_qp, tvb, local_offset, 3, FALSE); local_offset+=3;
+
+ *offset = local_offset;
+}
+
+/* Parse RETH - RDMA Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_RETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* RETH - RDMA Extended Transport Header */
+ proto_tree *RETH_header_tree = NULL;
+ proto_item *RETH_header_item = NULL;
+
+ RETH_header_item = proto_tree_add_item(parentTree, hf_infiniband_RETH, tvb, local_offset, 16, FALSE);
+ proto_item_set_text(RETH_header_item, "%s", "RETH - RDMA Extended Transport Header");
+ RETH_header_tree = proto_item_add_subtree(RETH_header_item, ett_infiniband);
+
+ proto_tree_add_item(RETH_header_tree, hf_infiniband_virtual_address, tvb, local_offset, 8, FALSE); local_offset+=8;
+ proto_tree_add_item(RETH_header_tree, hf_infiniband_remote_key, tvb, local_offset, 4, FALSE); local_offset+=4;
+ proto_tree_add_item(RETH_header_tree, hf_infiniband_dma_length, tvb, local_offset, 4, FALSE); local_offset+=4;
+
+ *offset = local_offset;
+}
+
+/* Parse AtomicETH - Atomic Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_ATOMICETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* AtomicETH - Atomic Extended Transport Header */
+ proto_tree *ATOMICETH_header_tree = NULL;
+ proto_item *ATOMICETH_header_item = NULL;
+
+ ATOMICETH_header_item = proto_tree_add_item(parentTree, hf_infiniband_AtomicETH, tvb, local_offset, 28, FALSE);
+ proto_item_set_text(ATOMICETH_header_item, "%s", "AtomicETH - Atomic Extended Transport Header");
+ ATOMICETH_header_tree = proto_item_add_subtree(ATOMICETH_header_item, ett_infiniband);
+
+ proto_tree_add_item(ATOMICETH_header_tree, hf_infiniband_virtual_address, tvb, local_offset, 8, FALSE); local_offset+=8;
+ proto_tree_add_item(ATOMICETH_header_tree, hf_infiniband_remote_key, tvb, local_offset, 4, FALSE); local_offset+=4;
+ proto_tree_add_item(ATOMICETH_header_tree, hf_infiniband_swap_or_add_data, tvb, local_offset, 8, FALSE); local_offset+=8;
+ proto_tree_add_item(ATOMICETH_header_tree, hf_infiniband_compare_data, tvb, local_offset, 8, FALSE); local_offset+=8;
+
+ *offset = local_offset;
+}
+
+/* Parse AETH - ACK Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_AETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* AETH - ACK Extended Transport Header */
+ proto_tree *AETH_header_tree = NULL;
+ proto_item *AETH_header_item = NULL;
+
+ AETH_header_item = proto_tree_add_item(parentTree, hf_infiniband_AETH, tvb, local_offset, 4, FALSE);
+ proto_item_set_text(AETH_header_item, "%s", "AETH - ACK Extended Transport Header");
+ AETH_header_tree = proto_item_add_subtree(AETH_header_item, ett_infiniband);
+
+ proto_tree_add_item(AETH_header_tree, hf_infiniband_syndrome, tvb, local_offset, 1, FALSE); local_offset+=1;
+ proto_tree_add_item(AETH_header_tree, hf_infiniband_message_sequence_number, tvb, local_offset, 3, FALSE); local_offset+=3;
+
+ *offset = local_offset;
+}
+
+/* Parse AtomicAckEth - Atomic ACK Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_ATOMICACKETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* AtomicAckEth - Atomic ACK Extended Transport Header */
+ proto_tree *ATOMICACKETH_header_tree = NULL;
+ proto_item *ATOMICACKETH_header_item = NULL;
+
+ ATOMICACKETH_header_item = proto_tree_add_item(parentTree, hf_infiniband_AtomicAckETH, tvb, local_offset, 8, FALSE);
+ proto_item_set_text(ATOMICACKETH_header_item, "%s", "ATOMICACKETH - Atomic ACK Extended Transport Header");
+ ATOMICACKETH_header_tree = proto_item_add_subtree(ATOMICACKETH_header_item, ett_infiniband);
+
+ proto_tree_add_item(ATOMICACKETH_header_tree, hf_infiniband_original_remote_data, tvb, local_offset, 8, FALSE); local_offset+=8;
+
+ *offset = local_offset;
+}
+
+/* Parse IMMDT - Immediate Data Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_IMMDT(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* IMMDT - Immediate Data Extended Transport Header */
+ proto_tree *IMMDT_header_tree = NULL;
+ proto_item *IMMDT_header_item = NULL;
+
+ IMMDT_header_item = proto_tree_add_item(parentTree, hf_infiniband_IMMDT, tvb, local_offset, 4, FALSE);
+ proto_item_set_text(IMMDT_header_item, "%s", "IMMDT - Immediate Data Extended Transport Header");
+ IMMDT_header_tree = proto_item_add_subtree(IMMDT_header_item, ett_infiniband);
+
+ proto_tree_add_item(IMMDT_header_tree, hf_infiniband_IMMDT, tvb, local_offset, 4, FALSE); local_offset+=4;
+
+ *offset = local_offset;
+}
+
+/* Parse IETH - Invalidate Extended Transport Header */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_IETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* IETH - Invalidate Extended Transport Header */
+ proto_tree *IETH_header_tree = NULL;
+ proto_item *IETH_header_item = NULL;
+
+ IETH_header_item = proto_tree_add_item(parentTree, hf_infiniband_IETH, tvb, local_offset, 4, FALSE);
+ proto_item_set_text(IETH_header_item, "%s", "IETH - Invalidate Extended Transport Header");
+ IETH_header_tree = proto_item_add_subtree(IETH_header_item, ett_infiniband);
+
+ proto_tree_add_item(IETH_header_tree, hf_infiniband_IETH, tvb, local_offset, 4, FALSE); local_offset+=4;
+
+ *offset = local_offset;
+}
+
+/* Parse Payload - Packet Payload / Invariant CRC / Variant CRC */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+/* IN: Length of Payload */
+static void
+parse_PAYLOAD(proto_tree * parentTree, tvbuff_t *tvb, gint *offset, gint length)
+{
+ gint local_offset = *offset;
+ /* Payload - Packet Payload */
+ proto_tree *PAYLOAD_header_tree = NULL;
+ proto_item *PAYLOAD_header_item = NULL;
+
+ if((length + local_offset) >= (gint)(tvb->length)) /* oreviously consumed bytes + offset was all the data - none or corrupt payload*/
+ {
+ /* Error condition */
+ return;
+ }
+
+
+ /* Calculation for Payload: */
+ /* (tvb->length) Length of entire packet - (local_offset) Starting byte of Payload Data */
+ PAYLOAD_header_item = proto_tree_add_item(parentTree, hf_infiniband_payload, tvb, local_offset, (tvb->length) - local_offset, FALSE); local_offset += (tvb->length - 6 - local_offset);
+ proto_item_set_text(PAYLOAD_header_item, "%s", "Payload");
+ PAYLOAD_header_tree = proto_item_add_subtree(PAYLOAD_header_item, ett_infiniband);
+
+ /* 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. */
+ proto_tree_add_item(PAYLOAD_header_tree, hf_infiniband_invariant_crc, tvb, local_offset, 4, FALSE); local_offset +=4;
+ proto_tree_add_item(PAYLOAD_header_tree, hf_infiniband_variant_crc, tvb, local_offset, 2, FALSE); local_offset +=2;
+
+ *offset = local_offset;
+}
+
+/* Parse VENDOR - Parse a vendor specific or unknown header sequence */
+/* IN: parentTree to add the dissection too - in this code the all_headers_tree */
+/* IN: tvb - the data buffer from wireshark */
+/* IN/OUT: The current and updated offset */
+static void
+parse_VENDOR(proto_tree * parentTree, tvbuff_t *tvb, gint *offset)
+{
+ gint local_offset = *offset;
+ /* IETH - Invalidate Extended Transport Header */
+ proto_tree *VENDOR_header_tree = NULL;
+ proto_item *VENDOR_header_item = NULL;
+
+ VENDOR_header_item = proto_tree_add_item(parentTree, hf_infiniband_vendor, tvb, local_offset, 4, FALSE);
+ proto_item_set_text(VENDOR_header_item, "%s", "Vendor Specific or Unknown Header Sequence");
+ VENDOR_header_tree = proto_item_add_subtree(VENDOR_header_item, ett_infiniband);
+
+ proto_tree_add_item(VENDOR_header_tree, hf_infiniband_vendor, tvb, local_offset, -1, FALSE);
+
+ *offset = local_offset;
+}
+
+
diff --git a/plugins/infiniband/packet-infiniband.h b/plugins/infiniband/packet-infiniband.h
new file mode 100644
index 0000000000..337d6c43b2
--- /dev/null
+++ b/plugins/infiniband/packet-infiniband.h
@@ -0,0 +1,686 @@
+/* packet-infiniband.h
+ * Routines for Infiniband/ERF Dissection
+ *
+ * Copyright 2008 Endace Technology Limited
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#ifndef __PACKET_INFINIBAND_H_
+#define __PACKET_INFINIBAND_H_
+
+#define PROTO_TAG_INFINIBAND "Infiniband"
+
+/* Wireshark ID */
+static int proto_infiniband = -1;
+/*static int hf_infiniband_pdu_type = -1; unnecessary for now */
+static gint ett_infiniband = -1;
+
+
+/* Dissector Declarations */
+static dissector_handle_t infiniband_handle;
+void proto_register_infiniband(void);
+void proto_reg_handoff_infiniband(void);
+static void dissect_infiniband(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static gint32 find_next_header_sequence(guint32 OpCode);
+static gboolean contains(guint32 value, guint32* arr, int length);
+
+/* Parsing Methods for specific IB headers. */
+
+static void parse_VENDOR(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_PAYLOAD(proto_tree * parentTree, tvbuff_t *tvb, gint *offset, gint length);
+static void parse_IETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_IMMDT(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_ATOMICACKETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_AETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_ATOMICETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_RETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_DETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+static void parse_RDETH(proto_tree * parentTree, tvbuff_t *tvb, gint *offset);
+
+/* These are not currently used, but in the future */
+/* can be expanded and used to provide better visualization in Wireshark. */
+static const value_string packettypenames[] =
+{
+ { 4, "Local" },
+ { 3, "Global" },
+ { 2, "Raw (Raw Header)" },
+ { 1, "Raw (IPv6 Header)"},
+ { 0, NULL}
+};
+
+/* Just a map so we can display a value for FT_BOOLEAN types */
+
+static const value_string IB_Boolean[] = {
+ { 0, " 0 " },
+ { 1, " 1 " },
+ { 2, NULL }
+};
+
+/* Local Route Header (LRH) */
+static int hf_infiniband_LRH = -1;
+static int hf_infiniband_virtual_lane = -1;
+static int hf_infiniband_link_version = -1;
+static int hf_infiniband_service_level = -1;
+static int hf_infiniband_reserved2 = -1;
+static int hf_infiniband_link_next_header = -1;
+static int hf_infiniband_destination_local_id = -1;
+static int hf_infiniband_reserved5 = -1;
+static int hf_infiniband_packet_length = -1;
+static int hf_infiniband_source_local_id = -1;
+/* Global Route Header (GRH) */
+static int hf_infiniband_GRH = -1;
+static int hf_infiniband_ip_version = -1;
+static int hf_infiniband_traffic_class = -1;
+static int hf_infiniband_flow_label = -1;
+static int hf_infiniband_payload_length = -1;
+static int hf_infiniband_next_header = -1;
+static int hf_infiniband_hop_limit = -1;
+static int hf_infiniband_source_gid = -1;
+static int hf_infiniband_destination_gid = -1;
+/* Base Transport Header (BTH) */
+static int hf_infiniband_BTH = -1;
+static int hf_infiniband_opcode = -1;
+static int hf_infiniband_solicited_event = -1;
+static int hf_infiniband_migreq = -1;
+static int hf_infiniband_pad_count = -1;
+static int hf_infiniband_transport_header_version = -1;
+static int hf_infiniband_partition_key = -1;
+static int hf_infiniband_reserved8 = -1;
+static int hf_infiniband_destination_qp = -1;
+static int hf_infiniband_acknowledge_request = -1;
+static int hf_infiniband_reserved7 = -1;
+static int hf_infiniband_packet_sequence_number = -1;
+/* Reliable Datagram Extended Transport Header (RDETH) */
+static int hf_infiniband_RDETH = -1;
+static int hf_infiniband_reserved8_RDETH = -1;
+static int hf_infiniband_ee_context = -1;
+/* Datagram Extended Transport Header (DETH) */
+static int hf_infiniband_DETH = -1;
+static int hf_infiniband_queue_key = -1;
+static int hf_infiniband_reserved8_DETH = -1;
+static int hf_infiniband_source_qp = -1;
+/* RDMA Extended Transport Header (RETH) */
+static int hf_infiniband_RETH = -1;
+static int hf_infiniband_virtual_address = -1;
+static int hf_infiniband_remote_key = -1;
+static int hf_infiniband_dma_length = -1;
+/* Atomic Extended Transport Header (AtomicETH) */
+static int hf_infiniband_AtomicETH = -1;
+static int hf_infiniband_virtual_address_AtomicETH = -1;
+static int hf_infiniband_remote_key_AtomicETH = -1;
+static int hf_infiniband_swap_or_add_data = -1;
+static int hf_infiniband_compare_data = -1;
+/* ACK Extended Transport Header (AETH) */
+static int hf_infiniband_AETH = -1;
+static int hf_infiniband_syndrome = -1;
+static int hf_infiniband_message_sequence_number = -1;
+/* Atomic ACK Extended Transport Header (AtomicAckETH) */
+static int hf_infiniband_AtomicAckETH = -1;
+static int hf_infiniband_original_remote_data = -1;
+/* Immediate Extended Transport Header (ImmDt) */
+static int hf_infiniband_IMMDT = -1;
+/* Invalidate Extended Transport Header (IETH) */
+static int hf_infiniband_IETH = -1;
+/* Payload */
+static int hf_infiniband_payload = -1;
+static int hf_infiniband_invariant_crc = -1;
+static int hf_infiniband_variant_crc = -1;
+/* Unknown or Vendor Specific */
+static int hf_infiniband_raw_data = -1;
+static int hf_infiniband_vendor = -1;
+
+
+
+/* Link Next Header Values */
+#define IBA_GLOBAL 3
+#define IBA_LOCAL 2
+#define IP_NON_IBA 1
+#define RAW 0
+
+/* OpCodeValues */
+/* Code Bits [7-5] Connection Type */
+/* [4-0] Message Type */
+
+/* Reliable Connection (RC) */
+/* [7-5] = 000 */
+#define RC_SEND_FIRST 0 /*0x00000000 */
+#define RC_SEND_MIDDLE 1 /*0x00000001 */
+#define RC_SEND_LAST 2 /*0x00000010 */
+#define RC_SEND_LAST_IMM 3 /*0x00000011 */
+#define RC_SEND_ONLY 4 /*0x00000100 */
+#define RC_SEND_ONLY_IMM 5 /*0x00000101 */
+#define RC_RDMA_WRITE_FIRST 6 /*0x00000110 */
+#define RC_RDMA_WRITE_MIDDLE 7 /*0x00000111 */
+#define RC_RDMA_WRITE_LAST 8 /*0x00001000 */
+#define RC_RDMA_WRITE_LAST_IMM 9 /*0x00001001 */
+#define RC_RDMA_WRITE_ONLY 10 /*0x00001010 */
+#define RC_RDMA_WRITE_ONLY_IMM 11 /*0x00001011 */
+#define RC_RDMA_READ_REQUEST 12 /*0x00001100 */
+#define RC_RDMA_READ_RESPONSE_FIRST 13 /*0x00001101 */
+#define RC_RDMA_READ_RESPONSE_MIDDLE 14 /*0x00001110 */
+#define RC_RDMA_READ_RESPONSE_LAST 15 /*0x00001111 */
+#define RC_RDMA_READ_RESPONSE_ONLY 16 /*0x00010000 */
+#define RC_ACKNOWLEDGE 17 /*0x00010001 */
+#define RC_ATOMIC_ACKNOWLEDGE 18 /*0x00010010 */
+#define RC_CMP_SWAP 19 /*0x00010011 */
+#define RC_FETCH_ADD 20 /*0x00010100 */
+#define RC_SEND_LAST_INVAL 22 /*0x00010110 */
+#define RC_SEND_ONLY_INVAL 23 /*0x00010111 */
+
+/* Reliable Datagram (RD) */
+/* [7-5] = 010 */
+#define RD_SEND_FIRST 64 /*0x01000000 */
+#define RD_SEND_MIDDLE 65 /*0x01000001 */
+#define RD_SEND_LAST 66 /*0x01000010 */
+#define RD_SEND_LAST_IMM 67 /*0x01000011 */
+#define RD_SEND_ONLY 68 /*0x01000100 */
+#define RD_SEND_ONLY_IMM 69 /*0x01000101 */
+#define RD_RDMA_WRITE_FIRST 70 /*0x01000110 */
+#define RD_RDMA_WRITE_MIDDLE 71 /*0x01000111 */
+#define RD_RDMA_WRITE_LAST 72 /*0x01001000 */
+#define RD_RDMA_WRITE_LAST_IMM 73 /*0x01001001 */
+#define RD_RDMA_WRITE_ONLY 74 /*0x01001010 */
+#define RD_RDMA_WRITE_ONLY_IMM 75 /*0x01001011 */
+#define RD_RDMA_READ_REQUEST 76 /*0x01001100 */
+#define RD_RDMA_READ_RESPONSE_FIRST 77 /*0x01001101 */
+#define RD_RDMA_READ_RESPONSE_MIDDLE 78 /*0x01001110 */
+#define RD_RDMA_READ_RESPONSE_LAST 79 /*0x01001111 */
+#define RD_RDMA_READ_RESPONSE_ONLY 80 /*0x01010000 */
+#define RD_ACKNOWLEDGE 81 /*0x01010001 */
+#define RD_ATOMIC_ACKNOWLEDGE 82 /*0x01010010 */
+#define RD_CMP_SWAP 83 /*0x01010011 */
+#define RD_FETCH_ADD 84 /*0x01010100 */
+#define RD_RESYNC 85 /*0x01010101 */
+
+/* Unreliable Datagram (UD) */
+/* [7-5] = 011 */
+#define UD_SEND_ONLY 100 /*0x01100100 */
+#define UD_SEND_ONLY_IMM 101 /*0x01100101 */
+
+/* Unreliable Connection (UC) */
+/* [7-5] = 001 */
+#define UC_SEND_FIRST 32 /*0x00100000 */
+#define UC_SEND_MIDDLE 33 /*0x00100001 */
+#define UC_SEND_LAST 34 /*0x00100010 */
+#define UC_SEND_LAST_IMM 35 /*0x00100011 */
+#define UC_SEND_ONLY 36 /*0x00100100 */
+#define UC_SEND_ONLY_IMM 37 /*0x00100101 */
+#define UC_RDMA_WRITE_FIRST 38 /*0x00100110 */
+#define UC_RDMA_WRITE_MIDDLE 39 /*0x00100111 */
+#define UC_RDMA_WRITE_LAST 40 /*0x00101000 */
+#define UC_RDMA_WRITE_LAST_IMM 41 /*0x00101001 */
+#define UC_RDMA_WRITE_ONLY 42 /*0x00101010 */
+#define UC_RDMA_WRITE_ONLY_IMM 43 /*0x00101011 */
+
+static value_string OpCodeMap[] =
+{
+ { RC_SEND_FIRST, "Reliable Connection Send First" },
+ { RC_SEND_MIDDLE, "Reliable Connection Send Middle"},
+ { RC_SEND_LAST, "Reliable Connection Send Last" },
+ { RC_SEND_LAST_IMM, "Reliable Connection Send Last Immediate"},
+ { RC_SEND_ONLY, "Reliable Connection Send Only"},
+ { RC_SEND_ONLY_IMM, "Reliable Connection Send Only Immediate"},
+ { RC_RDMA_WRITE_FIRST, "Reliable Connection RDMA Write First" },
+ { RC_RDMA_WRITE_MIDDLE, "Reliable Connection RDMA Write Middle"},
+ { RC_RDMA_WRITE_LAST, "Reliable Connection RDMA Write Last"},
+ { RC_RDMA_WRITE_LAST_IMM, "Reliable Connection RDMA Write Last Immediate " },
+ { RC_RDMA_WRITE_ONLY, "Reliable Connection RDMA Write Only" },
+ { RC_RDMA_WRITE_ONLY_IMM, "Reliable Connection RDMA Write Only Immediate"},
+ { RC_RDMA_READ_REQUEST, "Reliable Connection RDMA Read Request" },
+ { RC_RDMA_READ_RESPONSE_FIRST, "Reliable Connection RDMA Read Response First" },
+ { RC_RDMA_READ_RESPONSE_MIDDLE, "Reliable Connection RDMA Read Response Middle"},
+ { RC_RDMA_READ_RESPONSE_LAST, "Reliable Connection RDMA Read Response Last" },
+ { RC_RDMA_READ_RESPONSE_ONLY, "Reliable Connection RDMA Read Response Only"},
+ { RC_ACKNOWLEDGE, "Reliable Connection Acknowledge" },
+ { RC_ATOMIC_ACKNOWLEDGE, "Reliable Connection Atomic Acknowledge" },
+ { RC_CMP_SWAP, "Reliable Connection Compare Swap" },
+ { RC_FETCH_ADD, "Reliable Connection Fetch Add"},
+ { RC_SEND_LAST_INVAL, "Reliable Connection Send Last Invalidate"},
+ { RC_SEND_ONLY_INVAL, "Reliable Connection Send Only Invalidate" },
+
+
+ { RD_SEND_FIRST, "Reliable Datagram Send First"},
+ { RD_SEND_MIDDLE,"Reliable Datagram Send Middle" },
+ { RD_SEND_LAST, "Reliable Datagram Send Last"},
+ { RD_SEND_LAST_IMM, "Reliable Datagram Last Immediate" },
+ { RD_SEND_ONLY,"Reliable Datagram Send Only"},
+ { RD_SEND_ONLY_IMM,"Reliable Datagram Send Only Immediate"},
+ { RD_RDMA_WRITE_FIRST,"Reliable Datagram RDMA Write First"},
+ { RD_RDMA_WRITE_MIDDLE, "Reliable Datagram RDMA Write Middle"},
+ { RD_RDMA_WRITE_LAST,"Reliable Datagram RDMA Write Last"},
+ { RD_RDMA_WRITE_LAST_IMM,"Reliable Datagram RDMA Write Last Immediate"},
+ { RD_RDMA_WRITE_ONLY,"Reliable Datagram RDMA Write Only"},
+ { RD_RDMA_WRITE_ONLY_IMM,"Reliable Datagram RDMA Write Only Immediate"},
+ { RD_RDMA_READ_REQUEST,"Reliable Datagram RDMA Read Request"},
+ { RD_RDMA_READ_RESPONSE_FIRST,"Reliable Datagram RDMA Read Response First"},
+ { RD_RDMA_READ_RESPONSE_MIDDLE,"Reliable Datagram RDMA Read Response Middle"},
+ { RD_RDMA_READ_RESPONSE_LAST,"Reliable Datagram RDMA Read Response Last"},
+ { RD_RDMA_READ_RESPONSE_ONLY,"Reliable Datagram RDMA Read Response Only"},
+ { RD_ACKNOWLEDGE,"Reliable Datagram Acknowledge"},
+ { RD_ATOMIC_ACKNOWLEDGE,"Reliable Datagram Atomic Acknowledge"},
+ { RD_CMP_SWAP,"Reliable Datagram Compare Swap"},
+ { RD_FETCH_ADD, "Reliable Datagram Fetch Add"},
+ { RD_RESYNC,"Reliable Datagram RESYNC"},
+
+
+ { UD_SEND_ONLY, "Unreliable Datagram Send Only"},
+ { UD_SEND_ONLY_IMM, "Unreliable Datagram Send Only Immediate"},
+
+
+ { UC_SEND_FIRST,"Unreliable Connection Send First"},
+ { UC_SEND_MIDDLE,"Unreliable Connection Send Middle"},
+ { UC_SEND_LAST,"Unreliable Connection Send Last"},
+ { UC_SEND_LAST_IMM,"Unreliable Connection Send Last Immediate"},
+ { UC_SEND_ONLY,"Unreliable Connection Send Only"},
+ { UC_SEND_ONLY_IMM,"Unreliable Connection Send Only Immediate"},
+ { UC_RDMA_WRITE_FIRST,"Unreliable Connection RDMA Write First"},
+ { UC_RDMA_WRITE_MIDDLE,"Unreliable Connection RDMA Write Middle"},
+ { UC_RDMA_WRITE_LAST,"Unreliable Connection RDMA Write Last"},
+ { UC_RDMA_WRITE_LAST_IMM,"Unreliable Connection RDMA Write Last Immediate"},
+ { UC_RDMA_WRITE_ONLY,"Unreliable Connection RDMA Write Only"},
+ { UC_RDMA_WRITE_ONLY_IMM,"Unreliable Connection RDMA Write Only Immediate"},
+ { 0, NULL }
+
+};
+
+
+
+/* Header Ordering Based on OPCODES */
+/* These are simply an enumeration of the possible header combinations defined by the IB Spec. */
+/* These enumerations */
+/* #DEFINE [HEADER_ORDER] [ENUM] */
+/* __________________________________ */
+#define RDETH_DETH_PAYLD 0
+/* __________________________________ */
+#define RDETH_DETH_RETH_PAYLD 1
+/* __________________________________ */
+#define RDETH_DETH_IMMDT_PAYLD 2
+/* __________________________________ */
+#define RDETH_DETH_RETH_IMMDT_PAYLD 3
+/* __________________________________ */
+#define RDETH_DETH_RETH 4
+/* __________________________________ */
+#define RDETH_AETH_PAYLD 5
+/* __________________________________ */
+#define RDETH_PAYLD 6
+/* __________________________________ */
+#define RDETH_AETH 7
+/* __________________________________ */
+#define RDETH_AETH_ATOMICACKETH 8
+/* __________________________________ */
+#define RDETH_DETH_ATOMICETH 9
+/* ___________________________________ */
+#define RDETH_DETH 10
+/* ___________________________________ */
+#define DETH_PAYLD 11
+/* ___________________________________ */
+#define DETH_IMMDT_PAYLD 12
+/* ___________________________________ */
+#define PAYLD 13
+/* ___________________________________ */
+#define IMMDT_PAYLD 14
+/* ___________________________________ */
+#define RETH_PAYLD 15
+/* ___________________________________ */
+#define RETH_IMMDT_PAYLD 16
+/* ___________________________________ */
+#define RETH 17
+/* ___________________________________ */
+#define AETH_PAYLD 18
+/* ___________________________________ */
+#define AETH 19
+/* ___________________________________ */
+#define AETH_ATOMICACKETH 20
+/* ___________________________________ */
+#define ATOMICETH 21
+/* ___________________________________ */
+#define IETH_PAYLD 22
+/* ___________________________________ */
+
+
+/* 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. */
+static guint32 opCode_RDETH_DETH_ATOMICETH[] = {
+ RD_CMP_SWAP,
+ RD_FETCH_ADD
+};
+static guint32 opCode_IETH_PAYLD[] = {
+ RC_SEND_LAST_INVAL,
+ RC_SEND_ONLY_INVAL
+};
+static guint32 opCode_ATOMICETH[] = {
+ RC_CMP_SWAP,
+ RC_FETCH_ADD
+};
+static guint32 opCode_RDETH_DETH_RETH_PAYLD[] = {
+ RD_RDMA_WRITE_FIRST,
+ RD_RDMA_WRITE_ONLY
+};
+static guint32 opCode_RETH_IMMDT_PAYLD[] = {
+ RC_RDMA_WRITE_ONLY_IMM,
+ UC_RDMA_WRITE_ONLY_IMM
+};
+static guint32 opCode_RDETH_DETH_IMMDT_PAYLD[] = {
+ RD_SEND_LAST_IMM,
+ RD_SEND_ONLY_IMM,
+ RD_RDMA_WRITE_LAST_IMM
+};
+
+static guint32 opCode_RDETH_AETH_PAYLD[] = {
+ RD_RDMA_READ_RESPONSE_FIRST,
+ RD_RDMA_READ_RESPONSE_LAST,
+ RD_RDMA_READ_RESPONSE_ONLY
+};
+static guint32 opCode_AETH_PAYLD[] = {
+ RC_RDMA_READ_RESPONSE_FIRST,
+ RC_RDMA_READ_RESPONSE_LAST,
+ RC_RDMA_READ_RESPONSE_ONLY
+};
+static guint32 opCode_RETH_PAYLD[] = {
+ RC_RDMA_WRITE_FIRST,
+ RC_RDMA_WRITE_ONLY,
+ UC_RDMA_WRITE_FIRST,
+ UC_RDMA_WRITE_ONLY
+};
+
+static guint32 opCode_RDETH_DETH_PAYLD[] = {
+ RD_SEND_FIRST,
+ RD_SEND_MIDDLE,
+ RD_SEND_LAST,
+ RD_SEND_ONLY,
+ RD_RDMA_WRITE_MIDDLE,
+ RD_RDMA_WRITE_LAST
+};
+
+static guint32 opCode_IMMDT_PAYLD[] = {
+ RC_SEND_LAST_IMM,
+ RC_SEND_ONLY_IMM,
+ RC_RDMA_WRITE_LAST_IMM,
+ UC_SEND_LAST_IMM,
+ UC_SEND_ONLY_IMM,
+ UC_RDMA_WRITE_LAST_IMM
+};
+
+static guint32 opCode_PAYLD[] = {
+ RC_SEND_FIRST,
+ RC_SEND_MIDDLE,
+ RC_SEND_LAST,
+ RC_SEND_ONLY,
+ RC_RDMA_WRITE_MIDDLE,
+ RC_RDMA_WRITE_LAST,
+ RC_RDMA_READ_RESPONSE_MIDDLE,
+ UC_SEND_FIRST,
+ UC_SEND_MIDDLE,
+ UC_SEND_LAST,
+ UC_SEND_ONLY,
+ UC_RDMA_WRITE_MIDDLE,
+ UC_RDMA_WRITE_LAST
+};
+
+/* It is not necessary to create arrays for these OpCodes since they indicate only one further header. */
+/* We can just decode it directly */
+
+/*static guint32 opCode_DETH_IMMDT_PAYLD[] = { */
+/* UD_SEND_ONLY_IMM */
+/*}; */
+/*static guint32 opCode_DETH_PAYLD[] = { */
+/* UD_SEND_ONLY */
+/*}; */
+/*static guint32 opCode_RDETH_DETH[] = { */
+/* RD_RESYNC */
+/*}; */
+/*static guint32 opCode_RDETH_DETH_RETH[] = { */
+/* RD_RDMA_READ_REQUEST */
+/*}; */
+/*static guint32 opCode_RDETH_DETH_RETH_IMMDT_PAYLD[] = { */
+/* RD_RDMA_WRITE_ONLY_IMM */
+/*}; */
+/*static guint32 opCode_RDETH_AETH_ATOMICACKETH[] = { */
+/* RD_ATOMIC_ACKNOWLEDGE */
+/*}; */
+/*static guint32 opCode_RDETH_AETH[] = { */
+/* RD_ACKNOWLEDGE */
+/*}; */
+/*static guint32 opCode_RDETH_PAYLD[] = { */
+/* RD_RDMA_READ_RESPONSE_MIDDLE */
+/*}; */
+/*static guint32 opCode_AETH_ATOMICACKETH[] = { */
+/* RC_ATOMIC_ACKNOWLEDGE */
+/*}; */
+/*static guint32 opCode_RETH[] = { */
+/* RC_RDMA_READ_REQUEST */
+/*}; */
+/*static guint32 opCode_AETH[] = { */
+/* RC_ACKNOWLEDGE */
+/*}; */
+
+
+/* Field dissector structures. */
+/* For reserved fields, reservedX denotes the reserved field is X bits in length. */
+/* e.g. reserved2 is a reserved field 2 bits in length. */
+/* The third parameter is a filter string associated for this field. */
+/* So for instance, to filter packets for a given virtual lane, */
+/* The filter (infiniband.LRH.vl == 3) or something similar would be used. */
+
+static hf_register_info hf[] = {
+
+ /* Local Route Header (LRH) */
+ {&hf_infiniband_LRH,
+ {"Local Route Header", "infiniband.lrh", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_virtual_lane,
+ {"Virtual Lane", "infiniband.lrh.vl", FT_UINT8, BASE_HEX, NULL, 0xF0, NULL, HFILL}
+ },
+ {&hf_infiniband_link_version,
+ {"Link Version", "infiniband.lrh.lver", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}
+ },
+ {&hf_infiniband_service_level,
+ {"Service Level", "infiniband.lrh.sl", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}
+ },
+ {&hf_infiniband_reserved2,
+ {"Reserved (2 bits)", "infiniband.lrh.reserved2", FT_UINT8, BASE_DEC, NULL, 0x0C, NULL, HFILL}
+ },
+ {&hf_infiniband_link_next_header,
+ {"Link Next Header", "infiniband.lrh.lnh", FT_UINT8, BASE_HEX, NULL, 0x03, NULL, HFILL}
+ },
+ {&hf_infiniband_destination_local_id,
+ {"Destination Local ID", "infiniband.lrh.dlid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_reserved5,
+ {"Reserved (5 bits)", "infiniband.lrh.reserved5", FT_UINT16, BASE_DEC, NULL, 0xF800, NULL, HFILL}
+ },
+ {&hf_infiniband_packet_length,
+ {"Packet Length", "infiniband.lrh.pktlen", FT_UINT16, BASE_DEC, NULL, 0x07FF, NULL, HFILL}
+ },
+ {&hf_infiniband_source_local_id,
+ {"Source Local ID", "infiniband.lrh.slid", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* Global Route Header (GRH) */
+ {&hf_infiniband_GRH,
+ {"Global Route Header", "infiniband.grh", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_ip_version,
+ {"IP Version", "infiniband.grh.ipver", FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL}
+ },
+ {&hf_infiniband_traffic_class,
+ {"Traffic Class", "infiniband.grh.tclass", FT_UINT16, BASE_DEC, NULL, 0x0FF0, NULL, HFILL}
+ },
+ {&hf_infiniband_flow_label,
+ {"Flow Label", "infiniband.grh.flowlabel", FT_UINT32, BASE_DEC, NULL, 0x000FFFFF, NULL, HFILL}
+ },
+ {&hf_infiniband_payload_length,
+ {"Payload Length", "infiniband.grh.paylen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_next_header,
+ {"Next Header", "infiniband.grh.nxthdr", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_hop_limit,
+ {"Hop Limit", "infiniband.grh.hoplmt", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_source_gid,
+ {"Source GID", "infiniband.grh.sgid", FT_BYTES, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_destination_gid,
+ {"Destination GID", "infiniband.grh.dgid", FT_BYTES, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* Base Transport Header (BTH) */
+ {&hf_infiniband_BTH,
+ {"Base Transport Header", "infiniband.bth", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_opcode,
+ {"Opcode", "infiniband.bth.opcode", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_solicited_event,
+ {"Solicited Event", "infiniband.bth.se", FT_BOOLEAN, BASE_DEC, NULL, 0x80, NULL, HFILL}
+ },
+ {&hf_infiniband_migreq,
+ {"MigReq", "infiniband.bth.m", FT_BOOLEAN, BASE_DEC, NULL, 0x40, NULL, HFILL}
+ },
+ {&hf_infiniband_pad_count,
+ {"Pad Count", "infiniband.bth.padcnt", FT_UINT8, BASE_DEC, NULL, 0x30, NULL, HFILL}
+ },
+ {&hf_infiniband_transport_header_version,
+ {"Header Version", "infiniband.bth.tver", FT_UINT8, BASE_DEC, NULL, 0x0F, NULL, HFILL}
+ },
+ {&hf_infiniband_partition_key,
+ {"Partition Key", "infiniband.bth.p_key", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_reserved8,
+ {"Reserved (8 bits)", "infiniband.bth.reserved8", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_destination_qp,
+ {"Destination Queue Pair", "infiniband.bth.destqp", FT_UINT24, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_acknowledge_request,
+ {"Acknowledge Request", "infiniband.bth.a", FT_BOOLEAN, BASE_DEC, NULL, 0x80, NULL, HFILL}
+ },
+ {&hf_infiniband_reserved7,
+ {"Reserved (7 bits)", "infiniband.bth.reserved7", FT_UINT8, BASE_DEC, NULL, 0x7F, NULL, HFILL}
+ },
+ {&hf_infiniband_packet_sequence_number,
+ {"Packet Sequence Number", "infiniband.bth.psn", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* Reliable Datagram Extended Transport Header (RDETH) */
+ {&hf_infiniband_RDETH,
+ {"Reliable Datagram Extentded Transport Header", "infiniband.rdeth", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_reserved8_RDETH,
+ {"Reserved (8 bits)", "infiniband.rdeth.reserved8", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_ee_context,
+ {"E2E Context", "infiniband.rdeth.eecnxt", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* Datagram Extended Transport Header (DETH) */
+ {&hf_infiniband_DETH,
+ {"Datagram Extended Transport Header", "infiniband.deth", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_queue_key,
+ {"Queue Key", "infiniband.deth.q_key", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_reserved8_DETH,
+ {"Reserved (8 bits)", "infiniband.deth.reserved8", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_source_qp,
+ {"Source Queue Pair", "infiniband.deth.srcqp", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* RDMA Extended Transport Header (RETH) */
+ {&hf_infiniband_RETH,
+ {"RDMA Extended Transport Header", "infiniband.reth", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_virtual_address,
+ {"Virtual Address", "infiniband.reth.va", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_remote_key,
+ {"Remote Key", "infiniband.reth.r_key", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_dma_length,
+ {"DMA Length", "infiniband.reth.dmalen", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* Atomic Extended Transport Header (AtomicETH) */
+ {&hf_infiniband_AtomicETH,
+ {"Atomic Extended Transport Header", "infiniband.atomiceth", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_virtual_address_AtomicETH,
+ {"Virtual Address", "infiniband.atomiceth.va", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_remote_key_AtomicETH,
+ {"Remote Key", "infiniband.atomiceth.r_key", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_swap_or_add_data,
+ {"Swap (Or Add) Data", "infiniband.atomiceth.swapdt", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_compare_data,
+ {"Compare Data", "infiniband.atomiceth.cmpdt", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* ACK Extended Transport Header (AETH) */
+ {&hf_infiniband_AETH,
+ {"ACK Extended Transport Header", "infiniband.aeth", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_syndrome,
+ {"Syndrome", "infiniband.aeth.syndrome", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_message_sequence_number,
+ {"Message Sequence Number", "infiniband.aeth.msn", FT_UINT24, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+
+ /* Atomic ACK Extended Transport Header (AtomicAckETH) */
+ {&hf_infiniband_AtomicAckETH,
+ {"Atomic ACK Extended Transport Header", "infiniband.atomicacketh", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_original_remote_data,
+ {"Original Remote Data", "infiniband.atomicacketh.origremdt", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}
+ },
+ /* Immediate Extended Transport Header (ImmDT) */
+ {&hf_infiniband_IMMDT,
+ {"Immediate Data", "infiniband.immdt", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ /* Invalidate Extended Transport Header (IETH) */
+ {&hf_infiniband_IETH,
+ {"RKey", "infiniband.ieth", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ /* Payload */
+ {&hf_infiniband_payload,
+ {"Payload", "infiniband.payload", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_invariant_crc,
+ {"Invariant CRC", "infiniband.invariant.crc", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_variant_crc,
+ {"Variant CRC", "infiniband.variant.crc", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ {&hf_infiniband_raw_data,
+ {"Raw Data", "infiniband.rawdata", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ },
+ /* Unknown or Vendor Specific */
+ {&hf_infiniband_vendor,
+ {"Unknown/Vendor Specific Data", "infiniband.vendor", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL}
+ }
+
+};
+
+static gint *ett[] = {
+ &ett_infiniband
+};
+
+
+#endif
diff --git a/plugins/infiniband/plugin.rc.in b/plugins/infiniband/plugin.rc.in
new file mode 100644
index 0000000000..c01c45ba2a
--- /dev/null
+++ b/plugins/infiniband/plugin.rc.in
@@ -0,0 +1,34 @@
+#include "winver.h"
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION @RC_MODULE_VERSION@
+ PRODUCTVERSION @RC_VERSION@,0
+ FILEFLAGSMASK 0x0L
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_PRERELEASE+VS_FF_DEBUG
+#else
+ FILEFLAGS VS_FF_PRERELEASE
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_DLL
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Endace Technology Limited, http://www.endace.com/\0"
+ VALUE "FileDescription", "@PACKAGE@ dissector\0"
+ VALUE "FileVersion", "@MODULE_VERSION@\0"
+ VALUE "InternalName", "@PACKAGE@ @MODULE_VERSION@\0"
+ VALUE "LegalCopyright", "Copyright © 2008 Endace Technology Limited\0"
+ VALUE "OriginalFilename", "@PLUGIN_NAME@.dll\0"
+ VALUE "ProductName", "Wireshark\0"
+ VALUE "ProductVersion", "@VERSION@\0"
+ VALUE "Comments", "Build with @MSVC_VARIANT@\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/wiretap/erf.c b/wiretap/erf.c
index 01c6dbdbf4..e81f76cf55 100644
--- a/wiretap/erf.c
+++ b/wiretap/erf.c
@@ -159,7 +159,7 @@ int erf_open(wtap *wth, int *err, gchar **err_info _U_)
}
/* The ERF_TYPE_MAX is the PAD record, but the last used type is ERF_TYPE_AAL2 */
- if (header.type > ERF_TYPE_AAL2 ) {
+ if (header.type > ERF_TYPE_INFINIBAND) {
return 0;
}
@@ -347,7 +347,14 @@ static int erf_read_header(
pseudo_header->erf.phdr.wlen = g_ntohs(erf_header->wlen);
switch (erf_header->type) {
-
+
+ case ERF_TYPE_INFINIBAND:
+ if (phdr != NULL)
+ {
+ phdr->len = g_htons(erf_header->wlen);
+ phdr->caplen = g_htons(erf_header->wlen);
+ }
+ break;
case ERF_TYPE_HDLC_POS:
case ERF_TYPE_COLOR_HDLC_POS:
case ERF_TYPE_DSM_COLOR_HDLC_POS:
diff --git a/wiretap/erf.h b/wiretap/erf.h
index cf46072b29..ee79d974f1 100644
--- a/wiretap/erf.h
+++ b/wiretap/erf.h
@@ -58,6 +58,7 @@
#define ERF_TYPE_DSM_COLOR_ETH 16
#define ERF_TYPE_COLOR_MC_HDLC_POS 17
#define ERF_TYPE_AAL2 18
+#define ERF_TYPE_INFINIBAND 21
#define ERF_TYPE_PAD 48