diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/Makefile.am | 1 | ||||
-rw-r--r-- | plugins/Makefile.nmake | 4 | ||||
-rw-r--r-- | plugins/infiniband/Makefile.am | 119 | ||||
-rw-r--r-- | plugins/infiniband/Makefile.common | 26 | ||||
-rw-r--r-- | plugins/infiniband/Makefile.nmake | 96 | ||||
-rw-r--r-- | plugins/infiniband/moduleinfo.h | 18 | ||||
-rw-r--r-- | plugins/infiniband/moduleinfo.nmake | 28 | ||||
-rw-r--r-- | plugins/infiniband/packet-infiniband.c | 857 | ||||
-rw-r--r-- | plugins/infiniband/packet-infiniband.h | 686 | ||||
-rw-r--r-- | plugins/infiniband/plugin.rc.in | 34 |
10 files changed, 1869 insertions, 0 deletions
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 |