checkAPIs.pl: support for new-style dissectors in check_hf_entries
[metze/wireshark/wip.git] / epan / dissectors / packet-afp.c
index d3b2716a125e9fc946851d4d5230ca29fb52bc50..9297e404ecec5568b03d7298a395d65246a899d7 100644 (file)
@@ -2,8 +2,6 @@
  * Routines for afp packet dissection
  * Copyright 2002, Didier Gautheron <dgautheron@magic.fr>
  *
- * $Id$
- *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  * Copied from README.developer
  * Copied from packet-dsi.c
  *
- * 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.
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
-#include <string.h>
 
-#include <glib.h>
 #include <epan/packet.h>
-/* #include <epan/strutil.h> */
+#include <epan/exceptions.h>
+#include <epan/to_str.h>
 #include <epan/conversation.h>
-#include <epan/emem.h>
 #include <epan/tap.h>
+#include <epan/srt_table.h>
 #include <epan/expert.h>
 
 #include "packet-afp.h"
@@ -58,7 +41,7 @@ http://developer.apple.com/DOCUMENTATION/macos8/pdf/ASAppleTalkFiling2.1_2.2.pdf
 
 http://developer.apple.com/documentation/Networking/Conceptual/AFP/index.html
 
-  Current AFP 3.x specfication, in HTML form, at
+  Current AFP 3.x specification, in HTML form, at
 http://developer.apple.com/mac/library/documentation/Networking/Reference/AFP_Reference/Reference/reference.html
 
   Current AFP 3.x programming guide, in HTML form, at
@@ -66,24 +49,32 @@ http://developer.apple.com/mac/library/documentation/Networking/Conceptual/AFP/I
 
   The netatalk source code by Wesley Craig & Adrian Sun
        http://netatalk.sf.net
+
+  XXX - distinguish between UTF-8 and Mac proprietary encodings for strings?
+  Does that need a preference in case we didn't see the client and server
+  negotiate that?
 */
+/* Forward declarations */
+void proto_register_afp(void);
+void proto_reg_handoff_afp(void);
+
 /* from netatalk/include/afp.h */
 #define AFPTRANS_NONE          0
-#define AFPTRANS_DDP          (1 << 0)
-#define AFPTRANS_TCP          (1 << 1)
+#define AFPTRANS_DDP          (1U << 0)
+#define AFPTRANS_TCP          (1U << 1)
 #define AFPTRANS_ALL          (AFPTRANS_DDP | AFPTRANS_TCP)
 
 /* AFP Attention Codes -- 4 bits */
-#define AFPATTN_SHUTDOWN     (1 << 15)            /* shutdown/disconnect */
-#define AFPATTN_CRASH        (1 << 14)            /* server crashed */
-#define AFPATTN_MESG         (1 << 13)            /* server has message */
-#define AFPATTN_NORECONNECT  (1 << 12)            /* don't reconnect */
+#define AFPATTN_SHUTDOWN     (1U << 15)           /* shutdown/disconnect */
+#define AFPATTN_CRASH        (1U << 14)           /* server crashed */
+#define AFPATTN_MESG         (1U << 13)           /* server has message */
+#define AFPATTN_NORECONNECT  (1U << 12)           /* don't reconnect */
 /* server notification */
 #define AFPATTN_NOTIFY       (AFPATTN_MESG | AFPATTN_NORECONNECT)
 
 /* extended bitmap -- 12 bits. volchanged is only useful w/ a server
  * notification, and time is only useful for shutdown. */
-#define AFPATTN_VOLCHANGED   (1 << 0)             /* volume has changed */
+#define AFPATTN_VOLCHANGED   (1U << 0)            /* volume has changed */
 #define AFPATTN_TIME(x)      ((x) & 0xfff)        /* time in minutes */
 
 /* AFP functions */
@@ -139,8 +130,8 @@ http://developer.apple.com/mac/library/documentation/Networking/Conceptual/AFP/I
 #define AFP_RMVCMT             57
 #define AFP_GETCMT             58
 
-#define AFP_ZZZ                       122
-#define AFP_ADDICON           192
+#define AFP_ZZZ                        122
+#define AFP_ADDICON            192
 
 /* AFP 3.0 new calls */
 #define AFP_BYTELOCK_EXT       59
@@ -153,34 +144,37 @@ http://developer.apple.com/mac/library/documentation/Networking/Conceptual/AFP/I
 #define AFP_CATSEARCH_EXT      67
 
 /* AFP 3.1 new calls */
-#define AFP_ENUMERATE_EXT2      68
+#define AFP_ENUMERATE_EXT2     68
 
 /* AFP 3.2 new calls */
-#define AFP_GETEXTATTR          69
-#define AFP_SETEXTATTR          70
-#define AFP_REMOVEATTR          71
-#define AFP_LISTEXTATTR         72
-#define AFP_GETACL              73
-#define AFP_SETACL              74
-#define AFP_ACCESS              75
+#define AFP_GETEXTATTR         69
+#define AFP_SETEXTATTR         70
+#define AFP_REMOVEATTR         71
+#define AFP_LISTEXTATTR                72
+#define AFP_GETACL             73
+#define AFP_SETACL             74
+#define AFP_ACCESS             75
 
 /* AFP 3.2 calls added in 10.5 */
-#define AFP_SPOTLIGHTRPC        76
-#define AFP_SYNCDIR             78
-#define AFP_SYNCFORK            79
+#define AFP_SPOTLIGHTRPC       76
+#define AFP_SYNCDIR            78
+#define AFP_SYNCFORK           79
 
 /* FPSpotlightRPC subcommand codes */
-#define SPOTLIGHT_CMD_GET_VOLPATH 1
+#define SPOTLIGHT_CMD_GET_VOLPATH 4
 #define SPOTLIGHT_CMD_GET_VOLID   2
 #define SPOTLIGHT_CMD_GET_THREE   3
 
+/* Spotlight epoch is UNIX epoch minus SPOTLIGHT_TIME_DELTA */
+#define SPOTLIGHT_TIME_DELTA G_GUINT64_CONSTANT(280878921600)
+
 /* ----------------------------- */
 static int proto_afp                       = -1;
 static int hf_afp_reserved                 = -1;
 static int hf_afp_unknown                  = -1;
 
 static int hf_afp_command                  = -1;               /* CommandCode */
-static int hf_afp_AFPVersion               = -1;
+static int hf_afp_Version                  = -1;
 static int hf_afp_UAM                      = -1;
 static int hf_afp_user                     = -1;
 static int hf_afp_passwd                   = -1;
@@ -197,6 +191,7 @@ static int hf_afp_user_type             = -1;
 static int hf_afp_user_len                 = -1;
 static int hf_afp_user_name                = -1;
 
+static int hf_afp_vol_flag                 = -1;
 static int hf_afp_vol_flag_passwd          = -1;
 static int hf_afp_vol_flag_has_config      = -1;
 static int hf_afp_server_time              = -1;
@@ -250,8 +245,6 @@ static int hf_afp_create_flag                   = -1;
 static int hf_afp_struct_size              = -1;
 static int hf_afp_struct_size16                    = -1;
 
-static int hf_afp_request_bitmap           = -1;
-
 static int hf_afp_cat_count                = -1;
 static int hf_afp_cat_req_matches          = -1;
 static int hf_afp_cat_position             = -1;
@@ -283,7 +276,6 @@ static int hf_afp_rw_count              = -1;
 static int hf_afp_newline_mask             = -1;
 static int hf_afp_newline_char             = -1;
 static int hf_afp_last_written             = -1;
-static int hf_afp_actual_count             = -1;
 
 static int hf_afp_fork_type                = -1;
 static int hf_afp_access_mode              = -1;
@@ -356,9 +348,17 @@ static int hf_afp_extattr_start_index          = -1;
 static int hf_afp_extattr_reply_size       = -1;
 static int ett_afp_extattr_names           = -1;
 
+static expert_field ei_afp_subquery_count_over_safety_limit = EI_INIT;
+static expert_field ei_afp_subquery_count_over_query_count = EI_INIT;
+static expert_field ei_afp_abnormal_num_subqueries = EI_INIT;
+static expert_field ei_afp_too_many_acl_entries = EI_INIT;
+static expert_field ei_afp_ip_port_reused = EI_INIT;
+static expert_field ei_afp_toc_offset = EI_INIT;
+
+
 static int afp_tap                         = -1;
 
