cd74eceeb3c640f3a26c0969e7ce75738005cc13
[obnox/wireshark/wip.git] / packet-afp.c
1 /* packet-afp.c
2  * Routines for afp packet dissection
3  * Copyright 2002, Didier Gautheron <dgautheron@magic.fr>
4  *
5  * $Id: packet-afp.c,v 1.1 2002/04/25 23:58:02 guy Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 1998 Gerald Combs
10  *
11  * Copied from README.developer
12  * Copied from packet-dsi.c
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  * 
19  * This program is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  * GNU General Public License for more details.
23  * 
24  * You should have received a copy of the GNU General Public License
25  * along with this program; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
27  */
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <stdio.h>
34
35 #ifdef HAVE_SYS_TYPES_H
36 # include <sys/types.h>
37 #endif
38
39 #ifdef HAVE_NETINET_IN_H
40 # include <netinet/in.h>
41 #endif
42
43 #ifdef NEED_SNPRINTF_H
44 # ifdef HAVE_STDARG_H
45 #  include <stdarg.h>
46 # else
47 #  include <varargs.h>
48 # endif
49 # include "snprintf.h"
50 #endif
51
52 #include <string.h>
53 #include <glib.h>
54 #include <epan/packet.h>
55 #include <epan/strutil.h>
56 #include <epan/conversation.h>
57
58 #include "packet-afp.h"
59
60 /* The information in this module (AFP) comes from:
61
62   AFP 2.1 & 2.2.pdf contained in AppleShare_IP_6.3_SDK
63   available from http://www.apple.com
64  
65   AFP3.0.pdf from http://www.apple.com
66   
67   The netatalk source code by Wesley Craig & Adrian Sun
68         http://netatalk.sf.net
69 */
70 /* from netatalk/include/afp.h */
71 #define AFPTRANS_NONE          0
72 #define AFPTRANS_DDP          (1 << 0)
73 #define AFPTRANS_TCP          (1 << 1)
74 #define AFPTRANS_ALL          (AFPTRANS_DDP | AFPTRANS_TCP)
75
76 /* server flags */
77 #define AFPSRVRINFO_COPY                        (1<<0)  /* supports copyfile */
78 #define AFPSRVRINFO_PASSWD                      (1<<1)  /* supports change password */
79 #define AFPSRVRINFO_NOSAVEPASSWD        (1<<2)  /* don't allow save password */
80 #define AFPSRVRINFO_SRVMSGS             (1<<3)  /* supports server messages */
81 #define AFPSRVRINFO_SRVSIGNATURE        (1<<4)  /* supports server signature */
82 #define AFPSRVRINFO_TCPIP               (1<<5)  /* supports tcpip */
83 #define AFPSRVRINFO_SRVNOTIFY           (1<<6)  /* supports server notifications */ 
84 #define AFPSRVRINFO_FASTBOZO            (1<<15) /* fast copying */
85
86 /* AFP Attention Codes -- 4 bits */
87 #define AFPATTN_SHUTDOWN     (1 << 15)            /* shutdown/disconnect */
88 #define AFPATTN_CRASH        (1 << 14)            /* server crashed */
89 #define AFPATTN_MESG         (1 << 13)            /* server has message */
90 #define AFPATTN_NORECONNECT  (1 << 12)            /* don't reconnect */
91 /* server notification */
92 #define AFPATTN_NOTIFY       (AFPATTN_MESG | AFPATTN_NORECONNECT) 
93
94 /* extended bitmap -- 12 bits. volchanged is only useful w/ a server
95  * notification, and time is only useful for shutdown. */
96 #define AFPATTN_VOLCHANGED   (1 << 0)             /* volume has changed */
97 #define AFPATTN_TIME(x)      ((x) & 0xfff)        /* time in minutes */
98
99 /* AFP functions */
100 #define AFP_BYTELOCK         1
101 #define AFP_CLOSEVOL             2
102 #define AFP_CLOSEDIR             3
103 #define AFP_CLOSEFORK            4
104 #define AFP_COPYFILE             5
105 #define AFP_CREATEDIR            6
106 #define AFP_CREATEFILE           7
107 #define AFP_DELETE                   8
108 #define AFP_ENUMERATE            9
109 #define AFP_FLUSH                   10
110 #define AFP_FLUSHFORK           11
111 #define AFP_GETFORKPARAM        14
112 #define AFP_GETSRVINFO          15
113 #define AFP_GETSRVPARAM         16
114 #define AFP_GETVOLPARAM         17
115 #define AFP_LOGIN               18
116 #define AFP_LOGINCONT           19
117 #define AFP_LOGOUT              20
118 #define AFP_MAPID                   21
119 #define AFP_MAPNAME                 22
120 #define AFP_MOVE                    23
121 #define AFP_OPENVOL             24
122 #define AFP_OPENDIR                 25
123 #define AFP_OPENFORK            26
124 #define AFP_READ                    27
125 #define AFP_RENAME                  28
126 #define AFP_SETDIRPARAM         29
127 #define AFP_SETFILEPARAM        30
128 #define AFP_SETFORKPARAM        31
129 #define AFP_SETVOLPARAM         32
130 #define AFP_WRITE                   33
131 #define AFP_GETFLDRPARAM        34
132 #define AFP_SETFLDRPARAM        35
133 #define AFP_CHANGEPW            36
134 #define AFP_GETSRVRMSG          38
135 #define AFP_CREATEID            39
136 #define AFP_DELETEID            40
137 #define AFP_RESOLVEID           41
138 #define AFP_EXCHANGEFILE        42
139 #define AFP_CATSEARCH           43
140 #define AFP_OPENDT                  48
141 #define AFP_CLOSEDT                 49
142 #define AFP_GETICON         51
143 #define AFP_GTICNINFO       52
144 #define AFP_ADDAPPL         53
145 #define AFP_RMVAPPL         54
146 #define AFP_GETAPPL         55
147 #define AFP_ADDCMT          56
148 #define AFP_RMVCMT          57
149 #define AFP_GETCMT          58
150 #define AFP_ADDICON        192
151
152 /* ----------------------------- */
153 static int proto_afp = -1;
154 static int hf_afp_flags = -1;
155 static int hf_afp_requestid = -1;
156 static int hf_afp_code = -1;
157 static int hf_afp_length = -1;
158 static int hf_afp_reserved = -1;
159
160 static int hf_afp_command = -1;         /* CommandCode */
161 static int hf_afp_AFPVersion = -1; 
162 static int hf_afp_UAM = -1; 
163 static int hf_afp_user = -1; 
164 static int hf_afp_passwd = -1; 
165 static int hf_afp_pad = -1;
166
167 static int hf_afp_vol_bitmap = -1;
168 static int hf_afp_bitmap_offset = -1;
169 static int hf_afp_vol_id = -1;
170 static int hf_afp_vol_attribute = -1;
171 static int hf_afp_vol_name = -1;
172 static int hf_afp_vol_signature = -1;
173 static int hf_afp_vol_creation_date = -1;
174 static int hf_afp_vol_modification_date = -1;
175 static int hf_afp_vol_backup_date = -1;
176 static int hf_afp_vol_bytes_free = -1;
177 static int hf_afp_vol_bytes_total = -1;
178 static int hf_afp_vol_ex_bytes_free = -1;
179 static int hf_afp_vol_ex_bytes_total = -1;
180 static int hf_afp_vol_block_size = -1;
181
182 static int hf_afp_did = -1;
183 static int hf_afp_file_id = -1;
184 static int hf_afp_dir_bitmap = -1;
185 static int hf_afp_dir_off_spring = -1;
186
187 static int hf_afp_file_bitmap = -1;
188 static int hf_afp_req_count = -1;
189 static int hf_afp_start_index = -1;
190 static int hf_afp_max_reply_size = -1;
191 static int hf_afp_file_flag = -1;
192 static int hf_afp_struct_size = -1;
193
194 static int hf_afp_creation_date = -1;
195 static int hf_afp_modification_date = -1;
196 static int hf_afp_backup_date = -1;
197 static int hf_afp_finder_info = -1;
198
199 static int hf_afp_path_type = -1;
200 static int hf_afp_path_name = -1;
201
202 static int hf_afp_flag    = -1;
203 static int hf_afp_ofork   = -1;
204 static int hf_afp_offset  = -1;
205 static int hf_afp_rw_count = 1;
206 static int hf_afp_fork_type                     = -1;
207 static int hf_afp_access_mode           = -1;
208 static int hf_afp_access_read           = -1;
209 static int hf_afp_access_write          = -1;
210 static int hf_afp_access_deny_read  = -1;
211 static int hf_afp_access_deny_write = -1;
212
213 static gint ett_afp = -1;
214
215 static gint ett_afp_vol_attribute = -1;
216 static gint ett_afp_enumerate = -1;
217 static gint ett_afp_enumerate_line = -1;
218 static gint ett_afp_access_mode = -1;
219
220 static gint ett_afp_vol_bitmap = -1;
221 static gint ett_afp_dir_bitmap = -1;
222 static gint ett_afp_file_bitmap = -1;
223
224 static dissector_handle_t afp_handle;
225 static dissector_handle_t data_handle;
226
227 static const value_string vol_signature_vals[] = {
228         {1, "Flat"},
229         {2,  "Fixed Directory ID"},
230         {3,  "Variable Directory ID (deprecated)"},
231         {0,                              NULL } };
232
233 static const value_string CommandCode_vals[] = {
234   {AFP_BYTELOCK,        "afpByteRangeLock" },
235   {AFP_CLOSEVOL,        "afpVolClose" },
236   {AFP_CLOSEDIR,        "afpDirClose" },
237   {AFP_CLOSEFORK,       "afpForkClose" },
238   {AFP_COPYFILE,        "afpCopyFile" },
239   {AFP_CREATEDIR,       "afpDirCreate" },
240   {AFP_CREATEFILE,      "afpFileCreate" },
241   {AFP_DELETE,          "afpDelete" },
242   {AFP_ENUMERATE,       "afpEnumerate" },
243   {AFP_FLUSH,           "afpFlush" },
244   {AFP_FLUSHFORK,       "afpForkFlush" },
245   {AFP_GETFORKPARAM,"afpGetForkParms" },
246   {AFP_GETSRVINFO,      "afpGetSInfo" },
247   {AFP_GETSRVPARAM,     "afpGetSParms" },
248   {AFP_GETVOLPARAM,     "afpGetVolParms" },
249   {AFP_LOGIN,           "afpLogin" },
250   {AFP_LOGINCONT,       "afpContLogin" },
251   {AFP_LOGOUT,          "afpLogout" },
252   {AFP_MAPID,           "afpMapID" },
253   {AFP_MAPNAME,         "afpMapName" },
254   {AFP_MOVE,            "afpMove" },
255   {AFP_OPENVOL,         "afpOpenVol" },
256   {AFP_OPENDIR,         "afpOpenDir" },
257   {AFP_OPENFORK,        "afpOpenFork" },
258   {AFP_READ,            "afpRead" },
259   {AFP_RENAME,          "afpRename" },
260   {AFP_SETDIRPARAM,     "afpSetDirParms" },
261   {AFP_SETFILEPARAM,"afpSetFileParms" },
262   {AFP_SETFORKPARAM,"afpSetForkParms" },
263   {AFP_SETVOLPARAM,     "afpSetVolParms" },
264   {AFP_WRITE,           "afpWrite" },
265   {AFP_GETFLDRPARAM,"afpGetFlDrParms" },
266   {AFP_SETFLDRPARAM,"afpSetFlDrParms" },
267   {AFP_CHANGEPW,        "afpChangePw" },
268   {AFP_GETSRVRMSG,      "afpGetSrvrMsg" },
269   {AFP_CREATEID,        "afpCreateID" },
270   {AFP_DELETEID,        "afpDeleteID" },
271   {AFP_RESOLVEID,       "afpResolveID" },
272   {AFP_EXCHANGEFILE,"afpExchangeFiles" },
273   {AFP_CATSEARCH,       "afpCatSearch" },
274   {AFP_OPENDT,          "afpDTOpen" },
275   {AFP_CLOSEDT,         "afpDTClose" },
276   {AFP_GETICON,         "afpGetIcon" },
277   {AFP_GTICNINFO,       "afpGtIcnInfo" },
278   {AFP_ADDAPPL,         "afpAddAPPL" },
279   {AFP_RMVAPPL,         "afpRmvAPPL" },
280   {AFP_GETAPPL,         "afpGetAPPL" },
281   {AFP_ADDCMT,          "afpAddCmt" },
282   {AFP_RMVCMT,          "afpRmvCmt" },
283   {AFP_GETCMT,          "afpGetCmt" },
284   {AFP_ADDICON,         "afpAddIcon" },
285   {0,                            NULL } };
286
287
288 /* volume bitmap
289   from Apple AFP3.0.pdf 
290   Table 1-2 p. 20
291 */
292 #define kFPVolAttributeBit              (1 << 0)
293 #define kFPVolSignatureBit              (1 << 1)
294 #define kFPVolCreateDateBit     (1 << 2)
295 #define kFPVolModDateBit                (1 << 3)
296 #define kFPVolBackupDateBit     (1 << 4)
297 #define kFPVolIDBit                     (1 << 5)
298 #define kFPVolBytesFreeBit      (1 << 6)
299 #define kFPVolBytesTotalBit             (1 << 7)
300 #define kFPVolNameBit                   (1 << 8)
301 #define kFPVolExtBytesFreeBit   (1 << 9)
302 #define kFPVolExtBytesTotalBit  (1 << 10)
303 #define kFPVolBlockSizeBit              (1 << 11)
304
305 static int hf_afp_vol_bitmap_Attribute          = -1;
306 static int hf_afp_vol_bitmap_Signature          = -1;
307 static int hf_afp_vol_bitmap_CreateDate         = -1;
308 static int hf_afp_vol_bitmap_ModDate            = -1;
309 static int hf_afp_vol_bitmap_BackupDate         = -1;
310 static int hf_afp_vol_bitmap_ID                         = -1;
311 static int hf_afp_vol_bitmap_BytesFree          = -1;
312 static int hf_afp_vol_bitmap_BytesTotal         = -1;
313 static int hf_afp_vol_bitmap_Name                       = -1;
314 static int hf_afp_vol_bitmap_ExtBytesFree       = -1;
315 static int hf_afp_vol_bitmap_ExtBytesTotal      = -1;
316 static int hf_afp_vol_bitmap_BlockSize          = -1;
317
318 static int hf_afp_vol_attribute_ReadOnly                    = -1;
319 static int hf_afp_vol_attribute_HasVolumePassword                       = -1;
320 static int hf_afp_vol_attribute_SupportsFileIDs             = -1;
321 static int hf_afp_vol_attribute_SupportsCatSearch           = -1;
322 static int hf_afp_vol_attribute_SupportsBlankAccessPrivs    = -1;
323 static int hf_afp_vol_attribute_SupportsUnixPrivs           = -1;
324 static int hf_afp_vol_attribute_SupportsUTF8Names           = -1;
325
326 static int hf_afp_dir_bitmap_Attribute          = -1;
327 static int hf_afp_dir_bitmap_ParentDirID    = -1;
328 static int hf_afp_dir_bitmap_CreateDate     = -1;
329 static int hf_afp_dir_bitmap_ModDate        = -1;
330 static int hf_afp_dir_bitmap_BackupDate     = -1;
331 static int hf_afp_dir_bitmap_FinderInfo     = -1;
332 static int hf_afp_dir_bitmap_LongName       = -1;
333 static int hf_afp_dir_bitmap_ShortName      = -1;
334 static int hf_afp_dir_bitmap_NodeID         = -1;
335 static int hf_afp_dir_bitmap_OffspringCount = -1;
336 static int hf_afp_dir_bitmap_OwnerID        = -1;
337 static int hf_afp_dir_bitmap_GroupID        = -1;
338 static int hf_afp_dir_bitmap_AccessRights   = -1;
339 static int hf_afp_dir_bitmap_UTF8Name       = -1;
340 static int hf_afp_dir_bitmap_UnixPrivs      = -1;
341
342 static int hf_afp_file_bitmap_Attribute          = -1;
343 static int hf_afp_file_bitmap_ParentDirID    = -1;
344 static int hf_afp_file_bitmap_CreateDate     = -1;
345 static int hf_afp_file_bitmap_ModDate        = -1;
346 static int hf_afp_file_bitmap_BackupDate     = -1;
347 static int hf_afp_file_bitmap_FinderInfo     = -1;
348 static int hf_afp_file_bitmap_LongName       = -1;
349 static int hf_afp_file_bitmap_ShortName      = -1;
350 static int hf_afp_file_bitmap_NodeID         = -1;
351 static int hf_afp_file_bitmap_OffspringCount = -1;
352 static int hf_afp_file_bitmap_UTF8Name       = -1;
353 static int hf_afp_file_bitmap_UnixPrivs      = -1;
354
355 static const value_string vol_bitmap_vals[] = {
356   {kFPVolAttributeBit,          "VolAttribute"},
357   {kFPVolSignatureBit,                  "VolSignature"},
358   {kFPVolCreateDateBit,                 "VolCreateDate"},
359   {kFPVolModDateBit,                    "VolModDate"},
360   {kFPVolBackupDateBit,                 "VolBackupDate"},
361   {kFPVolIDBit,                                 "VolID"},
362   {kFPVolBytesFreeBit,                  "VolBytesFree"},
363   {kFPVolBytesTotalBit,                 "VolBytesTotal"},
364   {kFPVolNameBit,                               "VolNameBit"},
365   {kFPVolExtBytesFreeBit,               "VolExtBytesFree"},
366   {kFPVolExtBytesTotalBit,              "VolExtBytesTotal"},
367   {kFPVolBlockSizeBit,                  "VolBlockSize"},
368   {0,                            NULL } };
369
370 static const value_string flag_vals[] = {
371   {0,   "Start" },
372   {1,   "End" },
373   {0,                   NULL } };
374
375 static const value_string path_type_vals[] = {
376   {1,   "Short names" },
377   {2,   "Long names" },
378   {3,   "Unicode names" },
379   {0,                   NULL } };
380
381 /*
382   volume attribute from Apple AFP3.0.pdf 
383   Table 1-3 p. 22
384 */
385 #define kReadOnly                                       (1 << 0)
386 #define kHasVolumePassword                      (1 << 1)
387 #define kSupportsFileIDs                        (1 << 2)
388 #define kSupportsCatSearch                      (1 << 3)
389 #define kSupportsBlankAccessPrivs       (1 << 4)
390 #define kSupportsUnixPrivs                      (1 << 5)
391 #define kSupportsUTF8Names                      (1 << 6)
392
393 /*
394   directory bitmap from Apple AFP3.0.pdf 
395   Table 1-4 p. 31
396 */
397 #define kFPAttributeBit                 (1 << 0)
398 #define kFPParentDirIDBit               (1 << 1)
399 #define kFPCreateDateBit                (1 << 2)
400 #define kFPModDateBit                   (1 << 3)
401 #define kFPBackupDateBit                (1 << 4)
402 #define kFPFinderInfoBit                (1 << 5)
403 #define kFPLongNameBit                  (1 << 6)
404 #define kFPShortNameBit                 (1 << 7)
405 #define kFPNodeIDBit                    (1 << 8)
406 #define kFPOffspringCountBit    (1 << 9)
407 #define kFPOwnerIDBit                   (1 << 10)
408 #define kFPGroupIDBit                   (1 << 11)
409 #define kFPAccessRightsBit              (1 << 12)
410 #define kFPUTF8NameBit                  (1 << 13)
411 #define kFPUnixPrivsBit                 (1 << 14)
412
413 /*
414   file bitmap AFP3.0.pdf 
415   Table 1-7 p. 36
416 same as dir
417 kFPAttributeBit                 (bit 0)
418 kFPParentDirIDBit               (bit 1)
419 kFPCreateDateBit                (bit 2)
420 kFPModDateBit                   (bit 3)
421 kFPBackupDateBit                (bit 4)
422 kFPFinderInfoBit                (bit 5)
423 kFPLongNameBit                  (bit 6)
424 kFPShortNameBit                 (bit 7)
425 kFPNodeIDBit                    (bit 8)
426
427 kFPUTF8NameBit                  (bit 13)
428 */
429
430 #define kFPDataForkLenBit                       (1 << 9)
431 #define kFPRsrcForkLenBit                       (1 << 10)
432 #define kFPExtDataForkLenBit            (1 << 11)
433 #define kFPLaunchLimitBit                       (1 << 12)
434
435 #define kFPExtRsrcForkLenBit            (1 << 14)
436 #define kFPUnixPrivsBit_file            (1 << 15)       /* :( */
437
438 #define hash_init_count 20
439
440 /* Hash functions */
441 static gint  afp_equal (gconstpointer v, gconstpointer v2);
442 static guint afp_hash  (gconstpointer v);
443  
444 static guint afp_packet_init_count = 200;
445
446 typedef struct {
447         guint32 conversation;
448         guint16 seq;
449 } afp_request_key;
450  
451 typedef struct {
452         guint8  command;
453 } afp_request_val;
454  
455 static GHashTable *afp_request_hash = NULL;
456 static GMemChunk *afp_request_keys = NULL;
457 static GMemChunk *afp_request_vals = NULL;
458
459 /* Hash Functions */
460 static gint  afp_equal (gconstpointer v, gconstpointer v2)
461 {
462         afp_request_key *val1 = (afp_request_key*)v;
463         afp_request_key *val2 = (afp_request_key*)v2;
464
465         if (val1->conversation == val2->conversation &&
466                         val1->seq == val2->seq) {
467                 return 1;
468         }
469         return 0;
470 }
471
472 static guint afp_hash  (gconstpointer v)
473 {
474         afp_request_key *afp_key = (afp_request_key*)v;
475         return afp_key->seq;
476 }
477
478 /* -------------------------- 
479 */
480 #define PAD(x)      { proto_tree_add_item(tree, hf_afp_pad, tvb, offset,  x, FALSE); offset += x; }
481
482 static guint16
483 decode_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
484 {
485         proto_tree *sub_tree = NULL;
486         proto_item *item;
487         guint16  bitmap;
488
489         bitmap = tvb_get_ntohs(tvb, offset);
490         if (tree) {
491                 item = proto_tree_add_item(tree, hf_afp_vol_bitmap, tvb, offset, 2,FALSE);
492                 sub_tree = proto_item_add_subtree(item, ett_afp_vol_bitmap);
493         }
494         
495         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Attribute,              tvb, offset, 2,FALSE);
496         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Signature,              tvb, offset, 2,FALSE);
497         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_CreateDate,     tvb, offset, 2,FALSE);
498         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ModDate,                tvb, offset, 2,FALSE);
499         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BackupDate,     tvb, offset, 2,FALSE);
500         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ID,                     tvb, offset, 2,FALSE);
501         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BytesFree,              tvb, offset, 2,FALSE);
502         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BytesTotal,     tvb, offset, 2,FALSE);
503         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Name,                   tvb, offset, 2,FALSE);
504         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ExtBytesFree,   tvb, offset, 2,FALSE);
505         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ExtBytesTotal,  tvb, offset, 2,FALSE);
506         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BlockSize ,     tvb, offset, 2,FALSE);
507
508         return bitmap;
509 }
510
511 /* -------------------------- */
512 static guint16
513 decode_vol_attribute (proto_tree *tree, tvbuff_t *tvb, gint offset)
514 {
515         proto_tree *sub_tree = NULL;
516         proto_item *item;
517         guint16  bitmap;
518
519         bitmap = tvb_get_ntohs(tvb, offset);
520         if (tree) {
521                 item = proto_tree_add_item(tree, hf_afp_vol_attribute, tvb, offset, 2,FALSE);
522                 sub_tree = proto_item_add_subtree(item, ett_afp_vol_attribute);
523         }
524         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_ReadOnly                ,tvb, offset, 2,FALSE);
525         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_HasVolumePassword       ,tvb, offset, 2,FALSE);
526         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsFileIDs         ,tvb, offset, 2,FALSE);
527         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsCatSearch       ,tvb, offset, 2,FALSE);
528         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsBlankAccessPrivs,tvb, offset, 2,FALSE);
529         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsUnixPrivs       ,tvb, offset, 2,FALSE);
530         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsUTF8Names       ,tvb, offset, 2,FALSE);
531                                                                                
532         return bitmap;                                                             
533 }                                                                              
534                                                                                
535 /* -------------------------- */
536 static gint
537 parse_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
538 {
539 guint16 nameoff = 0;
540
541         if ((bitmap & kFPVolAttributeBit)) {
542                 decode_vol_attribute(tree,tvb,offset);
543                 offset += 2;
544         }
545         if ((bitmap & kFPVolSignatureBit)) {
546                 proto_tree_add_item(tree, hf_afp_vol_signature,tvb, offset, 2, FALSE);
547                 offset += 2;
548         }
549         if ((bitmap & kFPVolCreateDateBit)) {
550                 proto_tree_add_item(tree, hf_afp_vol_creation_date,tvb, offset, 4, FALSE);
551                 offset += 4;
552         }
553         if ((bitmap & kFPVolModDateBit)) {
554                 proto_tree_add_item(tree, hf_afp_vol_modification_date,tvb, offset, 4, FALSE);
555                 offset += 4;
556         }
557         if ((bitmap & kFPVolBackupDateBit)) {
558                 proto_tree_add_item(tree, hf_afp_vol_backup_date,tvb, offset, 4, FALSE);
559                 offset += 4;
560         }
561         if ((bitmap & kFPVolIDBit)) {
562                 proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
563                 offset += 2;
564         }
565         if ((bitmap & kFPVolBytesFreeBit)) {
566                 proto_tree_add_item(tree, hf_afp_vol_bytes_free,tvb, offset, 4, FALSE);
567                 offset += 4;
568         }
569         if ((bitmap & kFPVolBytesTotalBit)) {
570                 proto_tree_add_item(tree, hf_afp_vol_bytes_total,tvb, offset, 4, FALSE);
571                 offset += 4;
572         }
573         if ((bitmap & kFPVolNameBit)) {
574                 nameoff = tvb_get_ntohs(tvb, offset);
575                 proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
576                 offset += 2;
577
578         }
579         if ((bitmap & kFPVolExtBytesFreeBit)) {
580                 proto_tree_add_item(tree, hf_afp_vol_ex_bytes_free,tvb, offset, 8, FALSE);
581                 offset += 8;
582         }
583         if ((bitmap & kFPVolExtBytesTotalBit)) {
584                 proto_tree_add_item(tree, hf_afp_vol_ex_bytes_total,tvb, offset, 8, FALSE);
585                 offset += 8;
586         }
587         if ((bitmap & kFPVolBlockSizeBit)) {
588                 proto_tree_add_item(tree, hf_afp_vol_block_size,tvb, offset, 4, FALSE);
589                 offset += 4;
590         }
591         if (nameoff) {
592         int len;
593
594                 len = tvb_get_guint8(tvb, offset);
595                 proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
596                 offset += len +1;
597
598         }
599         return offset;
600 }
601
602 /* -------------------------- */
603 static guint16
604 decode_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
605 {
606         proto_tree *sub_tree = NULL;
607         proto_item *item;
608         guint16         bitmap;
609
610         bitmap = tvb_get_ntohs(tvb, offset);
611         if (tree) {
612                 item = proto_tree_add_item(tree, hf_afp_file_bitmap, tvb, offset, 2,FALSE);
613                 sub_tree = proto_item_add_subtree(item, ett_afp_file_bitmap);
614         }
615         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_Attribute      , tvb, offset, 2,FALSE);  
616         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ParentDirID    , tvb, offset, 2,FALSE);
617         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_CreateDate     , tvb, offset, 2,FALSE);
618         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ModDate        , tvb, offset, 2,FALSE);
619         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_BackupDate     , tvb, offset, 2,FALSE);
620         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_FinderInfo     , tvb, offset, 2,FALSE);
621         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_LongName       , tvb, offset, 2,FALSE);
622         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ShortName      , tvb, offset, 2,FALSE);
623         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_NodeID         , tvb, offset, 2,FALSE);
624
625         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_UTF8Name          , tvb, offset, 2,FALSE);
626
627         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UnixPrivs      , tvb, offset, 2,FALSE);
628
629         return bitmap;
630 }
631
632 /* -------------------------- */
633 static gint
634 parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
635 {
636         guint16 lnameoff = 0;
637         guint16 snameoff = 0;
638         guint16 unameoff = 0;
639         gint    max_offset = 0;
640
641         gint    org_offset = offset;
642
643         if ((bitmap & kFPAttributeBit)) {
644                 offset += 2;
645         }
646         if ((bitmap & kFPParentDirIDBit)) {
647                 proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
648                 offset += 4;
649         }
650         if ((bitmap & kFPCreateDateBit)) {
651                 proto_tree_add_item(tree, hf_afp_creation_date,tvb, offset, 4, FALSE);
652                 offset += 4;
653         }
654         if ((bitmap & kFPModDateBit)) {
655                 proto_tree_add_item(tree, hf_afp_modification_date,tvb, offset, 4, FALSE);
656                 offset += 4;
657         }
658         if ((bitmap & kFPBackupDateBit)) {
659                 proto_tree_add_item(tree, hf_afp_backup_date,tvb, offset, 4, FALSE);
660                 offset += 4;
661         }
662         if ((bitmap & kFPFinderInfoBit)) {
663                 proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
664                 offset += 32;
665         }
666         if ((bitmap & kFPLongNameBit)) {
667         gint tp_ofs;
668         guint8 len;
669                 lnameoff = tvb_get_ntohs(tvb, offset);
670                 if (lnameoff) {
671                         tp_ofs = lnameoff +org_offset;
672                         proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
673                         len = tvb_get_guint8(tvb, tp_ofs);
674                         proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, 1,FALSE);
675                         tp_ofs += len +1;
676                         max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
677                 }
678                 offset += 2;
679         }
680         if ((bitmap & kFPShortNameBit)) {
681                 snameoff = tvb_get_ntohs(tvb, offset);
682                 proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
683                 offset += 2;
684         }
685         if ((bitmap & kFPNodeIDBit)) {
686                 proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
687                 offset += 4;
688         }
689
690         return offset;
691 }
692
693 /* -------------------------- */
694 static guint16 
695 decode_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
696 {
697         proto_tree *sub_tree = NULL;
698         proto_item *item;
699         guint16         bitmap;
700         
701         bitmap = tvb_get_ntohs(tvb, offset);
702         if (tree) {
703                 item = proto_tree_add_item(tree, hf_afp_dir_bitmap, tvb, offset, 2,FALSE);
704                 sub_tree = proto_item_add_subtree(item, ett_afp_dir_bitmap);
705         }
706         
707         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_Attribute      , tvb, offset, 2,FALSE);  
708         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ParentDirID    , tvb, offset, 2,FALSE);
709         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_CreateDate     , tvb, offset, 2,FALSE);
710         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ModDate        , tvb, offset, 2,FALSE);
711         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_BackupDate     , tvb, offset, 2,FALSE);
712         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_FinderInfo     , tvb, offset, 2,FALSE);
713         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_LongName       , tvb, offset, 2,FALSE);
714         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ShortName      , tvb, offset, 2,FALSE);
715         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_NodeID         , tvb, offset, 2,FALSE);
716         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_OffspringCount , tvb, offset, 2,FALSE);
717         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_OwnerID        , tvb, offset, 2,FALSE);
718         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_GroupID        , tvb, offset, 2,FALSE);
719         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_AccessRights   , tvb, offset, 2,FALSE);
720         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UTF8Name           , tvb, offset, 2,FALSE);
721         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UnixPrivs      , tvb, offset, 2,FALSE);
722
723         return bitmap;
724 }
725
726 /* -------------------------- */
727 static gint
728 parse_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
729 {
730         guint16 lnameoff = 0;
731         guint16 snameoff = 0;
732         guint16 unameoff = 0;
733         gint    max_offset = 0;
734
735         gint    org_offset = offset;
736
737         if ((bitmap & kFPAttributeBit)) {
738                 offset += 2;
739         }
740         if ((bitmap & kFPParentDirIDBit)) {
741                 proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
742                 offset += 4;
743         }
744         if ((bitmap & kFPCreateDateBit)) {
745                 proto_tree_add_item(tree, hf_afp_creation_date,tvb, offset, 4, FALSE);
746                 offset += 4;
747         }
748         if ((bitmap & kFPModDateBit)) {
749                 proto_tree_add_item(tree, hf_afp_modification_date,tvb, offset, 4, FALSE);
750                 offset += 4;
751         }
752         if ((bitmap & kFPBackupDateBit)) {
753                 proto_tree_add_item(tree, hf_afp_backup_date,tvb, offset, 4, FALSE);
754                 offset += 4;
755         }
756         if ((bitmap & kFPFinderInfoBit)) {
757                 proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
758                 offset += 32;
759         }
760         if ((bitmap & kFPLongNameBit)) {
761                 gint tp_ofs;
762                 guint8 len;
763                 lnameoff = tvb_get_ntohs(tvb, offset);
764                 if (lnameoff) {
765                         tp_ofs = lnameoff +org_offset;
766                         proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
767                         len = tvb_get_guint8(tvb, tp_ofs);
768                         proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, 1,FALSE);
769                         tp_ofs += len +1;
770                         max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
771                 }
772                 offset += 2;
773         }
774         if ((bitmap & kFPShortNameBit)) {
775                 snameoff = tvb_get_ntohs(tvb, offset);
776                 proto_tree_add_item(tree, hf_afp_bitmap_offset,tvb, offset, 2, FALSE);
777                 offset += 2;
778         }
779         if ((bitmap & kFPNodeIDBit)) {
780                 proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
781                 offset += 4;
782         }
783         if ((bitmap & kFPOffspringCountBit)) {
784                 proto_tree_add_item(tree, hf_afp_dir_off_spring, tvb, offset, 2,FALSE);
785                 offset += 2;            /* error in AFP3.0.pdf */
786         }
787         if ((bitmap & kFPOwnerIDBit)) {
788                 offset += 4;
789         }
790         if ((bitmap & kFPGroupIDBit)) {
791                 offset += 4;
792         }
793         if ((bitmap & kFPAccessRightsBit)) {
794                 offset += 4;
795         }
796         if ((bitmap & kFPUTF8NameBit)) {
797                 offset += 2;
798         }
799         if ((bitmap & kFPUnixPrivsBit)) {
800                 unameoff = tvb_get_ntohs(tvb, offset);
801                 offset += 4;
802         }
803         return (max_offset)?max_offset:offset;
804 }
805
806 /* -------------------------- */
807 static gchar *
808 name_in_bitmap(tvbuff_t *tvb, gint *offset, guint16 bitmap)
809 {
810         gchar *name;
811         gint    org_offset = *offset;
812         guint16 nameoff;
813         guint8  len;
814         gint    tp_ofs;
815         
816         name = NULL;
817         if ((bitmap & kFPAttributeBit)) 
818                 *offset += 2;
819         if ((bitmap & kFPParentDirIDBit))
820                 *offset += 4;
821         if ((bitmap & kFPCreateDateBit)) 
822                 *offset += 4;
823         if ((bitmap & kFPModDateBit))
824                 *offset += 4;
825         if ((bitmap & kFPBackupDateBit)) 
826                 *offset += 4;
827         if ((bitmap & kFPFinderInfoBit)) 
828                 *offset += 32;
829         
830         if ((bitmap & kFPLongNameBit)) {
831                 nameoff = tvb_get_ntohs(tvb, *offset);
832                 if (nameoff) {
833                         tp_ofs = nameoff +org_offset;
834                         len = tvb_get_guint8(tvb, tp_ofs);
835                         tp_ofs++;
836                         if (!(name = g_malloc(len +1)))
837                                 return name;
838                         tvb_memcpy(tvb, name, tp_ofs, len);
839                         *(name +len) = 0;
840                         return name;
841                 }
842         }
843         /* short name ? */
844         return name;
845 }
846
847 /* -------------------------- */
848 static gchar *
849 name_in_dbitmap(tvbuff_t *tvb, gint offset, guint16 bitmap)
850 {
851         gchar *name;
852         
853         name = name_in_bitmap(tvb, &offset, bitmap);
854         if (name != NULL)
855                 return name;
856         /*
857                 check UTF8 name 
858         */
859         
860         return name;
861 }
862
863 /* -------------------------- */
864 static gchar *
865 name_in_fbitmap(tvbuff_t *tvb, gint offset, guint16 bitmap)
866 {
867         gchar *name;
868         
869         name = name_in_bitmap(tvb, &offset, bitmap);
870         if (name != NULL)
871                 return name;
872         /*
873                 check UTF8 name 
874         */
875         
876         return name;
877 }
878
879 /* -------------------------- */
880 static gint
881 decode_vol_did_file_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
882 {
883         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
884         offset += 2;
885
886         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
887         offset += 4;
888
889         decode_file_bitmap(tree, tvb, offset);
890         offset += 2;
891         
892         decode_dir_bitmap(tree, tvb, offset);
893         offset += 2;
894         
895         return offset;
896 }
897
898 /* -------------------------- */
899 static gint
900 decode_name (proto_tree *tree, tvbuff_t *tvb, gint offset)
901 {
902         int len;
903
904         proto_tree_add_item(tree, hf_afp_path_type, tvb, offset, 1,FALSE);
905         offset += 1;
906
907         len = tvb_get_guint8(tvb, offset);
908         proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, 1,FALSE);
909         offset += len +1;
910
911         return offset;
912 }
913
914 /* ************************** */
915 static gint
916 dissect_query_afp_open_vol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
917 {
918         int len;
919         
920         PAD(1);
921
922         decode_vol_bitmap(tree, tvb, offset);
923         offset += 2;
924         
925         len = tvb_get_guint8(tvb, offset);
926 #if 0   
927         if (check_col(pinfo->cinfo, COL_INFO)) {
928                 gchar   *func_str;
929
930                 if ((func_str = match_strval(afp_command, CommandCode_vals)))
931                 {
932                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", func_str, aspinfo->reply?"reply":"");
933                 }
934         }
935 #endif  
936         proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
937         offset += len +1;
938                 
939         len = tvb_reported_length_remaining(tvb,offset);
940         if (len >= 8) {
941                 /* optionnal password */
942                 proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, 8,FALSE);
943                 offset += 8;
944         }
945         return offset;
946 }
947
948 /* -------------------------- */
949 static gint
950 dissect_reply_afp_open_vol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
951 {
952         guint16 bitmap;
953
954         bitmap = decode_vol_bitmap(tree, tvb, offset);
955         offset += 2;
956         offset = parse_vol_bitmap(tree, tvb, offset, bitmap);
957
958         return offset;
959 }
960
961 /* ************************** */
962 static gint
963 dissect_query_afp_open_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
964 {
965         proto_tree *sub_tree = NULL;
966         proto_item *item;
967
968         proto_tree_add_item(tree, hf_afp_fork_type, tvb, offset, 1,FALSE);
969         offset++;
970         
971         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
972         offset += 2;
973
974         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
975         offset += 4;
976
977         decode_file_bitmap(tree, tvb, offset);
978         offset += 2;
979         if (tree) {
980                 item = proto_tree_add_item(tree, hf_afp_access_mode, tvb, offset, 2,FALSE);
981                 sub_tree = proto_item_add_subtree(item, ett_afp_access_mode);
982         }
983         item = proto_tree_add_item(sub_tree, hf_afp_access_read      , tvb, offset, 2,FALSE);
984         item = proto_tree_add_item(sub_tree, hf_afp_access_write     , tvb, offset, 2,FALSE);
985         item = proto_tree_add_item(sub_tree, hf_afp_access_deny_read , tvb, offset, 2,FALSE);
986         item = proto_tree_add_item(sub_tree, hf_afp_access_deny_write, tvb, offset, 2,FALSE);
987
988         offset += 2;
989
990         offset = decode_name(tree,tvb, offset);
991
992         return offset;
993 }
994
995 /* -------------------------- */
996 static gint
997 dissect_reply_afp_open_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
998 {
999         int f_bitmap;
1000
1001         f_bitmap = decode_file_bitmap(tree, tvb, offset);
1002         offset += 2;
1003
1004         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
1005         offset += 2;
1006
1007         offset = parse_file_bitmap(tree, tvb, offset, f_bitmap);
1008
1009         return offset;
1010 }
1011
1012 /* ************************** */
1013 static gint
1014 dissect_query_afp_enumerate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1015 {
1016         
1017         PAD(1);
1018         offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
1019
1020         proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
1021         offset += 2;
1022
1023         proto_tree_add_item(tree, hf_afp_start_index, tvb, offset, 2,FALSE);
1024         offset += 2;
1025
1026         proto_tree_add_item(tree, hf_afp_max_reply_size, tvb, offset, 2,FALSE);
1027         offset += 2;
1028
1029         offset = decode_name(tree,tvb, offset);
1030
1031         return offset;
1032 }
1033
1034 /* -------------------------- */
1035 static gint
1036 dissect_reply_afp_enumerate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1037 {
1038         proto_tree *sub_tree = NULL;
1039         proto_item *item;
1040         int count;
1041         int f_bitmap;
1042         int d_bitmap;
1043         guint8  flags;
1044         guint8  size;
1045         gint    org;
1046         int i;
1047         gchar *name;
1048         
1049         f_bitmap = decode_file_bitmap(tree, tvb, offset);
1050         offset += 2;
1051         
1052         d_bitmap = decode_dir_bitmap(tree, tvb, offset);
1053         offset += 2;
1054
1055         count = tvb_get_ntohs(tvb, offset);
1056         if (tree) {
1057                 item = proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
1058                 sub_tree = proto_item_add_subtree(item, ett_afp_enumerate);
1059         }
1060         offset += 2;
1061         /* loop */
1062         if (tree) for (i = 0; i < count; i++) {
1063                 org = offset;
1064                 name = NULL;
1065                 size = tvb_get_guint8(tvb, offset);
1066                 flags = tvb_get_guint8(tvb, offset +1);
1067
1068                 if (flags) {
1069                         name = name_in_dbitmap(tvb, offset +2, d_bitmap);
1070                 }
1071                 else {
1072                         name = name_in_fbitmap(tvb, offset +2, f_bitmap);
1073                 }
1074                 if (!name) {
1075                         if (!(name = g_malloc(50))) { /* no memory ! */
1076                         }
1077                         snprintf(name, 50,"line %d", i +1);
1078                 }
1079                 item = proto_tree_add_text(sub_tree, tvb, offset, size, name);
1080                 tree = proto_item_add_subtree(item, ett_afp_enumerate_line);
1081
1082                 proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1,FALSE);
1083                 offset++;
1084
1085                 proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
1086                 offset++;
1087                 if (flags) {
1088                         offset = parse_dir_bitmap(tree, tvb, offset, d_bitmap);
1089                 }
1090                 else {
1091                         offset = parse_file_bitmap(tree, tvb, offset, f_bitmap);
1092                 }
1093                 if ((offset & 1)) 
1094                         PAD(1);
1095                 offset = org +size;             /* play safe */
1096                 g_free((gpointer)name);
1097         }       
1098         return(offset);
1099
1100 }
1101
1102 /* **************************/
1103 static gint
1104 dissect_query_afp_get_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1105 {
1106         if (!tree)
1107                 return offset;
1108         PAD(1)
1109         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
1110         offset += 2;
1111
1112         decode_vol_bitmap(tree, tvb, offset);
1113         offset += 2;
1114         
1115         return offset;  
1116 }
1117
1118 /* ------------------------ */
1119 static gint
1120 dissect_reply_afp_get_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1121 {
1122         guint16 bitmap;
1123
1124         if (!tree)
1125                 return offset;
1126         bitmap = decode_vol_bitmap(tree, tvb, offset);
1127         offset += 2;
1128
1129         offset = parse_vol_bitmap(tree, tvb, offset, bitmap);
1130
1131         return offset;
1132 }
1133
1134 /* ***************************/
1135 static gint
1136 dissect_query_afp_login(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1137 {
1138         int len;
1139         
1140         if (!tree)
1141                 return offset;
1142         len = tvb_get_guint8(tvb, offset);
1143         proto_tree_add_item(tree, hf_afp_AFPVersion, tvb, offset, 1,FALSE);
1144         offset += len +1;
1145         len = tvb_get_guint8(tvb, offset);
1146         proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1,FALSE);
1147         offset += len +1;
1148
1149         /* clear text */
1150         len = tvb_get_guint8(tvb, offset);
1151         proto_tree_add_item(tree, hf_afp_user, tvb, offset, 1,FALSE);
1152         offset += len +1;
1153
1154         len = tvb_strsize(tvb, offset);
1155         proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, len,FALSE);
1156         offset += len;
1157
1158         return(offset);
1159 }
1160
1161 /* ************************** */
1162 static gint
1163 dissect_query_afp_write(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1164 {
1165         int len;
1166         
1167         if (!tree)
1168                 return offset;
1169         proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1,FALSE);
1170         offset += 1;
1171
1172         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
1173         offset += 2;
1174
1175         proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4,FALSE);
1176         offset += 4;
1177
1178         proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4,FALSE);
1179         offset += 4;
1180
1181         return offset;
1182 }
1183
1184 /* ************************** */
1185 static gint
1186 dissect_query_afp_get_fldr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1187 {
1188         if (!tree)
1189                 return offset;
1190         PAD(1);
1191         offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
1192
1193         offset = decode_name(tree, tvb, offset);
1194
1195         return offset;
1196 }
1197
1198 /* -------------------------- */
1199 static gint
1200 dissect_reply_afp_get_fldr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1201 {
1202 guint8  flags;
1203 guint16 f_bitmap, d_bitmap;
1204
1205         if (!tree)
1206                 return offset;
1207         f_bitmap = decode_file_bitmap(tree, tvb, offset);
1208         offset += 2;
1209         
1210         d_bitmap = decode_dir_bitmap(tree, tvb, offset);
1211         offset += 2;
1212
1213         flags = tvb_get_guint8(tvb, offset);
1214         proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
1215         offset++;
1216         PAD(1);
1217         if (flags) {
1218                 offset = parse_dir_bitmap(tree, tvb, offset, d_bitmap);
1219         }
1220         else {
1221                 offset = parse_file_bitmap(tree, tvb, offset, f_bitmap);
1222         }
1223         return offset;
1224 }
1225
1226 /* ************************** */
1227 static void
1228 dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1229 {
1230         struct aspinfo *aspinfo = pinfo->private_data;
1231         proto_tree      *afp_tree = NULL;
1232         proto_item      *ti;
1233         conversation_t  *conversation;
1234         gint            offset = 0;
1235         afp_request_key request_key, *new_request_key;
1236         afp_request_val *request_val;
1237
1238         gchar   *func_str;
1239
1240         guint8  afp_flags,afp_command;
1241         guint16 afp_requestid;
1242         gint32  afp_code;
1243         guint32 afp_length;
1244         guint32 afp_reserved;
1245         int     len =  tvb_reported_length_remaining(tvb,0);
1246         
1247         if (check_col(pinfo->cinfo, COL_PROTOCOL))
1248                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AFP");
1249         if (check_col(pinfo->cinfo, COL_INFO))
1250                 col_clear(pinfo->cinfo, COL_INFO);
1251
1252         conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
1253                 pinfo->srcport, pinfo->destport, 0);
1254
1255         if (conversation == NULL)
1256         {
1257                 conversation = conversation_new(&pinfo->src, &pinfo->dst,
1258                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1259         }
1260
1261         request_key.conversation = conversation->index; 
1262         request_key.seq = aspinfo->seq;
1263
1264         request_val = (afp_request_val *) g_hash_table_lookup(
1265                                                                 afp_request_hash, &request_key);
1266
1267         if (!request_val && !aspinfo->reply)  {
1268                 afp_command = tvb_get_guint8(tvb, offset);
1269                 new_request_key = g_mem_chunk_alloc(afp_request_keys);
1270                 *new_request_key = request_key;
1271
1272                 request_val = g_mem_chunk_alloc(afp_request_vals);
1273                 request_val->command = tvb_get_guint8(tvb, offset);
1274
1275                 g_hash_table_insert(afp_request_hash, new_request_key,
1276                                                                 request_val);
1277         }
1278
1279         if (!request_val) {     /* missing request */
1280                 return;
1281         }
1282
1283         afp_command = request_val->command;
1284         if (check_col(pinfo->cinfo, COL_INFO)) {
1285                 gchar   *func_str;
1286
1287                 if ((func_str = match_strval(afp_command, CommandCode_vals)))
1288                 {
1289                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s", func_str, aspinfo->reply?"reply":"");
1290                 }
1291         }
1292
1293         if (tree)
1294         {
1295                 ti = proto_tree_add_item(tree, proto_afp, tvb, offset, -1,FALSE);
1296                 afp_tree = proto_item_add_subtree(ti, ett_afp);
1297         }
1298         if (!aspinfo->reply)  {
1299                 proto_tree_add_uint(afp_tree, hf_afp_command, tvb,offset, 1, afp_command);
1300                 offset++;
1301                 switch(afp_command) {
1302                 case AFP_BYTELOCK:
1303                 case AFP_CLOSEVOL:
1304                 case AFP_CLOSEDIR:
1305                 case AFP_CLOSEFORK:
1306                 case AFP_COPYFILE:
1307                 case AFP_CREATEDIR:
1308                 case AFP_CREATEFILE:
1309                 case AFP_DELETE:
1310                         break;
1311                 case AFP_ENUMERATE:
1312                         offset = dissect_query_afp_enumerate(tvb, pinfo, afp_tree, offset);break;
1313                 case AFP_FLUSH:
1314                 case AFP_FLUSHFORK:
1315                 case AFP_GETFORKPARAM:
1316                 case AFP_GETSRVINFO:
1317                 case AFP_GETSRVPARAM:
1318                         break;
1319                 case AFP_GETVOLPARAM:
1320                         offset = dissect_query_afp_get_vol_param(tvb, pinfo, afp_tree, offset);break;
1321                 case AFP_LOGIN:
1322                         offset = dissect_query_afp_login(tvb, pinfo, afp_tree, offset);break;
1323                 case AFP_LOGINCONT:
1324                 case AFP_LOGOUT:
1325                 case AFP_MAPID:
1326                 case AFP_MAPNAME:
1327                 case AFP_MOVE:
1328                         break;
1329                 case AFP_OPENVOL:
1330                         offset = dissect_query_afp_open_vol(tvb, pinfo, afp_tree, offset);break;
1331                 case AFP_OPENDIR:
1332                         break;
1333                 case AFP_OPENFORK:
1334                         offset = dissect_query_afp_open_fork(tvb, pinfo, afp_tree, offset);break;
1335                 case AFP_READ:
1336                 case AFP_RENAME:
1337                 case AFP_SETDIRPARAM:
1338                 case AFP_SETFILEPARAM:
1339                 case AFP_SETFORKPARAM:
1340                 case AFP_SETVOLPARAM:
1341                         break;
1342                 case AFP_WRITE:
1343                         offset = dissect_query_afp_write(tvb, pinfo, afp_tree, offset);break;
1344                 case AFP_GETFLDRPARAM:
1345                         offset = dissect_query_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);break;
1346                 case AFP_SETFLDRPARAM:
1347                 case AFP_CHANGEPW:
1348                 case AFP_GETSRVRMSG:
1349                 case AFP_CREATEID:
1350                 case AFP_DELETEID:
1351                 case AFP_RESOLVEID:
1352                 case AFP_EXCHANGEFILE:
1353                 case AFP_CATSEARCH:
1354                 case AFP_OPENDT:
1355                 case AFP_CLOSEDT:
1356                 case AFP_GETICON:
1357                 case AFP_GTICNINFO:
1358                 case AFP_ADDAPPL:
1359                 case AFP_RMVAPPL:
1360                 case AFP_GETAPPL:
1361                 case AFP_ADDCMT:
1362                 case AFP_RMVCMT:
1363                 case AFP_GETCMT:
1364                 case AFP_ADDICON:
1365                         break;
1366                 }
1367         }
1368         else {
1369                 switch(afp_command) {
1370                 case AFP_ENUMERATE:
1371                         offset = dissect_reply_afp_enumerate(tvb, pinfo, afp_tree, offset);break;
1372                 case AFP_OPENVOL:
1373                         offset = dissect_reply_afp_open_vol(tvb, pinfo, afp_tree, offset);break;
1374                 case AFP_OPENFORK:
1375                         offset = dissect_reply_afp_open_fork(tvb, pinfo, afp_tree, offset);break;
1376                 case AFP_FLUSH:
1377                 case AFP_FLUSHFORK:
1378                 case AFP_GETFORKPARAM:
1379                 case AFP_GETSRVINFO:
1380                 case AFP_GETSRVPARAM:
1381                         break;
1382                 case AFP_GETVOLPARAM:
1383                         offset = dissect_reply_afp_get_vol_param(tvb, pinfo, afp_tree, offset);break;
1384                 case AFP_GETFLDRPARAM:
1385                         offset = dissect_reply_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);break;
1386                 }
1387         }
1388         if (tree && offset < len)
1389                 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,tvb_reported_length_remaining(tvb,offset)), pinfo, afp_tree);
1390 }
1391
1392 static void afp_reinit( void)
1393 {
1394
1395         if (afp_request_hash)
1396                 g_hash_table_destroy(afp_request_hash);
1397         if (afp_request_keys)
1398                 g_mem_chunk_destroy(afp_request_keys);
1399         if (afp_request_vals)
1400                 g_mem_chunk_destroy(afp_request_vals);
1401
1402         afp_request_hash = g_hash_table_new(afp_hash, afp_equal);
1403
1404         afp_request_keys = g_mem_chunk_new("afp_request_keys",
1405                 sizeof(afp_request_key),
1406                 afp_packet_init_count * sizeof(afp_request_key),
1407                 G_ALLOC_AND_FREE);
1408         afp_request_vals = g_mem_chunk_new("afp_request_vals",
1409                 sizeof(afp_request_val),
1410                 afp_packet_init_count * sizeof(afp_request_val),
1411                 G_ALLOC_AND_FREE);
1412
1413 }
1414
1415 void
1416 proto_register_afp(void)
1417 {
1418
1419   static hf_register_info hf[] = {
1420     { &hf_afp_command,
1421       { "Command",      "afp.command",
1422                 FT_UINT8, BASE_DEC, VALS(CommandCode_vals), 0x0,
1423         "AFP function", HFILL }},
1424
1425         { &hf_afp_pad,    
1426           { "pad",              "afp.pad",    
1427                 FT_NONE,   BASE_NONE, NULL, 0, 
1428                 "Pad Byte",     HFILL }},
1429
1430     { &hf_afp_AFPVersion,
1431       { "AFP Version",  "afp.AFPVersion",
1432                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1433         "client AFP version", HFILL }},
1434
1435     { &hf_afp_UAM,
1436       { "UAM",          "afp.UAM",
1437                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1438         "USer Authentication method", HFILL }},
1439
1440     { &hf_afp_user,
1441       { "user",         "afp.user",
1442                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1443         "User", HFILL }},
1444
1445     { &hf_afp_passwd,
1446       { "password",     "afp.passwd",
1447                 FT_STRINGZ, BASE_NONE, NULL, 0x0,
1448         "password", HFILL }},
1449
1450     { &hf_afp_vol_bitmap,
1451       { "bitmap",         "afp.vol_bitmap",
1452                 FT_UINT16, BASE_HEX, NULL, 0 /* 0x0FFF*/,
1453         "Volume bitmap", HFILL }},
1454
1455         { &hf_afp_vol_bitmap_Attribute,
1456       { "attribute",         "afp.vol_bitmap.attribute",
1457                 FT_BOOLEAN, 16, NULL, kFPVolAttributeBit,
1458         "Volume attribute", HFILL }},
1459
1460             { &hf_afp_vol_attribute, { "attribute",         "afp.vol_attribute",
1461                         FT_UINT16, BASE_HEX, NULL, 0 , "Volume attribute", HFILL }},
1462
1463             { &hf_afp_vol_attribute_ReadOnly, 
1464              { "read only",         "afp.vol_attribute.read_only",
1465                  FT_BOOLEAN, 16, NULL, kReadOnly,
1466          "Read only volume", HFILL }},
1467
1468             { &hf_afp_vol_attribute_HasVolumePassword,
1469              { "volume password",         "afp.vol_attribute.passwd",
1470                  FT_BOOLEAN, 16, NULL, kHasVolumePassword,
1471          "Has a volume password", HFILL }},
1472
1473             { &hf_afp_vol_attribute_SupportsFileIDs,
1474              { "files ID",         "afp.vol_attribute.fileIDs",
1475                  FT_BOOLEAN, 16, NULL, kSupportsFileIDs,
1476          "Supports files ID", HFILL }},
1477
1478             { &hf_afp_vol_attribute_SupportsCatSearch,
1479              { "cat search",         "afp.vol_attribute.cat_search",
1480                  FT_BOOLEAN, 16, NULL, kSupportsCatSearch,
1481          "Supports cat search call", HFILL }},
1482
1483             { &hf_afp_vol_attribute_SupportsBlankAccessPrivs,
1484              { "blank access privs",         "afp.vol_attribute.blank_access_privs",
1485                  FT_BOOLEAN, 16, NULL, kSupportsBlankAccessPrivs,
1486          "Supports blank access priv.", HFILL }},
1487
1488             { &hf_afp_vol_attribute_SupportsUnixPrivs,
1489             { "blank access privs",         "afp.vol_attribute.unix_privs",
1490                  FT_BOOLEAN, 16, NULL, kSupportsUnixPrivs,
1491          "Supports Unix access priv.", HFILL }},
1492
1493             { &hf_afp_vol_attribute_SupportsUTF8Names,
1494             { "blank access privs",         "afp.vol_attribute.utf8_names",
1495                  FT_BOOLEAN, 16, NULL, kSupportsUTF8Names,
1496          "Supports UTF8 names.", HFILL }},
1497
1498     { &hf_afp_vol_bitmap_Signature,
1499       { "signature",         "afp.vol_bitmap.signature",
1500                 FT_BOOLEAN, 16, NULL, kFPVolSignatureBit,
1501         "Volume signature", HFILL }},
1502     { &hf_afp_vol_bitmap_CreateDate,
1503       { "creation date",      "afp.vol_bitmap.create_date",
1504                 FT_BOOLEAN, 16, NULL, kFPVolCreateDateBit,
1505         "Volume creation date", HFILL }},
1506     { &hf_afp_vol_bitmap_ModDate,
1507       { "modification date",  "afp.vol_bitmap.mod_date",
1508                 FT_BOOLEAN, 16, NULL, kFPVolModDateBit,
1509         "Volume modification date", HFILL }},
1510     { &hf_afp_vol_bitmap_BackupDate,
1511       { "backup date",        "afp.vol_bitmap.backup_date",
1512                 FT_BOOLEAN, 16, NULL, kFPVolBackupDateBit,
1513         "Volume backup date", HFILL }},
1514     { &hf_afp_vol_bitmap_ID,
1515       { "ID",         "afp.vol_bitmap.id",
1516                 FT_BOOLEAN, 16, NULL,  kFPVolIDBit,
1517         "Volume ID", HFILL }},
1518     { &hf_afp_vol_bitmap_BytesFree,
1519       { "bytes free",         "afp.vol_bitmap.bytes_free",
1520                 FT_BOOLEAN, 16, NULL,  kFPVolBytesFreeBit,
1521         "Volume free bytes", HFILL }},
1522     { &hf_afp_vol_bitmap_BytesTotal,
1523       { "bytes total",         "afp.vol_bitmap.bytes_total",
1524                 FT_BOOLEAN, 16, NULL,  kFPVolBytesTotalBit,
1525         "Volume total bytes", HFILL }},
1526     { &hf_afp_vol_bitmap_Name,
1527       { "name",         "afp.vol_bitmap.name",
1528                 FT_BOOLEAN, 16, NULL,  kFPVolNameBit,
1529         "Volume name", HFILL }},
1530     { &hf_afp_vol_bitmap_ExtBytesFree,
1531       { "ex. bytes free",         "afp.vol_bitmap.ex_bytes_free",
1532                 FT_BOOLEAN, 16, NULL,  kFPVolExtBytesFreeBit,
1533         "Volume ext. free bytes", HFILL }},
1534     { &hf_afp_vol_bitmap_ExtBytesTotal,
1535       { "ex bytes total",         "afp.vol_bitmap.ex_bytes_total",
1536                 FT_BOOLEAN, 16, NULL,  kFPVolExtBytesTotalBit,
1537         "Volume ex. total byte", HFILL }},
1538     { &hf_afp_vol_bitmap_BlockSize,
1539       { "block size",         "afp.vol_bitmap.block_size",
1540                 FT_BOOLEAN, 16, NULL,  kFPVolBlockSizeBit,
1541         "Volume block size", HFILL }},
1542
1543     { &hf_afp_dir_bitmap_Attribute,        
1544       { "attribute",         "afp.dir_bitmap.attribute",
1545             FT_BOOLEAN, 16, NULL,  kFPAttributeBit,
1546         "directory attribute", HFILL }},
1547     { &hf_afp_dir_bitmap_ParentDirID,      
1548       { "DID",         "afp.dir_bitmap.did",
1549         FT_BOOLEAN, 16, NULL,  kFPParentDirIDBit,
1550         "parent directory ID", HFILL }},
1551     { &hf_afp_dir_bitmap_CreateDate,       
1552       { "creation date",         "afp.dir_bitmap.create_date",
1553             FT_BOOLEAN, 16, NULL,  kFPCreateDateBit,
1554         "directory creation date", HFILL }},
1555     { &hf_afp_dir_bitmap_ModDate,                  
1556       { "modification date",         "afp.dir_bitmap.mod_date",
1557         FT_BOOLEAN, 16, NULL,  kFPModDateBit,
1558         "directory modification date", HFILL }},
1559     { &hf_afp_dir_bitmap_BackupDate,       
1560       { "backup date",         "afp.dir_bitmap.backup_date",
1561             FT_BOOLEAN, 16, NULL,  kFPBackupDateBit,
1562         "directory backup date", HFILL }},
1563     { &hf_afp_dir_bitmap_FinderInfo,       
1564       { "Finder info",         "afp.dir_bitmap.finder_info",
1565         FT_BOOLEAN, 16, NULL,  kFPFinderInfoBit,
1566         "directory finder info", HFILL }},
1567     { &hf_afp_dir_bitmap_LongName,                 
1568       { "long name",         "afp.dir_bitmap.long_name",
1569             FT_BOOLEAN, 16, NULL,  kFPLongNameBit,
1570         "directory long name", HFILL }},
1571     { &hf_afp_dir_bitmap_ShortName,                
1572       { "short name",         "afp.dir_bitmap.short_name",
1573         FT_BOOLEAN, 16, NULL,  kFPShortNameBit,
1574         "directory short name", HFILL }},
1575     { &hf_afp_dir_bitmap_NodeID,                   
1576       { "file ID",         "afp.dir_bitmap.fid",
1577             FT_BOOLEAN, 16, NULL,  kFPNodeIDBit,
1578         "directory file ID", HFILL }},
1579     { &hf_afp_dir_bitmap_OffspringCount,   
1580       { "offspring count",         "afp.dir_bitmap.off_spring_count",
1581         FT_BOOLEAN, 16, NULL,  kFPOffspringCountBit,
1582         "directory offSpring count", HFILL }},
1583     { &hf_afp_dir_bitmap_OwnerID,                  
1584       { "owner id",         "afp.dir_bitmap.owner_id",
1585             FT_BOOLEAN, 16, NULL,  kFPOwnerIDBit,
1586         "directory owner id", HFILL }},
1587     { &hf_afp_dir_bitmap_GroupID,                  
1588       { "group id",         "afp.dir_bitmap.group_id",
1589         FT_BOOLEAN, 16, NULL,  kFPGroupIDBit,
1590         "directory group id", HFILL }},
1591     { &hf_afp_dir_bitmap_AccessRights,     
1592       { "access rights",         "afp.dir_bitmap.access_rights",
1593             FT_BOOLEAN, 16, NULL,  kFPAccessRightsBit,
1594         "directory access rights", HFILL }},
1595     { &hf_afp_dir_bitmap_UTF8Name,                 
1596       { "UTF8 name",         "afp.dir_bitmap.UTF8_name",
1597         FT_BOOLEAN, 16, NULL,  kFPUTF8NameBit,
1598         "directory UTF8 name", HFILL }},
1599     { &hf_afp_dir_bitmap_UnixPrivs,                
1600       { "unix privs",         "afp.dir_bitmap.unix_privs",
1601             FT_BOOLEAN, 16, NULL,  kFPUnixPrivsBit,
1602         "directory unix privs", HFILL }},
1603
1604     { &hf_afp_file_bitmap_Attribute,        
1605       { "attribute",         "afp.file_bitmap.attribute",
1606             FT_BOOLEAN, 16, NULL,  kFPAttributeBit,
1607         "file attribute", HFILL }},
1608     { &hf_afp_file_bitmap_ParentDirID,     
1609       { "DID",         "afp.file_bitmap.did",
1610         FT_BOOLEAN, 16, NULL,  kFPParentDirIDBit,
1611         "parent directory ID", HFILL }},
1612     { &hf_afp_file_bitmap_CreateDate,      
1613       { "creation date",         "afp.file_bitmap.create_date",
1614             FT_BOOLEAN, 16, NULL,  kFPCreateDateBit,
1615         "file creation date", HFILL }},
1616     { &hf_afp_file_bitmap_ModDate,                 
1617       { "modification date",         "afp.file_bitmap.mod_date",
1618         FT_BOOLEAN, 16, NULL,  kFPModDateBit,
1619         "file modification date", HFILL }},
1620     { &hf_afp_file_bitmap_BackupDate,      
1621       { "backup date",         "afp.file_bitmap.backup_date",
1622             FT_BOOLEAN, 16, NULL,  kFPBackupDateBit,
1623         "file backup date", HFILL }},
1624     { &hf_afp_file_bitmap_FinderInfo,      
1625       { "Finder info",         "afp.file_bitmap.finder_info",
1626         FT_BOOLEAN, 16, NULL,  kFPFinderInfoBit,
1627         "file finder info", HFILL }},
1628     { &hf_afp_file_bitmap_LongName,                
1629       { "long name",         "afp.file_bitmap.long_name",
1630             FT_BOOLEAN, 16, NULL,  kFPLongNameBit,
1631         "file long name", HFILL }},
1632     { &hf_afp_file_bitmap_ShortName,               
1633       { "short name",         "afp.file_bitmap.short_name",
1634         FT_BOOLEAN, 16, NULL,  kFPShortNameBit,
1635         "file short name", HFILL }},
1636     { &hf_afp_file_bitmap_NodeID,                  
1637       { "file ID",         "afp.file_bitmap.fid",
1638             FT_BOOLEAN, 16, NULL,  kFPNodeIDBit,
1639         "file file ID", HFILL }},
1640     { &hf_afp_file_bitmap_UTF8Name,                
1641       { "UTF8 name",         "afp.file_bitmap.UTF8_name",
1642         FT_BOOLEAN, 16, NULL,  kFPUTF8NameBit,
1643         "file UTF8 name", HFILL }},
1644     { &hf_afp_file_bitmap_UnixPrivs,               
1645       { "unix privs",         "afp.file_bitmap.unix_privs",
1646             FT_BOOLEAN, 16, NULL,  kFPUnixPrivsBit,
1647         "file unix privs", HFILL }},
1648
1649     { &hf_afp_vol_name,
1650       { "Volume",         "afp.vol_name",
1651         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1652         "Volume name", HFILL }},
1653     { &hf_afp_vol_id,
1654       { "volume id",         "afp.vol_id",
1655                 FT_UINT16, BASE_DEC, NULL, 0x0,
1656         "Volume id", HFILL }},
1657     { &hf_afp_vol_signature,
1658       { "signature",         "afp.vol_signature",
1659                 FT_UINT16, BASE_DEC, VALS(vol_signature_vals), 0x0,
1660         "Volume signature", HFILL }},
1661     { &hf_afp_bitmap_offset,
1662       { "offset",         "afp.bitmap_offset",
1663                 FT_UINT16, BASE_DEC, NULL, 0x0,
1664         "name offset in packet", HFILL }},
1665     { &hf_afp_vol_creation_date,
1666       { "creation date",         "afp.vol_creation_date",
1667                 FT_UINT32, BASE_HEX, NULL, 0x0,
1668         "volume creation date", HFILL }},
1669     { &hf_afp_vol_modification_date,
1670       { "modification date",         "afp.vol_modification_date",
1671                 FT_UINT32, BASE_HEX, NULL, 0x0,
1672         "volume modification date", HFILL }},
1673     { &hf_afp_vol_backup_date,
1674       { "backup date",         "afp.vol_backup_date",
1675                 FT_UINT32, BASE_HEX, NULL, 0x0,
1676         "volume backup date", HFILL }},
1677     { &hf_afp_vol_bytes_free,
1678       { "bytes free",         "afp.vol_bytes_free",
1679                 FT_UINT32, BASE_DEC, NULL, 0x0,
1680         "free space", HFILL }},
1681     { &hf_afp_vol_bytes_total,
1682       { "bytes total",         "afp.vol_bytes_total",
1683                 FT_UINT32, BASE_DEC, NULL, 0x0,
1684         "volume size ", HFILL }},
1685     { &hf_afp_vol_ex_bytes_free,
1686       { "ex. bytes free",         "afp.vol_ex_bytes_free",
1687                 FT_UINT64, BASE_DEC, NULL, 0x0,
1688         "ex. free space", HFILL }},
1689     { &hf_afp_vol_ex_bytes_total,
1690       { "ex. bytes total",         "afp.vol_ex_bytes_total",
1691                 FT_UINT64, BASE_DEC, NULL, 0x0,
1692         "ex. volume size ", HFILL }},
1693     { &hf_afp_vol_block_size,
1694       { "block size",         "afp.vol_block_size",
1695                 FT_UINT32, BASE_DEC, NULL, 0x0,
1696         "volume block size", HFILL }},
1697
1698     { &hf_afp_did,
1699       { "did",         "afp.did",
1700                 FT_UINT32, BASE_DEC, NULL, 0x0,
1701         "parent directory id", HFILL }},
1702
1703     { &hf_afp_dir_bitmap,
1704       { "dir bitmap",         "afp.dir_bitmap",
1705                 FT_UINT16, BASE_HEX, NULL, 0x0,
1706         "directory bitmap", HFILL }},
1707
1708     { &hf_afp_dir_off_spring,
1709       { "off spring",         "afp.dir_off_spring",
1710                 FT_UINT16, BASE_DEC, NULL, 0x0,
1711         "directory offspring", HFILL }},
1712
1713     { &hf_afp_creation_date,
1714       { "creation date",         "afp.creation_date",
1715                 FT_UINT32, BASE_HEX, NULL, 0x0,
1716         "creation date", HFILL }},
1717     { &hf_afp_modification_date,
1718       { "modification date",         "afp.modification_date",
1719                 FT_UINT32, BASE_HEX, NULL, 0x0,
1720         "modification date", HFILL }},
1721     { &hf_afp_backup_date,
1722       { "backup date",         "afp.backup_date",
1723                 FT_UINT32, BASE_HEX, NULL, 0x0,
1724         "backup date", HFILL }},
1725
1726     { &hf_afp_finder_info,
1727       { "finder info",         "afp.finder_info",
1728                 FT_BYTES, BASE_HEX, NULL, 0x0,
1729         "finder info", HFILL }},
1730
1731     { &hf_afp_file_id,
1732       { "file id",         "afp.file_id",
1733                 FT_UINT32, BASE_DEC, NULL, 0x0,
1734         "file/directory id", HFILL }},
1735     
1736     { &hf_afp_file_bitmap,
1737       { "file bitmap",         "afp.file_bitmap",
1738                 FT_UINT16, BASE_HEX, NULL, 0x0,
1739         "file bitmap", HFILL }},
1740     
1741     { &hf_afp_req_count,
1742       { "req count",         "afp.req_count",
1743                 FT_UINT16, BASE_DEC, NULL, 0x0,
1744         "Maximum number of structures returned", HFILL }},
1745
1746     { & hf_afp_start_index, 
1747       { "start index",         "afp.start_index",
1748                 FT_UINT16, BASE_DEC, NULL, 0x0,
1749         "first structure returned", HFILL }},
1750     
1751     { &hf_afp_max_reply_size,
1752       { "reply size",         "afp.reply_size",
1753                 FT_UINT16, BASE_DEC, NULL, 0x0,
1754         "first structure returned", HFILL }},
1755
1756     { &hf_afp_file_flag,
1757       { "dir",         "afp.flag",
1758                 FT_BOOLEAN, 8, NULL, 0x80,
1759         "is a dir", HFILL }},
1760
1761     { &hf_afp_struct_size,
1762       { "struct size",         "afp.struct_size",
1763                 FT_UINT8, BASE_DEC, NULL,0,
1764         "sizeof of struct", HFILL }},
1765     
1766     { &hf_afp_flag,
1767       { "from",         "afp.flag",
1768                 FT_UINT8, BASE_HEX, VALS(flag_vals), 0x80,
1769         "offset is relative to start/end of the fork", HFILL }},
1770
1771     { &hf_afp_ofork,
1772       { "fork",         "afp.ofork",
1773                 FT_UINT16, BASE_DEC, NULL, 0x0,
1774         "Open fork reference number", HFILL }},
1775
1776     { &hf_afp_offset,
1777       { "offset",         "afp.offset",
1778                 FT_INT32, BASE_DEC, NULL, 0x0,
1779         "offset ", HFILL }},
1780     
1781     { &hf_afp_rw_count,
1782       { "count",         "afp.rw_count",
1783                 FT_INT32, BASE_DEC, NULL, 0x0,
1784         "number of bytes to be written ", HFILL }},
1785       
1786     { &hf_afp_path_type,
1787       { "path type ",         "afp.path_type",
1788                 FT_UINT8, BASE_HEX, VALS(path_type_vals), 0,
1789         "type of names", HFILL }},
1790
1791     { &hf_afp_path_name,
1792       { "Name ",  "afp.path_name",
1793                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1794         "path name", HFILL }},
1795
1796     { &hf_afp_fork_type,
1797       { "ressource fork",         "afp.fork_type",
1798                 FT_BOOLEAN, 8, NULL, 0x80,
1799         "data/ressource fork", HFILL }},
1800
1801     { &hf_afp_access_mode,
1802       { "access mode",         "afp.access",
1803                 FT_UINT8, BASE_HEX, NULL, 0x0,
1804         "fork access mode", HFILL }},
1805     { &hf_afp_access_read,
1806       { "read",         "afp.access.read",
1807         FT_BOOLEAN, 8, NULL,  1,
1808         "open for reading", HFILL }},
1809     { &hf_afp_access_write,
1810       { "write",         "afp.access.write",
1811         FT_BOOLEAN, 8, NULL,  1,
1812         "open for writing", HFILL }},
1813     { &hf_afp_access_deny_read,
1814       { "deny read",         "afp.access.deny_read",
1815         FT_BOOLEAN, 8, NULL,  1,
1816         "deny read", HFILL }},
1817     { &hf_afp_access_deny_write,
1818       { "deny write",         "afp.access.deny_write",
1819         FT_BOOLEAN, 8, NULL,  1,
1820         "deny write", HFILL }},
1821
1822   };
1823
1824   static gint *ett[] = {
1825     &ett_afp,
1826         &ett_afp_vol_bitmap,
1827         &ett_afp_vol_attribute,
1828         &ett_afp_dir_bitmap,
1829         &ett_afp_file_bitmap,
1830         &ett_afp_enumerate,
1831         &ett_afp_enumerate_line,
1832         &ett_afp_access_mode,
1833   };
1834
1835   proto_afp = proto_register_protocol("AppleTalk Filing Protocol", "AFP", "afp");
1836   proto_register_field_array(proto_afp, hf, array_length(hf));
1837   proto_register_subtree_array(ett, array_length(ett));
1838
1839   register_init_routine( &afp_reinit);
1840
1841   register_dissector("afp", dissect_afp, proto_afp);
1842 }
1843
1844 void
1845 proto_reg_handoff_afp(void)
1846 {
1847   data_handle = find_dissector("data");
1848 }
1849
1850 /* -------------------------------
1851    end
1852 */