Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-mp2t.c
Line
Count
Source
1
/* packet-mp2t.c
2
 *
3
 * Routines for RFC 2250 MPEG2 (ISO/IEC 13818-1) Transport Stream dissection
4
 *
5
 * Copyright 2006, Erwin Rol <erwin@erwinrol.com>
6
 * Copyright 2012-2014, Guy Martin <gmsoft@tuxicoman.be>
7
 *
8
 * Wireshark - Network traffic analyzer
9
 * By Gerald Combs <gerald@wireshark.org>
10
 * Copyright 1998 Gerald Combs
11
 *
12
 * SPDX-License-Identifier: GPL-2.0-or-later
13
 */
14
15
#include "config.h"
16
17
#include <epan/packet.h>
18
#include <wiretap/wtap.h>
19
20
#include <epan/conversation.h>
21
#include <epan/expert.h>
22
#include <epan/reassemble.h>
23
#include <epan/proto_data.h>
24
#include <epan/exported_pdu.h>
25
#include <epan/tap.h>
26
#include <epan/follow.h>
27
#include <epan/exceptions.h>
28
#include <epan/show_exception.h>
29
#include <epan/addr_resolv.h>
30
#include "packet-l2tp.h"
31
#include "packet-udp.h"
32
#include "packet-mp2t.h"
33
#include "packet-rtp_pt.h"
34
35
void proto_register_mp2t(void);
36
void proto_reg_handoff_mp2t(void);
37
38
126
#define MP2T_PID_DOCSIS  0x1FFE
39
164
#define MP2T_PID_NULL    0x1FFF
40
41
static dissector_handle_t mp2t_handle;
42
43
static dissector_handle_t docsis_handle;
44
static dissector_handle_t mpeg_pes_handle;
45
static dissector_handle_t mpeg_sect_handle;
46
47
static heur_dissector_list_t heur_subdissector_list;
48
49
static int exported_pdu_tap;
50
static int mp2t_follow_tap;
51
52
static int proto_mp2t;
53
static int ett_mp2t;
54
static int ett_mp2t_header;
55
static int ett_mp2t_af;
56
static int ett_mp2t_analysis;
57
static int ett_stuff;
58
59
static int hf_mp2t_stream;
60
static int hf_mp2t_header;
61
static int hf_mp2t_sync_byte;
62
static int hf_mp2t_tei;
63
static int hf_mp2t_pusi;
64
static int hf_mp2t_tp;
65
static int hf_mp2t_pid;
66
static int hf_mp2t_tsc;
67
static int hf_mp2t_afc;
68
static int hf_mp2t_cc;
69
70
/* static int hf_mp2t_analysis_flags; */
71
static int hf_mp2t_analysis_skips;
72
static int hf_mp2t_analysis_drops;
73
74
15
#define MP2T_SYNC_BYTE_MASK  0xFF000000
75
15
#define MP2T_TEI_MASK        0x00800000
76
15
#define MP2T_PUSI_MASK       0x00400000
77
15
#define MP2T_TP_MASK         0x00200000
78
26.8k
#define MP2T_PID_MASK        0x001FFF00
79
26.8k
#define MP2T_TSC_MASK        0x000000C0
80
26.8k
#define MP2T_AFC_MASK        0x00000030
81
27.3k
#define MP2T_CC_MASK         0x0000000F
82
83
#define MP2T_SYNC_BYTE_SHIFT  24
84
#define MP2T_TEI_SHIFT        23
85
#define MP2T_PUSI_SHIFT       22
86
#define MP2T_TP_SHIFT         21
87
26.8k
#define MP2T_PID_SHIFT         8
88
#define MP2T_TSC_SHIFT         6
89
26.8k
#define MP2T_AFC_SHIFT         4
90
26.8k
#define MP2T_CC_SHIFT          0
91
92
static int hf_mp2t_af;
93
static int hf_mp2t_af_length;
94
static int hf_mp2t_af_di;
95
static int hf_mp2t_af_rai;
96
static int hf_mp2t_af_espi;
97
static int hf_mp2t_af_pcr_flag;
98
static int hf_mp2t_af_opcr_flag;
99
static int hf_mp2t_af_sp_flag;
100
static int hf_mp2t_af_tpd_flag;
101
static int hf_mp2t_af_afe_flag;
102
103
15
#define MP2T_AF_DI_MASK     0x80
104
15
#define MP2T_AF_RAI_MASK    0x40
105
15
#define MP2T_AF_ESPI_MASK   0x20
106
138
#define MP2T_AF_PCR_MASK    0x10
107
138
#define MP2T_AF_OPCR_MASK   0x08
108
138
#define MP2T_AF_SP_MASK     0x04
109
138
#define MP2T_AF_TPD_MASK    0x02
110
138
#define MP2T_AF_AFE_MASK    0x01
111
112
#define MP2T_AF_DI_SHIFT     7
113
#define MP2T_AF_RAI_SHIFT    6
114
#define MP2T_AF_ESPI_SHIFT   5
115
#define MP2T_AF_PCR_SHIFT    4
116
#define MP2T_AF_OPCR_SHIFT   3
117
#define MP2T_AF_SP_SHIFT     2
118
#define MP2T_AF_TPD_SHIFT    1
119
#define MP2T_AF_AFE_SHIFT    0
120
121
static int hf_mp2t_af_pcr;
122
static int hf_mp2t_af_opcr;
123
124
static int hf_mp2t_af_sc;
125
126
static int hf_mp2t_af_tpd_length;
127
static int hf_mp2t_af_tpd;
128
129
static int hf_mp2t_af_e_length;
130
static int hf_mp2t_af_e_ltw_flag;
131
static int hf_mp2t_af_e_pr_flag;
132
static int hf_mp2t_af_e_ss_flag;
133
static int hf_mp2t_af_e_reserved;
134
135
74
#define MP2T_AF_E_LTW_FLAG_MASK   0x80
136
74
#define MP2T_AF_E_PR_FLAG_MASK    0x40
137
74
#define MP2T_AF_E_SS_FLAG_MASK    0x20
138
139
static int hf_mp2t_af_e_reserved_bytes;
140
static int hf_mp2t_af_stuffing_bytes;
141
142
static int hf_mp2t_af_e_ltwv_flag;
143
static int hf_mp2t_af_e_ltwo;
144
145
static int hf_mp2t_af_e_pr_reserved;
146
static int hf_mp2t_af_e_pr;
147
148
static int hf_mp2t_af_e_st;
149
static int hf_mp2t_af_e_dnau_32_30;
150
static int hf_mp2t_af_e_m_1;
151
static int hf_mp2t_af_e_dnau_29_15;
152
static int hf_mp2t_af_e_m_2;
153
static int hf_mp2t_af_e_dnau_14_0;
154
static int hf_mp2t_af_e_m_3;
155
156
/* static int hf_mp2t_payload; */
157
static int hf_mp2t_stuff_bytes;
158
static int hf_mp2t_pointer;
159
160
/* proto data keys. Note that the packet_analysis_data structure is stored
161
 * using the layer number, but since that is at wmem_file_scope() while
162
 * the stream information is at pinfo->pool, they don't actually clash.
163
 */
164
28.5k
#define MP2T_PROTO_DATA_STREAM 1
165
26.8k
#define MP2T_PROTO_DATA_PID 2
166
167
static const value_string mp2t_sync_byte_vals[] = {
168
    { MP2T_SYNC_BYTE, "Correct" },
169
    { 0, NULL }
170
};
171
172
static const value_string mp2t_pid_vals[] = {
173
    { 0x0000, "Program Association Table" },
174
    { 0x0001, "Conditional Access Table" },
175
    { 0x0002, "Transport Stream Description Table" },
176
    { 0x0003, "Reserved" },
177
    { 0x0004, "Reserved" },
178
    { 0x0005, "Reserved" },
179
    { 0x0006, "Reserved" },
180
    { 0x0007, "Reserved" },
181
    { 0x0008, "Reserved" },
182
    { 0x0009, "Reserved" },
183
    { 0x000A, "Reserved" },
184
    { 0x000B, "Reserved" },
185
    { 0x000C, "Reserved" },
186
    { 0x000D, "Reserved" },
187
    { 0x000E, "Reserved" },
188
    { 0x000F, "Reserved" },
189
    { 0x0010, "Network Information or Stuffing Table" },
190
    { 0x0011, "Service Description or Bouquet Association or Stuffing Table" },
191
    { 0x0012, "Event Information or Stuffing or Content Identifier Table" },
192
    { 0x0013, "Running Status or Stuffing Table" },
193
    { 0x0014, "Time and Date or Time Offset or Stuffing Table" },
194
    { 0x0015, "Network Synchronization" },
195
    { 0x0016, "Resolution Authority Record Notification Table" },
196
    { 0x0017, "Reserved For Future Use" },
197
    { 0x0018, "Reserved For Future Use" },
198
    { 0x0019, "Reserved For Future Use" },
199
    { 0x001A, "Reserved For Future Use" },
200
    { 0x001B, "Reserved For Future Use" },
201
    { 0x001C, "Inband Signaling" },
202
    { 0x001D, "Measurement" },
203
    { 0x001E, "Discontinuity Information Table" },
204
    { 0x001F, "Selection Information Table" },
205
    { 0x1FFE, "DOCSIS Data-over-cable well-known PID" },
206
    { 0x1FFF, "Null packet" },
207
    { 0, NULL }
208
};
209
210
211
/* Values below according ETSI ETR 289 */
212
static const value_string mp2t_tsc_vals[] = {
213
    { 0, "Not scrambled" },
214
    { 1, "Reserved" },
215
    { 2, "Packet scrambled with Even Key" },
216
    { 3, "Packet scrambled with Odd Key" },
217
    { 0, NULL }
218
};
219
220
static const value_string mp2t_afc_vals[] = {
221
    { 0, "Reserved" },
222
    { 1, "Payload only" },
223
    { 2, "Adaptation Field only" },
224
    { 3, "Adaptation Field and Payload" },
225
    { 0, NULL }
226
};
227
228
static int ett_msg_fragment;
229
static int ett_msg_fragments;
230
static int hf_msg_fragments;
231
static int hf_msg_fragment;
232
static int hf_msg_fragment_overlap;
233
static int hf_msg_fragment_overlap_conflicts;
234
static int hf_msg_fragment_multiple_tails;
235
static int hf_msg_fragment_too_long_fragment;
236
static int hf_msg_fragment_error;
237
static int hf_msg_fragment_count;
238
static int hf_msg_reassembled_in;
239
static int hf_msg_reassembled_length;
240
241
static int hf_msg_ts_packet_reassembled;
242
243
static expert_field ei_mp2t_pointer;
244
static expert_field ei_mp2t_cc_drop;
245
static expert_field ei_mp2t_invalid_afc;
246
247
static const fragment_items mp2t_msg_frag_items = {
248
    /* Fragment subtrees */
249
    &ett_msg_fragment,
250
    &ett_msg_fragments,
251
    /* Fragment fields */
252
    &hf_msg_fragments,
253
    &hf_msg_fragment,
254
    &hf_msg_fragment_overlap,
255
    &hf_msg_fragment_overlap_conflicts,
256
    &hf_msg_fragment_multiple_tails,
257
    &hf_msg_fragment_too_long_fragment,
258
    &hf_msg_fragment_error,
259
    &hf_msg_fragment_count,
260
    /* Reassembled in field */
261
    &hf_msg_reassembled_in,
262
    /* Reassembled length field */
263
    &hf_msg_reassembled_length,
264
    /* Reassembled data field */
265
    NULL,
266
    /* Tag */
267
    "Message fragments"
268
};
269
270
271
/* Data structure used for detecting CC drops
272
 *
273
 *  conversation + direction
274
 *    |
275
 *    +-> mp2t_analysis_data
276
 *          |
277
 *          +-> pid_table (RB tree) (key: pid)
278
 *          |     |
279
 *          |     +-> pid_analysis_data (per pid)
280
 *          |     +-> pid_analysis_data
281
 *          |     +-> pid_analysis_data
282
 *          |
283
 *          +-> frame_table (RB tree) (key: pinfo->num)
284
 *                |
285
 *                +-> frame_analysis_data (only created if drop detected)
286
 *                      |
287
 *                      +-> ts_table (RB tree)
288
 *                            |
289
 *                            +-> ts_analysis_data (per TS subframe)
290
 *                            +-> ts_analysis_data
291
 *                            +-> ts_analysis_data
292
 */