-static dissector_handle_t data_handle;
+static dissector_handle_t spotlight_handle;
 
 static const value_string vol_signature_vals[] = {
        {1, "Flat"},
@@ -492,10 +492,10 @@ static const value_string unicode_hint_vals[] = {
        {  252, "MacVT100" },
        {  255, "MacHFS" },
        {  256, "UnicodeDefault" },
-/* {  257,  "UnicodeV1_1" },  */
+/* ??  {  257, "UnicodeV1_1" }, */
        {  257, "ISO10646_1993" },
        {  259, "UnicodeV2_0" },
-       {  259, "UnicodeV2_1" },
+/* ??  {  259, "UnicodeV2_1" }, */
        {  260, "UnicodeV3_0" },
        {  513, "ISOLatin1" },
        {  514, "ISOLatin2" },
@@ -532,7 +532,7 @@ static const value_string unicode_hint_vals[] = {
        { 1058, "DOSKorean" },
        { 1059, "DOSChineseTrad" },
        { 1280, "WindowsLatin1" },
-/* { 1280, "WindowsANSI" }, */
+/*     { 1280, "WindowsANSI" }, */
        { 1281, "WindowsLatin2" },
        { 1282, "WindowsCyrillic" },
        { 1283, "WindowsGreek" },
@@ -554,18 +554,18 @@ static value_string_ext unicode_hint_vals_ext = VALUE_STRING_EXT_INIT(unicode_hi
   from Apple AFP3.0.pdf
   Table 1-2 p. 20
 */
-#define kFPVolAttributeBit             (1 << 0)
-#define kFPVolSignatureBit             (1 << 1)
-#define kFPVolCreateDateBit            (1 << 2)
-#define kFPVolModDateBit               (1 << 3)
-#define kFPVolBackupDateBit            (1 << 4)
-#define kFPVolIDBit                    (1 << 5)
-#define kFPVolBytesFreeBit             (1 << 6)
-#define kFPVolBytesTotalBit            (1 << 7)
-#define kFPVolNameBit                  (1 << 8)
-#define kFPVolExtBytesFreeBit          (1 << 9)
-#define kFPVolExtBytesTotalBit         (1 << 10)
-#define kFPVolBlockSizeBit             (1 << 11)
+#define kFPVolAttributeBit             (1U << 0)
+#define kFPVolSignatureBit             (1U << 1)
+#define kFPVolCreateDateBit            (1U << 2)
+#define kFPVolModDateBit               (1U << 3)
+#define kFPVolBackupDateBit            (1U << 4)
+#define kFPVolIDBit                    (1U << 5)
+#define kFPVolBytesFreeBit             (1U << 6)
+#define kFPVolBytesTotalBit            (1U << 7)
+#define kFPVolNameBit                  (1U << 8)
+#define kFPVolExtBytesFreeBit          (1U << 9)
+#define kFPVolExtBytesTotalBit         (1U << 10)
+#define kFPVolBlockSizeBit             (1U << 11)
 
 static int hf_afp_vol_bitmap_Attributes        = -1;
 static int hf_afp_vol_bitmap_Signature                 = -1;
@@ -595,101 +595,112 @@ static int hf_afp_vol_attribute_SupportsACLs                = -1;
 static int hf_afp_vol_attribute_CaseSensitive              = -1;
 static int hf_afp_vol_attribute_SupportsTMLockSteal        = -1;
 
-static int hf_afp_dir_bitmap_Attributes     = -1;
-static int hf_afp_dir_bitmap_ParentDirID    = -1;
-static int hf_afp_dir_bitmap_CreateDate     = -1;
-static int hf_afp_dir_bitmap_ModDate        = -1;
-static int hf_afp_dir_bitmap_BackupDate     = -1;
-static int hf_afp_dir_bitmap_FinderInfo     = -1;
-static int hf_afp_dir_bitmap_LongName       = -1;
-static int hf_afp_dir_bitmap_ShortName      = -1;
-static int hf_afp_dir_bitmap_NodeID         = -1;
-static int hf_afp_dir_bitmap_OffspringCount = -1;
-static int hf_afp_dir_bitmap_OwnerID        = -1;
-static int hf_afp_dir_bitmap_GroupID        = -1;
-static int hf_afp_dir_bitmap_AccessRights   = -1;
-static int hf_afp_dir_bitmap_UTF8Name       = -1;
-static int hf_afp_dir_bitmap_UnixPrivs      = -1;
-
-static int hf_afp_dir_attribute_Invisible     = -1;
-static int hf_afp_dir_attribute_IsExpFolder   = -1;
-
-static int hf_afp_dir_attribute_System        = -1;
-static int hf_afp_dir_attribute_Mounted       = -1;
-static int hf_afp_dir_attribute_InExpFolder   = -1;
-
-static int hf_afp_dir_attribute_BackUpNeeded  = -1;
-static int hf_afp_dir_attribute_RenameInhibit = -1;
-static int hf_afp_dir_attribute_DeleteInhibit = -1;
-static int hf_afp_dir_attribute_SetClear      = -1;
-
-static int hf_afp_file_bitmap_Attributes       = -1;
-static int hf_afp_file_bitmap_ParentDirID      = -1;
-static int hf_afp_file_bitmap_CreateDate       = -1;
-static int hf_afp_file_bitmap_ModDate          = -1;
-static int hf_afp_file_bitmap_BackupDate       = -1;
-static int hf_afp_file_bitmap_FinderInfo       = -1;
-static int hf_afp_file_bitmap_LongName         = -1;
-static int hf_afp_file_bitmap_ShortName        = -1;
-static int hf_afp_file_bitmap_NodeID           = -1;
-static int hf_afp_file_bitmap_DataForkLen      = -1;
-static int hf_afp_file_bitmap_RsrcForkLen      = -1;
-static int hf_afp_file_bitmap_ExtDataForkLen   = -1;
-static int hf_afp_file_bitmap_LaunchLimit      = -1;
-
-static int hf_afp_file_bitmap_UTF8Name         = -1;
-static int hf_afp_file_bitmap_ExtRsrcForkLen   = -1;
-static int hf_afp_file_bitmap_UnixPrivs        = -1;
-
-static int hf_afp_file_attribute_Invisible     = -1;
-static int hf_afp_file_attribute_MultiUser     = -1;
-static int hf_afp_file_attribute_System        = -1;
-static int hf_afp_file_attribute_DAlreadyOpen  = -1;
-static int hf_afp_file_attribute_RAlreadyOpen  = -1;
-static int hf_afp_file_attribute_WriteInhibit  = -1;
-static int hf_afp_file_attribute_BackUpNeeded  = -1;
-static int hf_afp_file_attribute_RenameInhibit = -1;
-static int hf_afp_file_attribute_DeleteInhibit = -1;
-static int hf_afp_file_attribute_CopyProtect   = -1;
-static int hf_afp_file_attribute_SetClear      = -1;
-
-static int hf_afp_map_name_type     = -1;
-static int hf_afp_map_name         = -1;
-static int hf_afp_map_id           = -1;
-static int hf_afp_map_id_type      = -1;
-static int hf_afp_map_id_reply_type = -1;
-
-static int hf_afp_request_bitmap_Attributes     = -1;
-static int hf_afp_request_bitmap_ParentDirID    = -1;
-static int hf_afp_request_bitmap_CreateDate     = -1;
-static int hf_afp_request_bitmap_ModDate        = -1;
-static int hf_afp_request_bitmap_BackupDate     = -1;
-static int hf_afp_request_bitmap_FinderInfo     = -1;
-static int hf_afp_request_bitmap_LongName       = -1;
-static int hf_afp_request_bitmap_DataForkLen    = -1;
-static int hf_afp_request_bitmap_OffspringCount = -1;
-static int hf_afp_request_bitmap_RsrcForkLen    = -1;
-static int hf_afp_request_bitmap_ExtDataForkLen = -1;
-static int hf_afp_request_bitmap_UTF8Name       = -1;
-static int hf_afp_request_bitmap_ExtRsrcForkLen = -1;
-static int hf_afp_request_bitmap_PartialNames   = -1;
-
-static int ett_afp_spotlight_queries = -1;
-static int ett_afp_spotlight_query_line  = -1;
-static int ett_afp_spotlight_query = -1;
-static int ett_afp_spotlight_data = -1;
-static int ett_afp_spotlight_toc = -1;
-
-static int hf_afp_spotlight_request_flags = -1;
-static int hf_afp_spotlight_request_command = -1;
-static int hf_afp_spotlight_request_reserved = -1;
-static int hf_afp_spotlight_volpath_server = -1;
-static int hf_afp_spotlight_volpath_client = -1;
-static int hf_afp_spotlight_returncode = -1;
-static int hf_afp_spotlight_volflags = -1;
-static int hf_afp_spotlight_reqlen = -1;
-static int hf_afp_spotlight_toc_query_end = -1;
-static int hf_afp_spotlight_mdstring = -1;
+static int hf_afp_dir_bitmap_Attributes                             = -1;
+static int hf_afp_dir_bitmap_ParentDirID                    = -1;
+static int hf_afp_dir_bitmap_CreateDate                             = -1;
+static int hf_afp_dir_bitmap_ModDate                        = -1;
+static int hf_afp_dir_bitmap_BackupDate                             = -1;
+static int hf_afp_dir_bitmap_FinderInfo                             = -1;
+static int hf_afp_dir_bitmap_LongName                       = -1;
+static int hf_afp_dir_bitmap_ShortName                      = -1;
+static int hf_afp_dir_bitmap_NodeID                         = -1;
+static int hf_afp_dir_bitmap_OffspringCount                 = -1;
+static int hf_afp_dir_bitmap_OwnerID                        = -1;
+static int hf_afp_dir_bitmap_GroupID                        = -1;
+static int hf_afp_dir_bitmap_AccessRights                   = -1;
+static int hf_afp_dir_bitmap_UTF8Name                       = -1;
+static int hf_afp_dir_bitmap_UnixPrivs                      = -1;
+
+static int hf_afp_dir_attribute                                     = -1;
+static int hf_afp_dir_attribute_Invisible                   = -1;
+static int hf_afp_dir_attribute_IsExpFolder                 = -1;
+static int hf_afp_dir_attribute_System                      = -1;
+static int hf_afp_dir_attribute_Mounted                             = -1;
+static int hf_afp_dir_attribute_InExpFolder                 = -1;
+static int hf_afp_dir_attribute_BackUpNeeded                = -1;
+static int hf_afp_dir_attribute_RenameInhibit               = -1;
+static int hf_afp_dir_attribute_DeleteInhibit               = -1;
+
+static int hf_afp_file_bitmap_Attributes                    = -1;
+static int hf_afp_file_bitmap_ParentDirID                   = -1;
+static int hf_afp_file_bitmap_CreateDate                    = -1;
+static int hf_afp_file_bitmap_ModDate                       = -1;
+static int hf_afp_file_bitmap_BackupDate                    = -1;
+static int hf_afp_file_bitmap_FinderInfo                    = -1;
+static int hf_afp_file_bitmap_LongName                      = -1;
+static int hf_afp_file_bitmap_ShortName                             = -1;
+static int hf_afp_file_bitmap_NodeID                        = -1;
+static int hf_afp_file_bitmap_DataForkLen                   = -1;
+static int hf_afp_file_bitmap_RsrcForkLen                   = -1;
+static int hf_afp_file_bitmap_ExtDataForkLen                = -1;
+static int hf_afp_file_bitmap_LaunchLimit                   = -1;
+
+static int hf_afp_file_bitmap_UTF8Name                      = -1;
+static int hf_afp_file_bitmap_ExtRsrcForkLen                = -1;
+static int hf_afp_file_bitmap_UnixPrivs                             = -1;
+
+static int hf_afp_file_attribute                            = -1;
+static int hf_afp_file_attribute_Invisible                  = -1;
+static int hf_afp_file_attribute_MultiUser                  = -1;
+static int hf_afp_file_attribute_System                             = -1;
+static int hf_afp_file_attribute_DAlreadyOpen               = -1;
+static int hf_afp_file_attribute_RAlreadyOpen               = -1;
+static int hf_afp_file_attribute_WriteInhibit               = -1;
+static int hf_afp_file_attribute_BackUpNeeded               = -1;
+static int hf_afp_file_attribute_RenameInhibit              = -1;
+static int hf_afp_file_attribute_DeleteInhibit              = -1;
+static int hf_afp_file_attribute_CopyProtect                = -1;
+static int hf_afp_file_attribute_SetClear                   = -1;
+
+static int hf_afp_map_name_type                                     = -1;
+static int hf_afp_map_name                                  = -1;
+static int hf_afp_map_id                                    = -1;
+static int hf_afp_map_id_type                               = -1;
+static int hf_afp_map_id_reply_type                         = -1;
+
+static int hf_afp_request_bitmap_Attributes                 = -1;
+static int hf_afp_request_bitmap_ParentDirID                = -1;
+static int hf_afp_request_bitmap_CreateDate                 = -1;
+static int hf_afp_request_bitmap_ModDate                    = -1;
+static int hf_afp_request_bitmap_BackupDate                 = -1;
+static int hf_afp_request_bitmap_FinderInfo                 = -1;
+static int hf_afp_request_bitmap_LongName                   = -1;
+static int hf_afp_request_bitmap_DataForkLen                = -1;
+static int hf_afp_request_bitmap_OffspringCount                     = -1;
+static int hf_afp_request_bitmap_RsrcForkLen                = -1;
+static int hf_afp_request_bitmap_ExtDataForkLen                     = -1;
+static int hf_afp_request_bitmap_UTF8Name                   = -1;
+static int hf_afp_request_bitmap_ExtRsrcForkLen                     = -1;
+static int hf_afp_request_bitmap_PartialNames               = -1;
+
+/* Spotlight stuff */
+static int ett_afp_spotlight_queries                        = -1;
+static int ett_afp_spotlight_query_line                             = -1;
+static int ett_afp_spotlight_query                          = -1;
+static int ett_afp_spotlight_data                           = -1;
+static int ett_afp_spotlight_toc                            = -1;
+
+static int hf_afp_spotlight_request_flags                   = -1;
+static int hf_afp_spotlight_request_command                 = -1;
+static int hf_afp_spotlight_request_reserved                = -1;
+static int hf_afp_spotlight_reply_reserved                  = -1;
+static int hf_afp_spotlight_volpath_server                  = -1;
+static int hf_afp_spotlight_volpath_client                  = -1;
+static int hf_afp_spotlight_returncode                      = -1;
+static int hf_afp_spotlight_volflags                        = -1;
+static int hf_afp_spotlight_reqlen                          = -1;
+static int hf_afp_spotlight_uuid                            = -1;
+static int hf_afp_spotlight_date                            = -1;
+
+/* Status stuff from ASP or DSI */
+static int ett_afp_status                                   = -1;
+static int ett_afp_uams                                             = -1;
+static int ett_afp_vers                                             = -1;
+static int ett_afp_server_addr                              = -1;
+static int ett_afp_server_addr_line                         = -1;
+static int ett_afp_directory                                = -1;
+static int ett_afp_utf8_name                                = -1;
+static int ett_afp_status_server_flag                       = -1;
 
 static const value_string flag_vals[] = {
        {0,     "Start" },
@@ -732,70 +743,70 @@ static const value_string map_id_reply_type_vals[] = {
   volume attribute from Apple AFP3.0.pdf
   Table 1-3 p. 22
 */
-#define kReadOnly                              (1 << 0)
-#define kHasVolumePassword                     (1 << 1)
-#define kSupportsFileIDs                       (1 << 2)
-#define kSupportsCatSearch                     (1 << 3)
-#define kSupportsBlankAccessPrivs              (1 << 4)
-#define kSupportsUnixPrivs                     (1 << 5)
-#define kSupportsUTF8Names                     (1 << 6)
+#define kReadOnly                              (1U << 0)
+#define kHasVolumePassword                     (1U << 1)
+#define kSupportsFileIDs                       (1U << 2)
+#define kSupportsCatSearch                     (1U << 3)
+#define kSupportsBlankAccessPrivs              (1U << 4)
+#define kSupportsUnixPrivs                     (1U << 5)
+#define kSupportsUTF8Names                     (1U << 6)
 /* AFP3.1 */
-#define kNoNetworkUserIDs                      (1 << 7)
+#define kNoNetworkUserIDs                      (1U << 7)
 /* AFP3.2 */
-#define kDefaultPrivsFromParent                        (1 << 8)
-#define kNoExchangeFiles                       (1 << 9)
-#define kSupportsExtAttrs                      (1 << 10)
-#define kSupportsACLs                          (1 << 11)
+#define kDefaultPrivsFromParent                        (1U << 8)
+#define kNoExchangeFiles                       (1U << 9)
+#define kSupportsExtAttrs                      (1U << 10)
+#define kSupportsACLs                          (1U << 11)
 /* AFP3.2+ */
-#define kCaseSensitive                                 (1 << 12)
-#define kSupportsTMLockSteal                   (1 << 13)
+#define kCaseSensitive                                 (1U << 12)
+#define kSupportsTMLockSteal                   (1U << 13)
 
 /*
   directory bitmap from Apple AFP3.1.pdf
   Table 1-5 pp. 25-26
 */
-#define kFPAttributeBit                (1 << 0)
-#define kFPParentDirIDBit              (1 << 1)
-#define kFPCreateDateBit               (1 << 2)
-#define kFPModDateBit                  (1 << 3)
-#define kFPBackupDateBit               (1 << 4)
-#define kFPFinderInfoBit               (1 << 5)
-#define kFPLongNameBit                 (1 << 6)
-#define kFPShortNameBit                (1 << 7)
-#define kFPNodeIDBit                   (1 << 8)
-#define kFPOffspringCountBit           (1 << 9)
-#define kFPOwnerIDBit                  (1 << 10)
-#define kFPGroupIDBit                  (1 << 11)
-#define kFPAccessRightsBit             (1 << 12)
-#define kFPUTF8NameBit                         (1 << 13)
+#define kFPAttributeBit                (1U << 0)
+#define kFPParentDirIDBit              (1U << 1)
+#define kFPCreateDateBit               (1U << 2)
+#define kFPModDateBit                  (1U << 3)
+#define kFPBackupDateBit               (1U << 4)
+#define kFPFinderInfoBit               (1U << 5)
+#define kFPLongNameBit                 (1U << 6)
+#define kFPShortNameBit                (1U << 7)
+#define kFPNodeIDBit                   (1U << 8)
+#define kFPOffspringCountBit           (1U << 9)
+#define kFPOwnerIDBit                  (1U << 10)
+#define kFPGroupIDBit                  (1U << 11)
+#define kFPAccessRightsBit             (1U << 12)
+#define kFPUTF8NameBit                         (1U << 13)
 
 /* FIXME AFP3.0 bit 14, AFP3.1 bit 15 */
 
-#define kFPUnixPrivsBit                (1 << 15)
+#define kFPUnixPrivsBit                (1U << 15)
 
 /*
        directory Access Rights parameter AFP3.1.pdf
        table 1-7 p. 28
 */
 
-#define AR_O_SEARCH     (1 << 0)    /* owner has search access */
-#define AR_O_READ       (1 << 1)    /* owner has read access */
-#define AR_O_WRITE      (1 << 2)    /* owner has write access */
+#define AR_O_SEARCH     (1U << 0)   /* owner has search access */
+#define AR_O_READ       (1U << 1)   /* owner has read access */
+#define AR_O_WRITE      (1U << 2)   /* owner has write access */
 
-#define AR_G_SEARCH     (1 << 8)    /* group has search access */
-#define AR_G_READ       (1 << 9)    /* group has read access */
-#define AR_G_WRITE      (1 << 10)   /* group has write access */
+#define AR_G_SEARCH     (1U << 8)   /* group has search access */
+#define AR_G_READ       (1U << 9)   /* group has read access */
+#define AR_G_WRITE      (1U << 10)  /* group has write access */
 
-#define AR_E_SEARCH     (1 << 16)   /* everyone has search access */
-#define AR_E_READ       (1 << 17)   /* everyone has read access */
-#define AR_E_WRITE      (1 << 18)   /* everyone has write access */
+#define AR_E_SEARCH     (1U << 16)  /* everyone has search access */
+#define AR_E_READ       (1U << 17)  /* everyone has read access */
+#define AR_E_WRITE      (1U << 18)  /* everyone has write access */
 
-#define AR_U_SEARCH     (1 << 24)   /* user has search access */
-#define AR_U_READ       (1 << 25)   /* user has read access */
-#define AR_U_WRITE      (1 << 26)   /* user has write access */
+#define AR_U_SEARCH     (1U << 24)  /* user has search access */
+#define AR_U_READ       (1U << 25)  /* user has read access */
+#define AR_U_WRITE      (1U << 26)  /* user has write access */
 
-#define AR_BLANK        (1 << 28)   /* Blank Access Privileges (use parent dir privileges) */
-#define AR_U_OWN        (1UL << 31) /* user is the owner */
+#define AR_BLANK        (1U << 28)  /* Blank Access Privileges (use parent dir privileges) */
+#define AR_U_OWN        (1U << 31)  /* user is the owner */
 
 static int hf_afp_dir_ar           = -1;
 static int hf_afp_dir_ar_o_search  = -1;
@@ -861,33 +872,33 @@ kFPNodeIDBit                      (bit 8)
 kFPUTF8NameBit                         (bit 13)
 */
 
-#define kFPDataForkLenBit      (1 << 9)
-#define kFPRsrcForkLenBit      (1 << 10)
-#define kFPExtDataForkLenBit   (1 << 11)
-#define kFPLaunchLimitBit      (1 << 12)
+#define kFPDataForkLenBit      (1U << 9)
+#define kFPRsrcForkLenBit      (1U << 10)
+#define kFPExtDataForkLenBit   (1U << 11)
+#define kFPLaunchLimitBit      (1U << 12)
 
-#define kFPExtRsrcForkLenBit   (1 << 14)
+#define kFPExtRsrcForkLenBit   (1U << 14)
 
 /*
   file attribute AFP3.1.pdf
   Table 1-9 pp. 29-31
 */
-#define kFPInvisibleBit        (1 << 0)
-#define kFPMultiUserBit        (1 << 1)
-#define kFPSystemBit           (1 << 2)
-#define kFPDAlreadyOpenBit     (1 << 3)
-#define kFPRAlreadyOpenBit     (1 << 4)
-#define kFPWriteInhibitBit     (1 << 5)
-#define kFPBackUpNeededBit     (1 << 6)
-#define kFPRenameInhibitBit    (1 << 7)
-#define kFPDeleteInhibitBit    (1 << 8)
-#define kFPCopyProtectBit      (1 << 10)
-#define kFPSetClearBit                 (1 << 15)
+#define kFPInvisibleBit        (1U << 0)
+#define kFPMultiUserBit        (1U << 1)
+#define kFPSystemBit           (1U << 2)
+#define kFPDAlreadyOpenBit     (1U << 3)
+#define kFPRAlreadyOpenBit     (1U << 4)
+#define kFPWriteInhibitBit     (1U << 5)
+#define kFPBackUpNeededBit     (1U << 6)
+#define kFPRenameInhibitBit    (1U << 7)
+#define kFPDeleteInhibitBit    (1U << 8)
+#define kFPCopyProtectBit      (1U << 10)
+#define kFPSetClearBit                 (1U << 15)
 
 /* dir attribute */
-#define kIsExpFolder           (1 << 1)
-#define kMounted               (1 << 3)
-#define kInExpFolder           (1 << 4)
+#define kIsExpFolder           (1U << 1)
+#define kMounted               (1U << 3)
+#define kInExpFolder           (1U << 4)
 
 /* AFP 3.1 getsession token type */
 #define kLoginWithoutID         0
@@ -917,11 +928,11 @@ static const value_string token_type_vals[] = {
 static value_string_ext token_type_vals_ext = VALUE_STRING_EXT_INIT(token_type_vals);
 
 /* AFP 3.2 ACL bitmap */
-#define kFileSec_UUID          (1 << 0)
-#define kFileSec_GRPUUID       (1 << 1)
-#define kFileSec_ACL           (1 << 2)
-#define kFileSec_REMOVEACL     (1 << 3)
-#define kFileSec_Inherit       (1 << 4)
+#define kFileSec_UUID          (1U << 0)
+#define kFileSec_GRPUUID       (1U << 1)
+#define kFileSec_ACL           (1U << 2)
+#define kFileSec_REMOVEACL     (1U << 3)
+#define kFileSec_Inherit       (1U << 4)
 
 static int hf_afp_acl_list_bitmap              = -1;
 static int hf_afp_acl_list_bitmap_UUID         = -1;
@@ -936,9 +947,7 @@ static int hf_afp_access_bitmap                     = -1;
 static int hf_afp_acl_entrycount        = -1;
 static int hf_afp_acl_flags             = -1;
 
-static int hf_afp_ace_applicable        = -1;
 static int hf_afp_ace_flags             = -1;
-static int hf_afp_ace_rights            = -1;
 
 static int ett_afp_ace_flags            = -1;
 static int hf_afp_ace_flags_allow       = -1;
@@ -950,40 +959,40 @@ static int hf_afp_ace_flags_limitinherit = -1;
 static int hf_afp_ace_flags_onlyinherit  = -1;
 
 /* AFP 3.2 ACE flags */
-#define ACE_ALLOW        (1 << 0)
-#define ACE_DENY         (1 << 1)
-#define ACE_INHERITED    (1 << 4)
-#define ACE_FILE_INHERIT  (1 << 5)
-#define ACE_DIR_INHERIT          (1 << 6)
-#define ACE_LIMIT_INHERIT (1 << 7)
-#define ACE_ONLY_INHERIT  (1 << 8)
+#define ACE_ALLOW        (1U << 0)
+#define ACE_DENY         (1U << 1)
+#define ACE_INHERITED    (1U << 4)
+#define ACE_FILE_INHERIT  (1U << 5)
+#define ACE_DIR_INHERIT          (1U << 6)
+#define ACE_LIMIT_INHERIT (1U << 7)
+#define ACE_ONLY_INHERIT  (1U << 8)
 
 static int ett_afp_ace_entries          = -1;
 static int ett_afp_ace_entry            = -1;
 
 /* AFP 3.2 ACL access right cf page 248*/
-#define KAUTH_VNODE_READ_DATA          (1 << 1)
+#define KAUTH_VNODE_READ_DATA          (1U << 1)
 #define KAUTH_VNODE_LIST_DIRECTORY     KAUTH_VNODE_READ_DATA
-#define KAUTH_VNODE_WRITE_DATA         (1 << 2)
+#define KAUTH_VNODE_WRITE_DATA         (1U << 2)
 #define KAUTH_VNODE_ADD_FILE           KAUTH_VNODE_WRITE_DATA
-#define KAUTH_VNODE_EXECUTE            (1 << 3)
+#define KAUTH_VNODE_EXECUTE            (1U << 3)
 #define KAUTH_VNODE_SEARCH             KAUTH_VNODE_EXECUTE
-#define KAUTH_VNODE_DELETE             (1 << 4)
-#define KAUTH_VNODE_APPEND_DATA                (1 << 5)
+#define KAUTH_VNODE_DELETE             (1U << 4)
+#define KAUTH_VNODE_APPEND_DATA                (1U << 5)
 #define KAUTH_VNODE_ADD_SUBDIRECTORY   KAUTH_VNODE_APPEND_DATA
-#define KAUTH_VNODE_DELETE_CHILD       (1 << 6)
-#define KAUTH_VNODE_READ_ATTRIBUTES    (1 << 7)
-#define KAUTH_VNODE_WRITE_ATTRIBUTES   (1 << 8)
-#define KAUTH_VNODE_READ_EXTATTRIBUTES (1 << 9)
-#define KAUTH_VNODE_WRITE_EXTATTRIBUTES        (1 << 10)
-#define KAUTH_VNODE_READ_SECURITY      (1 << 11)
-#define KAUTH_VNODE_WRITE_SECURITY     (1 << 12)
-#define KAUTH_VNODE_CHANGE_OWNER       (1 << 13)
-#define KAUTH_VNODE_SYNCHRONIZE                (1 << 20)
-#define KAUTH_VNODE_GENERIC_ALL                (1 << 21)
-#define KAUTH_VNODE_GENERIC_EXECUTE    (1 << 22)
-#define KAUTH_VNODE_GENERIC_WRITE      (1 << 23)
-#define KAUTH_VNODE_GENERIC_READ       (1 << 24)
+#define KAUTH_VNODE_DELETE_CHILD       (1U << 6)
+#define KAUTH_VNODE_READ_ATTRIBUTES    (1U << 7)
+#define KAUTH_VNODE_WRITE_ATTRIBUTES   (1U << 8)
+#define KAUTH_VNODE_READ_EXTATTRIBUTES (1U << 9)
+#define KAUTH_VNODE_WRITE_EXTATTRIBUTES        (1U << 10)
+#define KAUTH_VNODE_READ_SECURITY      (1U << 11)
+#define KAUTH_VNODE_WRITE_SECURITY     (1U << 12)
+#define KAUTH_VNODE_CHANGE_OWNER       (1U << 13)
+#define KAUTH_VNODE_SYNCHRONIZE                (1U << 20)
+#define KAUTH_VNODE_GENERIC_ALL                (1U << 21)
+#define KAUTH_VNODE_GENERIC_EXECUTE    (1U << 22)
+#define KAUTH_VNODE_GENERIC_WRITE      (1U << 23)
+#define KAUTH_VNODE_GENERIC_READ       (1U << 24)
 
 
 static int hf_afp_acl_access_bitmap                = -1;
@@ -1007,9 +1016,115 @@ static int hf_afp_acl_access_bitmap_generic_execute = -1;
 static int hf_afp_acl_access_bitmap_generic_write   = -1;
 static int hf_afp_acl_access_bitmap_generic_read    = -1;
 
+/* Status stuff from ASP or DSI */
+static int hf_afp_server_name = -1;
+static int hf_afp_utf8_server_name_len = -1;
+static int hf_afp_utf8_server_name = -1;
+static int hf_afp_server_type = -1;
+static int hf_afp_server_vers = -1;
+static int hf_afp_server_uams = -1;
+static int hf_afp_server_icon = -1;
+static int hf_afp_server_directory = -1;
+
+static int hf_afp_server_flag = -1;
+static int hf_afp_server_flag_copyfile = -1;
+static int hf_afp_server_flag_passwd   = -1;
+static int hf_afp_server_flag_no_save_passwd = -1;
+static int hf_afp_server_flag_srv_msg   = -1;
+static int hf_afp_server_flag_srv_sig   = -1;
+static int hf_afp_server_flag_tcpip     = -1;
+static int hf_afp_server_flag_notify    = -1;
+static int hf_afp_server_flag_reconnect = -1;
+static int hf_afp_server_flag_directory = -1;
+static int hf_afp_server_flag_utf8_name = -1;
+static int hf_afp_server_flag_uuid      = -1;
+static int hf_afp_server_flag_ext_sleep = -1;
+static int hf_afp_server_flag_fast_copy = -1;
+static int hf_afp_server_signature      = -1;
+
+static int hf_afp_server_addr_len       = -1;
+static int hf_afp_server_addr_type      = -1;
+static int hf_afp_server_addr_value     = -1;
+
+/* Generated from convert_proto_tree_add_text.pl */
+static int hf_afp_int64 = -1;
+static int hf_afp_float = -1;
+static int hf_afp_unknown16 = -1;
+static int hf_afp_unknown32 = -1;
+static int hf_afp_cnid = -1;
+static int hf_afp_null = -1;
+static int hf_afp_string = -1;
+static int hf_afp_utf_16_string = -1;
+static int hf_afp_bool = -1;
+static int hf_afp_query_type = -1;
+static int hf_afp_toc_offset = -1;
+static int hf_afp_toc_entry = -1;
+static int hf_afp_endianness = -1;
+static int hf_afp_query_len = -1;
+static int hf_afp_num_toc_entries = -1;
+static int hf_afp_machine_offset = -1;
+static int hf_afp_version_offset = -1;
+static int hf_afp_uams_offset = -1;
+static int hf_afp_icon_offset = -1;
+static int hf_afp_signature_offset = -1;
+static int hf_afp_network_address_offset = -1;
+static int hf_afp_directory_services_offset = -1;
+static int hf_afp_utf8_server_name_offset = -1;
+
+static const value_string afp_server_addr_type_vals[] = {
+       {1,   "IP address" },
+       {2,   "IP+port address" },
+       {3,   "DDP address" },
+       {4,   "DNS name" },
+       {5,   "IP+port ssh tunnel" },
+       {6,   "IP6 address" },
+       {7,   "IP6+port address" },
+       {0,   NULL } };
+value_string_ext afp_server_addr_type_vals_ext = VALUE_STRING_EXT_INIT(afp_server_addr_type_vals);
+
+#define AFP_NUM_PROCEDURES     256
+
+static void
+afpstat_init(struct register_srt* srt _U_, GArray* srt_array)
+{
+       srt_stat_table *afp_srt_table;
+       guint32 i;
+
+       afp_srt_table = init_srt_table("AFP Commands", NULL, srt_array, AFP_NUM_PROCEDURES, NULL, "afp.command", NULL);
+       for (i = 0; i < AFP_NUM_PROCEDURES; i++)
+       {
+               gchar* tmp_str = val_to_str_ext_wmem(NULL, i, &CommandCode_vals_ext, "Unknown(%u)");
+               init_srt_table_row(afp_srt_table, i, tmp_str);
+               wmem_free(NULL, tmp_str);
+       }
+}
+
+static int
+afpstat_packet(void *pss, packet_info *pinfo, epan_dissect_t *edt _U_, const void *prv)
+{
+       guint i = 0;
+       srt_stat_table *afp_srt_table;
+       srt_data_t *data = (srt_data_t *)pss;
+       const afp_request_val *request_val = (const afp_request_val *)prv;
+
+       /* if we haven't seen the request, just ignore it */
+       if (!request_val) {
+               return 0;
+       }
+
+       afp_srt_table = g_array_index(data->srt_array, srt_stat_table*, i);
+
+       add_srt_table_data(afp_srt_table, request_val->command, &request_val->req_time, pinfo);
+
+       return 1;
+}
+
+
 
 #define hash_init_count 20
 
+/* Forward declarations */
+
 /* Hash functions */
 static gint  afp_equal (gconstpointer v, gconstpointer v2);
 static guint afp_hash  (gconstpointer v);
@@ -1019,23 +1134,35 @@ typedef struct {
        guint16 seq;
 } afp_request_key;
 
-static GHashTable *afp_request_hash = NULL;
+static wmem_map_t *afp_request_hash = NULL;
 
 static guint Vol;      /* volume */
 static guint Did;      /* parent directory ID */
 
-#define SPOTLIGHT_BIG_ENDIAN 0
-#define SPOTLIGHT_LITTLE_ENDIAN 1
-
-static gint spotlight_endianess;
+/*
+* Returns the UTF-16 byte order, as an ENC_xxx_ENDIAN value,
+* by checking the 2-byte byte order mark.
+* If there is no byte order mark, 0xFFFFFFFF is returned.
+*/
+static guint
+spotlight_get_utf16_string_byte_order(tvbuff_t *tvb, gint offset, gint query_length, guint encoding) {
+       guint byte_order;
+
+       /* check for byte order mark */
+       byte_order = 0xFFFFFFFF;
+       if (query_length >= 2) {
+               guint16 byte_order_mark;
+               byte_order_mark = tvb_get_guint16(tvb, offset, encoding);
+
+               if (byte_order_mark == 0xFFFE) {
+                       byte_order = ENC_BIG_ENDIAN;
+               }
+               else if (byte_order_mark == 0xFEFF) {
+                       byte_order = ENC_LITTLE_ENDIAN;
+               }
+       }
 
-static guint64
-spotlight_ntoh64(tvbuff_t *tvb, gint offset)
-{
-       if (spotlight_endianess == SPOTLIGHT_LITTLE_ENDIAN)
-               return tvb_get_letoh64(tvb, offset);
-       else
-               return tvb_get_ntoh64(tvb, offset);
+       return byte_order;
 }
 
 /* Hash Functions */
@@ -1059,33 +1186,31 @@ static guint afp_hash  (gconstpointer v)
 
 /* --------------------------
 */
-#define PAD(x)      { proto_tree_add_item(tree, hf_afp_pad, tvb, offset,  x, FALSE); offset += x; }
+#define PAD(x)      { proto_tree_add_item(tree, hf_afp_pad, tvb, offset,  x, ENC_NA); offset += x; }
 
 static guint16
 decode_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
        guint16  bitmap;
+       static const int * bitmaps[] = {
+               &hf_afp_vol_bitmap_Attributes,
+               &hf_afp_vol_bitmap_Signature,
+               &hf_afp_vol_bitmap_CreateDate,
+               &hf_afp_vol_bitmap_ModDate,
+               &hf_afp_vol_bitmap_BackupDate,
+               &hf_afp_vol_bitmap_ID,
+               &hf_afp_vol_bitmap_BytesFree,
+               &hf_afp_vol_bitmap_BytesTotal,
+               &hf_afp_vol_bitmap_Name,
+               &hf_afp_vol_bitmap_ExtBytesFree,
+               &hf_afp_vol_bitmap_ExtBytesTotal,
+               &hf_afp_vol_bitmap_BlockSize,
+               NULL
+       };
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_vol_bitmap,
+                                       ett_afp_vol_bitmap, bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               item = proto_tree_add_item(tree, hf_afp_vol_bitmap, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_vol_bitmap);
-
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Attributes,     tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Signature,      tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_CreateDate,     tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ModDate,        tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BackupDate,     tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ID,             tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BytesFree,      tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BytesTotal,     tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Name,           tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ExtBytesFree,   tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ExtBytesTotal,  tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BlockSize ,     tvb, offset, 2,FALSE);
-       }
 
        return bitmap;
 }
@@ -1094,30 +1219,28 @@ decode_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
 static guint16
 decode_vol_attribute (proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
        guint16  bitmap;
+       static const int * bitmaps[] = {
+               &hf_afp_vol_attribute_ReadOnly,
+               &hf_afp_vol_attribute_HasVolumePassword,
+               &hf_afp_vol_attribute_SupportsFileIDs,
+               &hf_afp_vol_attribute_SupportsCatSearch,
+               &hf_afp_vol_attribute_SupportsBlankAccessPrivs,
+               &hf_afp_vol_attribute_SupportsUnixPrivs,
+               &hf_afp_vol_attribute_SupportsUTF8Names,
+               &hf_afp_vol_attribute_NoNetworkUserID,
+               &hf_afp_vol_attribute_DefaultPrivsFromParent,
+               &hf_afp_vol_attribute_NoExchangeFiles,
+               &hf_afp_vol_attribute_SupportsExtAttrs,
+               &hf_afp_vol_attribute_SupportsACLs,
+               &hf_afp_vol_attribute_CaseSensitive,
+               &hf_afp_vol_attribute_SupportsTMLockSteal,
+               NULL
+       };
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_vol_attribute,
+                                       ett_afp_vol_attribute, bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               item = proto_tree_add_item(tree, hf_afp_vol_attribute, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_vol_attribute);
-
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_ReadOnly                ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_HasVolumePassword       ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsFileIDs         ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsCatSearch       ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsBlankAccessPrivs,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsUnixPrivs       ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsUTF8Names       ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_NoNetworkUserID         ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_DefaultPrivsFromParent  ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_NoExchangeFiles         ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsExtAttrs        ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsACLs            ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_CaseSensitive           ,tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsTMLockSteal     ,tvb, offset, 2,FALSE);
-       }
 
        return bitmap;
 }
@@ -1153,7 +1276,7 @@ parse_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
                offset += 2;
        }
        if ((bitmap & kFPVolSignatureBit)) {
-               proto_tree_add_item(tree, hf_afp_vol_signature,tvb, offset, 2, FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_signature,tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
        }
        if ((bitmap & kFPVolCreateDateBit)) {
@@ -1169,39 +1292,39 @@ parse_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
                offset += 4;
        }
        if ((bitmap & kFPVolIDBit)) {
-               proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
        }
        if ((bitmap & kFPVolBytesFreeBit)) {
-               proto_tree_add_item(tree, hf_afp_vol_bytes_free,tvb, offset, 4, FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_bytes_free,tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
        if ((bitmap & kFPVolBytesTotalBit)) {
-               proto_tree_add_item(tree, hf_afp_vol_bytes_total,tvb, offset, 4, FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_bytes_total,tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
        if ((bitmap & kFPVolNameBit)) {
                nameoff = tvb_get_ntohs(tvb, offset);
-               proto_tree_add_item(tree, hf_afp_vol_name_offset,tvb, offset, 2, FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_name_offset,tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
        }
        if ((bitmap & kFPVolExtBytesFreeBit)) {
-               proto_tree_add_item(tree, hf_afp_vol_ex_bytes_free,tvb, offset, 8, FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_ex_bytes_free,tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
        }
        if ((bitmap & kFPVolExtBytesTotalBit)) {
-               proto_tree_add_item(tree, hf_afp_vol_ex_bytes_total,tvb, offset, 8, FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_ex_bytes_total,tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
        }
        if ((bitmap & kFPVolBlockSizeBit)) {
-               proto_tree_add_item(tree, hf_afp_vol_block_size,tvb, offset, 4, FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_block_size,tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
        if (nameoff) {
                guint8 len;
 
                len = tvb_get_guint8(tvb, offset);
-               proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
                offset += len +1;
 
        }
@@ -1212,34 +1335,30 @@ parse_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
 static guint16
 decode_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
-       guint16     bitmap;
+       guint16  bitmap;
+       static const int * bitmaps[] = {
+               &hf_afp_file_bitmap_Attributes,
+               &hf_afp_file_bitmap_ParentDirID,
+               &hf_afp_file_bitmap_CreateDate,
+               &hf_afp_file_bitmap_ModDate,
+               &hf_afp_file_bitmap_BackupDate,
+               &hf_afp_file_bitmap_FinderInfo,
+               &hf_afp_file_bitmap_LongName,
+               &hf_afp_file_bitmap_ShortName,
+               &hf_afp_file_bitmap_NodeID,
+               &hf_afp_file_bitmap_DataForkLen,
+               &hf_afp_file_bitmap_RsrcForkLen,
+               &hf_afp_file_bitmap_ExtDataForkLen,
+               &hf_afp_file_bitmap_LaunchLimit,
+               &hf_afp_file_bitmap_UTF8Name,
+               &hf_afp_file_bitmap_ExtRsrcForkLen,
+               &hf_afp_file_bitmap_UnixPrivs,
+               NULL
+       };
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_file_bitmap,
+                                       ett_afp_file_bitmap, bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               item = proto_tree_add_item(tree, hf_afp_file_bitmap, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_file_bitmap);
-
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_Attributes     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ParentDirID    , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_CreateDate     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ModDate        , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_BackupDate     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_FinderInfo     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_LongName       , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ShortName      , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_NodeID         , tvb, offset, 2,FALSE);
-
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_DataForkLen    , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_RsrcForkLen    , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ExtDataForkLen , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_LaunchLimit    , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_UTF8Name       , tvb, offset, 2,FALSE);
-
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ExtRsrcForkLen , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_bitmap_UnixPrivs      , tvb, offset, 2,FALSE);
-       }
 
        return bitmap;
 }
@@ -1248,86 +1367,86 @@ decode_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
 static guint16
 decode_file_attribute(proto_tree *tree, tvbuff_t *tvb, gint offset, int shared)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
        guint16     attribute;
+       static const int * not_shared_attr[] = {
+               &hf_afp_file_attribute_Invisible,
+               &hf_afp_file_attribute_MultiUser,
+               &hf_afp_file_attribute_System,
+               &hf_afp_file_attribute_DAlreadyOpen,
+               &hf_afp_file_attribute_RAlreadyOpen,
+               /* writeinhibit is file only but Macs are setting it with FPSetFileDirParms too */
+               &hf_afp_file_attribute_WriteInhibit,
+               &hf_afp_file_attribute_BackUpNeeded,
+               &hf_afp_file_attribute_RenameInhibit,
+               &hf_afp_file_attribute_DeleteInhibit,
+               &hf_afp_file_attribute_CopyProtect,
+               &hf_afp_file_attribute_SetClear,
+               NULL
+       };
 
-       attribute = tvb_get_ntohs(tvb, offset);
-       if (!tree) {
-               return attribute;
-       }
-       item = proto_tree_add_text(tree, tvb, offset, 2,
-                               "File Attributes: 0x%04x", attribute);
-       sub_tree = proto_item_add_subtree(item, ett_afp_file_attribute);
-       proto_tree_add_item(sub_tree, hf_afp_file_attribute_Invisible    , tvb, offset, 2,FALSE);
-       if (!shared)
-               proto_tree_add_item(sub_tree, hf_afp_file_attribute_MultiUser    , tvb, offset, 2,FALSE);
-
-       proto_tree_add_item(sub_tree, hf_afp_file_attribute_System       , tvb, offset, 2,FALSE);
-
-       if (!shared) {
-               proto_tree_add_item(sub_tree, hf_afp_file_attribute_DAlreadyOpen , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_file_attribute_RAlreadyOpen , tvb, offset, 2,FALSE);
-       }
-       /* writeinhibit is file only but Macs are setting it with FPSetFileDirParms too */
-       proto_tree_add_item(sub_tree, hf_afp_file_attribute_WriteInhibit , tvb, offset, 2,FALSE);
-       proto_tree_add_item(sub_tree, hf_afp_file_attribute_BackUpNeeded , tvb, offset, 2,FALSE);
-       proto_tree_add_item(sub_tree, hf_afp_file_attribute_RenameInhibit, tvb, offset, 2,FALSE);
-       proto_tree_add_item(sub_tree, hf_afp_file_attribute_DeleteInhibit, tvb, offset, 2,FALSE);
+       static const int * shared_attr[] = {
+               &hf_afp_file_attribute_Invisible,
+               &hf_afp_file_attribute_System,
+               &hf_afp_file_attribute_WriteInhibit,
+               &hf_afp_file_attribute_BackUpNeeded,
+               &hf_afp_file_attribute_RenameInhibit,
+               &hf_afp_file_attribute_DeleteInhibit,
+               &hf_afp_file_attribute_SetClear,
+               NULL
+       };
 
        if (!shared)
-               proto_tree_add_item(sub_tree, hf_afp_file_attribute_CopyProtect  , tvb, offset, 2,FALSE);
-
-       proto_tree_add_item(sub_tree, hf_afp_file_attribute_SetClear     , tvb, offset, 2,FALSE);
+       {
+               proto_tree_add_bitmask(tree, tvb, offset, hf_afp_file_attribute,
+                                       ett_afp_file_attribute, not_shared_attr, ENC_BIG_ENDIAN);
+       }
+       else
+       {
+               proto_tree_add_bitmask(tree, tvb, offset, hf_afp_file_attribute,
+                                       ett_afp_file_attribute, shared_attr, ENC_BIG_ENDIAN);
+       }
 
+       attribute = tvb_get_ntohs(tvb, offset);
        return(attribute);
 }
 
 static void
 decode_access_rights (proto_tree *tree, tvbuff_t *tvb, int hf, gint offset)
 {
-       proto_tree *sub_tree;
-       proto_item *item;
-
-       if (tree) {
-               item = proto_tree_add_item(tree, hf, tvb, offset, 4, FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_dir_ar);
-
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_o_search, tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_o_read  , tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_o_write , tvb, offset, 4,   FALSE);
-
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_g_search, tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_g_read  , tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_g_write , tvb, offset, 4,   FALSE);
-
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_e_search, tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_e_read  , tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_e_write , tvb, offset, 4,   FALSE);
-
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_search, tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_read  , tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_write , tvb, offset, 4,   FALSE);
+       static const int * rights[] = {
+               &hf_afp_dir_ar_o_search,
+               &hf_afp_dir_ar_o_read,
+               &hf_afp_dir_ar_o_write,
+               &hf_afp_dir_ar_g_search,
+               &hf_afp_dir_ar_g_read,
+               &hf_afp_dir_ar_g_write,
+               &hf_afp_dir_ar_e_search,
+               &hf_afp_dir_ar_e_read,
+               &hf_afp_dir_ar_e_write,
+               &hf_afp_dir_ar_u_search,
+               &hf_afp_dir_ar_u_read,
+               &hf_afp_dir_ar_u_write,
+               &hf_afp_dir_ar_blank,
+               &hf_afp_dir_ar_u_own,
+               NULL
+       };
 
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_blank   , tvb, offset, 4,   FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_own   , tvb, offset, 4,   FALSE);
-       }
+       proto_tree_add_bitmask(tree, tvb, offset, hf,
+                                       ett_afp_dir_ar, rights, ENC_BIG_ENDIAN);
 }
 
 static void
 decode_unix_privs (proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
        proto_tree *sub_tree;
-       proto_item *item;
 
        if (tree) {
-               item = proto_tree_add_text(tree, tvb, offset, 16,
+               sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_afp_unix_privs, NULL,
                    "UNIX privileges");
-               sub_tree = proto_item_add_subtree(item, ett_afp_unix_privs);
 
-               proto_tree_add_item(sub_tree, hf_afp_unix_privs_uid, tvb, offset, 4, FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_unix_privs_gid, tvb, offset+4, 4, FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_unix_privs_permissions, tvb, offset+8, 4, FALSE);
+               proto_tree_add_item(sub_tree, hf_afp_unix_privs_uid, tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_unix_privs_gid, tvb, offset+4, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_unix_privs_permissions, tvb, offset+8, 4, ENC_BIG_ENDIAN);
                decode_access_rights(sub_tree, tvb, hf_afp_unix_privs_ua_permissions, offset+12);
        }
 }
@@ -1341,13 +1460,13 @@ parse_long_filename(proto_tree *tree, tvbuff_t *tvb, gint offset, gint org_offse
        guint8 len;
 
        lnameoff = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_long_name_offset,tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_afp_long_name_offset,tvb, offset, 2, ENC_BIG_ENDIAN);
        if (lnameoff) {
                tp_ofs = lnameoff +org_offset;
                len = tvb_get_guint8(tvb, tp_ofs);
-               proto_tree_add_item(tree, hf_afp_path_len, tvb, tp_ofs,  1,FALSE);
+               proto_tree_add_item(tree, hf_afp_path_len, tvb, tp_ofs,  1, ENC_BIG_ENDIAN);
                tp_ofs++;
-               proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, len,FALSE);
+               proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, len, ENC_UTF_8|ENC_NA);
                tp_ofs += len;
        }
        return tp_ofs;
