2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
5 * $Id: packet-atalk.c,v 1.84 2002/11/28 03:57:49 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 <epan/atalk-utils.h>
40 #include <epan/conversation.h>
43 #include "reassemble.h"
45 #include "packet-afp.h"
47 /* Tables for reassembly of fragments. */
48 static GHashTable *atp_fragment_table = NULL;
49 static GHashTable *atp_reassembled_table = NULL;
51 /* desegmentation of ATP */
52 static gboolean atp_defragment = TRUE;
54 static dissector_handle_t afp_handle;
56 static int proto_llap = -1;
57 static int hf_llap_dst = -1;
58 static int hf_llap_src = -1;
59 static int hf_llap_type = -1;
61 static int proto_ddp = -1;
62 static int hf_ddp_hopcount = -1;
63 static int hf_ddp_len = -1;
64 static int hf_ddp_checksum = -1;
65 static int hf_ddp_dst = -1;
66 static int hf_ddp_dst_net = -1;
67 static int hf_ddp_src = -1;
68 static int hf_ddp_src_net = -1;
69 static int hf_ddp_dst_node = -1;
70 static int hf_ddp_src_node = -1;
71 static int hf_ddp_dst_socket = -1;
72 static int hf_ddp_src_socket = -1;
73 static int hf_ddp_type = -1;
76 /* --------------------------------------
77 * ATP protocol parameters
78 * from netatalk/include/atalk/atp.h
80 #define ATP_MAXDATA (578+4) /* maximum ATP data size */
81 #define ATP_BUFSIZ 587 /* maximum packet size */
82 #define ATP_HDRSIZE 5 /* includes DDP type field */
84 #define ATP_TRELMASK 0x07 /* mask all but TREL */
85 #define ATP_RELTIME 30 /* base release timer (in secs) */
87 #define ATP_TREL30 0x0 /* release time codes */
88 #define ATP_TREL1M 0x1 /* these are passed in flags of */
89 #define ATP_TREL2M 0x2 /* atp_sreq call, and set in the */
90 #define ATP_TREL4M 0x3 /* packet control info. */
91 #define ATP_TREL8M 0x4
93 /* flags for ATP options (and control byte)
95 #define ATP_XO 0x20 /* (1<<5) eXactly Once mode */
96 #define ATP_EOM 0x10 /* (1<<4) End Of Message */
97 #define ATP_STS 0x08 /* (1<<3) Transaction Status */
101 #define ATP_FUNCMASK (3<<6) /* mask all but function */
103 #define ATP_TREQ 1 /* (1<<6) Trans. REQuest */
104 #define ATP_TRESP 2 /* (2<<6) Trans. RESPonse */
105 #define ATP_TREL 3 /* (3<<6) Trans. RELease */
107 /* ------------------------- */
108 static dissector_handle_t asp_handle;
110 static int proto_atp = -1;
111 static int hf_atp_ctrlinfo = -1; /* guint8_t control information */
112 static int hf_atp_function = -1; /* bits 7,6 function */
113 static int hf_atp_xo = -1; /* bit 5 exactly-once */
114 static int hf_atp_eom = -1; /* bit 4 end-of-message */
115 static int hf_atp_sts = -1; /* bit 3 send transaction status */
116 static int hf_atp_treltimer = -1; /* bits 2,1,0 TRel timeout indicator */
118 static int hf_atp_bitmap = -1; /* guint8_t bitmap or sequence number */
119 static int hf_atp_tid = -1; /* guint16_t transaction id. */
120 static int hf_atp_user_bytes = -1;
122 static int hf_atp_segments = -1;
123 static int hf_atp_segment = -1;
124 static int hf_atp_segment_overlap = -1;
125 static int hf_atp_segment_overlap_conflict = -1;
126 static int hf_atp_segment_multiple_tails = -1;
127 static int hf_atp_segment_too_long_segment = -1;
128 static int hf_atp_segment_error = -1;
130 /* ------------------------- */
131 static int proto_zip = -1;
132 static dissector_handle_t zip_atp_handle;
134 static int hf_zip_function = -1;
135 static int hf_zip_atp_function = -1;
136 static int hf_zip_start_index = -1;
137 static int hf_zip_count = -1;
138 static int hf_zip_zero_value = -1;
140 static int hf_zip_network_count = -1;
141 static int hf_zip_network = -1;
142 static int hf_zip_network_start = -1;
143 static int hf_zip_network_end = -1;
145 static int hf_zip_flags = -1;
147 static int hf_zip_flags_zone_invalid = -1;
148 static int hf_zip_flags_use_broadcast = -1;
149 static int hf_zip_flags_only_one_zone = -1;
151 static int hf_zip_last_flag = -1;
153 static int hf_zip_zone_name = -1;
154 static int hf_zip_default_zone = -1;
156 static int hf_zip_multicast_length = -1;
157 static int hf_zip_multicast_address = -1;
159 static const value_string zip_function_vals[] = {
162 {5, "GetNetInfo request"},
163 {6, "GetNetInfo reply"},
165 {8, "Extended reply"},
169 static const value_string zip_atp_function_vals[] = {
172 {9, "GetLocalZones"},
176 static gint ett_zip = -1;
177 static gint ett_zip_flags = -1;
178 static gint ett_zip_zones_list = -1;
179 static gint ett_zip_network_list = -1;
181 /* --------------------------------
182 * from netatalk/include/atalk/ats.h
185 #define ASPFUNC_CLOSE 1
186 #define ASPFUNC_CMD 2
187 #define ASPFUNC_STAT 3
188 #define ASPFUNC_OPEN 4
189 #define ASPFUNC_TICKLE 5
190 #define ASPFUNC_WRITE 6
191 #define ASPFUNC_WRTCONT 7
192 #define ASPFUNC_ATTN 8
195 #define ASPERR_OK 0x0000
196 #define ASPERR_BADVERS 0xfbd6
197 #define ASPERR_BUFSMALL 0xfbd5
198 #define ASPERR_NOSESS 0xfbd4
199 #define ASPERR_NOSERV 0xfbd3
200 #define ASPERR_PARM 0xfbd2
201 #define ASPERR_SERVBUSY 0xfbd1
202 #define ASPERR_SESSCLOS 0xfbd0
203 #define ASPERR_SIZERR 0xfbcf
204 #define ASPERR_TOOMANY 0xfbce
205 #define ASPERR_NOACK 0xfbcd
207 static int proto_asp = -1;
208 static int hf_asp_func = -1;
209 static int hf_asp_error = -1;
210 static int hf_asp_socket = -1;
211 static int hf_asp_version = -1;
212 static int hf_asp_session_id = -1;
213 static int hf_asp_zero_value = -1;
214 static int hf_asp_init_error = -1;
215 static int hf_asp_attn_code = -1;
216 static int hf_asp_seq = -1;
217 static int hf_asp_size = -1;
219 /* status stuff same for asp and afp */
220 static int hf_asp_server_name = -1;
221 static int hf_asp_server_type = -1;
222 static int hf_asp_server_vers = -1;
223 static int hf_asp_server_uams = -1;
224 static int hf_asp_server_icon = -1;
225 static int hf_asp_server_directory = -1;
227 static int hf_asp_server_flag = -1;
228 static int hf_asp_server_flag_copyfile = -1;
229 static int hf_asp_server_flag_passwd = -1;
230 static int hf_asp_server_flag_no_save_passwd = -1;
231 static int hf_asp_server_flag_srv_msg = -1;
232 static int hf_asp_server_flag_srv_sig = -1;
233 static int hf_asp_server_flag_tcpip = -1;
234 static int hf_asp_server_flag_notify = -1;
235 static int hf_asp_server_flag_reconnect = -1;
236 static int hf_asp_server_flag_directory = -1;
237 static int hf_asp_server_flag_utf8_name = -1;
238 static int hf_asp_server_flag_fast_copy = -1;
239 static int hf_asp_server_signature = -1;
240 static int hf_asp_server_utf8_name_len = -1;
241 static int hf_asp_server_utf8_name = -1;
243 static int hf_asp_server_addr_len = -1;
244 static int hf_asp_server_addr_type = -1;
245 static int hf_asp_server_addr_value = -1;
247 static gint ett_asp_status = -1;
248 static gint ett_asp_uams = -1;
249 static gint ett_asp_vers = -1;
250 static gint ett_asp_addr = -1;
251 static gint ett_asp_addr_line = -1;
252 static gint ett_asp_directory = -1;
253 static gint ett_asp_status_server_flag = -1;
255 static guint asp_packet_init_count = 200;
258 guint32 conversation;
264 guint8 value; /* command for asp, bitmap for atp */
267 static GHashTable *asp_request_hash = NULL;
268 static GMemChunk *asp_request_keys = NULL;
269 static GMemChunk *asp_request_vals = NULL;
272 static gint asp_equal (gconstpointer v, gconstpointer v2)
274 const asp_request_key *val1 = (const asp_request_key*)v;
275 const asp_request_key *val2 = (const asp_request_key*)v2;
277 if (val1->conversation == val2->conversation &&
278 val1->seq == val2->seq &&
279 !memcmp(val1->src, val2->src, 4)) {
285 static guint asp_hash (gconstpointer v)
287 const asp_request_key *asp_key = (const asp_request_key*)v;
291 /* ------------------------------------ */
292 static GHashTable *atp_request_hash = NULL;
293 static GMemChunk *atp_request_keys = NULL;
294 static GMemChunk *atp_request_vals = NULL;
297 /* ------------------------------------ */
298 static int proto_nbp = -1;
299 static int hf_nbp_op = -1;
300 static int hf_nbp_info = -1;
301 static int hf_nbp_count = -1;
302 static int hf_nbp_tid = -1;
304 static int hf_nbp_node_net = -1;
305 static int hf_nbp_node_port = -1;
306 static int hf_nbp_node_node = -1;
307 static int hf_nbp_node_enum = -1;
308 static int hf_nbp_node_object = -1;
309 static int hf_nbp_node_type = -1;
310 static int hf_nbp_node_zone = -1;
312 static int proto_rtmp = -1;
313 static int hf_rtmp_net = -1;
314 static int hf_rtmp_node_len = -1;
315 static int hf_rtmp_node = -1;
316 static int hf_rtmp_tuple_net = -1;
317 static int hf_rtmp_tuple_range_start = -1;
318 static int hf_rtmp_tuple_range_end = -1;
319 static int hf_rtmp_tuple_dist = -1;
320 static int hf_rtmp_function = -1;
322 static gint ett_atp = -1;
324 static gint ett_atp_segments = -1;
325 static gint ett_atp_segment = -1;
326 static gint ett_atp_info = -1;
327 static gint ett_asp = -1;
329 static gint ett_nbp = -1;
330 static gint ett_nbp_info = -1;
331 static gint ett_nbp_node = -1;
332 static gint ett_rtmp = -1;
333 static gint ett_rtmp_tuple = -1;
334 static gint ett_ddp = -1;
335 static gint ett_llap = -1;
336 static gint ett_pstring = -1;
338 static const fragment_items atp_frag_items = {
343 &hf_atp_segment_overlap,
344 &hf_atp_segment_overlap_conflict,
345 &hf_atp_segment_multiple_tails,
346 &hf_atp_segment_too_long_segment,
347 &hf_atp_segment_error,
351 static dissector_table_t ddp_dissector_table;
353 static dissector_handle_t data_handle;
355 #define DDP_SHORT_HEADER_SIZE 5
358 * P = Padding, H = Hops, L = Len
362 * Assumes the argument is in host byte order.
364 #define ddp_hops(x) ( ( x >> 10) & 0x3C )
365 #define ddp_len(x) ( x & 0x03ff )
366 typedef struct _e_ddp {
367 guint16 hops_len; /* combines pad, hops, and len */
368 guint16 sum,dnet,snet;
374 #define DDP_HEADER_SIZE 13
377 static const value_string op_vals[] = {
378 {DDP_RTMPDATA, "AppleTalk Routing Table response or data" },
379 {DDP_NBP, "AppleTalk Name Binding Protocol packet"},
380 {DDP_ATP, "AppleTalk Transaction Protocol packet"},
381 {DDP_AEP, "AppleTalk Echo Protocol packet"},
382 {DDP_RTMPREQ, "AppleTalk Routing Table request"},
383 {DDP_ZIP, "AppleTalk Zone Information Protocol packet"},
384 {DDP_ADSP, "AppleTalk Data Stream Protocol"},
385 {DDP_EIGRP, "Cisco EIGRP for AppleTalk"},
389 static const value_string rtmp_function_vals[] = {
391 {2, "Route Data Request (split horizon processed)"},
392 {3, "Route Data Request (no split horizon processing)"},
396 #define NBP_BROADCAST 1
398 #define NBP_FORWARD 4
401 static const value_string nbp_op_vals[] = {
402 {NBP_BROADCAST, "broadcast request"},
403 {NBP_LOOKUP, "lookup"},
404 {NBP_FORWARD, "forward request"},
405 {NBP_REPLY, "reply"},
409 static const value_string atp_function_vals[] = {
410 {ATP_TREQ ,"REQuest"},
411 {ATP_TRESP ,"RESPonse"},
412 {ATP_TREL ,"RELease"},
416 static const value_string atp_trel_timer_vals[] = {
427 static const value_string asp_func_vals[] = {
428 {ASPFUNC_CLOSE, "CloseSession" },
429 {ASPFUNC_CMD, "Command" },
430 {ASPFUNC_STAT, "GetStatus" },
431 {ASPFUNC_OPEN, "OpenSession" },
432 {ASPFUNC_TICKLE, "Tickle" },
433 {ASPFUNC_WRITE, "Write" },
434 {ASPFUNC_WRTCONT, "Write Cont" },
435 {ASPFUNC_ATTN, "Attention" },
438 const value_string asp_error_vals[] = {
439 {AFP_OK , "success"},
440 {AFPERR_ACCESS , "permission denied" },
441 {AFPERR_AUTHCONT , "logincont" },
442 {AFPERR_BADUAM , "uam doesn't exist" },
443 {AFPERR_BADVERS , "bad afp version number" },
444 {AFPERR_BITMAP , "invalid bitmap" },
445 {AFPERR_CANTMOVE , "can't move file" },
446 {AFPERR_DENYCONF , "file synchronization locks conflict" },
447 {AFPERR_DIRNEMPT , "directory not empty" },
448 {AFPERR_DFULL , "disk full" },
449 {AFPERR_EOF , "end of file" },
450 {AFPERR_BUSY , "FileBusy" },
451 {AFPERR_FLATVOL , "volume doesn't support directories" },
452 {AFPERR_NOITEM , "ItemNotFound" },
453 {AFPERR_LOCK , "LockErr" },
454 {AFPERR_MISC , "misc. err" },
455 {AFPERR_NLOCK , "no more locks" },
456 {AFPERR_NOSRVR , "no response by server at that address" },
457 {AFPERR_EXIST , "object already exists" },
458 {AFPERR_NOOBJ , "object not found" },
459 {AFPERR_PARAM , "parameter error" },
460 {AFPERR_NORANGE , "no range lock" },
461 {AFPERR_RANGEOVR , "range overlap" },
462 {AFPERR_SESSCLOS , "session closed" },
463 {AFPERR_NOTAUTH , "user not authenticated" },
464 {AFPERR_NOOP , "command not supported" },
465 {AFPERR_BADTYPE , "object is the wrong type" },
466 {AFPERR_NFILE , "too many files open" },
467 {AFPERR_SHUTDOWN , "server is going down" },
468 {AFPERR_NORENAME , "can't rename" },
469 {AFPERR_NODIR , "couldn't find directory" },
470 {AFPERR_ITYPE , "wrong icon type" },
471 {AFPERR_VLOCK , "volume locked" },
472 {AFPERR_OLOCK , "object locked" },
473 {AFPERR_CTNSHRD , "share point contains a share point" },
474 {AFPERR_NOID , "file thread not found" },
475 {AFPERR_EXISTID , "file already has an id" },
476 {AFPERR_DIFFVOL , "different volume" },
477 {AFPERR_CATCHNG , "catalog has changed" },
478 {AFPERR_SAMEOBJ , "source file == destination file" },
479 {AFPERR_BADID , "non-existent file id" },
480 {AFPERR_PWDSAME , "same password/can't change password" },
481 {AFPERR_PWDSHORT , "password too short" },
482 {AFPERR_PWDEXPR , "password expired" },
483 {AFPERR_INSHRD , "folder being shared is inside a shared folder." },
484 {AFPERR_INTRASH , "shared folder in trash." },
485 {AFPERR_PWDCHNG , "password needs to be changed" },
486 {AFPERR_PWDPOLCY , "password fails policy check" },
487 {AFPERR_USRLOGIN , "user already logged on" },
491 * XXX - do this with an FT_UINT_STRING?
492 * Unfortunately, you can't extract from an FT_UINT_STRING the string,
493 * which we'd want to do in order to put it into the "Data:" portion.
495 * Are these always in the Mac extended character set?
497 static int dissect_pascal_string(tvbuff_t *tvb, int offset, proto_tree *tree,
502 len = tvb_get_guint8(tvb, offset);
512 * XXX - if we could do this inside the protocol tree
513 * code, we could perhaps avoid allocating and freeing
514 * this string buffer.
516 tmp = g_malloc( len+1 );
517 tvb_memcpy(tvb, tmp, offset, len);
519 item = proto_tree_add_string(tree, hf_index, tvb, offset-1, len+1, tmp);
521 subtree = proto_item_add_subtree(item, ett_pstring);
522 proto_tree_add_text(subtree, tvb, offset-1, 1, "Length: %d", len);
523 proto_tree_add_text(subtree, tvb, offset, len, "Data: %s", tmp);
533 dissect_rtmp_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
534 proto_tree *rtmp_tree;
538 if (check_col(pinfo->cinfo, COL_PROTOCOL))
539 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
540 if (check_col(pinfo->cinfo, COL_INFO))
541 col_clear(pinfo->cinfo, COL_INFO);
543 function = tvb_get_guint8(tvb, 0);
545 if (check_col(pinfo->cinfo, COL_INFO))
546 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
547 val_to_str(function, rtmp_function_vals, "Unknown function (%02x)"));
550 ti = proto_tree_add_item(tree, proto_rtmp, tvb, 0, 1, FALSE);
551 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
553 proto_tree_add_uint(rtmp_tree, hf_rtmp_function, tvb, 0, 1, function);
558 dissect_rtmp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
559 proto_tree *rtmp_tree;
563 guint8 nodelen,nodelen_bits;
564 guint16 node; /* might be more than 8 bits */
567 if (check_col(pinfo->cinfo, COL_PROTOCOL))
568 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
569 if (check_col(pinfo->cinfo, COL_INFO))
570 col_clear(pinfo->cinfo, COL_INFO);
572 net = tvb_get_ntohs(tvb, offset);
573 nodelen_bits = tvb_get_guint8(tvb, offset+2);
574 if ( nodelen_bits <= 8 ) {
575 node = tvb_get_guint8(tvb, offset)+1;
578 node = tvb_get_ntohs(tvb, offset);
582 if (check_col(pinfo->cinfo, COL_INFO))
583 col_add_fstr(pinfo->cinfo, COL_INFO, "Net: %u Node Len: %u Node: %u",
584 net, nodelen_bits, node);
587 ti = proto_tree_add_item(tree, proto_rtmp, tvb, offset, -1, FALSE);
588 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
590 proto_tree_add_uint(rtmp_tree, hf_rtmp_net, tvb, offset, 2, net);
591 proto_tree_add_uint(rtmp_tree, hf_rtmp_node_len, tvb, offset+2, 1,
593 proto_tree_add_uint(rtmp_tree, hf_rtmp_node, tvb, offset+3, nodelen,
595 offset += 3 + nodelen;
598 while (tvb_offset_exists(tvb, offset)) {
599 proto_tree *tuple_item, *tuple_tree;
602 guint16 tuple_range_end;
604 tuple_net = tvb_get_ntohs(tvb, offset);
605 tuple_dist = tvb_get_guint8(tvb, offset+2);
607 if (tuple_dist & 0x80) {
608 tuple_range_end = tvb_get_ntohs(tvb, offset+3);
609 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 6,
610 "Tuple %d: Range Start: %u Dist: %u Range End: %u",
611 i, tuple_net, tuple_dist&0x7F, tuple_range_end);
613 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 3,
614 "Tuple %d: Net: %u Dist: %u",
615 i, tuple_net, tuple_dist);
617 tuple_tree = proto_item_add_subtree(tuple_item, ett_rtmp_tuple);
619 if (tuple_dist & 0x80) {
620 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_range_start, tvb, offset, 2,
623 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_net, tvb, offset, 2,
626 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_dist, tvb, offset+2, 1,
629 if (tuple_dist & 0x80) {
631 * Extended network tuple.
633 proto_tree_add_item(tuple_tree, hf_rtmp_tuple_range_end, tvb, offset+3, 2,
645 dissect_nbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
646 proto_tree *nbp_tree;
647 proto_tree *nbp_info_tree;
648 proto_item *ti, *info_item;
654 if (check_col(pinfo->cinfo, COL_PROTOCOL))
655 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBP");
656 if (check_col(pinfo->cinfo, COL_INFO))
657 col_clear(pinfo->cinfo, COL_INFO);
659 info = tvb_get_guint8(tvb, offset);
663 if (check_col(pinfo->cinfo, COL_INFO))
664 col_add_fstr(pinfo->cinfo, COL_INFO, "Op: %s Count: %u",
665 val_to_str(op, nbp_op_vals, "Unknown (0x%01x)"), count);
668 ti = proto_tree_add_item(tree, proto_nbp, tvb, offset, -1, FALSE);
669 nbp_tree = proto_item_add_subtree(ti, ett_nbp);
671 info_item = proto_tree_add_uint_format(nbp_tree, hf_nbp_info, tvb, offset, 1,
673 "Info: 0x%01X Operation: %s Count: %u", info,
674 val_to_str(op, nbp_op_vals, "Unknown (0x%01X)"),
676 nbp_info_tree = proto_item_add_subtree(info_item, ett_nbp_info);
677 proto_tree_add_uint(nbp_info_tree, hf_nbp_op, tvb, offset, 1, info);
678 proto_tree_add_uint(nbp_info_tree, hf_nbp_count, tvb, offset, 1, info);
679 proto_tree_add_item(nbp_tree, hf_nbp_tid, tvb, offset+1, 1, FALSE);
682 for (i=0; i<count; i++) {
683 proto_tree *node_item,*node_tree;
684 int soffset = offset;
686 node_item = proto_tree_add_text(nbp_tree, tvb, offset, -1,
688 node_tree = proto_item_add_subtree(node_item, ett_nbp_node);
690 proto_tree_add_item(node_tree, hf_nbp_node_net, tvb, offset, 2, FALSE);
692 proto_tree_add_item(node_tree, hf_nbp_node_node, tvb, offset, 1, FALSE);
694 proto_tree_add_item(node_tree, hf_nbp_node_port, tvb, offset, 1, FALSE);
696 proto_tree_add_item(node_tree, hf_nbp_node_enum, tvb, offset, 1, FALSE);
699 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_object);
700 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_type);
701 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_zone);
703 proto_item_set_len(node_item, offset-soffset);
710 /* -----------------------------
711 ATP protocol cf. inside appletalk chap. 9
712 desegmentation from packet-ieee80211.c
715 dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
716 proto_tree *atp_tree = NULL;
718 proto_tree *atp_info_tree;
719 proto_item *info_item;
722 guint8 frag_number = 0;
726 struct aspinfo aspinfo;
727 tvbuff_t *new_tvb = NULL;
728 gboolean save_fragmented;
729 gboolean more_fragment = FALSE;
734 conversation_t *conversation;
735 asp_request_key request_key, *new_request_key;
736 asp_request_val *request_val;
738 if (check_col(pinfo->cinfo, COL_PROTOCOL))
739 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
741 ctrlinfo = tvb_get_guint8(tvb, offset);
742 bitmap = tvb_get_guint8(tvb, offset +1);
743 tid = tvb_get_ntohs(tvb, offset +2);
753 aspinfo.reply = (0x80 == (ctrlinfo & ATP_FUNCMASK))?1:0;
754 aspinfo.release = (0xC0 == (ctrlinfo & ATP_FUNCMASK))?1:0;
757 query = (!aspinfo.reply && !aspinfo.release);
759 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
760 pinfo->srcport, pinfo->destport, 0);
762 if (conversation == NULL)
764 conversation = conversation_new(&pinfo->src, &pinfo->dst,
765 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
768 request_key.conversation = conversation->index;
769 memcpy(request_key.src, (!aspinfo.reply)?pinfo->src.data:pinfo->dst.data, 4);
770 request_key.seq = aspinfo.seq;
772 request_val = (asp_request_val *) g_hash_table_lookup(atp_request_hash, &request_key);
774 if (!request_val && query ) {
775 new_request_key = g_mem_chunk_alloc(atp_request_keys);
776 *new_request_key = request_key;
778 request_val = g_mem_chunk_alloc(atp_request_vals);
779 request_val->value = nbe;
781 g_hash_table_insert(atp_request_hash, new_request_key,request_val);
785 ATP_EOM is not mandatory. Some implementations don't always set it
786 if the query is only one packet.
788 So it needs to keep the number of packets asked in request.
792 more_fragment = !((ATP_EOM & ctrlinfo) || (request_val && 1 == request_val->value));
793 frag_number = bitmap;
796 if (check_col(pinfo->cinfo, COL_INFO)) {
797 col_clear(pinfo->cinfo, COL_INFO);
798 col_add_fstr(pinfo->cinfo, COL_INFO, "%s transaction %u",
799 val_to_str(op, atp_function_vals, "Unknown (0x%01x)"),tid);
801 col_append_fstr(pinfo->cinfo, COL_INFO, " [fragment]");
805 ti = proto_tree_add_item(tree, proto_atp, tvb, offset, -1, FALSE);
806 atp_tree = proto_item_add_subtree(ti, ett_atp);
807 proto_item_set_len(atp_tree, aspinfo.release?8:ATP_HDRSIZE -1);
809 info_item = proto_tree_add_item(atp_tree, hf_atp_ctrlinfo, tvb, offset, 1, FALSE);
810 atp_info_tree = proto_item_add_subtree(info_item, ett_atp_info);
812 proto_tree_add_item(atp_info_tree, hf_atp_function, tvb, offset, 1, FALSE);
813 proto_tree_add_item(atp_info_tree, hf_atp_xo, tvb, offset, 1, FALSE);
814 proto_tree_add_item(atp_info_tree, hf_atp_eom, tvb, offset, 1, FALSE);
815 proto_tree_add_item(atp_info_tree, hf_atp_sts, tvb, offset, 1, FALSE);
816 if ((ctrlinfo & (ATP_FUNCMASK|ATP_XO)) == (0x40|ATP_XO)) {
817 /* TReq with XO set */
818 proto_tree_add_item(atp_info_tree, hf_atp_treltimer, tvb, offset, 1, FALSE);
821 proto_tree_add_text(atp_tree, tvb, offset +1, 1,
822 "Bitmap: 0x%02x %u packet(s) max", bitmap, nbe);
825 proto_tree_add_item(atp_tree, hf_atp_bitmap, tvb, offset +1, 1, FALSE);
827 proto_tree_add_item(atp_tree, hf_atp_tid, tvb, offset +2, 2, FALSE);
830 proto_tree_add_item(atp_tree, hf_atp_user_bytes, tvb, offset +4, 4, FALSE);
837 save_fragmented = pinfo->fragmented;
840 asp doesn't fit very well here
841 move asp back in atp?
843 if (atp_defragment && aspinfo.reply && (more_fragment || frag_number != 0)) {
844 fragment_data *fd_head;
847 hdr = ATP_HDRSIZE -1;
848 if (frag_number != 0)
849 hdr += 4; /* asp header */
850 len = tvb_length_remaining(tvb, hdr);
851 fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid,
853 atp_reassembled_table,
857 if (fd_head != NULL) {
858 if (fd_head->next != NULL) {
859 new_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
860 tvb_set_child_real_data_tvbuff(tvb, new_tvb);
861 add_new_data_source(pinfo, new_tvb, "Reassembled ATP");
862 /* Show all fragments. */
864 show_fragment_seq_tree(fd_head, &atp_frag_items,
865 atp_tree, pinfo, new_tvb);
869 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1, -1);
877 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1,- 1);
881 pinfo->private_data = &aspinfo;
882 /* if port == 6 it's not an ASP packet but a ZIP packet */
883 if (pinfo->srcport == 6 || pinfo->destport == 6 )
884 call_dissector(zip_atp_handle, new_tvb, pinfo, tree);
886 call_dissector(asp_handle, new_tvb, pinfo, tree);
889 /* Just show this as a fragment. */
890 new_tvb = tvb_new_subset (tvb, ATP_HDRSIZE -1, -1, -1);
891 call_dissector(data_handle, new_tvb, pinfo, tree);
893 pinfo->fragmented = save_fragmented;
898 copy and paste from dsi
901 dissect_asp_reply_get_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
903 proto_tree *sub_tree;
909 guint16 sign_ofs = 0;
920 ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
921 tree = proto_item_add_subtree(ti, ett_asp_status);
923 machine_ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
924 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %u", machine_ofs);
926 machine_ofs += offset;
928 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
929 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %u", ofs);
931 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
932 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %u", ofs);
934 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
935 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %u", ofs);
937 ofs = offset +AFPSTATUS_FLAGOFF;
938 ti = proto_tree_add_item(tree, hf_asp_server_flag, tvb, ofs, 2, FALSE);
939 sub_tree = proto_item_add_subtree(ti, ett_asp_status_server_flag);
940 proto_tree_add_item(sub_tree, hf_asp_server_flag_copyfile , tvb, ofs, 2, FALSE);
941 proto_tree_add_item(sub_tree, hf_asp_server_flag_passwd , tvb, ofs, 2, FALSE);
942 proto_tree_add_item(sub_tree, hf_asp_server_flag_no_save_passwd, tvb, ofs, 2, FALSE);
943 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_msg , tvb, ofs, 2, FALSE);
944 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_sig , tvb, ofs, 2, FALSE);
945 proto_tree_add_item(sub_tree, hf_asp_server_flag_tcpip , tvb, ofs, 2, FALSE);
946 proto_tree_add_item(sub_tree, hf_asp_server_flag_notify , tvb, ofs, 2, FALSE);
947 proto_tree_add_item(sub_tree, hf_asp_server_flag_reconnect , tvb, ofs, 2, FALSE);
948 proto_tree_add_item(sub_tree, hf_asp_server_flag_directory , tvb, ofs, 2, FALSE);
949 proto_tree_add_item(sub_tree, hf_asp_server_flag_utf8_name , tvb, ofs, 2, FALSE);
950 proto_tree_add_item(sub_tree, hf_asp_server_flag_fast_copy , tvb, ofs, 2, FALSE);
952 proto_tree_add_item(tree, hf_asp_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, FALSE);
954 flag = tvb_get_ntohs(tvb, ofs);
955 if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
956 ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
960 sign_ofs = tvb_get_ntohs(tvb, ofs);
961 proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %u", sign_ofs);
965 if ((flag & AFPSRVRINFO_TCPIP) && ofs < machine_ofs ) {
966 adr_ofs = tvb_get_ntohs(tvb, ofs);
967 proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %u", adr_ofs);
972 if ((flag & AFPSRVRINFO_SRVDIRECTORY) && ofs < machine_ofs) {
973 dir_ofs = tvb_get_ntohs(tvb, ofs);
974 proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %u", dir_ofs);
979 if ((flag & AFPSRVRINFO_SRVUTF8) && ofs < machine_ofs) {
980 utf_ofs = tvb_get_ntohs(tvb, ofs);
981 proto_tree_add_text(tree, tvb, ofs, 2, "UTF-8 Server name offset: %u", utf_ofs);
987 proto_tree_add_item(tree, hf_asp_server_type, tvb, machine_ofs, 1, FALSE);
989 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
991 nbe = tvb_get_guint8(tvb, ofs);
992 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %u", nbe);
994 sub_tree = proto_item_add_subtree(ti, ett_asp_vers);
995 for (i = 0; i < nbe; i++) {
996 len = tvb_get_guint8(tvb, ofs) +1;
997 proto_tree_add_item(sub_tree, hf_asp_server_vers, tvb, ofs, 1, FALSE);
1002 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
1004 nbe = tvb_get_guint8(tvb, ofs);
1005 ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %u", nbe);
1007 sub_tree = proto_item_add_subtree(ti, ett_asp_uams);
1008 for (i = 0; i < nbe; i++) {
1009 len = tvb_get_guint8(tvb, ofs) +1;
1010 proto_tree_add_item(sub_tree, hf_asp_server_uams, tvb, ofs, 1, FALSE);
1015 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1017 proto_tree_add_item(tree, hf_asp_server_icon, tvb, ofs, 256, FALSE);
1020 proto_tree_add_item(tree, hf_asp_server_signature, tvb, sign_ofs, 16, FALSE);
1024 proto_tree *adr_tree;
1032 nbe = tvb_get_guint8(tvb, ofs);
1033 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %u", nbe);
1035 adr_tree = proto_item_add_subtree(ti, ett_asp_addr);
1036 for (i = 0; i < nbe; i++) {
1039 len = tvb_get_guint8(tvb, ofs);
1040 type = tvb_get_guint8(tvb, ofs +1);
1043 ip = tvb_get_ptr(tvb, ofs+2, 4);
1044 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", ip_to_str(ip));
1046 case 2: /* IP + port */
1047 ip = tvb_get_ptr(tvb, ofs+2, 4);
1048 port = tvb_get_ntohs(tvb, ofs+6);
1049 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%u",ip_to_str(ip),port);
1051 case 3: /* DDP, atalk_addr_to_str want host order not network */
1052 net = tvb_get_ntohs(tvb, ofs+2);
1053 node = tvb_get_guint8(tvb, ofs +4);
1054 port = tvb_get_guint8(tvb, ofs +5);
1055 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
1058 case 5: /* IP + port ssh tunnel */
1059 ip = tvb_get_ptr(tvb, ofs+2, 4);
1060 port = tvb_get_ntohs(tvb, ofs+6);
1061 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip (ssh tunnel) %s:%u",ip_to_str(ip),port);
1065 tmp = g_malloc( len -1);
1066 tvb_memcpy(tvb, tmp, ofs +2, len -2);
1068 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
1072 /* else fall to default malformed record */
1074 ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknow type : %u", type);
1078 sub_tree = proto_item_add_subtree(ti,ett_asp_addr_line);
1079 proto_tree_add_item(sub_tree, hf_asp_server_addr_len, tvb, ofs, 1, FALSE);
1081 proto_tree_add_item(sub_tree, hf_asp_server_addr_type, tvb, ofs, 1, FALSE);
1083 proto_tree_add_item(sub_tree, hf_asp_server_addr_value,tvb, ofs, len, FALSE);
1090 nbe = tvb_get_guint8(tvb, ofs);
1091 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %u", nbe);
1093 sub_tree = proto_item_add_subtree(ti, ett_asp_directory);
1094 for (i = 0; i < nbe; i++) {
1095 len = tvb_get_guint8(tvb, ofs) +1;
1096 proto_tree_add_item(sub_tree, hf_asp_server_directory, tvb, ofs, 1, FALSE);
1102 len = tvb_get_ntohs(tvb, ofs);
1103 proto_tree_add_item(tree, hf_asp_server_utf8_name_len, tvb, ofs, 2, FALSE);
1105 proto_tree_add_item(tree, hf_asp_server_utf8_name, tvb, ofs, len, FALSE);
1108 /* FIXME: offset is not updated */
1112 /* -----------------------------
1113 ASP protocol cf. inside appletalk chap. 11
1115 static struct aspinfo *
1116 get_transaction(tvbuff_t *tvb, packet_info *pinfo)
1118 struct aspinfo *aspinfo = pinfo->private_data;
1119 conversation_t *conversation;
1120 asp_request_key request_key, *new_request_key;
1121 asp_request_val *request_val;
1124 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
1125 pinfo->srcport, pinfo->destport, 0);
1127 if (conversation == NULL)
1129 conversation = conversation_new(&pinfo->src, &pinfo->dst,
1130 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1133 request_key.conversation = conversation->index;
1134 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
1135 request_key.seq = aspinfo->seq;
1137 request_val = (asp_request_val *) g_hash_table_lookup(
1138 asp_request_hash, &request_key);
1139 if (!request_val && !aspinfo->reply ) {
1140 fn = tvb_get_guint8(tvb, 0);
1141 new_request_key = g_mem_chunk_alloc(asp_request_keys);
1142 *new_request_key = request_key;
1144 request_val = g_mem_chunk_alloc(asp_request_vals);
1145 request_val->value = fn;
1147 g_hash_table_insert(asp_request_hash, new_request_key,
1154 aspinfo->command = request_val->value;
1160 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1162 struct aspinfo *aspinfo;
1164 proto_tree *asp_tree = NULL;
1169 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1170 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1171 if (check_col(pinfo->cinfo, COL_INFO))
1172 col_clear(pinfo->cinfo, COL_INFO);
1174 aspinfo = get_transaction(tvb, pinfo);
1178 fn = aspinfo->command;
1180 if (check_col(pinfo->cinfo, COL_INFO)) {
1182 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1184 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1185 val_to_str(fn, asp_func_vals, "Unknown (0x%01x)"), aspinfo->seq);
1189 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, FALSE);
1190 asp_tree = proto_item_add_subtree(ti, ett_asp);
1192 if (!aspinfo->reply) {
1194 /* let the called deal with asp_tree == NULL */
1196 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, FALSE);
1200 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1202 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, FALSE);
1205 case ASPFUNC_TICKLE:
1207 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1209 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1213 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1215 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1219 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1221 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, FALSE);
1226 proto_item_set_len(asp_tree, 4);
1227 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1229 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1231 len = tvb_reported_length_remaining(tvb,offset);
1232 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1233 call_dissector(afp_handle, new_tvb, pinfo, tree);
1235 case ASPFUNC_WRTCONT:
1236 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1238 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1240 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, FALSE);
1244 proto_item_set_len(asp_tree, 4);
1246 len = tvb_reported_length_remaining(tvb,offset);
1247 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1254 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1257 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1259 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1261 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, FALSE);
1265 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1267 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1269 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1273 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1275 dissect_asp_reply_get_status(tvb, pinfo, asp_tree, offset);
1279 proto_item_set_len(asp_tree, 4);
1280 aspinfo->code = tvb_get_ntohl(tvb, offset);;
1281 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, FALSE);
1283 len = tvb_reported_length_remaining(tvb,offset);
1284 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1285 call_dissector(afp_handle, new_tvb, pinfo, tree);
1287 case ASPFUNC_TICKLE:
1288 case ASPFUNC_WRTCONT:
1289 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1291 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1293 proto_item_set_len(asp_tree, 4);
1295 len = tvb_reported_length_remaining(tvb,offset);
1296 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1302 /* -----------------------------
1303 ZIP protocol cf. inside appletalk chap. 8
1306 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1308 struct aspinfo *aspinfo;
1310 proto_tree *zip_tree;
1311 proto_tree *sub_tree;
1317 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1318 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1319 if (check_col(pinfo->cinfo, COL_INFO))
1320 col_clear(pinfo->cinfo, COL_INFO);
1322 aspinfo = get_transaction(tvb, pinfo);
1326 fn = aspinfo->command;
1328 if (check_col(pinfo->cinfo, COL_INFO)) {
1330 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1332 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1333 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1339 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, FALSE);
1340 zip_tree = proto_item_add_subtree(ti, ett_zip);
1342 if (!aspinfo->reply) {
1343 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, FALSE);
1346 case 7: /* start_index = 0 */
1349 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1351 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, FALSE);
1358 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1363 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, FALSE);
1366 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1368 count = tvb_get_ntohs(tvb, offset);
1369 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, FALSE);
1371 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1372 for (i= 1; i <= count; i++) {
1373 len = tvb_get_guint8(tvb, offset);
1374 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1383 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1385 proto_tree *zip_tree = NULL;
1390 proto_tree *flag_tree;
1391 proto_tree *sub_tree;
1392 proto_tree *net_tree;
1398 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1399 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1400 if (check_col(pinfo->cinfo, COL_INFO))
1401 col_clear(pinfo->cinfo, COL_INFO);
1403 fn = tvb_get_guint8(tvb, 0);
1404 if (check_col(pinfo->cinfo, COL_INFO)) {
1405 col_add_str(pinfo->cinfo, COL_INFO,
1406 val_to_str(fn, zip_function_vals, "Unknown ZIP function (%02x)"));
1412 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, FALSE);
1413 zip_tree = proto_item_add_subtree(ti, ett_zip);
1415 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,FALSE);
1417 /* fn 1,7,2,8 are not tested */
1420 count = tvb_get_guint8(tvb, offset);
1421 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1423 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1424 for (i= 1; i <= count; i++) {
1425 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, FALSE);
1429 case 7: /* Notify */
1430 flag = tvb_get_guint8(tvb, offset);
1431 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1432 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1433 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1434 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1435 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1438 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1441 len = tvb_get_guint8(tvb, offset);
1442 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1445 len = tvb_get_guint8(tvb, offset);
1446 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1448 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1451 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1455 case 8: /* Extended Reply */
1456 count = tvb_get_guint8(tvb, offset);
1457 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1459 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1460 for (i= 1; i <= count; i++) {
1461 net = tvb_get_ntohs(tvb, offset);
1462 ti = proto_tree_add_text(zip_tree, tvb, offset , 2, "Zone for network : %u", net);
1463 net_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1464 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, FALSE);
1466 len = tvb_get_guint8(tvb, offset);
1467 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1472 case 5 : /* GetNetInfo request */
1473 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1475 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1477 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1480 case 6 : /* GetNetInfo reply */
1481 flag = tvb_get_guint8(tvb, offset);
1482 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1483 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1484 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1485 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1486 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1489 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, FALSE);
1492 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, FALSE);
1495 len = tvb_get_guint8(tvb, offset);
1496 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1499 len = tvb_get_guint8(tvb, offset);
1500 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1502 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1504 if ((flag & 0x80) != 0)
1505 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,FALSE);
1514 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, guint8 dnode,
1515 guint8 snode, proto_tree *tree)
1521 proto_tree *ddp_tree = NULL;
1523 static struct atalk_ddp_addr src, dst;
1526 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1527 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1528 if (check_col(pinfo->cinfo, COL_INFO))
1529 col_clear(pinfo->cinfo, COL_INFO);
1532 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1534 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1536 len = tvb_get_ntohs(tvb, 0);
1538 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1539 dport = tvb_get_guint8(tvb, 2);
1541 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1542 sport = tvb_get_guint8(tvb, 3);
1544 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1545 type = tvb_get_guint8(tvb, 4);
1551 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1552 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1553 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1554 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1556 pinfo->ptype = PT_DDP;
1557 pinfo->destport = dport;
1558 pinfo->srcport = sport;
1560 if (check_col(pinfo->cinfo, COL_INFO)) {
1561 col_add_str(pinfo->cinfo, COL_INFO,
1562 val_to_str(type, op_vals, "Unknown DDP protocol (%02x)"));
1565 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1566 4, 3, atalk_addr_to_str(&src));
1567 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1568 6, 3, atalk_addr_to_str(&dst));
1570 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1572 new_tvb = tvb_new_subset(tvb, DDP_SHORT_HEADER_SIZE, -1, -1);
1574 if (!dissector_try_port(ddp_dissector_table, type, new_tvb, pinfo, tree))
1575 call_dissector(data_handle,new_tvb, pinfo, tree);
1579 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1582 proto_tree *ddp_tree;
1584 static struct atalk_ddp_addr src, dst;
1587 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1588 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1589 if (check_col(pinfo->cinfo, COL_INFO))
1590 col_clear(pinfo->cinfo, COL_INFO);
1592 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1593 ddp.dnet=g_ntohs(ddp.dnet);
1594 ddp.snet=g_ntohs(ddp.snet);
1595 ddp.sum=g_ntohs(ddp.sum);
1596 ddp.hops_len=g_ntohs(ddp.hops_len);
1599 src.node = ddp.snode;
1601 dst.node = ddp.dnode;
1602 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1603 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1604 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1605 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1607 pinfo->ptype = PT_DDP;
1608 pinfo->destport = ddp.dport;
1609 pinfo->srcport = ddp.sport;
1611 if (check_col(pinfo->cinfo, COL_INFO))
1612 col_add_str(pinfo->cinfo, COL_INFO,
1613 val_to_str(ddp.type, op_vals, "Unknown DDP protocol (%02x)"));
1616 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1618 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1620 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1621 4, 3, atalk_addr_to_str(&src));
1622 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1623 6, 3, atalk_addr_to_str(&dst));
1625 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1626 ddp_hops(ddp.hops_len));
1627 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1628 ddp_len(ddp.hops_len));
1629 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1631 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1633 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1635 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1637 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1639 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1641 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1643 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1647 new_tvb = tvb_new_subset(tvb, DDP_HEADER_SIZE, -1, -1);
1649 if (!dissector_try_port(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1650 call_dissector(data_handle,new_tvb, pinfo, tree);
1653 static const value_string llap_type_vals[] = {
1654 {0x01, "Short DDP"},
1657 {0x82, "Acknowledgement"},
1664 capture_llap(packet_counts *ld)
1670 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1675 proto_tree *llap_tree = NULL;
1679 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1680 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1681 if (check_col(pinfo->cinfo, COL_INFO))
1682 col_clear(pinfo->cinfo, COL_INFO);
1685 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, FALSE);
1686 llap_tree = proto_item_add_subtree(ti, ett_llap);
1689 dnode = tvb_get_guint8(tvb, 0);
1691 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, dnode);
1692 snode = tvb_get_guint8(tvb, 1);
1694 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, snode);
1695 type = tvb_get_guint8(tvb, 2);
1696 if (check_col(pinfo->cinfo, COL_INFO)) {
1697 col_add_str(pinfo->cinfo, COL_INFO,
1698 val_to_str(type, llap_type_vals, "Unknown LLAP type (%02x)"));
1701 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1703 new_tvb = tvb_new_subset(tvb, 3, -1, -1);
1705 if (proto_is_protocol_enabled(proto_ddp)) {
1706 pinfo->current_proto = "DDP";
1710 dissect_ddp_short(new_tvb, pinfo, dnode, snode, tree);
1714 dissect_ddp(new_tvb, pinfo, tree);
1718 call_dissector(data_handle,new_tvb, pinfo, tree);
1725 fragment_table_init(&atp_fragment_table);
1726 reassembled_table_init(&atp_reassembled_table);
1728 if (atp_request_hash)
1729 g_hash_table_destroy(atp_request_hash);
1730 if (atp_request_keys)
1731 g_mem_chunk_destroy(atp_request_keys);
1732 if (atp_request_vals)
1733 g_mem_chunk_destroy(atp_request_vals);
1735 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1737 atp_request_keys = g_mem_chunk_new("atp_request_keys",
1738 sizeof(asp_request_key),
1739 asp_packet_init_count * sizeof(asp_request_key),
1741 atp_request_vals = g_mem_chunk_new("atp_request_vals",
1742 sizeof(asp_request_val),
1743 asp_packet_init_count * sizeof(asp_request_val),
1751 if (asp_request_hash)
1752 g_hash_table_destroy(asp_request_hash);
1753 if (asp_request_keys)
1754 g_mem_chunk_destroy(asp_request_keys);
1755 if (asp_request_vals)
1756 g_mem_chunk_destroy(asp_request_vals);
1758 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1760 asp_request_keys = g_mem_chunk_new("asp_request_keys",
1761 sizeof(asp_request_key),
1762 asp_packet_init_count * sizeof(asp_request_key),
1764 asp_request_vals = g_mem_chunk_new("asp_request_vals",
1765 sizeof(asp_request_val),
1766 asp_packet_init_count * sizeof(asp_request_val),
1772 proto_register_atalk(void)
1774 static hf_register_info hf_llap[] = {
1776 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1780 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1784 { "Type", "llap.type", FT_UINT8, BASE_HEX, VALS(llap_type_vals), 0x0,
1788 static hf_register_info hf_ddp[] = {
1790 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1794 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1798 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1802 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1806 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1810 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1814 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1818 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1822 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1825 { &hf_ddp_dst_socket,
1826 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1829 { &hf_ddp_src_socket,
1830 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1834 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC, VALS(op_vals), 0x0,
1838 static hf_register_info hf_nbp[] = {
1840 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1841 VALS(nbp_op_vals), 0xF0, "Operation", HFILL }},
1843 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1844 NULL, 0x0, "Info", HFILL }},
1846 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1847 NULL, 0x0F, "Count", HFILL }},
1849 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1850 NULL, 0x0, "Network", HFILL }},
1851 { &hf_nbp_node_node,
1852 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1853 NULL, 0x0, "Node", HFILL }},
1854 { &hf_nbp_node_port,
1855 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1856 NULL, 0x0, "Port", HFILL }},
1857 { &hf_nbp_node_enum,
1858 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1859 NULL, 0x0, "Enumerator", HFILL }},
1860 { &hf_nbp_node_object,
1861 { "Object", "nbp.object", FT_STRING, BASE_DEC,
1862 NULL, 0x0, "Object", HFILL }},
1863 { &hf_nbp_node_type,
1864 { "Type", "nbp.type", FT_STRING, BASE_DEC,
1865 NULL, 0x0, "Type", HFILL }},
1866 { &hf_nbp_node_zone,
1867 { "Zone", "nbp.zone", FT_STRING, BASE_DEC,
1868 NULL, 0x0, "Zone", HFILL }},
1870 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1871 NULL, 0x0, "Transaction ID", HFILL }}
1874 static hf_register_info hf_rtmp[] = {
1876 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1877 NULL, 0x0, "Net", HFILL }},
1879 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1880 NULL, 0x0, "Node", HFILL }},
1881 { &hf_rtmp_node_len,
1882 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1883 NULL, 0x0, "Node Length", HFILL }},
1884 { &hf_rtmp_tuple_net,
1885 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1886 NULL, 0x0, "Net", HFILL }},
1887 { &hf_rtmp_tuple_range_start,
1888 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
1889 NULL, 0x0, "Range Start", HFILL }},
1890 { &hf_rtmp_tuple_range_end,
1891 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
1892 NULL, 0x0, "Range End", HFILL }},
1893 { &hf_rtmp_tuple_dist,
1894 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
1895 NULL, 0x0, "Distance", HFILL }},
1896 { &hf_rtmp_function,
1897 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
1898 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
1901 static hf_register_info hf_atp[] = {
1903 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
1904 NULL, 0, "control info", HFILL }},
1907 { "Function", "atp.function", FT_UINT8, BASE_DEC,
1908 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
1912 { "XO", "atp.xo", FT_BOOLEAN, 8,
1913 NULL, ATP_XO, "Exactly-once flag", HFILL }},
1916 { "EOM", "atp.eom", FT_BOOLEAN, 8,
1917 NULL, ATP_EOM, "End-of-message", HFILL }},
1920 { "STS", "atp.sts", FT_BOOLEAN, 8,
1921 NULL, ATP_STS, "Send transaction status", HFILL }},
1923 { &hf_atp_treltimer,
1924 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
1925 VALS(atp_trel_timer_vals), 0x07, "TRel timer", HFILL }},
1928 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
1929 NULL, 0x0, "Bitmap or sequence number", HFILL }},
1932 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
1933 NULL, 0x0, "Transaction id", HFILL }},
1934 { &hf_atp_user_bytes,
1935 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
1936 NULL, 0x0, "User bytes", HFILL }},
1938 { &hf_atp_segment_overlap,
1939 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
1940 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
1942 { &hf_atp_segment_overlap_conflict,
1943 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
1944 FT_BOOLEAN, BASE_NONE,
1945 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
1947 { &hf_atp_segment_multiple_tails,
1948 { "Multiple tail segments found", "atp.segment.multipletails",
1949 FT_BOOLEAN, BASE_NONE,
1950 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
1952 { &hf_atp_segment_too_long_segment,
1953 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
1954 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
1956 { &hf_atp_segment_error,
1957 {"Desegmentation error", "atp.segment.error", FT_NONE, BASE_NONE,
1958 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
1961 { "ATP Fragment", "atp.fragment", FT_NONE, BASE_NONE,
1962 NULL, 0x0, "ATP Fragment", HFILL }},
1965 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
1966 NULL, 0x0, "ATP Fragments", HFILL }},
1969 static hf_register_info hf_asp[] = {
1971 { "asp function", "asp.function", FT_UINT8, BASE_DEC,
1972 VALS(asp_func_vals), 0, "asp function", HFILL }},
1975 { "asp error", "asp.error", FT_INT32, BASE_DEC,
1976 VALS(asp_error_vals), 0, "return error code", HFILL }},
1979 { "Version", "asp.version", FT_UINT16, BASE_HEX,
1980 NULL, 0, "asp version", HFILL }},
1982 { &hf_asp_attn_code,
1983 { "Attn code", "asp.attn_code", FT_UINT16, BASE_HEX,
1984 NULL, 0, "asp attention code", HFILL }},
1986 { &hf_asp_init_error,
1987 { "Error", "asp.init_error", FT_UINT16, BASE_DEC,
1988 NULL, 0, "asp init error", HFILL }},
1990 { &hf_asp_session_id,
1991 { "Session ID", "asp.session_id", FT_UINT8, BASE_DEC,
1992 NULL, 0, "asp session id", HFILL }},
1995 { "Socket", "asp.socket", FT_UINT8, BASE_DEC,
1996 NULL, 0, "asp socket", HFILL }},
1999 { "Sequence", "asp.seq", FT_UINT16, BASE_DEC,
2000 NULL, 0, "asp sequence number", HFILL }},
2003 { "size", "asp.size", FT_UINT16, BASE_DEC,
2004 NULL, 0, "asp available size for reply", HFILL }},
2006 { &hf_asp_zero_value,
2007 { "Pad (0)", "asp.zero_value",
2008 FT_BYTES, BASE_HEX, NULL, 0x0,
2012 { &hf_asp_server_name,
2013 { "Server name", "asp.server_name",
2014 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2015 "Server name", HFILL }},
2017 { &hf_asp_server_type,
2018 { "Server type", "asp.server_type",
2019 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2020 "Server type", HFILL }},
2022 { &hf_asp_server_vers,
2023 { "AFP version", "asp.server_vers",
2024 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2025 "AFP version", HFILL }},
2027 { &hf_asp_server_uams,
2028 { "UAM", "asp.server_uams",
2029 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2032 { &hf_asp_server_icon,
2033 { "Icon bitmap", "asp.server_icon",
2034 FT_BYTES, BASE_HEX, NULL, 0x0,
2035 "Server icon bitmap", HFILL }},
2037 { &hf_asp_server_directory,
2038 { "Directory service", "asp.server_directory",
2039 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2040 "Server directory service", HFILL }},
2042 { &hf_asp_server_signature,
2043 { "Server signature", "asp.server_signature",
2044 FT_BYTES, BASE_HEX, NULL, 0x0,
2045 "Server signature", HFILL }},
2047 { &hf_asp_server_flag,
2048 { "Flag", "asp.server_flag",
2049 FT_UINT16, BASE_HEX, NULL, 0x0,
2050 "Server capabilities flag", HFILL }},
2051 { &hf_asp_server_flag_copyfile,
2052 { "Support copyfile", "asp.server_flag.copyfile",
2053 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_COPY,
2054 "Server support copyfile", HFILL }},
2055 { &hf_asp_server_flag_passwd,
2056 { "Support change password", "asp.server_flag.passwd",
2057 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_PASSWD,
2058 "Server support change password", HFILL }},
2059 { &hf_asp_server_flag_no_save_passwd,
2060 { "Don't allow save password", "asp.server_flag.no_save_passwd",
2061 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_NOSAVEPASSWD,
2062 "Don't allow save password", HFILL }},
2063 { &hf_asp_server_flag_srv_msg,
2064 { "Support server message", "asp.server_flag.srv_msg",
2065 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVMSGS,
2066 "Support server message", HFILL }},
2067 { &hf_asp_server_flag_srv_sig,
2068 { "Support server signature", "asp.server_flag.srv_sig",
2069 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVSIGNATURE,
2070 "Support server signature", HFILL }},
2071 { &hf_asp_server_flag_tcpip,
2072 { "Support TCP/IP", "asp.server_flag.tcpip",
2073 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_TCPIP,
2074 "Server support TCP/IP", HFILL }},
2075 { &hf_asp_server_flag_notify,
2076 { "Support server notifications", "asp.server_flag.notify",
2077 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVNOTIFY,
2078 "Server support notifications", HFILL }},
2079 { &hf_asp_server_flag_reconnect,
2080 { "Support server reconnect", "asp.server_flag.reconnect",
2081 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVRECONNECT,
2082 "Server support reconnect", HFILL }},
2083 { &hf_asp_server_flag_directory,
2084 { "Support directory services", "asp.server_flag.directory",
2085 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVDIRECTORY,
2086 "Server support directory services", HFILL }},
2087 { &hf_asp_server_flag_utf8_name,
2088 { "Support UTF8 server name", "asp.server_flag.utf8_name",
2089 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVUTF8,
2090 "Server support UTF8 server name", HFILL }},
2091 { &hf_asp_server_flag_fast_copy,
2092 { "Support fast copy", "asp.server_flag.fast_copy",
2093 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_FASTBOZO,
2094 "Server support fast copy", HFILL }},
2096 { &hf_asp_server_addr_len,
2097 { "Length", "asp.server_addr.len",
2098 FT_UINT8, BASE_DEC, NULL, 0x0,
2099 "Address length.", HFILL }},
2101 { &hf_asp_server_addr_type,
2102 { "Type", "asp.server_addr.type",
2103 FT_UINT8, BASE_DEC, VALS(afp_server_addr_type_vals), 0x0,
2104 "Address type.", HFILL }},
2106 { &hf_asp_server_addr_value,
2107 { "Value", "asp.server_addr.value",
2108 FT_BYTES, BASE_HEX, NULL, 0x0,
2109 "Address value", HFILL }},
2111 { &hf_asp_server_utf8_name_len,
2112 { "Server name length", "asp.server_utf8_name_len",
2113 FT_UINT16, BASE_DEC, NULL, 0x0,
2114 "UTF8 server name length", HFILL }},
2116 { &hf_asp_server_utf8_name,
2117 { "Server name (UTF8)", "asp.server_utf8_name",
2118 FT_STRING, BASE_NONE, NULL, 0x0,
2119 "Server name (UTF8)", HFILL }},
2122 static hf_register_info hf_zip[] = {
2124 { "Function", "zip.function", FT_UINT8, BASE_DEC, VALS(zip_function_vals), 0x0,
2125 "ZIP function", HFILL }},
2127 { &hf_zip_zero_value,
2128 { "Pad (0)", "zip.zero_value",FT_BYTES, BASE_HEX, NULL, 0x0,
2131 { &hf_zip_atp_function,
2132 { "Function", "zip.atp_function", FT_UINT8, BASE_DEC, VALS(zip_atp_function_vals), 0x0,
2135 { &hf_zip_start_index,
2136 { "Start index", "zip.start_index", FT_UINT16, BASE_DEC, NULL, 0x0,
2140 { "Count", "zip.count", FT_UINT16, BASE_DEC, NULL, 0x0,
2143 { &hf_zip_network_count,
2144 { "Count", "zip.network_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2147 { "Network","zip.network", FT_UINT16, BASE_DEC, NULL, 0x0,
2149 { &hf_zip_network_start,
2150 { "Network start","zip.network_start", FT_UINT16, BASE_DEC, NULL, 0x0,
2152 { &hf_zip_network_end,
2153 { "Network end", "zip.network_end", FT_UINT16, BASE_DEC, NULL, 0x0,
2157 { "Flags", "zip.flags", FT_BOOLEAN, 8, NULL, 0xC0,
2160 { &hf_zip_last_flag,
2161 { "Last Flag", "zip.last_flag", FT_BOOLEAN, 8, NULL, 0,
2162 "Non zero if contains last zone name in the zone list", HFILL }},
2164 { &hf_zip_flags_zone_invalid,
2165 { "Zone invalid", "zip.flags.zone_invalid", FT_BOOLEAN, 8, NULL, 0x80,
2168 { &hf_zip_flags_use_broadcast,
2169 { "Use broadcast","zip.flags.use_broadcast", FT_BOOLEAN, 8, NULL, 0x40,
2172 { &hf_zip_flags_only_one_zone,
2173 { "Only one zone","zip.flags.only_one_zone", FT_BOOLEAN, 8, NULL, 0x20,
2176 { &hf_zip_zone_name,
2177 { "Zone", "zip.zone_name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2180 { &hf_zip_default_zone,
2181 { "Default zone", "zip.default_zone",FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2184 { &hf_zip_multicast_length,
2185 { "Multicast length", "zip.multicast_length", FT_UINT8, BASE_DEC, NULL, 0x0,
2186 "Multicast address length", HFILL }},
2188 { &hf_zip_multicast_address,
2189 { "Multicast address", "zip.multicast_address",FT_BYTES, BASE_HEX, NULL, 0x0,
2190 "Multicast address", HFILL }},
2194 static gint *ett[] = {
2205 &ett_asp_status_server_flag,
2221 &ett_zip_zones_list,
2222 &ett_zip_network_list,
2224 module_t *atp_module;
2226 proto_llap = proto_register_protocol("LocalTalk Link Access Protocol", "LLAP", "llap");
2227 proto_register_field_array(proto_llap, hf_llap, array_length(hf_llap));
2229 proto_ddp = proto_register_protocol("Datagram Delivery Protocol", "DDP", "ddp");
2230 proto_register_field_array(proto_ddp, hf_ddp, array_length(hf_ddp));
2232 proto_nbp = proto_register_protocol("Name Binding Protocol", "NBP", "nbp");
2233 proto_register_field_array(proto_nbp, hf_nbp, array_length(hf_nbp));
2235 proto_atp = proto_register_protocol("AppleTalk Transaction Protocol packet", "ATP", "atp");
2236 proto_register_field_array(proto_atp, hf_atp, array_length(hf_atp));
2238 proto_asp = proto_register_protocol("AppleTalk Session Protocol", "ASP", "asp");
2239 proto_register_field_array(proto_asp, hf_asp, array_length(hf_asp));
2241 proto_zip = proto_register_protocol("Zone Information Protocol", "ZIP", "zip");
2242 proto_register_field_array(proto_zip, hf_zip, array_length(hf_zip));
2244 atp_module = prefs_register_protocol(proto_atp, NULL);
2245 prefs_register_bool_preference(atp_module, "desegment",
2246 "Desegment all ATP messages spanning multiple DDP packets",
2247 "Whether the ATP dissector should desegment all messages spanning multiple DDP packets",
2250 proto_rtmp = proto_register_protocol("Routing Table Maintenance Protocol",
2252 proto_register_field_array(proto_rtmp, hf_rtmp, array_length(hf_rtmp));
2254 proto_register_subtree_array(ett, array_length(ett));
2256 /* subdissector code */
2257 ddp_dissector_table = register_dissector_table("ddp.type", "DDP packet type",
2258 FT_UINT8, BASE_HEX);
2262 proto_reg_handoff_atalk(void)
2264 dissector_handle_t ddp_handle, nbp_handle, rtmp_request_handle;
2265 dissector_handle_t atp_handle;
2266 dissector_handle_t zip_ddp_handle;
2267 dissector_handle_t rtmp_data_handle, llap_handle;
2269 ddp_handle = create_dissector_handle(dissect_ddp, proto_ddp);
2270 dissector_add("ethertype", ETHERTYPE_ATALK, ddp_handle);
2271 dissector_add("chdlctype", ETHERTYPE_ATALK, ddp_handle);
2272 dissector_add("ppp.protocol", PPP_AT, ddp_handle);
2273 dissector_add("null.type", BSD_AF_APPLETALK, ddp_handle);
2275 nbp_handle = create_dissector_handle(dissect_nbp, proto_nbp);
2276 dissector_add("ddp.type", DDP_NBP, nbp_handle);
2278 atp_handle = create_dissector_handle(dissect_atp, proto_atp);
2279 dissector_add("ddp.type", DDP_ATP, atp_handle);
2281 asp_handle = create_dissector_handle(dissect_asp, proto_asp);
2283 rtmp_request_handle = create_dissector_handle(dissect_rtmp_request, proto_rtmp);
2284 rtmp_data_handle = create_dissector_handle(dissect_rtmp_data, proto_rtmp);
2285 dissector_add("ddp.type", DDP_RTMPREQ, rtmp_request_handle);
2286 dissector_add("ddp.type", DDP_RTMPDATA, rtmp_data_handle);
2288 zip_ddp_handle = create_dissector_handle(dissect_ddp_zip, proto_zip);
2289 dissector_add("ddp.type", DDP_ZIP, zip_ddp_handle);
2291 zip_atp_handle = create_dissector_handle(dissect_atp_zip, proto_zip);
2293 llap_handle = create_dissector_handle(dissect_llap, proto_llap);
2294 dissector_add("wtap_encap", WTAP_ENCAP_LOCALTALK, llap_handle);
2296 register_init_routine( atp_init);
2297 register_init_routine( &asp_reinit);
2299 afp_handle = find_dissector("afp");
2300 data_handle = find_dissector("data");