/src/wireshark/epan/dissectors/packet-daap.c
Line | Count | Source |
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 <epan/proto_data.h> |
19 | | #include "packet-http.h" |
20 | | |
21 | 14 | #define TCP_PORT_DAAP 3689 |
22 | | |
23 | | /* DAAP tags */ |
24 | | /* Some information taken from http://tapjam.net/daap/ */ |
25 | | /* and http://www.deleet.de/projekte/daap/?ContentCodes */ |
26 | | /* DACP tags */ |
27 | | /* Information from http://dacp.jsharkey.org/ */ |
28 | | /* and http://code.google.com/p/tunesremote-plus/ */ |
29 | | |
30 | | /* Container tags */ |
31 | 0 | #define daap_mcon 0x6d636f6e |
32 | 0 | #define daap_msrv 0x6d737276 |
33 | 0 | #define daap_mccr 0x6d636372 |
34 | 0 | #define daap_mdcl 0x6d64636c |
35 | 0 | #define daap_mlog 0x6d6c6f67 |
36 | 0 | #define daap_mupd 0x6d757064 |
37 | 0 | #define daap_avdb 0x61766462 |
38 | 0 | #define daap_mlcl 0x6d6c636c |
39 | 0 | #define daap_mlit 0x6d6c6974 |
40 | 0 | #define daap_mbcl 0x6d62636c |
41 | 0 | #define daap_adbs 0x61646273 |
42 | 0 | #define daap_aply 0x61706c79 |
43 | 0 | #define daap_apso 0x6170736f |
44 | 0 | #define daap_mudl 0x6d75646c |
45 | 0 | #define daap_abro 0x6162726f |
46 | 0 | #define daap_abar 0x61626172 |
47 | 0 | #define daap_arsv 0x61727376 |
48 | 0 | #define daap_abal 0x6162616c |
49 | 0 | #define daap_abcp 0x61626370 |
50 | 0 | #define daap_abgn 0x6162676e |
51 | 0 | #define daap_prsv 0x70727376 |
52 | 0 | #define daap_arif 0x61726966 |
53 | 0 | #define daap_mctc 0x6d637463 |
54 | 0 | #define dacp_casp 0x63617370 |
55 | 0 | #define dacp_cmst 0x636d7374 |
56 | 0 | #define dacp_cmgt 0x636d6774 |
57 | | /* String tags */ |
58 | 0 | #define daap_minm 0x6d696e6d |
59 | 0 | #define daap_msts 0x6d737473 |
60 | 0 | #define daap_mcnm 0x6d636e6d |
61 | 0 | #define daap_mcna 0x6d636e61 |
62 | 0 | #define daap_asal 0x6173616c |
63 | 0 | #define daap_asar 0x61736172 |
64 | 0 | #define daap_ascm 0x6173636d |
65 | 0 | #define daap_asfm 0x6173666d |
66 | 0 | #define daap_aseq 0x61736571 |
67 | 0 | #define daap_asgn 0x6173676e |
68 | 0 | #define daap_asdt 0x61736474 |
69 | 0 | #define daap_asul 0x6173756c |
70 | 0 | #define daap_ascp 0x61736370 |
71 | 0 | #define daap_asct 0x61736374 |
72 | 0 | #define daap_ascn 0x6173636e |
73 | 0 | #define daap_aslc 0x61736c63 |
74 | 0 | #define daap_asky 0x61736b79 |
75 | 0 | #define daap_aeSN 0x6165534e |
76 | 0 | #define daap_aeNN 0x61654e4e |
77 | 0 | #define daap_aeEN 0x6165454e |
78 | 0 | #define daap_assn 0x6173736e |
79 | 0 | #define daap_assa 0x61737361 |
80 | 0 | #define daap_assl 0x6173736c |
81 | 0 | #define daap_assc 0x61737363 |
82 | 0 | #define daap_asss 0x61737373 |
83 | 0 | #define daap_asaa 0x61736161 |
84 | 0 | #define daap_aspu 0x61737075 |
85 | 0 | #define daap_aeCR 0x61654352 |
86 | 0 | #define dacp_cana 0x63616e61 |
87 | 0 | #define dacp_cang 0x63616e67 |
88 | 0 | #define dacp_canl 0x63616e6c |
89 | 0 | #define dacp_cann 0x63616e6e |
90 | | |
91 | | /* uint64 tags */ |
92 | 0 | #define daap_mper 0x6d706572 |
93 | 0 | #define daap_aeGU 0x61654755 |
94 | 0 | #define daap_aeGR 0x61654752 |
95 | 0 | #define daap_asai 0x61736169 |
96 | 0 | #define daap_asls 0x61736c73 |
97 | | |
98 | | /* uint32 tags */ |
99 | 0 | #define daap_mstt 0x6d737474 |
100 | 0 | #define daap_musr 0x6d757372 |
101 | 0 | #define daap_miid 0x6d696964 |
102 | 0 | #define daap_mcti 0x6d637469 |
103 | 0 | #define daap_mpco 0x6d70636f |
104 | 0 | #define daap_mimc 0x6d696d63 |
105 | 0 | #define daap_mrco 0x6d72636f |
106 | 0 | #define daap_mtco 0x6d74636f |
107 | 0 | #define daap_mstm 0x6d73746d |
108 | 0 | #define daap_msdc 0x6d736463 |
109 | 0 | #define daap_mlid 0x6d6c6964 |
110 | 0 | #define daap_msur 0x6d737572 |
111 | 0 | #define daap_asda 0x61736461 |
112 | 0 | #define daap_asdm 0x6173646d |
113 | 0 | #define daap_assr 0x61737372 |
114 | 0 | #define daap_assz 0x6173737a |
115 | 0 | #define daap_asst 0x61737374 |
116 | 0 | #define daap_assp 0x61737370 |
117 | 0 | #define daap_astm 0x6173746d |
118 | 0 | #define daap_aeNV 0x61654e56 |
119 | 0 | #define daap_ascd 0x61736364 |
120 | 0 | #define daap_ascs 0x61736373 |
121 | 0 | #define daap_aeSV 0x61655356 |
122 | 0 | #define daap_aePI 0x61655049 |
123 | 0 | #define daap_aeCI 0x61654349 |
124 | 0 | #define daap_aeGI 0x61654749 |
125 | 0 | #define daap_aeAI 0x61654149 |
126 | 0 | #define daap_aeSI 0x61655349 |
127 | 0 | #define daap_aeES 0x61654553 |
128 | | #define daap_aeSU 0x61655355 |
129 | 0 | #define daap_asbo 0x6173626f |
130 | 0 | #define daap_aeGH 0x61654748 |
131 | 0 | #define daap_aeGD 0x61654744 |
132 | 0 | #define daap_aeGE 0x61654745 |
133 | 0 | #define daap_meds 0x6d656473 |
134 | 0 | #define dacp_cmsr 0x636d7372 |
135 | 0 | #define dacp_cant 0x63616e74 |
136 | 0 | #define dacp_cast 0x63617374 |
137 | 0 | #define dacp_cmvo 0x636d766f |
138 | | /*TODO: |
139 | | #define daap_msto 0x6d7374OO utcoffset |
140 | | */ |
141 | | /* uint16 tags */ |
142 | 0 | #define daap_mcty 0x6d637479 |
143 | 0 | #define daap_asbt 0x61736274 |
144 | 0 | #define daap_asbr 0x61736272 |
145 | 0 | #define daap_asdc 0x61736463 |
146 | 0 | #define daap_asdn 0x6173646e |
147 | 0 | #define daap_astc 0x61737463 |
148 | 0 | #define daap_astn 0x6173746e |
149 | 0 | #define daap_asyr 0x61737972 |
150 | 0 | #define daap_ased 0x61736564 |
151 | | /* byte tags */ |
152 | 0 | #define daap_mikd 0x6d696b64 |
153 | 0 | #define daap_msau 0x6d736175 |
154 | 0 | #define daap_msty 0x6d737479 |
155 | 0 | #define daap_asrv 0x61737276 /* XXX: may be uint16 in newer iTunes versions! */ |
156 | 0 | #define daap_asur 0x61737572 |
157 | 0 | #define daap_asdk 0x6173646b |
158 | 0 | #define daap_muty 0x6d757479 |
159 | 0 | #define daap_msas 0x6d736173 |
160 | 0 | #define daap_aeHV 0x61654856 |
161 | 0 | #define daap_aeHD 0x61654844 |
162 | 0 | #define daap_aePC 0x61655043 |
163 | 0 | #define daap_aePP 0x61655050 |
164 | 0 | #define daap_aeMK 0x61654d4b |
165 | 0 | #define daap_aeSG 0x61655347 |
166 | 0 | #define daap_apsm 0x6170736d |
167 | 0 | #define daap_aprm 0x6170726d |
168 | 0 | #define daap_asgp 0x61736770 |
169 | 0 | #define daap_aePS 0x61655053 |
170 | 0 | #define daap_asbk 0x6173626b |
171 | 0 | #define dacp_cafs 0x63616673 |
172 | 0 | #define dacp_caps 0x63617073 |
173 | 0 | #define dacp_carp 0x63617270 |
174 | 0 | #define dacp_cash 0x63617368 |
175 | 0 | #define dacp_cavs 0x63617673 |
176 | | /* boolean tags */ |
177 | 0 | #define daap_mslr 0x6d736c72 |
178 | 0 | #define daap_msal 0x6d73616c |
179 | 0 | #define daap_msup 0x6d737570 |
180 | 0 | #define daap_mspi 0x6d737069 |
181 | 0 | #define daap_msex 0x6d736578 |
182 | 0 | #define daap_msbr 0x6d736272 |
183 | 0 | #define daap_msqy 0x6d737179 |
184 | 0 | #define daap_msix 0x6d736978 |
185 | 0 | #define daap_msrs 0x6d737273 |
186 | 0 | #define daap_asco 0x6173636f |
187 | 0 | #define daap_asdb 0x61736462 |
188 | 0 | #define daap_abpl 0x6162706c |
189 | 0 | #define daap_aeSP 0x61655350 |
190 | | #define daap_ashp 0x61736870 |
191 | | /* version (32-bit)*/ |
192 | 0 | #define daap_mpro 0x6d70726f |
193 | 0 | #define daap_apro 0x6170726f |
194 | | /* now playing */ |
195 | 0 | #define dacp_canp 0x63616e70 |
196 | | |
197 | 0 | #define daap_png 0x89504e47 |
198 | | /* date/time */ |
199 | | /* TODO: |
200 | | #define daap_mstc 0xMMSSTTCC utctime |
201 | | #define daap_asdr ("daap.songdatereleased") |
202 | | #define daap_asdp ("daap.songdatepurchased") |
203 | | */ |
204 | | |
205 | | void proto_register_daap(void); |
206 | | void proto_reg_handoff_daap(void); |
207 | | |
208 | | static dissector_handle_t daap_handle; |
209 | | |
210 | | static dissector_handle_t png_handle; |
211 | | |
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" }, |
366 | | { 0, NULL} |
367 | | }; |
368 | | static value_string_ext vals_tag_code_ext = VALUE_STRING_EXT_INIT(vals_tag_code); |
369 | | |
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; |
384 | | |
385 | | /* Initialize the subtree pointers */ |
386 | | static int ett_daap; |
387 | | static int ett_daap_sub; |
388 | | |
389 | | static expert_field ei_daap_max_recursion_depth_reached; |
390 | | |
391 | | /* Forward declarations */ |
392 | | static void dissect_daap_one_tag(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb); |
393 | | |
394 | | static int |
395 | | dissect_daap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
396 | 0 | { |
397 | 0 | proto_item *ti; |
398 | 0 | proto_tree *daap_tree; |
399 | 0 | unsigned first_tag; |
400 | |
|
401 | 0 | first_tag = tvb_get_ntohl(tvb, 0); |
402 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "DAAP"); |
403 | | |
404 | | /* |
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. |
409 | | */ |
410 | 0 | if (first_tag == daap_png) { |
411 | 0 | call_dissector(png_handle, tvb, pinfo, tree); |
412 | 0 | return tvb_captured_length(tvb); |
413 | 0 | } |
414 | | |
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 |
417 | | */ |
418 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DAAP Response"); |
419 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, " [first tag: %s, size: %d]", |
420 | 0 | tvb_format_text(pinfo->pool, tvb, 0, 4), |
421 | 0 | tvb_get_ntohl(tvb, 4)); |
422 | |
|
423 | 0 | ti = proto_tree_add_item(tree, proto_daap, tvb, 0, -1, ENC_NA); |
424 | 0 | daap_tree = proto_item_add_subtree(ti, ett_daap); |
425 | 0 | dissect_daap_one_tag(daap_tree, pinfo, tvb); |
426 | 0 | return tvb_captured_length(tvb); |
427 | 0 | } |
428 | | |
429 | 0 | #define DAAP_MAX_RECURSION_DEPTH 100 |
430 | | |
431 | | static void |
432 | | // NOLINTNEXTLINE(misc-no-recursion) |
433 | | dissect_daap_one_tag(proto_tree *tree, packet_info *pinfo, tvbuff_t *tvb) |
434 | 0 | { |
435 | 0 | unsigned offset = 0; |
436 | 0 | uint32_t tagname, tagsize; |
437 | 0 | proto_item *tag_ti; |
438 | 0 | proto_tree *tag_tree; |
439 | 0 | tvbuff_t *new_tvb; |
440 | 0 | unsigned recursion_depth = p_get_proto_depth(pinfo, proto_daap); |
441 | |
|
442 | 0 | if (++recursion_depth >= DAAP_MAX_RECURSION_DEPTH) { |
443 | 0 | proto_tree_add_expert(tree, pinfo, &ei_daap_max_recursion_depth_reached, |
444 | 0 | tvb, 0, 0); |
445 | 0 | return; |
446 | 0 | } |
447 | 0 | p_set_proto_depth(pinfo, proto_daap, recursion_depth); |
448 | |
|
449 | 0 | while (offset < tvb_reported_length(tvb)) { |
450 | 0 | tag_tree = proto_tree_add_subtree(tree, tvb, offset, -1, |
451 | 0 | ett_daap_sub, &tag_ti, "Tag:"); |
452 | |
|
453 | 0 | proto_tree_add_item_ret_uint(tag_tree, hf_daap_name, |
454 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN, &tagname); |
455 | 0 | proto_item_append_text(tag_ti, " %s", |
456 | 0 | val_to_str_ext(pinfo->pool, tagname, &vals_tag_code_ext, "Unknown tag (0x%0x)")); |
457 | 0 | offset += 4; |
458 | |
|
459 | 0 | proto_tree_add_item_ret_uint(tag_tree, hf_daap_size, |
460 | 0 | tvb, offset, 4, ENC_BIG_ENDIAN, &tagsize); |
461 | 0 | proto_item_append_text(tag_ti, ", %u byte%c", |
462 | 0 | tagsize, plurality(tagsize, ' ', 's')); |
463 | 0 | offset += 4; |
464 | 0 | proto_item_set_len(tag_ti, 8+tagsize); |
465 | |
|
466 | 0 | if (tagsize > INT_MAX) |
467 | 0 | break; |
468 | | |
469 | 0 | switch (tagname) { |
470 | 0 | case daap_mcon: |
471 | 0 | case daap_msrv: |
472 | 0 | case daap_mccr: |
473 | 0 | case daap_mdcl: |
474 | 0 | case daap_mlog: |
475 | 0 | case daap_mupd: |
476 | 0 | case daap_avdb: |
477 | 0 | case daap_mlcl: |
478 | 0 | case daap_mlit: |
479 | 0 | case daap_mbcl: |
480 | 0 | case daap_adbs: |
481 | 0 | case daap_aply: |
482 | 0 | case daap_apso: |
483 | 0 | case daap_mudl: |
484 | 0 | case daap_abro: |
485 | 0 | case daap_abar: |
486 | 0 | case daap_arsv: |
487 | 0 | case daap_abal: |
488 | 0 | case daap_abcp: |
489 | 0 | case daap_abgn: |
490 | 0 | case daap_prsv: |
491 | 0 | case daap_arif: |
492 | 0 | case dacp_casp: |
493 | 0 | case dacp_cmgt: |
494 | 0 | case dacp_cmst: |
495 | | /* Container tags */ |
496 | 0 | new_tvb = tvb_new_subset_length(tvb, offset, (int)tagsize); |
497 | 0 | dissect_daap_one_tag(tag_tree, pinfo, new_tvb); |
498 | 0 | break; |
499 | | |
500 | 0 | case daap_minm: |
501 | 0 | case daap_msts: |
502 | 0 | case daap_mcnm: |
503 | 0 | case daap_mcna: |
504 | 0 | case daap_asal: |
505 | 0 | case daap_asar: |
506 | 0 | case daap_ascm: |
507 | 0 | case daap_asfm: |
508 | 0 | case daap_aseq: |
509 | 0 | case daap_asgn: |
510 | 0 | case daap_asdt: |
511 | 0 | case daap_asul: |
512 | 0 | case daap_ascp: |
513 | 0 | case daap_asct: |
514 | 0 | case daap_ascn: |
515 | 0 | case daap_aslc: |
516 | 0 | case daap_asky: |
517 | 0 | case daap_aeSN: |
518 | 0 | case daap_aeNN: |
519 | 0 | case daap_aeEN: |
520 | 0 | case daap_assn: |
521 | 0 | case daap_assa: |
522 | 0 | case daap_assl: |
523 | 0 | case daap_assc: |
524 | 0 | case daap_asss: |
525 | 0 | case daap_asaa: |
526 | 0 | case daap_aspu: |
527 | 0 | case daap_aeCR: |
528 | 0 | case dacp_cana: |
529 | 0 | case dacp_cang: |
530 | 0 | case dacp_canl: |
531 | 0 | case dacp_cann: |
532 | | /* Tags contain strings |
533 | | XXX - verify that they're really 7bit ASCII */ |
534 | 0 | proto_tree_add_item(tag_tree, hf_daap_data_string, |
535 | 0 | tvb, offset, tagsize, ENC_ASCII); |
536 | 0 | break; |
537 | | |
538 | 0 | case daap_mper: |
539 | 0 | case daap_aeGR: |
540 | 0 | case daap_aeGU: |
541 | 0 | case daap_asai: |
542 | 0 | case daap_asls: |
543 | 0 | proto_tree_add_item(tag_tree, hf_daap_persistent_id, |
544 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
545 | 0 | break; |
546 | | |
547 | 0 | case daap_mstt: |
548 | 0 | proto_tree_add_item(tag_tree, hf_daap_status, |
549 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
550 | 0 | break; |
551 | | |
552 | 0 | case daap_musr: |
553 | 0 | case daap_msur: |
554 | 0 | proto_tree_add_item(tag_tree, hf_daap_rev, |
555 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
556 | 0 | break; |
557 | | |
558 | 0 | case daap_miid: |
559 | 0 | case daap_mcti: |
560 | 0 | case daap_mpco: |
561 | 0 | case daap_mlid: |
562 | 0 | proto_tree_add_item(tag_tree, hf_daap_id, |
563 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
564 | 0 | break; |
565 | | |
566 | 0 | case daap_mrco: |
567 | 0 | case daap_mtco: |
568 | 0 | case daap_mimc: |
569 | 0 | case daap_msdc: |
570 | 0 | case daap_mctc: |
571 | 0 | proto_tree_add_item(tag_tree, hf_daap_cnt, |
572 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
573 | 0 | break; |
574 | | |
575 | 0 | case daap_mstm: |
576 | 0 | proto_tree_add_item(tag_tree, hf_daap_timeout, |
577 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
578 | 0 | break; |
579 | | |
580 | 0 | case daap_asda: |
581 | 0 | case daap_asdm: |
582 | 0 | case daap_assr: |
583 | 0 | case daap_assz: |
584 | 0 | case daap_asst: |
585 | 0 | case daap_assp: |
586 | 0 | case daap_astm: |
587 | 0 | case daap_aeNV: |
588 | 0 | case daap_ascd: |
589 | 0 | case daap_ascs: |
590 | 0 | case daap_aeSV: |
591 | 0 | case daap_aePI: |
592 | 0 | case daap_aeCI: |
593 | 0 | case daap_aeGI: |
594 | 0 | case daap_aeAI: |
595 | 0 | case daap_aeSI: |
596 | 0 | case daap_aeES: |
597 | 0 | case daap_asbo: |
598 | 0 | case daap_aeGH: |
599 | 0 | case daap_aeGD: |
600 | 0 | case daap_aeGE: |
601 | 0 | case dacp_cant: |
602 | 0 | case dacp_cast: |
603 | 0 | case dacp_cmsr: |
604 | 0 | case dacp_cmvo: |
605 | 0 | case daap_meds: |
606 | | /* Tags contain uint32 |
607 | | XXX - check tagsize here and below */ |
608 | 0 | proto_tree_add_item(tag_tree, hf_daap_data, |
609 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
610 | 0 | break; |
611 | | |
612 | 0 | case daap_mcty: |
613 | 0 | case daap_asbt: |
614 | 0 | case daap_asbr: |
615 | 0 | case daap_asdc: |
616 | 0 | case daap_asdn: |
617 | 0 | case daap_astc: |
618 | 0 | case daap_astn: |
619 | 0 | case daap_asyr: |
620 | 0 | case daap_ased: |
621 | | /* Tags contain uint16 */ |
622 | 0 | proto_tree_add_item(tag_tree, hf_daap_data, |
623 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
624 | 0 | break; |
625 | | |
626 | 0 | case daap_mikd: |
627 | 0 | case daap_msau: |
628 | 0 | case daap_msty: |
629 | 0 | case daap_asrv: |
630 | 0 | case daap_asur: |
631 | 0 | case daap_asdk: |
632 | 0 | case daap_muty: |
633 | 0 | case daap_msas: |
634 | 0 | case daap_aeHV: |
635 | 0 | case daap_aeHD: |
636 | 0 | case daap_aePC: |
637 | 0 | case daap_aePP: |
638 | 0 | case daap_aeMK: |
639 | 0 | case daap_aeSG: |
640 | 0 | case daap_apsm: |
641 | 0 | case daap_aprm: |
642 | 0 | case daap_asgp: |
643 | 0 | case daap_aePS: |
644 | 0 | case dacp_cafs: |
645 | 0 | case dacp_caps: |
646 | 0 | case dacp_carp: |
647 | 0 | case dacp_cash: |
648 | 0 | case dacp_cavs: |
649 | | /* Tags contain uint8 */ |
650 | 0 | proto_tree_add_item(tag_tree, hf_daap_data, |
651 | 0 | tvb, offset, tagsize, ENC_BIG_ENDIAN); |
652 | 0 | break; |
653 | | |
654 | 0 | case daap_mslr: |
655 | 0 | case daap_msal: |
656 | 0 | case daap_msup: |
657 | 0 | case daap_mspi: |
658 | 0 | case daap_msex: |
659 | 0 | case daap_msbr: |
660 | 0 | case daap_msqy: |
661 | 0 | case daap_msix: |
662 | 0 | case daap_msrs: |
663 | 0 | case daap_asco: |
664 | 0 | case daap_asdb: |
665 | 0 | case daap_abpl: |
666 | 0 | case daap_aeSP: |
667 | 0 | case daap_asbk: |
668 | | /* Tags ARE boolean. Data is (uint8), but it seems |
669 | | * the value is always zero. So, if the tag is present |
670 | | * the "bool" is true. |
671 | | */ |
672 | 0 | proto_item_append_text(tag_ti, "; Data: True"); |
673 | 0 | break; |
674 | | |
675 | 0 | case daap_mpro: |
676 | 0 | case daap_apro: |
677 | | /* Tags contain version (uint32) */ |
678 | 0 | proto_item_append_text(tag_ti, "; Version: %d.%d.%d.%d", |
679 | 0 | tvb_get_uint8(tvb, offset), |
680 | 0 | tvb_get_uint8(tvb, offset+1), |
681 | 0 | tvb_get_uint8(tvb, offset+2), |
682 | 0 | tvb_get_uint8(tvb, offset+3)); |
683 | 0 | break; |
684 | | |
685 | 0 | case dacp_canp: |
686 | | /* now playing */ |
687 | | /* bytes 4-7 contain uint32 playlist id */ |
688 | | /* bytes 12-15 contain uint32 track id */ |
689 | |
|
690 | 0 | proto_tree_add_item(tag_tree, hf_daap_playlist_id, |
691 | 0 | tvb, offset+4, 4, ENC_BIG_ENDIAN); |
692 | 0 | proto_tree_add_item(tag_tree, hf_daap_track_id, |
693 | 0 | tvb, offset+12, 4, ENC_BIG_ENDIAN); |
694 | 0 | break; |
695 | | |
696 | 0 | default: |
697 | 0 | break; |
698 | 0 | } |
699 | | |
700 | 0 | offset += tagsize; |
701 | 0 | } |
702 | 0 | } |
703 | | |
704 | | |
705 | | /* Register the protocol with Wireshark */ |
706 | | void |
707 | | proto_register_daap(void) |
708 | 14 | { |
709 | | |
710 | 14 | static hf_register_info hf[] = { |
711 | 14 | { &hf_daap_name, |
712 | 14 | { "Tag name", "daap.name", FT_UINT32, |
713 | 14 | BASE_HEX|BASE_EXT_STRING, &vals_tag_code_ext, 0, NULL, HFILL } |
714 | 14 | }, |
715 | 14 | { &hf_daap_size, |
716 | 14 | { "Tag size", "daap.size", |
717 | 14 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } |
718 | 14 | }, |
719 | 14 | { &hf_daap_data_string, |
720 | 14 | { "Data string", "daap.data_string", |
721 | 14 | FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL } |
722 | 14 | }, |
723 | 14 | { &hf_daap_persistent_id, |
724 | 14 | { "Persistent Id", "daap.persistent_id", |
725 | 14 | FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL } |
726 | 14 | }, |
727 | 14 | { &hf_daap_status, |
728 | 14 | { "Status", "daap.status", |
729 | 14 | FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } |
730 | 14 | }, |
731 | 14 | { &hf_daap_rev, |
732 | 14 | { "Revision", "daap.revision", |
733 | 14 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } |
734 | 14 | }, |
735 | 14 | { &hf_daap_id, |
736 | 14 | { "Id", "daap.id", |
737 | 14 | FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } |
738 | 14 | }, |
739 | 14 | { &hf_daap_cnt, |
740 | 14 | { "Count", "daap.count", |
741 | 14 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } |
742 | 14 | }, |
743 | 14 | { &hf_daap_timeout, |
744 | 14 | { "Timeout (seconds)", "daap.timeout", |
745 | 14 | FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL } |
746 | 14 | }, |
747 | | /* this will hold data for the tags that contain |
748 | | 32, 16 or 8 bits of payload */ |
749 | 14 | { &hf_daap_data, |
750 | 14 | { "Data", "daap.data", |
751 | 14 | FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } |
752 | 14 | }, |
753 | 14 | { &hf_daap_playlist_id, |
754 | 14 | { "Playlist Id", "daap.playlist_id", |
755 | 14 | FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } |
756 | 14 | }, |
757 | 14 | { &hf_daap_track_id, |
758 | 14 | { "Track Id", "daap.track_id", |
759 | 14 | FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL } |
760 | 14 | } |
761 | 14 | }; |
762 | | |
763 | 14 | static int *ett[] = { |
764 | 14 | &ett_daap, |
765 | 14 | &ett_daap_sub, |
766 | 14 | }; |
767 | | |
768 | 14 | expert_module_t *expert_daap; |
769 | | |
770 | 14 | static ei_register_info ei[] = { |
771 | 14 | { &ei_daap_max_recursion_depth_reached, { "daap.max_recursion_depth_reached", |
772 | 14 | PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached - stop decoding", EXPFILL }} |
773 | 14 | }; |
774 | | |
775 | 14 | proto_daap = proto_register_protocol("Digital Audio Access Protocol", |
776 | 14 | "DAAP", "daap"); |
777 | | |
778 | 14 | expert_daap = expert_register_protocol(proto_daap); |
779 | 14 | expert_register_field_array(expert_daap, ei, array_length(ei)); |
780 | | |
781 | 14 | proto_register_field_array(proto_daap, hf, array_length(hf)); |
782 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
783 | | |
784 | 14 | daap_handle = register_dissector("daap", dissect_daap, proto_daap); |
785 | 14 | } |
786 | | |
787 | | void |
788 | | proto_reg_handoff_daap(void) |
789 | 14 | { |
790 | 14 | http_tcp_port_add(TCP_PORT_DAAP); |
791 | 14 | dissector_add_string("media_type", "application/x-dmap-tagged", daap_handle); |
792 | | |
793 | 14 | png_handle = find_dissector_add_dependency("png", proto_daap); |
794 | 14 | } |
795 | | |
796 | | /* |
797 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
798 | | * |
799 | | * Local Variables: |
800 | | * c-basic-offset: 3 |
801 | | * tab-width: 8 |
802 | | * indent-tabs-mode: nil |
803 | | * End: |
804 | | * |
805 | | * ex: set shiftwidth=3 tabstop=8 expandtab: |
806 | | * :indentSize=3:tabSize=8:noTabs=true: |
807 | | */ |