Ethereal-dev: [Ethereal-dev] A set of patches for Fibre Channel & SCSI

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Dinesh G Dutt <ddutt@xxxxxxxxx>
Date: Tue, 13 Sep 2005 23:41:25 -0700
I'm attaching a set of patches for various Fibre Channel and SCSI
dissectors. They support some new messages and fix a couple of bugs.

packet-fc.h - Added a #define for a Cisco MDS-specific frame called OHMS
(online health mgmt srv)
packet-fc.c - Support for OHMS frame, fixed an incorrect "malformed
frame" error caused on ACK1 frames (they
                   don't contain anything but (encap hdr + FC hdr +
encap trailer), fixed incorrect detection of
                   last-data-frame

packet-fcct.h - Support for new service type, "Fabric Controller", used
in conjunction with FC-SW3 ESS message,
                     exported the service name value string definitions
and  
packet-fcct.c - Support for recognizing "Fabric Controller" service type
and "vendor-specific" service

packet-fcswils.h - Support for ESS & MRRA messages, defined as part of
FC-SW3
packet-fcswils.c - Support for ESS & MRRA messages, defined as part of
FC-SW3

packet-scsi.c - Support for Verify and Write&Verify SBC commands.

Dinesh

-- 
The highest achievement possible to a man is the full consciousness of 
his own feelings and thoughts, for this gives him the means of knowing  
intimately the hearts of others.          - Johann Wolfgang von Goethe

Index: packet-fc.c
===================================================================
--- packet-fc.c	(revision 15739)
+++ packet-fc.c	(working copy)
@@ -291,6 +291,7 @@
     {FC_FTYPE_VDO,       "Video Data"},
     {FC_FTYPE_LINKCTL,   "Link Ctl"},
     {FC_FTYPE_SBCCS,     "SBCCS"},
+    {FC_FTYPE_OHMS,      "OHMS(Cisco MDS)"},
     {0, NULL},
 };
 
@@ -566,14 +567,18 @@
         case FC_TYPE_SB_FROM_CU:
         case FC_TYPE_SB_TO_CU:
             return FC_FTYPE_SBCCS;
+        case FC_TYPE_VENDOR:
+             return FC_FTYPE_OHMS;
         default:
             return FC_FTYPE_UNDEF;
         }
     case FC_RCTL_ELS:
         if (((r_ctl & 0x0F) == 0x2) || ((r_ctl & 0x0F) == 0x3))
             return FC_FTYPE_ELS;
+        else if (type == FC_TYPE_ELS) 
+            return FC_FTYPE_OHMS;
         else
-            return FC_FTYPE_UNDEF;
+             return FC_FTYPE_UNDEF;
     case FC_RCTL_LINK_DATA:
         return FC_FTYPE_LINKDATA;
     case FC_RCTL_VIDEO:
@@ -809,9 +814,7 @@
     
     is_lastframe_inseq = ((pinfo->sof_eof & PINFO_EOF_LAST_FRAME) == PINFO_EOF_LAST_FRAME);
 
-    if ((pinfo->sof_eof & PINFO_SOF_SOFF) == PINFO_SOF_SOFF) {
-        is_lastframe_inseq = fchdr.fctl & FC_FCTL_SEQ_LAST;
-    }
+    is_lastframe_inseq |= fchdr.fctl & FC_FCTL_SEQ_LAST;
     is_valid_frame = ((pinfo->sof_eof & 0x40) == 0x40);
 
     ftype = fc_get_ftype (fchdr.r_ctl, fchdr.type);
@@ -1113,14 +1116,22 @@
 
     frag_size = tvb_reported_length (tvb)-FC_HEADER_SIZE;
 
-    /* If there is an MDS header, we need to subtract the MDS trailer size */
+    /* If there is an MDS header, we need to subtract the MDS trailer size
+     * Link Ctl, BLS & OHMS are all (encap header + FC Header + encap trailer)
+     * and are never fragmented and so we ignore the frag_size assertion for
+     *  these frames.
+     */
     if ((pinfo->ethertype == ETHERTYPE_UNK) || (pinfo->ethertype == ETHERTYPE_FCFT)) {
-        if (frag_size <= MDSHDR_TRAILER_SIZE)
+         if ((frag_size <= MDSHDR_TRAILER_SIZE) &&
+             ((frag_size == MDSHDR_TRAILER_SIZE) && (ftype != FC_FTYPE_LINKCTL) &&
+              (ftype != FC_FTYPE_BLS) && (ftype != FC_FTYPE_OHMS)))
 	    THROW(ReportedBoundsError);
         frag_size -= MDSHDR_TRAILER_SIZE;
     } else if (pinfo->ethertype == ETHERTYPE_BRDWALK) {
-        if (frag_size <= 8)
-	    THROW(ReportedBoundsError);
+         if ((frag_size <= 8) &&
+             ((frag_size == MDSHDR_TRAILER_SIZE) && (ftype != FC_FTYPE_LINKCTL) &&
+              (ftype != FC_FTYPE_BLS) && (ftype != FC_FTYPE_OHMS)))
+              THROW(ReportedBoundsError);
         frag_size -= 8;         /* 4 byte of FC CRC +
                                    4 bytes of error+EOF = 8 bytes  */
     }
@@ -1136,6 +1147,7 @@
      * present, if we're configured to reassemble.
      */
     if ((ftype != FC_FTYPE_LINKCTL) && (ftype != FC_FTYPE_BLS) &&
+        (ftype != FC_FTYPE_OHMS) &&
         (!is_lastframe_inseq || !is_1frame_inseq) && fc_reassemble &&
         tvb_bytes_exist(tvb, FC_HEADER_SIZE, frag_size) && tree) {
         /* Add this to the list of fragments */

Index: packet-fc.h
===================================================================
--- packet-fc.h	(revision 15739)
+++ packet-fc.h	(working copy)
@@ -51,6 +51,7 @@
 #define FC_TYPE_SWILS          0x22
 #define FC_TYPE_AL             0x23
 #define FC_TYPE_SNMP           0x24
+#define FC_TYPE_VENDOR         0xFF
 
 
 /*
@@ -83,6 +84,7 @@
 #define FC_FTYPE_LINKCTL       0xA
 #define FC_FTYPE_SWILS_RSP     0xB
 #define FC_FTYPE_SBCCS         0xC
+#define FC_FTYPE_OHMS          0xD
 
 /* Well-known Address Definitions (in Network order) */
 #define FC_WKA_MULTICAST       0xFFFFF5


Index: packet-fcct.c
===================================================================
--- packet-fcct.c	(revision 15739)
+++ packet-fcct.c	(working copy)
@@ -78,16 +78,18 @@
     {0, NULL},
 };
 
-static const value_string fc_ct_gstype_vals[] = {
+const value_string fc_ct_gstype_vals[] = {
     {FCCT_GSTYPE_KEYSVC, "Key Service"},
     {FCCT_GSTYPE_ALIASSVC, "Alias Service"},
     {FCCT_GSTYPE_MGMTSVC, "Management Service"},
     {FCCT_GSTYPE_TIMESVC, "Time Service"},
     {FCCT_GSTYPE_DIRSVC, "Directory Service"},
+    {FCCT_GSTYPE_FCTLR, "Fabric Controller"},
+    {FCCT_GSTYPE_VENDOR, "Vendor-Specific"},
     {0, NULL},
 };
 
-static const value_string fc_ct_gsserver_vals[] = {
+const value_string fc_ct_gsserver_vals[] = {
     {FCCT_GSRVR_DNS, "dNS"},
     {FCCT_GSRVR_IP,  "IP"},
     {FCCT_GSRVR_FCS, "Fabric Config Server"},
@@ -96,13 +98,14 @@
     {FCCT_GSRVR_TS,  "Time Server"},
     {FCCT_GSRVR_KS,  "Key Server"},
     {FCCT_GSRVR_AS,  "Alias Server"},
+    {FCCT_GSRVR_FCTLR, "Fabric Controller"},
     {0, NULL},
 };
 
 static dissector_table_t fcct_gserver_table;
 static dissector_handle_t data_handle;
 
-static guint8
+guint8
 get_gs_server (guint8 gstype, guint8 gssubtype)
 {
     switch (gstype) {
@@ -130,6 +133,10 @@
         else if (gssubtype == FCCT_GSSUBTYPE_IP)
             return FCCT_GSRVR_IP;
         return FCCT_GSRVR_UNKNOWN;
+    case FCCT_GSRVR_FCTLR:
+         if (gssubtype == FCCT_GSSUBTYPE_FCTLR)
+              return (FCCT_GSRVR_FCTLR);
+         else return (FCCT_GSRVR_UNKNOWN);
     default:
         return FCCT_GSRVR_UNKNOWN;
     }

Index: packet-fcct.h
===================================================================
--- packet-fcct.h	(revision 15739)
+++ packet-fcct.h	(working copy)
@@ -30,9 +30,12 @@
 #define FCCT_GSTYPE_MGMTSVC  0xFA
 #define FCCT_GSTYPE_TIMESVC  0xFB
 #define FCCT_GSTYPE_DIRSVC   0xFC
+#define FCCT_GSTYPE_FCTLR    0xFD
+#define FCCT_GSTYPE_VENDOR   0xE0
 
 /* Well-known GSSUBTYPES */
-/* Actual servers serving the directory service type identified by subtype */ 
+/* Actual servers serving the directory service type identified by subtype */
+#define FCCT_GSSUBTYPE_FCTLR 0x0
 #define FCCT_GSSUBTYPE_DNS  0x02
 #define FCCT_GSSUBTYPE_IP   0x03
 #define FCCT_GSSUBTYPE_FCS  0x01
@@ -50,6 +53,7 @@
 #define FCCT_GSRVR_AS        0x6
 #define FCCT_GSRVR_TS        0x7
 #define FCCT_GSRVR_KS        0x8
+#define FCCT_GSRVR_FCTLR     0x9
 #define FCCT_GSRVR_UNKNOWN   0xFF
 
 /* Reject code definitions */
@@ -69,7 +73,10 @@
 #define FCCT_PRMBL_SIZE        16
 #define FCCT_EXTPRMBL_SIZE     88
 
+extern const value_string fc_ct_gstype_vals [];
+extern const value_string fc_ct_gsserver_vals [];
 extern const value_string fc_ct_rjt_code_vals [];
+extern guint8 get_gs_server (guint8 type, guint8 subtype);
 
 typedef struct _fc_ct_preamble {
     guint32 in_id:24,

Index: packet-mdshdr.c
===================================================================
--- packet-mdshdr.c	(revision 15739)
+++ packet-mdshdr.c	(working copy)
@@ -191,7 +191,7 @@
     }
 
     pinfo->src_idx = (tvb_get_ntohs (tvb, MDSHDR_SIDX_OFFSET) & 0x3FF);
-    pinfo->dst_idx = (tvb_get_ntohs (tvb, MDSHDR_DIDX_OFFSET) & 0xFFC) >> 6;
+    pinfo->dst_idx = (tvb_get_ntohs (tvb, MDSHDR_DIDX_OFFSET) & 0xFFC) >> 2;
     pinfo->vsan = vsan;
     pinfo->sof_eof = 0;
 

Index: packet-fcswils.c
===================================================================
--- packet-fcswils.c	(revision 15739)
+++ packet-fcswils.c	(working copy)
@@ -47,6 +47,7 @@
 #include "etypes.h"
 #include "packet-fc.h"
 #include "packet-fcswils.h"
+#include "packet-fcct.h"
 
 /*
  * See the FC-SW specifications.
@@ -147,7 +148,50 @@
 static int hf_swils_rjtdet             = -1;
 static int hf_swils_rjtvendor          = -1;
 static int hf_swils_zone_mbrid_lun     = -1;
+static int hf_swils_ess_rev = -1;
+static int hf_swils_ess_len = -1;
+static int hf_swils_ess_numobj = -1;
+static int hf_swils_interconnect_list_len = -1;
+static int hf_swils_ess_vendorname = -1;
+static int hf_swils_ess_modelname = -1;
+static int hf_swils_ess_relcode = -1;
+static int hf_swils_ess_vendorspecific = -1;
+static int hf_swils_ess_cap_type = -1;
+static int hf_swils_ess_cap_subtype = -1;
+static int hf_swils_ess_cap_numentries = -1;
+static int hf_swils_ess_cap_svc = -1;
+static int hf_swils_ess_dns_obj0h = -1;
+static int hf_swils_ess_dns_obj1h = -1;
+static int hf_swils_ess_dns_obj2h = -1;
+static int hf_swils_ess_dns_obj3h = -1;
+static int hf_swils_ess_dns_zlacc = -1;
+static int hf_swils_ess_dns_vendor = -1;
+static int hf_swils_ess_fctlr_rscn = -1;
+static int hf_swils_ess_fctlr_vendor = -1;
+static int hf_swils_ess_fcs_basic = -1;
+static int hf_swils_ess_fcs_platform = -1;
+static int hf_swils_ess_fcs_topology = -1;
+static int hf_swils_ess_fcs_enhanced = -1;
+static int hf_swils_ess_fzs_enh_supp = -1;
+static int hf_swils_ess_fzs_enh_ena = -1;
+static int hf_swils_ess_fzs_mr = -1;
+static int hf_swils_ess_fzs_zsdb_supp = -1;
+static int hf_swils_ess_fzs_zsdb_ena = -1;
+static int hf_swils_ess_fzs_adc_supp = -1;
+static int hf_swils_ess_fzs_hardzone = -1;
+static int hf_swils_mrra_rev = -1;
+static int hf_swils_mrra_size = -1;
+static int hf_swils_mrra_vendorid = -1;
+static int hf_swils_mrra_reply = -1;
+static int hf_swils_mrra_reply_size = -1;
+static int hf_swils_mrra_waittime = -1;
+static int hf_swils_ess_cap_t10 = -1;
+static int hf_swils_ess_cap_vendorobj = -1;
+static int hf_swils_ess_fzs_defzone = -1;
+static int hf_swils_ess_cap_len = -1;
+static int hf_swils_mrra_vendorinfo = -1;
 
+
 /* Initialize the subtree pointers */
 static gint ett_fcswils             = -1;
 static gint ett_fcswils_swacc       = -1;
@@ -179,6 +223,8 @@
 static gint ett_fcswils_ufc         = -1;
 static gint ett_fcswils_esc         = -1;
 static gint ett_fcswils_esc_pdesc   = -1;
+static gint ett_fcswils_ieinfo      = -1;
+static gint ett_fcswils_capinfo     = -1;
 
 static const value_string fc_swils_opcode_key_val[] = {
     {FC_SWILS_SWRJT  , "SW_RJT"},
@@ -202,6 +248,8 @@
     {FC_SWILS_SFC    , "SFC"},
     {FC_SWILS_UFC    , "UFC"},
     {FC_SWILS_ESC    , "ESC"},
+    {FC_SWILS_ESS    , "ESS"},
+    {FC_SWILS_MRRA   , "MRRA"},
     {FC_SWILS_AUTH_ILS, "AUTH_ILS"},
     {0, NULL},
 };
@@ -383,6 +431,13 @@
 
 GHashTable *fcswils_req_hash = NULL;
 
+/* list of commands for each commandset */
+typedef void (*fcswils_dissector_t)(tvbuff_t *tvb, proto_tree *tree, guint8 isreq);
+
+typedef struct _fcswils_func_table_t {
+	fcswils_dissector_t	func;
+} fcswils_func_table_t;
+
 static dissector_handle_t data_handle, fcsp_handle;
 
 static gint get_zoneobj_len (tvbuff_t *tvb, gint offset);
@@ -420,6 +475,7 @@
             g_hash_table_destroy (fcswils_req_hash);
 
 	fcswils_req_hash = g_hash_table_new(fcswils_hash, fcswils_equal);
+
 }
 
 static guint8 *
@@ -469,7 +525,190 @@
     return len;
 }
 
+#define MAX_INTERCONNECT_ELEMENT_INFO_LEN  252
+static int
+dissect_swils_interconnect_element_info (tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+     
+     int len, max_len = MAX_INTERCONNECT_ELEMENT_INFO_LEN;
+     
+     if (tree) {
+          proto_tree_add_item (tree, hf_swils_interconnect_list_len, tvb, offset+3, 1, 0);
+          len = tvb_strsize (tvb, offset+4);
+          proto_tree_add_item (tree, hf_swils_ess_vendorname, tvb, offset+4, len, FALSE);
+          offset += (4 + len);
+          max_len -= len;
+          len = tvb_strsize (tvb, offset);
+          proto_tree_add_item (tree, hf_swils_ess_modelname, tvb, offset, len, FALSE);
+          offset += len;
+          max_len -= len;
+          len = tvb_strsize (tvb, offset);
+          proto_tree_add_item (tree, hf_swils_ess_relcode, tvb, offset, len, FALSE);
+          offset += len;
+          max_len -= len;
+          while (max_len > 0) {
+               /* Vendor specific field is a set of one or more null-terminated
+                * strings
+                */
+               len = tvb_strsize (tvb, offset);
+               proto_tree_add_item (tree, hf_swils_ess_vendorspecific, tvb, offset, len, FALSE);
+               offset += len;
+               max_len -= len;
+          }
+     }
+
+     return TRUE;
+}
+
 static void
+dissect_swils_ess_capability (tvbuff_t *tvb, proto_tree *tree, int offset,
+                              guint8 srvr_type)
+{
+     if (tree) {
+          switch (srvr_type) {
+          case FCCT_GSRVR_DNS:
+               proto_tree_add_item (tree, hf_swils_ess_dns_zlacc, tvb, offset+3,
+                                    1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_dns_obj3h, tvb, offset+3,
+                                    1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_dns_obj2h, tvb, offset+3,
+                                    1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_dns_obj1h, tvb, offset+3,
+                                    1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_dns_obj0h, tvb, offset+3,
+                                    1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_dns_vendor, tvb,
+                                    offset+4, 4, 0);
+               break;
+          case FCCT_GSRVR_FCTLR:
+               proto_tree_add_item (tree, hf_swils_ess_fctlr_rscn, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fctlr_vendor, tvb,
+                                    offset+4, 4, 0);
+               break;
+          case FCCT_GSRVR_FCS:
+               proto_tree_add_item (tree, hf_swils_ess_fcs_basic, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fcs_platform, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fcs_topology, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fcs_enhanced, tvb,
+                                    offset+3, 1, 0);
+               break;
+          case FCCT_GSRVR_FZS:
+               proto_tree_add_item (tree, hf_swils_ess_fzs_enh_supp, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fzs_enh_ena, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fzs_mr, tvb, offset+3,
+                                    1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fzs_defzone, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fzs_zsdb_supp, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fzs_zsdb_ena, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fzs_adc_supp, tvb,
+                                    offset+3, 1, 0);
+               proto_tree_add_item (tree, hf_swils_ess_fzs_hardzone, tvb,
+                                    offset+3, 1, 0);
+               break;
+          default:
+               break;
+          }
+     }
+     
+     return;
+}
+
+static int
+dissect_swils_ess_capability_obj (tvbuff_t *tvb, proto_tree *tree, int offset)
+{
+     int i, num_entries, len = 0, total_len = 0;
+     guint8 type, subtype, srvr_type;
+     proto_item *ti = NULL;
+     proto_tree *capinfo_tree = NULL;
+
+     if (tree) {
+          /*
+           * Structure of capability object is: WK type (2B), WK subtype(2),
+           * rsvd (1), num_cap_entries (1), entry_1 (8) ... entry_n (8)
+           */
+          /* Compute length first to create subtree of cap object */
+          type = tvb_get_guint8 (tvb, offset);
+          if (type != FCCT_GSTYPE_VENDOR) {
+               num_entries = tvb_get_guint8 (tvb, offset+3);
+               total_len = 4 + (num_entries*8);
+               ti = proto_tree_add_text (tree, tvb, offset,
+                                         total_len, "Capabilty Object (%s)",
+                                         val_to_str (type, fc_ct_gstype_vals,
+                                                     "Unknown (0x%x)"));
+               capinfo_tree = proto_item_add_subtree (ti, ett_fcswils_capinfo);
+
+          } else {
+               i = tvb_get_guint8 (tvb, offset+3);
+               i += 12;
+
+               ti = proto_tree_add_text (tree, tvb, offset,
+                                         i, "Capabilty Object (Vendor-specific 0x%x)",
+                                         type);
+               capinfo_tree = proto_item_add_subtree (ti, ett_fcswils_capinfo);
+          }
+          
+          proto_tree_add_item (capinfo_tree, hf_swils_ess_cap_type, tvb, offset, 1, 0);
+          proto_tree_add_item (capinfo_tree, hf_swils_ess_cap_subtype, tvb, offset+1,
+                               1, 0);
+          subtype = tvb_get_guint8 (tvb, offset+1);
+          
+          if (type != FCCT_GSTYPE_VENDOR) {
+               srvr_type = get_gs_server (type, subtype);
+               proto_tree_add_uint (capinfo_tree, hf_swils_ess_cap_svc, tvb, offset, 2,
+                                    srvr_type);
+               proto_tree_add_item (capinfo_tree, hf_swils_ess_cap_numentries, tvb,
+                                    offset+3, 1, 0);
+               offset += 4;
+               len += 4;
+          
+               while ((num_entries > 0) && tvb_bytes_exist (tvb, offset, 8)) {
+                    dissect_swils_ess_capability (tvb, capinfo_tree, offset, srvr_type);
+                    num_entries--;
+                    offset += 8;
+                    len += 8;
+               }
+          } else {
+               /* Those damn T11 guys defined another format for
+                * Vendor-specific objects.
+                */
+               proto_tree_add_item (capinfo_tree, hf_swils_ess_cap_len, tvb, offset+3,
+                                    1, 0);
+               proto_tree_add_item (capinfo_tree, hf_swils_ess_cap_t10, tvb, offset+4,
+                                    8, 0);
+               i -= 8;          /* reduce length by t10 object size */
+               offset += 12;
+               len += 12;
+
+               while ((i > 0) && tvb_bytes_exist (tvb, offset, 8)) {
+                    proto_tree_add_item (capinfo_tree, hf_swils_ess_cap_vendorobj,
+                                         tvb, offset, 8, 0);
+                    i -= 8;
+                    offset += 8;
+                    len += 12;
+               }
+          }
+     }
+     return len;
+}
+
+static void
+dissect_swils_nullpayload (tvbuff_t *tvb _U_, proto_tree *tree _U_,
+                           guint8 isreq _U_)
+{
+     /* Common dissector for those ILSs without a payload */
+     return;
+}
+
+static void
 dissect_swils_elp (tvbuff_t *tvb, proto_tree *elp_tree, guint8 isreq _U_)
 {
     
@@ -1411,7 +1650,7 @@
 }
 
 static void
-dissect_swils_swrjt (tvbuff_t *tvb, proto_tree *swrjt_tree)
+dissect_swils_swrjt (tvbuff_t *tvb, proto_tree *swrjt_tree, guint8 isreq _U_)
 {
     /* Set up structures needed to add the protocol subtree and manage it */
     int offset = 0;
@@ -1424,6 +1663,132 @@
     }
 }
 
