2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
5 * $Id: packet-atalk.c,v 1.87 2003/03/05 07:17: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 "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;
131 /* ------------------------- */
132 static int proto_zip = -1;
133 static dissector_handle_t zip_atp_handle;
135 static int hf_zip_function = -1;
136 static int hf_zip_atp_function = -1;
137 static int hf_zip_start_index = -1;
138 static int hf_zip_count = -1;
139 static int hf_zip_zero_value = -1;
141 static int hf_zip_network_count = -1;
142 static int hf_zip_network = -1;
143 static int hf_zip_network_start = -1;
144 static int hf_zip_network_end = -1;
146 static int hf_zip_flags = -1;
148 static int hf_zip_flags_zone_invalid = -1;
149 static int hf_zip_flags_use_broadcast = -1;
150 static int hf_zip_flags_only_one_zone = -1;
152 static int hf_zip_last_flag = -1;
154 static int hf_zip_zone_name = -1;
155 static int hf_zip_default_zone = -1;
157 static int hf_zip_multicast_length = -1;
158 static int hf_zip_multicast_address = -1;
160 static const value_string zip_function_vals[] = {
163 {5, "GetNetInfo request"},
164 {6, "GetNetInfo reply"},
166 {8, "Extended reply"},
170 static const value_string zip_atp_function_vals[] = {
173 {9, "GetLocalZones"},
177 static gint ett_zip = -1;
178 static gint ett_zip_flags = -1;
179 static gint ett_zip_zones_list = -1;
180 static gint ett_zip_network_list = -1;
182 /* --------------------------------
183 * from netatalk/include/atalk/ats.h
186 #define ASPFUNC_CLOSE 1
187 #define ASPFUNC_CMD 2
188 #define ASPFUNC_STAT 3
189 #define ASPFUNC_OPEN 4
190 #define ASPFUNC_TICKLE 5
191 #define ASPFUNC_WRITE 6
192 #define ASPFUNC_WRTCONT 7
193 #define ASPFUNC_ATTN 8
196 #define ASPERR_OK 0x0000
197 #define ASPERR_BADVERS 0xfbd6
198 #define ASPERR_BUFSMALL 0xfbd5
199 #define ASPERR_NOSESS 0xfbd4
200 #define ASPERR_NOSERV 0xfbd3
201 #define ASPERR_PARM 0xfbd2
202 #define ASPERR_SERVBUSY 0xfbd1
203 #define ASPERR_SESSCLOS 0xfbd0
204 #define ASPERR_SIZERR 0xfbcf
205 #define ASPERR_TOOMANY 0xfbce
206 #define ASPERR_NOACK 0xfbcd
208 static int proto_asp = -1;
209 static int hf_asp_func = -1;
210 static int hf_asp_error = -1;
211 static int hf_asp_socket = -1;
212 static int hf_asp_version = -1;
213 static int hf_asp_session_id = -1;
214 static int hf_asp_zero_value = -1;
215 static int hf_asp_init_error = -1;
216 static int hf_asp_attn_code = -1;
217 static int hf_asp_seq = -1;
218 static int hf_asp_size = -1;
220 /* status stuff same for asp and afp */
221 static int hf_asp_server_name = -1;
222 static int hf_asp_server_type = -1;
223 static int hf_asp_server_vers = -1;
224 static int hf_asp_server_uams = -1;
225 static int hf_asp_server_icon = -1;
226 static int hf_asp_server_directory = -1;
228 static int hf_asp_server_flag = -1;
229 static int hf_asp_server_flag_copyfile = -1;
230 static int hf_asp_server_flag_passwd = -1;
231 static int hf_asp_server_flag_no_save_passwd = -1;
232 static int hf_asp_server_flag_srv_msg = -1;
233 static int hf_asp_server_flag_srv_sig = -1;
234 static int hf_asp_server_flag_tcpip = -1;
235 static int hf_asp_server_flag_notify = -1;
236 static int hf_asp_server_flag_reconnect = -1;
237 static int hf_asp_server_flag_directory = -1;
238 static int hf_asp_server_flag_utf8_name = -1;
239 static int hf_asp_server_flag_fast_copy = -1;
240 static int hf_asp_server_signature = -1;
241 static int hf_asp_server_utf8_name_len = -1;
242 static int hf_asp_server_utf8_name = -1;
244 static int hf_asp_server_addr_len = -1;
245 static int hf_asp_server_addr_type = -1;
246 static int hf_asp_server_addr_value = -1;
248 static gint ett_asp_status = -1;
249 static gint ett_asp_uams = -1;
250 static gint ett_asp_vers = -1;
251 static gint ett_asp_addr = -1;
252 static gint ett_asp_addr_line = -1;
253 static gint ett_asp_directory = -1;
254 static gint ett_asp_status_server_flag = -1;
256 static guint asp_packet_init_count = 200;
259 guint32 conversation;
265 guint8 value; /* command for asp, bitmap for atp */
268 static GHashTable *asp_request_hash = NULL;
269 static GMemChunk *asp_request_keys = NULL;
270 static GMemChunk *asp_request_vals = NULL;
273 static gint asp_equal (gconstpointer v, gconstpointer v2)
275 const asp_request_key *val1 = (const asp_request_key*)v;
276 const asp_request_key *val2 = (const asp_request_key*)v2;
278 if (val1->conversation == val2->conversation &&
279 val1->seq == val2->seq &&
280 !memcmp(val1->src, val2->src, 4)) {
286 static guint asp_hash (gconstpointer v)
288 const asp_request_key *asp_key = (const asp_request_key*)v;
292 /* ------------------------------------ */
293 static GHashTable *atp_request_hash = NULL;
294 static GMemChunk *atp_request_keys = NULL;
295 static GMemChunk *atp_request_vals = NULL;
298 /* ------------------------------------ */
299 static int proto_nbp = -1;
300 static int hf_nbp_op = -1;
301 static int hf_nbp_info = -1;
302 static int hf_nbp_count = -1;
303 static int hf_nbp_tid = -1;
305 static int hf_nbp_node_net = -1;
306 static int hf_nbp_node_port = -1;
307 static int hf_nbp_node_node = -1;
308 static int hf_nbp_node_enum = -1;
309 static int hf_nbp_node_object = -1;
310 static int hf_nbp_node_type = -1;
311 static int hf_nbp_node_zone = -1;
313 static int proto_rtmp = -1;
314 static int hf_rtmp_net = -1;
315 static int hf_rtmp_node_len = -1;
316 static int hf_rtmp_node = -1;
317 static int hf_rtmp_tuple_net = -1;
318 static int hf_rtmp_tuple_range_start = -1;
319 static int hf_rtmp_tuple_range_end = -1;
320 static int hf_rtmp_tuple_dist = -1;
321 static int hf_rtmp_function = -1;
323 static gint ett_atp = -1;
325 static gint ett_atp_segments = -1;
326 static gint ett_atp_segment = -1;
327 static gint ett_atp_info = -1;
328 static gint ett_asp = -1;
330 static gint ett_nbp = -1;
331 static gint ett_nbp_info = -1;
332 static gint ett_nbp_node = -1;
333 static gint ett_rtmp = -1;
334 static gint ett_rtmp_tuple = -1;
335 static gint ett_ddp = -1;
336 static gint ett_llap = -1;
337 static gint ett_pstring = -1;
339 static const fragment_items atp_frag_items = {
344 &hf_atp_segment_overlap,
345 &hf_atp_segment_overlap_conflict,
346 &hf_atp_segment_multiple_tails,
347 &hf_atp_segment_too_long_segment,
348 &hf_atp_segment_error,
352 static dissector_table_t ddp_dissector_table;
354 static dissector_handle_t data_handle;
356 #define DDP_SHORT_HEADER_SIZE 5
359 * P = Padding, H = Hops, L = Len
363 * Assumes the argument is in host byte order.
365 #define ddp_hops(x) ( ( x >> 10) & 0x3C )
366 #define ddp_len(x) ( x & 0x03ff )
367 typedef struct _e_ddp {
368 guint16 hops_len; /* combines pad, hops, and len */
369 guint16 sum,dnet,snet;
375 #define DDP_HEADER_SIZE 13
378 static const value_string op_vals[] = {
379 {DDP_RTMPDATA, "AppleTalk Routing Table response or data" },
380 {DDP_NBP, "AppleTalk Name Binding Protocol packet"},
381 {DDP_ATP, "AppleTalk Transaction Protocol packet"},
382 {DDP_AEP, "AppleTalk Echo Protocol packet"},
383 {DDP_RTMPREQ, "AppleTalk Routing Table request"},
384 {DDP_ZIP, "AppleTalk Zone Information Protocol packet"},
385 {DDP_ADSP, "AppleTalk Data Stream Protocol"},
386 {DDP_EIGRP, "Cisco EIGRP for AppleTalk"},
390 static const value_string rtmp_function_vals[] = {
392 {2, "Route Data Request (split horizon processed)"},
393 {3, "Route Data Request (no split horizon processing)"},
397 #define NBP_BROADCAST 1
399 #define NBP_FORWARD 4
402 static const value_string nbp_op_vals[] = {
403 {NBP_BROADCAST, "broadcast request"},
404 {NBP_LOOKUP, "lookup"},
405 {NBP_FORWARD, "forward request"},
406 {NBP_REPLY, "reply"},
410 static const value_string atp_function_vals[] = {
411 {ATP_TREQ ,"REQuest"},
412 {ATP_TRESP ,"RESPonse"},
413 {ATP_TREL ,"RELease"},
417 static const value_string atp_trel_timer_vals[] = {
428 static const value_string asp_func_vals[] = {
429 {ASPFUNC_CLOSE, "CloseSession" },
430 {ASPFUNC_CMD, "Command" },
431 {ASPFUNC_STAT, "GetStatus" },
432 {ASPFUNC_OPEN, "OpenSession" },
433 {ASPFUNC_TICKLE, "Tickle" },
434 {ASPFUNC_WRITE, "Write" },
435 {ASPFUNC_WRTCONT, "Write Cont" },
436 {ASPFUNC_ATTN, "Attention" },
439 const value_string asp_error_vals[] = {
440 {AFP_OK , "success"},
441 {AFPERR_ACCESS , "permission denied" },
442 {AFPERR_AUTHCONT , "logincont" },
443 {AFPERR_BADUAM , "uam doesn't exist" },
444 {AFPERR_BADVERS , "bad afp version number" },
445 {AFPERR_BITMAP , "invalid bitmap" },
446 {AFPERR_CANTMOVE , "can't move file" },
447 {AFPERR_DENYCONF , "file synchronization locks conflict" },
448 {AFPERR_DIRNEMPT , "directory not empty" },
449 {AFPERR_DFULL , "disk full" },
450 {AFPERR_EOF , "end of file" },
451 {AFPERR_BUSY , "FileBusy" },
452 {AFPERR_FLATVOL , "volume doesn't support directories" },
453 {AFPERR_NOITEM , "ItemNotFound" },
454 {AFPERR_LOCK , "LockErr" },
455 {AFPERR_MISC , "misc. err" },
456 {AFPERR_NLOCK , "no more locks" },
457 {AFPERR_NOSRVR , "no response by server at that address" },
458 {AFPERR_EXIST , "object already exists" },
459 {AFPERR_NOOBJ , "object not found" },
460 {AFPERR_PARAM , "parameter error" },
461 {AFPERR_NORANGE , "no range lock" },
462 {AFPERR_RANGEOVR , "range overlap" },
463 {AFPERR_SESSCLOS , "session closed" },
464 {AFPERR_NOTAUTH , "user not authenticated" },
465 {AFPERR_NOOP , "command not supported" },
466 {AFPERR_BADTYPE , "object is the wrong type" },
467 {AFPERR_NFILE , "too many files open" },
468 {AFPERR_SHUTDOWN , "server is going down" },
469 {AFPERR_NORENAME , "can't rename" },
470 {AFPERR_NODIR , "couldn't find directory" },
471 {AFPERR_ITYPE , "wrong icon type" },
472 {AFPERR_VLOCK , "volume locked" },
473 {AFPERR_OLOCK , "object locked" },
474 {AFPERR_CTNSHRD , "share point contains a share point" },
475 {AFPERR_NOID , "file thread not found" },
476 {AFPERR_EXISTID , "file already has an id" },
477 {AFPERR_DIFFVOL , "different volume" },
478 {AFPERR_CATCHNG , "catalog has changed" },
479 {AFPERR_SAMEOBJ , "source file == destination file" },
480 {AFPERR_BADID , "non-existent file id" },
481 {AFPERR_PWDSAME , "same password/can't change password" },
482 {AFPERR_PWDSHORT , "password too short" },
483 {AFPERR_PWDEXPR , "password expired" },
484 {AFPERR_INSHRD , "folder being shared is inside a shared folder." },
485 {AFPERR_INTRASH , "shared folder in trash." },
486 {AFPERR_PWDCHNG , "password needs to be changed" },
487 {AFPERR_PWDPOLCY , "password fails policy check" },
488 {AFPERR_USRLOGIN , "user already logged on" },
492 * XXX - do this with an FT_UINT_STRING?
493 * Unfortunately, you can't extract from an FT_UINT_STRING the string,
494 * which we'd want to do in order to put it into the "Data:" portion.
496 * Are these always in the Mac extended character set?
498 static int dissect_pascal_string(tvbuff_t *tvb, int offset, proto_tree *tree,
503 len = tvb_get_guint8(tvb, offset);
513 * XXX - if we could do this inside the protocol tree
514 * code, we could perhaps avoid allocating and freeing
515 * this string buffer.
517 tmp = g_malloc( len+1 );
518 tvb_memcpy(tvb, tmp, offset, len);
520 item = proto_tree_add_string(tree, hf_index, tvb, offset-1, len+1, tmp);
522 subtree = proto_item_add_subtree(item, ett_pstring);
523 proto_tree_add_text(subtree, tvb, offset-1, 1, "Length: %d", len);
524 proto_tree_add_text(subtree, tvb, offset, len, "Data: %s", tmp);
534 dissect_rtmp_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
535 proto_tree *rtmp_tree;
539 if (check_col(pinfo->cinfo, COL_PROTOCOL))
540 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
541 if (check_col(pinfo->cinfo, COL_INFO))
542 col_clear(pinfo->cinfo, COL_INFO);
544 function = tvb_get_guint8(tvb, 0);
546 if (check_col(pinfo->cinfo, COL_INFO))
547 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
548 val_to_str(function, rtmp_function_vals, "Unknown function (%02x)"));
551 ti = proto_tree_add_item(tree, proto_rtmp, tvb, 0, 1, FALSE);
552 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
554 proto_tree_add_uint(rtmp_tree, hf_rtmp_function, tvb, 0, 1, function);
559 dissect_rtmp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
560 proto_tree *rtmp_tree;
564 guint8 nodelen,nodelen_bits;
565 guint16 node; /* might be more than 8 bits */
568 if (check_col(pinfo->cinfo, COL_PROTOCOL))
569 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
570 if (check_col(pinfo->cinfo, COL_INFO))
571 col_clear(pinfo->cinfo, COL_INFO);
573 net = tvb_get_ntohs(tvb, offset);
574 nodelen_bits = tvb_get_guint8(tvb, offset+2);
575 if ( nodelen_bits <= 8 ) {
576 node = tvb_get_guint8(tvb, offset)+1;
579 node = tvb_get_ntohs(tvb, offset);
583 if (check_col(pinfo->cinfo, COL_INFO))
584 col_add_fstr(pinfo->cinfo, COL_INFO, "Net: %u Node Len: %u Node: %u",
585 net, nodelen_bits, node);
588 ti = proto_tree_add_item(tree, proto_rtmp, tvb, offset, -1, FALSE);
589 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
591 proto_tree_add_uint(rtmp_tree, hf_rtmp_net, tvb, offset, 2, net);
592 proto_tree_add_uint(rtmp_tree, hf_rtmp_node_len, tvb, offset+2, 1,
594 proto_tree_add_uint(rtmp_tree, hf_rtmp_node, tvb, offset+3, nodelen,
596 offset += 3 + nodelen;
599 while (tvb_offset_exists(tvb, offset)) {
600 proto_tree *tuple_item, *tuple_tree;
603 guint16 tuple_range_end;
605 tuple_net = tvb_get_ntohs(tvb, offset);
606 tuple_dist = tvb_get_guint8(tvb, offset+2);
608 if (tuple_dist & 0x80) {
609 tuple_range_end = tvb_get_ntohs(tvb, offset+3);
610 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 6,
611 "Tuple %d: Range Start: %u Dist: %u Range End: %u",
612 i, tuple_net, tuple_dist&0x7F, tuple_range_end);
614 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 3,
615 "Tuple %d: Net: %u Dist: %u",
616 i, tuple_net, tuple_dist);
618 tuple_tree = proto_item_add_subtree(tuple_item, ett_rtmp_tuple);
620 if (tuple_dist & 0x80) {
621 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_range_start, tvb, offset, 2,
624 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_net, tvb, offset, 2,
627 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_dist, tvb, offset+2, 1,
630 if (tuple_dist & 0x80) {
632 * Extended network tuple.
634 proto_tree_add_item(tuple_tree, hf_rtmp_tuple_range_end, tvb, offset+3, 2,
646 dissect_nbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
647 proto_tree *nbp_tree;
648 proto_tree *nbp_info_tree;
649 proto_item *ti, *info_item;
655 if (check_col(pinfo->cinfo, COL_PROTOCOL))
656 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBP");
657 if (check_col(pinfo->cinfo, COL_INFO))
658 col_clear(pinfo->cinfo, COL_INFO);
660 info = tvb_get_guint8(tvb, offset);
664 if (check_col(pinfo->cinfo, COL_INFO))
665 col_add_fstr(pinfo->cinfo, COL_INFO, "Op: %s Count: %u",
666 val_to_str(op, nbp_op_vals, "Unknown (0x%01x)"), count);
669 ti = proto_tree_add_item(tree, proto_nbp, tvb, offset, -1, FALSE);
670 nbp_tree = proto_item_add_subtree(ti, ett_nbp);
672 info_item = proto_tree_add_uint_format(nbp_tree, hf_nbp_info, tvb, offset, 1,
674 "Info: 0x%01X Operation: %s Count: %u", info,
675 val_to_str(op, nbp_op_vals, "Unknown (0x%01X)"),
677 nbp_info_tree = proto_item_add_subtree(info_item, ett_nbp_info);
678 proto_tree_add_uint(nbp_info_tree, hf_nbp_op, tvb, offset, 1, info);
679 proto_tree_add_uint(nbp_info_tree, hf_nbp_count, tvb, offset, 1, info);
680 proto_tree_add_item(nbp_tree, hf_nbp_tid, tvb, offset+1, 1, FALSE);
683 for (i=0; i<count; i++) {
684 proto_tree *node_item,*node_tree;
685 int soffset = offset;
687 node_item = proto_tree_add_text(nbp_tree, tvb, offset, -1,
689 node_tree = proto_item_add_subtree(node_item, ett_nbp_node);
691 proto_tree_add_item(node_tree, hf_nbp_node_net, tvb, offset, 2, FALSE);
693 proto_tree_add_item(node_tree, hf_nbp_node_node, tvb, offset, 1, FALSE);
695 proto_tree_add_item(node_tree, hf_nbp_node_port, tvb, offset, 1, FALSE);
697 proto_tree_add_item(node_tree, hf_nbp_node_enum, tvb, offset, 1, FALSE);
700 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_object);
701 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_type);
702 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_zone);
704 proto_item_set_len(node_item, offset-soffset);
711 /* -----------------------------
712 ATP protocol cf. inside appletalk chap. 9
713 desegmentation from packet-ieee80211.c
716 dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
717 proto_tree *atp_tree = NULL;
719 proto_tree *atp_info_tree;
720 proto_item *info_item;
723 guint8 frag_number = 0;
727 struct aspinfo aspinfo;
728 tvbuff_t *new_tvb = NULL;
729 gboolean save_fragmented;
730 gboolean more_fragment = FALSE;
735 conversation_t *conversation;
736 asp_request_key request_key, *new_request_key;
737 asp_request_val *request_val;
739 if (check_col(pinfo->cinfo, COL_PROTOCOL))
740 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
742 ctrlinfo = tvb_get_guint8(tvb, offset);
743 bitmap = tvb_get_guint8(tvb, offset +1);
744 tid = tvb_get_ntohs(tvb, offset +2);
754 aspinfo.reply = (0x80 == (ctrlinfo & ATP_FUNCMASK))?1:0;
755 aspinfo.release = (0xC0 == (ctrlinfo & ATP_FUNCMASK))?1:0;
758 query = (!aspinfo.reply && !aspinfo.release);
760 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
761 pinfo->srcport, pinfo->destport, 0);
763 if (conversation == NULL)
765 conversation = conversation_new(&pinfo->src, &pinfo->dst,
766 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
769 request_key.conversation = conversation->index;
770 memcpy(request_key.src, (!aspinfo.reply)?pinfo->src.data:pinfo->dst.data, 4);
771 request_key.seq = aspinfo.seq;
773 request_val = (asp_request_val *) g_hash_table_lookup(atp_request_hash, &request_key);
775 if (!request_val && query ) {
776 new_request_key = g_mem_chunk_alloc(atp_request_keys);
777 *new_request_key = request_key;
779 request_val = g_mem_chunk_alloc(atp_request_vals);
780 request_val->value = nbe;
782 g_hash_table_insert(atp_request_hash, new_request_key,request_val);
786 ATP_EOM is not mandatory. Some implementations don't always set it
787 if the query is only one packet.
789 So it needs to keep the number of packets asked in request.
793 more_fragment = !((ATP_EOM & ctrlinfo) || (request_val && 1 == request_val->value));
794 frag_number = bitmap;
797 if (check_col(pinfo->cinfo, COL_INFO)) {
798 col_clear(pinfo->cinfo, COL_INFO);
799 col_add_fstr(pinfo->cinfo, COL_INFO, "%s transaction %u",
800 val_to_str(op, atp_function_vals, "Unknown (0x%01x)"),tid);
802 col_append_fstr(pinfo->cinfo, COL_INFO, " [fragment]");
806 ti = proto_tree_add_item(tree, proto_atp, tvb, offset, -1, FALSE);
807 atp_tree = proto_item_add_subtree(ti, ett_atp);
808 proto_item_set_len(atp_tree, aspinfo.release?8:ATP_HDRSIZE -1);
810 info_item = proto_tree_add_item(atp_tree, hf_atp_ctrlinfo, tvb, offset, 1, FALSE);
811 atp_info_tree = proto_item_add_subtree(info_item, ett_atp_info);
813 proto_tree_add_item(atp_info_tree, hf_atp_function, tvb, offset, 1, FALSE);
814 proto_tree_add_item(atp_info_tree, hf_atp_xo, tvb, offset, 1, FALSE);
815 proto_tree_add_item(atp_info_tree, hf_atp_eom, tvb, offset, 1, FALSE);
816 proto_tree_add_item(atp_info_tree, hf_atp_sts, tvb, offset, 1, FALSE);
817 if ((ctrlinfo & (ATP_FUNCMASK|ATP_XO)) == (0x40|ATP_XO)) {
818 /* TReq with XO set */
819 proto_tree_add_item(atp_info_tree, hf_atp_treltimer, tvb, offset, 1, FALSE);
822 proto_tree_add_text(atp_tree, tvb, offset +1, 1,
823 "Bitmap: 0x%02x %u packet(s) max", bitmap, nbe);
826 proto_tree_add_item(atp_tree, hf_atp_bitmap, tvb, offset +1, 1, FALSE);
828 proto_tree_add_item(atp_tree, hf_atp_tid, tvb, offset +2, 2, FALSE);
831 proto_tree_add_item(atp_tree, hf_atp_user_bytes, tvb, offset +4, 4, FALSE);
838 save_fragmented = pinfo->fragmented;
841 asp doesn't fit very well here
842 move asp back in atp?
844 if (atp_defragment && aspinfo.reply && (more_fragment || frag_number != 0)) {
845 fragment_data *fd_head;
848 hdr = ATP_HDRSIZE -1;
849 if (frag_number != 0)
850 hdr += 4; /* asp header */
851 len = tvb_reported_length_remaining(tvb, hdr);
852 fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid,
854 atp_reassembled_table,
858 if (fd_head != NULL) {
859 if (fd_head->next != NULL) {
860 new_tvb = tvb_new_real_data(fd_head->data, fd_head->len, fd_head->len);
861 tvb_set_child_real_data_tvbuff(tvb, new_tvb);
862 add_new_data_source(pinfo, new_tvb, "Reassembled ATP");
863 /* Show all fragments. */
865 show_fragment_seq_tree(fd_head, &atp_frag_items,
866 atp_tree, pinfo, new_tvb);
870 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1, -1);
878 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1,- 1);
882 pinfo->private_data = &aspinfo;
883 /* if port == 6 it's not an ASP packet but a ZIP packet */
884 if (pinfo->srcport == 6 || pinfo->destport == 6 )
885 call_dissector(zip_atp_handle, new_tvb, pinfo, tree);
887 call_dissector(asp_handle, new_tvb, pinfo, tree);
890 /* Just show this as a fragment. */
891 new_tvb = tvb_new_subset (tvb, ATP_HDRSIZE -1, -1, -1);
892 call_dissector(data_handle, new_tvb, pinfo, tree);
894 pinfo->fragmented = save_fragmented;
899 copy and paste from dsi
902 dissect_asp_reply_get_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
904 proto_tree *sub_tree;
910 guint16 sign_ofs = 0;
921 ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
922 tree = proto_item_add_subtree(ti, ett_asp_status);
924 machine_ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
925 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %u", machine_ofs);
927 machine_ofs += offset;
929 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
930 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %u", ofs);
932 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
933 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %u", ofs);
935 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
936 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %u", ofs);
938 ofs = offset +AFPSTATUS_FLAGOFF;
939 ti = proto_tree_add_item(tree, hf_asp_server_flag, tvb, ofs, 2, FALSE);
940 sub_tree = proto_item_add_subtree(ti, ett_asp_status_server_flag);
941 proto_tree_add_item(sub_tree, hf_asp_server_flag_copyfile , tvb, ofs, 2, FALSE);
942 proto_tree_add_item(sub_tree, hf_asp_server_flag_passwd , tvb, ofs, 2, FALSE);
943 proto_tree_add_item(sub_tree, hf_asp_server_flag_no_save_passwd, tvb, ofs, 2, FALSE);
944 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_msg , tvb, ofs, 2, FALSE);
945 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_sig , tvb, ofs, 2, FALSE);
946 proto_tree_add_item(sub_tree, hf_asp_server_flag_tcpip , tvb, ofs, 2, FALSE);
947 proto_tree_add_item(sub_tree, hf_asp_server_flag_notify , tvb, ofs, 2, FALSE);
948 proto_tree_add_item(sub_tree, hf_asp_server_flag_reconnect , tvb, ofs, 2, FALSE);
949 proto_tree_add_item(sub_tree, hf_asp_server_flag_directory , tvb, ofs, 2, FALSE);
950 proto_tree_add_item(sub_tree, hf_asp_server_flag_utf8_name , tvb, ofs, 2, FALSE);
951 proto_tree_add_item(sub_tree, hf_asp_server_flag_fast_copy , tvb, ofs, 2, FALSE);
953 proto_tree_add_item(tree, hf_asp_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, FALSE);
955 flag = tvb_get_ntohs(tvb, ofs);
956 if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
957 ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
961 sign_ofs = tvb_get_ntohs(tvb, ofs);
962 proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %u", sign_ofs);
966 if ((flag & AFPSRVRINFO_TCPIP) && ofs < machine_ofs ) {
967 adr_ofs = tvb_get_ntohs(tvb, ofs);
968 proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %u", adr_ofs);
973 if ((flag & AFPSRVRINFO_SRVDIRECTORY) && ofs < machine_ofs) {
974 dir_ofs = tvb_get_ntohs(tvb, ofs);
975 proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %u", dir_ofs);
980 if ((flag & AFPSRVRINFO_SRVUTF8) && ofs < machine_ofs) {
981 utf_ofs = tvb_get_ntohs(tvb, ofs);
982 proto_tree_add_text(tree, tvb, ofs, 2, "UTF-8 Server name offset: %u", utf_ofs);
988 proto_tree_add_item(tree, hf_asp_server_type, tvb, machine_ofs, 1, FALSE);
990 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
992 nbe = tvb_get_guint8(tvb, ofs);
993 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %u", nbe);
995 sub_tree = proto_item_add_subtree(ti, ett_asp_vers);
996 for (i = 0; i < nbe; i++) {
997 len = tvb_get_guint8(tvb, ofs) +1;
998 proto_tree_add_item(sub_tree, hf_asp_server_vers, tvb, ofs, 1, FALSE);
1003 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
1005 nbe = tvb_get_guint8(tvb, ofs);
1006 ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %u", nbe);
1008 sub_tree = proto_item_add_subtree(ti, ett_asp_uams);
1009 for (i = 0; i < nbe; i++) {
1010 len = tvb_get_guint8(tvb, ofs) +1;
1011 proto_tree_add_item(sub_tree, hf_asp_server_uams, tvb, ofs, 1, FALSE);
1016 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1018 proto_tree_add_item(tree, hf_asp_server_icon, tvb, ofs, 256, FALSE);
1021 proto_tree_add_item(tree, hf_asp_server_signature, tvb, sign_ofs, 16, FALSE);
1025 proto_tree *adr_tree;
1033 nbe = tvb_get_guint8(tvb, ofs);
1034 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %u", nbe);
1036 adr_tree = proto_item_add_subtree(ti, ett_asp_addr);
1037 for (i = 0; i < nbe; i++) {
1040 len = tvb_get_guint8(tvb, ofs);
1041 type = tvb_get_guint8(tvb, ofs +1);
1044 ip = tvb_get_ptr(tvb, ofs+2, 4);
1045 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", ip_to_str(ip));
1047 case 2: /* IP + port */
1048 ip = tvb_get_ptr(tvb, ofs+2, 4);
1049 port = tvb_get_ntohs(tvb, ofs+6);
1050 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%u",ip_to_str(ip),port);
1052 case 3: /* DDP, atalk_addr_to_str want host order not network */
1053 net = tvb_get_ntohs(tvb, ofs+2);
1054 node = tvb_get_guint8(tvb, ofs +4);
1055 port = tvb_get_guint8(tvb, ofs +5);
1056 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
1059 case 5: /* IP + port ssh tunnel */
1060 ip = tvb_get_ptr(tvb, ofs+2, 4);
1061 port = tvb_get_ntohs(tvb, ofs+6);
1062 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip (ssh tunnel) %s:%u",ip_to_str(ip),port);
1066 tmp = g_malloc( len -1);
1067 tvb_memcpy(tvb, tmp, ofs +2, len -2);
1069 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
1073 /* else fall to default malformed record */
1075 ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknow type : %u", type);
1079 sub_tree = proto_item_add_subtree(ti,ett_asp_addr_line);
1080 proto_tree_add_item(sub_tree, hf_asp_server_addr_len, tvb, ofs, 1, FALSE);
1082 proto_tree_add_item(sub_tree, hf_asp_server_addr_type, tvb, ofs, 1, FALSE);
1084 proto_tree_add_item(sub_tree, hf_asp_server_addr_value,tvb, ofs, len, FALSE);
1091 nbe = tvb_get_guint8(tvb, ofs);
1092 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %u", nbe);
1094 sub_tree = proto_item_add_subtree(ti, ett_asp_directory);
1095 for (i = 0; i < nbe; i++) {
1096 len = tvb_get_guint8(tvb, ofs) +1;
1097 proto_tree_add_item(sub_tree, hf_asp_server_directory, tvb, ofs, 1, FALSE);
1103 len = tvb_get_ntohs(tvb, ofs);
1104 proto_tree_add_item(tree, hf_asp_server_utf8_name_len, tvb, ofs, 2, FALSE);
1106 proto_tree_add_item(tree, hf_asp_server_utf8_name, tvb, ofs, len, FALSE);
1109 /* FIXME: offset is not updated */
1113 /* -----------------------------
1114 ASP protocol cf. inside appletalk chap. 11
1116 static struct aspinfo *
1117 get_transaction(tvbuff_t *tvb, packet_info *pinfo)
1119 struct aspinfo *aspinfo = pinfo->private_data;
1120 conversation_t *conversation;
1121 asp_request_key request_key, *new_request_key;
1122 asp_request_val *request_val;
1125 conversation = find_conversation(&pinfo->src, &pinfo->dst, pinfo->ptype,
1126 pinfo->srcport, pinfo->destport, 0);
1128 if (conversation == NULL)
1130 conversation = conversation_new(&pinfo->src, &pinfo->dst,
1131 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1134 request_key.conversation = conversation->index;
1135 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
1136 request_key.seq = aspinfo->seq;
1138 request_val = (asp_request_val *) g_hash_table_lookup(
1139 asp_request_hash, &request_key);
1140 if (!request_val && !aspinfo->reply ) {
1141 fn = tvb_get_guint8(tvb, 0);
1142 new_request_key = g_mem_chunk_alloc(asp_request_keys);
1143 *new_request_key = request_key;
1145 request_val = g_mem_chunk_alloc(asp_request_vals);
1146 request_val->value = fn;
1148 g_hash_table_insert(asp_request_hash, new_request_key,
1155 aspinfo->command = request_val->value;
1161 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1163 struct aspinfo *aspinfo;
1165 proto_tree *asp_tree = NULL;
1170 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1171 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1172 if (check_col(pinfo->cinfo, COL_INFO))
1173 col_clear(pinfo->cinfo, COL_INFO);
1175 aspinfo = get_transaction(tvb, pinfo);
1179 fn = aspinfo->command;
1181 if (check_col(pinfo->cinfo, COL_INFO)) {
1183 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1185 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1186 val_to_str(fn, asp_func_vals, "Unknown (0x%01x)"), aspinfo->seq);
1190 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, FALSE);
1191 asp_tree = proto_item_add_subtree(ti, ett_asp);
1193 if (!aspinfo->reply) {
1195 /* let the called deal with asp_tree == NULL */
1197 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, FALSE);
1201 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1203 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, FALSE);
1206 case ASPFUNC_TICKLE:
1208 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1210 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1214 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1216 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1220 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1222 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, FALSE);
1227 proto_item_set_len(asp_tree, 4);
1228 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1230 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1232 len = tvb_reported_length_remaining(tvb,offset);
1233 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1234 call_dissector(afp_handle, new_tvb, pinfo, tree);
1236 case ASPFUNC_WRTCONT:
1237 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1239 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1241 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, FALSE);
1245 proto_item_set_len(asp_tree, 4);
1247 len = tvb_reported_length_remaining(tvb,offset);
1248 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1255 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1258 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1260 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1262 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, FALSE);
1266 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1268 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1270 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1274 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1276 dissect_asp_reply_get_status(tvb, pinfo, asp_tree, offset);
1280 proto_item_set_len(asp_tree, 4);
1281 aspinfo->code = tvb_get_ntohl(tvb, offset);;
1282 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, FALSE);
1284 len = tvb_reported_length_remaining(tvb,offset);
1285 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1286 call_dissector(afp_handle, new_tvb, pinfo, tree);
1288 case ASPFUNC_TICKLE:
1289 case ASPFUNC_WRTCONT:
1290 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1292 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1294 proto_item_set_len(asp_tree, 4);
1296 len = tvb_reported_length_remaining(tvb,offset);
1297 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1303 /* -----------------------------
1304 ZIP protocol cf. inside appletalk chap. 8
1307 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1309 struct aspinfo *aspinfo;
1311 proto_tree *zip_tree;
1312 proto_tree *sub_tree;
1318 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1319 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1320 if (check_col(pinfo->cinfo, COL_INFO))
1321 col_clear(pinfo->cinfo, COL_INFO);
1323 aspinfo = get_transaction(tvb, pinfo);
1327 fn = aspinfo->command;
1329 if (check_col(pinfo->cinfo, COL_INFO)) {
1331 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1333 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1334 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1340 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, FALSE);
1341 zip_tree = proto_item_add_subtree(ti, ett_zip);
1343 if (!aspinfo->reply) {
1344 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, FALSE);
1347 case 7: /* start_index = 0 */
1350 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1352 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, FALSE);
1359 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1364 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, FALSE);
1367 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1369 count = tvb_get_ntohs(tvb, offset);
1370 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, FALSE);
1372 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1373 for (i= 1; i <= count; i++) {
1374 len = tvb_get_guint8(tvb, offset);
1375 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1384 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1386 proto_tree *zip_tree = NULL;
1391 proto_tree *flag_tree;
1392 proto_tree *sub_tree;
1393 proto_tree *net_tree;
1399 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1400 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1401 if (check_col(pinfo->cinfo, COL_INFO))
1402 col_clear(pinfo->cinfo, COL_INFO);
1404 fn = tvb_get_guint8(tvb, 0);
1405 if (check_col(pinfo->cinfo, COL_INFO)) {
1406 col_add_str(pinfo->cinfo, COL_INFO,
1407 val_to_str(fn, zip_function_vals, "Unknown ZIP function (%02x)"));
1413 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, FALSE);
1414 zip_tree = proto_item_add_subtree(ti, ett_zip);
1416 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,FALSE);
1418 /* fn 1,7,2,8 are not tested */
1421 count = tvb_get_guint8(tvb, offset);
1422 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1424 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1425 for (i= 1; i <= count; i++) {
1426 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, FALSE);
1430 case 7: /* Notify */
1431 flag = tvb_get_guint8(tvb, offset);
1432 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1433 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1434 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1435 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1436 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1439 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1442 len = tvb_get_guint8(tvb, offset);
1443 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1446 len = tvb_get_guint8(tvb, offset);
1447 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1449 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1452 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1456 case 8: /* Extended Reply */
1457 count = tvb_get_guint8(tvb, offset);
1458 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1460 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1461 for (i= 1; i <= count; i++) {
1462 net = tvb_get_ntohs(tvb, offset);
1463 ti = proto_tree_add_text(zip_tree, tvb, offset , 2, "Zone for network : %u", net);
1464 net_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1465 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, FALSE);
1467 len = tvb_get_guint8(tvb, offset);
1468 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1473 case 5 : /* GetNetInfo request */
1474 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1476 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1478 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1481 case 6 : /* GetNetInfo reply */
1482 flag = tvb_get_guint8(tvb, offset);
1483 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1484 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1485 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1486 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1487 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1490 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, FALSE);
1493 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, FALSE);
1496 len = tvb_get_guint8(tvb, offset);
1497 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1500 len = tvb_get_guint8(tvb, offset);
1501 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1503 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1505 if ((flag & 0x80) != 0)
1506 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,FALSE);
1515 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, guint8 dnode,
1516 guint8 snode, proto_tree *tree)
1522 proto_tree *ddp_tree = NULL;
1524 static struct atalk_ddp_addr src, dst;
1527 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1528 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1529 if (check_col(pinfo->cinfo, COL_INFO))
1530 col_clear(pinfo->cinfo, COL_INFO);
1533 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1535 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1537 len = tvb_get_ntohs(tvb, 0);
1539 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1540 dport = tvb_get_guint8(tvb, 2);
1542 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1543 sport = tvb_get_guint8(tvb, 3);
1545 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1546 type = tvb_get_guint8(tvb, 4);
1552 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1553 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1554 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1555 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1557 pinfo->ptype = PT_DDP;
1558 pinfo->destport = dport;
1559 pinfo->srcport = sport;
1561 if (check_col(pinfo->cinfo, COL_INFO)) {
1562 col_add_str(pinfo->cinfo, COL_INFO,
1563 val_to_str(type, op_vals, "Unknown DDP protocol (%02x)"));
1566 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1567 4, 3, atalk_addr_to_str(&src));
1568 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1569 6, 3, atalk_addr_to_str(&dst));
1571 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1573 new_tvb = tvb_new_subset(tvb, DDP_SHORT_HEADER_SIZE, -1, -1);
1575 if (!dissector_try_port(ddp_dissector_table, type, new_tvb, pinfo, tree))
1576 call_dissector(data_handle,new_tvb, pinfo, tree);
1580 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1583 proto_tree *ddp_tree;
1585 static struct atalk_ddp_addr src, dst;
1588 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1589 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1590 if (check_col(pinfo->cinfo, COL_INFO))
1591 col_clear(pinfo->cinfo, COL_INFO);
1593 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1594 ddp.dnet=g_ntohs(ddp.dnet);
1595 ddp.snet=g_ntohs(ddp.snet);
1596 ddp.sum=g_ntohs(ddp.sum);
1597 ddp.hops_len=g_ntohs(ddp.hops_len);
1600 src.node = ddp.snode;
1602 dst.node = ddp.dnode;
1603 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1604 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1605 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1606 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1608 pinfo->ptype = PT_DDP;
1609 pinfo->destport = ddp.dport;
1610 pinfo->srcport = ddp.sport;
1612 if (check_col(pinfo->cinfo, COL_INFO))
1613 col_add_str(pinfo->cinfo, COL_INFO,
1614 val_to_str(ddp.type, op_vals, "Unknown DDP protocol (%02x)"));
1617 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1619 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1621 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1622 4, 3, atalk_addr_to_str(&src));
1623 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1624 6, 3, atalk_addr_to_str(&dst));
1626 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1627 ddp_hops(ddp.hops_len));
1628 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1629 ddp_len(ddp.hops_len));
1630 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1632 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1634 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1636 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1638 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1640 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1642 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1644 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1648 new_tvb = tvb_new_subset(tvb, DDP_HEADER_SIZE, -1, -1);
1650 if (!dissector_try_port(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1651 call_dissector(data_handle,new_tvb, pinfo, tree);
1654 static const value_string llap_type_vals[] = {
1655 {0x01, "Short DDP"},
1658 {0x82, "Acknowledgement"},
1665 capture_llap(packet_counts *ld)
1671 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1676 proto_tree *llap_tree = NULL;
1680 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1681 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1682 if (check_col(pinfo->cinfo, COL_INFO))
1683 col_clear(pinfo->cinfo, COL_INFO);
1686 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, FALSE);
1687 llap_tree = proto_item_add_subtree(ti, ett_llap);
1690 dnode = tvb_get_guint8(tvb, 0);
1692 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, dnode);
1693 snode = tvb_get_guint8(tvb, 1);
1695 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, snode);
1696 type = tvb_get_guint8(tvb, 2);
1697 if (check_col(pinfo->cinfo, COL_INFO)) {
1698 col_add_str(pinfo->cinfo, COL_INFO,
1699 val_to_str(type, llap_type_vals, "Unknown LLAP type (%02x)"));
1702 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1704 new_tvb = tvb_new_subset(tvb, 3, -1, -1);
1706 if (proto_is_protocol_enabled(proto_ddp)) {
1707 pinfo->current_proto = "DDP";
1711 dissect_ddp_short(new_tvb, pinfo, dnode, snode, tree);
1715 dissect_ddp(new_tvb, pinfo, tree);
1719 call_dissector(data_handle,new_tvb, pinfo, tree);
1726 fragment_table_init(&atp_fragment_table);
1727 reassembled_table_init(&atp_reassembled_table);
1729 if (atp_request_hash)
1730 g_hash_table_destroy(atp_request_hash);
1731 if (atp_request_keys)
1732 g_mem_chunk_destroy(atp_request_keys);
1733 if (atp_request_vals)
1734 g_mem_chunk_destroy(atp_request_vals);
1736 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1738 atp_request_keys = g_mem_chunk_new("atp_request_keys",
1739 sizeof(asp_request_key),
1740 asp_packet_init_count * sizeof(asp_request_key),
1742 atp_request_vals = g_mem_chunk_new("atp_request_vals",
1743 sizeof(asp_request_val),
1744 asp_packet_init_count * sizeof(asp_request_val),
1752 if (asp_request_hash)
1753 g_hash_table_destroy(asp_request_hash);
1754 if (asp_request_keys)
1755 g_mem_chunk_destroy(asp_request_keys);
1756 if (asp_request_vals)
1757 g_mem_chunk_destroy(asp_request_vals);
1759 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1761 asp_request_keys = g_mem_chunk_new("asp_request_keys",
1762 sizeof(asp_request_key),
1763 asp_packet_init_count * sizeof(asp_request_key),
1765 asp_request_vals = g_mem_chunk_new("asp_request_vals",
1766 sizeof(asp_request_val),
1767 asp_packet_init_count * sizeof(asp_request_val),
1773 proto_register_atalk(void)
1775 static hf_register_info hf_llap[] = {
1777 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1781 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1785 { "Type", "llap.type", FT_UINT8, BASE_HEX, VALS(llap_type_vals), 0x0,
1789 static hf_register_info hf_ddp[] = {
1791 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1795 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1799 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1803 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1807 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1811 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1815 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1819 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1823 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1826 { &hf_ddp_dst_socket,
1827 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1830 { &hf_ddp_src_socket,
1831 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1835 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC, VALS(op_vals), 0x0,
1839 static hf_register_info hf_nbp[] = {
1841 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1842 VALS(nbp_op_vals), 0xF0, "Operation", HFILL }},
1844 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1845 NULL, 0x0, "Info", HFILL }},
1847 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1848 NULL, 0x0F, "Count", HFILL }},
1850 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1851 NULL, 0x0, "Network", HFILL }},
1852 { &hf_nbp_node_node,
1853 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1854 NULL, 0x0, "Node", HFILL }},
1855 { &hf_nbp_node_port,
1856 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1857 NULL, 0x0, "Port", HFILL }},
1858 { &hf_nbp_node_enum,
1859 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1860 NULL, 0x0, "Enumerator", HFILL }},
1861 { &hf_nbp_node_object,
1862 { "Object", "nbp.object", FT_STRING, BASE_DEC,
1863 NULL, 0x0, "Object", HFILL }},
1864 { &hf_nbp_node_type,
1865 { "Type", "nbp.type", FT_STRING, BASE_DEC,
1866 NULL, 0x0, "Type", HFILL }},
1867 { &hf_nbp_node_zone,
1868 { "Zone", "nbp.zone", FT_STRING, BASE_DEC,
1869 NULL, 0x0, "Zone", HFILL }},
1871 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1872 NULL, 0x0, "Transaction ID", HFILL }}
1875 static hf_register_info hf_rtmp[] = {
1877 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1878 NULL, 0x0, "Net", HFILL }},
1880 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1881 NULL, 0x0, "Node", HFILL }},
1882 { &hf_rtmp_node_len,
1883 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1884 NULL, 0x0, "Node Length", HFILL }},
1885 { &hf_rtmp_tuple_net,
1886 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1887 NULL, 0x0, "Net", HFILL }},
1888 { &hf_rtmp_tuple_range_start,
1889 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
1890 NULL, 0x0, "Range Start", HFILL }},
1891 { &hf_rtmp_tuple_range_end,
1892 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
1893 NULL, 0x0, "Range End", HFILL }},
1894 { &hf_rtmp_tuple_dist,
1895 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
1896 NULL, 0x0, "Distance", HFILL }},
1897 { &hf_rtmp_function,
1898 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
1899 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
1902 static hf_register_info hf_atp[] = {
1904 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
1905 NULL, 0, "control info", HFILL }},
1908 { "Function", "atp.function", FT_UINT8, BASE_DEC,
1909 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
1913 { "XO", "atp.xo", FT_BOOLEAN, 8,
1914 NULL, ATP_XO, "Exactly-once flag", HFILL }},
1917 { "EOM", "atp.eom", FT_BOOLEAN, 8,
1918 NULL, ATP_EOM, "End-of-message", HFILL }},
1921 { "STS", "atp.sts", FT_BOOLEAN, 8,
1922 NULL, ATP_STS, "Send transaction status", HFILL }},
1924 { &hf_atp_treltimer,
1925 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
1926 VALS(atp_trel_timer_vals), 0x07, "TRel timer", HFILL }},
1929 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
1930 NULL, 0x0, "Bitmap or sequence number", HFILL }},
1933 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
1934 NULL, 0x0, "Transaction id", HFILL }},
1935 { &hf_atp_user_bytes,
1936 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
1937 NULL, 0x0, "User bytes", HFILL }},
1939 { &hf_atp_segment_overlap,
1940 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
1941 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
1943 { &hf_atp_segment_overlap_conflict,
1944 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
1945 FT_BOOLEAN, BASE_NONE,
1946 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
1948 { &hf_atp_segment_multiple_tails,
1949 { "Multiple tail segments found", "atp.segment.multipletails",
1950 FT_BOOLEAN, BASE_NONE,
1951 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
1953 { &hf_atp_segment_too_long_segment,
1954 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
1955 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
1957 { &hf_atp_segment_error,
1958 {"Desegmentation error", "atp.segment.error", FT_FRAMENUM, BASE_NONE,
1959 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
1962 { "ATP Fragment", "atp.fragment", FT_FRAMENUM, BASE_NONE,
1963 NULL, 0x0, "ATP Fragment", HFILL }},
1966 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
1967 NULL, 0x0, "ATP Fragments", 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");