2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
5 * $Id: packet-atalk.c,v 1.88 2003/04/20 11:36:11 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;
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 if (fd_head != NULL) {
861 if (fd_head->next != NULL) {
862 new_tvb = process_reassembled_data(tvb, pinfo, "Reassembled ATP",
863 fd_head, &atp_frag_items, NULL, atp_tree);
866 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1, -1);
874 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1,- 1);
878 pinfo->private_data = &aspinfo;
879 /* if port == 6 it's not an ASP packet but a ZIP packet */
880 if (pinfo->srcport == 6 || pinfo->destport == 6 )
881 call_dissector(zip_atp_handle, new_tvb, pinfo, tree);
883 call_dissector(asp_handle, new_tvb, pinfo, tree);
886 /* Just show this as a fragment. */
887 new_tvb = tvb_new_subset (tvb, ATP_HDRSIZE -1, -1, -1);
888 call_dissector(data_handle, new_tvb, pinfo, tree);
890 pinfo->fragmented = save_fragmented;
895 copy and paste from dsi
898 dissect_asp_reply_get_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
900 proto_tree *sub_tree;
906 guint16 sign_ofs = 0;
917 ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
918 tree = proto_item_add_subtree(ti, ett_asp_status);
920 machine_ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
921 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %u", machine_ofs);
923 machine_ofs += offset;
925 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
926 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %u", ofs);
928 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
929 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %u", ofs);
931 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
932 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %u", ofs);
934 ofs = offset +AFPSTATUS_FLAGOFF;
935 ti = proto_tree_add_item(tree, hf_asp_server_flag, tvb, ofs, 2, FALSE);
936 sub_tree = proto_item_add_subtree(ti, ett_asp_status_server_flag);
937 proto_tree_add_item(sub_tree, hf_asp_server_flag_copyfile , tvb, ofs, 2, FALSE);
938 proto_tree_add_item(sub_tree, hf_asp_server_flag_passwd , tvb, ofs, 2, FALSE);
939 proto_tree_add_item(sub_tree, hf_asp_server_flag_no_save_passwd, tvb, ofs, 2, FALSE);
940 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_msg , tvb, ofs, 2, FALSE);
941 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_sig , tvb, ofs, 2, FALSE);
942 proto_tree_add_item(sub_tree, hf_asp_server_flag_tcpip , tvb, ofs, 2, FALSE);
943 proto_tree_add_item(sub_tree, hf_asp_server_flag_notify , tvb, ofs, 2, FALSE);
944 proto_tree_add_item(sub_tree, hf_asp_server_flag_reconnect , tvb, ofs, 2, FALSE);
945 proto_tree_add_item(sub_tree, hf_asp_server_flag_directory , tvb, ofs, 2, FALSE);
946 proto_tree_add_item(sub_tree, hf_asp_server_flag_utf8_name , tvb, ofs, 2, FALSE);
947 proto_tree_add_item(sub_tree, hf_asp_server_flag_fast_copy , tvb, ofs, 2, FALSE);
949 proto_tree_add_item(tree, hf_asp_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, FALSE);
951 flag = tvb_get_ntohs(tvb, ofs);
952 if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
953 ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
957 sign_ofs = tvb_get_ntohs(tvb, ofs);
958 proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %u", sign_ofs);
962 if ((flag & AFPSRVRINFO_TCPIP) && ofs < machine_ofs ) {
963 adr_ofs = tvb_get_ntohs(tvb, ofs);
964 proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %u", adr_ofs);
969 if ((flag & AFPSRVRINFO_SRVDIRECTORY) && ofs < machine_ofs) {
970 dir_ofs = tvb_get_ntohs(tvb, ofs);
971 proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %u", dir_ofs);
976 if ((flag & AFPSRVRINFO_SRVUTF8) && ofs < machine_ofs) {
977 utf_ofs = tvb_get_ntohs(tvb, ofs);
978 proto_tree_add_text(tree, tvb, ofs, 2, "UTF-8 Server name offset: %u", utf_ofs);
984 proto_tree_add_item(tree, hf_asp_server_type, tvb, machine_ofs, 1, FALSE);
986 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
988 nbe = tvb_get_guint8(tvb, ofs);
989 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %u", nbe);
991 sub_tree = proto_item_add_subtree(ti, ett_asp_vers);
992 for (i = 0; i < nbe; i++) {
993 len = tvb_get_guint8(tvb, ofs) +1;
994 proto_tree_add_item(sub_tree, hf_asp_server_vers, tvb, ofs, 1, FALSE);
999 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
1001 nbe = tvb_get_guint8(tvb, ofs);
1002 ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %u", nbe);
1004 sub_tree = proto_item_add_subtree(ti, ett_asp_uams);
1005 for (i = 0; i < nbe; i++) {
1006 len = tvb_get_guint8(tvb, ofs) +1;
1007 proto_tree_add_item(sub_tree, hf_asp_server_uams, tvb, ofs, 1, FALSE);
1012 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1014 proto_tree_add_item(tree, hf_asp_server_icon, tvb, ofs, 256, FALSE);
1017 proto_tree_add_item(tree, hf_asp_server_signature, tvb, sign_ofs, 16, FALSE);
1021 proto_tree *adr_tree;
1029 nbe = tvb_get_guint8(tvb, ofs);
1030 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %u", nbe);
1032 adr_tree = proto_item_add_subtree(ti, ett_asp_addr);
1033 for (i = 0; i < nbe; i++) {
1036 len = tvb_get_guint8(tvb, ofs);
1037 type = tvb_get_guint8(tvb, ofs +1);
1040 ip = tvb_get_ptr(tvb, ofs+2, 4);
1041 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", ip_to_str(ip));
1043 case 2: /* IP + port */
1044 ip = tvb_get_ptr(tvb, ofs+2, 4);
1045 port = tvb_get_ntohs(tvb, ofs+6);
1046 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%u",ip_to_str(ip),port);
1048 case 3: /* DDP, atalk_addr_to_str want host order not network */
1049 net = tvb_get_ntohs(tvb, ofs+2);
1050 node = tvb_get_guint8(tvb, ofs +4);
1051 port = tvb_get_guint8(tvb, ofs +5);
1052 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
1055 case 5: /* IP + port ssh tunnel */
1056 ip = tvb_get_ptr(tvb, ofs+2, 4);
1057 port = tvb_get_ntohs(tvb, ofs+6);
1058 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip (ssh tunnel) %s:%u",ip_to_str(ip),port);
1062 tmp = g_malloc( len -1);
1063 tvb_memcpy(tvb, tmp, ofs +2, len -2);
1065 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
1069 /* else fall to default malformed record */
1071 ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknow type : %u", type);
1075 sub_tree = proto_item_add_subtree(ti,ett_asp_addr_line);
1076 proto_tree_add_item(sub_tree, hf_asp_server_addr_len, tvb, ofs, 1, FALSE);
1078 proto_tree_add_item(sub_tree, hf_asp_server_addr_type, tvb, ofs, 1, FALSE);
1080 proto_tree_add_item(sub_tree, hf_asp_server_addr_value,tvb, ofs, len, FALSE);
1087 nbe = tvb_get_guint8(tvb, ofs);
1088 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %u", nbe);
1090 sub_tree = proto_item_add_subtree(ti, ett_asp_directory);
1091 for (i = 0; i < nbe; i++) {
1092 len = tvb_get_guint8(tvb, ofs) +1;
1093 proto_tree_add_item(sub_tree, hf_asp_server_directory, tvb, ofs, 1, FALSE);
1099 len = tvb_get_ntohs(tvb, ofs);
1100 proto_tree_add_item(tree, hf_asp_server_utf8_name_len, tvb, ofs, 2, FALSE);
1102 proto_tree_add_item(tree, hf_asp_server_utf8_name, tvb, ofs, len, FALSE);
1105 /* FIXME: offset is not updated */
1109 /* -----------------------------
1110 ASP protocol cf. inside appletalk chap. 11
1112 static struct aspinfo *
1113 get_transaction(tvbuff_t *tvb, packet_info *pinfo)
1115 struct aspinfo *aspinfo = pinfo->private_data;
1116 conversation_t *conversation;
1117 asp_request_key request_key, *new_request_key;
1118 asp_request_val *request_val;
1121 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
1122 pinfo->srcport, pinfo->destport, 0);
1124 if (conversation == NULL)
1126 conversation = conversation_new(&pinfo->src, &pinfo->dst,
1127 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1130 request_key.conversation = conversation->index;
1131 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
1132 request_key.seq = aspinfo->seq;
1134 request_val = (asp_request_val *) g_hash_table_lookup(
1135 asp_request_hash, &request_key);
1136 if (!request_val && !aspinfo->reply ) {
1137 fn = tvb_get_guint8(tvb, 0);
1138 new_request_key = g_mem_chunk_alloc(asp_request_keys);
1139 *new_request_key = request_key;
1141 request_val = g_mem_chunk_alloc(asp_request_vals);
1142 request_val->value = fn;
1144 g_hash_table_insert(asp_request_hash, new_request_key,
1151 aspinfo->command = request_val->value;
1157 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1159 struct aspinfo *aspinfo;
1161 proto_tree *asp_tree = NULL;
1166 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1167 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1168 if (check_col(pinfo->cinfo, COL_INFO))
1169 col_clear(pinfo->cinfo, COL_INFO);
1171 aspinfo = get_transaction(tvb, pinfo);
1175 fn = aspinfo->command;
1177 if (check_col(pinfo->cinfo, COL_INFO)) {
1179 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1181 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1182 val_to_str(fn, asp_func_vals, "Unknown (0x%01x)"), aspinfo->seq);
1186 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, FALSE);
1187 asp_tree = proto_item_add_subtree(ti, ett_asp);
1189 if (!aspinfo->reply) {
1191 /* let the called deal with asp_tree == NULL */
1193 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, FALSE);
1197 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1199 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, FALSE);
1202 case ASPFUNC_TICKLE:
1204 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1206 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1210 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1212 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1216 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1218 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, FALSE);
1223 proto_item_set_len(asp_tree, 4);
1224 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1226 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1228 len = tvb_reported_length_remaining(tvb,offset);
1229 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1230 call_dissector(afp_handle, new_tvb, pinfo, tree);
1232 case ASPFUNC_WRTCONT:
1233 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1235 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1237 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, FALSE);
1241 proto_item_set_len(asp_tree, 4);
1243 len = tvb_reported_length_remaining(tvb,offset);
1244 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1251 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1254 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1256 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1258 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, FALSE);
1262 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1264 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1266 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1270 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1272 dissect_asp_reply_get_status(tvb, pinfo, asp_tree, offset);
1276 proto_item_set_len(asp_tree, 4);
1277 aspinfo->code = tvb_get_ntohl(tvb, offset);;
1278 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, FALSE);
1280 len = tvb_reported_length_remaining(tvb,offset);
1281 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1282 call_dissector(afp_handle, new_tvb, pinfo, tree);
1284 case ASPFUNC_TICKLE:
1285 case ASPFUNC_WRTCONT:
1286 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1288 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1290 proto_item_set_len(asp_tree, 4);
1292 len = tvb_reported_length_remaining(tvb,offset);
1293 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1299 /* -----------------------------
1300 ZIP protocol cf. inside appletalk chap. 8
1303 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1305 struct aspinfo *aspinfo;
1307 proto_tree *zip_tree;
1308 proto_tree *sub_tree;
1314 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1315 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1316 if (check_col(pinfo->cinfo, COL_INFO))
1317 col_clear(pinfo->cinfo, COL_INFO);
1319 aspinfo = get_transaction(tvb, pinfo);
1323 fn = aspinfo->command;
1325 if (check_col(pinfo->cinfo, COL_INFO)) {
1327 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1329 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1330 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1336 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, FALSE);
1337 zip_tree = proto_item_add_subtree(ti, ett_zip);
1339 if (!aspinfo->reply) {
1340 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, FALSE);
1343 case 7: /* start_index = 0 */
1346 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1348 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, FALSE);
1355 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1360 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, FALSE);
1363 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1365 count = tvb_get_ntohs(tvb, offset);
1366 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, FALSE);
1368 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1369 for (i= 1; i <= count; i++) {
1370 len = tvb_get_guint8(tvb, offset);
1371 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1380 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1382 proto_tree *zip_tree = NULL;
1387 proto_tree *flag_tree;
1388 proto_tree *sub_tree;
1389 proto_tree *net_tree;
1395 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1396 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1397 if (check_col(pinfo->cinfo, COL_INFO))
1398 col_clear(pinfo->cinfo, COL_INFO);
1400 fn = tvb_get_guint8(tvb, 0);
1401 if (check_col(pinfo->cinfo, COL_INFO)) {
1402 col_add_str(pinfo->cinfo, COL_INFO,
1403 val_to_str(fn, zip_function_vals, "Unknown ZIP function (%02x)"));
1409 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, FALSE);
1410 zip_tree = proto_item_add_subtree(ti, ett_zip);
1412 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,FALSE);
1414 /* fn 1,7,2,8 are not tested */
1417 count = tvb_get_guint8(tvb, offset);
1418 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1420 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1421 for (i= 1; i <= count; i++) {
1422 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, FALSE);
1426 case 7: /* Notify */
1427 flag = tvb_get_guint8(tvb, offset);
1428 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1429 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1430 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1431 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1432 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1435 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1438 len = tvb_get_guint8(tvb, offset);
1439 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1442 len = tvb_get_guint8(tvb, offset);
1443 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1445 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1448 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1452 case 8: /* Extended Reply */
1453 count = tvb_get_guint8(tvb, offset);
1454 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1456 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1457 for (i= 1; i <= count; i++) {
1458 net = tvb_get_ntohs(tvb, offset);
1459 ti = proto_tree_add_text(zip_tree, tvb, offset , 2, "Zone for network : %u", net);
1460 net_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1461 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, FALSE);
1463 len = tvb_get_guint8(tvb, offset);
1464 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1469 case 5 : /* GetNetInfo request */
1470 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1472 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1474 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1477 case 6 : /* GetNetInfo reply */
1478 flag = tvb_get_guint8(tvb, offset);
1479 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1480 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1481 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1482 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1483 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1486 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, FALSE);
1489 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, FALSE);
1492 len = tvb_get_guint8(tvb, offset);
1493 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1496 len = tvb_get_guint8(tvb, offset);
1497 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1499 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1501 if ((flag & 0x80) != 0)
1502 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,FALSE);
1511 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, guint8 dnode,
1512 guint8 snode, proto_tree *tree)
1518 proto_tree *ddp_tree = NULL;
1520 static struct atalk_ddp_addr src, dst;
1523 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1524 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1525 if (check_col(pinfo->cinfo, COL_INFO))
1526 col_clear(pinfo->cinfo, COL_INFO);
1529 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1531 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1533 len = tvb_get_ntohs(tvb, 0);
1535 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1536 dport = tvb_get_guint8(tvb, 2);
1538 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1539 sport = tvb_get_guint8(tvb, 3);
1541 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1542 type = tvb_get_guint8(tvb, 4);
1548 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1549 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1550 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1551 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1553 pinfo->ptype = PT_DDP;
1554 pinfo->destport = dport;
1555 pinfo->srcport = sport;
1557 if (check_col(pinfo->cinfo, COL_INFO)) {
1558 col_add_str(pinfo->cinfo, COL_INFO,
1559 val_to_str(type, op_vals, "Unknown DDP protocol (%02x)"));
1562 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1563 4, 3, atalk_addr_to_str(&src));
1564 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1565 6, 3, atalk_addr_to_str(&dst));
1567 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1569 new_tvb = tvb_new_subset(tvb, DDP_SHORT_HEADER_SIZE, -1, -1);
1571 if (!dissector_try_port(ddp_dissector_table, type, new_tvb, pinfo, tree))
1572 call_dissector(data_handle,new_tvb, pinfo, tree);
1576 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1579 proto_tree *ddp_tree;
1581 static struct atalk_ddp_addr src, dst;
1584 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1585 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1586 if (check_col(pinfo->cinfo, COL_INFO))
1587 col_clear(pinfo->cinfo, COL_INFO);
1589 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1590 ddp.dnet=g_ntohs(ddp.dnet);
1591 ddp.snet=g_ntohs(ddp.snet);
1592 ddp.sum=g_ntohs(ddp.sum);
1593 ddp.hops_len=g_ntohs(ddp.hops_len);
1596 src.node = ddp.snode;
1598 dst.node = ddp.dnode;
1599 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1600 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1601 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1602 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1604 pinfo->ptype = PT_DDP;
1605 pinfo->destport = ddp.dport;
1606 pinfo->srcport = ddp.sport;
1608 if (check_col(pinfo->cinfo, COL_INFO))
1609 col_add_str(pinfo->cinfo, COL_INFO,
1610 val_to_str(ddp.type, op_vals, "Unknown DDP protocol (%02x)"));
1613 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1615 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1617 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1618 4, 3, atalk_addr_to_str(&src));
1619 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1620 6, 3, atalk_addr_to_str(&dst));
1622 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1623 ddp_hops(ddp.hops_len));
1624 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1625 ddp_len(ddp.hops_len));
1626 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1628 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1630 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1632 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1634 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1636 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1638 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1640 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1644 new_tvb = tvb_new_subset(tvb, DDP_HEADER_SIZE, -1, -1);
1646 if (!dissector_try_port(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1647 call_dissector(data_handle,new_tvb, pinfo, tree);
1650 static const value_string llap_type_vals[] = {
1651 {0x01, "Short DDP"},
1654 {0x82, "Acknowledgement"},
1661 capture_llap(packet_counts *ld)
1667 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1672 proto_tree *llap_tree = NULL;
1676 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1677 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1678 if (check_col(pinfo->cinfo, COL_INFO))
1679 col_clear(pinfo->cinfo, COL_INFO);
1682 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, FALSE);
1683 llap_tree = proto_item_add_subtree(ti, ett_llap);
1686 dnode = tvb_get_guint8(tvb, 0);
1688 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, dnode);
1689 snode = tvb_get_guint8(tvb, 1);
1691 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, snode);
1692 type = tvb_get_guint8(tvb, 2);
1693 if (check_col(pinfo->cinfo, COL_INFO)) {
1694 col_add_str(pinfo->cinfo, COL_INFO,
1695 val_to_str(type, llap_type_vals, "Unknown LLAP type (%02x)"));
1698 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1700 new_tvb = tvb_new_subset(tvb, 3, -1, -1);
1702 if (proto_is_protocol_enabled(proto_ddp)) {
1703 pinfo->current_proto = "DDP";
1707 dissect_ddp_short(new_tvb, pinfo, dnode, snode, tree);
1711 dissect_ddp(new_tvb, pinfo, tree);
1715 call_dissector(data_handle,new_tvb, pinfo, tree);
1722 fragment_table_init(&atp_fragment_table);
1723 reassembled_table_init(&atp_reassembled_table);
1725 if (atp_request_hash)
1726 g_hash_table_destroy(atp_request_hash);
1727 if (atp_request_keys)
1728 g_mem_chunk_destroy(atp_request_keys);
1729 if (atp_request_vals)
1730 g_mem_chunk_destroy(atp_request_vals);
1732 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1734 atp_request_keys = g_mem_chunk_new("atp_request_keys",
1735 sizeof(asp_request_key),
1736 asp_packet_init_count * sizeof(asp_request_key),
1738 atp_request_vals = g_mem_chunk_new("atp_request_vals",
1739 sizeof(asp_request_val),
1740 asp_packet_init_count * sizeof(asp_request_val),
1748 if (asp_request_hash)
1749 g_hash_table_destroy(asp_request_hash);
1750 if (asp_request_keys)
1751 g_mem_chunk_destroy(asp_request_keys);
1752 if (asp_request_vals)
1753 g_mem_chunk_destroy(asp_request_vals);
1755 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1757 asp_request_keys = g_mem_chunk_new("asp_request_keys",
1758 sizeof(asp_request_key),
1759 asp_packet_init_count * sizeof(asp_request_key),
1761 asp_request_vals = g_mem_chunk_new("asp_request_vals",
1762 sizeof(asp_request_val),
1763 asp_packet_init_count * sizeof(asp_request_val),
1769 proto_register_atalk(void)
1771 static hf_register_info hf_llap[] = {
1773 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1777 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1781 { "Type", "llap.type", FT_UINT8, BASE_HEX, VALS(llap_type_vals), 0x0,
1785 static hf_register_info hf_ddp[] = {
1787 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1791 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1795 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1799 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1803 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1807 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1811 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1815 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1819 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1822 { &hf_ddp_dst_socket,
1823 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1826 { &hf_ddp_src_socket,
1827 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1831 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC, VALS(op_vals), 0x0,
1835 static hf_register_info hf_nbp[] = {
1837 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1838 VALS(nbp_op_vals), 0xF0, "Operation", HFILL }},
1840 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1841 NULL, 0x0, "Info", HFILL }},
1843 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1844 NULL, 0x0F, "Count", HFILL }},
1846 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1847 NULL, 0x0, "Network", HFILL }},
1848 { &hf_nbp_node_node,
1849 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1850 NULL, 0x0, "Node", HFILL }},
1851 { &hf_nbp_node_port,
1852 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1853 NULL, 0x0, "Port", HFILL }},
1854 { &hf_nbp_node_enum,
1855 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1856 NULL, 0x0, "Enumerator", HFILL }},
1857 { &hf_nbp_node_object,
1858 { "Object", "nbp.object", FT_STRING, BASE_DEC,
1859 NULL, 0x0, "Object", HFILL }},
1860 { &hf_nbp_node_type,
1861 { "Type", "nbp.type", FT_STRING, BASE_DEC,
1862 NULL, 0x0, "Type", HFILL }},
1863 { &hf_nbp_node_zone,
1864 { "Zone", "nbp.zone", FT_STRING, BASE_DEC,
1865 NULL, 0x0, "Zone", HFILL }},
1867 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1868 NULL, 0x0, "Transaction ID", HFILL }}
1871 static hf_register_info hf_rtmp[] = {
1873 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1874 NULL, 0x0, "Net", HFILL }},
1876 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1877 NULL, 0x0, "Node", HFILL }},
1878 { &hf_rtmp_node_len,
1879 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1880 NULL, 0x0, "Node Length", HFILL }},
1881 { &hf_rtmp_tuple_net,
1882 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1883 NULL, 0x0, "Net", HFILL }},
1884 { &hf_rtmp_tuple_range_start,
1885 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
1886 NULL, 0x0, "Range Start", HFILL }},
1887 { &hf_rtmp_tuple_range_end,
1888 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
1889 NULL, 0x0, "Range End", HFILL }},
1890 { &hf_rtmp_tuple_dist,
1891 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
1892 NULL, 0x0, "Distance", HFILL }},
1893 { &hf_rtmp_function,
1894 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
1895 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
1898 static hf_register_info hf_atp[] = {
1900 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
1901 NULL, 0, "control info", HFILL }},
1904 { "Function", "atp.function", FT_UINT8, BASE_DEC,
1905 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
1909 { "XO", "atp.xo", FT_BOOLEAN, 8,
1910 NULL, ATP_XO, "Exactly-once flag", HFILL }},
1913 { "EOM", "atp.eom", FT_BOOLEAN, 8,
1914 NULL, ATP_EOM, "End-of-message", HFILL }},
1917 { "STS", "atp.sts", FT_BOOLEAN, 8,
1918 NULL, ATP_STS, "Send transaction status", HFILL }},
1920 { &hf_atp_treltimer,
1921 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
1922 VALS(atp_trel_timer_vals), 0x07, "TRel timer", HFILL }},
1925 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
1926 NULL, 0x0, "Bitmap or sequence number", HFILL }},
1929 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
1930 NULL, 0x0, "Transaction id", HFILL }},
1931 { &hf_atp_user_bytes,
1932 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
1933 NULL, 0x0, "User bytes", HFILL }},
1935 { &hf_atp_segment_overlap,
1936 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
1937 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
1939 { &hf_atp_segment_overlap_conflict,
1940 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
1941 FT_BOOLEAN, BASE_NONE,
1942 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
1944 { &hf_atp_segment_multiple_tails,
1945 { "Multiple tail segments found", "atp.segment.multipletails",
1946 FT_BOOLEAN, BASE_NONE,
1947 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
1949 { &hf_atp_segment_too_long_segment,
1950 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
1951 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
1953 { &hf_atp_segment_error,
1954 {"Desegmentation error", "atp.segment.error", FT_FRAMENUM, BASE_NONE,
1955 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
1958 { "ATP Fragment", "atp.fragment", FT_FRAMENUM, BASE_NONE,
1959 NULL, 0x0, "ATP Fragment", HFILL }},
1962 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
1963 NULL, 0x0, "ATP Fragments", HFILL }},
1965 { &hf_atp_reassembled_in,
1966 { "Reassembled ATP in frame", "atp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1967 "This ATP packet is reassembled in this frame", HFILL }}
1970 static hf_register_info hf_asp[] = {
1972 { "asp function", "asp.function", FT_UINT8, BASE_DEC,
1973 VALS(asp_func_vals), 0, "asp function", HFILL }},
1976 { "asp error", "asp.error", FT_INT32, BASE_DEC,
1977 VALS(asp_error_vals), 0, "return error code", HFILL }},
1980 { "Version", "asp.version", FT_UINT16, BASE_HEX,
1981 NULL, 0, "asp version", HFILL }},
1983 { &hf_asp_attn_code,
1984 { "Attn code", "asp.attn_code", FT_UINT16, BASE_HEX,
1985 NULL, 0, "asp attention code", HFILL }},
1987 { &hf_asp_init_error,
1988 { "Error", "asp.init_error", FT_UINT16, BASE_DEC,
1989 NULL, 0, "asp init error", HFILL }},
1991 { &hf_asp_session_id,
1992 { "Session ID", "asp.session_id", FT_UINT8, BASE_DEC,
1993 NULL, 0, "asp session id", HFILL }},
1996 { "Socket", "asp.socket", FT_UINT8, BASE_DEC,
1997 NULL, 0, "asp socket", HFILL }},
2000 { "Sequence", "asp.seq", FT_UINT16, BASE_DEC,
2001 NULL, 0, "asp sequence number", HFILL }},
2004 { "size", "asp.size", FT_UINT16, BASE_DEC,
2005 NULL, 0, "asp available size for reply", HFILL }},
2007 { &hf_asp_zero_value,
2008 { "Pad (0)", "asp.zero_value",
2009 FT_BYTES, BASE_HEX, NULL, 0x0,
2013 { &hf_asp_server_name,
2014 { "Server name", "asp.server_name",
2015 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2016 "Server name", HFILL }},
2018 { &hf_asp_server_type,
2019 { "Server type", "asp.server_type",
2020 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2021 "Server type", HFILL }},
2023 { &hf_asp_server_vers,
2024 { "AFP version", "asp.server_vers",
2025 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2026 "AFP version", HFILL }},
2028 { &hf_asp_server_uams,
2029 { "UAM", "asp.server_uams",
2030 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2033 { &hf_asp_server_icon,
2034 { "Icon bitmap", "asp.server_icon",
2035 FT_BYTES, BASE_HEX, NULL, 0x0,
2036 "Server icon bitmap", HFILL }},
2038 { &hf_asp_server_directory,
2039 { "Directory service", "asp.server_directory",
2040 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2041 "Server directory service", HFILL }},
2043 { &hf_asp_server_signature,
2044 { "Server signature", "asp.server_signature",
2045 FT_BYTES, BASE_HEX, NULL, 0x0,
2046 "Server signature", HFILL }},
2048 { &hf_asp_server_flag,
2049 { "Flag", "asp.server_flag",
2050 FT_UINT16, BASE_HEX, NULL, 0x0,
2051 "Server capabilities flag", HFILL }},
2052 { &hf_asp_server_flag_copyfile,
2053 { "Support copyfile", "asp.server_flag.copyfile",
2054 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_COPY,
2055 "Server support copyfile", HFILL }},
2056 { &hf_asp_server_flag_passwd,
2057 { "Support change password", "asp.server_flag.passwd",
2058 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_PASSWD,
2059 "Server support change password", HFILL }},
2060 { &hf_asp_server_flag_no_save_passwd,
2061 { "Don't allow save password", "asp.server_flag.no_save_passwd",
2062 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_NOSAVEPASSWD,
2063 "Don't allow save password", HFILL }},
2064 { &hf_asp_server_flag_srv_msg,
2065 { "Support server message", "asp.server_flag.srv_msg",
2066 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVMSGS,
2067 "Support server message", HFILL }},
2068 { &hf_asp_server_flag_srv_sig,
2069 { "Support server signature", "asp.server_flag.srv_sig",
2070 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVSIGNATURE,
2071 "Support server signature", HFILL }},
2072 { &hf_asp_server_flag_tcpip,
2073 { "Support TCP/IP", "asp.server_flag.tcpip",
2074 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_TCPIP,
2075 "Server support TCP/IP", HFILL }},
2076 { &hf_asp_server_flag_notify,
2077 { "Support server notifications", "asp.server_flag.notify",
2078 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVNOTIFY,
2079 "Server support notifications", HFILL }},
2080 { &hf_asp_server_flag_reconnect,
2081 { "Support server reconnect", "asp.server_flag.reconnect",
2082 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVRECONNECT,
2083 "Server support reconnect", HFILL }},
2084 { &hf_asp_server_flag_directory,
2085 { "Support directory services", "asp.server_flag.directory",
2086 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVDIRECTORY,
2087 "Server support directory services", HFILL }},
2088 { &hf_asp_server_flag_utf8_name,
2089 { "Support UTF8 server name", "asp.server_flag.utf8_name",
2090 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVUTF8,
2091 "Server support UTF8 server name", HFILL }},
2092 { &hf_asp_server_flag_fast_copy,
2093 { "Support fast copy", "asp.server_flag.fast_copy",
2094 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_FASTBOZO,
2095 "Server support fast copy", HFILL }},
2097 { &hf_asp_server_addr_len,
2098 { "Length", "asp.server_addr.len",
2099 FT_UINT8, BASE_DEC, NULL, 0x0,
2100 "Address length.", HFILL }},
2102 { &hf_asp_server_addr_type,
2103 { "Type", "asp.server_addr.type",
2104 FT_UINT8, BASE_DEC, VALS(afp_server_addr_type_vals), 0x0,
2105 "Address type.", HFILL }},
2107 { &hf_asp_server_addr_value,
2108 { "Value", "asp.server_addr.value",
2109 FT_BYTES, BASE_HEX, NULL, 0x0,
2110 "Address value", HFILL }},
2112 { &hf_asp_server_utf8_name_len,
2113 { "Server name length", "asp.server_utf8_name_len",
2114 FT_UINT16, BASE_DEC, NULL, 0x0,
2115 "UTF8 server name length", HFILL }},
2117 { &hf_asp_server_utf8_name,
2118 { "Server name (UTF8)", "asp.server_utf8_name",
2119 FT_STRING, BASE_NONE, NULL, 0x0,
2120 "Server name (UTF8)", HFILL }},
2123 static hf_register_info hf_zip[] = {
2125 { "Function", "zip.function", FT_UINT8, BASE_DEC, VALS(zip_function_vals), 0x0,
2126 "ZIP function", HFILL }},
2128 { &hf_zip_zero_value,
2129 { "Pad (0)", "zip.zero_value",FT_BYTES, BASE_HEX, NULL, 0x0,
2132 { &hf_zip_atp_function,
2133 { "Function", "zip.atp_function", FT_UINT8, BASE_DEC, VALS(zip_atp_function_vals), 0x0,
2136 { &hf_zip_start_index,
2137 { "Start index", "zip.start_index", FT_UINT16, BASE_DEC, NULL, 0x0,
2141 { "Count", "zip.count", FT_UINT16, BASE_DEC, NULL, 0x0,
2144 { &hf_zip_network_count,
2145 { "Count", "zip.network_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2148 { "Network","zip.network", FT_UINT16, BASE_DEC, NULL, 0x0,
2150 { &hf_zip_network_start,
2151 { "Network start","zip.network_start", FT_UINT16, BASE_DEC, NULL, 0x0,
2153 { &hf_zip_network_end,
2154 { "Network end", "zip.network_end", FT_UINT16, BASE_DEC, NULL, 0x0,
2158 { "Flags", "zip.flags", FT_BOOLEAN, 8, NULL, 0xC0,
2161 { &hf_zip_last_flag,
2162 { "Last Flag", "zip.last_flag", FT_BOOLEAN, 8, NULL, 0,
2163 "Non zero if contains last zone name in the zone list", HFILL }},
2165 { &hf_zip_flags_zone_invalid,
2166 { "Zone invalid", "zip.flags.zone_invalid", FT_BOOLEAN, 8, NULL, 0x80,
2169 { &hf_zip_flags_use_broadcast,
2170 { "Use broadcast","zip.flags.use_broadcast", FT_BOOLEAN, 8, NULL, 0x40,
2173 { &hf_zip_flags_only_one_zone,
2174 { "Only one zone","zip.flags.only_one_zone", FT_BOOLEAN, 8, NULL, 0x20,
2177 { &hf_zip_zone_name,
2178 { "Zone", "zip.zone_name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2181 { &hf_zip_default_zone,
2182 { "Default zone", "zip.default_zone",FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2185 { &hf_zip_multicast_length,
2186 { "Multicast length", "zip.multicast_length", FT_UINT8, BASE_DEC, NULL, 0x0,
2187 "Multicast address length", HFILL }},
2189 { &hf_zip_multicast_address,
2190 { "Multicast address", "zip.multicast_address",FT_BYTES, BASE_HEX, NULL, 0x0,
2191 "Multicast address", HFILL }},
2195 static gint *ett[] = {
2206 &ett_asp_status_server_flag,
2222 &ett_zip_zones_list,
2223 &ett_zip_network_list,
2225 module_t *atp_module;
2227 proto_llap = proto_register_protocol("LocalTalk Link Access Protocol", "LLAP", "llap");
2228 proto_register_field_array(proto_llap, hf_llap, array_length(hf_llap));
2230 proto_ddp = proto_register_protocol("Datagram Delivery Protocol", "DDP", "ddp");
2231 proto_register_field_array(proto_ddp, hf_ddp, array_length(hf_ddp));
2233 proto_nbp = proto_register_protocol("Name Binding Protocol", "NBP", "nbp");
2234 proto_register_field_array(proto_nbp, hf_nbp, array_length(hf_nbp));
2236 proto_atp = proto_register_protocol("AppleTalk Transaction Protocol packet", "ATP", "atp");
2237 proto_register_field_array(proto_atp, hf_atp, array_length(hf_atp));
2239 proto_asp = proto_register_protocol("AppleTalk Session Protocol", "ASP", "asp");
2240 proto_register_field_array(proto_asp, hf_asp, array_length(hf_asp));
2242 proto_zip = proto_register_protocol("Zone Information Protocol", "ZIP", "zip");
2243 proto_register_field_array(proto_zip, hf_zip, array_length(hf_zip));
2245 atp_module = prefs_register_protocol(proto_atp, NULL);
2246 prefs_register_bool_preference(atp_module, "desegment",
2247 "Desegment all ATP messages spanning multiple DDP packets",
2248 "Whether the ATP dissector should desegment all messages spanning multiple DDP packets",
2251 proto_rtmp = proto_register_protocol("Routing Table Maintenance Protocol",
2253 proto_register_field_array(proto_rtmp, hf_rtmp, array_length(hf_rtmp));
2255 proto_register_subtree_array(ett, array_length(ett));
2257 /* subdissector code */
2258 ddp_dissector_table = register_dissector_table("ddp.type", "DDP packet type",
2259 FT_UINT8, BASE_HEX);
2263 proto_reg_handoff_atalk(void)
2265 dissector_handle_t ddp_handle, nbp_handle, rtmp_request_handle;
2266 dissector_handle_t atp_handle;
2267 dissector_handle_t zip_ddp_handle;
2268 dissector_handle_t rtmp_data_handle, llap_handle;
2270 ddp_handle = create_dissector_handle(dissect_ddp, proto_ddp);
2271 dissector_add("ethertype", ETHERTYPE_ATALK, ddp_handle);
2272 dissector_add("chdlctype", ETHERTYPE_ATALK, ddp_handle);
2273 dissector_add("ppp.protocol", PPP_AT, ddp_handle);
2274 dissector_add("null.type", BSD_AF_APPLETALK, ddp_handle);
2275 dissector_add("arcnet.protocol_id", ARCNET_PROTO_APPLETALK, ddp_handle);
2277 nbp_handle = create_dissector_handle(dissect_nbp, proto_nbp);
2278 dissector_add("ddp.type", DDP_NBP, nbp_handle);
2280 atp_handle = create_dissector_handle(dissect_atp, proto_atp);
2281 dissector_add("ddp.type", DDP_ATP, atp_handle);
2283 asp_handle = create_dissector_handle(dissect_asp, proto_asp);
2285 rtmp_request_handle = create_dissector_handle(dissect_rtmp_request, proto_rtmp);
2286 rtmp_data_handle = create_dissector_handle(dissect_rtmp_data, proto_rtmp);
2287 dissector_add("ddp.type", DDP_RTMPREQ, rtmp_request_handle);
2288 dissector_add("ddp.type", DDP_RTMPDATA, rtmp_data_handle);
2290 zip_ddp_handle = create_dissector_handle(dissect_ddp_zip, proto_zip);
2291 dissector_add("ddp.type", DDP_ZIP, zip_ddp_handle);
2293 zip_atp_handle = create_dissector_handle(dissect_atp_zip, proto_zip);
2295 llap_handle = create_dissector_handle(dissect_llap, proto_llap);
2296 dissector_add("wtap_encap", WTAP_ENCAP_LOCALTALK, llap_handle);
2298 register_init_routine( atp_init);
2299 register_init_routine( &asp_reinit);
2301 afp_handle = find_dissector("afp");
2302 data_handle = find_dissector("data");