293
294
static wmem_map_t *mp2t_stream_hashtable;
295
296
static uint32_t mp2t_stream_count;
297
298
typedef struct {
299
    const conversation_t* conv;
300
    int dir;
301
} mp2t_stream_key;
302
303
/* Hash functions */
304
static int
305
mp2t_stream_equal(const void *v, const void *w)
306
26.8k
{
307
26.8k
    const mp2t_stream_key *v1 = (const mp2t_stream_key *)v;
308
26.8k
    const mp2t_stream_key *v2 = (const mp2t_stream_key *)w;
309
26.8k
    int result;
310
26.8k
    result = (v1->conv == v2->conv && v1->dir == v2->dir);
311
26.8k
    return result;
312
26.8k
}
313
314
static unsigned
315
mp2t_stream_hash(const void *v)
316
26.9k
{
317
26.9k
    const mp2t_stream_key *key = (const mp2t_stream_key *)v;
318
    /* Actually getting multiple streams in opposite directions is
319
     * quite unlikely, so to optimize don't include it in the hash */
320
26.9k
    unsigned hash_val = GPOINTER_TO_UINT(key->conv);
321
26.9k
    return hash_val;
322
26.9k
}
323
324
typedef struct mp2t_analysis_data {
325
326
    /* This structure contains a tree containing data for the
327
     * individual pid's, this is only used when packets are
328
     * processed sequentially.
329
     */
330
    wmem_tree_t    *pid_table;
331
332
    /* When detecting a CC drop, store that information for the
333
     * given frame.  This info is needed, when clicking around in
334
     * wireshark, as the pid table data only makes sense during
335
     * sequential processing. The flag pinfo->fd->visited is
336
     * used to tell the difference.
337
     *
338
     */
339
    wmem_tree_t    *frame_table;
340
341
    uint32_t stream;
342
343
    /* Total counters per conversation / multicast stream */
344
    uint32_t total_skips;
345
    uint32_t total_discontinuity;
346
347
} mp2t_analysis_data_t;
348
349
enum pid_payload_type {
350
    pid_pload_unknown,
351
    pid_pload_docsis,
352
    pid_pload_pes,
353
    pid_pload_sect,
354
    pid_pload_null
355
};
356
357
typedef struct subpacket_analysis_data {
358
    uint32_t    frag_cur_pos;
359
    uint32_t    frag_tot_len;
360
    bool        fragmentation;
361
    uint32_t    frag_id;
362
} subpacket_analysis_data_t;
363
364
typedef struct packet_analysis_data {
365
366
    /* Contain information for each MPEG2-TS packet in the current big packet */
367
    wmem_tree_t *subpacket_table;
368
} packet_analysis_data_t;
369
370
/* Analysis TS frame info needed during sequential processing */
371
typedef struct pid_analysis_data {
372
    uint16_t                 pid;
373
    int8_t                   cc_prev;      /* Previous CC number */
374
    enum pid_payload_type    pload_type;
375
    wmem_tree_t             *stream_types;
376
377
    /* Fragments information used for first pass */
378
    bool                     fragmentation;
379
    uint32_t                 frag_cur_pos;
380
    uint32_t                 frag_tot_len;
381
    uint32_t                 frag_id;
382
} pid_analysis_data_t;
383
384
/* Analysis info stored for a TS frame */
385
typedef struct ts_analysis_data {
386
    uint16_t pid;
387
    int8_t   cc_prev;      /* Previous CC number */
388
    uint8_t  skips;          /* Skips between Ccs max 14 */
389
} ts_analysis_data_t;
390
391
392
typedef struct frame_analysis_data {
393
394
    /* As each frame has several pid's, thus need a pid data
395
     * structure per TS frame.
396
     */
397
    wmem_tree_t    *ts_table;
398
399
} frame_analysis_data_t;
400
401
static mp2t_analysis_data_t *
402
init_mp2t_conversation_data(void)
403
44
{
404
44
    mp2t_analysis_data_t *mp2t_data;
405
406
44
    mp2t_data = wmem_new0(wmem_file_scope(), struct mp2t_analysis_data);
407
408
44
    mp2t_data->stream = mp2t_stream_count++;
409
44
    mp2t_data->pid_table = wmem_tree_new(wmem_file_scope());
410
411
44
    mp2t_data->frame_table = wmem_tree_new(wmem_file_scope());
412
413
44
    mp2t_data->total_skips = 0;
414
44
    mp2t_data->total_discontinuity = 0;
415
416
44
    return mp2t_data;
417
44
}
418
419
static mp2t_analysis_data_t *
420
get_mp2t_conversation_data(mp2t_stream_key *key)
421
26.9k
{
422
26.9k
    mp2t_stream_key      *new_key;
423
26.9k
    mp2t_analysis_data_t *mp2t_data;
424
425
26.9k
    mp2t_data = (mp2t_analysis_data_t *)wmem_map_lookup(mp2t_stream_hashtable, key);
426
26.9k
    if (!mp2t_data) {
427
44
        new_key = wmem_new(wmem_file_scope(), mp2t_stream_key);
428
44
        *new_key = *key;
429
44
        mp2t_data = init_mp2t_conversation_data();
430
44
        wmem_map_insert(mp2t_stream_hashtable, new_key, mp2t_data);
431
44
    }
432
433
26.9k
    return mp2t_data;
434
26.9k
}
435
436
static frame_analysis_data_t *
437
init_frame_analysis_data(mp2t_analysis_data_t *mp2t_data, packet_info *pinfo)
438
136
{
439
136
    frame_analysis_data_t *frame_analysis_data_p;
440
441
136
    frame_analysis_data_p = wmem_new0(wmem_file_scope(), struct frame_analysis_data);
442
136
    frame_analysis_data_p->ts_table = wmem_tree_new(wmem_file_scope());
443
    /* Insert into mp2t tree */
444
136
    wmem_tree_insert32(mp2t_data->frame_table, pinfo->num,
445
136
            (void *)frame_analysis_data_p);
446
447
136
    return frame_analysis_data_p;
448
136
}
449
450
451
static frame_analysis_data_t *
452
get_frame_analysis_data(mp2t_analysis_data_t *mp2t_data, packet_info *pinfo)
453
137
{
454
137
    frame_analysis_data_t *frame_analysis_data_p;
455
137
    frame_analysis_data_p = (frame_analysis_data_t *)wmem_tree_lookup32(mp2t_data->frame_table, pinfo->num);
456
137
    return frame_analysis_data_p;
457
137
}
458
459
static pid_analysis_data_t *
460
get_pid_analysis(mp2t_analysis_data_t *mp2t_data, uint32_t pid)
461
27.5k
{
462
27.5k
    pid_analysis_data_t  *pid_data;
463
464
27.5k
    pid_data = (pid_analysis_data_t *)wmem_tree_lookup32(mp2t_data->pid_table, pid);
465
27.5k
    if (!pid_data) {
466
133
        pid_data          = wmem_new0(wmem_file_scope(), struct pid_analysis_data);
467
133
        pid_data->cc_prev = -1;
468
133
        pid_data->pid     = pid;
469
133
        pid_data->stream_types = wmem_tree_new(wmem_file_scope());
470
133
        pid_data->frag_id = (pid << (32 - 13)) | 0x1;
471
472
133
        wmem_tree_insert32(mp2t_data->pid_table, pid, (void *)pid_data);
473
133
    }
474
27.5k
    return pid_data;
475
27.5k
}
476
477
uint32_t
478
mp2t_get_stream_count(void)
479
0
{
480
0
    return mp2t_stream_count;
481
0
}
482
483
static void
484
mp2t_init(void)
485
15
{
486
15
    mp2t_stream_count = 0;
487
15
}
488
489
static gboolean
490
mp2t_stream_find(void *key _U_, void *value, void *user_data)
491
0
{
492
0
    uint32_t stream = GPOINTER_TO_UINT(user_data);
493
0
    mp2t_analysis_data_t *mp2t_data = (mp2t_analysis_data_t*)value;
494
0
    if (mp2t_data->stream == stream) {
495
0
        return true;
496
0
    }
497
0
    return false;
498
0
}
499
500
bool
501
mp2t_get_sub_stream_id(unsigned stream, unsigned sub_stream, bool le, unsigned *sub_stream_out)
502
0
{
503
0
    mp2t_analysis_data_t *mp2t_data = wmem_map_find(mp2t_stream_hashtable, mp2t_stream_find, GUINT_TO_POINTER(stream));
504
0
    pid_analysis_data_t *pid_data;
505
0
    if (!mp2t_data) {
506
0
        return false;
507
0
    }
508
0
    if (le) {
509
0
        pid_data = wmem_tree_lookup32_le(mp2t_data->pid_table, sub_stream);
510
0
    } else {
511
0
        pid_data = wmem_tree_lookup32_ge(mp2t_data->pid_table, sub_stream);
512
0
    }
513
0
    if (!pid_data) {
514
0
        return false;
515
0
    }
516
517
0
    *sub_stream_out = pid_data->pid;
518
0
    return true;
519
0
}
520
521
char *mp2t_follow_conv_filter(epan_dissect_t *edt _U_, packet_info *pinfo, unsigned *stream, unsigned *sub_stream)
522
0
{
523
0
    char *filter = NULL;
524
0
    mp2t_stream_key *stream_key;
525
0
    unsigned pid;
526
527
0
    stream_key = (mp2t_stream_key *)p_get_proto_data(pinfo->pool, pinfo, proto_mp2t, MP2T_PROTO_DATA_STREAM);
528
0
    if (stream_key) {
529
0
        mp2t_analysis_data_t *mp2t_data = get_mp2t_conversation_data(stream_key);
530
0
        pid = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_mp2t, MP2T_PROTO_DATA_PID));
531
0
        *stream = mp2t_data->stream;
532
0
        *sub_stream = pid;
533
0
        filter = ws_strdup_printf("mp2t.stream == %u && mp2t.pid == 0x%04x", *stream, pid);
534
0
    }
535
0
    return filter;
536
0
}
537
538
char *mp2t_follow_index_filter(unsigned stream, unsigned sub_stream)
539
0
{
540
0
    return ws_strdup_printf("mp2t.stream == %u && mp2t.pid == 0x%04x", stream, sub_stream);
541
0
}
542
543
/* Structure to handle packets, spanned across
544
 * multiple MPEG packets
545
 */
546
547
/* Reassembly functions */
548
typedef struct _mp2t_fragment_key {
549
    uint32_t conv_index; /* Just use the unique index */
550
    int     dir;
551
    uint32_t id;
552
} mp2t_fragment_key;
553
554
static unsigned
555
mp2t_fragment_hash(const void *k)
556
2.41k
{
557
2.41k
    const mp2t_fragment_key* key = (const mp2t_fragment_key*) k;
558
2.41k
    unsigned hash_val;
559
560
2.41k
    hash_val = 0;
561
562
    /* In most captures there is only one conversation so optimize on
563
     * only using the id for the hash. */
564
    // hash_val += (key->conv_index << 2) + key->dir;
565
566
2.41k
    hash_val ^= key->id;
567
568
2.41k
    return hash_val;
569
2.41k
}
570
571
static int
572
mp2t_fragment_equal(const void *k1, const void *k2)
573
1.11k
{
574
1.11k
    const mp2t_fragment_key* key1 = (const mp2t_fragment_key*) k1;
575
1.11k
    const mp2t_fragment_key* key2 = (const mp2t_fragment_key*) k2;
576
577
    /* Compare the id first since it's the most likely to differ */
578
1.11k
    return (key1->id == key2->id) &&
579
1.11k
           (key1->conv_index == key2->conv_index) &&
580
740
           (key1->dir == key2->dir);
581
1.11k
}
582
583
/*
584
 * Create a fragment key for permanent use; we are only copying ints,
585
 * so our temporary keys are the same as permanent ones.
586
 */
