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-mpeg-sect.c
Line
Count
Source
1
/* packet-mpeg-sect.c
2
 * Routines for MPEG2 (ISO/ISO 13818-1) Section dissection
3
 * Copyright 2012, Guy Martin <gmsoft@tuxicoman.be>
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include "jtckdint.h"
15
16
#include <epan/packet.h>
17
#include <epan/prefs.h>
18
#include <epan/crc32-tvb.h>
19
#include <epan/expert.h>
20
#include <epan/decode_as.h>
21
#include <epan/proto_data.h>
22
#include "packet-mpeg-sect.h"
23
24
void proto_register_mpeg_sect(void);
25
26
static int proto_mpeg_sect;
27
static int hf_mpeg_sect_table_id;
28
static int hf_mpeg_sect_syntax_indicator;
29
static int hf_mpeg_sect_reserved;
30
static int hf_mpeg_sect_length;
31
static int hf_mpeg_sect_crc;
32
static int hf_mpeg_sect_crc_status;
33
34
static int ett_mpeg_sect;
35
36
static expert_field ei_mpeg_sect_crc;
37
38
static dissector_table_t mpeg_sect_tid_dissector_table;
39
40
static bool mpeg_sect_check_crc;
41
42
/* minimum length of the entire section ==
43
   bytes from table_id to section_length == 3 bytes */
44
1.36k
#define MPEG_SECT_MIN_LEN    3
45
/* the section_length field is 12 bits, it can add up to 4096 bytes
46
   after the initial bytes */
