When registering a string preference, if the value of the preference is
[obnox/wireshark/wip.git] / packet-dsi.c
index aebc2afb62a995b82118799198bd09ea984a7f97..6ff9ce8745962308508a544ce86b8a60ce11f896 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for dsi packet dissection
  * Copyright 2001, Randy McEoin <rmceoin@pe.com>
  *
- * $Id: packet-dsi.c,v 1.17 2002/05/01 07:07:09 guy Exp $
+ * $Id: packet-dsi.c,v 1.25 2002/10/17 22:38:19 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
  * 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.
 
 #include <stdio.h>
 
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-
 #include <glib.h>
 #include <epan/packet.h>
 
 #include "prefs.h"
-#include "packet-frame.h"
+#include "packet-tcp.h"
 
 #include "packet-afp.h"
 
@@ -78,12 +70,47 @@ static int hf_dsi_reserved = -1;
 
 static gint ett_dsi = -1;
 
+static int hf_dsi_open_type    = -1;
+static int hf_dsi_open_len     = -1;
+static int hf_dsi_open_quantum = -1;
+static int hf_dsi_open_option  = -1;
+
+static int hf_dsi_attn_flag            = -1;
+static int hf_dsi_attn_flag_shutdown   = -1;
+static int hf_dsi_attn_flag_crash      = -1;
+static int hf_dsi_attn_flag_msg                = -1;
+static int hf_dsi_attn_flag_reconnect  = -1;
+static int hf_dsi_attn_flag_time       = -1;
+static int hf_dsi_attn_flag_bitmap     = -1;
+
+static gint ett_dsi_open       = -1;
+static gint ett_dsi_attn       = -1;
+static gint ett_dsi_attn_flag  = -1;
+
+static const value_string dsi_attn_flag_vals[] = {
+  {0x0,        "Reserved" },                                           /* 0000 */
+  {0x1,        "Reserved" },                                           /* 0001 */
+  {0x2,        "Server message" },                                     /* 0010 */
+  {0x3,        "Server notification, cf. extended bitmap" },           /* 0011 */
+  {0x4,        "Server is shutting down, internal error" },            /* 0100 */
+  {0x8,        "Server is shutting down" },                            /* 1000 */
+  {0x9,        "Server disconnects user" },                            /* 1001 */
+  {0x10,"Server is shutting down, message" },                  /* 1010 */
+  {0x11,"Server is shutting down, message,no reconnect"},      /* 1011 */
+  {0,                  NULL } };
+
+static const value_string dsi_open_type_vals[] = {
+  {0,  "Server quantum" },
+  {1,  "Attention quantum" },
+  {0,                  NULL } };
+
 /* status stuff same for asp and afp */
 static int hf_dsi_server_name = -1;
 static int hf_dsi_server_type = -1;
 static int hf_dsi_server_vers = -1;
 static int hf_dsi_server_uams = -1;
 static int hf_dsi_server_icon = -1;
+static int hf_dsi_server_directory = -1;
 
 static int hf_dsi_server_flag = -1;
 static int hf_dsi_server_flag_copyfile = -1;
@@ -93,6 +120,9 @@ static int hf_dsi_server_flag_srv_msg        = -1;
 static int hf_dsi_server_flag_srv_sig  = -1;
 static int hf_dsi_server_flag_tcpip    = -1;
 static int hf_dsi_server_flag_notify   = -1;
+static int hf_dsi_server_flag_reconnect        = -1;
+static int hf_dsi_server_flag_directory        = -1;
+static int hf_dsi_server_flag_utf8_name = -1;
 static int hf_dsi_server_flag_fast_copy = -1;
 static int hf_dsi_server_signature     = -1;
 
@@ -104,6 +134,8 @@ static gint ett_dsi_status = -1;
 static gint ett_dsi_uams   = -1;
 static gint ett_dsi_vers   = -1;
 static gint ett_dsi_addr   = -1;