587
static void *
588
mp2t_fragment_persistent_key(const packet_info *pinfo _U_, const uint32_t id, const void *data)
589
2.05k
{
590
2.05k
    mp2t_fragment_key *key = g_slice_new(mp2t_fragment_key);
591
2.05k
    DISSECTOR_ASSERT(data);
592
2.05k
    mp2t_stream_key *stream = (mp2t_stream_key *)data;
593
594
2.05k
    key->conv_index = stream->conv->conv_index;
595
2.05k
    key->dir = stream->dir;
596
2.05k
    key->id = id;
597
598
2.05k
    return (void *)key;
599
2.05k
}
600
601
static void
602
mp2t_fragment_free_persistent_key(void *ptr)
603
1.97k
{
604
1.97k
    mp2t_fragment_key *key = (mp2t_fragment_key *)ptr;
605
1.97k
    g_slice_free(mp2t_fragment_key, key);
606
1.97k
}
607
608
static const reassembly_table_functions
609
mp2t_reassembly_table_functions = {
610
    mp2t_fragment_hash,
611
    mp2t_fragment_equal,
612
    mp2t_fragment_persistent_key,
613
    mp2t_fragment_persistent_key,
614
    mp2t_fragment_free_persistent_key,
615
    mp2t_fragment_free_persistent_key
616
};
617
618
static reassembly_table mp2t_reassembly_table;
619
620
void
621
mp2t_add_stream_type(packet_info *pinfo, uint32_t pid, uint32_t stream_type)
622
88
{
623
88
    mp2t_stream_key *stream;
624
625
88
    stream = (mp2t_stream_key *)p_get_proto_data(pinfo->pool, pinfo, proto_mp2t, MP2T_PROTO_DATA_STREAM);
626
88
    if (!stream) {
627
0
        return;
628
0
    }
629
630
88
    mp2t_analysis_data_t *mp2t_data = get_mp2t_conversation_data(stream);
631
88
    pid_analysis_data_t *pid_data = get_pid_analysis(mp2t_data, pid);
632
633
88
    if (!pid_data->stream_types) {
634
0
        pid_data->stream_types = wmem_tree_new(wmem_file_scope());
635
0
    }
636
637
88
    wmem_tree_insert32(pid_data->stream_types, pinfo->num, GUINT_TO_POINTER(stream_type));
638
88
}
639
640
static void
641
mp2t_dissect_packet(tvbuff_t *tvb, const pid_analysis_data_t *pid_analysis,
642
            packet_info *pinfo, proto_tree *tree)
643
756
{
644
756
    if (have_tap_listener(mp2t_follow_tap)) {
645
0
        tap_queue_packet(mp2t_follow_tap, pinfo, tvb);
646
0
    }
647
648
756
    switch (pid_analysis->pload_type) {
649
293
        case pid_pload_docsis:
650
293
            call_dissector(docsis_handle, tvb, pinfo, tree);
651
293
            break;
652
8
        case pid_pload_pes:
653
8
            call_dissector_with_data(mpeg_pes_handle, tvb, pinfo, tree, wmem_tree_lookup32_le(pid_analysis->stream_types, pinfo->num));
654
8
            break;
655
455
        case pid_pload_sect:
656
455
            call_dissector(mpeg_sect_handle, tvb, pinfo, tree);
657
455
            break;
658
0
        default:
659
            /* Should not happen */
660
0
            call_data_dissector(tvb, pinfo, tree);
661
0
            break;
662
756
    }
663
756
}
664
665
/* Determine the length of a payload packet. If there aren't enough
666
 * bytes to determine the length, returns -1. This will usually be
667
 * called on the first fragment of a packet, but will be called
668
 * on the second fragment if it returned -1 previously. (Returning
669
 * -1 a second time indicates issues with dropped packets, etc.)
670
 */
671
static unsigned
672
mp2t_get_packet_length(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
673
            uint32_t frag_id, enum pid_payload_type pload_type)
674
815
{
675
815
    mp2t_stream_key *stream;
676
815
    fragment_head *frag_head;
677
815
    fragment_item *frag = NULL;
678
815
    tvbuff_t      *len_tvb = NULL, *frag_tvb = NULL, *data_tvb = NULL;
679
815
    int            pkt_len = 0;
680
815
    unsigned       remaining_len;
681
682
815
    stream = (mp2t_stream_key *)p_get_proto_data(pinfo->pool, pinfo, proto_mp2t, MP2T_PROTO_DATA_STREAM);
683
815
    if (pinfo->fd->visited) {
684
0
        frag_head = fragment_get_reassembled_id(&mp2t_reassembly_table, pinfo, frag_id);
685
0
        if (frag_head) {
686
0
            len_tvb = frag_head->tvb_data;
687
0
            offset = 0;
688
0
        } else {
689
            /* Not reassembled on the first pass. There are two possibilities:
690
             * 1) An entire packet contained within a TSP, so it never was
691
             * put in the table.
692
             * 2) Dangling fragments at the end of the capture.
693
             */
694
0
            frag_head = fragment_get(&mp2t_reassembly_table, pinfo, frag_id, stream);
695
0
            if (!frag_head) {
696
                /* This is the entire packet */
697
0
                len_tvb = tvb;
698
0
            } else {
699
                /* Dangling packets at the end that failed to reassemble the
700
                 * first time around, so don't bother this time
701
                 */
702
0
                return -1;
703
0
            }
704
0
        }
705
815
    } else {
706
815
        frag_head = fragment_get(&mp2t_reassembly_table, pinfo, frag_id, stream);
707
815
        if (frag_head) {
708
21
            frag = frag_head->next;
709
21
        }
710
711
815
        if (!frag) { /* First frame */
712
794
            len_tvb = tvb;
713
794
        } else {
714
            /* Create a composite tvb out of the two */
715
21
            frag_tvb = tvb_new_subset_remaining(frag->tvb_data, 0);
716
21
            len_tvb = tvb_new_composite();
717
21
            tvb_composite_append(len_tvb, frag_tvb);
718
719
21
            data_tvb = tvb_new_subset_remaining(tvb, offset);
720
21
            tvb_composite_append(len_tvb, data_tvb);
721
21
            tvb_composite_finalize(len_tvb);
722
723
21
            offset = frag->offset;
724
21
        }
725
815
    }
726
727
    /* Get the next packet's size if possible; if not, return -1 */
728
815
    remaining_len = tvb_reported_length_remaining(len_tvb, offset);
729
    /* Normally the only time we would not enough info to determine the size
730
     * of the encapsulated packet is when the first fragment is at the very end
731
     * of a TSP, but prevent exceptions in the case of dropped and OOO frames.
732
     */
733
815
    switch (pload_type) {
734
309
        case pid_pload_docsis:
735
309
            if (remaining_len < 4)
736
10
                return -1;
737
299
            pkt_len = tvb_get_ntohs(len_tvb, offset + 2) + 6;
738
299
            break;
739
10
        case pid_pload_pes:
740
10
            if (remaining_len < 6)
741
0
                return -1;
742
10
            pkt_len = tvb_get_ntohs(len_tvb, offset + 4);
743
10
            if (pkt_len) /* A size of 0 means size not bounded */
744
10
                pkt_len += 6;
745
10
            break;
746
496
        case pid_pload_sect:
747
496
            if (remaining_len < 3)
748
10
                return -1;
749
486
            pkt_len = (tvb_get_ntohs(len_tvb, offset + 1) & 0xFFF) + 3;
750
486
            break;
751
0
        default:
752
            /* Should not happen */
753
0
            break;
754
815
    }
755
756
795
    return pkt_len;
757
815
}
758
759
static void
760
mp2t_fragment_handle(tvbuff_t *tvb, unsigned offset, packet_info *pinfo,
761
        proto_tree *tree, uint32_t frag_id,
762
        unsigned frag_offset, unsigned frag_len,
763
        bool fragment_last, const pid_analysis_data_t *pid_analysis)
