Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / asn1 / mpeg-audio / packet-mpeg-audio-template.c
blob8b1c0c373f4a66b7271efbc2416c4cf903c778f5
1 /* MPEG audio packet decoder.
2 * Written by Shaun Jackman <sjackman@gmail.com>.
3 * Copyright 2007 Shaun Jackman
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
11 #include "config.h"
13 #include <epan/packet.h>
14 #include <epan/asn1.h>
16 #include <wsutil/mpeg-audio.h>
17 #include <wsutil/array.h>
19 #include "packet-per.h"
21 #include "packet-mpeg-audio-hf.c"
22 #include "packet-mpeg-audio-ett.c"
23 #include "packet-mpeg-audio-fn.c"
25 void proto_register_mpeg_audio(void);
26 void proto_reg_handoff_mpeg_audio(void);
28 dissector_handle_t mpeg_audio_handle;
30 static int proto_mpeg_audio;
31 static dissector_handle_t id3v2_handle;
33 static int hf_mpeg_audio_header;
34 static int hf_mpeg_audio_data;
35 static int hf_mpeg_audio_padbytes;
36 static int hf_id3v1;
38 static int ett_mpeg_audio;
40 static bool
41 test_mpeg_audio(tvbuff_t *tvb, int offset)
43 uint32_t hdr;
44 struct mpa mpa;
46 if (!tvb_bytes_exist(tvb, offset, 4))
47 return false;
48 if (tvb_strneql(tvb, offset, "TAG", 3) == 0)
49 return true;
50 if (tvb_strneql(tvb, offset, "ID3", 3) == 0)
51 return true;
53 hdr = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
54 MPA_UNMARSHAL(&mpa, hdr);
55 return MPA_VALID(&mpa);
58 static int
59 mpeg_resync(tvbuff_t *tvb, int offset)
61 uint32_t hdr;
62 struct mpa mpa;
64 /* This only looks to resync on another frame; it doesn't
65 * look for an ID3 tag.
67 offset = tvb_find_uint8(tvb, offset, -1, '\xff');
68 while (offset != -1 && tvb_bytes_exist(tvb, offset, 4)) {
69 hdr = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
70 MPA_UNMARSHAL(&mpa, hdr);
71 if (MPA_VALID(&mpa)) {
72 return offset;
74 offset = tvb_find_uint8(tvb, offset + 1, -1, '\xff');
76 return tvb_reported_length(tvb);
79 static int
80 dissect_mpeg_audio_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
82 uint32_t h;
83 struct mpa mpa;
84 int data_size = 0;
85 asn1_ctx_t asn1_ctx;
86 int offset = 0;
87 static const char *version_names[] = { "1", "2", "2.5" };
89 if (!tvb_bytes_exist(tvb, 0, 4))
90 return 0;
92 h = tvb_get_ntohl(tvb, 0);
93 MPA_UNMARSHAL(&mpa, h);
94 if (!MPA_SYNC_VALID(&mpa) || !MPA_VERSION_VALID(&mpa) || !MPA_LAYER_VALID(&mpa)) {
95 return 0;
98 col_add_fstr(pinfo->cinfo, COL_PROTOCOL,
99 "MPEG-%s", version_names[mpa_version(&mpa)]);
100 col_add_fstr(pinfo->cinfo, COL_INFO,
101 "Audio Layer %d", mpa_layer(&mpa) + 1);
102 if (MPA_BITRATE_VALID(&mpa) && MPA_FREQUENCY_VALID(&mpa)) {
103 data_size = (int)(MPA_DATA_BYTES(&mpa) - sizeof mpa);
104 col_append_fstr(pinfo->cinfo, COL_INFO,
105 ", %d kb/s, %g kHz",
106 mpa_bitrate(&mpa) / 1000,
107 mpa_frequency(&mpa) / (float)1000);
110 asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, true, pinfo);
111 offset = dissect_mpeg_audio_Audio(tvb, offset, &asn1_ctx,
112 tree, hf_mpeg_audio_header);
113 if (data_size > 0) {
114 unsigned int padding;
116 proto_tree_add_item(tree, hf_mpeg_audio_data, tvb,
117 offset / 8, data_size, ENC_NA);
118 offset += data_size * 8;
119 padding = mpa_padding(&mpa);
120 if (padding > 0) {
121 proto_tree_add_item(tree, hf_mpeg_audio_padbytes, tvb,
122 offset / 8, padding, ENC_NA);
123 offset += padding * 8;
126 return offset / 8;
129 static int
130 dissect_id3v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
132 asn1_ctx_t asn1_ctx;
134 col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v1");
135 col_clear(pinfo->cinfo, COL_INFO);
136 asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, true, pinfo);
137 return dissect_mpeg_audio_ID3v1(tvb, 0, &asn1_ctx,
138 tree, hf_id3v1);
141 static int
142 dissect_mpeg_audio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
144 proto_item *ti;
145 proto_tree *mpeg_audio_tree;
147 int magic, offset = 0;
148 uint32_t frame_len;
149 tvbuff_t *next_tvb;
151 ti = proto_tree_add_item(tree, proto_mpeg_audio, tvb, offset, -1, ENC_NA);
152 mpeg_audio_tree = proto_item_add_subtree(ti, ett_mpeg_audio);
153 while (tvb_reported_length_remaining(tvb, offset) >= 4) {
154 next_tvb = tvb_new_subset_remaining(tvb, offset);
155 magic = tvb_get_ntoh24(next_tvb, 0);
156 switch (magic) {
157 case 0x544147: /* TAG */
158 offset += dissect_id3v1(next_tvb, pinfo, mpeg_audio_tree);
159 break;
160 case 0x494433: /* ID3 */
161 offset += call_dissector(id3v2_handle, tvb, pinfo, mpeg_audio_tree);
162 break;
163 default:
164 frame_len = dissect_mpeg_audio_frame(next_tvb, pinfo, mpeg_audio_tree);
165 if (frame_len == 0) {
166 frame_len = mpeg_resync(next_tvb, 0);
168 offset += frame_len;
171 return tvb_reported_length(tvb);
174 static bool
175 dissect_mpeg_audio_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
177 if (!test_mpeg_audio(tvb, 0)) {
178 return false;
180 dissect_mpeg_audio(tvb, pinfo, tree, data);
181 return true;
184 void
185 proto_register_mpeg_audio(void)
187 static hf_register_info hf[] = {
188 #include "packet-mpeg-audio-hfarr.c"
189 { &hf_mpeg_audio_header,
190 { "Frame Header", "mpeg-audio.header",
191 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
192 { &hf_mpeg_audio_data,
193 { "Data", "mpeg-audio.data",
194 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
195 { &hf_mpeg_audio_padbytes,
196 { "Padding", "mpeg-audio.padbytes",
197 FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
199 { &hf_id3v1,
200 { "ID3v1", "mpeg-audio.id3v1",
201 FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
204 static int *ett[] = {
205 &ett_mpeg_audio,
206 #include "packet-mpeg-audio-ettarr.c"
209 proto_mpeg_audio = proto_register_protocol("Moving Picture Experts Group Audio", "MPEG Audio", "mpeg-audio");
210 proto_register_field_array(proto_mpeg_audio, hf, array_length(hf));
211 proto_register_subtree_array(ett, array_length(ett));
213 mpeg_audio_handle = register_dissector("mpeg-audio", dissect_mpeg_audio, proto_mpeg_audio);
216 void
217 proto_reg_handoff_mpeg_audio(void)
219 dissector_add_string("media_type", "audio/mpeg", mpeg_audio_handle);
220 /* "audio/mp3" used by Chrome before 2020 */
221 /* https://chromium.googlesource.com/chromium/src/+/842f46a95f49e24534ad35c7a71e5c425d426550 */
222 dissector_add_string("media_type", "audio/mp3", mpeg_audio_handle);
224 heur_dissector_add("mpeg", dissect_mpeg_audio_heur, "MPEG Audio", "mpeg_audio", proto_mpeg_audio, HEURISTIC_ENABLE);
226 id3v2_handle = find_dissector("id3v2");