2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
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>
43 #include <epan/prefs.h>
44 #include <epan/reassemble.h>
46 #include "packet-afp.h"
48 /* Tables for reassembly of fragments. */
49 static GHashTable *atp_fragment_table = NULL;
50 static GHashTable *atp_reassembled_table = NULL;
52 /* desegmentation of ATP */
53 static gboolean atp_defragment = TRUE;
55 static dissector_handle_t afp_handle;
57 static int proto_llap = -1;
58 static int hf_llap_dst = -1;
59 static int hf_llap_src = -1;
60 static int hf_llap_type = -1;
62 static int proto_ddp = -1;
63 static int hf_ddp_hopcount = -1;
64 static int hf_ddp_len = -1;
65 static int hf_ddp_checksum = -1;
66 static int hf_ddp_dst = -1;
67 static int hf_ddp_dst_net = -1;
68 static int hf_ddp_src = -1;
69 static int hf_ddp_src_net = -1;
70 static int hf_ddp_dst_node = -1;
71 static int hf_ddp_src_node = -1;
72 static int hf_ddp_dst_socket = -1;
73 static int hf_ddp_src_socket = -1;
74 static int hf_ddp_type = -1;
76 static dissector_handle_t ddp_handle;
78 /* --------------------------------------
79 * ATP protocol parameters
80 * from netatalk/include/atalk/atp.h
82 #define ATP_MAXDATA (578+4) /* maximum ATP data size */
83 #define ATP_BUFSIZ 587 /* maximum packet size */
84 #define ATP_HDRSIZE 5 /* includes DDP type field */
86 #define ATP_TRELMASK 0x07 /* mask all but TREL */
87 #define ATP_RELTIME 30 /* base release timer (in secs) */
89 #define ATP_TREL30 0x0 /* release time codes */
90 #define ATP_TREL1M 0x1 /* these are passed in flags of */
91 #define ATP_TREL2M 0x2 /* atp_sreq call, and set in the */
92 #define ATP_TREL4M 0x3 /* packet control info. */
93 #define ATP_TREL8M 0x4
95 /* flags for ATP options (and control byte)
97 #define ATP_XO 0x20 /* (1<<5) eXactly Once mode */
98 #define ATP_EOM 0x10 /* (1<<4) End Of Message */
99 #define ATP_STS 0x08 /* (1<<3) Transaction Status */
103 #define ATP_FUNCMASK (3<<6) /* mask all but function */
105 #define ATP_TREQ 1 /* (1<<6) Trans. REQuest */
106 #define ATP_TRESP 2 /* (2<<6) Trans. RESPonse */
107 #define ATP_TREL 3 /* (3<<6) Trans. RELease */
109 /* ------------------------- */
110 static dissector_handle_t asp_handle;
112 static int proto_atp = -1;
113 static int hf_atp_ctrlinfo = -1; /* guint8_t control information */
114 static int hf_atp_function = -1; /* bits 7,6 function */
115 static int hf_atp_xo = -1; /* bit 5 exactly-once */
116 static int hf_atp_eom = -1; /* bit 4 end-of-message */
117 static int hf_atp_sts = -1; /* bit 3 send transaction status */
118 static int hf_atp_treltimer = -1; /* bits 2,1,0 TRel timeout indicator */
120 static int hf_atp_bitmap = -1; /* guint8_t bitmap or sequence number */
121 static int hf_atp_tid = -1; /* guint16_t transaction id. */
122 static int hf_atp_user_bytes = -1;
124 static int hf_atp_segments = -1;
125 static int hf_atp_segment = -1;
126 static int hf_atp_segment_overlap = -1;
127 static int hf_atp_segment_overlap_conflict = -1;
128 static int hf_atp_segment_multiple_tails = -1;
129 static int hf_atp_segment_too_long_segment = -1;
130 static int hf_atp_segment_error = -1;
131 static int hf_atp_reassembled_in = -1;
133 /* ------------------------- */
134 static int proto_zip = -1;
135 static dissector_handle_t zip_atp_handle;
137 static int hf_zip_function = -1;
138 static int hf_zip_atp_function = -1;
139 static int hf_zip_start_index = -1;
140 static int hf_zip_count = -1;
141 static int hf_zip_zero_value = -1;
143 static int hf_zip_network_count = -1;
144 static int hf_zip_network = -1;
145 static int hf_zip_network_start = -1;
146 static int hf_zip_network_end = -1;
148 static int hf_zip_flags = -1;
150 static int hf_zip_flags_zone_invalid = -1;
151 static int hf_zip_flags_use_broadcast = -1;
152 static int hf_zip_flags_only_one_zone = -1;
154 static int hf_zip_last_flag = -1;
156 static int hf_zip_zone_name = -1;
157 static int hf_zip_default_zone = -1;
159 static int hf_zip_multicast_length = -1;
160 static int hf_zip_multicast_address = -1;
162 static const value_string zip_function_vals[] = {
165 {5, "GetNetInfo request"},
166 {6, "GetNetInfo reply"},
168 {8, "Extended reply"},
172 static const value_string zip_atp_function_vals[] = {
175 {9, "GetLocalZones"},
179 static gint ett_zip = -1;
180 static gint ett_zip_flags = -1;
181 static gint ett_zip_zones_list = -1;
182 static gint ett_zip_network_list = -1;
184 /* --------------------------------
185 * from netatalk/include/atalk/ats.h
188 #define ASPFUNC_CLOSE 1
189 #define ASPFUNC_CMD 2
190 #define ASPFUNC_STAT 3
191 #define ASPFUNC_OPEN 4
192 #define ASPFUNC_TICKLE 5
193 #define ASPFUNC_WRITE 6
194 #define ASPFUNC_WRTCONT 7
195 #define ASPFUNC_ATTN 8
198 #define ASPERR_OK 0x0000
199 #define ASPERR_BADVERS 0xfbd6
200 #define ASPERR_BUFSMALL 0xfbd5
201 #define ASPERR_NOSESS 0xfbd4
202 #define ASPERR_NOSERV 0xfbd3
203 #define ASPERR_PARM 0xfbd2
204 #define ASPERR_SERVBUSY 0xfbd1
205 #define ASPERR_SESSCLOS 0xfbd0
206 #define ASPERR_SIZERR 0xfbcf
207 #define ASPERR_TOOMANY 0xfbce
208 #define ASPERR_NOACK 0xfbcd
210 static int proto_asp = -1;
211 static int hf_asp_func = -1;
212 static int hf_asp_error = -1;
213 static int hf_asp_socket = -1;
214 static int hf_asp_version = -1;
215 static int hf_asp_session_id = -1;
216 static int hf_asp_zero_value = -1;
217 static int hf_asp_init_error = -1;
218 static int hf_asp_attn_code = -1;
219 static int hf_asp_seq = -1;
220 static int hf_asp_size = -1;
222 /* status stuff same for asp and afp */
223 static int hf_asp_server_name = -1;
224 static int hf_asp_server_type = -1;
225 static int hf_asp_server_vers = -1;
226 static int hf_asp_server_uams = -1;
227 static int hf_asp_server_icon = -1;
228 static int hf_asp_server_directory = -1;
230 static int hf_asp_server_flag = -1;
231 static int hf_asp_server_flag_copyfile = -1;
232 static int hf_asp_server_flag_passwd = -1;
233 static int hf_asp_server_flag_no_save_passwd = -1;
234 static int hf_asp_server_flag_srv_msg = -1;
235 static int hf_asp_server_flag_srv_sig = -1;
236 static int hf_asp_server_flag_tcpip = -1;
237 static int hf_asp_server_flag_notify = -1;
238 static int hf_asp_server_flag_reconnect = -1;
239 static int hf_asp_server_flag_directory = -1;
240 static int hf_asp_server_flag_utf8_name = -1;
241 static int hf_asp_server_flag_fast_copy = -1;
242 static int hf_asp_server_signature = -1;
243 static int hf_asp_server_utf8_name_len = -1;
244 static int hf_asp_server_utf8_name = -1;
246 static int hf_asp_server_addr_len = -1;
247 static int hf_asp_server_addr_type = -1;
248 static int hf_asp_server_addr_value = -1;
250 static gint ett_asp_status = -1;
251 static gint ett_asp_uams = -1;
252 static gint ett_asp_vers = -1;
253 static gint ett_asp_addr = -1;
254 static gint ett_asp_addr_line = -1;
255 static gint ett_asp_directory = -1;
256 static gint ett_asp_utf8_name = -1;
257 static gint ett_asp_status_server_flag = -1;
259 static guint asp_packet_init_count = 200;
262 guint32 conversation;
268 guint8 value; /* command for asp, bitmap for atp */
271 static GHashTable *asp_request_hash = NULL;
272 static GMemChunk *asp_request_keys = NULL;
273 static GMemChunk *asp_request_vals = NULL;
276 static gint asp_equal (gconstpointer v, gconstpointer v2)
278 const asp_request_key *val1 = (const asp_request_key*)v;
279 const asp_request_key *val2 = (const asp_request_key*)v2;
281 if (val1->conversation == val2->conversation &&
282 val1->seq == val2->seq &&
283 !memcmp(val1->src, val2->src, 4)) {
289 static guint asp_hash (gconstpointer v)
291 const asp_request_key *asp_key = (const asp_request_key*)v;
295 /* ------------------------------------ */
296 static GHashTable *atp_request_hash = NULL;
297 static GMemChunk *atp_request_keys = NULL;
298 static GMemChunk *atp_request_vals = NULL;
301 /* ------------------------------------ */
302 static int proto_nbp = -1;
303 static int hf_nbp_op = -1;
304 static int hf_nbp_info = -1;
305 static int hf_nbp_count = -1;
306 static int hf_nbp_tid = -1;
308 static int hf_nbp_node_net = -1;
309 static int hf_nbp_node_port = -1;
310 static int hf_nbp_node_node = -1;
311 static int hf_nbp_node_enum = -1;
312 static int hf_nbp_node_object = -1;
313 static int hf_nbp_node_type = -1;
314 static int hf_nbp_node_zone = -1;
316 static int proto_rtmp = -1;
317 static int hf_rtmp_net = -1;
318 static int hf_rtmp_node_len = -1;
319 static int hf_rtmp_node = -1;
320 static int hf_rtmp_tuple_net = -1;
321 static int hf_rtmp_tuple_range_start = -1;
322 static int hf_rtmp_tuple_range_end = -1;
323 static int hf_rtmp_tuple_dist = -1;
324 static int hf_rtmp_function = -1;
326 static gint ett_atp = -1;
328 static gint ett_atp_segments = -1;
329 static gint ett_atp_segment = -1;
330 static gint ett_atp_info = -1;
331 static gint ett_asp = -1;
333 static gint ett_nbp = -1;
334 static gint ett_nbp_info = -1;
335 static gint ett_nbp_node = -1;
336 static gint ett_rtmp = -1;
337 static gint ett_rtmp_tuple = -1;
338 static gint ett_ddp = -1;
339 static gint ett_llap = -1;
340 static gint ett_pstring = -1;
342 static const fragment_items atp_frag_items = {
347 &hf_atp_segment_overlap,
348 &hf_atp_segment_overlap_conflict,
349 &hf_atp_segment_multiple_tails,
350 &hf_atp_segment_too_long_segment,
351 &hf_atp_segment_error,
352 &hf_atp_reassembled_in,
356 static dissector_table_t ddp_dissector_table;
358 static dissector_handle_t data_handle;
360 #define DDP_SHORT_HEADER_SIZE 5
363 * P = Padding, H = Hops, L = Len
367 * Assumes the argument is in host byte order.
369 #define ddp_hops(x) ( ( x >> 10) & 0x3C )
370 #define ddp_len(x) ( x & 0x03ff )
371 typedef struct _e_ddp {
372 guint16 hops_len; /* combines pad, hops, and len */
373 guint16 sum,dnet,snet;
379 #define DDP_HEADER_SIZE 13
382 static const value_string op_vals[] = {
383 {DDP_RTMPDATA, "AppleTalk Routing Table response or data" },
384 {DDP_NBP, "AppleTalk Name Binding Protocol packet"},
385 {DDP_ATP, "AppleTalk Transaction Protocol packet"},
386 {DDP_AEP, "AppleTalk Echo Protocol packet"},
387 {DDP_RTMPREQ, "AppleTalk Routing Table request"},
388 {DDP_ZIP, "AppleTalk Zone Information Protocol packet"},
389 {DDP_ADSP, "AppleTalk Data Stream Protocol"},
390 {DDP_EIGRP, "Cisco EIGRP for AppleTalk"},
394 static const value_string rtmp_function_vals[] = {
396 {2, "Route Data Request (split horizon processed)"},
397 {3, "Route Data Request (no split horizon processing)"},
401 #define NBP_BROADCAST 1
403 #define NBP_FORWARD 4
406 static const value_string nbp_op_vals[] = {
407 {NBP_BROADCAST, "broadcast request"},
408 {NBP_LOOKUP, "lookup"},
409 {NBP_FORWARD, "forward request"},
410 {NBP_REPLY, "reply"},
414 static const value_string atp_function_vals[] = {
415 {ATP_TREQ ,"REQuest"},
416 {ATP_TRESP ,"RESPonse"},
417 {ATP_TREL ,"RELease"},
421 static const value_string atp_trel_timer_vals[] = {
432 static const value_string asp_func_vals[] = {
433 {ASPFUNC_CLOSE, "CloseSession" },
434 {ASPFUNC_CMD, "Command" },
435 {ASPFUNC_STAT, "GetStatus" },
436 {ASPFUNC_OPEN, "OpenSession" },
437 {ASPFUNC_TICKLE, "Tickle" },
438 {ASPFUNC_WRITE, "Write" },
439 {ASPFUNC_WRTCONT, "Write Cont" },
440 {ASPFUNC_ATTN, "Attention" },
443 const value_string asp_error_vals[] = {
444 {AFP_OK , "success"},
445 {AFPERR_ACCESS , "permission denied" },
446 {AFPERR_AUTHCONT , "logincont" },
447 {AFPERR_BADUAM , "uam doesn't exist" },
448 {AFPERR_BADVERS , "bad afp version number" },
449 {AFPERR_BITMAP , "invalid bitmap" },
450 {AFPERR_CANTMOVE , "can't move file" },
451 {AFPERR_DENYCONF , "file synchronization locks conflict" },
452 {AFPERR_DIRNEMPT , "directory not empty" },
453 {AFPERR_DFULL , "disk full" },
454 {AFPERR_EOF , "end of file" },
455 {AFPERR_BUSY , "FileBusy" },
456 {AFPERR_FLATVOL , "volume doesn't support directories" },
457 {AFPERR_NOITEM , "ItemNotFound" },
458 {AFPERR_LOCK , "LockErr" },
459 {AFPERR_MISC , "misc. err" },
460 {AFPERR_NLOCK , "no more locks" },
461 {AFPERR_NOSRVR , "no response by server at that address" },
462 {AFPERR_EXIST , "object already exists" },
463 {AFPERR_NOOBJ , "object not found" },
464 {AFPERR_PARAM , "parameter error" },
465 {AFPERR_NORANGE , "no range lock" },
466 {AFPERR_RANGEOVR , "range overlap" },
467 {AFPERR_SESSCLOS , "session closed" },
468 {AFPERR_NOTAUTH , "user not authenticated" },
469 {AFPERR_NOOP , "command not supported" },
470 {AFPERR_BADTYPE , "object is the wrong type" },
471 {AFPERR_NFILE , "too many files open" },
472 {AFPERR_SHUTDOWN , "server is going down" },
473 {AFPERR_NORENAME , "can't rename" },
474 {AFPERR_NODIR , "couldn't find directory" },
475 {AFPERR_ITYPE , "wrong icon type" },
476 {AFPERR_VLOCK , "volume locked" },
477 {AFPERR_OLOCK , "object locked" },
478 {AFPERR_CTNSHRD , "share point contains a share point" },
479 {AFPERR_NOID , "file thread not found" },
480 {AFPERR_EXISTID , "file already has an id" },
481 {AFPERR_DIFFVOL , "different volume" },
482 {AFPERR_CATCHNG , "catalog has changed" },
483 {AFPERR_SAMEOBJ , "source file == destination file" },
484 {AFPERR_BADID , "non-existent file id" },
485 {AFPERR_PWDSAME , "same password/can't change password" },
486 {AFPERR_PWDSHORT , "password too short" },
487 {AFPERR_PWDEXPR , "password expired" },
488 {AFPERR_INSHRD , "folder being shared is inside a shared folder." },
489 {AFPERR_INTRASH , "shared folder in trash." },
490 {AFPERR_PWDCHNG , "password needs to be changed" },
491 {AFPERR_PWDPOLCY , "password fails policy check" },
492 {AFPERR_USRLOGIN , "user already logged on" },
496 * XXX - do this with an FT_UINT_STRING?
497 * Unfortunately, you can't extract from an FT_UINT_STRING the string,
498 * which we'd want to do in order to put it into the "Data:" portion.
500 * Are these always in the Mac extended character set?
502 static int dissect_pascal_string(tvbuff_t *tvb, int offset, proto_tree *tree,
507 len = tvb_get_guint8(tvb, offset);
517 * XXX - if we could do this inside the protocol tree
518 * code, we could perhaps avoid allocating and freeing
519 * this string buffer.
521 tmp = tvb_get_string(tvb, offset, len);
522 item = proto_tree_add_string(tree, hf_index, tvb, offset-1, len+1, tmp);
524 subtree = proto_item_add_subtree(item, ett_pstring);
525 proto_tree_add_text(subtree, tvb, offset-1, 1, "Length: %d", len);
526 proto_tree_add_text(subtree, tvb, offset, len, "Data: %s", tmp);
536 dissect_rtmp_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
537 proto_tree *rtmp_tree;
541 if (check_col(pinfo->cinfo, COL_PROTOCOL))
542 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
543 if (check_col(pinfo->cinfo, COL_INFO))
544 col_clear(pinfo->cinfo, COL_INFO);
546 function = tvb_get_guint8(tvb, 0);
548 if (check_col(pinfo->cinfo, COL_INFO))
549 col_add_fstr(pinfo->cinfo, COL_INFO, "%s",
550 val_to_str(function, rtmp_function_vals, "Unknown function (%02x)"));
553 ti = proto_tree_add_item(tree, proto_rtmp, tvb, 0, 1, FALSE);
554 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
556 proto_tree_add_uint(rtmp_tree, hf_rtmp_function, tvb, 0, 1, function);
561 dissect_rtmp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
562 proto_tree *rtmp_tree;
566 guint8 nodelen,nodelen_bits;
567 guint16 node; /* might be more than 8 bits */
570 if (check_col(pinfo->cinfo, COL_PROTOCOL))
571 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
572 if (check_col(pinfo->cinfo, COL_INFO))
573 col_clear(pinfo->cinfo, COL_INFO);
575 net = tvb_get_ntohs(tvb, offset);
576 nodelen_bits = tvb_get_guint8(tvb, offset+2);
577 if ( nodelen_bits <= 8 ) {
578 node = tvb_get_guint8(tvb, offset)+1;
581 node = tvb_get_ntohs(tvb, offset);
585 if (check_col(pinfo->cinfo, COL_INFO))
586 col_add_fstr(pinfo->cinfo, COL_INFO, "Net: %u Node Len: %u Node: %u",
587 net, nodelen_bits, node);
590 ti = proto_tree_add_item(tree, proto_rtmp, tvb, offset, -1, FALSE);
591 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
593 proto_tree_add_uint(rtmp_tree, hf_rtmp_net, tvb, offset, 2, net);
594 proto_tree_add_uint(rtmp_tree, hf_rtmp_node_len, tvb, offset+2, 1,
596 proto_tree_add_uint(rtmp_tree, hf_rtmp_node, tvb, offset+3, nodelen,
598 offset += 3 + nodelen;
601 while (tvb_offset_exists(tvb, offset)) {
602 proto_tree *tuple_item, *tuple_tree;
605 guint16 tuple_range_end;
607 tuple_net = tvb_get_ntohs(tvb, offset);
608 tuple_dist = tvb_get_guint8(tvb, offset+2);
610 if (tuple_dist & 0x80) {
611 tuple_range_end = tvb_get_ntohs(tvb, offset+3);
612 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 6,
613 "Tuple %d: Range Start: %u Dist: %u Range End: %u",
614 i, tuple_net, tuple_dist&0x7F, tuple_range_end);
616 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 3,
617 "Tuple %d: Net: %u Dist: %u",
618 i, tuple_net, tuple_dist);
620 tuple_tree = proto_item_add_subtree(tuple_item, ett_rtmp_tuple);
622 if (tuple_dist & 0x80) {
623 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_range_start, tvb, offset, 2,
626 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_net, tvb, offset, 2,
629 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_dist, tvb, offset+2, 1,
632 if (tuple_dist & 0x80) {
634 * Extended network tuple.
636 proto_tree_add_item(tuple_tree, hf_rtmp_tuple_range_end, tvb, offset+3, 2,
648 dissect_nbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
649 proto_tree *nbp_tree;
650 proto_tree *nbp_info_tree;
651 proto_item *ti, *info_item;
657 if (check_col(pinfo->cinfo, COL_PROTOCOL))
658 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBP");
659 if (check_col(pinfo->cinfo, COL_INFO))
660 col_clear(pinfo->cinfo, COL_INFO);
662 info = tvb_get_guint8(tvb, offset);
666 if (check_col(pinfo->cinfo, COL_INFO))
667 col_add_fstr(pinfo->cinfo, COL_INFO, "Op: %s Count: %u",
668 val_to_str(op, nbp_op_vals, "Unknown (0x%01x)"), count);
671 ti = proto_tree_add_item(tree, proto_nbp, tvb, offset, -1, FALSE);
672 nbp_tree = proto_item_add_subtree(ti, ett_nbp);
674 info_item = proto_tree_add_uint_format(nbp_tree, hf_nbp_info, tvb, offset, 1,
676 "Info: 0x%01X Operation: %s Count: %u", info,
677 val_to_str(op, nbp_op_vals, "Unknown (0x%01X)"),
679 nbp_info_tree = proto_item_add_subtree(info_item, ett_nbp_info);
680 proto_tree_add_uint(nbp_info_tree, hf_nbp_op, tvb, offset, 1, info);
681 proto_tree_add_uint(nbp_info_tree, hf_nbp_count, tvb, offset, 1, info);
682 proto_tree_add_item(nbp_tree, hf_nbp_tid, tvb, offset+1, 1, FALSE);
685 for (i=0; i<count; i++) {
686 proto_tree *node_item,*node_tree;
687 int soffset = offset;
689 node_item = proto_tree_add_text(nbp_tree, tvb, offset, -1,
691 node_tree = proto_item_add_subtree(node_item, ett_nbp_node);
693 proto_tree_add_item(node_tree, hf_nbp_node_net, tvb, offset, 2, FALSE);
695 proto_tree_add_item(node_tree, hf_nbp_node_node, tvb, offset, 1, FALSE);
697 proto_tree_add_item(node_tree, hf_nbp_node_port, tvb, offset, 1, FALSE);
699 proto_tree_add_item(node_tree, hf_nbp_node_enum, tvb, offset, 1, FALSE);
702 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_object);
703 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_type);
704 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_zone);
706 proto_item_set_len(node_item, offset-soffset);
713 /* -----------------------------
714 ATP protocol cf. inside appletalk chap. 9
715 desegmentation from packet-ieee80211.c
718 dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
719 proto_tree *atp_tree = NULL;
721 proto_tree *atp_info_tree;
722 proto_item *info_item;
725 guint8 frag_number = 0;
729 struct aspinfo aspinfo;
730 tvbuff_t *new_tvb = NULL;
731 gboolean save_fragmented;
732 gboolean more_fragment = FALSE;
737 conversation_t *conversation;
738 asp_request_key request_key, *new_request_key;
739 asp_request_val *request_val;
741 if (check_col(pinfo->cinfo, COL_PROTOCOL))
742 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
744 ctrlinfo = tvb_get_guint8(tvb, offset);
745 bitmap = tvb_get_guint8(tvb, offset +1);
746 tid = tvb_get_ntohs(tvb, offset +2);
756 aspinfo.reply = (0x80 == (ctrlinfo & ATP_FUNCMASK))?1:0;
757 aspinfo.release = (0xC0 == (ctrlinfo & ATP_FUNCMASK))?1:0;
760 query = (!aspinfo.reply && !aspinfo.release);
762 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
763 pinfo->srcport, pinfo->destport, 0);
765 if (conversation == NULL)
767 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
768 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
771 request_key.conversation = conversation->index;
772 memcpy(request_key.src, (!aspinfo.reply)?pinfo->src.data:pinfo->dst.data, 4);
773 request_key.seq = aspinfo.seq;
775 request_val = (asp_request_val *) g_hash_table_lookup(atp_request_hash, &request_key);
777 if (!request_val && query ) {
778 new_request_key = g_mem_chunk_alloc(atp_request_keys);
779 *new_request_key = request_key;
781 request_val = g_mem_chunk_alloc(atp_request_vals);
782 request_val->value = nbe;
784 g_hash_table_insert(atp_request_hash, new_request_key,request_val);
788 ATP_EOM is not mandatory. Some implementations don't always set it
789 if the query is only one packet.
791 So it needs to keep the number of packets asked in request.
795 more_fragment = !((ATP_EOM & ctrlinfo) || (request_val && 1 == request_val->value));
796 frag_number = bitmap;
799 if (check_col(pinfo->cinfo, COL_INFO)) {
800 col_clear(pinfo->cinfo, COL_INFO);
801 col_add_fstr(pinfo->cinfo, COL_INFO, "%s transaction %u",
802 val_to_str(op, atp_function_vals, "Unknown (0x%01x)"),tid);
804 col_append_fstr(pinfo->cinfo, COL_INFO, " [fragment]");
808 ti = proto_tree_add_item(tree, proto_atp, tvb, offset, -1, FALSE);
809 atp_tree = proto_item_add_subtree(ti, ett_atp);
810 proto_item_set_len(atp_tree, aspinfo.release?8:ATP_HDRSIZE -1);
812 info_item = proto_tree_add_item(atp_tree, hf_atp_ctrlinfo, tvb, offset, 1, FALSE);
813 atp_info_tree = proto_item_add_subtree(info_item, ett_atp_info);
815 proto_tree_add_item(atp_info_tree, hf_atp_function, tvb, offset, 1, FALSE);
816 proto_tree_add_item(atp_info_tree, hf_atp_xo, tvb, offset, 1, FALSE);
817 proto_tree_add_item(atp_info_tree, hf_atp_eom, tvb, offset, 1, FALSE);
818 proto_tree_add_item(atp_info_tree, hf_atp_sts, tvb, offset, 1, FALSE);
819 if ((ctrlinfo & (ATP_FUNCMASK|ATP_XO)) == (0x40|ATP_XO)) {
820 /* TReq with XO set */
821 proto_tree_add_item(atp_info_tree, hf_atp_treltimer, tvb, offset, 1, FALSE);
824 proto_tree_add_text(atp_tree, tvb, offset +1, 1,
825 "Bitmap: 0x%02x %u packet(s) max", bitmap, nbe);
828 proto_tree_add_item(atp_tree, hf_atp_bitmap, tvb, offset +1, 1, FALSE);
830 proto_tree_add_item(atp_tree, hf_atp_tid, tvb, offset +2, 2, FALSE);
833 proto_tree_add_item(atp_tree, hf_atp_user_bytes, tvb, offset +4, 4, FALSE);
840 save_fragmented = pinfo->fragmented;
843 asp doesn't fit very well here
844 move asp back in atp?
846 if (atp_defragment && aspinfo.reply && (more_fragment || frag_number != 0)) {
847 fragment_data *fd_head;
850 hdr = ATP_HDRSIZE -1;
851 if (frag_number != 0)
852 hdr += 4; /* asp header */
853 len = tvb_reported_length_remaining(tvb, hdr);
854 fd_head = fragment_add_seq_check(tvb, hdr, pinfo, tid,
856 atp_reassembled_table,
860 new_tvb = process_reassembled_data(tvb, ATP_HDRSIZE -1, pinfo,
861 "Reassembled ATP", fd_head, &atp_frag_items,
866 new_tvb = tvb_new_subset(tvb, ATP_HDRSIZE -1, -1,- 1);
870 pinfo->private_data = &aspinfo;
871 /* if port == 6 it's not an ASP packet but a ZIP packet */
872 if (pinfo->srcport == 6 || pinfo->destport == 6 )
873 call_dissector(zip_atp_handle, new_tvb, pinfo, tree);
875 call_dissector(asp_handle, new_tvb, pinfo, tree);
878 /* Just show this as a fragment. */
879 new_tvb = tvb_new_subset (tvb, ATP_HDRSIZE -1, -1, -1);
880 call_dissector(data_handle, new_tvb, pinfo, tree);
882 pinfo->fragmented = save_fragmented;
887 copy and paste from dsi
888 XXX - is the format of this reply dependent on the type of server,
889 with this format being the format for AFP servers?
892 dissect_asp_reply_get_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
894 proto_tree *sub_tree;
900 guint16 sign_ofs = 0;
911 ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
912 tree = proto_item_add_subtree(ti, ett_asp_status);
914 machine_ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
915 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %u", machine_ofs);
917 machine_ofs += offset;
919 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
920 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %u", ofs);
922 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
923 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %u", ofs);
925 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
926 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %u", ofs);
928 ofs = offset +AFPSTATUS_FLAGOFF;
929 ti = proto_tree_add_item(tree, hf_asp_server_flag, tvb, ofs, 2, FALSE);
930 sub_tree = proto_item_add_subtree(ti, ett_asp_status_server_flag);
931 proto_tree_add_item(sub_tree, hf_asp_server_flag_copyfile , tvb, ofs, 2, FALSE);
932 proto_tree_add_item(sub_tree, hf_asp_server_flag_passwd , tvb, ofs, 2, FALSE);
933 proto_tree_add_item(sub_tree, hf_asp_server_flag_no_save_passwd, tvb, ofs, 2, FALSE);
934 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_msg , tvb, ofs, 2, FALSE);
935 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_sig , tvb, ofs, 2, FALSE);
936 proto_tree_add_item(sub_tree, hf_asp_server_flag_tcpip , tvb, ofs, 2, FALSE);
937 proto_tree_add_item(sub_tree, hf_asp_server_flag_notify , tvb, ofs, 2, FALSE);
938 proto_tree_add_item(sub_tree, hf_asp_server_flag_reconnect , tvb, ofs, 2, FALSE);
939 proto_tree_add_item(sub_tree, hf_asp_server_flag_directory , tvb, ofs, 2, FALSE);
940 proto_tree_add_item(sub_tree, hf_asp_server_flag_utf8_name , tvb, ofs, 2, FALSE);
941 proto_tree_add_item(sub_tree, hf_asp_server_flag_fast_copy , tvb, ofs, 2, FALSE);
943 proto_tree_add_item(tree, hf_asp_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, FALSE);
945 flag = tvb_get_ntohs(tvb, ofs);
946 if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
947 ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
951 sign_ofs = tvb_get_ntohs(tvb, ofs);
952 proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %u", sign_ofs);
956 if ((flag & AFPSRVRINFO_TCPIP) && ofs < machine_ofs ) {
957 adr_ofs = tvb_get_ntohs(tvb, ofs);
958 proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %u", adr_ofs);
963 if ((flag & AFPSRVRINFO_SRVDIRECTORY) && ofs < machine_ofs) {
964 dir_ofs = tvb_get_ntohs(tvb, ofs);
965 proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %u", dir_ofs);
970 if ((flag & AFPSRVRINFO_SRVUTF8) && ofs < machine_ofs) {
971 utf_ofs = tvb_get_ntohs(tvb, ofs);
972 proto_tree_add_text(tree, tvb, ofs, 2, "UTF-8 Server name offset: %u", utf_ofs);
978 proto_tree_add_item(tree, hf_asp_server_type, tvb, machine_ofs, 1, FALSE);
980 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
982 nbe = tvb_get_guint8(tvb, ofs);
983 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %u", nbe);
985 sub_tree = proto_item_add_subtree(ti, ett_asp_vers);
986 for (i = 0; i < nbe; i++) {
987 len = tvb_get_guint8(tvb, ofs);
988 proto_tree_add_item(sub_tree, hf_asp_server_vers, tvb, ofs, 1, FALSE);
993 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
995 nbe = tvb_get_guint8(tvb, ofs);
996 ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %u", nbe);
998 sub_tree = proto_item_add_subtree(ti, ett_asp_uams);
999 for (i = 0; i < nbe; i++) {
1000 len = tvb_get_guint8(tvb, ofs);
1001 proto_tree_add_item(sub_tree, hf_asp_server_uams, tvb, ofs, 1, FALSE);
1006 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1008 proto_tree_add_item(tree, hf_asp_server_icon, tvb, ofs, 256, FALSE);
1011 proto_tree_add_item(tree, hf_asp_server_signature, tvb, sign_ofs, 16, FALSE);
1015 proto_tree *adr_tree;
1023 nbe = tvb_get_guint8(tvb, ofs);
1024 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %u", nbe);
1026 adr_tree = proto_item_add_subtree(ti, ett_asp_addr);
1027 for (i = 0; i < nbe; i++) {
1030 len = tvb_get_guint8(tvb, ofs);
1031 type = tvb_get_guint8(tvb, ofs +1);
1034 ip = tvb_get_ptr(tvb, ofs+2, 4);
1035 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", ip_to_str(ip));
1037 case 2: /* IP + port */
1038 ip = tvb_get_ptr(tvb, ofs+2, 4);
1039 port = tvb_get_ntohs(tvb, ofs+6);
1040 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%u",ip_to_str(ip),port);
1042 case 3: /* DDP, atalk_addr_to_str want host order not network */
1043 net = tvb_get_ntohs(tvb, ofs+2);
1044 node = tvb_get_guint8(tvb, ofs +4);
1045 port = tvb_get_guint8(tvb, ofs +5);
1046 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
1049 case 5: /* IP + port ssh tunnel */
1050 ip = tvb_get_ptr(tvb, ofs+2, 4);
1051 port = tvb_get_ntohs(tvb, ofs+6);
1052 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip (ssh tunnel) %s:%u",ip_to_str(ip),port);
1056 tmp = tvb_get_string(tvb, ofs +2, len -2);
1057 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
1061 /* else fall to default malformed record */
1063 ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknow type : %u", type);
1067 sub_tree = proto_item_add_subtree(ti,ett_asp_addr_line);
1068 proto_tree_add_item(sub_tree, hf_asp_server_addr_len, tvb, ofs, 1, FALSE);
1070 proto_tree_add_item(sub_tree, hf_asp_server_addr_type, tvb, ofs, 1, FALSE);
1072 proto_tree_add_item(sub_tree, hf_asp_server_addr_value,tvb, ofs, len, FALSE);
1079 nbe = tvb_get_guint8(tvb, ofs);
1080 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %u", nbe);
1082 sub_tree = proto_item_add_subtree(ti, ett_asp_directory);
1083 for (i = 0; i < nbe; i++) {
1084 len = tvb_get_guint8(tvb, ofs);
1085 proto_tree_add_item(sub_tree, hf_asp_server_directory, tvb, ofs, 1, FALSE);
1094 ulen = tvb_get_ntohs(tvb, ofs);
1095 tmp = tvb_get_string(tvb, ofs + 2, ulen);
1096 ti = proto_tree_add_text(tree, tvb, ofs, ulen +2, "UTF8 server name: %s", tmp);
1097 sub_tree = proto_item_add_subtree(ti, ett_asp_utf8_name);
1098 proto_tree_add_uint(sub_tree, hf_asp_server_utf8_name_len, tvb, ofs, 2, ulen);
1100 proto_tree_add_string(sub_tree, hf_asp_server_utf8_name, tvb, ofs, ulen, tmp);
1104 /* FIXME: offset is not updated */
1108 /* -----------------------------
1109 ASP protocol cf. inside appletalk chap. 11
1111 static struct aspinfo *
1112 get_transaction(tvbuff_t *tvb, packet_info *pinfo)
1114 struct aspinfo *aspinfo = pinfo->private_data;
1115 conversation_t *conversation;
1116 asp_request_key request_key, *new_request_key;
1117 asp_request_val *request_val;
1120 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
1121 pinfo->srcport, pinfo->destport, 0);
1123 if (conversation == NULL)
1125 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1126 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1129 request_key.conversation = conversation->index;
1130 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
1131 request_key.seq = aspinfo->seq;
1133 request_val = (asp_request_val *) g_hash_table_lookup(
1134 asp_request_hash, &request_key);
1135 if (!request_val && !aspinfo->reply ) {
1136 fn = tvb_get_guint8(tvb, 0);
1137 new_request_key = g_mem_chunk_alloc(asp_request_keys);
1138 *new_request_key = request_key;
1140 request_val = g_mem_chunk_alloc(asp_request_vals);
1141 request_val->value = fn;
1143 g_hash_table_insert(asp_request_hash, new_request_key,
1150 aspinfo->command = request_val->value;
1156 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1158 struct aspinfo *aspinfo;
1160 proto_tree *asp_tree = NULL;
1165 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1166 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1167 if (check_col(pinfo->cinfo, COL_INFO))
1168 col_clear(pinfo->cinfo, COL_INFO);
1170 aspinfo = get_transaction(tvb, pinfo);
1174 fn = (guint8) aspinfo->command;
1176 if (check_col(pinfo->cinfo, COL_INFO)) {
1178 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1180 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1181 val_to_str(fn, asp_func_vals, "Unknown (0x%01x)"), aspinfo->seq);
1185 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, FALSE);
1186 asp_tree = proto_item_add_subtree(ti, ett_asp);
1188 if (!aspinfo->reply) {
1190 /* let the called deal with asp_tree == NULL */
1192 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, FALSE);
1196 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1198 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, FALSE);
1201 case ASPFUNC_TICKLE:
1203 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1205 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1209 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1211 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1215 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1217 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, FALSE);
1222 proto_item_set_len(asp_tree, 4);
1223 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1225 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1227 len = tvb_reported_length_remaining(tvb,offset);
1228 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1229 call_dissector(afp_handle, new_tvb, pinfo, tree);
1231 case ASPFUNC_WRTCONT:
1232 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1234 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, FALSE);
1236 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, FALSE);
1240 proto_item_set_len(asp_tree, 4);
1242 len = tvb_reported_length_remaining(tvb,offset);
1243 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1250 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1253 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, FALSE);
1255 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, FALSE);
1257 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, FALSE);
1261 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1263 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, FALSE);
1265 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, FALSE);
1269 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1271 dissect_asp_reply_get_status(tvb, pinfo, asp_tree, offset);
1275 proto_item_set_len(asp_tree, 4);
1276 aspinfo->code = tvb_get_ntohl(tvb, offset);
1277 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, FALSE);
1279 len = tvb_reported_length_remaining(tvb,offset);
1280 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1281 call_dissector(afp_handle, new_tvb, pinfo, tree);
1283 case ASPFUNC_TICKLE:
1284 case ASPFUNC_WRTCONT:
1285 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, FALSE);
1287 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1289 proto_item_set_len(asp_tree, 4);
1291 len = tvb_reported_length_remaining(tvb,offset);
1292 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1298 /* -----------------------------
1299 ZIP protocol cf. inside appletalk chap. 8
1302 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1304 struct aspinfo *aspinfo;
1306 proto_tree *zip_tree;
1307 proto_tree *sub_tree;
1313 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1314 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1315 if (check_col(pinfo->cinfo, COL_INFO))
1316 col_clear(pinfo->cinfo, COL_INFO);
1318 aspinfo = get_transaction(tvb, pinfo);
1322 fn = (guint8) aspinfo->command;
1324 if (check_col(pinfo->cinfo, COL_INFO)) {
1326 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1328 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1329 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1335 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, FALSE);
1336 zip_tree = proto_item_add_subtree(ti, ett_zip);
1338 if (!aspinfo->reply) {
1339 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, FALSE);
1342 case 7: /* start_index = 0 */
1345 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1347 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, FALSE);
1354 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1359 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, FALSE);
1362 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1364 count = tvb_get_ntohs(tvb, offset);
1365 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, FALSE);
1367 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1368 for (i= 1; i <= count; i++) {
1369 len = tvb_get_guint8(tvb, offset);
1370 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1379 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1381 proto_tree *zip_tree = NULL;
1386 proto_tree *flag_tree;
1387 proto_tree *sub_tree;
1388 proto_tree *net_tree;
1394 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1395 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1396 if (check_col(pinfo->cinfo, COL_INFO))
1397 col_clear(pinfo->cinfo, COL_INFO);
1399 fn = tvb_get_guint8(tvb, 0);
1400 if (check_col(pinfo->cinfo, COL_INFO)) {
1401 col_add_str(pinfo->cinfo, COL_INFO,
1402 val_to_str(fn, zip_function_vals, "Unknown ZIP function (%02x)"));
1408 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, FALSE);
1409 zip_tree = proto_item_add_subtree(ti, ett_zip);
1411 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,FALSE);
1413 /* fn 1,7,2,8 are not tested */
1416 count = tvb_get_guint8(tvb, offset);
1417 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1419 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1420 for (i= 1; i <= count; i++) {
1421 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, FALSE);
1425 case 7: /* Notify */
1426 flag = tvb_get_guint8(tvb, offset);
1427 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1428 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1429 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1430 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1431 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1434 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1437 len = tvb_get_guint8(tvb, offset);
1438 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1441 len = tvb_get_guint8(tvb, offset);
1442 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1444 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1447 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1451 case 8: /* Extended Reply */
1452 count = tvb_get_guint8(tvb, offset);
1453 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, FALSE);
1455 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1456 for (i= 1; i <= count; i++) {
1457 net = tvb_get_ntohs(tvb, offset);
1458 ti = proto_tree_add_text(zip_tree, tvb, offset , 2, "Zone for network : %u", net);
1459 net_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1460 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, FALSE);
1462 len = tvb_get_guint8(tvb, offset);
1463 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1468 case 5 : /* GetNetInfo request */
1469 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, FALSE);
1471 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, FALSE);
1473 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1476 case 6 : /* GetNetInfo reply */
1477 flag = tvb_get_guint8(tvb, offset);
1478 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1479 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1480 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,FALSE);
1481 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,FALSE);
1482 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,FALSE);
1485 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, FALSE);
1488 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, FALSE);
1491 len = tvb_get_guint8(tvb, offset);
1492 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,FALSE);
1495 len = tvb_get_guint8(tvb, offset);
1496 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,FALSE);
1498 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,FALSE);
1500 if ((flag & 0x80) != 0)
1501 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,FALSE);
1510 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, guint8 dnode,
1511 guint8 snode, proto_tree *tree)
1517 proto_tree *ddp_tree = NULL;
1519 static struct atalk_ddp_addr src, dst;
1522 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1523 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1524 if (check_col(pinfo->cinfo, COL_INFO))
1525 col_clear(pinfo->cinfo, COL_INFO);
1528 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1530 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1532 len = tvb_get_ntohs(tvb, 0);
1534 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1535 dport = tvb_get_guint8(tvb, 2);
1537 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1538 sport = tvb_get_guint8(tvb, 3);
1540 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1541 type = tvb_get_guint8(tvb, 4);
1547 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1548 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1549 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1550 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1552 pinfo->ptype = PT_DDP;
1553 pinfo->destport = dport;
1554 pinfo->srcport = sport;
1556 if (check_col(pinfo->cinfo, COL_INFO)) {
1557 col_add_str(pinfo->cinfo, COL_INFO,
1558 val_to_str(type, op_vals, "Unknown DDP protocol (%02x)"));
1561 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1562 4, 3, atalk_addr_to_str(&src));
1563 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1564 6, 3, atalk_addr_to_str(&dst));
1566 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1568 new_tvb = tvb_new_subset(tvb, DDP_SHORT_HEADER_SIZE, -1, -1);
1570 if (!dissector_try_port(ddp_dissector_table, type, new_tvb, pinfo, tree))
1571 call_dissector(data_handle,new_tvb, pinfo, tree);
1575 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1578 proto_tree *ddp_tree;
1580 static struct atalk_ddp_addr src, dst;
1583 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1584 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1585 if (check_col(pinfo->cinfo, COL_INFO))
1586 col_clear(pinfo->cinfo, COL_INFO);
1588 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1589 ddp.dnet=g_ntohs(ddp.dnet);
1590 ddp.snet=g_ntohs(ddp.snet);
1591 ddp.sum=g_ntohs(ddp.sum);
1592 ddp.hops_len=g_ntohs(ddp.hops_len);
1595 src.node = ddp.snode;
1597 dst.node = ddp.dnode;
1598 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1599 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1600 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1601 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1603 pinfo->ptype = PT_DDP;
1604 pinfo->destport = ddp.dport;
1605 pinfo->srcport = ddp.sport;
1607 if (check_col(pinfo->cinfo, COL_INFO))
1608 col_add_str(pinfo->cinfo, COL_INFO,
1609 val_to_str(ddp.type, op_vals, "Unknown DDP protocol (%02x)"));
1612 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1614 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1616 proto_tree_add_string_hidden(ddp_tree, hf_ddp_src, tvb,
1617 4, 3, atalk_addr_to_str(&src));
1618 proto_tree_add_string_hidden(ddp_tree, hf_ddp_dst, tvb,
1619 6, 3, atalk_addr_to_str(&dst));
1621 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1622 ddp_hops(ddp.hops_len));
1623 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1624 ddp_len(ddp.hops_len));
1625 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1627 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1629 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1631 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1633 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1635 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1637 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1639 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1643 new_tvb = tvb_new_subset(tvb, DDP_HEADER_SIZE, -1, -1);
1645 if (!dissector_try_port(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1646 call_dissector(data_handle,new_tvb, pinfo, tree);
1649 static const value_string llap_type_vals[] = {
1650 {0x01, "Short DDP"},
1653 {0x82, "Acknowledgement"},
1660 capture_llap(packet_counts *ld)
1666 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1671 proto_tree *llap_tree = NULL;
1675 if (check_col(pinfo->cinfo, COL_PROTOCOL))
1676 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1677 if (check_col(pinfo->cinfo, COL_INFO))
1678 col_clear(pinfo->cinfo, COL_INFO);
1681 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, FALSE);
1682 llap_tree = proto_item_add_subtree(ti, ett_llap);
1685 dnode = tvb_get_guint8(tvb, 0);
1687 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, dnode);
1688 snode = tvb_get_guint8(tvb, 1);
1690 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, snode);
1691 type = tvb_get_guint8(tvb, 2);
1692 if (check_col(pinfo->cinfo, COL_INFO)) {
1693 col_add_str(pinfo->cinfo, COL_INFO,
1694 val_to_str(type, llap_type_vals, "Unknown LLAP type (%02x)"));
1697 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1699 new_tvb = tvb_new_subset(tvb, 3, -1, -1);
1704 if (proto_is_protocol_enabled(find_protocol_by_id(proto_ddp))) {
1705 pinfo->current_proto = "DDP";
1706 dissect_ddp_short(new_tvb, pinfo, dnode, snode, tree);
1711 if (call_dissector(ddp_handle, new_tvb, pinfo, tree))
1714 call_dissector(data_handle,new_tvb, pinfo, tree);
1721 fragment_table_init(&atp_fragment_table);
1722 reassembled_table_init(&atp_reassembled_table);
1724 if (atp_request_hash)
1725 g_hash_table_destroy(atp_request_hash);
1726 if (atp_request_keys)
1727 g_mem_chunk_destroy(atp_request_keys);
1728 if (atp_request_vals)
1729 g_mem_chunk_destroy(atp_request_vals);
1731 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1733 atp_request_keys = g_mem_chunk_new("atp_request_keys",
1734 sizeof(asp_request_key),
1735 asp_packet_init_count * sizeof(asp_request_key),
1737 atp_request_vals = g_mem_chunk_new("atp_request_vals",
1738 sizeof(asp_request_val),
1739 asp_packet_init_count * sizeof(asp_request_val),
1747 if (asp_request_hash)
1748 g_hash_table_destroy(asp_request_hash);
1749 if (asp_request_keys)
1750 g_mem_chunk_destroy(asp_request_keys);
1751 if (asp_request_vals)
1752 g_mem_chunk_destroy(asp_request_vals);
1754 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1756 asp_request_keys = g_mem_chunk_new("asp_request_keys",
1757 sizeof(asp_request_key),
1758 asp_packet_init_count * sizeof(asp_request_key),
1760 asp_request_vals = g_mem_chunk_new("asp_request_vals",
1761 sizeof(asp_request_val),
1762 asp_packet_init_count * sizeof(asp_request_val),
1768 proto_register_atalk(void)
1770 static hf_register_info hf_llap[] = {
1772 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1776 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1780 { "Type", "llap.type", FT_UINT8, BASE_HEX, VALS(llap_type_vals), 0x0,
1784 static hf_register_info hf_ddp[] = {
1786 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1790 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1794 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1798 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1802 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1806 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1810 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1814 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1818 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1821 { &hf_ddp_dst_socket,
1822 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1825 { &hf_ddp_src_socket,
1826 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1830 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC, VALS(op_vals), 0x0,
1834 static hf_register_info hf_nbp[] = {
1836 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1837 VALS(nbp_op_vals), 0xF0, "Operation", HFILL }},
1839 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1840 NULL, 0x0, "Info", HFILL }},
1842 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1843 NULL, 0x0F, "Count", HFILL }},
1845 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1846 NULL, 0x0, "Network", HFILL }},
1847 { &hf_nbp_node_node,
1848 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1849 NULL, 0x0, "Node", HFILL }},
1850 { &hf_nbp_node_port,
1851 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1852 NULL, 0x0, "Port", HFILL }},
1853 { &hf_nbp_node_enum,
1854 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1855 NULL, 0x0, "Enumerator", HFILL }},
1856 { &hf_nbp_node_object,
1857 { "Object", "nbp.object", FT_STRING, BASE_DEC,
1858 NULL, 0x0, "Object", HFILL }},
1859 { &hf_nbp_node_type,
1860 { "Type", "nbp.type", FT_STRING, BASE_DEC,
1861 NULL, 0x0, "Type", HFILL }},
1862 { &hf_nbp_node_zone,
1863 { "Zone", "nbp.zone", FT_STRING, BASE_DEC,
1864 NULL, 0x0, "Zone", HFILL }},
1866 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1867 NULL, 0x0, "Transaction ID", HFILL }}
1870 static hf_register_info hf_rtmp[] = {
1872 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1873 NULL, 0x0, "Net", HFILL }},
1875 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1876 NULL, 0x0, "Node", HFILL }},
1877 { &hf_rtmp_node_len,
1878 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1879 NULL, 0x0, "Node Length", HFILL }},
1880 { &hf_rtmp_tuple_net,
1881 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1882 NULL, 0x0, "Net", HFILL }},
1883 { &hf_rtmp_tuple_range_start,
1884 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
1885 NULL, 0x0, "Range Start", HFILL }},
1886 { &hf_rtmp_tuple_range_end,
1887 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
1888 NULL, 0x0, "Range End", HFILL }},
1889 { &hf_rtmp_tuple_dist,
1890 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
1891 NULL, 0x0, "Distance", HFILL }},
1892 { &hf_rtmp_function,
1893 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
1894 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
1897 static hf_register_info hf_atp[] = {
1899 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
1900 NULL, 0, "control info", HFILL }},
1903 { "Function", "atp.function", FT_UINT8, BASE_DEC,
1904 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
1908 { "XO", "atp.xo", FT_BOOLEAN, 8,
1909 NULL, ATP_XO, "Exactly-once flag", HFILL }},
1912 { "EOM", "atp.eom", FT_BOOLEAN, 8,
1913 NULL, ATP_EOM, "End-of-message", HFILL }},
1916 { "STS", "atp.sts", FT_BOOLEAN, 8,
1917 NULL, ATP_STS, "Send transaction status", HFILL }},
1919 { &hf_atp_treltimer,
1920 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
1921 VALS(atp_trel_timer_vals), 0x07, "TRel timer", HFILL }},
1924 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
1925 NULL, 0x0, "Bitmap or sequence number", HFILL }},
1928 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
1929 NULL, 0x0, "Transaction id", HFILL }},
1930 { &hf_atp_user_bytes,
1931 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
1932 NULL, 0x0, "User bytes", HFILL }},
1934 { &hf_atp_segment_overlap,
1935 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
1936 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
1938 { &hf_atp_segment_overlap_conflict,
1939 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
1940 FT_BOOLEAN, BASE_NONE,
1941 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
1943 { &hf_atp_segment_multiple_tails,
1944 { "Multiple tail segments found", "atp.segment.multipletails",
1945 FT_BOOLEAN, BASE_NONE,
1946 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
1948 { &hf_atp_segment_too_long_segment,
1949 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
1950 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
1952 { &hf_atp_segment_error,
1953 {"Desegmentation error", "atp.segment.error", FT_FRAMENUM, BASE_NONE,
1954 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
1957 { "ATP Fragment", "atp.fragment", FT_FRAMENUM, BASE_NONE,
1958 NULL, 0x0, "ATP Fragment", HFILL }},
1961 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
1962 NULL, 0x0, "ATP Fragments", HFILL }},
1964 { &hf_atp_reassembled_in,
1965 { "Reassembled ATP in frame", "atp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1966 "This ATP packet is reassembled in this frame", 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,
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 "Reassemble ATP messages spanning multiple DDP packets",
2248 "Whether the ATP dissector should reassemble 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 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");