764
803
{
765
803
    fragment_head   *frag_msg;
766
803
    proto_item      *ti;
767
803
    tvbuff_t        *new_tvb;
768
803
    const char      *save_proto;
769
803
    mp2t_stream_key *stream;
770
803
    bool             save_fragmented;
771
772
803
    save_fragmented = pinfo->fragmented;
773
803
    pinfo->fragmented = true;
774
    /* It's possible that a fragment in the same packet set an address already
775
     * (e.g., with MPE), which is why we use the conversation and direction not
776
     * the addresses in the packet_info to reassemble.
777
     */
778
779
803
    stream = (mp2t_stream_key *)p_get_proto_data(pinfo->pool, pinfo, proto_mp2t, MP2T_PROTO_DATA_STREAM);
780
    /* check length; send frame for reassembly */
781
803
    frag_msg = fragment_add_check(&mp2t_reassembly_table,
782
803
            tvb, offset, pinfo, frag_id, stream,
783
803
            frag_offset,
784
803
            frag_len,
785
803
            !fragment_last);
786
787
    /* We only want to call subdissectors on the last fragment.
788
     * processed_reassembled_data checks the frame number and layer number,
789
     * but when there is more than one TSP in a frame, the fragment at the
790
     * end of one TSP and the first fragment of the next have the same layer
791
     * number. So use our own information about whether this is the last
792
     * fragment to avoid calling subdissectors early and often.
793
     */
794
803
    if (fragment_last) {
795
413
        new_tvb = process_reassembled_data(tvb, offset, pinfo,
796
413
                "Reassembled MP2T",
797
413
                frag_msg, &mp2t_msg_frag_items,
798
413
                NULL, tree);
799
413
    } else {
800
390
        new_tvb = NULL;
801
390
        if (frag_msg != NULL) {
802
0
            ti = proto_tree_add_uint(tree, hf_msg_reassembled_in, tvb, 0, 0, frag_msg->reassembled_in);
803
0
            proto_item_set_generated(ti);
804
0
        }
805
390
    }
806
807
803
    if (new_tvb) {
808
354
        proto_tree_add_item(tree, hf_msg_ts_packet_reassembled, tvb, 0, 0, ENC_NA);
809
354
        save_proto = pinfo->current_proto;
810
        /*
811
         * Dissect the reassembled packet.
812
         *
813
         * Because there isn't an explicit fragment ID (other than one
814
         * we've made ourselves) if frames were dropped or out of order
815
         * it's quite likely that a subdissector throws an exception.
816
         * However, that doesn't mean we must stop dissecting, since we have
817
         * the pointer to where the next upper level packet begins in the
818
         * TSP begins. (Also, we want to make sure we increment our fragment
819
         * ID and store the packet analysis data, which happens after this
820
         * back in the calling function.)
821
         */
822
354
        TRY {
823
354
            mp2t_dissect_packet(new_tvb, pid_analysis, pinfo, tree);
824
354
        }
825
354
        CATCH_NONFATAL_ERRORS {
826
269
            show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
827
828
269
            pinfo->current_proto = save_proto;
829
269
        }
830
354
        ENDTRY;
831
449
    } else {
832
449
        col_set_str(pinfo->cinfo, COL_INFO, "[MP2T fragment of a reassembled packet]");
833
449
    }
834
835
803
    pinfo->fragmented = save_fragmented;
836
803
}
837
838
839
/*
840
 * Reassembly of various payload types.
841
 *
842
 * DOCSIS MAC frames, PES packets, etc. may begin anywhere within an MPEG-TS
843
 * packet or span multiple MPEG packets.
844
 *
845
 * The payload_unit_start_indicator bit in the MPEG-TS header, and the pointer
846
 * field, are used to reassemble fragmented frames from MPEG-TS packets.
847
 *
848
 * If that bit is set, a higher-level packet begins in this MPEG-TS
849
 * packet, and the MPEG-TS header is followed by a 1-octet pointer field.
850
 * The value of the pointer field indicates at which byte the higher-
851
 * level packet begins.  If that bit is not set, the packet begun in
852
 * an earlier MPEG-TS packet continues in this packet, with the data
853
 * in the payload going after the data in the previous MPEG-TS packet
854
 * (there can be more than one continuing packet).
855
 *
856
 * If the pointer field is non-zero, this MPEG-TS packet contains
857
 * the conclusion of one higher-level packet and the beginning of
858
 * the next packet.
859
 *
860
 * As the MPEG-TS packets are of a fixed size, stuff bytes are used
861
 * as padding before the first byte of a higher-level packet as
862
 * necessary.
863
 *
864
 * This diagram is from Data-Over-Cable Service Interface Specifications,
865
 * Downstream RF Interface Specification, CM-SP-DRFI-I16-170111, section 7
866
 * "DOWNSTREAM TRANSMISSION CONVERGENCE SUBLAYER", and shows how the
867
 * higher-level packets are transported over the MPEG Transport Stream:
868
 *
869
 *+--------------------------------------------------------------------------------+
870
 *|MPEG Header | pointer_field | stuff_bytes | Start of Packet #1                  |
871
 *|(PUSI = 1)  | (= 0)         | (0 or more) | (up to 183 bytes)                   |
872
 *+--------------------------------------------------------------------------------+
873
 *+--------------------------------------------------------------------------------+
874
 *|MPEG Header |  Continuation of Packet #1                                        |
875
 *|(PUSI = 0)  |  (up to 183 bytes)                                                |
876
 *+--------------------------------------------------------------------------------+
877
 *+---------------------------------------------------------------------------------+
878
 *|MPEG Header | pointer_field |Tail of Packet #1 | stuff_bytes |Start of Packet #2 |
879
 *|(PUSI = 1)  | (= M)         |(M bytes)         | (0 or more) |(N bytes)          |
880
 *+---------------------------------------------------------------------------------+
881
 *
882
 * For PES and PSI, see ISO/IEC 13818-1 / ITU-T Rec. H.222.0 (05/2006),
883
 * section 2.4.3.3 "Semantic definition of fields in Transport Stream packet
884
 * layer", which says much the same thing.
885
 *
886
 * When the payload is PES packet data, note that there is no pointer_field;
887
 * if the PUSI is 1 then the TS payload "will commence with the first byte
888
 * of a PES packet" and "one and only one PES packet starts in this Transport
889
 * Stream packet". Furthermore, section 2.4.3.5 "Semantic definition of
890
 * fields in adaptation field" mentions that stuffing in an adaptation field
891
 * is "the only method of stuffing allowed for Transport Stream packets
892
 * carrying PES packets." Thus stuff_bytes is not relevant for MPEG-TS payloads
893
 * carrying PES. (It is possible to have stuffing *inside* the PES packet,
894
 * as seen in section 2.4.3.6 "PES packet" and 2.4.3.7 "Semantic definition
895
 * of fields in PES packet", which is handled in the MPEG PES dissector.)
896
 *
897
 * For MPEG-TS packets carrying PSI (which includes private data sections), an
898
 * alternative stuffing method is allowed. This method involves stuff bytes
899
 * at the end of a MPEG-TS packet after the last section contained within
900
 * (similar to the stuff_bytes that may appear after a continued section
901
 * before the byte referenced by pointer_field). According to Section 2.4.4
902
 * "Program specific information", once a packet stuffing byte 0xFF appears,
903
 * "all bytes until the end of the Transport Stream packet shall also be
904
 * stuffing bytes of value 0xFF." In other words, as section C.3 "The Mapping
905
 * of Sections into Transport Stream Packets" elaborates, while multiple
906
 * entire sections are allowed within a TS packet, "no gaps between sections
907
 * within a Transport Stream packet are allowed by the syntax".
908
 *
909
 * However, this function is permissive in what it accepts to the extent
910
 * possible; it will allow multiple PES packets in the same TS packet and
911
 * stuffing bytes to follow PES packets (at least those that indicate their
912
 * length) and will allow stuffing bytes between complete PSI sections.
913
 */
914
static void
915
mp2t_process_fragmented_payload(tvbuff_t *tvb, int offset, unsigned remaining_len, packet_info *pinfo,
916
        proto_tree *tree, proto_tree *header_tree, uint32_t pusi_flag,
917
        pid_analysis_data_t *pid_analysis)
918
524
{
919
524
    tvbuff_t                  *next_tvb;
920
524
    uint8_t                    pointer       = 0;
921
524
    proto_item                *pi;
922
524
    unsigned                   stuff_len     = 0;
923
524
    proto_tree                *stuff_tree;
924
524
    packet_analysis_data_t    *pdata         = NULL;
925
524
    subpacket_analysis_data_t *spdata        = NULL;
926
524
    uint32_t                   frag_cur_pos  = 0, frag_tot_len = 0;
927
524
    bool                       fragmentation = false;
928
524
    uint32_t                   frag_id       = 0;
929
930
524
    if (pusi_flag && pid_analysis->pload_type == pid_pload_unknown
931
39
            && remaining_len > 3) {
932
        /* We should already have identified if it was a DOCSIS packet
933
         * Remaining possibility is PES or SECT */
934
39
        if (tvb_get_ntoh24(tvb, offset) == 0x000001) {
935
            /* Looks like a PES packet to me ... */
936
2
            pid_analysis->pload_type = pid_pload_pes;
937
37
        } else {
938
            /* Most probably a SECT packet */
939
37
            pid_analysis->pload_type = pid_pload_sect;
940
37
        }
941
39
    }
942
943
    /* Unable to determine the payload type, do nothing */
944
524
    if (pid_analysis->pload_type == pid_pload_unknown)
945
19
        return;
946
947
    /* PES packet don't have pointer fields, others do */
948
505
    if (pusi_flag && pid_analysis->pload_type != pid_pload_pes) {
949
494
        pi = proto_tree_add_item_ret_uint8(header_tree, hf_mp2t_pointer, tvb, offset, 1, ENC_BIG_ENDIAN, &pointer);
950
494
        offset++;
951
494
        remaining_len--;
952
494
        if (pointer > remaining_len) {
953
            /* Bogus pointer */
954
33
            expert_add_info_format(pinfo, pi, &ei_mp2t_pointer,
955
33
                    "Pointer value is too large (> remaining data length %u)",
956
33
                    remaining_len);
957
33
        }
958
494
    }
959
960
505
    if (!pinfo->fd->visited) {
961
        /* Get values from our current PID analysis */
962
505
        frag_cur_pos = pid_analysis->frag_cur_pos;
963
505
        frag_tot_len = pid_analysis->frag_tot_len;
964
505
        fragmentation = pid_analysis->fragmentation;
965
505
        frag_id = pid_analysis->frag_id;
966
505
        pdata = (packet_analysis_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mp2t, pinfo->curr_layer_num);
967
505
        if (!pdata) {
968
505
            pdata = wmem_new0(wmem_file_scope(), packet_analysis_data_t);
969
505
            pdata->subpacket_table = wmem_tree_new(wmem_file_scope());
970
            /* Since the subpacket data is indexed by offset in the tvb,
971
             * lacking a fragment id transmitted in the protocol,
972
             * we need a different table for each mp2t layer.
973
             */
974
505
            p_add_proto_data(wmem_file_scope(), pinfo, proto_mp2t, pinfo->curr_layer_num, pdata);
975
976
505
        } else {
977
0
            spdata = (subpacket_analysis_data_t *)wmem_tree_lookup32(pdata->subpacket_table, offset);
978
0
        }
979
980
505
        if (!spdata) {
981
505
            spdata = wmem_new0(wmem_file_scope(), subpacket_analysis_data_t);
982
            /* Save the info into pdata from pid_analysis */
983
505
            spdata->frag_cur_pos = frag_cur_pos;
984
505
            spdata->frag_tot_len = frag_tot_len;
985
505
            spdata->fragmentation = fragmentation;
986
505
            spdata->frag_id = frag_id;
987
505
            wmem_tree_insert32(pdata->subpacket_table, offset, (void *)spdata);
988
505
        }
989
505
    } else {
990
        /* Get saved values */
991
0
        pdata = (packet_analysis_data_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_mp2t, pinfo->curr_layer_num);
992
0
        if (!pdata) {
993
            /* Occurs for the first packets in the capture which cannot be reassembled */
994
0
            return;
995
0
        }
996
997
0
        spdata = (subpacket_analysis_data_t *)wmem_tree_lookup32(pdata->subpacket_table, offset);
998
0
        if (!spdata) {
999
            /* Occurs for the first sub packets in the capture which cannot be reassembled */
1000
0
            return;
1001
0
        }
1002
1003
0
        frag_cur_pos = spdata->frag_cur_pos;
1004
0
        frag_tot_len = spdata->frag_tot_len;
1005
0
        fragmentation = spdata->fragmentation;
1006
0
        frag_id = spdata->frag_id;
1007
0
    }
1008
1009
505
    if (frag_tot_len == (unsigned)-1) {
1010
        /* We couldn't determine the total length of the reassembly from
1011
         * the first fragment (too short), so get it now that we have the
1012
         * second fragment.
1013
         */
1014
25
        frag_tot_len = mp2t_get_packet_length(tvb, offset, pinfo, frag_id, pid_analysis->pload_type);
1015
1016
25
        if (frag_tot_len == (unsigned)-1) {
1017
            /* We still don't have enough to determine the length; this can
1018
             * only happen with dropped or out of order packets. Bail out.
1019
             * XXX: This just skips the packet and tries the next one, but
1020
             * there are probably better ways to handle it, especially if
1021
             * the PUSI flag is set in this packet.
1022
             */
1023
0
            return;
1024
0
        }
1025
25
    }
1026
1027
    /* The beginning of a new packet is present */
1028
505
    if (pusi_flag) {
1029
503
        if (pointer > remaining_len) {
1030
            /*
1031
             * Quit, so we don't use the bogus pointer value;
1032
             * that could cause remaining_len to become
1033
             * "negative", meaning it becomes a very large
1034
             * positive value.
1035
             */
1036
33
            return;
1037
33
        }
1038
1039
        /* "pointer" contains the number of bytes until the
1040
         * start of the new section
1041
         *
1042
         * if the new section does not start immediately after the
1043
         * pointer field (i.e. pointer>0), the remaining bytes before the
1044
         * start of the section are another fragment of the
1045
         * current packet
1046
         *
1047
         * if pointer is 0, a new upper-layer packet starts at the
1048
         * beginning of this TS packet
1049
         * if we have pending fragments, the last TS packet contained the
1050
         * last fragment and at the time we processed it, we couldn't figure
1051
         * out that it is the last fragment
1052
         * this is the case e.g. for PES packets with a 0 length field
1053
         * ("unbounded length")
1054
         * to handle this case, we add an empty fragment (pointer==0)
1055
         * and reassemble, then we process the current TS packet as
1056
         * usual
1057
         */
1058
470
        if (fragmentation) {
1059
413
            mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos,
1060
413
                    pointer, true, pid_analysis);
1061
413
            frag_id++;
1062
413
        }
1063
1064
470
        offset += pointer;
1065
470
        remaining_len -= pointer;
1066
470
        fragmentation = false;
1067
470
        frag_cur_pos = 0;
1068
470
        frag_tot_len = 0;
1069
1070
470
        if (!remaining_len) {
1071
            /* Shouldn't happen */
1072
1
            goto save_state;
1073
1
        }
1074
1075
871
        while (remaining_len > 0) {
1076
            /* Don't let subsequent packets overwrite the Info column */
1077
791
            col_append_str(pinfo->cinfo, COL_INFO, " ");
1078
791
            col_set_fence(pinfo->cinfo, COL_INFO);
1079
1080
            /* Skip stuff bytes */
1081
791
            stuff_len = 0;
1082
1.26k
            while ((tvb_get_uint8(tvb, offset + stuff_len) == 0xFF)) {
1083
473
                stuff_len++;
1084
473
                if (stuff_len >= remaining_len) {
1085
1
                    remaining_len = 0;
1086
1
                    break;
1087
1
                }
1088
473
            }
1089
1090
791
            if (stuff_len) {
1091
33
                stuff_tree = proto_tree_add_subtree_format(tree, tvb, offset, stuff_len, ett_stuff, NULL, "Stuffing");
1092
33
                proto_tree_add_item(stuff_tree, hf_mp2t_stuff_bytes, tvb, offset, stuff_len, ENC_NA);
1093
33
                offset += stuff_len;
1094
33
                if (stuff_len >= remaining_len) {
1095
1
                    goto save_state;
1096
1
                }
1097
32
                remaining_len -= stuff_len;
1098
32
            }
1099
1100
            /* Get the next packet's size if possible */
1101
790
            frag_tot_len = mp2t_get_packet_length(tvb, offset, pinfo, frag_id, pid_analysis->pload_type);
1102
790
            if (frag_tot_len == (unsigned)-1 || !frag_tot_len) {
1103
20
                mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, 0, remaining_len, false, pid_analysis);
1104
20
                fragmentation = true;
1105
                /*offset += remaining_len;*/
1106
20
                frag_cur_pos += remaining_len;
1107
20
                goto save_state;
1108
20
            }
1109
1110
            /* Check for full packets within this TS frame */
1111
770
            if (frag_tot_len <= remaining_len) {
1112
402
                next_tvb = tvb_new_subset_length(tvb, offset, frag_tot_len);
1113
402
                mp2t_dissect_packet(next_tvb, pid_analysis, pinfo, tree);
1114
402
                remaining_len -= frag_tot_len;
1115
402
                offset += frag_tot_len;
1116
402
                frag_tot_len = 0;
1117
402
                frag_id++;
1118
402
            } else {
1119
368
                break;
1120
368
            }
1121
770
        }