+static gint ett_dsi_addr_line = -1;
+static gint ett_dsi_directory = -1;
 static gint ett_dsi_status_server_flag = -1;
 
 const value_string afp_server_addr_type_vals[] = {
@@ -111,6 +143,7 @@ const value_string afp_server_addr_type_vals[] = {
   {2,  "IP+port address" },
   {3,  "DDP address" },
   {4,  "DNS name" },
+  {5,  "IP+port ssh tunnel" },
   {0,                  NULL } };
 
 /* end status stuff */
@@ -155,10 +188,65 @@ static const value_string func_vals[] = {
   {DSIFUNC_ATTN,       "Attention" },
   {0,                  NULL } };
 
-/* ----------------------------- 
+static gint
+dissect_dsi_open_session(tvbuff_t *tvb, proto_tree *dsi_tree, gint offset)
+{
+        proto_tree      *tree;
+       proto_item      *ti;
+       guint8          type;
+       guint8          len;
+
+       ti = proto_tree_add_text(dsi_tree, tvb, offset, -1, "Open Session");
+       tree = proto_item_add_subtree(ti, ett_dsi_open);
+       type = tvb_get_guint8(tvb, offset);
+       proto_tree_add_item(tree, hf_dsi_open_type, tvb, offset, 1, FALSE);
+       offset++;
+       len = tvb_get_guint8(tvb, offset);
+       proto_tree_add_item(tree, hf_dsi_open_len, tvb, offset, 1, FALSE);
+       offset++;
+       if (type <= 1) {
+               proto_tree_add_item(tree, hf_dsi_open_quantum, tvb, offset, 4, FALSE);
+       }
+       else {
+               proto_tree_add_item(tree, hf_dsi_open_option, tvb, offset, len, FALSE);
+       }
+       offset += len;
+       return offset;
+}
+
+static gint
+dissect_dsi_attention(tvbuff_t *tvb, proto_tree *dsi_tree, gint offset)
+{
+        proto_tree      *tree;
+       proto_item      *ti;
+       guint16         flag;
+
+       if (!tvb_reported_length_remaining(tvb,offset))
+               return offset;
+
+       flag = tvb_get_ntohs(tvb, offset);
+       ti = proto_tree_add_text(dsi_tree, tvb, offset, -1, "Attention");
+       tree = proto_item_add_subtree(ti, ett_dsi_attn);
+
+       ti = proto_tree_add_item(tree, hf_dsi_attn_flag, tvb, offset, 2, FALSE);
+       tree = proto_item_add_subtree(ti, ett_dsi_attn_flag);
+       proto_tree_add_item(tree, hf_dsi_attn_flag_shutdown, tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_dsi_attn_flag_crash, tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_dsi_attn_flag_msg, tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_dsi_attn_flag_reconnect, tvb, offset, 2, FALSE);
+       /* FIXME */
+       if ((flag & 0xf000) != 0x3000)
+               proto_tree_add_item(tree, hf_dsi_attn_flag_time, tvb, offset, 2, FALSE);
+       else
+               proto_tree_add_item(tree, hf_dsi_attn_flag_bitmap, tvb, offset, 2, FALSE);
+       offset += 2;
+       return offset;
+}
+
+/* -----------------------------
        from netatalk/etc/afpd/status.c
 */
-static gint 
+static gint
 dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
 {
         proto_tree      *sub_tree;
@@ -168,10 +256,14 @@ dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
        guint16 flag;
        guint16 sign_ofs = 0;
        guint16 adr_ofs = 0;
+       guint16 dir_ofs = 0;
        guint8  nbe;
        guint8  len;
        guint8  i;
-               
+
+       if (!tree)
+               return offset;
+
        ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
        tree = proto_item_add_subtree(ti, ett_dsi_status);
 
@@ -197,14 +289,16 @@ dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
        proto_tree_add_item(sub_tree, hf_dsi_server_flag_srv_sig       , tvb, ofs, 2, FALSE);
        proto_tree_add_item(sub_tree, hf_dsi_server_flag_tcpip         , tvb, ofs, 2, FALSE);
        proto_tree_add_item(sub_tree, hf_dsi_server_flag_notify        , tvb, ofs, 2, FALSE);
+       proto_tree_add_item(sub_tree, hf_dsi_server_flag_reconnect     , tvb, ofs, 2, FALSE);
+       proto_tree_add_item(sub_tree, hf_dsi_server_flag_directory     , tvb, ofs, 2, FALSE);
+       proto_tree_add_item(sub_tree, hf_dsi_server_flag_utf8_name     , tvb, ofs, 2, FALSE);
        proto_tree_add_item(sub_tree, hf_dsi_server_flag_fast_copy     , tvb, ofs, 2, FALSE);
 
        proto_tree_add_item(tree, hf_dsi_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, FALSE);
 
-       /* FIXME wild guess */
        flag = tvb_get_ntohs(tvb, ofs);
        if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
-               ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN);
+               ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
                if ((ofs & 1))
                        ofs++;
 
@@ -218,8 +312,15 @@ dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
                        proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %d", adr_ofs);
                        adr_ofs += offset;
                }
+
+               if ((flag & AFPSRVRINFO_SRVDIRECTORY)) {
+                       ofs += 2;
+                       dir_ofs =  tvb_get_ntohs(tvb, ofs);
+                       proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %d", dir_ofs);
+                       dir_ofs += offset;
+               }
        }
-               
+
        ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
        if (ofs)
                proto_tree_add_item(tree, hf_dsi_server_type, tvb, ofs, 1, FALSE);
@@ -236,7 +337,7 @@ dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
                        ofs += len;
                }
        }
-       
+
        ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
        if (ofs) {
                nbe = tvb_get_guint8(tvb, ofs);
@@ -259,21 +360,78 @@ dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
        }
 
        if (adr_ofs) {
+               proto_tree *adr_tree;
+               char *tmp;
+               const guint8 *ip;
+               guint16 net;
+               guint8  node;
+               guint16 port;
+
                ofs = adr_ofs;
                nbe = tvb_get_guint8(tvb, ofs);
                ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %d", nbe);
                ofs++;
-               sub_tree = proto_item_add_subtree(ti, ett_dsi_addr);
+               adr_tree = proto_item_add_subtree(ti, ett_dsi_addr);
                for (i = 0; i < nbe; i++) {
-                       len = tvb_get_guint8(tvb, ofs) -2;
+                       guint8 type;
+
+                       len = tvb_get_guint8(tvb, ofs);
+                       type =  tvb_get_guint8(tvb, ofs +1);
+                       switch (type) {
+                       case 1: /* IP */
+                               ip = tvb_get_ptr(tvb, ofs+2, 4);
+                               ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", ip_to_str(ip));
+                               break;
+                       case 2: /* IP + port */
+                               ip = tvb_get_ptr(tvb, ofs+2, 4);
+                               port = tvb_get_ntohs(tvb, ofs+6);
+                               ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%d",ip_to_str(ip),port);
+                               break;
+                       case 3: /* DDP, atalk_addr_to_str want host order not network */
+                               net  = tvb_get_ntohs(tvb, ofs+2);
+                               node = tvb_get_guint8(tvb, ofs +4);
+                               port = tvb_get_guint8(tvb, ofs +5);
+                               ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
+                                       net, node, port);
+                               break;
+                       case 4: /* DNS */
+                               if (len > 2) {
+                                       tmp = g_malloc( len -1);
+                                       tvb_memcpy(tvb, tmp, ofs +2, len -2);
+                                       tmp[len -2] = 0;
+                                       ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
+                                       g_free(tmp);
+                                       break;
+                               }
+                               /* else fall to default malformed record */
+                       default:
+                               ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknow type : %d", type);
+                               break;
+                       }
+                       len -= 2;
+                       sub_tree = proto_item_add_subtree(ti,ett_dsi_addr_line);
                        proto_tree_add_item(sub_tree, hf_dsi_server_addr_len, tvb, ofs, 1, FALSE);
                        ofs++;
-                       proto_tree_add_item(sub_tree, hf_dsi_server_addr_type, tvb, ofs, 1, FALSE); 
+                       proto_tree_add_item(sub_tree, hf_dsi_server_addr_type, tvb, ofs, 1, FALSE);
                        ofs++;
                        proto_tree_add_item(sub_tree, hf_dsi_server_addr_value,tvb, ofs, len, FALSE);
                        ofs += len;
                }
        }