@@ -1362,7 +1481,7 @@ parse_UTF8_filename(proto_tree *tree, tvbuff_t *tvb, gint offset, gint org_offse
        guint16 len;
 
        unameoff = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_unicode_name_offset,tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_afp_unicode_name_offset,tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        if (unameoff) {
              /* FIXME AFP3.x reuses PDINFO bit for UTF8.
@@ -1373,20 +1492,20 @@ parse_UTF8_filename(proto_tree *tree, tvbuff_t *tvb, gint offset, gint org_offse
               */
 
                tp_ofs = unameoff +org_offset;
-              if (tp_ofs > offset) {
-                  PAD(4);
+               if (tp_ofs > offset) {
+                       PAD(4);
                }
                else if (tp_ofs < offset) {
-                   tp_ofs = offset;
+                       tp_ofs = offset;
                }
-               proto_tree_add_item( tree, hf_afp_path_unicode_hint, tvb, tp_ofs, 4,FALSE);
+               proto_tree_add_item( tree, hf_afp_path_unicode_hint, tvb, tp_ofs, 4, ENC_BIG_ENDIAN);
                tp_ofs += 4;
 
                len = tvb_get_ntohs(tvb, tp_ofs);
-               proto_tree_add_item( tree, hf_afp_path_unicode_len, tvb, tp_ofs, 2,FALSE);
+               proto_tree_add_item( tree, hf_afp_path_unicode_len, tvb, tp_ofs, 2, ENC_BIG_ENDIAN);
                tp_ofs += 2;
 
-               proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, len,FALSE);
+               proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, len, ENC_UTF_8|ENC_NA);
                tp_ofs += len;
        }
        return tp_ofs;
@@ -1406,7 +1525,7 @@ parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap,
                offset += 2;
        }
        if ((bitmap & kFPParentDirIDBit)) {
-               proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
        if ((bitmap & kFPCreateDateBit)) {
@@ -1422,7 +1541,7 @@ parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap,
                offset += 4;
        }
        if ((bitmap & kFPFinderInfoBit)) {
-               proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
+               proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, ENC_NA);
                offset += 32;
        }
        if ((bitmap & kFPLongNameBit)) {
@@ -1436,26 +1555,26 @@ parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap,
        }
        if ((bitmap & kFPShortNameBit)) {
                /* snameoff = tvb_get_ntohs(tvb, offset); */
-               proto_tree_add_item(tree, hf_afp_short_name_offset,tvb, offset, 2, FALSE);
+               proto_tree_add_item(tree, hf_afp_short_name_offset,tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
        }
        if ((bitmap & kFPNodeIDBit)) {
-               proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
 
        if ((bitmap & kFPDataForkLenBit)) {
-               proto_tree_add_item(tree, hf_afp_file_DataForkLen, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_file_DataForkLen, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
 
        if ((bitmap & kFPRsrcForkLenBit)) {
-               proto_tree_add_item(tree, hf_afp_file_RsrcForkLen, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_file_RsrcForkLen, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
 
        if ((bitmap & kFPExtDataForkLenBit)) {
-               proto_tree_add_item(tree, hf_afp_file_ExtDataForkLen, tvb, offset, 8,FALSE);
+               proto_tree_add_item(tree, hf_afp_file_ExtDataForkLen, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
        }
 
@@ -1472,7 +1591,7 @@ parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap,
        }
 
        if ((bitmap & kFPExtRsrcForkLenBit)) {
-               proto_tree_add_item(tree, hf_afp_file_ExtRsrcForkLen, tvb, offset, 8,FALSE);
+               proto_tree_add_item(tree, hf_afp_file_ExtRsrcForkLen, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
        }
 
@@ -1495,31 +1614,29 @@ parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap,
 static guint16
 decode_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
-       guint16         bitmap;
+       guint16  bitmap;
+       static const int * bitmaps[] = {
+               &hf_afp_dir_bitmap_Attributes,
+               &hf_afp_dir_bitmap_ParentDirID,
+               &hf_afp_dir_bitmap_CreateDate,
+               &hf_afp_dir_bitmap_ModDate,
+               &hf_afp_dir_bitmap_BackupDate,
+               &hf_afp_dir_bitmap_FinderInfo,
+               &hf_afp_dir_bitmap_LongName,
+               &hf_afp_dir_bitmap_ShortName,
+               &hf_afp_dir_bitmap_NodeID,
+               &hf_afp_dir_bitmap_OffspringCount,
+               &hf_afp_dir_bitmap_OwnerID,
+               &hf_afp_dir_bitmap_GroupID,
+               &hf_afp_dir_bitmap_AccessRights,
+               &hf_afp_dir_bitmap_UTF8Name,
+               &hf_afp_dir_bitmap_UnixPrivs,
+               NULL
+       };
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_dir_bitmap,
+                                       ett_afp_dir_bitmap, bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               item = proto_tree_add_item(tree, hf_afp_dir_bitmap, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_dir_bitmap);
-
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_Attributes     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ParentDirID    , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_CreateDate     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ModDate        , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_BackupDate     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_FinderInfo     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_LongName       , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ShortName      , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_NodeID         , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_OffspringCount , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_OwnerID        , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_GroupID        , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_AccessRights   , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UTF8Name       , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UnixPrivs      , tvb, offset, 2,FALSE);
-       }
 
        return bitmap;
 }
@@ -1528,25 +1645,22 @@ decode_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
 static guint16
 decode_dir_attribute(proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
-       guint16         attribute;
+       guint16  attribute;
+       static const int * attributes[] = {
+               &hf_afp_dir_attribute_Invisible,
+               &hf_afp_dir_attribute_IsExpFolder,
+               &hf_afp_dir_attribute_System,
+               &hf_afp_dir_attribute_Mounted,
+               &hf_afp_dir_attribute_InExpFolder,
+               &hf_afp_dir_attribute_BackUpNeeded,
+               &hf_afp_dir_attribute_RenameInhibit,
+               &hf_afp_dir_attribute_DeleteInhibit,
+               NULL
+       };
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_dir_attribute,
+                                       ett_afp_dir_attribute, attributes, ENC_BIG_ENDIAN);
        attribute = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               item = proto_tree_add_text(tree, tvb, offset, 2,
-                                       "Directory Attributes: 0x%04x", attribute);
-               sub_tree = proto_item_add_subtree(item, ett_afp_dir_attribute);
-
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_Invisible    , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_IsExpFolder  , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_System       , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_Mounted      , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_InExpFolder  , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_BackUpNeeded , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_RenameInhibit, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_dir_attribute_DeleteInhibit, tvb, offset, 2,FALSE);
-       }
 
        return(attribute);
 }
@@ -1565,7 +1679,7 @@ parse_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
                offset += 2;
        }
        if ((bitmap & kFPParentDirIDBit)) {
-               proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
        if ((bitmap & kFPCreateDateBit)) {
@@ -1581,7 +1695,7 @@ parse_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
                offset += 4;
        }
        if ((bitmap & kFPFinderInfoBit)) {
-               proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
+               proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, ENC_NA);
                offset += 32;
        }
        if ((bitmap & kFPLongNameBit)) {
@@ -1594,23 +1708,23 @@ parse_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
        }
        if ((bitmap & kFPShortNameBit)) {
                /* snameoff = tvb_get_ntohs(tvb, offset); */
-               proto_tree_add_item(tree, hf_afp_short_name_offset,tvb, offset, 2, FALSE);
+               proto_tree_add_item(tree, hf_afp_short_name_offset,tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
        }
        if ((bitmap & kFPNodeIDBit)) {
-               proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
        if ((bitmap & kFPOffspringCountBit)) {
-               proto_tree_add_item(tree, hf_afp_dir_offspring, tvb, offset, 2,FALSE);
+               proto_tree_add_item(tree, hf_afp_dir_offspring, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;            /* error in AFP3.0.pdf */
        }
        if ((bitmap & kFPOwnerIDBit)) {
-               proto_tree_add_item(tree, hf_afp_dir_OwnerID, tvb, offset, 4,   FALSE);
+               proto_tree_add_item(tree, hf_afp_dir_OwnerID, tvb, offset, 4,   ENC_BIG_ENDIAN);
                offset += 4;
        }
        if ((bitmap & kFPGroupIDBit)) {
-               proto_tree_add_item(tree, hf_afp_dir_GroupID, tvb, offset, 4,   FALSE);
+               proto_tree_add_item(tree, hf_afp_dir_GroupID, tvb, offset, 4,   ENC_BIG_ENDIAN);
                offset += 4;
        }
        if ((bitmap & kFPAccessRightsBit)) {
@@ -1668,7 +1782,8 @@ name_in_bitmap(tvbuff_t *tvb, gint offset, guint16 bitmap, int isdir)
                        tp_ofs = nameoff +org_offset;
                        len = tvb_get_guint8(tvb, tp_ofs);
                        tp_ofs++;
-                       name = tvb_get_ephemeral_string(tvb, tp_ofs, len);
+                       /* XXX - code page,, e.g. Mac{Roman,Japanese,etc.} */
+                       name = tvb_get_string_enc(wmem_packet_scope(), tvb, tp_ofs, len, ENC_ASCII|ENC_NA);
                        return name;
                }
                offset += 2;
@@ -1706,7 +1821,7 @@ name_in_bitmap(tvbuff_t *tvb, gint offset, guint16 bitmap, int isdir)
                        tp_ofs = nameoff +org_offset +4;
                        len16 = tvb_get_ntohs(tvb, tp_ofs);
                        tp_ofs += 2;
-                       name = tvb_get_ephemeral_string(tvb, tp_ofs, len16);
+                       name = tvb_get_string_enc(wmem_packet_scope(), tvb, tp_ofs, len16, ENC_UTF_8|ENC_NA);
                        return name;
                }
        }
@@ -1750,7 +1865,7 @@ static gint
 decode_vol(proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
        Vol = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        return offset + 2;
 }
 
@@ -1759,11 +1874,11 @@ static gint
 decode_vol_did(proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
        Vol = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        Did = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        return offset;
 }
@@ -1817,7 +1932,6 @@ decode_name_label (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint off
        const gchar *name;
        guint8 type;
        proto_tree *sub_tree = NULL;
-       proto_item *item;
 
        type = tvb_get_guint8(tvb, offset);
        if (type == 3) {
@@ -1838,19 +1952,19 @@ decode_name_label (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint off
        }
 
        if (tree) {
-               item = proto_tree_add_text(tree, tvb, offset, len +header, label, name);
-               sub_tree = proto_item_add_subtree(item, ett_afp_path_name);
+               sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, len +header,
+                               ett_afp_path_name, NULL, label, name);
 
-               proto_tree_add_item(  sub_tree, hf_afp_path_type, tvb, offset,   1,FALSE);
+               proto_tree_add_item( sub_tree, hf_afp_path_type, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset++;
                if (type == 3) {
-                       proto_tree_add_item( sub_tree, hf_afp_path_unicode_hint,  tvb, offset,  4,FALSE);
+                       proto_tree_add_item( sub_tree, hf_afp_path_unicode_hint, tvb, offset, 4, ENC_BIG_ENDIAN);
                        offset += 4;
-                       proto_tree_add_item( sub_tree, hf_afp_path_unicode_len,  tvb, offset,   2,FALSE);
+                       proto_tree_add_item( sub_tree, hf_afp_path_unicode_len, tvb, offset, 2, ENC_BIG_ENDIAN);
                        offset += 2;
                }
                else {
-                       proto_tree_add_item( sub_tree, hf_afp_path_len,  tvb, offset,   1,FALSE);
+                       proto_tree_add_item( sub_tree, hf_afp_path_len,  tvb, offset, 1, ENC_BIG_ENDIAN);
                        offset++;
                }
 
@@ -1911,13 +2025,13 @@ dissect_query_afp_open_vol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        if (!tree)
                return offset;
 
-       proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len +1;
 
        len = tvb_reported_length_remaining(tvb,offset);
        if (len >= 8) {
-               /* optionnal password */
-               proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, 8,FALSE);
+               /* optional password */
+               proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, 8, ENC_UTF_8|ENC_NA);
                offset += 8;
        }
        return offset;
@@ -1944,12 +2058,15 @@ dissect_reply_afp_get_server_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
 {
        guint8 num;
        guint8 len;
-       guint8 flag;
        guint8 i;
-       proto_tree *sub_tree = NULL;
-       proto_tree *flag_tree;
+       proto_tree *sub_tree;
        proto_item *item;
-       proto_item *ti;
+
+       static const int * flags[] = {
+               &hf_afp_vol_flag_passwd,
+               &hf_afp_vol_flag_has_config,
+               NULL
+       };
 
        if (!tree)
                return offset;
@@ -1958,30 +2075,26 @@ dissect_reply_afp_get_server_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_
        offset += 4;
 
        num = tvb_get_guint8(tvb, offset);
-       item = proto_tree_add_text(tree, tvb, offset, 1, "Volumes : %d", num);
-       sub_tree = proto_item_add_subtree(item, ett_afp_server_vol);
+       sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1,
+                                               ett_afp_server_vol, NULL, "Volumes : %d", num);
        offset++;
 
        for (i = 0; i < num; i++) {
                const gchar *rep;
 
-               item = proto_tree_add_text(sub_tree, tvb, offset, -1,"Volume");
-               tree = proto_item_add_subtree(item, ett_afp_vol_list);
+               tree = proto_tree_add_subtree(sub_tree, tvb, offset, -1,
+                               ett_afp_vol_list, NULL, "Volume");
 
-               flag = tvb_get_guint8(tvb, offset);
-
-               ti = proto_tree_add_text(tree, tvb, offset , 1,"Flags : 0x%02x", flag);
-               flag_tree = proto_item_add_subtree(ti, ett_afp_vol_flag);
-               proto_tree_add_item(flag_tree, hf_afp_vol_flag_passwd, tvb, offset, 1,FALSE);
-               proto_tree_add_item(flag_tree, hf_afp_vol_flag_has_config, tvb, offset, 1,FALSE);
+               item = proto_tree_add_bitmask(tree, tvb, offset, hf_afp_vol_flag,
+                                       ett_afp_vol_flag, flags, ENC_BIG_ENDIAN);
                offset++;
 
-               len  = tvb_get_guint8(tvb, offset) +1;
+               len = tvb_get_guint8(tvb, offset) +1;
                rep = get_name(tvb, offset, 2);
                proto_item_set_text(item, "%s", rep);
                proto_item_set_len(item, len +1);
 
-               proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
 
                offset += len;
        }
@@ -2004,7 +2117,7 @@ dissect_query_afp_with_vol_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
                return offset;
        PAD(1);
 
-       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        return offset;
 }
@@ -2013,25 +2126,23 @@ dissect_query_afp_with_vol_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
 static gint
 dissect_query_afp_open_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
+       static const int * access[] = {
+               &hf_afp_access_read,
+               &hf_afp_access_write,
+               &hf_afp_access_deny_read,
+               &hf_afp_access_deny_write,
+               NULL
+       };
 
-       proto_tree_add_item(tree, hf_afp_fork_type, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_fork_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
        offset = decode_vol_did(tree, tvb, offset);
 
        decode_file_bitmap(tree, tvb, offset);
        offset += 2;
-       if (tree) {
-               item = proto_tree_add_item(tree, hf_afp_access_mode, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_access_mode);
-
-               proto_tree_add_item(sub_tree, hf_afp_access_read      , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_access_write     , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_access_deny_read , tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_access_deny_write, tvb, offset, 2,FALSE);
-       }
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_access_mode,
+                                       ett_afp_access_mode, access, ENC_BIG_ENDIAN);
        offset += 2;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -2049,7 +2160,7 @@ dissect_reply_afp_open_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        offset = parse_file_bitmap(tree, tvb, offset, f_bitmap,0);
@@ -2065,13 +2176,13 @@ dissect_query_afp_enumerate_ext2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        PAD(1);
        offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_start_index32, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_start_index32, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_max_reply_size32, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_max_reply_size32, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -2087,13 +2198,13 @@ dissect_query_afp_enumerate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        PAD(1);
        offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_start_index, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_start_index, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_max_reply_size, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_max_reply_size, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -2107,7 +2218,6 @@ loop_record(tvbuff_t *tvb, proto_tree *ptree, gint offset,
                int count, guint16 d_bitmap, guint16 f_bitmap, int add, int ext)
 {
        proto_tree *tree = NULL;
-       proto_item *item;
        guint8  *name;
        guint8  flags;
        guint   size;
@@ -2139,23 +2249,24 @@ loop_record(tvbuff_t *tvb, proto_tree *ptree, gint offset,
                                name = name_in_fbitmap(tvb, offset +decal, f_bitmap);
                        }
                        if (name) {
-                               item = proto_tree_add_text(ptree, tvb, offset, size, "%s", name);
+                               tree = proto_tree_add_subtree(ptree, tvb, offset, size,
+                                                                               ett_afp_enumerate_line, NULL, name);
                        }
                        else {
-                               item = proto_tree_add_text(ptree, tvb, offset, size, "line %d", i+1);
+                               tree = proto_tree_add_subtree_format(ptree, tvb, offset, size,
+                                                                       ett_afp_enumerate_line, NULL, "line %d", i+1);
                        }
-                       tree = proto_item_add_subtree(item, ett_afp_enumerate_line);
                }
                if (ext) {
-                       proto_tree_add_item(tree, hf_afp_struct_size16, tvb, offset, 2,FALSE);
+                       proto_tree_add_item(tree, hf_afp_struct_size16, tvb, offset, 2, ENC_BIG_ENDIAN);
                        offset += 2;
                }
                else {
-                       proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1,FALSE);
+                       proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1, ENC_BIG_ENDIAN);
                        offset++;
                }
 
-               proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
+               proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset++;
                if (ext) {
                        PAD(1);
@@ -2190,7 +2301,7 @@ reply_enumerate(tvbuff_t *tvb, proto_tree *tree, gint offset, int ext)
 
        count = tvb_get_ntohs(tvb, offset);
        if (tree) {
-               item = proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
+               item = proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2, ENC_BIG_ENDIAN);
                sub_tree = proto_item_add_subtree(item, ett_afp_enumerate);
        }
        offset += 2;
