2 * Routines for Digital Audio Access Protocol dissection
3 * Copyright 2004, Kelly Byrd <kbyrd@memcpy.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/exceptions.h>
16 #include <wsutil/str_util.h>
17 #include <epan/expert.h>
18 #include <epan/proto_data.h>
19 #include "packet-http.h"
21 #define TCP_PORT_DAAP 3689
24 /* Some information taken from http://tapjam.net/daap/ */
25 /* and http://www.deleet.de/projekte/daap/?ContentCodes */
27 /* Information from http://dacp.jsharkey.org/ */
28 /* and http://code.google.com/p/tunesremote-plus/ */
31 #define daap_mcon 0x6d636f6e
32 #define daap_msrv 0x6d737276
33 #define daap_mccr 0x6d636372
34 #define daap_mdcl 0x6d64636c
35 #define daap_mlog 0x6d6c6f67
36 #define daap_mupd 0x6d757064
37 #define daap_avdb 0x61766462
38 #define daap_mlcl 0x6d6c636c
39 #define daap_mlit 0x6d6c6974
40 #define daap_mbcl 0x6d62636c
41 #define daap_adbs 0x61646273
42 #define daap_aply 0x61706c79
43 #define daap_apso 0x6170736f
44 #define daap_mudl 0x6d75646c
45 #define daap_abro 0x6162726f
46 #define daap_abar 0x61626172
47 #define daap_arsv 0x61727376
48 #define daap_abal 0x6162616c
49 #define daap_abcp 0x61626370
50 #define daap_abgn 0x6162676e
51 #define daap_prsv 0x70727376
52 #define daap_arif 0x61726966
53 #define daap_mctc 0x6d637463
54 #define dacp_casp 0x63617370
55 #define dacp_cmst 0x636d7374
56 #define dacp_cmgt 0x636d6774
58 #define daap_minm 0x6d696e6d
59 #define daap_msts 0x6d737473
60 #define daap_mcnm 0x6d636e6d
61 #define daap_mcna 0x6d636e61
62 #define daap_asal 0x6173616c
63 #define daap_asar 0x61736172
64 #define daap_ascm 0x6173636d
65 #define daap_asfm 0x6173666d
66 #define daap_aseq 0x61736571
67 #define daap_asgn 0x6173676e
68 #define daap_asdt 0x61736474
69 #define daap_asul 0x6173756c
70 #define daap_ascp 0x61736370
71 #define daap_asct 0x61736374
72 #define daap_ascn 0x6173636e
73 #define daap_aslc 0x61736c63
74 #define daap_asky 0x61736b79
75 #define daap_aeSN 0x6165534e
76 #define daap_aeNN 0x61654e4e
77 #define daap_aeEN 0x6165454e
78 #define daap_assn 0x6173736e
79 #define daap_assa 0x61737361
80 #define daap_assl 0x6173736c
81 #define daap_assc 0x61737363
82 #define daap_asss 0x61737373
83 #define daap_asaa 0x61736161
84 #define daap_aspu 0x61737075
85 #define daap_aeCR 0x61654352
86 #define dacp_cana 0x63616e61
87 #define dacp_cang 0x63616e67
88 #define dacp_canl 0x63616e6c
89 #define dacp_cann 0x63616e6e
92 #define daap_mper 0x6d706572
93 #define daap_aeGU 0x61654755
94 #define daap_aeGR 0x61654752
95 #define daap_asai 0x61736169
96 #define daap_asls 0x61736c73
99 #define daap_mstt 0x6d737474
100 #define daap_musr 0x6d757372
101 #define daap_miid 0x6d696964
102 #define daap_mcti 0x6d637469
103 #define daap_mpco 0x6d70636f
104 #define daap_mimc 0x6d696d63
105 #define daap_mrco 0x6d72636f
106 #define daap_mtco 0x6d74636f
107 #define daap_mstm 0x6d73746d
108 #define daap_msdc 0x6d736463
109 #define daap_mlid 0x6d6c6964
110 #define daap_msur 0x6d737572
111 #define daap_asda 0x61736461
112 #define daap_asdm 0x6173646d
113 #define daap_assr 0x61737372
114 #define daap_assz 0x6173737a
115 #define daap_asst 0x61737374
116 #define daap_assp 0x61737370
117 #define daap_astm 0x6173746d
118 #define daap_aeNV 0x61654e56
119 #define daap_ascd 0x61736364
120 #define daap_ascs 0x61736373
121 #define daap_aeSV 0x61655356
122 #define daap_aePI 0x61655049
123 #define daap_aeCI 0x61654349
124 #define daap_aeGI 0x61654749
125 #define daap_aeAI 0x61654149
126 #define daap_aeSI 0x61655349
127 #define daap_aeES 0x61654553
128 #define daap_aeSU 0x61655355
129 #define daap_asbo 0x6173626f
130 #define daap_aeGH 0x61654748
131 #define daap_aeGD 0x61654744
132 #define daap_aeGE 0x61654745
133 #define daap_meds 0x6d656473
134 #define dacp_cmsr 0x636d7372
135 #define dacp_cant 0x63616e74
136 #define dacp_cast 0x63617374
137 #define dacp_cmvo 0x636d766f
139 #define daap_msto 0x6d7374OO utcoffset
142 #define daap_mcty 0x6d637479
143 #define daap_asbt 0x61736274
144 #define daap_asbr 0x61736272
145 #define daap_asdc 0x61736463
146 #define daap_asdn 0x6173646e
147 #define daap_astc 0x61737463
148 #define daap_astn 0x6173746e
149 #define daap_asyr 0x61737972
150 #define daap_ased 0x61736564
152 #define daap_mikd 0x6d696b64
153 #define daap_msau 0x6d736175
154 #define daap_msty 0x6d737479
155 #define daap_asrv 0x61737276 /* XXX: may be uint16 in newer iTunes versions! */
156 #define daap_asur 0x61737572
157 #define daap_asdk 0x6173646b
158 #define daap_muty 0x6d757479
159 #define daap_msas 0x6d736173
160 #define daap_aeHV 0x61654856
161 #define daap_aeHD 0x61654844
162 #define daap_aePC 0x61655043
163 #define daap_aePP 0x61655050
164 #define daap_aeMK 0x61654d4b
165 #define daap_aeSG 0x61655347
166 #define daap_apsm 0x6170736d
167 #define daap_aprm 0x6170726d
168 #define daap_asgp 0x61736770
169 #define daap_aePS 0x61655053
170 #define daap_asbk 0x6173626b
171 #define dacp_cafs 0x63616673
172 #define dacp_caps 0x63617073
173 #define dacp_carp 0x63617270
174 #define dacp_cash 0x63617368
175 #define dacp_cavs 0x63617673
177 #define daap_mslr 0x6d736c72
178 #define daap_msal 0x6d73616c
179 #define daap_msup 0x6d737570
180 #define daap_mspi 0x6d737069
181 #define daap_msex 0x6d736578
182 #define daap_msbr 0x6d736272
183 #define daap_msqy 0x6d737179
184 #define daap_msix 0x6d736978
185 #define daap_msrs 0x6d737273
186 #define daap_asco 0x6173636f
187 #define daap_asdb 0x61736462
188 #define daap_abpl 0x6162706c
189 #define daap_aeSP 0x61655350
190 #define daap_ashp 0x61736870
191 /* version (32-bit)*/
192 #define daap_mpro 0x6d70726f
193 #define daap_apro 0x6170726f
195 #define dacp_canp 0x63616e70
197 #define daap_png 0x89504e47
200 #define daap_mstc 0xMMSSTTCC utctime
201 #define daap_asdr ("daap.songdatereleased")
202 #define daap_asdp ("daap.songdatepurchased")
205 void proto_register_daap(void);
206 void proto_reg_handoff_daap(void);
208 static dissector_handle_t daap_handle
;
210 static dissector_handle_t png_handle
;
212 /*XXX: Sorted by value definition since it appears that the "value" is just */
213 /* the ascii representation of the last 4 letters of the definition. */
214 /* (Sorted so a binary search can be done when using value_string_ext) */
215 static const value_string vals_tag_code
[] = {
216 { daap_abal
, "browse album listing" },
217 { daap_abar
, "browse artist listing" },
218 { daap_abcp
, "browse composer listing" },
219 { daap_abgn
, "browse genre listing" },
220 { daap_abpl
, "base playlist" },
221 { daap_abro
, "database browse" },
222 { daap_adbs
, "database songs" },
223 { daap_aeAI
, "com.apple.itunes.itms-artistid" },
224 { daap_aeCI
, "com.apple.itunes.itms-composerid" },
225 { daap_aeCR
, "com.apple.itunes.content-rating" },
226 { daap_aeEN
, "com.apple.itunes.episode-num-str" },
227 { daap_aeES
, "com.apple.itunes.episode-sort" },
228 { daap_aeGD
, "com.apple.itunes.gapless-enc-dr" },
229 { daap_aeGE
, "com.apple.itunes.gapless-enc-del" },
230 { daap_aeGH
, "com.apple.itunes.gapless-heur" },
231 { daap_aeGI
, "com.apple.itunes.itms-genreid" },
232 { daap_aeGR
, "com.apple.itunes.gapless-resy" },
233 { daap_aeGU
, "com.apple.itunes.gapless-dur" },
234 { daap_aeHD
, "com.apple.itunes.is-hd-video" },
235 { daap_aeHV
, "com.apple.itunes.has-video" },
236 { daap_aeMK
, "com.apple.itunes.mediakind" },
237 { daap_aeNN
, "com.apple.itunes.network-name" },
238 { daap_aeNV
, "com.apple.itunes.norm-volume" },
239 { daap_aePC
, "com.apple.itunes.is-podcast" },
240 { daap_aePI
, "com.apple.itunes.itms-playlistid" },
241 { daap_aePP
, "com.apple.itunes.is-podcast-playlist" },
242 { daap_aePS
, "com.apple.itunes.special-playlist" },
243 { daap_aeSG
, "com.apple.itunes.saved-genius" },
244 { daap_aeSI
, "com.apple.itunes.itms-songid" },
245 { daap_aeSN
, "com.apple.itunes.series-name" },
246 { daap_aeSP
, "com.apple.itunes.smart-playlist" },
247 { daap_aeSU
, "com.apple.itunes.season-num" },
248 { daap_aeSV
, "com.apple.itunes.music-sharing-version" },
249 { daap_aply
, "database playlists" },
250 { daap_aprm
, "playlist repeat mode" },
251 { daap_apro
, "protocol (application?) version (apro)" },
252 { daap_apsm
, "playlist shuffle mode" },
253 { daap_apso
, "playlist songs" },
254 { daap_arif
, "resolveinfo" },
255 { daap_arsv
, "resolve" },
256 { daap_asaa
, "song album artist" },
257 { daap_asai
, "song album id"},
258 { daap_asal
, "song album" },
259 { daap_asar
, "song artist" },
260 { daap_asbk
, "song bookmarkable" },
261 { daap_asbo
, "song bookmark" },
262 { daap_asbr
, "song bitrate" },
263 { daap_asbt
, "song beats-per-minute" },
264 { daap_ascd
, "song codec type" },
265 { daap_ascm
, "song comment" },
266 { daap_ascn
, "song content description" },
267 { daap_asco
, "song compilation" },
268 { daap_ascp
, "song composer" },
269 { daap_ascs
, "song codec subtype" },
270 { daap_asct
, "song category" },
271 { daap_asda
, "song date added" },
272 { daap_asdb
, "song disabled" },
273 { daap_asdc
, "song disccount" },
274 { daap_asdk
, "song data kind" },
275 { daap_asdm
, "song date modified" },
276 { daap_asdn
, "song discnumber" },
277 { daap_asdt
, "song description" },
278 { daap_ased
, "song extra data" },
279 { daap_aseq
, "song eq preset" },
280 { daap_asfm
, "song format" },
281 { daap_asgn
, "song genre" },
282 { daap_asgp
, "song gapless" },
283 { daap_ashp
, "song has been played" },
284 { daap_asky
, "song keywords" },
285 { daap_aslc
, "song long content description" },
286 { daap_asls
, "song long size"},
287 { daap_aspu
, "song podcast url" },
288 { daap_asrv
, "song relative volume" },
289 { daap_assa
, "sort artist" },
290 { daap_assc
, "sort composer" },
291 { daap_assn
, "sort name" },
292 { daap_assp
, "song stop time (milliseconds)" },
293 { daap_assr
, "song sample rate" },
294 { daap_asss
, "sort seriesname" },
295 { daap_asst
, "song start time (milliseconds)" },
296 { daap_assz
, "song size" },
297 { daap_astc
, "song track count" },
298 { daap_astm
, "song time (milliseconds)" },
299 { daap_astn
, "song track number" },
300 { daap_asul
, "song data url" },
301 { daap_asur
, "song user rating" },
302 { daap_asyr
, "song year" },
303 { daap_avdb
, "server databases" },
304 { dacp_cafs
, "fullscreen" },
305 { dacp_cana
, "song artist" },
306 { dacp_cang
, "song genre" },
307 { dacp_canl
, "song album" },
308 { dacp_cann
, "song name" },
309 { dacp_canp
, "now playing" },
310 { dacp_cant
, "song time remaining (milliseconds)" },
311 { dacp_caps
, "play status" },
312 { dacp_carp
, "repeat" },
313 { dacp_cash
, "shuffle" },
314 { dacp_casp
, "speakers container" },
315 { dacp_cast
, "song time total (milliseconds)" },
316 { dacp_cavs
, "visualizer" },
317 { dacp_cmgt
, "container (cmgt)" },
318 { dacp_cmsr
, "status revision" },
319 { dacp_cmst
, "control container" },
320 { dacp_cmvo
, "volume" },
321 { daap_mbcl
, "bag (mbcl)" },
322 { daap_mccr
, "content codes response" },
323 { daap_mcna
, "content codes name" },
324 { daap_mcnm
, "content codes number" },
325 { daap_mcon
, "container (mcon)" },
326 { daap_mctc
, "container count" },
327 { daap_mcti
, "container item id (mcti)" },
328 { daap_mcty
, "content codes type" },
329 { daap_mdcl
, "dictionary (mdcl)" },
330 { daap_meds
, "edit commands supported" },
331 { daap_miid
, "item id (miid)" },
332 { daap_mikd
, "item kind (mikd)" },
333 { daap_mimc
, "item count (mimc)" },
334 { daap_minm
, "item name (minm)" },
335 { daap_mlcl
, "listing (mlcl)" },
336 { daap_mlid
, "session id" },
337 { daap_mlit
, "listing item (mlit)" },
338 { daap_mlog
, "login response" },
339 { daap_mpco
, "parent container id (mpco)" },
340 { daap_mper
, "persistent id (mper)" },
341 { daap_mpro
, "protocol version (mpro)" },
342 { daap_mrco
, "returned count (mrco)" },
343 { daap_msal
, "supports auto-logout (msal)" },
344 { daap_msas
, "authentication schemes" },
345 { daap_msau
, "authentication method (msau)" },
346 { daap_msbr
, "supports browse" },
347 { daap_msdc
, "databases count" },
348 { daap_msex
, "supports extensions (msex)" },
349 { daap_msix
, "supports index" },
350 { daap_mslr
, "login required (mslr)" },
351 { daap_mspi
, "supports persistent ids (mspi)" },
352 { daap_msqy
, "supports query" },
353 { daap_msrs
, "supports resolve" },
354 { daap_msrv
, "server info response (msrv)" },
355 { daap_mstm
, "timeout interval" },
356 { daap_msts
, "status string (msts)" },
357 { daap_mstt
, "status (mstt)" },
358 { daap_msup
, "supports update (msup)" },
359 { daap_msur
, "server revision" },
360 { daap_mtco
, "specified total count (mtco)" },
361 { daap_mudl
, "deleted id listing" },
362 { daap_mupd
, "update response" },
363 { daap_musr
, "server revision" },
364 { daap_muty
, "update type" },
365 { daap_prsv
, "resolve" },
368 static value_string_ext vals_tag_code_ext
= VALUE_STRING_EXT_INIT(vals_tag_code
);
370 /* Initialize the protocol and registered fields */
371 static int proto_daap
;
372 static int hf_daap_name
;
373 static int hf_daap_size
;
374 static int hf_daap_data_string
;
375 static int hf_daap_persistent_id
;
376 static int hf_daap_status
;
377 static int hf_daap_rev
;
378 static int hf_daap_id
;
379 static int hf_daap_cnt
;
380 static int hf_daap_timeout
;
381 static int hf_daap_data
;
382 static int hf_daap_playlist_id
;
383 static int hf_daap_track_id
;
385 /* Initialize the subtree pointers */
387 static int ett_daap_sub
;
389 static expert_field ei_daap_max_recursion_depth_reached
;
391 /* Forward declarations */
392 static void dissect_daap_one_tag(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
);
395 dissect_daap(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
398 proto_tree
*daap_tree
;
401 first_tag
= tvb_get_ntohl(tvb
, 0);
402 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "DAAP");
405 * This catches album art coming back from iTunes.
406 * XXX - will those have a media type of image/png
407 * rather than application/x-dmap-tagged? If so,
408 * this is no longer necessary.
410 if (first_tag
== daap_png
) {
411 call_dissector(png_handle
, tvb
, pinfo
, tree
);
412 return tvb_captured_length(tvb
);
415 /* This is done in two functions on purpose. If the tvb_get_xxx()
416 * functions fail, at least something will be in the info column
418 col_set_str(pinfo
->cinfo
, COL_INFO
, "DAAP Response");
419 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " [first tag: %s, size: %d]",
420 tvb_format_text(pinfo
->pool
, tvb
, 0, 4),
421 tvb_get_ntohl(tvb
, 4));
423 ti
= proto_tree_add_item(tree
, proto_daap
, tvb
, 0, -1, ENC_NA
);
424 daap_tree
= proto_item_add_subtree(ti
, ett_daap
);
425 dissect_daap_one_tag(daap_tree
, pinfo
, tvb
);
426 return tvb_captured_length(tvb
);
429 #define DAAP_MAX_RECURSION_DEPTH 100
432 // NOLINTNEXTLINE(misc-no-recursion)
433 dissect_daap_one_tag(proto_tree
*tree
, packet_info
*pinfo
, tvbuff_t
*tvb
)
436 uint32_t tagname
, tagsize
;
438 proto_tree
*tag_tree
;
440 unsigned recursion_depth
= p_get_proto_depth(pinfo
, proto_daap
);
442 if (++recursion_depth
>= DAAP_MAX_RECURSION_DEPTH
) {
443 proto_tree_add_expert(tree
, pinfo
, &ei_daap_max_recursion_depth_reached
,
447 p_set_proto_depth(pinfo
, proto_daap
, recursion_depth
);
449 while (offset
< tvb_reported_length(tvb
)) {
450 tagname
= tvb_get_ntohl(tvb
, offset
);
451 tagsize
= tvb_get_ntohl(tvb
, offset
+4);
453 tag_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1,
454 ett_daap_sub
, &tag_ti
, "Tag: ");
456 proto_tree_add_item_ret_uint(tag_tree
, hf_daap_name
,
457 tvb
, offset
, 4, ENC_ASCII
|ENC_NA
, &tagname
);
459 proto_tree_add_item_ret_uint(tag_tree
, hf_daap_size
,
460 tvb
, offset
, 4, ENC_BIG_ENDIAN
, &tagsize
);
463 proto_item_append_text(tag_ti
, "%s, %u byte%c",
464 val_to_str_ext(tagname
, &vals_tag_code_ext
, "Unknown tag (0x%0x)"),
465 tagsize
, plurality(tagsize
, ' ', 's'));
466 proto_item_set_len(tag_ti
, 8+tagsize
);
468 if (tagsize
> INT_MAX
)
498 new_tvb
= tvb_new_subset_length(tvb
, offset
, (int)tagsize
);
499 dissect_daap_one_tag(tag_tree
, pinfo
, new_tvb
);
534 /* Tags contain strings
535 XXX - verify that they're really 7bit ASCII */
536 proto_tree_add_item(tag_tree
, hf_daap_data_string
,
537 tvb
, offset
, tagsize
, ENC_ASCII
);
545 proto_tree_add_item(tag_tree
, hf_daap_persistent_id
,
546 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
550 proto_tree_add_item(tag_tree
, hf_daap_status
,
551 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
556 proto_tree_add_item(tag_tree
, hf_daap_rev
,
557 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
564 proto_tree_add_item(tag_tree
, hf_daap_id
,
565 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
573 proto_tree_add_item(tag_tree
, hf_daap_cnt
,
574 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
578 proto_tree_add_item(tag_tree
, hf_daap_timeout
,
579 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
608 /* Tags contain uint32
609 XXX - check tagsize here and below */
610 proto_tree_add_item(tag_tree
, hf_daap_data
,
611 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
623 /* Tags contain uint16 */
624 proto_tree_add_item(tag_tree
, hf_daap_data
,
625 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
651 /* Tags contain uint8 */
652 proto_tree_add_item(tag_tree
, hf_daap_data
,
653 tvb
, offset
, tagsize
, ENC_BIG_ENDIAN
);
670 /* Tags ARE boolean. Data is (uint8), but it seems
671 * the value is always zero. So, if the tag is present
672 * the "bool" is true.
674 proto_item_append_text(tag_ti
, "; Data: True");
679 /* Tags contain version (uint32) */
680 proto_item_append_text(tag_ti
, "; Version: %d.%d.%d.%d",
681 tvb_get_uint8(tvb
, offset
),
682 tvb_get_uint8(tvb
, offset
+1),
683 tvb_get_uint8(tvb
, offset
+2),
684 tvb_get_uint8(tvb
, offset
+3));
689 /* bytes 4-7 contain uint32 playlist id */
690 /* bytes 12-15 contain uint32 track id */
692 proto_tree_add_item(tag_tree
, hf_daap_playlist_id
,
693 tvb
, offset
+4, 4, ENC_BIG_ENDIAN
);
694 proto_tree_add_item(tag_tree
, hf_daap_track_id
,
695 tvb
, offset
+12, 4, ENC_BIG_ENDIAN
);
707 /* Register the protocol with Wireshark */
709 proto_register_daap(void)
712 static hf_register_info hf
[] = {
714 { "Tag name", "daap.name", FT_UINT32
,
715 BASE_HEX
|BASE_EXT_STRING
, &vals_tag_code_ext
, 0, NULL
, HFILL
}
718 { "Tag size", "daap.size",
719 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
721 { &hf_daap_data_string
,
722 { "Data string", "daap.data_string",
723 FT_STRING
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}
725 { &hf_daap_persistent_id
,
726 { "Persistent Id", "daap.persistent_id",
727 FT_UINT64
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
730 { "Status", "daap.status",
731 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
734 { "Revision", "daap.revision",
735 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
739 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
742 { "Count", "daap.count",
743 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
746 { "Timeout (seconds)", "daap.timeout",
747 FT_UINT32
, BASE_DEC
, NULL
, 0, NULL
, HFILL
}
749 /* this will hold data for the tags that contain
750 32, 16 or 8 bits of payload */
752 { "Data", "daap.data",
753 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
755 { &hf_daap_playlist_id
,
756 { "Playlist Id", "daap.playlist_id",
757 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
760 { "Track Id", "daap.track_id",
761 FT_UINT32
, BASE_HEX
, NULL
, 0, NULL
, HFILL
}
765 static int *ett
[] = {
770 expert_module_t
*expert_daap
;
772 static ei_register_info ei
[] = {
773 { &ei_daap_max_recursion_depth_reached
, { "daap.max_recursion_depth_reached",
774 PI_PROTOCOL
, PI_WARN
, "Maximum allowed recursion depth reached - stop decoding", EXPFILL
}}
777 proto_daap
= proto_register_protocol("Digital Audio Access Protocol",
780 expert_daap
= expert_register_protocol(proto_daap
);
781 expert_register_field_array(expert_daap
, ei
, array_length(ei
));
783 proto_register_field_array(proto_daap
, hf
, array_length(hf
));
784 proto_register_subtree_array(ett
, array_length(ett
));
786 daap_handle
= register_dissector("daap", dissect_daap
, proto_daap
);
790 proto_reg_handoff_daap(void)
792 http_tcp_port_add(TCP_PORT_DAAP
);
793 dissector_add_string("media_type", "application/x-dmap-tagged", daap_handle
);
795 png_handle
= find_dissector_add_dependency("png", proto_daap
);
799 * Editor modelines - https://www.wireshark.org/tools/modelines.html
804 * indent-tabs-mode: nil
807 * ex: set shiftwidth=3 tabstop=8 expandtab:
808 * :indentSize=3:tabSize=8:noTabs=true: