2 * Routines for Digital Audio Access Protocol dissection
3 * Copyright 2004, Kelly Byrd <kbyrd@memcpy.com>
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
32 #include <epan/packet.h>
33 #include <epan/dissectors/packet-http.h>
35 #define TCP_PORT_DAAP 3689
39 #define daap_mcon 0x6d636f6e
40 #define daap_msrv 0x6d737276
41 #define daap_mccr 0x6d636372
42 #define daap_mdcl 0x6d64636c
43 #define daap_mlog 0x6d6c6f67
44 #define daap_mupd 0x6d757064
45 #define daap_avdb 0x61766462
46 #define daap_mlcl 0x6d6c636c
47 #define daap_mlit 0x6d6c6974
48 #define daap_mbcl 0x6d62636c
49 #define daap_adbs 0x61646273
50 #define daap_aply 0x61706c79
51 #define daap_apso 0x6170736f
52 #define daap_mudl 0x6d75646c
53 #define daap_abro 0x6162726f
54 #define daap_abal 0x6162616c
55 #define daap_abcp 0x61626370
56 #define daap_abgn 0x6162676e
57 #define daap_prsv 0x70727376
58 #define daap_arif 0x61726966
60 #define daap_minm 0x6d696e6d
61 #define daap_msts 0x6d737473
62 #define daap_mcnm 0x6d636e6d
63 #define daap_mcna 0x6d636e61
64 #define daap_asal 0x6173616c
65 #define daap_asar 0x61736172
66 #define daap_ascm 0x6173636d
67 #define daap_asfm 0x6173666d
68 #define daap_aseq 0x61736571
69 #define daap_asgn 0x6173676e
70 #define daap_asdt 0x61736474
71 #define daap_asul 0x6173756c
73 #define daap_mper 0x6d706572
75 #define daap_mstt 0x6d737474
76 #define daap_musr 0x6d757372
77 #define daap_miid 0x6d696964
78 #define daap_mcti 0x6d637469
79 #define daap_mpco 0x6d70636f
80 #define daap_mimc 0x6d696d63
81 #define daap_mrco 0x6d72636f
82 #define daap_mtco 0x6d74636f
83 #define daap_mstm 0x6d73746d
84 #define daap_msdc 0x6d736463
85 #define daap_mlid 0x6d6c6964
86 #define daap_msur 0x6d737572
87 #define daap_asda 0x61736461
88 #define daap_asdm 0x6173646d
89 #define daap_assr 0x61737372
90 #define daap_assz 0x6173737a
91 #define daap_asst 0x61737374
92 #define daap_assp 0x61737370
93 #define daap_astm 0x6173746d
94 #define daap_aeNV 0x61654e56
96 #define daap_mcty 0x6d637479
97 #define daap_asbt 0x61736274
98 #define daap_asbr 0x61736272
99 #define daap_asdc 0x61736463
100 #define daap_asdn 0x6173646e
101 #define daap_astc 0x61737463
102 #define daap_astn 0x6173746e
103 #define daap_asyr 0x61737972
105 #define daap_mikd 0x6d696b64
106 #define daap_msau 0x6d736175
107 #define daap_msty 0x6d737479
108 #define daap_asrv 0x61737276
109 #define daap_asur 0x61737572
110 #define daap_asdk 0x6173646b
112 #define daap_mslr 0x6d736c72
113 #define daap_msal 0x6d73616c
114 #define daap_msup 0x6d737570
115 #define daap_mspi 0x6d737069
116 #define daap_msex 0x6d736578
117 #define daap_msbr 0x6d736272
118 #define daap_msqy 0x6d737179
119 #define daap_msix 0x6d736978
120 #define daap_msrs 0x6d737273
121 #define daap_asco 0x6173636f
122 #define daap_asdb 0x61736462
123 #define daap_abpl 0x6162706c
124 #define daap_aeSP 0x61655350
125 /* version (32-bit)*/
126 #define daap_mpro 0x6d70726f
127 #define daap_apro 0x6170726f
130 /* Initialize the protocol and registered fields */
131 static int proto_daap = -1;
132 static int hf_daap_name = -1;
133 static int hf_daap_size = -1;
135 /* Initialize the subtree pointers */
136 static gint ett_daap = -1;
137 static gint ett_daap_sub = -1;
139 /* Forward declarations */
140 static int dissect_daap_one_tag(proto_tree *tree, tvbuff_t *tvb, int offset, int length);
143 dissect_daap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
146 proto_tree *daap_tree;
148 gboolean is_request = (pinfo->destport == TCP_PORT_DAAP);
151 if (check_col(pinfo->cinfo, COL_PROTOCOL))
152 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DAAP");
155 if (check_col(pinfo->cinfo, COL_INFO)) {
157 col_add_str(pinfo->cinfo, COL_INFO, "DAAP Request");
159 /* This is done in two functions on purpose. If the tvb_get_xxx()
160 * functions fail, at least something will be in the info column
162 col_add_str(pinfo->cinfo, COL_INFO, "DAAP Response");
163 col_append_fstr(pinfo->cinfo, COL_INFO, " [tag: %s, size: %d]",
164 tvb_format_text(tvb, offset, 4), tvb_get_ntohl(tvb, offset+4));
171 ti = proto_tree_add_item(tree, proto_daap, tvb, 0, -1, FALSE);
172 daap_tree = proto_item_add_subtree(ti, ett_daap);
173 dissect_daap_one_tag(daap_tree, tvb, offset, 0);
178 dissect_daap_one_tag(proto_tree *tree, tvbuff_t *tvb, int offset, int length)
180 unsigned int tagname;
183 proto_item *ti = NULL;
184 proto_item *ti2 = NULL;
185 proto_tree *new_tree = NULL;
188 if (!tvb_offset_exists(tvb, offset))
191 tagname = tvb_get_ntohl(tvb, offset);
192 tagsize = tvb_get_ntohl(tvb, offset+4);
193 tvb_ensure_bytes_exist(tvb, offset, tagsize+8);
194 ti = proto_tree_add_text(tree, tvb, offset, tagsize+8,
195 "Tag: %c%c%c%c, Size: %d",
196 tvb_get_guint8(tvb, offset),
197 tvb_get_guint8(tvb, offset+1),
198 tvb_get_guint8(tvb, offset+2),
199 tvb_get_guint8(tvb, offset+3),
202 ti2 = proto_tree_add_item(tree, hf_daap_name, tvb, offset, 4, FALSE);
203 PROTO_ITEM_SET_HIDDEN(ti2);
204 ti2 = proto_tree_add_item(tree, hf_daap_size, tvb, offset+4, 4, FALSE);
205 PROTO_ITEM_SET_HIDDEN(ti2);
231 new_tree = proto_item_add_subtree(ti, ett_daap_sub);
232 new_offset = dissect_daap_one_tag(new_tree, tvb, offset,
247 /* Tags contain strings */
248 proto_item_append_text(ti, ", Data: %s",
249 tvb_format_text(tvb, offset, tagsize));
252 /* Tags conain uint64 */
253 proto_item_append_text(ti, ", Persistent Id: %" PRIu64,
254 tvb_get_ntoh64(tvb, offset));
257 proto_item_append_text(ti, ", Status: %d",
258 tvb_get_ntohl(tvb, offset));
262 proto_item_append_text(ti, ", Revision: %d",
263 tvb_get_ntohl(tvb, offset));
269 proto_item_append_text(ti, ", Id: %d",
270 tvb_get_ntohl(tvb, offset));
276 proto_item_append_text(ti, ", Count: %d",
277 tvb_get_ntohl(tvb, offset));
280 proto_item_append_text(ti, ", Timeout: %d seconds",
281 tvb_get_ntohl(tvb, offset));
291 /* Tags conain uint32 */
292 proto_item_append_text(ti, ", Data: %d",
293 tvb_get_ntohl(tvb, offset));
304 /* Tags conain uint16 */
305 proto_item_append_text(ti, ", Data: %d",
306 tvb_get_ntohs(tvb, offset));
315 /* Tags conain uint8 */
316 proto_item_append_text(ti, ", Data: %d",
317 tvb_get_guint8(tvb, offset));
334 /* Tags ARE boolean. Data is (uint8), but it seems
335 * the value is always zero. So, if the tag is present
336 * the "bool" is true.
338 proto_item_append_text(ti, ", Data: True");
343 /* Tags conain version (uint32) */
344 proto_item_append_text(ti, ", Version: %d.%d.%d.%d",
345 tvb_get_guint8(tvb, offset),
346 tvb_get_guint8(tvb, offset+1),
347 tvb_get_guint8(tvb, offset+2),
348 tvb_get_guint8(tvb, offset+3));
356 } while (length > 0);
361 /* Register the protocol with Ethereal */
363 proto_register_daap(void)
366 static hf_register_info hf[] = {
368 { "Name", "daap.name", FT_STRING, BASE_NONE, NULL, 0x0,
372 { "Size", "daap.size", FT_UINT32, BASE_DEC, NULL, 0x0,
377 static gint *ett[] = {
382 proto_daap = proto_register_protocol("Digital Audio Access Protocol",
385 proto_register_field_array(proto_daap, hf, array_length(hf));
386 proto_register_subtree_array(ett, array_length(ett));
390 /* If this dissector uses sub-dissector registration add a registration routine.
391 This format is required because a script is used to find these routines and
392 create the code that calls these routines.
395 proto_reg_handoff_daap(void)
397 dissector_handle_t daap_handle;
399 daap_handle = create_dissector_handle(dissect_daap, proto_daap);
400 http_dissector_add(TCP_PORT_DAAP, daap_handle);