47
453
#define MPEG_SECT_MAX_LEN    MPEG_SECT_MIN_LEN+4096
48
49
50
120
#define MPEG_SECT_SYNTAX_INDICATOR_MASK 0x8000
51
19
#define MPEG_SECT_RESERVED_MASK         0x7000
52
399
#define MPEG_SECT_LENGTH_MASK           0x0FFF
53
54
/* From ISO/IEC 13818-1 */
55
enum {
56
    TID_PAT,
57
    TID_CA,
58
    TID_PMT,
59
    TID_TS_DESC,
60
    TID_SCENE_DESC,
61
    TID_OBJECT_DESC,
62
    TID_FORBIDEN    = 0xFF
63
};
64
65
/* From ETSI EN 300 468 */
66
enum {
67
    TID_NIT       = 0x40,
68
    TID_NIT_OTHER,
69
    TID_SDT,
70
    TID_SDT_OTHER = 0x46,
71
    TID_BAT       = 0x4A,
72
    TID_EIT_PF    = 0x4E,
73
    TID_EIT_PF_OTHER,
74
    TID_EIT_SC0   = 0x50,
75
    TID_EIT_SC1,
76
    TID_EIT_SC2,
77
    TID_EIT_SC3,
78
    TID_EIT_SC4,
79
    TID_EIT_SC5,
80
    TID_EIT_SC6,
81
    TID_EIT_SC7,
82
    TID_EIT_SC8,
83
    TID_EIT_SC9,
84
    TID_EIT_SCA,
85
    TID_EIT_SCB,
86
    TID_EIT_SCC,
87
    TID_EIT_SCD,
88
    TID_EIT_SCE,
89
    TID_EIT_SCF,
90
    TID_EIT_SC0_OTH = 0x60,
91
    TID_EIT_SC1_OTH,
92
    TID_EIT_SC2_OTH,
93
    TID_EIT_SC3_OTH,
94
    TID_EIT_SC4_OTH,
95
    TID_EIT_SC5_OTH,
96
    TID_EIT_SC6_OTH,
97
    TID_EIT_SC7_OTH,
98
    TID_EIT_SC8_OTH,
99
    TID_EIT_SC9_OTH,
100
    TID_EIT_SCA_OTH,
101
    TID_EIT_SCB_OTH,
102
    TID_EIT_SCC_OTH,
103
    TID_EIT_SCD_OTH,
104
    TID_EIT_SCE_OTH,
105
    TID_EIT_SCF_OTH,
106
    TID_TDT       = 0x70,
107
    TID_RST,
108
    TID_ST,
109
    TID_TOT,
110
    TID_SIT       = 0x7F
111
};
112
113
/* From ETSI EN 301 790 */
114
enum {
115
    TID_RMT = 0x41, /* Conflict with TID_NIT_OTHER */
116
    TID_SCT = 0xA0,
117
    TID_FCT,
118
    TID_TCT,
119
    TID_SPT,
120
    TID_CMT,
121
    TID_TBTP,
122
    TID_PCR,
123
    TID_TIM = 0xB0
124
};
125
126
/* From ETSI EN 301 192 */
127
enum {
128
    TID_DVB_MPE = 0x3E
129
};
130
131
/* From OC-SP-ETV-AM 1.0-IO5 */
132
enum {
133
    TID_ETV_EISS = 0xE0,
134
    TID_ETV_DII  = 0xE3,
135
    TID_ETV_DDB  = 0xE4
136
};
137
138
/* From ETSI TS 102 899 */
139
enum {
140
    TID_AIT = 0x74
141
};
142
143
144
static const value_string mpeg_sect_table_id_vals[] = {
145
146
    { TID_PAT,         "Program Association Table (PAT)" },
147
    { TID_CA,          "Conditional Access (CA)" },
148
    { TID_PMT,         "Program Map Table (PMT)" },
149
    { TID_TS_DESC,     "Transport Stream Description" },
150
    { TID_SCENE_DESC,  "ISO/IEC 14496 Scene Description" },
151
    { TID_OBJECT_DESC, "ISO/IEC 14496 Object Description" },
152
    { TID_NIT,         "Network Information Table (NIT), current network" },
153
    { TID_NIT_OTHER,   "Network Information Table (NIT), other network" },
154
    { TID_SDT,         "Service Description Table (SDT), current network" },
155
    { TID_SDT_OTHER,   "Service Description (SDT), other network" },
156
    { TID_BAT,         "Bouquet Association Table (BAT)" },
157
    { TID_EIT_PF,      "Event Information Table (EIT), present/following, actual TS" },
158
    { TID_EIT_PF_OTHER,"Event Information Table (EIT), present/following, other TS" },
159
    { TID_EIT_SC0,     "Event Information Table (EIT), schedule 0, actual TS" },
160
    { TID_EIT_SC1,     "Event Information Table (EIT), schedule 1, actual TS" },
161
    { TID_EIT_SC2,     "Event Information Table (EIT), schedule 2, actual TS" },
162
    { TID_EIT_SC3,     "Event Information Table (EIT), schedule 3, actual TS" },
163
    { TID_EIT_SC4,     "Event Information Table (EIT), schedule 4, actual TS" },
164
    { TID_EIT_SC5,     "Event Information Table (EIT), schedule 5, actual TS" },
165
    { TID_EIT_SC6,     "Event Information Table (EIT), schedule 6, actual TS" },
166
    { TID_EIT_SC7,     "Event Information Table (EIT), schedule 7, actual TS" },
167
    { TID_EIT_SC8,     "Event Information Table (EIT), schedule 8, actual TS" },
168
    { TID_EIT_SC9,     "Event Information Table (EIT), schedule 9, actual TS" },
169
    { TID_EIT_SCA,     "Event Information Table (EIT), schedule A, actual TS" },
170
    { TID_EIT_SCB,     "Event Information Table (EIT), schedule B, actual TS" },
171
    { TID_EIT_SCC,     "Event Information Table (EIT), schedule C, actual TS" },
172
    { TID_EIT_SCD,     "Event Information Table (EIT), schedule D, actual TS" },
173
    { TID_EIT_SCE,     "Event Information Table (EIT), schedule E, actual TS" },
174
    { TID_EIT_SCF,     "Event Information Table (EIT), schedule F, actual TS" },
175
    { TID_EIT_SC0_OTH, "Event Information Table (EIT), schedule 0, other TS" },
176
    { TID_EIT_SC1_OTH, "Event Information Table (EIT), schedule 1, other TS" },
177
    { TID_EIT_SC2_OTH, "Event Information Table (EIT), schedule 2, other TS" },
178
    { TID_EIT_SC3_OTH, "Event Information Table (EIT), schedule 3, other TS" },
179
    { TID_EIT_SC4_OTH, "Event Information Table (EIT), schedule 4, other TS" },
180
    { TID_EIT_SC5_OTH, "Event Information Table (EIT), schedule 5, other TS" },
181
    { TID_EIT_SC6_OTH, "Event Information Table (EIT), schedule 6, other TS" },
182
    { TID_EIT_SC7_OTH, "Event Information Table (EIT), schedule 7, other TS" },
183
    { TID_EIT_SC8_OTH, "Event Information Table (EIT), schedule 8, other TS" },
184
    { TID_EIT_SC9_OTH, "Event Information Table (EIT), schedule 9, other TS" },
185
    { TID_EIT_SCA_OTH, "Event Information Table (EIT), schedule A, other TS" },
186
    { TID_EIT_SCB_OTH, "Event Information Table (EIT), schedule B, other TS" },
187
    { TID_EIT_SCC_OTH, "Event Information Table (EIT), schedule C, other TS" },
188
    { TID_EIT_SCD_OTH, "Event Information Table (EIT), schedule D, other TS" },
189
    { TID_EIT_SCE_OTH, "Event Information Table (EIT), schedule E, other TS" },
190
    { TID_EIT_SCF_OTH, "Event Information Table (EIT), schedule F, other TS" },
191
    { TID_TDT,         "Time and Date Table (TDT)" },
192
    { TID_RST,         "Running Status Table (RST)" },
193
    { TID_ST,          "Stuffing Table (ST)" },
194
    { TID_TOT,         "Time Offset Table (TOT)" },
195
    { TID_AIT,         "Application Information Table (AIT)" },
196
    { TID_SIT,         "Selection Information Table (SIT)" },
197
    { TID_SCT,         "Superframe Composition Table (SCT)" },
198
    { TID_FCT,         "Frame Composition Table (FCT)" },
199
    { TID_TCT,         "Time-Slot Composition Table (TCT)" },
200
    { TID_SPT,         "Satellite Position Table (SPT)" },
201
    { TID_CMT,         "Correction Message Table (CMT)" },
202
    { TID_TBTP,        "Terminal Burst Time Plan (TBTP)" },
203
    { TID_TIM,         "Terminal Information Message (TIM)" },
204
    { TID_DVB_MPE,     "DVB MultiProtocol Encapsulation (MPE)" },
205
    { TID_ETV_EISS,    "ETV Integrated Signaling Stream (EISS)" },
206
    { TID_ETV_DII,     "ETV Download Info Indication" },
207
    { TID_ETV_DDB,     "ETV Download Data Block" },
208
    { TID_FORBIDEN,    "Forbidden" },
209
    { 0, NULL }
210
};
211
212
static void mpeg_sect_prompt(packet_info *pinfo, char* result)
213
0
{
214
0
    snprintf(result, MAX_DECODE_AS_PROMPT_LEN, "Table ID %u as",
215
0
        GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_mpeg_sect, MPEG_SECT_TID_KEY)));