1122
1123
448
        if (remaining_len == 0) {
1124
1
            pid_analysis->frag_cur_pos = 0;
1125
1
            pid_analysis->frag_tot_len = 0;
1126
1
            goto save_state;
1127
1128
1
        }
1129
1130
448
    }
1131
1132
    /* There are remaining bytes. Add them to the fragment list */
1133
1134
449
    if (frag_tot_len && frag_cur_pos + remaining_len > frag_tot_len) {
1135
        /* The case where PUSI was 0, a continuing SECT ended, and stuff
1136
         * bytes follow. */
1137
0
        stuff_len = frag_cur_pos + remaining_len - frag_tot_len;
1138
0
        mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, remaining_len - stuff_len, true, pid_analysis);
1139
0
        offset += remaining_len - stuff_len;
1140
0
        frag_id++;
1141
0
        fragmentation = false;
1142
0
        frag_cur_pos = 0;
1143
0
        frag_tot_len = 0;
1144
0
        stuff_tree = proto_tree_add_subtree_format(tree, tvb, offset, stuff_len, ett_stuff, NULL, "Stuffing");
1145
0
        proto_tree_add_item(stuff_tree, hf_mp2t_stuff_bytes, tvb, offset, stuff_len, ENC_NA);
1146
449
    } else if ((frag_tot_len && frag_cur_pos + remaining_len == frag_tot_len) || (!frag_tot_len && pusi_flag)) {
1147
0
        mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, remaining_len, true, pid_analysis);
1148
0
        frag_id++;
1149
0
        fragmentation = false;
1150
0
        frag_cur_pos = 0;
1151
0
        frag_tot_len = 0;
1152
449
    } else {
1153
449
        mp2t_fragment_handle(tvb, offset, pinfo, tree, frag_id, frag_cur_pos, remaining_len, false, pid_analysis);
1154
449
        fragmentation = true;
1155
449
        frag_cur_pos += remaining_len;
1156
449
    }
1157
1158
    /* XXX: Ideally this would be handled with a TRY...FINALLY or
1159
     * similar, with more care taken to keep things consistent even
1160
     * with fatal errors in subdissectors.
1161
     */
1162
449
save_state:
1163
393
    pid_analysis->fragmentation = fragmentation;
1164
393
    pid_analysis->frag_cur_pos = frag_cur_pos;
1165
393
    pid_analysis->frag_tot_len = frag_tot_len;
1166
393
    pid_analysis->frag_id = frag_id;
1167
393
}
1168
1169
1170
1171
/* Calc the number of skipped CC numbers. Note that this can easy
1172
 * overflow, and a value above 7 indicate several network packets
1173
 * could be lost.
1174
 */
1175
static uint32_t
1176
calc_skips(int32_t curr, int32_t prev)
1177
137
{
1178
137
    int res;
1179
1180
    /* Only count the missing TS frames in between prev and curr.
1181
     * The "prev" frame CC number seen is confirmed received, it's
1182
     * the next frames CC counter which is the first known missing
1183
     * TS frame
1184
     */
1185
137
    prev += 1;
1186
1187
    /* Calc missing TS frame 'skips' */
1188
137
    res = curr - prev;
1189
1190
    /* Handle wrap around */
1191
137
    if (res < 0)
1192
121
        res += 16;
1193
1194
137
    return res;
1195
137
}
1196
1197
137
#define KEY(pid, cc) ((pid << 4)|cc)
1198
1199
static uint32_t
1200
detect_cc_drops(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
1201
        uint32_t pid, int32_t cc_curr, mp2t_analysis_data_t *mp2t_data)
1202
603
{
1203
603
    int32_t cc_prev = -1;
1204
603
    pid_analysis_data_t   *pid_data              = NULL;
1205
603
    ts_analysis_data_t    *ts_data               = NULL;
1206
603
    frame_analysis_data_t *frame_analysis_data_p = NULL;
1207
603
    proto_item            *flags_item;
1208
1209
603
    bool detected_drop = false;
1210
603
    uint32_t skips = 0;
1211
1212
    /* The initial sequential processing stage */
1213
603
    if (!pinfo->fd->visited) {
1214
        /* This is the sequential processing stage */
1215
603
        pid_data = get_pid_analysis(mp2t_data, pid);
1216
1217
603
        cc_prev = pid_data->cc_prev;
1218
603
        pid_data->cc_prev = cc_curr;
1219
1220
        /* Null packet always have a CC value equal 0 */
1221
603
        if (pid == 0x1fff)
1222
0
            return 0;
1223
1224
        /* Its allowed that (cc_prev == cc_curr) if adaptation field */
1225
603
        if (cc_prev == cc_curr)
1226
27
            return 0;
1227
1228
        /* Have not seen this pid before */
1229
576
        if (cc_prev == -1)
1230
83
            return 0;
1231
1232
        /* Detect if CC is not increasing by one all the time */
1233
493
        if (cc_curr != ((cc_prev+1) & MP2T_CC_MASK)) {
1234
137
            detected_drop = true;
1235
1236
137
            skips = calc_skips(cc_curr, cc_prev);
1237
1238
137
            mp2t_data->total_skips += skips;
1239
137
            mp2t_data->total_discontinuity++;
1240
            /* TODO: if (skips > 7) signal_loss++; ??? */
1241
137
        }
1242
493
    }
1243
1244
    /* Save the info about the dropped packet */
1245
493
    if (detected_drop && !pinfo->fd->visited) {
1246
        /* Lookup frame data, contains TS pid data objects */
1247
137
        frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo);
1248
137
        if (!frame_analysis_data_p)
1249
136
            frame_analysis_data_p = init_frame_analysis_data(mp2t_data, pinfo);
1250
1251
        /* Create and store a new TS frame pid_data object.
1252
           This indicate that we have a drop
1253
         */
1254
137
        ts_data = wmem_new0(wmem_file_scope(), struct ts_analysis_data);
1255
137
        ts_data->cc_prev = cc_prev;
1256
137
        ts_data->pid = pid;
1257
137
        ts_data->skips = skips;
1258
137
        wmem_tree_insert32(frame_analysis_data_p->ts_table, KEY(pid, cc_curr),
1259
137
                 (void *)ts_data);
1260
137
    }
1261
1262
    /* See if we stored info about drops */
1263
493
    if (pinfo->fd->visited) {
1264
1265
        /* Lookup frame data, contains TS pid data objects */
1266
0
        frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo);
1267
0
        if (!frame_analysis_data_p)
1268
0
            return 0; /* No stored frame data -> no drops*/
1269
0
        else {
1270
0
            ts_data = (struct ts_analysis_data *)wmem_tree_lookup32(frame_analysis_data_p->ts_table,
1271
0
                           KEY(pid, cc_curr));
1272
1273
0
            if (ts_data) {
1274
0
                if (ts_data->skips > 0) {
1275
0
                    detected_drop = true;
1276
0
                    cc_prev = ts_data->cc_prev;
1277
0
                    skips   = ts_data->skips;
1278
0
                }
1279
0
            }
1280
0
        }
1281
0
    }
1282
1283
    /* Add info to the proto tree about drops */
1284
493
    if (detected_drop) {
1285
137
        expert_add_info_format(pinfo, tree, &ei_mp2t_cc_drop,
1286
137
                "Detected %d missing TS frames before this (last_cc:%d total skips:%d discontinuity:%d)",
1287
137
                skips, cc_prev,
1288
137
                mp2t_data->total_skips,
1289
137
                mp2t_data->total_discontinuity
1290
137
                );
1291
1292
137
        flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_skips,
1293
137
                tvb, 0, 0, skips);
1294
137
        proto_item_set_generated(flags_item);
1295
1296
137
        flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_drops,
1297
137
                tvb, 0, 0, 1);
1298
137
        proto_item_set_generated(flags_item);
1299
137
    }
1300
493
    return skips;
1301
493
}
1302
1303
static int
1304
dissect_mp2t_adaptation_field(tvbuff_t *tvb, int offset, proto_tree *tree)
1305
149
{
1306
149
    int         af_start_offset;
1307
149
    proto_item *hi;
1308
149
    proto_tree *mp2t_af_tree;
1309
149
    uint8_t     af_length;
1310
149
    uint8_t     af_flags;
1311
149
    int         stuffing_len;
1312
1313
149
    proto_tree_add_item_ret_uint8(tree, hf_mp2t_af_length, tvb, offset, 1, ENC_BIG_ENDIAN, &af_length);
1314
149
    offset += 1;
1315
    /* fix issues where afc==3 but af_length==0
1316
     *  Adaptation field...spec section 2.4.3.5: The value 0 is for inserting a single
1317
     *  stuffing byte in a Transport Stream packet. When the adaptation_field_control
1318
     *  value is '11', the value of the adaptation_field_length shall be in the range 0 to 182.
1319
     */
1320
149
    if (af_length == 0)
1321
26
        return offset;
1322
1323
123
    af_start_offset = offset;
1324
1325
123
    hi = proto_tree_add_item( tree, hf_mp2t_af, tvb, offset, af_length, ENC_NA);
1326
123
    mp2t_af_tree = proto_item_add_subtree( hi, ett_mp2t_af );
1327
1328
123
    af_flags = tvb_get_uint8(tvb, offset);
1329
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_di, tvb, offset, 1, ENC_BIG_ENDIAN);
1330
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_rai, tvb, offset, 1, ENC_BIG_ENDIAN);
1331
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_espi, tvb, offset, 1, ENC_BIG_ENDIAN);
1332
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_pcr_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1333
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_opcr_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1334
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sp_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1335
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1336
123
    proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_afe_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1337
