From Didier
[metze/wireshark/wip.git] / epan / dissectors / packet-afp.c
1 /* packet-afp.c
2  * Routines for afp packet dissection
3  * Copyright 2002, Didier Gautheron <dgautheron@magic.fr>
4  *
5  * $Id$
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 #include <string.h>
35
36 #include <string.h>
37 #include <glib.h>
38 #include <epan/packet.h>
39 /* #include <epan/strutil.h> */
40 #include <epan/conversation.h>
41 #include <epan/emem.h>
42 #include <epan/tap.h>
43
44 #include "packet-afp.h"
45
46 /* The information in this module (AFP) comes from:
47
48   AFP 2.1 & 2.2.pdf contained in AppleShare_IP_6.3_SDK
49   available from http://www.apple.com
50
51   AFP3.0.pdf from http://www.apple.com (still available?)
52   AFP3.1.pdf from
53
54    http://developer.apple.com/documentation/Networking/Conceptual/AFP/AFP3_1.pdf
55
56   AFP 3.1 in HTML from
57
58 http://developer.apple.com/documentation/Networking/Conceptual/AFP/index.html
59
60   The netatalk source code by Wesley Craig & Adrian Sun
61         http://netatalk.sf.net
62 */
63 /* from netatalk/include/afp.h */
64 #define AFPTRANS_NONE          0
65 #define AFPTRANS_DDP          (1 << 0)
66 #define AFPTRANS_TCP          (1 << 1)
67 #define AFPTRANS_ALL          (AFPTRANS_DDP | AFPTRANS_TCP)
68
69 /* AFP Attention Codes -- 4 bits */
70 #define AFPATTN_SHUTDOWN     (1 << 15)            /* shutdown/disconnect */
71 #define AFPATTN_CRASH        (1 << 14)            /* server crashed */
72 #define AFPATTN_MESG         (1 << 13)            /* server has message */
73 #define AFPATTN_NORECONNECT  (1 << 12)            /* don't reconnect */
74 /* server notification */
75 #define AFPATTN_NOTIFY       (AFPATTN_MESG | AFPATTN_NORECONNECT)
76
77 /* extended bitmap -- 12 bits. volchanged is only useful w/ a server
78  * notification, and time is only useful for shutdown. */
79 #define AFPATTN_VOLCHANGED   (1 << 0)             /* volume has changed */
80 #define AFPATTN_TIME(x)      ((x) & 0xfff)        /* time in minutes */
81
82 /* AFP functions */
83 #define AFP_BYTELOCK         1
84 #define AFP_CLOSEVOL             2
85 #define AFP_CLOSEDIR             3
86 #define AFP_CLOSEFORK            4
87 #define AFP_COPYFILE             5
88 #define AFP_CREATEDIR            6
89 #define AFP_CREATEFILE           7
90 #define AFP_DELETE                   8
91 #define AFP_ENUMERATE            9
92 #define AFP_FLUSH                   10
93 #define AFP_FLUSHFORK           11
94 #define AFP_GETFORKPARAM        14
95 #define AFP_GETSRVINFO          15
96 #define AFP_GETSRVPARAM         16
97 #define AFP_GETVOLPARAM         17
98 #define AFP_LOGIN               18
99 #define AFP_LOGINCONT           19
100 #define AFP_LOGOUT              20
101 #define AFP_MAPID                   21
102 #define AFP_MAPNAME                 22
103 #define AFP_MOVE                    23
104 #define AFP_OPENVOL             24
105 #define AFP_OPENDIR                 25
106 #define AFP_OPENFORK            26
107 #define AFP_READ                    27
108 #define AFP_RENAME                  28
109 #define AFP_SETDIRPARAM         29
110 #define AFP_SETFILEPARAM        30
111 #define AFP_SETFORKPARAM        31
112 #define AFP_SETVOLPARAM         32
113 #define AFP_WRITE                   33
114 #define AFP_GETFLDRPARAM        34
115 #define AFP_SETFLDRPARAM        35
116 #define AFP_CHANGEPW            36
117 #define AFP_GETUSERINFO         37
118 #define AFP_GETSRVRMSG          38
119 #define AFP_CREATEID            39
120 #define AFP_DELETEID            40
121 #define AFP_RESOLVEID           41
122 #define AFP_EXCHANGEFILE        42
123 #define AFP_CATSEARCH           43
124 #define AFP_OPENDT                  48
125 #define AFP_CLOSEDT                 49
126 #define AFP_GETICON         51
127 #define AFP_GTICNINFO       52
128 #define AFP_ADDAPPL         53
129 #define AFP_RMVAPPL         54
130 #define AFP_GETAPPL         55
131 #define AFP_ADDCMT          56
132 #define AFP_RMVCMT          57
133 #define AFP_GETCMT          58
134 #define AFP_ZZZ            122
135 #define AFP_ADDICON        192
136
137 /* AFP 3.0 new calls */
138 #define AFP_BYTELOCK_EXT        59
139 #define AFP_CATSEARCH_EXT       67
140 #define AFP_ENUMERATE_EXT       66
141 #define AFP_READ_EXT            60
142 #define AFP_WRITE_EXT           61
143 #define AFP_LOGIN_EXT           63
144 #define AFP_GETSESSTOKEN        64
145 #define AFP_DISCTOLDSESS        65
146
147 /* AFP 3.1 new calls */
148 #define AFP_ENUMERATE_EXT2      68
149
150 /* AFP 3.2 new calls */
151 #define AFP_GETEXTATTR          69
152 #define AFP_SETEXTATTR          70
153 #define AFP_REMOVEATTR          71
154 #define AFP_LISTEXTATTR         72
155 #define AFP_GETACL              73
156 #define AFP_SETACL              74
157 #define AFP_ACCESS              75
158
159 /* ----------------------------- */
160 static int proto_afp = -1;
161 static int hf_afp_reserved = -1;
162
163 static int hf_afp_command = -1;         /* CommandCode */
164 static int hf_afp_AFPVersion = -1;
165 static int hf_afp_UAM = -1;
166 static int hf_afp_user = -1;
167 static int hf_afp_passwd = -1;
168 static int hf_afp_random = -1;
169
170 static int hf_afp_response_to = -1;
171 static int hf_afp_time = -1;
172 static int hf_afp_response_in = -1;
173
174 static int hf_afp_login_flags = -1;
175 static int hf_afp_pad = -1;
176
177 static int hf_afp_user_type = -1;
178 static int hf_afp_user_len = -1;
179 static int hf_afp_user_name = -1;
180
181 static int hf_afp_vol_flag_passwd        = -1;
182 static int hf_afp_vol_flag_unix_priv = -1;
183 static int hf_afp_server_time            = -1;
184
185 static int hf_afp_vol_bitmap = -1;
186 static int hf_afp_vol_name_offset = -1;
187 static int hf_afp_vol_id = -1;
188 static int hf_afp_vol_attribute = -1;
189 static int hf_afp_vol_name = -1;
190 static int hf_afp_vol_signature = -1;
191 static int hf_afp_vol_creation_date = -1;
192 static int hf_afp_vol_modification_date = -1;
193 static int hf_afp_vol_backup_date = -1;
194 static int hf_afp_vol_bytes_free = -1;
195 static int hf_afp_vol_bytes_total = -1;
196 static int hf_afp_vol_ex_bytes_free = -1;
197 static int hf_afp_vol_ex_bytes_total = -1;
198 static int hf_afp_vol_block_size = -1;
199
200 /* desktop stuff */
201 static int hf_afp_comment               = -1;
202 static int hf_afp_file_creator  = -1;
203 static int hf_afp_file_type     = -1;
204 static int hf_afp_icon_type     = -1;
205 static int hf_afp_icon_length   = -1;
206 static int hf_afp_icon_tag              = -1;
207 static int hf_afp_icon_index    = -1;
208 static int hf_afp_appl_index    = -1;
209 static int hf_afp_appl_tag              = -1;
210
211 static int hf_afp_did                             = -1;
212 static int hf_afp_file_id                         = -1;
213 static int hf_afp_file_DataForkLen    = -1;
214 static int hf_afp_file_RsrcForkLen    = -1;
215 static int hf_afp_file_ExtDataForkLen = -1;
216 static int hf_afp_file_ExtRsrcForkLen = -1;
217
218 static int hf_afp_dir_bitmap     = -1;
219 static int hf_afp_dir_offspring  = -1;
220 static int hf_afp_dir_OwnerID    = -1;
221 static int hf_afp_dir_GroupID    = -1;
222
223 static int hf_afp_file_bitmap = -1;
224 static int hf_afp_req_count = -1;
225 static int hf_afp_start_index = -1;
226 static int hf_afp_start_index32 = -1;
227 static int hf_afp_max_reply_size = -1;
228 static int hf_afp_max_reply_size32 = -1;
229 static int hf_afp_file_flag = -1;
230 static int hf_afp_create_flag = -1;
231 static int hf_afp_struct_size = -1;
232 static int hf_afp_struct_size16 = -1;
233
234 static int hf_afp_request_bitmap = -1;
235
236 static int hf_afp_cat_count             = -1;
237 static int hf_afp_cat_req_matches   = -1;
238 static int hf_afp_cat_position          = -1;
239
240 static int hf_afp_creation_date = -1;
241 static int hf_afp_modification_date = -1;
242 static int hf_afp_backup_date = -1;
243 static int hf_afp_finder_info = -1;
244 static int hf_afp_long_name_offset = -1;
245 static int hf_afp_short_name_offset = -1;
246 static int hf_afp_unicode_name_offset = -1;
247 static int hf_afp_unix_privs_uid = -1;
248 static int hf_afp_unix_privs_gid = -1;
249 static int hf_afp_unix_privs_permissions = -1;
250 static int hf_afp_unix_privs_ua_permissions = -1;
251
252 static int hf_afp_path_type = -1;
253 static int hf_afp_path_len = -1;
254 static int hf_afp_path_name = -1;
255 static int hf_afp_path_unicode_hint = -1;
256 static int hf_afp_path_unicode_len = -1;
257
258 static int hf_afp_flag          = -1;
259 static int hf_afp_dt_ref        = -1;
260 static int hf_afp_ofork         = -1;
261 static int hf_afp_ofork_len     = -1;
262 static int hf_afp_offset        = -1;
263 static int hf_afp_rw_count      = -1;
264 static int hf_afp_newline_mask  = -1;
265 static int hf_afp_newline_char  = -1;
266 static int hf_afp_last_written  = -1;
267 static int hf_afp_actual_count  = -1;
268
269 static int hf_afp_fork_type                     = -1;
270 static int hf_afp_access_mode           = -1;
271 static int hf_afp_access_read           = -1;
272 static int hf_afp_access_write          = -1;
273 static int hf_afp_access_deny_read  = -1;
274 static int hf_afp_access_deny_write = -1;
275
276 static gint hf_afp_lock_op                      = -1;
277 static gint hf_afp_lock_from            = -1;
278 static gint hf_afp_lock_offset          = -1;
279 static gint hf_afp_lock_len             = -1;
280 static gint hf_afp_lock_range_start = -1;
281
282 static gint ett_afp = -1;
283
284 static gint ett_afp_vol_attribute = -1;
285 static gint ett_afp_enumerate = -1;
286 static gint ett_afp_enumerate_line = -1;
287 static gint ett_afp_access_mode = -1;
288
289 static gint ett_afp_vol_bitmap = -1;
290 static gint ett_afp_dir_bitmap = -1;
291 static gint ett_afp_dir_attribute = -1;
292 static gint ett_afp_file_attribute = -1;
293 static gint ett_afp_file_bitmap = -1;
294 static gint ett_afp_unix_privs = -1;
295 static gint ett_afp_path_name = -1;
296 static gint ett_afp_lock_flags = -1;
297 static gint ett_afp_dir_ar = -1;
298
299 static gint ett_afp_server_vol          = -1;
300 static gint ett_afp_vol_list            = -1;
301 static gint ett_afp_vol_flag            = -1;
302 static gint ett_afp_cat_search          = -1;
303 static gint ett_afp_cat_r_bitmap        = -1;
304 static gint ett_afp_cat_spec            = -1;
305 static gint ett_afp_vol_did     = -1;
306
307 /* AFP 3.0 parameters */
308 static gint hf_afp_lock_offset64        = -1;
309 static gint hf_afp_lock_len64           = -1;
310 static gint hf_afp_lock_range_start64   = -1;
311
312 static int hf_afp_offset64              = -1;
313 static int hf_afp_rw_count64            = -1;
314 static int hf_afp_reqcount64            = -1;
315
316 static int hf_afp_last_written64        = -1;
317
318 static int hf_afp_ofork_len64           = -1;
319 static int hf_afp_session_token_type    = -1;
320 static int hf_afp_session_token_len     = -1;
321 static int hf_afp_session_token         = -1;
322 static int hf_afp_session_token_timestamp = -1;
323
324 /* AFP 3.2 */
325
326 static int hf_afp_extattr_bitmap          = -1;
327 static int hf_afp_extattr_bitmap_NoFollow = -1;
328 static int hf_afp_extattr_bitmap_Create   = -1;
329 static int hf_afp_extattr_bitmap_Replace  = -1;
330 static int ett_afp_extattr_bitmap         = -1;
331 static int hf_afp_extattr_namelen         = -1;
332 static int hf_afp_extattr_name            = -1;
333 static int hf_afp_extattr_len             = -1;
334 static int hf_afp_extattr_data            = -1;
335 static int hf_afp_extattr_req_count       = -1;
336 static int hf_afp_extattr_start_index     = -1;
337 static int hf_afp_extattr_reply_size      = -1;
338 static int ett_afp_extattr_names          = -1;
339
340 static int afp_tap = -1;
341
342 static dissector_handle_t data_handle;
343
344 static const value_string vol_signature_vals[] = {
345         {1, "Flat"},
346         {2, "Fixed Directory ID"},
347         {3, "Variable Directory ID (deprecated)"},
348         {0, NULL }
349 };
350
351 const value_string CommandCode_vals[] = {
352   {AFP_BYTELOCK,        "FPByteRangeLock" },
353   {AFP_CLOSEVOL,        "FPCloseVol" },
354   {AFP_CLOSEDIR,        "FPCloseDir" },
355   {AFP_CLOSEFORK,       "FPCloseFork" },
356   {AFP_COPYFILE,        "FPCopyFile" },
357   {AFP_CREATEDIR,       "FPCreateDir" },
358   {AFP_CREATEFILE,      "FPCreateFile" },
359   {AFP_DELETE,          "FPDelete" },
360   {AFP_ENUMERATE,       "FPEnumerate" },
361   {AFP_FLUSH,           "FPFlush" },
362   {AFP_FLUSHFORK,       "FPFlushFork" },
363   {AFP_GETFORKPARAM,    "FPGetForkParms" },
364   {AFP_GETSRVINFO,      "FPGetSrvrInfo" },
365   {AFP_GETSRVPARAM,     "FPGetSrvrParms" },
366   {AFP_GETVOLPARAM,     "FPGetVolParms" },
367   {AFP_LOGIN,           "FPLogin" },
368   {AFP_LOGINCONT,       "FPLoginCont" },
369   {AFP_LOGOUT,          "FPLogout" },
370   {AFP_MAPID,           "FPMapID" },
371   {AFP_MAPNAME,         "FPMapName" },
372   {AFP_MOVE,            "FPMoveAndRename" },
373   {AFP_OPENVOL,         "FPOpenVol" },
374   {AFP_OPENDIR,         "FPOpenDir" },
375   {AFP_OPENFORK,        "FPOpenFork" },
376   {AFP_READ,            "FPRead" },
377   {AFP_RENAME,          "FPRename" },
378   {AFP_SETDIRPARAM,     "FPSetDirParms" },
379   {AFP_SETFILEPARAM,    "FPSetFileParms" },
380   {AFP_SETFORKPARAM,    "FPSetForkParms" },
381   {AFP_SETVOLPARAM,     "FPSetVolParms" },
382   {AFP_WRITE,           "FPWrite" },
383   {AFP_GETFLDRPARAM,    "FPGetFileDirParms" },
384   {AFP_SETFLDRPARAM,    "FPSetFileDirParms" },
385   {AFP_CHANGEPW,        "FPChangePassword" },
386   {AFP_GETUSERINFO,     "FPGetUserInfo" },
387   {AFP_GETSRVRMSG,      "FPGetSrvrMsg" },
388   {AFP_CREATEID,        "FPCreateID" },
389   {AFP_DELETEID,        "FPDeleteID" },
390   {AFP_RESOLVEID,       "FPResolveID" },
391   {AFP_EXCHANGEFILE,    "FPExchangeFiles" },
392   {AFP_CATSEARCH,       "FPCatSearch" },
393   {AFP_OPENDT,          "FPOpenDT" },
394   {AFP_CLOSEDT,         "FPCloseDT" },
395   {AFP_GETICON,         "FPGetIcon" },
396   {AFP_GTICNINFO,       "FPGetIconInfo" },
397   {AFP_ADDAPPL,         "FPAddAPPL" },
398   {AFP_RMVAPPL,         "FPRemoveAPPL" },
399   {AFP_GETAPPL,         "FPGetAPPL" },
400   {AFP_ADDCMT,          "FPAddComment" },
401   {AFP_RMVCMT,          "FPRemoveComment" },
402   {AFP_GETCMT,          "FPGetComment" },
403   {AFP_BYTELOCK_EXT,    "FPByteRangeLockExt" },
404   {AFP_CATSEARCH_EXT,   "FPCatSearchExt" },
405   {AFP_ENUMERATE_EXT,   "FPEnumerateExt" },
406   {AFP_ENUMERATE_EXT2,  "FPEnumerateExt2" },
407   {AFP_READ_EXT,        "FPReadExt" },
408   {AFP_WRITE_EXT,       "FPWriteExt" },
409   {AFP_LOGIN_EXT,       "FPLoginExt" },
410   {AFP_GETSESSTOKEN,    "FPGetSessionToken" },
411   {AFP_DISCTOLDSESS,    "FPDisconnectOldSession" },
412   {AFP_ZZZ,             "FPZzzzz" },
413   {AFP_ADDICON,         "FPAddIcon" },
414   {AFP_GETEXTATTR,      "FPGetExtAttr" },
415   {AFP_SETEXTATTR,      "FPSetExtAttr" },
416   {AFP_REMOVEATTR,      "FPRemoveExtAttr" },
417   {AFP_LISTEXTATTR,     "FPListExtAttrs" },
418   {AFP_GETACL,          "FPGetACL" },
419   {AFP_SETACL,          "FPSetACL" },
420   {AFP_ACCESS,          "FPAccess" },
421   {0,                    NULL }
422 };
423
424 static const value_string unicode_hint_vals[] = {
425    { 0,    "MacRoman" },
426    { 1,    "MacJapanese" },
427    { 2,    "MacChineseTrad" },
428    { 3,    "MacKorean" },
429    { 4,    "MacArabic" },
430    { 5,    "MacHebrew" },
431    { 6,    "MacGreek" },
432    { 7,    "MacCyrillic" },
433    { 9,    "MacDevanagari" },
434    { 10,   "MacGurmukhi" },
435    { 11,   "MacGujarati" },
436    { 12,   "MacOriya" },
437    { 13,   "MacBengali" },
438    { 14,   "MacTamil" },
439    { 15,   "MacTelugu" },
440    { 16,   "MacKannada" },
441    { 17,   "MacMalayalam" },
442    { 18,   "MacSinhalese" },
443    { 19,   "MacBurmese" },
444    { 20,   "MacKhmer" },
445    { 21,   "MacThai" },
446    { 22,   "MacLaotian" },
447    { 23,   "MacGeorgian" },
448    { 24,   "MacArmenian" },
449    { 25,   "MacChineseSimp" },
450    { 26,   "MacTibetan" },
451    { 27,   "MacMongolian" },
452    { 28,   "MacEthiopic" },
453    { 29,   "MacCentralEurRoman" },
454    { 30,   "MacVietnamese" },
455    { 31,   "MacExtArabic" },
456    { 33,   "MacSymbol" },
457    { 34,   "MacDingbats" },
458    { 35,   "MacTurkish" },
459    { 36,   "MacCroatian" },
460    { 37,   "MacIcelandic" },
461    { 38,   "MacRomanian" },
462    { 39,   "MacCeltic" },
463    { 40,   "MacGaelic" },
464    { 41,   "MacKeyboardGlyphs" },
465    { 126,  "MacUnicode" },
466    { 140,  "MacFarsi" },
467    { 152,  "MacUkrainian" },
468    { 236,  "MacInuit" },
469    { 252,  "MacVT100" },
470    { 255,  "MacHFS" },
471    { 256,  "UnicodeDefault" },
472 /* { 257,  "UnicodeV1_1" },  */
473    { 257,  "ISO10646_1993" },
474    { 259,  "UnicodeV2_0" },
475    { 259,  "UnicodeV2_1" },
476    { 260,  "UnicodeV3_0" },
477    { 513,  "ISOLatin1" },
478    { 514,  "ISOLatin2" },
479    { 515,  "ISOLatin3" },
480    { 516,  "ISOLatin4" },
481    { 517,  "ISOLatinCyrillic" },
482    { 518,  "ISOLatinArabic" },
483    { 519,  "ISOLatinGreek" },
484    { 520,  "ISOLatinHebrew" },
485    { 521,  "ISOLatin5" },
486    { 522,  "ISOLatin6" },
487    { 525,  "ISOLatin7" },
488    { 526,  "ISOLatin8" },
489    { 527,  "ISOLatin9" },
490    { 1024, "DOSLatinUS" },
491    { 1029, "DOSGreek" },
492    { 1030, "DOSBalticRim" },
493    { 1040, "DOSLatin1" },
494    { 1041, "DOSGreek1" },
495    { 1042, "DOSLatin2" },
496    { 1043, "DOSCyrillic" },
497    { 1044, "DOSTurkish" },
498    { 1045, "DOSPortuguese" },
499    { 1046, "DOSIcelandic" },
500    { 1047, "DOSHebrew" },
501    { 1048, "DOSCanadianFrench" },
502    { 1049, "DOSArabic" },
503    { 1050, "DOSNordic" },
504    { 1051, "DOSRussian" },
505    { 1052, "DOSGreek2" },
506    { 1053, "DOSThai" },
507    { 1056, "DOSJapanese" },
508    { 1057, "DOSChineseSimplif" },
509    { 1058, "DOSKorean" },
510    { 1059, "DOSChineseTrad" },
511    { 1280, "WindowsLatin1" },
512 /* { 1280, "WindowsANSI" }, */
513    { 1281, "WindowsLatin2" },
514    { 1282, "WindowsCyrillic" },
515    { 1283, "WindowsGreek" },
516    { 1284, "WindowsLatin5" },
517    { 1285, "WindowsHebrew" },
518    { 1286, "WindowsArabic" },
519    { 1287, "WindowsBalticRim" },
520    { 1288, "WindowsVietnamese" },
521    { 1296, "WindowsKoreanJohab" },
522    { 1536, "US_ASCII" },
523    { 1568, "JIS_X0201_76" },
524    { 1569, "JIS_X0208_83" },
525    { 1570, "JIS_X0208_90" },
526    { 0,    NULL }
527 };
528
529 /* volume bitmap
530   from Apple AFP3.0.pdf
531   Table 1-2 p. 20
532 */
533 #define kFPVolAttributeBit              (1 << 0)
534 #define kFPVolSignatureBit              (1 << 1)
535 #define kFPVolCreateDateBit             (1 << 2)
536 #define kFPVolModDateBit                (1 << 3)
537 #define kFPVolBackupDateBit             (1 << 4)
538 #define kFPVolIDBit                     (1 << 5)
539 #define kFPVolBytesFreeBit              (1 << 6)
540 #define kFPVolBytesTotalBit             (1 << 7)
541 #define kFPVolNameBit                   (1 << 8)
542 #define kFPVolExtBytesFreeBit           (1 << 9)
543 #define kFPVolExtBytesTotalBit          (1 << 10)
544 #define kFPVolBlockSizeBit              (1 << 11)
545
546 static int hf_afp_vol_bitmap_Attributes         = -1;
547 static int hf_afp_vol_bitmap_Signature          = -1;
548 static int hf_afp_vol_bitmap_CreateDate         = -1;
549 static int hf_afp_vol_bitmap_ModDate            = -1;
550 static int hf_afp_vol_bitmap_BackupDate         = -1;
551 static int hf_afp_vol_bitmap_ID                 = -1;
552 static int hf_afp_vol_bitmap_BytesFree          = -1;
553 static int hf_afp_vol_bitmap_BytesTotal         = -1;
554 static int hf_afp_vol_bitmap_Name               = -1;
555 static int hf_afp_vol_bitmap_ExtBytesFree       = -1;
556 static int hf_afp_vol_bitmap_ExtBytesTotal      = -1;
557 static int hf_afp_vol_bitmap_BlockSize          = -1;
558
559 static int hf_afp_vol_attribute_ReadOnly                        = -1;
560 static int hf_afp_vol_attribute_HasVolumePassword               = -1;
561 static int hf_afp_vol_attribute_SupportsFileIDs                 = -1;
562 static int hf_afp_vol_attribute_SupportsCatSearch               = -1;
563 static int hf_afp_vol_attribute_SupportsBlankAccessPrivs        = -1;
564 static int hf_afp_vol_attribute_SupportsUnixPrivs               = -1;
565 static int hf_afp_vol_attribute_SupportsUTF8Names               = -1;
566 static int hf_afp_vol_attribute_NoNetworkUserID                 = -1;
567 static int hf_afp_vol_attribute_DefaultPrivsFromParent          = -1;
568 static int hf_afp_vol_attribute_NoExchangeFiles                 = -1;
569 static int hf_afp_vol_attribute_SupportsExtAttrs                = -1;
570 static int hf_afp_vol_attribute_SupportsACLs                    = -1;
571
572 static int hf_afp_dir_bitmap_Attributes     = -1;
573 static int hf_afp_dir_bitmap_ParentDirID    = -1;
574 static int hf_afp_dir_bitmap_CreateDate     = -1;
575 static int hf_afp_dir_bitmap_ModDate        = -1;
576 static int hf_afp_dir_bitmap_BackupDate     = -1;
577 static int hf_afp_dir_bitmap_FinderInfo     = -1;
578 static int hf_afp_dir_bitmap_LongName       = -1;
579 static int hf_afp_dir_bitmap_ShortName      = -1;
580 static int hf_afp_dir_bitmap_NodeID         = -1;
581 static int hf_afp_dir_bitmap_OffspringCount = -1;
582 static int hf_afp_dir_bitmap_OwnerID        = -1;
583 static int hf_afp_dir_bitmap_GroupID        = -1;
584 static int hf_afp_dir_bitmap_AccessRights   = -1;
585 static int hf_afp_dir_bitmap_UTF8Name       = -1;
586 static int hf_afp_dir_bitmap_UnixPrivs      = -1;
587
588 static int hf_afp_dir_attribute_Invisible     = -1;
589 static int hf_afp_dir_attribute_IsExpFolder   = -1;
590
591 static int hf_afp_dir_attribute_System        = -1;
592 static int hf_afp_dir_attribute_Mounted       = -1;
593 static int hf_afp_dir_attribute_InExpFolder   = -1;
594
595 static int hf_afp_dir_attribute_BackUpNeeded  = -1;
596 static int hf_afp_dir_attribute_RenameInhibit = -1;
597 static int hf_afp_dir_attribute_DeleteInhibit = -1;
598 static int hf_afp_dir_attribute_SetClear      = -1;
599
600 static int hf_afp_file_bitmap_Attributes     = -1;
601 static int hf_afp_file_bitmap_ParentDirID    = -1;
602 static int hf_afp_file_bitmap_CreateDate     = -1;
603 static int hf_afp_file_bitmap_ModDate        = -1;
604 static int hf_afp_file_bitmap_BackupDate     = -1;
605 static int hf_afp_file_bitmap_FinderInfo     = -1;
606 static int hf_afp_file_bitmap_LongName       = -1;
607 static int hf_afp_file_bitmap_ShortName      = -1;
608 static int hf_afp_file_bitmap_NodeID         = -1;
609 static int hf_afp_file_bitmap_DataForkLen    = -1;
610 static int hf_afp_file_bitmap_RsrcForkLen    = -1;
611 static int hf_afp_file_bitmap_ExtDataForkLen = -1;
612 static int hf_afp_file_bitmap_LaunchLimit    = -1;
613
614 static int hf_afp_file_bitmap_UTF8Name       = -1;
615 static int hf_afp_file_bitmap_ExtRsrcForkLen = -1;
616 static int hf_afp_file_bitmap_UnixPrivs      = -1;
617
618 static int hf_afp_file_attribute_Invisible     = -1;
619 static int hf_afp_file_attribute_MultiUser     = -1;
620 static int hf_afp_file_attribute_System        = -1;
621 static int hf_afp_file_attribute_DAlreadyOpen  = -1;
622 static int hf_afp_file_attribute_RAlreadyOpen  = -1;
623 static int hf_afp_file_attribute_WriteInhibit  = -1;
624 static int hf_afp_file_attribute_BackUpNeeded  = -1;
625 static int hf_afp_file_attribute_RenameInhibit = -1;
626 static int hf_afp_file_attribute_DeleteInhibit = -1;
627 static int hf_afp_file_attribute_CopyProtect   = -1;
628 static int hf_afp_file_attribute_SetClear      = -1;
629
630 static int hf_afp_map_name_type = -1;
631 static int hf_afp_map_name      = -1;
632 static int hf_afp_map_id        = -1;
633 static int hf_afp_map_id_type   = -1;
634
635 static int hf_afp_request_bitmap_Attributes     = -1;
636 static int hf_afp_request_bitmap_ParentDirID    = -1;
637 static int hf_afp_request_bitmap_CreateDate     = -1;
638 static int hf_afp_request_bitmap_ModDate        = -1;
639 static int hf_afp_request_bitmap_BackupDate     = -1;
640 static int hf_afp_request_bitmap_FinderInfo     = -1;
641 static int hf_afp_request_bitmap_LongName       = -1;
642 static int hf_afp_request_bitmap_DataForkLen    = -1;
643 static int hf_afp_request_bitmap_OffspringCount = -1;
644 static int hf_afp_request_bitmap_RsrcForkLen    = -1;
645 static int hf_afp_request_bitmap_ExtDataForkLen = -1;
646 static int hf_afp_request_bitmap_UTF8Name       = -1;
647 static int hf_afp_request_bitmap_ExtRsrcForkLen = -1;
648 static int hf_afp_request_bitmap_PartialNames   = -1;
649
650 static const value_string flag_vals[] = {
651   {0,   "Start" },
652   {1,   "End" },
653   {0,   NULL } };
654
655 static const value_string path_type_vals[] = {
656   {1,   "Short names" },
657   {2,   "Long names" },
658   {3,   "Unicode names" },
659   {0,   NULL } };
660
661 static const value_string map_name_type_vals[] = {
662   {1,   "Unicode user name to a user ID" },
663   {2,   "Unicode group name to a group ID" },
664   {3,   "Macintosh roman user name to a user ID" },
665   {4,   "Macintosh roman group name to a group ID" },
666   {5,   "Unicode user name to a user UUID" },
667   {6,   "Unicode group name to a group UUID" },
668   {0,   NULL } };
669
670 static const value_string map_id_type_vals[] = {
671   {1,   "User ID to a Macintosh roman user name" },
672   {2,   "Group ID to a Macintosh roman group name" },
673   {3,   "User ID to a unicode user name" },
674   {4,   "Group ID to a unicode group name" },
675   {5,   "User UUID to a unicode user name" },
676   {6,   "Group UUID to a unicode group name" },
677   {0,   NULL } };
678
679 /*
680   volume attribute from Apple AFP3.0.pdf
681   Table 1-3 p. 22
682 */
683 #define kReadOnly                               (1 << 0)
684 #define kHasVolumePassword                      (1 << 1)
685 #define kSupportsFileIDs                        (1 << 2)
686 #define kSupportsCatSearch                      (1 << 3)
687 #define kSupportsBlankAccessPrivs               (1 << 4)
688 #define kSupportsUnixPrivs                      (1 << 5)
689 #define kSupportsUTF8Names                      (1 << 6)
690 /* AFP3.1 */
691 #define kNoNetworkUserIDs                       (1 << 7)
692 /* AFP3.2 */
693 #define kDefaultPrivsFromParent                 (1 << 8)
694 #define kNoExchangeFiles                        (1 << 9)
695 #define kSupportsExtAttrs                       (1 << 10)
696 #define kSupportsACLs                           (1 << 11)
697
698 /*
699   directory bitmap from Apple AFP3.1.pdf
700   Table 1-5 pp. 25-26
701 */
702 #define kFPAttributeBit                 (1 << 0)
703 #define kFPParentDirIDBit               (1 << 1)
704 #define kFPCreateDateBit                (1 << 2)
705 #define kFPModDateBit                   (1 << 3)
706 #define kFPBackupDateBit                (1 << 4)
707 #define kFPFinderInfoBit                (1 << 5)
708 #define kFPLongNameBit                  (1 << 6)
709 #define kFPShortNameBit                 (1 << 7)
710 #define kFPNodeIDBit                    (1 << 8)
711 #define kFPOffspringCountBit            (1 << 9)
712 #define kFPOwnerIDBit                   (1 << 10)
713 #define kFPGroupIDBit                   (1 << 11)
714 #define kFPAccessRightsBit              (1 << 12)
715 #define kFPUTF8NameBit                  (1 << 13)
716
717 /* FIXME AFP3.0 bit 14, AFP3.1 bit 15 */
718
719 #define kFPUnixPrivsBit                 (1 << 15)
720
721 /*
722         directory Access Rights parameter AFP3.1.pdf
723         table 1-7 p. 28
724 */
725
726 #define AR_O_SEARCH     (1 << 0)        /* owner has search access */
727 #define AR_O_READ       (1 << 1)    /* owner has read access */
728 #define AR_O_WRITE      (1 << 2)    /* owner has write access */
729
730 #define AR_G_SEARCH     (1 << 8)    /* group has search access */
731 #define AR_G_READ       (1 << 9)    /* group has read access */
732 #define AR_G_WRITE      (1 << 10)   /* group has write access */
733
734 #define AR_E_SEARCH     (1 << 16)       /* everyone has search access */
735 #define AR_E_READ       (1 << 17)   /* everyone has read access */
736 #define AR_E_WRITE      (1 << 18)   /* everyone has write access */
737
738 #define AR_U_SEARCH     (1 << 24)   /* user has search access */
739 #define AR_U_READ       (1 << 25)   /* user has read access */
740 #define AR_U_WRITE      (1 << 26)       /* user has write access */
741
742 #define AR_BLANK        (1 << 28)       /* Blank Access Privileges (use parent dir privileges) */
743 #define AR_U_OWN        (1UL << 31)     /* user is the owner */
744
745 static int hf_afp_dir_ar          = -1;
746 static int hf_afp_dir_ar_o_search = -1;
747 static int hf_afp_dir_ar_o_read   = -1;
748 static int hf_afp_dir_ar_o_write  = -1;
749 static int hf_afp_dir_ar_g_search = -1;
750 static int hf_afp_dir_ar_g_read   = -1;
751 static int hf_afp_dir_ar_g_write  = -1;
752 static int hf_afp_dir_ar_e_search = -1;
753 static int hf_afp_dir_ar_e_read   = -1;
754 static int hf_afp_dir_ar_e_write  = -1;
755 static int hf_afp_dir_ar_u_search = -1;
756 static int hf_afp_dir_ar_u_read   = -1;
757 static int hf_afp_dir_ar_u_write  = -1;
758 static int hf_afp_dir_ar_blank    = -1;
759 static int hf_afp_dir_ar_u_own    = -1;
760
761 static int hf_afp_user_flag       = -1;
762 static int hf_afp_user_ID         = -1;
763 static int hf_afp_group_ID        = -1;
764 static int hf_afp_UUID      = -1;
765 static int hf_afp_GRPUUID      = -1;
766 static int hf_afp_user_bitmap     = -1;
767 static int hf_afp_user_bitmap_UID = -1;
768 static int hf_afp_user_bitmap_GID = -1;
769 static int hf_afp_user_bitmap_UUID= -1;
770
771 static gint ett_afp_user_bitmap   = -1;
772
773 static const value_string user_flag_vals[] = {
774   {0,   "Use user ID" },
775   {1,   "Default user" },
776   {0,   NULL } };
777
778 static int hf_afp_message        = -1;
779 static int hf_afp_message_type    = -1;
780 static int hf_afp_message_bitmap  = -1;
781 static int hf_afp_message_bitmap_REQ = -1;
782 static int hf_afp_message_bitmap_UTF = -1;
783 static int hf_afp_message_len    = -1;
784
785 static gint ett_afp_message_bitmap = -1;
786
787 static const value_string server_message_type[] = {
788   {0,   "Login message" },
789   {1,   "Server message" },
790   {0,   NULL } };
791
792 /*
793   file bitmap AFP3.1.pdf
794   Table 1-8 p. 29
795 same as dir
796 kFPAttributeBit                 (bit 0)
797 kFPParentDirIDBit               (bit 1)
798 kFPCreateDateBit                (bit 2)
799 kFPModDateBit                   (bit 3)
800 kFPBackupDateBit                (bit 4)
801 kFPFinderInfoBit                (bit 5)
802 kFPLongNameBit                  (bit 6)
803 kFPShortNameBit                 (bit 7)
804 kFPNodeIDBit                    (bit 8)
805
806 kFPUTF8NameBit                  (bit 13)
807 */
808
809 #define kFPDataForkLenBit               (1 << 9)
810 #define kFPRsrcForkLenBit               (1 << 10)
811 #define kFPExtDataForkLenBit            (1 << 11)
812 #define kFPLaunchLimitBit               (1 << 12)
813
814 #define kFPExtRsrcForkLenBit            (1 << 14)
815
816 /*
817   file attribute AFP3.1.pdf
818   Table 1-9 pp. 29-31
819 */
820 #define kFPInvisibleBit                         (1 << 0)
821 #define kFPMultiUserBit                         (1 << 1)
822 #define kFPSystemBit                            (1 << 2)
823 #define kFPDAlreadyOpenBit                      (1 << 3)
824 #define kFPRAlreadyOpenBit                      (1 << 4)
825 #define kFPWriteInhibitBit                      (1 << 5)
826 #define kFPBackUpNeededBit                      (1 << 6)
827 #define kFPRenameInhibitBit                     (1 << 7)
828 #define kFPDeleteInhibitBit                     (1 << 8)
829 #define kFPCopyProtectBit                       (1 << 10)
830 #define kFPSetClearBit                          (1 << 15)
831
832 /* dir attribute */
833 #define kIsExpFolder    (1 << 1)
834 #define kMounted        (1 << 3)
835 #define kInExpFolder    (1 << 4)
836
837 /* AFP 3.1 getsession token type */
838 #define kLoginWithoutID         0
839 #define kLoginWithID            1       
840 #define kReconnWithID           2
841 #define kLoginWithTimeAndID     3
842 #define kReconnWithTimeAndID    4
843
844 /* modified AFP 3.1 token type cf. page 327 */
845 #define kRecon1Login            5
846 #define kRecon1ReconnectLogin   6
847 #define kRecon1Refresh          7
848 #define kGetKerberosSessionKey  8
849
850 static const value_string token_type_vals[] = {
851   {kLoginWithoutID,             "LoginWithoutID"},
852   {kLoginWithID,                "LoginWithID"},
853   {kReconnWithID,               "ReconnWithID"},
854   {kLoginWithTimeAndID,         "LoginWithTimeAndID"},
855   {kReconnWithTimeAndID,        "ReconnWithTimeAndID"},
856   {kRecon1Login,                "Recon1Login"},
857   {kRecon1ReconnectLogin,       "Recon1ReconnectLogin"},
858   {kRecon1Refresh,              "Recon1Refresh"},
859   {kGetKerberosSessionKey,      "GetKerberosSessionKey"},
860
861   {0,                            NULL } };
862
863 /* AFP 3.2 ACL bitmap */
864 #define kFileSec_UUID           (1 << 0)
865 #define kFileSec_GRPUUID        (1 << 1)        
866 #define kFileSec_ACL            (1 << 2)        
867 #define kFileSec_REMOVEACL      (1 << 3)
868 #define kFileSec_Inherit        (1 << 4)
869
870 static int hf_afp_acl_list_bitmap               = -1;
871 static int hf_afp_acl_list_bitmap_UUID          = -1;
872 static int hf_afp_acl_list_bitmap_GRPUUID       = -1;
873 static int hf_afp_acl_list_bitmap_ACL           = -1;
874 static int hf_afp_acl_list_bitmap_REMOVEACL     = -1;
875 static int hf_afp_acl_list_bitmap_Inherit       = -1;
876 static int ett_afp_acl_list_bitmap              = -1;
877
878 static int hf_afp_access_bitmap         = -1;
879
880 static int hf_afp_acl_entrycount        = -1;
881 static int hf_afp_acl_flags             = -1;
882
883 static int hf_afp_ace_applicable        = -1;
884 static int hf_afp_ace_flags             = -1;
885 static int hf_afp_ace_rights            = -1;
886
887 static int ett_afp_ace_flags            = -1;
888 static int hf_afp_ace_flags_allow       = -1;
889 static int hf_afp_ace_flags_deny        = -1;
890 static int hf_afp_ace_flags_inherited   = -1;
891 static int hf_afp_ace_flags_fileinherit = -1;
892 static int hf_afp_ace_flags_dirinherit  = -1;
893 static int hf_afp_ace_flags_limitinherit= -1;
894 static int hf_afp_ace_flags_onlyinherit = -1;
895
896 /* AFP 3.2 ACE flags */
897 #define ACE_ALLOW        (1 << 0)
898 #define ACE_DENY         (1 << 1)
899 #define ACE_INHERITED    (1 << 4)
900 #define ACE_FILE_INHERIT (1 << 5)
901 #define ACE_DIR_INHERIT  (1 << 6)
902 #define ACE_LIMIT_INHERIT (1 << 7)
903 #define ACE_ONLY_INHERIT (1 << 8)
904
905 static int ett_afp_ace_entries          = -1;
906 static int ett_afp_ace_entry            = -1;
907
908 /* AFP 3.2 ACL access right cf page 248*/
909 #define KAUTH_VNODE_READ_DATA           (1 << 1)
910 #define KAUTH_VNODE_LIST_DIRECTORY      KAUTH_VNODE_READ_DATA
911 #define KAUTH_VNODE_WRITE_DATA          (1 << 2)
912 #define KAUTH_VNODE_ADD_FILE            KAUTH_VNODE_WRITE_DATA
913 #define KAUTH_VNODE_EXECUTE             (1 << 3)
914 #define KAUTH_VNODE_SEARCH              KAUTH_VNODE_EXECUTE
915 #define KAUTH_VNODE_DELETE              (1 << 4)
916 #define KAUTH_VNODE_APPEND_DATA         (1 << 5)
917 #define KAUTH_VNODE_ADD_SUBDIRECTORY    KAUTH_VNODE_APPEND_DATA
918 #define KAUTH_VNODE_DELETE_CHILD        (1 << 6)
919 #define KAUTH_VNODE_READ_ATTRIBUTES     (1 << 7)
920 #define KAUTH_VNODE_WRITE_ATTRIBUTES    (1 << 8)
921 #define KAUTH_VNODE_READ_EXTATTRIBUTES  (1 << 9)
922 #define KAUTH_VNODE_WRITE_EXTATTRIBUTES (1 << 10)
923 #define KAUTH_VNODE_READ_SECURITY       (1 << 11)
924 #define KAUTH_VNODE_WRITE_SECURITY      (1 << 12)
925 #define KAUTH_VNODE_CHANGE_OWNER        (1 << 13)
926 #define KAUTH_VNODE_SYNCHRONIZE         (1 << 20)
927 #define KAUTH_VNODE_GENERIC_ALL         (1 << 21)
928 #define KAUTH_VNODE_GENERIC_EXECUTE     (1 << 22)
929 #define KAUTH_VNODE_GENERIC_WRITE       (1 << 23)
930 #define KAUTH_VNODE_GENERIC_READ        (1 << 24)
931
932
933 static int hf_afp_acl_access_bitmap             = -1;
934 static int ett_afp_acl_access_bitmap            = -1;
935 static int hf_afp_acl_access_bitmap_read_data   = -1;
936 static int hf_afp_acl_access_bitmap_write_data  = -1;
937 static int hf_afp_acl_access_bitmap_execute     = -1;
938 static int hf_afp_acl_access_bitmap_delete      = -1;
939 static int hf_afp_acl_access_bitmap_append_data = -1;
940 static int hf_afp_acl_access_bitmap_delete_child= -1;
941 static int hf_afp_acl_access_bitmap_read_attrs  = -1;
942 static int hf_afp_acl_access_bitmap_write_attrs = -1;
943 static int hf_afp_acl_access_bitmap_read_extattrs  = -1;
944 static int hf_afp_acl_access_bitmap_write_extattrs = -1;
945 static int hf_afp_acl_access_bitmap_read_security  = -1;
946 static int hf_afp_acl_access_bitmap_write_security = -1;
947 static int hf_afp_acl_access_bitmap_change_owner   = -1;
948 static int hf_afp_acl_access_bitmap_synchronize = -1;
949 static int hf_afp_acl_access_bitmap_generic_all = -1;
950 static int hf_afp_acl_access_bitmap_generic_execute = -1;
951 static int hf_afp_acl_access_bitmap_generic_write   = -1;
952 static int hf_afp_acl_access_bitmap_generic_read    = -1;
953
954
955 #define hash_init_count 20
956
957 /* Hash functions */
958 static gint  afp_equal (gconstpointer v, gconstpointer v2);
959 static guint afp_hash  (gconstpointer v);
960
961 typedef struct {
962         guint32 conversation;
963         guint16 seq;
964 } afp_request_key;
965
966 static GHashTable *afp_request_hash = NULL;
967
968 static guint Vol;      /* volume */
969 static guint Did;      /* parent directory ID */
970
971 /* Hash Functions */
972 static gint  afp_equal (gconstpointer v, gconstpointer v2)
973 {
974         const afp_request_key *val1 = (const afp_request_key*)v;
975         const afp_request_key *val2 = (const afp_request_key*)v2;
976
977         if (val1->conversation == val2->conversation &&
978                         val1->seq == val2->seq) {
979                 return 1;
980         }
981         return 0;
982 }
983
984 static guint afp_hash  (gconstpointer v)
985 {
986         const afp_request_key *afp_key = (const afp_request_key*)v;
987         return afp_key->seq;
988 }
989
990 /* --------------------------
991 */
992 #define PAD(x)      { proto_tree_add_item(tree, hf_afp_pad, tvb, offset,  x, FALSE); offset += x; }
993
994 static guint16
995 decode_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
996 {
997         proto_tree *sub_tree = NULL;
998         proto_item *item;
999         guint16  bitmap;
1000
1001         bitmap = tvb_get_ntohs(tvb, offset);
1002         if (tree) {
1003                 item = proto_tree_add_item(tree, hf_afp_vol_bitmap, tvb, offset, 2,FALSE);
1004                 sub_tree = proto_item_add_subtree(item, ett_afp_vol_bitmap);
1005         }
1006
1007         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Attributes,     tvb, offset, 2,FALSE);
1008         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Signature,      tvb, offset, 2,FALSE);
1009         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_CreateDate,     tvb, offset, 2,FALSE);
1010         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ModDate,        tvb, offset, 2,FALSE);
1011         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BackupDate,     tvb, offset, 2,FALSE);
1012         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ID,             tvb, offset, 2,FALSE);
1013         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BytesFree,      tvb, offset, 2,FALSE);
1014         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BytesTotal,     tvb, offset, 2,FALSE);
1015         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_Name,           tvb, offset, 2,FALSE);
1016         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ExtBytesFree,   tvb, offset, 2,FALSE);
1017         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_ExtBytesTotal,  tvb, offset, 2,FALSE);
1018         proto_tree_add_item(sub_tree, hf_afp_vol_bitmap_BlockSize ,     tvb, offset, 2,FALSE);
1019
1020         return bitmap;
1021 }
1022
1023 /* -------------------------- */
1024 static guint16
1025 decode_vol_attribute (proto_tree *tree, tvbuff_t *tvb, gint offset)
1026 {
1027         proto_tree *sub_tree = NULL;
1028         proto_item *item;
1029         guint16  bitmap;
1030
1031         bitmap = tvb_get_ntohs(tvb, offset);
1032         if (tree) {
1033                 item = proto_tree_add_item(tree, hf_afp_vol_attribute, tvb, offset, 2,FALSE);
1034                 sub_tree = proto_item_add_subtree(item, ett_afp_vol_attribute);
1035         }
1036         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_ReadOnly                ,tvb, offset, 2,FALSE);
1037         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_HasVolumePassword       ,tvb, offset, 2,FALSE);
1038         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsFileIDs         ,tvb, offset, 2,FALSE);
1039         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsCatSearch       ,tvb, offset, 2,FALSE);
1040         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsBlankAccessPrivs,tvb, offset, 2,FALSE);
1041         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsUnixPrivs       ,tvb, offset, 2,FALSE);
1042         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsUTF8Names       ,tvb, offset, 2,FALSE);
1043         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_NoNetworkUserID         ,tvb, offset, 2,FALSE);
1044         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_DefaultPrivsFromParent  ,tvb, offset, 2,FALSE);
1045         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_NoExchangeFiles         ,tvb, offset, 2,FALSE);
1046         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsExtAttrs        ,tvb, offset, 2,FALSE);
1047         proto_tree_add_item(sub_tree, hf_afp_vol_attribute_SupportsACLs            ,tvb, offset, 2,FALSE);
1048
1049         return bitmap;
1050 }
1051
1052 /* --------------------------
1053         cf AFP3.0.pdf page 38
1054         date  are number of seconds from 12:00am on 01.01.2000 GMT
1055         backup : 0x8000000 not set
1056         from netatalk adouble.h
1057 */
1058 #define DATE_NOT_SET         0x80000000
1059 #define AD_DATE_DELTA         946684800
1060 #define AD_DATE_TO_UNIX(x)    (x + AD_DATE_DELTA)
1061 static guint32
1062 print_date(proto_tree *tree,int id, tvbuff_t *tvb, gint offset)
1063 {
1064         time_t date = tvb_get_ntohl(tvb, offset);
1065         nstime_t tv;
1066
1067         tv.secs = AD_DATE_TO_UNIX(date);
1068         tv.nsecs = 0;
1069         proto_tree_add_time(tree, id, tvb, offset, 4, &tv);
1070
1071         return date;
1072 }
1073
1074 /* -------------------------- */
1075 static gint
1076 parse_vol_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
1077 {
1078         guint16 nameoff = 0;
1079
1080         if ((bitmap & kFPVolAttributeBit)) {
1081                 decode_vol_attribute(tree,tvb,offset);
1082                 offset += 2;
1083         }
1084         if ((bitmap & kFPVolSignatureBit)) {
1085                 proto_tree_add_item(tree, hf_afp_vol_signature,tvb, offset, 2, FALSE);
1086                 offset += 2;
1087         }
1088         if ((bitmap & kFPVolCreateDateBit)) {
1089                 print_date(tree, hf_afp_vol_creation_date,tvb, offset);
1090                 offset += 4;
1091         }
1092         if ((bitmap & kFPVolModDateBit)) {
1093                 print_date(tree, hf_afp_vol_modification_date,tvb, offset);
1094                 offset += 4;
1095         }
1096         if ((bitmap & kFPVolBackupDateBit)) {
1097                 print_date(tree, hf_afp_vol_backup_date,tvb, offset);
1098                 offset += 4;
1099         }
1100         if ((bitmap & kFPVolIDBit)) {
1101                 proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
1102                 offset += 2;
1103         }
1104         if ((bitmap & kFPVolBytesFreeBit)) {
1105                 proto_tree_add_item(tree, hf_afp_vol_bytes_free,tvb, offset, 4, FALSE);
1106                 offset += 4;
1107         }
1108         if ((bitmap & kFPVolBytesTotalBit)) {
1109                 proto_tree_add_item(tree, hf_afp_vol_bytes_total,tvb, offset, 4, FALSE);
1110                 offset += 4;
1111         }
1112         if ((bitmap & kFPVolNameBit)) {
1113                 nameoff = tvb_get_ntohs(tvb, offset);
1114                 proto_tree_add_item(tree, hf_afp_vol_name_offset,tvb, offset, 2, FALSE);
1115                 offset += 2;
1116         }
1117         if ((bitmap & kFPVolExtBytesFreeBit)) {
1118                 proto_tree_add_item(tree, hf_afp_vol_ex_bytes_free,tvb, offset, 8, FALSE);
1119                 offset += 8;
1120         }
1121         if ((bitmap & kFPVolExtBytesTotalBit)) {
1122                 proto_tree_add_item(tree, hf_afp_vol_ex_bytes_total,tvb, offset, 8, FALSE);
1123                 offset += 8;
1124         }
1125         if ((bitmap & kFPVolBlockSizeBit)) {
1126                 proto_tree_add_item(tree, hf_afp_vol_block_size,tvb, offset, 4, FALSE);
1127                 offset += 4;
1128         }
1129         if (nameoff) {
1130                 guint8 len;
1131
1132                 len = tvb_get_guint8(tvb, offset);
1133                 proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
1134                 offset += len +1;
1135
1136         }
1137         return offset;
1138 }
1139
1140 /* -------------------------- */
1141 static guint16
1142 decode_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
1143 {
1144         proto_tree *sub_tree = NULL;
1145         proto_item *item;
1146         guint16         bitmap;
1147
1148         bitmap = tvb_get_ntohs(tvb, offset);
1149         if (tree) {
1150                 item = proto_tree_add_item(tree, hf_afp_file_bitmap, tvb, offset, 2,FALSE);
1151                 sub_tree = proto_item_add_subtree(item, ett_afp_file_bitmap);
1152         }
1153         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_Attributes      , tvb, offset, 2,FALSE);
1154         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ParentDirID    , tvb, offset, 2,FALSE);
1155         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_CreateDate     , tvb, offset, 2,FALSE);
1156         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ModDate        , tvb, offset, 2,FALSE);
1157         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_BackupDate     , tvb, offset, 2,FALSE);
1158         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_FinderInfo     , tvb, offset, 2,FALSE);
1159         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_LongName       , tvb, offset, 2,FALSE);
1160         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ShortName      , tvb, offset, 2,FALSE);
1161         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_NodeID         , tvb, offset, 2,FALSE);
1162
1163         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_DataForkLen    , tvb, offset, 2,FALSE);
1164         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_RsrcForkLen    , tvb, offset, 2,FALSE);
1165         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ExtDataForkLen , tvb, offset, 2,FALSE);
1166         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_LaunchLimit    , tvb, offset, 2,FALSE);
1167         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_UTF8Name           , tvb, offset, 2,FALSE);
1168
1169         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_ExtRsrcForkLen , tvb, offset, 2,FALSE);
1170         proto_tree_add_item(sub_tree, hf_afp_file_bitmap_UnixPrivs      , tvb, offset, 2,FALSE);
1171
1172         return bitmap;
1173 }
1174
1175 /* -------------------------- */
1176 static guint16
1177 decode_file_attribute(proto_tree *tree, tvbuff_t *tvb, gint offset, int shared)
1178 {
1179         proto_tree *sub_tree = NULL;
1180         proto_item *item;
1181         guint16         attribute;
1182
1183         attribute = tvb_get_ntohs(tvb, offset);
1184         if (tree) {
1185                 item = proto_tree_add_text(tree, tvb, offset, 2,
1186                                         "File Attributes: 0x%04x", attribute);
1187                 sub_tree = proto_item_add_subtree(item, ett_afp_file_attribute);
1188         }
1189         proto_tree_add_item(sub_tree, hf_afp_file_attribute_Invisible    , tvb, offset, 2,FALSE);
1190         if (!shared)
1191                 proto_tree_add_item(sub_tree, hf_afp_file_attribute_MultiUser    , tvb, offset, 2,FALSE);
1192
1193         proto_tree_add_item(sub_tree, hf_afp_file_attribute_System       , tvb, offset, 2,FALSE);
1194
1195         if (!shared) {
1196                 proto_tree_add_item(sub_tree, hf_afp_file_attribute_DAlreadyOpen , tvb, offset, 2,FALSE);
1197                 proto_tree_add_item(sub_tree, hf_afp_file_attribute_RAlreadyOpen , tvb, offset, 2,FALSE);
1198         }
1199         /* writeinhibit is file only but Macs are setting it with FPSetFileDirParms too */
1200         proto_tree_add_item(sub_tree, hf_afp_file_attribute_WriteInhibit , tvb, offset, 2,FALSE);
1201         proto_tree_add_item(sub_tree, hf_afp_file_attribute_BackUpNeeded , tvb, offset, 2,FALSE);
1202         proto_tree_add_item(sub_tree, hf_afp_file_attribute_RenameInhibit, tvb, offset, 2,FALSE);
1203         proto_tree_add_item(sub_tree, hf_afp_file_attribute_DeleteInhibit, tvb, offset, 2,FALSE);
1204
1205         if (!shared)
1206                 proto_tree_add_item(sub_tree, hf_afp_file_attribute_CopyProtect  , tvb, offset, 2,FALSE);
1207
1208         proto_tree_add_item(sub_tree, hf_afp_file_attribute_SetClear     , tvb, offset, 2,FALSE);
1209
1210         return(attribute);
1211 }
1212
1213 static void
1214 decode_access_rights (proto_tree *tree, tvbuff_t *tvb, int hf, gint offset)
1215 {
1216         proto_tree *sub_tree;
1217         proto_item *item;
1218
1219         if (tree) {
1220                 item = proto_tree_add_item(tree, hf, tvb, offset, 4, FALSE);
1221                 sub_tree = proto_item_add_subtree(item, ett_afp_dir_ar);
1222
1223                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_o_search, tvb, offset, 4,   FALSE);
1224                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_o_read  , tvb, offset, 4,   FALSE);
1225                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_o_write , tvb, offset, 4,   FALSE);
1226
1227                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_g_search, tvb, offset, 4,   FALSE);
1228                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_g_read  , tvb, offset, 4,   FALSE);
1229                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_g_write , tvb, offset, 4,   FALSE);
1230
1231                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_e_search, tvb, offset, 4,   FALSE);
1232                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_e_read  , tvb, offset, 4,   FALSE);
1233                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_e_write , tvb, offset, 4,   FALSE);
1234
1235                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_search, tvb, offset, 4,   FALSE);
1236                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_read  , tvb, offset, 4,   FALSE);
1237                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_write , tvb, offset, 4,   FALSE);
1238
1239                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_blank   , tvb, offset, 4,   FALSE);
1240                 proto_tree_add_item(sub_tree, hf_afp_dir_ar_u_own   , tvb, offset, 4,   FALSE);
1241         }
1242 }
1243
1244 static void
1245 decode_unix_privs (proto_tree *tree, tvbuff_t *tvb, gint offset)
1246 {
1247         proto_tree *sub_tree;
1248         proto_item *item;
1249
1250         if (tree) {
1251                 item = proto_tree_add_text(tree, tvb, offset, 16,
1252                     "UNIX privileges");
1253                 sub_tree = proto_item_add_subtree(item, ett_afp_unix_privs);
1254
1255                 proto_tree_add_item(sub_tree, hf_afp_unix_privs_uid, tvb, offset, 4, FALSE);
1256                 proto_tree_add_item(sub_tree, hf_afp_unix_privs_gid, tvb, offset+4, 4, FALSE);
1257                 proto_tree_add_item(sub_tree, hf_afp_unix_privs_permissions, tvb, offset+8, 4, FALSE);
1258                 decode_access_rights(sub_tree, tvb, hf_afp_unix_privs_ua_permissions, offset+12);
1259         }
1260 }
1261
1262 /* -------------------------- */
1263 static gint
1264 parse_long_filename(proto_tree *tree, tvbuff_t *tvb, gint offset, gint org_offset)
1265 {
1266         guint16 lnameoff;
1267         gint tp_ofs = 0;
1268         guint8 len;
1269
1270         lnameoff = tvb_get_ntohs(tvb, offset);
1271         proto_tree_add_item(tree, hf_afp_long_name_offset,tvb, offset, 2, FALSE);
1272         if (lnameoff) {
1273                 tp_ofs = lnameoff +org_offset;
1274                 len = tvb_get_guint8(tvb, tp_ofs);
1275                 proto_tree_add_item(tree, hf_afp_path_len, tvb, tp_ofs,  1,FALSE);
1276                 tp_ofs++;
1277                 proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, len,FALSE);
1278                 tp_ofs += len;
1279         }
1280         return tp_ofs;
1281 }
1282
1283 /* -------------------------- */
1284 static gint
1285 parse_UTF8_filename(proto_tree *tree, tvbuff_t *tvb, gint offset, gint org_offset)
1286 {
1287         guint16 unameoff;
1288         gint tp_ofs = 0;
1289         guint16 len;
1290
1291         unameoff = tvb_get_ntohs(tvb, offset);
1292         proto_tree_add_item(tree, hf_afp_unicode_name_offset,tvb, offset, 2, FALSE);
1293         offset += 2;
1294         if (unameoff) {
1295               /* FIXME AFP3.x reuses PDINFO bit for UTF8. 
1296                * In enumerate_ext it's pad with 4 bytes, PDINFO was 6 bytes,
1297                * but not in catsearch_ext. 
1298                * Last but not least there's a bug in OSX catsearch_ext for spec2
1299                * offset is off by 2 bytes.
1300                */
1301                
1302                 tp_ofs = unameoff +org_offset;
1303                if (tp_ofs > offset) {
1304                    PAD(4);
1305                 }
1306                 else if (tp_ofs < offset) {
1307                     tp_ofs = offset;
1308                 }
1309                 proto_tree_add_item( tree, hf_afp_path_unicode_hint, tvb, tp_ofs, 4,FALSE);
1310                 tp_ofs += 4;
1311
1312                 len = tvb_get_ntohs(tvb, tp_ofs);
1313                 proto_tree_add_item( tree, hf_afp_path_unicode_len, tvb, tp_ofs, 2,FALSE);
1314                 tp_ofs += 2;
1315
1316                 proto_tree_add_item(tree, hf_afp_path_name, tvb, tp_ofs, len,FALSE);
1317                 tp_ofs += len;
1318         }
1319         return tp_ofs;
1320 }
1321
1322 /* -------------------------- */
1323 static gint
1324 parse_file_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap, int shared)
1325 {
1326         /* guint16 snameoff = 0; */
1327         gint    max_offset = 0;
1328
1329         gint    org_offset = offset;
1330
1331         if ((bitmap & kFPAttributeBit)) {
1332                 decode_file_attribute(tree, tvb, offset, shared);
1333                 offset += 2;
1334         }
1335         if ((bitmap & kFPParentDirIDBit)) {
1336                 proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
1337                 offset += 4;
1338         }
1339         if ((bitmap & kFPCreateDateBit)) {
1340                 print_date(tree, hf_afp_creation_date,tvb, offset);
1341                 offset += 4;
1342         }
1343         if ((bitmap & kFPModDateBit)) {
1344                 print_date(tree, hf_afp_modification_date,tvb, offset);
1345                 offset += 4;
1346         }
1347         if ((bitmap & kFPBackupDateBit)) {
1348                 print_date(tree, hf_afp_backup_date,tvb, offset);
1349                 offset += 4;
1350         }
1351         if ((bitmap & kFPFinderInfoBit)) {
1352                 proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
1353                 offset += 32;
1354         }
1355         if ((bitmap & kFPLongNameBit)) {
1356                 gint tp_ofs;
1357
1358                 tp_ofs = parse_long_filename(tree, tvb, offset, org_offset);
1359                 max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
1360
1361                 offset += 2;
1362
1363         }
1364         if ((bitmap & kFPShortNameBit)) {
1365                 /* snameoff = tvb_get_ntohs(tvb, offset); */
1366                 proto_tree_add_item(tree, hf_afp_short_name_offset,tvb, offset, 2, FALSE);
1367                 offset += 2;
1368         }
1369         if ((bitmap & kFPNodeIDBit)) {
1370                 proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
1371                 offset += 4;
1372         }
1373
1374         if ((bitmap & kFPDataForkLenBit)) {
1375                 proto_tree_add_item(tree, hf_afp_file_DataForkLen, tvb, offset, 4,FALSE);
1376                 offset += 4;
1377         }
1378
1379         if ((bitmap & kFPRsrcForkLenBit)) {
1380                 proto_tree_add_item(tree, hf_afp_file_RsrcForkLen, tvb, offset, 4,FALSE);
1381                 offset += 4;
1382         }
1383
1384         if ((bitmap & kFPExtDataForkLenBit)) {
1385                 proto_tree_add_item(tree, hf_afp_file_ExtDataForkLen, tvb, offset, 8,FALSE);
1386                 offset += 8;
1387         }
1388
1389         if ((bitmap & kFPLaunchLimitBit)) {
1390                 offset += 2;    /* ? */
1391         }
1392
1393         if ((bitmap & kFPUTF8NameBit)) {
1394                 gint tp_ofs;
1395
1396                 tp_ofs = parse_UTF8_filename(tree, tvb, offset, org_offset);
1397                 max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
1398                 offset += 6;
1399         }
1400
1401         if ((bitmap & kFPExtRsrcForkLenBit)) {
1402                 proto_tree_add_item(tree, hf_afp_file_ExtRsrcForkLen, tvb, offset, 8,FALSE);
1403                 offset += 8;
1404         }
1405
1406         if ((bitmap & kFPUnixPrivsBit)) {
1407                 /*
1408                  * XXX - the AFP 3.0 spec says this is "Four bytes", but
1409                  * also says the privileges are "stored in an FPUnixPrivs
1410                  * structure", which is 16 bytes long.
1411                  *
1412                  * We assume, for now, that the latter is true.
1413                  */
1414                 decode_unix_privs(tree, tvb, offset);
1415                 offset += 16;
1416         }
1417
1418         return (max_offset)?max_offset:offset;
1419 }
1420
1421 /* -------------------------- */
1422 static guint16
1423 decode_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
1424 {
1425         proto_tree *sub_tree = NULL;
1426         proto_item *item;
1427         guint16         bitmap;
1428
1429         bitmap = tvb_get_ntohs(tvb, offset);
1430         if (tree) {
1431                 item = proto_tree_add_item(tree, hf_afp_dir_bitmap, tvb, offset, 2,FALSE);
1432                 sub_tree = proto_item_add_subtree(item, ett_afp_dir_bitmap);
1433         }
1434
1435         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_Attributes      , tvb, offset, 2,FALSE);
1436         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ParentDirID    , tvb, offset, 2,FALSE);
1437         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_CreateDate     , tvb, offset, 2,FALSE);
1438         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ModDate        , tvb, offset, 2,FALSE);
1439         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_BackupDate     , tvb, offset, 2,FALSE);
1440         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_FinderInfo     , tvb, offset, 2,FALSE);
1441         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_LongName       , tvb, offset, 2,FALSE);
1442         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_ShortName      , tvb, offset, 2,FALSE);
1443         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_NodeID         , tvb, offset, 2,FALSE);
1444         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_OffspringCount , tvb, offset, 2,FALSE);
1445         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_OwnerID        , tvb, offset, 2,FALSE);
1446         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_GroupID        , tvb, offset, 2,FALSE);
1447         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_AccessRights   , tvb, offset, 2,FALSE);
1448         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UTF8Name           , tvb, offset, 2,FALSE);
1449         proto_tree_add_item(sub_tree, hf_afp_dir_bitmap_UnixPrivs      , tvb, offset, 2,FALSE);
1450
1451         return bitmap;
1452 }
1453
1454 /* -------------------------- */
1455 static guint16
1456 decode_dir_attribute(proto_tree *tree, tvbuff_t *tvb, gint offset)
1457 {
1458         proto_tree *sub_tree = NULL;
1459         proto_item *item;
1460         guint16         attribute;
1461
1462         attribute = tvb_get_ntohs(tvb, offset);
1463         if (tree) {
1464                 item = proto_tree_add_text(tree, tvb, offset, 2,
1465                                         "Directory Attributes: 0x%04x", attribute);
1466                 sub_tree = proto_item_add_subtree(item, ett_afp_dir_attribute);
1467         }
1468         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_Invisible    , tvb, offset, 2,FALSE);
1469         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_IsExpFolder  , tvb, offset, 2,FALSE);
1470         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_System       , tvb, offset, 2,FALSE);
1471         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_Mounted      , tvb, offset, 2,FALSE);
1472         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_InExpFolder  , tvb, offset, 2,FALSE);
1473         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_BackUpNeeded , tvb, offset, 2,FALSE);
1474         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_RenameInhibit, tvb, offset, 2,FALSE);
1475         proto_tree_add_item(sub_tree, hf_afp_dir_attribute_DeleteInhibit, tvb, offset, 2,FALSE);
1476
1477         return(attribute);
1478 }
1479
1480 /* -------------------------- */
1481 static gint
1482 parse_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset, guint16 bitmap)
1483 {
1484         /* guint16 snameoff = 0; */
1485         gint    max_offset = 0;
1486
1487         gint    org_offset = offset;
1488
1489         if ((bitmap & kFPAttributeBit)) {
1490                 decode_dir_attribute(tree, tvb, offset);
1491                 offset += 2;
1492         }
1493         if ((bitmap & kFPParentDirIDBit)) {
1494                 proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
1495                 offset += 4;
1496         }
1497         if ((bitmap & kFPCreateDateBit)) {
1498                 print_date(tree, hf_afp_creation_date,tvb, offset);
1499                 offset += 4;
1500         }
1501         if ((bitmap & kFPModDateBit)) {
1502                 print_date(tree, hf_afp_modification_date,tvb, offset);
1503                 offset += 4;
1504         }
1505         if ((bitmap & kFPBackupDateBit)) {
1506                 print_date(tree, hf_afp_backup_date,tvb, offset);
1507                 offset += 4;
1508         }
1509         if ((bitmap & kFPFinderInfoBit)) {
1510                 proto_tree_add_item(tree, hf_afp_finder_info,tvb, offset, 32, FALSE);
1511                 offset += 32;
1512         }
1513         if ((bitmap & kFPLongNameBit)) {
1514                 gint tp_ofs;
1515
1516                 tp_ofs = parse_long_filename(tree, tvb, offset, org_offset);
1517                 max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
1518
1519                 offset += 2;
1520         }
1521         if ((bitmap & kFPShortNameBit)) {
1522                 /* snameoff = tvb_get_ntohs(tvb, offset); */
1523                 proto_tree_add_item(tree, hf_afp_short_name_offset,tvb, offset, 2, FALSE);
1524                 offset += 2;
1525         }
1526         if ((bitmap & kFPNodeIDBit)) {
1527                 proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
1528                 offset += 4;
1529         }
1530         if ((bitmap & kFPOffspringCountBit)) {
1531                 proto_tree_add_item(tree, hf_afp_dir_offspring, tvb, offset, 2,FALSE);
1532                 offset += 2;            /* error in AFP3.0.pdf */
1533         }
1534         if ((bitmap & kFPOwnerIDBit)) {
1535                 proto_tree_add_item(tree, hf_afp_dir_OwnerID, tvb, offset, 4,   FALSE);
1536                 offset += 4;
1537         }
1538         if ((bitmap & kFPGroupIDBit)) {
1539                 proto_tree_add_item(tree, hf_afp_dir_GroupID, tvb, offset, 4,   FALSE);
1540                 offset += 4;
1541         }
1542         if ((bitmap & kFPAccessRightsBit)) {
1543                 decode_access_rights(tree, tvb, hf_afp_dir_ar, offset);
1544                 offset += 4;
1545         }
1546         if ((bitmap & kFPUTF8NameBit)) {
1547                 gint tp_ofs;
1548
1549                 tp_ofs = parse_UTF8_filename(tree, tvb, offset, org_offset);
1550                 max_offset = (tp_ofs >max_offset)?tp_ofs:max_offset;
1551                 offset += 6;
1552         }
1553         if ((bitmap & kFPUnixPrivsBit)) {
1554                 /*
1555                  * XXX - the AFP 3.0 spec says this is "Four bytes", but
1556                  * also says the privileges are "stored in an FPUnixPrivs
1557                  * structure", which is 16 bytes long.
1558                  *
1559                  * We assume, for now, that the latter is true.
1560                  */
1561                 decode_unix_privs(tree, tvb, offset);
1562                 offset += 16;
1563         }
1564         return (max_offset)?max_offset:offset;
1565 }
1566
1567 /* -------------------------- */
1568 static gchar *
1569 name_in_bitmap(tvbuff_t *tvb, gint offset, guint16 bitmap, int isdir)
1570 {
1571         gchar *name;
1572         gint    org_offset = offset;
1573         guint16 nameoff;
1574         guint8  len;
1575         guint16 len16;
1576         gint    tp_ofs;
1577
1578         if ((bitmap & kFPAttributeBit))         /* 0 */
1579                 offset += 2;
1580         if ((bitmap & kFPParentDirIDBit))       /* 1 */
1581                 offset += 4;
1582         if ((bitmap & kFPCreateDateBit))        /* 2 */
1583                 offset += 4;
1584         if ((bitmap & kFPModDateBit))           /* 3 */
1585                 offset += 4;
1586         if ((bitmap & kFPBackupDateBit))        /* 4 */
1587                 offset += 4;
1588         if ((bitmap & kFPFinderInfoBit))        /* 5 */
1589                 offset += 32;
1590
1591         if ((bitmap & kFPLongNameBit)) {        /* 6 */
1592                 nameoff = tvb_get_ntohs(tvb, offset);
1593                 if (nameoff) {
1594                         tp_ofs = nameoff +org_offset;
1595                         len = tvb_get_guint8(tvb, tp_ofs);
1596                         tp_ofs++;
1597                         name = tvb_get_ephemeral_string(tvb, tp_ofs, len);
1598                         return name;
1599                 }
1600                 offset += 2;
1601         }
1602         
1603         if ((bitmap & kFPShortNameBit))         /* 7 */
1604                 offset += 2;
1605         if ((bitmap & kFPNodeIDBit))            /* 8 */
1606                 offset += 4;
1607
1608         if (isdir) {
1609                 if ((bitmap & kFPOffspringCountBit))    /* 9 */
1610                         offset += 2;
1611                 if ((bitmap & kFPOwnerIDBit))           /* 10*/
1612                         offset += 4;
1613                 if ((bitmap & kFPGroupIDBit))           /* 11*/
1614                         offset += 4;
1615                 if ((bitmap & kFPAccessRightsBit))      /* 12*/
1616                         offset += 4;
1617         }
1618         else {
1619                 if ((bitmap & kFPDataForkLenBit))       /* 9 */
1620                         offset += 4;
1621                 if ((bitmap & kFPRsrcForkLenBit))       /* 10*/
1622                         offset += 4;
1623                 if ((bitmap & kFPExtDataForkLenBit))    /* 11*/
1624                         offset += 8;
1625                 if ((bitmap & kFPLaunchLimitBit))       /* 12*/
1626                         offset += 2; /* FIXME ? */
1627         }
1628
1629         if ((bitmap & kFPUTF8NameBit)) {                /* 13 */
1630                 nameoff = tvb_get_ntohs(tvb, offset);
1631                 if (nameoff) {
1632                         tp_ofs = nameoff +org_offset +4;
1633                         len16 = tvb_get_ntohs(tvb, tp_ofs);
1634                         tp_ofs += 2;
1635                         name = tvb_get_ephemeral_string(tvb, tp_ofs, len16);
1636                         return name;
1637                 }
1638         }
1639         return NULL;
1640 }
1641
1642 /* -------------------------- */
1643 static gchar *
1644 name_in_dbitmap(tvbuff_t *tvb, gint offset, guint16 bitmap)
1645 {
1646         gchar *name;
1647
1648         name = name_in_bitmap(tvb, offset, bitmap, 1);
1649         if (name != NULL)
1650                 return name;
1651         /*
1652                 check UTF8 name
1653         */
1654
1655         return name;
1656 }
1657
1658 /* -------------------------- */
1659 static gchar *
1660 name_in_fbitmap(tvbuff_t *tvb, gint offset, guint16 bitmap)
1661 {
1662         gchar *name;
1663
1664         name = name_in_bitmap(tvb, offset, bitmap, 0);
1665         if (name != NULL)
1666                 return name;
1667         /*
1668                 check UTF8 name
1669         */
1670
1671         return name;
1672 }
1673
1674 /* -------------------------- */
1675 static gint
1676 decode_vol_did(proto_tree *tree, tvbuff_t *tvb, gint offset)
1677 {
1678         Vol = tvb_get_ntohs(tvb, offset);
1679         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
1680         offset += 2;
1681
1682         Did = tvb_get_ntohl(tvb, offset);
1683         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
1684         offset += 4;
1685         return offset;
1686 }
1687
1688 /* -------------------------- */
1689 static gint
1690 decode_vol_did_file_dir_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
1691 {
1692         offset = decode_vol_did(tree, tvb, offset);
1693
1694         decode_file_bitmap(tree, tvb, offset);
1695         offset += 2;
1696
1697         decode_dir_bitmap(tree, tvb, offset);
1698         offset += 2;
1699
1700         return offset;
1701 }
1702
1703 /* ------------------------ */
1704 static const gchar *
1705 get_name(tvbuff_t *tvb, int offset, int type)
1706 {
1707         int   len;
1708         const gchar *string;
1709
1710         switch (type) {
1711         case 1:
1712         case 2:
1713                 len = tvb_get_guint8(tvb, offset);
1714                 offset++;
1715                 string = tvb_format_text(tvb,offset, len);
1716                 break;
1717         case 3:
1718                 len = tvb_get_ntohs(tvb, offset +4);
1719                 offset += 6;
1720                 string = tvb_format_text(tvb,offset, len);
1721                 break;
1722         default:
1723                 string = "Unknown type";
1724                 break;
1725         }
1726         return string;
1727 }
1728 /* -------------------------- */
1729 static gint
1730 decode_name_label (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset, const gchar *label)
1731 {
1732         int len;
1733         int header;
1734         const gchar *name;
1735         guint8 type;
1736         proto_tree *sub_tree = NULL;
1737         proto_item *item;
1738
1739         type = tvb_get_guint8(tvb, offset);
1740         if (type == 3) {
1741                 header = 7;
1742                 len = tvb_get_ntohs(tvb, offset +5);
1743         }
1744         else {
1745                 header = 2;
1746                 len = tvb_get_guint8(tvb, offset +1);
1747         }
1748         name = get_name(tvb, offset +1, type);
1749
1750         if (pinfo && check_col(pinfo->cinfo, COL_INFO)) {
1751                 col_append_fstr(pinfo->cinfo, COL_INFO, ": Vol=%u Did=%u", Vol, Did);
1752                 if (len) {
1753                         col_append_fstr(pinfo->cinfo, COL_INFO, " Name=%s", name);
1754                 }
1755         }
1756
1757         if (tree) {
1758                 item = proto_tree_add_text(tree, tvb, offset, len +header, label, name);
1759                 sub_tree = proto_item_add_subtree(item, ett_afp_path_name);
1760
1761                 proto_tree_add_item(  sub_tree, hf_afp_path_type, tvb, offset,   1,FALSE);
1762                 offset++;
1763                 if (type == 3) {
1764                         proto_tree_add_item( sub_tree, hf_afp_path_unicode_hint,  tvb, offset,  4,FALSE);
1765                         offset += 4;
1766                         proto_tree_add_item( sub_tree, hf_afp_path_unicode_len,  tvb, offset,   2,FALSE);
1767                         offset += 2;
1768                 }
1769                 else {
1770                         proto_tree_add_item( sub_tree, hf_afp_path_len,  tvb, offset,   1,FALSE);
1771                         offset++;
1772                 }
1773
1774                 proto_tree_add_string(sub_tree, hf_afp_path_name, tvb, offset, len,name);
1775         }
1776         else
1777                 offset += header;
1778
1779         return offset +len;
1780 }
1781
1782 /* -------------------------- */
1783 static gint
1784 decode_name (proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, gint offset)
1785 {
1786         return decode_name_label(tree, pinfo, tvb, offset, "Path: %s");
1787 }
1788
1789 /* -------------------------- */
1790 static void
1791 add_info_fork(tvbuff_t *tvb, packet_info *pinfo, gint offset)
1792 {
1793         guint16 ofork;
1794
1795         ofork = tvb_get_ntohs(tvb, offset);
1796         if (ofork && check_col(pinfo->cinfo, COL_INFO)) {
1797                 col_append_fstr(pinfo->cinfo, COL_INFO, ": Fork=%u", ofork);
1798         }
1799 }
1800
1801 /* -------------------------- */
1802 static void
1803 add_info_vol(tvbuff_t *tvb, packet_info *pinfo, gint offset)
1804 {
1805         guint16 vol;
1806
1807         vol = tvb_get_ntohs(tvb, offset);
1808         if (check_col(pinfo->cinfo, COL_INFO)) {
1809                 col_append_fstr(pinfo->cinfo, COL_INFO, ": Vol=%u", vol);
1810         }
1811 }
1812
1813 /* ************************** */
1814 static gint
1815 dissect_query_afp_open_vol(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1816 {
1817         int len;
1818
1819         PAD(1);
1820
1821         decode_vol_bitmap(tree, tvb, offset);
1822         offset += 2;
1823
1824         len = tvb_get_guint8(tvb, offset);
1825
1826         if (check_col(pinfo->cinfo, COL_INFO)) {
1827                 const gchar *rep;
1828                 rep = get_name(tvb, offset, 2);
1829                 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", rep);
1830         }
1831
1832         if (!tree)
1833                 return offset;
1834
1835         proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
1836         offset += len +1;
1837
1838         len = tvb_reported_length_remaining(tvb,offset);
1839         if (len >= 8) {
1840                 /* optionnal password */
1841                 proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, 8,FALSE);
1842                 offset += 8;
1843         }
1844         return offset;
1845 }
1846
1847 /* -------------------------- */
1848 static gint
1849 dissect_reply_afp_open_vol(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
1850 {
1851         guint16 bitmap;
1852
1853         if (!tree)
1854                 return offset;
1855         bitmap = decode_vol_bitmap(tree, tvb, offset);
1856         offset += 2;
1857         offset = parse_vol_bitmap(tree, tvb, offset, bitmap);
1858
1859         return offset;
1860 }
1861
1862 /* ************************** */
1863 static gint
1864 dissect_reply_afp_get_server_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
1865 {
1866         guint8 num;
1867         guint8 len;
1868         guint8 flag;
1869         guint8 i;
1870         proto_tree *sub_tree = NULL;
1871         proto_tree *flag_tree;
1872         proto_item *item;
1873         proto_item *ti;
1874
1875         if (!tree)
1876                 return offset;
1877
1878         print_date(tree, hf_afp_server_time,tvb, offset);
1879         offset += 4;
1880
1881         num = tvb_get_guint8(tvb, offset);
1882         item = proto_tree_add_text(tree, tvb, offset, 1, "Volumes : %d", num);
1883         sub_tree = proto_item_add_subtree(item, ett_afp_server_vol);
1884         offset++;
1885
1886         for (i = 0; i < num; i++) {
1887                 const gchar *rep;
1888
1889                 item = proto_tree_add_text(sub_tree, tvb, offset, -1,"Volume");
1890                 tree = proto_item_add_subtree(item, ett_afp_vol_list);
1891
1892                 flag = tvb_get_guint8(tvb, offset);
1893
1894                 ti = proto_tree_add_text(tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1895                 flag_tree = proto_item_add_subtree(ti, ett_afp_vol_flag);
1896                 proto_tree_add_item(flag_tree, hf_afp_vol_flag_passwd, tvb, offset, 1,FALSE);
1897                 proto_tree_add_item(flag_tree, hf_afp_vol_flag_unix_priv ,tvb, offset, 1,FALSE);
1898                 offset++;
1899
1900                 len  = tvb_get_guint8(tvb, offset) +1;
1901                 rep = get_name(tvb, offset, 2);
1902                 proto_item_set_text(item, "%s", rep);
1903                 proto_item_set_len(item, len +1);
1904
1905                 proto_tree_add_item(tree, hf_afp_vol_name, tvb, offset, 1,FALSE);
1906
1907                 offset += len;
1908         }
1909         return offset;
1910 }
1911
1912 /* **************************
1913         next calls use the same format :
1914                 1 pad byte
1915                 volume id
1916         AFP_FLUSH
1917         AFP_CLOSEVOL
1918         AFP_OPENDT
1919 */
1920 static gint
1921 dissect_query_afp_with_vol_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
1922 {
1923
1924         if (!tree)
1925                 return offset;
1926         PAD(1);
1927
1928         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
1929         offset += 2;
1930         return offset;
1931 }
1932
1933 /* ************************** */
1934 static gint
1935 dissect_query_afp_open_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1936 {
1937         proto_tree *sub_tree = NULL;
1938         proto_item *item;
1939
1940         proto_tree_add_item(tree, hf_afp_fork_type, tvb, offset, 1,FALSE);
1941         offset++;
1942
1943         offset = decode_vol_did(tree, tvb, offset);
1944
1945         decode_file_bitmap(tree, tvb, offset);
1946         offset += 2;
1947         if (tree) {
1948                 item = proto_tree_add_item(tree, hf_afp_access_mode, tvb, offset, 2,FALSE);
1949                 sub_tree = proto_item_add_subtree(item, ett_afp_access_mode);
1950
1951                 proto_tree_add_item(sub_tree, hf_afp_access_read      , tvb, offset, 2,FALSE);
1952                 proto_tree_add_item(sub_tree, hf_afp_access_write     , tvb, offset, 2,FALSE);
1953                 proto_tree_add_item(sub_tree, hf_afp_access_deny_read , tvb, offset, 2,FALSE);
1954                 proto_tree_add_item(sub_tree, hf_afp_access_deny_write, tvb, offset, 2,FALSE);
1955         }
1956         offset += 2;
1957
1958         offset = decode_name(tree, pinfo, tvb, offset);
1959
1960         return offset;
1961 }
1962
1963 /* -------------------------- */
1964 static gint
1965 dissect_reply_afp_open_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1966 {
1967         guint16 f_bitmap;
1968         
1969         f_bitmap = decode_file_bitmap(tree, tvb, offset);
1970         offset += 2;
1971
1972         add_info_fork(tvb, pinfo, offset);
1973         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
1974         offset += 2;
1975
1976         offset = parse_file_bitmap(tree, tvb, offset, f_bitmap,0);
1977
1978         return offset;
1979 }
1980
1981 /* ************************** */
1982 static gint
1983 dissect_query_afp_enumerate_ext2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
1984 {
1985
1986         PAD(1);
1987         offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
1988
1989         proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
1990         offset += 2;
1991
1992         proto_tree_add_item(tree, hf_afp_start_index32, tvb, offset, 4,FALSE);
1993         offset += 4;
1994
1995         proto_tree_add_item(tree, hf_afp_max_reply_size32, tvb, offset, 4,FALSE);
1996         offset += 4;
1997
1998         offset = decode_name(tree, pinfo, tvb, offset);
1999
2000         return offset;
2001 }
2002
2003 /* ************************** */
2004 static gint
2005 dissect_query_afp_enumerate(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2006 {
2007
2008         PAD(1);
2009         offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
2010
2011         proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
2012         offset += 2;
2013
2014         proto_tree_add_item(tree, hf_afp_start_index, tvb, offset, 2,FALSE);
2015         offset += 2;
2016
2017         proto_tree_add_item(tree, hf_afp_max_reply_size, tvb, offset, 2,FALSE);
2018         offset += 2;
2019
2020         offset = decode_name(tree, pinfo, tvb, offset);
2021
2022         return offset;
2023 }
2024
2025 /* -------------------------- */
2026 static int
2027 loop_record(tvbuff_t *tvb, proto_tree *ptree, gint offset,
2028                 int count, guint16 d_bitmap, guint16 f_bitmap, int add, int ext)
2029 {
2030         proto_tree *tree = NULL;
2031         proto_item *item;
2032         gchar   *name;
2033         guint8  flags;
2034         guint   size;
2035         gint    org;
2036         int i;
2037         int decal; 
2038
2039         for (i = 0; i < count; i++) {
2040                 org = offset;
2041                 if (ext) {
2042                         size = tvb_get_ntohs(tvb, offset) +add *2;
2043                         decal = 2;
2044                 }
2045                 else {
2046                         size = tvb_get_guint8(tvb, offset) +add;
2047                         decal = 1;
2048                 }
2049                 if (!size)
2050                         return offset;  /* packet is malformed */
2051                 flags = tvb_get_guint8(tvb, offset +decal);
2052
2053                 decal += (ext)?2:1;
2054
2055                 if (ptree) {
2056                         if (flags) {
2057                                 name = name_in_dbitmap(tvb, offset +decal, d_bitmap);
2058                         }
2059                         else {
2060                                 name = name_in_fbitmap(tvb, offset +decal, f_bitmap);
2061                         }
2062                         if (name) {
2063                                 item = proto_tree_add_text(ptree, tvb, offset, size, "%s", name);
2064                         }
2065                         else {
2066                                 item = proto_tree_add_text(ptree, tvb, offset, size, "line %d", i+1);
2067                         }
2068                         tree = proto_item_add_subtree(item, ett_afp_enumerate_line);
2069                 }
2070                 if (ext) {
2071                         proto_tree_add_item(tree, hf_afp_struct_size16, tvb, offset, 2,FALSE);
2072                         offset += 2;
2073                 }
2074                 else {
2075                         proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1,FALSE);
2076                         offset++;
2077                 }
2078
2079                 proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
2080                 offset++;
2081                 if (ext) {
2082                         PAD(1);
2083                 }
2084                 if (flags) {
2085                         offset = parse_dir_bitmap(tree, tvb, offset, d_bitmap);
2086                 }
2087                 else {
2088                         offset = parse_file_bitmap(tree, tvb, offset, f_bitmap,0);
2089                 }
2090                 if ((offset & 1))
2091                         PAD(1);
2092                 offset = org +size;             /* play safe */
2093         }
2094         return offset;
2095 }
2096 /* ------------------------- */
2097 static gint
2098 reply_enumerate(tvbuff_t *tvb, proto_tree *tree, gint offset, int ext)
2099 {
2100         proto_tree *sub_tree = NULL;
2101         proto_item *item;
2102         int count;
2103         guint16 f_bitmap;
2104         guint16 d_bitmap;
2105
2106         f_bitmap = decode_file_bitmap(tree, tvb, offset);
2107         offset += 2;
2108
2109         d_bitmap = decode_dir_bitmap(tree, tvb, offset);
2110         offset += 2;
2111
2112         count = tvb_get_ntohs(tvb, offset);
2113         if (tree) {
2114                 item = proto_tree_add_item(tree, hf_afp_req_count, tvb, offset, 2,FALSE);
2115                 sub_tree = proto_item_add_subtree(item, ett_afp_enumerate);
2116         }
2117         offset += 2;
2118
2119         return loop_record(tvb,sub_tree, offset, count, d_bitmap, f_bitmap,0, ext);
2120 }
2121
2122 /* ------------------------- */
2123 static gint
2124 dissect_reply_afp_enumerate(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2125 {
2126         return reply_enumerate(tvb, tree, offset, 0);
2127 }
2128
2129 /* **************************/
2130 static gint
2131 dissect_reply_afp_enumerate_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2132 {
2133         return reply_enumerate(tvb, tree, offset, 1);
2134 }
2135
2136 /* **************************/
2137 static gint
2138 catsearch_spec(tvbuff_t *tvb, proto_tree *ptree, gint offset, int ext, guint32  bitmap, const gchar *label)
2139 {
2140         proto_tree *tree = NULL;
2141         proto_item *item;
2142         guint16 size;
2143         gint    org;
2144
2145         org = offset;
2146
2147         if (ext) {
2148                 size = tvb_get_ntohs(tvb, offset) +2;
2149         }
2150         else {
2151                 size = tvb_get_guint8(tvb, offset) +2;
2152         }
2153
2154         item = proto_tree_add_text(ptree, tvb, offset, size, label);
2155         tree = proto_item_add_subtree(item, ett_afp_cat_spec);
2156
2157         if (ext) {
2158                 proto_tree_add_item(tree, hf_afp_struct_size16, tvb, offset, 2,FALSE);
2159                 offset += 2;
2160         }
2161         else {
2162                 proto_tree_add_item(tree, hf_afp_struct_size, tvb, offset, 1,FALSE);
2163                 offset++;
2164                 PAD(1);
2165         }
2166
2167         offset = parse_file_bitmap(tree, tvb, offset, (guint16) bitmap,0);
2168         offset = org +size;
2169
2170         return offset;
2171 }
2172
2173 /* ------------------------- */
2174 static gint
2175 query_catsearch(tvbuff_t *tvb, proto_tree *ptree, gint offset, int ext)
2176 {
2177         proto_tree *tree = NULL, *sub_tree;
2178         proto_item *item;
2179         guint16 f_bitmap;
2180         guint16 d_bitmap;
2181         guint32 r_bitmap;
2182
2183         if (!ptree)
2184                 return offset;
2185         PAD(1);
2186
2187         proto_tree_add_item(ptree, hf_afp_vol_id, tvb, offset, 2,FALSE);
2188         offset += 2;
2189
2190         proto_tree_add_item(ptree, hf_afp_cat_req_matches, tvb, offset, 4,FALSE);
2191         offset += 4;
2192
2193         proto_tree_add_item(ptree, hf_afp_reserved, tvb, offset, 4,FALSE);
2194         offset += 4;
2195
2196         proto_tree_add_item(ptree, hf_afp_cat_position, tvb, offset, 16,FALSE);
2197         offset += 16;
2198
2199         f_bitmap = decode_file_bitmap(ptree, tvb, offset);
2200         offset += 2;
2201
2202         d_bitmap = decode_dir_bitmap(ptree, tvb, offset);
2203         offset += 2;
2204
2205         r_bitmap = tvb_get_ntohl(tvb, offset);
2206         /* Already checked this above: if (ptree) */ {
2207                 item = proto_tree_add_item(ptree, hf_afp_file_bitmap, tvb, offset, 4,FALSE);
2208                 sub_tree = proto_item_add_subtree(item, ett_afp_cat_r_bitmap);
2209
2210                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_Attributes      , tvb, offset, 4,FALSE);
2211                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ParentDirID    , tvb, offset, 4,FALSE);
2212                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_CreateDate     , tvb, offset, 4,FALSE);
2213                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ModDate        , tvb, offset, 4,FALSE);
2214                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_BackupDate     , tvb, offset, 4,FALSE);
2215                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_FinderInfo     , tvb, offset, 4,FALSE);
2216                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_LongName       , tvb, offset, 4,FALSE);
2217
2218                 if (d_bitmap == 0) {
2219                         /* Only for file-only searches */
2220                         proto_tree_add_item(sub_tree, hf_afp_request_bitmap_DataForkLen         , tvb, offset, 4,FALSE);
2221                         proto_tree_add_item(sub_tree, hf_afp_request_bitmap_RsrcForkLen         , tvb, offset, 4,FALSE);
2222                         proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ExtDataForkLen      , tvb, offset, 4,FALSE);
2223                 }
2224                 if (f_bitmap == 0) {
2225                         /* Only for directory-only searches */
2226                         proto_tree_add_item(sub_tree, hf_afp_request_bitmap_OffspringCount      , tvb, offset, 4,FALSE);
2227                 }
2228
2229                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_UTF8Name        , tvb, offset, 4,FALSE);
2230
2231                 if (d_bitmap == 0) {
2232                         /* Only for file-only searches */
2233                         proto_tree_add_item(sub_tree, hf_afp_request_bitmap_ExtRsrcForkLen      , tvb, offset, 4,FALSE);
2234                 }
2235                 proto_tree_add_item(sub_tree, hf_afp_request_bitmap_PartialNames        , tvb, offset, 4,FALSE);
2236         }
2237         offset += 4;
2238
2239         /* spec 1 */
2240         offset = catsearch_spec(tvb, ptree, offset, ext, r_bitmap, "Spec 1");
2241
2242         /* spec 2 */
2243         offset = catsearch_spec(tvb, ptree, offset, ext, r_bitmap, "Spec 2");
2244         
2245         return offset;
2246 }
2247
2248 /* ------------------------- */
2249 static gint
2250 dissect_query_afp_cat_search(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ptree, gint offset)
2251 {
2252         return query_catsearch(tvb, ptree, offset, 0);
2253
2254 }
2255 /* **************************/
2256 static gint
2257 dissect_query_afp_cat_search_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *ptree, gint offset)
2258 {
2259         return query_catsearch(tvb, ptree, offset, 1);
2260
2261 }
2262
2263 /* **************************/
2264 static gint
2265 reply_catsearch(tvbuff_t *tvb, proto_tree *tree, gint offset, int ext)
2266 {
2267         proto_tree *sub_tree = NULL;
2268         proto_item *item;
2269         guint16 f_bitmap;
2270         guint16 d_bitmap;
2271         int count;
2272
2273         proto_tree_add_item(tree, hf_afp_cat_position, tvb, offset, 16,FALSE);
2274         offset += 16;
2275
2276         f_bitmap = decode_file_bitmap(tree, tvb, offset);
2277         offset += 2;
2278
2279         d_bitmap = decode_dir_bitmap(tree, tvb, offset);
2280         offset += 2;
2281
2282         count = tvb_get_ntohl(tvb, offset);
2283         if (tree) {
2284                 item = proto_tree_add_item(tree, hf_afp_cat_count, tvb, offset, 4,FALSE);
2285                 sub_tree = proto_item_add_subtree(item, ett_afp_cat_search);
2286         }
2287         offset += 4;
2288
2289         return loop_record(tvb,sub_tree, offset, count, d_bitmap, f_bitmap, 2, ext);
2290 }
2291
2292 /* -------------------------- */
2293 static gint
2294 dissect_reply_afp_cat_search(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2295 {
2296         return reply_catsearch(tvb, tree, offset, 0);
2297 }
2298
2299 /* **************************/
2300 static gint
2301 dissect_reply_afp_cat_search_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2302 {
2303         return reply_catsearch(tvb, tree, offset, 1);
2304 }
2305
2306 /* **************************/
2307 static gint
2308 dissect_query_afp_get_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2309 {
2310
2311         PAD(1)
2312         add_info_vol(tvb, pinfo, offset);
2313         
2314         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
2315         offset += 2;
2316
2317         decode_vol_bitmap(tree, tvb, offset);
2318         offset += 2;
2319
2320         return offset;
2321 }
2322
2323 /* ------------------------ */
2324 static gint
2325 dissect_reply_afp_get_vol_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2326 {
2327         guint16 bitmap;
2328
2329         bitmap = decode_vol_bitmap(tree, tvb, offset);
2330         offset += 2;
2331
2332         offset = parse_vol_bitmap(tree, tvb, offset, bitmap);
2333
2334         return offset;
2335 }
2336
2337 /* **************************/
2338 static gint
2339 dissect_query_afp_set_vol_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2340 {
2341         guint16 bitmap;
2342
2343         PAD(1)
2344
2345         add_info_vol(tvb, pinfo, offset);
2346         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
2347         offset += 2;
2348
2349         bitmap = decode_vol_bitmap(tree, tvb, offset);
2350         offset += 2;
2351
2352         offset = parse_vol_bitmap(tree, tvb, offset, bitmap);
2353
2354         return offset;
2355 }
2356
2357 /* ***************************/
2358 static gint
2359 decode_uam_parameters(const char *uam, int len_uam, tvbuff_t *tvb, proto_tree *tree, gint offset)
2360 {
2361         int len;
2362
2363         if (!strncasecmp(uam, "Cleartxt passwrd", len_uam)) {
2364                 if ((offset & 1))
2365                         PAD(1);
2366
2367                 len = 8; /* tvb_strsize(tvb, offset);*/
2368                 proto_tree_add_item(tree, hf_afp_passwd, tvb, offset, len,FALSE);
2369                 offset += len;
2370         }
2371         else if (!strncasecmp(uam, "DHCAST128", len_uam)) {
2372                 if ((offset & 1))
2373                         PAD(1);
2374
2375                 len = 16;
2376                 proto_tree_add_item(tree, hf_afp_random, tvb, offset, len,FALSE);
2377                 offset += len;
2378         }
2379         else if (!strncasecmp(uam, "2-Way Randnum exchange", len_uam)) {
2380                 /* nothing */
2381                 return offset;
2382         }
2383         return offset;
2384 }
2385
2386 /* ---------------- */
2387 static gint
2388 dissect_query_afp_login(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2389 {
2390         int len;
2391         int len_uam;
2392         const char *uam;
2393
2394         len = tvb_get_guint8(tvb, offset);
2395         proto_tree_add_item(tree, hf_afp_AFPVersion, tvb, offset, 1,FALSE);
2396         offset += len +1;
2397         len_uam = tvb_get_guint8(tvb, offset);
2398         uam = tvb_get_ptr(tvb, offset +1, len_uam);
2399         proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1,FALSE);
2400         offset += len_uam +1;
2401
2402         if (!strncasecmp(uam, "No User Authent", len_uam)) {
2403                 return offset;
2404         }
2405
2406         len = tvb_get_guint8(tvb, offset);
2407         proto_tree_add_item(tree, hf_afp_user, tvb, offset, 1,FALSE);
2408         offset += len +1;
2409         
2410         return decode_uam_parameters(uam, len_uam, tvb, tree, offset);
2411 }
2412
2413 /* ***************************/
2414 static gint
2415 dissect_query_afp_login_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2416 {
2417         int len;
2418         int len_uam;
2419         const char *uam;
2420         guint8 type;
2421
2422         type = tvb_get_guint8(tvb, offset);
2423
2424         PAD(1);
2425         proto_tree_add_item(tree, hf_afp_login_flags, tvb, offset, 2,FALSE);
2426         offset += 2;
2427         
2428         len = tvb_get_guint8(tvb, offset);
2429         proto_tree_add_item(tree, hf_afp_AFPVersion, tvb, offset, 1,FALSE);
2430         offset += len +1;
2431
2432         len_uam = tvb_get_guint8(tvb, offset);
2433         uam = tvb_get_ptr(tvb, offset +1, len_uam);
2434         proto_tree_add_item(tree, hf_afp_UAM, tvb, offset, 1,FALSE);
2435         offset += len_uam +1;
2436
2437         type = tvb_get_guint8(tvb, offset);
2438         proto_tree_add_item(tree, hf_afp_user_type, tvb, offset, 1,FALSE);
2439         offset++;
2440         /* only type 3 */
2441         len = tvb_get_ntohs(tvb, offset);
2442         proto_tree_add_item(tree, hf_afp_user_len, tvb, offset, 2,FALSE);
2443         offset += 2;
2444         proto_tree_add_item(tree, hf_afp_user_name, tvb, offset, len,FALSE);
2445         offset += len;
2446
2447         /* directory service */
2448         type = tvb_get_guint8(tvb, offset);
2449         proto_tree_add_item(tree, hf_afp_path_type, tvb, offset, 1,FALSE);
2450         offset++;
2451         /* FIXME use 16 bit len + unicode from smb dissector */
2452         switch (type) {
2453         case 1:
2454         case 2:
2455                 len = tvb_get_guint8(tvb, offset);
2456                 proto_tree_add_item(tree, hf_afp_path_len, tvb, offset,  1,FALSE);
2457                 offset++;
2458                 proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, len,FALSE);
2459                 offset += len;
2460                 break;
2461         case 3:
2462                 len = tvb_get_ntohs(tvb, offset);
2463                 proto_tree_add_item( tree, hf_afp_path_unicode_len, tvb, offset, 2,FALSE);
2464                 offset += 2;
2465                 proto_tree_add_item(tree, hf_afp_path_name, tvb, offset, len,FALSE);
2466                 offset += len;
2467                 break;
2468         default:
2469                 break;
2470         }
2471         
2472         return decode_uam_parameters(uam, len_uam, tvb, tree, offset);
2473 }
2474
2475 /* ************************** */
2476 static gint
2477 dissect_query_afp_write(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, gint offset)
2478 {
2479         int  param;
2480         gint col_info = check_col(pinfo->cinfo, COL_INFO);
2481
2482         
2483         proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1,FALSE);
2484         offset += 1;
2485
2486         add_info_fork(tvb, pinfo, offset);
2487         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2488         offset += 2;
2489
2490         proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4,FALSE);
2491         if (col_info) {
2492                 param = tvb_get_ntohl(tvb, offset);
2493                 col_append_fstr(pinfo->cinfo, COL_INFO, " Offset=%d", param);
2494         }
2495         offset += 4;
2496
2497         proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4,FALSE);
2498         if (col_info) {
2499                 param = tvb_get_ntohl(tvb, offset);
2500                 col_append_fstr(pinfo->cinfo, COL_INFO, " Size=%d", param);
2501         }
2502         offset += 4;
2503
2504         return offset;
2505 }
2506
2507 static gint
2508 dissect_reply_afp_write(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2509 {
2510         proto_tree_add_item(tree, hf_afp_last_written, tvb, offset, 4, FALSE);
2511         offset += 4;
2512
2513         return offset;
2514 }
2515
2516 /* ************************** */
2517 static gint
2518 dissect_query_afp_write_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2519 {
2520         proto_tree_add_item(tree, hf_afp_flag, tvb, offset, 1,FALSE);
2521         offset += 1;
2522
2523         add_info_fork(tvb, pinfo, offset);
2524         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2525         offset += 2;
2526
2527         proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
2528         offset += 8;
2529
2530         proto_tree_add_item(tree, hf_afp_rw_count64, tvb, offset, 8,FALSE);
2531         offset += 8;
2532
2533         return offset;
2534 }
2535
2536 static gint
2537 dissect_reply_afp_write_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2538 {
2539         proto_tree_add_item(tree, hf_afp_last_written64, tvb, offset, 8, FALSE);
2540         offset += 8;
2541
2542         return offset;
2543 }
2544
2545 /* ************************** */
2546 static gint
2547 dissect_query_afp_read(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2548 {
2549         int param;
2550         gint col_info = check_col(pinfo->cinfo, COL_INFO);
2551         
2552         PAD(1);
2553
2554         add_info_fork(tvb, pinfo, offset);
2555         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2556         offset += 2;
2557
2558         proto_tree_add_item(tree, hf_afp_offset, tvb, offset, 4,FALSE);
2559         if (col_info) {
2560                 param = tvb_get_ntohl(tvb, offset);
2561                 col_append_fstr(pinfo->cinfo, COL_INFO, " Offset=%d", param);
2562         }
2563         offset += 4;
2564
2565         proto_tree_add_item(tree, hf_afp_rw_count, tvb, offset, 4,FALSE);
2566         if (col_info) {
2567                 param = tvb_get_ntohl(tvb, offset);
2568                 col_append_fstr(pinfo->cinfo, COL_INFO, " Size=%d", param);
2569         }
2570         offset += 4;
2571
2572         proto_tree_add_item(tree, hf_afp_newline_mask, tvb, offset, 1,FALSE);
2573         offset++;
2574
2575         proto_tree_add_item(tree, hf_afp_newline_char, tvb, offset, 1,FALSE);
2576         offset++;
2577
2578         return offset;
2579 }
2580
2581 /* ************************** */
2582 static gint
2583 dissect_query_afp_read_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2584 {
2585         PAD(1);
2586
2587         add_info_fork(tvb, pinfo, offset);
2588         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2589         offset += 2;
2590
2591         proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
2592         offset += 8;
2593
2594         proto_tree_add_item(tree, hf_afp_rw_count64, tvb, offset, 8,FALSE);
2595         offset += 8;
2596
2597         return offset;
2598 }
2599
2600 /* **************************
2601    Open desktop call
2602    query is the same than       AFP_FLUSH, AFP_CLOSEVOL
2603
2604 */
2605 static gint
2606 dissect_reply_afp_open_dt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2607 {
2608         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
2609         offset += 2;
2610
2611         return offset;
2612 }
2613
2614 /* **************************
2615         no reply
2616 */
2617 static gint
2618 dissect_query_afp_close_dt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2619 {
2620         PAD(1);
2621         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
2622         offset += 2;
2623
2624         return offset;
2625 }
2626
2627 /* **************************
2628         calls using the same format :
2629                 1 pad byte
2630                 fork number
2631         AFP_FLUSHFORK
2632         AFP_CLOSEFORK
2633 */
2634 static gint
2635 dissect_query_afp_with_fork(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2636 {
2637         PAD(1);
2638         add_info_fork(tvb, pinfo, offset);
2639         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2640         offset += 2;
2641
2642         return offset;
2643 }
2644
2645 /* ************************** */
2646 static gint
2647 dissect_query_afp_get_fldr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2648 {
2649         PAD(1);
2650         offset = decode_vol_did_file_dir_bitmap(tree, tvb, offset);
2651
2652         offset = decode_name(tree, pinfo, tvb, offset);
2653
2654         return offset;
2655 }
2656
2657 /* -------------------------- */
2658 static gint
2659 dissect_reply_afp_get_fldr_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2660 {
2661         guint8  flags;
2662         guint16 f_bitmap, d_bitmap;
2663
2664         f_bitmap = decode_file_bitmap(tree, tvb, offset);
2665         offset += 2;
2666
2667         d_bitmap = decode_dir_bitmap(tree, tvb, offset);
2668         offset += 2;
2669
2670         flags = tvb_get_guint8(tvb, offset);
2671         proto_tree_add_item(tree, hf_afp_file_flag, tvb, offset, 1,FALSE);
2672         offset++;
2673         PAD(1);
2674         if (flags) {
2675                 offset = parse_dir_bitmap(tree, tvb, offset, d_bitmap);
2676         }
2677         else {
2678                 offset = parse_file_bitmap(tree, tvb, offset, f_bitmap,0);
2679         }
2680         return offset;
2681 }
2682
2683 /* **************************
2684         no reply
2685 */
2686 static gint
2687 dissect_query_afp_set_fldr_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2688 {
2689         guint16 f_bitmap;
2690
2691         PAD(1);
2692         offset = decode_vol_did(tree, tvb, offset);
2693
2694         f_bitmap = decode_file_bitmap(tree, tvb, offset);
2695         offset += 2;
2696
2697         offset = decode_name(tree, pinfo, tvb, offset);
2698
2699         if ((offset & 1))
2700                 PAD(1);
2701         /* did:name can be a file or a folder but only the intersection between
2702          * file bitmap and dir bitmap can be set.
2703          * Well it's in afp spec, but clients (Mac) are setting 'file only' bits with this call
2704          * (WriteInhibit for example).
2705          */
2706         offset = parse_file_bitmap(tree, tvb, offset, f_bitmap, 1);
2707
2708         return offset;
2709 }
2710
2711 /* **************************
2712         no reply
2713 */
2714 static gint
2715 dissect_query_afp_set_file_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2716 {
2717         guint16 f_bitmap;
2718
2719         PAD(1);
2720         offset = decode_vol_did(tree, tvb, offset);
2721
2722         f_bitmap = decode_file_bitmap(tree, tvb, offset);
2723         offset += 2;
2724
2725         offset = decode_name(tree, pinfo, tvb, offset);
2726
2727         if ((offset & 1))
2728                 PAD(1);
2729         offset = parse_file_bitmap(tree, tvb, offset, f_bitmap, 0);
2730
2731         return offset;
2732 }
2733
2734 /* **************************
2735         no reply
2736 */
2737 static gint
2738 dissect_query_afp_set_dir_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2739 {
2740         guint16 d_bitmap;
2741
2742         PAD(1);
2743         offset = decode_vol_did(tree, tvb, offset);
2744
2745         d_bitmap = decode_dir_bitmap(tree, tvb, offset);
2746         offset += 2;
2747
2748         offset = decode_name(tree, pinfo, tvb, offset);
2749
2750         if ((offset & 1))
2751                 PAD(1);
2752         offset = parse_dir_bitmap(tree, tvb, offset, d_bitmap);
2753
2754         offset += 4;
2755         return offset;
2756 }
2757
2758 /* **************************
2759         AFP_DELETE
2760         AFP_CREATE_DIR
2761  */
2762 static gint
2763 dissect_query_afp_create_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2764 {
2765         PAD(1);
2766         offset = decode_vol_did(tree, tvb, offset);
2767
2768         offset = decode_name(tree, pinfo, tvb, offset);
2769         return offset;
2770 }
2771
2772 /* --------------------------
2773         AFP_MOVE
2774 */
2775 static gint
2776 dissect_reply_afp_create_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2777 {
2778         proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
2779         offset += 4;
2780
2781         return offset;
2782 }
2783
2784 /* -------------------------- */
2785 static gint
2786 dissect_reply_afp_create_dir(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2787 {
2788         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
2789         offset += 4;
2790
2791         return offset;
2792 }
2793
2794 /* **************************
2795         no reply
2796 */
2797 static gint
2798 dissect_query_afp_delete_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2799 {
2800         PAD(1);
2801         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
2802         offset += 2;
2803         proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
2804         offset += 4;
2805
2806         return offset;
2807 }
2808
2809 /* **************************
2810         same reply as get_fork_param
2811 */
2812 static gint
2813 dissect_query_afp_resolve_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2814 {
2815         PAD(1);
2816         proto_tree_add_item(tree, hf_afp_vol_id, tvb, offset, 2,FALSE);
2817         offset += 2;
2818         proto_tree_add_item(tree, hf_afp_file_id, tvb, offset, 4,FALSE);
2819         offset += 4;
2820
2821         decode_file_bitmap(tree, tvb, offset);
2822         offset += 2;
2823
2824         return offset;
2825 }
2826
2827 /* ************************** */
2828 static gint
2829 dissect_query_afp_get_fork_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2830 {
2831
2832         PAD(1);
2833         add_info_fork(tvb, pinfo, offset);
2834         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2835         offset += 2;
2836
2837         decode_file_bitmap(tree, tvb, offset);
2838         offset += 2;
2839         return offset;
2840 }
2841
2842 /* -------------------------- */
2843 static gint
2844 dissect_reply_afp_get_fork_param(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2845 {
2846         guint16 f_bitmap;
2847
2848         f_bitmap = decode_file_bitmap(tree, tvb, offset);
2849         offset += 2;
2850
2851         offset = parse_file_bitmap(tree, tvb, offset, f_bitmap,0);
2852
2853         return offset;
2854 }
2855
2856 /* ************************** */
2857 static gint
2858 dissect_query_afp_set_fork_param(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2859 {
2860         guint16 bitmap;
2861         int param;
2862
2863         PAD(1);
2864         add_info_fork(tvb, pinfo, offset);
2865         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2866         offset += 2;
2867
2868         bitmap = decode_file_bitmap(tree, tvb, offset);
2869         offset += 2;
2870
2871         if ((bitmap & kFPExtDataForkLenBit) || (bitmap & kFPExtRsrcForkLenBit)) {
2872                 proto_tree_add_item(tree, hf_afp_ofork_len64, tvb, offset, 8, FALSE);
2873                 offset += 8;
2874         }
2875         else {
2876                 proto_tree_add_item(tree, hf_afp_ofork_len, tvb, offset, 4,FALSE);
2877                 if (check_col(pinfo->cinfo, COL_INFO)) {
2878                         param = tvb_get_ntohl(tvb, offset);
2879                         col_append_fstr(pinfo->cinfo, COL_INFO, " Size=%d", param);
2880                 }
2881                 offset += 4;
2882         }
2883         return offset;
2884 }
2885
2886 /* ************************** */
2887 static gint
2888 dissect_query_afp_move(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2889 {
2890
2891         PAD(1);
2892         offset = decode_vol_did(tree, tvb, offset);
2893
2894         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
2895         offset += 4;
2896
2897         offset = decode_name_label(tree, pinfo, tvb, offset, "Source path: %s");
2898         offset = decode_name_label(tree, NULL, tvb, offset,  "Dest dir:    %s");
2899         offset = decode_name_label(tree, NULL, tvb, offset,  "New name:    %s");
2900
2901         return offset;
2902 }
2903
2904 /* ************************** */
2905 static gint
2906 dissect_query_afp_exchange_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2907 {
2908
2909         PAD(1);
2910         offset = decode_vol_did(tree, tvb, offset);
2911
2912         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
2913         offset += 4;
2914
2915         offset = decode_name_label(tree, pinfo, tvb, offset, "Source path: %s");
2916         offset = decode_name_label(tree, NULL, tvb, offset,  "Dest path:   %s");
2917
2918         return offset;
2919 }
2920 /* ************************** */
2921 static gint
2922 dissect_query_afp_copy_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2923 {
2924         proto_tree *sub_tree = NULL;
2925         proto_item *item;
2926
2927         PAD(1);
2928         if (tree) {
2929                 item = proto_tree_add_text(tree, tvb, offset, 6,"Source volume");
2930                 sub_tree = proto_item_add_subtree(item, ett_afp_vol_did);
2931         }
2932         offset = decode_vol_did(sub_tree, tvb, offset);
2933
2934         if (tree) {
2935                 item = proto_tree_add_text(tree, tvb, offset, 6,"Dest volume");
2936                 sub_tree = proto_item_add_subtree(item, ett_afp_vol_did);
2937         }
2938         offset = decode_vol_did(sub_tree, tvb, offset);
2939
2940         offset = decode_name_label(tree, pinfo, tvb, offset, "Source path: %s");
2941         offset = decode_name_label(tree, NULL, tvb, offset,  "Dest dir:    %s");
2942         offset = decode_name_label(tree, NULL, tvb, offset,  "New name:    %s");
2943
2944         return offset;
2945 }
2946
2947 /* ************************** */
2948 static gint
2949 dissect_query_afp_rename(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
2950 {
2951
2952         PAD(1);
2953         offset = decode_vol_did(tree, tvb, offset);
2954
2955         offset = decode_name_label(tree, pinfo, tvb, offset, "Old name: %s");
2956         offset = decode_name_label(tree, NULL, tvb, offset,  "New name: %s");
2957
2958         return offset;
2959 }
2960
2961 /* ************************** */
2962 static gint
2963 dissect_query_afp_byte_lock(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2964 {
2965         proto_tree *sub_tree = NULL;
2966         proto_item *item;
2967         guint8 flag;
2968
2969         flag = tvb_get_guint8(tvb, offset);
2970         if (tree) {
2971                 item = proto_tree_add_text(tree, tvb, offset, 1, "Flags: 0x%02x", flag);
2972                 sub_tree = proto_item_add_subtree(item, ett_afp_lock_flags);
2973         }
2974
2975         proto_tree_add_item(sub_tree, hf_afp_lock_op, tvb, offset, 1,FALSE);
2976         proto_tree_add_item(sub_tree, hf_afp_lock_from, tvb, offset, 1,FALSE);
2977         offset += 1;
2978
2979         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
2980         offset += 2;
2981
2982         proto_tree_add_item(tree, hf_afp_lock_offset, tvb, offset, 4,FALSE);
2983         offset += 4;
2984
2985         proto_tree_add_item(tree, hf_afp_lock_len, tvb, offset, 4,FALSE);
2986         offset += 4;
2987         return offset;
2988 }
2989
2990 /* -------------------------- */
2991 static gint
2992 dissect_reply_afp_byte_lock(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
2993 {
2994         proto_tree_add_item(tree, hf_afp_lock_range_start, tvb, offset, 4,FALSE);
2995         offset += 4;
2996
2997         return offset;
2998 }
2999
3000 /* ************************** */
3001 static gint
3002 dissect_query_afp_byte_lock_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3003 {
3004         proto_tree *sub_tree = NULL;
3005         proto_item *item;
3006         guint8 flag;
3007
3008         flag = tvb_get_guint8(tvb, offset);
3009         if (tree) {
3010                 item = proto_tree_add_text(tree, tvb, offset, 1, "Flags: 0x%02x", flag);
3011                 sub_tree = proto_item_add_subtree(item, ett_afp_lock_flags);
3012         }
3013
3014         proto_tree_add_item(sub_tree, hf_afp_lock_op, tvb, offset, 1,FALSE);
3015         proto_tree_add_item(sub_tree, hf_afp_lock_from, tvb, offset, 1,FALSE);
3016         offset += 1;
3017
3018         proto_tree_add_item(tree, hf_afp_ofork, tvb, offset, 2,FALSE);
3019         offset += 2;
3020
3021         proto_tree_add_item(tree, hf_afp_lock_offset64, tvb, offset, 8,FALSE);
3022         offset += 8;
3023
3024         proto_tree_add_item(tree, hf_afp_lock_len64, tvb, offset, 8,FALSE);
3025         offset += 8;
3026         return offset;
3027 }
3028
3029 /* -------------------------- */
3030 static gint
3031 dissect_reply_afp_byte_lock_ext(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3032 {
3033         proto_tree_add_item(tree, hf_afp_lock_range_start64, tvb, offset, 8,FALSE);
3034         offset += 8;
3035
3036         return offset;
3037 }
3038
3039 /* ************************** */
3040 static gint
3041 dissect_query_afp_add_cmt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3042 {
3043         guint8 len;
3044
3045         PAD(1);
3046         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
3047         offset += 2;
3048
3049         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
3050         offset += 4;
3051
3052         offset = decode_name(tree, pinfo, tvb, offset);
3053
3054         if ((offset & 1))
3055                 PAD(1);
3056
3057         len = tvb_get_guint8(tvb, offset);
3058         proto_tree_add_item(tree, hf_afp_comment, tvb, offset, 1,FALSE);
3059         offset += len +1;
3060
3061         return offset;
3062 }
3063
3064
3065 /* ************************** */
3066 static gint
3067 dissect_query_afp_get_cmt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3068 {
3069
3070         PAD(1);
3071         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
3072         offset += 2;
3073
3074         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
3075         offset += 4;
3076
3077         offset = decode_name(tree, pinfo, tvb, offset);
3078         return offset;
3079 }
3080
3081 /* -------------------------- */
3082 static gint
3083 dissect_reply_afp_get_cmt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3084 {
3085         guint8 len;
3086
3087         len = tvb_get_guint8(tvb, offset);
3088         proto_tree_add_item(tree, hf_afp_comment, tvb, offset, 1,FALSE);
3089         offset += len +1;
3090
3091         return offset;
3092 }
3093
3094 /* ************************** */
3095 static gint
3096 dissect_query_afp_get_icon(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3097 {
3098
3099         PAD(1);
3100         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
3101         offset += 2;
3102         proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
3103         offset += 4;
3104
3105         proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4,FALSE);
3106         offset += 4;
3107
3108         proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1,FALSE);
3109         offset += 1;
3110         PAD(1);
3111
3112         proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2,FALSE);
3113         offset += 2;
3114
3115         return offset;
3116 }
3117
3118 /* ************************** */
3119 static gint
3120 dissect_query_afp_get_icon_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3121 {
3122
3123         PAD(1);
3124         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
3125         offset += 2;
3126         proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
3127         offset += 4;
3128
3129         proto_tree_add_item(tree, hf_afp_icon_index, tvb, offset, 2,FALSE);
3130         offset += 2;
3131
3132         return offset;
3133 }
3134
3135 /* -------------------------- */
3136 static gint
3137 dissect_reply_afp_get_icon_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3138 {
3139
3140         proto_tree_add_item(tree, hf_afp_icon_tag, tvb, offset, 4,FALSE);
3141         offset += 4;
3142
3143         proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4,FALSE);
3144         offset += 4;
3145
3146         proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1,FALSE);
3147         offset += 1;
3148
3149         PAD(1);
3150         proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2,FALSE);
3151         offset += 2;
3152
3153         return offset;
3154 }
3155
3156 /* ************************** */
3157 static gint
3158 dissect_query_afp_add_icon(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3159 {
3160
3161         PAD(1);
3162         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
3163         offset += 2;
3164         proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
3165         offset += 4;
3166
3167         proto_tree_add_item(tree, hf_afp_file_type, tvb, offset, 4,FALSE);
3168         offset += 4;
3169
3170         proto_tree_add_item(tree, hf_afp_icon_type, tvb, offset, 1,FALSE);
3171         offset += 1;
3172
3173         PAD(1);
3174         proto_tree_add_item(tree, hf_afp_icon_tag, tvb, offset, 4,FALSE);
3175         offset += 4;
3176
3177         proto_tree_add_item(tree, hf_afp_icon_length, tvb, offset, 2,FALSE);
3178         offset += 2;
3179
3180         return offset;
3181 }
3182
3183 /* **************************
3184         no reply
3185 */
3186 static gint
3187 decode_dt_did(proto_tree *tree, tvbuff_t *tvb, gint offset)
3188 {
3189         /* FIXME it's not volume but dt cf decode_name*/
3190         Vol = tvb_get_ntohs(tvb, offset);
3191         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
3192         offset += 2;
3193
3194         Did = tvb_get_ntohl(tvb, offset);
3195         proto_tree_add_item(tree, hf_afp_did, tvb, offset, 4,FALSE);
3196         offset += 4;
3197         return offset;
3198 }
3199
3200 /* -------------------------- */
3201 static gint
3202 dissect_query_afp_add_appl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3203 {
3204
3205         PAD(1);
3206         offset = decode_dt_did(tree, tvb, offset);
3207
3208         proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
3209         offset += 4;
3210
3211         proto_tree_add_item(tree, hf_afp_appl_tag, tvb, offset, 4,FALSE);
3212         offset += 4;
3213
3214         offset = decode_name(tree, pinfo, tvb, offset);
3215
3216         return offset;
3217 }
3218
3219 /* **************************
3220         no reply
3221 */
3222 static gint
3223 dissect_query_afp_rmv_appl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3224 {
3225
3226         PAD(1);
3227         offset = decode_dt_did(tree, tvb, offset);
3228
3229         proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
3230         offset += 4;
3231
3232         offset = decode_name(tree, pinfo, tvb, offset);
3233
3234         return offset;
3235 }
3236
3237 /* ************************** */
3238 static gint
3239 dissect_query_afp_get_appl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3240 {
3241
3242         PAD(1);
3243         proto_tree_add_item(tree, hf_afp_dt_ref, tvb, offset, 2,FALSE);
3244         offset += 2;
3245
3246         proto_tree_add_item(tree, hf_afp_file_creator, tvb, offset, 4,FALSE);
3247         offset += 4;
3248
3249         proto_tree_add_item(tree, hf_afp_appl_index, tvb, offset, 2,FALSE);
3250         offset += 2;
3251
3252         decode_file_bitmap(tree, tvb, offset);
3253         offset += 2;
3254
3255         return offset;
3256 }
3257
3258 /* -------------------------- */
3259 static gint
3260 dissect_reply_afp_get_appl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3261 {
3262         proto_tree_add_item(tree, hf_afp_appl_tag, tvb, offset, 4,FALSE);
3263         offset += 4;
3264
3265         return offset;
3266 }
3267
3268 /* ************************** */
3269 static gint
3270 dissect_query_afp_create_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3271 {
3272         proto_tree_add_item(tree, hf_afp_create_flag, tvb, offset, 1,FALSE);
3273         offset++;
3274
3275         offset = decode_vol_did(tree, tvb, offset);
3276
3277         offset = decode_name(tree, pinfo, tvb, offset);
3278
3279         return offset;
3280 }
3281
3282 /* ************************** */
3283 static gint
3284 dissect_query_afp_map_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3285 {
3286         guint8 type;
3287
3288         type = tvb_get_guint8(tvb, offset);
3289         proto_tree_add_item(tree, hf_afp_map_id_type, tvb, offset, 1,FALSE);
3290         offset++;
3291
3292         if ( type < 5) {
3293                 proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4,FALSE);
3294                 offset += 4;
3295         }
3296         else {
3297                 proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16,FALSE);
3298                 offset += 16;
3299         }
3300
3301         return offset;
3302 }
3303
3304 /* -------------------------- */
3305 static gint
3306 dissect_reply_afp_map_id(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3307 {
3308 int len;
3309
3310         len = tvb_get_guint8(tvb, offset);
3311         /* for type 3 and 4 len is 16 bits but we don't keep the type from the request 
3312          * XXX assume name < 256, ie the first byte is zero.
3313         */
3314         if (!len) {
3315                 gint remain = tvb_reported_length_remaining(tvb,offset);
3316                 if (remain && remain == (len = tvb_get_guint8(tvb, offset +1)) +2) {
3317                         offset++;
3318                 }
3319                 else {
3320                         /* give up */
3321                         len = 0;
3322                 }
3323         }
3324         proto_tree_add_item(tree, hf_afp_map_name, tvb, offset, 1,FALSE);
3325         offset += len +1;
3326         return offset;
3327 }
3328
3329 /* ************************** */
3330 static gint
3331 dissect_query_afp_map_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3332 {
3333 int len;
3334         proto_tree_add_item(tree, hf_afp_map_name_type, tvb, offset, 1,FALSE);
3335         offset++;
3336
3337         len = tvb_get_guint8(tvb, offset);
3338         proto_tree_add_item(tree, hf_afp_map_name, tvb, offset, 1,FALSE);
3339         offset += len +1;
3340
3341         return offset;
3342 }
3343
3344 /* -------------------------- */
3345 static gint
3346 dissect_reply_afp_map_name(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3347 {
3348         gint remain;
3349
3350         /* We don't keep the type from the request */
3351         /* If remain == 16, assume UUID */
3352         remain =  tvb_reported_length_remaining(tvb,0);
3353         if (remain == 16) {
3354                 proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
3355                 offset += 16;
3356         }
3357         else {
3358                 proto_tree_add_item(tree, hf_afp_map_id, tvb, offset, 4, FALSE);
3359                 offset += 4;
3360         }
3361
3362         return offset;
3363 }
3364
3365 /* ************************** */
3366 static gint
3367 dissect_query_afp_disconnect_old_session(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3368 {
3369 int len;
3370
3371         PAD(1);
3372
3373         proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2,FALSE);
3374         offset += 2;
3375
3376         len = tvb_get_ntohl(tvb, offset);
3377         proto_tree_add_item(tree, hf_afp_session_token_len, tvb, offset, 4,FALSE);
3378         offset += 4;
3379
3380         proto_tree_add_item(tree, hf_afp_session_token, tvb, offset, len,FALSE);
3381         offset += len;
3382
3383         return offset;
3384 }
3385
3386 /* ************************** */
3387 static gint
3388 dissect_query_afp_get_session_token(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3389 {
3390 guint16 token;
3391 int len;
3392
3393         PAD(1);
3394         token = tvb_get_ntohs(tvb, offset);
3395         proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2,FALSE);
3396         offset += 2;
3397         if (token == kLoginWithoutID || token == kGetKerberosSessionKey) /* 0 || 8 */
3398                 return offset;
3399
3400         len = tvb_get_ntohl(tvb, offset);
3401         proto_tree_add_item(tree, hf_afp_session_token_len, tvb, offset, 4,FALSE);
3402         offset += 4;
3403
3404         switch (token) {
3405         case kLoginWithTimeAndID:
3406         case kReconnWithTimeAndID:
3407                 proto_tree_add_item(tree, hf_afp_session_token_timestamp, tvb, offset, 4,FALSE);
3408                 offset += 4;
3409         }
3410
3411         proto_tree_add_item(tree, hf_afp_session_token, tvb, offset, len,FALSE);
3412         offset += len;
3413
3414         return offset;
3415 }
3416
3417 /* -------------------------- */
3418 static gint
3419 dissect_reply_afp_get_session_token(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3420 {
3421 int len;
3422 int size;
3423
3424         /* FIXME spec and capture disagree : or it's 4 bytes with no token type, or it's 2 bytes */
3425         size = 4;
3426         /* [cm]: FIXME continued:  Since size is set to 4, this test is never true.
3427         if (size == 2) {
3428                 proto_tree_add_item(tree, hf_afp_session_token_type, tvb, offset, 2,FALSE);
3429                 offset += 2;
3430         }
3431         */
3432         len = tvb_get_ntohl(tvb, offset);
3433         proto_tree_add_item(tree, hf_afp_session_token_len, tvb, offset, size,FALSE);
3434         offset += size;
3435
3436         proto_tree_add_item(tree, hf_afp_session_token, tvb, offset, len,FALSE);
3437         offset += len;
3438
3439         return offset;
3440 }
3441
3442 /* ************************** */
3443 static gint
3444 dissect_query_afp_get_server_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3445 {
3446
3447         PAD(1);
3448         proto_tree_add_item(tree, hf_afp_message_type, tvb, offset, 2, FALSE);
3449         offset += 2;
3450
3451         if (tree) {
3452                 proto_tree *sub_tree;
3453                 proto_item *item;
3454
3455                 item = proto_tree_add_item(tree, hf_afp_message_bitmap, tvb, offset, 2, FALSE);
3456                 sub_tree = proto_item_add_subtree(item, ett_afp_message_bitmap);
3457                 proto_tree_add_item(sub_tree, hf_afp_message_bitmap_REQ, tvb, offset, 2,FALSE);
3458                 proto_tree_add_item(sub_tree, hf_afp_message_bitmap_UTF, tvb, offset, 2,FALSE);
3459         }
3460         offset += 2;
3461
3462         return offset;
3463 }
3464
3465 /* ************************** */
3466 static gint
3467 dissect_reply_afp_get_server_message(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3468 {
3469         guint16  bitmap;
3470         guint16 len = 0;
3471
3472         /* FIXME: APF 3.1 specs also specify a long reply format, yet unused */
3473
3474         proto_tree_add_item(tree, hf_afp_message_type, tvb, offset, 2, FALSE);
3475         offset += 2;
3476
3477         bitmap = tvb_get_ntohs(tvb, offset);
3478         if (tree) {
3479                 proto_tree *sub_tree;
3480                 proto_item *item;
3481
3482                 item = proto_tree_add_item(tree, hf_afp_message_bitmap, tvb, offset, 2, FALSE);
3483                 sub_tree = proto_item_add_subtree(item, ett_afp_message_bitmap);
3484                 proto_tree_add_item(sub_tree, hf_afp_message_bitmap_REQ, tvb, offset, 2,FALSE);
3485                 proto_tree_add_item(sub_tree, hf_afp_message_bitmap_UTF, tvb, offset, 2,FALSE);
3486         }
3487         offset += 2;
3488
3489         /* FIXME: Not in the specs, but for UTF8 message length is 2 bytes */
3490         if ((bitmap & 3) == 3) {
3491                 len = tvb_get_ntohs(tvb, offset);
3492                 proto_tree_add_item(tree, hf_afp_message_len, tvb, offset, 2,FALSE);
3493                 offset += 2;
3494         }
3495         else if ((bitmap & 1)) {
3496                 len = tvb_get_guint8(tvb, offset);
3497                 proto_tree_add_item(tree, hf_afp_message_len, tvb, offset, 1,FALSE);
3498                 offset += 1;
3499         }
3500
3501         if (len) {
3502                 proto_tree_add_item(tree, hf_afp_message, tvb, offset, len ,FALSE);
3503                 offset += len;
3504         }
3505
3506         return offset;
3507 }
3508
3509 /* ************************** */
3510 static gint
3511 dissect_query_afp_get_user_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3512 {
3513
3514         proto_tree_add_item(tree, hf_afp_user_flag, tvb, offset, 1,FALSE);
3515         offset++;
3516
3517         proto_tree_add_item(tree, hf_afp_user_ID, tvb, offset, 4,FALSE);
3518         offset += 4;
3519
3520         if (tree) {
3521                 proto_tree *sub_tree;
3522                 proto_item *item;
3523                 
3524                 item = proto_tree_add_item(tree, hf_afp_user_bitmap, tvb, offset, 2,FALSE);
3525                 sub_tree = proto_item_add_subtree(item, ett_afp_user_bitmap);
3526                 proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UID, tvb, offset, 2,FALSE);
3527                 proto_tree_add_item(sub_tree, hf_afp_user_bitmap_GID, tvb, offset, 2,FALSE);
3528                 proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UUID, tvb, offset, 2,FALSE);
3529         }
3530         offset += 2;
3531
3532         return offset;
3533 }
3534
3535 /* -------------------------- */
3536 static gint
3537 dissect_reply_afp_get_user_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3538 {
3539         guint16  bitmap;
3540
3541         bitmap = tvb_get_ntohs(tvb, offset);
3542         if (tree) {
3543                 proto_tree *sub_tree;
3544                 proto_item *item;
3545                 
3546                 item = proto_tree_add_item(tree, hf_afp_user_bitmap, tvb, offset, 2,FALSE);
3547                 sub_tree = proto_item_add_subtree(item, ett_afp_user_bitmap);
3548                 proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UID, tvb, offset, 2,FALSE);
3549                 proto_tree_add_item(sub_tree, hf_afp_user_bitmap_GID, tvb, offset, 2,FALSE);
3550                 proto_tree_add_item(sub_tree, hf_afp_user_bitmap_UUID, tvb, offset, 2,FALSE);
3551         }
3552
3553         offset += 2;
3554         if ((bitmap & 1)) {
3555                 proto_tree_add_item(tree, hf_afp_user_ID, tvb, offset, 4,FALSE);
3556                 offset += 4;
3557         }
3558
3559         if ((bitmap & 2)) {
3560                 proto_tree_add_item(tree, hf_afp_group_ID, tvb, offset, 4,FALSE);
3561                 offset += 4;
3562         }
3563
3564         if ((bitmap & 4)) {
3565                 proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16,FALSE);
3566                 offset += 16;
3567         }
3568         return offset;
3569 }
3570
3571
3572 /* ************************** */
3573 static gint
3574 decode_attr_name (proto_tree *tree, packet_info *pinfo _U_, tvbuff_t *tvb, gint offset, const gchar *label)
3575 {
3576         int len;
3577
3578         if ((offset & 1))
3579                 PAD(1);
3580
3581         len = tvb_get_ntohs(tvb, offset);
3582
3583         if (tree) {
3584                 gchar *name;
3585                 proto_tree *sub_tree;
3586                 proto_item *item;
3587         
3588                 name = tvb_format_text(tvb,offset+2, len);
3589                 item = proto_tree_add_text(tree, tvb, offset, len + 2, label, name);
3590                 sub_tree = proto_item_add_subtree(item, ett_afp_extattr_names);
3591
3592                 proto_tree_add_item(sub_tree, hf_afp_extattr_namelen, tvb, offset, 2,FALSE);
3593                 proto_tree_add_item(sub_tree, hf_afp_extattr_name, tvb, offset +2, len, FALSE);
3594         }
3595         offset += 2 +len;
3596
3597         return offset;
3598 }
3599
3600 /* ************************** */
3601 static gint
3602 decode_attr_bitmap (proto_tree *tree, tvbuff_t *tvb, gint offset)
3603 {
3604
3605         if (tree) {
3606                 proto_tree *sub_tree;
3607                 proto_item *item;
3608                 
3609                 item = proto_tree_add_item(tree, hf_afp_extattr_bitmap, tvb, offset, 2,FALSE);
3610                 sub_tree = proto_item_add_subtree(item, ett_afp_extattr_bitmap);
3611                 proto_tree_add_item(sub_tree, hf_afp_extattr_bitmap_NoFollow, tvb, offset, 2,FALSE);
3612                 proto_tree_add_item(sub_tree, hf_afp_extattr_bitmap_Create, tvb, offset, 2,FALSE);
3613                 proto_tree_add_item(sub_tree, hf_afp_extattr_bitmap_Replace, tvb, offset, 2,FALSE);
3614         }
3615         offset += 2;
3616         return offset;
3617 }
3618
3619 /* ************************** */
3620 static gint
3621 dissect_query_afp_get_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3622 {
3623         PAD(1);
3624         offset = decode_vol_did(tree, tvb, offset);
3625
3626         offset = decode_attr_bitmap(tree, tvb, offset);
3627
3628         /* 8byte offset */
3629         proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
3630         offset += 8;
3631         /* 8byte reqcount */
3632         proto_tree_add_item(tree, hf_afp_reqcount64, tvb, offset, 8,FALSE);
3633         offset += 8;
3634
3635         /* maxreply */
3636         proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, FALSE);
3637         offset += 4;
3638
3639         offset = decode_name(tree, pinfo, tvb, offset);
3640
3641         offset = decode_attr_name(tree, pinfo, tvb, offset, "Attribute: %s");
3642
3643         return offset;
3644 }
3645
3646 /* -------------------------- */
3647 static gint
3648 dissect_reply_afp_get_ext_attr(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3649 {
3650         guint32  len;
3651         guint    remain;
3652
3653         offset = decode_attr_bitmap(tree, tvb, offset);
3654
3655         len = tvb_get_ntohl(tvb, offset);
3656         proto_tree_add_item(tree, hf_afp_extattr_len, tvb, offset, 4,FALSE);
3657         offset += 4;
3658
3659         remain =  tvb_reported_length_remaining(tvb, offset);
3660         if (len && remain >= len ) {
3661                 proto_tree_add_item(tree, hf_afp_extattr_data, tvb, offset, len, FALSE);
3662                 offset += len;
3663         }
3664
3665         return offset;  
3666 }
3667
3668 /* ************************** */
3669 static gint
3670 dissect_query_afp_set_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3671 {
3672         guint16  len;
3673
3674         PAD(1);
3675         offset = decode_vol_did(tree, tvb, offset);
3676
3677         offset = decode_attr_bitmap(tree, tvb, offset);
3678
3679         /* 8byte offset */
3680         proto_tree_add_item(tree, hf_afp_offset64, tvb, offset, 8,FALSE);
3681         offset += 8;
3682
3683         offset = decode_name(tree, pinfo, tvb, offset);
3684
3685         offset = decode_attr_name(tree, pinfo, tvb, offset, "Attribute: %s");
3686
3687         len = tvb_get_ntohl(tvb, offset);
3688         proto_tree_add_item(tree, hf_afp_extattr_len, tvb, offset, 4,FALSE);
3689         offset += 4;
3690
3691         proto_tree_add_item(tree, hf_afp_extattr_data, tvb, offset, len, FALSE);
3692         offset += len;
3693
3694         return offset;  
3695 }
3696
3697 /* ************************** */
3698 static gint
3699 dissect_query_afp_list_ext_attrs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3700 {
3701         PAD(1);
3702         offset = decode_vol_did(tree, tvb, offset);
3703
3704         /* for this command only kXAttrNoFollow is valid */
3705         offset = decode_attr_bitmap(tree, tvb, offset);
3706
3707         proto_tree_add_item(tree, hf_afp_extattr_req_count, tvb, offset, 2, FALSE);
3708         offset += 2;
3709
3710         proto_tree_add_item(tree, hf_afp_extattr_start_index, tvb, offset, 4, FALSE);
3711         offset += 4;
3712
3713         proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, FALSE);
3714         offset += 4;
3715
3716         offset = decode_name(tree, pinfo, tvb, offset);
3717
3718         return offset;
3719 }
3720
3721 /* -------------------------- */
3722 static gint
3723 dissect_reply_afp_list_ext_attrs(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3724 {
3725         proto_item *item;
3726         proto_tree *sub_tree;
3727         gint length = 0;
3728         int remain;
3729
3730         offset = decode_attr_bitmap(tree, tvb, offset);
3731
3732         length = tvb_get_ntohl(tvb, offset);
3733         proto_tree_add_item(tree, hf_afp_extattr_reply_size, tvb, offset, 4, FALSE);
3734         offset += 4;
3735
3736         /* If reply_size was 0 on request, server only reports the size of
3737            the entries without actually adding any entries */
3738         remain =  tvb_reported_length_remaining(tvb, offset);
3739         if (remain >= length) {
3740         
3741                 item = proto_tree_add_text(tree, tvb, offset, remain , "Attributes");
3742                 sub_tree = proto_item_add_subtree(item, ett_afp_extattr_names);
3743                 while ( remain > 0) {
3744                         tvb_get_ephemeral_stringz(tvb, offset, &length);  
3745                         proto_tree_add_item(sub_tree, hf_afp_extattr_name, tvb, offset, length, FALSE);
3746                         offset += length;
3747                         remain -= length;
3748                 }
3749
3750         }
3751
3752         return offset;
3753 }
3754
3755 /* ************************** */
3756 static gint
3757 dissect_query_afp_remove_ext_attr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3758 {
3759         PAD(1);
3760         offset = decode_vol_did(tree, tvb, offset);
3761
3762         offset = decode_attr_bitmap(tree, tvb, offset);
3763
3764         offset = decode_name(tree, pinfo, tvb, offset);
3765
3766         offset = decode_attr_name(tree, pinfo, tvb, offset, "Attribute: %s");
3767
3768         return offset;
3769 }
3770
3771 /* ************************** */
3772 static gint
3773 decode_acl_access_bitmap(tvbuff_t *tvb, proto_tree *tree, gint offset)
3774 {
3775         guint32 bitmap;
3776
3777         bitmap = tvb_get_ntohl(tvb, offset);
3778         if (tree) {
3779                 proto_tree *sub_tree;
3780                 proto_item *item;
3781                 
3782                 item = proto_tree_add_item(tree, hf_afp_acl_access_bitmap, tvb, offset, 4, FALSE);
3783                 sub_tree = proto_item_add_subtree(item, ett_afp_acl_access_bitmap);
3784
3785                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_data   , tvb, offset, 4,FALSE);
3786                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_data  , tvb, offset, 4,FALSE);
3787                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_execute     , tvb, offset, 4,FALSE);
3788                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_delete      , tvb, offset, 4,FALSE);
3789                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_append_data , tvb, offset, 4,FALSE);
3790                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_delete_child, tvb, offset, 4,FALSE);
3791                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_attrs  , tvb, offset, 4,FALSE);
3792                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_attrs , tvb, offset, 4,FALSE);
3793                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_extattrs , tvb, offset, 4,FALSE);
3794                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_extattrs, tvb, offset, 4,FALSE);
3795                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_read_security , tvb, offset, 4,FALSE);
3796                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_write_security, tvb, offset, 4,FALSE);
3797                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_change_owner  , tvb, offset, 4,FALSE);
3798                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_synchronize   , tvb, offset, 4,FALSE);
3799                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_all   , tvb, offset, 4,FALSE);
3800                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_execute, tvb, offset, 4,FALSE);
3801                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_write , tvb, offset, 4,FALSE);
3802                 proto_tree_add_item(sub_tree, hf_afp_acl_access_bitmap_generic_read  , tvb, offset, 4,FALSE);
3803         }
3804
3805         return bitmap;
3806 }
3807
3808 /* ************************** */
3809 static gint
3810 dissect_query_afp_access(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3811 {
3812         PAD(1);
3813         offset = decode_vol_did(tree, tvb, offset);
3814
3815         proto_tree_add_item(tree, hf_afp_access_bitmap, tvb, offset, 2, FALSE);
3816         offset += 2;
3817
3818         proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
3819         offset += 16;
3820
3821         decode_acl_access_bitmap(tvb, tree, offset);
3822         offset += 4;
3823
3824         offset = decode_name(tree, pinfo, tvb, offset);
3825
3826         return offset;
3827 }
3828
3829 /* ************************** */
3830 static guint16
3831 decode_acl_list_bitmap(tvbuff_t *tvb, proto_tree *tree, gint offset)
3832 {
3833         guint16 bitmap;
3834
3835         bitmap = tvb_get_ntohs(tvb, offset);
3836         if (tree) {
3837                 proto_tree *sub_tree;
3838                 proto_item *item;
3839                 
3840                 item = proto_tree_add_item(tree, hf_afp_acl_list_bitmap, tvb, offset, 2,FALSE);
3841                 sub_tree = proto_item_add_subtree(item, ett_afp_acl_list_bitmap);
3842                 proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_UUID, tvb, offset, 2,FALSE);
3843                 proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_GRPUUID, tvb, offset, 2,FALSE);
3844                 proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_ACL, tvb, offset, 2,FALSE);
3845                 proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_REMOVEACL, tvb, offset, 2,FALSE);
3846                 proto_tree_add_item(sub_tree, hf_afp_acl_list_bitmap_Inherit, tvb, offset, 2,FALSE);
3847         }
3848
3849         return bitmap;
3850 }
3851
3852
3853 /* ************************** */
3854 static guint32
3855 decode_ace_flags_bitmap(tvbuff_t *tvb, proto_tree *tree, gint offset)
3856 {
3857         guint32 bitmap;
3858
3859         bitmap = tvb_get_ntohl(tvb, offset);
3860         if (tree) {
3861                 proto_tree *sub_tree;
3862                 proto_item *item;
3863                 
3864                 item = proto_tree_add_item(tree, hf_afp_ace_flags, tvb, offset, 4,FALSE);
3865                 sub_tree = proto_item_add_subtree(item, ett_afp_ace_flags);
3866                 proto_tree_add_item(sub_tree, hf_afp_ace_flags_allow, tvb, offset, 4,FALSE);
3867                 proto_tree_add_item(sub_tree, hf_afp_ace_flags_deny, tvb, offset, 4,FALSE);
3868                 proto_tree_add_item(sub_tree, hf_afp_ace_flags_inherited, tvb, offset, 4,FALSE);
3869                 proto_tree_add_item(sub_tree, hf_afp_ace_flags_fileinherit, tvb, offset, 4,FALSE);
3870                 proto_tree_add_item(sub_tree, hf_afp_ace_flags_dirinherit, tvb, offset, 4,FALSE);
3871                 proto_tree_add_item(sub_tree, hf_afp_ace_flags_limitinherit, tvb, offset, 4,FALSE);
3872                 proto_tree_add_item(sub_tree, hf_afp_ace_flags_onlyinherit, tvb, offset, 4,FALSE);
3873         }
3874
3875         return bitmap;
3876 }
3877
3878 static gint
3879 decode_kauth_ace(tvbuff_t *tvb, proto_tree *tree, gint offset)
3880 {
3881         /* FIXME: preliminary decoding... */
3882         if (tree) {
3883                 proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16,FALSE);
3884                 offset += 16;
3885
3886                 decode_ace_flags_bitmap(tvb, tree, offset);
3887                 offset += 4;
3888
3889                 decode_acl_access_bitmap(tvb, tree, offset);
3890                 offset += 4;
3891         }
3892         else {
3893                 offset += 24;
3894         }
3895         return offset;
3896 }
3897
3898 static gint
3899 decode_kauth_acl(tvbuff_t *tvb, proto_tree *tree, gint offset)
3900 {
3901         int entries;
3902         int i;
3903         proto_tree *sub_tree;
3904         proto_tree *ace_tree;
3905         proto_item *item;
3906
3907         /* FIXME: preliminary decoding... */
3908         entries = tvb_get_ntohl(tvb, offset);
3909
3910         item = proto_tree_add_text(tree, tvb, offset, 4, "ACEs : %d", entries);
3911         sub_tree = proto_item_add_subtree(item, ett_afp_ace_entries);
3912         offset += 4;
3913
3914         proto_tree_add_item(tree, hf_afp_acl_flags, tvb, offset, 4,FALSE);
3915         offset += 4;
3916
3917         for (i = 0; i < entries; i++) {
3918                 item = proto_tree_add_text(sub_tree, tvb, offset, 24, "ACE: %u", i);
3919                 ace_tree = proto_item_add_subtree(item, ett_afp_ace_entry);
3920
3921                 offset = decode_kauth_ace(tvb, ace_tree, offset);
3922         }       
3923
3924         return offset;
3925 }
3926
3927 static gint
3928 decode_uuid_acl(tvbuff_t *tvb, proto_tree *tree, gint offset, guint16 bitmap)
3929 {
3930         if ((offset & 1))
3931                 PAD(1);
3932
3933         if ((bitmap & kFileSec_UUID)) {
3934                 proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
3935                 offset += 16;
3936         }
3937
3938         if ((bitmap & kFileSec_GRPUUID)) {
3939                 proto_tree_add_item(tree, hf_afp_UUID, tvb, offset, 16, FALSE);
3940                 offset += 16;
3941         }
3942
3943         if ((bitmap & kFileSec_ACL)) {
3944                 offset = decode_kauth_acl(tvb, tree, offset);
3945         }
3946
3947         return offset;
3948 }
3949                 
3950 /* ************************** */
3951 static gint
3952 dissect_query_afp_set_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3953 {
3954         guint16 bitmap;
3955
3956         PAD(1);
3957         offset = decode_vol_did(tree, tvb, offset);
3958
3959         bitmap = decode_acl_list_bitmap(tvb, tree, offset);
3960         offset += 2;
3961
3962         offset = decode_name(tree, pinfo, tvb, offset);
3963
3964         offset = decode_uuid_acl(tvb, tree, offset, bitmap);
3965
3966         return offset;
3967 }
3968
3969 /* ************************** */
3970 static gint
3971 dissect_query_afp_get_acl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
3972 {
3973         PAD(1);
3974         offset = decode_vol_did(tree, tvb, offset);
3975
3976         decode_acl_list_bitmap(tvb, tree, offset);
3977         offset += 2;
3978
3979         proto_tree_add_item(tree, hf_afp_max_reply_size32, tvb, offset, 4,FALSE);
3980         offset += 4;
3981
3982         offset = decode_name(tree, pinfo, tvb, offset);
3983
3984         return offset;
3985 }
3986
3987 /* -------------------------- */
3988 static gint
3989 dissect_reply_afp_get_acl(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
3990 {
3991         guint16 bitmap;
3992
3993         bitmap = decode_acl_list_bitmap(tvb, tree, offset);
3994         offset += 2;
3995         
3996         offset = decode_uuid_acl(tvb, tree, offset, bitmap);
3997
3998         return offset;
3999 }
4000
4001 /* ************************** */
4002 static void
4003 dissect_afp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
4004 {
4005         struct aspinfo  *aspinfo = pinfo->private_data;
4006         proto_tree      *afp_tree = NULL;
4007         proto_item      *ti;
4008         conversation_t  *conversation;
4009         gint            offset = 0;
4010         afp_request_key request_key, *new_request_key;
4011         afp_request_val *request_val;
4012         guint8          afp_command;
4013         nstime_t        delta_ts;
4014
4015         int     len =  tvb_reported_length_remaining(tvb,0);
4016         gint col_info = check_col(pinfo->cinfo, COL_INFO);
4017
4018         if (check_col(pinfo->cinfo, COL_PROTOCOL))
4019                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "AFP");
4020         if (col_info)
4021                 col_clear(pinfo->cinfo, COL_INFO);
4022
4023         conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
4024                 pinfo->srcport, pinfo->destport, 0);
4025
4026         if (conversation == NULL)
4027         {
4028                 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
4029                         pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
4030         }
4031
4032         request_key.conversation = conversation->index;
4033         request_key.seq = aspinfo->seq;
4034
4035         request_val = (afp_request_val *) g_hash_table_lookup(
4036                                                                 afp_request_hash, &request_key);
4037
4038         if (!request_val && !aspinfo->reply)  {
4039                 afp_command = tvb_get_guint8(tvb, offset);
4040                 new_request_key = se_alloc(sizeof(afp_request_key));
4041                 *new_request_key = request_key;
4042
4043                 request_val = se_alloc(sizeof(afp_request_val));
4044                 request_val->command = afp_command;
4045                 request_val->frame_req = pinfo->fd->num;
4046                 request_val->frame_res = 0;
4047                 request_val->req_time=pinfo->fd->abs_ts;
4048
4049                 g_hash_table_insert(afp_request_hash, new_request_key,
4050                                                                 request_val);
4051         }
4052
4053         if (!request_val) {     /* missing request */
4054                 if (col_info)
4055                         col_add_fstr(pinfo->cinfo, COL_INFO, "[Reply without query?]");
4056                 return;
4057         }
4058
4059         afp_command = request_val->command;
4060         if (col_info) {
4061                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s",
4062                              val_to_str(afp_command, CommandCode_vals,
4063                                         "Unknown command (%u)"),
4064                              aspinfo->reply ? "reply" : "request");
4065                 if (aspinfo->reply && aspinfo->code != 0) {
4066                         col_append_fstr(pinfo->cinfo, COL_INFO, ": %s (%d)",
4067                                 val_to_str(aspinfo->code, asp_error_vals,
4068                                         "Unknown error (%u)"), aspinfo->code);
4069                 }
4070         }
4071
4072         if (tree)
4073         {
4074                 ti = proto_tree_add_item(tree, proto_afp, tvb, offset, -1,FALSE);
4075                 afp_tree = proto_item_add_subtree(ti, ett_afp);
4076         }
4077         if (!aspinfo->reply)  {
4078                 
4079                 proto_tree_add_uint(afp_tree, hf_afp_command, tvb,offset, 1, afp_command);
4080                 if (afp_command != tvb_get_guint8(tvb, offset))
4081                 {
4082                         /* we have the same conversation for different connections eg:
4083                          * ip1:2048 --> ip2:548
4084                          * ip1:2048 --> ip2:548 <RST>
4085                          * ....
4086                          * ip1:2048 --> ip2:548 <SYN> use the same port but it's a new session!
4087                          */
4088                         if (col_info) {
4089                                 col_add_fstr(pinfo->cinfo, COL_INFO, 
4090                                   "[Error!IP port reused, you need to split the capture file]");
4091                                 return;
4092                         }
4093                 }
4094
4095                 /*
4096                  * Put in a field for the frame number of the frame to which
4097                  * this is a response if we know that frame number (i.e.,
4098                  * it's not 0).
4099                  */
4100                 if (request_val->frame_res != 0) {
4101                         ti = proto_tree_add_uint(afp_tree, hf_afp_response_in,
4102                             tvb, 0, 0, request_val->frame_res);
4103                         PROTO_ITEM_SET_GENERATED(ti);
4104                 }
4105
4106                 offset++;
4107                 switch(afp_command) {
4108                 case AFP_BYTELOCK:
4109                         offset = dissect_query_afp_byte_lock(tvb, pinfo, afp_tree, offset);break;
4110                 case AFP_BYTELOCK_EXT:
4111                         offset = dissect_query_afp_byte_lock_ext(tvb, pinfo, afp_tree, offset);break;
4112                 case AFP_OPENDT:        /* same as close vol */
4113                 case AFP_FLUSH:
4114                 case AFP_CLOSEVOL:
4115                         offset = dissect_query_afp_with_vol_id(tvb, pinfo, afp_tree, offset);break;
4116                 case AFP_CLOSEDIR:
4117                         /* offset = dissect_query_afp_close_dir(tvb, pinfo, afp_tree, offset);break; */
4118                         break;
4119                 case AFP_CLOSEDT:
4120                         offset = dissect_query_afp_close_dt(tvb, pinfo, afp_tree, offset);break;
4121                 case AFP_FLUSHFORK: /* same packet as closefork */
4122                 case AFP_CLOSEFORK:
4123                         offset = dissect_query_afp_with_fork(tvb, pinfo, afp_tree, offset);break;
4124                 case AFP_COPYFILE:
4125                         offset = dissect_query_afp_copy_file(tvb, pinfo, afp_tree, offset);break;
4126                 case AFP_CREATEFILE:
4127                         offset = dissect_query_afp_create_file(tvb, pinfo, afp_tree, offset);break;
4128                 case AFP_DISCTOLDSESS:
4129                         offset = dissect_query_afp_disconnect_old_session(tvb, pinfo, afp_tree, offset);break;
4130                 case AFP_ENUMERATE_EXT2:
4131                         offset = dissect_query_afp_enumerate_ext2(tvb, pinfo, afp_tree, offset);break;
4132                 case AFP_ENUMERATE_EXT:
4133                 case AFP_ENUMERATE:
4134                         offset = dissect_query_afp_enumerate(tvb, pinfo, afp_tree, offset);break;
4135                 case AFP_GETFORKPARAM:
4136                         offset = dissect_query_afp_get_fork_param(tvb, pinfo, afp_tree, offset);break;
4137                 case AFP_GETSESSTOKEN:
4138                         offset = dissect_query_afp_get_session_token(tvb, pinfo, afp_tree, offset);break;
4139                 case AFP_GETUSERINFO:
4140                         offset = dissect_query_afp_get_user_info(tvb, pinfo, afp_tree, offset);break;
4141                 case AFP_GETSRVINFO:
4142                         /* offset = dissect_query_afp_get_server_info(tvb, pinfo, afp_tree, offset);break; */
4143                 case AFP_GETSRVPARAM:
4144                         break;                                  /* no parameters */
4145                 case AFP_GETVOLPARAM:
4146                         offset = dissect_query_afp_get_vol_param(tvb, pinfo, afp_tree, offset);break;
4147                 case AFP_LOGIN_EXT:
4148                         offset = dissect_query_afp_login_ext(tvb, pinfo, afp_tree, offset);break;
4149                 case AFP_LOGIN:
4150                         offset = dissect_query_afp_login(tvb, pinfo, afp_tree, offset);break;
4151                 case AFP_LOGINCONT:
4152                 case AFP_LOGOUT:
4153                         break;
4154                 case AFP_MAPID:
4155                         offset = dissect_query_afp_map_id(tvb, pinfo, afp_tree, offset);break;
4156                 case AFP_MAPNAME:
4157                         offset = dissect_query_afp_map_name(tvb, pinfo, afp_tree, offset);break;
4158                 case AFP_MOVE:
4159                         offset = dissect_query_afp_move(tvb, pinfo, afp_tree, offset);break;
4160                 case AFP_OPENVOL:
4161                         offset = dissect_query_afp_open_vol(tvb, pinfo, afp_tree, offset);break;
4162                 case AFP_OPENDIR:
4163                         break;
4164                 case AFP_OPENFORK:
4165                         offset = dissect_query_afp_open_fork(tvb, pinfo, afp_tree, offset);break;
4166                 case AFP_READ:
4167                         offset = dissect_query_afp_read(tvb, pinfo, afp_tree, offset);break;
4168                 case AFP_READ_EXT:
4169                         offset = dissect_query_afp_read_ext(tvb, pinfo, afp_tree, offset);break;
4170                 case AFP_RENAME:
4171                         offset = dissect_query_afp_rename(tvb, pinfo, afp_tree, offset);break;
4172                 case AFP_SETDIRPARAM:
4173                         offset = dissect_query_afp_set_dir_param(tvb, pinfo, afp_tree, offset);break;
4174                 case AFP_SETFILEPARAM:
4175                         offset = dissect_query_afp_set_file_param(tvb, pinfo, afp_tree, offset);break;
4176                 case AFP_SETFORKPARAM:
4177                         offset = dissect_query_afp_set_fork_param(tvb, pinfo, afp_tree, offset);break;
4178                 case AFP_SETVOLPARAM:
4179                         offset = dissect_query_afp_set_vol_param(tvb, pinfo, afp_tree, offset);break;
4180                 case AFP_WRITE:
4181                         offset = dissect_query_afp_write(tvb, pinfo, afp_tree, offset);break;
4182                 case AFP_WRITE_EXT:
4183                         offset = dissect_query_afp_write_ext(tvb, pinfo, afp_tree, offset);break;
4184                 case AFP_GETFLDRPARAM:
4185                         offset = dissect_query_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);break;
4186                 case AFP_SETFLDRPARAM:
4187                         offset = dissect_query_afp_set_fldr_param(tvb, pinfo, afp_tree, offset);break;
4188                 case AFP_CHANGEPW:
4189                         break;
4190                 case AFP_GETSRVRMSG:
4191                         offset = dissect_query_afp_get_server_message(tvb, pinfo, afp_tree, offset);break;
4192                 case AFP_DELETE:        /* same as create_id */
4193                 case AFP_CREATEDIR:
4194                 case AFP_CREATEID:
4195                         offset = dissect_query_afp_create_id(tvb, pinfo, afp_tree, offset);break;
4196                 case AFP_DELETEID:
4197                         offset = dissect_query_afp_delete_id(tvb, pinfo, afp_tree, offset);break;
4198                 case AFP_RESOLVEID:
4199                         offset = dissect_query_afp_resolve_id(tvb, pinfo, afp_tree, offset);break;
4200                 case AFP_EXCHANGEFILE:
4201                         offset = dissect_query_afp_exchange_file(tvb, pinfo, afp_tree, offset);break;
4202                 case AFP_CATSEARCH_EXT:
4203                         offset = dissect_query_afp_cat_search_ext(tvb, pinfo, afp_tree, offset);break;
4204                 case AFP_CATSEARCH:
4205                         offset = dissect_query_afp_cat_search(tvb, pinfo, afp_tree, offset);break;
4206                 case AFP_GETICON:
4207                         offset = dissect_query_afp_get_icon(tvb, pinfo, afp_tree, offset);break;
4208                 case AFP_GTICNINFO:
4209                         offset = dissect_query_afp_get_icon_info(tvb, pinfo, afp_tree, offset);break;
4210                 case AFP_ADDAPPL:
4211                         offset = dissect_query_afp_add_appl(tvb, pinfo, afp_tree, offset);break;
4212                 case AFP_RMVAPPL:
4213                         offset = dissect_query_afp_rmv_appl(tvb, pinfo, afp_tree, offset);break;
4214                 case AFP_GETAPPL:
4215                         offset = dissect_query_afp_get_appl(tvb, pinfo, afp_tree, offset);break;
4216                 case AFP_ADDCMT:
4217                         offset = dissect_query_afp_add_cmt(tvb, pinfo, afp_tree, offset);break;
4218                 case AFP_RMVCMT: /* same as get_cmt */
4219                 case AFP_GETCMT:
4220                         offset = dissect_query_afp_get_cmt(tvb, pinfo, afp_tree, offset);break;
4221                 case AFP_ADDICON:
4222                         offset = dissect_query_afp_add_icon(tvb, pinfo, afp_tree, offset);break;
4223                 case AFP_GETEXTATTR:
4224                         offset = dissect_query_afp_get_ext_attr(tvb, pinfo, afp_tree, offset);break;
4225                 case AFP_SETEXTATTR:
4226                         offset = dissect_query_afp_set_ext_attr(tvb, pinfo, afp_tree, offset);break;
4227                 case AFP_LISTEXTATTR:
4228                         offset = dissect_query_afp_list_ext_attrs(tvb, pinfo, afp_tree, offset);break;
4229                 case AFP_REMOVEATTR:
4230                         offset = dissect_query_afp_remove_ext_attr(tvb, pinfo, afp_tree, offset);break;
4231                 case AFP_GETACL:
4232                         offset = dissect_query_afp_get_acl(tvb, pinfo, afp_tree, offset);break;
4233                 case AFP_SETACL:
4234                         offset = dissect_query_afp_set_acl(tvb, pinfo, afp_tree, offset);break;
4235                 case AFP_ACCESS:
4236                         offset = dissect_query_afp_access(tvb, pinfo, afp_tree, offset);break;
4237                 }
4238         }
4239         else {
4240                 proto_tree_add_uint(afp_tree, hf_afp_command, tvb, 0, 0, afp_command);
4241
4242                 /*
4243                  * Put in fields for the frame with the response to this
4244                  * frame - if we know the frame number (i.e., it's not 0).
4245                  */
4246                 if (request_val->frame_req != 0) {
4247                         ti = proto_tree_add_uint(afp_tree, hf_afp_response_to,
4248                             tvb, 0, 0, request_val->frame_req);
4249                         PROTO_ITEM_SET_GENERATED(ti);
4250                         nstime_delta(&delta_ts, &pinfo->fd->abs_ts, &request_val->req_time);
4251                         ti = proto_tree_add_time(afp_tree, hf_afp_time, tvb,
4252                             0, 0, &delta_ts);
4253                         PROTO_ITEM_SET_GENERATED(ti);
4254                 }
4255
4256                 /*
4257                  * Set "frame_res" if it's not already known.
4258                  */
4259                 if (request_val->frame_res == 0)
4260                         request_val->frame_res = pinfo->fd->num;
4261
4262                 /*
4263                  * Tap the packet before the dissectors are called so we
4264                  * still get the tap listener called even if there is an
4265                  * exception.
4266                  */
4267                 tap_queue_packet(afp_tap, pinfo, request_val);
4268
4269                 if (!len) {
4270                         /* for some calls if the reply is an error there's no data
4271                         */
4272                         return;
4273                 }
4274
4275                 switch(afp_command) {
4276                 case AFP_BYTELOCK:
4277                         offset = dissect_reply_afp_byte_lock(tvb, pinfo, afp_tree, offset);break;
4278                 case AFP_BYTELOCK_EXT:
4279                         offset = dissect_reply_afp_byte_lock_ext(tvb, pinfo, afp_tree, offset);break;
4280                 case AFP_ENUMERATE_EXT2:
4281                 case AFP_ENUMERATE_EXT:
4282                         offset = dissect_reply_afp_enumerate_ext(tvb, pinfo, afp_tree, offset);break;
4283                 case AFP_ENUMERATE:
4284                         offset = dissect_reply_afp_enumerate(tvb, pinfo, afp_tree, offset);break;
4285                 case AFP_OPENVOL:
4286                         offset = dissect_reply_afp_open_vol(tvb, pinfo, afp_tree, offset);break;
4287                 case AFP_OPENFORK:
4288                         offset = dissect_reply_afp_open_fork(tvb, pinfo, afp_tree, offset);break;
4289                 case AFP_RESOLVEID:
4290                 case AFP_GETFORKPARAM:
4291                         offset =dissect_reply_afp_get_fork_param(tvb, pinfo, afp_tree, offset);break;
4292                 case AFP_GETUSERINFO:
4293                         offset = dissect_reply_afp_get_user_info(tvb, pinfo, afp_tree, offset);break;
4294                 case AFP_GETSRVPARAM:
4295                         offset = dissect_reply_afp_get_server_param(tvb, pinfo, afp_tree, offset);break;
4296                 case AFP_GETSRVRMSG:
4297                         offset = dissect_reply_afp_get_server_message(tvb, pinfo, afp_tree, offset);break;
4298                 case AFP_CREATEDIR:
4299                         offset = dissect_reply_afp_create_dir(tvb, pinfo, afp_tree, offset);break;
4300                 case AFP_MAPID:
4301                         offset = dissect_reply_afp_map_id(tvb, pinfo, afp_tree, offset);break;
4302                 case AFP_MAPNAME:
4303                         offset = dissect_reply_afp_map_name(tvb, pinfo, afp_tree, offset);break;
4304                 case AFP_MOVE:          /* same as create_id */
4305                 case AFP_CREATEID:
4306                         offset = dissect_reply_afp_create_id(tvb, pinfo, afp_tree, offset);break;
4307                 case AFP_GETSESSTOKEN:
4308                         offset = dissect_reply_afp_get_session_token(tvb, pinfo, afp_tree, offset);break;
4309                 case AFP_GETVOLPARAM:
4310                         offset = dissect_reply_afp_get_vol_param(tvb, pinfo, afp_tree, offset);break;
4311                 case AFP_GETFLDRPARAM:
4312                         offset = dissect_reply_afp_get_fldr_param(tvb, pinfo, afp_tree, offset);break;
4313                 case AFP_OPENDT:
4314                         offset = dissect_reply_afp_open_dt(tvb, pinfo, afp_tree, offset);break;
4315                 case AFP_CATSEARCH_EXT:
4316                         offset = dissect_reply_afp_cat_search_ext(tvb, pinfo, afp_tree, offset);break;
4317                 case AFP_CATSEARCH:
4318                         offset = dissect_reply_afp_cat_search(tvb, pinfo, afp_tree, offset);break;
4319                 case AFP_GTICNINFO:
4320                         offset = dissect_reply_afp_get_icon_info(tvb, pinfo, afp_tree, offset);break;
4321                 case AFP_GETAPPL:
4322                         offset = dissect_reply_afp_get_appl(tvb, pinfo, afp_tree, offset);break;
4323                 case AFP_GETCMT:
4324                         offset = dissect_reply_afp_get_cmt(tvb, pinfo, afp_tree, offset);break;
4325                 case AFP_WRITE:
4326                         offset = dissect_reply_afp_write(tvb, pinfo, afp_tree, offset);break;
4327                 case AFP_WRITE_EXT:
4328                         offset = dissect_reply_afp_write_ext(tvb, pinfo, afp_tree, offset);break;
4329                 case AFP_GETEXTATTR:
4330                         offset = dissect_reply_afp_get_ext_attr(tvb, pinfo, afp_tree, offset);break;
4331                 case AFP_LISTEXTATTR:
4332                         offset = dissect_reply_afp_list_ext_attrs(tvb, pinfo, afp_tree, offset);break;
4333                 case AFP_GETACL:
4334                         offset = dissect_reply_afp_get_acl(tvb, pinfo, afp_tree, offset);break;
4335                 }
4336         }
4337         if (tree && offset < len) {
4338                 call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1),
4339                     pinfo, afp_tree);
4340         }
4341 }
4342
4343 static void afp_reinit( void)
4344 {
4345
4346         if (afp_request_hash)
4347                 g_hash_table_destroy(afp_request_hash);
4348
4349         afp_request_hash = g_hash_table_new(afp_hash, afp_equal);
4350
4351 }
4352
4353 void
4354 proto_register_afp(void)
4355 {
4356
4357   static hf_register_info hf[] = {
4358     { &hf_afp_command,
4359       { "Command",      "afp.command",
4360                 FT_UINT8, BASE_DEC, VALS(CommandCode_vals), 0x0,
4361         "AFP function", HFILL }},
4362
4363     { &hf_afp_pad,
4364       { "Pad",          "afp.pad",
4365                 FT_NONE,   BASE_NONE, NULL, 0,
4366         "Pad Byte",     HFILL }},
4367
4368     { &hf_afp_AFPVersion,
4369       { "AFP Version",  "afp.AFPVersion",
4370                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
4371         "Client AFP version", HFILL }},
4372
4373     { &hf_afp_UAM,
4374       { "UAM",          "afp.UAM",
4375                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
4376         "User Authentication Method", HFILL }},
4377
4378     { &hf_afp_user,
4379       { "User",         "afp.user",
4380                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
4381         "User", HFILL }},
4382
4383     { &hf_afp_user_type,
4384       { "Type",         "afp.user_type",
4385                 FT_UINT8, BASE_HEX, VALS(path_type_vals), 0,
4386         "Type of user name", HFILL }},
4387     { &hf_afp_user_len,
4388       { "Len",  "afp.user_len",
4389                 FT_UINT16, BASE_DEC, NULL, 0x0,
4390         "User name length (unicode)", HFILL }},
4391     { &hf_afp_user_name,
4392       { "User",  "afp.user_name",
4393                 FT_STRING, BASE_NONE, NULL, 0x0,
4394         "User name (unicode)", HFILL }},
4395
4396     { &hf_afp_passwd,
4397       { "Password",     "afp.passwd",
4398                 FT_STRINGZ, BASE_NONE, NULL, 0x0,
4399         "Password", HFILL }},
4400
4401     { &hf_afp_random,
4402       { "Random number",         "afp.random",
4403                 FT_BYTES, BASE_HEX, NULL, 0x0,
4404         "UAM random number", HFILL }},
4405
4406     { &hf_afp_response_to,
4407       { "Response to",  "afp.response_to",
4408                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4409         "This packet is a response to the packet in this frame", HFILL }},
4410
4411     { &hf_afp_time,
4412       { "Time from request",    "afp.time",
4413                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
4414         "Time between Request and Response for AFP cmds", HFILL }},
4415
4416     { &hf_afp_response_in,
4417       { "Response in",  "afp.response_in",
4418                 FT_FRAMENUM, BASE_NONE, NULL, 0x0,
4419         "The response to this packet is in this packet", HFILL }},
4420
4421     { &hf_afp_login_flags,
4422       { "Flags",         "afp.afp_login_flags",
4423                 FT_UINT16, BASE_HEX, NULL, 0 /* 0x0FFF*/,
4424         "Login flags", HFILL }},
4425
4426     { &hf_afp_vol_bitmap,
4427       { "Bitmap",         "afp.vol_bitmap",
4428                 FT_UINT16, BASE_HEX, NULL, 0 /* 0x0FFF*/,
4429         "Volume bitmap", HFILL }},
4430
4431     { &hf_afp_vol_bitmap_Attributes,
4432       { "Attributes",      "afp.vol_bitmap.attributes",
4433                 FT_BOOLEAN, 16, NULL, kFPVolAttributeBit,
4434         "Volume attributes", HFILL }},
4435
4436     { &hf_afp_vol_attribute,
4437       { "Attributes",         "afp.vol_attributes",
4438                 FT_UINT16, BASE_HEX, NULL, 0,
4439         "Volume attributes", HFILL }},
4440
4441     { &hf_afp_vol_attribute_ReadOnly,
4442       { "Read only",         "afp.vol_attribute.read_only",
4443                  FT_BOOLEAN, 16, NULL, kReadOnly,
4444         "Read only volume", HFILL }},
4445
4446     { &hf_afp_vol_attribute_HasVolumePassword,
4447       { "Volume password",         "afp.vol_attribute.passwd",
4448                  FT_BOOLEAN, 16, NULL, kHasVolumePassword,
4449         "Has a volume password", HFILL }},
4450
4451     { &hf_afp_vol_attribute_SupportsFileIDs,
4452       { "File IDs",         "afp.vol_attribute.fileIDs",
4453                  FT_BOOLEAN, 16, NULL, kSupportsFileIDs,
4454         "Supports file IDs", HFILL }},
4455
4456     { &hf_afp_vol_attribute_SupportsCatSearch,
4457       { "Catalog search",         "afp.vol_attribute.cat_search",
4458                  FT_BOOLEAN, 16, NULL, kSupportsCatSearch,
4459         "Supports catalog search operations", HFILL }},
4460
4461     { &hf_afp_vol_attribute_SupportsBlankAccessPrivs,
4462       { "Blank access privileges",         "afp.vol_attribute.blank_access_privs",
4463                  FT_BOOLEAN, 16, NULL, kSupportsBlankAccessPrivs,
4464         "Supports blank access privileges", HFILL }},
4465
4466     { &hf_afp_vol_attribute_SupportsUnixPrivs,
4467       { "UNIX access privileges",         "afp.vol_attribute.unix_privs",
4468                  FT_BOOLEAN, 16, NULL, kSupportsUnixPrivs,
4469         "Supports UNIX access privileges", HFILL }},
4470
4471     { &hf_afp_vol_attribute_SupportsUTF8Names,
4472       { "UTF-8 names",         "afp.vol_attribute.utf8_names",
4473                  FT_BOOLEAN, 16, NULL, kSupportsUTF8Names,
4474         "Supports UTF-8 names", HFILL }},
4475
4476     { &hf_afp_vol_attribute_NoNetworkUserID,
4477       { "No Network User ID",         "afp.vol_attribute.network_user_id",
4478                  FT_BOOLEAN, 16, NULL, kNoNetworkUserIDs,
4479         "No Network User ID", HFILL }},
4480
4481     { &hf_afp_vol_attribute_DefaultPrivsFromParent,
4482       { "Inherit parent privileges",         "afp.vol_attribute.inherit_parent_privs",
4483                  FT_BOOLEAN, 16, NULL, kDefaultPrivsFromParent,
4484         "Inherit parent privileges", HFILL }},
4485
4486     { &hf_afp_vol_attribute_NoExchangeFiles,
4487       { "No exchange files",         "afp.vol_attribute.no_exchange_files",
4488                  FT_BOOLEAN, 16, NULL, kNoExchangeFiles,
4489         "Exchange files not supported", HFILL }},
4490
4491     { &hf_afp_vol_attribute_SupportsExtAttrs,
4492       { "Extended Attributes",         "afp.vol_attribute.extended_attributes",
4493                  FT_BOOLEAN, 16, NULL, kSupportsExtAttrs,
4494         "Supports Extended Attributes", HFILL }},
4495
4496     { &hf_afp_vol_attribute_SupportsACLs,
4497       { "ACLs",         "afp.vol_attribute.acls",
4498                  FT_BOOLEAN, 16, NULL, kSupportsACLs,
4499         "Supports access control lists", HFILL }},
4500
4501     { &hf_afp_vol_bitmap_Signature,
4502       { "Signature",         "afp.vol_bitmap.signature",
4503                 FT_BOOLEAN, 16, NULL, kFPVolSignatureBit,
4504         "Volume signature", HFILL }},
4505
4506     { &hf_afp_vol_bitmap_CreateDate,
4507       { "Creation date",      "afp.vol_bitmap.create_date",
4508                 FT_BOOLEAN, 16, NULL, kFPVolCreateDateBit,
4509         "Volume creation date", HFILL }},
4510
4511     { &hf_afp_vol_bitmap_ModDate,
4512       { "Modification date",  "afp.vol_bitmap.mod_date",
4513                 FT_BOOLEAN, 16, NULL, kFPVolModDateBit,
4514         "Volume modification date", HFILL }},
4515
4516     { &hf_afp_vol_bitmap_BackupDate,
4517       { "Backup date",        "afp.vol_bitmap.backup_date",
4518                 FT_BOOLEAN, 16, NULL, kFPVolBackupDateBit,
4519         "Volume backup date", HFILL }},
4520
4521     { &hf_afp_vol_bitmap_ID,
4522       { "ID",         "afp.vol_bitmap.id",
4523                 FT_BOOLEAN, 16, NULL,  kFPVolIDBit,
4524         "Volume ID", HFILL }},
4525
4526     { &hf_afp_vol_bitmap_BytesFree,
4527       { "Bytes free",         "afp.vol_bitmap.bytes_free",
4528                 FT_BOOLEAN, 16, NULL,  kFPVolBytesFreeBit,
4529         "Volume free bytes", HFILL }},
4530
4531     { &hf_afp_vol_bitmap_BytesTotal,
4532       { "Bytes total",         "afp.vol_bitmap.bytes_total",
4533                 FT_BOOLEAN, 16, NULL,  kFPVolBytesTotalBit,
4534         "Volume total bytes", HFILL }},
4535
4536     { &hf_afp_vol_bitmap_Name,
4537       { "Name",         "afp.vol_bitmap.name",
4538                 FT_BOOLEAN, 16, NULL,  kFPVolNameBit,
4539         "Volume name", HFILL }},
4540
4541     { &hf_afp_vol_bitmap_ExtBytesFree,
4542       { "Extended bytes free",         "afp.vol_bitmap.ex_bytes_free",
4543                 FT_BOOLEAN, 16, NULL,  kFPVolExtBytesFreeBit,
4544         "Volume extended (>2GB) free bytes", HFILL }},
4545
4546     { &hf_afp_vol_bitmap_ExtBytesTotal,
4547       { "Extended bytes total",         "afp.vol_bitmap.ex_bytes_total",
4548                 FT_BOOLEAN, 16, NULL,  kFPVolExtBytesTotalBit,
4549         "Volume extended (>2GB) total bytes", HFILL }},
4550
4551     { &hf_afp_vol_bitmap_BlockSize,
4552       { "Block size",         "afp.vol_bitmap.block_size",
4553                 FT_BOOLEAN, 16, NULL,  kFPVolBlockSizeBit,
4554         "Volume block size", HFILL }},
4555
4556     { &hf_afp_dir_bitmap_Attributes,
4557       { "Attributes",         "afp.dir_bitmap.attributes",
4558             FT_BOOLEAN, 16, NULL,  kFPAttributeBit,
4559         "Return attributes if directory", HFILL }},
4560
4561     { &hf_afp_dir_bitmap_ParentDirID,
4562       { "DID",         "afp.dir_bitmap.did",
4563         FT_BOOLEAN, 16, NULL,  kFPParentDirIDBit,
4564         "Return parent directory ID if directory", HFILL }},
4565
4566     { &hf_afp_dir_bitmap_CreateDate,
4567       { "Creation date",         "afp.dir_bitmap.create_date",
4568             FT_BOOLEAN, 16, NULL,  kFPCreateDateBit,
4569         "Return creation date if directory", HFILL }},
4570
4571     { &hf_afp_dir_bitmap_ModDate,
4572       { "Modification date",         "afp.dir_bitmap.mod_date",
4573         FT_BOOLEAN, 16, NULL,  kFPModDateBit,
4574         "Return modification date if directory", HFILL }},
4575
4576     { &hf_afp_dir_bitmap_BackupDate,
4577       { "Backup date",         "afp.dir_bitmap.backup_date",
4578             FT_BOOLEAN, 16, NULL,  kFPBackupDateBit,
4579         "Return backup date if directory", HFILL }},
4580
4581     { &hf_afp_dir_bitmap_FinderInfo,
4582       { "Finder info",         "afp.dir_bitmap.finder_info",
4583         FT_BOOLEAN, 16, NULL,  kFPFinderInfoBit,
4584         "Return finder info if directory", HFILL }},
4585
4586     { &hf_afp_dir_bitmap_LongName,
4587       { "Long name",         "afp.dir_bitmap.long_name",
4588             FT_BOOLEAN, 16, NULL,  kFPLongNameBit,
4589         "Return long name if directory", HFILL }},
4590
4591     { &hf_afp_dir_bitmap_ShortName,
4592       { "Short name",         "afp.dir_bitmap.short_name",
4593         FT_BOOLEAN, 16, NULL,  kFPShortNameBit,
4594         "Return short name if directory", HFILL }},
4595
4596     { &hf_afp_dir_bitmap_NodeID,
4597       { "File ID",         "afp.dir_bitmap.fid",
4598             FT_BOOLEAN, 16, NULL,  kFPNodeIDBit,
4599         "Return file ID if directory", HFILL }},
4600
4601     { &hf_afp_dir_bitmap_OffspringCount,
4602       { "Offspring count",         "afp.dir_bitmap.offspring_count",
4603         FT_BOOLEAN, 16, NULL,  kFPOffspringCountBit,
4604         "Return offspring count if directory", HFILL }},
4605
4606     { &hf_afp_dir_bitmap_OwnerID,
4607       { "Owner id",         "afp.dir_bitmap.owner_id",
4608             FT_BOOLEAN, 16, NULL,  kFPOwnerIDBit,
4609         "Return owner id if directory", HFILL }},
4610
4611     { &hf_afp_dir_bitmap_GroupID,
4612       { "Group id",         "afp.dir_bitmap.group_id",
4613         FT_BOOLEAN, 16, NULL,  kFPGroupIDBit,
4614         "Return group id if directory", HFILL }},
4615
4616     { &hf_afp_dir_bitmap_AccessRights,
4617       { "Access rights",         "afp.dir_bitmap.access_rights",
4618             FT_BOOLEAN, 16, NULL,  kFPAccessRightsBit,
4619         "Return access rights if directory", HFILL }},
4620
4621     { &hf_afp_dir_bitmap_UTF8Name,
4622       { "UTF-8 name",         "afp.dir_bitmap.UTF8_name",
4623         FT_BOOLEAN, 16, NULL,  kFPUTF8NameBit,
4624         "Return UTF-8 name if diectory", HFILL }},
4625
4626     { &hf_afp_dir_bitmap_UnixPrivs,
4627       { "UNIX privileges",         "afp.dir_bitmap.unix_privs",
4628             FT_BOOLEAN, 16, NULL,  kFPUnixPrivsBit,
4629         "Return UNIX privileges if directory", HFILL }},
4630
4631     { &hf_afp_dir_attribute_Invisible,
4632       { "Invisible",         "afp.dir_attribute.invisible",
4633             FT_BOOLEAN, 16, NULL,  kFPInvisibleBit,
4634         "Directory is not visible", HFILL }},
4635
4636     { &hf_afp_dir_attribute_IsExpFolder,
4637       { "Share point",         "afp.dir_attribute.share",
4638             FT_BOOLEAN, 16, NULL,  kFPMultiUserBit,
4639         "Directory is a share point", HFILL }},
4640
4641     { &hf_afp_dir_attribute_System,
4642       { "System",                "afp.dir_attribute.system",
4643             FT_BOOLEAN, 16, NULL,  kFPSystemBit,
4644         "Directory is a system directory", HFILL }},
4645
4646     { &hf_afp_dir_attribute_Mounted,
4647       { "Mounted",         "afp.dir_attribute.mounted",
4648             FT_BOOLEAN, 16, NULL,  kFPDAlreadyOpenBit,
4649         "Directory is mounted", HFILL }},
4650
4651     { &hf_afp_dir_attribute_InExpFolder,
4652       { "Shared area",         "afp.dir_attribute.in_exported_folder",
4653             FT_BOOLEAN, 16, NULL,  kFPRAlreadyOpenBit,
4654         "Directory is in a shared area", HFILL }},
4655
4656     { &hf_afp_dir_attribute_BackUpNeeded,
4657       { "Backup needed",         "afp.dir_attribute.backup_needed",
4658             FT_BOOLEAN, 16, NULL,  kFPBackUpNeededBit,
4659         "Directory needs to be backed up", HFILL }},
4660
4661     { &hf_afp_dir_attribute_RenameInhibit,
4662       { "Rename inhibit",         "afp.dir_attribute.rename_inhibit",
4663             FT_BOOLEAN, 16, NULL,  kFPRenameInhibitBit,
4664         "Rename inhibit", HFILL }},
4665
4666     { &hf_afp_dir_attribute_DeleteInhibit,
4667       { "Delete inhibit",         "afp.dir_attribute.delete_inhibit",
4668             FT_BOOLEAN, 16, NULL,  kFPDeleteInhibitBit,
4669         "Delete inhibit", HFILL }},
4670
4671     { &hf_afp_dir_attribute_SetClear,
4672       { "Set",         "afp.dir_attribute.set_clear",
4673             FT_BOOLEAN, 16, NULL,  kFPSetClearBit,
4674         "Clear/set attribute", HFILL }},
4675
4676     { &hf_afp_file_bitmap_Attributes,
4677       { "Attributes",         "afp.file_bitmap.attributes",
4678             FT_BOOLEAN, 16, NULL,  kFPAttributeBit,
4679         "Return attributes if file", HFILL }},
4680
4681     { &hf_afp_file_bitmap_ParentDirID,
4682       { "DID",         "afp.file_bitmap.did",
4683         FT_BOOLEAN, 16, NULL,  kFPParentDirIDBit,
4684         "Return parent directory ID if file", HFILL }},
4685
4686     { &hf_afp_file_bitmap_CreateDate,
4687       { "Creation date",         "afp.file_bitmap.create_date",
4688             FT_BOOLEAN, 16, NULL,  kFPCreateDateBit,
4689         "Return creation date if file", HFILL }},
4690
4691     { &hf_afp_file_bitmap_ModDate,
4692       { "Modification date",         "afp.file_bitmap.mod_date",
4693         FT_BOOLEAN, 16, NULL,  kFPModDateBit,
4694         "Return modification date if file", HFILL }},
4695
4696     { &hf_afp_file_bitmap_BackupDate,
4697       { "Backup date",         "afp.file_bitmap.backup_date",
4698             FT_BOOLEAN, 16, NULL,  kFPBackupDateBit,
4699         "Return backup date if file", HFILL }},
4700
4701     { &hf_afp_file_bitmap_FinderInfo,
4702       { "Finder info",         "afp.file_bitmap.finder_info",
4703         FT_BOOLEAN, 16, NULL,  kFPFinderInfoBit,
4704         "Return finder info if file", HFILL }},
4705
4706     { &hf_afp_file_bitmap_LongName,
4707       { "Long name",         "afp.file_bitmap.long_name",
4708             FT_BOOLEAN, 16, NULL,  kFPLongNameBit,
4709         "Return long name if file", HFILL }},
4710
4711     { &hf_afp_file_bitmap_ShortName,
4712       { "Short name",         "afp.file_bitmap.short_name",
4713         FT_BOOLEAN, 16, NULL,  kFPShortNameBit,
4714         "Return short name if file", HFILL }},
4715
4716     { &hf_afp_file_bitmap_NodeID,
4717       { "File ID",         "afp.file_bitmap.fid",
4718             FT_BOOLEAN, 16, NULL,  kFPNodeIDBit,
4719         "Return file ID if file", HFILL }},
4720
4721     { &hf_afp_file_bitmap_DataForkLen,
4722       { "Data fork size",         "afp.file_bitmap.data_fork_len",
4723             FT_BOOLEAN, 16, NULL,  kFPDataForkLenBit,
4724         "Return data fork size if file", HFILL }},
4725
4726     { &hf_afp_file_bitmap_RsrcForkLen,
4727       { "Resource fork size",         "afp.file_bitmap.resource_fork_len",
4728             FT_BOOLEAN, 16, NULL,  kFPRsrcForkLenBit,
4729         "Return resource fork size if file", HFILL }},
4730
4731     { &hf_afp_file_bitmap_ExtDataForkLen,
4732       { "Extended data fork size",         "afp.file_bitmap.ex_data_fork_len",
4733             FT_BOOLEAN, 16, NULL,  kFPExtDataForkLenBit,
4734         "Return extended (>2GB) data fork size if file", HFILL }},
4735
4736     { &hf_afp_file_bitmap_LaunchLimit,
4737       { "Launch limit",         "afp.file_bitmap.launch_limit",
4738             FT_BOOLEAN, 16, NULL,  kFPLaunchLimitBit,
4739         "Return launch limit if file", HFILL }},
4740
4741     { &hf_afp_file_bitmap_UTF8Name,
4742       { "UTF-8 name",         "afp.file_bitmap.UTF8_name",
4743         FT_BOOLEAN, 16, NULL,  kFPUTF8NameBit,
4744         "Return UTF-8 name if file", HFILL }},
4745
4746     { &hf_afp_file_bitmap_ExtRsrcForkLen,
4747         { "Extended resource fork size",         "afp.file_bitmap.ex_resource_fork_len",
4748             FT_BOOLEAN, 16, NULL,  kFPExtRsrcForkLenBit,
4749         "Return extended (>2GB) resource fork size if file", HFILL }},
4750
4751     { &hf_afp_file_bitmap_UnixPrivs,
4752       { "UNIX privileges",    "afp.file_bitmap.unix_privs",
4753             FT_BOOLEAN, 16, NULL,  kFPUnixPrivsBit,
4754         "Return UNIX privileges if file", HFILL }},
4755
4756         /* ---------- */
4757     { &hf_afp_file_attribute_Invisible,
4758       { "Invisible",         "afp.file_attribute.invisible",
4759             FT_BOOLEAN, 16, NULL,  kFPInvisibleBit,
4760         "File is not visible", HFILL }},
4761
4762     { &hf_afp_file_attribute_MultiUser,
4763       { "Multi user",         "afp.file_attribute.multi_user",
4764             FT_BOOLEAN, 16, NULL,  kFPMultiUserBit,
4765         "multi user", HFILL }},
4766
4767     { &hf_afp_file_attribute_System,
4768       { "System",                "afp.file_attribute.system",
4769             FT_BOOLEAN, 16, NULL,  kFPSystemBit,
4770         "File is a system file", HFILL }},
4771
4772     { &hf_afp_file_attribute_DAlreadyOpen,
4773       { "Data fork open",         "afp.file_attribute.df_open",
4774             FT_BOOLEAN, 16, NULL,  kFPDAlreadyOpenBit,
4775         "Data fork already open", HFILL }},
4776
4777     { &hf_afp_file_attribute_RAlreadyOpen,
4778       { "Resource fork open",         "afp.file_attribute.rf_open",
4779             FT_BOOLEAN, 16, NULL,  kFPRAlreadyOpenBit,
4780         "Resource fork already open", HFILL }},
4781
4782     { &hf_afp_file_attribute_WriteInhibit,
4783       { "Write inhibit",         "afp.file_attribute.write_inhibit",
4784             FT_BOOLEAN, 16, NULL,  kFPWriteInhibitBit,
4785         "Write inhibit", HFILL }},
4786
4787     { &hf_afp_file_attribute_BackUpNeeded,
4788       { "Backup needed",         "afp.file_attribute.backup_needed",
4789             FT_BOOLEAN, 16, NULL,  kFPBackUpNeededBit,
4790         "File needs to be backed up", HFILL }},
4791
4792     { &hf_afp_file_attribute_RenameInhibit,
4793       { "Rename inhibit",         "afp.file_attribute.rename_inhibit",
4794             FT_BOOLEAN, 16, NULL,  kFPRenameInhibitBit,
4795         "rename inhibit", HFILL }},
4796
4797     { &hf_afp_file_attribute_DeleteInhibit,
4798       { "Delete inhibit",         "afp.file_attribute.delete_inhibit",
4799             FT_BOOLEAN, 16, NULL,  kFPDeleteInhibitBit,
4800         "delete inhibit", HFILL }},
4801
4802     { &hf_afp_file_attribute_CopyProtect,
4803       { "Copy protect",         "afp.file_attribute.copy_protect",
4804             FT_BOOLEAN, 16, NULL,  kFPCopyProtectBit,
4805         "copy protect", HFILL }},
4806
4807     { &hf_afp_file_attribute_SetClear,
4808       { "Set",         "afp.file_attribute.set_clear",
4809             FT_BOOLEAN, 16, NULL,  kFPSetClearBit,
4810         "Clear/set attribute", HFILL }},
4811         /* ---------- */
4812
4813     { &hf_afp_vol_name,
4814       { "Volume",         "afp.vol_name",
4815         FT_UINT_STRING, BASE_NONE, NULL, 0x0,
4816         "Volume name", HFILL }},
4817
4818     { &hf_afp_vol_flag_passwd,
4819       { "Password",         "afp.vol_flag_passwd",
4820             FT_BOOLEAN, 8, NULL,  1,
4821         "Volume is password-protected", HFILL }},
4822
4823     { &hf_afp_vol_flag_unix_priv,
4824       { "Unix privs",         "afp.vol_flag_unix_priv",
4825             FT_BOOLEAN, 8, NULL,  2,
4826         "Volume has unix privileges", HFILL }},
4827
4828     { &hf_afp_vol_id,
4829       { "Volume id",         "afp.vol_id",
4830                 FT_UINT16, BASE_DEC, NULL, 0x0,
4831         "Volume id", HFILL }},
4832
4833     { &hf_afp_vol_signature,
4834       { "Signature",         "afp.vol_signature",
4835                 FT_UINT16, BASE_DEC, VALS(vol_signature_vals), 0x0,
4836         "Volume signature", HFILL }},
4837
4838     { &hf_afp_vol_name_offset,
4839       { "Volume name offset","afp.vol_name_offset",
4840                 FT_UINT16, BASE_DEC, NULL, 0x0,
4841         "Volume name offset in packet", HFILL }},
4842
4843     { &hf_afp_vol_creation_date,
4844       { "Creation date",         "afp.vol_creation_date",
4845                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4846         "Volume creation date", HFILL }},
4847
4848     { &hf_afp_vol_modification_date,
4849       { "Modification date",         "afp.vol_modification_date",
4850                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4851         "Volume modification date", HFILL }},
4852
4853     { &hf_afp_vol_backup_date,
4854       { "Backup date",         "afp.vol_backup_date",
4855                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4856         "Volume backup date", HFILL }},
4857
4858     { &hf_afp_vol_bytes_free,
4859       { "Bytes free",         "afp.vol_bytes_free",
4860                 FT_UINT32, BASE_DEC, NULL, 0x0,
4861         "Free space", HFILL }},
4862
4863     { &hf_afp_vol_bytes_total,
4864       { "Bytes total",         "afp.vol_bytes_total",
4865                 FT_UINT32, BASE_DEC, NULL, 0x0,
4866         "Volume size", HFILL }},
4867
4868     { &hf_afp_vol_ex_bytes_free,
4869       { "Extended bytes free",         "afp.vol_ex_bytes_free",
4870                 FT_UINT64, BASE_DEC, NULL, 0x0,
4871         "Extended (>2GB) free space", HFILL }},
4872
4873     { &hf_afp_vol_ex_bytes_total,
4874       { "Extended bytes total",         "afp.vol_ex_bytes_total",
4875                 FT_UINT64, BASE_DEC, NULL, 0x0,
4876         "Extended (>2GB) volume size", HFILL }},
4877
4878     { &hf_afp_vol_block_size,
4879       { "Block size",         "afp.vol_block_size",
4880                 FT_UINT32, BASE_DEC, NULL, 0x0,
4881         "Volume block size", HFILL }},
4882
4883     { &hf_afp_did,
4884       { "DID",         "afp.did",
4885                 FT_UINT32, BASE_DEC, NULL, 0x0,
4886         "Parent directory ID", HFILL }},
4887
4888     { &hf_afp_dir_bitmap,
4889       { "Directory bitmap",         "afp.dir_bitmap",
4890                 FT_UINT16, BASE_HEX, NULL, 0x0,
4891         "Directory bitmap", HFILL }},
4892
4893     { &hf_afp_dir_offspring,
4894       { "Offspring",         "afp.dir_offspring",
4895                 FT_UINT16, BASE_DEC, NULL, 0x0,
4896         "Directory offspring", HFILL }},
4897
4898     { &hf_afp_dir_OwnerID,
4899       { "Owner ID",         "afp.dir_owner_id",
4900                 FT_INT32, BASE_DEC, NULL, 0x0,
4901         "Directory owner ID", HFILL }},
4902
4903     { &hf_afp_dir_GroupID,
4904       { "Group ID",         "afp.dir_group_id",
4905                 FT_INT32, BASE_DEC, NULL, 0x0,
4906         "Directory group ID", HFILL }},
4907
4908     { &hf_afp_creation_date,
4909       { "Creation date",         "afp.creation_date",
4910                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4911         "Creation date", HFILL }},
4912
4913     { &hf_afp_modification_date,
4914       { "Modification date",         "afp.modification_date",
4915                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4916         "Modification date", HFILL }},
4917
4918     { &hf_afp_backup_date,
4919       { "Backup date",         "afp.backup_date",
4920                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
4921         "Backup date", HFILL }},
4922
4923     { &hf_afp_finder_info,
4924       { "Finder info",         "afp.finder_info",
4925                 FT_BYTES, BASE_HEX, NULL, 0x0,
4926         "Finder info", HFILL }},
4927
4928     { &hf_afp_long_name_offset,
4929       { "Long name offset",    "afp.long_name_offset",
4930                 FT_UINT16, BASE_DEC, NULL, 0x0,
4931         "Long name offset in packet", HFILL }},
4932
4933     { &hf_afp_short_name_offset,
4934       { "Short name offset",   "afp.short_name_offset",
4935                 FT_UINT16, BASE_DEC, NULL, 0x0,
4936         "Short name offset in packet", HFILL }},
4937
4938     { &hf_afp_unicode_name_offset,
4939       { "Unicode name offset", "afp.unicode_name_offset",
4940                 FT_UINT16, BASE_DEC, NULL, 0x0,
4941         "Unicode name offset in packet", HFILL }},
4942
4943     { &hf_afp_unix_privs_uid,
4944       { "UID",             "afp.unix_privs.uid",
4945                 FT_UINT32, BASE_DEC, NULL, 0x0,
4946         "User ID", HFILL }},
4947
4948     { &hf_afp_unix_privs_gid,
4949       { "GID",             "afp.unix_privs.gid",
4950                 FT_UINT32, BASE_DEC, NULL, 0x0,
4951         "Group ID", HFILL }},
4952
4953     { &hf_afp_unix_privs_permissions,
4954       { "Permissions",     "afp.unix_privs.permissions",
4955                 FT_UINT32, BASE_OCT, NULL, 0x0,
4956         "Permissions", HFILL }},
4957
4958     { &hf_afp_unix_privs_ua_permissions,
4959       { "User's access rights",     "afp.unix_privs.ua_permissions",
4960                 FT_UINT32, BASE_HEX, NULL, 0x0,
4961         "User's access rights", HFILL }},
4962
4963     { &hf_afp_file_id,
4964       { "File ID",         "afp.file_id",
4965                 FT_UINT32, BASE_DEC, NULL, 0x0,
4966         "File/directory ID", HFILL }},
4967
4968     { &hf_afp_file_DataForkLen,
4969       { "Data fork size",         "afp.data_fork_len",
4970                 FT_UINT32, BASE_DEC, NULL, 0x0,
4971         "Data fork size", HFILL }},
4972
4973     { &hf_afp_file_RsrcForkLen,
4974       { "Resource fork size",         "afp.resource_fork_len",
4975                 FT_UINT32, BASE_DEC, NULL, 0x0,
4976         "Resource fork size", HFILL }},
4977
4978     { &hf_afp_file_ExtDataForkLen,
4979       { "Extended data fork size",         "afp.ext_data_fork_len",
4980                 FT_UINT64, BASE_DEC, NULL, 0x0,
4981         "Extended (>2GB) data fork length", HFILL }},
4982
4983     { &hf_afp_file_ExtRsrcForkLen,
4984       { "Extended resource fork size",         "afp.ext_resource_fork_len",
4985                 FT_UINT64, BASE_DEC, NULL, 0x0,
4986         "Extended (>2GB) resource fork length", HFILL }},
4987
4988     { &hf_afp_file_bitmap,
4989       { "File bitmap",         "afp.file_bitmap",
4990                 FT_UINT16, BASE_HEX, NULL, 0x0,
4991         "File bitmap", HFILL }},
4992
4993     { &hf_afp_req_count,
4994       { "Req count",         "afp.req_count",
4995                 FT_UINT16, BASE_DEC, NULL, 0x0,
4996         "Maximum number of structures returned", HFILL }},
4997
4998     { &hf_afp_start_index,
4999       { "Start index",         "afp.start_index",
5000                 FT_UINT16, BASE_DEC, NULL, 0x0,
5001         "First structure returned", HFILL }},
5002
5003     { &hf_afp_max_reply_size,
5004       { "Reply size",         "afp.reply_size",
5005                 FT_UINT16, BASE_DEC, NULL, 0x0,
5006         "Reply size", HFILL }},
5007
5008     { &hf_afp_start_index32,
5009       { "Start index",         "afp.start_index32",
5010                 FT_UINT32, BASE_DEC, NULL, 0x0,
5011         "First structure returned", HFILL }},
5012
5013     { &hf_afp_max_reply_size32,
5014       { "Reply size",         "afp.reply_size32",
5015                 FT_UINT32, BASE_DEC, NULL, 0x0,
5016         "Reply size", HFILL }},
5017
5018     { &hf_afp_file_flag,
5019       { "Dir",         "afp.file_flag",
5020                 FT_BOOLEAN, 8, NULL, 0x80,
5021         "Is a dir", HFILL }},
5022
5023     { &hf_afp_create_flag,
5024       { "Hard create",         "afp.create_flag",
5025                 FT_BOOLEAN, 8, NULL, 0x80,
5026         "Soft/hard create file", HFILL }},
5027
5028     { &hf_afp_request_bitmap_Attributes,
5029       { "Attributes",         "afp.request_bitmap.attributes",
5030             FT_BOOLEAN, 32, NULL,  kFPAttributeBit,
5031         "Search attributes", HFILL }},
5032
5033     { &hf_afp_request_bitmap_ParentDirID,
5034       { "DID",         "afp.request_bitmap.did",
5035         FT_BOOLEAN, 32, NULL,  kFPParentDirIDBit,
5036         "Search parent directory ID", HFILL }},
5037
5038     { &hf_afp_request_bitmap_CreateDate,
5039       { "Creation date",         "afp.request_bitmap.create_date",
5040             FT_BOOLEAN, 32, NULL,  kFPCreateDateBit,
5041         "Search creation date", HFILL }},
5042
5043     { &hf_afp_request_bitmap_ModDate,
5044       { "Modification date",         "afp.request_bitmap.mod_date",
5045         FT_BOOLEAN, 32, NULL,  kFPModDateBit,
5046         "Search modification date", HFILL }},
5047
5048     { &hf_afp_request_bitmap_BackupDate,
5049       { "Backup date",         "afp.request_bitmap.backup_date",
5050             FT_BOOLEAN, 32, NULL,  kFPBackupDateBit,
5051         "Search backup date", HFILL }},
5052
5053     { &hf_afp_request_bitmap_FinderInfo,
5054       { "Finder info",         "afp.request_bitmap.finder_info",
5055         FT_BOOLEAN, 32, NULL,  kFPFinderInfoBit,
5056         "Search finder info", HFILL }},
5057
5058     { &hf_afp_request_bitmap_LongName,
5059       { "Long name",         "afp.request_bitmap.long_name",
5060             FT_BOOLEAN, 32, NULL,  kFPLongNameBit,
5061         "Search long name", HFILL }},
5062
5063     { &hf_afp_request_bitmap_DataForkLen,
5064       { "Data fork size",         "afp.request_bitmap.data_fork_len",
5065             FT_BOOLEAN, 32, NULL,  kFPDataForkLenBit,
5066         "Search data fork size", HFILL }},
5067
5068     { &hf_afp_request_bitmap_OffspringCount,
5069       { "Offspring count",         "afp.request_bitmap.offspring_count",
5070         FT_BOOLEAN, 32, NULL,  kFPOffspringCountBit,
5071         "Search offspring count", HFILL }},
5072
5073     { &hf_afp_request_bitmap_RsrcForkLen,
5074       { "Resource fork size",         "afp.request_bitmap.resource_fork_len",
5075             FT_BOOLEAN, 32, NULL,  kFPRsrcForkLenBit,
5076         "Search resource fork size", HFILL }},
5077
5078     { &hf_afp_request_bitmap_ExtDataForkLen,
5079       { "Extended data fork size",         "afp.request_bitmap.ex_data_fork_len",
5080             FT_BOOLEAN, 32, NULL,  kFPExtDataForkLenBit,
5081         "Search extended (>2GB) data fork size", HFILL }},
5082
5083     { &hf_afp_request_bitmap_UTF8Name,
5084       { "UTF-8 name",         "afp.request_bitmap.UTF8_name",
5085         FT_BOOLEAN, 32, NULL,  kFPUTF8NameBit,
5086         "Search UTF-8 name", HFILL }},
5087
5088     { &hf_afp_request_bitmap_ExtRsrcForkLen,
5089         { "Extended resource fork size",         "afp.request_bitmap.ex_resource_fork_len",
5090             FT_BOOLEAN, 32, NULL,  kFPExtRsrcForkLenBit,
5091         "Search extended (>2GB) resource fork size", HFILL }},
5092
5093     { &hf_afp_request_bitmap_PartialNames,
5094         { "Match on partial names",         "afp.request_bitmap.partial_names",
5095             FT_BOOLEAN, 32, NULL,  0x80000000,
5096         "Match on partial names", HFILL }},
5097
5098     { &hf_afp_request_bitmap,
5099       { "Request bitmap",         "afp.request_bitmap",
5100                 FT_UINT32, BASE_HEX, NULL, 0x0,
5101         "Request bitmap", HFILL }},
5102
5103     { &hf_afp_struct_size,
5104       { "Struct size",         "afp.struct_size",
5105                 FT_UINT8, BASE_DEC, NULL,0,
5106         "Sizeof of struct", HFILL }},
5107
5108     { &hf_afp_struct_size16,
5109       { "Struct size",         "afp.struct_size16",
5110                 FT_UINT16, BASE_DEC, NULL,0,
5111         "Sizeof of struct", HFILL }},
5112
5113     { &hf_afp_flag,
5114       { "From",         "afp.flag",
5115                 FT_UINT8, BASE_HEX, VALS(flag_vals), 0x80,
5116         "Offset is relative to start/end of the fork", HFILL }},
5117
5118     { &hf_afp_dt_ref,
5119       { "DT ref",         "afp.dt_ref",
5120                 FT_UINT16, BASE_DEC, NULL, 0x0,
5121         "Desktop database reference num", HFILL }},
5122
5123     { &hf_afp_ofork,
5124       { "Fork",         "afp.ofork",
5125                 FT_UINT16, BASE_DEC, NULL, 0x0,
5126         "Open fork reference number", HFILL }},
5127
5128     { &hf_afp_offset,
5129       { "Offset",         "afp.offset",
5130                 FT_INT32, BASE_DEC, NULL, 0x0,
5131         "Offset", HFILL }},
5132
5133     { &hf_afp_rw_count,
5134       { "Count",         "afp.rw_count",
5135                 FT_INT32, BASE_DEC, NULL, 0x0,
5136         "Number of bytes to be read/written", HFILL }},
5137
5138     { &hf_afp_newline_mask,
5139       { "Newline mask",  "afp.newline_mask",
5140                 FT_UINT8, BASE_HEX, NULL, 0x0,
5141         "Value to AND bytes with when looking for newline", HFILL }},
5142
5143     { &hf_afp_newline_char,
5144       { "Newline char",  "afp.newline_char",
5145                 FT_UINT8, BASE_HEX, NULL, 0x0,
5146         "Value to compare ANDed bytes with when looking for newline", HFILL }},
5147
5148     { &hf_afp_last_written,
5149       { "Last written",  "afp.last_written",
5150                 FT_UINT32, BASE_DEC, NULL, 0x0,
5151         "Offset of the last byte written", HFILL }},
5152
5153     { &hf_afp_actual_count,
5154       { "Count",         "afp.actual_count",
5155                 FT_INT32, BASE_DEC, NULL, 0x0,
5156         "Number of bytes returned by read/write", HFILL }},
5157
5158     { &hf_afp_ofork_len,
5159       { "New length",         "afp.ofork_len",
5160                 FT_INT32, BASE_DEC, NULL, 0x0,
5161         "New length", HFILL }},
5162
5163     { &hf_afp_path_type,
5164       { "Type",         "afp.path_type",
5165                 FT_UINT8, BASE_HEX, VALS(path_type_vals), 0,
5166         "Type of names", HFILL }},
5167
5168     { &hf_afp_path_len,
5169       { "Len",  "afp.path_len",
5170                 FT_UINT8, BASE_DEC, NULL, 0x0,
5171         "Path length", HFILL }},
5172
5173     { &hf_afp_path_unicode_len,
5174       { "Len",  "afp.path_unicode_len",
5175                 FT_UINT16, BASE_DEC, NULL, 0x0,
5176         "Path length (unicode)", HFILL }},
5177
5178     { &hf_afp_path_unicode_hint,
5179       { "Unicode hint",  "afp.path_unicode_hint",
5180                 FT_UINT32, BASE_HEX, VALS(unicode_hint_vals), 0x0,
5181         "Unicode hint", HFILL }},
5182
5183     { &hf_afp_path_name,
5184       { "Name",  "afp.path_name",
5185                 FT_STRING, BASE_NONE, NULL, 0x0,
5186         "Path name", HFILL }},
5187
5188     { &hf_afp_fork_type,
5189       { "Resource fork",         "afp.fork_type",
5190                 FT_BOOLEAN, 8, NULL, 0x80,
5191         "Data/resource fork", HFILL }},
5192
5193     { &hf_afp_access_mode,
5194       { "Access mode",         "afp.access",
5195                 FT_UINT8, BASE_HEX, NULL, 0x0,
5196         "Fork access mode", HFILL }},
5197
5198     { &hf_afp_access_read,
5199       { "Read",         "afp.access.read",
5200         FT_BOOLEAN, 8, NULL,  1,
5201         "Open for reading", HFILL }},
5202
5203     { &hf_afp_access_write,
5204       { "Write",         "afp.access.write",
5205         FT_BOOLEAN, 8, NULL,  2,
5206         "Open for writing", HFILL }},
5207
5208     { &hf_afp_access_deny_read,
5209       { "Deny read",         "afp.access.deny_read",
5210         FT_BOOLEAN, 8, NULL,  0x10,
5211         "Deny read", HFILL }},
5212
5213     { &hf_afp_access_deny_write,
5214       { "Deny write",         "afp.access.deny_write",
5215         FT_BOOLEAN, 8, NULL,  0x20,
5216         "Deny write", HFILL }},
5217
5218     { &hf_afp_comment,
5219       { "Comment",         "afp.comment",
5220                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
5221         "File/folder comment", HFILL }},
5222
5223     { &hf_afp_file_creator,
5224       { "File creator",         "afp.file_creator",
5225                 FT_STRING, BASE_NONE, NULL, 0x0,
5226         "File creator", HFILL }},
5227
5228     { &hf_afp_file_type,
5229       { "File type",         "afp.file_type",
5230                 FT_STRING, BASE_NONE, NULL, 0x0,
5231         "File type", HFILL }},
5232
5233     { &hf_afp_icon_type,
5234       { "Icon type",         "afp.icon_type",
5235                 FT_UINT8, BASE_HEX, NULL , 0,
5236         "Icon type", HFILL }},
5237
5238     { &hf_afp_icon_length,
5239       { "Size",         "afp.icon_length",
5240                 FT_UINT16, BASE_DEC, NULL, 0x0,
5241         "Size for icon bitmap", HFILL }},
5242
5243     { &hf_afp_icon_index,
5244       { "Index",         "afp.icon_index",
5245                 FT_UINT16, BASE_DEC, NULL, 0x0,
5246         "Icon index in desktop database", HFILL }},
5247
5248     { &hf_afp_icon_tag,
5249       { "Tag",         "afp.icon_tag",
5250                 FT_UINT32, BASE_HEX, NULL, 0x0,
5251         "Icon tag", HFILL }},
5252
5253     { &hf_afp_appl_index,
5254       { "Index",         "afp.appl_index",
5255                 FT_UINT16, BASE_DEC, NULL, 0x0,
5256         "Application index", HFILL }},
5257
5258     { &hf_afp_appl_tag,
5259       { "Tag",         "afp.appl_tag",
5260                 FT_UINT32, BASE_HEX, NULL, 0x0,
5261         "Application tag", HFILL }},
5262
5263     { &hf_afp_lock_op,
5264       { "unlock",         "afp.lock_op",
5265                 FT_BOOLEAN, 8, NULL, 0x1,
5266         "Lock/unlock op", HFILL }},
5267
5268     { &hf_afp_lock_from,
5269       { "End",         "afp.lock_from",
5270                 FT_BOOLEAN, 8, NULL, 0x80,
5271         "Offset is relative to the end of the fork", HFILL }},
5272
5273     { &hf_afp_lock_offset,
5274       { "Offset",         "afp.lock_offset",
5275                 FT_INT32, BASE_DEC, NULL, 0x0,
5276         "First byte to be locked", HFILL }},
5277
5278     { &hf_afp_lock_len,
5279       { "Length",         "afp.lock_len",
5280                 FT_INT32, BASE_DEC, NULL, 0x0,
5281         "Number of bytes to be locked/unlocked", HFILL }},
5282
5283     { &hf_afp_lock_range_start,
5284       { "Start",         "afp.lock_range_start",
5285                 FT_INT32, BASE_DEC, NULL, 0x0,
5286         "First byte locked/unlocked", HFILL }},
5287
5288     { &hf_afp_dir_ar,
5289       { "Access rights",         "afp.dir_ar",
5290                 FT_UINT32, BASE_HEX, NULL, 0x0,
5291         "Directory access rights", HFILL }},
5292
5293     { &hf_afp_dir_ar_o_search,
5294       { "Owner has search access",      "afp.dir_ar.o_search",
5295                 FT_BOOLEAN, 32, NULL, AR_O_SEARCH,
5296         "Owner has search access", HFILL }},
5297
5298     { &hf_afp_dir_ar_o_read,
5299       { "Owner has read access",        "afp.dir_ar.o_read",
5300                 FT_BOOLEAN, 32, NULL, AR_O_READ,
5301         "Owner has read access", HFILL }},
5302
5303     { &hf_afp_dir_ar_o_write,
5304       { "Owner has write access",       "afp.dir_ar.o_write",
5305                 FT_BOOLEAN, 32, NULL, AR_O_WRITE,
5306         "Gwner has write access", HFILL }},
5307
5308     { &hf_afp_dir_ar_g_search,
5309       { "Group has search access",      "afp.dir_ar.g_search",
5310                 FT_BOOLEAN, 32, NULL, AR_G_SEARCH,
5311         "Group has search access", HFILL }},
5312
5313     { &hf_afp_dir_ar_g_read,
5314       { "Group has read access",        "afp.dir_ar.g_read",
5315                 FT_BOOLEAN, 32, NULL, AR_G_READ,
5316         "Group has read access", HFILL }},
5317
5318     { &hf_afp_dir_ar_g_write,
5319       { "Group has write access",       "afp.dir_ar.g_write",
5320                 FT_BOOLEAN, 32, NULL, AR_G_WRITE,
5321         "Group has write access", HFILL }},
5322
5323     { &hf_afp_dir_ar_e_search,
5324       { "Everyone has search access",   "afp.dir_ar.e_search",
5325                 FT_BOOLEAN, 32, NULL, AR_E_SEARCH,
5326         "Everyone has search access", HFILL }},
5327
5328     { &hf_afp_dir_ar_e_read,
5329       { "Everyone has read access",     "afp.dir_ar.e_read",
5330                 FT_BOOLEAN, 32, NULL, AR_E_READ,
5331         "Everyone has read access", HFILL }},
5332
5333     { &hf_afp_dir_ar_e_write,
5334       { "Everyone has write access",    "afp.dir_ar.e_write",
5335                 FT_BOOLEAN, 32, NULL, AR_E_WRITE,
5336         "Everyone has write access", HFILL }},
5337
5338     { &hf_afp_dir_ar_u_search,
5339       { "User has search access",   "afp.dir_ar.u_search",
5340                 FT_BOOLEAN, 32, NULL, AR_U_SEARCH,
5341         "User has search access", HFILL }},
5342
5343     { &hf_afp_dir_ar_u_read,
5344       { "User has read access",     "afp.dir_ar.u_read",
5345                 FT_BOOLEAN, 32, NULL, AR_U_READ,
5346         "User has read access", HFILL }},
5347
5348     { &hf_afp_dir_ar_u_write,
5349       { "User has write access",     "afp.dir_ar.u_write",
5350                 FT_BOOLEAN, 32, NULL, AR_U_WRITE,
5351         "User has write access", HFILL }},
5352
5353     { &hf_afp_dir_ar_blank,
5354       { "Blank access right",     "afp.dir_ar.blank",
5355                 FT_BOOLEAN, 32, NULL, AR_BLANK,
5356         "Blank access right", HFILL }},
5357
5358     { &hf_afp_dir_ar_u_own,
5359       { "User is the owner",     "afp.dir_ar.u_owner",
5360                 FT_BOOLEAN, 32, NULL, AR_U_OWN,
5361         "Current user is the directory owner", HFILL }},
5362
5363     { &hf_afp_server_time,
5364       { "Server time",         "afp.server_time",
5365                 FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0x0,
5366         "Server time", HFILL }},
5367
5368     { &hf_afp_cat_req_matches,
5369       { "Max answers",         "afp.cat_req_matches",
5370                 FT_INT32, BASE_DEC, NULL, 0x0,
5371         "Maximum number of matches to return.", HFILL }},
5372
5373     { &hf_afp_reserved,
5374       { "Reserved",         "afp.reserved",
5375                 FT_BYTES, BASE_HEX, NULL, 0x0,
5376         "Reserved", HFILL }},
5377
5378     { &hf_afp_cat_count,
5379       { "Cat count",         "afp.cat_count",
5380                 FT_UINT32, BASE_DEC, NULL, 0x0,
5381         "Number of structures returned", HFILL }},
5382
5383     { &hf_afp_cat_position,
5384       { "Position",         "afp.cat_position",
5385                 FT_BYTES, BASE_HEX, NULL, 0x0,
5386         "Reserved", HFILL }},
5387
5388
5389     { &hf_afp_map_name_type,
5390       { "Type",      "afp.map_name_type",
5391                 FT_UINT8, BASE_DEC, VALS(map_name_type_vals), 0x0,
5392         "Map name type", HFILL }},
5393
5394     { &hf_afp_map_id_type,
5395       { "Type",      "afp.map_id_type",
5396                 FT_UINT8, BASE_DEC, VALS(map_id_type_vals), 0x0,
5397         "Map ID type", HFILL }},
5398
5399     { &hf_afp_map_id,
5400       { "ID",             "afp.map_id",
5401                 FT_UINT32, BASE_DEC, NULL, 0x0,
5402         "User/Group ID", HFILL }},
5403
5404     { &hf_afp_map_name,
5405       { "Name",             "afp.map_name",
5406                 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
5407         "User/Group name", HFILL }},
5408
5409     /* AFP 3.0 */
5410     { &hf_afp_lock_offset64,
5411       { "Offset",         "afp.lock_offset64",
5412                 FT_INT64, BASE_DEC, NULL, 0x0,
5413         "First byte to be locked (64 bits)", HFILL }},
5414
5415     { &hf_afp_lock_len64,
5416       { "Length",         "afp.lock_len64",
5417                 FT_INT64, BASE_DEC, NULL, 0x0,
5418         "Number of bytes to be locked/unlocked (64 bits)", HFILL }},
5419
5420     { &hf_afp_lock_range_start64,
5421       { "Start",         "afp.lock_range_start64",
5422                 FT_INT64, BASE_DEC, NULL, 0x0,
5423         "First byte locked/unlocked (64 bits)", HFILL }},
5424
5425     { &hf_afp_offset64,
5426       { "Offset",         "afp.offset64",
5427                 FT_INT64, BASE_DEC, NULL, 0x0,
5428         "Offset (64 bits)", HFILL }},
5429
5430     { &hf_afp_rw_count64,
5431       { "Count",         "afp.rw_count64",
5432                 FT_INT64, BASE_DEC, NULL, 0x0,
5433         "Number of bytes to be read/written (64 bits)", HFILL }},
5434
5435     { &hf_afp_last_written64,
5436       { "Last written",  "afp.last_written64",
5437                 FT_UINT64, BASE_DEC, NULL, 0x0,
5438         "Offset of the last byte written (64 bits)", HFILL }},
5439
5440     { &hf_afp_ofork_len64,
5441       { "New length",         "afp.ofork_len64",
5442                 FT_INT64, BASE_DEC, NULL, 0x0,
5443         "New length (64 bits)", HFILL }},
5444
5445     { &hf_afp_session_token_type,
5446       { "Type",         "afp.session_token_type",
5447                 FT_UINT16, BASE_HEX, VALS(token_type_vals), 0x0,
5448         "Session token type", HFILL }},
5449
5450     /* FIXME FT_UINT32 in specs */
5451     { &hf_afp_session_token_len,
5452       { "Len",         "afp.session_token_len",
5453                 FT_UINT32, BASE_DEC, NULL, 0x0,
5454         "Session token length", HFILL }},
5455
5456     { &hf_afp_session_token_timestamp,
5457       { "Time stamp",         "afp.session_token_timestamp",
5458                 FT_UINT32, BASE_HEX, NULL, 0x0,
5459         "Session time stamp", HFILL }},
5460
5461     { &hf_afp_session_token,
5462       { "Token",         "afp.session_token",
5463                 FT_BYTES, BASE_HEX, NULL, 0x0,
5464         "Session token", HFILL }},
5465
5466     { &hf_afp_user_flag,
5467       { "Flag",         "afp.user_flag",
5468                 FT_UINT8, BASE_HEX, VALS(user_flag_vals), 0x01,
5469         "User Info flag", HFILL }},
5470
5471     { &hf_afp_user_ID,
5472       { "User ID",         "afp.user_ID",
5473                 FT_UINT32, BASE_DEC, NULL, 0x0,
5474         "User ID", HFILL }},
5475
5476     { &hf_afp_group_ID,
5477       { "Group ID",         "afp.group_ID",
5478                 FT_UINT32, BASE_DEC, NULL, 0x0,
5479         "Group ID", HFILL }},
5480
5481     { &hf_afp_UUID,
5482       { "UUID",         "afp.uuid",
5483                 FT_BYTES, BASE_HEX, NULL, 0x0,
5484         "UUID", HFILL }},
5485
5486     { &hf_afp_GRPUUID,
5487       { "GRPUUID",         "afp.grpuuid",
5488                 FT_BYTES, BASE_HEX, NULL, 0x0,
5489         "Group UUID", HFILL }},
5490
5491     { &hf_afp_user_bitmap,
5492       { "Bitmap",         "afp.user_bitmap",
5493                 FT_UINT16, BASE_HEX, NULL, 0,
5494         "User Info bitmap", HFILL }},
5495
5496     { &hf_afp_user_bitmap_UID,
5497       { "User ID",         "afp.user_bitmap.UID",
5498                 FT_BOOLEAN, 16, NULL, 0x01,
5499         "User ID", HFILL }},
5500
5501     { &hf_afp_user_bitmap_GID,
5502       { "Primary group ID",         "afp.user_bitmap.GID",
5503                 FT_BOOLEAN, 16, NULL, 0x02,
5504         "Primary group ID", HFILL }},
5505
5506     { &hf_afp_user_bitmap_UUID,
5507       { "UUID",         "afp.user_bitmap.UUID",
5508                 FT_BOOLEAN, 16, NULL, 0x04,
5509         "UUID", HFILL }},
5510
5511     { &hf_afp_message_type,
5512       { "Type",         "afp.message_type",
5513                 FT_UINT16, BASE_HEX, VALS(server_message_type), 0,
5514         "Type of server message", HFILL }},
5515
5516     { &hf_afp_message_bitmap,
5517       { "Bitmap",         "afp.message_bitmap",
5518                 FT_UINT16, BASE_HEX, NULL, 0,
5519         "Message bitmap", HFILL }},
5520
5521     { &hf_afp_message_bitmap_REQ,
5522       { "Request message",         "afp.message_bitmap.requested",
5523                 FT_BOOLEAN, 16, NULL, 0x01,
5524         "Message Requested", HFILL }},
5525
5526     { &hf_afp_message_bitmap_UTF,
5527       { "Message is UTF8",         "afp.message_bitmap.utf8",
5528                 FT_BOOLEAN, 16, NULL, 0x02,
5529         "Message is UTF8", HFILL }},
5530
5531     { &hf_afp_message_len,
5532       { "Len",         "afp.message_length",
5533                 FT_UINT32, BASE_DEC, NULL, 0x0,
5534         "Message length", HFILL }},
5535
5536     { &hf_afp_message,
5537       { "Message",  "afp.message",
5538                 FT_STRING, BASE_NONE, NULL, 0x0,
5539         "Message", HFILL }},
5540
5541     { &hf_afp_reqcount64,
5542       { "Count",         "afp.reqcount64",
5543                 FT_INT64, BASE_DEC, NULL, 0x0,
5544         "Request Count (64 bits)", HFILL }},
5545
5546     { &hf_afp_extattr_bitmap,
5547       { "Bitmap",         "afp.extattr_bitmap",
5548                 FT_UINT16, BASE_HEX, NULL, 0,
5549         "Extended attributes bitmap", HFILL }},
5550
5551     { &hf_afp_extattr_bitmap_NoFollow,
5552       { "No follow symlinks",         "afp.extattr_bitmap.nofollow",
5553                 FT_BOOLEAN, 16, NULL, 0x01,
5554         "Do not follow symlink", HFILL }},
5555
5556     { &hf_afp_extattr_bitmap_Create,
5557       { "Create",         "afp.extattr_bitmap.create",
5558                 FT_BOOLEAN, 16, NULL, 0x02,
5559         "Create extended attribute", HFILL }},
5560
5561     { &hf_afp_extattr_bitmap_Replace,
5562       { "Replace",         "afp.extattr_bitmap.replace",
5563                 FT_BOOLEAN, 16, NULL, 0x04,
5564         "Replace extended attribute", HFILL }},
5565
5566     { &hf_afp_extattr_namelen,
5567       { "Length",         "afp.extattr.namelen",
5568                 FT_UINT16, BASE_DEC, NULL, 0x0,
5569         "Extended attribute name length", HFILL }},
5570
5571     { &hf_afp_extattr_name,
5572       { "Name",             "afp.extattr.name",
5573                 FT_STRING, BASE_NONE, NULL, 0x0,
5574         "Extended attribute name", HFILL }},
5575
5576     { &hf_afp_extattr_len,
5577       { "Length",         "afp.extattr.len",
5578                 FT_UINT32, BASE_DEC, NULL, 0x0,
5579         "Extended attribute length", HFILL }},
5580
5581     { &hf_afp_extattr_data,
5582       { "Data",         "afp.extattr.data",
5583                 FT_BYTES, BASE_HEX, NULL, 0x0,
5584         "Extendend attribute data", HFILL }},
5585
5586     { &hf_afp_extattr_req_count,
5587       { "Request Count",         "afp.extattr.req_count",
5588                 FT_UINT16, BASE_DEC, NULL, 0x0,
5589         "Request Count.", HFILL }},
5590
5591     { &hf_afp_extattr_start_index,
5592       { "Index",         "afp.extattr.start_index",
5593                 FT_UINT32, BASE_DEC, NULL, 0x0,
5594         "Start index", HFILL }},
5595
5596     { &hf_afp_extattr_reply_size,
5597       { "Reply size",         "afp.extattr.reply_size",
5598                 FT_UINT32, BASE_DEC, NULL, 0x0,
5599         "Reply size", HFILL }},
5600
5601         /* ACL control list bitmap */
5602     { &hf_afp_access_bitmap,
5603       { "Bitmap",         "afp.access_bitmap",
5604                 FT_UINT16, BASE_HEX, NULL, 0,
5605         "Bitmap (reserved)", HFILL }},
5606
5607     { &hf_afp_acl_list_bitmap,
5608       { "ACL bitmap",         "afp.acl_list_bitmap",
5609                 FT_UINT16, BASE_HEX, NULL, 0,
5610         "ACL control list bitmap", HFILL }},
5611
5612     { &hf_afp_acl_list_bitmap_UUID,
5613       { "UUID",         "afp.acl_list_bitmap.UUID",
5614                 FT_BOOLEAN, 16, NULL, kFileSec_UUID,
5615         "User UUID", HFILL }},
5616
5617     { &hf_afp_acl_list_bitmap_GRPUUID,
5618       { "GRPUUID",         "afp.acl_list_bitmap.GRPUUID",
5619                 FT_BOOLEAN, 16, NULL, kFileSec_GRPUUID,
5620         "Group UUID", HFILL }},
5621
5622     { &hf_afp_acl_list_bitmap_ACL,
5623       { "ACL",         "afp.acl_list_bitmap.ACL",
5624                 FT_BOOLEAN, 16, NULL, kFileSec_ACL,
5625         "ACL", HFILL }},
5626
5627     { &hf_afp_acl_list_bitmap_REMOVEACL,
5628       { "Remove ACL",         "afp.acl_list_bitmap.REMOVEACL",
5629                 FT_BOOLEAN, 16, NULL, kFileSec_REMOVEACL,
5630         "Remove ACL", HFILL }},
5631
5632     { &hf_afp_acl_list_bitmap_Inherit,
5633       { "Inherit",         "afp.acl_list_bitmap.Inherit",
5634                 FT_BOOLEAN, 16, NULL, kFileSec_Inherit,
5635         "Inherit ACL", HFILL }},
5636
5637     { &hf_afp_acl_entrycount,
5638       { "Count",         "afp.acl_entrycount",
5639                 FT_UINT32, BASE_HEX, NULL, 0,
5640         "Number of ACL entries", HFILL }},
5641
5642     { &hf_afp_acl_flags,
5643       { "ACL flags",         "afp.acl_flags",
5644                 FT_UINT32, BASE_HEX, NULL, 0,
5645         "ACL flags", HFILL }},
5646
5647     { &hf_afp_ace_applicable,
5648       { "ACE",         "afp.ace_applicable",
5649                 FT_BYTES, BASE_HEX, NULL, 0x0,
5650         "ACE applicable", HFILL }},
5651
5652     { &hf_afp_ace_rights,
5653       { "Rights",         "afp.ace_rights",
5654                 FT_UINT32, BASE_HEX, NULL, 0,
5655         "ACE flags", HFILL }},
5656
5657     { &hf_afp_acl_access_bitmap,
5658       { "Bitmap",         "afp.acl_access_bitmap",
5659                 FT_UINT32, BASE_HEX, NULL, 0,
5660         "ACL access bitmap", HFILL }},
5661
5662     { &hf_afp_acl_access_bitmap_read_data,
5663       { "Read/List",         "afp.acl_access_bitmap.read_data",
5664                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_READ_DATA,
5665         "Read data / list directory", HFILL }},
5666
5667     { &hf_afp_acl_access_bitmap_write_data,
5668       { "Write/Add file",         "afp.acl_access_bitmap.write_data",
5669                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_WRITE_DATA,
5670         "Write data to a file / add a file to a directory", HFILL }},
5671
5672     { &hf_afp_acl_access_bitmap_execute,
5673       { "Execute/Search",         "afp.acl_access_bitmap.execute",
5674                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_EXECUTE,
5675         "Execute a program", HFILL }},
5676
5677     { &hf_afp_acl_access_bitmap_delete,
5678       { "Delete",         "afp.acl_access_bitmap.delete",
5679                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_DELETE,
5680         "Delete", HFILL }},
5681
5682     { &hf_afp_acl_access_bitmap_append_data,
5683       { "Append data/create subdir",         "afp.acl_access_bitmap.append_data",
5684                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_APPEND_DATA,
5685         "Append data to a file / create a subdirectory", HFILL }},
5686
5687     { &hf_afp_acl_access_bitmap_delete_child,
5688       { "Delete dir",         "afp.acl_access_bitmap.delete_child",
5689                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_DELETE_CHILD,
5690         "Delete directory", HFILL }},
5691
5692     { &hf_afp_acl_access_bitmap_read_attrs,
5693       { "Read attributes",         "afp.acl_access_bitmap.read_attrs",
5694                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_READ_ATTRIBUTES,
5695         "Read attributes", HFILL }},
5696
5697     { &hf_afp_acl_access_bitmap_write_attrs,
5698       { "Write attributes",         "afp.acl_access_bitmap.write_attrs",
5699                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_WRITE_ATTRIBUTES,
5700         "Write attributes", HFILL }},
5701
5702     { &hf_afp_acl_access_bitmap_read_extattrs,
5703       { "Read extended attributes", "afp.acl_access_bitmap.read_extattrs",
5704                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_READ_EXTATTRIBUTES,
5705         "Read extended attributes", HFILL }},
5706
5707     { &hf_afp_acl_access_bitmap_write_extattrs,
5708       { "Write extended attributes", "afp.acl_access_bitmap.write_extattrs",
5709                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_WRITE_EXTATTRIBUTES,
5710         "Write extended attributes", HFILL }},
5711
5712     { &hf_afp_acl_access_bitmap_read_security,
5713       { "Read security",         "afp.acl_access_bitmap.read_security",
5714                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_READ_SECURITY,
5715         "Read access rights", HFILL }},
5716
5717     { &hf_afp_acl_access_bitmap_write_security,
5718       { "Write security",         "afp.acl_access_bitmap.write_security",
5719                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_WRITE_SECURITY,
5720         "Write access rights", HFILL }},
5721
5722     { &hf_afp_acl_access_bitmap_change_owner,
5723       { "Change owner",         "afp.acl_access_bitmap.change_owner",
5724                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_CHANGE_OWNER,
5725         "Change owner", HFILL }},
5726
5727     { &hf_afp_acl_access_bitmap_synchronize,
5728       { "Synchronize",         "afp.acl_access_bitmap.synchronize",
5729                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_SYNCHRONIZE,
5730         "Synchronize", HFILL }},
5731
5732     { &hf_afp_acl_access_bitmap_generic_all,
5733       { "Generic all",         "afp.acl_access_bitmap.generic_all",
5734                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_GENERIC_ALL,
5735         "Generic all", HFILL }},
5736
5737     { &hf_afp_acl_access_bitmap_generic_execute,
5738       { "Generic execute",         "afp.acl_access_bitmap.generic_execute",
5739                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_GENERIC_EXECUTE,
5740         "Generic execute", HFILL }},
5741
5742     { &hf_afp_acl_access_bitmap_generic_write,
5743       { "Generic write",         "afp.acl_access_bitmap.generic_write",
5744                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_GENERIC_WRITE,
5745         "Generic write", HFILL }},
5746
5747     { &hf_afp_acl_access_bitmap_generic_read,
5748       { "Generic read",         "afp.acl_access_bitmap.generic_read",
5749                 FT_BOOLEAN, 32, NULL, KAUTH_VNODE_GENERIC_READ,
5750         "Generic read", HFILL }},
5751
5752     { &hf_afp_ace_flags,
5753       { "Flags",         "afp.ace_flags",
5754                 FT_UINT32, BASE_HEX, NULL, 0,
5755         "ACE flags", HFILL }},
5756
5757     { &hf_afp_ace_flags_allow,
5758       { "Allow",         "afp.ace_flags.allow",
5759                 FT_BOOLEAN, 32, NULL, ACE_ALLOW,
5760         "Allow rule", HFILL }},
5761
5762     { &hf_afp_ace_flags_deny,
5763       { "Deny",         "afp.ace_flags.deny",
5764                 FT_BOOLEAN, 32, NULL, ACE_DENY,
5765         "Deny rule", HFILL }},
5766
5767     { &hf_afp_ace_flags_inherited,
5768       { "Inherited",         "afp.ace_flags.inherited",
5769                 FT_BOOLEAN, 32, NULL, ACE_INHERITED,
5770         "Inherited", HFILL }},
5771
5772     { &hf_afp_ace_flags_fileinherit,
5773       { "File inherit",         "afp.ace_flags.file_inherit",
5774                 FT_BOOLEAN, 32, NULL, ACE_FILE_INHERIT,
5775         "File inherit", HFILL }},
5776
5777     { &hf_afp_ace_flags_dirinherit,
5778       { "Dir inherit",         "afp.ace_flags.directory_inherit",
5779                 FT_BOOLEAN, 32, NULL, ACE_DIR_INHERIT,
5780         "Dir inherit", HFILL }},
5781
5782     { &hf_afp_ace_flags_limitinherit,
5783       { "Limit inherit",         "afp.ace_flags.limit_inherit",
5784                 FT_BOOLEAN, 32, NULL, ACE_LIMIT_INHERIT,
5785         "Limit inherit", HFILL }},
5786
5787     { &hf_afp_ace_flags_onlyinherit,
5788       { "Only inherit",         "afp.ace_flags.only_inherit",
5789                 FT_BOOLEAN, 32, NULL, ACE_ONLY_INHERIT,
5790         "Only inherit", HFILL }},
5791   };
5792
5793   static gint *ett[] = {
5794         &ett_afp,
5795         &ett_afp_server_vol,
5796         &ett_afp_vol_list,
5797         &ett_afp_vol_flag,
5798         &ett_afp_vol_bitmap,
5799         &ett_afp_vol_attribute,
5800         &ett_afp_dir_bitmap,
5801         &ett_afp_file_bitmap,
5802         &ett_afp_unix_privs,
5803         &ett_afp_enumerate,
5804         &ett_afp_enumerate_line,
5805         &ett_afp_access_mode,
5806         &ett_afp_dir_attribute,
5807         &ett_afp_file_attribute,
5808         &ett_afp_path_name,
5809         &ett_afp_lock_flags,
5810         &ett_afp_dir_ar,
5811         &ett_afp_cat_search,
5812         &ett_afp_cat_r_bitmap,
5813         &ett_afp_cat_spec,
5814         &ett_afp_vol_did,
5815         &ett_afp_user_bitmap,
5816         &ett_afp_message_bitmap,
5817         &ett_afp_extattr_bitmap,
5818         &ett_afp_extattr_names,
5819         &ett_afp_acl_list_bitmap,
5820         &ett_afp_acl_access_bitmap,
5821         &ett_afp_ace_entries,
5822         &ett_afp_ace_entry,
5823         &ett_afp_ace_flags,
5824   };
5825
5826   proto_afp = proto_register_protocol("Apple Filing Protocol", "AFP", "afp");
5827   proto_register_field_array(proto_afp, hf, array_length(hf));
5828   proto_register_subtree_array(ett, array_length(ett));
5829
5830   register_init_routine(afp_reinit);
5831
5832   register_dissector("afp", dissect_afp, proto_afp);
5833   data_handle = find_dissector("data");
5834
5835   afp_tap = register_tap("afp");
5836 }
5837
5838 void
5839 proto_reg_handoff_afp(void)
5840 {
5841   data_handle = find_dissector("data");
5842 }
5843
5844 /* -------------------------------
5845    end
5846 */