2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
5 * $Id: packet-atalk.c,v 1.91 2003/11/16 23:17:16 guy Exp $
7 * Simon Wilkinson <sxw@dcs.ed.ac.uk>
9 * Ethereal - Network traffic analyzer
10 * By Gerald Combs <gerald@ethereal.com>
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
33 #include <epan/packet.h>
39 #include "arcnet_pids.h"
40 #include <epan/atalk-utils.h>
41 #include <epan/conversation.h>
44 #include "reassemble.h"
46 #include "packet-afp.h"
48 /* Tables for reassembly of fragments. */
49 static GHashTable *atp_fragment_table = NULL;
50 static GHashTable *atp_reassembled_table = NULL;
52 /* desegmentation of ATP */
53 static gboolean atp_defragment = TRUE;
55 static dissector_handle_t afp_handle;
57 static int proto_llap = -1;
58 static int hf_llap_dst = -1;
59 static int hf_llap_src = -1;
60 static int hf_llap_type = -1;
62 static int proto_ddp = -1;
63 static int hf_ddp_hopcount = -1;
64 static int hf_ddp_len = -1;
65 static int hf_ddp_checksum = -1;
66 static int hf_ddp_dst = -1;
67 static int hf_ddp_dst_net = -1;
68 static int hf_ddp_src = -1;
69 static int hf_ddp_src_net = -1;
70 static int hf_ddp_dst_node = -1;
71 static int hf_ddp_src_node = -1;
72 static int hf_ddp_dst_socket = -1;
73 static int hf_ddp_src_socket = -1;
74 static int hf_ddp_type = -1;
76 static dissector_handle_t ddp_handle;
78 /* --------------------------------------
79 * ATP protocol parameters
80 * from netatalk/include/atalk/atp.h
82 #define ATP_MAXDATA (578+4) /* maximum ATP data size */
83 #define ATP_BUFSIZ 587 /* maximum packet size */
84 #define ATP_HDRSIZE 5 /* includes DDP type field */
86 #define ATP_TRELMASK 0x07 /* mask all but TREL */
87 #define ATP_RELTIME 30 /* base release timer (in secs) */
89 #define ATP_TREL30 0x0 /* release time codes */
90 #define ATP_TREL1M 0x1 /* these are passed in flags of */
91 #define ATP_TREL2M 0x2 /* atp_sreq call, and set in the */
92 #define ATP_TREL4M 0x3 /* packet control info. */
93 #define ATP_TREL8M 0x4
95 /* flags for ATP options (and control byte)
97 #define ATP_XO 0x20 /* (1<<5) eXactly Once mode */
98 #define ATP_EOM 0x10 /* (1<<4) End Of Message */
99 #define ATP_STS 0x08 /* (1<<3) Transaction Status */
103 #define ATP_FUNCMASK (3<<6) /* mask all but function */
105 #define ATP_TREQ 1 /* (1<<6) Trans. REQuest */
106 #define ATP_TRESP 2 /* (2<<6) Trans. RESPonse */
107 #define ATP_TREL 3 /* (3<<6) Trans. RELease */
109 /* ------------------------- */
110 static dissector_handle_t asp_handle;
112 static int proto_atp = -1;
113 static int hf_atp_ctrlinfo = -1; /* guint8_t control information */
114 static int hf_atp_function = -1; /* bits 7,6 function */
115 static int hf_atp_xo = -1; /* bit 5 exactly-once */
116 static int hf_atp_eom = -1; /* bit 4 end-of-message */
117 static int hf_atp_sts = -1; /* bit 3 send transaction status */
118 static int hf_atp_treltimer = -1; /* bits 2,1,0 TRel timeout indicator */
120 static int hf_atp_bitmap = -1; /* guint8_t bitmap or sequence number */
121 static int hf_atp_tid = -1; /* guint16_t transaction id. */
122 static int hf_atp_user_bytes = -1;
124 static int hf_atp_segments = -1;
125 static int hf_atp_segment = -1;
126 static int hf_atp_segment_overlap = -1;
127 static int hf_atp_segment_overlap_conflict = -1;
128 static int hf_atp_segment_multiple_tails = -1;
129 static int hf_atp_segment_too_long_segment = -1;
130 static int hf_atp_segment_error = -1;
131 static int hf_atp_reassembled_in = -1;
133 /* ------------------------- */
134 static int proto_zip = -1;
135 static dissector_handle_t zip_atp_handle;
137 static int hf_zip_function = -1;
138 static int hf_zip_atp_function = -1;
139 static int hf_zip_start_index = -1;
140 static int hf_zip_count = -1;
141 static int hf_zip_zero_value = -1;
143 static int hf_zip_network_count = -1;
144 static int hf_zip_network = -1;
145 static int hf_zip_network_start = -1;
146 static int hf_zip_network_end = -1;
148 static int hf_zip_flags = -1;
150 static int hf_zip_flags_zone_invalid = -1;
151 static int hf_zip_flags_use_broadcast = -1;
152 static int hf_zip_flags_only_one_zone = -1;
154 static int hf_zip_last_flag = -1;
156 static int hf_zip_zone_name = -1;
157 static int hf_zip_default_zone = -1;
159 static int hf_zip_multicast_length = -1;
160 static int hf_zip_multicast_address = -1;
162 static const value_string zip_function_vals[] = {
165 {5, "GetNetInfo request"},
166 {6, "GetNetInfo reply"},
168 {8, "Extended reply"},
172 static const value_string zip_atp_function_vals[] = {
175 {9, "GetLocalZones"},
179 static gint ett_zip = -1;
180 static gint ett_zip_flags = -1;
181 static gint ett_zip_zones_list = -1;
182 static gint ett_zip_network_list = -1;
184 /* --------------------------------
185 * from netatalk/include/atalk/ats.h
188 #define ASPFUNC_CLOSE 1
189 #define ASPFUNC_CMD 2
190 #define ASPFUNC_STAT 3
191 #define ASPFUNC_OPEN 4
192 #define ASPFUNC_TICKLE 5
193 #define ASPFUNC_WRITE 6
194 #define ASPFUNC_WRTCONT 7
195 #define ASPFUNC_ATTN 8
198 #define ASPERR_OK 0x0000
199 #define ASPERR_BADVERS 0xfbd6
200 #define ASPERR_BUFSMALL 0xfbd5
201 #define ASPERR_NOSESS 0xfbd4
202 #define ASPERR_NOSERV 0xfbd3
203 #define ASPERR_PARM 0xfbd2
204 #define ASPERR_SERVBUSY 0xfbd1
205 #define ASPERR_SESSCLOS 0xfbd0
206 #define ASPERR_SIZERR 0xfbcf
207 #define ASPERR_TOOMANY 0xfbce
208 #define ASPERR_NOACK 0xfbcd
210 static int proto_asp = -1;
211 static int hf_asp_func = -1;
212 static int hf_asp_error = -1;
213 static int hf_asp_socket = -1;
214 static int hf_asp_version = -1;
215 static int hf_asp_session_id = -1;
216 static int hf_asp_zero_value = -1;
217 static int hf_asp_init_error = -1;
218 static int hf_asp_attn_code = -1;
219 static int hf_asp_seq = -1;
220 static int hf_asp_size = -1;
222 /* status stuff same for asp and afp */
223 static int hf_asp_server_name = -1;
224 static int hf_asp_server_type = -1;
225 static int hf_asp_server_vers = -1;
226 static int hf_asp_server_uams = -1;
227 static int hf_asp_server_icon = -1;
228 static int hf_asp_server_directory = -1;
230 static int hf_asp_server_flag = -1;
231 static int hf_asp_server_flag_copyfile = -1;
232 static int hf_asp_server_flag_passwd = -1;
233 static int hf_asp_server_flag_no_save_passwd = -1;
234 static int hf_asp_server_flag_srv_msg = -1;
235 static int hf_asp_server_flag_srv_sig = -1;
236 static int hf_asp_server_flag_tcpip = -1;
237 static int hf_asp_server_flag_notify = -1;
238 static int hf_asp_server_flag_reconnect = -1;
239 static int hf_asp_server_flag_directory = -1;
240 static int hf_asp_server_flag_utf8_name = -1;
241 static int hf_asp_server_flag_fast_copy = -1;
242 static int hf_asp_server_signature = -1;
243 static int hf_asp_server_utf8_name_len = -1;
244 static int hf_asp_server_utf8_name = -1;
246 static int hf_asp_server_addr_len = -1;
247 static int hf_asp_server_addr_type = -1;
248 static int hf_asp_server_addr_value = -1;
250 static gint ett_asp_status = -1;
251 static gint ett_asp_uams = -1;
252 static gint ett_asp_vers = -1;
253 static gint ett_asp_addr = -1;
254 static gint ett_asp_addr_line = -1;
255 static gint ett_asp_directory = -1;
256 static gint ett_asp_status_server_flag = -1;
258 static guint asp_packet_init_count = 200;
261 guint32 conversation;
267 guint8 value; /* command for asp, bitmap for atp */
270 static GHashTable *asp_request_hash = NULL;
271 static GMemChunk *asp_request_keys = NULL;
272 static GMemChunk *asp_request_vals = NULL;
275 static gint asp_equal (gconstpointer v, gconstpointer v2)
277 const asp_request_key *val1 = (const asp_request_key*)v;
278 const asp_request_key *val2 = (const asp_request_key*)v2;
280 if (val1->conversation == val2->conversation &&
281 val1->seq == val2->seq &&
282 !memcmp(val1->src, val2->src, 4)) {
288 static guint asp_hash (gconstpointer v)
290 const asp_request_key *asp_key = (const asp_request_key*)v;
294 /* ------------------------------------ */
295 static GHashTable *atp_request_hash = NULL;
296 static GMemChunk *atp_request_keys = NULL;
297 static GMemChunk *atp_request_vals = NULL;
300 /* ------------------------------------ */
301 static int proto_nbp = -1;
302 static int hf_nbp_op = -1;
303 static int hf_nbp_info = -1;
304 static int hf_nbp_count = -1;
305 static int hf_nbp_tid = -1;
307 static int hf_nbp_node_net = -1;
308 static int hf_nbp_node_port = -1;
309 static int hf_nbp_node_node = -1;
310 static int hf_nbp_node_enum = -1;
311 static int hf_nbp_node_object = -1;
312 static int hf_nbp_node_type = -1;
313 static int hf_nbp_node_zone = -1;
315 static int proto_rtmp = -1;
316 static int hf_rtmp_net = -1;
317 static int hf_rtmp_node_len = -1;
318 static int hf_rtmp_node = -1;
319 static int hf_rtmp_tuple_net = -1;
320 static int hf_rtmp_tuple_range_start = -1;
321 static int hf_rtmp_tuple_range_end = -1;
322 static int hf_rtmp_tuple_dist = -1;
323 static int hf_rtmp_function = -1;
325 static gint ett_atp = -1;
327 static gint ett_atp_segments = -1;
328 static gint ett_atp_segment = -1;
329 static gint ett_atp_info = -1;
330 static gint ett_asp = -1;
332 static gint ett_nbp = -1;
333 static gint ett_nbp_info = -1;
334 static gint ett_nbp_node = -1;
335 static gint ett_rtmp = -1;
336 static gint ett_rtmp_tuple = -1;
337 static gint ett_ddp = -1;
338 static gint ett_llap = -1;
339 static gint ett_pstring = -1;
341 static const fragment_items atp_frag_items = {
346 &hf_atp_segment_overlap,
347 &hf_atp_segment_overlap_conflict,
348 &hf_atp_segment_multiple_tails,
349 &hf_atp_segment_too_long_segment,
350 &hf_atp_segment_error,
351 &hf_atp_reassembled_in,
355 static dissector_table_t ddp_dissector_table;
357 static dissector_handle_t data_handle;
359 #define DDP_SHORT_HEADER_SIZE 5
362 * P = Padding, H = Hops, L = Len
366 * Assumes the argument is in host byte order.
368 #define ddp_hops(x) ( ( x >> 10) & 0x3C )
369 #define ddp_len(x) ( x & 0x03ff )
370 typedef struct _e_ddp {
371 guint16 hops_len; /* combines pad, hops, and len */
372 guint16 sum,dnet,snet;
378 #define DDP_HEADER_SIZE 13
381 static const value_string op_vals[] = {
382 {DDP_RTMPDATA, "AppleTalk Routing Table response or data" },
383 {DDP_NBP, "AppleTalk Name Binding Protocol packet"},
384 {DDP_ATP, "AppleTalk Transaction Protocol packet"},
385 {DDP_AEP, "AppleTalk Echo Protocol packet"},
386 {DDP_RTMPREQ, "AppleTalk Routing Table request"},
387 {DDP_ZIP, "AppleTalk Zone Information Protocol packet"},
388 {DDP_ADSP, "AppleTalk Data Stream Protocol"},
389 {DDP_EIGRP, "Cisco EIGRP for AppleTalk"},
393 static const value_string rtmp_function_vals[] = {
395 {2, "Route Data Request (split horizon processed)"},
396 {3, "Route Data Request (no split horizon processing)"},
400 #define NBP_BROADCAST 1
402 #define NBP_FORWARD 4
405 static const value_string nbp_op_vals[] = {
406 {NBP_BROADCAST, "broadcast request"},
407 {NBP_LOOKUP, "lookup"},
408 {NBP_FORWARD, "forward request"},
409 {NBP_REPLY, "reply"},
413 static const value_string atp_function_vals[] = {
414 {ATP_TREQ ,"REQuest"},
415 {ATP_TRESP ,"RESPonse"},
416 {ATP_TREL ,"RELease"},
420 static const value_string atp_trel_timer_vals[] = {
431 static const value_string asp_func_vals[] = {
432 {ASPFUNC_CLOSE, "CloseSession" },
433 {ASPFUNC_CMD, "Command" },
434 {ASPFUNC_STAT, "GetStatus" },
435 {ASPFUNC_OPEN, "OpenSession" },
436 {ASPFUNC_TICKLE, "Tickle" },
437 {ASPFUNC_WRITE, "Write" },
438 {ASPFUNC_WRTCONT, "Write Cont" },
439 {ASPFUNC_ATTN, "Attention" },
442 const value_string asp_error_vals[] = {
443 {AFP_OK , "success"},
444 {AFPERR_ACCESS , "permission denied" },
445 {AFPERR_AUTHCONT , "logincont" },
446 {AFPERR_BADUAM , "uam doesn't exist" },
447 {AFPERR_BADVERS , "bad afp version number" },
448 {AFPERR_BITMAP , "invalid bitmap" },
449 {AFPERR_CANTMOVE , "can't move file" },
450 {AFPERR_DENYCONF , "file synchronization locks conflict" },
451 {AFPERR_DIRNEMPT , "directory not empty" },
452 {AFPERR_DFULL , "disk full" },
453 {AFPERR_EOF , "end of file" },
454 {AFPERR_BUSY , "FileBusy" },
455 {AFPERR_FLATVOL , "volume doesn't support directories" },
456 {AFPERR_NOITEM , "ItemNotFound" },
457 {AFPERR_LOCK , "LockErr" },
458 {AFPERR_MISC , "misc. err" },
459 {AFPERR_NLOCK , "no more locks" },
460 {AFPERR_NOSRVR , "no response by server at that address" },
461 {AFPERR_EXIST , "object already exists" },
462 {AFPERR_NOOBJ , "object not found" },
463 {AFPERR_PARAM , "parameter error" },
464 {AFPERR_NORANGE , "no range lock" },
465 {AFPERR_RANGEOVR , "range overlap" },
466 {AFPERR_SESSCLOS , "session closed" },
467 {AFPERR_NOTAUTH , "user not authenticated" },
468 {AFPERR_NOOP , "command not supported" },
469 {AFPERR_BADTYPE , "object is the wrong type" },
470 {AFPERR_NFILE , "too many files open" },
471 {AFPERR_SHUTDOWN , "server is going down" },
472 {AFPERR_NORENAME , "can't rename" },
473 {AFPERR_NODIR , "couldn't find directory" },
474 {AFPERR_ITYPE , "wrong icon type" },
475 {AFPERR_VLOCK , "volume locked" },
476 {AFPERR_OLOCK , "object locked" },
477 {AFPERR_CTNSHRD , "share point contains a share point" },
478 {AFPERR_NOID , "file thread not found" },
479 {AFPERR_EXISTID , "file already has an id" },
480 {AFPERR_DIFFVOL , "different volume" },
481 {AFPERR_CATCHNG , "catalog has changed" },
482 {AFPERR_SAMEOBJ , "source file == destination file" },
483 {AFPERR_BADID , "non-existent file id" },
484 {AFPERR_PWDSAME , "same password/can't change password" },
485 {AFPERR_PWDSHORT , "password too short" },
486 {AFPERR_PWDEXPR , "password expired" },
487 {AFPERR_INSHRD , "folder being shared is inside a shared folder." },
488 {AFPERR_INTRASH , "shared folder in trash." },
489 {AFPERR_PWDCHNG , "password needs to be changed" },
490 {AFPERR_PWDPOLCY , "password fails policy check" },
491 {AFPERR_USRLOGIN , "user already logged on" },
495 * XXX - do this with an FT_UINT_STRING?
496 * Unfortunately, you can't extract from an FT_UINT_STRING the string,
497 * which we'd want to do in order to put it into the "Data:" portion.
499 * Are these always in the Mac extended character set?
501 static int dissect_pascal_string(tvbuff_t *tvb, int offset, proto_tree *tree,
506 len = tvb_get_guint8(tvb, offset);
516 * XXX - if we could do this inside the protocol tree
517 * code, we could perhaps avoid allocating and freeing
518 * this string buffer.
520 tmp = g_malloc( len+1 );
521 tvb_memcpy(tvb, tmp, offset, len);
523 item = proto_tree_add_string(tree, hf_index, tvb, offset-1, len+1, tmp);
525 subtree = proto_item_add_subtree(item, ett_pstring);
526 proto_tree_add_text(subtree, tvb, offset-1, 1, "Length: %d", len);
527 proto_tree_add_text(subtree, tvb, offset, len, "Data: %s", tmp);
537 dissect_rtmp_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
538 proto_tree *rtmp_tree;
542 if (check_col(pinfo->cinfo, COL_PROTOCOL))
543 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
544 if (check_col(pinfo->cinfo, COL_INFO))
545 col_clear(pinfo->cinfo, COL_INFO);
547 function = tvb_get_guint8(tvb, 0);
549 if (check_col(pinfo->cinfo, COL_INFO))
550 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
551 val_to_str(function, rtmp_function_vals, "Unknown function (%02x)"));
554 ti = proto_tree_add_item(tree, proto_rtmp, tvb, 0, 1, FALSE);
555 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
557 proto_tree_add_uint(rtmp_tree, hf_rtmp_function, tvb, 0, 1, function);
562 dissect_rtmp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
563 proto_tree *rtmp_tree;
567 guint8 nodelen,nodelen_bits;
568 guint16 node; /* might be more than 8 bits */
571 if (check_col(pinfo->cinfo, COL_PROTOCOL))
572 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
573 if (check_col(pinfo->cinfo, COL_INFO))
574 col_clear(pinfo->cinfo, COL_INFO);
576 net = tvb_get_ntohs(tvb, offset);
577 nodelen_bits = tvb_get_guint8(tvb, offset+2);
578 if ( nodelen_bits <= 8 ) {
579 node = tvb_get_guint8(tvb, offset)+1;
582 node = tvb_get_ntohs(tvb, offset);
586 if (check_col(pinfo->cinfo, COL_INFO))
587 col_add_fstr(pinfo->cinfo, COL_INFO, "Net: %u Node Len: %u Node: %u",
588 net, nodelen_bits, node);
591 ti = proto_tree_add_item(tree, proto_rtmp, tvb, offset, -1, FALSE);
592 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
594 proto_tree_add_uint(rtmp_tree, hf_rtmp_net, tvb, offset, 2, net);
595 proto_tree_add_uint(rtmp_tree, hf_rtmp_node_len, tvb, offset+2, 1,
597 proto_tree_add_uint(rtmp_tree, hf_rtmp_node, tvb, offset+3, nodelen,
599 offset += 3 + nodelen;
602 while (tvb_offset_exists(tvb, offset)) {
603 proto_tree *tuple_item, *tuple_tree;
606 guint16 tuple_range_end;
608 tuple_net = tvb_get_ntohs(tvb, offset);
609 tuple_dist = tvb_get_guint8(tvb, offset+2);
611 if (tuple_dist & 0x80) {
612 tuple_range_end = tvb_get_ntohs(tvb, offset+3);
613 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 6,
614 "Tuple %d: Range Start: %u Dist: %u Range End: %u",
615 i, tuple_net, tuple_dist&0x7F, tuple_range_end);
617 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 3,
618 "Tuple %d: Net: %u Dist: %u",
619 i, tuple_net, tuple_dist);
621 tuple_tree = proto_item_add_subtree(tuple_item, ett_rtmp_tuple);
623 if (tuple_dist & 0x80) {
624 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_range_start, tvb, offset, 2,
627 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_net, tvb, offset, 2,
630 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_dist, tvb, offset+2, 1,
633 if (tuple_dist & 0x80) {
635 * Extended network tuple.
637 proto_tree_add_item(tuple_tree, hf_rtmp_tuple_range_end, tvb, offset+3, 2,
649 dissect_nbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
650 proto_tree *nbp_tree;
651 proto_tree *nbp_info_tree;
652 proto_item *ti, *info_item;
658 if (check_col(pinfo->cinfo, COL_PROTOCOL))
659 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBP");
660 if (check_col(pinfo->cinfo, COL_INFO))
661 col_clear(pinfo->cinfo, COL_INFO);
663 info = tvb_get_guint8(tvb, offset);
667 if (check_col(pinfo->cinfo, COL_INFO))
668 col_add_fstr(pinfo->cinfo, COL_INFO, "Op: %s Count: %u",
669 val_to_str(op, nbp_op_vals, "Unknown (0x%01x)"), count);
672 ti = proto_tree_add_item(tree, proto_nbp, tvb, offset, -1, FALSE);
673 nbp_tree = proto_item_add_subtree(ti, ett_nbp);
675 info_item = proto_tree_add_uint_format(nbp_tree, hf_nbp_info, tvb, offset, 1,
677 "Info: 0x%01X Operation: %s Count: %u", info,
678 val_to_str(op, nbp_op_vals, "Unknown (0x%01X)"),
680 nbp_info_tree = proto_item_add_subtree(info_item, ett_nbp_info);
681 proto_tree_add_uint(nbp_info_tree, hf_nbp_op, tvb, offset, 1, info);
682 proto_tree_add_uint(nbp_info_tree, hf_nbp_count, tvb, offset, 1, info);
683 proto_tree_add_item(nbp_tree, hf_nbp_tid, tvb, offset+1, 1, FALSE);
686 for (i=0; i<count; i++) {
687 proto_tree *node_item,*node_tree;
688 int soffset = offset;
690 node_item = proto_tree_add_text(nbp_tree, tvb, offset, -1,
692 node_tree = proto_item_add_subtree(node_item, ett_nbp_node);
694 proto_tree_add_item(node_tree, hf_nbp_node_net, tvb, offset, 2, FALSE);
696 proto_tree_add_item(node_tree, hf_nbp_node_node, tvb, offset, 1, FALSE);
698 proto_tree_add_item(node_tree, hf_nbp_node_port, tvb, offset, 1, FALSE);
700 proto_tree_add_item(node_tree, hf_nbp_node_enum, tvb, offset, 1, FALSE);
703 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_object);
704 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_type);
705 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_zone);
707 proto_item_set_len(node_item, offset-soffset);
714 /* -----------------------------
715 ATP protocol cf. inside appletalk chap. 9
716 desegmentation from packet-ieee80211.c
719 dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
720 proto_tree *atp_tree = NULL;
722 proto_tree *atp_info_tree;
723 proto_item *info_item;
726 guint8 frag_number = 0;
730 struct aspinfo aspinfo;
731 tvbuff_t *new_tvb = NULL;
732 gboolean save_fragmented;
733 gboolean more_fragment = FALSE;
738 conversation_t *conversation;
739 asp_request_key request_key, *new_request_key;
740 asp_request_val *request_val;
742 if (check_col(pinfo->cinfo, COL_PROTOCOL))
743 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
745 ctrlinfo = tvb_get_guint8(tvb, offset);
746 bitmap = tvb_get_guint8(tvb, offset +1);
747 tid = tvb_get_ntohs(tvb, offset +2);
757 aspinfo.reply = (0x80 == (ctrlinfo & ATP_FUNCMASK))?1:0;
758 aspinfo.release = (0xC0 == (ctrlinfo & ATP_FUNCMASK))?1:0;
761 query = (!aspinfo.reply && !aspinfo.release);
763 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
764 pinfo->srcport, pinfo->destport, 0);
766 if (conversation == NULL)
768 conversation = conversation_new(&pinfo->src, &pinfo->dst,
769 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
772 request_key.conversation = conversation->index;
773 memcpy(request_key.src, (!aspinfo.reply)?pinfo->src.data:pinfo->dst.data, 4);
774 request_key.seq = aspinfo.seq;
776 request_val = (asp_request_val *) g_hash_table_lookup(atp_request_hash, &request_key);
778 if (!request_val && query ) {
779 new_request_key = g_mem_chunk_alloc(atp_request_keys);
780 *new_request_key = request_key;
782 request_val = g_mem_chunk_alloc(atp_request_vals);
783 request_val->value = nbe;
785 g_hash_table_insert(atp_request_hash, new_request_key,request_val);
789 ATP_EOM is not mandatory. Some implementations don't always set it
790 if the query is only one packet.
792 So it needs to keep the number of packets asked in request.
796 more_fragment = !((ATP_EOM & ctrlinfo) || (request_val && 1 == request_val->value));
797 frag_number = bitmap;
800 if (check_col(pinfo->cinfo, COL_INFO)) {
801 col_clear(pinfo->cinfo, COL_INFO);
802 col_add_fstr(pinfo->cinfo, COL_INFO, "%s transaction %u",
803 val_to_str(op, atp_function_vals, "Unknown (0x%01x)"),tid);
805 col_append_fstr(pinfo->cinfo, COL_INFO, " [fragment]");
809 ti = proto_tree_add_item(tree, proto_atp, tvb, offset, -1, FALSE);
810 atp_tree = proto_item_add_subtree(ti, ett_atp);
811 proto_item_set_len(atp_tree, aspinfo.release?8:ATP_HDRSIZE -1);
813 info_item = proto_tree_add_item(atp_tree, hf_atp_ctrlinfo, tvb, offset, 1, FALSE);
814 atp_info_tree = proto_item_add_subtree(info_item, ett_atp_info);
816 proto_tree_add_item(atp_info_tree, hf_atp_function, tvb, offset, 1, FALSE);
817 proto_tree_add_item(atp_info_tree, hf_atp_xo, tvb, offset, 1, FALSE);
818 proto_tree_add_item(atp_info_tree, hf_atp_eom, tvb, offset, 1, FALSE);
819 proto_tree_add_item(atp_info_tree, hf_atp_sts, tvb, offset, 1, FALSE);
820 if ((ctrlinfo & (ATP_FUNCMASK|ATP_XO)) == (0x40|ATP_XO)) {
821 /* TReq with XO set */
822 proto_tree_add_item(atp_info_tree, hf_atp_treltimer, tvb, offset, 1, FALSE);
825 proto_tree_add_text(atp_tree, tvb, offset +1, 1,
826 "Bitmap: 0x%02x %u packet(s) max", bitmap, nbe);
829 proto_tree_add_item(atp_tree, hf_atp_bitmap, tvb, offset +1, 1, FALSE);
831 proto_tree_add_item(atp_tree, hf_atp_tid, tvb, offset +2, 2, FALSE);
834 proto_tree_add_item(atp_tree, hf_atp_user_bytes, tvb, offset +4, 4, FALSE);
841 save_fragmented = pinfo->fragmented;
844 asp doesn't fit very well here
845 move asp back in atp?
847 if (atp_defragment && aspinfo.reply && (more_fragment || frag_number != 0)) {
848 fragment_data *fd_head;
851 hdr = ATP_HDRSIZE -1;
852 if (frag_number != 0)
853 hdr += 4; /* asp header */
854 len = tvb_reported_length_remaining(tvb, hdr);
855 fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid,
857 atp_reassembled_table,
861 new_tvb = process_reassembled_data(tvb, ATP_HDRSIZE -1, pinfo,
862 "Reassembled ATP", fd_head, &atp_frag_items,
867 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1,- 1);
871 pinfo->private_data = &aspinfo;
872 /* if port == 6 it's not an ASP packet but a ZIP packet */
873 if (pinfo->srcport == 6 || pinfo->destport == 6 )
874 call_dissector(zip_atp_handle, new_tvb, pinfo, tree);
876 call_dissector(asp_handle, new_tvb, pinfo, tree);
879 /* Just show this as a fragment. */
880 new_tvb = tvb_new_subset (tvb, ATP_HDRSIZE -1, -1, -1);
881 call_dissector(data_handle, new_tvb, pinfo, tree);
883 pinfo->fragmented = save_fragmented;
888 copy and paste from dsi
891 dissect_asp_reply_get_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
893 proto_tree *sub_tree;
899 guint16 sign_ofs = 0;
910 ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
911 tree = proto_item_add_subtree(ti, ett_asp_status);
913 machine_ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
914 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %u", machine_ofs);
916 machine_ofs += offset;
918 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
919 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %u", ofs);
921 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
922 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %u", ofs);
924 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
925 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %u", ofs);
927 ofs = offset +AFPSTATUS_FLAGOFF;
928 ti = proto_tree_add_item(tree, hf_asp_server_flag, tvb, ofs, 2, FALSE);
929 sub_tree = proto_item_add_subtree(ti, ett_asp_status_server_flag);
930 proto_tree_add_item(sub_tree, hf_asp_server_flag_copyfile , tvb, ofs, 2, FALSE);
931 proto_tree_add_item(sub_tree, hf_asp_server_flag_passwd , tvb, ofs, 2, FALSE);
932 proto_tree_add_item(sub_tree, hf_asp_server_flag_no_save_passwd, tvb, ofs, 2, FALSE);
933 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_msg , tvb, ofs, 2, FALSE);
934 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_sig , tvb, ofs, 2, FALSE);
935 proto_tree_add_item(sub_tree, hf_asp_server_flag_tcpip , tvb, ofs, 2, FALSE);
936 proto_tree_add_item(sub_tree, hf_asp_server_flag_notify , tvb, ofs, 2, FALSE);
937 proto_tree_add_item(sub_tree, hf_asp_server_flag_reconnect , tvb, ofs, 2, FALSE);
938 proto_tree_add_item(sub_tree, hf_asp_server_flag_directory , tvb, ofs, 2, FALSE);
939 proto_tree_add_item(sub_tree, hf_asp_server_flag_utf8_name , tvb, ofs, 2, FALSE);
940 proto_tree_add_item(sub_tree, hf_asp_server_flag_fast_copy , tvb, ofs, 2, FALSE);
942 proto_tree_add_item(tree, hf_asp_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, FALSE);
944 flag = tvb_get_ntohs(tvb, ofs);
945 if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
946 ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
950 sign_ofs = tvb_get_ntohs(tvb, ofs);
951 proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %u", sign_ofs);
955 if ((flag & AFPSRVRINFO_TCPIP) && ofs < machine_ofs ) {
956 adr_ofs = tvb_get_ntohs(tvb, ofs);
957 proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %u", adr_ofs);
962 if ((flag & AFPSRVRINFO_SRVDIRECTORY) && ofs < machine_ofs) {
963 dir_ofs = tvb_get_ntohs(tvb, ofs);
964 proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %u", dir_ofs);
969 if ((flag & AFPSRVRINFO_SRVUTF8) && ofs < machine_ofs) {
970 utf_ofs = tvb_get_ntohs(tvb, ofs);
971 proto_tree_add_text(tree, tvb, ofs, 2, "UTF-8 Server name offset: %u", utf_ofs);
977 proto_tree_add_item(tree, hf_asp_server_type, tvb, machine_ofs, 1, FALSE);
979 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
981 nbe = tvb_get_guint8(tvb, ofs);
982 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %u", nbe);
984 sub_tree = proto_item_add_subtree(ti, ett_asp_vers);
985 for (i = 0; i < nbe; i++) {
986 len = tvb_get_guint8(tvb, ofs) +1;
987 proto_tree_add_item(sub_tree, hf_asp_server_vers, tvb, ofs, 1, FALSE);
992 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
994 nbe = tvb_get_guint8(tvb, ofs);
995 ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %u", nbe);
997 sub_tree = proto_item_add_subtree(ti, ett_asp_uams);
998 for (i = 0; i < nbe; i++) {
999 len = tvb_get_guint8(tvb, ofs) +1;
1000 proto_tree_add_item(sub_tree, hf_asp_server_uams, tvb, ofs, 1, FALSE);
1005 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1007 proto_tree_add_item(tree, hf_asp_server_icon, tvb, ofs, 256, FALSE);
1010 proto_tree_add_item(tree, hf_asp_server_signature, tvb, sign_ofs, 16, FALSE);
1014 proto_tree *adr_tree;
1022 nbe = tvb_get_guint8(tvb, ofs);
1023 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %u", nbe);
1025 adr_tree = proto_item_add_subtree(ti, ett_asp_addr);
1026 for (i = 0; i < nbe; i++) {
1029 len = tvb_get_guint8(tvb, ofs);
1030 type = tvb_get_guint8(tvb, ofs +1);
1033 ip = tvb_get_ptr(tvb, ofs+2, 4);
1034 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", ip_to_str(ip));
1036 case 2: /* IP + port */
1037 ip = tvb_get_ptr(tvb, ofs+2, 4);
1038 port = tvb_get_ntohs(tvb, ofs+6);
1039 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%u",ip_to_str(ip),port);
1041 case 3: /* DDP, atalk_addr_to_str want host order not network */
1042 net = tvb_get_ntohs(tvb, ofs+2);
1043 node = tvb_get_guint8(tvb, ofs +4);
1044 port = tvb_get_guint8(tvb, ofs +5);
1045 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
1048 case 5: /* IP + port ssh tunnel */
1049 ip = tvb_get_ptr(tvb, ofs+2, 4);
1050 port = tvb_get_ntohs(tvb, ofs+6);
1051 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip (ssh tunnel) %s:%u",ip_to_str(ip),port);
1055 tmp = g_malloc( len -1);
1056 tvb_memcpy(tvb, tmp, ofs +2, len -2);
1058 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
1062 /* else fall to default malformed record */
1064 ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknow type : %u", type);
1068 sub_tree = proto_item_add_subtree(ti,ett_asp_addr_line);
1069 proto_tree_add_item(sub_tree, hf_asp_server_addr_len, tvb, ofs, 1, FALSE);
1071 proto_tree_add_item(sub_tree, hf_asp_server_addr_type, tvb, ofs, 1, FALSE);
1073 proto_tree_add_item(sub_tree, hf_asp_server_addr_value,tvb, ofs, len, FALSE);
1080 nbe = tvb_get_guint8(tvb, ofs);
1081 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %u", nbe);
1083 sub_tree = proto_item_add_subtree(ti, ett_asp_directory);
1084 for (i = 0; i < nbe; i++) {
1085 len = tvb_get_guint8(tvb, ofs) +1;
1086 proto_tree_add_item(sub_tree, hf_asp_server_directory, tvb, ofs, 1, FALSE);
1092 len = tvb_get_ntohs(tvb, ofs);
1093 proto_tree_add_item(tree, hf_asp_server_utf8_name_len, tvb, ofs, 2, FALSE);
1095 proto_tree_add_item(tree, hf_asp_server_utf8_name, tvb, ofs, len, FALSE);
1098 /* FIXME: offset is not updated */
1102 /* -----------------------------
1103 ASP protocol cf. inside appletalk chap. 11
1105 static struct aspinfo *
1106 get_transaction(tvbuff_t *tvb, packet_info *pinfo)
1108 struct aspinfo *aspinfo = pinfo->private_data;
1109 conversation_t *conversation;
1110 asp_request_key request_key, *new_request_key;
1111 asp_request_val *request_val;
1114 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
1115 pinfo->srcport, pinfo->destport, 0);
1117 if (conversation == NULL)
1119 conversation = conversation_new(&pinfo->src, &pinfo->dst,
1120 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1123 request_key.conversation = conversation->index;
1124 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
1125 request_key.seq = aspinfo->seq;
1127 request_val = (asp_request_val *) g_hash_table_lookup(
1128 asp_request_hash, &request_key);
1129 if (!request_val && !aspinfo->reply ) {
1130 fn = tvb_get_guint8(tvb, 0);
1131 new_request_key = g_mem_chunk_alloc(asp_request_keys);
1132 *new_request_key = request_key;
1134 request_val = g_mem_chunk_alloc(asp_request_vals);
1135 request_val->value = fn;
1137 g_hash_table_insert(asp_request_hash, new_request_key,
1144 aspinfo->command = request_val->value;
1150 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1152 struct aspinfo *aspinfo;
1154 proto_tree *asp_tree = NULL;
1159 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1160 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1161 if (check_col(pinfo->cinfo, COL_INFO))
1162 col_clear(pinfo->cinfo, COL_INFO);
1164 aspinfo = get_transaction(tvb, pinfo);
1168 fn = aspinfo->command;
1170 if (check_col(pinfo->cinfo, COL_INFO)) {
1172 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1174 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1175 val_to_str(fn, asp_func_vals, "Unknown (0x%01x)"), aspinfo->seq);
1179 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, FALSE);
1180 asp_tree = proto_item_add_subtree(ti, ett_asp);
1182 if (!aspinfo->reply) {
1184 /* let the called deal with asp_tree == NULL */
1186 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, FALSE);
1190 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1192 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, FALSE);
1195 case ASPFUNC_TICKLE:
1197 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1199 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1203 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1205 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1209 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1211 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, FALSE);
1216 proto_item_set_len(asp_tree, 4);
1217 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1219 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1221 len = tvb_reported_length_remaining(tvb,offset);
1222 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1223 call_dissector(afp_handle, new_tvb, pinfo, tree);
1225 case ASPFUNC_WRTCONT:
1226 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1228 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1230 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, FALSE);
1234 proto_item_set_len(asp_tree, 4);
1236 len = tvb_reported_length_remaining(tvb,offset);
1237 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1244 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1247 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1249 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1251 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, FALSE);
1255 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1257 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1259 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1263 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1265 dissect_asp_reply_get_status(tvb, pinfo, asp_tree, offset);
1269 proto_item_set_len(asp_tree, 4);
1270 aspinfo->code = tvb_get_ntohl(tvb, offset);
1271 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, FALSE);
1273 len = tvb_reported_length_remaining(tvb,offset);
1274 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1275 call_dissector(afp_handle, new_tvb, pinfo, tree);
1277 case ASPFUNC_TICKLE:
1278 case ASPFUNC_WRTCONT:
1279 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1281 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1283 proto_item_set_len(asp_tree, 4);
1285 len = tvb_reported_length_remaining(tvb,offset);
1286 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1292 /* -----------------------------
1293 ZIP protocol cf. inside appletalk chap. 8
1296 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1298 struct aspinfo *aspinfo;
1300 proto_tree *zip_tree;
1301 proto_tree *sub_tree;
1307 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1308 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1309 if (check_col(pinfo->cinfo, COL_INFO))
1310 col_clear(pinfo->cinfo, COL_INFO);
1312 aspinfo = get_transaction(tvb, pinfo);
1316 fn = aspinfo->command;
1318 if (check_col(pinfo->cinfo, COL_INFO)) {
1320 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1322 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1323 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1329 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, FALSE);
1330 zip_tree = proto_item_add_subtree(ti, ett_zip);
1332 if (!aspinfo->reply) {
1333 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, FALSE);
1336 case 7: /* start_index = 0 */
1339 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1341 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, FALSE);
1348 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1353 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, FALSE);
1356 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1358 count = tvb_get_ntohs(tvb, offset);
1359 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, FALSE);
1361 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1362 for (i= 1; i <= count; i++) {
1363 len = tvb_get_guint8(tvb, offset);
1364 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1373 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1375 proto_tree *zip_tree = NULL;
1380 proto_tree *flag_tree;
1381 proto_tree *sub_tree;
1382 proto_tree *net_tree;
1388 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1389 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1390 if (check_col(pinfo->cinfo, COL_INFO))
1391 col_clear(pinfo->cinfo, COL_INFO);
1393 fn = tvb_get_guint8(tvb, 0);
1394 if (check_col(pinfo->cinfo, COL_INFO)) {
1395 col_add_str(pinfo->cinfo, COL_INFO,
1396 val_to_str(fn, zip_function_vals, "Unknown ZIP function (%02x)"));
1402 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, FALSE);
1403 zip_tree = proto_item_add_subtree(ti, ett_zip);
1405 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,FALSE);
1407 /* fn 1,7,2,8 are not tested */
1410 count = tvb_get_guint8(tvb, offset);
1411 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1413 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1414 for (i= 1; i <= count; i++) {
1415 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, FALSE);
1419 case 7: /* Notify */
1420 flag = tvb_get_guint8(tvb, offset);
1421 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1422 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1423 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1424 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1425 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1428 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1431 len = tvb_get_guint8(tvb, offset);
1432 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1435 len = tvb_get_guint8(tvb, offset);
1436 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1438 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1441 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1445 case 8: /* Extended Reply */
1446 count = tvb_get_guint8(tvb, offset);
1447 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1449 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1450 for (i= 1; i <= count; i++) {
1451 net = tvb_get_ntohs(tvb, offset);
1452 ti = proto_tree_add_text(zip_tree, tvb, offset , 2, "Zone for network : %u", net);
1453 net_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1454 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, FALSE);
1456 len = tvb_get_guint8(tvb, offset);
1457 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1462 case 5 : /* GetNetInfo request */
1463 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1465 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1467 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1470 case 6 : /* GetNetInfo reply */
1471 flag = tvb_get_guint8(tvb, offset);
1472 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1473 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1474 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1475 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1476 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1479 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, FALSE);
1482 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, FALSE);
1485 len = tvb_get_guint8(tvb, offset);
1486 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1489 len = tvb_get_guint8(tvb, offset);
1490 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1492 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1494 if ((flag & 0x80) != 0)
1495 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,FALSE);
1504 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, guint8 dnode,
1505 guint8 snode, proto_tree *tree)
1511 proto_tree *ddp_tree = NULL;
1513 static struct atalk_ddp_addr src, dst;
1516 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1517 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1518 if (check_col(pinfo->cinfo, COL_INFO))
1519 col_clear(pinfo->cinfo, COL_INFO);
1522 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1524 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1526 len = tvb_get_ntohs(tvb, 0);
1528 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1529 dport = tvb_get_guint8(tvb, 2);
1531 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1532 sport = tvb_get_guint8(tvb, 3);
1534 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1535 type = tvb_get_guint8(tvb, 4);
1541 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1542 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1543 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1544 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1546 pinfo->ptype = PT_DDP;
1547 pinfo->destport = dport;
1548 pinfo->srcport = sport;
1550 if (check_col(pinfo->cinfo, COL_INFO)) {
1551 col_add_str(pinfo->cinfo, COL_INFO,
1552 val_to_str(type, op_vals, "Unknown DDP protocol (%02x)"));
1555 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1556 4, 3, atalk_addr_to_str(&src));
1557 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1558 6, 3, atalk_addr_to_str(&dst));
1560 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1562 new_tvb = tvb_new_subset(tvb, DDP_SHORT_HEADER_SIZE, -1, -1);
1564 if (!dissector_try_port(ddp_dissector_table, type, new_tvb, pinfo, tree))
1565 call_dissector(data_handle,new_tvb, pinfo, tree);
1569 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1572 proto_tree *ddp_tree;
1574 static struct atalk_ddp_addr src, dst;
1577 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1578 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1579 if (check_col(pinfo->cinfo, COL_INFO))
1580 col_clear(pinfo->cinfo, COL_INFO);
1582 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1583 ddp.dnet=g_ntohs(ddp.dnet);
1584 ddp.snet=g_ntohs(ddp.snet);
1585 ddp.sum=g_ntohs(ddp.sum);
1586 ddp.hops_len=g_ntohs(ddp.hops_len);
1589 src.node = ddp.snode;
1591 dst.node = ddp.dnode;
1592 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1593 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1594 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1595 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1597 pinfo->ptype = PT_DDP;
1598 pinfo->destport = ddp.dport;
1599 pinfo->srcport = ddp.sport;
1601 if (check_col(pinfo->cinfo, COL_INFO))
1602 col_add_str(pinfo->cinfo, COL_INFO,
1603 val_to_str(ddp.type, op_vals, "Unknown DDP protocol (%02x)"));
1606 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1608 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1610 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1611 4, 3, atalk_addr_to_str(&src));
1612 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1613 6, 3, atalk_addr_to_str(&dst));
1615 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1616 ddp_hops(ddp.hops_len));
1617 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1618 ddp_len(ddp.hops_len));
1619 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1621 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1623 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1625 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1627 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1629 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1631 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1633 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1637 new_tvb = tvb_new_subset(tvb, DDP_HEADER_SIZE, -1, -1);
1639 if (!dissector_try_port(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1640 call_dissector(data_handle,new_tvb, pinfo, tree);
1643 static const value_string llap_type_vals[] = {
1644 {0x01, "Short DDP"},
1647 {0x82, "Acknowledgement"},
1654 capture_llap(packet_counts *ld)
1660 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1665 proto_tree *llap_tree = NULL;
1669 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1670 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1671 if (check_col(pinfo->cinfo, COL_INFO))
1672 col_clear(pinfo->cinfo, COL_INFO);
1675 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, FALSE);
1676 llap_tree = proto_item_add_subtree(ti, ett_llap);
1679 dnode = tvb_get_guint8(tvb, 0);
1681 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, dnode);
1682 snode = tvb_get_guint8(tvb, 1);
1684 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, snode);
1685 type = tvb_get_guint8(tvb, 2);
1686 if (check_col(pinfo->cinfo, COL_INFO)) {
1687 col_add_str(pinfo->cinfo, COL_INFO,
1688 val_to_str(type, llap_type_vals, "Unknown LLAP type (%02x)"));
1691 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1693 new_tvb = tvb_new_subset(tvb, 3, -1, -1);
1698 if (proto_is_protocol_enabled(find_protocol_by_id(proto_ddp))) {
1699 pinfo->current_proto = "DDP";
1700 dissect_ddp_short(new_tvb, pinfo, dnode, snode, tree);
1705 if (call_dissector(ddp_handle, new_tvb, pinfo, tree))
1708 call_dissector(data_handle,new_tvb, pinfo, tree);
1715 fragment_table_init(&atp_fragment_table);
1716 reassembled_table_init(&atp_reassembled_table);
1718 if (atp_request_hash)
1719 g_hash_table_destroy(atp_request_hash);
1720 if (atp_request_keys)
1721 g_mem_chunk_destroy(atp_request_keys);
1722 if (atp_request_vals)
1723 g_mem_chunk_destroy(atp_request_vals);
1725 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1727 atp_request_keys = g_mem_chunk_new("atp_request_keys",
1728 sizeof(asp_request_key),
1729 asp_packet_init_count * sizeof(asp_request_key),
1731 atp_request_vals = g_mem_chunk_new("atp_request_vals",
1732 sizeof(asp_request_val),
1733 asp_packet_init_count * sizeof(asp_request_val),
1741 if (asp_request_hash)
1742 g_hash_table_destroy(asp_request_hash);
1743 if (asp_request_keys)
1744 g_mem_chunk_destroy(asp_request_keys);
1745 if (asp_request_vals)
1746 g_mem_chunk_destroy(asp_request_vals);
1748 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1750 asp_request_keys = g_mem_chunk_new("asp_request_keys",
1751 sizeof(asp_request_key),
1752 asp_packet_init_count * sizeof(asp_request_key),
1754 asp_request_vals = g_mem_chunk_new("asp_request_vals",
1755 sizeof(asp_request_val),
1756 asp_packet_init_count * sizeof(asp_request_val),
1762 proto_register_atalk(void)
1764 static hf_register_info hf_llap[] = {
1766 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1770 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1774 { "Type", "llap.type", FT_UINT8, BASE_HEX, VALS(llap_type_vals), 0x0,
1778 static hf_register_info hf_ddp[] = {
1780 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1784 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1788 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1792 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1796 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1800 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1804 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1808 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1812 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1815 { &hf_ddp_dst_socket,
1816 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1819 { &hf_ddp_src_socket,
1820 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1824 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC, VALS(op_vals), 0x0,
1828 static hf_register_info hf_nbp[] = {
1830 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1831 VALS(nbp_op_vals), 0xF0, "Operation", HFILL }},
1833 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1834 NULL, 0x0, "Info", HFILL }},
1836 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1837 NULL, 0x0F, "Count", HFILL }},
1839 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1840 NULL, 0x0, "Network", HFILL }},
1841 { &hf_nbp_node_node,
1842 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1843 NULL, 0x0, "Node", HFILL }},
1844 { &hf_nbp_node_port,
1845 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1846 NULL, 0x0, "Port", HFILL }},
1847 { &hf_nbp_node_enum,
1848 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1849 NULL, 0x0, "Enumerator", HFILL }},
1850 { &hf_nbp_node_object,
1851 { "Object", "nbp.object", FT_STRING, BASE_DEC,
1852 NULL, 0x0, "Object", HFILL }},
1853 { &hf_nbp_node_type,
1854 { "Type", "nbp.type", FT_STRING, BASE_DEC,
1855 NULL, 0x0, "Type", HFILL }},
1856 { &hf_nbp_node_zone,
1857 { "Zone", "nbp.zone", FT_STRING, BASE_DEC,
1858 NULL, 0x0, "Zone", HFILL }},
1860 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1861 NULL, 0x0, "Transaction ID", HFILL }}
1864 static hf_register_info hf_rtmp[] = {
1866 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1867 NULL, 0x0, "Net", HFILL }},
1869 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1870 NULL, 0x0, "Node", HFILL }},
1871 { &hf_rtmp_node_len,
1872 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1873 NULL, 0x0, "Node Length", HFILL }},
1874 { &hf_rtmp_tuple_net,
1875 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1876 NULL, 0x0, "Net", HFILL }},
1877 { &hf_rtmp_tuple_range_start,
1878 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
1879 NULL, 0x0, "Range Start", HFILL }},
1880 { &hf_rtmp_tuple_range_end,
1881 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
1882 NULL, 0x0, "Range End", HFILL }},
1883 { &hf_rtmp_tuple_dist,
1884 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
1885 NULL, 0x0, "Distance", HFILL }},
1886 { &hf_rtmp_function,
1887 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
1888 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
1891 static hf_register_info hf_atp[] = {
1893 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
1894 NULL, 0, "control info", HFILL }},
1897 { "Function", "atp.function", FT_UINT8, BASE_DEC,
1898 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
1902 { "XO", "atp.xo", FT_BOOLEAN, 8,
1903 NULL, ATP_XO, "Exactly-once flag", HFILL }},
1906 { "EOM", "atp.eom", FT_BOOLEAN, 8,
1907 NULL, ATP_EOM, "End-of-message", HFILL }},
1910 { "STS", "atp.sts", FT_BOOLEAN, 8,
1911 NULL, ATP_STS, "Send transaction status", HFILL }},
1913 { &hf_atp_treltimer,
1914 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
1915 VALS(atp_trel_timer_vals), 0x07, "TRel timer", HFILL }},
1918 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
1919 NULL, 0x0, "Bitmap or sequence number", HFILL }},
1922 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
1923 NULL, 0x0, "Transaction id", HFILL }},
1924 { &hf_atp_user_bytes,
1925 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
1926 NULL, 0x0, "User bytes", HFILL }},
1928 { &hf_atp_segment_overlap,
1929 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
1930 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
1932 { &hf_atp_segment_overlap_conflict,
1933 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
1934 FT_BOOLEAN, BASE_NONE,
1935 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
1937 { &hf_atp_segment_multiple_tails,
1938 { "Multiple tail segments found", "atp.segment.multipletails",
1939 FT_BOOLEAN, BASE_NONE,
1940 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
1942 { &hf_atp_segment_too_long_segment,
1943 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
1944 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
1946 { &hf_atp_segment_error,
1947 {"Desegmentation error", "atp.segment.error", FT_FRAMENUM, BASE_NONE,
1948 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
1951 { "ATP Fragment", "atp.fragment", FT_FRAMENUM, BASE_NONE,
1952 NULL, 0x0, "ATP Fragment", HFILL }},
1955 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
1956 NULL, 0x0, "ATP Fragments", HFILL }},
1958 { &hf_atp_reassembled_in,
1959 { "Reassembled ATP in frame", "atp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1960 "This ATP packet is reassembled in this frame", HFILL }}
1963 static hf_register_info hf_asp[] = {
1965 { "asp function", "asp.function", FT_UINT8, BASE_DEC,
1966 VALS(asp_func_vals), 0, "asp function", HFILL }},
1969 { "asp error", "asp.error", FT_INT32, BASE_DEC,
1970 VALS(asp_error_vals), 0, "return error code", HFILL }},
1973 { "Version", "asp.version", FT_UINT16, BASE_HEX,
1974 NULL, 0, "asp version", HFILL }},
1976 { &hf_asp_attn_code,
1977 { "Attn code", "asp.attn_code", FT_UINT16, BASE_HEX,
1978 NULL, 0, "asp attention code", HFILL }},
1980 { &hf_asp_init_error,
1981 { "Error", "asp.init_error", FT_UINT16, BASE_DEC,
1982 NULL, 0, "asp init error", HFILL }},
1984 { &hf_asp_session_id,
1985 { "Session ID", "asp.session_id", FT_UINT8, BASE_DEC,
1986 NULL, 0, "asp session id", HFILL }},
1989 { "Socket", "asp.socket", FT_UINT8, BASE_DEC,
1990 NULL, 0, "asp socket", HFILL }},
1993 { "Sequence", "asp.seq", FT_UINT16, BASE_DEC,
1994 NULL, 0, "asp sequence number", HFILL }},
1997 { "size", "asp.size", FT_UINT16, BASE_DEC,
1998 NULL, 0, "asp available size for reply", HFILL }},
2000 { &hf_asp_zero_value,
2001 { "Pad (0)", "asp.zero_value",
2002 FT_BYTES, BASE_HEX, NULL, 0x0,
2006 { &hf_asp_server_name,
2007 { "Server name", "asp.server_name",
2008 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2009 "Server name", HFILL }},
2011 { &hf_asp_server_type,
2012 { "Server type", "asp.server_type",
2013 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2014 "Server type", HFILL }},
2016 { &hf_asp_server_vers,
2017 { "AFP version", "asp.server_vers",
2018 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2019 "AFP version", HFILL }},
2021 { &hf_asp_server_uams,
2022 { "UAM", "asp.server_uams",
2023 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2026 { &hf_asp_server_icon,
2027 { "Icon bitmap", "asp.server_icon",
2028 FT_BYTES, BASE_HEX, NULL, 0x0,
2029 "Server icon bitmap", HFILL }},
2031 { &hf_asp_server_directory,
2032 { "Directory service", "asp.server_directory",
2033 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2034 "Server directory service", HFILL }},
2036 { &hf_asp_server_signature,
2037 { "Server signature", "asp.server_signature",
2038 FT_BYTES, BASE_HEX, NULL, 0x0,
2039 "Server signature", HFILL }},
2041 { &hf_asp_server_flag,
2042 { "Flag", "asp.server_flag",
2043 FT_UINT16, BASE_HEX, NULL, 0x0,
2044 "Server capabilities flag", HFILL }},
2045 { &hf_asp_server_flag_copyfile,
2046 { "Support copyfile", "asp.server_flag.copyfile",
2047 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_COPY,
2048 "Server support copyfile", HFILL }},
2049 { &hf_asp_server_flag_passwd,
2050 { "Support change password", "asp.server_flag.passwd",
2051 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_PASSWD,
2052 "Server support change password", HFILL }},
2053 { &hf_asp_server_flag_no_save_passwd,
2054 { "Don't allow save password", "asp.server_flag.no_save_passwd",
2055 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_NOSAVEPASSWD,
2056 "Don't allow save password", HFILL }},
2057 { &hf_asp_server_flag_srv_msg,
2058 { "Support server message", "asp.server_flag.srv_msg",
2059 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVMSGS,
2060 "Support server message", HFILL }},
2061 { &hf_asp_server_flag_srv_sig,
2062 { "Support server signature", "asp.server_flag.srv_sig",
2063 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVSIGNATURE,
2064 "Support server signature", HFILL }},
2065 { &hf_asp_server_flag_tcpip,
2066 { "Support TCP/IP", "asp.server_flag.tcpip",
2067 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_TCPIP,
2068 "Server support TCP/IP", HFILL }},
2069 { &hf_asp_server_flag_notify,
2070 { "Support server notifications", "asp.server_flag.notify",
2071 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVNOTIFY,
2072 "Server support notifications", HFILL }},
2073 { &hf_asp_server_flag_reconnect,
2074 { "Support server reconnect", "asp.server_flag.reconnect",
2075 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVRECONNECT,
2076 "Server support reconnect", HFILL }},
2077 { &hf_asp_server_flag_directory,
2078 { "Support directory services", "asp.server_flag.directory",
2079 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVDIRECTORY,
2080 "Server support directory services", HFILL }},
2081 { &hf_asp_server_flag_utf8_name,
2082 { "Support UTF8 server name", "asp.server_flag.utf8_name",
2083 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVUTF8,
2084 "Server support UTF8 server name", HFILL }},
2085 { &hf_asp_server_flag_fast_copy,
2086 { "Support fast copy", "asp.server_flag.fast_copy",
2087 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_FASTBOZO,
2088 "Server support fast copy", HFILL }},
2090 { &hf_asp_server_addr_len,
2091 { "Length", "asp.server_addr.len",
2092 FT_UINT8, BASE_DEC, NULL, 0x0,
2093 "Address length.", HFILL }},
2095 { &hf_asp_server_addr_type,
2096 { "Type", "asp.server_addr.type",
2097 FT_UINT8, BASE_DEC, VALS(afp_server_addr_type_vals), 0x0,
2098 "Address type.", HFILL }},
2100 { &hf_asp_server_addr_value,
2101 { "Value", "asp.server_addr.value",
2102 FT_BYTES, BASE_HEX, NULL, 0x0,
2103 "Address value", HFILL }},
2105 { &hf_asp_server_utf8_name_len,
2106 { "Server name length", "asp.server_utf8_name_len",
2107 FT_UINT16, BASE_DEC, NULL, 0x0,
2108 "UTF8 server name length", HFILL }},
2110 { &hf_asp_server_utf8_name,
2111 { "Server name (UTF8)", "asp.server_utf8_name",
2112 FT_STRING, BASE_NONE, NULL, 0x0,
2113 "Server name (UTF8)", HFILL }},
2116 static hf_register_info hf_zip[] = {
2118 { "Function", "zip.function", FT_UINT8, BASE_DEC, VALS(zip_function_vals), 0x0,
2119 "ZIP function", HFILL }},
2121 { &hf_zip_zero_value,
2122 { "Pad (0)", "zip.zero_value",FT_BYTES, BASE_HEX, NULL, 0x0,
2125 { &hf_zip_atp_function,
2126 { "Function", "zip.atp_function", FT_UINT8, BASE_DEC, VALS(zip_atp_function_vals), 0x0,
2129 { &hf_zip_start_index,
2130 { "Start index", "zip.start_index", FT_UINT16, BASE_DEC, NULL, 0x0,
2134 { "Count", "zip.count", FT_UINT16, BASE_DEC, NULL, 0x0,
2137 { &hf_zip_network_count,
2138 { "Count", "zip.network_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2141 { "Network","zip.network", FT_UINT16, BASE_DEC, NULL, 0x0,
2143 { &hf_zip_network_start,
2144 { "Network start","zip.network_start", FT_UINT16, BASE_DEC, NULL, 0x0,
2146 { &hf_zip_network_end,
2147 { "Network end", "zip.network_end", FT_UINT16, BASE_DEC, NULL, 0x0,
2151 { "Flags", "zip.flags", FT_BOOLEAN, 8, NULL, 0xC0,
2154 { &hf_zip_last_flag,
2155 { "Last Flag", "zip.last_flag", FT_BOOLEAN, 8, NULL, 0,
2156 "Non zero if contains last zone name in the zone list", HFILL }},
2158 { &hf_zip_flags_zone_invalid,
2159 { "Zone invalid", "zip.flags.zone_invalid", FT_BOOLEAN, 8, NULL, 0x80,
2162 { &hf_zip_flags_use_broadcast,
2163 { "Use broadcast","zip.flags.use_broadcast", FT_BOOLEAN, 8, NULL, 0x40,
2166 { &hf_zip_flags_only_one_zone,
2167 { "Only one zone","zip.flags.only_one_zone", FT_BOOLEAN, 8, NULL, 0x20,
2170 { &hf_zip_zone_name,
2171 { "Zone", "zip.zone_name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2174 { &hf_zip_default_zone,
2175 { "Default zone", "zip.default_zone",FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2178 { &hf_zip_multicast_length,
2179 { "Multicast length", "zip.multicast_length", FT_UINT8, BASE_DEC, NULL, 0x0,
2180 "Multicast address length", HFILL }},
2182 { &hf_zip_multicast_address,
2183 { "Multicast address", "zip.multicast_address",FT_BYTES, BASE_HEX, NULL, 0x0,
2184 "Multicast address", HFILL }},
2188 static gint *ett[] = {
2199 &ett_asp_status_server_flag,
2215 &ett_zip_zones_list,
2216 &ett_zip_network_list,
2218 module_t *atp_module;
2220 proto_llap = proto_register_protocol("LocalTalk Link Access Protocol", "LLAP", "llap");
2221 proto_register_field_array(proto_llap, hf_llap, array_length(hf_llap));
2223 proto_ddp = proto_register_protocol("Datagram Delivery Protocol", "DDP", "ddp");
2224 proto_register_field_array(proto_ddp, hf_ddp, array_length(hf_ddp));
2226 proto_nbp = proto_register_protocol("Name Binding Protocol", "NBP", "nbp");
2227 proto_register_field_array(proto_nbp, hf_nbp, array_length(hf_nbp));
2229 proto_atp = proto_register_protocol("AppleTalk Transaction Protocol packet", "ATP", "atp");
2230 proto_register_field_array(proto_atp, hf_atp, array_length(hf_atp));
2232 proto_asp = proto_register_protocol("AppleTalk Session Protocol", "ASP", "asp");
2233 proto_register_field_array(proto_asp, hf_asp, array_length(hf_asp));
2235 proto_zip = proto_register_protocol("Zone Information Protocol", "ZIP", "zip");
2236 proto_register_field_array(proto_zip, hf_zip, array_length(hf_zip));
2238 atp_module = prefs_register_protocol(proto_atp, NULL);
2239 prefs_register_bool_preference(atp_module, "desegment",
2240 "Desegment all ATP messages spanning multiple DDP packets",
2241 "Whether the ATP dissector should desegment all messages spanning multiple DDP packets",
2244 proto_rtmp = proto_register_protocol("Routing Table Maintenance Protocol",
2246 proto_register_field_array(proto_rtmp, hf_rtmp, array_length(hf_rtmp));
2248 proto_register_subtree_array(ett, array_length(ett));
2250 /* subdissector code */
2251 ddp_dissector_table = register_dissector_table("ddp.type", "DDP packet type",
2252 FT_UINT8, BASE_HEX);
2256 proto_reg_handoff_atalk(void)
2258 dissector_handle_t nbp_handle, rtmp_request_handle;
2259 dissector_handle_t atp_handle;
2260 dissector_handle_t zip_ddp_handle;
2261 dissector_handle_t rtmp_data_handle, llap_handle;
2263 ddp_handle = create_dissector_handle(dissect_ddp, proto_ddp);
2264 dissector_add("ethertype", ETHERTYPE_ATALK, ddp_handle);
2265 dissector_add("chdlctype", ETHERTYPE_ATALK, ddp_handle);
2266 dissector_add("ppp.protocol", PPP_AT, ddp_handle);
2267 dissector_add("null.type", BSD_AF_APPLETALK, ddp_handle);
2268 dissector_add("arcnet.protocol_id", ARCNET_PROTO_APPLETALK, ddp_handle);
2270 nbp_handle = create_dissector_handle(dissect_nbp, proto_nbp);
2271 dissector_add("ddp.type", DDP_NBP, nbp_handle);
2273 atp_handle = create_dissector_handle(dissect_atp, proto_atp);
2274 dissector_add("ddp.type", DDP_ATP, atp_handle);
2276 asp_handle = create_dissector_handle(dissect_asp, proto_asp);
2278 rtmp_request_handle = create_dissector_handle(dissect_rtmp_request, proto_rtmp);
2279 rtmp_data_handle = create_dissector_handle(dissect_rtmp_data, proto_rtmp);
2280 dissector_add("ddp.type", DDP_RTMPREQ, rtmp_request_handle);
2281 dissector_add("ddp.type", DDP_RTMPDATA, rtmp_data_handle);
2283 zip_ddp_handle = create_dissector_handle(dissect_ddp_zip, proto_zip);
2284 dissector_add("ddp.type", DDP_ZIP, zip_ddp_handle);
2286 zip_atp_handle = create_dissector_handle(dissect_atp_zip, proto_zip);
2288 llap_handle = create_dissector_handle(dissect_llap, proto_llap);
2289 dissector_add("wtap_encap", WTAP_ENCAP_LOCALTALK, llap_handle);
2291 register_init_routine( atp_init);
2292 register_init_routine( &asp_reinit);
2294 afp_handle = find_dissector("afp");
2295 data_handle = find_dissector("data");