123
    offset += 1;
1338
1339
123
    if (af_flags &  MP2T_AF_PCR_MASK) {
1340
58
        uint64_t pcr_base;
1341
58
        uint16_t pcr_ext;
1342
1343
        /* 33 bit PCR base, 6 bit reserved, 9 bit PCR ext */
1344
58
        pcr_base = tvb_get_ntoh48(tvb, offset) >> (48-33);
1345
58
        pcr_ext  = (uint16_t)(tvb_get_ntoh48(tvb, offset) & 0x1FF);
1346
1347
58
         proto_tree_add_uint64(mp2t_af_tree, hf_mp2t_af_pcr, tvb, offset, 6,
1348
58
                pcr_base*300 + pcr_ext);
1349
1350
58
        offset += 6;
1351
58
    }
1352
1353
123
    if (af_flags &  MP2T_AF_OPCR_MASK) {
1354
53
        uint64_t opcr_base;
1355
53
        uint16_t opcr_ext;
1356
1357
        /* the same format as PCR above */
1358
53
        opcr_base = tvb_get_ntoh48(tvb, offset) >> (48-33);
1359
53
        opcr_ext  = (uint16_t)(tvb_get_ntoh48(tvb, offset) & 0x1FF);
1360
1361
53
        proto_tree_add_uint64(mp2t_af_tree, hf_mp2t_af_opcr, tvb, offset, 6,
1362
53
                opcr_base*300 + opcr_ext);
1363
1364
53
        offset += 6;
1365
53
    }
1366
1367
123
    if (af_flags &  MP2T_AF_SP_MASK) {
1368
53
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sc, tvb, offset, 1, ENC_BIG_ENDIAN);
1369
53
        offset += 1;
1370
53
    }
1371
1372
123
    if (af_flags &  MP2T_AF_TPD_MASK) {
1373
53
        uint8_t tpd_len;
1374
1375
53
        tpd_len = tvb_get_uint8(tvb, offset);
1376
53
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1377
53
        offset += 1;
1378
1379
53
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd, tvb, offset, tpd_len, ENC_NA);
1380
53
        offset += tpd_len;
1381
53
    }
1382
1383
123
    if (af_flags &  MP2T_AF_AFE_MASK) {
1384
59
        uint8_t e_len;
1385
59
        uint8_t e_flags;
1386
59
        int e_start_offset = offset;
1387
59
        int reserved_len = 0;
1388
1389
59
        e_len = tvb_get_uint8(tvb, offset);
1390
59
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_length, tvb, offset, 1, ENC_BIG_ENDIAN);
1391
59
        offset += 1;
1392
1393
59
        e_flags = tvb_get_uint8(tvb, offset);
1394
59
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltw_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1395
59
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1396
59
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ss_flag, tvb, offset, 1, ENC_BIG_ENDIAN);
1397
59
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
1398
59
        offset += 1;
1399
1400
59
        if (e_flags & MP2T_AF_E_LTW_FLAG_MASK) {
1401
22
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwv_flag, tvb, offset, 2, ENC_BIG_ENDIAN);
1402
22
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwo, tvb, offset, 2, ENC_BIG_ENDIAN);
1403
22
            offset += 2;
1404
22
        }
1405
1406
59
        if (e_flags & MP2T_AF_E_PR_FLAG_MASK) {
1407
23
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_reserved, tvb, offset, 3, ENC_BIG_ENDIAN);
1408
23
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr, tvb, offset, 3, ENC_BIG_ENDIAN);
1409
23
            offset += 3;
1410
23
        }
1411
1412
59
        if (e_flags & MP2T_AF_E_SS_FLAG_MASK) {
1413
31
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_st, tvb, offset, 1, ENC_BIG_ENDIAN);
1414
31
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_32_30, tvb, offset, 1, ENC_BIG_ENDIAN);
1415
31
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_1, tvb, offset, 1, ENC_BIG_ENDIAN);
1416
31
            offset += 1;
1417
31
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_29_15, tvb, offset, 2, ENC_BIG_ENDIAN);
1418
31
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_2, tvb, offset, 2, ENC_BIG_ENDIAN);
1419
31
            offset += 2;
1420
31
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_14_0, tvb, offset, 2, ENC_BIG_ENDIAN);
1421
31
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_3, tvb, offset, 2, ENC_BIG_ENDIAN);
1422
31
            offset += 2;
1423
31
        }
1424
1425
59
        reserved_len = (e_len + 1) - (offset - e_start_offset);
1426
59
        if (reserved_len > 0) {
1427
45
            proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved_bytes, tvb, offset, reserved_len, ENC_NA);
1428
45
            offset += reserved_len;
1429
45
        }
1430
59
    }
1431
1432
123
    stuffing_len = af_length - (offset - af_start_offset);
1433
123
    if (stuffing_len > 0) {
1434
52
        proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_stuffing_bytes, tvb, offset, stuffing_len, ENC_NA);
1435
52
        offset += stuffing_len;
1436
52
    }
1437
1438
123
    return offset;
1439
149
}
1440
1441
static void
1442
dissect_tsp(tvbuff_t *tvb, int offset, packet_info *pinfo,
1443
        proto_tree *tree, mp2t_analysis_data_t *mp2t_data)