216
0
}
217
218
static void *mpeg_sect_value(packet_info *pinfo)
219
0
{
220
0
    return p_get_proto_data(pinfo->pool, pinfo, proto_mpeg_sect, MPEG_SECT_TID_KEY);
221
0
}
222
223
/* read a utc_time field in a tvb and write it to the utc_time struct
224
   the encoding of the field is according to DVB-SI specification, section 5.2.5
225
   16bit modified julian day (MJD), 24bit 6*4bit BCD digits hhmmss
226
   return the length in bytes or -1 for error */
227
int
228
packet_mpeg_sect_mjd_to_utc_time(tvbuff_t *tvb, int offset, nstime_t *utc_time)
229
112
{
230
112
    int    bcd_time_offset;     /* start offset of the bcd time in the tvbuff */
231
112
    uint8_t hour, min, sec;
232
233
112
    if (!utc_time)
234
0
        return -1;
235
236
112
    nstime_set_zero(utc_time);
237
    /* The 16-bit MJD epoch is November 17, 1858, which is 40587 days
238
     * before the UN*X epoch. */
239
112
    if (ckd_mul(&utc_time->secs, tvb_get_ntohs(tvb, offset) - 40587, 86400)) {
240
        /* This can overflow with 32-bit time_t. */
241
0
        return -1;
242
0
    }
243
112
    bcd_time_offset = offset+2;
244
112
    hour            = MPEG_SECT_BCD44_TO_DEC(tvb_get_uint8(tvb, bcd_time_offset));
245
112
    min             = MPEG_SECT_BCD44_TO_DEC(tvb_get_uint8(tvb, bcd_time_offset+1));
246
112
    sec             = MPEG_SECT_BCD44_TO_DEC(tvb_get_uint8(tvb, bcd_time_offset+2));
247
112
    if (hour>23 || min>59 || sec>59)
248
64
        return -1;
249
250
48
    utc_time->secs += hour*3600 + min*60 + sec;
251
48
    return 5;
252
112
}
253
254
unsigned
255
packet_mpeg_sect_header(tvbuff_t *tvb, unsigned offset,
256
            proto_tree *tree, unsigned *sect_len, bool *ssi)
257
443
{
258
443
    return packet_mpeg_sect_header_extra(tvb, offset, tree, sect_len,
259
443
                         NULL, ssi, NULL);
260
443
}
261
262
unsigned
263
packet_mpeg_sect_header_extra(tvbuff_t *tvb, unsigned offset, proto_tree *tree,
264
                unsigned *sect_len, unsigned *reserved, bool *ssi,
265
                proto_item **items)
266
447
{
267
447
    unsigned    tmp;
268
447
    unsigned    len = 0;
269
447
    proto_item *pi[PACKET_MPEG_SECT_PI__SIZE];
270
447
    int         i;
271
272
2.23k
    for (i = 0; i < PACKET_MPEG_SECT_PI__SIZE; i++) {
273
1.78k
        pi[i] = NULL;
274
1.78k
    }
275
276
447
    if (tree) {
277
447
        pi[PACKET_MPEG_SECT_PI__TABLE_ID] =
278
447
            proto_tree_add_item(tree, hf_mpeg_sect_table_id,
279
447
                    tvb, offset + len, 1, ENC_BIG_ENDIAN);
280
447
    }
281
282
447
    len++;
283
284
447
    if (tree) {
285
447
        pi[PACKET_MPEG_SECT_PI__SSI] =
286
447
            proto_tree_add_item(tree, hf_mpeg_sect_syntax_indicator,
287
447
                    tvb, offset + len, 2, ENC_BIG_ENDIAN);
288
289
447
        pi[PACKET_MPEG_SECT_PI__RESERVED] =
290
447
            proto_tree_add_item(tree, hf_mpeg_sect_reserved, tvb,
291
447
                    offset + len, 2, ENC_BIG_ENDIAN);
292
293
447
        pi[PACKET_MPEG_SECT_PI__LENGTH] =
294
447
            proto_tree_add_item(tree, hf_mpeg_sect_length, tvb,
295
447
                    offset + len, 2, ENC_BIG_ENDIAN);
296
447
    }
297
298
447
    tmp = tvb_get_ntohs(tvb, offset + len);
299
300
447
    if (sect_len)
301
384
        *sect_len = MPEG_SECT_LENGTH_MASK & tmp;
302
303
447
    if (reserved)
304
4
        *reserved = (MPEG_SECT_RESERVED_MASK & tmp) >> 12;
305
306
447
    if (ssi)
307
105
        *ssi = (MPEG_SECT_SYNTAX_INDICATOR_MASK & tmp);
308
309
447
    if (items) {
310
20
        for (i = 0; i < PACKET_MPEG_SECT_PI__SIZE; i++) {
311
16
            items[i] = pi[i];
312
16
        }
313
4
    }
314
315
447
    len += 2;
316
317
447
    return len;
318
447
}
319
320
321
unsigned
322
packet_mpeg_sect_crc(tvbuff_t *tvb, packet_info *pinfo,
323
             proto_tree *tree, unsigned start, unsigned end)
