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