+static void
+dissect_swils_ess (tvbuff_t *tvb, proto_tree *ess_tree, guint8 isreq _U_)
+{
+     int offset = 0;
+     gint16 numcapobj = 0;
+     gint len = 0;
+     gint capobjlen = 0;
+     proto_item *ti = NULL;
+     proto_tree *ieinfo_tree = NULL;
+
+     if (!ess_tree) {
+          return;
+     }
+
+     proto_tree_add_item (ess_tree, hf_swils_ess_rev, tvb, offset+4, 4, 0);
+     proto_tree_add_item (ess_tree, hf_swils_ess_len, tvb, offset+8, 4, 0);
+     len = tvb_get_ntohl (tvb, offset+8);
+
+     ti = proto_tree_add_text (ess_tree, tvb, offset+12,
+                               MAX_INTERCONNECT_ELEMENT_INFO_LEN+4,
+                               "Interconnect Element Info");
+     ieinfo_tree = proto_item_add_subtree (ti, ett_fcswils_ieinfo);
+     dissect_swils_interconnect_element_info (tvb, ieinfo_tree, offset+12);
+     len -= 256;                /* the interconnect obj above is 256 bytes */
+     offset += 268;
+
+     proto_tree_add_item (ess_tree, hf_swils_ess_numobj, tvb, offset, 2, 0);
+     numcapobj = tvb_get_ntohs (tvb, offset);
+
+     len -= 4;                  /* 2B numcapobj + 2B rsvd */
+     offset += 4;
+
+     while ((len > 0) && (numcapobj > 0)) {
+          capobjlen = dissect_swils_ess_capability_obj (tvb, ess_tree, offset);
+          numcapobj--;
+          len -= capobjlen;
+          offset += capobjlen;
+     }
+}
+
+static void
+dissect_swils_mrra (tvbuff_t *tvb, proto_tree *tree, guint8 isreq)
+{
+
+     int offset = 0;
+     
+     if (!tree) {
+          return;
+     }
+
+     if (isreq) {
+          proto_tree_add_item (tree, hf_swils_mrra_rev, tvb, offset+4, 4, 0);
+          proto_tree_add_item (tree, hf_swils_mrra_size, tvb, offset+8, 4, 0);
+          proto_tree_add_item (tree, hf_swils_mrra_vendorid, tvb, offset+12, 8, 0);
+          proto_tree_add_item (tree, hf_swils_mrra_vendorinfo, tvb, offset+20,
+                               8, 0);
+     } else {
+          proto_tree_add_item (tree, hf_swils_mrra_vendorid, tvb, offset+4,
+                               8, 0);
+          proto_tree_add_item (tree, hf_swils_mrra_reply, tvb, offset+12,
+                               4, 0);
+          proto_tree_add_item (tree, hf_swils_mrra_reply_size, tvb, offset+16,
+                               4, 0);
+          proto_tree_add_item (tree, hf_swils_mrra_waittime, tvb, offset+20,
+                               4, 0);
+     }
+
+     
+}
+
+static fcswils_func_table_t fcswils_func_table[FC_SWILS_MAXCODE] = {
+     /* 0x00 */ {NULL},
+     /* 0x01 */ {dissect_swils_swrjt},
+     /* 0x02 */ {NULL},
+     /* 0x03 */ {NULL},
+     /* 0x04 */ {NULL},
+     /* 0x05 */ {NULL},
+     /* 0x06 */ {NULL},
+     /* 0x07 */ {NULL},
+     /* 0x08 */ {NULL},
+     /* 0x09 */ {NULL},
+     /* 0x0a */ {NULL},
+     /* 0x0b */ {NULL},
+     /* 0x0c */ {NULL},
+     /* 0x0d */ {NULL},
+     /* 0x0e */ {NULL},
+     /* 0x0f */ {NULL},
+     /* 0x10 */ {dissect_swils_elp},
+     /* 0x11 */ {dissect_swils_efp},
+     /* 0x12 */ {dissect_swils_dia},
+     /* 0x13 */ {dissect_swils_rdi},
+     /* 0x14 */ {dissect_swils_hello},
+     /* 0x15 */ {dissect_swils_lsupdate},
+     /* 0x16 */ {dissect_swils_lsack},
+     /* 0x17 */ {dissect_swils_nullpayload},
+     /* 0x18 */ {dissect_swils_nullpayload},
+     /* 0x19 */ {NULL},
+     /* 0x1a */ {NULL},
+     /* 0x1b */ {dissect_swils_rscn},
+     /* 0x1c */ {NULL},
+     /* 0x1d */ {NULL},
+     /* 0x1e */ {dissect_swils_drlir},
+     /* 0x1f */ {NULL},
+     /* 0x20 */ {NULL /*dissect_swils_dscn*/},
+     /* 0x21 */ {NULL /*dissect_swils_loopd*/},
+     /* 0x22 */ {dissect_swils_mergereq},
+     /* 0x23 */ {dissect_swils_aca},
+     /* 0x24 */ {dissect_swils_rca},
+     /* 0x25 */ {dissect_swils_sfc},
+     /* 0x26 */ {dissect_swils_ufc},
+     /* 0x27 */ {NULL},
+     /* 0x28 */ {NULL},
+     /* 0x29 */ {NULL},
+     /* 0x2a */ {NULL},
+     /* 0x2b */ {NULL},
+     /* 0x2c */ {NULL},
+     /* 0x2d */ {NULL},
+     /* 0x2e */ {NULL},
+     /* 0x2f */ {NULL},
+     /* 0x30 */ {dissect_swils_esc},
+     /* 0x31 */ {dissect_swils_ess},
+     /* 0x32 */ {NULL},
+     /* 0x33 */ {NULL},
+     /* 0x34 */ {dissect_swils_mrra}
+};
+
 /* Code to actually dissect the packets */
 static void
 dissect_fcswils (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@@ -1540,66 +1905,16 @@
         proto_tree_add_item (swils_tree, hf_swils_opcode, tvb, offset, 1, 0);
     }
 