@@ -2216,8 +2327,7 @@ dissect_reply_afp_enumerate_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
 static gint
 catsearch_spec(tvbuff_t *tvb, proto_tree *ptree, gint offset, int ext, guint32 bitmap, const gchar *label)
 {
-       proto_tree *tree = NULL;
-       proto_item *item;
+       proto_tree *tree;
        guint16 size;
        gint    org;
 
@@ -2230,20 +2340,19 @@ catsearch_spec(tvbuff_t *tvb, proto_tree *ptree, gint offset, int ext, guint32  b
                size = tvb_get_guint8(tvb, offset) +2;
        }
 
-       item = proto_tree_add_text(ptree, tvb, offset, size, "%s", label);
-       tree = proto_item_add_subtree(item, ett_afp_cat_spec);
+       tree = proto_tree_add_subtree(ptree, tvb, offset, size, ett_afp_cat_spec, NULL, label);
 
        if (ext) {
-               proto_tree_add_item(tree, hf_afp_struct_size16, tvb, offset, 2,FALSE);
+               proto_tree_add_item(tree, hf_afp_struct_size16, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
        }
        else {
-               proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1,FALSE);
+               proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset++;
                PAD(1);
        }
 
-       offset = parse_file_bitmap(tree, tvb, offset, (guint16) bitmap,0);
+       parse_file_bitmap(tree, tvb, offset, (guint16) bitmap,0);
        offset = org +size;
 
        return offset;
@@ -2263,16 +2372,16 @@ query_catsearch(tvbuff_t *tvb, proto_tree *ptree, gint offset, int ext)
                return offset;
        PAD(1);
 
-       proto_tree_add_item(ptree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(ptree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(ptree, hf_afp_cat_req_matches, tvb, offset, 4,FALSE);
+       proto_tree_add_item(ptree, hf_afp_cat_req_matches, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       proto_tree_add_item(ptree, hf_afp_reserved, tvb, offset, 4,FALSE);
+       proto_tree_add_item(ptree, hf_afp_reserved, tvb, offset, 4, ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(ptree, hf_afp_cat_position, tvb, offset, 16,FALSE);
+       proto_tree_add_item(ptree, hf_afp_cat_position, tvb, offset, 16, ENC_NA);
        offset += 16;
 
        f_bitmap = decode_file_bitmap(ptree, tvb, offset);
@@ -2283,35 +2392,35 @@ query_catsearch(tvbuff_t *tvb, proto_tree *ptree, gint offset, int ext)
 
        r_bitmap = tvb_get_ntohl(tvb, offset);
        /* Already checked this above: if (ptree) */ {
-               item = proto_tree_add_item(ptree, hf_afp_file_bitmap, tvb, offset, 4,FALSE);
+               item = proto_tree_add_item(ptree, hf_afp_file_bitmap, tvb, offset, 4, ENC_BIG_ENDIAN);
                sub_tree = proto_item_add_subtree(item, ett_afp_cat_r_bitmap);
 
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_Attributes      , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ParentDirID    , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_CreateDate     , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ModDate        , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_BackupDate     , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_FinderInfo     , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_LongName       , tvb, offset, 4,FALSE);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_Attributes , tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ParentDirID, tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_CreateDate , tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ModDate    , tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_BackupDate , tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_FinderInfo , tvb, offset, 4, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_LongName   , tvb, offset, 4, ENC_BIG_ENDIAN);
 
                if (d_bitmap == 0) {
                        /* Only for file-only searches */
-                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_DataForkLen         , tvb, offset, 4,FALSE);
-                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_RsrcForkLen         , tvb, offset, 4,FALSE);
-                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ExtDataForkLen      , tvb, offset, 4,FALSE);
+                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_DataForkLen    , tvb, offset, 4, ENC_BIG_ENDIAN);
+                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_RsrcForkLen    , tvb, offset, 4, ENC_BIG_ENDIAN);
+                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ExtDataForkLen , tvb, offset, 4, ENC_BIG_ENDIAN);
                }
                if (f_bitmap == 0) {
                        /* Only for directory-only searches */
-                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_OffspringCount      , tvb, offset, 4,FALSE);
+                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_OffspringCount , tvb, offset, 4, ENC_BIG_ENDIAN);
                }
 
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_UTF8Name        , tvb, offset, 4,FALSE);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_UTF8Name , tvb, offset, 4, ENC_BIG_ENDIAN);
 
                if (d_bitmap == 0) {
                        /* Only for file-only searches */
-                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ExtRsrcForkLen      , tvb, offset, 4,FALSE);
+                       proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ExtRsrcForkLen , tvb, offset, 4, ENC_BIG_ENDIAN);
                }
-               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_PartialNames        , tvb, offset, 4,FALSE);
+               proto_tree_add_item(sub_tree, hf_afp_request_bitmap_PartialNames , tvb, offset, 4, ENC_BIG_ENDIAN);
        }
        offset += 4;
 
@@ -2349,7 +2458,7 @@ reply_catsearch(tvbuff_t *tvb, proto_tree *tree, gint offset, int ext)
        guint16 d_bitmap;
        int count;
 
-       proto_tree_add_item(tree, hf_afp_cat_position, tvb, offset, 16,FALSE);
+       proto_tree_add_item(tree, hf_afp_cat_position, tvb, offset, 16, ENC_NA);
        offset += 16;
 
        f_bitmap = decode_file_bitmap(tree, tvb, offset);
@@ -2360,7 +2469,7 @@ reply_catsearch(tvbuff_t *tvb, proto_tree *tree, gint offset, int ext)
 
        count = tvb_get_ntohl(tvb, offset);
        if (tree) {
-               item = proto_tree_add_item(tree, hf_afp_cat_count, tvb, offset, 4,FALSE);
+               item = proto_tree_add_item(tree, hf_afp_cat_count, tvb, offset, 4, ENC_BIG_ENDIAN);
                sub_tree = proto_item_add_subtree(item, ett_afp_cat_search);
        }
        offset += 4;
@@ -2390,7 +2499,7 @@ dissect_query_afp_get_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        PAD(1)
        add_info_vol(tvb, pinfo, offset);
 
