MSWSP: add ids for another unknown Property Set
[wireshark-wip.git] / epan / dissectors / packet-atalk.c
blob2575a6473a5a813d8bd7c8648c4e74004d582cb2
1 /* packet-atalk.c
2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
3 * RTMP, PAP.
5 * $Id$
7 * Simon Wilkinson <sxw@dcs.ed.ac.uk>
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "config.h"
30 #include <glib.h>
31 #include <epan/packet.h>
32 #include <string.h>
34 #include <epan/etypes.h>
35 #include <epan/ppptypes.h>
36 #include <epan/aftypes.h>
37 #include <epan/arcnet_pids.h>
38 #include <epan/atalk-utils.h>
39 #include <epan/conversation.h>
41 #include <epan/prefs.h>
42 #include <epan/reassemble.h>
43 #include <epan/wmem/wmem.h>
45 #include "packet-atalk.h"
46 #include "packet-afp.h"
48 void proto_register_atalk(void);
49 void proto_reg_handoff_atalk(void);
51 /* Tables for reassembly of fragments. */
52 static reassembly_table atp_reassembly_table;
54 /* desegmentation of ATP */
55 static gboolean atp_defragment = TRUE;
57 static dissector_handle_t afp_handle;
59 static int proto_llap = -1;
60 static int hf_llap_dst = -1;
61 static int hf_llap_src = -1;
62 static int hf_llap_type = -1;
64 static int proto_ddp = -1;
65 static int hf_ddp_hopcount = -1;
66 static int hf_ddp_len = -1;
67 static int hf_ddp_checksum = -1;
68 static int hf_ddp_dst = -1;
69 static int hf_ddp_dst_net = -1;
70 static int hf_ddp_src = -1;
71 static int hf_ddp_src_net = -1;
72 static int hf_ddp_dst_node = -1;
73 static int hf_ddp_src_node = -1;
74 static int hf_ddp_dst_socket = -1;
75 static int hf_ddp_src_socket = -1;
76 static int hf_ddp_type = -1;
78 static dissector_handle_t ddp_handle;
80 /* --------------------------------------
81 * ATP protocol parameters
82 * from netatalk/include/atalk/atp.h
84 #define ATP_MAXDATA (578+4) /* maximum ATP data size */
85 #define ATP_BUFSIZ 587 /* maximum packet size */
86 #define ATP_HDRSIZE 5 /* includes DDP type field */
88 #define ATP_TRELMASK 0x07 /* mask all but TREL */
89 #define ATP_RELTIME 30 /* base release timer (in secs) */
91 #define ATP_TREL30 0x0 /* release time codes */
92 #define ATP_TREL1M 0x1 /* these are passed in flags of */
93 #define ATP_TREL2M 0x2 /* atp_sreq call, and set in the */
94 #define ATP_TREL4M 0x3 /* packet control info. */
95 #define ATP_TREL8M 0x4
97 /* flags for ATP options (and control byte)
99 #define ATP_XO 0x20 /* (1<<5) eXactly Once mode */
100 #define ATP_EOM 0x10 /* (1<<4) End Of Message */
101 #define ATP_STS 0x08 /* (1<<3) Transaction Status */
103 /* function codes
105 #define ATP_FUNCMASK (3<<6) /* mask all but function */
107 #define ATP_TREQ 1 /* (1<<6) Trans. REQuest */
108 #define ATP_TRESP 2 /* (2<<6) Trans. RESPonse */
109 #define ATP_TREL 3 /* (3<<6) Trans. RELease */
111 /* ------------------------- */
112 static dissector_handle_t asp_handle;
113 static dissector_handle_t pap_handle;
115 static int proto_atp = -1;
116 static int hf_atp_ctrlinfo = -1; /* guint8_t control information */
117 static int hf_atp_function = -1; /* bits 7,6 function */
118 static int hf_atp_xo = -1; /* bit 5 exactly-once */
119 static int hf_atp_eom = -1; /* bit 4 end-of-message */
120 static int hf_atp_sts = -1; /* bit 3 send transaction status */
121 static int hf_atp_treltimer = -1; /* bits 2,1,0 TRel timeout indicator */
123 static int hf_atp_bitmap = -1; /* guint8_t bitmap or sequence number */
124 static int hf_atp_tid = -1; /* guint16_t transaction id. */
125 static int hf_atp_user_bytes = -1;
127 static int hf_atp_segments = -1;
128 static int hf_atp_segment = -1;
129 static int hf_atp_segment_overlap = -1;
130 static int hf_atp_segment_overlap_conflict = -1;
131 static int hf_atp_segment_multiple_tails = -1;
132 static int hf_atp_segment_too_long_segment = -1;
133 static int hf_atp_segment_error = -1;
134 static int hf_atp_segment_count = -1;
135 static int hf_atp_reassembled_in = -1;
136 static int hf_atp_reassembled_length = -1;
138 /* ------------------------- */
139 static int proto_zip = -1;
140 static dissector_handle_t zip_atp_handle;
142 static int hf_zip_function = -1;
143 static int hf_zip_atp_function = -1;
144 static int hf_zip_start_index = -1;
145 static int hf_zip_count = -1;
146 static int hf_zip_zero_value = -1;
148 static int hf_zip_network_count = -1;
149 static int hf_zip_network = -1;
150 static int hf_zip_network_start = -1;
151 static int hf_zip_network_end = -1;
153 /* static int hf_zip_flags = -1; */
155 static int hf_zip_flags_zone_invalid = -1;
156 static int hf_zip_flags_use_broadcast = -1;
157 static int hf_zip_flags_only_one_zone = -1;
159 static int hf_zip_last_flag = -1;
161 static int hf_zip_zone_name = -1;
162 static int hf_zip_default_zone = -1;
164 static int hf_zip_multicast_length = -1;
165 static int hf_zip_multicast_address = -1;
167 static const value_string zip_function_vals[] = {
168 {1, "Query"},
169 {2, "Reply"},
170 {5, "GetNetInfo request"},
171 {6, "GetNetInfo reply"},
172 {7, "notify"},
173 {8, "Extended reply"},
174 {0, NULL}
176 static value_string_ext zip_function_vals_ext = VALUE_STRING_EXT_INIT(zip_function_vals);
178 static const value_string zip_atp_function_vals[] = {
179 {7, "GetMyZone"},
180 {8, "GetZoneList"},
181 {9, "GetLocalZones"},
182 {0, NULL}
185 static gint ett_zip = -1;
186 static gint ett_zip_flags = -1;
187 static gint ett_zip_zones_list = -1;
188 static gint ett_zip_network_list = -1;
190 /* --------------------------------
191 * from netatalk/include/atalk/ats.h
194 #define ASPFUNC_CLOSE 1
195 #define ASPFUNC_CMD 2
196 #define ASPFUNC_STAT 3
197 #define ASPFUNC_OPEN 4
198 #define ASPFUNC_TICKLE 5
199 #define ASPFUNC_WRITE 6
200 #define ASPFUNC_WRTCONT 7
201 #define ASPFUNC_ATTN 8
203 #define ASP_HDRSIZ 4
204 #define ASPERR_OK 0
205 #define ASPERR_BADVERS (-1066)
206 #define ASPERR_BUFSMALL (-1067)
207 #define ASPERR_NOSESS (-1068)
208 #define ASPERR_NOSERV (-1069)
209 #define ASPERR_PARM (-1070)
210 #define ASPERR_SERVBUSY (-1071)
211 #define ASPERR_SESSCLOS (-1072)
212 #define ASPERR_SIZERR (-1073)
213 #define ASPERR_TOOMANY (-1074)
214 #define ASPERR_NOACK (-1075)
216 static int proto_asp = -1;
217 static int hf_asp_func = -1;
218 static int hf_asp_error = -1;
219 static int hf_asp_socket = -1;
220 static int hf_asp_version = -1;
221 static int hf_asp_session_id = -1;
222 static int hf_asp_zero_value = -1;
223 static int hf_asp_init_error = -1;
224 static int hf_asp_attn_code = -1;
225 static int hf_asp_seq = -1;
226 static int hf_asp_size = -1;
228 /* status stuff same for asp and afp */
229 static int hf_asp_server_name = -1;
230 static int hf_asp_server_type = -1;
231 static int hf_asp_server_vers = -1;
232 static int hf_asp_server_uams = -1;
233 static int hf_asp_server_icon = -1;
234 static int hf_asp_server_directory = -1;
236 static int hf_asp_server_flag = -1;
237 static int hf_asp_server_flag_copyfile = -1;
238 static int hf_asp_server_flag_passwd = -1;
239 static int hf_asp_server_flag_no_save_passwd = -1;
240 static int hf_asp_server_flag_srv_msg = -1;
241 static int hf_asp_server_flag_srv_sig = -1;
242 static int hf_asp_server_flag_tcpip = -1;
243 static int hf_asp_server_flag_notify = -1;
244 static int hf_asp_server_flag_reconnect = -1;
245 static int hf_asp_server_flag_directory = -1;
246 static int hf_asp_server_flag_utf8_name = -1;
247 static int hf_asp_server_flag_fast_copy = -1;
248 static int hf_asp_server_signature = -1;
249 static int hf_asp_server_utf8_name_len = -1;
250 static int hf_asp_server_utf8_name = -1;
252 static int hf_asp_server_addr_len = -1;
253 static int hf_asp_server_addr_type = -1;
254 static int hf_asp_server_addr_value = -1;
256 static gint ett_asp_status = -1;
257 static gint ett_asp_uams = -1;
258 static gint ett_asp_vers = -1;
259 static gint ett_asp_addr = -1;
260 static gint ett_asp_addr_line = -1;
261 static gint ett_asp_directory = -1;
262 static gint ett_asp_utf8_name = -1;
263 static gint ett_asp_status_server_flag = -1;
265 typedef struct {
266 guint32 conversation;
267 guint8 src[4];
268 guint16 seq;
269 } asp_request_key;
271 typedef struct {
272 guint8 value; /* command for asp, bitmap for atp */
273 } asp_request_val;
275 static GHashTable *asp_request_hash = NULL;
277 /* Hash Functions */
278 static gint asp_equal (gconstpointer v, gconstpointer v2)
280 const asp_request_key *val1 = (const asp_request_key*)v;
281 const asp_request_key *val2 = (const asp_request_key*)v2;
283 if (val1->conversation == val2->conversation &&
284 val1->seq == val2->seq &&
285 !memcmp(val1->src, val2->src, 4)) {
286 return 1;
288 return 0;
291 static guint asp_hash (gconstpointer v)
293 const asp_request_key *asp_key = (const asp_request_key*)v;
294 return asp_key->seq;
297 /* ------------------------------------ */
298 static GHashTable *atp_request_hash = 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;
332 static gint ett_pap = -1;
334 static gint ett_nbp = -1;
335 static gint ett_nbp_info = -1;
336 static gint ett_nbp_node = -1;
337 static gint ett_rtmp = -1;
338 static gint ett_rtmp_tuple = -1;
339 static gint ett_ddp = -1;
340 static gint ett_llap = -1;
341 static gint ett_pstring = -1;
343 static const fragment_items atp_frag_items = {
344 &ett_atp_segment,
345 &ett_atp_segments,
346 &hf_atp_segments,
347 &hf_atp_segment,
348 &hf_atp_segment_overlap,
349 &hf_atp_segment_overlap_conflict,
350 &hf_atp_segment_multiple_tails,
351 &hf_atp_segment_too_long_segment,
352 &hf_atp_segment_error,
353 &hf_atp_segment_count,
354 &hf_atp_reassembled_in,
355 &hf_atp_reassembled_length,
356 /* Reassembled data field */
357 NULL,
358 "segments"
361 /* -------------------------------- */
363 #define PAPOpenConn 1
364 #define PAPOpenConnReply 2
365 #define PAPSendData 3
366 #define PAPData 4
367 #define PAPTickle 5
368 #define PAPCloseConn 6
369 #define PAPCloseConnReply 7
370 #define PAPSendStatus 8
371 #define PAPStatus 9
373 static int proto_pap = -1;
375 static int hf_pap_connid = -1;
376 static int hf_pap_function = -1;
377 static int hf_pap_socket = -1;
378 static int hf_pap_quantum = -1;
379 static int hf_pap_waittime = -1;
380 static int hf_pap_result = -1;
381 static int hf_pap_status = -1;
382 static int hf_pap_seq = -1;
383 static int hf_pap_eof = -1;
385 static int hf_pap_pad = -1;
387 static const value_string pap_function_vals[] = {
388 {PAPOpenConn , "Open Connection Query"},
389 {PAPOpenConnReply , "Open Connection Reply"},
390 {PAPSendData , "Send Data"},
391 {PAPData , "Data"},
392 {PAPTickle , "Tickle"},
393 {PAPCloseConn , "Close Connection Query"},
394 {PAPCloseConnReply , "Close Connection reply"},
395 {PAPSendStatus , "Send Status"},
396 {PAPStatus , "Status"},
398 {0, NULL}
400 static value_string_ext pap_function_vals_ext = VALUE_STRING_EXT_INIT(pap_function_vals);
402 /* -------------------------------- */
404 static dissector_table_t ddp_dissector_table;
406 static dissector_handle_t data_handle;
408 #define DDP_SHORT_HEADER_SIZE 5
411 * P = Padding, H = Hops, L = Len
413 * PPHHHHLL LLLLLLLL
415 * Assumes the argument is in host byte order.
417 #define ddp_hops(x) ( ( x >> 10) & 0x3C )
418 #define ddp_len(x) ( x & 0x03ff )
419 typedef struct _e_ddp {
420 guint16 hops_len; /* combines pad, hops, and len */
421 guint16 sum,dnet,snet;
422 guint8 dnode,snode;
423 guint8 dport,sport;
424 guint8 type;
425 } e_ddp;
427 #define DDP_HEADER_SIZE 13
430 static const value_string op_vals[] = {
431 {DDP_RTMPDATA, "AppleTalk Routing Table response or data" },
432 {DDP_NBP, "AppleTalk Name Binding Protocol packet"},
433 {DDP_ATP, "AppleTalk Transaction Protocol packet"},
434 {DDP_AEP, "AppleTalk Echo Protocol packet"},
435 {DDP_RTMPREQ, "AppleTalk Routing Table request"},
436 {DDP_ZIP, "AppleTalk Zone Information Protocol packet"},
437 {DDP_ADSP, "AppleTalk Data Stream Protocol"},
438 {DDP_EIGRP, "Cisco EIGRP for AppleTalk"},
439 {0, NULL}
441 static value_string_ext op_vals_ext = VALUE_STRING_EXT_INIT(op_vals);
443 static const value_string rtmp_function_vals[] = {
444 {1, "Request"},
445 {2, "Route Data Request (split horizon processed)"},
446 {3, "Route Data Request (no split horizon processing)"},
447 {0, NULL}
450 #define NBP_BROADCAST 1
451 #define NBP_LOOKUP 2
452 #define NBP_FORWARD 4
453 #define NBP_REPLY 3
455 static const value_string nbp_op_vals[] = {
456 {NBP_BROADCAST, "broadcast request"},
457 {NBP_LOOKUP, "lookup"},
458 {NBP_FORWARD, "forward request"},
459 {NBP_REPLY, "reply"},
460 {0, NULL}
463 static const value_string atp_function_vals[] = {
464 {ATP_TREQ ,"REQuest"},
465 {ATP_TRESP ,"RESPonse"},
466 {ATP_TREL ,"RELease"},
467 {0, NULL}
470 static const value_string atp_trel_timer_vals[] = {
471 {0, "30 seconds"},
472 {1, "1 minute"},
473 {2, "2 minutes"},
474 {3, "4 minutes"},
475 {4, "8 minutes"},
476 {0, NULL}
481 static const value_string asp_func_vals[] = {
482 {ASPFUNC_CLOSE, "CloseSession" },
483 {ASPFUNC_CMD, "Command" },
484 {ASPFUNC_STAT, "GetStatus" },
485 {ASPFUNC_OPEN, "OpenSession" },
486 {ASPFUNC_TICKLE, "Tickle" },
487 {ASPFUNC_WRITE, "Write" },
488 {ASPFUNC_WRTCONT, "Write Cont" },
489 {ASPFUNC_ATTN, "Attention" },
490 {0, NULL } };
491 static value_string_ext asp_func_vals_ext = VALUE_STRING_EXT_INIT(asp_func_vals);
493 /* XXX: Array sorted in ascending order (unsigned) to allow value_string_ext binary search */
494 static const value_string asp_error_vals[] = {
495 {AFP_OK , "success"},
496 {AFPERR_USRLOGIN , "user already logged on" },
497 {AFPERR_PWDPOLCY , "password fails policy check" },
498 {AFPERR_PWDCHNG , "password needs to be changed" },
499 {AFPERR_INTRASH , "shared folder in trash." },
500 {AFPERR_INSHRD , "folder being shared is inside a shared folder." },
501 {AFPERR_PWDEXPR , "password expired" },
502 {AFPERR_PWDSHORT , "password too short" },
503 {AFPERR_PWDSAME , "same password/can't change password" },
504 {AFPERR_BADID , "non-existent file id" },
505 {AFPERR_SAMEOBJ , "source file == destination file" },
506 {AFPERR_CATCHNG , "catalog has changed" },
507 {AFPERR_DIFFVOL , "different volume" },
508 {AFPERR_EXISTID , "file already has an id" },
509 {AFPERR_NOID , "file thread not found" },
510 {AFPERR_CTNSHRD , "share point contains a share point" },
511 {AFPERR_OLOCK , "object locked" },
512 {AFPERR_VLOCK , "volume locked" },
513 {AFPERR_ITYPE , "wrong icon type" },
514 {AFPERR_NODIR , "couldn't find directory" },
515 {AFPERR_NORENAME , "can't rename" },
516 {AFPERR_SHUTDOWN , "server is going down" },
517 {AFPERR_NFILE , "too many files open" },
518 {AFPERR_BADTYPE , "object is the wrong type" },
519 {AFPERR_NOOP , "command not supported" },
520 {AFPERR_NOTAUTH , "user not authenticated" },
521 {AFPERR_SESSCLOS , "session closed" },
522 {AFPERR_RANGEOVR , "range overlap" },
523 {AFPERR_NORANGE , "no range lock" },
524 {AFPERR_PARAM , "parameter error" },
525 {AFPERR_NOOBJ , "object not found" },
526 {AFPERR_EXIST , "object already exists" },
527 {AFPERR_NOSRVR , "no response by server at that address" },
528 {AFPERR_NLOCK , "no more locks" },
529 {AFPERR_MISC , "misc. err" },
530 {AFPERR_LOCK , "LockErr" },
531 {AFPERR_NOITEM , "ItemNotFound" },
532 {AFPERR_FLATVOL , "volume doesn't support directories" },
533 {AFPERR_BUSY , "FileBusy" },
534 {AFPERR_EOF , "end of file" },
535 {AFPERR_DFULL , "disk full" },
536 {AFPERR_DIRNEMPT , "directory not empty" },
537 {AFPERR_DENYCONF , "file synchronization locks conflict" },
538 {AFPERR_CANTMOVE , "can't move file" },
539 {AFPERR_BITMAP , "invalid bitmap" },
540 {AFPERR_BADVERS , "bad afp version number" },
541 {AFPERR_BADUAM , "uam doesn't exist" },
542 {AFPERR_AUTHCONT , "logincont" },
543 {AFPERR_ACCESS , "permission denied" },
544 {ASPERR_SESSCLOS , "session closed (ASP)" },
545 {ASPERR_NOSESS , "no more sessions available"},
546 {0, NULL } };
547 value_string_ext asp_error_vals_ext = VALUE_STRING_EXT_INIT(asp_error_vals);
550 * XXX - do this with an FT_UINT_STRING?
551 * Unfortunately, you can't extract from an FT_UINT_STRING the string,
552 * which we'd want to do in order to put it into the "Data:" portion.
554 * Are these always in the Mac extended character set?
556 static int dissect_pascal_string(tvbuff_t *tvb, int offset, proto_tree *tree,
557 int hf_index)
559 int len;
560 char *tmp;
562 len = tvb_get_guint8(tvb, offset);
563 offset++;
565 if ( tree )
567 proto_tree *item;
568 proto_tree *subtree;
571 * XXX - if we could do this inside the protocol tree
572 * code, we could perhaps avoid allocating and freeing
573 * this string buffer.
575 tmp = (gchar*)tvb_get_string(wmem_packet_scope(), tvb, offset, len);
576 item = proto_tree_add_string(tree, hf_index, tvb, offset-1, len+1, tmp);
578 subtree = proto_item_add_subtree(item, ett_pstring);
579 proto_tree_add_text(subtree, tvb, offset-1, 1, "Length: %d", len);
580 proto_tree_add_text(subtree, tvb, offset, len, "Data: %s", tmp);
583 offset += len;
585 return offset;
588 static void
589 dissect_rtmp_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
590 proto_tree *rtmp_tree;
591 proto_item *ti;
592 guint8 function;
594 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
595 col_clear(pinfo->cinfo, COL_INFO);
597 function = tvb_get_guint8(tvb, 0);
599 col_add_str(pinfo->cinfo, COL_INFO,
600 val_to_str(function, rtmp_function_vals, "Unknown function (%02x)"));
602 if (tree) {
603 ti = proto_tree_add_item(tree, proto_rtmp, tvb, 0, 1, ENC_NA);
604 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
606 proto_tree_add_uint(rtmp_tree, hf_rtmp_function, tvb, 0, 1, function);
610 static void
611 dissect_rtmp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
612 proto_tree *rtmp_tree;
613 proto_item *ti;
614 int offset = 0;
615 guint16 net;
616 guint8 nodelen,nodelen_bits;
617 guint16 node; /* might be more than 8 bits */
618 int i;
620 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
621 col_clear(pinfo->cinfo, COL_INFO);
623 net = tvb_get_ntohs(tvb, offset);
624 nodelen_bits = tvb_get_guint8(tvb, offset+2);
625 if ( nodelen_bits <= 8 ) {
626 node = tvb_get_guint8(tvb, offset+3);
627 nodelen = 1;
628 } else {
629 node = tvb_get_ntohs(tvb, offset+3);
630 nodelen = 2;
633 col_add_fstr(pinfo->cinfo, COL_INFO, "Net: %u Node Len: %u Node: %u",
634 net, nodelen_bits, node);
636 if (tree) {
637 ti = proto_tree_add_item(tree, proto_rtmp, tvb, offset, -1, ENC_NA);
638 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
640 proto_tree_add_uint(rtmp_tree, hf_rtmp_net, tvb, offset, 2, net);
641 proto_tree_add_uint(rtmp_tree, hf_rtmp_node_len, tvb, offset+2, 1,
642 nodelen_bits);
643 proto_tree_add_uint(rtmp_tree, hf_rtmp_node, tvb, offset+3, nodelen,
644 node);
645 offset += 3 + nodelen;
647 i = 1;
648 while (tvb_offset_exists(tvb, offset)) {
649 proto_tree *tuple_item, *tuple_tree;
650 guint16 tuple_net;
651 guint8 tuple_dist;
652 guint16 tuple_range_end;
654 tuple_net = tvb_get_ntohs(tvb, offset);
655 tuple_dist = tvb_get_guint8(tvb, offset+2);
657 if (tuple_dist & 0x80) {
658 tuple_range_end = tvb_get_ntohs(tvb, offset+3);
659 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 6,
660 "Tuple %d: Range Start: %u Dist: %u Range End: %u",
661 i, tuple_net, tuple_dist&0x7F, tuple_range_end);
662 } else {
663 tuple_item = proto_tree_add_text(rtmp_tree, tvb, offset, 3,
664 "Tuple %d: Net: %u Dist: %u",
665 i, tuple_net, tuple_dist);
667 tuple_tree = proto_item_add_subtree(tuple_item, ett_rtmp_tuple);
669 if (tuple_dist & 0x80) {
670 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_range_start, tvb, offset, 2,
671 tuple_net);
672 } else {
673 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_net, tvb, offset, 2,
674 tuple_net);
676 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_dist, tvb, offset+2, 1,
677 tuple_dist & 0x7F);
679 if (tuple_dist & 0x80) {
681 * Extended network tuple.
683 proto_tree_add_item(tuple_tree, hf_rtmp_tuple_range_end, tvb, offset+3, 2,
684 ENC_BIG_ENDIAN);
685 offset += 6;
686 } else
687 offset += 3;
689 i++;
694 static void
695 dissect_nbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
696 proto_tree *nbp_tree;
697 proto_tree *nbp_info_tree;
698 proto_item *ti, *info_item;
699 int offset = 0;
700 guint8 info;
701 guint op, count;
702 guint i;
704 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBP");
705 col_clear(pinfo->cinfo, COL_INFO);
707 info = tvb_get_guint8(tvb, offset);
708 op = info >> 4;
709 count = info & 0x0F;
711 col_add_fstr(pinfo->cinfo, COL_INFO, "Op: %s Count: %u",
712 val_to_str(op, nbp_op_vals, "Unknown (0x%01x)"), count);
714 if (tree) {
715 ti = proto_tree_add_item(tree, proto_nbp, tvb, offset, -1, ENC_NA);
716 nbp_tree = proto_item_add_subtree(ti, ett_nbp);
718 info_item = proto_tree_add_uint_format(nbp_tree, hf_nbp_info, tvb, offset, 1,
719 info,
720 "Info: 0x%01X Operation: %s Count: %u", info,
721 val_to_str(op, nbp_op_vals, "Unknown (0x%01X)"),
722 count);
723 nbp_info_tree = proto_item_add_subtree(info_item, ett_nbp_info);
724 proto_tree_add_uint(nbp_info_tree, hf_nbp_op, tvb, offset, 1, info);
725 proto_tree_add_uint(nbp_info_tree, hf_nbp_count, tvb, offset, 1, info);
726 proto_tree_add_item(nbp_tree, hf_nbp_tid, tvb, offset+1, 1, ENC_BIG_ENDIAN);
727 offset += 2;
729 for (i = 0; i < count; i++) {
730 proto_tree *node_item,*node_tree;
731 int soffset = offset;
733 node_item = proto_tree_add_text(nbp_tree, tvb, offset, -1,
734 "Node %u", i+1);
735 node_tree = proto_item_add_subtree(node_item, ett_nbp_node);
737 proto_tree_add_item(node_tree, hf_nbp_node_net, tvb, offset, 2, ENC_BIG_ENDIAN);
738 offset += 2;
739 proto_tree_add_item(node_tree, hf_nbp_node_node, tvb, offset, 1, ENC_BIG_ENDIAN);
740 offset++;
741 proto_tree_add_item(node_tree, hf_nbp_node_port, tvb, offset, 1, ENC_BIG_ENDIAN);
742 offset++;
743 proto_tree_add_item(node_tree, hf_nbp_node_enum, tvb, offset, 1, ENC_BIG_ENDIAN);
744 offset++;
746 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_object);
747 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_type);
748 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_zone);
750 proto_item_set_len(node_item, offset-soffset);
754 return;
757 /* -----------------------------
758 ATP protocol cf. inside appletalk chap. 9
759 desegmentation from packet-ieee80211.c
761 static void
762 dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
763 proto_tree *atp_tree = NULL;
764 proto_item *ti;
765 proto_tree *atp_info_tree;
766 proto_item *info_item;
767 int offset = 0;
768 guint8 ctrlinfo;
769 guint8 frag_number = 0;
770 guint op;
771 guint16 tid;
772 guint8 query;
773 struct aspinfo aspinfo;
774 tvbuff_t *new_tvb = NULL;
775 gboolean save_fragmented;
776 gboolean more_fragment = FALSE;
777 int len;
778 guint8 bitmap;
779 guint8 nbe = 0;
780 guint8 t = 0;
781 conversation_t *conversation;
782 asp_request_val *request_val = NULL;
784 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
786 ctrlinfo = tvb_get_guint8(tvb, offset);
787 bitmap = tvb_get_guint8(tvb, offset +1);
788 tid = tvb_get_ntohs(tvb, offset +2);
790 t = bitmap;
791 while(t) {
792 nbe++;
793 t >>= 1;
796 op = ctrlinfo >> 6;
798 aspinfo.reply = (0x80 == (ctrlinfo & ATP_FUNCMASK))?1:0;
799 aspinfo.release = (0xC0 == (ctrlinfo & ATP_FUNCMASK))?1:0;
800 aspinfo.seq = tid;
801 aspinfo.code = 0;
802 query = (!aspinfo.reply && !aspinfo.release);
804 conversation = find_or_create_conversation(pinfo);
806 if (atp_defragment) {
807 asp_request_key request_key;
809 request_key.conversation = conversation->index;
810 memcpy(request_key.src, (!aspinfo.reply)?pinfo->src.data:pinfo->dst.data, 4);
811 request_key.seq = aspinfo.seq;
813 request_val = (asp_request_val *) g_hash_table_lookup(atp_request_hash, &request_key);
815 if (!request_val && query && nbe > 1) {
816 asp_request_key *new_request_key;
818 /* only save nbe packets if more than 1 requested
819 save some memory and help the defragmentation if tid wraparound, ie
820 we have both a request for 1 packet and a request for n packets,
821 hopefully most of the time ATP_EOM will be set in the last packet.
823 new_request_key = wmem_new(wmem_file_scope(), asp_request_key);
824 *new_request_key = request_key;
826 request_val = wmem_new(wmem_file_scope(), asp_request_val);
827 request_val->value = nbe;
829 g_hash_table_insert(atp_request_hash, new_request_key,request_val);
834 ATP_EOM is not mandatory. Some implementations don't always set it
835 if the query is only one packet.
837 So it needs to keep the number of packets asked in request.
840 if (aspinfo.reply) {
841 more_fragment = !(ATP_EOM & ctrlinfo) && request_val;
842 frag_number = bitmap;
845 col_clear(pinfo->cinfo, COL_INFO);
846 col_add_fstr(pinfo->cinfo, COL_INFO, "%s transaction %u",
847 val_to_str(op, atp_function_vals, "Unknown (0x%01x)"),tid);
848 if (more_fragment)
849 col_append_str(pinfo->cinfo, COL_INFO, " [fragment]");
851 if (tree) {
852 ti = proto_tree_add_item(tree, proto_atp, tvb, offset, -1, ENC_NA);
853 atp_tree = proto_item_add_subtree(ti, ett_atp);
854 proto_item_set_len(atp_tree, aspinfo.release?8:ATP_HDRSIZE -1);
856 info_item = proto_tree_add_item(atp_tree, hf_atp_ctrlinfo, tvb, offset, 1, ENC_BIG_ENDIAN);
857 atp_info_tree = proto_item_add_subtree(info_item, ett_atp_info);
859 proto_tree_add_item(atp_info_tree, hf_atp_function, tvb, offset, 1, ENC_BIG_ENDIAN);
860 proto_tree_add_item(atp_info_tree, hf_atp_xo, tvb, offset, 1, ENC_BIG_ENDIAN);
861 proto_tree_add_item(atp_info_tree, hf_atp_eom, tvb, offset, 1, ENC_BIG_ENDIAN);
862 proto_tree_add_item(atp_info_tree, hf_atp_sts, tvb, offset, 1, ENC_BIG_ENDIAN);
863 if ((ctrlinfo & (ATP_FUNCMASK|ATP_XO)) == (0x40|ATP_XO)) {
864 /* TReq with XO set */
865 proto_tree_add_item(atp_info_tree, hf_atp_treltimer, tvb, offset, 1, ENC_BIG_ENDIAN);
867 if (query) {
868 proto_tree_add_text(atp_tree, tvb, offset +1, 1,
869 "Bitmap: 0x%02x %u packet(s) max", bitmap, nbe);
871 else {
872 proto_tree_add_item(atp_tree, hf_atp_bitmap, tvb, offset +1, 1, ENC_BIG_ENDIAN);
874 proto_tree_add_item(atp_tree, hf_atp_tid, tvb, offset +2, 2, ENC_BIG_ENDIAN);
876 if (aspinfo.release)
877 proto_tree_add_item(atp_tree, hf_atp_user_bytes, tvb, offset +4, 4, ENC_BIG_ENDIAN);
881 if (aspinfo.release)
882 return;
884 save_fragmented = pinfo->fragmented;
886 /* FIXME
887 asp doesn't fit very well here
888 move asp back in atp?
890 if (atp_defragment && aspinfo.reply && (more_fragment || frag_number != 0)) {
891 fragment_head *fd_head;
892 int hdr;
894 hdr = ATP_HDRSIZE -1;
895 if (frag_number != 0)
896 hdr += 4; /* asp header */
897 len = tvb_reported_length_remaining(tvb, hdr);
898 fd_head = fragment_add_seq_check(&atp_reassembly_table,
899 tvb, hdr, pinfo, tid, NULL,
900 frag_number,
901 len,
902 more_fragment);
903 new_tvb = process_reassembled_data(tvb, ATP_HDRSIZE -1, pinfo,
904 "Reassembled ATP", fd_head, &atp_frag_items,
905 NULL, atp_tree);
907 else {
908 /* full packet */
909 new_tvb = tvb_new_subset_remaining(tvb, ATP_HDRSIZE -1 );
912 if (new_tvb) {
913 /* if port == 6 it's not an ASP packet but a ZIP packet */
914 if (pinfo->srcport == 6 || pinfo->destport == 6 )
915 call_dissector_with_data(zip_atp_handle, new_tvb, pinfo, tree, &aspinfo);
916 else {
917 /* XXX need a conversation_get_dissector function ? */
918 if (!aspinfo.reply && !conversation->dissector_handle) {
919 dissector_handle_t sub;
921 /* if it's a known ASP function call ASP dissector
922 else assume it's a PAP connection ID.
923 the test is wrong because PAP conn IDs overlapped with ASP fn
924 but I don't want to keep track of NBP msgs and open connection
925 port allocation.
927 guint8 fn = tvb_get_guint8(new_tvb, 0);
929 if (!fn || fn > ASPFUNC_ATTN) {
930 sub = pap_handle;
932 else {
933 sub = asp_handle;
935 call_dissector_with_data(sub, new_tvb, pinfo, tree, &aspinfo);
936 conversation_set_dissector(conversation, sub);
938 else if (!try_conversation_dissector(&pinfo->src, &pinfo->dst, pinfo->ptype,
939 pinfo->srcport, pinfo->destport, new_tvb,pinfo, tree, NULL)) {
940 call_dissector(data_handle, new_tvb, pinfo, tree);
945 else {
946 /* Just show this as a fragment. */
947 new_tvb = tvb_new_subset_remaining (tvb, ATP_HDRSIZE -1);
948 call_dissector(data_handle, new_tvb, pinfo, tree);
950 pinfo->fragmented = save_fragmented;
951 return;
955 copy and paste from dsi
956 XXX - is the format of this reply dependent on the type of server,
957 with this format being the format for AFP servers?
959 static gint
960 dissect_asp_reply_get_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, gint offset)
962 proto_tree *sub_tree;
963 proto_item *ti;
965 guint16 ofs;
966 guint16 flag;
967 guint16 machine_ofs;
968 guint16 sign_ofs = 0;
969 guint16 adr_ofs = 0;
970 guint16 dir_ofs = 0;
971 guint16 utf_ofs = 0;
972 guint8 nbe;
973 guint len;
974 guint i;
976 proto_tree *adr_tree;
977 char *tmp;
978 guint16 net;
979 guint8 node;
980 guint16 port;
982 guint16 ulen;
984 if (!tree)
985 return offset;
987 ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
988 tree = proto_item_add_subtree(ti, ett_asp_status);
990 machine_ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
991 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %u", machine_ofs);
992 if (machine_ofs)
993 machine_ofs += offset;
995 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
996 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %u", ofs);
998 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
999 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %u", ofs);
1001 ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1002 proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %u", ofs);
1004 ofs = offset +AFPSTATUS_FLAGOFF;
1005 ti = proto_tree_add_item(tree, hf_asp_server_flag, tvb, ofs, 2, ENC_BIG_ENDIAN);
1006 sub_tree = proto_item_add_subtree(ti, ett_asp_status_server_flag);
1007 proto_tree_add_item(sub_tree, hf_asp_server_flag_copyfile , tvb, ofs, 2, ENC_BIG_ENDIAN);
1008 proto_tree_add_item(sub_tree, hf_asp_server_flag_passwd , tvb, ofs, 2, ENC_BIG_ENDIAN);
1009 proto_tree_add_item(sub_tree, hf_asp_server_flag_no_save_passwd, tvb, ofs, 2, ENC_BIG_ENDIAN);
1010 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_msg , tvb, ofs, 2, ENC_BIG_ENDIAN);
1011 proto_tree_add_item(sub_tree, hf_asp_server_flag_srv_sig , tvb, ofs, 2, ENC_BIG_ENDIAN);
1012 proto_tree_add_item(sub_tree, hf_asp_server_flag_tcpip , tvb, ofs, 2, ENC_BIG_ENDIAN);
1013 proto_tree_add_item(sub_tree, hf_asp_server_flag_notify , tvb, ofs, 2, ENC_BIG_ENDIAN);
1014 proto_tree_add_item(sub_tree, hf_asp_server_flag_reconnect , tvb, ofs, 2, ENC_BIG_ENDIAN);
1015 proto_tree_add_item(sub_tree, hf_asp_server_flag_directory , tvb, ofs, 2, ENC_BIG_ENDIAN);
1016 proto_tree_add_item(sub_tree, hf_asp_server_flag_utf8_name , tvb, ofs, 2, ENC_BIG_ENDIAN);
1017 proto_tree_add_item(sub_tree, hf_asp_server_flag_fast_copy , tvb, ofs, 2, ENC_BIG_ENDIAN);
1019 proto_tree_add_item(tree, hf_asp_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, ENC_ASCII|ENC_NA);
1021 flag = tvb_get_ntohs(tvb, ofs);
1022 if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
1023 ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
1024 if ((ofs & 1))
1025 ofs++;
1027 sign_ofs = tvb_get_ntohs(tvb, ofs);
1028 proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %u", sign_ofs);
1029 sign_ofs += offset;
1030 ofs += 2;
1032 if ((flag & AFPSRVRINFO_TCPIP) && ofs < machine_ofs ) {
1033 adr_ofs = tvb_get_ntohs(tvb, ofs);
1034 proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %u", adr_ofs);
1035 adr_ofs += offset;
1036 ofs += 2;
1039 if ((flag & AFPSRVRINFO_SRVDIRECTORY) && ofs < machine_ofs) {
1040 dir_ofs = tvb_get_ntohs(tvb, ofs);
1041 proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %u", dir_ofs);
1042 dir_ofs += offset;
1043 ofs += 2;
1046 if ((flag & AFPSRVRINFO_SRVUTF8) && ofs < machine_ofs) {
1047 utf_ofs = tvb_get_ntohs(tvb, ofs);
1048 proto_tree_add_text(tree, tvb, ofs, 2, "UTF-8 Server name offset: %u", utf_ofs);
1049 utf_ofs += offset;
1053 if (machine_ofs)
1054 proto_tree_add_item(tree, hf_asp_server_type, tvb, machine_ofs, 1, ENC_ASCII|ENC_NA);
1056 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
1057 if (ofs) {
1058 nbe = tvb_get_guint8(tvb, ofs);
1059 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %u", nbe);
1060 ofs++;
1061 sub_tree = proto_item_add_subtree(ti, ett_asp_vers);
1062 for (i = 0; i < nbe; i++) {
1063 len = tvb_get_guint8(tvb, ofs);
1064 proto_tree_add_item(sub_tree, hf_asp_server_vers, tvb, ofs, 1, ENC_ASCII|ENC_NA);
1065 ofs += len + 1;
1069 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
1070 if (ofs) {
1071 nbe = tvb_get_guint8(tvb, ofs);
1072 ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %u", nbe);
1073 ofs++;
1074 sub_tree = proto_item_add_subtree(ti, ett_asp_uams);
1075 for (i = 0; i < nbe; i++) {
1076 len = tvb_get_guint8(tvb, ofs);
1077 proto_tree_add_item(sub_tree, hf_asp_server_uams, tvb, ofs, 1, ENC_ASCII|ENC_NA);
1078 ofs += len + 1;
1082 ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
1083 if (ofs)
1084 proto_tree_add_item(tree, hf_asp_server_icon, tvb, ofs, 256, ENC_NA);
1086 if (sign_ofs) {
1087 proto_tree_add_item(tree, hf_asp_server_signature, tvb, sign_ofs, 16, ENC_NA);
1090 if (adr_ofs) {
1092 ofs = adr_ofs;
1093 nbe = tvb_get_guint8(tvb, ofs);
1094 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %u", nbe);
1095 ofs++;
1096 adr_tree = proto_item_add_subtree(ti, ett_asp_addr);
1097 for (i = 0; i < nbe; i++) {
1098 guint8 type;
1100 len = tvb_get_guint8(tvb, ofs);
1101 type = tvb_get_guint8(tvb, ofs +1);
1102 switch (type) {
1103 case 1: /* IP */
1104 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s", tvb_ip_to_str(tvb, ofs+2));
1105 break;
1106 case 2: /* IP + port */
1107 port = tvb_get_ntohs(tvb, ofs+6);
1108 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%u",
1109 tvb_ip_to_str(tvb, ofs+2), port);
1110 break;
1111 case 3: /* DDP, atalk_addr_to_str want host order not network */
1112 net = tvb_get_ntohs(tvb, ofs+2);
1113 node = tvb_get_guint8(tvb, ofs +4);
1114 port = tvb_get_guint8(tvb, ofs +5);
1115 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp %u.%u:%u",
1116 net, node, port);
1117 break;
1118 case 5: /* IP + port ssh tunnel */
1119 port = tvb_get_ntohs(tvb, ofs+6);
1120 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip (ssh tunnel) %s:%u",
1121 tvb_ip_to_str(tvb, ofs+2), port);
1122 break;
1123 case 4: /* DNS */
1124 if (len > 2) {
1125 tmp = (gchar*)tvb_get_string(wmem_packet_scope(), tvb, ofs +2, len -2);
1126 ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "dns %s", tmp);
1127 break;
1129 /* else fall to default malformed record */
1130 default:
1131 ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknown type : %u", type);
1132 break;
1134 len -= 2;
1135 sub_tree = proto_item_add_subtree(ti,ett_asp_addr_line);
1136 proto_tree_add_item(sub_tree, hf_asp_server_addr_len, tvb, ofs, 1, ENC_BIG_ENDIAN);
1137 ofs++;
1138 proto_tree_add_item(sub_tree, hf_asp_server_addr_type, tvb, ofs, 1, ENC_BIG_ENDIAN);
1139 ofs++;
1140 proto_tree_add_item(sub_tree, hf_asp_server_addr_value,tvb, ofs, len, ENC_NA);
1141 ofs += len;
1145 if (dir_ofs) {
1146 ofs = dir_ofs;
1147 nbe = tvb_get_guint8(tvb, ofs);
1148 ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %u", nbe);
1149 ofs++;
1150 sub_tree = proto_item_add_subtree(ti, ett_asp_directory);
1151 for (i = 0; i < nbe; i++) {
1152 len = tvb_get_guint8(tvb, ofs);
1153 proto_tree_add_item(sub_tree, hf_asp_server_directory, tvb, ofs, 1, ENC_ASCII|ENC_NA);
1154 ofs += len + 1;
1157 if (utf_ofs) {
1159 ofs = utf_ofs;
1160 ulen = tvb_get_ntohs(tvb, ofs);
1161 tmp = (gchar*)tvb_get_string(wmem_packet_scope(), tvb, ofs + 2, ulen);
1162 ti = proto_tree_add_text(tree, tvb, ofs, ulen +2, "UTF8 server name: %s", tmp);
1163 sub_tree = proto_item_add_subtree(ti, ett_asp_utf8_name);
1164 proto_tree_add_uint(sub_tree, hf_asp_server_utf8_name_len, tvb, ofs, 2, ulen);
1165 ofs += 2;
1166 proto_tree_add_string(sub_tree, hf_asp_server_utf8_name, tvb, ofs, ulen, tmp);
1167 ofs += ulen;
1169 return ofs;
1172 /* -----------------------------
1173 PAP protocol cf. inside appletalk chap. 10
1175 #define PAD(x) { proto_tree_add_item(pap_tree, hf_pap_pad, tvb, offset, x, ENC_NA); offset += x; }
1177 static int
1178 dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1180 int offset = 0;
1181 guint8 fn;
1182 guint8 connID;
1183 proto_tree *pap_tree = NULL;
1184 proto_item *ti;
1185 int len;
1187 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAP");
1188 col_clear(pinfo->cinfo, COL_INFO);
1190 if (tree) {
1191 ti = proto_tree_add_item(tree, proto_pap, tvb, offset, -1, ENC_NA);
1192 pap_tree = proto_item_add_subtree(ti, ett_pap);
1195 connID = tvb_get_guint8(tvb, offset);
1196 proto_tree_add_item(pap_tree, hf_pap_connid, tvb, offset, 1, ENC_BIG_ENDIAN);
1197 offset++;
1199 fn = tvb_get_guint8(tvb, offset);
1200 proto_tree_add_item(pap_tree, hf_pap_function, tvb, offset, 1, ENC_BIG_ENDIAN);
1201 offset++;
1203 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ID: %d",
1204 val_to_str_ext(fn, &pap_function_vals_ext, "Unknown (0x%01x)"), connID);
1206 switch(fn) {
1207 case PAPOpenConn:
1208 PAD(2);
1209 proto_tree_add_item(pap_tree, hf_pap_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
1210 offset++;
1211 proto_tree_add_item(pap_tree, hf_pap_quantum, tvb, offset, 1, ENC_BIG_ENDIAN);
1212 offset++;
1213 proto_tree_add_item(pap_tree, hf_pap_waittime, tvb, offset, 2, ENC_BIG_ENDIAN);
1214 offset += 2;
1215 break;
1217 case PAPOpenConnReply:
1218 PAD(2);
1219 proto_tree_add_item(pap_tree, hf_pap_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
1220 offset++;
1221 proto_tree_add_item(pap_tree, hf_pap_quantum, tvb, offset, 1, ENC_BIG_ENDIAN);
1222 offset++;
1223 proto_tree_add_item(pap_tree, hf_pap_result, tvb, offset, 2, ENC_BIG_ENDIAN);
1224 offset += 2;
1225 offset = dissect_pascal_string(tvb, offset, pap_tree, hf_pap_status);
1226 break;
1228 case PAPSendData:
1229 proto_tree_add_item(pap_tree, hf_pap_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
1230 offset += 2;
1231 break;
1233 case PAPData:
1234 proto_tree_add_item(pap_tree, hf_pap_eof, tvb, offset, 1, ENC_BIG_ENDIAN);
1235 offset++;
1236 PAD(1);
1237 /* follow by data */
1238 len = tvb_reported_length_remaining(tvb,offset);
1239 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1240 break;
1242 case PAPTickle:
1243 case PAPCloseConn:
1244 case PAPCloseConnReply:
1245 PAD(2);
1246 break;
1248 case PAPSendStatus:
1249 PAD(2);
1250 break;
1252 case PAPStatus:
1253 PAD(2);
1254 PAD(4);
1255 offset = dissect_pascal_string(tvb, offset, pap_tree, hf_pap_status);
1256 break;
1258 default: /* unknown */
1259 break;
1261 return offset;
1264 /* -----------------------------
1265 ASP protocol cf. inside appletalk chap. 11
1267 static struct aspinfo *
1268 get_transaction(tvbuff_t *tvb, packet_info *pinfo, struct aspinfo *aspinfo)
1270 conversation_t *conversation;
1271 asp_request_key request_key, *new_request_key;
1272 asp_request_val *request_val;
1273 guint8 fn;
1275 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
1276 pinfo->srcport, pinfo->destport, 0);
1278 if (conversation == NULL)
1280 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1281 pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
1284 request_key.conversation = conversation->index;
1285 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
1286 request_key.seq = aspinfo->seq;
1288 request_val = (asp_request_val *) g_hash_table_lookup(asp_request_hash, &request_key);
1289 if (!request_val && !aspinfo->reply ) {
1290 fn = tvb_get_guint8(tvb, 0);
1291 new_request_key = wmem_new(wmem_file_scope(), asp_request_key);
1292 *new_request_key = request_key;
1294 request_val = wmem_new(wmem_file_scope(), asp_request_val);
1295 request_val->value = fn;
1297 g_hash_table_insert(asp_request_hash, new_request_key, request_val);
1300 if (!request_val)
1301 return NULL;
1303 aspinfo->command = request_val->value;
1304 return aspinfo;
1308 static int
1309 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1311 struct aspinfo *aspinfo;
1312 int offset = 0;
1313 proto_tree *asp_tree = NULL;
1314 proto_item *ti;
1315 guint8 fn;
1316 int len;
1318 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1319 col_clear(pinfo->cinfo, COL_INFO);
1321 aspinfo = get_transaction(tvb, pinfo, (struct aspinfo *)data);
1322 if (!aspinfo)
1323 return 0;
1325 fn = (guint8) aspinfo->command;
1327 if (aspinfo->reply)
1328 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1329 else
1330 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1331 val_to_str_ext(fn, &asp_func_vals_ext, "Unknown (0x%01x)"), aspinfo->seq);
1333 if (tree) {
1334 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, ENC_NA);
1335 asp_tree = proto_item_add_subtree(ti, ett_asp);
1337 if (!aspinfo->reply) {
1338 tvbuff_t *new_tvb;
1339 /* let the called deal with asp_tree == NULL */
1341 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, ENC_BIG_ENDIAN);
1342 offset++;
1343 switch(fn) {
1344 case ASPFUNC_OPEN:
1345 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
1346 offset++;
1347 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1348 offset += 2;
1349 break;
1350 case ASPFUNC_TICKLE:
1351 case ASPFUNC_CLOSE:
1352 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1353 offset++;
1354 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, ENC_NA);
1355 offset +=2;
1356 break;
1357 case ASPFUNC_STAT:
1358 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, ENC_NA);
1359 offset++;
1360 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, ENC_NA);
1361 offset += 2;
1362 break;
1363 case ASPFUNC_ATTN:
1364 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1365 offset++;
1366 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, ENC_BIG_ENDIAN);
1367 offset +=2;
1368 break;
1369 case ASPFUNC_CMD:
1370 case ASPFUNC_WRITE:
1371 proto_item_set_len(asp_tree, 4);
1372 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1373 offset++;
1374 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
1375 offset += 2;
1376 len = tvb_reported_length_remaining(tvb,offset);
1377 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1378 call_dissector(afp_handle, new_tvb, pinfo, tree);
1379 break;
1380 case ASPFUNC_WRTCONT:
1381 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1382 offset++;
1383 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
1384 offset += 2;
1385 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, ENC_BIG_ENDIAN);
1386 offset += 2;
1387 break;
1388 default:
1389 proto_item_set_len(asp_tree, 4);
1390 offset += 3;
1391 len = tvb_reported_length_remaining(tvb,offset);
1392 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1393 break;
1396 else {
1397 tvbuff_t *new_tvb;
1399 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1400 switch(fn) {
1401 case ASPFUNC_OPEN:
1402 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
1403 offset++;
1404 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1405 offset++;
1406 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, ENC_BIG_ENDIAN);
1407 offset += 2;
1408 break;
1409 case ASPFUNC_CLOSE:
1410 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, ENC_NA);
1411 offset++;
1412 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, ENC_NA);
1413 offset++;
1414 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, ENC_NA);
1415 offset += 2;
1416 break;
1417 case ASPFUNC_STAT:
1418 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, ENC_NA);
1419 offset += 4;
1420 dissect_asp_reply_get_status(tvb, pinfo, asp_tree, offset);
1421 break;
1422 case ASPFUNC_CMD:
1423 case ASPFUNC_WRITE:
1424 proto_item_set_len(asp_tree, 4);
1425 aspinfo->code = tvb_get_ntohl(tvb, offset);
1426 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, ENC_BIG_ENDIAN);
1427 offset += 4;
1428 len = tvb_reported_length_remaining(tvb,offset);
1429 new_tvb = tvb_new_subset(tvb, offset,-1,len);
1430 call_dissector(afp_handle, new_tvb, pinfo, tree);
1431 break;
1432 case ASPFUNC_TICKLE:
1433 case ASPFUNC_WRTCONT:
1434 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, ENC_NA);
1435 /* fall */
1436 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1437 default:
1438 proto_item_set_len(asp_tree, 4);
1439 offset += 4;
1440 len = tvb_reported_length_remaining(tvb,offset);
1441 call_dissector(data_handle,tvb_new_subset(tvb, offset,-1,len), pinfo, tree);
1442 break;
1445 return offset;
1448 /* -----------------------------
1449 ZIP protocol cf. inside appletalk chap. 8
1451 static int
1452 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1454 struct aspinfo *aspinfo;
1455 int offset = 0;
1456 proto_tree *zip_tree;
1457 proto_tree *sub_tree;
1458 proto_item *ti;
1459 guint8 fn;
1460 guint16 count;
1461 guint8 len;
1463 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1464 col_clear(pinfo->cinfo, COL_INFO);
1466 aspinfo = get_transaction(tvb, pinfo, (struct aspinfo *)data);
1467 if (!aspinfo)
1468 return tvb_length(tvb);
1470 fn = (guint8) aspinfo->command;
1472 if (aspinfo->reply)
1473 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1474 else
1475 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1476 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1478 if (!tree)
1479 return tvb_length(tvb);
1481 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, ENC_NA);
1482 zip_tree = proto_item_add_subtree(ti, ett_zip);
1484 if (!aspinfo->reply) {
1485 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, ENC_BIG_ENDIAN);
1486 offset++;
1487 switch(fn) {
1488 case 7: /* start_index = 0 */
1489 case 8:
1490 case 9:
1491 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, ENC_NA);
1492 offset++;
1493 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, ENC_BIG_ENDIAN);
1494 break;
1497 else {
1498 guint i;
1500 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1501 switch(fn) {
1502 case 7:
1503 case 8:
1504 case 9:
1505 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1506 offset++;
1508 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, ENC_NA);
1509 offset++;
1510 count = tvb_get_ntohs(tvb, offset);
1511 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, ENC_BIG_ENDIAN);
1512 offset += 2;
1513 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1514 for (i = 0; i < count; i++) {
1515 len = tvb_get_guint8(tvb, offset);
1516 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_NA);
1517 offset += len +1;
1519 break;
1523 return tvb_length(tvb);
1526 static void
1527 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1529 proto_tree *zip_tree = NULL;
1530 proto_item *ti;
1531 guint8 fn;
1532 guint8 len;
1533 gint offset = 0;
1534 proto_tree *flag_tree;
1535 proto_tree *sub_tree;
1536 proto_tree *net_tree;
1537 guint8 flag;
1538 guint16 net;
1539 guint i;
1540 guint count;
1542 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1543 col_clear(pinfo->cinfo, COL_INFO);
1545 fn = tvb_get_guint8(tvb, 0);
1546 col_add_str(pinfo->cinfo, COL_INFO,
1547 val_to_str_ext(fn, &zip_function_vals_ext, "Unknown ZIP function (%02x)"));
1549 if (!tree)
1550 return;
1552 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, ENC_NA);
1553 zip_tree = proto_item_add_subtree(ti, ett_zip);
1555 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,ENC_BIG_ENDIAN);
1556 offset++;
1557 /* fn 1,7,2,8 are not tested */
1558 switch (fn) {
1559 case 1: /* Query */
1560 count = tvb_get_guint8(tvb, offset);
1561 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1562 offset++;
1563 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1564 for (i = 0; i < count; i++) {
1565 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, ENC_BIG_ENDIAN);
1566 offset += 2;
1568 break;
1569 case 7: /* Notify */
1570 flag = tvb_get_guint8(tvb, offset);
1571 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1572 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1573 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,ENC_BIG_ENDIAN);
1574 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,ENC_BIG_ENDIAN);
1575 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,ENC_BIG_ENDIAN);
1576 offset++;
1578 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, ENC_NA);
1579 offset += 4;
1581 len = tvb_get_guint8(tvb, offset);
1582 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_NA);
1583 offset += len +1;
1585 len = tvb_get_guint8(tvb, offset);
1586 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,ENC_BIG_ENDIAN);
1587 offset++;
1588 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,ENC_NA);
1589 offset += len;
1591 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_NA);
1592 break;
1594 case 2: /* Reply */
1595 case 8: /* Extended Reply */
1596 count = tvb_get_guint8(tvb, offset);
1597 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1598 offset++;
1599 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1600 for (i = 0; i < count; i++) {
1601 net = tvb_get_ntohs(tvb, offset);
1602 ti = proto_tree_add_text(sub_tree, tvb, offset , 2, "Zone for network : %u", net);
1603 net_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1604 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, ENC_BIG_ENDIAN);
1605 offset += 2;
1606 len = tvb_get_guint8(tvb, offset);
1607 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_NA);
1608 offset += len +1;
1610 break;
1612 case 5 : /* GetNetInfo request */
1613 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, ENC_NA);
1614 offset++;
1615 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, ENC_NA);
1616 offset += 4;
1617 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_NA);
1618 break;
1620 case 6 : /* GetNetInfo reply */
1621 flag = tvb_get_guint8(tvb, offset);
1622 ti = proto_tree_add_text(zip_tree, tvb, offset , 1,"Flags : 0x%02x", flag);
1623 flag_tree = proto_item_add_subtree(ti, ett_zip_flags);
1624 proto_tree_add_item(flag_tree, hf_zip_flags_zone_invalid, tvb, offset, 1,ENC_BIG_ENDIAN);
1625 proto_tree_add_item(flag_tree, hf_zip_flags_use_broadcast,tvb, offset, 1,ENC_BIG_ENDIAN);
1626 proto_tree_add_item(flag_tree, hf_zip_flags_only_one_zone,tvb, offset, 1,ENC_BIG_ENDIAN);
1627 offset++;
1629 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, ENC_BIG_ENDIAN);
1630 offset += 2;
1632 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, ENC_BIG_ENDIAN);
1633 offset += 2;
1635 len = tvb_get_guint8(tvb, offset);
1636 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_NA);
1637 offset += len +1;
1639 len = tvb_get_guint8(tvb, offset);
1640 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,ENC_BIG_ENDIAN);
1641 offset++;
1642 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,ENC_NA);
1643 offset += len;
1644 if ((flag & 0x80) != 0)
1645 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,ENC_ASCII|ENC_NA);
1646 break;
1648 default:
1649 break;
1653 static void
1654 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, guint8 dnode,
1655 guint8 snode, proto_tree *tree)
1657 guint16 len;
1658 guint8 dport;
1659 guint8 sport;
1660 guint8 type;
1661 proto_tree *ddp_tree = NULL;
1662 proto_item *ti, *hidden_item;
1663 static struct atalk_ddp_addr src, dst;
1664 tvbuff_t *new_tvb;
1666 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1667 col_clear(pinfo->cinfo, COL_INFO);
1669 if (tree) {
1670 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1671 ENC_NA);
1672 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1674 len = tvb_get_ntohs(tvb, 0);
1675 if (tree)
1676 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1677 dport = tvb_get_guint8(tvb, 2);
1678 if (tree)
1679 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1680 sport = tvb_get_guint8(tvb, 3);
1681 if (tree)
1682 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1683 type = tvb_get_guint8(tvb, 4);
1685 src.net = 0;
1686 src.node = snode;
1687 dst.net = 0;
1688 dst.node = dnode;
1689 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1690 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1691 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1692 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1694 pinfo->ptype = PT_DDP;
1695 pinfo->destport = dport;
1696 pinfo->srcport = sport;
1698 col_add_str(pinfo->cinfo, COL_INFO,
1699 val_to_str_ext(type, &op_vals_ext, "Unknown DDP protocol (%02x)"));
1701 if (tree) {
1702 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_src, tvb,
1703 4, 3, atalk_addr_to_str(&src));
1704 PROTO_ITEM_SET_HIDDEN(hidden_item);
1705 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_dst, tvb,
1706 6, 3, atalk_addr_to_str(&dst));
1707 PROTO_ITEM_SET_HIDDEN(hidden_item);
1709 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1711 new_tvb = tvb_new_subset_remaining(tvb, DDP_SHORT_HEADER_SIZE);
1713 if (!dissector_try_uint(ddp_dissector_table, type, new_tvb, pinfo, tree))
1714 call_dissector(data_handle,new_tvb, pinfo, tree);
1717 static void
1718 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1720 e_ddp ddp;
1721 proto_tree *ddp_tree;
1722 proto_item *ti, *hidden_item;
1723 static struct atalk_ddp_addr src, dst; /* has to be static due to SET_ADDRESS */
1724 tvbuff_t *new_tvb;
1726 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1727 col_clear(pinfo->cinfo, COL_INFO);
1729 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1730 ddp.dnet=g_ntohs(ddp.dnet);
1731 ddp.snet=g_ntohs(ddp.snet);
1732 ddp.sum=g_ntohs(ddp.sum);
1733 ddp.hops_len=g_ntohs(ddp.hops_len);
1735 src.net = ddp.snet;
1736 src.node = ddp.snode;
1737 dst.net = ddp.dnet;
1738 dst.node = ddp.dnode;
1739 SET_ADDRESS(&pinfo->net_src, AT_ATALK, sizeof src, (guint8 *)&src);
1740 SET_ADDRESS(&pinfo->src, AT_ATALK, sizeof src, (guint8 *)&src);
1741 SET_ADDRESS(&pinfo->net_dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1742 SET_ADDRESS(&pinfo->dst, AT_ATALK, sizeof dst, (guint8 *)&dst);
1744 pinfo->ptype = PT_DDP;
1745 pinfo->destport = ddp.dport;
1746 pinfo->srcport = ddp.sport;
1748 col_add_str(pinfo->cinfo, COL_INFO,
1749 val_to_str_ext(ddp.type, &op_vals_ext, "Unknown DDP protocol (%02x)"));
1751 if (tree) {
1752 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1753 ENC_NA);
1754 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1756 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_src, tvb,
1757 4, 3, atalk_addr_to_str(&src));
1758 PROTO_ITEM_SET_HIDDEN(hidden_item);
1760 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_dst, tvb,
1761 6, 3, atalk_addr_to_str(&dst));
1762 PROTO_ITEM_SET_HIDDEN(hidden_item);
1764 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1765 ddp_hops(ddp.hops_len));
1766 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1767 ddp_len(ddp.hops_len));
1768 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1769 ddp.sum);
1770 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1771 ddp.dnet);
1772 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1773 ddp.snet);
1774 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1775 ddp.dnode);
1776 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1777 ddp.snode);
1778 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1779 ddp.dport);
1780 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1781 ddp.sport);
1782 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1783 ddp.type);
1786 new_tvb = tvb_new_subset_remaining(tvb, DDP_HEADER_SIZE);
1788 if (!dissector_try_uint(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1789 call_dissector(data_handle,new_tvb, pinfo, tree);
1792 static const value_string llap_type_vals[] = {
1793 {0x01, "Short DDP"},
1794 {0x02, "DDP" },
1795 {0x81, "Enquiry"},
1796 {0x82, "Acknowledgement"},
1797 {0x84, "RTS"},
1798 {0x85, "CTS"},
1799 {0, NULL}
1801 static value_string_ext llap_type_vals_ext = VALUE_STRING_EXT_INIT(llap_type_vals);
1803 void
1804 capture_llap(packet_counts *ld)
1806 ld->other++;
1809 static void
1810 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1812 guint8 dnode;
1813 guint8 snode;
1814 guint8 type;
1815 proto_tree *llap_tree = NULL;
1816 proto_item *ti;
1817 tvbuff_t *new_tvb;
1819 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1820 col_clear(pinfo->cinfo, COL_INFO);
1822 if (tree) {
1823 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, ENC_NA);
1824 llap_tree = proto_item_add_subtree(ti, ett_llap);
1827 dnode = tvb_get_guint8(tvb, 0);
1828 if (tree)
1829 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, dnode);
1830 snode = tvb_get_guint8(tvb, 1);
1831 if (tree)
1832 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, snode);
1833 type = tvb_get_guint8(tvb, 2);
1834 col_add_str(pinfo->cinfo, COL_INFO,
1835 val_to_str_ext(type, &llap_type_vals_ext, "Unknown LLAP type (%02x)"));
1837 if (tree)
1838 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1840 new_tvb = tvb_new_subset_remaining(tvb, 3);
1842 switch (type) {
1844 case 0x01:
1845 if (proto_is_protocol_enabled(find_protocol_by_id(proto_ddp))) {
1846 pinfo->current_proto = "DDP";
1847 dissect_ddp_short(new_tvb, pinfo, dnode, snode, tree);
1848 return;
1851 case 0x02:
1852 if (call_dissector(ddp_handle, new_tvb, pinfo, tree))
1853 return;
1855 call_dissector(data_handle,new_tvb, pinfo, tree);
1858 static void
1859 atp_init(void)
1861 /* fragment */
1862 reassembly_table_init(&atp_reassembly_table,
1863 &addresses_reassembly_table_functions);
1864 /* bitmap */
1865 if (atp_request_hash)
1866 g_hash_table_destroy(atp_request_hash);
1868 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1872 static void
1873 asp_reinit( void)
1876 if (asp_request_hash)
1877 g_hash_table_destroy(asp_request_hash);
1879 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1883 void
1884 proto_register_atalk(void)
1886 static hf_register_info hf_llap[] = {
1887 { &hf_llap_dst,
1888 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1889 NULL, HFILL }},
1891 { &hf_llap_src,
1892 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1893 NULL, HFILL }},
1895 { &hf_llap_type,
1896 { "Type", "llap.type", FT_UINT8, BASE_HEX|BASE_EXT_STRING, &llap_type_vals_ext, 0x0,
1897 NULL, HFILL }},
1900 static hf_register_info hf_ddp[] = {
1901 { &hf_ddp_hopcount,
1902 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1903 NULL, HFILL }},
1905 { &hf_ddp_len,
1906 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1907 NULL, HFILL }},
1909 { &hf_ddp_checksum,
1910 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1911 NULL, HFILL }},
1913 { &hf_ddp_dst,
1914 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1915 NULL, HFILL }},
1917 { &hf_ddp_dst_net,
1918 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1919 NULL, HFILL }},
1921 { &hf_ddp_src,
1922 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1923 NULL, HFILL }},
1925 { &hf_ddp_src_net,
1926 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1927 NULL, HFILL }},
1929 { &hf_ddp_dst_node,
1930 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1931 NULL, HFILL }},
1933 { &hf_ddp_src_node,
1934 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1935 NULL, HFILL }},
1937 { &hf_ddp_dst_socket,
1938 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1939 NULL, HFILL }},
1941 { &hf_ddp_src_socket,
1942 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1943 NULL, HFILL }},
1945 { &hf_ddp_type,
1946 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &op_vals_ext, 0x0,
1947 NULL, HFILL }},
1950 static hf_register_info hf_nbp[] = {
1951 { &hf_nbp_op,
1952 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1953 VALS(nbp_op_vals), 0xF0, NULL, HFILL }},
1954 { &hf_nbp_info,
1955 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1956 NULL, 0x0, NULL, HFILL }},
1957 { &hf_nbp_count,
1958 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1959 NULL, 0x0F, NULL, HFILL }},
1960 { &hf_nbp_node_net,
1961 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1962 NULL, 0x0, NULL, HFILL }},
1963 { &hf_nbp_node_node,
1964 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1965 NULL, 0x0, NULL, HFILL }},
1966 { &hf_nbp_node_port,
1967 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1968 NULL, 0x0, NULL, HFILL }},
1969 { &hf_nbp_node_enum,
1970 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1971 NULL, 0x0, NULL, HFILL }},
1972 { &hf_nbp_node_object,
1973 { "Object", "nbp.object", FT_STRING, BASE_NONE,
1974 NULL, 0x0, NULL, HFILL }},
1975 { &hf_nbp_node_type,
1976 { "Type", "nbp.type", FT_STRING, BASE_NONE,
1977 NULL, 0x0, NULL, HFILL }},
1978 { &hf_nbp_node_zone,
1979 { "Zone", "nbp.zone", FT_STRING, BASE_NONE,
1980 NULL, 0x0, NULL, HFILL }},
1981 { &hf_nbp_tid,
1982 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1983 NULL, 0x0, NULL, HFILL }}
1986 static hf_register_info hf_rtmp[] = {
1987 { &hf_rtmp_net,
1988 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1989 NULL, 0x0, NULL, HFILL }},
1990 { &hf_rtmp_node,
1991 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1992 NULL, 0x0, NULL, HFILL }},
1993 { &hf_rtmp_node_len,
1994 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1995 NULL, 0x0, NULL, HFILL }},
1996 { &hf_rtmp_tuple_net,
1997 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1998 NULL, 0x0, NULL, HFILL }},
1999 { &hf_rtmp_tuple_range_start,
2000 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
2001 NULL, 0x0, NULL, HFILL }},
2002 { &hf_rtmp_tuple_range_end,
2003 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
2004 NULL, 0x0, NULL, HFILL }},
2005 { &hf_rtmp_tuple_dist,
2006 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
2007 NULL, 0x0, NULL, HFILL }},
2008 { &hf_rtmp_function,
2009 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
2010 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
2013 static hf_register_info hf_atp[] = {
2014 { &hf_atp_ctrlinfo,
2015 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
2016 NULL, 0, NULL, HFILL }},
2018 { &hf_atp_function,
2019 { "Function", "atp.function", FT_UINT8, BASE_DEC,
2020 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
2023 { &hf_atp_xo,
2024 { "XO", "atp.xo", FT_BOOLEAN, 8,
2025 NULL, ATP_XO, "Exactly-once flag", HFILL }},
2027 { &hf_atp_eom,
2028 { "EOM", "atp.eom", FT_BOOLEAN, 8,
2029 NULL, ATP_EOM, "End-of-message", HFILL }},
2031 { &hf_atp_sts,
2032 { "STS", "atp.sts", FT_BOOLEAN, 8,
2033 NULL, ATP_STS, "Send transaction status", HFILL }},
2035 { &hf_atp_treltimer,
2036 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
2037 VALS(atp_trel_timer_vals), 0x07, NULL, HFILL }},
2039 { &hf_atp_bitmap,
2040 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
2041 NULL, 0x0, "Bitmap or sequence number", HFILL }},
2043 { &hf_atp_tid,
2044 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
2045 NULL, 0x0, "Transaction id", HFILL }},
2046 { &hf_atp_user_bytes,
2047 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
2048 NULL, 0x0, NULL, HFILL }},
2050 { &hf_atp_segment_overlap,
2051 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
2052 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
2054 { &hf_atp_segment_overlap_conflict,
2055 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
2056 FT_BOOLEAN, BASE_NONE,
2057 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
2059 { &hf_atp_segment_multiple_tails,
2060 { "Multiple tail segments found", "atp.segment.multipletails",
2061 FT_BOOLEAN, BASE_NONE,
2062 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
2064 { &hf_atp_segment_too_long_segment,
2065 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
2066 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
2068 { &hf_atp_segment_error,
2069 {"Desegmentation error", "atp.segment.error", FT_FRAMENUM, BASE_NONE,
2070 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
2072 { &hf_atp_segment_count,
2073 { "Segment count", "atp.segment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
2074 NULL, HFILL }},
2076 { &hf_atp_segment,
2077 { "ATP Fragment", "atp.fragment", FT_FRAMENUM, BASE_NONE,
2078 NULL, 0x0, NULL, HFILL }},
2080 { &hf_atp_segments,
2081 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
2082 NULL, 0x0, NULL, HFILL }},
2084 { &hf_atp_reassembled_in,
2085 { "Reassembled ATP in frame", "atp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
2086 "This ATP packet is reassembled in this frame", HFILL }},
2088 { &hf_atp_reassembled_length,
2089 { "Reassembled ATP length", "atp.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
2090 "The total length of the reassembled payload", HFILL }}
2093 static hf_register_info hf_asp[] = {
2094 { &hf_asp_func,
2095 { "asp function", "asp.function", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
2096 &asp_func_vals_ext, 0, NULL, HFILL }},
2098 { &hf_asp_error,
2099 { "asp error", "asp.error", FT_INT32, BASE_DEC|BASE_EXT_STRING,
2100 &asp_error_vals_ext, 0, "return error code", HFILL }},
2102 { &hf_asp_version,
2103 { "Version", "asp.version", FT_UINT16, BASE_HEX,
2104 NULL, 0, "asp version", HFILL }},
2106 { &hf_asp_attn_code,
2107 { "Attn code", "asp.attn_code", FT_UINT16, BASE_HEX,
2108 NULL, 0, "asp attention code", HFILL }},
2110 { &hf_asp_init_error,
2111 { "Error", "asp.init_error", FT_UINT16, BASE_DEC,
2112 NULL, 0, "asp init error", HFILL }},
2114 { &hf_asp_session_id,
2115 { "Session ID", "asp.session_id", FT_UINT8, BASE_DEC,
2116 NULL, 0, "asp session id", HFILL }},
2118 { &hf_asp_socket,
2119 { "Socket", "asp.socket", FT_UINT8, BASE_DEC,
2120 NULL, 0, "asp socket", HFILL }},
2122 { &hf_asp_seq,
2123 { "Sequence", "asp.seq", FT_UINT16, BASE_DEC,
2124 NULL, 0, "asp sequence number", HFILL }},
2126 { &hf_asp_size,
2127 { "size", "asp.size", FT_UINT16, BASE_DEC,
2128 NULL, 0, "asp available size for reply", HFILL }},
2130 { &hf_asp_zero_value,
2131 { "Pad (0)", "asp.zero_value",
2132 FT_BYTES, BASE_NONE, NULL, 0x0,
2133 "Pad", HFILL }},
2135 /* asp ,dsi, afp */
2136 { &hf_asp_server_name,
2137 { "Server name", "asp.server_name",
2138 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2139 NULL, HFILL }},
2141 { &hf_asp_server_type,
2142 { "Server type", "asp.server_type",
2143 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2144 NULL, HFILL }},
2146 { &hf_asp_server_vers,
2147 { "AFP version", "asp.server_vers",
2148 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2149 NULL, HFILL }},
2151 { &hf_asp_server_uams,
2152 { "UAM", "asp.server_uams",
2153 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2154 NULL, HFILL }},
2156 { &hf_asp_server_icon,
2157 { "Icon bitmap", "asp.server_icon",
2158 FT_BYTES, BASE_NONE, NULL, 0x0,
2159 "Server icon bitmap", HFILL }},
2161 { &hf_asp_server_directory,
2162 { "Directory service", "asp.server_directory",
2163 FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2164 "Server directory service", HFILL }},
2166 { &hf_asp_server_signature,
2167 { "Server signature", "asp.server_signature",
2168 FT_BYTES, BASE_NONE, NULL, 0x0,
2169 NULL, HFILL }},
2171 { &hf_asp_server_flag,
2172 { "Flag", "asp.server_flag",
2173 FT_UINT16, BASE_HEX, NULL, 0x0,
2174 "Server capabilities flag", HFILL }},
2175 { &hf_asp_server_flag_copyfile,
2176 { "Support copyfile", "asp.server_flag.copyfile",
2177 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_COPY,
2178 "Server support copyfile", HFILL }},
2179 { &hf_asp_server_flag_passwd,
2180 { "Support change password", "asp.server_flag.passwd",
2181 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_PASSWD,
2182 "Server support change password", HFILL }},
2183 { &hf_asp_server_flag_no_save_passwd,
2184 { "Don't allow save password", "asp.server_flag.no_save_passwd",
2185 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_NOSAVEPASSWD,
2186 NULL, HFILL }},
2187 { &hf_asp_server_flag_srv_msg,
2188 { "Support server message", "asp.server_flag.srv_msg",
2189 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVMSGS,
2190 NULL, HFILL }},
2191 { &hf_asp_server_flag_srv_sig,
2192 { "Support server signature", "asp.server_flag.srv_sig",
2193 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVSIGNATURE,
2194 NULL, HFILL }},
2195 { &hf_asp_server_flag_tcpip,
2196 { "Support TCP/IP", "asp.server_flag.tcpip",
2197 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_TCPIP,
2198 "Server support TCP/IP", HFILL }},
2199 { &hf_asp_server_flag_notify,
2200 { "Support server notifications", "asp.server_flag.notify",
2201 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVNOTIFY,
2202 "Server support notifications", HFILL }},
2203 { &hf_asp_server_flag_reconnect,
2204 { "Support server reconnect", "asp.server_flag.reconnect",
2205 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVRECONNECT,
2206 "Server support reconnect", HFILL }},
2207 { &hf_asp_server_flag_directory,
2208 { "Support directory services", "asp.server_flag.directory",
2209 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVDIRECTORY,
2210 "Server support directory services", HFILL }},
2211 { &hf_asp_server_flag_utf8_name,
2212 { "Support UTF8 server name", "asp.server_flag.utf8_name",
2213 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_SRVUTF8,
2214 "Server support UTF8 server name", HFILL }},
2215 { &hf_asp_server_flag_fast_copy,
2216 { "Support fast copy", "asp.server_flag.fast_copy",
2217 FT_BOOLEAN, 16, NULL, AFPSRVRINFO_FASTBOZO,
2218 "Server support fast copy", HFILL }},
2220 { &hf_asp_server_addr_len,
2221 { "Length", "asp.server_addr.len",
2222 FT_UINT8, BASE_DEC, NULL, 0x0,
2223 "Address length.", HFILL }},
2225 { &hf_asp_server_addr_type,
2226 { "Type", "asp.server_addr.type",
2227 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &afp_server_addr_type_vals_ext, 0x0,
2228 "Address type.", HFILL }},
2230 { &hf_asp_server_addr_value,
2231 { "Value", "asp.server_addr.value",
2232 FT_BYTES, BASE_NONE, NULL, 0x0,
2233 "Address value", HFILL }},
2235 { &hf_asp_server_utf8_name_len,
2236 { "Server name length", "asp.server_utf8_name_len",
2237 FT_UINT16, BASE_DEC, NULL, 0x0,
2238 "UTF8 server name length", HFILL }},
2240 { &hf_asp_server_utf8_name,
2241 { "Server name (UTF8)", "asp.server_utf8_name",
2242 FT_STRING, BASE_NONE, NULL, 0x0,
2243 NULL, HFILL }},
2246 static hf_register_info hf_zip[] = {
2247 { &hf_zip_function,
2248 { "Function", "zip.function", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &zip_function_vals_ext, 0x0,
2249 "ZIP function", HFILL }},
2251 { &hf_zip_zero_value,
2252 { "Pad (0)", "zip.zero_value",FT_BYTES, BASE_NONE, NULL, 0x0,
2253 "Pad", HFILL }},
2255 { &hf_zip_atp_function,
2256 { "Function", "zip.atp_function", FT_UINT8, BASE_DEC, VALS(zip_atp_function_vals), 0x0,
2257 NULL, HFILL }},
2259 { &hf_zip_start_index,
2260 { "Start index", "zip.start_index", FT_UINT16, BASE_DEC, NULL, 0x0,
2261 NULL, HFILL }},
2263 { &hf_zip_count,
2264 { "Count", "zip.count", FT_UINT16, BASE_DEC, NULL, 0x0,
2265 NULL, HFILL }},
2267 { &hf_zip_network_count,
2268 { "Count", "zip.network_count", FT_UINT8, BASE_DEC, NULL, 0x0,
2269 NULL, HFILL }},
2270 { &hf_zip_network,
2271 { "Network","zip.network", FT_UINT16, BASE_DEC, NULL, 0x0,
2272 NULL, HFILL }},
2273 { &hf_zip_network_start,
2274 { "Network start","zip.network_start", FT_UINT16, BASE_DEC, NULL, 0x0,
2275 NULL, HFILL }},
2276 { &hf_zip_network_end,
2277 { "Network end", "zip.network_end", FT_UINT16, BASE_DEC, NULL, 0x0,
2278 NULL, HFILL }},
2280 #if 0
2281 { &hf_zip_flags,
2282 { "Flags", "zip.flags", FT_BOOLEAN, 8, NULL, 0xC0,
2283 NULL, HFILL }},
2284 #endif
2286 { &hf_zip_last_flag,
2287 { "Last Flag", "zip.last_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2288 "Non zero if contains last zone name in the zone list", HFILL }},
2290 { &hf_zip_flags_zone_invalid,
2291 { "Zone invalid", "zip.flags.zone_invalid", FT_BOOLEAN, 8, NULL, 0x80,
2292 NULL, HFILL }},
2294 { &hf_zip_flags_use_broadcast,
2295 { "Use broadcast","zip.flags.use_broadcast", FT_BOOLEAN, 8, NULL, 0x40,
2296 NULL, HFILL }},
2298 { &hf_zip_flags_only_one_zone,
2299 { "Only one zone","zip.flags.only_one_zone", FT_BOOLEAN, 8, NULL, 0x20,
2300 NULL, HFILL }},
2302 { &hf_zip_zone_name,
2303 { "Zone", "zip.zone_name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2304 NULL, HFILL }},
2306 { &hf_zip_default_zone,
2307 { "Default zone", "zip.default_zone",FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2308 NULL, HFILL }},
2310 { &hf_zip_multicast_length,
2311 { "Multicast length", "zip.multicast_length", FT_UINT8, BASE_DEC, NULL, 0x0,
2312 "Multicast address length", HFILL }},
2314 { &hf_zip_multicast_address,
2315 { "Multicast address", "zip.multicast_address",FT_BYTES, BASE_NONE, NULL, 0x0,
2316 NULL, HFILL }},
2320 static hf_register_info hf_pap[] = {
2321 { &hf_pap_connid,
2322 { "ConnID", "prap.connid", FT_UINT8, BASE_DEC, NULL, 0x0,
2323 "PAP connection ID", HFILL }},
2325 { &hf_pap_function,
2326 { "Function", "prap.function", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &pap_function_vals_ext, 0x0,
2327 "PAP function", HFILL }},
2329 { &hf_pap_socket,
2330 { "Socket", "prap.socket", FT_UINT8, BASE_DEC, NULL, 0x0,
2331 "ATP responding socket number", HFILL }},
2333 { &hf_pap_quantum,
2334 { "Quantum", "prap.quantum", FT_UINT8, BASE_DEC, NULL, 0x0,
2335 "Flow quantum", HFILL }},
2337 { &hf_pap_waittime,
2338 { "Wait time", "prap.waittime", FT_UINT16, BASE_DEC, NULL, 0x0,
2339 NULL, HFILL }},
2341 { &hf_pap_result,
2342 { "Result", "prap.result", FT_UINT16, BASE_DEC, NULL, 0x0,
2343 NULL, HFILL }},
2345 { &hf_pap_seq,
2346 { "Sequence", "prap.seq", FT_UINT16, BASE_DEC, NULL, 0x0,
2347 "Sequence number", HFILL }},
2349 { &hf_pap_status,
2350 { "Status", "prap.status", FT_STRING, BASE_NONE, NULL, 0x0,
2351 "Printer status", HFILL }},
2353 { &hf_pap_eof,
2354 { "EOF", "prap.eof", FT_BOOLEAN, BASE_NONE,
2355 NULL, 0x0, NULL, HFILL }},
2357 { &hf_pap_pad,
2358 { "Pad", "prap.pad", FT_NONE, BASE_NONE, NULL, 0,
2359 "Pad Byte", HFILL }},
2363 static gint *ett[] = {
2364 &ett_llap,
2365 &ett_ddp,
2366 &ett_atp,
2367 &ett_atp_info,
2368 &ett_atp_segments,
2369 &ett_atp_segment,
2370 &ett_asp,
2371 &ett_pap,
2373 /* asp dsi afp */
2374 &ett_asp_status,
2375 &ett_asp_status_server_flag,
2376 &ett_asp_vers,
2377 &ett_asp_uams,
2378 &ett_asp_addr,
2379 &ett_asp_addr_line,
2380 &ett_asp_directory,
2381 &ett_asp_utf8_name,
2383 &ett_nbp,
2384 &ett_nbp_info,
2385 &ett_nbp_node,
2386 &ett_pstring,
2387 &ett_rtmp,
2388 &ett_rtmp_tuple,
2390 &ett_zip,
2391 &ett_zip_flags,
2392 &ett_zip_zones_list,
2393 &ett_zip_network_list,
2395 module_t *atp_module;
2397 proto_llap = proto_register_protocol("LocalTalk Link Access Protocol", "LLAP", "llap");
2398 proto_register_field_array(proto_llap, hf_llap, array_length(hf_llap));
2400 proto_ddp = proto_register_protocol("Datagram Delivery Protocol", "DDP", "ddp");
2401 proto_register_field_array(proto_ddp, hf_ddp, array_length(hf_ddp));
2403 proto_nbp = proto_register_protocol("Name Binding Protocol", "NBP", "nbp");
2404 proto_register_field_array(proto_nbp, hf_nbp, array_length(hf_nbp));
2406 proto_atp = proto_register_protocol("AppleTalk Transaction Protocol packet", "ATP", "atp");
2407 proto_register_field_array(proto_atp, hf_atp, array_length(hf_atp));
2409 proto_asp = proto_register_protocol("AppleTalk Session Protocol", "ASP", "asp");
2410 proto_register_field_array(proto_asp, hf_asp, array_length(hf_asp));
2412 proto_pap = proto_register_protocol("Printer Access Protocol", "PrAP", "prap");
2413 proto_register_field_array(proto_pap, hf_pap, array_length(hf_pap));
2415 proto_zip = proto_register_protocol("Zone Information Protocol", "ZIP", "zip");
2416 proto_register_field_array(proto_zip, hf_zip, array_length(hf_zip));
2418 atp_module = prefs_register_protocol(proto_atp, NULL);
2419 prefs_register_bool_preference(atp_module, "desegment",
2420 "Reassemble ATP messages spanning multiple DDP packets",
2421 "Whether the ATP dissector should reassemble messages spanning multiple DDP packets",
2422 &atp_defragment);
2424 proto_rtmp = proto_register_protocol("Routing Table Maintenance Protocol",
2425 "RTMP", "rtmp");
2426 proto_register_field_array(proto_rtmp, hf_rtmp, array_length(hf_rtmp));
2428 proto_register_subtree_array(ett, array_length(ett));
2430 /* subdissector code */
2431 ddp_dissector_table = register_dissector_table("ddp.type", "DDP packet type",
2432 FT_UINT8, BASE_HEX);
2435 void
2436 proto_reg_handoff_atalk(void)
2438 dissector_handle_t nbp_handle, rtmp_request_handle;
2439 dissector_handle_t atp_handle;
2440 dissector_handle_t zip_ddp_handle;
2441 dissector_handle_t rtmp_data_handle, llap_handle;
2443 ddp_handle = create_dissector_handle(dissect_ddp, proto_ddp);
2444 dissector_add_uint("ethertype", ETHERTYPE_ATALK, ddp_handle);
2445 dissector_add_uint("chdlc.protocol", ETHERTYPE_ATALK, ddp_handle);
2446 dissector_add_uint("ppp.protocol", PPP_AT, ddp_handle);
2447 dissector_add_uint("null.type", BSD_AF_APPLETALK, ddp_handle);
2448 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_APPLETALK, ddp_handle);
2450 nbp_handle = create_dissector_handle(dissect_nbp, proto_nbp);
2451 dissector_add_uint("ddp.type", DDP_NBP, nbp_handle);
2453 atp_handle = create_dissector_handle(dissect_atp, proto_atp);
2454 dissector_add_uint("ddp.type", DDP_ATP, atp_handle);
2456 asp_handle = new_create_dissector_handle(dissect_asp, proto_asp);
2457 pap_handle = new_create_dissector_handle(dissect_pap, proto_pap);
2459 rtmp_request_handle = create_dissector_handle(dissect_rtmp_request, proto_rtmp);
2460 rtmp_data_handle = create_dissector_handle(dissect_rtmp_data, proto_rtmp);
2461 dissector_add_uint("ddp.type", DDP_RTMPREQ, rtmp_request_handle);
2462 dissector_add_uint("ddp.type", DDP_RTMPDATA, rtmp_data_handle);
2464 zip_ddp_handle = create_dissector_handle(dissect_ddp_zip, proto_zip);
2465 dissector_add_uint("ddp.type", DDP_ZIP, zip_ddp_handle);
2467 zip_atp_handle = new_create_dissector_handle(dissect_atp_zip, proto_zip);
2469 llap_handle = create_dissector_handle(dissect_llap, proto_llap);
2470 dissector_add_uint("wtap_encap", WTAP_ENCAP_LOCALTALK, llap_handle);
2472 register_init_routine( atp_init);
2473 register_init_routine( &asp_reinit);
2475 afp_handle = find_dissector("afp");
2476 data_handle = find_dissector("data");
2480 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2482 * Local variables:
2483 * c-basic-offset: 2
2484 * tab-width: 8
2485 * indent-tabs-mode: nil
2486 * End:
2488 * vi: set shiftwidth=2 tabstop=8 expandtab:
2489 * :indentSize=4:tabSize=8:noTabs=true: