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