-       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        decode_vol_bitmap(tree, tvb, offset);
@@ -2422,7 +2531,7 @@ dissect_query_afp_set_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        PAD(1)
 
        add_info_vol(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        bitmap = decode_vol_bitmap(tree, tvb, offset);
@@ -2444,7 +2553,7 @@ decode_uam_parameters(const guint8 *uam, int len_uam, tvbuff_t *tvb, proto_tree
                        PAD(1);
 
                len = 8; /* tvb_strsize(tvb, offset);*/
-               proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, len,FALSE);
+               proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, len, ENC_UTF_8|ENC_NA);
                offset += len;
        }
        else if (!g_ascii_strncasecmp(uam, "DHCAST128", len_uam)) {
@@ -2452,7 +2561,7 @@ decode_uam_parameters(const guint8 *uam, int len_uam, tvbuff_t *tvb, proto_tree
                        PAD(1);
 
                len = 16;
-               proto_tree_add_item(tree, hf_afp_random, tvb, offset, len,FALSE);
+               proto_tree_add_item(tree, hf_afp_random, tvb, offset, len, ENC_NA);
                offset += len;
        }
        else if (!g_ascii_strncasecmp(uam, "2-Way Randnum exchange", len_uam)) {
@@ -2471,11 +2580,11 @@ dissect_query_afp_login(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        const guint8 *uam;
 
        len = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_AFPVersion, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_Version, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len +1;
        len_uam = tvb_get_guint8(tvb, offset);
-       uam = tvb_get_ephemeral_string(tvb, offset +1, len_uam);
-       proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1,FALSE);
+       uam = tvb_get_string_enc(wmem_packet_scope(), tvb, offset +1, len_uam, ENC_UTF_8|ENC_NA);
+       proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len_uam +1;
 
        if (!g_ascii_strncasecmp(uam, "No User Authent", len_uam)) {
@@ -2483,7 +2592,7 @@ dissect_query_afp_login(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
        }
 
        len = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_user, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_user, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len +1;
 
        return decode_uam_parameters(uam, len_uam, tvb, tree, offset);
@@ -2496,52 +2605,49 @@ dissect_query_afp_login_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
        int len;
        int len_uam;
        const guint8 *uam;
-       guint8 type;
-
-       type = tvb_get_guint8(tvb, offset);
+       guint8 path_type;
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_login_flags, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_login_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        len = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_AFPVersion, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_Version, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len +1;
 
        len_uam = tvb_get_guint8(tvb, offset);
-       uam = tvb_get_ephemeral_string(tvb, offset +1, len_uam);
-       proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1,FALSE);
+       uam = tvb_get_string_enc(wmem_packet_scope(), tvb, offset +1, len_uam, ENC_UTF_8|ENC_NA);
+       proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len_uam +1;
 
-       type = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_user_type, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_user_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
        /* only type 3 */
        len = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_user_len, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_user_len, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
-       proto_tree_add_item(tree, hf_afp_user_name, tvb, offset, len,FALSE);
+       proto_tree_add_item(tree, hf_afp_user_name, tvb, offset, len, ENC_UTF_8|ENC_NA);
        offset += len;
 
        /* directory service */
-       type = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_path_type, tvb, offset, 1,FALSE);
+       path_type = tvb_get_guint8(tvb, offset);
+       proto_tree_add_item(tree, hf_afp_path_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
        /* FIXME use 16 bit len + unicode from smb dissector */
-       switch (type) {
+       switch (path_type) {
        case 1:
        case 2:
                len = tvb_get_guint8(tvb, offset);
-               proto_tree_add_item(tree, hf_afp_path_len, tvb, offset,  1,FALSE);
+               proto_tree_add_item(tree, hf_afp_path_len, tvb, offset,  1, ENC_BIG_ENDIAN);
                offset++;
-               proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, len,FALSE);
+               proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, len, ENC_UTF_8|ENC_NA);
                offset += len;
                break;
        case 3:
                len = tvb_get_ntohs(tvb, offset);
-               proto_tree_add_item( tree, hf_afp_path_unicode_len, tvb, offset, 2,FALSE);
+               proto_tree_add_item( tree, hf_afp_path_unicode_len, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
-               proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, len,FALSE);
+               proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, len, ENC_UTF_8|ENC_NA);
                offset += len;
                break;
        default:
@@ -2555,22 +2661,22 @@ dissect_query_afp_login_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 static gint
 dissect_query_afp_write(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, gint offset)
 {
-       int  param;
+       int param;
 
 
-       proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
 
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
        param = tvb_get_ntohl(tvb, offset);
        col_append_fstr(pinfo->cinfo, COL_INFO, " Offset=%d", param);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4, ENC_BIG_ENDIAN);
        param = tvb_get_ntohl(tvb, offset);
        col_append_fstr(pinfo->cinfo, COL_INFO, " Size=%d", param);
        offset += 4;
@@ -2581,7 +2687,7 @@ dissect_query_afp_write(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, gi
 static gint
 dissect_reply_afp_write(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_last_written, tvb, offset, 4, FALSE);
+       proto_tree_add_item(tree, hf_afp_last_written, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        return offset;
@@ -2589,19 +2695,19 @@ dissect_reply_afp_write(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 
 /* ************************** */
 static gint
-dissect_query_afp_write_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
+dissect_query_afp_write_ext(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
 
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
-       proto_tree_add_item(tree, hf_afp_rw_count64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_rw_count64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
        return offset;
@@ -2610,7 +2716,7 @@ dissect_query_afp_write_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 static gint
 dissect_reply_afp_write_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_last_written64, tvb, offset, 8, FALSE);
+       proto_tree_add_item(tree, hf_afp_last_written64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
        return offset;
@@ -2618,30 +2724,30 @@ dissect_reply_afp_write_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 
 /* ************************** */
 static gint
-dissect_query_afp_read(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
+dissect_query_afp_read(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
        int param;
 
        PAD(1);
 
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
        param = tvb_get_ntohl(tvb, offset);
        col_append_fstr(pinfo->cinfo, COL_INFO, " Offset=%d", param);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4, ENC_BIG_ENDIAN);
        param = tvb_get_ntohl(tvb, offset);
        col_append_fstr(pinfo->cinfo, COL_INFO, " Size=%d", param);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_newline_mask, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_newline_mask, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
-       proto_tree_add_item(tree, hf_afp_newline_char, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_newline_char, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
        return offset;
@@ -2649,18 +2755,18 @@ dissect_query_afp_read(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree,
 
 /* ************************** */
 static gint
-dissect_query_afp_read_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
+dissect_query_afp_read_ext(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
        PAD(1);
 
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
-       proto_tree_add_item(tree, hf_afp_rw_count64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_rw_count64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
        return offset;
@@ -2674,7 +2780,7 @@ dissect_query_afp_read_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 static gint
 dissect_reply_afp_open_dt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -2687,7 +2793,7 @@ static gint
 dissect_query_afp_close_dt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -2706,7 +2812,7 @@ dissect_query_afp_with_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 {
        PAD(1);
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -2738,7 +2844,7 @@ dissect_reply_afp_get_fldr_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
        offset += 2;
 
        flags = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
        PAD(1);
        if (flags) {
@@ -2845,7 +2951,7 @@ dissect_query_afp_create_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 static gint
 dissect_reply_afp_create_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        return offset;
@@ -2855,7 +2961,7 @@ dissect_reply_afp_create_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 static gint
 dissect_reply_afp_create_dir(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        return offset;
@@ -2868,9 +2974,9 @@ static gint
 dissect_query_afp_delete_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
-       proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        return offset;
@@ -2883,9 +2989,9 @@ static gint
 dissect_query_afp_resolve_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
-       proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        decode_file_bitmap(tree, tvb, offset);
@@ -2901,7 +3007,7 @@ dissect_query_afp_get_fork_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 
        PAD(1);
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        decode_file_bitmap(tree, tvb, offset);
@@ -2932,18 +3038,18 @@ dissect_query_afp_set_fork_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 
        PAD(1);
        add_info_fork(tvb, pinfo, offset);
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        bitmap = decode_file_bitmap(tree, tvb, offset);
        offset += 2;
 
        if ((bitmap & kFPExtDataForkLenBit) || (bitmap & kFPExtRsrcForkLenBit)) {
-               proto_tree_add_item(tree, hf_afp_ofork_len64, tvb, offset, 8, FALSE);
+               proto_tree_add_item(tree, hf_afp_ofork_len64, tvb, offset, 8, ENC_BIG_ENDIAN);
                offset += 8;
        }
        else {
-               proto_tree_add_item(tree, hf_afp_ofork_len, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_ofork_len, tvb, offset, 4, ENC_BIG_ENDIAN);
                param = tvb_get_ntohl(tvb, offset);
                col_append_fstr(pinfo->cinfo, COL_INFO, " Size=%d", param);
                offset += 4;
@@ -2959,12 +3065,12 @@ dissect_query_afp_move(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint
        PAD(1);
        offset = decode_vol_did(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name_label(tree, pinfo, tvb, offset, "Source path: %s");
-       offset = decode_name_label(tree, NULL, tvb, offset,  "Dest dir:    %s");
-       offset = decode_name_label(tree, NULL, tvb, offset,  "New name:    %s");
+       offset = decode_name_label(tree, NULL, tvb, offset,  "Dest dir:    %s");
+       offset = decode_name_label(tree, NULL, tvb, offset,  "New name:    %s");
 
        return offset;
 }
@@ -2977,7 +3083,7 @@ dissect_query_afp_exchange_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
        PAD(1);
        offset = decode_vol_did(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name_label(tree, pinfo, tvb, offset, "Source path: %s");
@@ -2989,25 +3095,20 @@ dissect_query_afp_exchange_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 static gint
 dissect_query_afp_copy_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
+       proto_tree *sub_tree;
 
        PAD(1);
-       if (tree) {
-               item = proto_tree_add_text(tree, tvb, offset, 6,"Source volume");
-               sub_tree = proto_item_add_subtree(item, ett_afp_vol_did);
-       }
+       sub_tree = proto_tree_add_subtree(tree, tvb, offset, 6, ett_afp_vol_did, NULL, "Source volume");
+
        offset = decode_vol_did(sub_tree, tvb, offset);
 
-       if (tree) {
-               item = proto_tree_add_text(tree, tvb, offset, 6,"Dest volume");
-               sub_tree = proto_item_add_subtree(item, ett_afp_vol_did);
-       }
+       sub_tree = proto_tree_add_subtree(tree, tvb, offset, 6, ett_afp_vol_did, NULL, "Dest volume");
+
        offset = decode_vol_did(sub_tree, tvb, offset);
 
        offset = decode_name_label(tree, pinfo, tvb, offset, "Source path: %s");
-       offset = decode_name_label(tree, NULL, tvb, offset,  "Dest dir:    %s");
-       offset = decode_name_label(tree, NULL, tvb, offset,  "New name:    %s");
+       offset = decode_name_label(tree, NULL, tvb, offset,  "Dest dir:    %s");
+       offset = decode_name_label(tree, NULL, tvb, offset,  "New name:    %s");
 
        return offset;
 }
@@ -3030,27 +3131,24 @@ dissect_query_afp_rename(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
 static gint
 dissect_query_afp_byte_lock(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
+       proto_tree *sub_tree;
        guint8 flag;
 
        flag = tvb_get_guint8(tvb, offset);
-       if (tree) {
-               item = proto_tree_add_text(tree, tvb, offset, 1, "Flags: 0x%02x", flag);
-               sub_tree = proto_item_add_subtree(item, ett_afp_lock_flags);
-       }
+       sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1,
+                                       ett_afp_lock_flags, NULL, "Flags: 0x%02x", flag);
 
-       proto_tree_add_item(sub_tree, hf_afp_lock_op, tvb, offset, 1,FALSE);
-       proto_tree_add_item(sub_tree, hf_afp_lock_from, tvb, offset, 1,FALSE);
+       proto_tree_add_item(sub_tree, hf_afp_lock_op, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(sub_tree, hf_afp_lock_from, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
 
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_lock_offset, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_lock_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_lock_len, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_lock_len, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        return offset;
 }
@@ -3059,7 +3157,7 @@ dissect_query_afp_byte_lock(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 static gint
 dissect_reply_afp_byte_lock(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_lock_range_start, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_lock_range_start, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        return offset;
@@ -3069,27 +3167,24 @@ dissect_reply_afp_byte_lock(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
 static gint
 dissect_query_afp_byte_lock_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree *sub_tree = NULL;
-       proto_item *item;
+       proto_tree *sub_tree;
        guint8 flag;
 
        flag = tvb_get_guint8(tvb, offset);
-       if (tree) {
-               item = proto_tree_add_text(tree, tvb, offset, 1, "Flags: 0x%02x", flag);
-               sub_tree = proto_item_add_subtree(item, ett_afp_lock_flags);
-       }
+       sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1,
+                                               ett_afp_lock_flags, NULL, "Flags: 0x%02x", flag);
 
-       proto_tree_add_item(sub_tree, hf_afp_lock_op, tvb, offset, 1,FALSE);
-       proto_tree_add_item(sub_tree, hf_afp_lock_from, tvb, offset, 1,FALSE);
+       proto_tree_add_item(sub_tree, hf_afp_lock_op, tvb, offset, 1, ENC_BIG_ENDIAN);
+       proto_tree_add_item(sub_tree, hf_afp_lock_from, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
 
-       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_lock_offset64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_lock_offset64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
-       proto_tree_add_item(tree, hf_afp_lock_len64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_lock_len64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        return offset;
 }
@@ -3098,7 +3193,7 @@ dissect_query_afp_byte_lock_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
 static gint
 dissect_reply_afp_byte_lock_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_lock_range_start64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_lock_range_start64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
        return offset;
@@ -3111,10 +3206,10 @@ dissect_query_afp_add_cmt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
        guint8 len;
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -3123,7 +3218,7 @@ dissect_query_afp_add_cmt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
                PAD(1);
 
        len = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_comment, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_comment, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len +1;
 
        return offset;
@@ -3136,10 +3231,10 @@ dissect_query_afp_get_cmt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
 {
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -3153,7 +3248,7 @@ dissect_reply_afp_get_cmt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tre
        guint8 len;
 
        len = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_comment, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_comment, tvb, offset, 1, ENC_UTF_8|ENC_BIG_ENDIAN);
        offset += len +1;
 
        return offset;
@@ -3165,19 +3260,19 @@ dissect_query_afp_get_icon(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 {
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
-       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4, ENC_UTF_8|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
        PAD(1);
 
-       proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -3189,12 +3284,12 @@ dissect_query_afp_get_icon_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
 {
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
-       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_icon_index, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_index, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -3205,17 +3300,17 @@ static gint
 dissect_reply_afp_get_icon_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
 
-       proto_tree_add_item(tree, hf_afp_icon_tag, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_tag, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -3227,22 +3322,22 @@ dissect_query_afp_add_icon(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 {
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
-       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_icon_tag, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_tag, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -3256,11 +3351,11 @@ decode_dt_did(proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
        /* FIXME it's not volume but dt cf decode_name*/
        Vol = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        Did = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
        return offset;
 }
@@ -3273,10 +3368,10 @@ dissect_query_afp_add_appl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        PAD(1);
        offset = decode_dt_did(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_appl_tag, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_appl_tag, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -3294,7 +3389,7 @@ dissect_query_afp_rmv_appl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        PAD(1);
        offset = decode_dt_did(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -3308,13 +3403,13 @@ dissect_query_afp_get_appl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 {
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4, ENC_ASCII|ENC_NA);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_appl_index, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_appl_index, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
        decode_file_bitmap(tree, tvb, offset);
@@ -3327,7 +3422,7 @@ dissect_query_afp_get_appl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 static gint
 dissect_reply_afp_get_appl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_appl_tag, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_appl_tag, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        return offset;
@@ -3337,7 +3432,7 @@ dissect_reply_afp_get_appl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 static gint
 dissect_query_afp_create_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
-       proto_tree_add_item(tree, hf_afp_create_flag, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_create_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
        offset = decode_vol_did(tree, tvb, offset);
@@ -3354,15 +3449,15 @@ dissect_query_afp_map_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
        guint8 type;
 
        type = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_map_id_type, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_map_id_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
        if ( type < 5) {
-               proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
        else {
-               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16,FALSE);
+               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, ENC_BIG_ENDIAN);
                offset += 16;
        }
 
@@ -3383,34 +3478,37 @@ dissect_reply_afp_map_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree
        if (!len) {
                len = tvb_get_guint8(tvb, offset +1);
                if (!len) {
-                   /* assume it's undocumented type 5 or 6 reply */
-                   proto_tree_add_item(tree, hf_afp_map_id_reply_type, tvb, offset, 4,FALSE);
-                   offset += 4;
+                       /*
+                        * Assume it's kUserUUIDToUTF8Name or
+                        * kGroupUUIDToUTF8Name.
+                        */
+                       proto_tree_add_item(tree, hf_afp_map_id_reply_type, tvb, offset, 4, ENC_BIG_ENDIAN);
+                       offset += 4;
 
-                   proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4,FALSE);
-                   offset += 4;
+                       proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+                       offset += 4;
 
-                   size = 2;
-                   len = tvb_get_guint8(tvb, offset +1);
+                       size = 2;
+                       len = tvb_get_guint8(tvb, offset +1);
 
                }
                else {
-                   gint remain = tvb_reported_length_remaining(tvb,offset);
-                   if (remain == len +2) {
+                       gint remain = tvb_reported_length_remaining(tvb,offset);
+                       if (remain == len +2) {
                        size = 2;
-                   }
-                   else {
+                       }
+                       else {
                        /* give up */
                        len = remain;
                        size = 0;
-                   }
+                       }
                }
        }
        if (size) {
-           proto_tree_add_item(tree, hf_afp_map_name, tvb, offset, size, FALSE);
+               proto_tree_add_item(tree, hf_afp_map_name, tvb, offset, size, ENC_ASCII|ENC_BIG_ENDIAN);
        }
        else {
-           proto_tree_add_item(tree, hf_afp_unknown, tvb, offset, len, FALSE);
+               proto_tree_add_item(tree, hf_afp_unknown, tvb, offset, len, ENC_NA);
        }
        offset += len +size;
        return offset;
@@ -3425,20 +3523,27 @@ dissect_query_afp_map_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        int size;
 
        type = tvb_get_guint8(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_map_name_type, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_map_name_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
        switch (type) {
-       case 5: /* use 16 bits length */
+       case 5:
        case 6:
+               /*
+                * Maps to UUID, UTF-8 string
+                *
+                * XXX - the spec doesn't say the string length is 2 bytes
+                * for this case.
+                */
                size = 2;
                len = tvb_get_ntohs(tvb, offset);
                break;
        default:
+               /* Maps to UID/GID */
                size = 1;
                len = tvb_get_guint8(tvb, offset);
                break;
        }
-       proto_tree_add_item(tree, hf_afp_map_name, tvb, offset, size, FALSE);
+       proto_tree_add_item(tree, hf_afp_map_name, tvb, offset, size, ENC_ASCII|ENC_BIG_ENDIAN);
        offset += len +size;
 
        return offset;
@@ -3452,13 +3557,13 @@ dissect_reply_afp_map_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 
        /* We don't keep the type from the request */
        /* If remain == 16, assume UUID */
-       remain =  tvb_reported_length(tvb);
+       remain = tvb_reported_length(tvb);
        if (remain == 16) {
-               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
+               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, ENC_BIG_ENDIAN);
                offset += 16;
        }
        else {
-               proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4, FALSE);
+               proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
 
@@ -3469,22 +3574,23 @@ dissect_reply_afp_map_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
 static gint
 dissect_query_afp_disconnect_old_session(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       int len, orig_offset = offset;
+       guint32 token_len;
 
        PAD(1);
 
-       proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       len = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_session_token_len, tvb, offset, 4,FALSE);
+       proto_tree_add_item_ret_uint(tree, hf_afp_session_token_len,
+                       tvb, offset, 4, ENC_BIG_ENDIAN, &token_len);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_session_token, tvb, offset, len,FALSE);
-       offset += len;
+       if ((guint32)offset + token_len > G_MAXINT)
+               return offset;
 
-       if (offset <= orig_offset)
-               THROW(ReportedBoundsError);
+       proto_tree_add_item(tree, hf_afp_session_token,
+                       tvb, offset, (gint)token_len, ENC_NA);
+       offset += (gint)token_len;
 
        return offset;
 }
@@ -3494,31 +3600,32 @@ static gint
 dissect_query_afp_get_session_token(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
        guint16 token;
-       int len, orig_offset = offset;
+       guint32 token_len;
 
        PAD(1);
+
        token = tvb_get_ntohs(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2,FALSE);
+       proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        if (token == kLoginWithoutID || token == kGetKerberosSessionKey) /* 0 || 8 */
                return offset;
 
-       len = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_session_token_len, tvb, offset, 4,FALSE);
+       proto_tree_add_item_ret_uint(tree, hf_afp_session_token_len,
+                       tvb, offset, 4, ENC_BIG_ENDIAN, &token_len);
        offset += 4;
 
-       switch (token) {
-       case kLoginWithTimeAndID:
-       case kReconnWithTimeAndID:
-               proto_tree_add_item(tree, hf_afp_session_token_timestamp, tvb, offset, 4,FALSE);
+       if (token==kLoginWithTimeAndID || token==kReconnWithTimeAndID) {
+               proto_tree_add_item(tree, hf_afp_session_token_timestamp,
+                               tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
 
-       proto_tree_add_item(tree, hf_afp_session_token, tvb, offset, len,FALSE);
-       offset += len;
+       if ((guint32)offset + token_len > G_MAXINT)
+               return offset;
 
-       if (offset <= orig_offset)
-               THROW(ReportedBoundsError);
+       proto_tree_add_item(tree, hf_afp_session_token,
+                       tvb, offset, (gint)token_len, ENC_NA);
+       offset += (gint)token_len;
 
        return offset;
 }
@@ -3527,48 +3634,48 @@ dissect_query_afp_get_session_token(tvbuff_t *tvb, packet_info *pinfo _U_, proto
 static gint
 dissect_reply_afp_get_session_token(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       int len, orig_offset = offset;
        int size;
+       guint32 token_len;
 
        /* FIXME spec and capture disagree : or it's 4 bytes with no token type, or it's 2 bytes */
        size = 4;
        /* [cm]: FIXME continued:  Since size is set to 4, this test is never true.
        if (size == 2) {
-               proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2,FALSE);
+               proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
        }
        */
-       len = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_session_token_len, tvb, offset, size,FALSE);
+       proto_tree_add_item_ret_uint(tree, hf_afp_session_token_len,
+                       tvb, offset, size, ENC_BIG_ENDIAN, &token_len);
        offset += size;
 
-       proto_tree_add_item(tree, hf_afp_session_token, tvb, offset, len,FALSE);
-       offset += len;
+       if ((guint32)offset + token_len > G_MAXINT)
+               return offset;
 
-       if (offset <= orig_offset)
-               THROW(ReportedBoundsError);
+       proto_tree_add_item(tree, hf_afp_session_token,
+                       tvb, offset, (gint)token_len, ENC_NA);
+       offset += (gint)token_len;
 
        return offset;
 }
 
 /* ************************** */
+static const int * afp_message_bitmaps[] = {
+       &hf_afp_message_bitmap_REQ,
+       &hf_afp_message_bitmap_UTF,
+       NULL
+};
+
 static gint
 dissect_query_afp_get_server_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
 
        PAD(1);
-       proto_tree_add_item(tree, hf_afp_message_type, tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_afp_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
-
-               item = proto_tree_add_item(tree, hf_afp_message_bitmap, tvb, offset, 2, FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_message_bitmap);
-               proto_tree_add_item(sub_tree, hf_afp_message_bitmap_REQ, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_message_bitmap_UTF, tvb, offset, 2,FALSE);
-       }
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_message_bitmap,
+                                       ett_afp_message_bitmap, afp_message_bitmaps, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -3583,62 +3690,67 @@ dissect_reply_afp_get_server_message(tvbuff_t *tvb, packet_info *pinfo _U_, prot
 
        /* FIXME: APF 3.1 specs also specify a long reply format, yet unused */
 
-       proto_tree_add_item(tree, hf_afp_message_type, tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_afp_message_type, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_message_bitmap,
+                                       ett_afp_message_bitmap, afp_message_bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
-
-               item = proto_tree_add_item(tree, hf_afp_message_bitmap, tvb, offset, 2, FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_message_bitmap);
-               proto_tree_add_item(sub_tree, hf_afp_message_bitmap_REQ, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_message_bitmap_UTF, tvb, offset, 2,FALSE);
-       }
        offset += 2;
 
-       /* FIXME: Not in the specs, but for UTF8 message length is 2 bytes */
-       if ((bitmap & 3) == 3) {
+       /*
+        * XXX - the spec says that the 0x01 bit indicates whether
+        * the ServerMessage field contains a server message or a login
+        * message.
+        */
+       if (bitmap & 0x02) {
+               /* Message is UTF-8, and message length is 2 bytes */
                len = tvb_get_ntohs(tvb, offset);
-               proto_tree_add_item(tree, hf_afp_message_len, tvb, offset, 2,FALSE);
+               proto_tree_add_item(tree, hf_afp_message_len, tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
-       }
-       else if ((bitmap & 1)) {
+               if (len) {
+                       proto_tree_add_item(tree, hf_afp_message, tvb, offset, len , ENC_UTF_8|ENC_NA);
+                       offset += len;
+               }
+       } else {
+               /*
+                * Message is not UTF-8, and message length is 1 byte.
+                *
+                * Is the message in some Mac encoding? Always Mac Roman,
+                * or possibly some other encoding for other locales?
+                */
                len = tvb_get_guint8(tvb, offset);
-               proto_tree_add_item(tree, hf_afp_message_len, tvb, offset, 1,FALSE);
+               proto_tree_add_item(tree, hf_afp_message_len, tvb, offset, 1, ENC_BIG_ENDIAN);
                offset += 1;
-       }
-
-       if (len) {
-               proto_tree_add_item(tree, hf_afp_message, tvb, offset, len ,FALSE);
-               offset += len;
+               if (len) {
+                       proto_tree_add_item(tree, hf_afp_message, tvb, offset, len , ENC_ASCII|ENC_NA);
+                       offset += len;
+               }
        }
 
        return offset;
 }
 
 /* ************************** */
+static const int * afp_user_bitmaps[] = {
+       &hf_afp_user_bitmap_UID,
+       &hf_afp_user_bitmap_GID,
+       &hf_afp_user_bitmap_UUID,
+       NULL
+};
+
 static gint
 dissect_query_afp_get_user_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
 
-       proto_tree_add_item(tree, hf_afp_user_flag, tvb, offset, 1,FALSE);
+       proto_tree_add_item(tree, hf_afp_user_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset++;
 
-       proto_tree_add_item(tree, hf_afp_user_ID, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_user_ID, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
-
-               item = proto_tree_add_item(tree, hf_afp_user_bitmap, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_user_bitmap);
-               proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UID, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_user_bitmap_GID, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UUID, tvb, offset, 2,FALSE);
-       }
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_user_bitmap,
+                                       ett_afp_user_bitmap, afp_user_bitmaps, ENC_BIG_ENDIAN);
        offset += 2;
 
        return offset;
@@ -3650,31 +3762,23 @@ dissect_reply_afp_get_user_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre
 {
        guint16  bitmap;
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_user_bitmap,
+                                       ett_afp_user_bitmap, afp_user_bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
-
-               item = proto_tree_add_item(tree, hf_afp_user_bitmap, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_user_bitmap);
-               proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UID, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_user_bitmap_GID, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UUID, tvb, offset, 2,FALSE);
-       }
 
        offset += 2;
        if ((bitmap & 1)) {
-               proto_tree_add_item(tree, hf_afp_user_ID, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_user_ID, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
 
        if ((bitmap & 2)) {
-               proto_tree_add_item(tree, hf_afp_group_ID, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_group_ID, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
        }
 
        if ((bitmap & 4)) {
-               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16,FALSE);
+               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, ENC_BIG_ENDIAN);
                offset += 16;
        }
        return offset;
@@ -3695,14 +3799,13 @@ decode_attr_name (proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, gint
        if (tree) {
                gchar *name;
                proto_tree *sub_tree;
-               proto_item *item;
 
                name = tvb_format_text(tvb,offset+2, len);
-               item = proto_tree_add_text(tree, tvb, offset, len + 2, label, name);
-               sub_tree = proto_item_add_subtree(item, ett_afp_extattr_names);
+               sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, len + 2,
+                                                                               ett_afp_extattr_names, NULL, label, name);
 
-               proto_tree_add_item(sub_tree, hf_afp_extattr_namelen, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_extattr_name, tvb, offset +2, len, FALSE);
+               proto_tree_add_item(sub_tree, hf_afp_extattr_namelen, tvb, offset, 2, ENC_BIG_ENDIAN);
+               proto_tree_add_item(sub_tree, hf_afp_extattr_name, tvb, offset +2, len, ENC_UTF_8|ENC_NA);
        }
        offset += 2 +len;
 
@@ -3713,17 +3816,15 @@ decode_attr_name (proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, gint
 static gint
 decode_attr_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
 {
+       static const int * bitmaps[] = {
+               &hf_afp_extattr_bitmap_NoFollow,
+               &hf_afp_extattr_bitmap_Create,
+               &hf_afp_extattr_bitmap_Replace,
+               NULL
+       };
 
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
-
-               item = proto_tree_add_item(tree, hf_afp_extattr_bitmap, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_extattr_bitmap);
-               proto_tree_add_item(sub_tree, hf_afp_extattr_bitmap_NoFollow, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_extattr_bitmap_Create, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_extattr_bitmap_Replace, tvb, offset, 2,FALSE);
-       }
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_extattr_bitmap,
+                                       ett_afp_extattr_bitmap, bitmaps, ENC_BIG_ENDIAN);
        offset += 2;
        return offset;
 }
@@ -3738,14 +3839,14 @@ dissect_query_afp_get_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        offset = decode_attr_bitmap(tree, tvb, offset);
 
        /* 8byte offset */
-       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
        /* 8byte reqcount */
-       proto_tree_add_item(tree, hf_afp_reqcount64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_reqcount64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
        /* maxreply */
-       proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, FALSE);
+       proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -3759,24 +3860,20 @@ dissect_query_afp_get_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 static gint
 dissect_reply_afp_get_ext_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       guint32  len;
-       guint    remain;
-       int      orig_offset = offset;
+       guint32  extattr_len;
 
        offset = decode_attr_bitmap(tree, tvb, offset);
 
-       len = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_extattr_len, tvb, offset, 4,FALSE);
+       proto_tree_add_item_ret_uint(tree, hf_afp_extattr_len,
+                       tvb, offset, 4, ENC_BIG_ENDIAN, &extattr_len);
        offset += 4;
 
-       remain =  tvb_reported_length_remaining(tvb, offset);
-       if (len && remain >= len ) {
-               proto_tree_add_item(tree, hf_afp_extattr_data, tvb, offset, len, FALSE);
-               offset += len;
-       }
+       if ((guint32)offset + extattr_len > G_MAXINT)
+               return offset;
 
-       if (offset <= orig_offset)
-               THROW(ReportedBoundsError);
+       proto_tree_add_item(tree, hf_afp_extattr_data,
+                       tvb, offset, (gint)extattr_len, ENC_NA);
+       offset += (gint)extattr_len;
 
        return offset;
 }
@@ -3785,7 +3882,7 @@ dissect_reply_afp_get_ext_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree
 static gint
 dissect_query_afp_set_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
-       guint16  len;
+       guint32  len;
 
        PAD(1);
        offset = decode_vol_did(tree, tvb, offset);
@@ -3793,18 +3890,17 @@ dissect_query_afp_set_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
        offset = decode_attr_bitmap(tree, tvb, offset);
 
        /* 8byte offset */
-       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
+       proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8, ENC_BIG_ENDIAN);
        offset += 8;
 
        offset = decode_name(tree, pinfo, tvb, offset);
 
        offset = decode_attr_name(tree, pinfo, tvb, offset, "Attribute: %s");
 
-       len = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_extattr_len, tvb, offset, 4,FALSE);
+       proto_tree_add_item_ret_uint(tree, hf_afp_extattr_len, tvb, offset, 4, ENC_BIG_ENDIAN, &len);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_extattr_data, tvb, offset, len, FALSE);
+       proto_tree_add_item(tree, hf_afp_extattr_data, tvb, offset, len, ENC_NA);
        offset += len;
 
        return offset;
@@ -3820,13 +3916,13 @@ dissect_query_afp_list_ext_attrs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
        /* for this command only kXAttrNoFollow is valid */
        offset = decode_attr_bitmap(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_extattr_req_count, tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_afp_extattr_req_count, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_extattr_start_index, tvb, offset, 4, FALSE);
+       proto_tree_add_item(tree, hf_afp_extattr_start_index, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, FALSE);
+       proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -3838,35 +3934,36 @@ dissect_query_afp_list_ext_attrs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 static gint
 dissect_reply_afp_list_ext_attrs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
 {
-       proto_item *item;
        proto_tree *sub_tree;
-       gint length = 0, orig_offset = offset;
-       int remain;
+       guint len_field = 0;
+       gint length;
+       gint remain;
 
        offset = decode_attr_bitmap(tree, tvb, offset);
 
-       length = tvb_get_ntohl(tvb, offset);
-       proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, FALSE);
+       proto_tree_add_item_ret_uint(tree, hf_afp_extattr_reply_size,
+                       tvb, offset, 4, ENC_BIG_ENDIAN, &len_field);
        offset += 4;
+       if (len_field > G_MAXINT) {
+               /* XXX - add expert info */
+               return offset;
+       }
 
        /* If reply_size was 0 on request, server only reports the size of
           the entries without actually adding any entries */
-       remain =  tvb_reported_length_remaining(tvb, offset);
-       if (remain >= length) {
-
-               item = proto_tree_add_text(tree, tvb, offset, remain , "Attributes");
-               sub_tree = proto_item_add_subtree(item, ett_afp_extattr_names);
-               while ( remain > 0) {
-                       tvb_get_ephemeral_stringz(tvb, offset, &length);
-                       proto_tree_add_item(sub_tree, hf_afp_extattr_name, tvb, offset, length, FALSE);
-                       offset += length;
-                       remain -= length;
-               }
+       remain = tvb_reported_length_remaining(tvb, offset);
+       if (remain < (gint)len_field)
+               return offset;
 
-       }
+       sub_tree = proto_tree_add_subtree(tree, tvb, offset, remain,
+                       ett_afp_extattr_names, NULL, "Attributes");
+       while (remain > 0) {
+               length = (gint)tvb_strsize(tvb, offset);
 
-       if (offset <= orig_offset)
-               THROW(ReportedBoundsError);
+               proto_tree_add_item(sub_tree, hf_afp_extattr_name, tvb, offset, length, ENC_UTF_8|ENC_NA);
+               offset += length;
+               remain -= length;
+       }
 
        return offset;
 }
@@ -3892,34 +3989,31 @@ static gint
 decode_acl_access_bitmap(tvbuff_t *tvb, proto_tree *tree, gint offset)
 {
        guint32 bitmap;
+       static const int * bitmaps[] = {
+               &hf_afp_acl_access_bitmap_read_data,
+               &hf_afp_acl_access_bitmap_write_data,
+               &hf_afp_acl_access_bitmap_execute,
+               &hf_afp_acl_access_bitmap_delete,
+               &hf_afp_acl_access_bitmap_append_data,
+               &hf_afp_acl_access_bitmap_delete_child,
+               &hf_afp_acl_access_bitmap_read_attrs,
+               &hf_afp_acl_access_bitmap_write_attrs,
+               &hf_afp_acl_access_bitmap_read_extattrs,
+               &hf_afp_acl_access_bitmap_write_extattrs,
+               &hf_afp_acl_access_bitmap_read_security,
+               &hf_afp_acl_access_bitmap_write_security,
+               &hf_afp_acl_access_bitmap_change_owner,
+               &hf_afp_acl_access_bitmap_synchronize,
+               &hf_afp_acl_access_bitmap_generic_all,
+               &hf_afp_acl_access_bitmap_generic_execute,
+               &hf_afp_acl_access_bitmap_generic_write,
+               &hf_afp_acl_access_bitmap_generic_read,
+               NULL
+       };
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_acl_access_bitmap,
+                                       ett_afp_acl_access_bitmap, bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohl(tvb, offset);
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
-
-               item = proto_tree_add_item(tree, hf_afp_acl_access_bitmap, tvb, offset, 4, FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_acl_access_bitmap);
-
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_data      , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_data     , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_execute        , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_delete         , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_append_data    , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_delete_child   , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_attrs     , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_attrs    , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_extattrs  , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_extattrs , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_security  , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_security , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_change_owner   , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_synchronize    , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_all    , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_execute, tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_write  , tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_read   , tvb, offset, 4,FALSE);
-       }
 
        return bitmap;
 }
@@ -3931,10 +4025,10 @@ dissect_query_afp_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gi
        PAD(1);
        offset = decode_vol_did(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_access_bitmap, tvb, offset, 2, FALSE);
+       proto_tree_add_item(tree, hf_afp_access_bitmap, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
+       proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, ENC_BIG_ENDIAN);
        offset += 16;
 
        decode_acl_access_bitmap(tvb, tree, offset);
@@ -3952,224 +4046,511 @@ dissect_query_afp_with_did(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tr
        PAD(1);
        offset = decode_vol_did(tree, tvb, offset);
 
-       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        return offset;
 }
 
 /* ************************** */
+
+#define SQ_TYPE_NULL    0x0000
+#define SQ_TYPE_COMPLEX 0x0200
+#define SQ_TYPE_INT64   0x8400
+#define SQ_TYPE_BOOL    0x0100
+#define SQ_TYPE_FLOAT   0x8500
+#define SQ_TYPE_DATA    0x0700
+#define SQ_TYPE_CNIDS   0x8700
+#define SQ_TYPE_UUID    0x0e00
+#define SQ_TYPE_DATE    0x8600
+
+#define SQ_CPX_TYPE_ARRAY              0x0a00
+#define SQ_CPX_TYPE_STRING             0x0c00
+#define SQ_CPX_TYPE_UTF16_STRING       0x1c00
+#define SQ_CPX_TYPE_DICT               0x0d00
+#define SQ_CPX_TYPE_CNIDS              0x1a00
+#define SQ_CPX_TYPE_FILEMETA           0x1b00
+
+#define SUBQ_SAFETY_LIM 20
+
 static gint
-dissect_spotlight(tvbuff_t *tvb, proto_tree *tree, gint offset)
+spotlight_int64(tvbuff_t *tvb, proto_tree *tree, gint offset, guint encoding)
 {
-       gint i;
-       gint mdlen;
-       gint query_offset;
-       gint query_offset_next;
-       gint querylen;
-       gint toc_offset;
-       gint num_queries;
-       gint query_data_len;
+       guint count, i;
        guint64 query_data64;
-       guint64 toc_entry;
-       guint8 *mds;
 
-       proto_item *item_queries_data;
-       proto_tree *sub_tree_queries;
-       proto_item *item_toc;
-       proto_tree *sub_tree_toc;
-       proto_item *item_query;
-       proto_tree *sub_tree_query;
-       proto_item *item_data;
-       proto_tree *sub_tree_data;
-
-       if (strncmp(tvb_get_ephemeral_string(tvb, offset, 8), "md031234", 8) == 0)
-               spotlight_endianess = SPOTLIGHT_BIG_ENDIAN;
-       else
-               spotlight_endianess = SPOTLIGHT_LITTLE_ENDIAN;
-       proto_tree_add_text(tree,
-                           tvb,
-                           offset,
-                           8,
-                           "Endianess: %s",
-                           spotlight_endianess == SPOTLIGHT_BIG_ENDIAN ?
-                           "Big Endian" : "Litte Endian");
+       query_data64 = tvb_get_guint64(tvb, offset, encoding);
+       count = (guint)(query_data64 >> 32);
        offset += 8;
 
-       toc_offset = (spotlight_ntoh64(tvb, offset) >> 32) * 8 - 8;
-       querylen = (spotlight_ntoh64(tvb, offset) & 0xffffffff) * 8 - 8;
-       proto_tree_add_text(tree,
-                           tvb,
-                           offset,
-                           8,
-                           "ToC Offset: %u Bytes, Query length: %u Bytes",
-                           toc_offset,
-                           querylen);
-       offset += 8;
+       for (i = 0; i < count; i++) {
+               proto_tree_add_item(tree, hf_afp_int64, tvb, offset, 8, encoding);
+               offset += 8;
+       }
 
-       num_queries = (gint)(spotlight_ntoh64(tvb, offset + toc_offset) & 0xffff) - 1;
+       return count;
+}
 
-       item_queries_data = proto_tree_add_text(tree,
-                                               tvb,
-                                               offset,
-                                               toc_offset,
-                                               "Query data (%u queries)",
-                                               num_queries);
+static gint
+spotlight_date(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, guint encoding)
+{
+       guint count, i;
+       guint64 query_data64;
+       nstime_t t;
 
-       sub_tree_queries = proto_item_add_subtree(item_queries_data, ett_afp_spotlight_queries);
-       /* Queries */
-       query_offset_next = (spotlight_ntoh64(tvb, offset + toc_offset + 8) & 0xff) * 8 - 16;
-       for (i = 0; i < num_queries; i++) {
-               query_offset = query_offset_next;
-               if (i == num_queries - 1)
-                       /* last */
-                       query_offset_next = toc_offset;
-               else
-                       /* peek at next offset */
-                       query_offset_next = (spotlight_ntoh64(tvb, offset + toc_offset + 8 + (i+1)*8) & 0xff) * 8 - 16;
-
-               /* this is obviously the length of one query */
-               query_data_len = query_offset_next - query_offset;
-
-               if (query_data_len > 8)
-                       item_query = proto_tree_add_text(sub_tree_queries,
-                                                        tvb,
-                                                        offset + query_offset,
-                                                        query_data_len,
-                                                        "Query %u",
-                                                        i + 1);
-               else
-                       item_query = proto_tree_add_text(sub_tree_queries,
-                                                        tvb,
-                                                        offset + query_offset,
-                                                        query_data_len,
-                                                        "Query %u (empty?)",
-                                                        i + 1);
-
-               /* tree per query */
-               sub_tree_query = proto_item_add_subtree(item_query, ett_afp_spotlight_query_line);
-               query_data64 = spotlight_ntoh64(tvb, offset + query_offset);
-
-               /* print the query line */
-               proto_tree_add_text(sub_tree_query,
-                                   tvb,
-                                   offset + query_offset,
-                                   8,
-                                   "Index: %" G_GINT64_MODIFIER "u, ?: 0x%08" G_GINT64_MODIFIER "x",
-                                   query_data64 >> 32,
-                                   query_data64 & 0xffffffff);
-
-               /* really any data in the query */
-               if (query_data_len > 8) {
-                       /* populate the query tree */
-                       query_data64 = spotlight_ntoh64(tvb, offset + query_offset + 8);
-                       mdlen = ((query_data64 & 0xffff) - 1) * 8;
-                       proto_tree_add_text(sub_tree_query,
-                                           tvb,
-                                           offset + query_offset + 8,
-                                           8,
-                                           "?(reappears in ToC): 0x%08" G_GINT64_MODIFIER "x, ?: 0x%04" G_GINT64_MODIFIER "x, strlen: ((%u-1)*8 = ) %u",
-                                           query_data64 >> 32,
-                                           (query_data64 & 0xffff0000) >> 16,
-                                           mdlen/8+1,
-                                           mdlen);
-
-                       mds = tvb_get_ephemeral_string(tvb, offset + query_offset + 16, mdlen);
-                       proto_item_append_text(item_query, ": \"%s\"", mds);
-
-                       proto_tree_add_text(sub_tree_query,
-                                           tvb,
-                                           offset + query_offset + 16,
-                                           mdlen,
-                                           "mdstring: \"%s\" (%u bytes)",
-                                           mds,
-                                           mdlen);
-
-                       item_data = proto_tree_add_text(sub_tree_query,
-                                                       tvb,
-                                                       offset + query_offset + 16 + mdlen,
-                                                       query_data_len - 16 - mdlen,
-                                                       "data: %u bytes",
-                                                       query_data_len - 16 - mdlen);
-
-                       /* If there are more then 8 bytes theres at least x*8+8 bytes */
-                       if ((query_data_len - 16 - mdlen) >= 16) {
-                               sub_tree_data = proto_item_add_subtree(item_data, ett_afp_spotlight_data);
-                               query_data64 = spotlight_ntoh64(tvb, offset + query_offset + 16 + mdlen);
-
-                               proto_tree_add_text(sub_tree_data,
-                                                   tvb,
-                                                   offset + query_offset + 16 + mdlen,
-                                                   8,
-                                                   "data: %" G_GINT64_MODIFIER "u * 8 (= %" G_GINT64_MODIFIER "u) bytes, ?: 0x%04" G_GINT64_MODIFIER "x",
-                                                   (query_data64 & G_GINT64_CONSTANT(0xffffffff00000000)) >> 32,
-                                                   ((query_data64 & G_GINT64_CONSTANT(0xffffffff00000000)) >> 32) * 8,
-                                                   query_data64 & 0xffffffff);
-                               proto_tree_add_text(sub_tree_data,
-                                                   tvb,
-                                                   offset + query_offset + 16 + mdlen + 8,
-                                                   query_data_len - 16 - mdlen - 8,
-                                                   "data: %u  bytes",
-                                                   query_data_len - 16 - mdlen - 8);
-                       }
+       query_data64 = tvb_get_guint64(tvb, offset, encoding);
+       count = (guint)(query_data64 >> 32);
+       offset += 8;
 
-               }
+       if (count > SUBQ_SAFETY_LIM) {
+               expert_add_info_format(pinfo, tree, &ei_afp_subquery_count_over_safety_limit,
+                                                          "Subquery count (%d) > safety limit (%d)", count, SUBQ_SAFETY_LIM);
+               return -1;
        }
-       offset += toc_offset;
 
-       /* ToC */
-       item_toc = proto_tree_add_text(tree,
-                                      tvb,
-                                      offset,
-                                      querylen - toc_offset,
-                                      "ToC (%u entries)",
-                                      num_queries);
-       sub_tree_toc = proto_item_add_subtree(item_toc, ett_afp_spotlight_toc);
-       proto_tree_add_text(sub_tree_toc,
-                           tvb,
-                           offset,
-                           8,
-                           "Number of entries (%u)",
-                           num_queries);
-       for (i = 0; i < num_queries; i++) {
-               toc_entry = spotlight_ntoh64(tvb, offset + 8 + i*8);
-               proto_tree_add_text(sub_tree_toc,
-                                   tvb,
-                                   offset + 8 + i*8,
-                                   8,
-                                   "Index: %u, ?(reappears in queries): 0x%08" G_GINT64_MODIFIER "x, ?: 0x%04" G_GINT64_MODIFIER "x, Offset: %" G_GINT64_MODIFIER "u",
-                                   i+1,
-                                   toc_entry >> 32,
-                                   (toc_entry & 0xffff0000) >> 16,
-                                   (toc_entry & 0xffff) * 8);
-       }
-
-       offset += querylen - toc_offset;
-       return offset;
+       for (i = 0; i < count; i++) {
+               query_data64 = tvb_get_guint64(tvb, offset, encoding) >> 24;
+               t.secs = (time_t)(query_data64 - SPOTLIGHT_TIME_DELTA);
+               t.nsecs = 0;
+               proto_tree_add_time(tree, hf_afp_spotlight_date, tvb, offset, 8, &t);
+               offset += 8;
+       }
+
+       return count;
 }
 
 static gint
-dissect_query_afp_spotlight(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset, afp_request_val *request_val)
+spotlight_uuid(tvbuff_t *tvb, proto_tree *tree, gint offset, guint encoding)
 {
-       gint len;
+       guint count, i;
+       guint64 query_data64;
 
-       PAD(1);
-       offset = decode_vol(tree, tvb, offset);
+       query_data64 = tvb_get_guint64(tvb, offset, encoding);
+       count = (guint)(query_data64 >> 32);
+       offset += 8;
 
-       proto_tree_add_item(tree, hf_afp_spotlight_request_flags, tvb, offset, 4, FALSE);
-       offset += 4;
+       for (i = 0; i < count; i++) {
+               proto_tree_add_item(tree, hf_afp_spotlight_uuid, tvb, offset, 16, ENC_BIG_ENDIAN);
+               offset += 16;
+       }
 
-       proto_tree_add_item(tree, hf_afp_spotlight_request_command, tvb, offset, 4, FALSE);
-       offset += 4;
+       return count;
+}
 
-       proto_tree_add_item(tree, hf_afp_spotlight_request_reserved, tvb, offset, 4, FALSE);
-       offset += 4;
+static gint
+spotlight_float(tvbuff_t *tvb, proto_tree *tree, gint offset, guint encoding)
+{
+       guint count, i;
+       guint64 query_data64;
+
+       query_data64 = tvb_get_guint64(tvb, offset, encoding);
+       count = (guint)(query_data64 >> 32);
+       offset += 8;
+
+       for (i = 0; i < count; i++) {
+               proto_tree_add_item(tree, hf_afp_float, tvb, offset, 8, encoding);
+               offset += 8;
+       }
+
+       return count;
+}
+
+static gint
+spotlight_CNID_array(tvbuff_t *tvb, proto_tree *tree, gint offset, guint encoding)
+{
+       guint count;
+       guint64 query_data64;
+       guint16 unknown1;
+       guint32 unknown2;
+
+       query_data64 = tvb_get_guint64(tvb, offset, encoding);
+       count = (guint)(query_data64 & 0xffff);
+       unknown1 = (query_data64 & 0xffff0000) >> 16;
+       unknown2 = (guint32)(query_data64 >> 32);
+
+       proto_tree_add_uint(tree, hf_afp_unknown16, tvb, offset + 2, 2, unknown1);
+       proto_tree_add_uint(tree, hf_afp_unknown32, tvb, offset + 4, 4, unknown2);
+       offset += 8;
+
+
+       while (count --) {
+               proto_tree_add_item(tree, hf_afp_cnid, tvb, offset, 8, encoding);
+               offset += 8;
+       }
+
+       return 0;
+}
+
+static const val64_string qtype_string_values[] = {
+       {SQ_TYPE_NULL, "null" },
+       {SQ_TYPE_COMPLEX, "complex"},
+       {SQ_TYPE_INT64, "int64" },
+       {SQ_TYPE_BOOL, "bool"},
+       {SQ_TYPE_FLOAT, "float" },
+       {SQ_TYPE_DATA, "data"},
+       {SQ_TYPE_CNIDS, "CNIDs" },
+       {0, NULL}
+};
+
+static const val64_string cpx_qtype_string_values[] = {
+       {SQ_CPX_TYPE_ARRAY, "array" },
+       {SQ_CPX_TYPE_STRING, "string"},
+       {SQ_CPX_TYPE_UTF16_STRING, "utf-16 string" },
+       {SQ_CPX_TYPE_DICT, "dictionary"},
+       {SQ_CPX_TYPE_CNIDS, "CNIDs" },
+       {SQ_CPX_TYPE_FILEMETA, "FileMeta"},
+       {0, NULL}
+};
+
+static gint
+spotlight_dissect_query_loop(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset,
+                            guint64 cpx_query_type, gint count, gint toc_offset, guint encoding)
+{
+       gint i, j;
+       gint subquery_count;
+       gint toc_index;
+       guint64 query_data64;
+       gint query_length;
+       guint64 query_type;
+       guint64 complex_query_type;
+       guint byte_order;
+       gboolean mark_exists;
+       tvbuff_t *spotlight_tvb;
+       guint8 *str_tmp;
+
+       proto_item *item_query;
+       proto_tree *sub_tree;
+
+       /*
+        * This loops through a possibly nested query data structure.
+        * The outermost one is always without count and called from
+        * dissect_spotlight() with count = INT_MAX thus the while (...)
+        * loop terminates if (offset >= toc_offset).
+        * If nested structures are found, these will have an encoded element
+        * count which is used in a recursive call to
+        * spotlight_dissect_query_loop as count parameter, thus in this case
+        * the while (...) loop will terminate when count reaches 0.
+        */
+       while ((offset < (toc_offset - 8)) && (count > 0)) {
+               query_data64 = tvb_get_guint64(tvb, offset, encoding);
+               query_length = ((gint)query_data64 & 0xffff) * 8;
+               if (query_length == 0) {
+                       /* XXX - report this as an error */
+                       break;
+               }
+               query_type = (query_data64 & 0xffff0000) >> 16;
+
+               switch (query_type) {
+               case SQ_TYPE_COMPLEX:
+                       toc_index = (gint)((query_data64 >> 32) - 1);
+                       query_data64 = tvb_get_guint64(tvb, toc_offset + toc_index * 8, encoding);
+                       complex_query_type = (query_data64 & 0xffff0000) >> 16;
+
+                       switch (complex_query_type) {
+                       case SQ_CPX_TYPE_ARRAY:
+                       case SQ_CPX_TYPE_DICT:
+                               subquery_count = (gint)(query_data64 >> 32);
+                               sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, query_length,
+                                                                ett_afp_spotlight_query_line, NULL,
+                                                                "%s, toc index: %u, children: %u",
+                                                                val64_to_str_const(complex_query_type, cpx_qtype_string_values, "Unknown"),
+                                                                toc_index + 1,
+                                                                subquery_count);
+                               break;
+                       case SQ_CPX_TYPE_STRING:
+                               subquery_count = 1;
+                               query_data64 = tvb_get_guint64(tvb, offset + 8, encoding);
+                               query_length = ((gint)query_data64 & 0xffff) * 8;
+                               sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, query_length + 8,
+                                                                ett_afp_spotlight_query_line, NULL,
+                                                                "%s, toc index: %u, string: '%s'",
+                                                                val64_to_str_const(complex_query_type, cpx_qtype_string_values, "Unknown"),
+                                                                toc_index + 1,
+                                                                tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 16, query_length - 8, ENC_UTF_8|ENC_NA));
+                               break;
+                       case SQ_CPX_TYPE_UTF16_STRING:
+                               /*
+                               * This is an UTF-16 string.
+                               * Dissections show the typical byte order mark 0xFFFE or 0xFEFF, respectively.
+                               * However the existence of such a mark can not be assumed.
+                               * If the mark is missing, big endian encoding is assumed.
+                               * XXX - assume the encoding given by "encoding"?
+                               */
+
+                               subquery_count = 1;
+                               query_data64 = tvb_get_guint64(tvb, offset + 8, encoding);
+                               query_length = ((gint)query_data64 & 0xffff) * 8;
+
+                               byte_order = spotlight_get_utf16_string_byte_order(tvb, offset + 16, query_length - 8, encoding);
+                               if (byte_order == 0xFFFFFFFF) {
+                                       byte_order = ENC_BIG_ENDIAN;
+                                       mark_exists = FALSE;
+                               } else
+                                       mark_exists = TRUE;
+
+                               sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, query_length + 8,
+                                                                ett_afp_spotlight_query_line, NULL,
+                                                                "%s, toc index: %u, utf-16 string: '%s'",
+                                                                val64_to_str_const(complex_query_type, cpx_qtype_string_values, "Unknown"),
+                                                                toc_index + 1,
+                                                                tvb_get_string_enc(wmem_packet_scope(), tvb, offset + (mark_exists ? 18 : 16),
+                                                                query_length - (mark_exists? 10 : 8), ENC_UTF_16 | byte_order));
+                               break;
+                       default:
+                               subquery_count = 1;
+                               sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, query_length,
+                                                                ett_afp_spotlight_query_line, NULL,
+                                                                "type: %s (%s), toc index: %u, children: %u",
+                                                                val64_to_str_const(query_type, qtype_string_values, "Unknown"),
+                                                                val64_to_str_const(complex_query_type, cpx_qtype_string_values, "Unknown"),
+                                                                toc_index + 1,
+                                                                subquery_count);
+                               break;
+                       }
+
+                       offset += 8;
+                       offset = spotlight_dissect_query_loop(tvb, pinfo, sub_tree, offset, complex_query_type, subquery_count, toc_offset, encoding);
+                       count--;
+                       break;
+               case SQ_TYPE_NULL:
+                       subquery_count = (gint)(query_data64 >> 32);
+                       if (subquery_count > count) {
+                               item_query = proto_tree_add_item(tree, hf_afp_null, tvb, offset, query_length, ENC_NA);
+                               expert_add_info_format(pinfo, item_query, &ei_afp_subquery_count_over_query_count,
+                                       "Subquery count (%d) > query count (%d)", subquery_count, count);
+                               count = 0;
+                       } else if (subquery_count > 20) {
+                               item_query = proto_tree_add_item(tree, hf_afp_null, tvb, offset, query_length, ENC_NA);
+                               expert_add_info_format(pinfo, item_query, &ei_afp_abnormal_num_subqueries,
+                                       "Abnormal number of subqueries (%d)", subquery_count);
+                               count -= subquery_count;
+                       } else {
+                               for (i = 0; i < subquery_count; i++, count--)
+                                       proto_tree_add_item(tree, hf_afp_null, tvb, offset, query_length, encoding);
+                       }
+                       offset += query_length;
+                       break;
+               case SQ_TYPE_BOOL:
+                       proto_tree_add_uint64_format_value(tree, hf_afp_bool, tvb, offset, query_length, (query_data64 >> 32), "%s", (query_data64 >> 32) ? "true" : "false");
+                       count--;
+                       offset += query_length;
+                       break;
+               case SQ_TYPE_INT64:
+                       sub_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_afp_spotlight_query_line, NULL, "int64");
+                       j = spotlight_int64(tvb, sub_tree, offset, encoding);
+                       count -= j;
+                       offset += query_length;
+                       break;
+               case SQ_TYPE_UUID:
+                       sub_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_afp_spotlight_query_line, NULL, "UUID");
+                       j = spotlight_uuid(tvb, sub_tree, offset, encoding);
+                       count -= j;
+                       offset += query_length;
+                       break;
+               case SQ_TYPE_FLOAT:
+                       sub_tree = proto_tree_add_subtree(tree, tvb, offset, 8, ett_afp_spotlight_query_line, NULL, "float");
+                       j = spotlight_float(tvb, sub_tree, offset, encoding);
+                       count -= j;
+                       offset += query_length;
+                       break;
+               case SQ_TYPE_DATA:
+                       switch (cpx_query_type) {
+                       case SQ_CPX_TYPE_STRING:
+                               str_tmp = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 8, query_length - 8, ENC_UTF_8|ENC_NA);
+                               proto_tree_add_string(tree, hf_afp_string, tvb, offset, query_length, str_tmp);
+                               break;
+                       case SQ_CPX_TYPE_UTF16_STRING: {
+                               /* description see above */
+                               byte_order = spotlight_get_utf16_string_byte_order(tvb, offset + 16, query_length - 8, encoding);
+                               if (byte_order == 0xFFFFFFFF) {
+                                       byte_order = ENC_BIG_ENDIAN;
+                                       mark_exists = FALSE;
+                               } else
+                                       mark_exists = TRUE;
+
+                               str_tmp = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + (mark_exists ? 10 : 8),
+                                                               query_length - (mark_exists? 10 : 8), ENC_UTF_16 | byte_order);
+                               proto_tree_add_string(tree, hf_afp_utf_16_string, tvb, offset, query_length, str_tmp);
+                               break;
+                       }
+                       case SQ_CPX_TYPE_FILEMETA:
+                               sub_tree = proto_tree_add_subtree(tree, tvb, offset, query_length,
+                                                                                       ett_afp_spotlight_query_line, &item_query, "filemeta");
+                               if (query_length <= 8) {
+                                       proto_item_append_text(item_query, " (empty)");
+                               } else {
+                                       spotlight_tvb = tvb_new_subset_length(tvb, offset+8, query_length);
+                                       call_dissector(spotlight_handle, spotlight_tvb, pinfo, sub_tree);
+                               }
+                               break;
+                       }
+                       count--;
+                       offset += query_length;
+                       break;
+               case SQ_TYPE_CNIDS:
+                       sub_tree = proto_tree_add_subtree(tree, tvb, offset, query_length,
+                                                       ett_afp_spotlight_query_line, &item_query, "CNID Array");
+                       if (query_length <= 8) {
+                               proto_item_append_text(item_query, " (empty)");
+                       } else {
+                               spotlight_CNID_array(tvb, sub_tree, offset + 8, encoding);
+                       }
+                       count--;
+                       offset += query_length;
+                       break;
+               case SQ_TYPE_DATE:
+                       if ((j = spotlight_date(tvb, pinfo, tree, offset, encoding)) == -1)
+                               return offset;
+                       count -= j;
+                       offset += query_length;
+                       break;
+               default:
+                       proto_tree_add_string(tree, hf_afp_query_type, tvb, offset, query_length, val64_to_str_const(query_type, qtype_string_values, "Unknown"));
+                       count--;
+                       offset += query_length;
+                       break;
+               }
+       }
+
+       return offset;
+}
+
+static const val64_string endian_vals[] = {
+       {0,     "Little Endian" },
+       {1,     "Big Endian" },
+       {0,     NULL } };
+
+static gint
+dissect_spotlight(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
+{
+       guint encoding;
+       gint i;
+       gint offset = 0;
+       guint64 toc_offset;
+       guint64 querylen;
+       gint toc_entries;
+       guint64 toc_entry;
+
+       proto_tree *sub_tree_queries;
+       proto_tree *sub_tree_toc;
+       proto_item *ti;
+
+       if (strncmp(tvb_get_string_enc(wmem_packet_scope(), tvb, offset, 8, ENC_UTF_8|ENC_NA), "md031234", 8) == 0)
+               encoding = ENC_BIG_ENDIAN;
+       else
+               encoding = ENC_LITTLE_ENDIAN;
+       proto_tree_add_uint64(tree, hf_afp_endianness, tvb, offset, 8, (encoding == ENC_BIG_ENDIAN));
+       offset += 8;
+
+       toc_offset = (tvb_get_guint64(tvb, offset, encoding) >> 32) * 8;
+       if (toc_offset < 8) {
+               ti = proto_tree_add_uint64(tree, hf_afp_toc_offset, tvb, offset, 8, toc_offset);
+               expert_add_info_format(pinfo, ti, &ei_afp_toc_offset, "%" G_GINT64_MODIFIER "u < 8 (bogus)", toc_offset);
+               return tvb_captured_length(tvb);
+       }
+       toc_offset -= 8;
+       if (offset + toc_offset + 8 > G_MAXINT) {
+               ti = proto_tree_add_uint64(tree, hf_afp_toc_offset, tvb, offset, 8, toc_offset);
+               expert_add_info_format(pinfo, ti, &ei_afp_toc_offset, "%" G_GINT64_MODIFIER "u > %u (bogus)", toc_offset, G_MAXINT - 8 - offset);
+               return tvb_captured_length(tvb);
+       }
+       querylen = (tvb_get_guint64(tvb, offset, encoding) & 0xffffffff) * 8;
+       if (querylen < 8) {
+               ti = proto_tree_add_uint64(tree, hf_afp_toc_offset, tvb, offset, 8, toc_offset);
+               expert_add_info_format(pinfo, ti, &ei_afp_toc_offset, "%" G_GINT64_MODIFIER "u Bytes, Query length: %" G_GINT64_MODIFIER "u < 8 (bogus)",
+                                   toc_offset, querylen);
+               return tvb_captured_length(tvb);
+       }
+       querylen -= 8;
+       if (querylen > G_MAXINT) {
+               ti = proto_tree_add_uint64(tree, hf_afp_toc_offset, tvb, offset, 8, toc_offset);
+               expert_add_info_format(pinfo, ti, &ei_afp_toc_offset, "%" G_GINT64_MODIFIER "u Bytes, Query length: %" G_GINT64_MODIFIER "u > %u (bogus)",
+                                   toc_offset, querylen, G_MAXINT);
+               return tvb_captured_length(tvb);
+       }
+       proto_tree_add_uint64(tree, hf_afp_toc_offset, tvb, offset, 8, toc_offset);
+       proto_tree_add_uint64(tree, hf_afp_query_len, tvb, offset, 8, querylen);
+       offset += 8;
+
+       toc_entries = (gint)(tvb_get_guint64(tvb, offset + (gint)toc_offset, encoding) & 0xffff);
+
+       sub_tree_queries = proto_tree_add_subtree(tree, tvb, offset, (gint)toc_offset,
+                                               ett_afp_spotlight_queries, NULL,
+                                               "Spotlight RPC data");
+
+       /* Queries */
+       offset = spotlight_dissect_query_loop(tvb, pinfo, sub_tree_queries, offset, SQ_CPX_TYPE_ARRAY, INT_MAX, offset + (gint)toc_offset + 8, encoding);
+
+       /* ToC */
+       sub_tree_toc = proto_tree_add_subtree_format(tree, tvb, offset,
+                                      (gint)querylen - (gint)toc_offset,
+                                      ett_afp_spotlight_toc, &ti,
+                                      "Complex types ToC (%u entries)",
+                                      toc_entries);
+       if (toc_entries < 1) {
+               proto_item_append_text(ti, " (%u < 1 - bogus)", toc_entries);
+               return tvb_captured_length(tvb);
+       }
+       proto_item_append_text(ti, " (%u entries)", toc_entries);
+
+       toc_entries -= 1;
+       proto_tree_add_uint(sub_tree_toc, hf_afp_num_toc_entries, tvb, offset, 2, toc_entries);
+       proto_tree_add_item(sub_tree_toc, hf_afp_unknown16, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
+       proto_tree_add_item(sub_tree_toc, hf_afp_unknown32, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
+
+       offset += 8;
+       for (i = 0; i < toc_entries; i++, offset += 8) {
+               toc_entry = tvb_get_guint64(tvb, offset, encoding);
+               switch((toc_entry & 0xffff0000) >> 16)
+               {
+               case SQ_CPX_TYPE_ARRAY:
+               case SQ_CPX_TYPE_DICT:
+                       proto_tree_add_uint64_format(sub_tree_toc, hf_afp_toc_entry, tvb, offset, 8, toc_entry,
+                                               "%u: count: %" G_GINT64_MODIFIER "u, type: %s, offset: %" G_GINT64_MODIFIER "u",
+                                               i+1, toc_entry >> 32, val64_to_str_const((toc_entry & 0xffff0000) >> 16, cpx_qtype_string_values, "Unknown"),
+                                               (toc_entry & 0xffff) * 8);
+                       break;
+               case SQ_CPX_TYPE_STRING:
+               case SQ_CPX_TYPE_UTF16_STRING:
+                       proto_tree_add_uint64_format(sub_tree_toc, hf_afp_toc_entry, tvb, offset, 8, toc_entry,
+                                               "%u: pad byte count: %" G_GINT64_MODIFIER "x, type: %s, offset: %" G_GINT64_MODIFIER "u",
+                                               i+1, 8 - (toc_entry >> 32), val64_to_str_const((toc_entry & 0xffff0000) >> 16, cpx_qtype_string_values, "Unknown"),
+                                               (toc_entry & 0xffff) * 8);
+                       break;
+               default:
+                       proto_tree_add_uint64_format(sub_tree_toc, hf_afp_toc_entry, tvb, offset, 8, toc_entry,
+                                               "%u: unknown: 0x%08" G_GINT64_MODIFIER "x, type: %s, offset: %" G_GINT64_MODIFIER "u",
+                                               i+1, toc_entry >> 32, val64_to_str_const((toc_entry & 0xffff0000) >> 16, cpx_qtype_string_values, "Unknown"),
+                                               (toc_entry & 0xffff) * 8);
+               }
+       }
+
+       return offset;
+}
+
+static gint
+dissect_query_afp_spotlight(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, afp_request_val *request_val)
+{
+       gint len;
+       tvbuff_t *spotlight_tvb;
+
+       PAD(1);
+       offset = decode_vol(tree, tvb, offset);
+
+       proto_tree_add_item(tree, hf_afp_spotlight_request_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
+       offset += 4;
+
+       proto_tree_add_item(tree, hf_afp_spotlight_request_command, tvb, offset, 4, ENC_BIG_ENDIAN);
+       offset += 4;
+
+       proto_tree_add_item(tree, hf_afp_spotlight_request_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
+       offset += 4;
 
        switch (request_val->spotlight_req_command) {
 
        case SPOTLIGHT_CMD_GET_VOLPATH:
-               tvb_get_ephemeral_stringz(tvb, offset, &len);
-               proto_tree_add_item(tree, hf_afp_spotlight_volpath_client, tvb, offset, len, FALSE);
+               tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_UTF_8|ENC_NA);
+               proto_tree_add_item(tree, hf_afp_spotlight_volpath_client, tvb, offset, len, ENC_UTF_8|ENC_NA);
                offset += len;
                break;
 
@@ -4178,14 +4559,14 @@ dissect_query_afp_spotlight(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *t
                break;
 
        case SPOTLIGHT_CMD_GET_THREE:
-               proto_tree_add_item(tree, hf_afp_spotlight_volflags, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_spotlight_volflags, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
 
-               proto_tree_add_item(tree, hf_afp_spotlight_reqlen, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_spotlight_reqlen, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
 
-               offset = dissect_spotlight(tvb, tree, offset);
-
+               spotlight_tvb = tvb_new_subset_remaining(tvb, offset);
+               offset += call_dissector(spotlight_handle, spotlight_tvb, pinfo, tree);
                break;
        }
        return offset;
@@ -4196,21 +4577,18 @@ static guint16
 decode_acl_list_bitmap(tvbuff_t *tvb, proto_tree *tree, gint offset)
 {
        guint16 bitmap;
+       static const int * bitmaps[] = {
+               &hf_afp_acl_list_bitmap_UUID,
+               &hf_afp_acl_list_bitmap_GRPUUID,
+               &hf_afp_acl_list_bitmap_ACL,
+               &hf_afp_acl_list_bitmap_REMOVEACL,
+               &hf_afp_acl_list_bitmap_Inherit,
+               NULL
+       };
 
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_acl_list_bitmap,
+                                       ett_afp_acl_list_bitmap, bitmaps, ENC_BIG_ENDIAN);
        bitmap = tvb_get_ntohs(tvb, offset);
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
-
-               item = proto_tree_add_item(tree, hf_afp_acl_list_bitmap, tvb, offset, 2,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_acl_list_bitmap);
-               proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_UUID, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_GRPUUID, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_ACL, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_REMOVEACL, tvb, offset, 2,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_Inherit, tvb, offset, 2,FALSE);
-       }
-
        return bitmap;
 }
 
@@ -4221,21 +4599,20 @@ decode_ace_flags_bitmap(tvbuff_t *tvb, proto_tree *tree, gint offset)
 {
        guint32 bitmap;
 
-       bitmap = tvb_get_ntohl(tvb, offset);
-       if (tree) {
-               proto_tree *sub_tree;
-               proto_item *item;
+       static const int * bitmaps[] = {
+               &hf_afp_ace_flags_allow,
+               &hf_afp_ace_flags_deny,
+               &hf_afp_ace_flags_inherited,
+               &hf_afp_ace_flags_fileinherit,
+               &hf_afp_ace_flags_dirinherit,
+               &hf_afp_ace_flags_limitinherit,
+               &hf_afp_ace_flags_onlyinherit,
+               NULL
+       };
 
-               item = proto_tree_add_item(tree, hf_afp_ace_flags, tvb, offset, 4,FALSE);
-               sub_tree = proto_item_add_subtree(item, ett_afp_ace_flags);
-               proto_tree_add_item(sub_tree, hf_afp_ace_flags_allow, tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_ace_flags_deny, tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_ace_flags_inherited, tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_ace_flags_fileinherit, tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_ace_flags_dirinherit, tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_ace_flags_limitinherit, tvb, offset, 4,FALSE);
-               proto_tree_add_item(sub_tree, hf_afp_ace_flags_onlyinherit, tvb, offset, 4,FALSE);
-       }
+       proto_tree_add_bitmask(tree, tvb, offset, hf_afp_ace_flags,
+                                       ett_afp_ace_flags, bitmaps, ENC_BIG_ENDIAN);
+       bitmap = tvb_get_ntohl(tvb, offset);
 
        return bitmap;
 }
@@ -4245,7 +4622,7 @@ decode_kauth_ace(tvbuff_t *tvb, proto_tree *tree, gint offset)
 {
        /* FIXME: preliminary decoding... */
        if (tree) {
-               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16,FALSE);
+               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, ENC_BIG_ENDIAN);
                offset += 16;
 
                decode_ace_flags_bitmap(tvb, tree, offset);
@@ -4260,29 +4637,31 @@ decode_kauth_ace(tvbuff_t *tvb, proto_tree *tree, gint offset)
        return offset;
 }
 
+#define AFP_MAX_ACL_ENTRIES 500 /* Arbitrary. */
 static gint
-decode_kauth_acl(tvbuff_t *tvb, proto_tree *tree, gint offset)
+decode_kauth_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
-       int entries;
-       int i;
-       proto_tree *sub_tree;
-       proto_tree *ace_tree;
+       guint32     num_entries, i;
+       proto_tree *sub_tree, *ace_tree;
        proto_item *item;
 
-       /* FIXME: preliminary decoding... */
-       entries = tvb_get_ntohl(tvb, offset);
-
-       item = proto_tree_add_text(tree, tvb, offset, 4, "ACEs : %d", entries);
+       item = proto_tree_add_item_ret_uint(tree, hf_afp_acl_entrycount,
+                       tvb, offset, 4, ENC_BIG_ENDIAN, &num_entries);
        sub_tree = proto_item_add_subtree(item, ett_afp_ace_entries);
        offset += 4;
 
-       proto_tree_add_item(tree, hf_afp_acl_flags, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_acl_flags, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
-       for (i = 0; i < entries; i++) {
-               item = proto_tree_add_text(sub_tree, tvb, offset, 24, "ACE: %u", i);
-               ace_tree = proto_item_add_subtree(item, ett_afp_ace_entry);
+       if (num_entries > AFP_MAX_ACL_ENTRIES) {
+               expert_add_info_format(pinfo, item, &ei_afp_too_many_acl_entries,
+                               "Too many ACL entries (%u). Stopping dissection.",
+                               num_entries);
+               return offset;
+       }
 
+       for (i = 0; i < num_entries; i++) {
+               ace_tree = proto_tree_add_subtree_format(sub_tree, tvb, offset, 24, ett_afp_ace_entry, NULL, "ACE: %u", i);
                offset = decode_kauth_ace(tvb, ace_tree, offset);
        }
 
@@ -4290,23 +4669,23 @@ decode_kauth_acl(tvbuff_t *tvb, proto_tree *tree, gint offset)
 }
 
 static gint
-decode_uuid_acl(tvbuff_t *tvb, proto_tree *tree, gint offset, guint16 bitmap)
+decode_uuid_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, guint16 bitmap)
 {
        if ((offset & 1))
                PAD(1);
 
        if ((bitmap & kFileSec_UUID)) {
-               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
+               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, ENC_BIG_ENDIAN);
                offset += 16;
        }
 
        if ((bitmap & kFileSec_GRPUUID)) {
-               proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
+               proto_tree_add_item(tree, hf_afp_GRPUUID, tvb, offset, 16, ENC_BIG_ENDIAN);
                offset += 16;
        }
 
        if ((bitmap & kFileSec_ACL)) {
-               offset = decode_kauth_acl(tvb, tree, offset);
+               offset = decode_kauth_acl(tvb, pinfo, tree, offset);
        }
 
        return offset;
@@ -4326,7 +4705,7 @@ dissect_query_afp_set_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
 
        offset = decode_name(tree, pinfo, tvb, offset);
 
-       offset = decode_uuid_acl(tvb, tree, offset, bitmap);
+       offset = decode_uuid_acl(tvb, pinfo, tree, offset, bitmap);
 
        return offset;
 }
@@ -4341,7 +4720,7 @@ dissect_query_afp_get_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
        decode_acl_list_bitmap(tvb, tree, offset);
        offset += 2;
 
-       proto_tree_add_item(tree, hf_afp_max_reply_size32, tvb, offset, 4,FALSE);
+       proto_tree_add_item(tree, hf_afp_max_reply_size32, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;
 
        offset = decode_name(tree, pinfo, tvb, offset);
@@ -4351,56 +4730,366 @@ dissect_query_afp_get_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g
 
 /* -------------------------- */
 static gint
-dissect_reply_afp_get_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
+dissect_reply_afp_get_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
 {
        guint16 bitmap;
 
        bitmap = decode_acl_list_bitmap(tvb, tree, offset);
        offset += 2;
 
-       offset = decode_uuid_acl(tvb, tree, offset, bitmap);
+       offset = decode_uuid_acl(tvb, pinfo, tree, offset, bitmap);
 
        return offset;
 }
 
 /* ************************** */
 static gint
-dissect_reply_afp_spotlight(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset, afp_request_val *request_val)
+dissect_reply_afp_spotlight(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, afp_request_val *request_val)
 {
        gint len;
+       tvbuff_t *spotlight_tvb;
 
        switch (request_val->spotlight_req_command) {
 
        case SPOTLIGHT_CMD_GET_VOLPATH:
-               proto_tree_add_item(tree, hf_afp_spotlight_returncode, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 4, ENC_BIG_ENDIAN);
+               offset += 4;
+
+               proto_tree_add_item(tree, hf_afp_spotlight_reply_reserved, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
 
-               tvb_get_ephemeral_stringz(tvb, offset, &len);;
-               proto_tree_add_item(tree, hf_afp_spotlight_volpath_server, tvb, offset, len, FALSE);
+               tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_UTF_8|ENC_NA);
+               proto_tree_add_item(tree, hf_afp_spotlight_volpath_server, tvb, offset, len, ENC_UTF_8|ENC_NA);
                offset += len;
                break;
 
        case SPOTLIGHT_CMD_GET_VOLID:
-               proto_tree_add_item(tree, hf_afp_spotlight_volflags, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_spotlight_volflags, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
                break;
 
        case SPOTLIGHT_CMD_GET_THREE:
-               proto_tree_add_item(tree, hf_afp_spotlight_returncode, tvb, offset, 4,FALSE);
+               proto_tree_add_item(tree, hf_afp_spotlight_returncode, tvb, offset, 4, ENC_BIG_ENDIAN);
                offset += 4;
 
-               offset = dissect_spotlight(tvb, tree, offset);
+               spotlight_tvb = tvb_new_subset_remaining(tvb, offset);
+               offset += call_dissector(spotlight_handle, spotlight_tvb, pinfo, tree);
                break;
        }
        return offset;
 }
 
+/* -----------------------------
+       from netatalk/etc/afpd/status.c
+*/
+
+/* server flags */
+#define AFPSRVRINFO_COPY         (1<<0)  /* supports copyfile */
+#define AFPSRVRINFO_PASSWD       (1<<1)  /* supports change password */
+#define AFPSRVRINFO_NOSAVEPASSWD (1<<2)  /* don't allow save password */
+#define AFPSRVRINFO_SRVMSGS      (1<<3)  /* supports server messages */
+#define AFPSRVRINFO_SRVSIGNATURE (1<<4)  /* supports server signature */
+#define AFPSRVRINFO_TCPIP        (1<<5)  /* supports tcpip */
+#define AFPSRVRINFO_SRVNOTIFY    (1<<6)  /* supports server notifications */
+#define AFPSRVRINFO_SRVRECONNECT (1<<7)  /* supports reconnect */
+#define AFPSRVRINFO_SRVDIRECTORY (1<<8)  /* supports directory services */
+#define AFPSRVRINFO_SRVUTF8      (1<<9)  /* supports UTF8 names AFP 3.1 */
+#define AFPSRVRINFO_UUID         (1<<10) /* supports UUIDs AFP 3.2 */
+#define AFPSRVRINFO_EXT_SLEEP    (1<<11) /* supports extended sleep, AFP 3.3 */
+#define AFPSRVRINFO_FASTBOZO     (1<<15) /* fast copying */
+
+#define AFPSTATUS_MACHOFF     0
+#define AFPSTATUS_VERSOFF     2
+#define AFPSTATUS_UAMSOFF     4
+#define AFPSTATUS_ICONOFF     6
+#define AFPSTATUS_FLAGOFF     8
+#define AFPSTATUS_PRELEN     10
+#define AFPSTATUS_POSTLEN     4
+#define AFPSTATUS_LEN        (AFPSTATUS_PRELEN + AFPSTATUS_POSTLEN)
+
+#define INET6_ADDRLEN  16
+
+static gint
+dissect_afp_server_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void *data _U_)
+{
+       int             offset = 0;
+       proto_tree      *sub_tree;
+
+       guint16 flag;
+       guint8  server_name_len;
+       guint16 sign_ofs = 0;
+       guint16 adr_ofs = 0;
+       guint16 dir_ofs = 0;
+       guint16 utf_ofs = 0;
+       gint    variable_data_offset;
+       guint8  nbe;
+       guint   len;
+       guint   i;
+
+       static const int * flags[] = {
+               &hf_afp_server_flag_copyfile,
+               &hf_afp_server_flag_passwd,
+               &hf_afp_server_flag_no_save_passwd,
+               &hf_afp_server_flag_srv_msg,
+               &hf_afp_server_flag_srv_sig,
+               &hf_afp_server_flag_tcpip,
+               &hf_afp_server_flag_notify,
+               &hf_afp_server_flag_reconnect,
+               &hf_afp_server_flag_directory,
+               &hf_afp_server_flag_utf8_name,
+               &hf_afp_server_flag_uuid,
+               &hf_afp_server_flag_ext_sleep,
+               &hf_afp_server_flag_fast_copy,
+               NULL
+       };
+
+       tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_afp_status, NULL, "Get Status");
+
+       proto_tree_add_item(tree, hf_afp_machine_offset, tvb, AFPSTATUS_MACHOFF, 2, ENC_BIG_ENDIAN);
+
+       proto_tree_add_item(tree, hf_afp_version_offset, tvb, AFPSTATUS_VERSOFF, 2, ENC_BIG_ENDIAN);
+
+       proto_tree_add_item(tree, hf_afp_uams_offset, tvb, AFPSTATUS_UAMSOFF, 2, ENC_BIG_ENDIAN);
+
+       proto_tree_add_item(tree, hf_afp_icon_offset, tvb, AFPSTATUS_ICONOFF, 2, ENC_BIG_ENDIAN);
+
+       flag = tvb_get_ntohs(tvb, AFPSTATUS_FLAGOFF);
+
+       proto_tree_add_bitmask(tree, tvb, AFPSTATUS_FLAGOFF, hf_afp_server_flag,
+                                       ett_afp_status_server_flag, flags, ENC_BIG_ENDIAN);
+
+       offset = AFPSTATUS_PRELEN;
+       server_name_len = tvb_get_guint8(tvb, offset);
+       proto_tree_add_item(tree, hf_afp_server_name, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
+       offset += 1 + server_name_len;  /* 1 for the length byte */
+
+       if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
+               if ((offset & 1))
+                       offset++;
+               sign_ofs = tvb_get_ntohs(tvb, offset);
+               proto_tree_add_item(tree, hf_afp_signature_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
+               offset += 2;
+       }
+
+       if ((flag & AFPSRVRINFO_TCPIP)) {
+               if ((offset & 1))
+                       offset++;
+               adr_ofs = tvb_get_ntohs(tvb, offset);
+               proto_tree_add_item(tree, hf_afp_network_address_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
+               offset += 2;
+       }
+
+       if ((flag & AFPSRVRINFO_SRVDIRECTORY)) {
+               if ((offset & 1))
+                       offset++;
+               dir_ofs = tvb_get_ntohs(tvb, offset);
+               proto_tree_add_item(tree, hf_afp_directory_services_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
+               offset += 2;
+       }
+
+       if ((flag & AFPSRVRINFO_SRVUTF8)) {
+               if ((offset & 1))
+                       offset++;
+               utf_ofs = tvb_get_ntohs(tvb, offset);
+               proto_tree_add_item(tree, hf_afp_utf8_server_name_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
+               offset += 2;
+       }
+
+       /*
+        * XXX - should also check for overlap between "variable data" fields;
+        * that requires keeping all the offsets and lengths and checking
+        * against all the ones we've dissected so far.
+        *
+        * XXX - should report an error if there's overlap, rather than
+        * just ignoring the field.
+        */
+       variable_data_offset = offset;
+       offset = tvb_get_ntohs(tvb, AFPSTATUS_MACHOFF);
+       if (offset) {
+               if (offset >= variable_data_offset) {
+                       proto_tree_add_item(tree, hf_afp_server_type, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
+               }
+       }
+
+       offset = tvb_get_ntohs(tvb, AFPSTATUS_VERSOFF);
+       if (offset) {
+               if (offset >= variable_data_offset) {
+                       nbe = tvb_get_guint8(tvb, offset);
+                       sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1,
+                                                                       ett_afp_vers, NULL, "Version list: %u", nbe);
+                       offset++;
+                       for (i = 0; i < nbe; i++) {
+                               len = tvb_get_guint8(tvb, offset);
+                               proto_tree_add_item(sub_tree, hf_afp_server_vers, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
+                               offset += len + 1;
+                       }
+               }
+       }
+
+       offset = tvb_get_ntohs(tvb, AFPSTATUS_UAMSOFF);
+       if (offset) {
+               if (offset >= variable_data_offset) {
+                       nbe = tvb_get_guint8(tvb, offset);
+                       sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1,
+                                                                               ett_afp_uams, NULL, "UAMS list: %u", nbe);
+                       offset++;
+                       for (i = 0; i < nbe; i++) {
+                               len = tvb_get_guint8(tvb, offset);
+                               proto_tree_add_item(sub_tree, hf_afp_server_uams, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
+                               offset += len + 1;
+                       }
+               }
+       }
+
+       offset = tvb_get_ntohs(tvb, AFPSTATUS_ICONOFF);
+       if (offset) {
+               if (offset >= variable_data_offset)
+                       proto_tree_add_item(tree, hf_afp_server_icon, tvb, offset, 256, ENC_NA);
+       }
+
+       if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
+               if (sign_ofs >= variable_data_offset)
+                       proto_tree_add_item(tree, hf_afp_server_signature, tvb, sign_ofs, 16, ENC_NA);
+       }
+
+       if ((flag & AFPSRVRINFO_TCPIP)) {
+               if (adr_ofs >= variable_data_offset) {
+                       proto_tree *adr_tree;
+                       unsigned char *tmp;
+                       guint16 net;
+                       guint8  node;
+                       guint16 port;
+
+                       offset = adr_ofs;
+                       nbe = tvb_get_guint8(tvb, offset);
+                       adr_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1,
+                                               ett_afp_server_addr, NULL, "Address list: %d", nbe);
+                       offset++;
+                       for (i = 0; i < nbe; i++) {
+                               guint8 type;
+
+                               len = tvb_get_guint8(tvb, offset);
+                               type =  tvb_get_guint8(tvb, offset +1);
+                               switch (type) {
+                               case 1: /* IP */
+                                       sub_tree = proto_tree_add_subtree_format(adr_tree, tvb, offset, len, ett_afp_server_addr_line, NULL, "IP: %s", tvb_ip_to_str(tvb, offset+2));
+                                       break;
+                               case 2: /* IP + port */
+                                       port = tvb_get_ntohs(tvb, offset+6);
+                                       sub_tree = proto_tree_add_subtree_format(adr_tree, tvb, offset, len,
+                                                                               ett_afp_server_addr_line, NULL,
+                                                                               "IP: %s:%d", tvb_ip_to_str(tvb, offset+2), port);
+                                       break;
+                               case 3: /* DDP, atalk_addr_to_str want host order not network */
+                                       net  = tvb_get_ntohs(tvb, offset+2);
+                                       node = tvb_get_guint8(tvb, offset +4);
+                                       port = tvb_get_guint8(tvb, offset +5);
+                                       sub_tree = proto_tree_add_subtree_format(adr_tree, tvb, offset, len,
+                                                                               ett_afp_server_addr_line, NULL,
+                                                                               "DDP: %u.%u:%u", net, node, port);
+                                       break;
+                               case 4: /* DNS */
+                               case 5: /* SSH tunnel */
+                                       /*
+                                        * The AFP specifcation says of
+                                        * the SSH tunnel type:
+                                        *
+                                        *  IP address (four bytes) with port
+                                        *  number (2 bytes). If this tag is
+                                        *  present and the client is so
+                                        *  configured, the client attempts
+                                        *  to build a Secure Shell (SSH)
+                                        *  tunnel between itself and the
+                                        *  server and tries to connect
+                                        *  through it. This functionality
+                                        *  is deprecated.
+                                        *
+                                        * and, in the only place I've seen
+                                        * it, it was like DNS.
+                                        *
+                                        * So we treat it as DNS.
+                                        *
+                                        * XXX - should we treat it as
+                                        * IP+port if this is transported
+                                        * over ASP rather DSI?  The old
+                                        * ASP code to dissect this
+                                        * dissected it as IP+port.
+                                        */
+                                       if (len > 2) {
+                                               /* XXX - internationalized DNS? */
+                                               tmp = tvb_get_string_enc(wmem_packet_scope(), tvb, offset +2, len -2, ENC_ASCII|ENC_NA);
+                                               sub_tree = proto_tree_add_subtree_format(adr_tree, tvb, offset, len, ett_afp_server_addr_line, NULL, "%s: %s", (type==4)?"DNS":"IP (SSH tunnel)", tmp);
+                                               break;
+                                       }
+                                       else {
+                                               sub_tree = proto_tree_add_subtree(adr_tree, tvb, offset, len,
+                                                                               ett_afp_server_addr_line, NULL, "Malformed DNS address");
+                                       }
+                                       break;
+                               case 6: /* IP6 */
+                                       sub_tree = proto_tree_add_subtree_format(adr_tree, tvb, offset, len, ett_afp_server_addr_line, NULL, "IPv6: %s", tvb_ip6_to_str(tvb, offset+2));
+                                       break;
+                               case 7: /* IP6 + 2bytes port */
+                                       port = tvb_get_ntohs(tvb, offset+ 2+INET6_ADDRLEN);
+                                       sub_tree = proto_tree_add_subtree_format(adr_tree, tvb, offset, len,
+                                                                               ett_afp_server_addr_line, NULL,
+                                                                               "IPv6: %s:%d", tvb_ip6_to_str(tvb, offset+2), port);
+                                       break;
+                               default:
+                                       sub_tree = proto_tree_add_subtree_format(adr_tree, tvb, offset, len, ett_afp_server_addr_line, NULL, "Unknown type: %u", type);
+                                       break;
+                               }
+                               len -= 2;
+                               proto_tree_add_item(sub_tree, hf_afp_server_addr_len, tvb, offset, 1, ENC_BIG_ENDIAN);
+                               offset++;
+                               proto_tree_add_item(sub_tree, hf_afp_server_addr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
+                               offset++;
+                               proto_tree_add_item(sub_tree, hf_afp_server_addr_value,tvb, offset, len, ENC_NA);
+                               offset += len;
+                       }
+               }
+       }
+
+       if ((flag & AFPSRVRINFO_SRVDIRECTORY)) {
+               if (dir_ofs >= variable_data_offset) {
+                       offset = dir_ofs;
+                       nbe = tvb_get_guint8(tvb, offset);
+                       sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, 1,
+                                               ett_afp_directory, NULL, "Directory services list: %d", nbe);
+                       offset++;
+                       for (i = 0; i < nbe; i++) {
+                               len = tvb_get_guint8(tvb, offset);
+                               proto_tree_add_item(sub_tree, hf_afp_server_directory, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
+                               offset += len + 1;
+                       }
+               }
+       }
+
+       if ((flag & AFPSRVRINFO_SRVUTF8)) {
+               if (utf_ofs >= variable_data_offset) {
+                       guint16 ulen;
+                       char *tmp;
+
+                       offset = utf_ofs;
+                       ulen = tvb_get_ntohs(tvb, offset);
+                       tmp = tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 2, ulen, ENC_UTF_8|ENC_NA);
+                       sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, ulen + 2,
+                                               ett_afp_utf8_name, NULL, "UTF-8 server name: %s", tmp);
+                       proto_tree_add_uint(sub_tree, hf_afp_utf8_server_name_len, tvb, offset, 2, ulen);
+                       offset += 2;
+                       proto_tree_add_string(sub_tree, hf_afp_utf8_server_name, tvb, offset, ulen, tmp);
+                       offset += ulen;
+               }
+       }
+
+       return offset;
+}
 
 /* ************************** */
-static void
-dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+static int
+dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
 {
-       struct aspinfo  *aspinfo = pinfo->private_data;
+       struct aspinfo  *aspinfo = (struct aspinfo*)data;
        proto_tree      *afp_tree = NULL;
        proto_item      *ti;
        conversation_t  *conversation;
@@ -4409,26 +5098,30 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        afp_request_val *request_val;
        guint8          afp_command;
        nstime_t        delta_ts;
+       int             len;
 
-       int     len =  tvb_reported_length(tvb);
+       /* Reject the packet if data is NULL */
+       if (data == NULL)
+               return 0;
 
+       len = tvb_reported_length(tvb);
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "AFP");
        col_clear(pinfo->cinfo, COL_INFO);
 
        conversation = find_or_create_conversation(pinfo);
 
-       request_key.conversation = conversation->index;
+       request_key.conversation = conversation->conv_index;
        request_key.seq = aspinfo->seq;
 
-       request_val = (afp_request_val *) g_hash_table_lookup(
+       request_val = (afp_request_val *) wmem_map_lookup(
                                                                afp_request_hash, &request_key);
 
-       if (!request_val && !aspinfo->reply)  {
+       if (!request_val && !aspinfo->reply) {
                afp_command = tvb_get_guint8(tvb, offset);
-               new_request_key = se_alloc(sizeof(afp_request_key));
+               new_request_key = wmem_new(wmem_file_scope(), afp_request_key);
                *new_request_key = request_key;
 
-               request_val = se_alloc(sizeof(afp_request_val));
+               request_val = wmem_new(wmem_file_scope(), afp_request_val);
                request_val->command = afp_command;
 
                if (afp_command == AFP_SPOTLIGHTRPC)
@@ -4436,17 +5129,17 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                else
                        request_val->spotlight_req_command = -1;
 
-               request_val->frame_req = pinfo->fd->num;
+               request_val->frame_req = pinfo->num;
                request_val->frame_res = 0;
-               request_val->req_time=pinfo->fd->abs_ts;
+               request_val->req_time=pinfo->abs_ts;
 
-               g_hash_table_insert(afp_request_hash, new_request_key,
+               wmem_map_insert(afp_request_hash, new_request_key,
                                                                request_val);
        }
 
        if (!request_val) {     /* missing request */
                col_set_str(pinfo->cinfo, COL_INFO, "[Reply without query?]");
-               return;
+               return tvb_captured_length(tvb);
        }
 
        afp_command = request_val->command;
@@ -4460,16 +5153,13 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                                "Unknown error (%u)"), aspinfo->code);
        }
 
-       if (tree)
-       {
-               ti = proto_tree_add_item(tree, proto_afp, tvb, offset, -1,FALSE);
-               afp_tree = proto_item_add_subtree(ti, ett_afp);
-       }
+       ti = proto_tree_add_item(tree, proto_afp, tvb, offset, -1, ENC_NA);
+       afp_tree = proto_item_add_subtree(ti, ett_afp);
+
        if (!aspinfo->reply)  {
 
                ti = proto_tree_add_uint(afp_tree, hf_afp_command, tvb,offset, 1, afp_command);
-               if (afp_command != tvb_get_guint8(tvb, offset))
-               {
+               if (afp_command != tvb_get_guint8(tvb, offset)) {
                        /* we have the same conversation for different connections eg:
                         * ip1:2048 --> ip2:548
                         * ip1:2048 --> ip2:548 <RST>
@@ -4478,9 +5168,8 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                         */
                        col_set_str(pinfo->cinfo, COL_INFO,
                                    "[Error!IP port reused, you need to split the capture file]");
-                       expert_add_info_format(pinfo, ti, PI_SEQUENCE, PI_WARN,
-                                              "IP port reused, you need to split the capture file");
-                       return;
+                       expert_add_info(pinfo, ti, &ei_afp_ip_port_reused);
+                       return tvb_captured_length(tvb);
                }
 
                /*
@@ -4495,139 +5184,195 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                }
 
                offset++;
-               switch(afp_command) {
+               switch (afp_command) {
                case AFP_BYTELOCK:
-                       offset = dissect_query_afp_byte_lock(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_byte_lock(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_BYTELOCK_EXT:
-                       offset = dissect_query_afp_byte_lock_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_byte_lock_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_OPENDT:        /* same as close vol */
                case AFP_FLUSH:
                case AFP_CLOSEVOL:
-                       offset = dissect_query_afp_with_vol_id(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_with_vol_id(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CLOSEDIR:
-                       /* offset = dissect_query_afp_close_dir(tvb, pinfo, afp_tree, offset);break; */
+                       /* offset = dissect_query_afp_close_dir(tvb, pinfo, afp_tree, offset); */
                        break;
                case AFP_CLOSEDT:
-                       offset = dissect_query_afp_close_dt(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_close_dt(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_FLUSHFORK: /* same packet as closefork */
                case AFP_SYNCFORK:
                case AFP_CLOSEFORK:
-                       offset = dissect_query_afp_with_fork(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_with_fork(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_COPYFILE:
-                       offset = dissect_query_afp_copy_file(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_copy_file(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CREATEFILE:
-                       offset = dissect_query_afp_create_file(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_create_file(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_DISCTOLDSESS:
-                       offset = dissect_query_afp_disconnect_old_session(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_disconnect_old_session(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ENUMERATE_EXT2:
-                       offset = dissect_query_afp_enumerate_ext2(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_enumerate_ext2(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ENUMERATE_EXT:
                case AFP_ENUMERATE:
-                       offset = dissect_query_afp_enumerate(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_enumerate(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETFORKPARAM:
-                       offset = dissect_query_afp_get_fork_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_fork_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETSESSTOKEN:
-                       offset = dissect_query_afp_get_session_token(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_session_token(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETUSERINFO:
-                       offset = dissect_query_afp_get_user_info(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_user_info(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETSRVINFO:
-                       /* offset = dissect_query_afp_get_server_info(tvb, pinfo, afp_tree, offset);break; */
+                       /* offset = dissect_query_afp_get_server_info(tvb, pinfo, afp_tree, offset); */
+                       break;
                case AFP_GETSRVPARAM:
                        break;                                  /* no parameters */
                case AFP_GETVOLPARAM:
-                       offset = dissect_query_afp_get_vol_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_vol_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_LOGIN_EXT:
-                       offset = dissect_query_afp_login_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_login_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_LOGIN:
-                       offset = dissect_query_afp_login(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_login(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_LOGINCONT:
                case AFP_LOGOUT:
                        break;
                case AFP_MAPID:
-                       offset = dissect_query_afp_map_id(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_map_id(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_MAPNAME:
-                       offset = dissect_query_afp_map_name(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_map_name(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_MOVE:
-                       offset = dissect_query_afp_move(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_move(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_OPENVOL:
-                       offset = dissect_query_afp_open_vol(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_open_vol(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_OPENDIR:
                        break;
                case AFP_OPENFORK:
-                       offset = dissect_query_afp_open_fork(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_open_fork(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_READ:
-                       offset = dissect_query_afp_read(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_read(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_READ_EXT:
-                       offset = dissect_query_afp_read_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_read_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_RENAME:
-                       offset = dissect_query_afp_rename(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_rename(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SETDIRPARAM:
-                       offset = dissect_query_afp_set_dir_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_set_dir_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SETFILEPARAM:
-                       offset = dissect_query_afp_set_file_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_set_file_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SETFORKPARAM:
-                       offset = dissect_query_afp_set_fork_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_set_fork_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SETVOLPARAM:
-                       offset = dissect_query_afp_set_vol_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_set_vol_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_WRITE:
-                       offset = dissect_query_afp_write(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_write(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_WRITE_EXT:
-                       offset = dissect_query_afp_write_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_write_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETFLDRPARAM:
-                       offset = dissect_query_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SETFLDRPARAM:
-                       offset = dissect_query_afp_set_fldr_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_set_fldr_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CHANGEPW:
                        break;
                case AFP_GETSRVRMSG:
-                       offset = dissect_query_afp_get_server_message(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_server_message(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_DELETE:        /* same as create_id */
                case AFP_CREATEDIR:
                case AFP_CREATEID:
-                       offset = dissect_query_afp_create_id(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_create_id(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_DELETEID:
-                       offset = dissect_query_afp_delete_id(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_delete_id(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_RESOLVEID:
-                       offset = dissect_query_afp_resolve_id(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_resolve_id(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_EXCHANGEFILE:
-                       offset = dissect_query_afp_exchange_file(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_exchange_file(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CATSEARCH_EXT:
-                       offset = dissect_query_afp_cat_search_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_cat_search_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CATSEARCH:
-                       offset = dissect_query_afp_cat_search(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_cat_search(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETICON:
-                       offset = dissect_query_afp_get_icon(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_icon(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GTICNINFO:
-                       offset = dissect_query_afp_get_icon_info(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_icon_info(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ADDAPPL:
-                       offset = dissect_query_afp_add_appl(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_add_appl(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_RMVAPPL:
-                       offset = dissect_query_afp_rmv_appl(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_rmv_appl(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETAPPL:
-                       offset = dissect_query_afp_get_appl(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_appl(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ADDCMT:
-                       offset = dissect_query_afp_add_cmt(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_add_cmt(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_RMVCMT: /* same as get_cmt */
                case AFP_GETCMT:
-                       offset = dissect_query_afp_get_cmt(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_cmt(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ADDICON:
-                       offset = dissect_query_afp_add_icon(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_add_icon(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETEXTATTR:
-                       offset = dissect_query_afp_get_ext_attr(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_ext_attr(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SETEXTATTR:
-                       offset = dissect_query_afp_set_ext_attr(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_set_ext_attr(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_LISTEXTATTR:
-                       offset = dissect_query_afp_list_ext_attrs(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_list_ext_attrs(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_REMOVEATTR:
-                       offset = dissect_query_afp_remove_ext_attr(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_remove_ext_attr(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETACL:
-                       offset = dissect_query_afp_get_acl(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_get_acl(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SETACL:
-                       offset = dissect_query_afp_set_acl(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_set_acl(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ACCESS:
-                       offset = dissect_query_afp_access(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_access(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SYNCDIR:
-                       offset = dissect_query_afp_with_did(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_query_afp_with_did(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SPOTLIGHTRPC:
                        offset = dissect_query_afp_spotlight(tvb, pinfo, afp_tree, offset, request_val);
                        break;
@@ -4644,7 +5389,7 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                        ti = proto_tree_add_uint(afp_tree, hf_afp_response_to,
                            tvb, 0, 0, request_val->frame_req);
                        PROTO_ITEM_SET_GENERATED(ti);
-                       nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &request_val->req_time);
+                       nstime_delta(&delta_ts, &pinfo->abs_ts, &request_val->req_time);
                        ti = proto_tree_add_time(afp_tree, hf_afp_time, tvb,
                            0, 0, &delta_ts);
                        PROTO_ITEM_SET_GENERATED(ti);
@@ -4654,7 +5399,7 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                 * Set "frame_res" if it's not already known.
                 */
                if (request_val->frame_res == 0)
-                       request_val->frame_res = pinfo->fd->num;
+                       request_val->frame_res = pinfo->num;
 
                /*
                 * Tap the packet before the dissectors are called so we
@@ -4666,87 +5411,108 @@ dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
                if (!len) {
                        /* for some calls if the reply is an error there's no data
                        */
-                       return;
+                       return tvb_captured_length(tvb);
                }
 
-               switch(afp_command) {
+               switch (afp_command) {
                case AFP_BYTELOCK:
-                       offset = dissect_reply_afp_byte_lock(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_byte_lock(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_BYTELOCK_EXT:
-                       offset = dissect_reply_afp_byte_lock_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_byte_lock_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ENUMERATE_EXT2:
                case AFP_ENUMERATE_EXT:
-                       offset = dissect_reply_afp_enumerate_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_enumerate_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_ENUMERATE:
-                       offset = dissect_reply_afp_enumerate(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_enumerate(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_OPENVOL:
-                       offset = dissect_reply_afp_open_vol(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_open_vol(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_OPENFORK:
-                       offset = dissect_reply_afp_open_fork(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_open_fork(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_RESOLVEID:
                case AFP_GETFORKPARAM:
-                       offset =dissect_reply_afp_get_fork_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_fork_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETUSERINFO:
-                       offset = dissect_reply_afp_get_user_info(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_user_info(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETSRVPARAM:
-                       offset = dissect_reply_afp_get_server_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_server_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETSRVRMSG:
-                       offset = dissect_reply_afp_get_server_message(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_server_message(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CREATEDIR:
-                       offset = dissect_reply_afp_create_dir(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_create_dir(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_MAPID:
-                       offset = dissect_reply_afp_map_id(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_map_id(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_MAPNAME:
-                       offset = dissect_reply_afp_map_name(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_map_name(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_MOVE:          /* same as create_id */
                case AFP_CREATEID:
-                       offset = dissect_reply_afp_create_id(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_create_id(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETSESSTOKEN:
-                       offset = dissect_reply_afp_get_session_token(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_session_token(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETVOLPARAM:
-                       offset = dissect_reply_afp_get_vol_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_vol_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETFLDRPARAM:
-                       offset = dissect_reply_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_OPENDT:
-                       offset = dissect_reply_afp_open_dt(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_open_dt(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CATSEARCH_EXT:
-                       offset = dissect_reply_afp_cat_search_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_cat_search_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_CATSEARCH:
-                       offset = dissect_reply_afp_cat_search(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_cat_search(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GTICNINFO:
-                       offset = dissect_reply_afp_get_icon_info(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_icon_info(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETAPPL:
-                       offset = dissect_reply_afp_get_appl(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_appl(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETCMT:
-                       offset = dissect_reply_afp_get_cmt(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_cmt(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_WRITE:
-                       offset = dissect_reply_afp_write(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_write(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_WRITE_EXT:
-                       offset = dissect_reply_afp_write_ext(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_write_ext(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETEXTATTR:
-                       offset = dissect_reply_afp_get_ext_attr(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_ext_attr(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_LISTEXTATTR:
-                       offset = dissect_reply_afp_list_ext_attrs(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_list_ext_attrs(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_GETACL:
-                       offset = dissect_reply_afp_get_acl(tvb, pinfo, afp_tree, offset);break;
+                       offset = dissect_reply_afp_get_acl(tvb, pinfo, afp_tree, offset);
+                       break;
                case AFP_SPOTLIGHTRPC:
-                       offset = dissect_reply_afp_spotlight(tvb, pinfo, afp_tree, offset, request_val);break;
+                       offset = dissect_reply_afp_spotlight(tvb, pinfo, afp_tree, offset, request_val);
+                       break;
                }
        }
        if (offset < len) {
-               call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset),
+               call_data_dissector(tvb_new_subset_remaining(tvb, offset),
                    pinfo, afp_tree);
        }
-}
-
-static void afp_reinit( void)
-{
-
-       if (afp_request_hash)
-               g_hash_table_destroy(afp_request_hash);
-
-       afp_request_hash = g_hash_table_new(afp_hash, afp_equal);
 
+       return tvb_captured_length(tvb);
 }
 
 void
@@ -4764,8 +5530,8 @@ proto_register_afp(void)
                    FT_NONE,   BASE_NONE, NULL, 0,
                    "Pad Byte", HFILL }},
 
-               { &hf_afp_AFPVersion,
-                 { "AFP Version",  "afp.AFPVersion",
+               { &hf_afp_Version,
+                 { "AFP Version",  "afp.Version",
                    FT_UINT_STRING, BASE_NONE, NULL, 0x0,
                    "Client AFP version", HFILL }},
 
@@ -5037,6 +5803,11 @@ proto_register_afp(void)
                    FT_BOOLEAN, 16, NULL,  kFPUnixPrivsBit,
                    "Return UNIX privileges if directory", HFILL }},
 
+               { &hf_afp_dir_attribute,
+                 { "Directory Attributes",         "afp.dir_attribute",
+                   FT_UINT16, BASE_HEX, NULL,  0x0,
+                   NULL, HFILL }},
+
                { &hf_afp_dir_attribute_Invisible,
                  { "Invisible",         "afp.dir_attribute.invisible",
                    FT_BOOLEAN, 16, NULL,  kFPInvisibleBit,
@@ -5077,11 +5848,6 @@ proto_register_afp(void)
                    FT_BOOLEAN, 16, NULL,  kFPDeleteInhibitBit,
                    NULL, HFILL }},
 
-               { &hf_afp_dir_attribute_SetClear,
-                 { "Set",         "afp.dir_attribute.set_clear",
-                   FT_BOOLEAN, 16, NULL,  kFPSetClearBit,
-                   "Clear/set attribute", HFILL }},
-
                { &hf_afp_file_bitmap_Attributes,
                  { "Attributes",         "afp.file_bitmap.attributes",
                    FT_BOOLEAN, 16, NULL,  kFPAttributeBit,
@@ -5163,6 +5929,11 @@ proto_register_afp(void)
                    "Return UNIX privileges if file", HFILL }},
 
                /* ---------- */
+               { &hf_afp_file_attribute,
+                 { "File Attributes",         "afp.file_attribute",
+                   FT_UINT16, BASE_HEX, NULL,  0x0,
+                   NULL, HFILL }},
+
                { &hf_afp_file_attribute_Invisible,
                  { "Invisible",         "afp.file_attribute.invisible",
                    FT_BOOLEAN, 16, NULL,  kFPInvisibleBit,
@@ -5224,6 +5995,11 @@ proto_register_afp(void)
                    FT_UINT_STRING, BASE_NONE, NULL, 0x0,
                    "Volume name", HFILL }},
 
+               { &hf_afp_vol_flag,
+                 { "Flags",         "afp.vol_flag",
+                   FT_UINT8, BASE_HEX, NULL,  0x0,
+                   NULL, HFILL }},
+
                { &hf_afp_vol_flag_passwd,
                  { "Password",         "afp.vol_flag_passwd",
                    FT_BOOLEAN, 8, NULL,  128,
@@ -5504,11 +6280,6 @@ proto_register_afp(void)
                    FT_BOOLEAN, 32, NULL,  0x80000000,
                    NULL, HFILL }},
 
-               { &hf_afp_request_bitmap,
-                 { "Request bitmap",         "afp.request_bitmap",
-                   FT_UINT32, BASE_HEX, NULL, 0x0,
-                   NULL, HFILL }},
-
                { &hf_afp_struct_size,
                  { "Struct size",         "afp.struct_size",
                    FT_UINT8, BASE_DEC, NULL,0,
@@ -5559,11 +6330,6 @@ proto_register_afp(void)
                    FT_UINT32, BASE_DEC, NULL, 0x0,
                    "Offset of the last byte written", HFILL }},
 
-               { &hf_afp_actual_count,
-                 { "Count",         "afp.actual_count",
-                   FT_INT32, BASE_DEC, NULL, 0x0,
-                   "Number of bytes returned by read/write", HFILL }},
-
                { &hf_afp_ofork_len,
                  { "New length",         "afp.ofork_len",
                    FT_INT32, BASE_DEC, NULL, 0x0,
@@ -5629,11 +6395,21 @@ proto_register_afp(void)
                    FT_UINT_STRING, BASE_NONE, NULL, 0x0,
                    "File/folder comment", HFILL }},
 
+               /*
+                * XXX - should this be a type that's displayed as
+                * text if it's all printable ASCII and hex otherwise,
+                * or something such as that?
+                */
                { &hf_afp_file_creator,
                  { "File creator",         "afp.file_creator",
                    FT_STRING, BASE_NONE, NULL, 0x0,
                    NULL, HFILL }},
 
+               /*
+                * XXX - should this be a type that's displayed as
+                * text if it's all printable ASCII and hex otherwise,
+                * or something such as that?
+                */
                { &hf_afp_file_type,
                  { "File type",         "afp.file_type",
                    FT_STRING, BASE_NONE, NULL, 0x0,
@@ -5792,7 +6568,7 @@ proto_register_afp(void)
                { &hf_afp_cat_position,
                  { "Position",         "afp.cat_position",
                    FT_BYTES, BASE_NONE, NULL, 0x0,
-                   "Reserved", HFILL }},
+                   "Catalog position", HFILL }},
 
                { &hf_afp_map_name_type,
                  { "Type",      "afp.map_name_type",
@@ -5893,12 +6669,12 @@ proto_register_afp(void)
 
                { &hf_afp_UUID,
                  { "UUID",         "afp.uuid",
-                   FT_BYTES, BASE_NONE, NULL, 0x0,
+                   FT_GUID, BASE_NONE, NULL, 0x0,
                    NULL, HFILL }},
 
                { &hf_afp_GRPUUID,
                  { "GRPUUID",         "afp.grpuuid",
-                   FT_BYTES, BASE_NONE, NULL, 0x0,
+                   FT_GUID, BASE_NONE, NULL, 0x0,
                    "Group UUID", HFILL }},
 
                { &hf_afp_user_bitmap,
@@ -5931,13 +6707,17 @@ proto_register_afp(void)
                    FT_UINT16, BASE_HEX, NULL, 0,
                    "Message bitmap", HFILL }},
 
+               /*
+                * XXX - in the reply, this indicates whether the message
+                * is a server message or a login message.
+                */
                { &hf_afp_message_bitmap_REQ,
                  { "Request message",         "afp.message_bitmap.requested",
                    FT_BOOLEAN, 16, NULL, 0x01,
                    "Message Requested", HFILL }},
 
                { &hf_afp_message_bitmap_UTF,
-                 { "Message is UTF8",         "afp.message_bitmap.utf8",
+                 { "Message is UTF-8",         "afp.message_bitmap.utf8",
                    FT_BOOLEAN, 16, NULL, 0x02,
                    NULL, HFILL }},
 
@@ -6048,7 +6828,7 @@ proto_register_afp(void)
                    "Inherit ACL", HFILL }},
 
                { &hf_afp_acl_entrycount,
-                 { "Count",         "afp.acl_entrycount",
+                 { "ACEs count",         "afp.acl_entrycount",
                    FT_UINT32, BASE_HEX, NULL, 0,
                    "Number of ACL entries", HFILL }},
 
@@ -6057,16 +6837,6 @@ proto_register_afp(void)
                    FT_UINT32, BASE_HEX, NULL, 0,
                    NULL, HFILL }},
 
-               { &hf_afp_ace_applicable,
-                 { "ACE",         "afp.ace_applicable",
-                   FT_BYTES, BASE_NONE, NULL, 0x0,
-                   "ACE applicable", HFILL }},
-
-               { &hf_afp_ace_rights,
-                 { "Rights",         "afp.ace_rights",
-                   FT_UINT32, BASE_HEX, NULL, 0,
-                   "ACE flags", HFILL }},
-
                { &hf_afp_acl_access_bitmap,
                  { "Bitmap",         "afp.acl_access_bitmap",
                    FT_UINT32, BASE_HEX, NULL, 0,
@@ -6217,6 +6987,11 @@ proto_register_afp(void)
                    FT_UINT32, BASE_HEX, NULL, 0x0,
                    "Spotlight RPC Padding", HFILL }},
 
+               { &hf_afp_spotlight_reply_reserved,
+                 { "Reserved",               "afp.spotlight.reserved",
+                   FT_UINT32, BASE_HEX, NULL, 0x0,
+                   "Spotlight RPC Padding", HFILL }},
+
                { &hf_afp_spotlight_volpath_client,
                  { "Client's volume path",               "afp.spotlight.volpath_client",
                    FT_STRING, BASE_NONE, NULL, 0x0,
@@ -6242,20 +7017,164 @@ proto_register_afp(void)
                    FT_UINT32, BASE_DEC, NULL, 0x0,
                    NULL, HFILL }},
 
-               { &hf_afp_spotlight_toc_query_end,
-                 { "End marker",               "afp.spotlight.query_end",
-                   FT_UINT32, BASE_HEX, NULL, 0x0,
+               { &hf_afp_spotlight_uuid,
+                 { "UUID",               "afp.spotlight.uuid",
+                   FT_GUID, BASE_NONE, NULL, 0x0,
                    NULL, HFILL }},
 
-               { &hf_afp_spotlight_mdstring,
-                 { "mdquery string",               "afp.spotlight.mds",
-                   FT_STRINGZ, BASE_NONE, NULL, 0x0,
+               { &hf_afp_spotlight_date,
+                 { "Date",               "afp.spotlight.date",
+                   FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0x0,
                    NULL, HFILL }},
 
                { &hf_afp_unknown,
-                 { "Unknown parameter",         "afp.unknown",
+                 { "Unknown parameter",         "afp.unknown_bytes",
                    FT_BYTES, BASE_NONE, NULL, 0x0,
                    NULL, HFILL }},
+
+               /* Status stuff from ASP or DSI */
+               { &hf_afp_utf8_server_name_len,
+                 { "UTF-8 server name length",          "afp.utf8_server_name_len",
+                   FT_UINT16, BASE_DEC, NULL, 0x0,
+                   NULL, HFILL }},
+
+               { &hf_afp_utf8_server_name,
+                 { "UTF-8 server name",         "afp.utf8_server_name",
+                   FT_STRING, STR_UNICODE, NULL, 0x0,
+                   NULL, HFILL }},
+
+               { &hf_afp_server_name,
+                 { "Server name",         "afp.server_name",
+                   FT_UINT_STRING, STR_UNICODE, NULL, 0x0,
+                   NULL, HFILL }},
+
+               { &hf_afp_server_type,
+                 { "Server type",         "afp.server_type",
+                   FT_UINT_STRING, STR_UNICODE, NULL, 0x0,
+                   NULL, HFILL }},
+
+               { &hf_afp_server_vers,
+                 { "AFP version",         "afp.server_vers",
+                   FT_UINT_STRING, STR_UNICODE, NULL, 0x0,
+                   NULL, HFILL }},
+
+               { &hf_afp_server_uams,
+                 { "UAM",         "afp.server_uams",
+                   FT_UINT_STRING, STR_UNICODE, NULL, 0x0,
+                   NULL, HFILL }},
+
+               { &hf_afp_server_icon,
+                 { "Icon bitmap",         "afp.server_icon",
+                   FT_BYTES, BASE_NONE, NULL, 0x0,
+                   "Server icon bitmap", HFILL }},
+
+               { &hf_afp_server_directory,
+                 { "Directory service",         "afp.server_directory",
+                   FT_UINT_STRING, STR_UNICODE, NULL, 0x0,
+                   "Server directory service", HFILL }},
+
+               { &hf_afp_server_signature,
+                 { "Server signature",         "afp.server_signature",
+                   FT_BYTES, BASE_NONE, NULL, 0x0,
+                   NULL, HFILL }},
+
+               { &hf_afp_server_flag,
+                 { "Flag",         "afp.server_flag",
+                   FT_UINT16, BASE_HEX, NULL, 0x0,
+                   "Server capabilities flag", HFILL }},
+               { &hf_afp_server_flag_copyfile,
+                 { "Support copyfile",      "afp.server_flag.copyfile",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_COPY,
+                   "Server support copyfile", HFILL }},
+               { &hf_afp_server_flag_passwd,
+                 { "Support change password",      "afp.server_flag.passwd",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_PASSWD,
+                   "Server support change password", HFILL }},
+               { &hf_afp_server_flag_no_save_passwd,
+                 { "Don't allow save password",      "afp.server_flag.no_save_passwd",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_NOSAVEPASSWD,
+                   NULL, HFILL }},
+               { &hf_afp_server_flag_srv_msg,
+                 { "Support server message",      "afp.server_flag.srv_msg",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVMSGS,
+                   NULL, HFILL }},
+               { &hf_afp_server_flag_srv_sig,
+                 { "Support server signature",      "afp.server_flag.srv_sig",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVSIGNATURE,
+                   NULL, HFILL }},
+               { &hf_afp_server_flag_tcpip,
+                 { "Support TCP/IP",      "afp.server_flag.tcpip",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_TCPIP,
+                   "Server support TCP/IP", HFILL }},
+               { &hf_afp_server_flag_notify,
+                 { "Support server notifications",      "afp.server_flag.notify",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVNOTIFY,
+                   "Server support notifications", HFILL }},
+               { &hf_afp_server_flag_reconnect,
+                 { "Support server reconnect",      "afp.server_flag.reconnect",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVRECONNECT,
+                   "Server support reconnect", HFILL }},
+               { &hf_afp_server_flag_directory,
+                 { "Support directory services",      "afp.server_flag.directory",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVDIRECTORY,
+                   "Server support directory services", HFILL }},
+               { &hf_afp_server_flag_utf8_name,
+                 { "Support UTF-8 server name",      "afp.server_flag.utf8_name",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVUTF8,
+                   "Server support UTF-8 server name", HFILL }},
+               { &hf_afp_server_flag_uuid,
+                 { "Support UUIDs",      "afp.server_flag.uuids",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_UUID,
+                   "Server supports UUIDs", HFILL }},
+               { &hf_afp_server_flag_ext_sleep,
+                 { "Support extended sleep",      "afp.server_flag.ext_sleep",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_EXT_SLEEP,
+                   "Server supports extended sleep", HFILL }},
+               { &hf_afp_server_flag_fast_copy,
+                 { "Support fast copy",      "afp.server_flag.fast_copy",
+                   FT_BOOLEAN, 16, NULL, AFPSRVRINFO_FASTBOZO,
+                   "Server support fast copy", HFILL }},
+
+
+               { &hf_afp_server_addr_len,
+                 { "Length",          "afp.server_addr.len",
+                   FT_UINT8, BASE_DEC, NULL, 0x0,
+                   "Address length.", HFILL }},
+
+               { &hf_afp_server_addr_type,
+                 { "Type",          "afp.server_addr.type",
+                   FT_UINT8, BASE_DEC|BASE_EXT_STRING, &afp_server_addr_type_vals_ext, 0x0,
+                   "Address type.", HFILL }},
+
+               { &hf_afp_server_addr_value,
+                 { "Value",          "afp.server_addr.value",
+                   FT_BYTES, BASE_NONE, NULL, 0x0,
+                   "Address value", HFILL }},
+
+               /* Generated from convert_proto_tree_add_text.pl */
+               { &hf_afp_int64, { "int64", "afp.int64", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_float, { "float", "afp.float", FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_unknown16, { "unknown1", "afp.unknown", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_unknown32, { "unknown2", "afp.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_cnid, { "CNID", "afp.cnid", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_null, { "null", "afp.null", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_string, { "string", "afp.string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_utf_16_string, { "utf-16 string", "afp.utf_16_string", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_bool, { "bool", "afp.bool", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_query_type, { "type", "afp.query_type", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_toc_offset, { "ToC Offset", "afp.toc_offset", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_toc_entry, { "ToC Entry", "afp.toc_entry", FT_UINT64, BASE_HEX, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_endianness, { "Endianness", "afp.endianness", FT_UINT64, BASE_HEX | BASE_VAL64_STRING, VALS64(endian_vals), 0x0, NULL, HFILL }},
+               { &hf_afp_query_len, { "Query length", "afp.query_len", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_num_toc_entries, { "Number of entries", "afp.num_toc_entries", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_machine_offset, { "Machine offset", "afp.machine_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_version_offset, { "Version offset", "afp.version_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_uams_offset, { "UAMS offset", "afp.uams_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_icon_offset, { "Icon offset", "afp.icon_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_signature_offset, { "Signature offset", "afp.signature_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_network_address_offset, { "Network address offset", "afp.network_address_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_directory_services_offset, { "Directory services offset", "afp.directory_services_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
+               { &hf_afp_utf8_server_name_offset, { "UTF-8 server name offset", "afp.utf8_server_name_offset", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
        };
 
        static gint *ett[] = {
@@ -6293,26 +7212,66 @@ proto_register_afp(void)
                &ett_afp_spotlight_query_line,
                &ett_afp_spotlight_query,
                &ett_afp_spotlight_data,
-               &ett_afp_spotlight_toc
+               &ett_afp_spotlight_toc,
+
+               /* Status stuff from ASP or DSI */
+               &ett_afp_status,
+               &ett_afp_status_server_flag,
+               &ett_afp_vers,
+               &ett_afp_uams,
+               &ett_afp_server_addr,
+               &ett_afp_server_addr_line,
+               &ett_afp_directory,
+               &ett_afp_utf8_name
        };
 
+       static ei_register_info ei[] = {
+               { &ei_afp_subquery_count_over_safety_limit, { "afp.subquery_count_over_safety_limit", PI_MALFORMED, PI_ERROR, "Subquery count > safety limit ", EXPFILL }},
+               { &ei_afp_subquery_count_over_query_count, { "afp.subquery_count_over_query_count", PI_MALFORMED, PI_ERROR, "Subquery count > query count", EXPFILL }},
+               { &ei_afp_abnormal_num_subqueries, { "afp.abnormal_num_subqueries", PI_PROTOCOL, PI_WARN, "Abnormal number of subqueries", EXPFILL }},
+               { &ei_afp_too_many_acl_entries, { "afp.too_many_acl_entries", PI_UNDECODED, PI_WARN, "Too many ACL entries", EXPFILL }},
+               { &ei_afp_ip_port_reused, { "afp.ip_port_reused", PI_SEQUENCE, PI_WARN, "IP port reused, you need to split the capture file", EXPFILL }},
+               { &ei_afp_toc_offset, { "afp.toc_offset.bogus", PI_PROTOCOL, PI_WARN, "ToC offset bogus", EXPFILL }},
+       };
+       expert_module_t* expert_afp;
+
        proto_afp = proto_register_protocol("Apple Filing Protocol", "AFP", "afp");
        proto_register_field_array(proto_afp, hf, array_length(hf));
        proto_register_subtree_array(ett, array_length(ett));
+       expert_afp = expert_register_protocol(proto_afp);
+       expert_register_field_array(expert_afp, ei, array_length(ei));
 
-       register_init_routine(afp_reinit);
+       afp_request_hash = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), afp_hash, afp_equal);
 
        register_dissector("afp", dissect_afp, proto_afp);
+       register_dissector("afp_server_status", dissect_afp_server_status,
+           proto_afp);
+       register_dissector("afp_spotlight", dissect_spotlight, proto_afp);
 
        afp_tap = register_tap("afp");
+
+       register_srt_table(proto_afp, NULL, 1, afpstat_packet, afpstat_init, NULL);
 }
 
 void
 proto_reg_handoff_afp(void)
 {
-       data_handle = find_dissector("data");
+       spotlight_handle = find_dissector_add_dependency("afp_spotlight", proto_afp);
 }
 
 /* -------------------------------
        end
 */
+
+/*
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 8
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * End:
+ *
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
+ * :indentSize=8:tabSize=8:noTabs=false:
+ */