1 /* packet-opus.c
2 * Routines for OPUS dissection
3 * Copyright 2014, Owen Williams williams.owen@gmail.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 #include "tvbuff.h"
14
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/expert.h>
18 #include <ftypes/ftypes.h>
19 #include <glibconfig.h>
20 #include <proto.h>
21 #include <stdint.h>
22
23 #define MAX_FRAMES_COUNT 48
24
25 void proto_reg_handoff_opus(void);
26 void proto_register_opus(void);
27
28 static range_t *g_dynamic_payload_type_range = NULL;
29
30 static dissector_handle_t opus_handle;
31
32 /* Initialize the protocol and registered fields */
33 static int proto_opus = -1;
34 static int hf_opus_toc_config = -1;
35 static int hf_opus_toc_s = -1;
36 static int hf_opus_toc_c = -1;
37 static int hf_opus_frame = -1;
38 static int hf_opus_frame_size = -1;
39 static int hf_opus_frame_count_v = -1;
40 static int hf_opus_frame_count_p = -1;
41 static int hf_opus_frame_count_m = -1;
42 static int hf_opus_padding = -1;
43
44 /* Initialize the subtree pointers */
45 static gint ett_opus = -1;
46
47 static expert_field ei_opus_err_r1 = EI_INIT;
48 static expert_field ei_opus_err_r2 = EI_INIT;
49 static expert_field ei_opus_err_r3 = EI_INIT;
50 static expert_field ei_opus_err_r4 = EI_INIT;
51 static expert_field ei_opus_err_r5 = EI_INIT;
52 static expert_field ei_opus_err_r6 = EI_INIT;
53 static expert_field ei_opus_err_r7 = EI_INIT;
54
55 /* From RFC6716 chapter 3.1
56 * The top five bits of the TOC byte, labeled "config", encode one of 32
57 * possible configurations of operating mode, audio bandwidth, and frame size.
58 */
59 static const value_string opus_codec_toc_config_request_vals[] = {
60 {0, "NB, SILK-only ptime=10"},
61 {1, "NB, SILK-only ptime=20"},
62 {2, "NB, SILK-only ptime=30"},
63 {3, "NB, SILK-only ptime=40"},
64 {4, "MB, SILK-only ptime=10"},
65 {5, "MB, SILK-only ptime=20"},
66 {6, "MB, SILK-only ptime=30"},
67 {7, "MB, SILK-only ptime=40"},
68 {8, "WB, SILK-only ptime=10"},
69 {9, "WB, SILK-only ptime=20"},
70 {10, "WB, SILK-only ptime=30"},
71 {11, "WB, SILK-only ptime=40"},
72 {12, "SWB, Hybrid ptime=10"},
73 {13, "SWB, Hybrid ptime=20"},
74 {14, "FB, Hybrid ptime=10"},
75 {15, "FB, Hybrid ptime=20"},
76 {16, "NB, CELT-only ptime=2.5"},
77 {17, "NB, CELT-only ptime=5"},
78 {18, "NB, CELT-only ptime=10"},
79 {19, "NB, CELT-only ptime=20"},
80 {20, "WB, CELT-only ptime=2.5"},
81 {21, "WB, CELT-only ptime=5"},
82 {22, "WB, CELT-only ptime=10"},
83 {23, "WB, CELT-only ptime=20"},
84 {24, "SWB, CELT-only ptime=2.5"},
85 {25, "SWB, CELT-only ptime=5"},
86 {26, "SWB, CELT-only ptime=10"},
87 {27, "SWB, CELT-only ptime=20"},
88 {28, "FB, CELT-only ptime=2.5"},
89 {29, "FB, CELT-only ptime=5"},
90 {30, "FB, CELT-only ptime=10"},
91 {31, "FB, CELT-only ptime=20"},
92 {0, NULL}};
93 static value_string_ext opus_codec_toc_config_request_vals_ext
94 = VALUE_STRING_EXT_INIT(opus_codec_toc_config_request_vals);
95
96 static const true_false_string toc_s_bit_vals = {"stereo", "mono"};
97 static const true_false_string fc_v_bit_vals = {"VBR", "CBR"};
98 static const true_false_string fc_p_bit_vals = {"Padding", "No Padding"};
99
100 static const value_string opus_codec_toc_c_request_vals[]
101 = {{0, "1 frame in the packet"},
102 {1, "2 frames in the packet, each with equal compressed size"},
103 {2, "2 frames in the packet, with different compressed sizes"},
104 {3, "an arbitrary number of frames in the packet"},
105 {0, NULL}};
106 static value_string_ext opus_codec_toc_c_request_vals_ext
107 = VALUE_STRING_EXT_INIT(opus_codec_toc_c_request_vals);
108
109 static int
parse_size_field(const unsigned char * ch,int32_t cn,int16_t * size)110 parse_size_field(const unsigned char *ch, int32_t cn, int16_t *size)
111 {
112 if (cn < 1) {
113 *size = -1;
114 return -1;
115 }
116 else if (ch[0] < 252) {
117 *size = ch[0];
118 return 1;
119 }
120 else if (cn < 2) {
121 *size = -1;
122 return -1;
123 }
124 else {
125 *size = 4 * ch[1] + ch[0];
126 return 2;
127 }
128 }
129
130 static int16_t
opus_packet_get_samples_per_frame(const unsigned char * data,int16_t Fs)131 opus_packet_get_samples_per_frame(const unsigned char *data, int16_t Fs)
132 {
133 int audiosize;
134 if (data[0] & 0x80) {
135 audiosize = ((data[0] >> 3) & 0x3);
136 audiosize = (Fs << audiosize) / 400;
137 }
138 else if ((data[0] & 0x60) == 0x60) {
139 audiosize = (data[0] & 0x08) ? Fs / 50 : Fs / 100;
140 }
141 else {
142 audiosize = ((data[0] >> 3) & 0x3);
143 if (audiosize == 3)
144 audiosize = Fs * 60 / 1000;
145 else
146 audiosize = (Fs << audiosize) / 100;
147 }
148 return audiosize;
149 }
150
151 static int
dissect_opus(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)152 dissect_opus(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
153 {
154 int idx;
155
156 proto_item *item;
157 proto_tree *opus_tree;
158
159 gint pkt_total = 0, offset = 0;
160 guint cap_len = 0;
161 guint8 ch = 0, toc = 0, octet[2] = {0, 0};
162 int octet_cnt = 0;
163 int bytes = 0;
164 int16_t framesize = 0;
165 struct FRAME_T {
166 int16_t begin;
167 int16_t size;
168 } frames[MAX_FRAMES_COUNT] = {{0}};
169 int frame_count = 0;
170 static int *toc_fields[]
171 = {&hf_opus_toc_config, &hf_opus_toc_s, &hf_opus_toc_c, NULL};
172 static int *frame_count_fields[]
173 = {&hf_opus_frame_count_v, &hf_opus_frame_count_p,
174 &hf_opus_frame_count_m, NULL};
175
176 col_set_str(pinfo->cinfo, COL_PROTOCOL, "OPUS");
177
178 item = proto_tree_add_item(tree, proto_opus, tvb, 0, -1, ENC_NA);
179 opus_tree = proto_item_add_subtree(item, ett_opus);
180
181 /*
182 * A ToC entry takes the following format, details defined in section-3.1:
183 *
184 * 0 1 2 3 4 5 6 7
185 * +-+-+-+-+-+-+-+-+
186 * | config |s| c |
187 * +-+-+-+-+-+-+-+-+
188 */
189 proto_tree_add_bitmask_list(opus_tree, tvb, offset, 1, toc_fields, ENC_NA);
190
191 cap_len = tvb_captured_length(tvb);
192 pkt_total = tvb_captured_length_remaining(tvb, offset);
193
194 if (pkt_total <= 0) {
195 expert_add_info(pinfo, opus_tree, &ei_opus_err_r1);
196 return cap_len;
197 }
198
199 toc = tvb_get_guint8(tvb, offset++);
200
201 switch (toc & 0x3) {
202 case 0: /* One frame */
203 frames[0].begin = offset;
204 frames[0].size = pkt_total - offset;
205 frame_count = 1;
206 break;
207 case 1: /* Two CBR frames */
208 if ((pkt_total - offset) & 0x1) {
209 expert_add_info(pinfo, opus_tree, &ei_opus_err_r3);
210 return cap_len;
211 }
212 frames[0].begin = offset;
213 frames[0].size = frames[1].size = (pkt_total - offset) / 2;
214 frames[1].begin = frames[0].begin + frames[0].size;
215 frame_count = 2;
216 break;
217 case 2: /* Two VBR frames */
218 if (offset >= pkt_total) {
219 expert_add_info(pinfo, opus_tree, &ei_opus_err_r4);
220 return cap_len;
221 }
222 /* offset < pkt_total */
223 octet[octet_cnt++] = tvb_get_guint8(tvb, offset);
224 if (offset + 1 < pkt_total) {
225 octet[octet_cnt++] = tvb_get_guint8(tvb, offset + 1);
226 }
227 bytes = parse_size_field(octet, octet_cnt, &framesize);
228 if (framesize < 0 || framesize > pkt_total) {
229 expert_add_info(pinfo, opus_tree, &ei_opus_err_r1);
230 return cap_len;
231 }
232 proto_tree_add_item(opus_tree, hf_opus_frame_size, tvb, offset, bytes,
233 ENC_NA);
234 offset += bytes;
235 /* frame[0] has size header, frame[1] is remaining */
236 frames[0].begin = offset;
237 frames[0].size = framesize;
238 frames[1].begin = frames[0].begin + framesize;
239 frames[1].size = -1;
240 frame_count = 2;
241 break;
242 /* Multiple CBR/VBR frames (from 0 to 120 ms) */
243 default: /* case 3:*/
244 if ((pkt_total - offset) < 2) {
245 expert_add_info(pinfo, opus_tree, &ei_opus_err_r6);
246 return cap_len;
247 }
248 proto_tree_add_bitmask_list(opus_tree, tvb, offset, 1,
249 frame_count_fields, ENC_NA);
250 /* Number of frames encoded in bits 0 to 5 */
251 ch = tvb_get_guint8(tvb, offset++);
252 frame_count = ch & 0x3F;
253 framesize = opus_packet_get_samples_per_frame(&toc, 48000U);
254 if (frame_count <= 0
255 || framesize * frame_count > 120 * MAX_FRAMES_COUNT) {
256 expert_add_info(pinfo, opus_tree, &ei_opus_err_r5);
257 return cap_len;
258 }
259 /* Padding flag (bit 6) used */
260 if (ch & 0x40) {
261 int p;
262 gint padding_size = 0;
263 gint padding_begin = offset;
264 do {
265 int tmp;
266 if (offset >= pkt_total) {
267 expert_add_info(pinfo, opus_tree, &ei_opus_err_r7);
268 return cap_len;
269 }
270 p = tvb_get_guint8(tvb, offset++);
271 tmp = p == 255 ? 254 : p;
272 padding_size += tmp;
273 } while (p == 255);
274 proto_tree_add_item(opus_tree, hf_opus_padding, tvb, padding_begin,
275 padding_size, ENC_NA);
276 offset = padding_begin + padding_size;
277 }
278 if (offset >= pkt_total) {
279 expert_add_info(pinfo, opus_tree, &ei_opus_err_r7);
280 return cap_len;
281 }
282 /* VBR flag is bit 7 */
283 if (ch & 0x80) { /* VBR case */
284 for (idx = 0; idx < frame_count; idx++) {
285 octet_cnt = 0;
286 octet[octet_cnt++] = tvb_get_guint8(tvb, offset);
287 if (offset + 1 < pkt_total) {
288 octet[octet_cnt++] = tvb_get_guint8(tvb, offset);
289 }
290 bytes = parse_size_field(octet, octet_cnt, &frames[idx].size);
291 if (frames[idx].size < 0
292 || frames[idx].size > (pkt_total - offset)) {
293 expert_add_info(pinfo, opus_tree, &ei_opus_err_r1);
294 return cap_len;
295 }
296
297 proto_tree_add_item(opus_tree, hf_opus_frame_size, tvb, offset,
298 bytes, ENC_NA);
299 offset += bytes;
300 }
301 for (idx = 0; idx < frame_count; idx++) {
302 frames[idx].begin = offset;
303 offset += frames[idx].size;
304 }
305 if (offset > pkt_total) {
306 expert_add_info(pinfo, opus_tree, &ei_opus_err_r7);
307 return cap_len;
308 }
309 }
310 else { /* CBR case */
311 guint frame_size = (pkt_total - offset) / frame_count;
312 if (frame_size * frame_count != (guint)(pkt_total - offset)) {
313 expert_add_info(pinfo, opus_tree, &ei_opus_err_r6);
314 return cap_len;
315 }
316 for (idx = 0; idx < frame_count; idx++) {
317 frames[idx].begin = offset + idx * frame_size;
318 frames[idx].size = frame_size;
319 }
320 }
321 break;
322 }
323
324 for (idx = 0; idx < frame_count; idx++) {
325 struct FRAME_T *f = &frames[idx];
326 /* reject the frame which is larger than 1275. */
327 if (f->size > 1275) {
328 expert_add_info(pinfo, opus_tree, &ei_opus_err_r2);
329 return cap_len;
330 }
331 proto_tree_add_item(opus_tree, hf_opus_frame, tvb, f->begin, f->size,
332 ENC_NA);
333 }
334
335 return cap_len;
336 }
337
338 void
proto_register_opus(void)339 proto_register_opus(void)
340 {
341 module_t *opus_module;
342 expert_module_t* expert_opus;
343
344 static hf_register_info hf[] = {
345 {&hf_opus_toc_config,
346 {"TOC.config", "opus.TOC.config", FT_UINT8, BASE_DEC | BASE_EXT_STRING,
347 &opus_codec_toc_config_request_vals_ext, 0xF8, "Opus TOC config",
348 HFILL}},
349 {&hf_opus_toc_s,
350 {"TOC.S bit", "opus.TOC.s", FT_BOOLEAN, SEP_DOT, TFS(&toc_s_bit_vals),
351 0x04, NULL, HFILL}},
352 {&hf_opus_toc_c,
353 {"TOC.C bits", "opus.TOC.c", FT_UINT8, BASE_DEC | BASE_EXT_STRING,
354 &opus_codec_toc_c_request_vals_ext, 0x03, "Opus TOC code", HFILL}},
355 {&hf_opus_frame_count_m,
356 {"Frame Count.m", "opus.FC.m", FT_UINT8, BASE_DEC, NULL, 0x3F,
357 "Frame Count", HFILL}},
358 {&hf_opus_frame_count_p,
359 {"Frame Count.p bit", "opus.FC.p", FT_BOOLEAN, SEP_DOT,
360 TFS(&fc_p_bit_vals), 0x40, NULL, HFILL}},
361 {&hf_opus_frame_count_v,
362 {"Frame Count.v bit", "opus.FC.v", FT_BOOLEAN, SEP_DOT,
363 TFS(&fc_v_bit_vals), 0x80, NULL, HFILL}},
364 {&hf_opus_frame_size,
365 {"Frame Size", "opus.frame_size", FT_BYTES, BASE_NONE, NULL, 0x0, NULL,
366 HFILL}},
367 {&hf_opus_frame,
368 {"Frame Data", "opus.frame_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL,
369 HFILL}},
370 {&hf_opus_padding,
371 {"Padding", "opus.padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL,
372 HFILL}},
373 };
374
375 static gint *ett[] = { &ett_opus, };
376
377 static ei_register_info ei[] = {
378 {&ei_opus_err_r1,
379 {"opus.violate_r1", PI_PROTOCOL, PI_ERROR,
380 "Error:[R1] Packets are at least one byte.", EXPFILL}},
381 {&ei_opus_err_r2,
382 {"opus.violate_r2", PI_MALFORMED, PI_ERROR,
383 "Error:[R2] No implicit frame length is larger than 1275 bytes.",
384 EXPFILL}},
385 {&ei_opus_err_r3,
386 {"opus.violate_r3", PI_MALFORMED, PI_ERROR,
387 "Error:[R3] Code 1 packets have an odd total length, N, so that "
388 "(N-1)/2 is an integer.",
389 EXPFILL}},
390 {&ei_opus_err_r4,
391 {"opus.violate_r4", PI_MALFORMED, PI_ERROR,
392 "Error:[R4] Code 2 packets have enough bytes after the TOC for a "
393 "valid frame length, and that length is no larger than the number of"
394 "bytes remaining in the packet.",
395 EXPFILL}},
396 {&ei_opus_err_r5,
397 {"opus.violate_r5", PI_PROTOCOL, PI_ERROR,
398 "Error:[R5] Code 3 packets contain at least one frame, but no more "
399 "than 120 ms of audio total.",
400 EXPFILL}},
401 {&ei_opus_err_r6,
402 {"opus.violate_r6", PI_PROTOCOL, PI_ERROR,
403 "Error:[R6] The length of a CBR code 3 packet, N, is at least two "
404 "bytes, the number of bytes added to indicate the padding size plus "
405 "the trailing padding bytes themselves, P, is no more than N-2, and "
406 "the frame count, M, satisfies the constraint that (N-2-P) is a "
407 "non-negative integer multiple of M.",
408 EXPFILL}},
409 {&ei_opus_err_r7,
410 {"opus.violate_r7", PI_PROTOCOL, PI_ERROR,
411 "Error:[R7] VBR code 3 packets are large enough to contain all the "
412 "header bytes (TOC byte, frame count byte, any padding length bytes, "
413 "and any frame length bytes), plus the length of the first M-1 "
414 "frames, plus any trailing padding bytes.",
415 EXPFILL}},
416 };
417
418 proto_opus
419 = proto_register_protocol("Opus Interactive Audio Codec", /* name */
420 "OPUS", /* short name */
421 "opus" /* abbrev */
422 );
423
424 proto_register_field_array(proto_opus, hf, array_length(hf));
425 proto_register_subtree_array(ett, array_length(ett));
426
427 opus_module = prefs_register_protocol(proto_opus, proto_reg_handoff_opus);
428
429 expert_opus = expert_register_protocol(proto_opus);
430 expert_register_field_array(expert_opus, ei, array_length(ei));
431
432 prefs_register_range_preference(opus_module, "dynamic.payload.type",
433 "OPUS dynamic payload types",
434 "Dynamic payload types which will be "
435 "interpreted as OPUS; Values must be in "
436 "the range 1 - 127",
437 &g_dynamic_payload_type_range, 127);
438
439 opus_handle = register_dissector("opus", dissect_opus, proto_opus);
440 }
441
442 void
proto_reg_handoff_opus(void)443 proto_reg_handoff_opus(void)
444 {
445 static range_t *dynamic_payload_type_range = NULL;
446 static gboolean opus_prefs_initialized = FALSE;
447
448 if (!opus_prefs_initialized) {
449 dissector_add_string("rtp_dyn_payload_type" , "OPUS", opus_handle);
450 opus_prefs_initialized = TRUE;
451 } else {
452 dissector_delete_uint_range("rtp.pt", dynamic_payload_type_range, opus_handle);
453 wmem_free(wmem_epan_scope(), dynamic_payload_type_range);
454 }
455
456 dynamic_payload_type_range = range_copy(wmem_epan_scope(), g_dynamic_payload_type_range);
457 range_remove_value(wmem_epan_scope(), &dynamic_payload_type_range, 0);
458 dissector_add_uint_range("rtp.pt", dynamic_payload_type_range, opus_handle);
459 }
460
461 /*
462 * Editor modelines - https://www.wireshark.org/tools/modelines.html
463 *
464 * Local variables:
465 * c-basic-offset: 4
466 * tab-width: 8
467 * indent-tabs-mode: nil
468 * End:
469 *
470 * vi: set shiftwidth=4 tabstop=8 expandtab:
471 * :indentSize=4:tabSize=8:noTabs=true:
472 */
473