1444
26.8k
{
1445
26.8k
    uint32_t             header;
1446
26.8k
    unsigned             afc;
1447
26.8k
    int                  start_offset = offset;
1448
26.8k
    int                  payload_len;
1449
26.8k
    pid_analysis_data_t *pid_analysis;
1450
1451
26.8k
    uint32_t    skips;
1452
26.8k
    uint32_t    pid;
1453
26.8k
    uint32_t    cc;
1454
26.8k
    uint32_t    pusi_flag;
1455
1456
26.8k
    uint32_t tsc;
1457
1458
26.8k
    proto_item *ti;
1459
26.8k
    proto_item *hi;
1460
26.8k
    proto_item *item = NULL;
1461
26.8k
    proto_tree *mp2t_tree;
1462
26.8k
    proto_tree *mp2t_header_tree;
1463
26.8k
    proto_tree *mp2t_analysis_tree;
1464
26.8k
    proto_item *afci;
1465
1466
26.8k
    ti = proto_tree_add_item( tree, proto_mp2t, tvb, offset, MP2T_PACKET_SIZE, ENC_NA );
1467
26.8k
    mp2t_tree = proto_item_add_subtree( ti, ett_mp2t );
1468
1469
26.8k
    header = tvb_get_ntohl(tvb, offset);
1470
26.8k
    pusi_flag = (header & 0x00400000);
1471
26.8k
    pid = (header & MP2T_PID_MASK) >> MP2T_PID_SHIFT;
1472
26.8k
    tsc = (header & MP2T_TSC_MASK);
1473
26.8k
    afc = (header & MP2T_AFC_MASK) >> MP2T_AFC_SHIFT;
1474
26.8k
    cc  = (header & MP2T_CC_MASK)  >> MP2T_CC_SHIFT;
1475
1476
26.8k
    p_add_proto_data(pinfo->pool, pinfo, proto_mp2t, MP2T_PROTO_DATA_PID, GUINT_TO_POINTER(pid));
1477
26.8k
    proto_item_append_text(ti, " PID=0x%x CC=%d", pid, cc);
1478
26.8k
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG TS");
1479
1480
26.8k
    hi = proto_tree_add_uint(mp2t_tree, hf_mp2t_stream, tvb, 0, 0, mp2t_data->stream);
1481
26.8k
    proto_item_set_generated(hi);
1482
1483
26.8k
    hi = proto_tree_add_item( mp2t_tree, hf_mp2t_header, tvb, offset, 4, ENC_BIG_ENDIAN);
1484
26.8k
    mp2t_header_tree = proto_item_add_subtree( hi, ett_mp2t_header );
1485
1486
26.8k
    proto_tree_add_item( mp2t_header_tree, hf_mp2t_sync_byte, tvb, offset, 4, ENC_BIG_ENDIAN);
1487
26.8k
    proto_tree_add_item( mp2t_header_tree, hf_mp2t_tei, tvb, offset, 4, ENC_BIG_ENDIAN);
1488
26.8k
    proto_tree_add_item( mp2t_header_tree, hf_mp2t_pusi, tvb, offset, 4, ENC_BIG_ENDIAN);
1489
26.8k
    proto_tree_add_item( mp2t_header_tree, hf_mp2t_tp, tvb, offset, 4, ENC_BIG_ENDIAN);
1490
26.8k
    proto_tree_add_item( mp2t_header_tree, hf_mp2t_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
1491
26.8k
    proto_tree_add_item( mp2t_header_tree, hf_mp2t_tsc, tvb, offset, 4, ENC_BIG_ENDIAN);
1492
26.8k
    afci = proto_tree_add_item( mp2t_header_tree, hf_mp2t_afc, tvb, offset, 4, ENC_BIG_ENDIAN);
1493
26.8k
    proto_tree_add_item( mp2t_header_tree, hf_mp2t_cc, tvb, offset, 4, ENC_BIG_ENDIAN);
1494
1495
26.8k
    pid_analysis = get_pid_analysis(mp2t_data, pid);
1496
1497
26.8k
    if (pid_analysis->pload_type == pid_pload_unknown) {
1498
164
        if (pid == MP2T_PID_NULL) {
1499
38
            pid_analysis->pload_type = pid_pload_null;
1500
126
        } else if (pid == MP2T_PID_DOCSIS) {
1501
7
            pid_analysis->pload_type = pid_pload_docsis;
1502
7
        }
1503
164
    }
1504
1505
26.8k
    if (pid_analysis->pload_type == pid_pload_docsis && (afc != 1)) {
1506
        /* DOCSIS packets should not have an adaptation field */
1507
51
        expert_add_info_format(pinfo, afci, &ei_mp2t_invalid_afc,
1508
51
                               "Adaptation Field Control for DOCSIS packets must be 0x01");
1509
51
    }
1510
1511
26.8k
    if (pid_analysis->pload_type == pid_pload_null) {
1512
26.2k
        col_set_str(pinfo->cinfo, COL_INFO, "NULL packet");
1513
26.2k
        if (afc != 1) {
1514
12
            expert_add_info_format(pinfo, afci, &ei_mp2t_invalid_afc,
1515
12
                    "Adaptation Field Control for NULL packets must be 0x01");
1516
12
        }
1517
        /* Nothing more to do */
1518
26.2k
        return;
1519
26.2k
    }
1520
1521
603
    offset += 4;
1522
1523
    /* Create a subtree for analysis stuff */
1524
603
    mp2t_analysis_tree = proto_tree_add_subtree_format(mp2t_tree, tvb, offset, 0, ett_mp2t_analysis, &item, "MPEG2 PCR Analysis");
1525
603
    proto_item_set_generated(item);
1526
1527
603
    skips = detect_cc_drops(tvb, mp2t_analysis_tree, pinfo, pid, cc, mp2t_data);
1528
1529
603
    if (skips > 0)
1530
137
        proto_item_append_text(ti, " skips=%d", skips);
1531
1532
603
    if (afc == 2 || afc == 3)
1533
149
        offset = dissect_mp2t_adaptation_field(tvb, offset, mp2t_tree);
1534
1535
603
    if ((offset - start_offset) < MP2T_PACKET_SIZE)
1536
558
        payload_len = MP2T_PACKET_SIZE - (offset - start_offset);
1537
45
    else
1538
45
        payload_len = 0;
1539
1540
603
    if (!payload_len)
1541
1
        return;
1542
1543
602
    if (afc == 2) {
1544
18
        col_set_str(pinfo->cinfo, COL_INFO, "Adaptation field only");
1545
        /* The rest of the packet is stuffing bytes */
1546
18
        proto_tree_add_item( mp2t_tree, hf_mp2t_stuff_bytes, tvb, offset, payload_len, ENC_NA);
1547
18
        offset += payload_len;
1548
18
    }
1549
1550
602
    if (!tsc) {
1551
524
        mp2t_process_fragmented_payload(tvb, offset, payload_len, pinfo, tree, mp2t_tree, pusi_flag, pid_analysis);
1552
524
    } else {
1553
        /* Payload is scrambled */
1554
78
        col_set_str(pinfo->cinfo, COL_INFO, "Scrambled TS payload");
1555
78
    }
1556
602
}
1557
1558
static void
1559
export_pdu(tvbuff_t *tvb, packet_info *pinfo)
1560
26.8k
{
1561
26.8k
    if (have_tap_listener(exported_pdu_tap)) {
1562
0
        exp_pdu_data_t *exp_pdu_data = wmem_new0(pinfo->pool, exp_pdu_data_t);
1563
1564
0
        exp_pdu_data->tvb_captured_length = tvb_captured_length(tvb);
1565
0
        exp_pdu_data->tvb_reported_length = tvb_reported_length(tvb);
1566
0
        exp_pdu_data->pdu_tvb = tvb;
1567
0
        tap_queue_packet(exported_pdu_tap, pinfo, exp_pdu_data);
1568
0
    }
1569
26.8k
}
1570
1571
static int
1572
dissect_mp2t( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ )
1573
26.8k
{
1574
26.8k
    volatile unsigned     offset = 0;
1575
26.8k
    conversation_t       *conv;
1576
26.8k
    mp2t_stream_key      *stream;
1577
26.8k
    mp2t_analysis_data_t *mp2t_data;
1578
26.8k
    const char           *saved_proto;
1579
1580
26.8k
    conv = find_or_create_conversation(pinfo);
1581
26.8k
    stream = wmem_new(pinfo->pool, mp2t_stream_key);
1582
26.8k
    stream->conv = conv;
1583
    /* Conversations on UDP, etc. are bidirectional, but in the odd case
1584
     * that we have two MP2T streams in the opposite directions, we have to
1585
     * separately track their Continuity Counters, manage their fragmentation
1586
     * status information, etc.
1587
     */
1588
26.8k
    if (addresses_equal(&pinfo->src, conversation_key_addr1(conv->key_ptr))) {
1589
26.8k
        stream->dir = P2P_DIR_SENT;
1590
26.8k
    } else if (addresses_equal(&pinfo->dst, conversation_key_addr1(conv->key_ptr))) {
1591
0
        stream->dir = P2P_DIR_RECV;
1592
0
    } else {
1593
        /* DVB Base Band Frames, or some other endpoint that doesn't set the
1594
         * address, presumably unidirectional.
1595
         */
1596
0
        stream->dir = P2P_DIR_SENT;
1597
0
    }
1598
1599
26.8k
    p_add_proto_data(pinfo->pool, pinfo, proto_mp2t, MP2T_PROTO_DATA_STREAM, stream);
1600
1601
53.6k
    for (; tvb_reported_length_remaining(tvb, offset) >= MP2T_PACKET_SIZE; offset += MP2T_PACKET_SIZE) {
1602
        /*
1603
         * Dissect the TSP.
1604
         *
1605
         * If it gets an error that means there's no point in
1606
         * dissecting any more TSPs, rethrow the exception in
1607
         * question.
1608
         *
1609
         * If it gets any other error, report it and continue, as that
1610
         * means that TSP got an error, but that doesn't mean we should
1611
         * stop dissecting TSPs within this frame or chunk of reassembled
1612
         * data.
1613
         */
1614
26.8k
        saved_proto = pinfo->current_proto;
1615
26.8k
        export_pdu(tvb_new_subset_length(tvb, offset, MP2T_PACKET_SIZE), pinfo);
1616
26.8k
        TRY {
1617
26.8k
            mp2t_data = get_mp2t_conversation_data(stream);
1618
26.8k
            dissect_tsp(tvb, offset, pinfo, tree, mp2t_data);
1619
26.8k
        }
1620
26.8k
        CATCH_NONFATAL_ERRORS {
1621
123
            show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
1622
1623
            /*
1624
             * Restore the saved protocol as well; we do this after
1625
             * show_exception(), so that the "Malformed packet" indication
1626
             * shows the protocol for which dissection failed.
1627
             */
1628
123
            pinfo->current_proto = saved_proto;
1629
123
        }
1630
26.8k
        ENDTRY;
1631
26.8k
    }
1632
26.8k
    return tvb_captured_length(tvb);
1633
26.8k
}
1634
1635
static bool
1636
heur_dissect_mp2t( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
1637
920
{
1638
920
    int length;
1639
920
    unsigned offset = 0;
1640
1641
920
    length = tvb_reported_length_remaining(tvb, offset);
1642
920
    if (length == 0) {
1643
        /* Nothing to check for */
1644
0
        return false;
1645
0
    }
1646
920
    if ((length % MP2T_PACKET_SIZE) != 0) {
1647
        /* Not a multiple of the MPEG-2 transport packet size */
1648
914
        return false;
1649
914
    } else {
1650
10
        while (tvb_offset_exists(tvb, offset)) {
1651
7
            if (tvb_get_uint8(tvb, offset) != MP2T_SYNC_BYTE) {
1652
                /* No sync byte at the appropriate offset */
1653
3
                return false;
1654
3
            }
1655
4
            offset += MP2T_PACKET_SIZE;
1656
4
        }
1657
6
    }
1658
1659
3
    dissect_mp2t(tvb, pinfo, tree, data);
1660
3
    return true;
1661
920
}
1662
1663
1664
void
1665
proto_register_mp2t(void)
1666
15
{
1667
15
    static hf_register_info hf[] = {
1668
15
        { &hf_mp2t_stream, {
1669
15
            "Stream index", "mp2t.stream",
1670
15
            FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL
1671
15
        } } ,
1672
15
        { &hf_mp2t_header, {
1673
15
            "Header", "mp2t.header",
1674
15
            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL
1675
15
        } } ,
1676
15
        { &hf_mp2t_sync_byte, {
1677
15
            "Sync Byte", "mp2t.sync_byte",
1678
15
            FT_UINT32, BASE_HEX, VALS(mp2t_sync_byte_vals), MP2T_SYNC_BYTE_MASK, NULL, HFILL
1679
15
        } } ,
1680
15
        { &hf_mp2t_tei, {
1681
15
            "Transport Error Indicator", "mp2t.tei",
1682
15
            FT_UINT32, BASE_DEC, NULL, MP2T_TEI_MASK, NULL, HFILL
1683
15
        } } ,
1684
15
        { &hf_mp2t_pusi, {
1685
15
            "Payload Unit Start Indicator", "mp2t.pusi",
1686
15
            FT_UINT32, BASE_DEC, NULL, MP2T_PUSI_MASK, NULL, HFILL
1687
15
        } } ,
1688
15
        { &hf_mp2t_tp, {
1689
15
            "Transport Priority", "mp2t.tp",
1690
15
            FT_UINT32, BASE_DEC, NULL, MP2T_TP_MASK, NULL, HFILL
1691
15
        } } ,
1692
15
        { &hf_mp2t_pid, {
1693
15
            "PID", "mp2t.pid",
1694
15
            FT_UINT32, BASE_HEX, VALS(mp2t_pid_vals), MP2T_PID_MASK, NULL, HFILL
1695
15
        } } ,
1696
15
        { &hf_mp2t_tsc, {
1697
15
            "Transport Scrambling Control", "mp2t.tsc",
1698
15
            FT_UINT32, BASE_HEX, VALS(mp2t_tsc_vals), MP2T_TSC_MASK, NULL, HFILL
1699
15
        } } ,
1700
15
        { &hf_mp2t_afc, {
1701
15
            "Adaptation Field Control", "mp2t.afc",
1702
15
            FT_UINT32, BASE_HEX, VALS(mp2t_afc_vals) , MP2T_AFC_MASK, NULL, HFILL
1703
15
        } } ,
1704
15
        { &hf_mp2t_cc, {
1705
15
            "Continuity Counter", "mp2t.cc",
1706
15
            FT_UINT32, BASE_DEC, NULL, MP2T_CC_MASK, NULL, HFILL
1707
15
        } } ,
1708
#if 0
1709
        { &hf_mp2t_analysis_flags, {
1710
            "MPEG2-TS Analysis Flags", "mp2t.analysis.flags",
1711
            FT_NONE, BASE_NONE, NULL, 0x0,
1712
            "This frame has some of the MPEG2 analysis flags set", HFILL
1713
        } } ,
1714
#endif
1715
15
        { &hf_mp2t_analysis_skips, {
1716
15
            "TS Continuity Counter Skips", "mp2t.analysis.skips",
1717
15
            FT_UINT8, BASE_DEC, NULL, 0x0,
1718
15
            "Missing TS frames according to CC counter values", HFILL
1719
15
        } } ,
1720
15
        { &hf_mp2t_analysis_drops, {
1721
15
            "Some frames dropped", "mp2t.analysis.drops",
1722
15
            FT_UINT8, BASE_DEC, NULL, 0x0,
1723
15
            "Discontinuity: A number of TS frames were dropped", HFILL
1724
15
        } } ,
1725
15
        { &hf_mp2t_af, {
1726
15
            "Adaptation Field", "mp2t.af",
1727
15
            FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1728
15
        } } ,
1729
15
        { &hf_mp2t_af_length, {
1730
15
            "Adaptation Field Length", "mp2t.af.length",
1731
15
            FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
1732
15
        } } ,
1733
15
        { &hf_mp2t_af_di, {
1734
15
            "Discontinuity Indicator", "mp2t.af.di",
1735
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_DI_MASK, NULL, HFILL
1736
15
        } } ,
1737
15
        { &hf_mp2t_af_rai, {
1738
15
            "Random Access Indicator", "mp2t.af.rai",
1739
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_RAI_MASK, NULL, HFILL
1740
15
        } } ,
1741
15
        { &hf_mp2t_af_espi, {
1742
15
            "Elementary Stream Priority Indicator", "mp2t.af.espi",
1743
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_ESPI_MASK, NULL, HFILL
1744
15
        } } ,
1745
15
        { &hf_mp2t_af_pcr_flag, {
1746
15
            "PCR Flag", "mp2t.af.pcr_flag",
1747
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_PCR_MASK, NULL, HFILL
1748
15
        } } ,
1749
15
        { &hf_mp2t_af_opcr_flag, {
1750
15
            "OPCR Flag", "mp2t.af.opcr_flag",
1751
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_OPCR_MASK, NULL, HFILL
1752
15
        } } ,
1753
15
        { &hf_mp2t_af_sp_flag, {
1754
15
            "Splicing Point Flag", "mp2t.af.sp_flag",
1755
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_SP_MASK, NULL, HFILL
1756
15
        } } ,
1757
15
        { &hf_mp2t_af_tpd_flag, {
1758
15
            "Transport Private Data Flag", "mp2t.af.tpd_flag",
1759
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_TPD_MASK, NULL, HFILL
1760
15
        } } ,
1761
15
        { &hf_mp2t_af_afe_flag, {
1762
15
            "Adaptation Field Extension Flag", "mp2t.af.afe_flag",
1763
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_AFE_MASK, NULL, HFILL
1764
15
        } } ,
1765
15
        { &hf_mp2t_af_pcr, {
1766
15
            "Program Clock Reference", "mp2t.af.pcr",
1767
15
            FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL
1768
15
        } } ,
1769
15
        { &hf_mp2t_af_opcr, {
1770
15
            "Original Program Clock Reference", "mp2t.af.opcr",
1771
15
            FT_UINT64, BASE_HEX, NULL, 0, NULL, HFILL
1772
15
        } } ,
1773
15
        { &hf_mp2t_af_sc, {
1774
15
            "Splice Countdown", "mp2t.af.sc",
1775
15
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
1776
15
        } } ,
1777
15
        { &hf_mp2t_af_tpd_length, {
1778
15
            "Transport Private Data Length", "mp2t.af.tpd_length",
1779
15
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
1780
15
        } } ,
1781
15
        { &hf_mp2t_af_tpd, {
1782
15
            "Transport Private Data", "mp2t.af.tpd",
1783
15
            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL
1784
15
        } } ,
1785
15
        { &hf_mp2t_af_e_length, {
1786
15
            "Adaptation Field Extension Length", "mp2t.af.e_length",
1787
15
            FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
1788
15
        } } ,
1789
15
        { &hf_mp2t_af_e_ltw_flag, {
1790
15
            "LTW Flag", "mp2t.af.e.ltw_flag",
1791
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_LTW_FLAG_MASK, NULL, HFILL
1792
15
        } } ,
1793
15
        { &hf_mp2t_af_e_pr_flag, {
1794
15
            "Piecewise Rate Flag", "mp2t.af.e.pr_flag",
1795
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_PR_FLAG_MASK, NULL, HFILL
1796
15
        } } ,
1797
15
        { &hf_mp2t_af_e_ss_flag, {
1798
15
            "Seamless Splice Flag", "mp2t.af.e.ss_flag",
1799
15
            FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_SS_FLAG_MASK, NULL, HFILL
1800
15
        } } ,
1801
15
        { &hf_mp2t_af_e_reserved, {
1802
15
            "Reserved", "mp2t.af.e.reserved",
1803
15
            FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL
1804
15
        } } ,
1805
15
        { &hf_mp2t_af_e_reserved_bytes, {
1806
15
            "Reserved", "mp2t.af.e.reserved_bytes",
1807
15
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1808
15
        } } ,
1809
15
        { &hf_mp2t_af_stuffing_bytes, {
1810
15
            "Stuffing", "mp2t.af.stuffing_bytes",
1811
15
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1812
15
        } } ,
1813
15
        { &hf_mp2t_af_e_ltwv_flag, {
1814
15
            "LTW Valid Flag", "mp2t.af.e.ltwv_flag",
1815
15
            FT_UINT16, BASE_DEC, NULL, 0x8000, NULL, HFILL
1816
15
        } } ,
1817
15
        { &hf_mp2t_af_e_ltwo, {
1818
15
            "LTW Offset", "mp2t.af.e.ltwo",
1819
15
            FT_UINT16, BASE_DEC, NULL, 0x7FFF, NULL, HFILL
1820
15
        } } ,
1821
15
        { &hf_mp2t_af_e_pr_reserved, {
1822
15
            "Reserved", "mp2t.af.e.pr_reserved",
1823
15
            FT_UINT24, BASE_DEC, NULL, 0xC00000, NULL, HFILL
1824
15
        } } ,
1825
15
        { &hf_mp2t_af_e_pr, {
1826
15
            "Piecewise Rate", "mp2t.af.e.pr",
1827
15
            FT_UINT24, BASE_DEC, NULL, 0x3FFFFF, NULL, HFILL
1828
15
        } } ,
1829
15
        { &hf_mp2t_af_e_st, {
1830
15
            "Splice Type", "mp2t.af.e.st",
1831
15
            FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL
1832
15
        } } ,
1833
15
        { &hf_mp2t_af_e_dnau_32_30, {
1834
15
            "DTS Next AU[32...30]", "mp2t.af.e.dnau_32_30",
1835
15
            FT_UINT8, BASE_DEC, NULL, 0x0E, NULL, HFILL
1836
15
        } } ,
1837
15
        { &hf_mp2t_af_e_m_1, {
1838
15
            "Marker Bit", "mp2t.af.e.m_1",
1839
15
            FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL
1840
15
        } } ,
1841
15
        { &hf_mp2t_af_e_dnau_29_15, {
1842
15
            "DTS Next AU[29...15]", "mp2t.af.e.dnau_29_15",
1843
15
            FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL
1844
15
        } } ,
1845
15
        { &hf_mp2t_af_e_m_2, {
1846
15
            "Marker Bit", "mp2t.af.e.m_2",
1847
15
            FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL
1848
15
        } } ,
1849
15
        { &hf_mp2t_af_e_dnau_14_0, {
1850
15
            "DTS Next AU[14...0]", "mp2t.af.e.dnau_14_0",
1851
15
            FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL
1852
15
        } } ,
1853
15
        { &hf_mp2t_af_e_m_3, {
1854
15
            "Marker Bit", "mp2t.af.e.m_3",
1855
15
            FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL
1856
15
        } } ,
1857
#if 0
1858
        { &hf_mp2t_payload, {
1859
            "Payload", "mp2t.payload",
1860
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1861
        } } ,
1862
#endif
1863
15
        { &hf_mp2t_stuff_bytes, {
1864
15
            "Stuffing", "mp2t.stuff_bytes",
1865
15
            FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1866
15
        } },
1867
15
        { &hf_mp2t_pointer, {
1868
15
            "Pointer", "mp2t.pointer",
1869
15
            FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
1870
15
        } },
1871
15
        {  &hf_msg_fragments, {
1872
15
            "Message fragments", "mp2t.msg.fragments",
1873
15
            FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL
1874
15
        } },
1875
15
        {  &hf_msg_fragment, {
1876
15
            "Message fragment", "mp2t.msg.fragment",
1877
15
            FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL
1878
15
        } },
1879
15
        {  &hf_msg_fragment_overlap, {
1880
15
            "Message fragment overlap", "mp2t.msg.fragment.overlap",
1881
15
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1882
15
        } },
1883
15
        {  &hf_msg_fragment_overlap_conflicts, {
1884
15
            "Message fragment overlapping with conflicting data",
1885
15
            "mp2t.msg.fragment.overlap.conflicts",
1886
15
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1887
15
        } },
1888
15
        {  &hf_msg_fragment_multiple_tails, {
1889
15
            "Message has multiple tail fragments",
1890
15
            "mp2t.msg.fragment.multiple_tails",
1891
15
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1892
15
        } },
1893
15
        {  &hf_msg_fragment_too_long_fragment, {
1894
15
            "Message fragment too long", "mp2t.msg.fragment.too_long_fragment",
1895
15
            FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1896
15
        } },
1897
15
        {  &hf_msg_fragment_error, {
1898
15
            "Message defragmentation error", "mp2t.msg.fragment.error",
1899
15
            FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL
1900
15
        } },
1901
15
        {  &hf_msg_fragment_count, {
1902
15
            "Message fragment count", "mp2t.msg.fragment.count",
1903
15
            FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL
1904
15
        } },
1905
15
        {  &hf_msg_reassembled_in, {
1906
15
            "Reassembled in", "mp2t.msg.reassembled.in",
1907
15
            FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL
1908
15
        } },
1909
15
        {  &hf_msg_reassembled_length, {
1910
15
            "Reassembled MP2T length", "mp2t.msg.reassembled.length",
1911
15
            FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL
1912
15
        } },
1913
15
        {  &hf_msg_ts_packet_reassembled, {
1914
15
            "MPEG TS Packet (reassembled)", "mp2t.ts_packet_reassembled",
1915
15
            FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL
1916
15
        } },
1917
15
    };
1918
1919
15
    static int *ett[] =
1920
15
    {
1921
15
        &ett_mp2t,
1922
15
        &ett_mp2t_header,
1923
15
        &ett_mp2t_af,
1924
15
        &ett_mp2t_analysis,
1925
15
        &ett_stuff,
1926
15
        &ett_msg_fragment,
1927
15
        &ett_msg_fragments
1928
15
    };
1929
1930
15
    static ei_register_info ei[] = {
1931
15
        { &ei_mp2t_pointer, { "mp2t.pointer_too_large", PI_MALFORMED, PI_ERROR, "Pointer value is too large", EXPFILL }},
1932
15
        { &ei_mp2t_cc_drop, { "mp2t.cc.drop", PI_SEQUENCE, PI_ERROR, "Detected missing TS frames", EXPFILL }},
1933
15
        { &ei_mp2t_invalid_afc, { "mp2t.afc.invalid", PI_PROTOCOL, PI_WARN,
1934
15
                                    "Adaptation Field Control contains an invalid value", EXPFILL }}
1935
15
    };
1936
1937
15
    expert_module_t* expert_mp2t;
1938
1939
15
    proto_mp2t = proto_register_protocol("ISO/IEC 13818-1", "MP2T", "mp2t");
1940
1941
15
    mp2t_handle = register_dissector("mp2t", dissect_mp2t, proto_mp2t);
1942
1943
15
    proto_register_field_array(proto_mp2t, hf, array_length(hf));
1944
15
    proto_register_subtree_array(ett, array_length(ett));
1945
15
    expert_mp2t = expert_register_protocol(proto_mp2t);
1946
15
    expert_register_field_array(expert_mp2t, ei, array_length(ei));
1947
1948
15
    heur_subdissector_list = register_heur_dissector_list_with_description("mp2t.pid", "Unused", proto_mp2t);
1949
    /* Register init of processing of fragmented DEPI packets */
1950
15
    reassembly_table_register(&mp2t_reassembly_table,
1951
15
        &mp2t_reassembly_table_functions);
1952
1953
15
    mp2t_stream_hashtable = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), mp2t_stream_hash, mp2t_stream_equal);
1954
1955
15
    register_init_routine(mp2t_init);
1956
1957
15
    exported_pdu_tap = register_export_pdu_tap_with_encap("MP2T", WTAP_ENCAP_MPEG_2_TS);
1958
15
    mp2t_follow_tap = register_tap("mp2t_follow");
1959
1960
    /* MPEG2 TS is sometimes carried on UDP or RTP over UDP so using the UDP
1961
     * address filter is better than nothing for tshark. */
1962
15
    register_follow_stream(proto_mp2t, "mp2t_follow", mp2t_follow_conv_filter, mp2t_follow_index_filter, udp_follow_address_filter, udp_port_to_display, follow_tvb_tap_listener, mp2t_get_stream_count, mp2t_get_sub_stream_id);
1963
15
}
1964
1965
1966
1967
void
1968
proto_reg_handoff_mp2t(void)
1969
15
{
1970
15
    heur_dissector_add("udp", heur_dissect_mp2t, "MP2T over UDP", "mp2t_udp", proto_mp2t, HEURISTIC_ENABLE);
1971
1972
15
    dissector_add_uint("rtp.pt", PT_MP2T, mp2t_handle);
1973
15
    dissector_add_for_decode_as_with_preference("tcp.port", mp2t_handle);
1974
15
    dissector_add_for_decode_as_with_preference("udp.port", mp2t_handle);
1975
15
    heur_dissector_add("usb.bulk", heur_dissect_mp2t, "MP2T USB bulk endpoint", "mp2t_usb_bulk", proto_mp2t, HEURISTIC_ENABLE);
1976
15
    dissector_add_uint("wtap_encap", WTAP_ENCAP_MPEG_2_TS, mp2t_handle);
1977
15
    dissector_add_uint("l2tp.pw_type", L2TPv3_PW_DOCSIS_DMPT, mp2t_handle);
1978
15
    dissector_add_string("media_type", "video/mp2t", mp2t_handle);
1979
1980
15
    docsis_handle = find_dissector("docsis");
1981
15
    mpeg_pes_handle = find_dissector("mpeg-pes");
1982
15
    mpeg_sect_handle = find_dissector("mpeg_sect");
1983
15
}
1984
1985
/*
1986
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1987
 *
1988
 * Local variables:
1989
 * c-basic-offset: 4
1990
 * tab-width: 8
1991
 * indent-tabs-mode: nil
1992
 * End:
1993
 *
1994
 * vi: set shiftwidth=4 tabstop=8 expandtab:
1995
 * :indentSize=4:tabSize=8:noTabs=true:
1996
 */