-    switch (opcode) {
-    case FC_SWILS_SWRJT:
-        dissect_swils_swrjt (tvb, swils_tree);
-        break;
-    case FC_SWILS_ELP:
-        dissect_swils_elp (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_EFP:
-        dissect_swils_efp (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_DIA:
-        dissect_swils_dia (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_RDI:
-        dissect_swils_rdi (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_HLO:
-        dissect_swils_hello (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_LSU:
-        dissect_swils_lsupdate (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_LSA:
-        dissect_swils_lsack (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_BF:
-    case FC_SWILS_RCF:
-        /* Nothing to be displayed for these two commands */
-        break;
-    case FC_SWILS_RSCN:
-        dissect_swils_rscn (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_DRLIR:
-        dissect_swils_drlir (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_MR:
-        dissect_swils_mergereq (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_ACA:
-        dissect_swils_aca (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_RCA:
-        dissect_swils_rca (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_SFC:
-        dissect_swils_sfc (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_UFC:
-        dissect_swils_ufc (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_ESC:
-        dissect_swils_esc (tvb, swils_tree, isreq);
-        break;
-    case FC_SWILS_AUTH_ILS:
-        if (isreq && fcsp_handle) 
-            call_dissector (fcsp_handle, tvb, pinfo, swils_tree);
-        break;
-    default:
-        next_tvb = tvb_new_subset (tvb, offset+4, -1, -1);
-        call_dissector (data_handle, next_tvb, pinfo, tree);
+    if ((opcode < FC_SWILS_MAXCODE) && fcswils_func_table[opcode].func) {
+         fcswils_func_table[opcode].func (tvb, swils_tree, isreq);
+    } else if (opcode == FC_SWILS_AUTH_ILS) {
+         /* This is treated differently */
+         if (isreq && fcsp_handle) 
+              call_dissector (fcsp_handle, tvb, pinfo, swils_tree);
+    } else {
+         /* data dissector */
+         next_tvb = tvb_new_subset (tvb, offset+4, -1, -1);
+         call_dissector (data_handle, next_tvb, pinfo, tree);
     }
 
 }
@@ -1864,6 +2179,135 @@
         { &hf_swils_zone_mbrid_lun,
           {"LUN", "swils.zone.lun", FT_BYTES, BASE_HEX, NULL, 0x0, "",
            HFILL}},
+        { &hf_swils_ess_rev,
+          {"Revision", "swils.ess.revision", FT_UINT32, BASE_DEC, NULL, 0x0, "",
+           HFILL}},
+        { &hf_swils_ess_len,
+          {"Payload Length", "swils.ess.leb", FT_UINT32, BASE_DEC, NULL, 0x0,
+           "", HFILL}},
+        { &hf_swils_ess_numobj,
+          {"Number of Capability Objects", "swils.ess.numobj", FT_UINT16, BASE_DEC,
+           NULL, 0x0, "", HFILL}},
+        { &hf_swils_interconnect_list_len,
+          {"List Length", "swils.ess.listlen", FT_UINT8, BASE_DEC, NULL, 0x0, "",
+           HFILL}},
+        { &hf_swils_ess_vendorname,
+          {"Vendor Name", "swils.ess.vendorname", FT_STRING, BASE_DEC, NULL,
+           0x0, "", HFILL}},
+        { &hf_swils_ess_modelname,
+          {"Model Name", "swils.ess.modelname", FT_STRING, BASE_DEC, NULL, 0x0,
+           "", HFILL}},
+        { &hf_swils_ess_relcode,
+          {"Release Code", "swils.ess.relcode", FT_STRING, BASE_DEC, NULL, 0x0,
+           "", HFILL}},
+        { &hf_swils_ess_vendorspecific,
+          {"Vendor Specific", "swils.ess.vendorspecific", FT_STRING, BASE_HEX,
+           NULL, 0x0, "", HFILL}},
+        { &hf_swils_ess_cap_type,
+          {"Type", "swils.ess.capability.type", FT_UINT8, BASE_DEC,
+           VALS (fc_ct_gstype_vals), 0x0, "", HFILL}},
+        { &hf_swils_ess_cap_subtype,
+          {"Subtype", "swils.ess.capability.subtype", FT_UINT8, BASE_DEC, NULL,
+           0x0, "", HFILL}},
+        { &hf_swils_ess_cap_numentries,
+          {"Number of Entries", "swils.ess.capability.numentries", FT_UINT8,
+           BASE_DEC, NULL, 0x0, "", HFILL}},
+        { &hf_swils_ess_cap_svc,
+          {"Service Name", "swils.ess.capability.service", FT_UINT8, BASE_DEC,
+           VALS (fc_ct_gsserver_vals), 0x0, "", HFILL}},
+        { &hf_swils_ess_dns_obj0h,
+          {"Name Server Entry Object 00h Support", "swils.ess.capability.dns.obj0h",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x1, "", HFILL}},
+        { &hf_swils_ess_dns_obj1h,
+          {"Name Server Entry Object 01h Support", "swils.ess.capability.dns.obj1h",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x2, "", HFILL}},
+        { &hf_swils_ess_dns_obj2h,
+          {"Name Server Entry Object 02h Support", "swils.ess.capability.dns.obj2h",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x4, "", HFILL}},
+        { &hf_swils_ess_dns_obj3h,
+          {"Name Server Entry Object 03h Support", "swils.ess.capability.dns.obj3h",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x8, "", HFILL}},
+        { &hf_swils_ess_dns_zlacc,
+          {"GE_PT Zero Length Accepted", "swils.ess.capability.dns.zlacc",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x10, "", HFILL}},
+        { &hf_swils_ess_dns_vendor,
+          {"Vendor Specific Flags", "swils.ess.capability.dns.vendor", FT_UINT32,
+           BASE_HEX, NULL, 0x0, "", HFILL}},
+        { &hf_swils_ess_fctlr_rscn,
+          {"SW_RSCN Supported", "swils.ess.capability.fctlr.rscn", FT_BOOLEAN,
+           BASE_HEX, NULL, 0x1, "", HFILL}},
+        { &hf_swils_ess_fctlr_vendor,
+          {"Vendor Specific Flags", "swils.ess.capability.fctlr.vendor",
+           FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL}},
+        { &hf_swils_ess_fcs_basic,
+          {"Basic Configuration Services", "swils.ess.capability.fcs.basic",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x1, "", HFILL}},
+        { &hf_swils_ess_fcs_platform,
+          {"Platform Configuration Services",
+           "swils.ess.capability.fcs.platform", FT_BOOLEAN, BASE_HEX, NULL,
+           0x2, "", HFILL}},
+        { &hf_swils_ess_fcs_topology,
+          {"Topology Discovery Services", "swils.ess.capability.fcs.topology",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x4, "", HFILL}},
+        { &hf_swils_ess_fcs_enhanced,
+          {"Enhanced Configuration Services",
+           "swils.ess.capability.fcs.enhanced", FT_BOOLEAN, BASE_HEX, NULL, 0x8,
+           "", HFILL}},
+        { &hf_swils_ess_fzs_enh_supp,
+          {"Enhanced Zoning Supported", "swils.ess.capability.fzs.ezonesupp",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x1, "", HFILL}},
+        { &hf_swils_ess_fzs_enh_ena,
+          {"Enhanced Zoning Enabled", "swils.ess.capability.fzs.ezoneena",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x2, "", HFILL}},
+        { &hf_swils_ess_fzs_mr,
+          {"Merge Control Setting", "swils.ess.capability.fzs.mr", FT_BOOLEAN,
+           BASE_HEX, NULL, 0x4, "", HFILL}},
+        { &hf_swils_ess_fzs_defzone,
+          {"Default Zone Setting", "swils.ess.capability.fzs.defzone",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x8, "", HFILL}},
+        { &hf_swils_ess_fzs_zsdb_supp,
+          {"Zoneset Database Supported", "swils.ess.capability.fzs.zsdbsupp",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x10, "", HFILL}},
+        { &hf_swils_ess_fzs_zsdb_ena,
+          {"Zoneset Database Enabled", "swils.ess.capability.fzs.zsdbena",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x20, "", HFILL}},
+        { &hf_swils_ess_fzs_adc_supp,
+          {"Active Direct Command Supported",
+           "swils.ess.capability.fzs.adcsupp", FT_BOOLEAN, BASE_HEX, NULL, 
+           0x40, "", HFILL}},
+        { &hf_swils_ess_fzs_hardzone,
+          {"Hard Zoning Supported", "swils.ess.capability.fzs.hardzone",
+           FT_BOOLEAN, BASE_HEX, NULL, 0x80, "", HFILL}},
+        { &hf_swils_ess_cap_len,
+          {"Length", "swils.ess.capability.length", FT_UINT8, BASE_DEC, NULL,
+           0x0, "", HFILL}},
+        { &hf_swils_ess_cap_t10,
+          {"T10 Vendor ID", "swils.ess.capability.t10id", FT_STRING, BASE_HEX,
+           NULL, 0x0, "", HFILL}},
+        { &hf_swils_ess_cap_vendorobj,
+          {"Vendor-Specific Info", "swils.ess.capability.vendorobj", FT_BYTES,
+           BASE_HEX, NULL, 0x0, "", HFILL}},
+        { &hf_swils_mrra_rev,
+          {"Revision", "swils.mrra.revision", FT_UINT32, BASE_DEC, NULL,
+           0x0, "", HFILL}},
+        { &hf_swils_mrra_size,
+          {"Merge Request Size", "swils.mrra.size", FT_UINT32, BASE_DEC, NULL,
+           0x0, "", HFILL}},
+        { &hf_swils_mrra_vendorid,
+          {"Vendor ID", "swils.mrra.vendorid", FT_STRING, BASE_HEX,
+           NULL, 0x0, "", HFILL}},
+        { &hf_swils_mrra_vendorinfo,
+          {"Vendor-Specific Info", "swils.mrra.vendorinfo", FT_BYTES, BASE_HEX,
+           NULL, 0x0, "", HFILL}},
+        { &hf_swils_mrra_reply,
+          {"MRRA Response", "swils.mrra.reply", FT_UINT32, BASE_DEC, NULL, 0x0,
+           "", HFILL}},
+        { &hf_swils_mrra_reply_size,
+          {"Maximum Resources Available", "swils.mrra.replysize", FT_UINT32,
+           BASE_DEC, NULL, 0x0, "", HFILL}},
+        { &hf_swils_mrra_waittime,
+          {"Waiting Period (secs)", "swils.mrra.waittime", FT_UINT32, BASE_DEC,
+           NULL, 0x0, "", HFILL}},
     };
 
     /* Setup protocol subtree array */
@@ -1898,6 +2342,8 @@
         &ett_fcswils_ufc,
         &ett_fcswils_esc,
         &ett_fcswils_esc_pdesc,
+        &ett_fcswils_ieinfo,
+        &ett_fcswils_capinfo
     };
 
     /* Register the protocol name and description */

Index: packet-fcswils.h
===================================================================
--- packet-fcswils.h	(revision 15739)
+++ packet-fcswils.h	(working copy)
@@ -48,7 +48,11 @@
 #define FC_SWILS_SFC            0x25
 #define FC_SWILS_UFC            0x26
 #define FC_SWILS_ESC            0x30
+#define FC_SWILS_ESS            0x31
+#define FC_SWILS_MRRA           0x34
 #define FC_SWILS_AUTH_ILS       0x40
+#define FC_SWILS_MAXCODE        0x35 /* the dissector jump table is sized to
+                                        this table */
 
 /* Reject reason codes */
 

Index: packet-scsi.c
===================================================================
--- packet-scsi.c	(revision 15739)
+++ packet-scsi.c	(working copy)
@@ -296,7 +296,21 @@
 static int hf_scsi_disc_info_last_session_lead_in_start_address = -1;
 static int hf_scsi_disc_info_last_possible_lead_out_start_address = -1;
 static int hf_scsi_disc_info_disc_bar_code = -1;
+static int hf_sbc2_verify_lba = -1;
+static int hf_sbc2_verify_vlen = -1;
+static int hf_sbc2_verify_dpo = -1;
+static int hf_sbc2_verify_blkvfy = -1;
+static int hf_sbc2_verify_reladdr = -1;
+static int hf_sbc2_verify_vlen32 = -1;
+static int hf_sbc2_verify_lba64 = -1;
+static int hf_sbc2_wrverify_ebp = -1;
+static int hf_sbc2_wrverify_lba = -1;
+static int hf_sbc2_wrverify_xferlen = -1;
+static int hf_sbc2_wrverify_lba64 = -1;
+static int hf_sbc2_wrverify_xferlen32 = -1;
+static int hf_sbc2_verify_bytchk = -1;
 
+
 static gint ett_scsi         = -1;
 static gint ett_scsi_page    = -1;
 
@@ -3465,6 +3479,13 @@
 {
     guint8 flags;
 
+    if (isreq && iscdb) {
+        if (check_col (pinfo->cinfo, COL_INFO))
+            col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: %" PRIu64 ", Len: %u)",
+                             tvb_get_ntoh64 (tvb, offset+1),
+                             tvb_get_ntohl (tvb, offset+9));
+    }
+
     if (tree && isreq && iscdb) {
         flags = tvb_get_guint8 (tvb, offset);
 
@@ -3482,6 +3503,196 @@
     }
 }
 
+static void
+dissect_sbc2_verify10 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
+                       guint offset, gboolean isreq, gboolean iscdb,
+                       guint payload_len _U_, scsi_task_data_t *cdata _U_)
+
+{
+    guint8 flags;
+
+    if (isreq && iscdb) {
+        if (check_col (pinfo->cinfo, COL_INFO))
+            col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
+                             tvb_get_ntohl (tvb, offset+2),
+                             tvb_get_ntohs (tvb, offset+7));
+    }
+
+    if (tree && isreq && iscdb) {
+         proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_blkvfy, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
+                              0);
+         proto_tree_add_item (tree, hf_sbc2_verify_lba, tvb, offset+2, 4, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_vlen, tvb, offset+7, 2, 0);
+         flags = tvb_get_guint8 (tvb, offset+9);
+         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+9, 1,
+                                     flags,
+                                     "Vendor Unique = %u, NACA = %u, Link = %u",
+                                     flags & 0xC0, flags & 0x4, flags & 0x1);
+    }
+}
+
+static void
+dissect_sbc2_verify12 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
+                       guint offset, gboolean isreq, gboolean iscdb,
+                       guint payload_len _U_, scsi_task_data_t *cdata _U_)
+
+{
+    guint8 flags;
+     
+    if (isreq && iscdb) {
+        if (check_col (pinfo->cinfo, COL_INFO))
+            col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
+                             tvb_get_ntohl (tvb, offset+2),
+                             tvb_get_ntohl (tvb, offset+6));
+    }
+
+    if (tree && isreq && iscdb) {
+         proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_blkvfy, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
+                              0);
+         proto_tree_add_item (tree, hf_sbc2_verify_lba, tvb, offset+2, 4, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_vlen32, tvb, offset+6, 4, 0);
+         flags = tvb_get_guint8 (tvb, offset+11);
+         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+11, 1,
+                                     flags,
+                                     "Vendor Unique = %u, NACA = %u, Link = %u",
+                                     flags & 0xC0, flags & 0x4, flags & 0x1);
+    }
+}
+
+static void
+dissect_sbc2_verify16 (tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
+                       guint offset, gboolean isreq, gboolean iscdb,
+                       guint payload_len _U_, scsi_task_data_t *cdata _U_)
+
+{
+    guint8 flags;
+
+    if (isreq && iscdb) {
+        if (check_col (pinfo->cinfo, COL_INFO))
+            col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: %" PRIu64 ", Len: %u)",
+                             tvb_get_ntoh64 (tvb, offset+2),
+                             tvb_get_ntohl (tvb, offset+10));
+    }
+
+    if (tree && isreq && iscdb) {
+         proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_blkvfy, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
+                              0);
+         proto_tree_add_item (tree, hf_sbc2_verify_lba, tvb, offset+2, 8, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_vlen, tvb, offset+10, 4, 0);
+         flags = tvb_get_guint8 (tvb, offset+15);
+         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+15, 1,
+                                     flags,
+                                     "Vendor Unique = %u, NACA = %u, Link = %u",
+                                     flags & 0xC0, flags & 0x4, flags & 0x1);
+    }
+}
+
+static void
+dissect_sbc2_wrverify10 (tvbuff_t *tvb, packet_info *pinfo _U_,
+                         proto_tree *tree, guint offset, gboolean isreq,
+                         gboolean iscdb, guint payload_len _U_,
+                         scsi_task_data_t *cdata _U_)
+
+{
+    guint8 flags;
+     
+    if (isreq && iscdb) {
+        if (check_col (pinfo->cinfo, COL_INFO))
+            col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
+                             tvb_get_ntohl (tvb, offset+2),
+                             tvb_get_ntohs (tvb, offset+7));
+    }
+
+    if (tree && isreq && iscdb) {
+         proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_ebp, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
+                              0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_lba, tvb, offset+2, 4, 0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_xferlen, tvb, offset+7,
+                              2, 0);
+         flags = tvb_get_guint8 (tvb, offset+9);
+         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+9, 1,
+                                     flags,
+                                     "Vendor Unique = %u, NACA = %u, Link = %u",
+                                     flags & 0xC0, flags & 0x4, flags & 0x1);
+    }
+}
+
+static void
+dissect_sbc2_wrverify12 (tvbuff_t *tvb, packet_info *pinfo _U_,
+                         proto_tree *tree, guint offset, gboolean isreq,
+                         gboolean iscdb, guint payload_len _U_,
+                         scsi_task_data_t *cdata _U_)
+{
+    guint8 flags;
+     
+    if (isreq && iscdb) {
+        if (check_col (pinfo->cinfo, COL_INFO))
+            col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: 0x%08x, Len: %u)",
+                             tvb_get_ntohl (tvb, offset+2),
+                             tvb_get_ntohl (tvb, offset+6));
+    }
+
+    if (tree && isreq && iscdb) {
+         proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_ebp, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
+                              0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_lba, tvb, offset+2, 4, 0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_xferlen32, tvb, offset+6,
+                              4, 0);
+         flags = tvb_get_guint8 (tvb, offset+11);
+         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+11, 1,
+                                     flags,
+                                     "Vendor Unique = %u, NACA = %u, Link = %u",
+                                     flags & 0xC0, flags & 0x4, flags & 0x1);
+    }
+}
+
+static void
+dissect_sbc2_wrverify16 (tvbuff_t *tvb, packet_info *pinfo _U_,
+                         proto_tree *tree, guint offset, gboolean isreq,
+                         gboolean iscdb, guint payload_len _U_,
+                         scsi_task_data_t *cdata _U_)
+{
+    guint8 flags;
+     
+    if (isreq && iscdb) {
+        if (check_col (pinfo->cinfo, COL_INFO))
+            col_append_fstr (pinfo->cinfo, COL_INFO, "(LBA: %" PRIu64 ", Len: %u)",
+                             tvb_get_ntoh64 (tvb, offset+2),
+                             tvb_get_ntohl (tvb, offset+10));
+    }
+
+    if (tree && isreq && iscdb) {
+         proto_tree_add_item (tree, hf_sbc2_verify_dpo, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_ebp, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_bytchk, tvb, offset+1, 1, 0);
+         proto_tree_add_item (tree, hf_sbc2_verify_reladdr, tvb, offset+1, 1,
+                              0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_lba64, tvb, offset+2, 8, 0);
+         proto_tree_add_item (tree, hf_sbc2_wrverify_xferlen32, tvb, offset+10,
+                              4, 0);
+         flags = tvb_get_guint8 (tvb, offset+15);
+         proto_tree_add_uint_format (tree, hf_scsi_control, tvb, offset+15, 1,
+                                     flags,
+                                     "Vendor Unique = %u, NACA = %u, Link = %u",
+                                     flags & 0xC0, flags & 0x4, flags & 0x1);
+    }
+}
+
 static const value_string scsi_key_class_val[] = {
     {0x00, "DVD CSS/CPPM or CPRM"},
     {0x01, "ReWriteable Security Service - A"},
@@ -5623,8 +5834,8 @@
 /*SBC 0x2b*/{NULL},
 /*SBC 0x2c*/{NULL},
 /*SBC 0x2d*/{NULL},
-/*SBC 0x2e*/{NULL},
-/*SBC 0x2f*/{NULL},
+/*SBC 0x2e*/{dissect_sbc2_wrverify10},
+/*SBC 0x2f*/{dissect_sbc2_verify10},
 /*SBC 0x30*/{NULL},
 /*SBC 0x31*/{NULL},
 /*SBC 0x32*/{NULL},
@@ -5719,8 +5930,8 @@
 /*SBC 0x8b*/{NULL},
 /*SBC 0x8c*/{NULL},
 /*SBC 0x8d*/{NULL},
-/*SBC 0x8e*/{NULL},
-/*SBC 0x8f*/{NULL},
+/*SBC 0x8e*/{dissect_sbc2_wrverify16},
+/*SBC 0x8f*/{dissect_sbc2_verify16},
 /*SBC 0x90*/{NULL},
 /*SBC 0x91*/{NULL},
 /*SBC 0x92*/{NULL},
@@ -5751,8 +5962,8 @@
 /*SBC 0xab*/{NULL},
 /*SBC 0xac*/{NULL},
 /*SBC 0xad*/{NULL},
-/*SBC 0xae*/{NULL},
-/*SBC 0xaf*/{NULL},
+/*SBC 0xae*/{dissect_sbc2_wrverify12},
+/*SBC 0xaf*/{dissect_sbc2_verify12},
 /*SBC 0xb0*/{NULL},
 /*SBC 0xb1*/{NULL},
 /*SBC 0xb2*/{NULL},
@@ -7478,7 +7689,45 @@
         { &hf_scsi_disc_info_disc_bar_code,
           {"Disc Bar Code", "scsi.disc_info.disc_bar_code", FT_UINT64, BASE_HEX,
            NULL, 0, "", HFILL}},
-
+        { &hf_sbc2_verify_lba,
+          {"LBA", "scsi.sbc2.verify.lba", FT_UINT32, BASE_DEC, NULL, 0x0, "",
+           HFILL}},
+        { &hf_sbc2_verify_vlen,
+          {"Verification Length", "scsi.sbc2.verify.vlen", FT_UINT16,
+           BASE_DEC, NULL, 0x0, "", HFILL}},
+        { &hf_sbc2_verify_dpo,
+          {"DPO", "scsi.sbc2.verify.dpo", FT_BOOLEAN, BASE_HEX, NULL, 0x10, "",
+           HFILL}},
+        { &hf_sbc2_verify_blkvfy,
+          {"BLKVFY", "scsi.sbc2.verify.blkvfy", FT_BOOLEAN, BASE_HEX, NULL, 0x4,
+           "", HFILL}},
+        { &hf_sbc2_verify_bytchk,
+          {"BYTCHK", "scsi.sbc2.verify.bytchk", FT_BOOLEAN, BASE_HEX, NULL, 0x2,
+           "", HFILL}},
+        { &hf_sbc2_verify_reladdr,
+          {"RELADDR", "scsi.sbc2.verify.reladdr", FT_BOOLEAN, BASE_HEX, NULL,
+           0x1, "", HFILL}},
+        { &hf_sbc2_verify_vlen32,
+          {"Verification Length", "scsi.sbc2.verify.vlen32", FT_UINT32,
+           BASE_DEC, NULL, 0x0, "", HFILL}},
+        { &hf_sbc2_verify_lba64,
+          {"LBA", "scsi.sbc2.verify.lba64", FT_UINT64, BASE_DEC, NULL, 0x0, "",
+           HFILL}},
+        { &hf_sbc2_wrverify_ebp,
+          {"EBP", "scsi.sbc2.wrverify.ebp", FT_BOOLEAN, BASE_HEX, NULL, 0x4, "",
+           HFILL}},
+        { &hf_sbc2_wrverify_lba,
+          {"LBA", "scsi.sbc2.wrverify.lba", FT_UINT32, BASE_DEC, NULL, 0x0, "",
+           HFILL}},
+        { &hf_sbc2_wrverify_xferlen,
+          {"Transfer Length", "scsi.sbc2.wrverify.xferlen", FT_UINT16, BASE_DEC,
+           NULL, 0x0, "", HFILL}},
+        { &hf_sbc2_wrverify_lba64,
+          {"LBA", "scsi.sbc2.wrverify.lba64", FT_UINT64, BASE_DEC, NULL, 0x0,
+           "", HFILL}},
+        { &hf_sbc2_wrverify_xferlen32,
+          {"Transfer Length", "scsi.sbc2.wrverify.xferlen32", FT_UINT32,
+           BASE_DEC, NULL, 0x0, "", HFILL}},
     };
 
     /* Setup protocol subtree array */