+
+       if (dir_ofs) {
+               ofs = dir_ofs;
+               nbe = tvb_get_guint8(tvb, ofs);
+               ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %d", nbe);
+               ofs++;
+               sub_tree = proto_item_add_subtree(ti, ett_dsi_directory);
+               for (i = 0; i < nbe; i++) {
+                       len = tvb_get_guint8(tvb, ofs) +1;
+                       proto_tree_add_item(sub_tree, hf_dsi_server_directory, tvb, ofs, 1, FALSE);
+                       ofs += len;
+               }
+       }
+
        return offset;
 }
 
@@ -288,7 +446,7 @@ dissect_dsi_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        guint32         dsi_length;
        guint32         dsi_reserved;
        struct          aspinfo aspinfo;
+
        if (check_col(pinfo->cinfo, COL_PROTOCOL))
                col_set_str(pinfo->cinfo, COL_PROTOCOL, "DSI");
        if (check_col(pinfo->cinfo, COL_INFO))
@@ -339,14 +497,24 @@ dissect_dsi_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                proto_tree_add_uint(dsi_tree, hf_dsi_reserved, tvb,
                        12, 4, dsi_reserved);
        }
-       else 
+       else
                dsi_tree = tree;
        switch (dsi_command) {
+       case DSIFUNC_OPEN:
+               if (tree) {
+                       dissect_dsi_open_session(tvb, dsi_tree, DSI_BLOCKSIZ);
+               }
+               break;
+       case DSIFUNC_ATTN:
+               if (tree) {
+                       dissect_dsi_attention(tvb, dsi_tree, DSI_BLOCKSIZ);
+               }
+               break;
        case DSIFUNC_STAT:
                if (tree && (dsi_flags == DSIFL_REPLY)) {
                        dissect_dsi_reply_get_status(tvb, dsi_tree, DSI_BLOCKSIZ);
                }
-               break;  
+               break;
        case DSIFUNC_CMD:
        case DSIFUNC_WRITE:
                {
@@ -365,123 +533,37 @@ dissect_dsi_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                }
                break;
        default:
-               if (tree) {     
-                       call_dissector(data_handle,tvb_new_subset(tvb, DSI_BLOCKSIZ,-1,tvb_reported_length_remaining(tvb,DSI_BLOCKSIZ)), pinfo, dsi_tree); 
+               if (tree) {
+                       call_dissector(data_handle,
+                           tvb_new_subset(tvb, DSI_BLOCKSIZ, -1, -1),
+                           pinfo, dsi_tree);
                }
                break;
        }
 }
 
