2 * Routines for AppleTalk packet disassembly: LLAP, DDP, NBP, ATP, ASP,
5 * Simon Wilkinson <sxw@dcs.ed.ac.uk>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <epan/packet.h>
30 #include <epan/etypes.h>
31 #include <epan/ppptypes.h>
32 #include <epan/aftypes.h>
33 #include <epan/arcnet_pids.h>
34 #include <epan/conversation.h>
35 #include <epan/prefs.h>
36 #include <epan/reassemble.h>
37 #include <epan/address_types.h>
38 #include <epan/to_str.h>
39 #include <wiretap/wtap.h>
40 #include <epan/capture_dissectors.h>
41 #include "packet-atalk.h"
42 #include "packet-afp.h"
44 void proto_register_atalk(void);
45 void proto_reg_handoff_atalk(void);
47 /* Tables for reassembly of fragments. */
48 static reassembly_table atp_reassembly_table;
50 /* desegmentation of ATP */
51 static gboolean atp_defragment = TRUE;
53 static dissector_handle_t afp_handle;
54 static dissector_handle_t afp_server_status_handle;
56 static int proto_llap = -1;
57 static int hf_llap_dst = -1;
58 static int hf_llap_src = -1;
59 static int hf_llap_type = -1;
61 static int proto_ddp = -1;
62 static int hf_ddp_hopcount = -1;
63 static int hf_ddp_len = -1;
64 static int hf_ddp_checksum = -1;
65 static int hf_ddp_dst = -1;
66 static int hf_ddp_dst_net = -1;
67 static int hf_ddp_src = -1;
68 static int hf_ddp_src_net = -1;
69 static int hf_ddp_dst_node = -1;
70 static int hf_ddp_src_node = -1;
71 static int hf_ddp_dst_socket = -1;
72 static int hf_ddp_src_socket = -1;
73 static int hf_ddp_type = -1;
75 static dissector_handle_t ddp_handle;
76 static dissector_handle_t ddp_short_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;
111 static dissector_handle_t pap_handle;
113 static int proto_atp = -1;
114 static int hf_atp_ctrlinfo = -1; /* guint8_t control information */
115 static int hf_atp_function = -1; /* bits 7,6 function */
116 static int hf_atp_xo = -1; /* bit 5 exactly-once */
117 static int hf_atp_eom = -1; /* bit 4 end-of-message */
118 static int hf_atp_sts = -1; /* bit 3 send transaction status */
119 static int hf_atp_treltimer = -1; /* bits 2,1,0 TRel timeout indicator */
121 static int hf_atp_bitmap = -1; /* guint8_t bitmap or sequence number */
122 static int hf_atp_tid = -1; /* guint16_t transaction id. */
123 static int hf_atp_user_bytes = -1;
125 static int hf_atp_segments = -1;
126 static int hf_atp_segment = -1;
127 static int hf_atp_segment_overlap = -1;
128 static int hf_atp_segment_overlap_conflict = -1;
129 static int hf_atp_segment_multiple_tails = -1;
130 static int hf_atp_segment_too_long_segment = -1;
131 static int hf_atp_segment_error = -1;
132 static int hf_atp_segment_count = -1;
133 static int hf_atp_reassembled_in = -1;
134 static int hf_atp_reassembled_length = -1;
136 /* ------------------------- */
137 static int proto_zip = -1;
138 static dissector_handle_t zip_atp_handle;
140 static int hf_zip_function = -1;
141 static int hf_zip_atp_function = -1;
142 static int hf_zip_start_index = -1;
143 static int hf_zip_count = -1;
144 static int hf_zip_zero_value = -1;
146 static int hf_zip_network_count = -1;
147 static int hf_zip_network = -1;
148 static int hf_zip_network_start = -1;
149 static int hf_zip_network_end = -1;
151 static int hf_zip_flags = -1;
152 static int hf_zip_flags_zone_invalid = -1;
153 static int hf_zip_flags_use_broadcast = -1;
154 static int hf_zip_flags_only_one_zone = -1;
156 static int hf_zip_last_flag = -1;
158 static int hf_zip_zone_name = -1;
159 static int hf_zip_default_zone = -1;
161 static int hf_zip_multicast_length = -1;
162 static int hf_zip_multicast_address = -1;
164 static const value_string zip_function_vals[] = {
167 {5, "GetNetInfo request"},
168 {6, "GetNetInfo reply"},
170 {8, "Extended reply"},
173 static value_string_ext zip_function_vals_ext = VALUE_STRING_EXT_INIT(zip_function_vals);
175 static const value_string zip_atp_function_vals[] = {
178 {9, "GetLocalZones"},
182 static gint ett_zip = -1;
183 static gint ett_zip_flags = -1;
184 static gint ett_zip_zones_list = -1;
185 static gint ett_zip_network_list = -1;
187 /* --------------------------------
188 * from netatalk/include/atalk/ats.h
191 #define ASPFUNC_CLOSE 1
192 #define ASPFUNC_CMD 2
193 #define ASPFUNC_STAT 3
194 #define ASPFUNC_OPEN 4
195 #define ASPFUNC_TICKLE 5
196 #define ASPFUNC_WRITE 6
197 #define ASPFUNC_WRTCONT 7
198 #define ASPFUNC_ATTN 8
202 #define ASPERR_BADVERS (-1066)
203 #define ASPERR_BUFSMALL (-1067)
204 #define ASPERR_NOSESS (-1068)
205 #define ASPERR_NOSERV (-1069)
206 #define ASPERR_PARM (-1070)
207 #define ASPERR_SERVBUSY (-1071)
208 #define ASPERR_SESSCLOS (-1072)
209 #define ASPERR_SIZERR (-1073)
210 #define ASPERR_TOOMANY (-1074)
211 #define ASPERR_NOACK (-1075)
213 static int proto_asp = -1;
214 static int hf_asp_func = -1;
215 static int hf_asp_error = -1;
216 static int hf_asp_socket = -1;
217 static int hf_asp_version = -1;
218 static int hf_asp_session_id = -1;
219 static int hf_asp_zero_value = -1;
220 static int hf_asp_init_error = -1;
221 static int hf_asp_attn_code = -1;
222 static int hf_asp_seq = -1;
223 static int hf_asp_size = -1;
226 guint32 conversation;
232 guint8 value; /* command for asp, bitmap for atp */
235 static GHashTable *asp_request_hash = NULL;
238 static gint asp_equal (gconstpointer v, gconstpointer v2)
240 const asp_request_key *val1 = (const asp_request_key*)v;
241 const asp_request_key *val2 = (const asp_request_key*)v2;
243 if (val1->conversation == val2->conversation &&
244 val1->seq == val2->seq &&
245 !memcmp(val1->src, val2->src, 4)) {
251 static guint asp_hash (gconstpointer v)
253 const asp_request_key *asp_key = (const asp_request_key*)v;
257 /* ------------------------------------ */
258 static GHashTable *atp_request_hash = NULL;
261 /* ------------------------------------ */
262 static int proto_nbp = -1;
263 static int hf_nbp_op = -1;
264 static int hf_nbp_info = -1;
265 static int hf_nbp_count = -1;
266 static int hf_nbp_tid = -1;
268 static int hf_nbp_node_net = -1;
269 static int hf_nbp_node_port = -1;
270 static int hf_nbp_node_node = -1;
271 static int hf_nbp_node_enum = -1;
272 static int hf_nbp_node_object = -1;
273 static int hf_nbp_node_type = -1;
274 static int hf_nbp_node_zone = -1;
276 static int proto_rtmp = -1;
277 static int hf_rtmp_net = -1;
278 static int hf_rtmp_node_len = -1;
279 static int hf_rtmp_node = -1;
280 static int hf_rtmp_tuple_net = -1;
281 static int hf_rtmp_tuple_range_start = -1;
282 static int hf_rtmp_tuple_range_end = -1;
283 static int hf_rtmp_tuple_dist = -1;
284 static int hf_rtmp_function = -1;
286 static gint ett_atp = -1;
288 static gint ett_atp_segments = -1;
289 static gint ett_atp_segment = -1;
290 static gint ett_atp_info = -1;
291 static gint ett_asp = -1;
292 static gint ett_pap = -1;
294 static gint ett_nbp = -1;
295 static gint ett_nbp_info = -1;
296 static gint ett_nbp_node = -1;
297 static gint ett_rtmp = -1;
298 static gint ett_rtmp_tuple = -1;
299 static gint ett_ddp = -1;
300 static gint ett_llap = -1;
301 static gint ett_pstring = -1;
303 static const fragment_items atp_frag_items = {
308 &hf_atp_segment_overlap,
309 &hf_atp_segment_overlap_conflict,
310 &hf_atp_segment_multiple_tails,
311 &hf_atp_segment_too_long_segment,
312 &hf_atp_segment_error,
313 &hf_atp_segment_count,
314 &hf_atp_reassembled_in,
315 &hf_atp_reassembled_length,
316 /* Reassembled data field */
321 /* -------------------------------- */
323 #define PAPOpenConn 1
324 #define PAPOpenConnReply 2
325 #define PAPSendData 3
328 #define PAPCloseConn 6
329 #define PAPCloseConnReply 7
330 #define PAPSendStatus 8
333 static int proto_pap = -1;
335 static int hf_pap_connid = -1;
336 static int hf_pap_function = -1;
337 static int hf_pap_socket = -1;
338 static int hf_pap_quantum = -1;
339 static int hf_pap_waittime = -1;
340 static int hf_pap_result = -1;
341 static int hf_pap_status = -1;
342 static int hf_pap_seq = -1;
343 static int hf_pap_eof = -1;
345 static int hf_pap_pad = -1;
347 static int atalk_address_type = -1;
349 static const value_string pap_function_vals[] = {
350 {PAPOpenConn , "Open Connection Query"},
351 {PAPOpenConnReply , "Open Connection Reply"},
352 {PAPSendData , "Send Data"},
354 {PAPTickle , "Tickle"},
355 {PAPCloseConn , "Close Connection Query"},
356 {PAPCloseConnReply , "Close Connection reply"},
357 {PAPSendStatus , "Send Status"},
358 {PAPStatus , "Status"},
362 static value_string_ext pap_function_vals_ext = VALUE_STRING_EXT_INIT(pap_function_vals);
364 /* -------------------------------- */
366 static dissector_table_t ddp_dissector_table;
368 #define DDP_SHORT_HEADER_SIZE 5
371 * P = Padding, H = Hops, L = Len
375 * Assumes the argument is in host byte order.
377 #define ddp_hops(x) ( ( x >> 10) & 0x3C )
378 #define ddp_len(x) ( x & 0x03ff )
379 typedef struct _e_ddp {
380 guint16 hops_len; /* combines pad, hops, and len */
381 guint16 sum,dnet,snet;
387 #define DDP_HEADER_SIZE 13
390 static const value_string op_vals[] = {
391 {DDP_RTMPDATA, "AppleTalk Routing Table response or data" },
392 {DDP_NBP, "AppleTalk Name Binding Protocol packet"},
393 {DDP_ATP, "AppleTalk Transaction Protocol packet"},
394 {DDP_AEP, "AppleTalk Echo Protocol packet"},
395 {DDP_RTMPREQ, "AppleTalk Routing Table request"},
396 {DDP_ZIP, "AppleTalk Zone Information Protocol packet"},
397 {DDP_ADSP, "AppleTalk Data Stream Protocol"},
398 {DDP_EIGRP, "Cisco EIGRP for AppleTalk"},
401 static value_string_ext op_vals_ext = VALUE_STRING_EXT_INIT(op_vals);
403 static const value_string rtmp_function_vals[] = {
405 {2, "Route Data Request (split horizon processed)"},
406 {3, "Route Data Request (no split horizon processing)"},
410 #define NBP_BROADCAST 1
412 #define NBP_FORWARD 4
415 static const value_string nbp_op_vals[] = {
416 {NBP_BROADCAST, "broadcast request"},
417 {NBP_LOOKUP, "lookup"},
418 {NBP_FORWARD, "forward request"},
419 {NBP_REPLY, "reply"},
423 static const value_string atp_function_vals[] = {
424 {ATP_TREQ ,"REQuest"},
425 {ATP_TRESP ,"RESPonse"},
426 {ATP_TREL ,"RELease"},
430 static const value_string atp_trel_timer_vals[] = {
441 static const value_string asp_func_vals[] = {
442 {ASPFUNC_CLOSE, "CloseSession" },
443 {ASPFUNC_CMD, "Command" },
444 {ASPFUNC_STAT, "GetStatus" },
445 {ASPFUNC_OPEN, "OpenSession" },
446 {ASPFUNC_TICKLE, "Tickle" },
447 {ASPFUNC_WRITE, "Write" },
448 {ASPFUNC_WRTCONT, "Write Cont" },
449 {ASPFUNC_ATTN, "Attention" },
451 static value_string_ext asp_func_vals_ext = VALUE_STRING_EXT_INIT(asp_func_vals);
453 /* XXX: Array sorted in ascending order (unsigned) to allow value_string_ext binary search */
454 static const value_string asp_error_vals[] = {
455 {AFP_OK , "success"},
456 {AFPERR_USRLOGIN , "user already logged on" },
457 {AFPERR_PWDPOLCY , "password fails policy check" },
458 {AFPERR_PWDCHNG , "password needs to be changed" },
459 {AFPERR_INTRASH , "shared folder in trash." },
460 {AFPERR_INSHRD , "folder being shared is inside a shared folder." },
461 {AFPERR_PWDEXPR , "password expired" },
462 {AFPERR_PWDSHORT , "password too short" },
463 {AFPERR_PWDSAME , "same password/can't change password" },
464 {AFPERR_BADID , "non-existent file id" },
465 {AFPERR_SAMEOBJ , "source file == destination file" },
466 {AFPERR_CATCHNG , "catalog has changed" },
467 {AFPERR_DIFFVOL , "different volume" },
468 {AFPERR_EXISTID , "file already has an id" },
469 {AFPERR_NOID , "file thread not found" },
470 {AFPERR_CTNSHRD , "share point contains a share point" },
471 {AFPERR_OLOCK , "object locked" },
472 {AFPERR_VLOCK , "volume locked" },
473 {AFPERR_ITYPE , "wrong icon type" },
474 {AFPERR_NODIR , "couldn't find directory" },
475 {AFPERR_NORENAME , "can't rename" },
476 {AFPERR_SHUTDOWN , "server is going down" },
477 {AFPERR_NFILE , "too many files open" },
478 {AFPERR_BADTYPE , "object is the wrong type" },
479 {AFPERR_NOOP , "command not supported" },
480 {AFPERR_NOTAUTH , "user not authenticated" },
481 {AFPERR_SESSCLOS , "session closed" },
482 {AFPERR_RANGEOVR , "range overlap" },
483 {AFPERR_NORANGE , "no range lock" },
484 {AFPERR_PARAM , "parameter error" },
485 {AFPERR_NOOBJ , "object not found" },
486 {AFPERR_EXIST , "object already exists" },
487 {AFPERR_NOSRVR , "no response by server at that address" },
488 {AFPERR_NLOCK , "no more locks" },
489 {AFPERR_MISC , "misc. err" },
490 {AFPERR_LOCK , "LockErr" },
491 {AFPERR_NOITEM , "ItemNotFound" },
492 {AFPERR_FLATVOL , "volume doesn't support directories" },
493 {AFPERR_BUSY , "FileBusy" },
494 {AFPERR_EOF , "end of file" },
495 {AFPERR_DFULL , "disk full" },
496 {AFPERR_DIRNEMPT , "directory not empty" },
497 {AFPERR_DENYCONF , "file synchronization locks conflict" },
498 {AFPERR_CANTMOVE , "can't move file" },
499 {AFPERR_BITMAP , "invalid bitmap" },
500 {AFPERR_BADVERS , "bad afp version number" },
501 {AFPERR_BADUAM , "uam doesn't exist" },
502 {AFPERR_AUTHCONT , "logincont" },
503 {AFPERR_ACCESS , "permission denied" },
504 {ASPERR_SESSCLOS , "session closed (ASP)" },
505 {ASPERR_NOSESS , "no more sessions available"},
507 value_string_ext asp_error_vals_ext = VALUE_STRING_EXT_INIT(asp_error_vals);
510 * hf_index must be a FT_UINT_STRING type
511 * Are these always in the Mac extended character set?
513 static int dissect_pascal_string(tvbuff_t *tvb, int offset, proto_tree *tree,
518 len = tvb_get_guint8(tvb, offset);
519 proto_tree_add_item(tree, hf_index, tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
527 dissect_rtmp_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
528 proto_tree *rtmp_tree;
532 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
533 col_clear(pinfo->cinfo, COL_INFO);
535 function = tvb_get_guint8(tvb, 0);
537 col_add_str(pinfo->cinfo, COL_INFO,
538 val_to_str(function, rtmp_function_vals, "Unknown function (%02x)"));
541 ti = proto_tree_add_item(tree, proto_rtmp, tvb, 0, 1, ENC_NA);
542 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
544 proto_tree_add_uint(rtmp_tree, hf_rtmp_function, tvb, 0, 1, function);
546 return tvb_captured_length(tvb);
550 dissect_rtmp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
551 proto_tree *rtmp_tree;
555 guint8 nodelen,nodelen_bits;
556 guint16 node; /* might be more than 8 bits */
559 col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
560 col_clear(pinfo->cinfo, COL_INFO);
562 net = tvb_get_ntohs(tvb, offset);
563 nodelen_bits = tvb_get_guint8(tvb, offset+2);
564 if ( nodelen_bits <= 8 ) {
565 node = tvb_get_guint8(tvb, offset+3);
568 node = tvb_get_ntohs(tvb, offset+3);
572 col_add_fstr(pinfo->cinfo, COL_INFO, "Net: %u Node Len: %u Node: %u",
573 net, nodelen_bits, node);
576 ti = proto_tree_add_item(tree, proto_rtmp, tvb, offset, -1, ENC_NA);
577 rtmp_tree = proto_item_add_subtree(ti, ett_rtmp);
579 proto_tree_add_uint(rtmp_tree, hf_rtmp_net, tvb, offset, 2, net);
580 proto_tree_add_uint(rtmp_tree, hf_rtmp_node_len, tvb, offset+2, 1,
582 proto_tree_add_uint(rtmp_tree, hf_rtmp_node, tvb, offset+3, nodelen,
584 offset += 3 + nodelen;
587 while (tvb_offset_exists(tvb, offset)) {
588 proto_tree *tuple_tree;
591 guint16 tuple_range_end;
593 tuple_net = tvb_get_ntohs(tvb, offset);
594 tuple_dist = tvb_get_guint8(tvb, offset+2);
596 if (tuple_dist & 0x80) {
597 tuple_range_end = tvb_get_ntohs(tvb, offset+3);
598 tuple_tree = proto_tree_add_subtree_format(rtmp_tree, tvb, offset, 6,
599 ett_rtmp_tuple, NULL,
600 "Tuple %d: Range Start: %u Dist: %u Range End: %u",
601 i, tuple_net, tuple_dist&0x7F, tuple_range_end);
603 tuple_tree = proto_tree_add_subtree_format(rtmp_tree, tvb, offset, 3,
604 ett_rtmp_tuple, NULL,
605 "Tuple %d: Net: %u Dist: %u",
606 i, tuple_net, tuple_dist);
609 if (tuple_dist & 0x80) {
610 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_range_start, tvb, offset, 2,
613 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_net, tvb, offset, 2,
616 proto_tree_add_uint(tuple_tree, hf_rtmp_tuple_dist, tvb, offset+2, 1,
619 if (tuple_dist & 0x80) {
621 * Extended network tuple.
623 proto_tree_add_item(tuple_tree, hf_rtmp_tuple_range_end, tvb, offset+3, 2,
632 return tvb_captured_length(tvb);
636 dissect_nbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
637 proto_tree *nbp_tree;
638 proto_tree *nbp_info_tree;
639 proto_item *ti, *info_item;
645 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBP");
646 col_clear(pinfo->cinfo, COL_INFO);
648 info = tvb_get_guint8(tvb, offset);
652 col_add_fstr(pinfo->cinfo, COL_INFO, "Op: %s Count: %u",
653 val_to_str(op, nbp_op_vals, "Unknown (0x%01x)"), count);
656 ti = proto_tree_add_item(tree, proto_nbp, tvb, offset, -1, ENC_NA);
657 nbp_tree = proto_item_add_subtree(ti, ett_nbp);
659 info_item = proto_tree_add_uint_format(nbp_tree, hf_nbp_info, tvb, offset, 1,
661 "Info: 0x%01X Operation: %s Count: %u", info,
662 val_to_str(op, nbp_op_vals, "Unknown (0x%01X)"),
664 nbp_info_tree = proto_item_add_subtree(info_item, ett_nbp_info);
665 proto_tree_add_uint(nbp_info_tree, hf_nbp_op, tvb, offset, 1, info);
666 proto_tree_add_uint(nbp_info_tree, hf_nbp_count, tvb, offset, 1, info);
667 proto_tree_add_item(nbp_tree, hf_nbp_tid, tvb, offset+1, 1, ENC_BIG_ENDIAN);
670 for (i = 0; i < count; i++) {
671 proto_tree *node_item,*node_tree;
672 int soffset = offset;
674 node_tree = proto_tree_add_subtree_format(nbp_tree, tvb, offset, -1,
675 ett_nbp_node, &node_item, "Node %u", i+1);
677 proto_tree_add_item(node_tree, hf_nbp_node_net, tvb, offset, 2, ENC_BIG_ENDIAN);
679 proto_tree_add_item(node_tree, hf_nbp_node_node, tvb, offset, 1, ENC_BIG_ENDIAN);
681 proto_tree_add_item(node_tree, hf_nbp_node_port, tvb, offset, 1, ENC_BIG_ENDIAN);
683 proto_tree_add_item(node_tree, hf_nbp_node_enum, tvb, offset, 1, ENC_BIG_ENDIAN);
686 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_object);
687 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_type);
688 offset = dissect_pascal_string(tvb, offset, node_tree, hf_nbp_node_zone);
690 proto_item_set_len(node_item, offset-soffset);
694 return tvb_captured_length(tvb);
697 /* -----------------------------
698 ATP protocol cf. inside appletalk chap. 9
699 desegmentation from packet-ieee80211.c
702 dissect_atp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) {
703 proto_tree *atp_tree = NULL;
705 proto_tree *atp_info_tree;
706 proto_item *info_item;
709 guint8 frag_number = 0;
713 struct aspinfo aspinfo;
714 tvbuff_t *new_tvb = NULL;
715 gboolean save_fragmented;
716 gboolean more_fragment = FALSE;
721 conversation_t *conversation;
722 asp_request_val *request_val = NULL;
724 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ATP");
726 ctrlinfo = tvb_get_guint8(tvb, offset);
727 bitmap = tvb_get_guint8(tvb, offset +1);
728 tid = tvb_get_ntohs(tvb, offset +2);
738 aspinfo.reply = (0x80 == (ctrlinfo & ATP_FUNCMASK))?1:0;
739 aspinfo.release = (0xC0 == (ctrlinfo & ATP_FUNCMASK))?1:0;
742 query = (!aspinfo.reply && !aspinfo.release);
744 conversation = find_or_create_conversation(pinfo);
746 if (atp_defragment) {
747 asp_request_key request_key;
749 request_key.conversation = conversation->index;
750 memcpy(request_key.src, (!aspinfo.reply)?pinfo->src.data:pinfo->dst.data, 4);
751 request_key.seq = aspinfo.seq;
753 request_val = (asp_request_val *) g_hash_table_lookup(atp_request_hash, &request_key);
755 if (!request_val && query && nbe > 1) {
756 asp_request_key *new_request_key;
758 /* only save nbe packets if more than 1 requested
759 save some memory and help the defragmentation if tid wraparound, ie
760 we have both a request for 1 packet and a request for n packets,
761 hopefully most of the time ATP_EOM will be set in the last packet.
763 new_request_key = wmem_new(wmem_file_scope(), asp_request_key);
764 *new_request_key = request_key;
766 request_val = wmem_new(wmem_file_scope(), asp_request_val);
767 request_val->value = nbe;
769 g_hash_table_insert(atp_request_hash, new_request_key,request_val);
774 ATP_EOM is not mandatory. Some implementations don't always set it
775 if the query is only one packet.
777 So it needs to keep the number of packets asked in request.
781 more_fragment = !(ATP_EOM & ctrlinfo) && request_val;
782 frag_number = bitmap;
785 col_clear(pinfo->cinfo, COL_INFO);
786 col_add_fstr(pinfo->cinfo, COL_INFO, "%s transaction %u",
787 val_to_str(op, atp_function_vals, "Unknown (0x%01x)"),tid);
789 col_append_str(pinfo->cinfo, COL_INFO, " [fragment]");
792 ti = proto_tree_add_item(tree, proto_atp, tvb, offset, -1, ENC_NA);
793 atp_tree = proto_item_add_subtree(ti, ett_atp);
794 proto_item_set_len(atp_tree, aspinfo.release?8:ATP_HDRSIZE -1);
796 info_item = proto_tree_add_item(atp_tree, hf_atp_ctrlinfo, tvb, offset, 1, ENC_BIG_ENDIAN);
797 atp_info_tree = proto_item_add_subtree(info_item, ett_atp_info);
799 proto_tree_add_item(atp_info_tree, hf_atp_function, tvb, offset, 1, ENC_BIG_ENDIAN);
800 proto_tree_add_item(atp_info_tree, hf_atp_xo, tvb, offset, 1, ENC_BIG_ENDIAN);
801 proto_tree_add_item(atp_info_tree, hf_atp_eom, tvb, offset, 1, ENC_BIG_ENDIAN);
802 proto_tree_add_item(atp_info_tree, hf_atp_sts, tvb, offset, 1, ENC_BIG_ENDIAN);
803 if ((ctrlinfo & (ATP_FUNCMASK|ATP_XO)) == (0x40|ATP_XO)) {
804 /* TReq with XO set */
805 proto_tree_add_item(atp_info_tree, hf_atp_treltimer, tvb, offset, 1, ENC_BIG_ENDIAN);
808 proto_tree_add_uint_format_value(atp_tree, hf_atp_bitmap, tvb, offset +1, 1,
809 bitmap, "0x%02x %u packet(s) max", bitmap, nbe);
812 proto_tree_add_item(atp_tree, hf_atp_bitmap, tvb, offset +1, 1, ENC_BIG_ENDIAN);
814 proto_tree_add_item(atp_tree, hf_atp_tid, tvb, offset +2, 2, ENC_BIG_ENDIAN);
817 proto_tree_add_item(atp_tree, hf_atp_user_bytes, tvb, offset +4, 4, ENC_BIG_ENDIAN);
822 return tvb_captured_length(tvb);
824 save_fragmented = pinfo->fragmented;
827 asp doesn't fit very well here
828 move asp back in atp?
830 if (atp_defragment && aspinfo.reply && (more_fragment || frag_number != 0)) {
831 fragment_head *fd_head;
834 hdr = ATP_HDRSIZE -1;
835 if (frag_number != 0)
836 hdr += 4; /* asp header */
837 len = tvb_reported_length_remaining(tvb, hdr);
838 fd_head = fragment_add_seq_check(&atp_reassembly_table,
839 tvb, hdr, pinfo, tid, NULL,
843 new_tvb = process_reassembled_data(tvb, ATP_HDRSIZE -1, pinfo,
844 "Reassembled ATP", fd_head, &atp_frag_items,
849 new_tvb = tvb_new_subset_remaining(tvb, ATP_HDRSIZE -1 );
853 /* if port == 6 it's not an ASP packet but a ZIP packet */
854 if (pinfo->srcport == 6 || pinfo->destport == 6 )
855 call_dissector_with_data(zip_atp_handle, new_tvb, pinfo, tree, &aspinfo);
857 /* XXX need a conversation_get_dissector function ? */
858 if (!aspinfo.reply && !conversation_get_dissector(conversation, pinfo->num)) {
859 dissector_handle_t sub;
861 /* if it's a known ASP function call ASP dissector
862 else assume it's a PAP connection ID.
863 the test is wrong because PAP conn IDs overlapped with ASP fn
864 but I don't want to keep track of NBP msgs and open connection
867 guint8 fn = tvb_get_guint8(new_tvb, 0);
869 if (!fn || fn > ASPFUNC_ATTN) {
875 call_dissector_with_data(sub, new_tvb, pinfo, tree, &aspinfo);
876 conversation_set_dissector(conversation, sub);
878 else if (!try_conversation_dissector(&pinfo->src, &pinfo->dst, pinfo->ptype,
879 pinfo->srcport, pinfo->destport, new_tvb,pinfo, tree, &aspinfo)) {
880 call_data_dissector(new_tvb, pinfo, tree);
886 /* Just show this as a fragment. */
887 new_tvb = tvb_new_subset_remaining (tvb, ATP_HDRSIZE -1);
888 call_data_dissector(new_tvb, pinfo, tree);
890 pinfo->fragmented = save_fragmented;
891 return tvb_captured_length(tvb);
894 /* -----------------------------
895 PAP protocol cf. inside appletalk chap. 10
897 #define PAD(x) { proto_tree_add_item(pap_tree, hf_pap_pad, tvb, offset, x, ENC_NA); offset += x; }
900 dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
905 proto_tree *pap_tree = NULL;
908 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAP");
909 col_clear(pinfo->cinfo, COL_INFO);
912 ti = proto_tree_add_item(tree, proto_pap, tvb, offset, -1, ENC_NA);
913 pap_tree = proto_item_add_subtree(ti, ett_pap);
916 connID = tvb_get_guint8(tvb, offset);
917 proto_tree_add_item(pap_tree, hf_pap_connid, tvb, offset, 1, ENC_BIG_ENDIAN);
920 fn = tvb_get_guint8(tvb, offset);
921 proto_tree_add_item(pap_tree, hf_pap_function, tvb, offset, 1, ENC_BIG_ENDIAN);
924 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ID: %d",
925 val_to_str_ext(fn, &pap_function_vals_ext, "Unknown (0x%01x)"), connID);
930 proto_tree_add_item(pap_tree, hf_pap_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
932 proto_tree_add_item(pap_tree, hf_pap_quantum, tvb, offset, 1, ENC_BIG_ENDIAN);
934 proto_tree_add_item(pap_tree, hf_pap_waittime, tvb, offset, 2, ENC_BIG_ENDIAN);
938 case PAPOpenConnReply:
940 proto_tree_add_item(pap_tree, hf_pap_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
942 proto_tree_add_item(pap_tree, hf_pap_quantum, tvb, offset, 1, ENC_BIG_ENDIAN);
944 proto_tree_add_item(pap_tree, hf_pap_result, tvb, offset, 2, ENC_BIG_ENDIAN);
946 offset = dissect_pascal_string(tvb, offset, pap_tree, hf_pap_status);
950 proto_tree_add_item(pap_tree, hf_pap_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
955 proto_tree_add_item(pap_tree, hf_pap_eof, tvb, offset, 1, ENC_BIG_ENDIAN);
959 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
964 case PAPCloseConnReply:
975 offset = dissect_pascal_string(tvb, offset, pap_tree, hf_pap_status);
978 default: /* unknown */
984 /* -----------------------------
985 ASP protocol cf. inside appletalk chap. 11
987 static struct aspinfo *
988 get_transaction(tvbuff_t *tvb, packet_info *pinfo, struct aspinfo *aspinfo)
990 conversation_t *conversation;
991 asp_request_key request_key, *new_request_key;
992 asp_request_val *request_val;
995 conversation = find_or_create_conversation(pinfo);
997 request_key.conversation = conversation->index;
998 memcpy(request_key.src, (!aspinfo->reply)?pinfo->src.data:pinfo->dst.data, 4);
999 request_key.seq = aspinfo->seq;
1001 request_val = (asp_request_val *) g_hash_table_lookup(asp_request_hash, &request_key);
1002 if (!request_val && !aspinfo->reply ) {
1003 fn = tvb_get_guint8(tvb, 0);
1004 new_request_key = wmem_new(wmem_file_scope(), asp_request_key);
1005 *new_request_key = request_key;
1007 request_val = wmem_new(wmem_file_scope(), asp_request_val);
1008 request_val->value = fn;
1010 g_hash_table_insert(asp_request_hash, new_request_key, request_val);
1016 aspinfo->command = request_val->value;
1022 dissect_asp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1024 struct aspinfo *aspinfo;
1026 proto_tree *asp_tree = NULL;
1030 /* Reject the packet if data is NULL */
1034 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ASP");
1035 col_clear(pinfo->cinfo, COL_INFO);
1037 aspinfo = get_transaction(tvb, pinfo, (struct aspinfo *)data);
1041 fn = (guint8) aspinfo->command;
1044 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1046 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1047 val_to_str_ext(fn, &asp_func_vals_ext, "Unknown (0x%01x)"), aspinfo->seq);
1050 ti = proto_tree_add_item(tree, proto_asp, tvb, offset, -1, ENC_NA);
1051 asp_tree = proto_item_add_subtree(ti, ett_asp);
1053 if (!aspinfo->reply) {
1055 /* let the called deal with asp_tree == NULL */
1057 proto_tree_add_item(asp_tree, hf_asp_func, tvb, offset, 1, ENC_BIG_ENDIAN);
1061 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
1063 proto_tree_add_item(asp_tree, hf_asp_version, tvb, offset, 2, ENC_BIG_ENDIAN);
1066 case ASPFUNC_TICKLE:
1068 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1070 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, ENC_NA);
1074 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, ENC_NA);
1076 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, ENC_NA);
1080 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1082 proto_tree_add_item(asp_tree, hf_asp_attn_code, tvb, offset, 2, ENC_BIG_ENDIAN);
1087 proto_item_set_len(asp_tree, 4);
1088 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1090 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
1092 new_tvb = tvb_new_subset_remaining(tvb, offset);
1093 call_dissector_with_data(afp_handle, new_tvb, pinfo, tree, aspinfo);
1095 case ASPFUNC_WRTCONT:
1096 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1098 proto_tree_add_item(asp_tree, hf_asp_seq, tvb, offset, 2, ENC_BIG_ENDIAN);
1100 proto_tree_add_item(asp_tree, hf_asp_size, tvb, offset, 2, ENC_BIG_ENDIAN);
1104 proto_item_set_len(asp_tree, 4);
1106 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1113 proto_tree_add_uint(asp_tree, hf_asp_func, tvb, 0, 0, fn);
1116 proto_tree_add_item(asp_tree, hf_asp_socket, tvb, offset, 1, ENC_BIG_ENDIAN);
1118 proto_tree_add_item(asp_tree, hf_asp_session_id, tvb, offset, 1, ENC_BIG_ENDIAN);
1120 proto_tree_add_item(asp_tree, hf_asp_init_error, tvb, offset, 2, ENC_BIG_ENDIAN);
1124 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, ENC_NA);
1126 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 1, ENC_NA);
1128 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 2, ENC_NA);
1132 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, ENC_NA);
1134 /* XXX - what if something other than AFP is running atop ASP? */
1135 new_tvb = tvb_new_subset_remaining(tvb, offset);
1136 call_dissector(afp_server_status_handle, new_tvb, pinfo, asp_tree);
1140 proto_item_set_len(asp_tree, 4);
1141 aspinfo->code = tvb_get_ntohl(tvb, offset);
1142 proto_tree_add_item(asp_tree, hf_asp_error, tvb, offset, 4, ENC_BIG_ENDIAN);
1144 new_tvb = tvb_new_subset_remaining(tvb, offset);
1145 call_dissector_with_data(afp_handle, new_tvb, pinfo, tree, aspinfo);
1147 case ASPFUNC_TICKLE:
1148 case ASPFUNC_WRTCONT:
1149 proto_tree_add_item(asp_tree, hf_asp_zero_value, tvb, offset, 4, ENC_NA);
1151 case ASPFUNC_ATTN: /* FIXME capture and spec disagree */
1153 proto_item_set_len(asp_tree, 4);
1155 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1162 /* -----------------------------
1163 ZIP protocol cf. inside appletalk chap. 8
1166 * Structure used to represent a DDP address; gives the layout of the
1167 * data pointed to by an Appletalk "address" structure.
1169 struct atalk_ddp_addr {
1175 static int atalk_str_len(const address* addr _U_)
1180 static int atalk_to_str(const address* addr, gchar *buf, int buf_len _U_)
1182 struct atalk_ddp_addr atalk;
1183 memcpy(&atalk, addr->data, sizeof atalk);
1185 buf = word_to_hex(buf, atalk.net);
1187 buf = bytes_to_hexstr(buf, &atalk.node, 1);
1188 *buf++ = '\0'; /* NULL terminate */
1190 return atalk_str_len(addr);
1193 static const char* atalk_col_filter_str(const address* addr _U_, gboolean is_src)
1201 static int atalk_len(void)
1207 dissect_atp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1209 struct aspinfo *aspinfo;
1211 proto_tree *zip_tree;
1212 proto_tree *sub_tree;
1218 /* Reject the packet if data is NULL */
1222 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1223 col_clear(pinfo->cinfo, COL_INFO);
1225 aspinfo = get_transaction(tvb, pinfo, (struct aspinfo *)data);
1227 return tvb_reported_length(tvb);
1229 fn = (guint8) aspinfo->command;
1232 col_add_fstr(pinfo->cinfo, COL_INFO, "Reply tid %u",aspinfo->seq);
1234 col_add_fstr(pinfo->cinfo, COL_INFO, "Function: %s tid %u",
1235 val_to_str(fn, zip_atp_function_vals, "Unknown (0x%01x)"), aspinfo->seq);
1238 return tvb_reported_length(tvb);
1240 ti = proto_tree_add_item(tree, proto_zip, tvb, offset, -1, ENC_NA);
1241 zip_tree = proto_item_add_subtree(ti, ett_zip);
1243 if (!aspinfo->reply) {
1244 proto_tree_add_item(zip_tree, hf_zip_atp_function, tvb, offset, 1, ENC_BIG_ENDIAN);
1247 case 7: /* start_index = 0 */
1250 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, ENC_NA);
1252 proto_tree_add_item(zip_tree, hf_zip_start_index, tvb, offset, 2, ENC_BIG_ENDIAN);
1259 proto_tree_add_uint(zip_tree, hf_zip_atp_function, tvb, 0, 0, fn);
1264 proto_tree_add_item(zip_tree, hf_zip_last_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1267 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, ENC_NA);
1269 count = tvb_get_ntohs(tvb, offset);
1270 ti = proto_tree_add_item(zip_tree, hf_zip_count, tvb, offset, 2, ENC_BIG_ENDIAN);
1272 sub_tree = proto_item_add_subtree(ti, ett_zip_zones_list);
1273 for (i = 0; i < count; i++) {
1274 len = tvb_get_guint8(tvb, offset);
1275 proto_tree_add_item(sub_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_BIG_ENDIAN);
1282 return tvb_reported_length(tvb);
1286 dissect_ddp_zip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1288 proto_tree *zip_tree = NULL;
1293 proto_tree *sub_tree;
1294 proto_tree *net_tree;
1300 static const int * zip_flags[] = {
1301 &hf_zip_flags_zone_invalid,
1302 &hf_zip_flags_use_broadcast,
1303 &hf_zip_flags_only_one_zone,
1307 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZIP");
1308 col_clear(pinfo->cinfo, COL_INFO);
1310 fn = tvb_get_guint8(tvb, 0);
1311 col_add_str(pinfo->cinfo, COL_INFO,
1312 val_to_str_ext(fn, &zip_function_vals_ext, "Unknown ZIP function (%02x)"));
1315 return tvb_captured_length(tvb);
1317 ti = proto_tree_add_item(tree, proto_zip, tvb, 0, -1, ENC_NA);
1318 zip_tree = proto_item_add_subtree(ti, ett_zip);
1320 proto_tree_add_item(zip_tree, hf_zip_function, tvb, offset, 1,ENC_BIG_ENDIAN);
1322 /* fn 1,7,2,8 are not tested */
1325 count = tvb_get_guint8(tvb, offset);
1326 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1328 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1329 for (i = 0; i < count; i++) {
1330 proto_tree_add_item(sub_tree, hf_zip_network, tvb, offset, 2, ENC_BIG_ENDIAN);
1334 case 7: /* Notify */
1335 proto_tree_add_bitmask(zip_tree, tvb, offset, hf_zip_flags, ett_zip_flags, zip_flags, ENC_NA);
1338 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, ENC_NA);
1341 len = tvb_get_guint8(tvb, offset);
1342 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_BIG_ENDIAN);
1345 len = tvb_get_guint8(tvb, offset);
1346 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,ENC_BIG_ENDIAN);
1348 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,ENC_NA);
1351 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_BIG_ENDIAN);
1355 case 8: /* Extended Reply */
1356 count = tvb_get_guint8(tvb, offset);
1357 ti = proto_tree_add_item(zip_tree, hf_zip_network_count, tvb, offset, 1, ENC_BIG_ENDIAN);
1359 sub_tree = proto_item_add_subtree(ti, ett_zip_network_list);
1360 for (i = 0; i < count; i++) {
1361 net = tvb_get_ntohs(tvb, offset);
1362 net_tree = proto_tree_add_subtree_format(sub_tree, tvb, offset, 2, ett_zip_network_list, &ti, "Zone for network: %u", net);
1363 proto_tree_add_item(net_tree, hf_zip_network, tvb, offset, 2, ENC_BIG_ENDIAN);
1365 len = tvb_get_guint8(tvb, offset);
1366 proto_tree_add_item(net_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_BIG_ENDIAN);
1368 proto_item_set_len(ti, len+3);
1372 case 5 : /* GetNetInfo request */
1373 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 1, ENC_NA);
1375 proto_tree_add_item(zip_tree, hf_zip_zero_value, tvb, offset, 4, ENC_NA);
1377 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_BIG_ENDIAN);
1380 case 6 : /* GetNetInfo reply */
1381 flag = tvb_get_guint8(tvb, offset);
1382 proto_tree_add_bitmask(zip_tree, tvb, offset, hf_zip_flags, ett_zip_flags, zip_flags, ENC_NA);
1385 proto_tree_add_item(zip_tree, hf_zip_network_start, tvb, offset, 2, ENC_BIG_ENDIAN);
1388 proto_tree_add_item(zip_tree, hf_zip_network_end, tvb, offset, 2, ENC_BIG_ENDIAN);
1391 len = tvb_get_guint8(tvb, offset);
1392 proto_tree_add_item(zip_tree, hf_zip_zone_name, tvb, offset, 1,ENC_ASCII|ENC_BIG_ENDIAN);
1395 len = tvb_get_guint8(tvb, offset);
1396 proto_tree_add_item(zip_tree, hf_zip_multicast_length,tvb, offset, 1,ENC_BIG_ENDIAN);
1398 proto_tree_add_item(zip_tree, hf_zip_multicast_address,tvb, offset, len,ENC_NA);
1400 if ((flag & 0x80) != 0)
1401 proto_tree_add_item(zip_tree, hf_zip_default_zone, tvb, offset, 1,ENC_ASCII|ENC_BIG_ENDIAN);
1407 return tvb_captured_length(tvb);
1410 typedef struct ddp_nodes
1418 dissect_ddp_short(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1424 proto_tree *ddp_tree = NULL;
1425 proto_item *ti, *hidden_item;
1426 struct atalk_ddp_addr *src = wmem_new0(pinfo->pool, struct atalk_ddp_addr),
1427 *dst = wmem_new0(pinfo->pool, struct atalk_ddp_addr);
1429 ddp_nodes_t *ddp_node = (ddp_nodes_t*)data;
1431 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1432 col_clear(pinfo->cinfo, COL_INFO);
1435 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_SHORT_HEADER_SIZE,
1437 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1439 len = tvb_get_ntohs(tvb, 0);
1441 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2, len);
1442 dport = tvb_get_guint8(tvb, 2);
1444 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 2, 1, dport);
1445 sport = tvb_get_guint8(tvb, 3);
1447 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 3, 1, sport);
1448 type = tvb_get_guint8(tvb, 4);
1451 src->node = ddp_node->snode;
1453 dst->node = ddp_node->dnode;
1454 set_address(&pinfo->net_src, atalk_address_type, sizeof(struct atalk_ddp_addr), src);
1455 copy_address_shallow(&pinfo->src, &pinfo->net_src);
1456 set_address(&pinfo->net_dst, atalk_address_type, sizeof(struct atalk_ddp_addr), dst);
1457 copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
1459 pinfo->ptype = PT_DDP;
1460 pinfo->destport = dport;
1461 pinfo->srcport = sport;
1463 col_add_str(pinfo->cinfo, COL_INFO,
1464 val_to_str_ext(type, &op_vals_ext, "Unknown DDP protocol (%02x)"));
1467 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_src, tvb,
1468 4, 3, address_to_str(wmem_packet_scope(), &pinfo->src));
1469 PROTO_ITEM_SET_HIDDEN(hidden_item);
1470 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_dst, tvb,
1471 6, 3, address_to_str(wmem_packet_scope(), &pinfo->dst));
1472 PROTO_ITEM_SET_HIDDEN(hidden_item);
1474 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 4, 1, type);
1476 new_tvb = tvb_new_subset_remaining(tvb, DDP_SHORT_HEADER_SIZE);
1478 if (!dissector_try_uint(ddp_dissector_table, type, new_tvb, pinfo, tree))
1479 call_data_dissector(new_tvb, pinfo, tree);
1481 return tvb_captured_length(tvb);
1485 dissect_ddp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1488 proto_tree *ddp_tree;
1489 proto_item *ti, *hidden_item;
1490 struct atalk_ddp_addr *src = wmem_new0(pinfo->pool, struct atalk_ddp_addr),
1491 *dst = wmem_new0(pinfo->pool, struct atalk_ddp_addr);
1494 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DDP");
1495 col_clear(pinfo->cinfo, COL_INFO);
1497 tvb_memcpy(tvb, (guint8 *)&ddp, 0, sizeof(e_ddp));
1498 ddp.dnet=g_ntohs(ddp.dnet);
1499 ddp.snet=g_ntohs(ddp.snet);
1500 ddp.sum=g_ntohs(ddp.sum);
1501 ddp.hops_len=g_ntohs(ddp.hops_len);
1503 src->net = ddp.snet;
1504 src->node = ddp.snode;
1505 dst->net = ddp.dnet;
1506 dst->node = ddp.dnode;
1507 set_address(&pinfo->net_src, atalk_address_type, sizeof(struct atalk_ddp_addr), src);
1508 copy_address_shallow(&pinfo->src, &pinfo->net_src);
1509 set_address(&pinfo->net_dst, atalk_address_type, sizeof(struct atalk_ddp_addr), dst);
1510 copy_address_shallow(&pinfo->dst, &pinfo->net_dst);
1512 pinfo->ptype = PT_DDP;
1513 pinfo->destport = ddp.dport;
1514 pinfo->srcport = ddp.sport;
1516 col_add_str(pinfo->cinfo, COL_INFO,
1517 val_to_str_ext(ddp.type, &op_vals_ext, "Unknown DDP protocol (%02x)"));
1520 ti = proto_tree_add_item(tree, proto_ddp, tvb, 0, DDP_HEADER_SIZE,
1522 ddp_tree = proto_item_add_subtree(ti, ett_ddp);
1524 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_src, tvb,
1525 4, 3, address_to_str(wmem_packet_scope(), &pinfo->src));
1526 PROTO_ITEM_SET_HIDDEN(hidden_item);
1528 hidden_item = proto_tree_add_string(ddp_tree, hf_ddp_dst, tvb,
1529 6, 3, address_to_str(wmem_packet_scope(), &pinfo->dst));
1530 PROTO_ITEM_SET_HIDDEN(hidden_item);
1532 proto_tree_add_uint(ddp_tree, hf_ddp_hopcount, tvb, 0, 1,
1533 ddp_hops(ddp.hops_len));
1534 proto_tree_add_uint(ddp_tree, hf_ddp_len, tvb, 0, 2,
1535 ddp_len(ddp.hops_len));
1536 proto_tree_add_uint(ddp_tree, hf_ddp_checksum, tvb, 2, 2,
1538 proto_tree_add_uint(ddp_tree, hf_ddp_dst_net, tvb, 4, 2,
1540 proto_tree_add_uint(ddp_tree, hf_ddp_src_net, tvb, 6, 2,
1542 proto_tree_add_uint(ddp_tree, hf_ddp_dst_node, tvb, 8, 1,
1544 proto_tree_add_uint(ddp_tree, hf_ddp_src_node, tvb, 9, 1,
1546 proto_tree_add_uint(ddp_tree, hf_ddp_dst_socket, tvb, 10, 1,
1548 proto_tree_add_uint(ddp_tree, hf_ddp_src_socket, tvb, 11, 1,
1550 proto_tree_add_uint(ddp_tree, hf_ddp_type, tvb, 12, 1,
1554 new_tvb = tvb_new_subset_remaining(tvb, DDP_HEADER_SIZE);
1556 if (!dissector_try_uint(ddp_dissector_table, ddp.type, new_tvb, pinfo, tree))
1558 call_data_dissector(new_tvb, pinfo, tree);
1560 return tvb_captured_length(tvb);
1563 static const value_string llap_type_vals[] = {
1564 {0x01, "Short DDP"},
1567 {0x82, "Acknowledgement"},
1572 static value_string_ext llap_type_vals_ext = VALUE_STRING_EXT_INIT(llap_type_vals);
1575 capture_llap(const guchar *pd _U_, int offset _U_, int len _U_, capture_packet_info_t *cpinfo _U_, const union wtap_pseudo_header *pseudo_header _U_)
1577 /* XXX - get its own counter
1583 dissect_llap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1585 ddp_nodes_t ddp_node;
1587 proto_tree *llap_tree;
1591 col_set_str(pinfo->cinfo, COL_PROTOCOL, "LLAP");
1592 col_clear(pinfo->cinfo, COL_INFO);
1594 ti = proto_tree_add_item(tree, proto_llap, tvb, 0, 3, ENC_NA);
1595 llap_tree = proto_item_add_subtree(ti, ett_llap);
1597 ddp_node.dnode = tvb_get_guint8(tvb, 0);
1598 proto_tree_add_uint(llap_tree, hf_llap_dst, tvb, 0, 1, ddp_node.dnode);
1600 ddp_node.snode = tvb_get_guint8(tvb, 1);
1601 proto_tree_add_uint(llap_tree, hf_llap_src, tvb, 1, 1, ddp_node.snode);
1603 type = tvb_get_guint8(tvb, 2);
1604 col_add_str(pinfo->cinfo, COL_INFO,
1605 val_to_str_ext(type, &llap_type_vals_ext, "Unknown LLAP type (%02x)"));
1606 proto_tree_add_uint(llap_tree, hf_llap_type, tvb, 2, 1, type);
1608 new_tvb = tvb_new_subset_remaining(tvb, 3);
1612 if (call_dissector_with_data(ddp_short_handle, new_tvb, pinfo, tree, &ddp_node))
1613 return tvb_captured_length(tvb);
1616 if (call_dissector(ddp_handle, new_tvb, pinfo, tree))
1617 return tvb_captured_length(tvb);
1620 call_data_dissector(new_tvb, pinfo, tree);
1621 return tvb_captured_length(tvb);
1627 reassembly_table_init(&atp_reassembly_table,
1628 &addresses_reassembly_table_functions);
1629 atp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1635 reassembly_table_destroy(&atp_reassembly_table);
1636 g_hash_table_destroy(atp_request_hash);
1643 if (asp_request_hash)
1644 g_hash_table_destroy(asp_request_hash);
1646 asp_request_hash = g_hash_table_new(asp_hash, asp_equal);
1651 proto_register_atalk(void)
1653 static hf_register_info hf_llap[] = {
1655 { "Destination Node", "llap.dst", FT_UINT8, BASE_DEC, NULL, 0x0,
1659 { "Source Node", "llap.src", FT_UINT8, BASE_DEC, NULL, 0x0,
1663 { "Type", "llap.type", FT_UINT8, BASE_HEX|BASE_EXT_STRING, &llap_type_vals_ext, 0x0,
1667 static hf_register_info hf_ddp[] = {
1669 { "Hop count", "ddp.hopcount", FT_UINT8, BASE_DEC, NULL, 0x0,
1673 { "Datagram length", "ddp.len", FT_UINT16, BASE_DEC, NULL, 0x0,
1677 { "Checksum", "ddp.checksum", FT_UINT16, BASE_DEC, NULL, 0x0,
1681 { "Destination address", "ddp.dst", FT_STRING, BASE_NONE, NULL, 0x0,
1685 { "Destination Net", "ddp.dst.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1689 { "Source address", "ddp.src", FT_STRING, BASE_NONE, NULL, 0x0,
1693 { "Source Net", "ddp.src.net", FT_UINT16, BASE_DEC, NULL, 0x0,
1697 { "Destination Node", "ddp.dst.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1701 { "Source Node", "ddp.src.node", FT_UINT8, BASE_DEC, NULL, 0x0,
1704 { &hf_ddp_dst_socket,
1705 { "Destination Socket", "ddp.dst_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1708 { &hf_ddp_src_socket,
1709 { "Source Socket", "ddp.src_socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1713 { "Protocol type", "ddp.type", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &op_vals_ext, 0x0,
1717 static hf_register_info hf_nbp[] = {
1719 { "Operation", "nbp.op", FT_UINT8, BASE_DEC,
1720 VALS(nbp_op_vals), 0xF0, NULL, HFILL }},
1722 { "Info", "nbp.info", FT_UINT8, BASE_HEX,
1723 NULL, 0x0, NULL, HFILL }},
1725 { "Count", "nbp.count", FT_UINT8, BASE_DEC,
1726 NULL, 0x0F, NULL, HFILL }},
1728 { "Network", "nbp.net", FT_UINT16, BASE_DEC,
1729 NULL, 0x0, NULL, HFILL }},
1730 { &hf_nbp_node_node,
1731 { "Node", "nbp.node", FT_UINT8, BASE_DEC,
1732 NULL, 0x0, NULL, HFILL }},
1733 { &hf_nbp_node_port,
1734 { "Port", "nbp.port", FT_UINT8, BASE_DEC,
1735 NULL, 0x0, NULL, HFILL }},
1736 { &hf_nbp_node_enum,
1737 { "Enumerator", "nbp.enum", FT_UINT8, BASE_DEC,
1738 NULL, 0x0, NULL, HFILL }},
1739 { &hf_nbp_node_object,
1740 { "Object", "nbp.object", FT_UINT_STRING, BASE_NONE,
1741 NULL, 0x0, NULL, HFILL }},
1742 { &hf_nbp_node_type,
1743 { "Type", "nbp.type", FT_UINT_STRING, BASE_NONE,
1744 NULL, 0x0, NULL, HFILL }},
1745 { &hf_nbp_node_zone,
1746 { "Zone", "nbp.zone", FT_UINT_STRING, BASE_NONE,
1747 NULL, 0x0, NULL, HFILL }},
1749 { "Transaction ID", "nbp.tid", FT_UINT8, BASE_DEC,
1750 NULL, 0x0, NULL, HFILL }}
1753 static hf_register_info hf_rtmp[] = {
1755 { "Net", "rtmp.net", FT_UINT16, BASE_DEC,
1756 NULL, 0x0, NULL, HFILL }},
1758 { "Node", "nbp.nodeid", FT_UINT8, BASE_DEC,
1759 NULL, 0x0, NULL, HFILL }},
1760 { &hf_rtmp_node_len,
1761 { "Node Length", "nbp.nodeid.length", FT_UINT8, BASE_DEC,
1762 NULL, 0x0, NULL, HFILL }},
1763 { &hf_rtmp_tuple_net,
1764 { "Net", "rtmp.tuple.net", FT_UINT16, BASE_DEC,
1765 NULL, 0x0, NULL, HFILL }},
1766 { &hf_rtmp_tuple_range_start,
1767 { "Range Start", "rtmp.tuple.range_start", FT_UINT16, BASE_DEC,
1768 NULL, 0x0, NULL, HFILL }},
1769 { &hf_rtmp_tuple_range_end,
1770 { "Range End", "rtmp.tuple.range_end", FT_UINT16, BASE_DEC,
1771 NULL, 0x0, NULL, HFILL }},
1772 { &hf_rtmp_tuple_dist,
1773 { "Distance", "rtmp.tuple.dist", FT_UINT16, BASE_DEC,
1774 NULL, 0x0, NULL, HFILL }},
1775 { &hf_rtmp_function,
1776 { "Function", "rtmp.function", FT_UINT8, BASE_DEC,
1777 VALS(rtmp_function_vals), 0x0, "Request Function", HFILL }}
1780 static hf_register_info hf_atp[] = {
1782 { "Control info", "atp.ctrlinfo", FT_UINT8, BASE_HEX,
1783 NULL, 0, NULL, HFILL }},
1786 { "Function", "atp.function", FT_UINT8, BASE_DEC,
1787 VALS(atp_function_vals), ATP_FUNCMASK, "function code", HFILL }},
1791 { "XO", "atp.xo", FT_BOOLEAN, 8,
1792 NULL, ATP_XO, "Exactly-once flag", HFILL }},
1795 { "EOM", "atp.eom", FT_BOOLEAN, 8,
1796 NULL, ATP_EOM, "End-of-message", HFILL }},
1799 { "STS", "atp.sts", FT_BOOLEAN, 8,
1800 NULL, ATP_STS, "Send transaction status", HFILL }},
1802 { &hf_atp_treltimer,
1803 { "TRel timer", "atp.treltimer", FT_UINT8, BASE_DEC,
1804 VALS(atp_trel_timer_vals), 0x07, NULL, HFILL }},
1807 { "Bitmap", "atp.bitmap", FT_UINT8, BASE_HEX,
1808 NULL, 0x0, "Bitmap or sequence number", HFILL }},
1811 { "TID", "atp.tid", FT_UINT16, BASE_DEC,
1812 NULL, 0x0, "Transaction id", HFILL }},
1813 { &hf_atp_user_bytes,
1814 { "User bytes", "atp.user_bytes", FT_UINT32, BASE_HEX,
1815 NULL, 0x0, NULL, HFILL }},
1817 { &hf_atp_segment_overlap,
1818 { "Segment overlap", "atp.segment.overlap", FT_BOOLEAN, BASE_NONE,
1819 NULL, 0x0, "Segment overlaps with other segments", HFILL }},
1821 { &hf_atp_segment_overlap_conflict,
1822 { "Conflicting data in segment overlap", "atp.segment.overlap.conflict",
1823 FT_BOOLEAN, BASE_NONE,
1824 NULL, 0x0, "Overlapping segments contained conflicting data", HFILL }},
1826 { &hf_atp_segment_multiple_tails,
1827 { "Multiple tail segments found", "atp.segment.multipletails",
1828 FT_BOOLEAN, BASE_NONE,
1829 NULL, 0x0, "Several tails were found when desegmenting the packet", HFILL }},
1831 { &hf_atp_segment_too_long_segment,
1832 { "Segment too long", "atp.segment.toolongsegment", FT_BOOLEAN, BASE_NONE,
1833 NULL, 0x0, "Segment contained data past end of packet", HFILL }},
1835 { &hf_atp_segment_error,
1836 {"Desegmentation error", "atp.segment.error", FT_FRAMENUM, BASE_NONE,
1837 NULL, 0x0, "Desegmentation error due to illegal segments", HFILL }},
1839 { &hf_atp_segment_count,
1840 { "Segment count", "atp.segment.count", FT_UINT32, BASE_DEC, NULL, 0x0,
1844 { "ATP Fragment", "atp.fragment", FT_FRAMENUM, BASE_NONE,
1845 NULL, 0x0, NULL, HFILL }},
1848 { "ATP Fragments", "atp.fragments", FT_NONE, BASE_NONE,
1849 NULL, 0x0, NULL, HFILL }},
1851 { &hf_atp_reassembled_in,
1852 { "Reassembled ATP in frame", "atp.reassembled_in", FT_FRAMENUM, BASE_NONE, NULL, 0x0,
1853 "This ATP packet is reassembled in this frame", HFILL }},
1855 { &hf_atp_reassembled_length,
1856 { "Reassembled ATP length", "atp.reassembled.length", FT_UINT32, BASE_DEC, NULL, 0x0,
1857 "The total length of the reassembled payload", HFILL }}
1860 static hf_register_info hf_asp[] = {
1862 { "asp function", "asp.function", FT_UINT8, BASE_DEC|BASE_EXT_STRING,
1863 &asp_func_vals_ext, 0, NULL, HFILL }},
1866 { "asp error", "asp.error", FT_INT32, BASE_DEC|BASE_EXT_STRING,
1867 &asp_error_vals_ext, 0, "return error code", HFILL }},
1870 { "Version", "asp.version", FT_UINT16, BASE_HEX,
1871 NULL, 0, "asp version", HFILL }},
1873 { &hf_asp_attn_code,
1874 { "Attn code", "asp.attn_code", FT_UINT16, BASE_HEX,
1875 NULL, 0, "asp attention code", HFILL }},
1877 { &hf_asp_init_error,
1878 { "Error", "asp.init_error", FT_UINT16, BASE_DEC,
1879 NULL, 0, "asp init error", HFILL }},
1881 { &hf_asp_session_id,
1882 { "Session ID", "asp.session_id", FT_UINT8, BASE_DEC,
1883 NULL, 0, "asp session id", HFILL }},
1886 { "Socket", "asp.socket", FT_UINT8, BASE_DEC,
1887 NULL, 0, "asp socket", HFILL }},
1890 { "Sequence", "asp.seq", FT_UINT16, BASE_DEC,
1891 NULL, 0, "asp sequence number", HFILL }},
1894 { "size", "asp.size", FT_UINT16, BASE_DEC,
1895 NULL, 0, "asp available size for reply", HFILL }},
1897 { &hf_asp_zero_value,
1898 { "Pad (0)", "asp.zero_value",
1899 FT_BYTES, BASE_NONE, NULL, 0x0,
1903 static hf_register_info hf_zip[] = {
1905 { "Function", "zip.function", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &zip_function_vals_ext, 0x0,
1906 "ZIP function", HFILL }},
1908 { &hf_zip_zero_value,
1909 { "Pad (0)", "zip.zero_value",FT_BYTES, BASE_NONE, NULL, 0x0,
1912 { &hf_zip_atp_function,
1913 { "Function", "zip.atp_function", FT_UINT8, BASE_DEC, VALS(zip_atp_function_vals), 0x0,
1916 { &hf_zip_start_index,
1917 { "Start index", "zip.start_index", FT_UINT16, BASE_DEC, NULL, 0x0,
1921 { "Count", "zip.count", FT_UINT16, BASE_DEC, NULL, 0x0,
1924 { &hf_zip_network_count,
1925 { "Count", "zip.network_count", FT_UINT8, BASE_DEC, NULL, 0x0,
1928 { "Network","zip.network", FT_UINT16, BASE_DEC, NULL, 0x0,
1930 { &hf_zip_network_start,
1931 { "Network start","zip.network_start", FT_UINT16, BASE_DEC, NULL, 0x0,
1933 { &hf_zip_network_end,
1934 { "Network end", "zip.network_end", FT_UINT16, BASE_DEC, NULL, 0x0,
1938 { "Flags", "zip.flags", FT_UINT8, BASE_HEX, NULL, 0xC0,
1940 { &hf_zip_last_flag,
1941 { "Last Flag", "zip.last_flag", FT_BOOLEAN, BASE_NONE, NULL, 0x0,
1942 "Non zero if contains last zone name in the zone list", HFILL }},
1944 { &hf_zip_flags_zone_invalid,
1945 { "Zone invalid", "zip.flags.zone_invalid", FT_BOOLEAN, 8, NULL, 0x80,
1948 { &hf_zip_flags_use_broadcast,
1949 { "Use broadcast","zip.flags.use_broadcast", FT_BOOLEAN, 8, NULL, 0x40,
1952 { &hf_zip_flags_only_one_zone,
1953 { "Only one zone","zip.flags.only_one_zone", FT_BOOLEAN, 8, NULL, 0x20,
1956 { &hf_zip_zone_name,
1957 { "Zone", "zip.zone_name", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1960 { &hf_zip_default_zone,
1961 { "Default zone", "zip.default_zone",FT_UINT_STRING, BASE_NONE, NULL, 0x0,
1964 { &hf_zip_multicast_length,
1965 { "Multicast length", "zip.multicast_length", FT_UINT8, BASE_DEC, NULL, 0x0,
1966 "Multicast address length", HFILL }},
1968 { &hf_zip_multicast_address,
1969 { "Multicast address", "zip.multicast_address",FT_BYTES, BASE_NONE, NULL, 0x0,
1974 static hf_register_info hf_pap[] = {
1976 { "ConnID", "prap.connid", FT_UINT8, BASE_DEC, NULL, 0x0,
1977 "PAP connection ID", HFILL }},
1980 { "Function", "prap.function", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &pap_function_vals_ext, 0x0,
1981 "PAP function", HFILL }},
1984 { "Socket", "prap.socket", FT_UINT8, BASE_DEC, NULL, 0x0,
1985 "ATP responding socket number", HFILL }},
1988 { "Quantum", "prap.quantum", FT_UINT8, BASE_DEC, NULL, 0x0,
1989 "Flow quantum", HFILL }},
1992 { "Wait time", "prap.waittime", FT_UINT16, BASE_DEC, NULL, 0x0,
1996 { "Result", "prap.result", FT_UINT16, BASE_DEC, NULL, 0x0,
2000 { "Sequence", "prap.seq", FT_UINT16, BASE_DEC, NULL, 0x0,
2001 "Sequence number", HFILL }},
2004 { "Status", "prap.status", FT_UINT_STRING, BASE_NONE, NULL, 0x0,
2005 "Printer status", HFILL }},
2008 { "EOF", "prap.eof", FT_BOOLEAN, BASE_NONE,
2009 NULL, 0x0, NULL, HFILL }},
2012 { "Pad", "prap.pad", FT_NONE, BASE_NONE, NULL, 0,
2013 "Pad Byte", HFILL }},
2017 static gint *ett[] = {
2036 &ett_zip_zones_list,
2037 &ett_zip_network_list,
2039 module_t *atp_module;
2041 proto_llap = proto_register_protocol("LocalTalk Link Access Protocol", "LLAP", "llap");
2042 proto_register_field_array(proto_llap, hf_llap, array_length(hf_llap));
2044 proto_ddp = proto_register_protocol("Datagram Delivery Protocol", "DDP", "ddp");
2045 proto_register_field_array(proto_ddp, hf_ddp, array_length(hf_ddp));
2047 proto_nbp = proto_register_protocol("Name Binding Protocol", "NBP", "nbp");
2048 proto_register_field_array(proto_nbp, hf_nbp, array_length(hf_nbp));
2050 proto_atp = proto_register_protocol("AppleTalk Transaction Protocol packet", "ATP", "atp");
2051 proto_register_field_array(proto_atp, hf_atp, array_length(hf_atp));
2053 proto_asp = proto_register_protocol("AppleTalk Session Protocol", "ASP", "asp");
2054 proto_register_field_array(proto_asp, hf_asp, array_length(hf_asp));
2056 proto_pap = proto_register_protocol("Printer Access Protocol", "PrAP", "prap");
2057 proto_register_field_array(proto_pap, hf_pap, array_length(hf_pap));
2059 proto_zip = proto_register_protocol("Zone Information Protocol", "ZIP", "zip");
2060 proto_register_field_array(proto_zip, hf_zip, array_length(hf_zip));
2062 atp_module = prefs_register_protocol(proto_atp, NULL);
2063 prefs_register_bool_preference(atp_module, "desegment",
2064 "Reassemble ATP messages spanning multiple DDP packets",
2065 "Whether the ATP dissector should reassemble messages spanning multiple DDP packets",
2068 proto_rtmp = proto_register_protocol("Routing Table Maintenance Protocol",
2070 proto_register_field_array(proto_rtmp, hf_rtmp, array_length(hf_rtmp));
2072 proto_register_subtree_array(ett, array_length(ett));
2074 /* subdissector code */
2075 ddp_dissector_table = register_dissector_table("ddp.type", "DDP packet type", proto_ddp,
2076 FT_UINT8, BASE_HEX, DISSECTOR_TABLE_ALLOW_DUPLICATE);
2078 atalk_address_type = address_type_dissector_register("AT_ATALK", "Appletalk DDP", atalk_to_str, atalk_str_len, NULL, atalk_col_filter_str, atalk_len, NULL, NULL);
2082 proto_reg_handoff_atalk(void)
2084 dissector_handle_t nbp_handle, rtmp_request_handle;
2085 dissector_handle_t atp_handle;
2086 dissector_handle_t zip_ddp_handle;
2087 dissector_handle_t rtmp_data_handle, llap_handle;
2089 ddp_short_handle = create_dissector_handle(dissect_ddp_short, proto_ddp);
2090 ddp_handle = create_dissector_handle(dissect_ddp, proto_ddp);
2091 dissector_add_uint("ethertype", ETHERTYPE_ATALK, ddp_handle);
2092 dissector_add_uint("chdlc.protocol", ETHERTYPE_ATALK, ddp_handle);
2093 dissector_add_uint("ppp.protocol", PPP_AT, ddp_handle);
2094 dissector_add_uint("null.type", BSD_AF_APPLETALK, ddp_handle);
2095 dissector_add_uint("arcnet.protocol_id", ARCNET_PROTO_APPLETALK, ddp_handle);
2097 nbp_handle = create_dissector_handle(dissect_nbp, proto_nbp);
2098 dissector_add_uint("ddp.type", DDP_NBP, nbp_handle);
2099 dissector_add_for_decode_as("udp.port", nbp_handle);
2101 atp_handle = create_dissector_handle(dissect_atp, proto_atp);
2102 dissector_add_uint("ddp.type", DDP_ATP, atp_handle);
2104 asp_handle = create_dissector_handle(dissect_asp, proto_asp);
2105 pap_handle = create_dissector_handle(dissect_pap, proto_pap);
2107 rtmp_request_handle = create_dissector_handle(dissect_rtmp_request, proto_rtmp);
2108 rtmp_data_handle = create_dissector_handle(dissect_rtmp_data, proto_rtmp);
2109 dissector_add_uint("ddp.type", DDP_RTMPREQ, rtmp_request_handle);
2110 dissector_add_uint("ddp.type", DDP_RTMPDATA, rtmp_data_handle);
2112 zip_ddp_handle = create_dissector_handle(dissect_ddp_zip, proto_zip);
2113 dissector_add_uint("ddp.type", DDP_ZIP, zip_ddp_handle);
2115 zip_atp_handle = create_dissector_handle(dissect_atp_zip, proto_zip);
2117 llap_handle = create_dissector_handle(dissect_llap, proto_llap);
2118 dissector_add_uint("wtap_encap", WTAP_ENCAP_LOCALTALK, llap_handle);
2119 register_capture_dissector("wtap_encap", WTAP_ENCAP_LOCALTALK, capture_llap, proto_llap);
2121 register_init_routine( atp_init);
2122 register_cleanup_routine( atp_cleanup);
2123 register_init_routine( &asp_reinit);
2125 afp_handle = find_dissector_add_dependency("afp", proto_asp);
2126 afp_server_status_handle = find_dissector_add_dependency("afp_server_status", proto_asp);
2130 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2135 * indent-tabs-mode: nil
2138 * vi: set shiftwidth=2 tabstop=8 expandtab:
2139 * :indentSize=4:tabSize=8:noTabs=true: