aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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