aboutsummaryrefslogtreecommitdiffstats
path: root/packet-afp.c
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2002-04-25 23:58:02 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2002-04-25 23:58:02 +0000
commit2ae2bf1a840b8ef894cb07adf1f9edc19c518c1b (patch)
treed6384693c6891873d95c7eb16183740e12001b0a /packet-afp.c
parentfa45a56fb5bb2a5ff8a38ce5b4a83ec8797512b1 (diff)
ATP, ASP, and AFP support, from Didier Gautheron.
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@5254 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'packet-afp.c')
-rw-r--r--packet-afp.c1852
1 files changed, 1852 insertions, 0 deletions
diff --git a/packet-afp.c b/packet-afp.c
new file mode 100644
index 0000000000..cd74eceeb3
--- /dev/null
+++ b/packet-afp.c
@@ -0,0 +1,1852 @@
+/* packet-afp.c
+ * Routines for afp packet dissection
+ * Copyright 2002, Didier Gautheron <dgautheron@magic.fr>
+ *
+ * $Id: packet-afp.c,v 1.1 2002/04/25 23:58:02 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@ethereal.com>
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+#ifdef HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+
+#ifdef NEED_SNPRINTF_H
+# ifdef HAVE_STDARG_H
+# include <stdarg.h>
+# else
+# include <varargs.h>
+# endif
+# include "snprintf.h"
+#endif
+
+#include <string.h>
+#include <glib.h>
+#include <epan/packet.h>
+#include <epan/strutil.h>
+#include <epan/conversation.h>
+
+#include "packet-afp.h"
+
+/* The information in this module (AFP) comes from:
+
+ AFP 2.1 & 2.2.pdf contained in AppleShare_IP_6.3_SDK
+ available from http://www.apple.com
+
+ AFP3.0.pdf from http://www.apple.com
+
+ The netatalk source code by Wesley Craig & Adrian Sun
+ http://netatalk.sf.net
+*/
+/* from netatalk/include/afp.h */
+#define AFPTRANS_NONE 0
+#define AFPTRANS_DDP (1 << 0)
+#define AFPTRANS_TCP (1 << 1)
+#define AFPTRANS_ALL (AFPTRANS_DDP | AFPTRANS_TCP)
+
+/* 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_FASTBOZO (1<<15) /* fast copying */
+
+/* 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 */
+/* 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_TIME(x) ((x) & 0xfff) /* time in minutes */
+
+/* AFP functions */
+#define AFP_BYTELOCK 1
+#define AFP_CLOSEVOL 2
+#define AFP_CLOSEDIR 3
+#define AFP_CLOSEFORK 4
+#define AFP_COPYFILE 5
+#define AFP_CREATEDIR 6
+#define AFP_CREATEFILE 7
+#define AFP_DELETE 8
+#define AFP_ENUMERATE 9
+#define AFP_FLUSH 10
+#define AFP_FLUSHFORK 11
+#define AFP_GETFORKPARAM 14
+#define AFP_GETSRVINFO 15
+#define AFP_GETSRVPARAM 16
+#define AFP_GETVOLPARAM 17
+#define AFP_LOGIN 18
+#define AFP_LOGINCONT 19
+#define AFP_LOGOUT 20
+#define AFP_MAPID 21
+#define AFP_MAPNAME 22
+#define AFP_MOVE 23
+#define AFP_OPENVOL 24
+#define AFP_OPENDIR 25
+#define AFP_OPENFORK 26
+#define AFP_READ 27
+#define AFP_RENAME 28
+#define AFP_SETDIRPARAM 29
+#define AFP_SETFILEPARAM 30
+#define AFP_SETFORKPARAM 31
+#define AFP_SETVOLPARAM 32
+#define AFP_WRITE 33
+#define AFP_GETFLDRPARAM 34
+#define AFP_SETFLDRPARAM 35
+#define AFP_CHANGEPW 36
+#define AFP_GETSRVRMSG 38
+#define AFP_CREATEID 39
+#define AFP_DELETEID 40
+#define AFP_RESOLVEID 41
+#define AFP_EXCHANGEFILE 42
+#define AFP_CATSEARCH 43
+#define AFP_OPENDT 48
+#define AFP_CLOSEDT 49
+#define AFP_GETICON 51
+#define AFP_GTICNINFO 52
+#define AFP_ADDAPPL 53
+#define AFP_RMVAPPL 54
+#define AFP_GETAPPL 55
+#define AFP_ADDCMT 56
+#define AFP_RMVCMT 57
+#define AFP_GETCMT 58
+#define AFP_ADDICON 192
+
+/* ----------------------------- */
+static int proto_afp = -1;
+static int hf_afp_flags = -1;
+static int hf_afp_requestid = -1;
+static int hf_afp_code = -1;
+static int hf_afp_length = -1;
+static int hf_afp_reserved = -1;
+
+static int hf_afp_command = -1; /* CommandCode */
+static int hf_afp_AFPVersion = -1;
+static int hf_afp_UAM = -1;
+static int hf_afp_user = -1;
+static int hf_afp_passwd = -1;
+static int hf_afp_pad = -1;
+
+static int hf_afp_vol_bitmap = -1;
+static int hf_afp_bitmap_offset = -1;
+static int hf_afp_vol_id = -1;
+static int hf_afp_vol_attribute = -1;
+static int hf_afp_vol_name = -1;
+static int hf_afp_vol_signature = -1;
+static int hf_afp_vol_creation_date = -1;
+static int hf_afp_vol_modification_date = -1;
+static int hf_afp_vol_backup_date = -1;
+static int hf_afp_vol_bytes_free = -1;
+static int hf_afp_vol_bytes_total = -1;
+static int hf_afp_vol_ex_bytes_free = -1;
+static int hf_afp_vol_ex_bytes_total = -1;
+static int hf_afp_vol_block_size = -1;
+
+static int hf_afp_did = -1;
+static int hf_afp_file_id = -1;
+static int hf_afp_dir_bitmap = -1;
+static int hf_afp_dir_off_spring = -1;
+
+static int hf_afp_file_bitmap = -1;
+static int hf_afp_req_count = -1;
+static int hf_afp_start_index = -1;
+static int hf_afp_max_reply_size = -1;
+static int hf_afp_file_flag = -1;
+static int hf_afp_struct_size = -1;
+
+static int hf_afp_creation_date = -1;
+static int hf_afp_modification_date = -1;
+static int hf_afp_backup_date = -1;
+static int hf_afp_finder_info = -1;
+
+static int hf_afp_path_type = -1;
+static int hf_afp_path_name = -1;
+
+static int hf_afp_flag = -1;
+static int hf_afp_ofork = -1;
+static int hf_afp_offset = -1;
+static int hf_afp_rw_count = 1;
+static int hf_afp_fork_type = -1;
+static int hf_afp_access_mode = -1;
+static int hf_afp_access_read = -1;
+static int hf_afp_access_write = -1;
+static int hf_afp_access_deny_read = -1;
+static int hf_afp_access_deny_write = -1;
+
+static gint ett_afp = -1;
+
+static gint ett_afp_vol_attribute = -1;
+static gint ett_afp_enumerate = -1;
+static gint ett_afp_enumerate_line = -1;
+static gint ett_afp_access_mode = -1;
+
+static gint ett_afp_vol_bitmap = -1;
+static gint ett_afp_dir_bitmap = -1;
+static gint ett_afp_file_bitmap = -1;
+
+static dissector_handle_t afp_handle;
+static dissector_handle_t data_handle;
+
+static const value_string vol_signature_vals[] = {
+ {1, "Flat"},
+ {2, "Fixed Directory ID"},
+ {3, "Variable Directory ID (deprecated)"},
+ {0, NULL } };
+
+static const value_string CommandCode_vals[] = {
+ {AFP_BYTELOCK, "afpByteRangeLock" },
+ {AFP_CLOSEVOL, "afpVolClose" },
+ {AFP_CLOSEDIR, "afpDirClose" },
+ {AFP_CLOSEFORK, "afpForkClose" },
+ {AFP_COPYFILE, "afpCopyFile" },
+ {AFP_CREATEDIR, "afpDirCreate" },
+ {AFP_CREATEFILE, "afpFileCreate" },
+ {AFP_DELETE, "afpDelete" },
+ {AFP_ENUMERATE, "afpEnumerate" },
+ {AFP_FLUSH, "afpFlush" },
+ {AFP_FLUSHFORK, "afpForkFlush" },
+ {AFP_GETFORKPARAM,"afpGetForkParms" },
+ {AFP_GETSRVINFO, "afpGetSInfo" },
+ {AFP_GETSRVPARAM, "afpGetSParms" },
+ {AFP_GETVOLPARAM, "afpGetVolParms" },
+ {AFP_LOGIN, "afpLogin" },
+ {AFP_LOGINCONT, "afpContLogin" },
+ {AFP_LOGOUT, "afpLogout" },
+ {AFP_MAPID, "afpMapID" },
+ {AFP_MAPNAME, "afpMapName" },
+ {AFP_MOVE, "afpMove" },
+ {AFP_OPENVOL, "afpOpenVol" },
+ {AFP_OPENDIR, "afpOpenDir" },
+ {AFP_OPENFORK, "afpOpenFork" },
+ {AFP_READ, "afpRead" },
+ {AFP_RENAME, "afpRename" },
+ {AFP_SETDIRPARAM, "afpSetDirParms" },
+ {AFP_SETFILEPARAM,"afpSetFileParms" },
+ {AFP_SETFORKPARAM,"afpSetForkParms" },
+ {AFP_SETVOLPARAM, "afpSetVolParms" },
+ {AFP_WRITE, "afpWrite" },
+ {AFP_GETFLDRPARAM,"afpGetFlDrParms" },
+ {AFP_SETFLDRPARAM,"afpSetFlDrParms" },
+ {AFP_CHANGEPW, "afpChangePw" },
+ {AFP_GETSRVRMSG, "afpGetSrvrMsg" },
+ {AFP_CREATEID, "afpCreateID" },
+ {AFP_DELETEID, "afpDeleteID" },
+ {AFP_RESOLVEID, "afpResolveID" },
+ {AFP_EXCHANGEFILE,"afpExchangeFiles" },
+ {AFP_CATSEARCH, "afpCatSearch" },
+ {AFP_OPENDT, "afpDTOpen" },
+ {AFP_CLOSEDT, "afpDTClose" },
+ {AFP_GETICON, "afpGetIcon" },
+ {AFP_GTICNINFO, "afpGtIcnInfo" },
+ {AFP_ADDAPPL, "afpAddAPPL" },
+ {AFP_RMVAPPL, "afpRmvAPPL" },
+ {AFP_GETAPPL, "afpGetAPPL" },
+ {AFP_ADDCMT, "afpAddCmt" },
+ {AFP_RMVCMT, "afpRmvCmt" },
+ {AFP_GETCMT, "afpGetCmt" },
+ {AFP_ADDICON, "afpAddIcon" },
+ {0, NULL } };
+
+
+/* volume bitmap
+ 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)
+
+static int hf_afp_vol_bitmap_Attribute = -1;
+static int hf_afp_vol_bitmap_Signature = -1;
+static int hf_afp_vol_bitmap_CreateDate = -1;
+static int hf_afp_vol_bitmap_ModDate = -1;
+static int hf_afp_vol_bitmap_BackupDate = -1;
+static int hf_afp_vol_bitmap_ID = -1;
+static int hf_afp_vol_bitmap_BytesFree = -1;
+static int hf_afp_vol_bitmap_BytesTotal = -1;
+static int hf_afp_vol_bitmap_Name = -1;
+static int hf_afp_vol_bitmap_ExtBytesFree = -1;
+static int hf_afp_vol_bitmap_ExtBytesTotal = -1;
+static int hf_afp_vol_bitmap_BlockSize = -1;
+
+static int hf_afp_vol_attribute_ReadOnly = -1;
+static int hf_afp_vol_attribute_HasVolumePassword = -1;
+static int hf_afp_vol_attribute_SupportsFileIDs = -1;
+static int hf_afp_vol_attribute_SupportsCatSearch = -1;
+static int hf_afp_vol_attribute_SupportsBlankAccessPrivs = -1;
+static int hf_afp_vol_attribute_SupportsUnixPrivs = -1;
+static int hf_afp_vol_attribute_SupportsUTF8Names = -1;
+
+static int hf_afp_dir_bitmap_Attribute = -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_file_bitmap_Attribute = -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_OffspringCount = -1;
+static int hf_afp_file_bitmap_UTF8Name = -1;
+static int hf_afp_file_bitmap_UnixPrivs = -1;
+
+static const value_string vol_bitmap_vals[] = {
+ {kFPVolAttributeBit, "VolAttribute"},
+ {kFPVolSignatureBit, "VolSignature"},
+ {kFPVolCreateDateBit, "VolCreateDate"},
+ {kFPVolModDateBit, "VolModDate"},
+ {kFPVolBackupDateBit, "VolBackupDate"},
+ {kFPVolIDBit, "VolID"},
+ {kFPVolBytesFreeBit, "VolBytesFree"},
+ {kFPVolBytesTotalBit, "VolBytesTotal"},
+ {kFPVolNameBit, "VolNameBit"},
+ {kFPVolExtBytesFreeBit, "VolExtBytesFree"},
+ {kFPVolExtBytesTotalBit, "VolExtBytesTotal"},
+ {kFPVolBlockSizeBit, "VolBlockSize"},
+ {0, NULL } };
+
+static const value_string flag_vals[] = {
+ {0, "Start" },
+ {1, "End" },
+ {0, NULL } };
+
+static const value_string path_type_vals[] = {
+ {1, "Short names" },
+ {2, "Long names" },
+ {3, "Unicode names" },
+ {0, NULL } };
+
+/*
+ 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)
+
+/*
+ directory bitmap from Apple AFP3.0.pdf
+ Table 1-4 p. 31
+*/
+#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 kFPUnixPrivsBit (1 << 14)
+
+/*
+ file bitmap AFP3.0.pdf
+ Table 1-7 p. 36
+same as dir
+kFPAttributeBit (bit 0)
+kFPParentDirIDBit (bit 1)
+kFPCreateDateBit (bit 2)
+kFPModDateBit (bit 3)
+kFPBackupDateBit (bit 4)
+kFPFinderInfoBit (bit 5)
+kFPLongNameBit (bit 6)
+kFPShortNameBit (bit 7)
+kFPNodeIDBit (bit 8)
+
+kFPUTF8NameBit (bit 13)
+*/
+
+#define kFPDataForkLenBit (1 << 9)
+#define kFPRsrcForkLenBit (1 << 10)
+#define kFPExtDataForkLenBit (1 << 11)
+#define kFPLaunchLimitBit (1 << 12)
+
+#define kFPExtRsrcForkLenBit (1 << 14)
+#define kFPUnixPrivsBit_file (1 << 15) /* :( */
+
+#define hash_init_count 20
+
+/* Hash functions */
+static gint afp_equal (gconstpointer v, gconstpointer v2);
+static guint afp_hash (gconstpointer v);
+
+static guint afp_packet_init_count = 200;
+
+typedef struct {
+ guint32 conversation;
+ guint16 seq;
+} afp_request_key;
+
+typedef struct {
+ guint8 command;
+} afp_request_val;
+
+static GHashTable *afp_request_hash = NULL;
+static GMemChunk *afp_request_keys = NULL;
+static GMemChunk *afp_request_vals = NULL;
+
+/* Hash Functions */
+static gint afp_equal (gconstpointer v, gconstpointer v2)
+{
+ afp_request_key *val1 = (afp_request_key*)v;
+ afp_request_key *val2 = (afp_request_key*)v2;
+
+ if (val1->conversation == val2->conversation &&
+ val1->seq == val2->seq) {
+ return 1;
+ }
+ return 0;
+}
+
+static guint afp_hash (gconstpointer v)
+{
+ afp_request_key *afp_key = (afp_request_key*)v;
+ return afp_key->seq;
+}
+
+/* --------------------------
+*/
+#define PAD(x) { proto_tree_add_item(tree, hf_afp_pad, tvb, offset, x, FALSE); 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;
+
+ 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_Attribute, 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;
+}
+
+/* -------------------------- */
+static guint16
+decode_vol_attribute (proto_tree *tree, tvbuff_t *tvb, gint offset)
+{
+ proto_tree *sub_tree = NULL;
+ proto_item *item;
+ guint16 bitmap;
+
+ 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);
+
+ return bitmap;
+}
+
+/* -------------------------- */
+static gint
+parse_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
+{
+guint16 nameoff = 0;
+
+ if ((bitmap & kFPVolAttributeBit)) {
+ decode_vol_attribute(tree,tvb,offset);
+ offset += 2;
+ }
+ if ((bitmap & kFPVolSignatureBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_signature,tvb, offset, 2, FALSE);
+ offset += 2;
+ }
+ if ((bitmap & kFPVolCreateDateBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_creation_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPVolModDateBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_modification_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPVolBackupDateBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_backup_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPVolIDBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+ offset += 2;
+ }
+ if ((bitmap & kFPVolBytesFreeBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_bytes_free,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPVolBytesTotalBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_bytes_total,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPVolNameBit)) {
+ nameoff = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
+ offset += 2;
+
+ }
+ if ((bitmap & kFPVolExtBytesFreeBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_ex_bytes_free,tvb, offset, 8, FALSE);
+ offset += 8;
+ }
+ if ((bitmap & kFPVolExtBytesTotalBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_ex_bytes_total,tvb, offset, 8, FALSE);
+ offset += 8;
+ }
+ if ((bitmap & kFPVolBlockSizeBit)) {
+ proto_tree_add_item(tree, hf_afp_vol_block_size,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if (nameoff) {
+ int len;
+
+ len = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
+ offset += len +1;
+
+ }
+ return offset;
+}
+
+/* -------------------------- */
+static guint16
+decode_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
+{
+ proto_tree *sub_tree = NULL;
+ proto_item *item;
+ guint16 bitmap;
+
+ 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_Attribute , 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_UTF8Name , tvb, offset, 2,FALSE);
+
+ proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UnixPrivs , tvb, offset, 2,FALSE);
+
+ return bitmap;
+}
+
+/* -------------------------- */
+static gint
+parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
+{
+ guint16 lnameoff = 0;
+ guint16 snameoff = 0;
+ guint16 unameoff = 0;
+ gint max_offset = 0;
+
+ gint org_offset = offset;
+
+ if ((bitmap & kFPAttributeBit)) {
+ offset += 2;
+ }
+ if ((bitmap & kFPParentDirIDBit)) {
+ proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPCreateDateBit)) {
+ proto_tree_add_item(tree, hf_afp_creation_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPModDateBit)) {
+ proto_tree_add_item(tree, hf_afp_modification_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPBackupDateBit)) {
+ proto_tree_add_item(tree, hf_afp_backup_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPFinderInfoBit)) {
+ proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
+ offset += 32;
+ }
+ if ((bitmap & kFPLongNameBit)) {
+ gint tp_ofs;
+ guint8 len;
+ lnameoff = tvb_get_ntohs(tvb, offset);
+ if (lnameoff) {
+ tp_ofs = lnameoff +org_offset;
+ proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
+ len = tvb_get_guint8(tvb, tp_ofs);
+ proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, 1,FALSE);
+ tp_ofs += len +1;
+ max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
+ }
+ offset += 2;
+ }
+ if ((bitmap & kFPShortNameBit)) {
+ snameoff = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
+ offset += 2;
+ }
+ if ((bitmap & kFPNodeIDBit)) {
+ proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
+ offset += 4;
+ }
+
+ return offset;
+}
+
+/* -------------------------- */
+static guint16
+decode_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
+{
+ proto_tree *sub_tree = NULL;
+ proto_item *item;
+ guint16 bitmap;
+
+ 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_Attribute , 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;
+}
+
+/* -------------------------- */
+static gint
+parse_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
+{
+ guint16 lnameoff = 0;
+ guint16 snameoff = 0;
+ guint16 unameoff = 0;
+ gint max_offset = 0;
+
+ gint org_offset = offset;
+
+ if ((bitmap & kFPAttributeBit)) {
+ offset += 2;
+ }
+ if ((bitmap & kFPParentDirIDBit)) {
+ proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPCreateDateBit)) {
+ proto_tree_add_item(tree, hf_afp_creation_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPModDateBit)) {
+ proto_tree_add_item(tree, hf_afp_modification_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPBackupDateBit)) {
+ proto_tree_add_item(tree, hf_afp_backup_date,tvb, offset, 4, FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPFinderInfoBit)) {
+ proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
+ offset += 32;
+ }
+ if ((bitmap & kFPLongNameBit)) {
+ gint tp_ofs;
+ guint8 len;
+ lnameoff = tvb_get_ntohs(tvb, offset);
+ if (lnameoff) {
+ tp_ofs = lnameoff +org_offset;
+ proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
+ len = tvb_get_guint8(tvb, tp_ofs);
+ proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, 1,FALSE);
+ tp_ofs += len +1;
+ max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
+ }
+ offset += 2;
+ }
+ if ((bitmap & kFPShortNameBit)) {
+ snameoff = tvb_get_ntohs(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
+ offset += 2;
+ }
+ if ((bitmap & kFPNodeIDBit)) {
+ proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
+ offset += 4;
+ }
+ if ((bitmap & kFPOffspringCountBit)) {
+ proto_tree_add_item(tree, hf_afp_dir_off_spring, tvb, offset, 2,FALSE);
+ offset += 2; /* error in AFP3.0.pdf */
+ }
+ if ((bitmap & kFPOwnerIDBit)) {
+ offset += 4;
+ }
+ if ((bitmap & kFPGroupIDBit)) {
+ offset += 4;
+ }
+ if ((bitmap & kFPAccessRightsBit)) {
+ offset += 4;
+ }
+ if ((bitmap & kFPUTF8NameBit)) {
+ offset += 2;
+ }
+ if ((bitmap & kFPUnixPrivsBit)) {
+ unameoff = tvb_get_ntohs(tvb, offset);
+ offset += 4;
+ }
+ return (max_offset)?max_offset:offset;
+}
+
+/* -------------------------- */
+static gchar *
+name_in_bitmap(tvbuff_t *tvb, gint *offset, guint16 bitmap)
+{
+ gchar *name;
+ gint org_offset = *offset;
+ guint16 nameoff;
+ guint8 len;
+ gint tp_ofs;
+
+ name = NULL;
+ if ((bitmap & kFPAttributeBit))
+ *offset += 2;
+ if ((bitmap & kFPParentDirIDBit))
+ *offset += 4;
+ if ((bitmap & kFPCreateDateBit))
+ *offset += 4;
+ if ((bitmap & kFPModDateBit))
+ *offset += 4;
+ if ((bitmap & kFPBackupDateBit))
+ *offset += 4;
+ if ((bitmap & kFPFinderInfoBit))
+ *offset += 32;
+
+ if ((bitmap & kFPLongNameBit)) {
+ nameoff = tvb_get_ntohs(tvb, *offset);
+ if (nameoff) {
+ tp_ofs = nameoff +org_offset;
+ len = tvb_get_guint8(tvb, tp_ofs);
+ tp_ofs++;
+ if (!(name = g_malloc(len +1)))
+ return name;
+ tvb_memcpy(tvb, name, tp_ofs, len);
+ *(name +len) = 0;
+ return name;
+ }
+ }
+ /* short name ? */
+ return name;
+}
+
+/* -------------------------- */
+static gchar *
+name_in_dbitmap(tvbuff_t *tvb, gint offset, guint16 bitmap)
+{
+ gchar *name;
+
+ name = name_in_bitmap(tvb, &offset, bitmap);
+ if (name != NULL)
+ return name;
+ /*
+ check UTF8 name
+ */
+
+ return name;
+}
+
+/* -------------------------- */
+static gchar *
+name_in_fbitmap(tvbuff_t *tvb, gint offset, guint16 bitmap)
+{
+ gchar *name;
+
+ name = name_in_bitmap(tvb, &offset, bitmap);
+ if (name != NULL)
+ return name;
+ /*
+ check UTF8 name
+ */
+
+ return name;
+}
+
+/* -------------------------- */
+static gint
+decode_vol_did_file_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
+{
+ proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+ offset += 4;
+
+ decode_file_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ decode_dir_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ return offset;
+}
+
+/* -------------------------- */
+static gint
+decode_name (proto_tree *tree, tvbuff_t *tvb, gint offset)
+{
+ int len;
+
+ proto_tree_add_item(tree, hf_afp_path_type, tvb, offset, 1,FALSE);
+ offset += 1;
+
+ len = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, 1,FALSE);
+ offset += len +1;
+
+ return offset;
+}
+
+/* ************************** */
+static gint
+dissect_query_afp_open_vol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ int len;
+
+ PAD(1);
+
+ decode_vol_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ len = tvb_get_guint8(tvb, offset);
+#if 0
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ gchar *func_str;
+
+ if ((func_str = match_strval(afp_command, CommandCode_vals)))
+ {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", func_str, aspinfo->reply?"reply":"");
+ }
+ }
+#endif
+ proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
+ 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);
+ offset += 8;
+ }
+ return offset;
+}
+
+/* -------------------------- */
+static gint
+dissect_reply_afp_open_vol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ guint16 bitmap;
+
+ bitmap = decode_vol_bitmap(tree, tvb, offset);
+ offset += 2;
+ offset = parse_vol_bitmap(tree, tvb, offset, bitmap);
+
+ return offset;
+}
+
+/* ************************** */
+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;
+
+ proto_tree_add_item(tree, hf_afp_fork_type, tvb, offset, 1,FALSE);
+ offset++;
+
+ proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
+ offset += 4;
+
+ 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);
+ }
+ item = proto_tree_add_item(sub_tree, hf_afp_access_read , tvb, offset, 2,FALSE);
+ item = proto_tree_add_item(sub_tree, hf_afp_access_write , tvb, offset, 2,FALSE);
+ item = proto_tree_add_item(sub_tree, hf_afp_access_deny_read , tvb, offset, 2,FALSE);
+ item = proto_tree_add_item(sub_tree, hf_afp_access_deny_write, tvb, offset, 2,FALSE);
+
+ offset += 2;
+
+ offset = decode_name(tree,tvb, offset);
+
+ return offset;
+}
+
+/* -------------------------- */
+static gint
+dissect_reply_afp_open_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ int f_bitmap;
+
+ f_bitmap = decode_file_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+ offset += 2;
+
+ offset = parse_file_bitmap(tree, tvb, offset, f_bitmap);
+
+ return offset;
+}
+
+/* ************************** */
+static gint
+dissect_query_afp_enumerate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+
+ 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);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_afp_start_index, tvb, offset, 2,FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_afp_max_reply_size, tvb, offset, 2,FALSE);
+ offset += 2;
+
+ offset = decode_name(tree,tvb, offset);
+
+ return offset;
+}
+
+/* -------------------------- */
+static gint
+dissect_reply_afp_enumerate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ proto_tree *sub_tree = NULL;
+ proto_item *item;
+ int count;
+ int f_bitmap;
+ int d_bitmap;
+ guint8 flags;
+ guint8 size;
+ gint org;
+ int i;
+ gchar *name;
+
+ f_bitmap = decode_file_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ d_bitmap = decode_dir_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ count = tvb_get_ntohs(tvb, offset);
+ if (tree) {
+ item = proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
+ sub_tree = proto_item_add_subtree(item, ett_afp_enumerate);
+ }
+ offset += 2;
+ /* loop */
+ if (tree) for (i = 0; i < count; i++) {
+ org = offset;
+ name = NULL;
+ size = tvb_get_guint8(tvb, offset);
+ flags = tvb_get_guint8(tvb, offset +1);
+
+ if (flags) {
+ name = name_in_dbitmap(tvb, offset +2, d_bitmap);
+ }
+ else {
+ name = name_in_fbitmap(tvb, offset +2, f_bitmap);
+ }
+ if (!name) {
+ if (!(name = g_malloc(50))) { /* no memory ! */
+ }
+ snprintf(name, 50,"line %d", i +1);
+ }
+ item = proto_tree_add_text(sub_tree, tvb, offset, size, name);
+ tree = proto_item_add_subtree(item, ett_afp_enumerate_line);
+
+ proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1,FALSE);
+ offset++;
+
+ proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
+ offset++;
+ if (flags) {
+ offset = parse_dir_bitmap(tree, tvb, offset, d_bitmap);
+ }
+ else {
+ offset = parse_file_bitmap(tree, tvb, offset, f_bitmap);
+ }
+ if ((offset & 1))
+ PAD(1);
+ offset = org +size; /* play safe */
+ g_free((gpointer)name);
+ }
+ return(offset);
+
+}
+
+/* **************************/
+static gint
+dissect_query_afp_get_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ if (!tree)
+ return offset;
+ PAD(1)
+ proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
+ offset += 2;
+
+ decode_vol_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ return offset;
+}
+
+/* ------------------------ */
+static gint
+dissect_reply_afp_get_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ guint16 bitmap;
+
+ if (!tree)
+ return offset;
+ bitmap = decode_vol_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ offset = parse_vol_bitmap(tree, tvb, offset, bitmap);
+
+ return offset;
+}
+
+/* ***************************/
+static gint
+dissect_query_afp_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ int len;
+
+ if (!tree)
+ return offset;
+ len = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_AFPVersion, tvb, offset, 1,FALSE);
+ offset += len +1;
+ len = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1,FALSE);
+ offset += len +1;
+
+ /* clear text */
+ len = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_user, tvb, offset, 1,FALSE);
+ offset += len +1;
+
+ len = tvb_strsize(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, len,FALSE);
+ offset += len;
+
+ return(offset);
+}
+
+/* ************************** */
+static gint
+dissect_query_afp_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ int len;
+
+ if (!tree)
+ return offset;
+ proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1,FALSE);
+ offset += 1;
+
+ proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
+ offset += 2;
+
+ proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4,FALSE);
+ offset += 4;
+
+ proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4,FALSE);
+ offset += 4;
+
+ return offset;
+}
+
+/* ************************** */
+static gint
+dissect_query_afp_get_fldr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+ if (!tree)
+ return offset;
+ PAD(1);
+ offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
+
+ offset = decode_name(tree, tvb, offset);
+
+ return offset;
+}
+
+/* -------------------------- */
+static gint
+dissect_reply_afp_get_fldr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
+{
+guint8 flags;
+guint16 f_bitmap, d_bitmap;
+
+ if (!tree)
+ return offset;
+ f_bitmap = decode_file_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ d_bitmap = decode_dir_bitmap(tree, tvb, offset);
+ offset += 2;
+
+ flags = tvb_get_guint8(tvb, offset);
+ proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
+ offset++;
+ PAD(1);
+ if (flags) {
+ offset = parse_dir_bitmap(tree, tvb, offset, d_bitmap);
+ }
+ else {
+ offset = parse_file_bitmap(tree, tvb, offset, f_bitmap);
+ }
+ return offset;
+}
+
+/* ************************** */
+static void
+dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ struct aspinfo *aspinfo = pinfo->private_data;
+ proto_tree *afp_tree = NULL;
+ proto_item *ti;
+ conversation_t *conversation;
+ gint offset = 0;
+ afp_request_key request_key, *new_request_key;
+ afp_request_val *request_val;
+
+ gchar *func_str;
+
+ guint8 afp_flags,afp_command;
+ guint16 afp_requestid;
+ gint32 afp_code;
+ guint32 afp_length;
+ guint32 afp_reserved;
+ int len = tvb_reported_length_remaining(tvb,0);
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "AFP");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
+ pinfo->srcport, pinfo->destport, 0);
+
+ if (conversation == NULL)
+ {
+ conversation = conversation_new(&pinfo->src, &pinfo->dst,
+ pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
+ }
+
+ request_key.conversation = conversation->index;
+ request_key.seq = aspinfo->seq;
+
+ request_val = (afp_request_val *) g_hash_table_lookup(
+ afp_request_hash, &request_key);
+
+ if (!request_val && !aspinfo->reply) {
+ afp_command = tvb_get_guint8(tvb, offset);
+ new_request_key = g_mem_chunk_alloc(afp_request_keys);
+ *new_request_key = request_key;
+
+ request_val = g_mem_chunk_alloc(afp_request_vals);
+ request_val->command = tvb_get_guint8(tvb, offset);
+
+ g_hash_table_insert(afp_request_hash, new_request_key,
+ request_val);
+ }
+
+ if (!request_val) { /* missing request */
+ return;
+ }
+
+ afp_command = request_val->command;
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ gchar *func_str;
+
+ if ((func_str = match_strval(afp_command, CommandCode_vals)))
+ {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", func_str, aspinfo->reply?"reply":"");
+ }
+ }
+
+ if (tree)
+ {
+ ti = proto_tree_add_item(tree, proto_afp, tvb, offset, -1,FALSE);
+ afp_tree = proto_item_add_subtree(ti, ett_afp);
+ }
+ if (!aspinfo->reply) {
+ proto_tree_add_uint(afp_tree, hf_afp_command, tvb,offset, 1, afp_command);
+ offset++;
+ switch(afp_command) {
+ case AFP_BYTELOCK:
+ case AFP_CLOSEVOL:
+ case AFP_CLOSEDIR:
+ case AFP_CLOSEFORK:
+ case AFP_COPYFILE:
+ case AFP_CREATEDIR:
+ case AFP_CREATEFILE:
+ case AFP_DELETE:
+ break;
+ case AFP_ENUMERATE:
+ offset = dissect_query_afp_enumerate(tvb, pinfo, afp_tree, offset);break;
+ case AFP_FLUSH:
+ case AFP_FLUSHFORK:
+ case AFP_GETFORKPARAM:
+ case AFP_GETSRVINFO:
+ case AFP_GETSRVPARAM:
+ break;
+ case AFP_GETVOLPARAM:
+ offset = dissect_query_afp_get_vol_param(tvb, pinfo, afp_tree, offset);break;
+ case AFP_LOGIN:
+ offset = dissect_query_afp_login(tvb, pinfo, afp_tree, offset);break;
+ case AFP_LOGINCONT:
+ case AFP_LOGOUT:
+ case AFP_MAPID:
+ case AFP_MAPNAME:
+ case AFP_MOVE:
+ break;
+ case AFP_OPENVOL:
+ 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;
+ case AFP_READ:
+ case AFP_RENAME:
+ case AFP_SETDIRPARAM:
+ case AFP_SETFILEPARAM:
+ case AFP_SETFORKPARAM:
+ case AFP_SETVOLPARAM:
+ break;
+ case AFP_WRITE:
+ offset = dissect_query_afp_write(tvb, pinfo, afp_tree, offset);break;
+ case AFP_GETFLDRPARAM:
+ offset = dissect_query_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);break;
+ case AFP_SETFLDRPARAM:
+ case AFP_CHANGEPW:
+ case AFP_GETSRVRMSG:
+ case AFP_CREATEID:
+ case AFP_DELETEID:
+ case AFP_RESOLVEID:
+ case AFP_EXCHANGEFILE:
+ case AFP_CATSEARCH:
+ case AFP_OPENDT:
+ case AFP_CLOSEDT:
+ case AFP_GETICON:
+ case AFP_GTICNINFO:
+ case AFP_ADDAPPL:
+ case AFP_RMVAPPL:
+ case AFP_GETAPPL:
+ case AFP_ADDCMT:
+ case AFP_RMVCMT:
+ case AFP_GETCMT:
+ case AFP_ADDICON:
+ break;
+ }
+ }
+ else {
+ switch(afp_command) {
+ case AFP_ENUMERATE:
+ 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;
+ case AFP_OPENFORK:
+ offset = dissect_reply_afp_open_fork(tvb, pinfo, afp_tree, offset);break;
+ case AFP_FLUSH:
+ case AFP_FLUSHFORK:
+ case AFP_GETFORKPARAM:
+ case AFP_GETSRVINFO:
+ case AFP_GETSRVPARAM:
+ break;
+ case AFP_GETVOLPARAM:
+ 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;
+ }
+ }
+ if (tree && offset < len)
+ call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, afp_tree);
+}
+
+static void afp_reinit( void)
+{
+
+ if (afp_request_hash)
+ g_hash_table_destroy(afp_request_hash);
+ if (afp_request_keys)
+ g_mem_chunk_destroy(afp_request_keys);
+ if (afp_request_vals)
+ g_mem_chunk_destroy(afp_request_vals);
+
+ afp_request_hash = g_hash_table_new(afp_hash, afp_equal);
+
+ afp_request_keys = g_mem_chunk_new("afp_request_keys",
+ sizeof(afp_request_key),
+ afp_packet_init_count * sizeof(afp_request_key),
+ G_ALLOC_AND_FREE);
+ afp_request_vals = g_mem_chunk_new("afp_request_vals",
+ sizeof(afp_request_val),
+ afp_packet_init_count * sizeof(afp_request_val),
+ G_ALLOC_AND_FREE);
+
+}
+
+void
+proto_register_afp(void)
+{
+
+ static hf_register_info hf[] = {
+ { &hf_afp_command,
+ { "Command", "afp.command",
+ FT_UINT8, BASE_DEC, VALS(CommandCode_vals), 0x0,
+ "AFP function", HFILL }},
+
+ { &hf_afp_pad,
+ { "pad", "afp.pad",
+ FT_NONE, BASE_NONE, NULL, 0,
+ "Pad Byte", HFILL }},
+
+ { &hf_afp_AFPVersion,
+ { "AFP Version", "afp.AFPVersion",
+ FT_UINT_STRING, BASE_NONE, NULL, 0x0,
+ "client AFP version", HFILL }},
+
+ { &hf_afp_UAM,
+ { "UAM", "afp.UAM",
+ FT_UINT_STRING, BASE_NONE, NULL, 0x0,
+ "USer Authentication method", HFILL }},
+
+ { &hf_afp_user,
+ { "user", "afp.user",
+ FT_UINT_STRING, BASE_NONE, NULL, 0x0,
+ "User", HFILL }},
+
+ { &hf_afp_passwd,
+ { "password", "afp.passwd",
+ FT_STRINGZ, BASE_NONE, NULL, 0x0,
+ "password", HFILL }},
+
+ { &hf_afp_vol_bitmap,
+ { "bitmap", "afp.vol_bitmap",
+ FT_UINT16, BASE_HEX, NULL, 0 /* 0x0FFF*/,
+ "Volume bitmap", HFILL }},
+
+ { &hf_afp_vol_bitmap_Attribute,
+ { "attribute", "afp.vol_bitmap.attribute",
+ FT_BOOLEAN, 16, NULL, kFPVolAttributeBit,
+ "Volume attribute", HFILL }},
+
+ { &hf_afp_vol_attribute, { "attribute", "afp.vol_attribute",
+ FT_UINT16, BASE_HEX, NULL, 0 , "Volume attribute", HFILL }},
+
+ { &hf_afp_vol_attribute_ReadOnly,
+ { "read only", "afp.vol_attribute.read_only",
+ FT_BOOLEAN, 16, NULL, kReadOnly,
+ "Read only volume", HFILL }},
+
+ { &hf_afp_vol_attribute_HasVolumePassword,
+ { "volume password", "afp.vol_attribute.passwd",
+ FT_BOOLEAN, 16, NULL, kHasVolumePassword,
+ "Has a volume password", HFILL }},
+
+ { &hf_afp_vol_attribute_SupportsFileIDs,
+ { "files ID", "afp.vol_attribute.fileIDs",
+ FT_BOOLEAN, 16, NULL, kSupportsFileIDs,
+ "Supports files ID", HFILL }},
+
+ { &hf_afp_vol_attribute_SupportsCatSearch,
+ { "cat search", "afp.vol_attribute.cat_search",
+ FT_BOOLEAN, 16, NULL, kSupportsCatSearch,
+ "Supports cat search call", HFILL }},
+
+ { &hf_afp_vol_attribute_SupportsBlankAccessPrivs,
+ { "blank access privs", "afp.vol_attribute.blank_access_privs",
+ FT_BOOLEAN, 16, NULL, kSupportsBlankAccessPrivs,
+ "Supports blank access priv.", HFILL }},
+
+ { &hf_afp_vol_attribute_SupportsUnixPrivs,
+ { "blank access privs", "afp.vol_attribute.unix_privs",
+ FT_BOOLEAN, 16, NULL, kSupportsUnixPrivs,
+ "Supports Unix access priv.", HFILL }},
+
+ { &hf_afp_vol_attribute_SupportsUTF8Names,
+ { "blank access privs", "afp.vol_attribute.utf8_names",
+ FT_BOOLEAN, 16, NULL, kSupportsUTF8Names,
+ "Supports UTF8 names.", HFILL }},
+
+ { &hf_afp_vol_bitmap_Signature,
+ { "signature", "afp.vol_bitmap.signature",
+ FT_BOOLEAN, 16, NULL, kFPVolSignatureBit,
+ "Volume signature", HFILL }},
+ { &hf_afp_vol_bitmap_CreateDate,
+ { "creation date", "afp.vol_bitmap.create_date",
+ FT_BOOLEAN, 16, NULL, kFPVolCreateDateBit,
+ "Volume creation date", HFILL }},
+ { &hf_afp_vol_bitmap_ModDate,
+ { "modification date", "afp.vol_bitmap.mod_date",
+ FT_BOOLEAN, 16, NULL, kFPVolModDateBit,
+ "Volume modification date", HFILL }},
+ { &hf_afp_vol_bitmap_BackupDate,
+ { "backup date", "afp.vol_bitmap.backup_date",
+ FT_BOOLEAN, 16, NULL, kFPVolBackupDateBit,
+ "Volume backup date", HFILL }},
+ { &hf_afp_vol_bitmap_ID,
+ { "ID", "afp.vol_bitmap.id",
+ FT_BOOLEAN, 16, NULL, kFPVolIDBit,
+ "Volume ID", HFILL }},
+ { &hf_afp_vol_bitmap_BytesFree,
+ { "bytes free", "afp.vol_bitmap.bytes_free",
+ FT_BOOLEAN, 16, NULL, kFPVolBytesFreeBit,
+ "Volume free bytes", HFILL }},
+ { &hf_afp_vol_bitmap_BytesTotal,
+ { "bytes total", "afp.vol_bitmap.bytes_total",
+ FT_BOOLEAN, 16, NULL, kFPVolBytesTotalBit,
+ "Volume total bytes", HFILL }},
+ { &hf_afp_vol_bitmap_Name,
+ { "name", "afp.vol_bitmap.name",
+ FT_BOOLEAN, 16, NULL, kFPVolNameBit,
+ "Volume name", HFILL }},
+ { &hf_afp_vol_bitmap_ExtBytesFree,
+ { "ex. bytes free", "afp.vol_bitmap.ex_bytes_free",
+ FT_BOOLEAN, 16, NULL, kFPVolExtBytesFreeBit,
+ "Volume ext. free bytes", HFILL }},
+ { &hf_afp_vol_bitmap_ExtBytesTotal,
+ { "ex bytes total", "afp.vol_bitmap.ex_bytes_total",
+ FT_BOOLEAN, 16, NULL, kFPVolExtBytesTotalBit,
+ "Volume ex. total byte", HFILL }},
+ { &hf_afp_vol_bitmap_BlockSize,
+ { "block size", "afp.vol_bitmap.block_size",
+ FT_BOOLEAN, 16, NULL, kFPVolBlockSizeBit,
+ "Volume block size", HFILL }},
+
+ { &hf_afp_dir_bitmap_Attribute,
+ { "attribute", "afp.dir_bitmap.attribute",
+ FT_BOOLEAN, 16, NULL, kFPAttributeBit,
+ "directory attribute", HFILL }},
+ { &hf_afp_dir_bitmap_ParentDirID,
+ { "DID", "afp.dir_bitmap.did",
+ FT_BOOLEAN, 16, NULL, kFPParentDirIDBit,
+ "parent directory ID", HFILL }},
+ { &hf_afp_dir_bitmap_CreateDate,
+ { "creation date", "afp.dir_bitmap.create_date",
+ FT_BOOLEAN, 16, NULL, kFPCreateDateBit,
+ "directory creation date", HFILL }},
+ { &hf_afp_dir_bitmap_ModDate,
+ { "modification date", "afp.dir_bitmap.mod_date",
+ FT_BOOLEAN, 16, NULL, kFPModDateBit,
+ "directory modification date", HFILL }},
+ { &hf_afp_dir_bitmap_BackupDate,
+ { "backup date", "afp.dir_bitmap.backup_date",
+ FT_BOOLEAN, 16, NULL, kFPBackupDateBit,
+ "directory backup date", HFILL }},
+ { &hf_afp_dir_bitmap_FinderInfo,
+ { "Finder info", "afp.dir_bitmap.finder_info",
+ FT_BOOLEAN, 16, NULL, kFPFinderInfoBit,
+ "directory finder info", HFILL }},
+ { &hf_afp_dir_bitmap_LongName,
+ { "long name", "afp.dir_bitmap.long_name",
+ FT_BOOLEAN, 16, NULL, kFPLongNameBit,
+ "directory long name", HFILL }},
+ { &hf_afp_dir_bitmap_ShortName,
+ { "short name", "afp.dir_bitmap.short_name",
+ FT_BOOLEAN, 16, NULL, kFPShortNameBit,
+ "directory short name", HFILL }},
+ { &hf_afp_dir_bitmap_NodeID,
+ { "file ID", "afp.dir_bitmap.fid",
+ FT_BOOLEAN, 16, NULL, kFPNodeIDBit,
+ "directory file ID", HFILL }},
+ { &hf_afp_dir_bitmap_OffspringCount,
+ { "offspring count", "afp.dir_bitmap.off_spring_count",
+ FT_BOOLEAN, 16, NULL, kFPOffspringCountBit,
+ "directory offSpring count", HFILL }},
+ { &hf_afp_dir_bitmap_OwnerID,
+ { "owner id", "afp.dir_bitmap.owner_id",
+ FT_BOOLEAN, 16, NULL, kFPOwnerIDBit,
+ "directory owner id", HFILL }},
+ { &hf_afp_dir_bitmap_GroupID,
+ { "group id", "afp.dir_bitmap.group_id",
+ FT_BOOLEAN, 16, NULL, kFPGroupIDBit,
+ "directory group id", HFILL }},
+ { &hf_afp_dir_bitmap_AccessRights,
+ { "access rights", "afp.dir_bitmap.access_rights",
+ FT_BOOLEAN, 16, NULL, kFPAccessRightsBit,
+ "directory access rights", HFILL }},
+ { &hf_afp_dir_bitmap_UTF8Name,
+ { "UTF8 name", "afp.dir_bitmap.UTF8_name",
+ FT_BOOLEAN, 16, NULL, kFPUTF8NameBit,
+ "directory UTF8 name", HFILL }},
+ { &hf_afp_dir_bitmap_UnixPrivs,
+ { "unix privs", "afp.dir_bitmap.unix_privs",
+ FT_BOOLEAN, 16, NULL, kFPUnixPrivsBit,
+ "directory unix privs", HFILL }},
+
+ { &hf_afp_file_bitmap_Attribute,
+ { "attribute", "afp.file_bitmap.attribute",
+ FT_BOOLEAN, 16, NULL, kFPAttributeBit,
+ "file attribute", HFILL }},
+ { &hf_afp_file_bitmap_ParentDirID,
+ { "DID", "afp.file_bitmap.did",
+ FT_BOOLEAN, 16, NULL, kFPParentDirIDBit,
+ "parent directory ID", HFILL }},
+ { &hf_afp_file_bitmap_CreateDate,
+ { "creation date", "afp.file_bitmap.create_date",
+ FT_BOOLEAN, 16, NULL, kFPCreateDateBit,
+ "file creation date", HFILL }},
+ { &hf_afp_file_bitmap_ModDate,
+ { "modification date", "afp.file_bitmap.mod_date",
+ FT_BOOLEAN, 16, NULL, kFPModDateBit,
+ "file modification date", HFILL }},
+ { &hf_afp_file_bitmap_BackupDate,
+ { "backup date", "afp.file_bitmap.backup_date",
+ FT_BOOLEAN, 16, NULL, kFPBackupDateBit,
+ "file backup date", HFILL }},
+ { &hf_afp_file_bitmap_FinderInfo,
+ { "Finder info", "afp.file_bitmap.finder_info",
+ FT_BOOLEAN, 16, NULL, kFPFinderInfoBit,
+ "file finder info", HFILL }},
+ { &hf_afp_file_bitmap_LongName,
+ { "long name", "afp.file_bitmap.long_name",
+ FT_BOOLEAN, 16, NULL, kFPLongNameBit,
+ "file long name", HFILL }},
+ { &hf_afp_file_bitmap_ShortName,
+ { "short name", "afp.file_bitmap.short_name",
+ FT_BOOLEAN, 16, NULL, kFPShortNameBit,
+ "file short name", HFILL }},
+ { &hf_afp_file_bitmap_NodeID,
+ { "file ID", "afp.file_bitmap.fid",
+ FT_BOOLEAN, 16, NULL, kFPNodeIDBit,
+ "file file ID", HFILL }},
+ { &hf_afp_file_bitmap_UTF8Name,
+ { "UTF8 name", "afp.file_bitmap.UTF8_name",
+ FT_BOOLEAN, 16, NULL, kFPUTF8NameBit,
+ "file UTF8 name", HFILL }},
+ { &hf_afp_file_bitmap_UnixPrivs,
+ { "unix privs", "afp.file_bitmap.unix_privs",
+ FT_BOOLEAN, 16, NULL, kFPUnixPrivsBit,
+ "file unix privs", HFILL }},
+
+ { &hf_afp_vol_name,
+ { "Volume", "afp.vol_name",
+ FT_UINT_STRING, BASE_NONE, NULL, 0x0,
+ "Volume name", HFILL }},
+ { &hf_afp_vol_id,
+ { "volume id", "afp.vol_id",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Volume id", HFILL }},
+ { &hf_afp_vol_signature,
+ { "signature", "afp.vol_signature",
+ FT_UINT16, BASE_DEC, VALS(vol_signature_vals), 0x0,
+ "Volume signature", HFILL }},
+ { &hf_afp_bitmap_offset,
+ { "offset", "afp.bitmap_offset",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "name offset in packet", HFILL }},
+ { &hf_afp_vol_creation_date,
+ { "creation date", "afp.vol_creation_date",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "volume creation date", HFILL }},
+ { &hf_afp_vol_modification_date,
+ { "modification date", "afp.vol_modification_date",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "volume modification date", HFILL }},
+ { &hf_afp_vol_backup_date,
+ { "backup date", "afp.vol_backup_date",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "volume backup date", HFILL }},
+ { &hf_afp_vol_bytes_free,
+ { "bytes free", "afp.vol_bytes_free",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "free space", HFILL }},
+ { &hf_afp_vol_bytes_total,
+ { "bytes total", "afp.vol_bytes_total",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "volume size ", HFILL }},
+ { &hf_afp_vol_ex_bytes_free,
+ { "ex. bytes free", "afp.vol_ex_bytes_free",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ "ex. free space", HFILL }},
+ { &hf_afp_vol_ex_bytes_total,
+ { "ex. bytes total", "afp.vol_ex_bytes_total",
+ FT_UINT64, BASE_DEC, NULL, 0x0,
+ "ex. volume size ", HFILL }},
+ { &hf_afp_vol_block_size,
+ { "block size", "afp.vol_block_size",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "volume block size", HFILL }},
+
+ { &hf_afp_did,
+ { "did", "afp.did",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "parent directory id", HFILL }},
+
+ { &hf_afp_dir_bitmap,
+ { "dir bitmap", "afp.dir_bitmap",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "directory bitmap", HFILL }},
+
+ { &hf_afp_dir_off_spring,
+ { "off spring", "afp.dir_off_spring",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "directory offspring", HFILL }},
+
+ { &hf_afp_creation_date,
+ { "creation date", "afp.creation_date",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "creation date", HFILL }},
+ { &hf_afp_modification_date,
+ { "modification date", "afp.modification_date",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "modification date", HFILL }},
+ { &hf_afp_backup_date,
+ { "backup date", "afp.backup_date",
+ FT_UINT32, BASE_HEX, NULL, 0x0,
+ "backup date", HFILL }},
+
+ { &hf_afp_finder_info,
+ { "finder info", "afp.finder_info",
+ FT_BYTES, BASE_HEX, NULL, 0x0,
+ "finder info", HFILL }},
+
+ { &hf_afp_file_id,
+ { "file id", "afp.file_id",
+ FT_UINT32, BASE_DEC, NULL, 0x0,
+ "file/directory id", HFILL }},
+
+ { &hf_afp_file_bitmap,
+ { "file bitmap", "afp.file_bitmap",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ "file bitmap", HFILL }},
+
+ { &hf_afp_req_count,
+ { "req count", "afp.req_count",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Maximum number of structures returned", HFILL }},
+
+ { & hf_afp_start_index,
+ { "start index", "afp.start_index",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "first structure returned", HFILL }},
+
+ { &hf_afp_max_reply_size,
+ { "reply size", "afp.reply_size",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "first structure returned", HFILL }},
+
+ { &hf_afp_file_flag,
+ { "dir", "afp.flag",
+ FT_BOOLEAN, 8, NULL, 0x80,
+ "is a dir", HFILL }},
+
+ { &hf_afp_struct_size,
+ { "struct size", "afp.struct_size",
+ FT_UINT8, BASE_DEC, NULL,0,
+ "sizeof of struct", HFILL }},
+
+ { &hf_afp_flag,
+ { "from", "afp.flag",
+ FT_UINT8, BASE_HEX, VALS(flag_vals), 0x80,
+ "offset is relative to start/end of the fork", HFILL }},
+
+ { &hf_afp_ofork,
+ { "fork", "afp.ofork",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Open fork reference number", HFILL }},
+
+ { &hf_afp_offset,
+ { "offset", "afp.offset",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ "offset ", HFILL }},
+
+ { &hf_afp_rw_count,
+ { "count", "afp.rw_count",
+ FT_INT32, BASE_DEC, NULL, 0x0,
+ "number of bytes to be written ", HFILL }},
+
+ { &hf_afp_path_type,
+ { "path type ", "afp.path_type",
+ FT_UINT8, BASE_HEX, VALS(path_type_vals), 0,
+ "type of names", HFILL }},
+
+ { &hf_afp_path_name,
+ { "Name ", "afp.path_name",
+ FT_UINT_STRING, BASE_NONE, NULL, 0x0,
+ "path name", HFILL }},
+
+ { &hf_afp_fork_type,
+ { "ressource fork", "afp.fork_type",
+ FT_BOOLEAN, 8, NULL, 0x80,
+ "data/ressource fork", HFILL }},
+
+ { &hf_afp_access_mode,
+ { "access mode", "afp.access",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ "fork access mode", HFILL }},
+ { &hf_afp_access_read,
+ { "read", "afp.access.read",
+ FT_BOOLEAN, 8, NULL, 1,
+ "open for reading", HFILL }},
+ { &hf_afp_access_write,
+ { "write", "afp.access.write",
+ FT_BOOLEAN, 8, NULL, 1,
+ "open for writing", HFILL }},
+ { &hf_afp_access_deny_read,
+ { "deny read", "afp.access.deny_read",
+ FT_BOOLEAN, 8, NULL, 1,
+ "deny read", HFILL }},
+ { &hf_afp_access_deny_write,
+ { "deny write", "afp.access.deny_write",
+ FT_BOOLEAN, 8, NULL, 1,
+ "deny write", HFILL }},
+
+ };
+
+ static gint *ett[] = {
+ &ett_afp,
+ &ett_afp_vol_bitmap,
+ &ett_afp_vol_attribute,
+ &ett_afp_dir_bitmap,
+ &ett_afp_file_bitmap,
+ &ett_afp_enumerate,
+ &ett_afp_enumerate_line,
+ &ett_afp_access_mode,
+ };
+
+ proto_afp = proto_register_protocol("AppleTalk Filing Protocol", "AFP", "afp");
+ proto_register_field_array(proto_afp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+
+ register_init_routine( &afp_reinit);
+
+ register_dissector("afp", dissect_afp, proto_afp);
+}
+
+void
+proto_reg_handoff_afp(void)
+{
+ data_handle = find_dissector("data");
+}
+
+/* -------------------------------
+ end
+*/