/src/wireshark/epan/dissectors/packet-mpeg-audio.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Do not modify this file. Changes will be overwritten. */ |
2 | | /* Generated automatically by the ASN.1 to Wireshark dissector compiler */ |
3 | | /* packet-mpeg-audio.c */ |
4 | | /* asn2wrs.py -q -L -p mpeg-audio -c ./mpeg-audio.cnf -s ./packet-mpeg-audio-template -D . -O ../.. mpeg-audio.asn */ |
5 | | |
6 | | /* MPEG audio packet decoder. |
7 | | * Written by Shaun Jackman <sjackman@gmail.com>. |
8 | | * Copyright 2007 Shaun Jackman |
9 | | * |
10 | | * Wireshark - Network traffic analyzer |
11 | | * By Gerald Combs <gerald@wireshark.org> |
12 | | * |
13 | | * SPDX-License-Identifier: GPL-2.0-or-later |
14 | | */ |
15 | | |
16 | | #include "config.h" |
17 | | |
18 | | #include <epan/packet.h> |
19 | | #include <epan/asn1.h> |
20 | | |
21 | | #include <wsutil/mpeg-audio.h> |
22 | | #include <wsutil/array.h> |
23 | | |
24 | | #include "packet-per.h" |
25 | | |
26 | | static int hf_mpeg_audio_sync; /* BIT_STRING_SIZE_11 */ |
27 | | static int hf_mpeg_audio_version; /* T_version */ |
28 | | static int hf_mpeg_audio_layer; /* T_layer */ |
29 | | static int hf_mpeg_audio_protection; /* T_protection */ |
30 | | static int hf_mpeg_audio_bitrate; /* INTEGER_0_15 */ |
31 | | static int hf_mpeg_audio_frequency; /* INTEGER_0_3 */ |
32 | | static int hf_mpeg_audio_padding; /* BOOLEAN */ |
33 | | static int hf_mpeg_audio_private; /* BOOLEAN */ |
34 | | static int hf_mpeg_audio_channel_mode; /* T_channel_mode */ |
35 | | static int hf_mpeg_audio_mode_extension; /* INTEGER_0_3 */ |
36 | | static int hf_mpeg_audio_copyright; /* BOOLEAN */ |
37 | | static int hf_mpeg_audio_original; /* BOOLEAN */ |
38 | | static int hf_mpeg_audio_emphasis; /* T_emphasis */ |
39 | | static int hf_mpeg_audio_tag; /* OCTET_STRING_SIZE_3 */ |
40 | | static int hf_mpeg_audio_title; /* OCTET_STRING_SIZE_30 */ |
41 | | static int hf_mpeg_audio_artist; /* OCTET_STRING_SIZE_30 */ |
42 | | static int hf_mpeg_audio_album; /* OCTET_STRING_SIZE_30 */ |
43 | | static int hf_mpeg_audio_year; /* OCTET_STRING_SIZE_4 */ |
44 | | static int hf_mpeg_audio_comment; /* OCTET_STRING_SIZE_28 */ |
45 | | static int hf_mpeg_audio_must_be_zero; /* INTEGER_0_255 */ |
46 | | static int hf_mpeg_audio_track; /* INTEGER_0_255 */ |
47 | | static int hf_mpeg_audio_genre; /* T_genre */ |
48 | | static int ett_mpeg_audio_Audio; |
49 | | static int ett_mpeg_audio_ID3v1; |
50 | | |
51 | | |
52 | | static int |
53 | 0 | dissect_mpeg_audio_BIT_STRING_SIZE_11(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
54 | 0 | offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index, |
55 | 0 | 11, 11, false, NULL, 0, NULL, NULL); |
56 | |
|
57 | 0 | return offset; |
58 | 0 | } |
59 | | |
60 | | |
61 | | static const value_string mpeg_audio_T_version_vals[] = { |
62 | | { 0, "mpeg-2-5" }, |
63 | | { 1, "reserved" }, |
64 | | { 2, "mpeg-2" }, |
65 | | { 3, "mpeg-1" }, |
66 | | { 0, NULL } |
67 | | }; |
68 | | |
69 | | |
70 | | static int |
71 | 0 | dissect_mpeg_audio_T_version(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
72 | 0 | offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, |
73 | 0 | 4, NULL, false, 0, NULL); |
74 | |
|
75 | 0 | return offset; |
76 | 0 | } |
77 | | |
78 | | |
79 | | static const value_string mpeg_audio_T_layer_vals[] = { |
80 | | { 0, "reserved" }, |
81 | | { 1, "layer-3" }, |
82 | | { 2, "layer-2" }, |
83 | | { 3, "layer-1" }, |
84 | | { 0, NULL } |
85 | | }; |
86 | | |
87 | | |
88 | | static int |
89 | 0 | dissect_mpeg_audio_T_layer(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
90 | 0 | offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, |
91 | 0 | 4, NULL, false, 0, NULL); |
92 | |
|
93 | 0 | return offset; |
94 | 0 | } |
95 | | |
96 | | |
97 | | static const value_string mpeg_audio_T_protection_vals[] = { |
98 | | { 0, "crc" }, |
99 | | { 1, "none" }, |
100 | | { 0, NULL } |
101 | | }; |
102 | | |
103 | | |
104 | | static int |
105 | 0 | dissect_mpeg_audio_T_protection(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
106 | 0 | offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, |
107 | 0 | 2, NULL, false, 0, NULL); |
108 | |
|
109 | 0 | return offset; |
110 | 0 | } |
111 | | |
112 | | |
113 | | |
114 | | static int |
115 | 0 | dissect_mpeg_audio_INTEGER_0_15(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
116 | 0 | offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, |
117 | 0 | 0U, 15U, NULL, false); |
118 | |
|
119 | 0 | return offset; |
120 | 0 | } |
121 | | |
122 | | |
123 | | |
124 | | static int |
125 | 0 | dissect_mpeg_audio_INTEGER_0_3(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
126 | 0 | offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, |
127 | 0 | 0U, 3U, NULL, false); |
128 | |
|
129 | 0 | return offset; |
130 | 0 | } |
131 | | |
132 | | |
133 | | |
134 | | static int |
135 | 0 | dissect_mpeg_audio_BOOLEAN(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
136 | 0 | offset = dissect_per_boolean(tvb, offset, actx, tree, hf_index, NULL); |
137 | |
|
138 | 0 | return offset; |
139 | 0 | } |
140 | | |
141 | | |
142 | | static const value_string mpeg_audio_T_channel_mode_vals[] = { |
143 | | { 0, "stereo" }, |
144 | | { 1, "joint-stereo" }, |
145 | | { 2, "dual-channel" }, |
146 | | { 3, "single-channel" }, |
147 | | { 0, NULL } |
148 | | }; |
149 | | |
150 | | |
151 | | static int |
152 | 0 | dissect_mpeg_audio_T_channel_mode(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
153 | 0 | offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, |
154 | 0 | 4, NULL, false, 0, NULL); |
155 | |
|
156 | 0 | return offset; |
157 | 0 | } |
158 | | |
159 | | |
160 | | static const value_string mpeg_audio_T_emphasis_vals[] = { |
161 | | { 0, "none" }, |
162 | | { 1, "em-50-15-ms" }, |
163 | | { 2, "reserved" }, |
164 | | { 3, "ccit-j-17" }, |
165 | | { 0, NULL } |
166 | | }; |
167 | | |
168 | | |
169 | | static int |
170 | 0 | dissect_mpeg_audio_T_emphasis(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
171 | 0 | offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index, |
172 | 0 | 4, NULL, false, 0, NULL); |
173 | |
|
174 | 0 | return offset; |
175 | 0 | } |
176 | | |
177 | | |
178 | | static const per_sequence_t Audio_sequence[] = { |
179 | | { &hf_mpeg_audio_sync , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BIT_STRING_SIZE_11 }, |
180 | | { &hf_mpeg_audio_version , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_version }, |
181 | | { &hf_mpeg_audio_layer , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_layer }, |
182 | | { &hf_mpeg_audio_protection, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_protection }, |
183 | | { &hf_mpeg_audio_bitrate , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_15 }, |
184 | | { &hf_mpeg_audio_frequency, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_3 }, |
185 | | { &hf_mpeg_audio_padding , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN }, |
186 | | { &hf_mpeg_audio_private , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN }, |
187 | | { &hf_mpeg_audio_channel_mode, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_channel_mode }, |
188 | | { &hf_mpeg_audio_mode_extension, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_3 }, |
189 | | { &hf_mpeg_audio_copyright, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN }, |
190 | | { &hf_mpeg_audio_original , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN }, |
191 | | { &hf_mpeg_audio_emphasis , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_emphasis }, |
192 | | { NULL, 0, 0, NULL } |
193 | | }; |
194 | | |
195 | | static int |
196 | 0 | dissect_mpeg_audio_Audio(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
197 | 0 | offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index, |
198 | 0 | ett_mpeg_audio_Audio, Audio_sequence); |
199 | |
|
200 | 0 | return offset; |
201 | 0 | } |
202 | | |
203 | | |
204 | | |
205 | | static int |
206 | 0 | dissect_mpeg_audio_OCTET_STRING_SIZE_3(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
207 | 0 | offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, |
208 | 0 | 3, 3, false, NULL); |
209 | |
|
210 | 0 | return offset; |
211 | 0 | } |
212 | | |
213 | | |
214 | | |
215 | | static int |
216 | 0 | dissect_mpeg_audio_OCTET_STRING_SIZE_30(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
217 | 0 | offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, |
218 | 0 | 30, 30, false, NULL); |
219 | |
|
220 | 0 | return offset; |
221 | 0 | } |
222 | | |
223 | | |
224 | | |
225 | | static int |
226 | 0 | dissect_mpeg_audio_OCTET_STRING_SIZE_4(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
227 | 0 | offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, |
228 | 0 | 4, 4, false, NULL); |
229 | |
|
230 | 0 | return offset; |
231 | 0 | } |
232 | | |
233 | | |
234 | | |
235 | | static int |
236 | 0 | dissect_mpeg_audio_OCTET_STRING_SIZE_28(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
237 | 0 | offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index, |
238 | 0 | 28, 28, false, NULL); |
239 | |
|
240 | 0 | return offset; |
241 | 0 | } |
242 | | |
243 | | |
244 | | |
245 | | static int |
246 | 0 | dissect_mpeg_audio_INTEGER_0_255(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
247 | 0 | offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, |
248 | 0 | 0U, 255U, NULL, false); |
249 | |
|
250 | 0 | return offset; |
251 | 0 | } |
252 | | |
253 | | |
254 | | static const value_string mpeg_audio_T_genre_vals[] = { |
255 | | { 0, "blues" }, |
256 | | { 1, "classic-rock" }, |
257 | | { 2, "country" }, |
258 | | { 3, "dance" }, |
259 | | { 4, "disco" }, |
260 | | { 5, "funk" }, |
261 | | { 6, "grunge" }, |
262 | | { 7, "hip-hop" }, |
263 | | { 8, "jazz" }, |
264 | | { 9, "metal" }, |
265 | | { 10, "new-age" }, |
266 | | { 11, "oldies" }, |
267 | | { 12, "other" }, |
268 | | { 13, "pop" }, |
269 | | { 14, "r-and-b" }, |
270 | | { 15, "rap" }, |
271 | | { 16, "reggae" }, |
272 | | { 17, "rock" }, |
273 | | { 18, "techno" }, |
274 | | { 19, "industrial" }, |
275 | | { 20, "alternative" }, |
276 | | { 21, "ska" }, |
277 | | { 22, "death-metal" }, |
278 | | { 23, "pranks" }, |
279 | | { 24, "soundtrack" }, |
280 | | { 25, "euro-techno" }, |
281 | | { 26, "ambient" }, |
282 | | { 27, "trip-hop" }, |
283 | | { 28, "vocal" }, |
284 | | { 29, "jazz-and-funk" }, |
285 | | { 30, "fusion" }, |
286 | | { 31, "trance" }, |
287 | | { 32, "classical" }, |
288 | | { 33, "instrumental" }, |
289 | | { 34, "acid" }, |
290 | | { 35, "house" }, |
291 | | { 36, "game" }, |
292 | | { 37, "sound-clip" }, |
293 | | { 38, "gospel" }, |
294 | | { 39, "noise" }, |
295 | | { 40, "alternative-rock" }, |
296 | | { 41, "bass" }, |
297 | | { 42, "soul" }, |
298 | | { 43, "punk" }, |
299 | | { 44, "space" }, |
300 | | { 45, "meditative" }, |
301 | | { 46, "instrumental-pop" }, |
302 | | { 47, "instrumental-rock" }, |
303 | | { 48, "ethnic" }, |
304 | | { 49, "gothic" }, |
305 | | { 50, "darkwave" }, |
306 | | { 51, "techno-industrial" }, |
307 | | { 52, "electronic" }, |
308 | | { 53, "pop-folk" }, |
309 | | { 54, "eurodance" }, |
310 | | { 55, "dream" }, |
311 | | { 56, "southern-rock" }, |
312 | | { 57, "comedy" }, |
313 | | { 58, "cult" }, |
314 | | { 59, "gangsta" }, |
315 | | { 60, "top-40" }, |
316 | | { 61, "christian-rap" }, |
317 | | { 62, "pop-funk" }, |
318 | | { 63, "jungle" }, |
319 | | { 64, "native-american" }, |
320 | | { 65, "cabaret" }, |
321 | | { 66, "new-wave" }, |
322 | | { 67, "psychedelic" }, |
323 | | { 68, "rave" }, |
324 | | { 69, "showtunes" }, |
325 | | { 70, "trailer" }, |
326 | | { 71, "lo-fi" }, |
327 | | { 72, "tribal" }, |
328 | | { 73, "acid-punk" }, |
329 | | { 74, "acid-jazz" }, |
330 | | { 75, "polka" }, |
331 | | { 76, "retro" }, |
332 | | { 77, "musical" }, |
333 | | { 78, "rock-and-roll" }, |
334 | | { 79, "hard-rock" }, |
335 | | { 80, "folk" }, |
336 | | { 81, "folk-rock" }, |
337 | | { 82, "national-folk" }, |
338 | | { 83, "swing" }, |
339 | | { 84, "fast-fusion" }, |
340 | | { 85, "bebob" }, |
341 | | { 86, "latin" }, |
342 | | { 87, "revival" }, |
343 | | { 88, "celtic" }, |
344 | | { 89, "bluegrass" }, |
345 | | { 90, "avantgarde" }, |
346 | | { 91, "gothic-rock" }, |
347 | | { 92, "progressive-rock" }, |
348 | | { 93, "psychedelic-rock" }, |
349 | | { 94, "symphonic-rock" }, |
350 | | { 95, "slow-rock" }, |
351 | | { 96, "big-band" }, |
352 | | { 97, "chorus" }, |
353 | | { 98, "easy-listening" }, |
354 | | { 99, "acoustic" }, |
355 | | { 100, "humour" }, |
356 | | { 101, "speech" }, |
357 | | { 102, "chanson" }, |
358 | | { 103, "opera" }, |
359 | | { 104, "chamber-music" }, |
360 | | { 105, "sonata" }, |
361 | | { 106, "symphony" }, |
362 | | { 107, "booty-bass" }, |
363 | | { 108, "primus" }, |
364 | | { 109, "porn-groove" }, |
365 | | { 110, "satire" }, |
366 | | { 111, "slow-jam" }, |
367 | | { 112, "club" }, |
368 | | { 113, "tango" }, |
369 | | { 114, "samba" }, |
370 | | { 115, "folklore" }, |
371 | | { 116, "ballad" }, |
372 | | { 117, "power-ballad" }, |
373 | | { 118, "rhythmic-soul" }, |
374 | | { 119, "freestyle" }, |
375 | | { 120, "duet" }, |
376 | | { 121, "punk-rock" }, |
377 | | { 122, "drum-solo" }, |
378 | | { 123, "a-cappella" }, |
379 | | { 124, "euro-house" }, |
380 | | { 125, "dance-hall" }, |
381 | | { 0, NULL } |
382 | | }; |
383 | | |
384 | | |
385 | | static int |
386 | 0 | dissect_mpeg_audio_T_genre(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
387 | 0 | offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index, |
388 | 0 | 0U, 255U, NULL, false); |
389 | |
|
390 | 0 | return offset; |
391 | 0 | } |
392 | | |
393 | | |
394 | | static const per_sequence_t ID3v1_sequence[] = { |
395 | | { &hf_mpeg_audio_tag , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_3 }, |
396 | | { &hf_mpeg_audio_title , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_30 }, |
397 | | { &hf_mpeg_audio_artist , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_30 }, |
398 | | { &hf_mpeg_audio_album , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_30 }, |
399 | | { &hf_mpeg_audio_year , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_4 }, |
400 | | { &hf_mpeg_audio_comment , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_28 }, |
401 | | { &hf_mpeg_audio_must_be_zero, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_255 }, |
402 | | { &hf_mpeg_audio_track , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_255 }, |
403 | | { &hf_mpeg_audio_genre , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_genre }, |
404 | | { NULL, 0, 0, NULL } |
405 | | }; |
406 | | |
407 | | static int |
408 | 0 | dissect_mpeg_audio_ID3v1(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) { |
409 | 0 | offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index, |
410 | 0 | ett_mpeg_audio_ID3v1, ID3v1_sequence); |
411 | |
|
412 | 0 | return offset; |
413 | 0 | } |
414 | | |
415 | | |
416 | | void proto_register_mpeg_audio(void); |
417 | | void proto_reg_handoff_mpeg_audio(void); |
418 | | |
419 | | dissector_handle_t mpeg_audio_handle; |
420 | | |
421 | | static int proto_mpeg_audio; |
422 | | static dissector_handle_t id3v2_handle; |
423 | | |
424 | | static int hf_mpeg_audio_header; |
425 | | static int hf_mpeg_audio_data; |
426 | | static int hf_mpeg_audio_padbytes; |
427 | | static int hf_id3v1; |
428 | | |
429 | | static int ett_mpeg_audio; |
430 | | |
431 | | static bool |
432 | | test_mpeg_audio(tvbuff_t *tvb, int offset) |
433 | 0 | { |
434 | 0 | uint32_t hdr; |
435 | 0 | struct mpa mpa; |
436 | |
|
437 | 0 | if (!tvb_bytes_exist(tvb, offset, 4)) |
438 | 0 | return false; |
439 | 0 | if (tvb_strneql(tvb, offset, "TAG", 3) == 0) |
440 | 0 | return true; |
441 | 0 | if (tvb_strneql(tvb, offset, "ID3", 3) == 0) |
442 | 0 | return true; |
443 | | |
444 | 0 | hdr = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN); |
445 | 0 | MPA_UNMARSHAL(&mpa, hdr); |
446 | 0 | return MPA_VALID(&mpa); |
447 | 0 | } |
448 | | |
449 | | static int |
450 | | mpeg_resync(tvbuff_t *tvb, int offset) |
451 | 0 | { |
452 | 0 | uint32_t hdr; |
453 | 0 | struct mpa mpa; |
454 | | |
455 | | /* This only looks to resync on another frame; it doesn't |
456 | | * look for an ID3 tag. |
457 | | */ |
458 | 0 | offset = tvb_find_uint8(tvb, offset, -1, '\xff'); |
459 | 0 | while (offset != -1 && tvb_bytes_exist(tvb, offset, 4)) { |
460 | 0 | hdr = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN); |
461 | 0 | MPA_UNMARSHAL(&mpa, hdr); |
462 | 0 | if (MPA_VALID(&mpa)) { |
463 | 0 | return offset; |
464 | 0 | } |
465 | 0 | offset = tvb_find_uint8(tvb, offset + 1, -1, '\xff'); |
466 | 0 | } |
467 | 0 | return tvb_reported_length(tvb); |
468 | 0 | } |
469 | | |
470 | | static int |
471 | | dissect_mpeg_audio_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
472 | 0 | { |
473 | 0 | uint32_t h; |
474 | 0 | struct mpa mpa; |
475 | 0 | int data_size = 0; |
476 | 0 | asn1_ctx_t asn1_ctx; |
477 | 0 | int offset = 0; |
478 | 0 | static const char *version_names[] = { "1", "2", "2.5" }; |
479 | |
|
480 | 0 | if (!tvb_bytes_exist(tvb, 0, 4)) |
481 | 0 | return 0; |
482 | | |
483 | 0 | h = tvb_get_ntohl(tvb, 0); |
484 | 0 | MPA_UNMARSHAL(&mpa, h); |
485 | 0 | if (!MPA_SYNC_VALID(&mpa) || !MPA_VERSION_VALID(&mpa) || !MPA_LAYER_VALID(&mpa)) { |
486 | 0 | return 0; |
487 | 0 | } |
488 | | |
489 | 0 | col_add_fstr(pinfo->cinfo, COL_PROTOCOL, |
490 | 0 | "MPEG-%s", version_names[mpa_version(&mpa)]); |
491 | 0 | col_add_fstr(pinfo->cinfo, COL_INFO, |
492 | 0 | "Audio Layer %d", mpa_layer(&mpa) + 1); |
493 | 0 | if (MPA_BITRATE_VALID(&mpa) && MPA_FREQUENCY_VALID(&mpa)) { |
494 | 0 | data_size = (int)(MPA_DATA_BYTES(&mpa) - sizeof mpa); |
495 | 0 | col_append_fstr(pinfo->cinfo, COL_INFO, |
496 | 0 | ", %d kb/s, %g kHz", |
497 | 0 | mpa_bitrate(&mpa) / 1000, |
498 | 0 | mpa_frequency(&mpa) / (float)1000); |
499 | 0 | } |
500 | |
|
501 | 0 | asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, true, pinfo); |
502 | 0 | offset = dissect_mpeg_audio_Audio(tvb, offset, &asn1_ctx, |
503 | 0 | tree, hf_mpeg_audio_header); |
504 | 0 | if (data_size > 0) { |
505 | 0 | unsigned int padding; |
506 | |
|
507 | 0 | proto_tree_add_item(tree, hf_mpeg_audio_data, tvb, |
508 | 0 | offset / 8, data_size, ENC_NA); |
509 | 0 | offset += data_size * 8; |
510 | 0 | padding = mpa_padding(&mpa); |
511 | 0 | if (padding > 0) { |
512 | 0 | proto_tree_add_item(tree, hf_mpeg_audio_padbytes, tvb, |
513 | 0 | offset / 8, padding, ENC_NA); |
514 | 0 | offset += padding * 8; |
515 | 0 | } |
516 | 0 | } |
517 | 0 | return offset / 8; |
518 | 0 | } |
519 | | |
520 | | static int |
521 | | dissect_id3v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) |
522 | 0 | { |
523 | 0 | asn1_ctx_t asn1_ctx; |
524 | |
|
525 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v1"); |
526 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
527 | 0 | asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, true, pinfo); |
528 | 0 | return dissect_mpeg_audio_ID3v1(tvb, 0, &asn1_ctx, |
529 | 0 | tree, hf_id3v1); |
530 | 0 | } |
531 | | |
532 | | static int |
533 | | dissect_mpeg_audio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
534 | 0 | { |
535 | 0 | proto_item *ti; |
536 | 0 | proto_tree *mpeg_audio_tree; |
537 | |
|
538 | 0 | int magic, offset = 0; |
539 | 0 | uint32_t frame_len; |
540 | 0 | tvbuff_t *next_tvb; |
541 | |
|
542 | 0 | ti = proto_tree_add_item(tree, proto_mpeg_audio, tvb, offset, -1, ENC_NA); |
543 | 0 | mpeg_audio_tree = proto_item_add_subtree(ti, ett_mpeg_audio); |
544 | 0 | while (tvb_reported_length_remaining(tvb, offset) >= 4) { |
545 | 0 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
546 | 0 | magic = tvb_get_ntoh24(next_tvb, 0); |
547 | 0 | switch (magic) { |
548 | 0 | case 0x544147: /* TAG */ |
549 | 0 | offset += dissect_id3v1(next_tvb, pinfo, mpeg_audio_tree); |
550 | 0 | break; |
551 | 0 | case 0x494433: /* ID3 */ |
552 | 0 | offset += call_dissector(id3v2_handle, tvb, pinfo, mpeg_audio_tree); |
553 | 0 | break; |
554 | 0 | default: |
555 | 0 | frame_len = dissect_mpeg_audio_frame(next_tvb, pinfo, mpeg_audio_tree); |
556 | 0 | if (frame_len == 0) { |
557 | 0 | frame_len = mpeg_resync(next_tvb, 0); |
558 | 0 | } |
559 | 0 | offset += frame_len; |
560 | 0 | } |
561 | 0 | } |
562 | 0 | return tvb_reported_length(tvb); |
563 | 0 | } |
564 | | |
565 | | static bool |
566 | | dissect_mpeg_audio_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) |
567 | 0 | { |
568 | 0 | if (!test_mpeg_audio(tvb, 0)) { |
569 | 0 | return false; |
570 | 0 | } |
571 | 0 | dissect_mpeg_audio(tvb, pinfo, tree, data); |
572 | 0 | return true; |
573 | 0 | } |
574 | | |
575 | | void |
576 | | proto_register_mpeg_audio(void) |
577 | 14 | { |
578 | 14 | static hf_register_info hf[] = { |
579 | 14 | { &hf_mpeg_audio_sync, |
580 | 14 | { "sync", "mpeg-audio.sync", |
581 | 14 | FT_BYTES, BASE_NONE, NULL, 0, |
582 | 14 | "BIT_STRING_SIZE_11", HFILL }}, |
583 | 14 | { &hf_mpeg_audio_version, |
584 | 14 | { "version", "mpeg-audio.version", |
585 | 14 | FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_version_vals), 0, |
586 | 14 | NULL, HFILL }}, |
587 | 14 | { &hf_mpeg_audio_layer, |
588 | 14 | { "layer", "mpeg-audio.layer", |
589 | 14 | FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_layer_vals), 0, |
590 | 14 | NULL, HFILL }}, |
591 | 14 | { &hf_mpeg_audio_protection, |
592 | 14 | { "protection", "mpeg-audio.protection", |
593 | 14 | FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_protection_vals), 0, |
594 | 14 | NULL, HFILL }}, |
595 | 14 | { &hf_mpeg_audio_bitrate, |
596 | 14 | { "bitrate", "mpeg-audio.bitrate", |
597 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
598 | 14 | "INTEGER_0_15", HFILL }}, |
599 | 14 | { &hf_mpeg_audio_frequency, |
600 | 14 | { "frequency", "mpeg-audio.frequency", |
601 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
602 | 14 | "INTEGER_0_3", HFILL }}, |
603 | 14 | { &hf_mpeg_audio_padding, |
604 | 14 | { "padding", "mpeg-audio.padding", |
605 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
606 | 14 | "BOOLEAN", HFILL }}, |
607 | 14 | { &hf_mpeg_audio_private, |
608 | 14 | { "private", "mpeg-audio.private", |
609 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
610 | 14 | "BOOLEAN", HFILL }}, |
611 | 14 | { &hf_mpeg_audio_channel_mode, |
612 | 14 | { "channel-mode", "mpeg-audio.channel_mode", |
613 | 14 | FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_channel_mode_vals), 0, |
614 | 14 | NULL, HFILL }}, |
615 | 14 | { &hf_mpeg_audio_mode_extension, |
616 | 14 | { "mode-extension", "mpeg-audio.mode_extension", |
617 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
618 | 14 | "INTEGER_0_3", HFILL }}, |
619 | 14 | { &hf_mpeg_audio_copyright, |
620 | 14 | { "copyright", "mpeg-audio.copyright", |
621 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
622 | 14 | "BOOLEAN", HFILL }}, |
623 | 14 | { &hf_mpeg_audio_original, |
624 | 14 | { "original", "mpeg-audio.original", |
625 | 14 | FT_BOOLEAN, BASE_NONE, NULL, 0, |
626 | 14 | "BOOLEAN", HFILL }}, |
627 | 14 | { &hf_mpeg_audio_emphasis, |
628 | 14 | { "emphasis", "mpeg-audio.emphasis", |
629 | 14 | FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_emphasis_vals), 0, |
630 | 14 | NULL, HFILL }}, |
631 | 14 | { &hf_mpeg_audio_tag, |
632 | 14 | { "tag", "mpeg-audio.tag", |
633 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
634 | 14 | "OCTET_STRING_SIZE_3", HFILL }}, |
635 | 14 | { &hf_mpeg_audio_title, |
636 | 14 | { "title", "mpeg-audio.title", |
637 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
638 | 14 | "OCTET_STRING_SIZE_30", HFILL }}, |
639 | 14 | { &hf_mpeg_audio_artist, |
640 | 14 | { "artist", "mpeg-audio.artist", |
641 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
642 | 14 | "OCTET_STRING_SIZE_30", HFILL }}, |
643 | 14 | { &hf_mpeg_audio_album, |
644 | 14 | { "album", "mpeg-audio.album", |
645 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
646 | 14 | "OCTET_STRING_SIZE_30", HFILL }}, |
647 | 14 | { &hf_mpeg_audio_year, |
648 | 14 | { "year", "mpeg-audio.year", |
649 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
650 | 14 | "OCTET_STRING_SIZE_4", HFILL }}, |
651 | 14 | { &hf_mpeg_audio_comment, |
652 | 14 | { "comment", "mpeg-audio.comment", |
653 | 14 | FT_STRING, BASE_NONE, NULL, 0, |
654 | 14 | "OCTET_STRING_SIZE_28", HFILL }}, |
655 | 14 | { &hf_mpeg_audio_must_be_zero, |
656 | 14 | { "must-be-zero", "mpeg-audio.must_be_zero", |
657 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
658 | 14 | "INTEGER_0_255", HFILL }}, |
659 | 14 | { &hf_mpeg_audio_track, |
660 | 14 | { "track", "mpeg-audio.track", |
661 | 14 | FT_UINT32, BASE_DEC, NULL, 0, |
662 | 14 | "INTEGER_0_255", HFILL }}, |
663 | 14 | { &hf_mpeg_audio_genre, |
664 | 14 | { "genre", "mpeg-audio.genre", |
665 | 14 | FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_genre_vals), 0, |
666 | 14 | NULL, HFILL }}, |
667 | 14 | { &hf_mpeg_audio_header, |
668 | 14 | { "Frame Header", "mpeg-audio.header", |
669 | 14 | FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, |
670 | 14 | { &hf_mpeg_audio_data, |
671 | 14 | { "Data", "mpeg-audio.data", |
672 | 14 | FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, |
673 | 14 | { &hf_mpeg_audio_padbytes, |
674 | 14 | { "Padding", "mpeg-audio.padbytes", |
675 | 14 | FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, |
676 | | |
677 | 14 | { &hf_id3v1, |
678 | 14 | { "ID3v1", "mpeg-audio.id3v1", |
679 | 14 | FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, |
680 | 14 | }; |
681 | | |
682 | 14 | static int *ett[] = { |
683 | 14 | &ett_mpeg_audio, |
684 | 14 | &ett_mpeg_audio_Audio, |
685 | 14 | &ett_mpeg_audio_ID3v1, |
686 | 14 | }; |
687 | | |
688 | 14 | proto_mpeg_audio = proto_register_protocol("Moving Picture Experts Group Audio", "MPEG Audio", "mpeg-audio"); |
689 | 14 | proto_register_field_array(proto_mpeg_audio, hf, array_length(hf)); |
690 | 14 | proto_register_subtree_array(ett, array_length(ett)); |
691 | | |
692 | 14 | mpeg_audio_handle = register_dissector("mpeg-audio", dissect_mpeg_audio, proto_mpeg_audio); |
693 | 14 | } |
694 | | |
695 | | void |
696 | | proto_reg_handoff_mpeg_audio(void) |
697 | 14 | { |
698 | 14 | dissector_add_string("media_type", "audio/mpeg", mpeg_audio_handle); |
699 | | /* "audio/mp3" used by Chrome before 2020 */ |
700 | | /* https://chromium.googlesource.com/chromium/src/+/842f46a95f49e24534ad35c7a71e5c425d426550 */ |
701 | 14 | dissector_add_string("media_type", "audio/mp3", mpeg_audio_handle); |
702 | | |
703 | 14 | heur_dissector_add("mpeg", dissect_mpeg_audio_heur, "MPEG Audio", "mpeg_audio", proto_mpeg_audio, HEURISTIC_ENABLE); |
704 | | |
705 | 14 | id3v2_handle = find_dissector("id3v2"); |
706 | 14 | } |