-static void
-dissect_dsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static guint
+get_dsi_pdu_len(tvbuff_t *tvb, int offset)
 {
-       volatile int offset = 0;
-       int length_remaining;
        guint32 plen;
-       int length;
-       tvbuff_t *next_tvb;
-
-       while (tvb_reported_length_remaining(tvb, offset) != 0) {
-               length_remaining = tvb_length_remaining(tvb, offset);
-
-               /*
-                * Can we do reassembly?
-                */
-               if (dsi_desegment && pinfo->can_desegment) {
-                       /*
-                        * Yes - is the DSI header split across segment
-                        * boundaries?
-                        */
-                       if (length_remaining < 12) {
-                               /*
-                                * Yes.  Tell the TCP dissector where
-                                * the data for this message starts in
-                                * the data it handed us, and how many
-                                * more bytes we need, and return.
-                                */
-                               pinfo->desegment_offset = offset;
-                               pinfo->desegment_len = 12 - length_remaining;
-                               return;
-                       }
-               }
 
-               /*
-                * Get the length of the DSI packet.
-                */
-               plen = tvb_get_ntohl(tvb, offset+8);
-
-               /*
-                * Can we do reassembly?
-                */
-               if (dsi_desegment && pinfo->can_desegment) {
-                       /*
-                        * Yes - is the DSI packet split across segment
-                        * boundaries?
-                        */
-                       if ((guint32)length_remaining < plen + 16) {
-                               /*
-                                * Yes.  Tell the TCP dissector where
-                                * the data for this message starts in
-                                * the data it handed us, and how many
-                                * more bytes we need, and return.
-                                */
-                               pinfo->desegment_offset = offset;
-                               pinfo->desegment_len =
-                                   (plen + 16) - length_remaining;
-                               return;
-                       }
-               }
+       /*
+        * Get the length of the DSI packet.
+        */
+       plen = tvb_get_ntohl(tvb, offset+8);
 
-               /*
-                * Construct a tvbuff containing the amount of the payload
-                * we have available.  Make its reported length the
-                * amount of data in the DSI packet.
-                *
-                * XXX - if reassembly isn't enabled. the subdissector
-                * will throw a BoundsError exception, rather than a
-                * ReportedBoundsError exception.  We really want
-                * a tvbuff where the length is "length", the reported
-                * length is "plen + 16", and the "if the snapshot length
-                * were infinite" length is the minimum of the
-                * reported length of the tvbuff handed to us and "plen+16",
-                * with a new type of exception thrown if the offset is
-                * within the reported length but beyond that third length,
-                * with that exception getting the "Unreassembled Packet"
-                * error.
-                */
-               length = length_remaining;
-               if ((guint32)length > plen + 16)
-                       length = plen + 16;
-               next_tvb = tvb_new_subset(tvb, offset, length, plen + 16);
-
-               /*
-                * Dissect the DSI packet.
-                *
-                * Catch the ReportedBoundsError exception; if this
-                * particular message happens to get a ReportedBoundsError
-                * exception, that doesn't mean that we should stop
-                * dissecting DSI messages within this frame or chunk
-                * of reassembled data.
-                *
-                * If it gets a BoundsError, we can stop, as there's nothing
-                * more to see, so we just re-throw it.
-                */
-               TRY {
-                       dissect_dsi_packet(next_tvb, pinfo, tree);
-               }
-               CATCH(BoundsError) {
-                       RETHROW;
-               }
-               CATCH(ReportedBoundsError) {
-                       show_reported_bounds_error(tvb, pinfo, tree);
-               }
-               ENDTRY;
+       /*
+        * That length doesn't include the length of the header itself;
+        * add that in.
+        */
+       return plen + 16;
+}
 
-               /*
-                * Skip the DSI header and the payload.
-                */
-               offset += plen + 16;
-       }
+static void
+dissect_dsi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+       tcp_dissect_pdus(tvb, pinfo, tree, dsi_desegment, 12,
+           get_dsi_pdu_len, dissect_dsi_packet);
 }
 
 void
@@ -523,7 +605,7 @@ proto_register_dsi(void)
       { "Reserved",         "dsi.reserved",
        FT_UINT32, BASE_HEX, NULL, 0x0,
        "Reserved for future use.  Should be set to zero.", HFILL }},
-
+       /* asp , afp */
     { &hf_dsi_server_name,
       { "Server name",         "dsi.server_name",
        FT_UINT_STRING, BASE_NONE, NULL, 0x0,
@@ -549,6 +631,11 @@ proto_register_dsi(void)
        FT_BYTES, BASE_HEX, NULL, 0x0,
        "Server icon bitmap", HFILL }},
 
