GSM A DTAP: add UMTS EVS to supported codecs list IE
[metze/wireshark/wip.git] / epan / dissectors / packet-daap.c
1 /* packet-daap.c
2  * Routines for Digital Audio Access Protocol dissection
3  * Copyright 2004, Kelly Byrd <kbyrd@memcpy.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11
12 #include "config.h"
13
14 #include <epan/packet.h>
15 #include <epan/exceptions.h>
16 #include <wsutil/str_util.h>
17 #include <epan/expert.h>
18 #include "packet-http.h"
19
20 #define TCP_PORT_DAAP 3689
21
22 /* DAAP tags */
23 /* Some information taken from http://tapjam.net/daap/ */
24 /* and http://www.deleet.de/projekte/daap/?ContentCodes */
25 /* DACP tags */
26 /* Information from http://dacp.jsharkey.org/ */
27 /* and http://code.google.com/p/tunesremote-plus/ */
28
29 /* Container tags */
30 #define daap_mcon       0x6d636f6e
31 #define daap_msrv       0x6d737276
32 #define daap_mccr       0x6d636372
33 #define daap_mdcl       0x6d64636c
34 #define daap_mlog       0x6d6c6f67
35 #define daap_mupd       0x6d757064
36 #define daap_avdb       0x61766462
37 #define daap_mlcl       0x6d6c636c
38 #define daap_mlit       0x6d6c6974
39 #define daap_mbcl       0x6d62636c
40 #define daap_adbs       0x61646273
41 #define daap_aply       0x61706c79
42 #define daap_apso       0x6170736f
43 #define daap_mudl       0x6d75646c
44 #define daap_abro       0x6162726f
45 #define daap_abar       0x61626172
46 #define daap_arsv       0x61727376
47 #define daap_abal       0x6162616c
48 #define daap_abcp       0x61626370
49 #define daap_abgn       0x6162676e
50 #define daap_prsv       0x70727376
51 #define daap_arif       0x61726966
52 #define daap_mctc       0x6d637463
53 #define dacp_casp       0x63617370
54 #define dacp_cmst       0x636d7374
55 #define dacp_cmgt       0x636d6774
56 /* String tags */
57 #define daap_minm       0x6d696e6d
58 #define daap_msts       0x6d737473
59 #define daap_mcnm       0x6d636e6d
60 #define daap_mcna       0x6d636e61
61 #define daap_asal       0x6173616c
62 #define daap_asar       0x61736172
63 #define daap_ascm       0x6173636d
64 #define daap_asfm       0x6173666d
65 #define daap_aseq       0x61736571
66 #define daap_asgn       0x6173676e
67 #define daap_asdt       0x61736474
68 #define daap_asul       0x6173756c
69 #define daap_ascp       0x61736370
70 #define daap_asct       0x61736374
71 #define daap_ascn       0x6173636e
72 #define daap_aslc       0x61736c63
73 #define daap_asky       0x61736b79
74 #define daap_aeSN       0x6165534e
75 #define daap_aeNN       0x61654e4e
76 #define daap_aeEN       0x6165454e
77 #define daap_assn       0x6173736e
78 #define daap_assa       0x61737361
79 #define daap_assl       0x6173736c
80 #define daap_assc       0x61737363
81 #define daap_asss       0x61737373
82 #define daap_asaa       0x61736161
83 #define daap_aspu       0x61737075
84 #define daap_aeCR       0x61654352
85 #define dacp_cana       0x63616e61
86 #define dacp_cang       0x63616e67
87 #define dacp_canl       0x63616e6c
88 #define dacp_cann       0x63616e6e
89
90 /* uint64 tags */
91 #define daap_mper       0x6d706572
92 #define daap_aeGU       0x61654755
93 #define daap_aeGR       0x61654752
94 #define daap_asai       0x61736169
95 #define daap_asls       0x61736c73
96
97 /* uint32 tags */
98 #define daap_mstt       0x6d737474
99 #define daap_musr       0x6d757372
100 #define daap_miid       0x6d696964
101 #define daap_mcti       0x6d637469
102 #define daap_mpco       0x6d70636f
103 #define daap_mimc       0x6d696d63
104 #define daap_mrco       0x6d72636f
105 #define daap_mtco       0x6d74636f
106 #define daap_mstm       0x6d73746d
107 #define daap_msdc       0x6d736463
108 #define daap_mlid       0x6d6c6964
109 #define daap_msur       0x6d737572
110 #define daap_asda       0x61736461
111 #define daap_asdm       0x6173646d
112 #define daap_assr       0x61737372
113 #define daap_assz       0x6173737a
114 #define daap_asst       0x61737374
115 #define daap_assp       0x61737370
116 #define daap_astm       0x6173746d
117 #define daap_aeNV       0x61654e56
118 #define daap_ascd       0x61736364
119 #define daap_ascs       0x61736373
120 #define daap_aeSV       0x61655356
121 #define daap_aePI       0x61655049
122 #define daap_aeCI       0x61654349
123 #define daap_aeGI       0x61654749
124 #define daap_aeAI       0x61654149
125 #define daap_aeSI       0x61655349
126 #define daap_aeES       0x61654553
127 #define daap_aeSU       0x61655355
128 #define daap_asbo       0x6173626f
129 #define daap_aeGH       0x61654748
130 #define daap_aeGD       0x61654744
131 #define daap_aeGE       0x61654745
132 #define daap_meds       0x6d656473
133 #define dacp_cmsr       0x636d7372
134 #define dacp_cant       0x63616e74
135 #define dacp_cast       0x63617374
136 #define dacp_cmvo       0x636d766f
137 /*TODO:
138 #define daap_msto               0x6d7374OO utcoffset
139 */
140 /* uint16 tags */
141 #define daap_mcty       0x6d637479
142 #define daap_asbt       0x61736274
143 #define daap_asbr       0x61736272
144 #define daap_asdc       0x61736463
145 #define daap_asdn       0x6173646e
146 #define daap_astc       0x61737463
147 #define daap_astn       0x6173746e
148 #define daap_asyr       0x61737972
149 #define daap_ased       0x61736564
150 /* byte  tags */
151 #define daap_mikd       0x6d696b64
152 #define daap_msau       0x6d736175
153 #define daap_msty       0x6d737479
154 #define daap_asrv       0x61737276 /* XXX: may be uint16 in newer iTunes versions! */
155 #define daap_asur       0x61737572
156 #define daap_asdk       0x6173646b
157 #define daap_muty       0x6d757479
158 #define daap_msas       0x6d736173
159 #define daap_aeHV       0x61654856
160 #define daap_aeHD       0x61654844
161 #define daap_aePC       0x61655043
162 #define daap_aePP       0x61655050
163 #define daap_aeMK       0x61654d4b
164 #define daap_aeSG       0x61655347
165 #define daap_apsm       0x6170736d
166 #define daap_aprm       0x6170726d
167 #define daap_asgp       0x61736770
168 #define daap_aePS       0x61655053
169 #define daap_asbk       0x6173626b
170 #define dacp_cafs       0x63616673
171 #define dacp_caps       0x63617073
172 #define dacp_carp       0x63617270
173 #define dacp_cash       0x63617368
174 #define dacp_cavs       0x63617673
175 /* boolean  tags */
176 #define daap_mslr       0x6d736c72
177 #define daap_msal       0x6d73616c
178 #define daap_msup       0x6d737570
179 #define daap_mspi       0x6d737069
180 #define daap_msex       0x6d736578
181 #define daap_msbr       0x6d736272
182 #define daap_msqy       0x6d737179
183 #define daap_msix       0x6d736978
184 #define daap_msrs       0x6d737273
185 #define daap_asco       0x6173636f
186 #define daap_asdb       0x61736462
187 #define daap_abpl       0x6162706c
188 #define daap_aeSP       0x61655350
189 #define daap_ashp       0x61736870
190 /* version (32-bit)*/
191 #define daap_mpro       0x6d70726f
192 #define daap_apro       0x6170726f
193 /* now playing */
194 #define dacp_canp       0x63616e70
195
196 #define daap_png        0x89504e47
197 /* date/time */
198 /* TODO:
199 #define daap_mstc 0xMMSSTTCC utctime
200 #define daap_asdr ("daap.songdatereleased")
201 #define daap_asdp ("daap.songdatepurchased")
202 */
203
204 void proto_register_daap(void);
205 void proto_reg_handoff_daap(void);
206
207 static dissector_handle_t png_handle;
208
209 /*XXX: Sorted by value definition since it appears that the "value" is just */
210 /*     the ascii representation of the last 4 letters of the definition.    */
211 /*     (Sorted so a binary search can be done when using value_string_ext)  */
212 static const value_string vals_tag_code[] = {
213    { daap_abal, "browse album listing" },
214    { daap_abar, "browse artist listing" },
215    { daap_abcp, "browse composer listing" },
216    { daap_abgn, "browse genre listing" },
217    { daap_abpl, "base playlist" },
218    { daap_abro, "database browse" },
219    { daap_adbs, "database songs" },
220    { daap_aeAI, "com.apple.itunes.itms-artistid" },
221    { daap_aeCI, "com.apple.itunes.itms-composerid" },
222    { daap_aeCR, "com.apple.itunes.content-rating" },
223    { daap_aeEN, "com.apple.itunes.episode-num-str" },
224    { daap_aeES, "com.apple.itunes.episode-sort" },
225    { daap_aeGD, "com.apple.itunes.gapless-enc-dr" },
226    { daap_aeGE, "com.apple.itunes.gapless-enc-del" },
227    { daap_aeGH, "com.apple.itunes.gapless-heur" },
228    { daap_aeGI, "com.apple.itunes.itms-genreid" },
229    { daap_aeGR, "com.apple.itunes.gapless-resy" },
230    { daap_aeGU, "com.apple.itunes.gapless-dur" },
231    { daap_aeHD, "com.apple.itunes.is-hd-video" },
232    { daap_aeHV, "com.apple.itunes.has-video" },
233    { daap_aeMK, "com.apple.itunes.mediakind" },
234    { daap_aeNN, "com.apple.itunes.network-name" },
235    { daap_aeNV, "com.apple.itunes.norm-volume" },
236    { daap_aePC, "com.apple.itunes.is-podcast" },
237    { daap_aePI, "com.apple.itunes.itms-playlistid" },
238    { daap_aePP, "com.apple.itunes.is-podcast-playlist" },
239    { daap_aePS, "com.apple.itunes.special-playlist" },
240    { daap_aeSG, "com.apple.itunes.saved-genius" },
241    { daap_aeSI, "com.apple.itunes.itms-songid" },
242    { daap_aeSN, "com.apple.itunes.series-name" },
243    { daap_aeSP, "com.apple.itunes.smart-playlist" },
244    { daap_aeSU, "com.apple.itunes.season-num" },
245    { daap_aeSV, "com.apple.itunes.music-sharing-version" },
246    { daap_aply, "database playlists" },
247    { daap_aprm, "playlist repeat mode" },
248    { daap_apro, "protocol (application?) version (apro)" },
249    { daap_apsm, "playlist shuffle mode" },
250    { daap_apso, "playlist songs" },
251    { daap_arif, "resolveinfo" },
252    { daap_arsv, "resolve" },
253    { daap_asaa, "song album artist" },
254    { daap_asai, "song album id"},
255    { daap_asal, "song album" },
256    { daap_asar, "song artist" },
257    { daap_asbk, "song bookmarkable" },
258    { daap_asbo, "song bookmark" },
259    { daap_asbr, "song bitrate" },
260    { daap_asbt, "song beats-per-minute" },
261    { daap_ascd, "song codec type" },
262    { daap_ascm, "song comment" },
263    { daap_ascn, "song content description" },
264    { daap_asco, "song compilation" },
265    { daap_ascp, "song composer" },
266    { daap_ascs, "song codec subtype" },
267    { daap_asct, "song category" },
268    { daap_asda, "song date added" },
269    { daap_asdb, "song disabled" },
270    { daap_asdc, "song disccount" },
271    { daap_asdk, "song data kind" },
272    { daap_asdm, "song date modified" },
273    { daap_asdn, "song discnumber" },
274    { daap_asdt, "song description" },
275    { daap_ased, "song extra data" },
276    { daap_aseq, "song eq preset" },
277    { daap_asfm, "song format" },
278    { daap_asgn, "song genre" },
279    { daap_asgp, "song gapless" },
280    { daap_ashp, "song has been played" },
281    { daap_asky, "song keywords" },
282    { daap_aslc, "song long content description" },
283    { daap_asls, "song long size"},
284    { daap_aspu, "song podcast url" },
285    { daap_asrv, "song relative volume" },
286    { daap_assa, "sort artist" },
287    { daap_assc, "sort composer" },
288    { daap_assn, "sort name" },
289    { daap_assp, "song stop time (milliseconds)" },
290    { daap_assr, "song sample rate" },
291    { daap_asss, "sort seriesname" },
292    { daap_asst, "song start time (milliseconds)" },
293    { daap_assz, "song size" },
294    { daap_astc, "song track count" },
295    { daap_astm, "song time (milliseconds)" },
296    { daap_astn, "song track number" },
297    { daap_asul, "song data url" },
298    { daap_asur, "song user rating" },
299    { daap_asyr, "song year" },
300    { daap_avdb, "server databases" },
301    { dacp_cafs, "fullscreen" },
302    { dacp_cana, "song artist" },
303    { dacp_cang, "song genre" },
304    { dacp_canl, "song album" },
305    { dacp_cann, "song name" },
306    { dacp_canp, "now playing" },
307    { dacp_cant, "song time remaining (milliseconds)" },
308    { dacp_caps, "play status" },
309    { dacp_carp, "repeat" },
310    { dacp_cash, "shuffle" },
311    { dacp_casp, "speakers container" },
312    { dacp_cast, "song time total (milliseconds)" },
313    { dacp_cavs, "visualizer" },
314    { dacp_cmgt, "container (cmgt)" },
315    { dacp_cmsr, "status revision" },
316    { dacp_cmst, "control container" },
317    { dacp_cmvo, "volume" },
318    { daap_mbcl, "bag (mbcl)" },
319    { daap_mccr, "content codes response" },
320    { daap_mcna, "content codes name" },
321    { daap_mcnm, "content codes number" },
322    { daap_mcon, "container (mcon)" },
323    { daap_mctc, "container count" },
324    { daap_mcti, "container item id (mcti)" },
325    { daap_mcty, "content codes type" },
326    { daap_mdcl, "dictionary (mdcl)" },
327    { daap_meds, "edit commands supported" },
328    { daap_miid, "item id (miid)" },
329    { daap_mikd, "item kind (mikd)" },
330    { daap_mimc, "item count (mimc)" },
331    { daap_minm, "item name (minm)" },
332    { daap_mlcl, "listing (mlcl)" },
333    { daap_mlid, "session id" },
334    { daap_mlit, "listing item (mlit)" },
335    { daap_mlog, "login response" },
336    { daap_mpco, "parent container id (mpco)" },
337    { daap_mper, "persistent id (mper)" },
338    { daap_mpro, "protocol version (mpro)" },
339    { daap_mrco, "returned count (mrco)" },
340    { daap_msal, "supports auto-logout (msal)" },
341    { daap_msas, "authentication schemes" },
342    { daap_msau, "authentication method (msau)" },
343    { daap_msbr, "supports browse" },
344    { daap_msdc, "databases count" },
345    { daap_msex, "supports extensions (msex)" },
346    { daap_msix, "supports index" },
347    { daap_mslr, "login required (mslr)" },
348    { daap_mspi, "supports persistent ids (mspi)" },
349    { daap_msqy, "supports query" },
350    { daap_msrs, "supports resolve" },
351    { daap_msrv, "server info response (msrv)" },
352    { daap_mstm, "timeout interval" },
353    { daap_msts, "status string (msts)" },
354    { daap_mstt, "status (mstt)" },
355    { daap_msup, "supports update (msup)" },
356    { daap_msur, "server revision" },
357    { daap_mtco, "specified total count (mtco)" },
358    { daap_mudl, "deleted id listing" },
359    { daap_mupd, "update response" },
360    { daap_musr, "server revision" },
361    { daap_muty, "update type" },
362    { daap_prsv, "resolve" },
363    { 0,         NULL}
364 };
365 static value_string_ext vals_tag_code_ext = VALUE_STRING_EXT_INIT(vals_tag_code);
366
367 /* Initialize the protocol and registered fields */
368 static int proto_daap = -1;
369 static int hf_daap_name = -1;
370 static int hf_daap_size = -1;
371 static int hf_daap_data_string = -1;
372 static int hf_daap_persistent_id = -1;
373 static int hf_daap_status = -1;
374 static int hf_daap_rev = -1;
375 static int hf_daap_id = -1;
376 static int hf_daap_cnt = -1;
377 static int hf_daap_timeout = -1;
378 static int hf_daap_data = -1;
379 static int hf_daap_playlist_id = -1;
380 static int hf_daap_track_id = -1;
381
382 /* Initialize the subtree pointers */
383 static gint ett_daap = -1;
384 static gint ett_daap_sub = -1;
385
386 static expert_field ei_daap_max_recursion_depth_reached = EI_INIT;
387
388 /* Forward declarations */
389 static void dissect_daap_one_tag(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int recursion_depth);
390
391 static int
392 dissect_daap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
393 {
394    proto_item *ti;
395    proto_tree *daap_tree;
396    guint first_tag;
397
398    first_tag = tvb_get_ntohl(tvb, 0);
399    col_set_str(pinfo->cinfo, COL_PROTOCOL, "DAAP");
400
401    /*
402     * This catches album art coming back from iTunes.
403     * XXX - will those have a media type of image/png
404     * rather than application/x-dmap-tagged?  If so,
405     * this is no longer necessary.
406     */
407    if (first_tag == daap_png) {
408       call_dissector(png_handle, tvb, pinfo, tree);
409       return tvb_captured_length(tvb);
410    }
411
412    /* This is done in two functions on purpose. If the tvb_get_xxx()
413     * functions fail, at least something will be in the info column
414     */
415    col_set_str(pinfo->cinfo, COL_INFO, "DAAP Response");
416    col_append_fstr(pinfo->cinfo, COL_INFO, " [first tag: %s, size: %d]",
417                    tvb_format_text(tvb, 0, 4),
418                    tvb_get_ntohl(tvb, 4));
419
420    ti = proto_tree_add_item(tree, proto_daap, tvb, 0, -1, ENC_NA);
421    daap_tree = proto_item_add_subtree(ti, ett_daap);
422    dissect_daap_one_tag(daap_tree, pinfo, tvb, 0);
423    return tvb_captured_length(tvb);
424 }
425
426 #define DAAP_MAX_RECURSION_DEPTH 100
427
428 static void
429 dissect_daap_one_tag(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb, int recursion_depth)
430 {
431    guint       offset = 0;
432    guint32     tagname, tagsize;
433    proto_item *tag_ti;
434    proto_tree *tag_tree;
435    tvbuff_t   *new_tvb;
436
437    if (recursion_depth >= DAAP_MAX_RECURSION_DEPTH) {
438       proto_tree_add_expert(tree, pinfo, &ei_daap_max_recursion_depth_reached,
439                             tvb, 0, 0);
440       return;
441    }
442    while (offset < tvb_reported_length(tvb)) {
443       tagname = tvb_get_ntohl(tvb, offset);
444       tagsize = tvb_get_ntohl(tvb, offset+4);
445
446       tag_tree = proto_tree_add_subtree(tree, tvb, offset, -1,
447             ett_daap_sub, &tag_ti, "Tag: ");
448
449       proto_tree_add_item_ret_uint(tag_tree, hf_daap_name,
450             tvb, offset, 4, ENC_ASCII|ENC_NA, &tagname);
451       offset += 4;
452       proto_tree_add_item_ret_uint(tag_tree, hf_daap_size,
453             tvb, offset, 4, ENC_BIG_ENDIAN, &tagsize);
454       offset += 4;
455
456       proto_item_append_text(tag_ti, "%s, %u byte%c",
457             val_to_str_ext(tagname, &vals_tag_code_ext, "Unknown tag (0x%0x)"),
458             tagsize, plurality(tagsize, ' ', 's'));
459       proto_item_set_len(tag_ti, 8+tagsize);
460
461       if (tagsize > G_MAXINT)
462          break;
463
464       switch (tagname) {
465          case daap_mcon:
466          case daap_msrv:
467          case daap_mccr:
468          case daap_mdcl:
469          case daap_mlog:
470          case daap_mupd:
471          case daap_avdb:
472          case daap_mlcl:
473          case daap_mlit:
474          case daap_mbcl:
475          case daap_adbs:
476          case daap_aply:
477          case daap_apso:
478          case daap_mudl:
479          case daap_abro:
480          case daap_abar:
481          case daap_arsv:
482          case daap_abal:
483          case daap_abcp:
484          case daap_abgn:
485          case daap_prsv:
486          case daap_arif:
487          case dacp_casp:
488          case dacp_cmgt:
489          case dacp_cmst:
490             /* Container tags */
491             new_tvb  = tvb_new_subset_length(tvb, offset, (gint)tagsize);
492             dissect_daap_one_tag(tag_tree, pinfo, new_tvb, recursion_depth+1);
493             break;
494
495          case daap_minm:
496          case daap_msts:
497          case daap_mcnm:
498          case daap_mcna:
499          case daap_asal:
500          case daap_asar:
501          case daap_ascm:
502          case daap_asfm:
503          case daap_aseq:
504          case daap_asgn:
505          case daap_asdt:
506          case daap_asul:
507          case daap_ascp:
508          case daap_asct:
509          case daap_ascn:
510          case daap_aslc:
511          case daap_asky:
512          case daap_aeSN:
513          case daap_aeNN:
514          case daap_aeEN:
515          case daap_assn:
516          case daap_assa:
517          case daap_assl:
518          case daap_assc:
519          case daap_asss:
520          case daap_asaa:
521          case daap_aspu:
522          case daap_aeCR:
523          case dacp_cana:
524          case dacp_cang:
525          case dacp_canl:
526          case dacp_cann:
527             /* Tags contain strings
528                XXX - verify that they're really 7bit ASCII */
529             proto_tree_add_item(tag_tree, hf_daap_data_string,
530                   tvb, offset, tagsize, ENC_ASCII|ENC_NA);
531             break;
532
533          case daap_mper:
534          case daap_aeGR:
535          case daap_aeGU:
536          case daap_asai:
537          case daap_asls:
538             proto_tree_add_item(tag_tree, hf_daap_persistent_id,
539                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
540             break;
541
542          case daap_mstt:
543             proto_tree_add_item(tag_tree, hf_daap_status,
544                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
545             break;
546
547          case daap_musr:
548          case daap_msur:
549             proto_tree_add_item(tag_tree, hf_daap_rev,
550                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
551             break;
552
553          case daap_miid:
554          case daap_mcti:
555          case daap_mpco:
556          case daap_mlid:
557             proto_tree_add_item(tag_tree, hf_daap_id,
558                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
559             break;
560
561          case daap_mrco:
562          case daap_mtco:
563          case daap_mimc:
564          case daap_msdc:
565          case daap_mctc:
566             proto_tree_add_item(tag_tree, hf_daap_cnt,
567                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
568             break;
569
570          case daap_mstm:
571             proto_tree_add_item(tag_tree, hf_daap_timeout,
572                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
573             break;
574
575          case daap_asda:
576          case daap_asdm:
577          case daap_assr:
578          case daap_assz:
579          case daap_asst:
580          case daap_assp:
581          case daap_astm:
582          case daap_aeNV:
583          case daap_ascd:
584          case daap_ascs:
585          case daap_aeSV:
586          case daap_aePI:
587          case daap_aeCI:
588          case daap_aeGI:
589          case daap_aeAI:
590          case daap_aeSI:
591          case daap_aeES:
592          case daap_asbo:
593          case daap_aeGH:
594          case daap_aeGD:
595          case daap_aeGE:
596          case dacp_cant:
597          case dacp_cast:
598          case dacp_cmsr:
599          case dacp_cmvo:
600          case daap_meds:
601             /* Tags contain uint32
602                XXX - check tagsize here and below */
603             proto_tree_add_item(tag_tree, hf_daap_data,
604                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
605             break;
606
607          case daap_mcty:
608          case daap_asbt:
609          case daap_asbr:
610          case daap_asdc:
611          case daap_asdn:
612          case daap_astc:
613          case daap_astn:
614          case daap_asyr:
615          case daap_ased:
616             /* Tags contain uint16 */
617             proto_tree_add_item(tag_tree, hf_daap_data,
618                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
619             break;
620
621          case daap_mikd:
622          case daap_msau:
623          case daap_msty:
624          case daap_asrv:
625          case daap_asur:
626          case daap_asdk:
627          case daap_muty:
628          case daap_msas:
629          case daap_aeHV:
630          case daap_aeHD:
631          case daap_aePC:
632          case daap_aePP:
633          case daap_aeMK:
634          case daap_aeSG:
635          case daap_apsm:
636          case daap_aprm:
637          case daap_asgp:
638          case daap_aePS:
639          case dacp_cafs:
640          case dacp_caps:
641          case dacp_carp:
642          case dacp_cash:
643          case dacp_cavs:
644             /* Tags contain uint8 */
645             proto_tree_add_item(tag_tree, hf_daap_data,
646                   tvb, offset, tagsize, ENC_BIG_ENDIAN);
647             break;
648
649          case daap_mslr:
650          case daap_msal:
651          case daap_msup:
652          case daap_mspi:
653          case daap_msex:
654          case daap_msbr:
655          case daap_msqy:
656          case daap_msix:
657          case daap_msrs:
658          case daap_asco:
659          case daap_asdb:
660          case daap_abpl:
661          case daap_aeSP:
662          case daap_asbk:
663             /* Tags ARE boolean. Data is (uint8), but it seems
664              * the value is always zero. So, if the tag is present
665              * the "bool" is true.
666              */
667             proto_item_append_text(tag_ti, "; Data: True");
668             break;
669
670          case daap_mpro:
671          case daap_apro:
672             /* Tags contain version (uint32) */
673             proto_item_append_text(tag_ti, "; Version: %d.%d.%d.%d",
674                   tvb_get_guint8(tvb, offset),
675                   tvb_get_guint8(tvb, offset+1),
676                   tvb_get_guint8(tvb, offset+2),
677                   tvb_get_guint8(tvb, offset+3));
678             break;
679
680          case dacp_canp:
681             /* now playing */
682             /* bytes  4-7  contain uint32 playlist id */
683             /* bytes 12-15 contain uint32 track id */
684
685             proto_tree_add_item(tag_tree, hf_daap_playlist_id,
686                   tvb, offset+4, 4, ENC_BIG_ENDIAN);
687             proto_tree_add_item(tag_tree, hf_daap_track_id,
688                   tvb, offset+12, 4, ENC_BIG_ENDIAN);
689             break;
690
691          default:
692             break;
693       }
694
695       offset += tagsize;
696    }
697 }
698
699
700 /* Register the protocol with Wireshark */
701 void
702 proto_register_daap(void)
703 {
704
705    static hf_register_info hf[] = {
706       { &hf_daap_name,
707         { "Tag name", "daap.name", FT_UINT32,
708            BASE_HEX|BASE_EXT_STRING, &vals_tag_code_ext, 0, NULL, HFILL }
709       },
710       { &hf_daap_size,
711         { "Tag size", "daap.size",
712            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
713       },
714       { &hf_daap_data_string,
715         { "Data string", "daap.data_string",
716            FT_STRING, STR_ASCII, NULL, 0, NULL, HFILL }
717       },
718       { &hf_daap_persistent_id,
719         { "Persistent Id", "daap.persistent_id",
720            FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL }
721       },
722       { &hf_daap_status,
723         { "Staus", "daap.status",
724            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
725       },
726       { &hf_daap_rev,
727         { "Revision", "daap.revision",
728            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
729       },
730       { &hf_daap_id,
731         { "Id", "daap.id",
732            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
733       },
734       { &hf_daap_cnt,
735         { "Count", "daap.count",
736            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
737       },
738       { &hf_daap_timeout,
739         { "Timeout (seconds)", "daap.timeout",
740            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
741       },
742       /* this will hold data for the tags that contain
743          32, 16 or 8 bits of payload */
744       { &hf_daap_data,
745         { "Data", "daap.data",
746            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
747       },
748       { &hf_daap_playlist_id,
749         { "Playlist Id", "daap.playlist_id",
750            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
751       },
752       { &hf_daap_track_id,
753         { "Track Id", "daap.track_id",
754            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }
755       }
756    };
757
758    static gint *ett[] = {
759       &ett_daap,
760       &ett_daap_sub,
761    };
762
763    expert_module_t *expert_daap;
764
765    static ei_register_info ei[] = {
766       { &ei_daap_max_recursion_depth_reached, { "daap.max_recursion_depth_reached",
767         PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached - stop decoding", EXPFILL }}
768    };
769
770    proto_daap = proto_register_protocol("Digital Audio Access Protocol",
771                                         "DAAP", "daap");
772
773    expert_daap = expert_register_protocol(proto_daap);
774    expert_register_field_array(expert_daap, ei, array_length(ei));
775
776    proto_register_field_array(proto_daap, hf, array_length(hf));
777    proto_register_subtree_array(ett, array_length(ett));
778 }
779
780 void
781 proto_reg_handoff_daap(void)
782 {
783    dissector_handle_t daap_handle;
784
785    daap_handle = create_dissector_handle(dissect_daap, proto_daap);
786    http_tcp_port_add(TCP_PORT_DAAP);
787    dissector_add_string("media_type", "application/x-dmap-tagged", daap_handle);
788
789    png_handle = find_dissector_add_dependency("png", proto_daap);
790 }
791
792 /*
793  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
794  *
795  * Local Variables:
796  * c-basic-offset: 3
797  * tab-width: 8
798  * indent-tabs-mode: nil
799  * End:
800  *
801  * ex: set shiftwidth=3 tabstop=8 expandtab:
802  * :indentSize=3:tabSize=8:noTabs=true:
803  */