324
74
{
325
74
    if (mpeg_sect_check_crc) {
326
0
        proto_tree_add_checksum(tree, tvb, end, hf_mpeg_sect_crc, hf_mpeg_sect_crc_status, &ei_mpeg_sect_crc, pinfo, crc32_mpeg2_tvb_offset(tvb, start, end),
327
0
                                ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
328
74
    } else {
329
74
        proto_tree_add_checksum(tree, tvb, end, hf_mpeg_sect_crc, hf_mpeg_sect_crc_status, &ei_mpeg_sect_crc, pinfo, crc32_mpeg2_tvb_offset(tvb, start, end),
330
74
                                ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
331
74
    }
332
333
74
    return 4;
334
74
}
335
336
337
static int
338
dissect_mpeg_sect(tvbuff_t *tvb, packet_info *pinfo,
339
        proto_tree *tree, void *data _U_)
340
455
{
341
455
    int      tvb_len;
342
455
    int      offset           = 0;
343
455
    unsigned section_length   = 0;
344
455
    bool     syntax_indicator = false;
345
455
    uint8_t  table_id;
346
347
455
    proto_item *ti;
348
455
    proto_tree *mpeg_sect_tree;
349
350
    /* the incoming tvb contains only one section, no additional data */
351
352
455
    tvb_len = (int)tvb_reported_length(tvb);
353
455
    if (tvb_len<MPEG_SECT_MIN_LEN || tvb_len>MPEG_SECT_MAX_LEN)
354
2
        return 0;
355
356
453
    table_id = tvb_get_uint8(tvb, offset);
357
453
    p_add_proto_data(pinfo->pool, pinfo, proto_mpeg_sect, MPEG_SECT_TID_KEY, GUINT_TO_POINTER(table_id));
358
359
    /* Check if a dissector can parse the current table */
360
453
    if (dissector_try_uint(mpeg_sect_tid_dissector_table, table_id, tvb, pinfo, tree))
361
38
        return tvb_len;
362
363
    /* If no dissector is registered, use the common one */
364
415
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG SECT");
365
415
    col_add_fstr(pinfo->cinfo, COL_INFO, "Table ID 0x%02x", table_id);
366
367
415
    ti = proto_tree_add_item(tree, proto_mpeg_sect, tvb, offset, -1, ENC_NA);
368
415
    mpeg_sect_tree = proto_item_add_subtree(ti, ett_mpeg_sect);
369
370
415
    proto_item_append_text(ti, " Table_ID=0x%02x", table_id);
371
372
415
    packet_mpeg_sect_header(tvb, offset, mpeg_sect_tree,
373
415
                &section_length, &syntax_indicator);
374
375
415
    if (syntax_indicator)
376
25
        packet_mpeg_sect_crc(tvb, pinfo, mpeg_sect_tree, 0, (section_length-1));
377
378
415
    return tvb_len;
379
453
}
380
381
382
void
383
proto_register_mpeg_sect(void)
384
15
{
385
15
    static hf_register_info hf[] = {
386
15
        { &hf_mpeg_sect_table_id, {
387
15
            "Table ID", "mpeg_sect.tid",
388
15
            FT_UINT8, BASE_HEX, VALS(mpeg_sect_table_id_vals), 0, NULL, HFILL
389
15
        } },
390
391
15
        { &hf_mpeg_sect_syntax_indicator, {
392
15
            "Syntax indicator", "mpeg_sect.syntax_indicator",
393
15
            FT_UINT16, BASE_DEC, NULL, MPEG_SECT_SYNTAX_INDICATOR_MASK, NULL, HFILL
394
15
        } },
395
396
15
        { &hf_mpeg_sect_reserved, {
397
15
            "Reserved", "mpeg_sect.reserved",
398
15
            FT_UINT16, BASE_HEX, NULL, MPEG_SECT_RESERVED_MASK, NULL, HFILL
399
15
        } },
400
401
15
        { &hf_mpeg_sect_length, {
402
15
            "Length", "mpeg_sect.len",
403
15
            FT_UINT16, BASE_DEC, NULL, MPEG_SECT_LENGTH_MASK, NULL, HFILL
404
15
        } },
405
406
15
        { &hf_mpeg_sect_crc, {
407
15
            "CRC 32", "mpeg_sect.crc",
408
15
            FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL
409
15
        } },
410
411
15
        { &hf_mpeg_sect_crc_status, {
412
15
            "CRC 32 Status", "mpeg_sect.crc.status",
413
15
            FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0, NULL, HFILL
414
15
        } },
415
416
15
    };
417
418
15
    static int *ett[] = {
419
15
        &ett_mpeg_sect
420
15
    };
421
422
15
    static ei_register_info ei[] = {
423
15
        { &ei_mpeg_sect_crc, { "mpeg_sect.crc.invalid", PI_CHECKSUM, PI_WARN, "Invalid CRC", EXPFILL }},
424
15
    };
425
426
    /* Decode As handling */
427
15
    static build_valid_func mpeg_sect_da_build_value[1] = {mpeg_sect_value};
428
15
    static decode_as_value_t mpeg_sect_da_values = {mpeg_sect_prompt, 1, mpeg_sect_da_build_value};
429
15
    static decode_as_t mpeg_sect_da = {"mpeg_sect", "mpeg_sect.tid", 1, 0, &mpeg_sect_da_values, NULL, NULL, decode_as_default_populate_list, decode_as_default_reset, decode_as_default_change, NULL, NULL, NULL };
430
431
15
    module_t *mpeg_sect_module;
432
15
    expert_module_t* expert_mpeg_sect;
433
434
15
    proto_mpeg_sect = proto_register_protocol("MPEG2 Section", "MPEG SECT", "mpeg_sect");
435
15
    register_dissector("mpeg_sect", dissect_mpeg_sect, proto_mpeg_sect);
436
437
15
    proto_register_field_array(proto_mpeg_sect, hf, array_length(hf));
438
15
    proto_register_subtree_array(ett, array_length(ett));
439
15
    expert_mpeg_sect = expert_register_protocol(proto_mpeg_sect);
440
15
    expert_register_field_array(expert_mpeg_sect, ei, array_length(ei));
441
442
15
    mpeg_sect_module = prefs_register_protocol(proto_mpeg_sect, NULL);
443
444
15
    prefs_register_bool_preference(mpeg_sect_module,
445
15
        "verify_crc",
446
15
        "Verify the section CRC",
447
15
        "Whether the section dissector should verify the CRC",
448
15
        &mpeg_sect_check_crc);
449
450
15
    mpeg_sect_tid_dissector_table = register_dissector_table("mpeg_sect.tid",
451
15
                                 "MPEG SECT Table ID",
452
15
                                 proto_mpeg_sect, FT_UINT8, BASE_HEX);
453
454
15
    register_decode_as(&mpeg_sect_da);
455
15
}
456
457
/*
458
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
459
 *
460
 * Local variables:
461
 * c-basic-offset: 4
462
 * tab-width: 8
463
 * indent-tabs-mode: nil
464
 * End:
465
 *
466
 * vi: set shiftwidth=4 tabstop=8 expandtab:
467
 * :indentSize=4:tabSize=8:noTabs=true:
468
 */