+    { &hf_dsi_server_directory,
+      { "Directory service",         "dsi.server_directory",
+       FT_UINT_STRING, BASE_NONE, NULL, 0x0,
+       "Server directory service", HFILL }},
+
     { &hf_dsi_server_signature,
       { "Server signature",         "dsi.server_signature",
        FT_BYTES, BASE_HEX, NULL, 0x0,
@@ -586,6 +673,18 @@ proto_register_dsi(void)
       { "Support server notifications",      "dsi.server_flag.notify",
                FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVNOTIFY,
        "Server support notifications", HFILL }},
+    { &hf_dsi_server_flag_reconnect,
+      { "Support server reconnect",      "dsi.server_flag.reconnect",
+               FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVRECONNECT,
+       "Server support reconnect", HFILL }},
+    { &hf_dsi_server_flag_directory,
+      { "Support directory services",      "dsi.server_flag.directory",
+               FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVDIRECTORY,
+       "Server support directory services", HFILL }},
+    { &hf_dsi_server_flag_utf8_name,
+      { "Support UTF8 server name",      "dsi.server_flag.utf8_name",
+               FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVUTF8,
+       "Server support UTF8 server name", HFILL }},
     { &hf_dsi_server_flag_fast_copy,
       { "Support fast copy",      "dsi.server_flag.fast_copy",
                FT_BOOLEAN, 16, NULL, AFPSRVRINFO_FASTBOZO,
@@ -607,14 +706,70 @@ proto_register_dsi(void)
        FT_BYTES, BASE_HEX, NULL, 0x0,
        "Address value", HFILL }},
 
+    { &hf_dsi_open_type,
+      { "Flags",          "dsi.open_type",
+       FT_UINT8, BASE_DEC, VALS(dsi_open_type_vals), 0x0,
+       "Open session option type.", HFILL }},
+
+    { &hf_dsi_open_len,
+      { "Length",          "dsi.open_len",
+       FT_UINT8, BASE_DEC, NULL, 0x0,
+       "Open session option len", HFILL }},
+
+    { &hf_dsi_open_quantum,
+      { "Quantum",       "dsi.open_quantum",
+       FT_UINT32, BASE_DEC, NULL, 0x0,
+       "Server/Attention quantum", HFILL }},
+
+    { &hf_dsi_open_option,
+      { "Option",          "dsi.open_option",
+       FT_BYTES, BASE_HEX, NULL, 0x0,
+       "Open session options (undecoded)", HFILL }},
+
+    { &hf_dsi_attn_flag,
+      { "Flags",          "dsi.attn_flag",
+       FT_UINT16, BASE_HEX, VALS(dsi_attn_flag_vals), 0xf000,
+       "Server attention flag", HFILL }},
+    { &hf_dsi_attn_flag_shutdown,
+      { "Shutdown",      "dsi.attn_flag.shutdown",
+               FT_BOOLEAN, 16, NULL, 1<<15,
+       "Attention flag, server is shutting down", HFILL }},
+    { &hf_dsi_attn_flag_crash,
+      { "Crash",      "dsi.attn_flag.crash",
+               FT_BOOLEAN, 16, NULL, 1<<14,
+       "Attention flag, server crash bit", HFILL }},
+    { &hf_dsi_attn_flag_msg,
+      { "Message",      "dsi.attn_flag.msg",
+               FT_BOOLEAN, 16, NULL, 1<<13,
+       "Attention flag, server message bit", HFILL }},
+    { &hf_dsi_attn_flag_reconnect,
+      { "Don't reconnect",      "dsi.attn_flag.reconnect",
+               FT_BOOLEAN, 16, NULL, 1<<12,
+       "Attention flag, don't reconnect bit", HFILL }},
+    { &hf_dsi_attn_flag_time,
+     { "Minutes",          "dsi.attn_flag.time",
+       FT_UINT16, BASE_DEC, NULL, 0xfff,
+       "Number of minutes", HFILL }},
+    { &hf_dsi_attn_flag_bitmap,
+     { "Bitmap",          "dsi.attn_flag.time",
+       FT_UINT16, BASE_HEX, NULL, 0xfff,
+       "Attention extended bitmap", HFILL }},
+
   };
+
   static gint *ett[] = {
     &ett_dsi,
+    &ett_dsi_open,
+    &ett_dsi_attn,
+    &ett_dsi_attn_flag,
+    /* asp afp */
     &ett_dsi_status,
     &ett_dsi_status_server_flag,
     &ett_dsi_vers,
     &ett_dsi_uams,
     &ett_dsi_addr,
+    &ett_dsi_addr_line,
+    &ett_dsi_directory,
   };
   module_t *dsi_module;