Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-dvb-s2-bb.c
blobb8beac0e9706d5e6a06cb5fd2299974f89d96525
1 /* packet-dvb-s2-bb.c
2 * Routines for DVB Dynamic Mode Adaptation dissection
3 * refer to
4 * https://web.archive.org/web/20170226064346/http://satlabs.org/pdf/sl_561_Mode_Adaptation_Input_and_Output_Interfaces_for_DVB-S2_Equipment_v1.3.pdf
6 * (http://satlabs.org/pdf/sl_561_Mode_Adaptation_Input_and_Output_Interfaces_for_DVB-S2_Equipment_v1.3.pdf
7 * is no longer available)
9 * Standards:
10 * ETSI EN 302 307-1 - Digital Video Broadcasting (DVB) - Framing Structure Part 1: DVB-S2
11 * ETSI EN 302 307-2 - Digital Video Broadcasting (DVB) - Framing Structure Part 2: DVB-S2X
12 * ETSI TS 102 606-1 - Digital Video Broadcasting (DVB) - Generic Stream Encapsulation (GSE) Part 1: Protocol
13 * ETSI TS 102 771 - Digital Video Broadcasting (DVB) - GSE implementation guidelines
14 * SatLabs sl_561 - Mode Adaptation Interfaces for DVB-S2 equipment
15 * ETSI EN 302 769 - Digital Video Broadcasting (DVB) - Framing Structure DVB-C2
16 * ETSI EN 302 755 - Digital Video Broadcasting (DVB) - Framing Structure DVB-T2
17 * ETSI EN 301 545 - Digital Video Broadcasting (DVB) - Second Generation DVB Interactive Satellite System (DVB-RCS2)
18 * RFC 4326 - Unidirectional Lightweight Encapsulation (ULE) for Transmission of IP Datagrams over an MPEG-2 Transport Stream (TS)
19 * IANA registries:
21 * Mandatory Extension Headers (or link-dependent type fields) for ULE (Range 0-255 decimal):
23 * https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml#ule-next-headers-1
25 * and
27 * Optional Extension Headers for ULE (Range 256-511 decimal):
29 * https://www.iana.org/assignments/ule-next-headers/ule-next-headers.xhtml#ule-next-headers-2
31 * Copyright 2012, Tobias Rutz <tobias.rutz@work-microwave.de>
32 * Copyright 2013-2020, Thales Alenia Space
33 * Copyright 2013-2021, Viveris Technologies <adrien.destugues@opensource.viveris.fr>
34 * Copyright 2021, John Thacker <johnthacker@gmail.com>
36 * Wireshark - Network traffic analyzer
37 * By Gerald Combs <gerald@wireshark.org>
38 * Copyright 1998 Gerald Combs
40 * SPDX-License-Identifier: GPL-2.0-or-later
43 #include "config.h"
45 #include <epan/packet.h>
46 #include <epan/prefs.h>
47 #include <epan/crc32-tvb.h>
48 #include <epan/etypes.h>
49 #include <epan/expert.h>
50 #include <epan/reassemble.h>
51 #include <epan/conversation.h>
52 #include <epan/tfs.h>
53 #include <epan/stream.h>
54 #include <wsutil/bits_count_ones.h>
55 #include <wsutil/str_util.h>
57 #include "packet-mp2t.h"
59 #define BIT_IS_SET(var, bit) ((var) & (1 << (bit)))
60 #define BIT_IS_CLEAR(var, bit) !BIT_IS_SET(var, bit)
62 #define DVB_S2_MODEADAPT_MINSIZE (DVB_S2_BB_OFFS_CRC + 1)
64 /* Types of mode adaptation headers supported. */
65 #define DVB_S2_MODEADAPT_TYPE_L1 1
66 #define DVB_S2_MODEADAPT_TYPE_L2 2
67 #define DVB_S2_MODEADAPT_TYPE_L3 3
68 #define DVB_S2_MODEADAPT_TYPE_L4 4
70 #define DVB_S2_MODEADAPT_L1SIZE 0
71 #define DVB_S2_MODEADAPT_L2SIZE 2
72 #define DVB_S2_MODEADAPT_L3SIZE 4
73 #define DVB_S2_MODEADAPT_L4SIZE 3
75 static const int dvb_s2_modeadapt_sizes[] = {
76 [DVB_S2_MODEADAPT_TYPE_L1] = DVB_S2_MODEADAPT_L1SIZE,
77 [DVB_S2_MODEADAPT_TYPE_L2] = DVB_S2_MODEADAPT_L2SIZE,
78 [DVB_S2_MODEADAPT_TYPE_L3] = DVB_S2_MODEADAPT_L3SIZE,
79 [DVB_S2_MODEADAPT_TYPE_L4] = DVB_S2_MODEADAPT_L4SIZE,
83 /* CRC table crc-8, poly=0xD5 */
84 static uint8_t crc8_table[256] = {
85 0x00, 0xD5, 0x7F, 0xAA, 0xFE, 0x2B, 0x81, 0x54, 0x29, 0xFC, 0x56, 0x83, 0xD7, 0x02, 0xA8, 0x7D,
86 0x52, 0x87, 0x2D, 0xF8, 0xAC, 0x79, 0xD3, 0x06, 0x7B, 0xAE, 0x04, 0xD1, 0x85, 0x50, 0xFA, 0x2F,
87 0xA4, 0x71, 0xDB, 0x0E, 0x5A, 0x8F, 0x25, 0xF0, 0x8D, 0x58, 0xF2, 0x27, 0x73, 0xA6, 0x0C, 0xD9,
88 0xF6, 0x23, 0x89, 0x5C, 0x08, 0xDD, 0x77, 0xA2, 0xDF, 0x0A, 0xA0, 0x75, 0x21, 0xF4, 0x5E, 0x8B,
89 0x9D, 0x48, 0xE2, 0x37, 0x63, 0xB6, 0x1C, 0xC9, 0xB4, 0x61, 0xCB, 0x1E, 0x4A, 0x9F, 0x35, 0xE0,
90 0xCF, 0x1A, 0xB0, 0x65, 0x31, 0xE4, 0x4E, 0x9B, 0xE6, 0x33, 0x99, 0x4C, 0x18, 0xCD, 0x67, 0xB2,
91 0x39, 0xEC, 0x46, 0x93, 0xC7, 0x12, 0xB8, 0x6D, 0x10, 0xC5, 0x6F, 0xBA, 0xEE, 0x3B, 0x91, 0x44,
92 0x6B, 0xBE, 0x14, 0xC1, 0x95, 0x40, 0xEA, 0x3F, 0x42, 0x97, 0x3D, 0xE8, 0xBC, 0x69, 0xC3, 0x16,
93 0xEF, 0x3A, 0x90, 0x45, 0x11, 0xC4, 0x6E, 0xBB, 0xC6, 0x13, 0xB9, 0x6C, 0x38, 0xED, 0x47, 0x92,
94 0xBD, 0x68, 0xC2, 0x17, 0x43, 0x96, 0x3C, 0xE9, 0x94, 0x41, 0xEB, 0x3E, 0x6A, 0xBF, 0x15, 0xC0,
95 0x4B, 0x9E, 0x34, 0xE1, 0xB5, 0x60, 0xCA, 0x1F, 0x62, 0xB7, 0x1D, 0xC8, 0x9C, 0x49, 0xE3, 0x36,
96 0x19, 0xCC, 0x66, 0xB3, 0xE7, 0x32, 0x98, 0x4D, 0x30, 0xE5, 0x4F, 0x9A, 0xCE, 0x1B, 0xB1, 0x64,
97 0x72, 0xA7, 0x0D, 0xD8, 0x8C, 0x59, 0xF3, 0x26, 0x5B, 0x8E, 0x24, 0xF1, 0xA5, 0x70, 0xDA, 0x0F,
98 0x20, 0xF5, 0x5F, 0x8A, 0xDE, 0x0B, 0xA1, 0x74, 0x09, 0xDC, 0x76, 0xA3, 0xF7, 0x22, 0x88, 0x5D,
99 0xD6, 0x03, 0xA9, 0x7C, 0x28, 0xFD, 0x57, 0x82, 0xFF, 0x2A, 0x80, 0x55, 0x01, 0xD4, 0x7E, 0xAB,
100 0x84, 0x51, 0xFB, 0x2E, 0x7A, 0xAF, 0x05, 0xD0, 0xAD, 0x78, 0xD2, 0x07, 0x53, 0x86, 0x2C, 0xF9
104 static dissector_handle_t ip_handle;
105 static dissector_handle_t ipv6_handle;
106 static dissector_handle_t eth_withoutfcs_handle;
107 static dissector_handle_t dvb_s2_table_handle;
108 static dissector_handle_t data_handle;
109 static dissector_handle_t mp2t_handle;
110 static dissector_handle_t dvb_s2_modeadapt_handle;
112 void proto_register_dvb_s2_modeadapt(void);
113 void proto_reg_handoff_dvb_s2_modeadapt(void);
115 /* preferences */
116 #define DVB_S2_RCS_TABLE_DECODING 0
117 #define DVB_S2_RCS2_TABLE_DECODING 1
119 static const enum_val_t dvb_s2_modeadapt_enum[] = {
120 {"l1", "L.1 (0 bytes)", DVB_S2_MODEADAPT_TYPE_L1},
121 {"l2", "L.2 (2 bytes including sync)", DVB_S2_MODEADAPT_TYPE_L2},
122 {"l3", "L.3 (4 bytes including sync)", DVB_S2_MODEADAPT_TYPE_L3},
123 {"l4", "L.4 (3 bytes)", DVB_S2_MODEADAPT_TYPE_L4},
124 {NULL, NULL, -1}
127 static bool dvb_s2_full_dissection;
128 static bool dvb_s2_df_dissection;
129 static int dvb_s2_default_modeadapt = DVB_S2_MODEADAPT_TYPE_L3;
130 static bool dvb_s2_try_all_modeadapt = true;
132 /* Initialize the protocol and registered fields */
133 static int proto_dvb_s2_modeadapt;
134 static int hf_dvb_s2_modeadapt_sync;
135 static int hf_dvb_s2_modeadapt_acm;
136 static int hf_dvb_s2_modeadapt_acm_fecframe;
137 static int hf_dvb_s2_modeadapt_acm_pilot;
138 static int hf_dvb_s2_modeadapt_acm_modcod;
139 static int hf_dvb_s2_modeadapt_acm_modcod_s2x;
140 static int hf_dvb_s2_modeadapt_cni;
141 static int hf_dvb_s2_modeadapt_frameno;
143 static int proto_dvb_s2_bb;
144 static int hf_dvb_s2_bb_matype1;
145 static int hf_dvb_s2_bb_matype1_gs;
146 static int hf_dvb_s2_bb_matype1_mis;
147 static int hf_dvb_s2_bb_matype1_acm;
148 static int hf_dvb_s2_bb_matype1_issyi;
149 static int hf_dvb_s2_bb_matype1_npd;
150 static int hf_dvb_s2_bb_matype1_high_ro;
151 static int hf_dvb_s2_bb_matype1_low_ro;
152 static int hf_dvb_s2_bb_matype2;
153 static int hf_dvb_s2_bb_upl;
154 static int hf_dvb_s2_bb_dfl;
155 static int hf_dvb_s2_bb_sync;
156 static int hf_dvb_s2_bb_syncd;
157 static int hf_dvb_s2_bb_crc;
158 static int hf_dvb_s2_bb_crc_status;
159 static int hf_dvb_s2_bb_df;
160 static int hf_dvb_s2_bb_eip_crc32;
161 static int hf_dvb_s2_bb_eip_crc32_status;
162 static int hf_dvb_s2_bb_up_crc;
163 static int hf_dvb_s2_bb_up_crc_status;
164 static int hf_dvb_s2_bb_issy_short;
165 static int hf_dvb_s2_bb_issy_long;
166 static int hf_dvb_s2_bb_dnp;
168 static int hf_dvb_s2_bb_packetized;
169 static int hf_dvb_s2_bb_transport;
170 static int hf_dvb_s2_bb_reserved;
172 static int proto_dvb_s2_gse;
173 static int hf_dvb_s2_gse_hdr;
174 static int hf_dvb_s2_gse_hdr_start;
175 static int hf_dvb_s2_gse_hdr_stop;
176 static int hf_dvb_s2_gse_hdr_labeltype;
177 static int hf_dvb_s2_gse_hdr_length;
178 static int hf_dvb_s2_gse_padding;
179 static int hf_dvb_s2_gse_proto_next_header;
180 static int hf_dvb_s2_gse_proto_ethertype;
181 static int hf_dvb_s2_gse_label6;
182 static int hf_dvb_s2_gse_label3;
183 static int hf_dvb_s2_gse_fragid;
184 static int hf_dvb_s2_gse_totlength;
185 static int hf_dvb_s2_gse_exthdr;
186 static int hf_dvb_s2_gse_ncr;
187 static int hf_dvb_s2_gse_data;
188 static int hf_dvb_s2_gse_crc32;
189 static int hf_dvb_s2_gse_crc32_status;
191 /* Initialize the subtree pointers */
192 static int ett_dvb_s2_modeadapt;
193 static int ett_dvb_s2_modeadapt_acm;
195 static int ett_dvb_s2_bb;
196 static int ett_dvb_s2_bb_matype1;
198 static int ett_dvb_s2_gse;
199 static int ett_dvb_s2_gse_hdr;
200 static int ett_dvb_s2_gse_ncr;
202 static expert_field ei_dvb_s2_bb_crc;
203 static expert_field ei_dvb_s2_bb_header_ambiguous;
204 static expert_field ei_dvb_s2_bb_issy_invalid;
205 static expert_field ei_dvb_s2_bb_npd_invalid;
206 static expert_field ei_dvb_s2_bb_upl_invalid;
207 static expert_field ei_dvb_s2_bb_dfl_invalid;
208 static expert_field ei_dvb_s2_bb_sync_invalid;
209 static expert_field ei_dvb_s2_bb_syncd_invalid;
210 static expert_field ei_dvb_s2_bb_up_reassembly_invalid;
211 static expert_field ei_dvb_s2_bb_reserved;
213 static expert_field ei_dvb_s2_gse_length_invalid;
214 static expert_field ei_dvb_s2_gse_totlength_invalid;
215 static expert_field ei_dvb_s2_gse_crc32;
217 /* Reassembly support */
219 /* ETSI TS 102 606-1 3.1 distinguishes "slicing", the splitting of a User
220 * Packet over consecutive Base Band Frames of the same stream, and
221 * "fragmentation", the splitting of a PDU (& optionally Extension Header)
222 * over multiple GSE packets.
224 * Slicing does not occur with GSE as carried in DVB-S2 according to the
225 * original method in ETSI EN 302 307-1 (TS/GS bits 01), but it does occur
226 * with Transport Streams, Generic Packetized Streams (non-GSE, deprecated),
227 * and with the GSE High Efficiency Mode used in DVB-C2, DVB-T2, and DVB-S2X
228 * (TS/GS bits 10, originally reserved.)
230 * According to ETSI TS 102 606-1 D.2.2 "Fragmention", for simplicity when
231 * GSE-HEM and thus slicing is used, PDU fragmentation is not performed
232 * on the GSE layer (but note it's possible to mix stream types in one
233 * capture.)
235 * We have two sets of fragment items, one for slicing of User Packets at the
236 * BBF level, and one for GSE fragmentation. We only have one reassembly table,
237 * however, as the slicing of User Packets is handled through the stream.h
238 * API.
241 static int ett_dvbs2_fragments;
242 static int ett_dvbs2_fragment;
243 static int hf_dvbs2_fragments;
244 static int hf_dvbs2_fragment;
245 static int hf_dvbs2_fragment_overlap;
246 static int hf_dvbs2_fragment_overlap_conflict;
247 static int hf_dvbs2_fragment_multiple_tails;
248 static int hf_dvbs2_fragment_too_long_fragment;
249 static int hf_dvbs2_fragment_error;
250 static int hf_dvbs2_fragment_count;
251 static int hf_dvbs2_reassembled_in;
252 static int hf_dvbs2_reassembled_length;
253 static int hf_dvbs2_reassembled_data;
255 static const fragment_items dvbs2_frag_items = {
256 &ett_dvbs2_fragment,
257 &ett_dvbs2_fragments,
258 &hf_dvbs2_fragments,
259 &hf_dvbs2_fragment,
260 &hf_dvbs2_fragment_overlap,
261 &hf_dvbs2_fragment_overlap_conflict,
262 &hf_dvbs2_fragment_multiple_tails,
263 &hf_dvbs2_fragment_too_long_fragment,
264 &hf_dvbs2_fragment_error,
265 &hf_dvbs2_fragment_count,
266 &hf_dvbs2_reassembled_in,
267 &hf_dvbs2_reassembled_length,
268 &hf_dvbs2_reassembled_data,
269 "DVB-S2 UP fragments"
272 static reassembly_table dvb_s2_gse_reassembly_table;
274 static void
275 dvb_s2_gse_defragment_init(void)
277 reassembly_table_init(&dvb_s2_gse_reassembly_table,
278 &addresses_reassembly_table_functions);
281 static int ett_dvb_s2_gse_fragments;
282 static int ett_dvb_s2_gse_fragment;
283 static int hf_dvb_s2_gse_fragments;
284 static int hf_dvb_s2_gse_fragment;
285 static int hf_dvb_s2_gse_fragment_overlap;
286 static int hf_dvb_s2_gse_fragment_overlap_conflict;
287 static int hf_dvb_s2_gse_fragment_multiple_tails;
288 static int hf_dvb_s2_gse_fragment_too_long_fragment;
289 static int hf_dvb_s2_gse_fragment_error;
290 static int hf_dvb_s2_gse_fragment_count;
291 static int hf_dvb_s2_gse_reassembled_in;
292 static int hf_dvb_s2_gse_reassembled_length;
293 static int hf_dvb_s2_gse_reassembled_data;
295 static const fragment_items dvb_s2_gse_frag_items = {
296 &ett_dvb_s2_gse_fragment,
297 &ett_dvb_s2_gse_fragments,
298 &hf_dvb_s2_gse_fragments,
299 &hf_dvb_s2_gse_fragment,
300 &hf_dvb_s2_gse_fragment_overlap,
301 &hf_dvb_s2_gse_fragment_overlap_conflict,
302 &hf_dvb_s2_gse_fragment_multiple_tails,
303 &hf_dvb_s2_gse_fragment_too_long_fragment,
304 &hf_dvb_s2_gse_fragment_error,
305 &hf_dvb_s2_gse_fragment_count,
306 &hf_dvb_s2_gse_reassembled_in,
307 &hf_dvb_s2_gse_reassembled_length,
308 &hf_dvb_s2_gse_reassembled_data,
309 "DVB-S2 GSE fragments"
312 /* Offset in SYNC MARKER */
313 #define DVB_S2_OFFS_SYNCBYTE 0
315 /* *** DVB-S2 Modeadaption Header *** */
317 /* first byte */
318 #define DVB_S2_MODEADAPT_OFFS_SYNCBYTE 0
319 #define DVB_S2_MODEADAPT_SYNCBYTE 0xB8
321 /* second byte */
322 #define DVB_S2_MODEADAPT_MODCODS_MASK 0x1F
323 #define DVB_S2_MODEADAPT_MODCODS_S2X_MASK 0xDF
324 static const value_string modeadapt_modcods[] = {
325 { 0, "DUMMY PLFRAME"},
326 { 1, "QPSK 1/4"},
327 { 2, "QPSK 1/3"},
328 { 3, "QPSK 2/5"},
329 { 4, "QPSK 1/2"},
330 { 5, "QPSK 3/5"},
331 { 6, "QPSK 2/3"},
332 { 7, "QPSK 3/4"},
333 { 8, "QPSK 4/5"},
334 { 9, "QPSK 5/6"},
335 {10, "QPSK 8/9"},
336 {11, "QPSK 9/10"},
337 {12, "8PSK 3/5"},
338 {13, "8PSK 2/3"},
339 {14, "8PSK 3/4"},
340 {15, "8PSK 5/6"},
341 {16, "8PSK 8/9"},
342 {17, "8PSK 9/10"},
343 {18, "16APSK 2/3"},
344 {19, "16APSK 3/4"},
345 {20, "16APSK 4/5"},
346 {21, "16APSK 5/6"},
347 {22, "16APSK 8/9"},
348 {23, "16APSK 9/10"},
349 {24, "32APSK 3/4"},
350 {25, "32APSK 4/5"},
351 {26, "32APSK 5/6"},
352 {27, "32APSK 8/9"},
353 {28, "32APSK 9/10"},
354 {29, "reserved"},
355 {30, "reserved"},
356 {31, "reserved"},
357 {32, "QPSK 1/3 SF48"},
358 {33, "QPSK 1/2 SF48"},
359 {34, "QPSK 1/4 SF12"},
360 {35, "QPSK 1/3 SF12"},
361 {36, "QPSK 1/2 SF12"},
362 {37, "QPSK 1/3 SF6"},
363 {38, "QPSK 1/2 SF6"},
364 {39, "QPSK 1/3 SF3"},
365 {40, "QPSK 2/5 SF3"},
366 {41, "QPSK 1/3 SF2"},
367 {42, "QPSK 2/5 SF2"},
368 {43, "QPSK 1/2 SF2"},
369 {44, "QPSK 1/3 SF1"},
370 {45, "QPSK 2/5 SF1"},
371 {46, "QPSK 1/2 SF1"},
372 {47, "reserved"},
373 {48, "reserved"},
374 {49, "reserved"},
375 {50, "reserved"},
376 {51, "reserved"},
377 {52, "reserved"},
378 {53, "reserved"},
379 {54, "reserved"},
380 {55, "reserved"},
381 {56, "reserved"},
382 {57, "reserved"},
383 {58, "reserved"},
384 {59, "reserved"},
385 {60, "reserved"},
386 {61, "reserved"},
387 {62, "reserved"},
388 {63, "reserved"},
389 {64, "reserved"},
390 {65, "reserved"},
391 {66, "reserved"},
392 {67, "reserved"},
393 {68, "reserved"},
394 {69, "reserved"},
395 {70, "reserved"},
396 {71, "reserved"},
397 {72, "reserved"},
398 {73, "reserved"},
399 {74, "reserved"},
400 {75, "reserved"},
401 {76, "reserved"},
402 {77, "reserved"},
403 {78, "reserved"},
404 {79, "reserved"},
405 {80, "reserved"},
406 {81, "reserved"},
407 {82, "reserved"},
408 {83, "reserved"},
409 {84, "reserved"},
410 {85, "reserved"},
411 {86, "reserved"},
412 {87, "reserved"},
413 {88, "reserved"},
414 {89, "reserved"},
415 {90, "reserved"},
416 {91, "reserved"},
417 {92, "reserved"},
418 {93, "reserved"},
419 {94, "reserved"},
420 {95, "reserved"},
421 {96, "reserved"},
422 {97, "reserved"},
423 {98, "reserved"},
424 {99, "reserved"},
425 {100, "reserved"},
426 {101, "reserved"},
427 {102, "reserved"},
428 {103, "reserved"},
429 {104, "reserved"},
430 {105, "reserved"},
431 {106, "reserved"},
432 {107, "reserved"},
433 {108, "reserved"},
434 {109, "reserved"},
435 {110, "reserved"},
436 {111, "reserved"},
437 {112, "reserved"},
438 {113, "reserved"},
439 {114, "reserved"},
440 {115, "reserved"},
441 {116, "reserved"},
442 {117, "reserved"},
443 {118, "reserved"},
444 {119, "reserved"},
445 {120, "reserved"},
446 {121, "reserved"},
447 {122, "reserved"},
448 {123, "reserved"},
449 {124, "reserved"},
450 {125, "reserved"},
451 {126, "reserved"},
452 {127, "reserved"},
453 {128, "reserved"},
454 {129, "reserved"},
455 {130, "reserved"},
456 {131, "reserved"},
457 {132, "QPSK 13/45"},
458 {133, "reserved"},
459 {134, "QPSK 9/20"},
460 {135, "reserved"},
461 {136, "QPSK 11/20"},
462 {137, "reserved"},
463 {138, "8PSK 5/9-L"},
464 {139, "reserved"},
465 {140, "8PSK 26/45-L"},
466 {141, "reserved"},
467 {142, "8PSK 23/36"},
468 {143, "reserved"},
469 {144, "8PSK 25/36"},
470 {145, "reserved"},
471 {146, "8PSK 13/18"},
472 {147, "reserved"},
473 {148, "16APSK 1/2-L"},
474 {149, "reserved"},
475 {150, "16APSK 8/15-L"},
476 {151, "reserved"},
477 {152, "16APSK 5/9-L"},
478 {153, "reserved"},
479 {154, "16APSK 26/45"},
480 {155, "reserved"},
481 {156, "16APSK 3/5"},
482 {157, "reserved"},
483 {158, "16APSK 3/5-L"},
484 {159, "reserved"},
485 {160, "16APSK 28/45"},
486 {161, "reserved"},
487 {162, "16APSK 23/36"},
488 {163, "reserved"},
489 {164, "16APSK 2/3-L"},
490 {165, "reserved"},
491 {166, "16APSK 25/36"},
492 {167, "reserved"},
493 {168, "16APSK 13/18"},
494 {169, "reserved"},
495 {170, "16APSK 7/9"},
496 {171, "reserved"},
497 {172, "16APSK 77/90"},
498 {173, "reserved"},
499 {174, "32APSK 2/3-L"},
500 {175, "reserved"},
501 {176, "reserved"},
502 {177, "reserved"},
503 {178, "32APSK 32/45"},
504 {179, "reserved"},
505 {180, "32APSK 11/15"},
506 {181, "reserved"},
507 {182, "32APSK 7/9"},
508 {183, "reserved"},
509 {184, "64APSK 32/45-L"},
510 {185, "reserved"},
511 {186, "64APSK 11/15"},
512 {187, "reserved"},
513 {188, "reserved"},
514 {189, "reserved"},
515 {190, "64APSK 7/9"},
516 {191, "reserved"},
517 {192, "reserved"},
518 {193, "reserved"},
519 {194, "64APSK 4/5"},
520 {195, "reserved"},
521 {196, "reserved"},
522 {197, "reserved"},
523 {198, "64APSK 5/6"},
524 {199, "reserved"},
525 {200, "128APSK 3/4"},
526 {201, "reserved"},
527 {202, "128APSK 7/9"},
528 {203, "reserved"},
529 {204, "256APSK 29/45-L"},
530 {205, "reserved"},
531 {206, "256APSK 2/3-L"},
532 {207, "reserved"},
533 {208, "256APSK 31/45-L"},
534 {209, "reserved"},
535 {210, "256APSK 32/45"},
536 {211, "reserved"},
537 {212, "256APSK 11/15-L"},
538 {213, "reserved"},
539 {214, "256APSK 3/4"},
540 {215, "reserved"},
541 {216, "QPSK 11/45"},
542 {217, "reserved"},
543 {218, "QPSK 4/15"},
544 {219, "reserved"},
545 {220, "QPSK 14/45"},
546 {221, "reserved"},
547 {222, "QPSK 7/15"},
548 {223, "reserved"},
549 {224, "QPSK 8/15"},
550 {225, "reserved"},
551 {226, "QPSK 32/45"},
552 {227, "reserved"},
553 {228, "8PSK 7/15"},
554 {229, "reserved"},
555 {230, "8PSK 8/15"},
556 {231, "reserved"},
557 {232, "8PSK 26/45"},
558 {233, "reserved"},
559 {234, "8PSK 32/45"},
560 {235, "reserved"},
561 {236, "16APSK 7/15"},
562 {237, "reserved"},
563 {238, "16APSK 8/15"},
564 {239, "reserved"},
565 {240, "16APSK 26/45"},
566 {241, "reserved"},
567 {242, "16APSK 3/5"},
568 {243, "reserved"},
569 {244, "16APSK 32/45"},
570 {245, "reserved"},
571 {246, "32APSK 2/3"},
572 {247, "reserved"},
573 {248, "32APSK 32/45"},
574 {249, "reserved"},
575 {250, "reserved"},
576 {251, "reserved"},
577 {252, "reserved"},
578 {253, "reserved"},
579 {254, "reserved"},
580 {255, "reserved"},
581 { 0, NULL}
583 static value_string_ext modeadapt_modcods_ext = VALUE_STRING_EXT_INIT(modeadapt_modcods);
585 #define DVB_S2_MODEADAPT_PILOTS_MASK 0x20
587 #define DVB_S2_MODEADAPT_FECFRAME_MASK 0x40
588 static const true_false_string tfs_modeadapt_fecframe = {
589 "short",
590 "normal"
593 /* third byte */
594 #define DVB_S2_MODEADAPT_OFFS_CNI 2
595 static const value_string modeadapt_esno[] = {
596 { 0, "modem unlocked, SNR not available"},
597 { 1, "-1.000"},
598 { 2, "-0.875"},
599 { 3, "-0.750"},
600 { 4, "-0.625"},
601 { 5, "-0.500"},
602 { 6, "-0.375"},
603 { 7, "-0.250"},
604 { 8, "-0.125"},
605 { 9, "0.000"},
606 { 10, "0.125"},
607 { 11, "0.250"},
608 { 12, "0.375"},
609 { 13, "0.500"},
610 { 14, "0.625"},
611 { 15, "0.750"},
612 { 16, "0.875"},
613 { 17, "1.000"},
614 { 18, "1.125"},
615 { 19, "1.250"},
616 { 20, "1.375"},
617 { 21, "1.500"},
618 { 22, "1.625"},
619 { 23, "1.750"},
620 { 24, "1.875"},
621 { 25, "2.000"},
622 { 26, "2.125"},
623 { 27, "2.250"},
624 { 28, "2.375"},
625 { 29, "2.500"},
626 { 30, "2.625"},
627 { 31, "2.750"},
628 { 32, "2.875"},
629 { 33, "3.000"},
630 { 34, "3.125"},
631 { 35, "3.250"},
632 { 36, "3.375"},
633 { 37, "3.500"},
634 { 38, "3.625"},
635 { 39, "3.750"},
636 { 40, "3.875"},
637 { 41, "4.000"},
638 { 42, "4.125"},
639 { 43, "4.250"},
640 { 44, "4.375"},
641 { 45, "4.500"},
642 { 46, "4.625"},
643 { 47, "4.750"},
644 { 48, "4.875"},
645 { 49, "5.000"},
646 { 50, "5.125"},
647 { 51, "5.250"},
648 { 52, "5.375"},
649 { 53, "5.500"},
650 { 54, "5.625"},
651 { 55, "5.750"},
652 { 56, "5.875"},
653 { 57, "6.000"},
654 { 58, "6.125"},
655 { 59, "6.250"},
656 { 60, "6.375"},
657 { 61, "6.500"},
658 { 62, "6.625"},
659 { 63, "6.750"},
660 { 64, "6.875"},
661 { 65, "7.000"},
662 { 66, "7.125"},
663 { 67, "7.250"},
664 { 68, "7.375"},
665 { 69, "7.500"},
666 { 70, "7.625"},
667 { 71, "7.750"},
668 { 72, "7.875"},
669 { 73, "8.000"},
670 { 74, "8.125"},
671 { 75, "8.250"},
672 { 76, "8.375"},
673 { 77, "8.500"},
674 { 78, "8.625"},
675 { 79, "8.750"},
676 { 80, "8.875"},
677 { 81, "9.000"},
678 { 82, "9.125"},
679 { 83, "9.250"},
680 { 84, "9.375"},
681 { 85, "9.500"},
682 { 86, "9.625"},
683 { 87, "9.750"},
684 { 88, "9.875"},
685 { 89, "10.000"},
686 { 90, "10.125"},
687 { 91, "10.250"},
688 { 92, "10.375"},
689 { 93, "10.500"},
690 { 94, "10.625"},
691 { 95, "10.750"},
692 { 96, "10.875"},
693 { 97, "11.000"},
694 { 98, "11.125"},
695 { 99, "11.250"},
696 {100, "11.375"},
697 {101, "11.500"},
698 {102, "11.625"},
699 {103, "11.750"},
700 {104, "11.875"},
701 {105, "12.000"},
702 {106, "12.125"},
703 {107, "12.250"},
704 {108, "12.375"},
705 {109, "12.500"},
706 {110, "12.625"},
707 {111, "12.750"},
708 {112, "12.875"},
709 {113, "13.000"},
710 {114, "13.125"},
711 {115, "13.250"},
712 {116, "13.375"},
713 {117, "13.500"},
714 {118, "13.625"},
715 {119, "13.750"},
716 {120, "13.875"},
717 {121, "14.000"},
718 {122, "14.125"},
719 {123, "14.250"},
720 {124, "14.375"},
721 {125, "14.500"},
722 {126, "14.625"},
723 {127, "14.750"},
724 {128, "14.875"},
725 {129, "15.000"},
726 {130, "15.125"},
727 {131, "15.250"},
728 {132, "15.375"},
729 {133, "15.500"},
730 {134, "15.625"},
731 {135, "15.750"},
732 {136, "15.875"},
733 {137, "16.000"},
734 {138, "16.125"},
735 {139, "16.250"},
736 {140, "16.375"},
737 {141, "16.500"},
738 {142, "16.625"},
739 {143, "16.750"},
740 {144, "16.875"},
741 {145, "17.000"},
742 {146, "17.125"},
743 {147, "17.250"},
744 {148, "17.375"},
745 {149, "17.500"},
746 {150, "17.625"},
747 {151, "17.750"},
748 {152, "17.875"},
749 {153, "18.000"},
750 {154, "18.125"},
751 {155, "18.250"},
752 {156, "18.375"},
753 {157, "18.500"},
754 {158, "18.625"},
755 {159, "18.750"},
756 {160, "18.875"},
757 {161, "19.000"},
758 {162, "19.125"},
759 {163, "19.250"},
760 {164, "19.375"},
761 {165, "19.500"},
762 {166, "19.625"},
763 {167, "19.750"},
764 {168, "19.875"},
765 {169, "20.000"},
766 {170, "20.125"},
767 {171, "20.250"},
768 {172, "20.375"},
769 {173, "20.500"},
770 {174, "20.625"},
771 {175, "20.750"},
772 {176, "20.875"},
773 {177, "21.000"},
774 {178, "21.125"},
775 {179, "21.250"},
776 {180, "21.375"},
777 {181, "21.500"},
778 {182, "21.625"},
779 {183, "21.750"},
780 {184, "21.875"},
781 {185, "22.000"},
782 {186, "22.125"},
783 {187, "22.250"},
784 {188, "22.375"},
785 {189, "22.500"},
786 {190, "22.625"},
787 {191, "22.750"},
788 {192, "22.875"},
789 {193, "23.000"},
790 {194, "23.125"},
791 {195, "23.250"},
792 {196, "23.375"},
793 {197, "23.500"},
794 {198, "23.625"},
795 {199, "23.750"},
796 {200, "23.875"},
797 {201, "24.000"},
798 {202, "24.125"},
799 {203, "24.250"},
800 {204, "24.375"},
801 {205, "24.500"},
802 {206, "24.625"},
803 {207, "24.750"},
804 {208, "24.875"},
805 {209, "25.000"},
806 {210, "25.125"},
807 {211, "25.250"},
808 {212, "25.375"},
809 {213, "25.500"},
810 {214, "25.625"},
811 {215, "25.750"},
812 {216, "25.875"},
813 {217, "26.000"},
814 {218, "26.125"},
815 {219, "26.250"},
816 {220, "26.375"},
817 {221, "26.500"},
818 {222, "26.625"},
819 {223, "26.750"},
820 {224, "26.875"},
821 {225, "27.000"},
822 {226, "27.125"},
823 {227, "27.250"},
824 {228, "27.375"},
825 {229, "27.500"},
826 {230, "27.625"},
827 {231, "27.750"},
828 {232, "27.875"},
829 {233, "28.000"},
830 {234, "28.125"},
831 {235, "28.250"},
832 {236, "28.375"},
833 {237, "28.500"},
834 {238, "28.625"},
835 {239, "28.750"},
836 {240, "28.875"},
837 {241, "29.000"},
838 {242, "29.125"},
839 {243, "29.250"},
840 {244, "29.375"},
841 {245, "29.500"},
842 {246, "29.625"},
843 {247, "29.750"},
844 {248, "29.875"},
845 {249, "30.000"},
846 {250, "30.125"},
847 {251, "30.250"},
848 {252, "30.375"},
849 {253, "30.500"},
850 {254, "30.625"},
851 {255, ">30.750"},
852 { 0, NULL}
854 static value_string_ext modeadapt_esno_ext = VALUE_STRING_EXT_INIT(modeadapt_esno);
856 /* fourth byte */
857 #define DVB_S2_MODEADAPT_OFFS_FNO 3
859 /* *** DVB-S2 Base-Band Frame *** */
861 #define DVB_S2_BB_HEADER_LEN ((unsigned)10)
863 #define DVB_S2_BB_OFFS_MATYPE1 0
864 #define DVB_S2_BB_TSGS_MASK 0xC0
865 #define DVB_S2_BB_TSGS_GENERIC_PACKETIZED 0x00
866 #define DVB_S2_BB_TSGS_GENERIC_CONTINUOUS 0x40
867 #define DVB_S2_BB_TSGS_TRANSPORT_STREAM 0xC0
868 #define DVB_S2_BB_TSGS_RESERVED 0x80
869 static const value_string bb_tsgs[] = {
870 {0, "Generic Packetized (not GSE)"},
871 {1, "Generic Continuous (GSE)"},
872 {2, "GSE High Efficiency Mode (GSE-HEM)"},
873 {3, "Transport (TS)"},
874 {0, NULL}
877 #define DVB_S2_BB_MIS_POS 5
878 #define DVB_S2_BB_MIS_MASK 0x20
879 static const true_false_string tfs_bb_mis = {
880 "single (SIS)",
881 "multiple (MIS)"
884 #define DVB_S2_BB_ACM_MASK 0x10
885 static const true_false_string tfs_bb_acm = {
886 "constant (CCM)",
887 "adaptive (ACM)"
890 #define DVB_S2_BB_ISSYI_POS 3
891 #define DVB_S2_BB_ISSYI_MASK 0x08
893 #define DVB_S2_BB_NPD_POS 2
894 #define DVB_S2_BB_NPD_MASK 0x04
896 #define DVB_S2_BB_RO_MASK 0x03
897 static const value_string bb_high_ro[] = {
898 {0, "0,35"},
899 {1, "0,25"},
900 {2, "0,20"},
901 {3, "Low rolloff flag"},
902 {0, NULL}
905 static const value_string bb_low_ro[] = {
906 {0, "0,15"},
907 {1, "0,10"},
908 {2, "0,05"},
909 {3, "Low rolloff flag"},
910 {0, NULL}
914 #define DVB_S2_BB_OFFS_MATYPE2 1
915 #define DVB_S2_BB_OFFS_UPL 2
916 #define DVB_S2_BB_OFFS_DFL 4
917 #define DVB_S2_BB_OFFS_SYNC 6
918 #define DVB_S2_BB_OFFS_SYNCD 7
919 #define DVB_S2_BB_OFFS_CRC 9
920 #define DVB_S2_BB_EIP_CRC32_LEN 4
921 #define DVB_S2_BB_SYNC_EIP_CRC32 1
923 /* *** DVB-S2 GSE Frame *** */
925 #define DVB_S2_GSE_MINSIZE 2
927 #define DVB_S2_GSE_OFFS_HDR 0
928 #define DVB_S2_GSE_HDR_START_MASK 0x8000
929 #define DVB_S2_GSE_HDR_START_POS 15
930 #define DVB_S2_GSE_HDR_STOP_MASK 0x4000
931 #define DVB_S2_GSE_HDR_STOP_POS 14
934 #define DVB_S2_GSE_HDR_LABELTYPE_MASK 0x3000
935 #define DVB_S2_GSE_HDR_LABELTYPE_SHIFT 12
936 static const value_string gse_labeltype[] = {
937 {0, "6 byte"},
938 {1, "3 byte"},
939 {2, "0 byte (Broadcast)"},
940 {3, "re-use last label"},
941 {0, NULL}
944 #define DVB_S2_GSE_HDR_LENGTH_MASK 0x0FFF
946 #define DVB_RCS2_NCR 0x0081
947 #define DVB_RCS2_SIGNAL_TABLE 0x0082
949 static const value_string gse_proto_next_header_str[] = {
950 /* Mandatory Extension Headers (or link-dependent type fields) for ULE (Range 0-255 decimal) */
951 {0x0000, "Test SNDU" },
952 {0x0001, "Bridged Frame" },
953 {0x0002, "TS-Concat" },
954 {0x0003, "PDU-Concat" },
955 {DVB_RCS2_NCR, "NCR" },
956 {DVB_RCS2_SIGNAL_TABLE, "Signaling Table" },
957 {131, "LL_RCS_DCP" },
958 {132, "LL_RCS_1" },
959 {133, "LL_RCS_TRANSEC_SYS" },
960 {134, "LL_RCS_TRANSEC_PAY" },
961 {135, "DVB-GSE_LLC" },
962 /* Unassigned, private, unassigned ranges */
963 {200, "LL_RCS_FEC_EDT" },
964 /* Unassigned */
966 /* Optional Extension Headers for ULE (Range 256-511 decimal) */
967 {256, "Extension-Padding" },
968 {257, "Timestamp" },
969 /* Unassigned */
970 {450, "LL_RCS_FEC_ADT" },
971 {451, "LL_CRC32" },
972 /* Unassigned */
974 {0, NULL}
977 #define DVB_S2_GSE_CRC32_LEN 4
979 /* Virtual circuit handling
981 * BBFrames have an Input Stream Identifier (equivalently PLP_ID in -T2, -C2),
982 * but (cf. H.223), we are likely to encounter Base Band Frames over UDP or RTP.
983 * In those situations, the ISI might be reused on different conversations
984 * (or unused/0 on all of them). So we have a hash table that maps the
985 * conversation and the ISI to a unique virtual stream identifier.
988 typedef struct {
989 const conversation_t* conv;
990 uint32_t isi;
991 } virtual_stream_key;
993 static wmem_map_t *virtual_stream_hashtable;
994 static unsigned virtual_stream_count = 1;
996 /* Hash functions */
997 static int
998 virtual_stream_equal(const void *v, const void *w)
1000 const virtual_stream_key *v1 = (const virtual_stream_key *)v;
1001 const virtual_stream_key *v2 = (const virtual_stream_key *)w;
1002 int result;
1003 result = (v1->conv == v2->conv && v1->isi == v2->isi);
1004 return result;
1007 static unsigned
1008 virtual_stream_hash(const void *v)
1010 const virtual_stream_key *key = (const virtual_stream_key *)v;
1011 unsigned hash_val = (GPOINTER_TO_UINT(key->conv)) ^ (key->isi << 16);
1012 return hash_val;
1015 static uint32_t
1016 virtual_stream_lookup(const conversation_t* conv, uint32_t isi)
1018 virtual_stream_key key, *new_key;
1019 uint32_t virtual_isi;
1020 key.conv = conv;
1021 key.isi = isi;
1022 virtual_isi = GPOINTER_TO_UINT(wmem_map_lookup(virtual_stream_hashtable, &key));
1023 if (virtual_isi == 0) {
1024 new_key = wmem_new(wmem_file_scope(), virtual_stream_key);
1025 *new_key = key;
1026 virtual_isi = virtual_stream_count++;
1027 wmem_map_insert(virtual_stream_hashtable, new_key, GUINT_TO_POINTER(virtual_isi));
1029 return virtual_isi;
1032 static void
1033 virtual_stream_init(void)
1035 virtual_stream_count = 1;
1038 /* Data that is associated with a receiver at the BBFrame level, stored
1039 * at the conversation level. The Transmission Roll-off factor applies
1040 * for all ISI in a Multiple Input Stream Configuration (see ETSI EN
1041 * 302 307-2, clause 5.1.6 "Base-Band Header insertion".) Upon first
1042 * detection of '11' for the RO value, receiver will switch to low
1043 * roll-off range for the entire conversation.
1045 typedef struct {
1046 uint32_t use_low_ro;
1047 } dvbs2_bb_conv_data;
1049 static dvbs2_bb_conv_data *
1050 get_dvbs2_bb_conv_data(conversation_t *conv)
1052 dvbs2_bb_conv_data *bb_data;
1054 bb_data = (dvbs2_bb_conv_data *)conversation_get_proto_data(conv, proto_dvb_s2_bb);
1055 if (!bb_data) {
1056 bb_data = wmem_new0(wmem_file_scope(), dvbs2_bb_conv_data);
1057 conversation_add_proto_data(conv, proto_dvb_s2_bb, bb_data);
1060 return bb_data;
1063 /* Data that is associated with one BBFrame, used by GSE or TS packets
1064 * contained within it. Lifetime of the packet.
1066 typedef struct {
1067 address src;
1068 address dst;
1069 port_type ptype;
1070 uint32_t srcport;
1071 uint32_t destport;
1072 uint8_t isi;
1073 } dvbs2_bb_data;
1075 /* GSE defragmentation related data, one set of data per conversation.
1076 * Two tables are used. One is for the first pass, and contains the most
1077 * recent information for each Frag ID for that conversation. The other is
1078 * for later random access, indexed by both packet number and Frag ID.
1079 * (It seems very unlikely according to the spec that the same Frag ID would
1080 * be reused on the same BBFrame that it was completed. If that does happen,
1081 * then we would have to index by something else, say, subpacket number in the
1082 * BBFrame (which we would have to track ourselves.)
1084 typedef struct {
1085 wmem_tree_t *fragid_table;
1086 wmem_tree_t *subpacket_table;
1087 } gse_analysis_data;
1089 typedef struct {
1090 uint8_t labeltype;
1091 } gse_frag_data;
1093 static gse_analysis_data *
1094 init_gse_analysis_data(void)
1096 gse_analysis_data *gse_data;
1098 gse_data = wmem_new0(wmem_file_scope(), gse_analysis_data);
1099 gse_data->fragid_table = wmem_tree_new(wmem_file_scope());
1100 gse_data->subpacket_table = wmem_tree_new(wmem_file_scope());
1102 return gse_data;
1105 static gse_analysis_data *
1106 get_gse_analysis_data(conversation_t *conv)
1108 gse_analysis_data *gse_data;
1110 gse_data = (gse_analysis_data *)conversation_get_proto_data(conv, proto_dvb_s2_gse);
1111 if (!gse_data) {
1112 gse_data = init_gse_analysis_data();
1113 conversation_add_proto_data(conv, proto_dvb_s2_gse, gse_data);
1116 return gse_data;
1119 static gse_frag_data *
1120 get_gse_frag_data(gse_analysis_data *dvbs2_data, uint32_t fragid, bool create)
1122 gse_frag_data *frag_data;
1124 frag_data = (gse_frag_data *)wmem_tree_lookup32(dvbs2_data->fragid_table, fragid);
1125 if (!frag_data && create) {
1126 frag_data = wmem_new0(wmem_file_scope(), gse_frag_data);
1127 wmem_tree_insert32(dvbs2_data->fragid_table, fragid, (void *)frag_data);
1129 return frag_data;
1132 static gse_frag_data *
1133 get_gse_subpacket_data(gse_analysis_data *dvbs2_data, uint32_t num, uint32_t fragid, bool create)
1135 gse_frag_data *subpacket_data;
1136 wmem_tree_key_t subpacket_key[3];
1138 subpacket_key[0].length = 1;
1139 subpacket_key[0].key = &num;
1140 subpacket_key[1].length = 1;
1141 subpacket_key[1].key = &fragid;
1142 subpacket_key[2].length = 0;
1143 subpacket_key[2].key = NULL;
1145 subpacket_data = (gse_frag_data *)wmem_tree_lookup32_array(dvbs2_data->subpacket_table, subpacket_key);
1146 if (!subpacket_data && create) {
1147 subpacket_data = wmem_new0(wmem_file_scope(), gse_frag_data);
1148 wmem_tree_insert32_array(dvbs2_data->subpacket_table, subpacket_key, (void *)subpacket_data);
1150 return subpacket_data;
1153 /* *** helper functions *** */
1154 static uint8_t compute_crc8(tvbuff_t *p, uint8_t len, unsigned offset)
1156 int i;
1157 uint8_t crc = 0, tmp;
1159 for (i = 0; i < len; i++) {
1160 tmp = tvb_get_uint8(p, offset++);
1161 crc = crc8_table[crc ^ tmp];
1163 return crc;
1166 /* *** Code to actually dissect the packets *** */
1167 static int dissect_dvb_s2_gse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1169 int new_off = 0;
1170 uint8_t labeltype, isi = 0;
1171 uint16_t gse_hdr, data_len, packet_len, gse_proto = 0;
1172 uint32_t fragid, totlength, crc32_calc = 0;
1174 proto_item *ti;
1175 proto_item *ttf;
1176 proto_tree *dvb_s2_gse_tree, *dvb_s2_gse_ncr_tree;
1178 tvbuff_t *next_tvb, *data_tvb;
1179 bool dissected = false;
1180 bool update_col_info = true;
1181 bool complete = false;
1183 dvbs2_bb_data *pdata;
1184 conversation_t *conv;
1185 gse_analysis_data *gse_data;
1187 address save_src, save_dst;
1188 port_type save_ptype;
1189 uint32_t save_srcport, save_destport;
1191 static int * const gse_header_bitfields[] = {
1192 &hf_dvb_s2_gse_hdr_start,
1193 &hf_dvb_s2_gse_hdr_stop,
1194 &hf_dvb_s2_gse_hdr_labeltype,
1195 &hf_dvb_s2_gse_hdr_length,
1196 NULL
1199 col_append_str(pinfo->cinfo, COL_INFO, " GSE");
1201 /* get the GSE header */
1202 gse_hdr = tvb_get_ntohs(tvb, DVB_S2_GSE_OFFS_HDR);
1203 labeltype = (gse_hdr & DVB_S2_GSE_HDR_LABELTYPE_MASK) >> DVB_S2_GSE_HDR_LABELTYPE_SHIFT;
1205 /* check if this is just padding, which takes up the rest of the frame */
1206 if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) &&
1207 BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS) &&
1208 labeltype == 0) {
1210 packet_len = tvb_reported_length(tvb);
1211 proto_tree_add_uint_format(tree, hf_dvb_s2_gse_padding, tvb, new_off, packet_len, packet_len,
1212 "DVB-S2 GSE Padding, Length: %d", packet_len);
1213 col_append_str(pinfo->cinfo, COL_INFO, " pad");
1214 } else {
1215 /* Not padding, parse as a GSE Header */
1217 copy_address_shallow(&save_src, &pinfo->src);
1218 copy_address_shallow(&save_dst, &pinfo->dst);
1219 save_ptype = pinfo->ptype;
1220 save_srcport = pinfo->srcport;
1221 save_destport = pinfo->destport;
1223 /* We restore the original addresses and ports before each
1224 * GSE packet so reassembly works. We do it here, because
1225 * we don't want to restore them after calling a subdissector
1226 * (so that the final values are that from the last protocol
1227 * in the last PDU), but we also don't want to restore them
1228 * if the remainder is just padding either, for the same reason.
1229 * So we restore them here after the test for padding.
1231 if (data) { // Called from the BBFrame dissector
1232 pdata = (dvbs2_bb_data *)data;
1233 isi = pdata->isi;
1234 copy_address_shallow(&pinfo->src, &pdata->src);
1235 copy_address_shallow(&pinfo->dst, &pdata->dst);
1236 pinfo->ptype = pdata->ptype;
1237 pinfo->srcport = pdata->srcport;
1238 pinfo->destport = pdata->destport;
1241 conv = find_or_create_conversation(pinfo);
1242 gse_data = get_gse_analysis_data(conv);
1244 /* Length in header does not include header itself */
1245 packet_len = (gse_hdr & DVB_S2_GSE_HDR_LENGTH_MASK) + 2;
1246 ti = proto_tree_add_item(tree, proto_dvb_s2_gse, tvb, 0, packet_len, ENC_NA);
1247 dvb_s2_gse_tree = proto_item_add_subtree(ti, ett_dvb_s2_gse);
1248 new_off += 2;
1249 ti = proto_tree_add_bitmask_with_flags(dvb_s2_gse_tree, tvb, DVB_S2_GSE_OFFS_HDR, hf_dvb_s2_gse_hdr,
1250 ett_dvb_s2_gse_hdr, gse_header_bitfields, ENC_BIG_ENDIAN, BMT_NO_TFS);
1251 if (packet_len > tvb_reported_length(tvb)) {
1252 expert_add_info(pinfo, ti, &ei_dvb_s2_gse_length_invalid);
1253 packet_len = tvb_reported_length(tvb);
1256 /* If not both a start and an end packet, then it's a fragment */
1257 if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) || BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {
1258 proto_tree_add_item_ret_uint(dvb_s2_gse_tree, hf_dvb_s2_gse_fragid, tvb, new_off, 1, ENC_BIG_ENDIAN, &fragid);
1259 col_append_str(pinfo->cinfo, COL_INFO, "(frag) ");
1260 /* Differentiate between the same frag id on different ISI */
1261 fragid ^= (isi << 8);
1262 new_off += 1;
1264 gse_frag_data *subpacket_data = NULL;
1265 if (!PINFO_FD_VISITED(pinfo)) {
1266 gse_frag_data *frag_data;
1267 if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_START_POS)) {
1268 frag_data = get_gse_frag_data(gse_data, fragid, true);
1269 frag_data->labeltype = labeltype;
1270 /* Delete any previous in-progress reassembly if
1271 * we get a new start packet. */
1272 data_tvb = fragment_delete(&dvb_s2_gse_reassembly_table,
1273 pinfo, fragid, NULL);
1274 /* Since we use fragment_add_seq_next, which (as part of
1275 * the fragment_*_check family) moves completed assemblies
1276 * to a new table (and only checks the completed table
1277 * after a packet is visited once), this will never return
1278 * non-NULL nor cause problems later.
1279 * If it does, something changed in the API.
1281 if (data_tvb != NULL) {
1282 DISSECTOR_ASSERT_NOT_REACHED();
1284 subpacket_data = get_gse_subpacket_data(gse_data, pinfo->num, fragid, true);
1285 subpacket_data->labeltype = frag_data->labeltype;
1286 } else {
1287 frag_data = get_gse_frag_data(gse_data, fragid, false);
1288 /* ETSI TS 102 601-1 A.2 Reassembly
1289 * Discard the packet if no buffer is in the re-assembly
1290 * state for the Frag ID (check with fragment_get).
1292 if (frag_data && fragment_get(&dvb_s2_gse_reassembly_table, pinfo, fragid, NULL)) {
1293 subpacket_data = get_gse_subpacket_data(gse_data, pinfo->num, fragid, true);
1294 subpacket_data->labeltype = frag_data->labeltype;
1297 } else {
1298 subpacket_data = get_gse_subpacket_data(gse_data, pinfo->num, fragid, false);
1300 fragment_head *dvbs2_frag_head = NULL;
1301 if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {
1302 data_len = packet_len - new_off - DVB_S2_GSE_CRC32_LEN;
1303 } else {
1304 data_len = packet_len - new_off;
1306 if (subpacket_data) {
1307 dvbs2_frag_head = fragment_add_seq_next(&dvb_s2_gse_reassembly_table, tvb, new_off,
1308 pinfo, fragid, NULL, data_len, BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_STOP_POS));
1310 next_tvb = process_reassembled_data(tvb, new_off, pinfo, "Reassembled GSE",
1311 dvbs2_frag_head, &dvb_s2_gse_frag_items, &update_col_info, tree);
1313 if (next_tvb != NULL && subpacket_data) {
1314 /* We have a reassembled packet. */
1315 complete = true;
1316 labeltype = subpacket_data->labeltype;
1317 crc32_calc = crc32_mpeg2_tvb_offset(next_tvb, 0, tvb_reported_length(next_tvb));
1318 new_off = 0;
1319 ti = proto_tree_add_item_ret_uint(dvb_s2_gse_tree, hf_dvb_s2_gse_totlength, next_tvb, new_off, 2, ENC_BIG_ENDIAN, &totlength);
1320 new_off += 2;
1321 /* Value of totlength field does not include itself or the
1322 * CRC32.
1324 if (totlength != (uint32_t)tvb_reported_length_remaining(next_tvb, new_off)) {
1325 expert_add_info(pinfo, ti, &ei_dvb_s2_gse_totlength_invalid);
1327 } else {
1328 next_tvb = tvb_new_subset_length(tvb, new_off, data_len);
1329 new_off = 0;
1330 if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_START_POS)) {
1331 /* Start packet, add the total length */
1332 proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_totlength, next_tvb, new_off, 2, ENC_BIG_ENDIAN);
1333 new_off += 2;
1336 } else {
1337 complete = true;
1338 next_tvb = tvb_new_subset_length(tvb, 0, packet_len);
1341 if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_START_POS) || complete) {
1342 /* Start packet, decode the header */
1343 gse_proto = tvb_get_ntohs(next_tvb, new_off);
1345 /* Protocol Type */
1346 if (gse_proto <= 1535) {
1347 /* Type 1 (Next-Header Type field) */
1348 proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_proto_next_header, next_tvb, new_off, 2, ENC_BIG_ENDIAN);
1350 else {
1351 /* Type 2 (EtherType compatible Type Fields) */
1352 proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_proto_ethertype, next_tvb, new_off, 2, ENC_BIG_ENDIAN);
1354 new_off += 2;
1356 switch (labeltype) {
1357 case 0:
1358 if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS))
1359 col_append_str(pinfo->cinfo, COL_INFO, "6 ");
1360 proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_label6, next_tvb, new_off, 6, ENC_NA);
1361 new_off += 6;
1362 break;
1363 case 1:
1364 if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS))
1365 col_append_str(pinfo->cinfo, COL_INFO, "3 ");
1366 proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_label3, next_tvb, new_off, 3, ENC_BIG_ENDIAN);
1367 new_off += 3;
1368 break;
1369 case 2:
1370 case 3:
1371 /* TODO: Case 3 means "same as previous in the BBF."
1372 * We can treat it as no label length because nothing
1373 * is in the packet.
1374 * In the future we could save the values in packet data
1375 * and include them here as generated values. Then we
1376 * could also set expert_info if no previous packet in
1377 * the BBF had a label, or if the previous label was
1378 * zero length, both illegal according to ETSI TS
1379 * 102 606-1 A.1 "Filtering".
1381 if (BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS))
1382 col_append_str(pinfo->cinfo, COL_INFO, "0 ");
1383 break;
1385 if (gse_proto < 0x0600 && gse_proto >= 0x100) {
1386 /* Only display optional extension headers */
1387 /* TODO: needs to be tested */
1389 /* TODO: implementation needs to be checked (len of ext-header??) */
1390 proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_exthdr, next_tvb, new_off, 1, ENC_BIG_ENDIAN);
1392 new_off += 1;
1396 data_tvb = tvb_new_subset_remaining(next_tvb, new_off);
1398 copy_address_shallow(&pinfo->src, &save_src);
1399 copy_address_shallow(&pinfo->dst, &save_dst);
1400 pinfo->ptype = save_ptype;
1401 pinfo->srcport = save_srcport;
1402 pinfo->destport = save_destport;
1404 if (complete) {
1405 switch (gse_proto) {
1406 case ETHERTYPE_IP:
1407 if (dvb_s2_full_dissection)
1409 call_dissector(ip_handle, data_tvb, pinfo, tree);
1410 dissected = true;
1412 break;
1414 case ETHERTYPE_IPv6:
1415 if (dvb_s2_full_dissection)
1417 call_dissector(ipv6_handle, data_tvb, pinfo, tree);
1418 dissected = true;
1420 break;
1422 case ETHERTYPE_VLAN:
1423 if (dvb_s2_full_dissection)
1425 call_dissector(eth_withoutfcs_handle, data_tvb, pinfo, tree);
1426 dissected = true;
1428 break;
1430 case DVB_RCS2_SIGNAL_TABLE:
1431 call_dissector(dvb_s2_table_handle, data_tvb, pinfo, tree);
1432 dissected = true;
1433 break;
1435 case DVB_RCS2_NCR:
1436 ttf = proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_ncr, data_tvb, 0, -1, ENC_NA);
1437 dvb_s2_gse_ncr_tree = proto_item_add_subtree(ttf, ett_dvb_s2_gse_ncr);
1438 proto_tree_add_item(dvb_s2_gse_ncr_tree, hf_dvb_s2_gse_data, data_tvb, 0, -1, ENC_NA);
1439 dissected = true;
1440 break;
1442 default:
1443 /* Not handled! TODO: expert info? */
1444 break;
1448 if (!dissected) {
1449 proto_tree_add_item(dvb_s2_gse_tree, hf_dvb_s2_gse_data, data_tvb, 0, -1, ENC_NA);
1452 /* add crc32 if last fragment */
1453 if (BIT_IS_CLEAR(gse_hdr, DVB_S2_GSE_HDR_START_POS) && BIT_IS_SET(gse_hdr, DVB_S2_GSE_HDR_STOP_POS)) {
1454 unsigned flags = PROTO_CHECKSUM_NO_FLAGS;
1455 if (complete) {
1456 flags = PROTO_CHECKSUM_VERIFY;
1458 proto_tree_add_checksum(dvb_s2_gse_tree, tvb, packet_len - DVB_S2_GSE_CRC32_LEN, hf_dvb_s2_gse_crc32, hf_dvb_s2_gse_crc32_status, &ei_dvb_s2_gse_crc32, pinfo, crc32_calc, ENC_BIG_ENDIAN, flags);
1462 return packet_len;
1465 static bool test_dvb_s2_crc(tvbuff_t *tvb, unsigned offset) {
1467 uint8_t input8;
1469 /* only check BB Header and return */
1470 if (tvb_captured_length(tvb) < (offset + DVB_S2_BB_HEADER_LEN))
1471 return false;
1473 input8 = tvb_get_uint8(tvb, offset + DVB_S2_BB_OFFS_CRC);
1475 if (compute_crc8(tvb, DVB_S2_BB_HEADER_LEN - 1, offset) != input8)
1476 return false;
1477 else
1478 return true;
1484 static int dissect_dvb_s2_bb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1486 proto_item *ti;
1487 proto_tree *dvb_s2_bb_tree;
1489 tvbuff_t *sync_tvb = NULL, *tsp_tvb = NULL, *next_tvb = NULL;
1491 conversation_t *conv, *subcircuit;
1492 stream_t *ts_stream;
1493 stream_pdu_fragment_t *ts_frag;
1494 fragment_head *fd_head;
1495 dvbs2_bb_conv_data *conv_data;
1496 dvbs2_bb_data *pdata;
1498 bool npd, composite_init = false;
1499 uint8_t input8, matype1, crc8, isi = 0, issyi;
1500 uint8_t sync_flag = 0;
1501 uint16_t input16, bb_data_len = 0, user_packet_length, syncd;
1502 uint32_t virtual_id;
1503 unsigned flags;
1505 int sub_dissected = 0, flag_is_ms = 0, new_off = 0;
1507 static int * const bb_header_bitfields_low_ro[] = {
1508 &hf_dvb_s2_bb_matype1_gs,
1509 &hf_dvb_s2_bb_matype1_mis,
1510 &hf_dvb_s2_bb_matype1_acm,
1511 &hf_dvb_s2_bb_matype1_issyi,
1512 &hf_dvb_s2_bb_matype1_npd,
1513 &hf_dvb_s2_bb_matype1_low_ro,
1514 NULL
1517 static int * const bb_header_bitfields_high_ro[] = {
1518 &hf_dvb_s2_bb_matype1_gs,
1519 &hf_dvb_s2_bb_matype1_mis,
1520 &hf_dvb_s2_bb_matype1_acm,
1521 &hf_dvb_s2_bb_matype1_issyi,
1522 &hf_dvb_s2_bb_matype1_npd,
1523 &hf_dvb_s2_bb_matype1_high_ro,
1524 NULL
1527 conv = find_or_create_conversation(pinfo);
1529 col_append_str(pinfo->cinfo, COL_PROTOCOL, "BB ");
1530 col_append_str(pinfo->cinfo, COL_INFO, "Baseband ");
1532 /* create display subtree for the protocol */
1533 ti = proto_tree_add_item(tree, proto_dvb_s2_bb, tvb, 0, DVB_S2_BB_HEADER_LEN, ENC_NA);
1534 dvb_s2_bb_tree = proto_item_add_subtree(ti, ett_dvb_s2_bb);
1536 matype1 = tvb_get_uint8(tvb, DVB_S2_BB_OFFS_MATYPE1);
1537 new_off += 1;
1539 if (BIT_IS_CLEAR(matype1, DVB_S2_BB_MIS_POS))
1540 flag_is_ms = 1;
1542 issyi = (matype1 & DVB_S2_BB_ISSYI_MASK) >> DVB_S2_BB_ISSYI_POS;
1543 npd = (matype1 & DVB_S2_BB_NPD_MASK) >> DVB_S2_BB_NPD_POS;
1545 conv_data = get_dvbs2_bb_conv_data(conv);
1547 if (((matype1 & DVB_S2_BB_RO_MASK) == 3) && !conv_data->use_low_ro) {
1548 conv_data->use_low_ro = pinfo->num;
1550 if (conv_data->use_low_ro && pinfo->num >= conv_data->use_low_ro) {
1551 proto_tree_add_bitmask_with_flags(dvb_s2_bb_tree, tvb, DVB_S2_BB_OFFS_MATYPE1, hf_dvb_s2_bb_matype1,
1552 ett_dvb_s2_bb_matype1, bb_header_bitfields_low_ro, ENC_BIG_ENDIAN, BMT_NO_FLAGS);
1553 } else {
1554 proto_tree_add_bitmask_with_flags(dvb_s2_bb_tree, tvb, DVB_S2_BB_OFFS_MATYPE1, hf_dvb_s2_bb_matype1,
1555 ett_dvb_s2_bb_matype1, bb_header_bitfields_high_ro, ENC_BIG_ENDIAN, BMT_NO_FLAGS);
1558 input8 = tvb_get_uint8(tvb, DVB_S2_BB_OFFS_MATYPE2);
1559 new_off += 1;
1560 if (flag_is_ms) {
1561 proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb,
1562 DVB_S2_BB_OFFS_MATYPE2, 1, input8, "Input Stream Identifier (ISI): %d",
1563 input8);
1564 isi = input8;
1565 } else {
1566 proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_matype2, tvb,
1567 DVB_S2_BB_OFFS_MATYPE2, 1, input8, "reserved");
1570 user_packet_length = input16 = tvb_get_ntohs(tvb, DVB_S2_BB_OFFS_UPL);
1571 new_off += 2;
1573 proto_tree_add_uint_format(dvb_s2_bb_tree, hf_dvb_s2_bb_upl, tvb,
1574 DVB_S2_BB_OFFS_UPL, 2, input16, "User Packet Length: %d bits (%d bytes)",
1575 (uint16_t) input16, (uint16_t) input16 / 8);
1577 new_off += 2;
1578 bb_data_len = input16 = tvb_get_ntohs(tvb, DVB_S2_BB_OFFS_DFL);
1579 bb_data_len /= 8;
1580 if (bb_data_len + DVB_S2_BB_HEADER_LEN > tvb_reported_length(tvb)) {
1581 /* DFL can be less than the length of the BBFrame (zero padding is
1582 * applied, see ETSI EN 302 307-1 5.2.1), but cannot be greater
1583 * than the frame length (minus 10 bytes of header).
1585 expert_add_info(pinfo, ti, &ei_dvb_s2_bb_dfl_invalid);
1586 bb_data_len = tvb_reported_length_remaining(tvb, DVB_S2_BB_HEADER_LEN);
1589 proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_dfl, tvb,
1590 DVB_S2_BB_OFFS_DFL, 2, input16, "%d bits (%d bytes)", input16, input16 / 8);
1592 new_off += 1;
1593 sync_flag = tvb_get_uint8(tvb, DVB_S2_BB_OFFS_SYNC);
1594 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_sync, tvb, DVB_S2_BB_OFFS_SYNC, 1, ENC_BIG_ENDIAN);
1596 new_off += 2;
1597 syncd = tvb_get_ntohs(tvb, DVB_S2_BB_OFFS_SYNCD);
1598 proto_tree_add_uint_format_value(dvb_s2_bb_tree, hf_dvb_s2_bb_syncd, tvb,
1599 DVB_S2_BB_OFFS_SYNCD, 2, syncd, "%d bits (%d bytes)", syncd, syncd >> 3);
1601 new_off += 1;
1602 proto_tree_add_checksum(dvb_s2_bb_tree, tvb, DVB_S2_BB_OFFS_CRC, hf_dvb_s2_bb_crc, hf_dvb_s2_bb_crc_status, &ei_dvb_s2_bb_crc, pinfo,
1603 compute_crc8(tvb, DVB_S2_BB_HEADER_LEN - 1, 0), ENC_NA, PROTO_CHECKSUM_VERIFY);
1605 /* The Base-Band Frame can have multiple GSE (or TS, which can have ULE
1606 * or MPE) packets that are concatenated, can be fragmented, and can call
1607 * subdissectors including IP (which itself can be fragmented) that
1608 * overwrite the pinfo addresses & ports, which are used as keys for
1609 * reassembly tables, conversations, and other purposes.
1611 * Thus, we need to save the current values before any subdissectors
1612 * are run, and restore them each time before each subpacket.
1614 * When BBFrames are carried over UDP or RTP we can't necessarily rely on
1615 * the ISI being unique - a capture might include different streams sent
1616 * as single input streams or with the same ISI over different UDP
1617 * endpoints and we don't want to mix data when defragmenting. So we
1618 * create a virtual ISI.
1621 /* UDP and RTP both always create conversations. If we later have
1622 * support for DVB Base Band Frames as the link-layer of a capture file,
1623 * we'll need to handle it differently. In that case just use the
1624 * ISI directly in conversation_new_by_id() instead of creating a
1625 * virtual stream identifier.
1628 if (conv) {
1629 virtual_id = virtual_stream_lookup(conv, isi);
1630 /* DVB Base Band streams are unidirectional. Differentiate by direction
1631 * for the unlikely case of two streams between the same endpointss in
1632 * the opposite direction.
1634 if (addresses_equal(&pinfo->src, conversation_key_addr1(conv->key_ptr))) {
1635 pinfo->p2p_dir = P2P_DIR_SENT;
1636 } else {
1637 pinfo->p2p_dir = P2P_DIR_RECV;
1640 } else {
1641 virtual_id = isi;
1642 pinfo->p2p_dir = P2P_DIR_SENT;
1644 subcircuit = find_conversation_by_id(pinfo->num, CONVERSATION_DVBBBF, virtual_id);
1645 if (subcircuit == NULL) {
1646 subcircuit = conversation_new_by_id(pinfo->num, CONVERSATION_DVBBBF, virtual_id);
1649 /* conversation_set_conv_addr_port_endpoints() could be useful for the subdissectors
1650 * this calls (whether GSE or TS, and replace passing the packet data
1651 * below), but it could cause problems when the subdissectors of those
1652 * subdissectors try and call find_or_create_conversation().
1653 * pinfo->use_conv_addr_port_endpoints doesn't affect reassembly tables
1654 * in the default reassembly functions, either. So maybe the eventual
1655 * approach is to create a conversation key but set
1656 * pinfo->use_conv_addr_port_endpoints back to false, and also make the
1657 * GSE and MP2T dissectors more (DVB BBF) conversation key aware,
1658 * including in their reassembly functions.
1661 pdata = wmem_new0(pinfo->pool, dvbs2_bb_data);
1662 copy_address_shallow(&pdata->src, &pinfo->src);
1663 copy_address_shallow(&pdata->dst, &pinfo->dst);
1664 pdata->ptype = pinfo->ptype;
1665 pdata->srcport = pinfo->srcport;
1666 pdata->destport = pinfo->destport;
1667 pdata->isi = isi;
1669 switch (matype1 & DVB_S2_BB_TSGS_MASK) {
1670 case DVB_S2_BB_TSGS_GENERIC_CONTINUOUS:
1671 /* Check GSE constraints on the BB header per 9.2.1 of ETSI TS 102 771 */
1672 if (issyi) {
1673 expert_add_info(pinfo, ti, &ei_dvb_s2_bb_issy_invalid);
1675 if (npd) {
1676 expert_add_info(pinfo, ti, &ei_dvb_s2_bb_npd_invalid);
1678 if (user_packet_length != 0x0000) {
1679 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_upl_invalid,
1680 "UPL is 0x%04x. It must be 0x0000 for GSE packets.", user_packet_length);
1684 if (dvb_s2_df_dissection) {
1685 while (bb_data_len) {
1686 if (sync_flag == DVB_S2_BB_SYNC_EIP_CRC32 && bb_data_len == DVB_S2_BB_EIP_CRC32_LEN) {
1687 proto_tree_add_checksum(dvb_s2_bb_tree, tvb, new_off, hf_dvb_s2_bb_eip_crc32, hf_dvb_s2_bb_eip_crc32_status, &ei_dvb_s2_bb_crc, pinfo, crc32_mpeg2_tvb_offset(tvb, DVB_S2_BB_HEADER_LEN, new_off - DVB_S2_BB_HEADER_LEN), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
1688 bb_data_len = 0;
1689 new_off += DVB_S2_BB_EIP_CRC32_LEN;
1690 } else {
1691 /* start DVB-GSE dissector */
1692 sub_dissected = dissect_dvb_s2_gse(tvb_new_subset_length(tvb, new_off, bb_data_len), pinfo, tree, pdata);
1693 new_off += sub_dissected;
1695 if ((sub_dissected <= bb_data_len) && (sub_dissected >= DVB_S2_GSE_MINSIZE)) {
1696 bb_data_len -= sub_dissected;
1697 if (bb_data_len < DVB_S2_GSE_MINSIZE)
1698 bb_data_len = 0;
1699 } else {
1700 bb_data_len = 0;
1704 } else {
1705 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_df, tvb, new_off, bb_data_len, ENC_NA);
1706 new_off += bb_data_len;
1708 break;
1710 case DVB_S2_BB_TSGS_GENERIC_PACKETIZED:
1711 proto_tree_add_item(tree, hf_dvb_s2_bb_packetized, tvb, new_off, bb_data_len, ENC_NA);
1712 new_off += bb_data_len;
1713 break;
1715 case DVB_S2_BB_TSGS_TRANSPORT_STREAM:
1716 crc8 = 0;
1717 // TODO: Save from frame to frame to test the first TSP when syncd == 0?
1718 flags = PROTO_CHECKSUM_NO_FLAGS;
1719 /* Check TS constraints on the BB header per 5.1 of ETSI EN 302 307 */
1720 if (sync_flag != MP2T_SYNC_BYTE) {
1721 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_sync_invalid,
1722 "Copy of User Packet Sync is 0x%02x. It must be 0x%02x for TS packets.", sync_flag, MP2T_SYNC_BYTE);
1724 /* ETSI 302 307-1 5.1.6: SYNCD == 0xFFFF -> "no UP starts in the
1725 * DATA FIELD"; otherwise it should not point past the UPL.
1727 if (syncd != 0xFFFF && (syncd >> 3) >= bb_data_len) {
1728 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_syncd_invalid,
1729 "SYNCD >= DFL (points past the end of the Data Field)");
1730 syncd = 0xFFFF;
1732 /* Assume byte aligned. */
1733 user_packet_length >>= 3;
1734 /* UPL should be *at least* MP2T_PACKET_SIZE, depending on npd (1 byte)
1735 * and issy (2 or 3 bytes). The fields are overdetermined (something
1736 * addressed in -C2 and -T2's High Efficiency Mode for TS), so how to
1737 * process in the case of inconsistency is a judgment call. The
1738 * approach here is to disable anything for which there is insufficent
1739 * room, but not to enable anything marked as inactive.
1741 switch (user_packet_length) {
1742 case MP2T_PACKET_SIZE:
1743 if (issyi) {
1744 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_issy_invalid,
1745 "ISSYI is active on TS but UPL is only %d bytes",
1746 user_packet_length);
1747 issyi = 0;
1749 if (npd) {
1750 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_npd_invalid,
1751 "NPD is active on TS but UPL is only %d bytes",
1752 user_packet_length);
1753 npd = false;
1755 break;
1756 case MP2T_PACKET_SIZE + 1:
1757 if (issyi) {
1758 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_issy_invalid,
1759 "ISSYI is active on TS but UPL is only %d bytes",
1760 user_packet_length);
1761 issyi = 0;
1763 if (!npd) {
1764 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_npd_invalid,
1765 "NPD is inactive on TS but UPL is %d bytes",
1766 user_packet_length);
1768 break;
1769 case MP2T_PACKET_SIZE + 2:
1770 if (!issyi) {
1771 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_issy_invalid,
1772 "ISSYI is inactive on TS but UPL is %d bytes",
1773 user_packet_length);
1774 } else {
1775 issyi = 2;
1777 if (npd) {
1778 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_npd_invalid,
1779 "NPD is active on TS but UPL is %d bytes",
1780 user_packet_length);
1781 npd = false;
1783 break;
1784 case MP2T_PACKET_SIZE + 3:
1785 if (npd) {
1786 if (!issyi) {
1787 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_issy_invalid,
1788 "ISSYI is inactive on TS with NPD active but UPL is %d bytes",
1789 user_packet_length);
1790 } else {
1791 issyi = 2;
1793 } else {
1794 if (!issyi) {
1795 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_issy_invalid,
1796 "ISSYI is inactive on TS with NPD inactive but UPL is %d bytes",
1797 user_packet_length);
1798 } else {
1799 issyi = 3;
1802 break;
1803 case MP2T_PACKET_SIZE + 4:
1804 if (!issyi) {
1805 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_issy_invalid,
1806 "ISSYI is inactive on TS but UPL is %d bytes",
1807 user_packet_length);
1808 } else {
1809 issyi = 3;
1811 if (!npd) {
1812 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_npd_invalid,
1813 "NPD is inactive on TS but UPL is %d bytes",
1814 user_packet_length);
1816 break;
1817 default:
1818 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_upl_invalid,
1819 "UPL is %d byte%s. It must be between %d and %d bytes for TS packets.",
1820 user_packet_length, plurality(user_packet_length, "", "s"),
1821 MP2T_PACKET_SIZE, MP2T_PACKET_SIZE+4);
1822 if (user_packet_length < MP2T_PACKET_SIZE) {
1823 user_packet_length = 0;
1825 break;
1827 if (dvb_s2_df_dissection && user_packet_length) {
1828 sync_tvb = tvb_new_subset_length(tvb, DVB_S2_BB_OFFS_SYNC, 1);
1829 ts_stream = find_stream(subcircuit, pinfo->p2p_dir);
1830 if (ts_stream == NULL) {
1831 ts_stream = stream_new(subcircuit, pinfo->p2p_dir);
1833 if (syncd == 0xFFFF) {
1834 /* Largely theoretical for TS (cf. Generic Packetized, GSE-HEM)
1835 * due to the small size of TSPs versus transmitted BBFrames.
1837 next_tvb = tvb_new_subset_length(tvb, new_off, bb_data_len);
1838 ts_frag = stream_find_frag(ts_stream, pinfo->num, new_off);
1839 if (ts_frag == NULL) {
1840 ts_frag = stream_add_frag(ts_stream, pinfo->num, new_off,
1841 next_tvb, pinfo, true);
1843 stream_process_reassembled(next_tvb, 0, pinfo,
1844 "Reassembled TSP", ts_frag, &dvbs2_frag_items, NULL,
1845 tree);
1846 new_off += bb_data_len;
1847 } else {
1848 syncd >>= 3;
1849 /* Do this even if syncd is zero just to clear out a partial
1850 * fragment from before in the case of drops or out of order. */
1851 next_tvb = tvb_new_subset_length(tvb, new_off, syncd);
1852 ts_frag = stream_find_frag(ts_stream, pinfo->num, new_off);
1853 if (ts_frag == NULL) {
1854 ts_frag = stream_add_frag(ts_stream, pinfo->num, new_off,
1855 next_tvb, pinfo, false);
1857 fd_head = stream_get_frag_data(ts_frag);
1858 /* Don't put anything in the tree when SYNCD is 0 and there was
1859 * no earlier fragment (i.e., zero length reassembly)
1861 if (syncd || (fd_head && fd_head->datalen)) {
1862 next_tvb = stream_process_reassembled(next_tvb, 0, pinfo,
1863 "Reassembled TSP", ts_frag, &dvbs2_frag_items, NULL,
1864 tree);
1865 if (next_tvb && tvb_reported_length(next_tvb) == user_packet_length) {
1866 tsp_tvb = tvb_new_composite();
1867 composite_init = true;
1868 tvb_composite_append(tsp_tvb, sync_tvb);
1869 proto_tree_add_checksum(dvb_s2_bb_tree, next_tvb, 0,
1870 hf_dvb_s2_bb_up_crc, hf_dvb_s2_bb_up_crc_status,
1871 &ei_dvb_s2_bb_crc, pinfo, crc8, ENC_NA, flags);
1872 crc8 = compute_crc8(next_tvb, user_packet_length - 1, 1);
1873 flags = PROTO_CHECKSUM_VERIFY;
1874 tvb_composite_append(tsp_tvb, tvb_new_subset_length(next_tvb, 1, MP2T_PACKET_SIZE - 1));
1875 /* XXX: ISSY is not fully dissected */
1876 if (issyi == 2) {
1877 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_issy_short,
1878 next_tvb, MP2T_PACKET_SIZE, issyi, ENC_BIG_ENDIAN);
1879 } else if (issyi == 3) {
1880 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_issy_short,
1881 next_tvb, MP2T_PACKET_SIZE, issyi, ENC_BIG_ENDIAN);
1883 if (npd) {
1884 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_dnp,
1885 next_tvb, MP2T_PACKET_SIZE + issyi, 1, ENC_NA);
1887 } else if (pinfo->num != subcircuit->setup_frame) {
1888 /* Bad reassembly due to a dropped or out of order
1889 * packet, or maybe the previous packet cut short.
1891 expert_add_info(pinfo, ti, &ei_dvb_s2_bb_up_reassembly_invalid);
1893 new_off += syncd;
1896 while ((bb_data_len + DVB_S2_BB_HEADER_LEN - new_off) >= user_packet_length) {
1897 proto_tree_add_checksum(dvb_s2_bb_tree, tvb, new_off,
1898 hf_dvb_s2_bb_up_crc, hf_dvb_s2_bb_up_crc_status,
1899 &ei_dvb_s2_bb_crc, pinfo, crc8, ENC_NA, flags);
1900 if (!composite_init) {
1901 tsp_tvb = tvb_new_composite();
1902 composite_init = true;
1904 tvb_composite_append(tsp_tvb, sync_tvb);
1905 new_off++;
1906 crc8 = compute_crc8(tvb, user_packet_length - 1, new_off);
1907 flags = PROTO_CHECKSUM_VERIFY;
1908 tvb_composite_append(tsp_tvb, tvb_new_subset_length(tvb, new_off, MP2T_PACKET_SIZE - 1));
1909 new_off += MP2T_PACKET_SIZE - 1;
1910 /* XXX: ISSY is not fully dissected */
1911 if (issyi == 2) {
1912 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_issy_short,
1913 tvb, new_off, issyi, ENC_BIG_ENDIAN);
1914 } else if (issyi == 3) {
1915 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_issy_long,
1916 tvb, new_off, issyi, ENC_BIG_ENDIAN);
1918 if (npd) {
1919 proto_tree_add_item(dvb_s2_bb_tree, hf_dvb_s2_bb_dnp,
1920 tvb, new_off + issyi, 1, ENC_NA);
1922 new_off += user_packet_length - MP2T_PACKET_SIZE;
1924 if (bb_data_len + DVB_S2_BB_HEADER_LEN - new_off) {
1925 next_tvb = tvb_new_subset_length(tvb, new_off, bb_data_len + DVB_S2_BB_HEADER_LEN - new_off);
1926 ts_frag = stream_find_frag(ts_stream, pinfo->num, new_off);
1927 if (ts_frag == NULL) {
1928 ts_frag = stream_add_frag(ts_stream, pinfo->num, new_off,
1929 next_tvb, pinfo, true);
1931 stream_process_reassembled(next_tvb, 0, pinfo,
1932 "Reassembled TSP", ts_frag, &dvbs2_frag_items, NULL, tree);
1934 if (composite_init) {
1935 tvb_composite_finalize(tsp_tvb);
1936 add_new_data_source(pinfo, tsp_tvb, "Sync-swapped TS");
1937 /* The way the MP2T dissector handles reassembly (using the
1938 * offsets into the TVB to store per-packet information), it
1939 * needs the entire composite TVB at once rather than be passed
1940 * one TSP at a time. That's why bb_data_len is limited to the
1941 * reported frame length, to avoid throwing an exception running
1942 * off the end before processing the TSPs that are present.
1944 call_dissector(mp2t_handle, tsp_tvb, pinfo, tree);
1946 } else {
1947 proto_tree_add_item(tree, hf_dvb_s2_bb_transport, tvb, new_off, bb_data_len, ENC_NA);
1948 new_off += bb_data_len;
1950 break;
1952 default:
1953 proto_tree_add_item(tree, hf_dvb_s2_bb_reserved, tvb, new_off, bb_data_len, ENC_NA);
1954 new_off += bb_data_len;
1955 expert_add_info(pinfo, ti, &ei_dvb_s2_bb_reserved);
1956 break;
1959 return new_off;
1962 static int detect_dvb_s2_modeadapt(tvbuff_t *tvb)
1964 int matched_headers = 0;
1966 /* Check that there's enough data */
1967 if (tvb_captured_length(tvb) < DVB_S2_MODEADAPT_MINSIZE)
1968 return 0;
1970 /* There are four different mode adaptation formats, with different
1971 length headers. Two of them have a sync byte at the beginning, but
1972 the other two do not. In every case, the mode adaptation header is
1973 followed by the baseband header, which is protected by a CRC-8.
1974 The CRC-8 is weak protection, so it can match by accident, leading
1975 to an ambiguity in identifying which format is in use. We will
1976 check for ambiguity and report it. */
1977 /* Try L.1 format: no header. */
1978 if (test_dvb_s2_crc(tvb, DVB_S2_MODEADAPT_L1SIZE)) {
1979 matched_headers |= (1 << DVB_S2_MODEADAPT_TYPE_L1);
1982 /* Try L.2 format: header includes sync byte */
1983 if ((tvb_get_uint8(tvb, DVB_S2_MODEADAPT_OFFS_SYNCBYTE) == DVB_S2_MODEADAPT_SYNCBYTE) &&
1984 test_dvb_s2_crc(tvb, DVB_S2_MODEADAPT_L2SIZE)) {
1985 matched_headers |= (1 << DVB_S2_MODEADAPT_TYPE_L2);
1988 /* Try L.4 format: header does not include sync byte */
1989 if (test_dvb_s2_crc(tvb, DVB_S2_MODEADAPT_L4SIZE)) {
1990 matched_headers |= (1 << DVB_S2_MODEADAPT_TYPE_L4);
1993 /* Try L.3 format: header includes sync byte */
1994 if ((tvb_get_uint8(tvb, DVB_S2_MODEADAPT_OFFS_SYNCBYTE) == DVB_S2_MODEADAPT_SYNCBYTE) &&
1995 test_dvb_s2_crc(tvb, DVB_S2_MODEADAPT_L3SIZE)) {
1996 matched_headers |= (1 << DVB_S2_MODEADAPT_TYPE_L3);
1999 return matched_headers;
2002 static int dissect_dvb_s2_modeadapt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2004 int cur_off = 0, modeadapt_len, modeadapt_type, matched_headers = 0;
2006 proto_item *ti, *tf;
2007 proto_tree *dvb_s2_modeadapt_tree;
2008 proto_tree *dvb_s2_modeadapt_acm_tree;
2010 unsigned int modcod, mc;
2011 static int * const modeadapt_acm_bitfields[] = {
2012 &hf_dvb_s2_modeadapt_acm_fecframe,
2013 &hf_dvb_s2_modeadapt_acm_pilot,
2014 &hf_dvb_s2_modeadapt_acm_modcod,
2015 NULL
2018 if (dvb_s2_try_all_modeadapt) {
2019 matched_headers = detect_dvb_s2_modeadapt(tvb);
2020 if (matched_headers & (1 << dvb_s2_default_modeadapt)) {
2021 /* If the default value from preferences matches, use it first */
2022 modeadapt_type = dvb_s2_default_modeadapt;
2023 } else if (matched_headers & (1 << DVB_S2_MODEADAPT_TYPE_L3)) {
2024 /* In my experience and in product data sheets, L.3 format is the
2025 * most common for outputting over UDP or RTP, so try it next.
2027 modeadapt_type = DVB_S2_MODEADAPT_TYPE_L3;
2028 } else if (matched_headers & (1 << DVB_S2_MODEADAPT_TYPE_L4)) {
2029 modeadapt_type = DVB_S2_MODEADAPT_TYPE_L4;
2030 } else if (matched_headers & (1 << DVB_S2_MODEADAPT_TYPE_L2)) {
2031 modeadapt_type = DVB_S2_MODEADAPT_TYPE_L2;
2032 } else if (matched_headers & (1 << DVB_S2_MODEADAPT_TYPE_L1)) {
2033 modeadapt_type = DVB_S2_MODEADAPT_TYPE_L1;
2034 } else {
2035 /* If nothing matches, use the default value from preferences.
2037 modeadapt_type = dvb_s2_default_modeadapt;
2039 } else {
2040 /* Assume it's the preferred type */
2041 modeadapt_type = dvb_s2_default_modeadapt;
2043 modeadapt_len = dvb_s2_modeadapt_sizes[modeadapt_type];
2045 col_set_str(pinfo->cinfo, COL_PROTOCOL, "DVB-S2 ");
2046 col_set_str(pinfo->cinfo, COL_INFO, "DVB-S2 ");
2048 /* Add the protocol even if no length (L.1) so we get access to prefs. */
2049 ti = proto_tree_add_protocol_format(tree, proto_dvb_s2_modeadapt, tvb, 0, modeadapt_len,
2050 "DVB-S2 Mode Adaptation Header L.%d", modeadapt_type);
2051 if (ws_count_ones(matched_headers) > 1) {
2052 expert_add_info_format(pinfo, ti, &ei_dvb_s2_bb_header_ambiguous,
2053 "Mode adaptation header format is ambiguous. Assuming L.%d", modeadapt_type);
2055 /* If there's a mode adaptation header, create display subtree for it */
2056 if (modeadapt_len > 0) {
2057 dvb_s2_modeadapt_tree = proto_item_add_subtree(ti, ett_dvb_s2_modeadapt);
2059 /* SYNC byte if used in this header format; value has already been checked */
2060 if (modeadapt_type == DVB_S2_MODEADAPT_TYPE_L2 ||
2061 modeadapt_type == DVB_S2_MODEADAPT_TYPE_L3) {
2062 proto_tree_add_item(dvb_s2_modeadapt_tree, hf_dvb_s2_modeadapt_sync, tvb, cur_off, 1, ENC_BIG_ENDIAN);
2063 cur_off++;
2066 /* ACM byte and subfields if used in this header format */
2067 if (modeadapt_type == DVB_S2_MODEADAPT_TYPE_L2 ||
2068 modeadapt_type == DVB_S2_MODEADAPT_TYPE_L3 ||
2069 modeadapt_type == DVB_S2_MODEADAPT_TYPE_L4) {
2070 mc = tvb_get_uint8(tvb, cur_off);
2071 if (mc & 0x80) {
2072 modcod = 0x80;
2073 modcod |= ((mc & 0x1F) << 2);
2074 modcod |= ((mc & 0x40) >> 5);
2075 tf = proto_tree_add_item(dvb_s2_modeadapt_tree, hf_dvb_s2_modeadapt_acm, tvb,
2076 cur_off, 1, ENC_BIG_ENDIAN);
2078 dvb_s2_modeadapt_acm_tree = proto_item_add_subtree(tf, ett_dvb_s2_modeadapt_acm);
2080 proto_tree_add_item(dvb_s2_modeadapt_acm_tree, hf_dvb_s2_modeadapt_acm_pilot, tvb,
2081 cur_off, 1, ENC_BIG_ENDIAN);
2082 proto_tree_add_uint_format_value(dvb_s2_modeadapt_acm_tree, hf_dvb_s2_modeadapt_acm_modcod_s2x, tvb,
2083 cur_off, 1, mc, "DVBS2X %s(%d)", modeadapt_modcods[modcod].strptr, modcod);
2084 } else {
2085 proto_tree_add_bitmask_with_flags(dvb_s2_modeadapt_tree, tvb, cur_off, hf_dvb_s2_modeadapt_acm,
2086 ett_dvb_s2_modeadapt_acm, modeadapt_acm_bitfields, ENC_BIG_ENDIAN, BMT_NO_FLAGS);
2088 cur_off++;
2091 /* CNI and Frame No if used in this header format */
2092 if (modeadapt_type == DVB_S2_MODEADAPT_TYPE_L3 ||
2093 modeadapt_type == DVB_S2_MODEADAPT_TYPE_L4) {
2094 proto_tree_add_item(dvb_s2_modeadapt_tree, hf_dvb_s2_modeadapt_cni, tvb, cur_off, 1, ENC_BIG_ENDIAN);
2095 cur_off++;
2097 proto_tree_add_item(dvb_s2_modeadapt_tree, hf_dvb_s2_modeadapt_frameno, tvb, cur_off, 1, ENC_BIG_ENDIAN);
2098 cur_off++;
2102 /* start DVB-BB dissector */
2103 cur_off += dissect_dvb_s2_bb(tvb_new_subset_remaining(tvb, cur_off), pinfo, tree, NULL);
2105 return cur_off;
2108 static bool dissect_dvb_s2_modeadapt_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
2110 int matched_headers = detect_dvb_s2_modeadapt(tvb);
2111 if (dvb_s2_try_all_modeadapt) {
2112 if (matched_headers == 0) {
2113 /* This does not look like a DVB-S2-BB frame at all. We are a
2114 heuristic dissector, so we should just punt and let another
2115 dissector have a try at this one. */
2116 return false;
2118 } else if (! (matched_headers & (1 << dvb_s2_default_modeadapt))) {
2119 return false;
2122 int dissected_bytes;
2123 dissected_bytes = dissect_dvb_s2_modeadapt(tvb, pinfo, tree, data);
2124 if (dissected_bytes > 0) {
2125 return true;
2126 } else {
2127 return false;
2131 /* Register the protocol with Wireshark */
2132 void proto_register_dvb_s2_modeadapt(void)
2134 module_t *dvb_s2_modeadapt_module;
2136 static hf_register_info hf_modeadapt[] = {
2137 {&hf_dvb_s2_modeadapt_sync, {
2138 "Sync Byte", "dvb-s2_modeadapt.sync",
2139 FT_UINT8, BASE_HEX, NULL, 0x0,
2140 "Das Sync Byte", HFILL}
2142 {&hf_dvb_s2_modeadapt_acm, {
2143 "ACM command", "dvb-s2_modeadapt.acmcmd",
2144 FT_UINT8, BASE_HEX, NULL, 0x0,
2145 NULL, HFILL}
2147 {&hf_dvb_s2_modeadapt_acm_fecframe, {
2148 "FEC frame size", "dvb-s2_modeadapt.acmcmd.fecframe",
2149 FT_BOOLEAN, 8, TFS(&tfs_modeadapt_fecframe), DVB_S2_MODEADAPT_FECFRAME_MASK,
2150 NULL, HFILL}
2152 {&hf_dvb_s2_modeadapt_acm_pilot, {
2153 "Pilots configuration", "dvb-s2_modeadapt.acmcmd.pilots",
2154 FT_BOOLEAN, 8, TFS(&tfs_on_off), DVB_S2_MODEADAPT_PILOTS_MASK,
2155 NULL, HFILL}
2157 {&hf_dvb_s2_modeadapt_acm_modcod, {
2158 "Modcod indicator", "dvb-s2_modeadapt.acmcmd.modcod",
2159 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &modeadapt_modcods_ext, DVB_S2_MODEADAPT_MODCODS_MASK,
2160 NULL, HFILL}
2162 {&hf_dvb_s2_modeadapt_acm_modcod_s2x, {
2163 "Modcod indicator", "dvb-s2_modeadapt.acmcmd.modcod",
2164 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &modeadapt_modcods_ext, DVB_S2_MODEADAPT_MODCODS_S2X_MASK,
2165 "Modcod S2X", HFILL}
2167 {&hf_dvb_s2_modeadapt_cni, {
2168 "Carrier to Noise [dB]", "dvb-s2_modeadapt.cni",
2169 FT_UINT8, BASE_DEC|BASE_EXT_STRING, &modeadapt_esno_ext, 0x0,
2170 "CNI", HFILL}
2172 {&hf_dvb_s2_modeadapt_frameno, {
2173 "Frame number", "dvb-s2_modeadapt.frameno",
2174 FT_UINT8, BASE_DEC, NULL, 0x0,
2175 "fno", HFILL}
2179 /* Setup protocol subtree array */
2180 static int *ett_modeadapt[] = {
2181 &ett_dvb_s2_modeadapt,
2182 &ett_dvb_s2_modeadapt_acm
2185 static hf_register_info hf_bb[] = {
2186 {&hf_dvb_s2_bb_matype1, {
2187 "MATYPE1", "dvb-s2_bb.matype1",
2188 FT_UINT8, BASE_HEX, NULL, 0x0,
2189 "MATYPE1 Header Field", HFILL}
2191 {&hf_dvb_s2_bb_matype1_gs, {
2192 "TS/GS Stream Input", "dvb-s2_bb.matype1.tsgs",
2193 FT_UINT8, BASE_DEC, VALS(bb_tsgs), DVB_S2_BB_TSGS_MASK,
2194 "Transport Stream Input or Generic Stream Input", HFILL}
2196 {&hf_dvb_s2_bb_matype1_mis, {
2197 "Input Stream", "dvb-s2_bb.matype1.mis",
2198 FT_BOOLEAN, 8, TFS(&tfs_bb_mis), DVB_S2_BB_MIS_MASK,
2199 "Single Input Stream or Multiple Input Stream", HFILL}
2201 {&hf_dvb_s2_bb_matype1_acm, {
2202 "Coding and Modulation", "dvb-s2_bb.matype1.acm",
2203 FT_BOOLEAN, 8, TFS(&tfs_bb_acm), DVB_S2_BB_ACM_MASK,
2204 "Constant Coding and Modulation or Adaptive Coding and Modulation", HFILL}
2206 {&hf_dvb_s2_bb_matype1_issyi, {
2207 "ISSYI", "dvb-s2_bb.matype1.issyi",
2208 FT_BOOLEAN, 8, TFS(&tfs_active_inactive), DVB_S2_BB_ISSYI_MASK,
2209 "Input Stream Synchronization Indicator", HFILL}
2211 {&hf_dvb_s2_bb_matype1_npd, {
2212 "NPD", "dvb-s2_bb.matype1.npd",
2213 FT_BOOLEAN, 8, TFS(&tfs_active_inactive), DVB_S2_BB_NPD_MASK,
2214 "Null-packet deletion enabled", HFILL}
2216 {&hf_dvb_s2_bb_matype1_high_ro, {
2217 "RO", "dvb-s2_bb.matype1.ro",
2218 FT_UINT8, BASE_DEC, VALS(bb_high_ro), DVB_S2_BB_RO_MASK,
2219 "Transmission Roll-off factor", HFILL}
2221 {&hf_dvb_s2_bb_matype1_low_ro, {
2222 "RO", "dvb-s2_bb.matype1.ro",
2223 FT_UINT8, BASE_DEC, VALS(bb_low_ro), DVB_S2_BB_RO_MASK,
2224 "Transmission Roll-off factor", HFILL}
2226 {&hf_dvb_s2_bb_matype2, {
2227 "MATYPE2", "dvb-s2_bb.matype2",
2228 FT_UINT8, BASE_HEX, NULL, 0x0,
2229 "MATYPE2 Header Field", HFILL}
2231 {&hf_dvb_s2_bb_upl, {
2232 "UPL", "dvb-s2_bb.upl",
2233 FT_UINT16, BASE_DEC, NULL, 0x0,
2234 "User Packet Length", HFILL}
2236 {&hf_dvb_s2_bb_dfl, {
2237 "DFL", "dvb-s2_bb.dfl",
2238 FT_UINT16, BASE_DEC, NULL, 0x0,
2239 "Data Field Length", HFILL}
2241 {&hf_dvb_s2_bb_sync, {
2242 "SYNC", "dvb-s2_bb.sync",
2243 FT_UINT8, BASE_HEX, NULL, 0x0,
2244 "Copy of the User Packet Sync-byte", HFILL}
2246 {&hf_dvb_s2_bb_syncd, {
2247 "SYNCD", "dvb-s2_bb.syncd",
2248 FT_UINT16, BASE_DEC, NULL, 0x0,
2249 "Distance to first user packet", HFILL}
2251 {&hf_dvb_s2_bb_crc, {
2252 "Checksum", "dvb-s2_bb.crc",
2253 FT_UINT8, BASE_HEX, NULL, 0x0,
2254 "BB Header CRC-8", HFILL}
2256 {&hf_dvb_s2_bb_crc_status, {
2257 "Checksum Status", "dvb-s2_bb.crc.status",
2258 FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
2259 NULL, HFILL}
2261 {&hf_dvb_s2_bb_packetized, {
2262 "Packetized Generic Stream Data", "dvb-s2_bb.packetized",
2263 FT_BYTES, BASE_NONE, NULL, 0x0,
2264 "Packetized Generic Stream (non-TS) Data", HFILL}
2266 {&hf_dvb_s2_bb_transport, {
2267 "Transport Stream Data", "dvb-s2_bb.transport",
2268 FT_BYTES, BASE_NONE, NULL, 0x0,
2269 "Transport Stream (TS) Data", HFILL}
2271 {&hf_dvb_s2_bb_reserved, {
2272 "GSE High Efficiency Mode Data", "dvb-s2_bb.reserved",
2273 FT_BYTES, BASE_NONE, NULL, 0x0,
2274 "GSE High Efficiency Mode (GSE-HEM) Data", HFILL}
2276 {&hf_dvb_s2_bb_df, {
2277 "BBFrame user data", "dvb-s2_bb.df",
2278 FT_BYTES, BASE_NONE, NULL, 0x0,
2279 NULL, HFILL}
2281 {&hf_dvb_s2_bb_issy_short, {
2282 "ISSY (short)", "dvb-s2_bb.issy.short",
2283 FT_UINT16, BASE_HEX, NULL, 0x0,
2284 "Input stream synchronizer (2 octet version)", HFILL}
2286 {&hf_dvb_s2_bb_issy_long, {
2287 "ISSY (long)", "dvb-s2_bb.issy.long",
2288 FT_UINT24, BASE_HEX, NULL, 0x0,
2289 "Input stream synchronizer (3 octet version)", HFILL}
2291 {&hf_dvb_s2_bb_dnp, {
2292 "DNP", "dvb-s2_bb.dnp",
2293 FT_UINT8, BASE_DEC, NULL, 0x0,
2294 "Deleted Null-Packets counter", HFILL}
2296 {&hf_dvb_s2_bb_eip_crc32, {
2297 "EIP CRC32", "dvb-s2_bb.eip_crc32",
2298 FT_UINT32, BASE_HEX, NULL, 0x0,
2299 "Explicit Integrity Protection CRC32", HFILL}
2301 {&hf_dvb_s2_bb_eip_crc32_status, {
2302 "EIP CRC32 Status", "dvb-s2_bb.eip_crc32.status",
2303 FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
2304 NULL, HFILL}
2306 {&hf_dvb_s2_bb_up_crc, {
2307 "UP Checksum", "dvb-s2_bb.up.crc",
2308 FT_UINT8, BASE_HEX, NULL, 0x0,
2309 "User Packet CRC-8", HFILL}
2311 {&hf_dvb_s2_bb_up_crc_status, {
2312 "UP Checksum Status", "dvb-s2_bb.up.crc.status",
2313 FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
2314 NULL, HFILL}
2316 { &hf_dvbs2_fragment_overlap,
2317 { "Fragment overlap", "dvb-s2_bb.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2318 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2319 { &hf_dvbs2_fragment_overlap_conflict,
2320 { "Conflicting data in fragment overlap", "dvb-s2_bb.fragment.overlap.conflict",
2321 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2322 "Overlapping fragments contained conflicting data", HFILL }},
2323 { &hf_dvbs2_fragment_multiple_tails,
2324 { "Multiple tail fragments found", "dvb-s2_bb.fragment.multipletails",
2325 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2326 "Several tails were found when defragmenting the packet", HFILL }},
2327 { &hf_dvbs2_fragment_too_long_fragment,
2328 { "Fragment too long", "dvb-s2_bb.fragment.toolongfragment",
2329 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2330 "Fragment contained data past end of packet", HFILL }},
2331 { &hf_dvbs2_fragment_error,
2332 { "Defragmentation error", "dvb-s2_bb.fragment.error", FT_FRAMENUM, BASE_NONE,
2333 NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
2334 { &hf_dvbs2_fragment_count,
2335 { "Fragment count", "dvb-s2_bb.fragment.count", FT_UINT32, BASE_DEC,
2336 NULL, 0x0, NULL, HFILL }},
2337 { &hf_dvbs2_fragment,
2338 { "DVB-S2 UP Fragment", "dvb-s2_bb.fragment", FT_FRAMENUM, BASE_NONE,
2339 NULL, 0x0, NULL, HFILL }},
2340 { &hf_dvbs2_fragments,
2341 { "DVB-S2 UP Fragments", "dvb-s2_bb.fragments", FT_BYTES, BASE_NONE,
2342 NULL, 0x0, NULL, HFILL }},
2343 { &hf_dvbs2_reassembled_in,
2344 { "Reassembled DVB-S2 UP in frame", "dvb-s2_bb.reassembled_in", FT_FRAMENUM, BASE_NONE,
2345 NULL, 0x0, "This User Packet is reassembled in this frame", HFILL }},
2347 { &hf_dvbs2_reassembled_length,
2348 { "Reassembled DVB-S2 UP length", "dvb-s2_bb.reassembled.length", FT_UINT32, BASE_DEC,
2349 NULL, 0x0, "The total length of the reassembled payload", HFILL }},
2351 { &hf_dvbs2_reassembled_data,
2352 { "Reassembled DVB-S2 UP data", "dvb-s2_bb.reassembled.data", FT_BYTES, BASE_NONE,
2353 NULL, 0x0, "The reassembled payload", HFILL }}
2356 static int *ett_bb[] = {
2357 &ett_dvb_s2_bb,
2358 &ett_dvb_s2_bb_matype1,
2359 &ett_dvbs2_fragments,
2360 &ett_dvbs2_fragment,
2363 /* DVB-S2 GSE Frame */
2364 static hf_register_info hf_gse[] = {
2365 {&hf_dvb_s2_gse_hdr, {
2366 "GSE header", "dvb-s2_gse.hdr",
2367 FT_UINT16, BASE_HEX, NULL, 0x0,
2368 "GSE Header (start/stop/length)", HFILL}
2370 {&hf_dvb_s2_gse_hdr_start, {
2371 "Start", "dvb-s2_gse.hdr.start",
2372 FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), DVB_S2_GSE_HDR_START_MASK,
2373 "Start Indicator", HFILL}
2375 {&hf_dvb_s2_gse_hdr_stop, {
2376 "Stop", "dvb-s2_gse.hdr.stop",
2377 FT_BOOLEAN, 16, TFS(&tfs_enabled_disabled), DVB_S2_GSE_HDR_STOP_MASK,
2378 "Stop Indicator", HFILL}
2380 {&hf_dvb_s2_gse_hdr_labeltype, {
2381 "Label Type", "dvb-s2_gse.hdr.labeltype",
2382 FT_UINT16, BASE_HEX, VALS(gse_labeltype), DVB_S2_GSE_HDR_LABELTYPE_MASK,
2383 "Label Type Indicator", HFILL}
2385 {&hf_dvb_s2_gse_hdr_length, {
2386 "Length", "dvb-s2_gse.hdr.length",
2387 FT_UINT16, BASE_DEC, NULL, DVB_S2_GSE_HDR_LENGTH_MASK,
2388 "GSE Length", HFILL}
2390 {&hf_dvb_s2_gse_padding, {
2391 "GSE Padding", "dvb-s2_gse.padding",
2392 FT_UINT16, BASE_DEC, NULL, 0x0,
2393 "GSE Padding Bytes", HFILL}
2395 {&hf_dvb_s2_gse_proto_next_header, {
2396 "Protocol", "dvb-s2_gse.proto",
2397 FT_UINT16, BASE_HEX, VALS(gse_proto_next_header_str), 0x0,
2398 "Protocol Type", HFILL}
2400 {&hf_dvb_s2_gse_proto_ethertype, {
2401 "Protocol", "dvb-s2_gse.proto",
2402 FT_UINT16, BASE_HEX, VALS(etype_vals), 0x0,
2403 "Protocol Type", HFILL}
2405 {&hf_dvb_s2_gse_label6, {
2406 "Label", "dvb-s2_gse.label_ether",
2407 FT_ETHER, BASE_NONE, NULL, 0x0,
2408 "Label Field", HFILL}
2410 {&hf_dvb_s2_gse_label3, {
2411 "Label", "dvb-s2_gse.label",
2412 FT_UINT24, BASE_HEX, NULL, 0x0,
2413 "Label Field", HFILL}
2415 {&hf_dvb_s2_gse_fragid, {
2416 "Frag ID", "dvb-s2_gse.fragid",
2417 FT_UINT8, BASE_HEX, NULL, 0x0,
2418 "Fragment ID", HFILL}
2420 {&hf_dvb_s2_gse_totlength, {
2421 "Total Length", "dvb-s2_gse.totlength",
2422 FT_UINT16, BASE_DEC, NULL, 0x0,
2423 "GSE Total Frame Length", HFILL}
2425 {&hf_dvb_s2_gse_exthdr, {
2426 "Extension Header", "dvb-s2_gse.exthdr",
2427 FT_UINT8, BASE_HEX, NULL, 0x0,
2428 "optional Extension Header", HFILL}
2430 {&hf_dvb_s2_gse_ncr, {
2431 "NCR Packet", "dvb-s2_gse.ncr",
2432 FT_BYTES, BASE_NONE, NULL, 0x0,
2433 "GSE NCR PAcket", HFILL}
2435 {&hf_dvb_s2_gse_data, {
2436 "PDU Data", "dvb-s2_gse.data",
2437 FT_BYTES, BASE_NONE, NULL, 0x0,
2438 "GSE Frame User Data", HFILL}
2440 {&hf_dvb_s2_gse_crc32, {
2441 "CRC", "dvb-s2_gse.crc",
2442 FT_UINT32, BASE_HEX, NULL, 0x0,
2443 "CRC-32", HFILL}
2445 {&hf_dvb_s2_gse_crc32_status, {
2446 "CRC Status", "dvb-s2_gse.crc.status",
2447 FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0,
2448 NULL, HFILL}
2450 { &hf_dvb_s2_gse_fragment_overlap,
2451 { "Fragment overlap", "dvb-s2_gse.fragment.overlap", FT_BOOLEAN, BASE_NONE,
2452 NULL, 0x0, "Fragment overlaps with other fragments", HFILL }},
2454 { &hf_dvb_s2_gse_fragment_overlap_conflict,
2455 { "Conflicting data in fragment overlap", "dvb-s2_gse.fragment.overlap.conflict",
2456 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2457 "Overlapping fragments contained conflicting data", HFILL }},
2459 { &hf_dvb_s2_gse_fragment_multiple_tails,
2460 { "Multiple tail fragments found", "dvb-s2_gse.fragment.multipletails",
2461 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2462 "Several tails were found when defragmenting the packet", HFILL }},
2464 { &hf_dvb_s2_gse_fragment_too_long_fragment,
2465 { "Fragment too long", "dvb-s2_gse.fragment.toolongfragment",
2466 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2467 "Fragment contained data past end of packet", HFILL }},
2469 { &hf_dvb_s2_gse_fragment_error,
2470 { "Defragmentation error", "dvb-s2_gse.fragment.error", FT_FRAMENUM, BASE_NONE,
2471 NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
2473 { &hf_dvb_s2_gse_fragment_count,
2474 { "Fragment count", "dvb-s2_gse.fragment.count", FT_UINT32, BASE_DEC,
2475 NULL, 0x0, NULL, HFILL }},
2477 { &hf_dvb_s2_gse_fragment,
2478 { "DVB-S2 GSE Fragment", "dvb-s2_gse.fragment", FT_FRAMENUM, BASE_NONE,
2479 NULL, 0x0, NULL, HFILL }},
2481 { &hf_dvb_s2_gse_fragments,
2482 { "DVB-S2 GSE Fragments", "dvb-s2_gse.fragments", FT_BYTES, BASE_NONE,
2483 NULL, 0x0, NULL, HFILL }},
2485 { &hf_dvb_s2_gse_reassembled_in,
2486 { "Reassembled DVB-S2 GSE in frame", "dvb-s2_gse.reassembled_in", FT_FRAMENUM, BASE_NONE,
2487 NULL, 0x0, "This GSE packet is reassembled in this frame", HFILL }},
2489 { &hf_dvb_s2_gse_reassembled_length,
2490 { "Reassembled DVB-S2 GSE length", "dvb-s2_gse.reassembled.length", FT_UINT32, BASE_DEC,
2491 NULL, 0x0, "The total length of the reassembled payload", HFILL }},
2493 { &hf_dvb_s2_gse_reassembled_data,
2494 { "Reassembled DVB-S2 GSE data", "dvb-s2_gse.reassembled.data", FT_BYTES, BASE_NONE,
2495 NULL, 0x0, "The reassembled payload", HFILL }}
2498 static int *ett_gse[] = {
2499 &ett_dvb_s2_gse,
2500 &ett_dvb_s2_gse_hdr,
2501 &ett_dvb_s2_gse_ncr,
2502 &ett_dvb_s2_gse_fragments,
2503 &ett_dvb_s2_gse_fragment,
2506 static ei_register_info ei[] = {
2507 { &ei_dvb_s2_bb_crc, { "dvb-s2_bb.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
2508 { &ei_dvb_s2_bb_issy_invalid, {"dvb-s2_bb.issy_invalid", PI_PROTOCOL, PI_WARN, "ISSY is active, which is not allowed for GSE packets", EXPFILL }},
2509 { &ei_dvb_s2_bb_npd_invalid, {"dvb-s2_bb.npd_invalid", PI_PROTOCOL, PI_WARN, "NPD is active, which is not allowed for GSE packets", EXPFILL }},
2510 { &ei_dvb_s2_bb_upl_invalid, {"dvb-s2_bb.upl_invalid", PI_PROTOCOL, PI_WARN, "User Packet Length non-zero, which is not allowed for GSE packets", EXPFILL }},
2511 { &ei_dvb_s2_bb_dfl_invalid, {"dvb-s2_bb.dfl_invalid", PI_PROTOCOL, PI_WARN, "Data Field Length greater than reported frame length", EXPFILL }},
2512 { &ei_dvb_s2_bb_sync_invalid, {"dvb-s2_bb.sync_invalid", PI_PROTOCOL, PI_WARN, "User Packet Sync-byte not 0x47, which is not allowed for TS packets", EXPFILL }},
2513 { &ei_dvb_s2_bb_syncd_invalid, {"dvb-s2_bb.syncd_invalid", PI_PROTOCOL, PI_WARN, "Sync Distance is invalid", EXPFILL }},
2514 { &ei_dvb_s2_bb_up_reassembly_invalid, {"dvb-s2_bb.up_reassembly_invalid", PI_REASSEMBLE, PI_ERROR, "Reassembled User Packet has invalid length (dropped or out of order frames)", EXPFILL }},
2515 { &ei_dvb_s2_bb_reserved, {"dvb-s2_bb.reserved_frame_format", PI_UNDECODED, PI_WARN, "Dissection of GSE-HEM is not (yet) supported", EXPFILL }},
2516 { &ei_dvb_s2_bb_header_ambiguous, { "dvb-s2_bb.header_ambiguous", PI_ASSUMPTION, PI_WARN, "Mode Adaptation header ambiguous", EXPFILL }},
2519 expert_module_t* expert_dvb_s2_bb;
2521 static ei_register_info ei_gse[] = {
2522 { &ei_dvb_s2_gse_length_invalid, {"dvb-s2_gse.hdr.length_invalid", PI_PROTOCOL, PI_ERROR, "Length field in header exceeds available bytes in frame", EXPFILL }},
2523 { &ei_dvb_s2_gse_totlength_invalid, {"dvb-s2_gse.totlength_invalid", PI_REASSEMBLE, PI_ERROR, "Length of reassembled packet does not equal total length field (missing fragments?)", EXPFILL }},
2524 { &ei_dvb_s2_gse_crc32, { "dvb-s2_gse.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
2527 expert_module_t* expert_dvb_s2_gse;
2529 proto_dvb_s2_modeadapt = proto_register_protocol("DVB-S2 Mode Adaptation Header", "DVB-S2", "dvb-s2_modeadapt");
2531 proto_dvb_s2_bb = proto_register_protocol("DVB-S2 Baseband Frame", "DVB-S2-BB", "dvb-s2_bb");
2533 proto_dvb_s2_gse = proto_register_protocol("DVB-S2 GSE Packet", "DVB-S2-GSE", "dvb-s2_gse");
2535 proto_register_field_array(proto_dvb_s2_modeadapt, hf_modeadapt, array_length(hf_modeadapt));
2536 proto_register_subtree_array(ett_modeadapt, array_length(ett_modeadapt));
2538 proto_register_field_array(proto_dvb_s2_bb, hf_bb, array_length(hf_bb));
2539 proto_register_subtree_array(ett_bb, array_length(ett_bb));
2540 expert_dvb_s2_bb = expert_register_protocol(proto_dvb_s2_bb);
2541 expert_register_field_array(expert_dvb_s2_bb, ei, array_length(ei));
2543 proto_register_field_array(proto_dvb_s2_gse, hf_gse, array_length(hf_gse));
2544 proto_register_subtree_array(ett_gse, array_length(ett_gse));
2545 expert_dvb_s2_gse = expert_register_protocol(proto_dvb_s2_gse);
2546 expert_register_field_array(expert_dvb_s2_gse, ei_gse, array_length(ei_gse));
2548 dvb_s2_modeadapt_module = prefs_register_protocol(proto_dvb_s2_modeadapt, NULL);
2550 prefs_register_obsolete_preference(dvb_s2_modeadapt_module, "enable");
2552 prefs_register_bool_preference(dvb_s2_modeadapt_module, "decode_df",
2553 "Enable dissection of DATA FIELD",
2554 "Check this to enable full protocol dissection of data above BBHeader",
2555 &dvb_s2_df_dissection);
2557 prefs_register_bool_preference(dvb_s2_modeadapt_module, "full_decode",
2558 "Enable dissection of GSE data",
2559 "Check this to enable full protocol dissection of data above GSE Layer",
2560 &dvb_s2_full_dissection);
2562 prefs_register_enum_preference(dvb_s2_modeadapt_module, "default_modeadapt",
2563 "Preferred Mode Adaptation Interface",
2564 "The preferred Mode Adaptation Interface",
2565 &dvb_s2_default_modeadapt, dvb_s2_modeadapt_enum, false);
2567 prefs_register_bool_preference(dvb_s2_modeadapt_module, "try_all_modeadapt",
2568 "Try all Mode Adaptation Interface Types",
2569 "Try all supported Mode Adaptation Interface Types, using the preferred"
2570 " value in the case of ambiguity; if unset, only look for Base Band"
2571 " Frames with the preferred type",
2572 &dvb_s2_try_all_modeadapt);
2574 prefs_register_obsolete_preference(dvb_s2_modeadapt_module, "dynamic.payload.type");
2576 register_init_routine(dvb_s2_gse_defragment_init);
2577 register_init_routine(&virtual_stream_init);
2579 virtual_stream_hashtable = wmem_map_new_autoreset(wmem_epan_scope(), wmem_file_scope(), virtual_stream_hash, virtual_stream_equal);
2581 dvb_s2_modeadapt_handle = register_dissector_with_description("dvb-s2_modeadapt", "DVB-S2 Mode adaptation header", dissect_dvb_s2_modeadapt, proto_dvb_s2_modeadapt);
2584 void proto_reg_handoff_dvb_s2_modeadapt(void)
2586 heur_dissector_add("udp", dissect_dvb_s2_modeadapt_heur, "DVB-S2 over UDP", "dvb_s2_udp", proto_dvb_s2_modeadapt, HEURISTIC_DISABLE);
2587 dissector_add_for_decode_as("udp.port", dvb_s2_modeadapt_handle);
2588 ip_handle = find_dissector_add_dependency("ip", proto_dvb_s2_bb);
2589 ipv6_handle = find_dissector_add_dependency("ipv6", proto_dvb_s2_bb);
2590 dvb_s2_table_handle = find_dissector("dvb-s2_table");
2591 eth_withoutfcs_handle = find_dissector("eth_withoutfcs");
2592 data_handle = find_dissector("data");
2593 mp2t_handle = find_dissector_add_dependency("mp2t", proto_dvb_s2_bb);
2595 dissector_add_string("rtp_dyn_payload_type","DVB-S2", dvb_s2_modeadapt_handle);
2596 dissector_add_uint_range_with_preference("rtp.pt", "", dvb_s2_modeadapt_handle);
2600 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2602 * Local variables:
2603 * c-basic-offset: 4
2604 * tab-width: 8
2605 * indent-tabs-mode: nil
2606 * End:
2608 * vi: set shiftwidth=4 tabstop=8 expandtab:
2609 * :indentSize=4:tabSize=8:noTabs=true: