2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
5 * $Id: packet-atalk.c,v 1.90 2003/09/21 20:05:59 gerald 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;
77 /* --------------------------------------
78 * ATP protocol parameters
79 * from netatalk/include/atalk/atp.h
81 #define ATP_MAXDATA (578+4) /* maximum ATP data size */
82 #define ATP_BUFSIZ 587 /* maximum packet size */
83 #define ATP_HDRSIZE 5 /* includes DDP type field */
85 #define ATP_TRELMASK 0x07 /* mask all but TREL */
86 #define ATP_RELTIME 30 /* base release timer (in secs) */
88 #define ATP_TREL30 0x0 /* release time codes */
89 #define ATP_TREL1M 0x1 /* these are passed in flags of */
90 #define ATP_TREL2M 0x2 /* atp_sreq call, and set in the */
91 #define ATP_TREL4M 0x3 /* packet control info. */
92 #define ATP_TREL8M 0x4
94 /* flags for ATP options (and control byte)
96 #define ATP_XO 0x20 /* (1<<5) eXactly Once mode */
97 #define ATP_EOM 0x10 /* (1<<4) End Of Message */
98 #define ATP_STS 0x08 /* (1<<3) Transaction Status */
102 #define ATP_FUNCMASK (3<<6) /* mask all but function */
104 #define ATP_TREQ 1 /* (1<<6) Trans. REQuest */
105 #define ATP_TRESP 2 /* (2<<6) Trans. RESPonse */
106 #define ATP_TREL 3 /* (3<<6) Trans. RELease */
108 /* ------------------------- */
109 static dissector_handle_t asp_handle;
111 static int proto_atp = -1;
112 static int hf_atp_ctrlinfo = -1; /* guint8_t control information */
113 static int hf_atp_function = -1; /* bits 7,6 function */
114 static int hf_atp_xo = -1; /* bit 5 exactly-once */
115 static int hf_atp_eom = -1; /* bit 4 end-of-message */
116 static int hf_atp_sts = -1; /* bit 3 send transaction status */
117 static int hf_atp_treltimer = -1; /* bits 2,1,0 TRel timeout indicator */
119 static int hf_atp_bitmap = -1; /* guint8_t bitmap or sequence number */
120 static int hf_atp_tid = -1; /* guint16_t transaction id. */
121 static int hf_atp_user_bytes = -1;
123 static int hf_atp_segments = -1;
124 static int hf_atp_segment = -1;
125 static int hf_atp_segment_overlap = -1;
126 static int hf_atp_segment_overlap_conflict = -1;
127 static int hf_atp_segment_multiple_tails = -1;
128 static int hf_atp_segment_too_long_segment = -1;
129 static int hf_atp_segment_error = -1;
130 static int hf_atp_reassembled_in = -1;
132 /* ------------------------- */
133 static int proto_zip = -1;
134 static dissector_handle_t zip_atp_handle;
136 static int hf_zip_function = -1;
137 static int hf_zip_atp_function = -1;
138 static int hf_zip_start_index = -1;
139 static int hf_zip_count = -1;
140 static int hf_zip_zero_value = -1;
142 static int hf_zip_network_count = -1;
143 static int hf_zip_network = -1;
144 static int hf_zip_network_start = -1;
145 static int hf_zip_network_end = -1;
147 static int hf_zip_flags = -1;
149 static int hf_zip_flags_zone_invalid = -1;
150 static int hf_zip_flags_use_broadcast = -1;
151 static int hf_zip_flags_only_one_zone = -1;
153 static int hf_zip_last_flag = -1;
155 static int hf_zip_zone_name = -1;
156 static int hf_zip_default_zone = -1;
158 static int hf_zip_multicast_length = -1;
159 static int hf_zip_multicast_address = -1;
161 static const value_string zip_function_vals[] = {
164 {5, "GetNetInfo request"},
165 {6, "GetNetInfo reply"},
167 {8, "Extended reply"},
171 static const value_string zip_atp_function_vals[] = {
174 {9, "GetLocalZones"},
178 static gint ett_zip = -1;
179 static gint ett_zip_flags = -1;
180 static gint ett_zip_zones_list = -1;
181 static gint ett_zip_network_list = -1;
183 /* --------------------------------
184 * from netatalk/include/atalk/ats.h
187 #define ASPFUNC_CLOSE 1
188 #define ASPFUNC_CMD 2
189 #define ASPFUNC_STAT 3
190 #define ASPFUNC_OPEN 4
191 #define ASPFUNC_TICKLE 5
192 #define ASPFUNC_WRITE 6
193 #define ASPFUNC_WRTCONT 7
194 #define ASPFUNC_ATTN 8
197 #define ASPERR_OK 0x0000
198 #define ASPERR_BADVERS 0xfbd6
199 #define ASPERR_BUFSMALL 0xfbd5
200 #define ASPERR_NOSESS 0xfbd4
201 #define ASPERR_NOSERV 0xfbd3
202 #define ASPERR_PARM 0xfbd2
203 #define ASPERR_SERVBUSY 0xfbd1
204 #define ASPERR_SESSCLOS 0xfbd0
205 #define ASPERR_SIZERR 0xfbcf
206 #define ASPERR_TOOMANY 0xfbce
207 #define ASPERR_NOACK 0xfbcd
209 static int proto_asp = -1;
210 static int hf_asp_func = -1;
211 static int hf_asp_error = -1;
212 static int hf_asp_socket = -1;
213 static int hf_asp_version = -1;
214 static int hf_asp_session_id = -1;
215 static int hf_asp_zero_value = -1;
216 static int hf_asp_init_error = -1;
217 static int hf_asp_attn_code = -1;
218 static int hf_asp_seq = -1;
219 static int hf_asp_size = -1;
221 /* status stuff same for asp and afp */
222 static int hf_asp_server_name = -1;
223 static int hf_asp_server_type = -1;
224 static int hf_asp_server_vers = -1;
225 static int hf_asp_server_uams = -1;
226 static int hf_asp_server_icon = -1;
227 static int hf_asp_server_directory = -1;
229 static int hf_asp_server_flag = -1;
230 static int hf_asp_server_flag_copyfile = -1;
231 static int hf_asp_server_flag_passwd = -1;
232 static int hf_asp_server_flag_no_save_passwd = -1;
233 static int hf_asp_server_flag_srv_msg = -1;
234 static int hf_asp_server_flag_srv_sig = -1;
235 static int hf_asp_server_flag_tcpip = -1;
236 static int hf_asp_server_flag_notify = -1;
237 static int hf_asp_server_flag_reconnect = -1;
238 static int hf_asp_server_flag_directory = -1;
239 static int hf_asp_server_flag_utf8_name = -1;
240 static int hf_asp_server_flag_fast_copy = -1;
241 static int hf_asp_server_signature = -1;
242 static int hf_asp_server_utf8_name_len = -1;
243 static int hf_asp_server_utf8_name = -1;
245 static int hf_asp_server_addr_len = -1;
246 static int hf_asp_server_addr_type = -1;
247 static int hf_asp_server_addr_value = -1;
249 static gint ett_asp_status = -1;
250 static gint ett_asp_uams = -1;
251 static gint ett_asp_vers = -1;
252 static gint ett_asp_addr = -1;
253 static gint ett_asp_addr_line = -1;
254 static gint ett_asp_directory = -1;
255 static gint ett_asp_status_server_flag = -1;
257 static guint asp_packet_init_count = 200;
260 guint32 conversation;
266 guint8 value; /* command for asp, bitmap for atp */
269 static GHashTable *asp_request_hash = NULL;
270 static GMemChunk *asp_request_keys = NULL;
271 static GMemChunk *asp_request_vals = NULL;
274 static gint asp_equal (gconstpointer v, gconstpointer v2)
276 const asp_request_key *val1 = (const asp_request_key*)v;
277 const asp_request_key *val2 = (const asp_request_key*)v2;
279 if (val1->conversation == val2->conversation &&
280 val1->seq == val2->seq &&
281 !memcmp(val1->src, val2->src, 4)) {
287 static guint asp_hash (gconstpointer v)
289 const asp_request_key *asp_key = (const asp_request_key*)v;
293 /* ------------------------------------ */
294 static GHashTable *atp_request_hash = NULL;
295 static GMemChunk *atp_request_keys = NULL;
296 static GMemChunk *atp_request_vals = NULL;
299 /* ------------------------------------ */
300 static int proto_nbp = -1;
301 static int hf_nbp_op = -1;
302 static int hf_nbp_info = -1;
303 static int hf_nbp_count = -1;
304 static int hf_nbp_tid = -1;
306 static int hf_nbp_node_net = -1;
307 static int hf_nbp_node_port = -1;
308 static int hf_nbp_node_node = -1;
309 static int hf_nbp_node_enum = -1;
310 static int hf_nbp_node_object = -1;
311 static int hf_nbp_node_type = -1;
312 static int hf_nbp_node_zone = -1;
314 static int proto_rtmp = -1;
315 static int hf_rtmp_net = -1;
316 static int hf_rtmp_node_len = -1;
317 static int hf_rtmp_node = -1;
318 static int hf_rtmp_tuple_net = -1;
319 static int hf_rtmp_tuple_range_start = -1;
320 static int hf_rtmp_tuple_range_end = -1;
321 static int hf_rtmp_tuple_dist = -1;
322 static int hf_rtmp_function = -1;
324 static gint ett_atp = -1;
326 static gint ett_atp_segments = -1;
327 static gint ett_atp_segment = -1;
328 static gint ett_atp_info = -1;
329 static gint ett_asp = -1;
331 static gint ett_nbp = -1;
332 static gint ett_nbp_info = -1;
333 static gint ett_nbp_node = -1;
334 static gint ett_rtmp = -1;
335 static gint ett_rtmp_tuple = -1;
336 static gint ett_ddp = -1;
337 static gint ett_llap = -1;
338 static gint ett_pstring = -1;
340 static const fragment_items atp_frag_items = {
345 &hf_atp_segment_overlap,
346 &hf_atp_segment_overlap_conflict,
347 &hf_atp_segment_multiple_tails,
348 &hf_atp_segment_too_long_segment,
349 &hf_atp_segment_error,
350 &hf_atp_reassembled_in,
354 static dissector_table_t ddp_dissector_table;
356 static dissector_handle_t data_handle;
358 #define DDP_SHORT_HEADER_SIZE 5
361 * P = Padding, H = Hops, L = Len
365 * Assumes the argument is in host byte order.
367 #define ddp_hops(x) ( ( x >> 10) & 0x3C )
368 #define ddp_len(x) ( x & 0x03ff )
369 typedef struct _e_ddp {
370 guint16 hops_len; /* combines pad, hops, and len */
371 guint16 sum,dnet,snet;
377 #define DDP_HEADER_SIZE 13
380 static const value_string op_vals[] = {
381 {DDP_RTMPDATA, "AppleTalk Routing Table response or data" },
382 {DDP_NBP, "AppleTalk Name Binding Protocol packet"},
383 {DDP_ATP, "AppleTalk Transaction Protocol packet"},
384 {DDP_AEP, "AppleTalk Echo Protocol packet"},
385 {DDP_RTMPREQ, "AppleTalk Routing Table request"},
386 {DDP_ZIP, "AppleTalk Zone Information Protocol packet"},
387 {DDP_ADSP, "AppleTalk Data Stream Protocol"},
388 {DDP_EIGRP, "Cisco EIGRP for AppleTalk"},
392 static const value_string rtmp_function_vals[] = {
394 {2, "Route Data Request (split horizon processed)"},
395 {3, "Route Data Request (no split horizon processing)"},
399 #define NBP_BROADCAST 1
401 #define NBP_FORWARD 4
404 static const value_string nbp_op_vals[] = {
405 {NBP_BROADCAST, "broadcast request"},
406 {NBP_LOOKUP, "lookup"},
407 {NBP_FORWARD, "forward request"},
408 {NBP_REPLY, "reply"},
412 static const value_string atp_function_vals[] = {
413 {ATP_TREQ ,"REQuest"},
414 {ATP_TRESP ,"RESPonse"},
415 {ATP_TREL ,"RELease"},
419 static const value_string atp_trel_timer_vals[] = {
430 static const value_string asp_func_vals[] = {
431 {ASPFUNC_CLOSE, "CloseSession" },
432 {ASPFUNC_CMD, "Command" },
433 {ASPFUNC_STAT, "GetStatus" },
434 {ASPFUNC_OPEN, "OpenSession" },
435 {ASPFUNC_TICKLE, "Tickle" },
436 {ASPFUNC_WRITE, "Write" },
437 {ASPFUNC_WRTCONT, "Write Cont" },
438 {ASPFUNC_ATTN, "Attention" },
441 const value_string asp_error_vals[] = {
442 {AFP_OK , "success"},
443 {AFPERR_ACCESS , "permission denied" },
444 {AFPERR_AUTHCONT , "logincont" },
445 {AFPERR_BADUAM , "uam doesn't exist" },
446 {AFPERR_BADVERS , "bad afp version number" },
447 {AFPERR_BITMAP , "invalid bitmap" },
448 {AFPERR_CANTMOVE , "can't move file" },
449 {AFPERR_DENYCONF , "file synchronization locks conflict" },
450 {AFPERR_DIRNEMPT , "directory not empty" },
451 {AFPERR_DFULL , "disk full" },
452 {AFPERR_EOF , "end of file" },
453 {AFPERR_BUSY , "FileBusy" },
454 {AFPERR_FLATVOL , "volume doesn't support directories" },
455 {AFPERR_NOITEM , "ItemNotFound" },
456 {AFPERR_LOCK , "LockErr" },
457 {AFPERR_MISC , "misc. err" },
458 {AFPERR_NLOCK , "no more locks" },
459 {AFPERR_NOSRVR , "no response by server at that address" },
460 {AFPERR_EXIST , "object already exists" },
461 {AFPERR_NOOBJ , "object not found" },
462 {AFPERR_PARAM , "parameter error" },
463 {AFPERR_NORANGE , "no range lock" },
464 {AFPERR_RANGEOVR , "range overlap" },
465 {AFPERR_SESSCLOS , "session closed" },
466 {AFPERR_NOTAUTH , "user not authenticated" },
467 {AFPERR_NOOP , "command not supported" },
468 {AFPERR_BADTYPE , "object is the wrong type" },
469 {AFPERR_NFILE , "too many files open" },
470 {AFPERR_SHUTDOWN , "server is going down" },
471 {AFPERR_NORENAME , "can't rename" },
472 {AFPERR_NODIR , "couldn't find directory" },
473 {AFPERR_ITYPE , "wrong icon type" },
474 {AFPERR_VLOCK , "volume locked" },
475 {AFPERR_OLOCK , "object locked" },
476 {AFPERR_CTNSHRD , "share point contains a share point" },
477 {AFPERR_NOID , "file thread not found" },
478 {AFPERR_EXISTID , "file already has an id" },
479 {AFPERR_DIFFVOL , "different volume" },
480 {AFPERR_CATCHNG , "catalog has changed" },
481 {AFPERR_SAMEOBJ , "source file == destination file" },
482 {AFPERR_BADID , "non-existent file id" },
483 {AFPERR_PWDSAME , "same password/can't change password" },
484 {AFPERR_PWDSHORT , "password too short" },
485 {AFPERR_PWDEXPR , "password expired" },
486 {AFPERR_INSHRD , "folder being shared is inside a shared folder." },
487 {AFPERR_INTRASH , "shared folder in trash." },
488 {AFPERR_PWDCHNG , "password needs to be changed" },
489 {AFPERR_PWDPOLCY , "password fails policy check" },
490 {AFPERR_USRLOGIN , "user already logged on" },
494 * XXX - do this with an FT_UINT_STRING?
495 * Unfortunately, you can't extract from an FT_UINT_STRING the string,
496 * which we'd want to do in order to put it into the "Data:" portion.
498 * Are these always in the Mac extended character set?
500 static int dissect_pascal_string(tvbuff_t *tvb, int offset, proto_tree *tree,
505 len = tvb_get_guint8(tvb, offset);
515 * XXX - if we could do this inside the protocol tree
516 * code, we could perhaps avoid allocating and freeing
517 * this string buffer.
519 tmp = g_malloc( len+1 );
520 tvb_memcpy(tvb, tmp, offset, len);
522 item = proto_tree_add_string(tree, hf_index, tvb, offset-1, len+1, tmp);
524 subtree = proto_item_add_subtree(item, ett_pstring);
525 proto_tree_add_text(subtree, tvb, offset-1, 1, "Length: %d", len);
526 proto_tree_add_text(subtree, tvb, offset, len, "Data: %s", tmp);
536 dissect_rtmp_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
537 proto_tree *rtmp_tree;
541 if (check_col(pinfo->cinfo, COL_PROTOCOL))
542 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
543 if (check_col(pinfo->cinfo, COL_INFO))
544 col_clear(pinfo->cinfo, COL_INFO);
546 function = tvb_get_guint8(tvb, 0);
548 if (check_col(pinfo->cinfo, COL_INFO))
549 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
550 val_to_str(function, rtmp_function_vals, "Unknown function (%02x)"));
553 ti = proto_tree_add_item(tree, proto_rtmp, tvb, 0, 1, FALSE);
554 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
556 proto_tree_add_uint(rtmp_tree, hf_rtmp_function, tvb, 0, 1, function);
561 dissect_rtmp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
562 proto_tree *rtmp_tree;
566 guint8 nodelen,nodelen_bits;
567 guint16 node; /* might be more than 8 bits */
570 if (check_col(pinfo->cinfo, COL_PROTOCOL))
571 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
572 if (check_col(pinfo->cinfo, COL_INFO))
573 col_clear(pinfo->cinfo, COL_INFO);
575 net = tvb_get_ntohs(tvb, offset);
576 nodelen_bits = tvb_get_guint8(tvb, offset+2);
577 if ( nodelen_bits <= 8 ) {
578 node = tvb_get_guint8(tvb, offset)+1;
581 node = tvb_get_ntohs(tvb, offset);
585 if (check_col(pinfo->cinfo, COL_INFO))
586 col_add_fstr(pinfo->cinfo, COL_INFO, "Net: %u Node Len: %u Node: %u",
587 net, nodelen_bits, node);
590 ti = proto_tree_add_item(tree, proto_rtmp, tvb, offset, -1, FALSE);
591 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
593 proto_tree_add_uint(rtmp_tree, hf_rtmp_net, tvb, offset, 2, net);
594 proto_tree_add_uint(rtmp_tree, hf_rtmp_node_len, tvb, offset+2, 1,
596 proto_tree_add_uint(rtmp_tree, hf_rtmp_node, tvb, offset+3, nodelen,
598 offset += 3 + nodelen;
601 while (tvb_offset_exists(tvb, offset)) {
602 proto_tree *tuple_item, *tuple_tree;
605 guint16 tuple_range_end;
607 tuple_net = tvb_get_ntohs(tvb, offset);
608 tuple_dist = tvb_get_guint8(tvb, offset+2);
610 if (tuple_dist & 0x80) {
611 tuple_range_end = tvb_get_ntohs(tvb, offset+3);
612 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 6,
613 "Tuple %d: Range Start: %u Dist: %u Range End: %u",
614 i, tuple_net, tuple_dist&0x7F, tuple_range_end);
616 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 3,
617 "Tuple %d: Net: %u Dist: %u",
618 i, tuple_net, tuple_dist);
620 tuple_tree = proto_item_add_subtree(tuple_item, ett_rtmp_tuple);
622 if (tuple_dist & 0x80) {
623 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_range_start, tvb, offset, 2,
626 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_net, tvb, offset, 2,
629 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_dist, tvb, offset+2, 1,
632 if (tuple_dist & 0x80) {
634 * Extended network tuple.
636 proto_tree_add_item(tuple_tree, hf_rtmp_tuple_range_end, tvb, offset+3, 2,
648 dissect_nbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
649 proto_tree *nbp_tree;
650 proto_tree *nbp_info_tree;
651 proto_item *ti, *info_item;
657 if (check_col(pinfo->cinfo, COL_PROTOCOL))
658 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBP");
659 if (check_col(pinfo->cinfo, COL_INFO))
660 col_clear(pinfo->cinfo, COL_INFO);
662 info = tvb_get_guint8(tvb, offset);
666 if (check_col(pinfo->cinfo, COL_INFO))
667 col_add_fstr(pinfo->cinfo, COL_INFO, "Op: %s Count: %u",
668 val_to_str(op, nbp_op_vals, "Unknown (0x%01x)"), count);
671 ti = proto_tree_add_item(tree, proto_nbp, tvb, offset, -1, FALSE);
672 nbp_tree = proto_item_add_subtree(ti, ett_nbp);
674 info_item = proto_tree_add_uint_format(nbp_tree, hf_nbp_info, tvb, offset, 1,
676 "Info: 0x%01X Operation: %s Count: %u", info,
677 val_to_str(op, nbp_op_vals, "Unknown (0x%01X)"),
679 nbp_info_tree = proto_item_add_subtree(info_item, ett_nbp_info);
680 proto_tree_add_uint(nbp_info_tree, hf_nbp_op, tvb, offset, 1, info);
681 proto_tree_add_uint(nbp_info_tree, hf_nbp_count, tvb, offset, 1, info);
682 proto_tree_add_item(nbp_tree, hf_nbp_tid, tvb, offset+1, 1, FALSE);
685 for (i=0; i<count; i++) {
686 proto_tree *node_item,*node_tree;
687 int soffset = offset;
689 node_item = proto_tree_add_text(nbp_tree, tvb, offset, -1,
691 node_tree = proto_item_add_subtree(node_item, ett_nbp_node);
693 proto_tree_add_item(node_tree, hf_nbp_node_net, tvb, offset, 2, FALSE);
695 proto_tree_add_item(node_tree, hf_nbp_node_node, tvb, offset, 1, FALSE);
697 proto_tree_add_item(node_tree, hf_nbp_node_port, tvb, offset, 1, FALSE);
699 proto_tree_add_item(node_tree, hf_nbp_node_enum, tvb, offset, 1, FALSE);
702 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_object);
703 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_type);
704 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_zone);
706 proto_item_set_len(node_item, offset-soffset);
713 /* -----------------------------
714 ATP protocol cf. inside appletalk chap. 9
715 desegmentation from packet-ieee80211.c
718 dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
719 proto_tree *atp_tree = NULL;
721 proto_tree *atp_info_tree;
722 proto_item *info_item;
725 guint8 frag_number = 0;
729 struct aspinfo aspinfo;
730 tvbuff_t *new_tvb = NULL;
731 gboolean save_fragmented;
732 gboolean more_fragment = FALSE;
737 conversation_t *conversation;
738 asp_request_key request_key, *new_request_key;
739 asp_request_val *request_val;
741 if (check_col(pinfo->cinfo, COL_PROTOCOL))
742 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
744 ctrlinfo = tvb_get_guint8(tvb, offset);
745 bitmap = tvb_get_guint8(tvb, offset +1);
746 tid = tvb_get_ntohs(tvb, offset +2);
756 aspinfo.reply = (0x80 == (ctrlinfo & ATP_FUNCMASK))?1:0;
757 aspinfo.release = (0xC0 == (ctrlinfo & ATP_FUNCMASK))?1:0;
760 query = (!aspinfo.reply && !aspinfo.release);
762 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
763 pinfo->srcport, pinfo->destport, 0);
765 if (conversation == NULL)
767 conversation = conversation_new(&pinfo->src, &pinfo->dst,
768 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
771 request_key.conversation = conversation->index;
772 memcpy(request_key.src, (!aspinfo.reply)?pinfo->src.data:pinfo->dst.data, 4);
773 request_key.seq = aspinfo.seq;
775 request_val = (asp_request_val *) g_hash_table_lookup(atp_request_hash, &request_key);
777 if (!request_val && query ) {
778 new_request_key = g_mem_chunk_alloc(atp_request_keys);
779 *new_request_key = request_key;
781 request_val = g_mem_chunk_alloc(atp_request_vals);
782 request_val->value = nbe;
784 g_hash_table_insert(atp_request_hash, new_request_key,request_val);
788 ATP_EOM is not mandatory. Some implementations don't always set it
789 if the query is only one packet.
791 So it needs to keep the number of packets asked in request.
795 more_fragment = !((ATP_EOM & ctrlinfo) || (request_val && 1 == request_val->value));
796 frag_number = bitmap;
799 if (check_col(pinfo->cinfo, COL_INFO)) {
800 col_clear(pinfo->cinfo, COL_INFO);
801 col_add_fstr(pinfo->cinfo, COL_INFO, "%s transaction %u",
802 val_to_str(op, atp_function_vals, "Unknown (0x%01x)"),tid);
804 col_append_fstr(pinfo->cinfo, COL_INFO, " [fragment]");
808 ti = proto_tree_add_item(tree, proto_atp, tvb, offset, -1, FALSE);
809 atp_tree = proto_item_add_subtree(ti, ett_atp);
810 proto_item_set_len(atp_tree, aspinfo.release?8:ATP_HDRSIZE -1);
812 info_item = proto_tree_add_item(atp_tree, hf_atp_ctrlinfo, tvb, offset, 1, FALSE);
813 atp_info_tree = proto_item_add_subtree(info_item, ett_atp_info);
815 proto_tree_add_item(atp_info_tree, hf_atp_function, tvb, offset, 1, FALSE);
816 proto_tree_add_item(atp_info_tree, hf_atp_xo, tvb, offset, 1, FALSE);
817 proto_tree_add_item(atp_info_tree, hf_atp_eom, tvb, offset, 1, FALSE);
818 proto_tree_add_item(atp_info_tree, hf_atp_sts, tvb, offset, 1, FALSE);
819 if ((ctrlinfo & (ATP_FUNCMASK|ATP_XO)) == (0x40|ATP_XO)) {
820 /* TReq with XO set */
821 proto_tree_add_item(atp_info_tree, hf_atp_treltimer, tvb, offset, 1, FALSE);
824 proto_tree_add_text(atp_tree, tvb, offset +1, 1,
825 "Bitmap: 0x%02x %u packet(s) max", bitmap, nbe);
828 proto_tree_add_item(atp_tree, hf_atp_bitmap, tvb, offset +1, 1, FALSE);
830 proto_tree_add_item(atp_tree, hf_atp_tid, tvb, offset +2, 2, FALSE);
833 proto_tree_add_item(atp_tree, hf_atp_user_bytes, tvb, offset +4, 4, FALSE);
840 save_fragmented = pinfo->fragmented;
843 asp doesn't fit very well here
844 move asp back in atp?
846 if (atp_defragment && aspinfo.reply && (more_fragment || frag_number != 0)) {
847 fragment_data *fd_head;
850 hdr = ATP_HDRSIZE -1;
851 if (frag_number != 0)
852 hdr += 4; /* asp header */
853 len = tvb_reported_length_remaining(tvb, hdr);
854 fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid,
856 atp_reassembled_table,
860 new_tvb = process_reassembled_data(tvb, ATP_HDRSIZE -1, pinfo,
861 "Reassembled ATP", fd_head, &atp_frag_items,
866 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1,- 1);
870 pinfo->private_data = &aspinfo;
871 /* if port == 6 it's not an ASP packet but a ZIP packet */
872 if (pinfo->srcport == 6 || pinfo->destport == 6 )
873 call_dissector(zip_atp_handle, new_tvb, pinfo, tree);
875 call_dissector(asp_handle, new_tvb, pinfo, tree);
878 /* Just show this as a fragment. */
879 new_tvb = tvb_new_subset (tvb, ATP_HDRSIZE -1, -1, -1);
880 call_dissector(data_handle, new_tvb, pinfo, tree);
882 pinfo->fragmented = save_fragmented;
887 copy and paste from dsi
890 dissect_asp_reply_get_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
892 proto_tree *sub_tree;
898 guint16 sign_ofs = 0;
909 ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
910 tree = proto_item_add_subtree(ti, ett_asp_status);
912 machine_ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
913 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %u", machine_ofs);
915 machine_ofs += offset;
917 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
918 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %u", ofs);
920 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
921 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %u", ofs);
923 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
924 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %u", ofs);
926 ofs = offset +AFPSTATUS_FLAGOFF;
927 ti = proto_tree_add_item(tree, hf_asp_server_flag, tvb, ofs, 2, FALSE);
928 sub_tree = proto_item_add_subtree(ti, ett_asp_status_server_flag);
929 proto_tree_add_item(sub_tree, hf_asp_server_flag_copyfile , tvb, ofs, 2, FALSE);
930 proto_tree_add_item(sub_tree, hf_asp_server_flag_passwd , tvb, ofs, 2, FALSE);
931 proto_tree_add_item(sub_tree, hf_asp_server_flag_no_save_passwd, tvb, ofs, 2, FALSE);
932 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_msg , tvb, ofs, 2, FALSE);
933 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_sig , tvb, ofs, 2, FALSE);
934 proto_tree_add_item(sub_tree, hf_asp_server_flag_tcpip , tvb, ofs, 2, FALSE);
935 proto_tree_add_item(sub_tree, hf_asp_server_flag_notify , tvb, ofs, 2, FALSE);
936 proto_tree_add_item(sub_tree, hf_asp_server_flag_reconnect , tvb, ofs, 2, FALSE);
937 proto_tree_add_item(sub_tree, hf_asp_server_flag_directory , tvb, ofs, 2, FALSE);
938 proto_tree_add_item(sub_tree, hf_asp_server_flag_utf8_name , tvb, ofs, 2, FALSE);
939 proto_tree_add_item(sub_tree, hf_asp_server_flag_fast_copy , tvb, ofs, 2, FALSE);
941 proto_tree_add_item(tree, hf_asp_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, FALSE);
943 flag = tvb_get_ntohs(tvb, ofs);
944 if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
945 ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
949 sign_ofs = tvb_get_ntohs(tvb, ofs);
950 proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %u", sign_ofs);
954 if ((flag & AFPSRVRINFO_TCPIP) && ofs < machine_ofs ) {
955 adr_ofs = tvb_get_ntohs(tvb, ofs);
956 proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %u", adr_ofs);
961 if ((flag & AFPSRVRINFO_SRVDIRECTORY) && ofs < machine_ofs) {
962 dir_ofs = tvb_get_ntohs(tvb, ofs);
963 proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %u", dir_ofs);
968 if ((flag & AFPSRVRINFO_SRVUTF8) && ofs < machine_ofs) {
969 utf_ofs = tvb_get_ntohs(tvb, ofs);
970 proto_tree_add_text(tree, tvb, ofs, 2, "UTF-8 Server name offset: %u", utf_ofs);
976 proto_tree_add_item(tree, hf_asp_server_type, tvb, machine_ofs, 1, FALSE);
978 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
980 nbe = tvb_get_guint8(tvb, ofs);
981 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %u", nbe);
983 sub_tree = proto_item_add_subtree(ti, ett_asp_vers);
984 for (i = 0; i < nbe; i++) {
985 len = tvb_get_guint8(tvb, ofs) +1;
986 proto_tree_add_item(sub_tree, hf_asp_server_vers, tvb, ofs, 1, FALSE);
991 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
993 nbe = tvb_get_guint8(tvb, ofs);
994 ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %u", nbe);
996 sub_tree = proto_item_add_subtree(ti, ett_asp_uams);
997 for (i = 0; i < nbe; i++) {
998 len = tvb_get_guint8(tvb, ofs) +1;
999 proto_tree_add_item(sub_tree, hf_asp_server_uams, tvb, ofs, 1, FALSE);
1004 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1006 proto_tree_add_item(tree, hf_asp_server_icon, tvb, ofs, 256, FALSE);
1009 proto_tree_add_item(tree, hf_asp_server_signature, tvb, sign_ofs, 16, FALSE);
1013 proto_tree *adr_tree;
1021 nbe = tvb_get_guint8(tvb, ofs);
1022 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %u", nbe);
1024 adr_tree = proto_item_add_subtree(ti, ett_asp_addr);
1025 for (i = 0; i < nbe; i++) {
1028 len = tvb_get_guint8(tvb, ofs);
1029 type = tvb_get_guint8(tvb, ofs +1);
1032 ip = tvb_get_ptr(tvb, ofs+2, 4);
1033 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", ip_to_str(ip));
1035 case 2: /* IP + port */
1036 ip = tvb_get_ptr(tvb, ofs+2, 4);
1037 port = tvb_get_ntohs(tvb, ofs+6);
1038 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%u",ip_to_str(ip),port);
1040 case 3: /* DDP, atalk_addr_to_str want host order not network */
1041 net = tvb_get_ntohs(tvb, ofs+2);
1042 node = tvb_get_guint8(tvb, ofs +4);
1043 port = tvb_get_guint8(tvb, ofs +5);
1044 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
1047 case 5: /* IP + port ssh tunnel */
1048 ip = tvb_get_ptr(tvb, ofs+2, 4);
1049 port = tvb_get_ntohs(tvb, ofs+6);
1050 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip (ssh tunnel) %s:%u",ip_to_str(ip),port);
1054 tmp = g_malloc( len -1);
1055 tvb_memcpy(tvb, tmp, ofs +2, len -2);
1057 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
1061 /* else fall to default malformed record */
1063 ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknow type : %u", type);
1067 sub_tree = proto_item_add_subtree(ti,ett_asp_addr_line);
1068 proto_tree_add_item(sub_tree, hf_asp_server_addr_len, tvb, ofs, 1, FALSE);
1070 proto_tree_add_item(sub_tree, hf_asp_server_addr_type, tvb, ofs, 1, FALSE);
1072 proto_tree_add_item(sub_tree, hf_asp_server_addr_value,tvb, ofs, len, FALSE);
1079 nbe = tvb_get_guint8(tvb, ofs);
1080 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %u", nbe);
1082 sub_tree = proto_item_add_subtree(ti, ett_asp_directory);
1083 for (i = 0; i < nbe; i++) {
1084 len = tvb_get_guint8(tvb, ofs) +1;
1085 proto_tree_add_item(sub_tree, hf_asp_server_directory, tvb, ofs, 1, FALSE);
1091 len = tvb_get_ntohs(tvb, ofs);
1092 proto_tree_add_item(tree, hf_asp_server_utf8_name_len, tvb, ofs, 2, FALSE);
1094 proto_tree_add_item(tree, hf_asp_server_utf8_name, tvb, ofs, len, FALSE);
1097 /* FIXME: offset is not updated */
1101 /* -----------------------------
1102 ASP protocol cf. inside appletalk chap. 11
1104 static struct aspinfo *
1105 get_transaction(tvbuff_t *tvb, packet_info *pinfo)
1107 struct aspinfo *aspinfo = pinfo->private_data;
1108 conversation_t *conversation;
1109 asp_request_key request_key, *new_request_key;
1110 asp_request_val *request_val;
1113 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
1114 pinfo->srcport, pinfo->destport, 0);
1116 if (conversation == NULL)
1118 conversation = conversation_new(&pinfo->src, &pinfo->dst,
1119 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1122 request_key.conversation = conversation->index;
1123 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
1124 request_key.seq = aspinfo->seq;
1126 request_val = (asp_request_val *) g_hash_table_lookup(
1127 asp_request_hash, &request_key);
1128 if (!request_val && !aspinfo->reply ) {
1129 fn = tvb_get_guint8(tvb, 0);
1130 new_request_key = g_mem_chunk_alloc(asp_request_keys);
1131 *new_request_key = request_key;
1133 request_val = g_mem_chunk_alloc(asp_request_vals);
1134 request_val->value = fn;
1136 g_hash_table_insert(asp_request_hash, new_request_key,
1143 aspinfo->command = request_val->value;
1149 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1151 struct aspinfo *aspinfo;
1153 proto_tree *asp_tree = NULL;
1158 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1159 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1160 if (check_col(pinfo->cinfo, COL_INFO))
1161 col_clear(pinfo->cinfo, COL_INFO);
1163 aspinfo = get_transaction(tvb, pinfo);
1167 fn = aspinfo->command;
1169 if (check_col(pinfo->cinfo, COL_INFO)) {
1171 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1173 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1174 val_to_str(fn, asp_func_vals, "Unknown (0x%01x)"), aspinfo->seq);
1178 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, FALSE);
1179 asp_tree = proto_item_add_subtree(ti, ett_asp);
1181 if (!aspinfo->reply) {
1183 /* let the called deal with asp_tree == NULL */
1185 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, FALSE);
1189 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1191 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, FALSE);
1194 case ASPFUNC_TICKLE:
1196 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1198 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1202 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1204 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1208 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1210 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, FALSE);
1215 proto_item_set_len(asp_tree, 4);
1216 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1218 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1220 len = tvb_reported_length_remaining(tvb,offset);
1221 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1222 call_dissector(afp_handle, new_tvb, pinfo, tree);
1224 case ASPFUNC_WRTCONT:
1225 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1227 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1229 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, FALSE);
1233 proto_item_set_len(asp_tree, 4);
1235 len = tvb_reported_length_remaining(tvb,offset);
1236 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1243 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1246 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1248 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1250 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, FALSE);
1254 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1256 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1258 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1262 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1264 dissect_asp_reply_get_status(tvb, pinfo, asp_tree, offset);
1268 proto_item_set_len(asp_tree, 4);
1269 aspinfo->code = tvb_get_ntohl(tvb, offset);
1270 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, FALSE);
1272 len = tvb_reported_length_remaining(tvb,offset);
1273 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1274 call_dissector(afp_handle, new_tvb, pinfo, tree);
1276 case ASPFUNC_TICKLE:
1277 case ASPFUNC_WRTCONT:
1278 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1280 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1282 proto_item_set_len(asp_tree, 4);
1284 len = tvb_reported_length_remaining(tvb,offset);
1285 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1291 /* -----------------------------
1292 ZIP protocol cf. inside appletalk chap. 8
1295 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1297 struct aspinfo *aspinfo;
1299 proto_tree *zip_tree;
1300 proto_tree *sub_tree;
1306 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1307 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1308 if (check_col(pinfo->cinfo, COL_INFO))
1309 col_clear(pinfo->cinfo, COL_INFO);
1311 aspinfo = get_transaction(tvb, pinfo);
1315 fn = aspinfo->command;
1317 if (check_col(pinfo->cinfo, COL_INFO)) {
1319 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1321 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1322 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1328 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, FALSE);
1329 zip_tree = proto_item_add_subtree(ti, ett_zip);
1331 if (!aspinfo->reply) {
1332 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, FALSE);
1335 case 7: /* start_index = 0 */
1338 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1340 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, FALSE);
1347 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1352 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, FALSE);
1355 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1357 count = tvb_get_ntohs(tvb, offset);
1358 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, FALSE);
1360 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1361 for (i= 1; i <= count; i++) {
1362 len = tvb_get_guint8(tvb, offset);
1363 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1372 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1374 proto_tree *zip_tree = NULL;
1379 proto_tree *flag_tree;
1380 proto_tree *sub_tree;
1381 proto_tree *net_tree;
1387 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1388 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1389 if (check_col(pinfo->cinfo, COL_INFO))
1390 col_clear(pinfo->cinfo, COL_INFO);
1392 fn = tvb_get_guint8(tvb, 0);
1393 if (check_col(pinfo->cinfo, COL_INFO)) {
1394 col_add_str(pinfo->cinfo, COL_INFO,
1395 val_to_str(fn, zip_function_vals, "Unknown ZIP function (%02x)"));
1401 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, FALSE);
1402 zip_tree = proto_item_add_subtree(ti, ett_zip);
1404 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,FALSE);
1406 /* fn 1,7,2,8 are not tested */
1409 count = tvb_get_guint8(tvb, offset);
1410 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1412 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1413 for (i= 1; i <= count; i++) {
1414 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, FALSE);
1418 case 7: /* Notify */
1419 flag = tvb_get_guint8(tvb, offset);
1420 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1421 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1422 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1423 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1424 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1427 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1430 len = tvb_get_guint8(tvb, offset);
1431 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1434 len = tvb_get_guint8(tvb, offset);
1435 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1437 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1440 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1444 case 8: /* Extended Reply */
1445 count = tvb_get_guint8(tvb, offset);
1446 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1448 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1449 for (i= 1; i <= count; i++) {
1450 net = tvb_get_ntohs(tvb, offset);
1451 ti = proto_tree_add_text(zip_tree, tvb, offset , 2, "Zone for network : %u", net);
1452 net_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1453 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, FALSE);
1455 len = tvb_get_guint8(tvb, offset);
1456 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1461 case 5 : /* GetNetInfo request */
1462 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1464 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1466 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1469 case 6 : /* GetNetInfo reply */
1470 flag = tvb_get_guint8(tvb, offset);
1471 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1472 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1473 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1474 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1475 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1478 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, FALSE);
1481 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, FALSE);
1484 len = tvb_get_guint8(tvb, offset);
1485 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1488 len = tvb_get_guint8(tvb, offset);
1489 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1491 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1493 if ((flag & 0x80) != 0)
1494 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,FALSE);
1503 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, guint8 dnode,
1504 guint8 snode, proto_tree *tree)
1510 proto_tree *ddp_tree = NULL;
1512 static struct atalk_ddp_addr src, dst;
1515 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1516 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1517 if (check_col(pinfo->cinfo, COL_INFO))
1518 col_clear(pinfo->cinfo, COL_INFO);
1521 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1523 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1525 len = tvb_get_ntohs(tvb, 0);
1527 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1528 dport = tvb_get_guint8(tvb, 2);
1530 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1531 sport = tvb_get_guint8(tvb, 3);
1533 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1534 type = tvb_get_guint8(tvb, 4);
1540 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1541 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1542 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1543 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1545 pinfo->ptype = PT_DDP;
1546 pinfo->destport = dport;
1547 pinfo->srcport = sport;
1549 if (check_col(pinfo->cinfo, COL_INFO)) {
1550 col_add_str(pinfo->cinfo, COL_INFO,
1551 val_to_str(type, op_vals, "Unknown DDP protocol (%02x)"));
1554 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1555 4, 3, atalk_addr_to_str(&src));
1556 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1557 6, 3, atalk_addr_to_str(&dst));
1559 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1561 new_tvb = tvb_new_subset(tvb, DDP_SHORT_HEADER_SIZE, -1, -1);
1563 if (!dissector_try_port(ddp_dissector_table, type, new_tvb, pinfo, tree))
1564 call_dissector(data_handle,new_tvb, pinfo, tree);
1568 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1571 proto_tree *ddp_tree;
1573 static struct atalk_ddp_addr src, dst;
1576 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1577 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1578 if (check_col(pinfo->cinfo, COL_INFO))
1579 col_clear(pinfo->cinfo, COL_INFO);
1581 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1582 ddp.dnet=g_ntohs(ddp.dnet);
1583 ddp.snet=g_ntohs(ddp.snet);
1584 ddp.sum=g_ntohs(ddp.sum);
1585 ddp.hops_len=g_ntohs(ddp.hops_len);
1588 src.node = ddp.snode;
1590 dst.node = ddp.dnode;
1591 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1592 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1593 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1594 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1596 pinfo->ptype = PT_DDP;
1597 pinfo->destport = ddp.dport;
1598 pinfo->srcport = ddp.sport;
1600 if (check_col(pinfo->cinfo, COL_INFO))
1601 col_add_str(pinfo->cinfo, COL_INFO,
1602 val_to_str(ddp.type, op_vals, "Unknown DDP protocol (%02x)"));
1605 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1607 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1609 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1610 4, 3, atalk_addr_to_str(&src));
1611 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1612 6, 3, atalk_addr_to_str(&dst));
1614 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1615 ddp_hops(ddp.hops_len));
1616 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1617 ddp_len(ddp.hops_len));
1618 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1620 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1622 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1624 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1626 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1628 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1630 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1632 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1636 new_tvb = tvb_new_subset(tvb, DDP_HEADER_SIZE, -1, -1);
1638 if (!dissector_try_port(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1639 call_dissector(data_handle,new_tvb, pinfo, tree);
1642 static const value_string llap_type_vals[] = {
1643 {0x01, "Short DDP"},
1646 {0x82, "Acknowledgement"},
1653 capture_llap(packet_counts *ld)
1659 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1664 proto_tree *llap_tree = NULL;
1668 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1669 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1670 if (check_col(pinfo->cinfo, COL_INFO))
1671 col_clear(pinfo->cinfo, COL_INFO);
1674 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, FALSE);
1675 llap_tree = proto_item_add_subtree(ti, ett_llap);
1678 dnode = tvb_get_guint8(tvb, 0);
1680 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, dnode);
1681 snode = tvb_get_guint8(tvb, 1);
1683 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, snode);
1684 type = tvb_get_guint8(tvb, 2);
1685 if (check_col(pinfo->cinfo, COL_INFO)) {
1686 col_add_str(pinfo->cinfo, COL_INFO,
1687 val_to_str(type, llap_type_vals, "Unknown LLAP type (%02x)"));
1690 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1692 new_tvb = tvb_new_subset(tvb, 3, -1, -1);
1694 if (proto_is_protocol_enabled(proto_ddp)) {
1695 pinfo->current_proto = "DDP";
1699 dissect_ddp_short(new_tvb, pinfo, dnode, snode, tree);
1703 dissect_ddp(new_tvb, pinfo, tree);
1707 call_dissector(data_handle,new_tvb, pinfo, tree);
1714 fragment_table_init(&atp_fragment_table);
1715 reassembled_table_init(&atp_reassembled_table);
1717 if (atp_request_hash)
1718 g_hash_table_destroy(atp_request_hash);
1719 if (atp_request_keys)
1720 g_mem_chunk_destroy(atp_request_keys);
1721 if (atp_request_vals)
1722 g_mem_chunk_destroy(atp_request_vals);
1724 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1726 atp_request_keys = g_mem_chunk_new("atp_request_keys",
1727 sizeof(asp_request_key),
1728 asp_packet_init_count * sizeof(asp_request_key),
1730 atp_request_vals = g_mem_chunk_new("atp_request_vals",
1731 sizeof(asp_request_val),
1732 asp_packet_init_count * sizeof(asp_request_val),
1740 if (asp_request_hash)
1741 g_hash_table_destroy(asp_request_hash);
1742 if (asp_request_keys)
1743 g_mem_chunk_destroy(asp_request_keys);
1744 if (asp_request_vals)
1745 g_mem_chunk_destroy(asp_request_vals);
1747 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1749 asp_request_keys = g_mem_chunk_new("asp_request_keys",
1750 sizeof(asp_request_key),
1751 asp_packet_init_count * sizeof(asp_request_key),
1753 asp_request_vals = g_mem_chunk_new("asp_request_vals",
1754 sizeof(asp_request_val),
1755 asp_packet_init_count * sizeof(asp_request_val),
1761 proto_register_atalk(void)
1763 static hf_register_info hf_llap[] = {
1765 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1769 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1773 { "Type", "llap.type", FT_UINT8, BASE_HEX, VALS(llap_type_vals), 0x0,
1777 static hf_register_info hf_ddp[] = {
1779 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1783 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1787 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1791 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1795 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1799 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1803 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1807 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1811 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1814 { &hf_ddp_dst_socket,
1815 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1818 { &hf_ddp_src_socket,
1819 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1823 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC, VALS(op_vals), 0x0,
1827 static hf_register_info hf_nbp[] = {
1829 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1830 VALS(nbp_op_vals), 0xF0, "Operation", HFILL }},
1832 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1833 NULL, 0x0, "Info", HFILL }},
1835 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1836 NULL, 0x0F, "Count", HFILL }},
1838 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1839 NULL, 0x0, "Network", HFILL }},
1840 { &hf_nbp_node_node,
1841 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1842 NULL, 0x0, "Node", HFILL }},
1843 { &hf_nbp_node_port,
1844 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1845 NULL, 0x0, "Port", HFILL }},
1846 { &hf_nbp_node_enum,
1847 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1848 NULL, 0x0, "Enumerator", HFILL }},
1849 { &hf_nbp_node_object,
1850 { "Object", "nbp.object", FT_STRING, BASE_DEC,
1851 NULL, 0x0, "Object", HFILL }},
1852 { &hf_nbp_node_type,
1853 { "Type", "nbp.type", FT_STRING, BASE_DEC,
1854 NULL, 0x0, "Type", HFILL }},
1855 { &hf_nbp_node_zone,
1856 { "Zone", "nbp.zone", FT_STRING, BASE_DEC,
1857 NULL, 0x0, "Zone", HFILL }},
1859 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1860 NULL, 0x0, "Transaction ID", HFILL }}
1863 static hf_register_info hf_rtmp[] = {
1865 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1866 NULL, 0x0, "Net", HFILL }},
1868 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1869 NULL, 0x0, "Node", HFILL }},
1870 { &hf_rtmp_node_len,
1871 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1872 NULL, 0x0, "Node Length", HFILL }},
1873 { &hf_rtmp_tuple_net,
1874 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1875 NULL, 0x0, "Net", HFILL }},
1876 { &hf_rtmp_tuple_range_start,
1877 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
1878 NULL, 0x0, "Range Start", HFILL }},
1879 { &hf_rtmp_tuple_range_end,
1880 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
1881 NULL, 0x0, "Range End", HFILL }},
1882 { &hf_rtmp_tuple_dist,
1883 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
1884 NULL, 0x0, "Distance", HFILL }},
1885 { &hf_rtmp_function,
1886 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
1887 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
1890 static hf_register_info hf_atp[] = {
1892 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
1893 NULL, 0, "control info", HFILL }},
1896 { "Function", "atp.function", FT_UINT8, BASE_DEC,
1897 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
1901 { "XO", "atp.xo", FT_BOOLEAN, 8,
1902 NULL, ATP_XO, "Exactly-once flag", HFILL }},
1905 { "EOM", "atp.eom", FT_BOOLEAN, 8,
1906 NULL, ATP_EOM, "End-of-message", HFILL }},
1909 { "STS", "atp.sts", FT_BOOLEAN, 8,
1910 NULL, ATP_STS, "Send transaction status", HFILL }},
1912 { &hf_atp_treltimer,
1913 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
1914 VALS(atp_trel_timer_vals), 0x07, "TRel timer", HFILL }},
1917 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
1918 NULL, 0x0, "Bitmap or sequence number", HFILL }},
1921 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
1922 NULL, 0x0, "Transaction id", HFILL }},
1923 { &hf_atp_user_bytes,
1924 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
1925 NULL, 0x0, "User bytes", HFILL }},
1927 { &hf_atp_segment_overlap,
1928 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
1929 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
1931 { &hf_atp_segment_overlap_conflict,
1932 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
1933 FT_BOOLEAN, BASE_NONE,
1934 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
1936 { &hf_atp_segment_multiple_tails,
1937 { "Multiple tail segments found", "atp.segment.multipletails",
1938 FT_BOOLEAN, BASE_NONE,
1939 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
1941 { &hf_atp_segment_too_long_segment,
1942 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
1943 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
1945 { &hf_atp_segment_error,
1946 {"Desegmentation error", "atp.segment.error", FT_FRAMENUM, BASE_NONE,
1947 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
1950 { "ATP Fragment", "atp.fragment", FT_FRAMENUM, BASE_NONE,
1951 NULL, 0x0, "ATP Fragment", HFILL }},
1954 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
1955 NULL, 0x0, "ATP Fragments", HFILL }},
1957 { &hf_atp_reassembled_in,
1958 { "Reassembled ATP in frame", "atp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1959 "This ATP packet is reassembled in this frame", HFILL }}
1962 static hf_register_info hf_asp[] = {
1964 { "asp function", "asp.function", FT_UINT8, BASE_DEC,
1965 VALS(asp_func_vals), 0, "asp function", HFILL }},
1968 { "asp error", "asp.error", FT_INT32, BASE_DEC,
1969 VALS(asp_error_vals), 0, "return error code", HFILL }},
1972 { "Version", "asp.version", FT_UINT16, BASE_HEX,
1973 NULL, 0, "asp version", HFILL }},
1975 { &hf_asp_attn_code,
1976 { "Attn code", "asp.attn_code", FT_UINT16, BASE_HEX,
1977 NULL, 0, "asp attention code", HFILL }},
1979 { &hf_asp_init_error,
1980 { "Error", "asp.init_error", FT_UINT16, BASE_DEC,
1981 NULL, 0, "asp init error", HFILL }},
1983 { &hf_asp_session_id,
1984 { "Session ID", "asp.session_id", FT_UINT8, BASE_DEC,
1985 NULL, 0, "asp session id", HFILL }},
1988 { "Socket", "asp.socket", FT_UINT8, BASE_DEC,
1989 NULL, 0, "asp socket", HFILL }},
1992 { "Sequence", "asp.seq", FT_UINT16, BASE_DEC,
1993 NULL, 0, "asp sequence number", HFILL }},
1996 { "size", "asp.size", FT_UINT16, BASE_DEC,
1997 NULL, 0, "asp available size for reply", HFILL }},
1999 { &hf_asp_zero_value,
2000 { "Pad (0)", "asp.zero_value",
2001 FT_BYTES, BASE_HEX, NULL, 0x0,
2005 { &hf_asp_server_name,
2006 { "Server name", "asp.server_name",
2007 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2008 "Server name", HFILL }},
2010 { &hf_asp_server_type,
2011 { "Server type", "asp.server_type",
2012 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2013 "Server type", HFILL }},
2015 { &hf_asp_server_vers,
2016 { "AFP version", "asp.server_vers",
2017 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2018 "AFP version", HFILL }},
2020 { &hf_asp_server_uams,
2021 { "UAM", "asp.server_uams",
2022 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2025 { &hf_asp_server_icon,
2026 { "Icon bitmap", "asp.server_icon",
2027 FT_BYTES, BASE_HEX, NULL, 0x0,
2028 "Server icon bitmap", HFILL }},
2030 { &hf_asp_server_directory,
2031 { "Directory service", "asp.server_directory",
2032 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2033 "Server directory service", HFILL }},
2035 { &hf_asp_server_signature,
2036 { "Server signature", "asp.server_signature",
2037 FT_BYTES, BASE_HEX, NULL, 0x0,
2038 "Server signature", HFILL }},
2040 { &hf_asp_server_flag,
2041 { "Flag", "asp.server_flag",
2042 FT_UINT16, BASE_HEX, NULL, 0x0,
2043 "Server capabilities flag", HFILL }},
2044 { &hf_asp_server_flag_copyfile,
2045 { "Support copyfile", "asp.server_flag.copyfile",
2046 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_COPY,
2047 "Server support copyfile", HFILL }},
2048 { &hf_asp_server_flag_passwd,
2049 { "Support change password", "asp.server_flag.passwd",
2050 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_PASSWD,
2051 "Server support change password", HFILL }},
2052 { &hf_asp_server_flag_no_save_passwd,
2053 { "Don't allow save password", "asp.server_flag.no_save_passwd",
2054 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_NOSAVEPASSWD,
2055 "Don't allow save password", HFILL }},
2056 { &hf_asp_server_flag_srv_msg,
2057 { "Support server message", "asp.server_flag.srv_msg",
2058 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVMSGS,
2059 "Support server message", HFILL }},
2060 { &hf_asp_server_flag_srv_sig,
2061 { "Support server signature", "asp.server_flag.srv_sig",
2062 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVSIGNATURE,
2063 "Support server signature", HFILL }},
2064 { &hf_asp_server_flag_tcpip,
2065 { "Support TCP/IP", "asp.server_flag.tcpip",
2066 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_TCPIP,
2067 "Server support TCP/IP", HFILL }},
2068 { &hf_asp_server_flag_notify,
2069 { "Support server notifications", "asp.server_flag.notify",
2070 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVNOTIFY,
2071 "Server support notifications", HFILL }},
2072 { &hf_asp_server_flag_reconnect,
2073 { "Support server reconnect", "asp.server_flag.reconnect",
2074 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVRECONNECT,
2075 "Server support reconnect", HFILL }},
2076 { &hf_asp_server_flag_directory,
2077 { "Support directory services", "asp.server_flag.directory",
2078 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVDIRECTORY,
2079 "Server support directory services", HFILL }},
2080 { &hf_asp_server_flag_utf8_name,
2081 { "Support UTF8 server name", "asp.server_flag.utf8_name",
2082 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVUTF8,
2083 "Server support UTF8 server name", HFILL }},
2084 { &hf_asp_server_flag_fast_copy,
2085 { "Support fast copy", "asp.server_flag.fast_copy",
2086 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_FASTBOZO,
2087 "Server support fast copy", HFILL }},
2089 { &hf_asp_server_addr_len,
2090 { "Length", "asp.server_addr.len",
2091 FT_UINT8, BASE_DEC, NULL, 0x0,
2092 "Address length.", HFILL }},
2094 { &hf_asp_server_addr_type,
2095 { "Type", "asp.server_addr.type",
2096 FT_UINT8, BASE_DEC, VALS(afp_server_addr_type_vals), 0x0,
2097 "Address type.", HFILL }},
2099 { &hf_asp_server_addr_value,
2100 { "Value", "asp.server_addr.value",
2101 FT_BYTES, BASE_HEX, NULL, 0x0,
2102 "Address value", HFILL }},
2104 { &hf_asp_server_utf8_name_len,
2105 { "Server name length", "asp.server_utf8_name_len",
2106 FT_UINT16, BASE_DEC, NULL, 0x0,
2107 "UTF8 server name length", HFILL }},
2109 { &hf_asp_server_utf8_name,
2110 { "Server name (UTF8)", "asp.server_utf8_name",
2111 FT_STRING, BASE_NONE, NULL, 0x0,
2112 "Server name (UTF8)", HFILL }},
2115 static hf_register_info hf_zip[] = {
2117 { "Function", "zip.function", FT_UINT8, BASE_DEC, VALS(zip_function_vals), 0x0,
2118 "ZIP function", HFILL }},
2120 { &hf_zip_zero_value,
2121 { "Pad (0)", "zip.zero_value",FT_BYTES, BASE_HEX, NULL, 0x0,
2124 { &hf_zip_atp_function,
2125 { "Function", "zip.atp_function", FT_UINT8, BASE_DEC, VALS(zip_atp_function_vals), 0x0,
2128 { &hf_zip_start_index,
2129 { "Start index", "zip.start_index", FT_UINT16, BASE_DEC, NULL, 0x0,
2133 { "Count", "zip.count", FT_UINT16, BASE_DEC, NULL, 0x0,
2136 { &hf_zip_network_count,
2137 { "Count", "zip.network_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2140 { "Network","zip.network", FT_UINT16, BASE_DEC, NULL, 0x0,
2142 { &hf_zip_network_start,
2143 { "Network start","zip.network_start", FT_UINT16, BASE_DEC, NULL, 0x0,
2145 { &hf_zip_network_end,
2146 { "Network end", "zip.network_end", FT_UINT16, BASE_DEC, NULL, 0x0,
2150 { "Flags", "zip.flags", FT_BOOLEAN, 8, NULL, 0xC0,
2153 { &hf_zip_last_flag,
2154 { "Last Flag", "zip.last_flag", FT_BOOLEAN, 8, NULL, 0,
2155 "Non zero if contains last zone name in the zone list", HFILL }},
2157 { &hf_zip_flags_zone_invalid,
2158 { "Zone invalid", "zip.flags.zone_invalid", FT_BOOLEAN, 8, NULL, 0x80,
2161 { &hf_zip_flags_use_broadcast,
2162 { "Use broadcast","zip.flags.use_broadcast", FT_BOOLEAN, 8, NULL, 0x40,
2165 { &hf_zip_flags_only_one_zone,
2166 { "Only one zone","zip.flags.only_one_zone", FT_BOOLEAN, 8, NULL, 0x20,
2169 { &hf_zip_zone_name,
2170 { "Zone", "zip.zone_name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2173 { &hf_zip_default_zone,
2174 { "Default zone", "zip.default_zone",FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2177 { &hf_zip_multicast_length,
2178 { "Multicast length", "zip.multicast_length", FT_UINT8, BASE_DEC, NULL, 0x0,
2179 "Multicast address length", HFILL }},
2181 { &hf_zip_multicast_address,
2182 { "Multicast address", "zip.multicast_address",FT_BYTES, BASE_HEX, NULL, 0x0,
2183 "Multicast address", HFILL }},
2187 static gint *ett[] = {
2198 &ett_asp_status_server_flag,
2214 &ett_zip_zones_list,
2215 &ett_zip_network_list,
2217 module_t *atp_module;
2219 proto_llap = proto_register_protocol("LocalTalk Link Access Protocol", "LLAP", "llap");
2220 proto_register_field_array(proto_llap, hf_llap, array_length(hf_llap));
2222 proto_ddp = proto_register_protocol("Datagram Delivery Protocol", "DDP", "ddp");
2223 proto_register_field_array(proto_ddp, hf_ddp, array_length(hf_ddp));
2225 proto_nbp = proto_register_protocol("Name Binding Protocol", "NBP", "nbp");
2226 proto_register_field_array(proto_nbp, hf_nbp, array_length(hf_nbp));
2228 proto_atp = proto_register_protocol("AppleTalk Transaction Protocol packet", "ATP", "atp");
2229 proto_register_field_array(proto_atp, hf_atp, array_length(hf_atp));
2231 proto_asp = proto_register_protocol("AppleTalk Session Protocol", "ASP", "asp");
2232 proto_register_field_array(proto_asp, hf_asp, array_length(hf_asp));
2234 proto_zip = proto_register_protocol("Zone Information Protocol", "ZIP", "zip");
2235 proto_register_field_array(proto_zip, hf_zip, array_length(hf_zip));
2237 atp_module = prefs_register_protocol(proto_atp, NULL);
2238 prefs_register_bool_preference(atp_module, "desegment",
2239 "Desegment all ATP messages spanning multiple DDP packets",
2240 "Whether the ATP dissector should desegment all messages spanning multiple DDP packets",
2243 proto_rtmp = proto_register_protocol("Routing Table Maintenance Protocol",
2245 proto_register_field_array(proto_rtmp, hf_rtmp, array_length(hf_rtmp));
2247 proto_register_subtree_array(ett, array_length(ett));
2249 /* subdissector code */
2250 ddp_dissector_table = register_dissector_table("ddp.type", "DDP packet type",
2251 FT_UINT8, BASE_HEX);
2255 proto_reg_handoff_atalk(void)
2257 dissector_handle_t ddp_handle, nbp_handle, rtmp_request_handle;
2258 dissector_handle_t atp_handle;
2259 dissector_handle_t zip_ddp_handle;
2260 dissector_handle_t rtmp_data_handle, llap_handle;
2262 ddp_handle = create_dissector_handle(dissect_ddp, proto_ddp);
2263 dissector_add("ethertype", ETHERTYPE_ATALK, ddp_handle);
2264 dissector_add("chdlctype", ETHERTYPE_ATALK, ddp_handle);
2265 dissector_add("ppp.protocol", PPP_AT, ddp_handle);
2266 dissector_add("null.type", BSD_AF_APPLETALK, ddp_handle);
2267 dissector_add("arcnet.protocol_id", ARCNET_PROTO_APPLETALK, ddp_handle);
2269 nbp_handle = create_dissector_handle(dissect_nbp, proto_nbp);
2270 dissector_add("ddp.type", DDP_NBP, nbp_handle);
2272 atp_handle = create_dissector_handle(dissect_atp, proto_atp);
2273 dissector_add("ddp.type", DDP_ATP, atp_handle);
2275 asp_handle = create_dissector_handle(dissect_asp, proto_asp);
2277 rtmp_request_handle = create_dissector_handle(dissect_rtmp_request, proto_rtmp);
2278 rtmp_data_handle = create_dissector_handle(dissect_rtmp_data, proto_rtmp);
2279 dissector_add("ddp.type", DDP_RTMPREQ, rtmp_request_handle);
2280 dissector_add("ddp.type", DDP_RTMPDATA, rtmp_data_handle);
2282 zip_ddp_handle = create_dissector_handle(dissect_ddp_zip, proto_zip);
2283 dissector_add("ddp.type", DDP_ZIP, zip_ddp_handle);
2285 zip_atp_handle = create_dissector_handle(dissect_atp_zip, proto_zip);
2287 llap_handle = create_dissector_handle(dissect_llap, proto_llap);
2288 dissector_add("wtap_encap", WTAP_ENCAP_LOCALTALK, llap_handle);
2290 register_init_routine( atp_init);
2291 register_init_routine( &asp_reinit);
2293 afp_handle = find_dissector("afp");
2294 data_handle = find_dissector("data");