Define some fcns & vars as static...
[metze/wireshark/wip.git] / epan / dissectors / packet-mp2t.c
1 /* packet-mp2t.c
2  *
3  * Routines for RFC 2250 MPEG2 (ISO/IEC 13818-1) Transport Stream dissection
4  *
5  * $Id$
6  *
7  * Copyright 2006, Erwin Rol <erwin@erwinrol.com>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26  */
27
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
31
32 #include <glib.h>
33 #include <epan/packet.h>
34
35 #include <epan/rtp_pt.h>
36 #include "packet-frame.h"
37
38 #include <epan/emem.h>
39 #include <epan/conversation.h>
40 #include <epan/expert.h>
41 #include <epan/reassemble.h>
42
43 /* The MPEG2 TS packet size */
44 #define MP2T_PACKET_SIZE 188
45 #define MP2T_SYNC_BYTE 0x47
46
47 static dissector_handle_t pes_handle;
48 static dissector_handle_t docsis_handle;
49 static dissector_handle_t data_handle;
50
51 static int proto_mp2t = -1;
52 static gint ett_mp2t = -1;
53 static gint ett_mp2t_header = -1;
54 static gint ett_mp2t_af = -1;
55 static gint ett_mp2t_analysis = -1;
56 static gint ett_dmpt = -1;
57
58 static int hf_mp2t_header = -1;
59 static int hf_mp2t_sync_byte = -1;
60 static int hf_mp2t_tei = -1;
61 static int hf_mp2t_pusi = -1;
62 static int hf_mp2t_tp = -1;
63 static int hf_mp2t_pid = -1;
64 static int hf_mp2t_tsc = -1;
65 static int hf_mp2t_afc = -1;
66 static int hf_mp2t_cc = -1;
67 static int hf_mp2t_cc_drop = -1;
68
69 static int hf_mp2t_analysis_flags = -1;
70 static int hf_mp2t_analysis_skips = -1;
71 static int hf_mp2t_analysis_drops = -1;
72
73 #define MP2T_SYNC_BYTE_MASK     0xFF000000
74 #define MP2T_TEI_MASK           0x00800000
75 #define MP2T_PUSI_MASK          0x00400000
76 #define MP2T_TP_MASK            0x00200000
77 #define MP2T_PID_MASK           0x001FFF00
78 #define MP2T_TSC_MASK           0x000000C0
79 #define MP2T_AFC_MASK           0x00000030
80 #define MP2T_CC_MASK            0x0000000F
81
82 #define MP2T_SYNC_BYTE_SHIFT    24
83 #define MP2T_TEI_SHIFT          23
84 #define MP2T_PUSI_SHIFT         22
85 #define MP2T_TP_SHIFT           21
86 #define MP2T_PID_SHIFT          8
87 #define MP2T_TSC_SHIFT          6
88 #define MP2T_AFC_SHIFT          4
89 #define MP2T_CC_SHIFT           0
90
91 static int hf_mp2t_af = -1;
92 static int hf_mp2t_af_length = -1;
93 static int hf_mp2t_af_di = -1;
94 static int hf_mp2t_af_rai = -1;
95 static int hf_mp2t_af_espi = -1;
96 static int hf_mp2t_af_pcr_flag = -1;
97 static int hf_mp2t_af_opcr_flag = -1;
98 static int hf_mp2t_af_sp_flag = -1;
99 static int hf_mp2t_af_tpd_flag = -1;
100 static int hf_mp2t_af_afe_flag = -1;
101
102 #define MP2T_AF_DI_MASK         0x80
103 #define MP2T_AF_RAI_MASK        0x40
104 #define MP2T_AF_ESPI_MASK       0x20
105 #define MP2T_AF_PCR_MASK        0x10
106 #define MP2T_AF_OPCR_MASK       0x08
107 #define MP2T_AF_SP_MASK         0x04
108 #define MP2T_AF_TPD_MASK        0x02
109 #define MP2T_AF_AFE_MASK        0x01
110
111 #define MP2T_AF_DI_SHIFT        7
112 #define MP2T_AF_RAI_SHIFT       6
113 #define MP2T_AF_ESPI_SHIFT      5
114 #define MP2T_AF_PCR_SHIFT       4
115 #define MP2T_AF_OPCR_SHIFT      3
116 #define MP2T_AF_SP_SHIFT        2
117 #define MP2T_AF_TPD_SHIFT       1
118 #define MP2T_AF_AFE_SHIFT       0
119
120 static int hf_mp2t_af_pcr = -1;
121 static int hf_mp2t_af_opcr = -1;
122
123 static int hf_mp2t_af_sc = -1;
124
125 static int hf_mp2t_af_tpd_length = -1;
126 static int hf_mp2t_af_tpd = -1;
127
128 static int hf_mp2t_af_e_length = -1;
129 static int hf_mp2t_af_e_ltw_flag = -1;
130 static int hf_mp2t_af_e_pr_flag = -1;
131 static int hf_mp2t_af_e_ss_flag = -1;
132 static int hf_mp2t_af_e_reserved = -1;
133
134 #define MP2T_AF_E_LTW_FLAG_MASK 0x80
135 #define MP2T_AF_E_PR_FLAG_MASK  0x40
136 #define MP2T_AF_E_SS_FLAG_MASK  0x20
137
138 static int hf_mp2t_af_e_reserved_bytes = -1;
139 static int hf_mp2t_af_stuffing_bytes = -1;
140
141 static int hf_mp2t_af_e_ltwv_flag = -1;
142 static int hf_mp2t_af_e_ltwo = -1;
143
144 static int hf_mp2t_af_e_pr_reserved = -1;
145 static int hf_mp2t_af_e_pr = -1;
146
147 static int hf_mp2t_af_e_st = -1;
148 static int hf_mp2t_af_e_dnau_32_30 = -1;
149 static int hf_mp2t_af_e_m_1 = -1;
150 static int hf_mp2t_af_e_dnau_29_15 = -1;
151 static int hf_mp2t_af_e_m_2 = -1;
152 static int hf_mp2t_af_e_dnau_14_0 = -1;
153 static int hf_mp2t_af_e_m_3 = -1;
154
155 static int hf_mp2t_payload = -1;
156 static int hf_mp2t_malformed_payload = -1;
157
158
159 static const value_string mp2t_sync_byte_vals[] = {
160         { MP2T_SYNC_BYTE, "Correct" },
161         { 0, NULL }
162 };
163
164 static const value_string mp2t_pid_vals[] = {
165         { 0x0000, "Program Association Table" },
166         { 0x0001, "Conditional Access Table" },
167         { 0x0002, "Transport Stream Description Table" },
168         { 0x0003, "Reserved" },
169         { 0x0004, "Reserved" },
170         { 0x0005, "Reserved" },
171         { 0x0006, "Reserved" },
172         { 0x0007, "Reserved" },
173         { 0x0008, "Reserved" },
174         { 0x0009, "Reserved" },
175         { 0x000A, "Reserved" },
176         { 0x000B, "Reserved" },
177         { 0x000C, "Reserved" },
178         { 0x000D, "Reserved" },
179         { 0x000E, "Reserved" },
180         { 0x000F, "Reserved" },
181         { 0x1FFE, "DOCSIS Data-over-cable well-known PID" },
182         { 0x1FFF, "Null packet" },
183         { 0, NULL }
184 };
185
186 static const value_string mp2t_tsc_vals[] = {
187         { 0, "Not scrambled" },
188         { 1, "User-defined" },
189         { 2, "User-defined" },
190         { 3, "User-defined" },
191         { 0, NULL }
192 };
193
194 static const value_string mp2t_afc_vals[] = {
195         { 0, "Reserved" },
196         { 1, "Payload only" },
197         { 2, "Adaptation Field only" },
198         { 3, "Adaptation Field and Payload" },
199         { 0, NULL }
200 };
201
202 static gint ett_depi_msg_fragment = -1;
203 static gint ett_depi_msg_fragments = -1;
204 static int hf_depi_msg_fragments = -1;
205 static int hf_depi_msg_fragment = -1;
206 static int hf_depi_msg_fragment_overlap = -1;
207 static int hf_depi_msg_fragment_overlap_conflicts = -1;
208 static int hf_depi_msg_fragment_multiple_tails = -1;
209 static int hf_depi_msg_fragment_too_long_fragment = -1;
210 static int hf_depi_msg_fragment_error = -1;
211 static int hf_depi_msg_reassembled_in = -1;
212 static int hf_depi_msg_reassembled_length = -1;
213
214 static const fragment_items depi_msg_frag_items = {
215     /* Fragment subtrees */
216     &ett_depi_msg_fragment,
217     &ett_depi_msg_fragments,
218     /* Fragment fields */
219     &hf_depi_msg_fragments,
220     &hf_depi_msg_fragment,
221     &hf_depi_msg_fragment_overlap,
222     &hf_depi_msg_fragment_overlap_conflicts,
223     &hf_depi_msg_fragment_multiple_tails,
224     &hf_depi_msg_fragment_too_long_fragment,
225     &hf_depi_msg_fragment_error,
226     /* Reassembled in field */
227     &hf_depi_msg_reassembled_in,
228     /* Reassembled length field */
229     &hf_depi_msg_reassembled_length,
230     /* Tag */
231     "Message fragments"
232 };
233
234 /* Structures to handle DOCSIS-DEPI packets, spanned across
235  * multiple MPEG packets
236  */
237 static GHashTable *mp2t_depi_fragment_table = NULL;
238 static GHashTable *mp2t_depi_reassembled_table = NULL;
239
240 /*****************   DOCSIS defragmentation support *******************/
241 /* definitions of DOCSIS payload type - from plugins/docsis/packet-docsis.c  */
242 #define DOCSIS_FC_TYPE_DATA         0x00
243 #define DOCSIS_FC_TYPE_ATM          0x01
244 #define DOCSIS_FC_TYPE_RESERVED     0x02
245 #define DOCSIS_FC_TYPE_MAC          0x03
246
247 static guint16
248 get_docsis_packet_length(tvbuff_t * tvb, gint offset)
249 {
250     guint16 len;
251     guint8  fc;
252     guint8  fctype;
253
254     /* Extract FC_TYPE and FC_PARM */
255     fc = tvb_get_guint8 (tvb, offset);  /* Frame Control Byte */
256     fctype = (fc >> 6) & 0x03;  /* Frame Control Type: 2 MSB Bits */
257
258     if((fctype == DOCSIS_FC_TYPE_ATM) ||
259        (fctype == DOCSIS_FC_TYPE_RESERVED)) {
260         /* add text - this FC type is not supported */
261         return 0;
262     }
263
264     /* The only case when this field is used for SID is for
265      * request frames, but they are in upstream direction.
266      */
267     len = tvb_get_ntohs(tvb, offset + 2)  +  6;
268
269     return (len);
270 }
271
272 static void
273 mp2t_depi_docsis_fragmentation_handle(tvbuff_t *tvb, guint offset,
274                                       packet_info *pinfo, proto_tree *tree,
275                                       guint frag_offset, guint frag_len,
276                                       gboolean fragment_last)
277 {
278     fragment_data *frag_msg = NULL;
279     tvbuff_t *new_tvb = NULL;
280     tvbuff_t *next_tvb = NULL;
281     proto_item *ti;
282     proto_tree *dmpt_tree;
283
284     pinfo->fragmented = TRUE;
285
286     /* check length; send frame for reassembly */
287     frag_msg = fragment_add_check(tvb, offset, pinfo,
288                    0, mp2t_depi_fragment_table,
289                    mp2t_depi_reassembled_table,
290                    frag_offset,
291                    frag_len,
292                    !fragment_last);
293
294     new_tvb = process_reassembled_data(tvb, offset, pinfo,
295                   "Reassembled MP2T",
296                   frag_msg, &depi_msg_frag_items,
297                   NULL, tree);
298
299     if (frag_msg) { /* Reassembled */
300         col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled)");
301     } else { /* Not last packet of reassembled Short Message */
302         col_append_fstr(pinfo->cinfo, COL_INFO," (Message fragment %u)", 0);
303     }
304
305     /* put DOCSIS handler here */
306     if (new_tvb) { /* take it all */
307         next_tvb = new_tvb;
308
309         ti = proto_tree_add_text(tree, tvb, offset, 0, "DOCSIS MAC Frame (reassembled)");
310         dmpt_tree = proto_item_add_subtree(ti, ett_dmpt);
311
312         if (docsis_handle)
313             call_dissector(docsis_handle, next_tvb, pinfo, dmpt_tree);
314         else
315             call_dissector(data_handle, next_tvb, pinfo, dmpt_tree);
316     } else { /* make a new subset */
317         next_tvb = tvb_new_subset(tvb, offset, -1, -1);
318     }
319
320     return;
321 }
322
323 /*  Decoding of DOCSIS MAC frames within MPEG packets. MAC frames may begin anywhere
324  *  within an MPEG packet or span multiple MPEG packets.
325  *  payload_unit_start_indicator bit in MPEG header, and pointer field are used to
326  *  decode fragmented DOCSIS frames within MPEG packet.
327  *-------------------------------------------------------------------------------
328  *MPEG Header | pointer_field | stuff_bytes | Start of MAC Frame #1              |
329  *(PUSI = 1)  | (= 0)         | (0 or more) |(up to 183 bytes)                   |
330  *-------------------------------------------------------------------------------
331  *-------------------------------------------------------------------------------
332  *MPEG Header |  Continuation of MAC Frame #1                                    |
333  *(PUSI = 0)  |  (up to 183 bytes)                                               |
334  *-------------------------------------------------------------------------------
335  *-------------------------------------------------------------------------------
336  *MPEG Header | pointer_field |Tail of MAC Frame| stuff_bytes |Start of MAC Frame|
337  *(PUSI = 1)  | (= M)         | #1  (M bytes)   | (0 or more) |# 2 (N bytes)     |
338  *-------------------------------------------------------------------------------
339  *  Source - Data-Over-Cable Service Interface Specifications
340  *  CM-SP-DRFI-I07-081209
341  */
342 static void
343 mp2t_depi_docsis_process_payload(tvbuff_t *tvb, gint offset, packet_info *pinfo,
344                                  proto_tree *tree, proto_tree *header_tree)
345 {
346     guint32  pusi_flag;
347     tvbuff_t *next_tvb;
348     guint8   pointer;
349     proto_item *ti;
350     proto_tree *dmpt_tree;
351     static gboolean fragmentation = FALSE;
352     static guint32 mac_frame_len, cumulative_len;
353
354     pusi_flag = (tvb_get_ntohl(tvb, offset) & 0x00400000);
355
356     offset += 4;
357
358     if (pusi_flag) {
359         pointer = tvb_get_guint8(tvb, offset);
360         proto_tree_add_text(header_tree, tvb, offset, 1,
361             "Pointer: %u", tvb_get_guint8(tvb, offset));
362         offset += 1;
363     }
364
365     /* get tail of MAC frame */
366     if (pusi_flag && fragmentation) {
367         fragmentation = FALSE;
368
369         /* check length; send frame for reassembly */
370         mp2t_depi_docsis_fragmentation_handle(tvb, offset, pinfo,
371             tree,
372             cumulative_len,
373             pointer,
374             TRUE);
375         cumulative_len += pointer;
376
377         if (cumulative_len != mac_frame_len) {
378             proto_tree_add_text(tree, tvb, offset, mac_frame_len,
379                 "Invalid cumulative length %u",
380                 cumulative_len);
381             return;
382         }
383     }
384
385     /* Get start of MAC frame or get complete frame */
386     if (pusi_flag && !fragmentation) {
387         guint16 remaining_length;
388
389         remaining_length = 183 - pointer;
390         offset += pointer;
391
392         while (remaining_length > 0) {
393             while ((tvb_get_guint8(tvb, offset) == 0xFF)) {
394                 remaining_length--;
395                 if (remaining_length == 0)
396                     return;
397                 offset += 1;
398             }
399
400             /* Here, we start DOCSIS frame */
401             mac_frame_len = get_docsis_packet_length(tvb, offset);
402             cumulative_len = 0;
403
404             if (!mac_frame_len) {
405                 proto_tree_add_text(tree, tvb, offset, mac_frame_len,
406                     "Invalid DOCSIS length %u", mac_frame_len);
407                 return;
408             }
409
410             if (mac_frame_len <= remaining_length) {
411                 fragmentation = FALSE;
412                 /* send for processing */
413                 ti = proto_tree_add_text(tree, tvb, offset,
414                     mac_frame_len,
415                     "DOCSIS MAC Frame: %u bytes", mac_frame_len);
416                 dmpt_tree = proto_item_add_subtree(ti, ett_dmpt);
417                 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
418                 call_dissector(docsis_handle, next_tvb, pinfo, dmpt_tree);
419
420                 offset += mac_frame_len;
421                 remaining_length -= mac_frame_len;
422             } else {
423                 fragmentation = TRUE;
424
425                 mp2t_depi_docsis_fragmentation_handle(tvb, offset, pinfo,
426                     tree, 0, remaining_length, FALSE);
427                 cumulative_len = remaining_length;
428                 return;
429             }
430         }
431     }
432
433     /* if PUSI flag == 0 - check fragmentation flag */
434     if (!pusi_flag) {
435         gboolean last_fragment = FALSE;
436
437         if (fragmentation == FALSE) {
438             /* Error - fragmentation should be TRUE */
439             proto_tree_add_text(tree, tvb, offset, mac_frame_len,
440                 "Error - PUSI is 0 in unfragmented DOCSIS packet");
441             return;
442         }
443
444         /* If packet length is consistent with MAC frame length -
445          * call function to handle all fragments
446          */
447         if ((cumulative_len + 184) == mac_frame_len) {
448             last_fragment = TRUE;
449             fragmentation = FALSE;
450         }
451
452         mp2t_depi_docsis_fragmentation_handle(tvb, offset, pinfo,
453             tree, cumulative_len, 184, last_fragment);
454         cumulative_len += 184;
455
456         return;
457     }
458 }
459
460
461 /* Data structure used for detecting CC drops
462  *
463  *  conversation
464  *    |
465  *    +-> mp2t_analysis_data
466  *          |
467  *          +-> pid_table (RB tree) (key: pid)
468  *          |     |
469  *          |     +-> pid_analysis_data (per pid)
470  *          |     +-> pid_analysis_data
471  *          |     +-> pid_analysis_data
472  *          |
473  *          +-> frame_table (RB tree) (key: pinfo->fd->num)
474  *                |
475  *                +-> frame_analysis_data (only created if drop detected)
476  *                      |
477  *                      +-> ts_table (RB tree)
478  *                            |
479  *                            +-> ts_analysis_data (per TS subframe)
480  *                            +-> ts_analysis_data
481  *                            +-> ts_analysis_data
482  */
483
484 typedef struct mp2t_analysis_data {
485
486         /* This structure contains a tree containing data for the
487          * individual pid's, this is only used when packets are
488          * processed sequencially.
489          */
490         emem_tree_t     *pid_table;
491
492         /* When detecting a CC drop, store that information for the
493          * given frame.  This info is needed, when clicking around in
494          * wireshark, as the pid table data only makes sence during
495          * sequencial processing. The flag pinfo->fd->flags.visited is
496          * used to tell the difference.
497          *
498          */
499         emem_tree_t     *frame_table;
500
501         /* Total counters per conversation / multicast stream */
502         guint32 total_skips;
503         guint32 total_discontinuity;
504
505 } mp2t_analysis_data_t;
506
507 /* Analysis TS frame info needed during sequential processing */
508 typedef struct pid_analysis_data {
509         guint16 pid;
510         gint8   cc_prev;        /* Previous CC number */
511 } pid_analysis_data_t;
512
513 /* Analysis info stored for a TS frame */
514 typedef struct ts_analysis_data {
515         guint16 pid;
516         gint8   cc_prev;        /* Previous CC number */
517         guint8  skips;          /* Skips between CCs max 14 */
518 } ts_analysis_data_t;
519
520
521 typedef struct frame_analysis_data {
522
523         /* As each frame has several pid's, thus need a pid data
524          * structure per TS frame.
525          */
526         emem_tree_t     *ts_table;
527
528 } frame_analysis_data_t;
529
530 static mp2t_analysis_data_t *
531 init_mp2t_conversation_data(void)
532 {
533         mp2t_analysis_data_t *mp2t_data = NULL;
534
535         mp2t_data = se_alloc0(sizeof(struct mp2t_analysis_data));
536
537         mp2t_data->pid_table =
538                 se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK,
539                                               "mp2t_pid_table");
540         mp2t_data->frame_table =
541                 se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK,
542                                               "mp2t_frame_table");
543
544         mp2t_data->total_skips = 0;
545         mp2t_data->total_discontinuity = 0;
546
547         return mp2t_data;
548 }
549
550 static mp2t_analysis_data_t *
551 get_mp2t_conversation_data(conversation_t *conv)
552 {
553         mp2t_analysis_data_t *mp2t_data = NULL;
554
555         mp2t_data = conversation_get_proto_data(conv, proto_mp2t);
556         if (!mp2t_data) {
557                 mp2t_data = init_mp2t_conversation_data();
558                 conversation_add_proto_data(conv, proto_mp2t, mp2t_data);
559         }
560
561         return mp2t_data;
562 }
563
564 static frame_analysis_data_t *
565 init_frame_analysis_data(mp2t_analysis_data_t *mp2t_data, packet_info *pinfo)
566 {
567         frame_analysis_data_t *frame_analysis_data_p = NULL;
568
569         frame_analysis_data_p = se_alloc0(sizeof(struct frame_analysis_data));
570         frame_analysis_data_p->ts_table =
571           se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK,
572                                         "mp2t_frame_pid_table");
573         /* Insert into mp2t tree */
574         se_tree_insert32(mp2t_data->frame_table, pinfo->fd->num,
575                          (void *)frame_analysis_data_p);
576
577         return frame_analysis_data_p;
578 }
579
580
581 static frame_analysis_data_t *
582 get_frame_analysis_data(mp2t_analysis_data_t *mp2t_data, packet_info *pinfo)
583 {
584         frame_analysis_data_t *frame_analysis_data_p = NULL;
585         frame_analysis_data_p = se_tree_lookup32(mp2t_data->frame_table, pinfo->fd->num);
586         return frame_analysis_data_p;
587 }
588
589 static pid_analysis_data_t *
590 get_pid_analysis(guint32 pid, conversation_t *conv)
591 {
592
593         pid_analysis_data_t  *pid_data  = NULL;
594         mp2t_analysis_data_t *mp2t_data = NULL;
595         mp2t_data = get_mp2t_conversation_data(conv);
596
597         pid_data = se_tree_lookup32(mp2t_data->pid_table, pid);
598         if (!pid_data) {
599                 pid_data          = se_alloc0(sizeof(struct pid_analysis_data));
600                 pid_data->cc_prev = -1;
601                 pid_data->pid     = pid;
602
603                 se_tree_insert32(mp2t_data->pid_table, pid, (void *)pid_data);
604         }
605         return pid_data;
606 }
607
608 /* Calc the number of skipped CC numbers. Note that this can easy
609  * overflow, and a value above 7 indicate several network packets
610  * could be lost.
611  */
612 static guint32
613 calc_skips(gint32 curr, gint32 prev)
614 {
615         int res = 0;
616
617         /* Only count the missing TS frames in between prev and curr.
618          * The "prev" frame CC number seen is confirmed received, its
619          * the next frames CC counter which is the first known missing
620          * TS frame
621          */
622         prev += 1;
623
624         /* Calc missing TS frame 'skips' */
625         res = curr - prev;
626
627         /* Handle wrap around */
628         if (res < 0)
629                 res += 16;
630
631         return res;
632 }
633
634 #define KEY(pid, cc) ((pid << 4)|cc)
635
636 static guint32
637 detect_cc_drops(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo,
638                 guint32 pid, gint32 cc_curr, conversation_t *conv)
639 {
640         gint32 cc_prev = -1;
641         pid_analysis_data_t   *pid_data              = NULL;
642         ts_analysis_data_t    *ts_data               = NULL;
643         mp2t_analysis_data_t  *mp2t_data             = NULL;
644         frame_analysis_data_t *frame_analysis_data_p = NULL;
645         proto_item            *flags_item;
646
647         guint32 detected_drop = 0;
648         guint32 skips = 0;
649
650         mp2t_data = get_mp2t_conversation_data(conv);
651
652         /* The initial sequencial processing stage */
653         if (!pinfo->fd->flags.visited) {
654
655                 /* This is the sequencial processing stage */
656                 pid_data = get_pid_analysis(pid, conv);
657
658                 cc_prev = pid_data->cc_prev;
659                 pid_data->cc_prev = cc_curr;
660
661                 /* Null packet always have a CC value equal 0 */
662                 if (pid == 0x1fff)
663                         return 0;
664
665                 /* Its allowed that (cc_prev == cc_curr) if adaptation field */
666                 if (cc_prev == cc_curr)
667                         return 0;
668
669                 /* Have not seen this pid before */
670                 if (cc_prev == -1)
671                         return 0;
672
673                 /* Detect if CC is not increasing by one all the time */
674                 if (cc_curr != ((cc_prev+1) & MP2T_CC_MASK)) {
675                         detected_drop = 1;
676
677                         skips = calc_skips(cc_curr, cc_prev);
678
679                         mp2t_data->total_skips += skips;
680                         mp2t_data->total_discontinuity++;
681                         /* TODO: if (skips > 7) signal_loss++; ??? */
682                 }
683         }
684
685         /* Save the info about the dropped packet */
686         if (detected_drop && !pinfo->fd->flags.visited) {
687
688                 /* Lookup frame data, contains TS pid data objects */
689                 frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo);
690                 if (!frame_analysis_data_p)
691                         frame_analysis_data_p = init_frame_analysis_data(mp2t_data, pinfo);
692
693                 /* Create and store a new TS frame pid_data object.
694                    This indicate that we have a drop
695                  */
696                 ts_data = se_alloc0(sizeof(struct ts_analysis_data));
697                 ts_data->cc_prev = cc_prev;
698                 ts_data->pid = pid;
699                 ts_data->skips = skips;
700                 se_tree_insert32(frame_analysis_data_p->ts_table, KEY(pid, cc_curr),
701                                  (void *)ts_data);
702         }
703
704         /* See if we stored info about drops */
705         if (pinfo->fd->flags.visited) {
706
707                 /* Lookup frame data, contains TS pid data objects */
708                 frame_analysis_data_p = get_frame_analysis_data(mp2t_data, pinfo);
709                 if (!frame_analysis_data_p)
710                         return 0; /* No stored frame data -> no drops*/
711                 else {
712                         ts_data = se_tree_lookup32(frame_analysis_data_p->ts_table,
713                                                    KEY(pid, cc_curr));
714
715                         if (ts_data) {
716                                 if (ts_data->skips > 0) {
717                                         detected_drop = 1;
718                                         cc_prev = ts_data->cc_prev;
719                                         skips   = ts_data->skips;
720                                 }
721                         }
722                 }
723
724         }
725
726         /* Add info to the proto tree about drops */
727         if (detected_drop) {
728
729                 flags_item =
730                         proto_tree_add_none_format(
731                                 tree, hf_mp2t_cc_drop, tvb, 0, 0,
732                                 "Detected %d missing TS frames before this"
733                                 " (last_cc:%d total skips:%d discontinuity:%d)",
734                                 skips, cc_prev,
735                                 mp2t_data->total_skips,
736                                 mp2t_data->total_discontinuity
737                                 );
738
739                 PROTO_ITEM_SET_GENERATED(flags_item);
740                 expert_add_info_format(pinfo, flags_item, PI_MALFORMED,
741                                        PI_ERROR, "Detected TS frame loss");
742
743                 flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_skips,
744                                                tvb, 0, 0, skips);
745                 PROTO_ITEM_SET_GENERATED(flags_item);
746
747                 flags_item = proto_tree_add_uint(tree, hf_mp2t_analysis_drops,
748                                                tvb, 0, 0, 1);
749                 PROTO_ITEM_SET_GENERATED(flags_item);
750
751         }
752         return skips;
753 }
754
755
756 static gint
757 dissect_tsp(tvbuff_t *tvb, volatile gint offset, packet_info *pinfo,
758             proto_tree *tree, conversation_t *conv)
759 {
760         guint32 header;
761         guint afc;
762         gint start_offset = offset;
763         volatile gint payload_len;
764
765         guint32 skips;
766         guint32 pid;
767         guint32 cc;
768
769         proto_item *ti = NULL;
770         proto_item *hi = NULL;
771         proto_item *item = NULL;
772         proto_tree *mp2t_tree = NULL;
773         proto_tree *mp2t_header_tree = NULL;
774         proto_tree *mp2t_af_tree = NULL;
775         proto_tree *mp2t_analysis_tree = NULL;
776
777         ti = proto_tree_add_item( tree, proto_mp2t, tvb, offset, MP2T_PACKET_SIZE, FALSE );
778         mp2t_tree = proto_item_add_subtree( ti, ett_mp2t );
779
780         header = tvb_get_ntohl(tvb, offset);
781
782         pid = (header & MP2T_PID_MASK) >> MP2T_PID_SHIFT;
783         cc  = (header & MP2T_CC_MASK)  >> MP2T_CC_SHIFT;
784         proto_item_append_text(ti, " PID=0x%x CC=%d", pid, cc);
785
786         hi = proto_tree_add_item( mp2t_tree, hf_mp2t_header, tvb, offset, 4, FALSE);
787         mp2t_header_tree = proto_item_add_subtree( hi, ett_mp2t_header );
788
789         proto_tree_add_item( mp2t_header_tree, hf_mp2t_sync_byte, tvb, offset, 4, FALSE);
790         proto_tree_add_item( mp2t_header_tree, hf_mp2t_tei, tvb, offset, 4, FALSE);
791         proto_tree_add_item( mp2t_header_tree, hf_mp2t_pusi, tvb, offset, 4, FALSE);
792         proto_tree_add_item( mp2t_header_tree, hf_mp2t_tp, tvb, offset, 4, FALSE);
793         proto_tree_add_item( mp2t_header_tree, hf_mp2t_pid, tvb, offset, 4, FALSE);
794         proto_tree_add_item( mp2t_header_tree, hf_mp2t_tsc, tvb, offset, 4, FALSE);
795         proto_tree_add_item( mp2t_header_tree, hf_mp2t_afc, tvb, offset, 4, FALSE);
796         proto_tree_add_item( mp2t_header_tree, hf_mp2t_cc, tvb, offset, 4, FALSE);
797
798         /* If this is a DOCSIS packet - reassemble MPEG frames and call DOCSIS dissector */
799         if (((header & MP2T_PID_MASK) >> MP2T_PID_SHIFT) == 0x1FFE) {
800                 mp2t_depi_docsis_process_payload(tvb, offset, pinfo, tree, mp2t_tree);
801         }
802
803         offset += 4;
804
805         /* Create a subtree for analysis stuff */
806         item = proto_tree_add_text(mp2t_tree, tvb, 0, 0, "MPEG2 PCR Analysis");
807         PROTO_ITEM_SET_GENERATED(item);
808         mp2t_analysis_tree = proto_item_add_subtree(item, ett_mp2t_analysis);
809
810         skips = detect_cc_drops(tvb, mp2t_analysis_tree, pinfo, pid, cc, conv);
811         if (skips > 0)
812                 proto_item_append_text(ti, " skips=%d", skips);
813
814
815         afc = (header & MP2T_AFC_MASK) >> MP2T_AFC_SHIFT;
816
817         if (afc == 2 || afc == 3)
818         {
819                 gint af_start_offset = offset;
820
821                 guint8 af_length;
822                 guint8 af_flags;
823                 gint stuffing_len;
824
825
826                 af_length = tvb_get_guint8(tvb, offset);
827
828                 proto_tree_add_item( mp2t_tree, hf_mp2t_af_length, tvb, offset, 1, FALSE);
829                 offset += 1;
830                 /* fix issues where afc==3 but af_length==0
831                  *  Adaptaion field...spec section 2.4.3.5: The value 0 is for inserting a single
832                  *  stuffing byte in a Transport Stream packet. When the adaptation_field_control
833                  *  value is '11', the value of the adaptation_field_length shall be in the range 0 to 182.
834                  */
835                 if (af_length > 0 ) {
836                         hi = proto_tree_add_item( mp2t_tree, hf_mp2t_af, tvb, offset, af_length, FALSE);
837                         mp2t_af_tree = proto_item_add_subtree( hi, ett_mp2t_af );
838
839                         af_flags = tvb_get_guint8(tvb, offset);
840
841                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_di, tvb, offset, 1, FALSE);
842                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_rai, tvb, offset, 1, FALSE);
843                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_espi, tvb, offset, 1, FALSE);
844                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_pcr_flag, tvb, offset, 1, FALSE);
845                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_opcr_flag, tvb, offset, 1, FALSE);
846                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sp_flag, tvb, offset, 1, FALSE);
847                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_flag, tvb, offset, 1, FALSE);
848                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_afe_flag, tvb, offset, 1, FALSE);
849
850                         offset += 1;
851
852                         if (af_flags &  MP2T_AF_PCR_MASK) {
853                                 guint64 pcr_base = 0;
854                                 guint32 pcr_ext = 0;
855                                 guint8 tmp;
856
857                                 tmp = tvb_get_guint8(tvb, offset);
858                                 pcr_base = (pcr_base << 8) | tmp;
859                                 offset += 1;
860
861                                 tmp = tvb_get_guint8(tvb, offset);
862                                 pcr_base = (pcr_base << 8) | tmp;
863                                 offset += 1;
864
865                                 tmp = tvb_get_guint8(tvb, offset);
866                                 pcr_base = (pcr_base << 8) | tmp;
867                                 offset += 1;
868
869                                 tmp = tvb_get_guint8(tvb, offset);
870                                 pcr_base = (pcr_base << 8) | tmp;
871                                 offset += 1;
872
873                                 tmp = tvb_get_guint8(tvb, offset);
874                                 pcr_base = (pcr_base << 1) | ((tmp >> 7) & 0x01);
875                                 pcr_ext = (tmp & 0x01);
876                                 offset += 1;
877
878                                 tmp = tvb_get_guint8(tvb, offset);
879                                 pcr_ext = (pcr_ext << 8) | tmp;
880                                 offset += 1;
881
882                                 proto_tree_add_none_format(mp2t_af_tree, hf_mp2t_af_pcr, tvb, offset - 6, 6,
883                                                 "Program Clock Reference: base(%" G_GINT64_MODIFIER "u) * 300 + ext(%u) = %" G_GINT64_MODIFIER "u",
884                                                 pcr_base, pcr_ext, pcr_base * 300 + pcr_ext);
885                         }
886
887                         if (af_flags &  MP2T_AF_OPCR_MASK) {
888                                 guint64 opcr_base = 0;
889                                 guint32 opcr_ext = 0;
890                                 guint8 tmp = 0;
891
892                                 tmp = tvb_get_guint8(tvb, offset);
893                                 opcr_base = (opcr_base << 8) | tmp;
894                                 offset += 1;
895
896                                 tmp = tvb_get_guint8(tvb, offset);
897                                 opcr_base = (opcr_base << 8) | tmp;
898                                 offset += 1;
899
900                                 tmp = tvb_get_guint8(tvb, offset);
901                                 opcr_base = (opcr_base << 8) | tmp;
902                                 offset += 1;
903
904                                 tmp = tvb_get_guint8(tvb, offset);
905                                 opcr_base = (opcr_base << 8) | tmp;
906                                 offset += 1;
907
908                                 tmp = tvb_get_guint8(tvb, offset);
909                                 opcr_base = (opcr_base << 1) | ((tmp >> 7) & 0x01);
910                                 opcr_ext = (tmp & 0x01);
911                                 offset += 1;
912
913                                 tmp = tvb_get_guint8(tvb, offset);
914                                 opcr_ext = (opcr_ext << 8) | tmp;
915                                 offset += 1;
916
917                                 proto_tree_add_none_format(mp2t_af_tree, hf_mp2t_af_opcr, tvb, offset - 6, 6,
918                                                 "Original Program Clock Reference: base(%" G_GINT64_MODIFIER "u) * 300 + ext(%u) = %" G_GINT64_MODIFIER "u",
919                                                 opcr_base, opcr_ext, opcr_base * 300 + opcr_ext);
920
921                                 offset += 6;
922                         }
923
924                         if (af_flags &  MP2T_AF_SP_MASK) {
925                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_sc, tvb, offset, 1, FALSE);
926                                 offset += 1;
927                         }
928
929                         if (af_flags &  MP2T_AF_TPD_MASK) {
930                                 guint8 tpd_len;
931
932                                 tpd_len = tvb_get_guint8(tvb, offset);
933                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd_length, tvb, offset, 1, FALSE);
934                                 offset += 1;
935
936                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_tpd, tvb, offset, tpd_len, FALSE);
937                                 offset += tpd_len;
938                         }
939
940                         if (af_flags &  MP2T_AF_AFE_MASK) {
941                                 guint8 e_len;
942                                 guint8 e_flags;
943                                 gint e_start_offset = offset;
944                                 gint reserved_len = 0;
945
946                                 e_len = tvb_get_guint8(tvb, offset);
947                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_length, tvb, offset, 1, FALSE);
948                                 offset += 1;
949
950                                 e_flags = tvb_get_guint8(tvb, offset);
951                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltw_flag, tvb, offset, 1, FALSE);
952                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_flag, tvb, offset, 1, FALSE);
953                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ss_flag, tvb, offset, 1, FALSE);
954                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved, tvb, offset, 1, FALSE);
955                                 offset += 1;
956
957                                 if (e_flags & MP2T_AF_E_LTW_FLAG_MASK) {
958                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwv_flag, tvb, offset, 2, FALSE);
959                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_ltwo, tvb, offset, 2, FALSE);
960                                         offset += 2;
961                                 }
962
963                                 if (e_flags & MP2T_AF_E_PR_FLAG_MASK) {
964                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr_reserved, tvb, offset, 3, FALSE);
965                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_pr, tvb, offset, 3, FALSE);
966                                         offset += 3;
967                                 }
968
969                                 if (e_flags & MP2T_AF_E_SS_FLAG_MASK) {
970                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_st, tvb, offset, 1, FALSE);
971                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_32_30, tvb, offset, 1, FALSE);
972                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_1, tvb, offset, 1, FALSE);
973                                         offset += 1;
974                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_29_15, tvb, offset, 2, FALSE);
975                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_2, tvb, offset, 2, FALSE);
976                                         offset += 2;
977                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_dnau_14_0, tvb, offset, 2, FALSE);
978                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_m_3, tvb, offset, 2, FALSE);
979                                         offset += 2;
980                                 }
981
982                                 reserved_len = (e_len + 1) - (offset - e_start_offset);
983                                 if (reserved_len > 0) {
984                                         proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_e_reserved_bytes, tvb, offset, reserved_len, FALSE);
985                                         offset += reserved_len;
986                                 }
987                         }
988
989                         stuffing_len = (af_length + 1) - (offset - af_start_offset);
990                         if (stuffing_len > 0) {
991                                 proto_tree_add_item( mp2t_af_tree, hf_mp2t_af_stuffing_bytes, tvb, offset, stuffing_len, FALSE);
992                                 offset += stuffing_len;
993                         }
994                 }
995         }
996
997         payload_len = MP2T_PACKET_SIZE - (offset - start_offset);
998         if (payload_len > 0) {
999                 if (afc == 2) { /* AF only */
1000                         /* Packet is malformed */
1001                         proto_tree_add_item( mp2t_tree, hf_mp2t_malformed_payload, tvb, offset, payload_len, FALSE);
1002                         offset += payload_len;
1003                 } else {
1004                         /* Check to make sure if we are not at end of payload, if we have less than 3 bytes, the tvb_get_ntoh24 fails. */
1005                         if (payload_len >=3 ) {
1006                                 if (tvb_get_ntoh24(tvb, offset) == 0x000001) {
1007                                         tvbuff_t *next_tvb = tvb_new_subset(tvb, offset, payload_len, payload_len);
1008                                         const char *saved_proto = pinfo->current_proto;
1009                                         void *pd_save = pinfo->private_data;
1010
1011                                         TRY {
1012                                                 call_dissector(pes_handle, next_tvb, pinfo, mp2t_tree);
1013                                         }
1014
1015                                         /*
1016                                          Don't stop processing TS packets if somebody threw
1017                                          BoundsError, which means that dissecting the payload found
1018                                          that the packet was cut off by before the end of the
1019                                          payload.  This is very likely as this protocol splits the
1020                                          media stream up into chunks of MP2T_PACKET_SIZE.
1021                                         */
1022                                         CATCH2(BoundsError, ReportedBoundsError) {
1023                                                 /*  Restore the private_data structure in case one of the
1024                                                  *  called dissectors modified it (and, due to the exception,
1025                                                  *  was unable to restore it).
1026                                                  */
1027                                                 pinfo->private_data = pd_save;
1028                                                 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
1029                                                 pinfo->current_proto = saved_proto;
1030                                         }
1031
1032                                         ENDTRY;
1033                                 } else {
1034                                         proto_tree_add_item( mp2t_tree, hf_mp2t_payload, tvb, offset, payload_len, FALSE);
1035                                 }
1036                         } else {
1037                                 proto_tree_add_item( mp2t_tree, hf_mp2t_payload, tvb, offset, payload_len, FALSE);
1038                         }
1039                         offset += payload_len;
1040                 }
1041         }
1042
1043         return offset;
1044 }
1045
1046
1047 static void
1048 dissect_mp2t( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
1049 {
1050         guint offset = 0;
1051         conversation_t *conv;
1052         conv = find_or_create_conversation(pinfo);
1053
1054         while ( tvb_reported_length_remaining(tvb, offset) >= MP2T_PACKET_SIZE ) {
1055                 offset = dissect_tsp(tvb, offset, pinfo, tree, conv);
1056         }
1057 }
1058
1059 static gboolean
1060 heur_dissect_mp2t( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
1061 {
1062         guint offset = 0;
1063
1064         if (tvb_length_remaining(tvb, offset) % MP2T_PACKET_SIZE) {
1065                 return FALSE;
1066         } else {
1067                 while (tvb_length_remaining(tvb, offset)) {
1068                         if (tvb_get_guint8(tvb, offset) != MP2T_SYNC_BYTE)
1069                                 return FALSE;
1070                         offset += MP2T_PACKET_SIZE;
1071                 }
1072         }
1073
1074         dissect_mp2t(tvb, pinfo, tree);
1075         return TRUE;
1076 }
1077
1078 void
1079 proto_register_mp2t(void)
1080 {
1081         static hf_register_info hf[] = {
1082                 { &hf_mp2t_header, {
1083                         "Header", "mp2t.header",
1084                         FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL
1085                 } } ,
1086                 { &hf_mp2t_sync_byte, {
1087                         "Sync Byte", "mp2t.sync_byte",
1088                         FT_UINT32, BASE_HEX, VALS(mp2t_sync_byte_vals), MP2T_SYNC_BYTE_MASK, NULL, HFILL
1089                 } } ,
1090                 { &hf_mp2t_tei, {
1091                         "Transport Error Indicator", "mp2t.tei",
1092                         FT_UINT32, BASE_DEC, NULL, MP2T_TEI_MASK, NULL, HFILL
1093                 } } ,
1094                 { &hf_mp2t_pusi, {
1095                         "Payload Unit Start Indicator", "mp2t.pusi",
1096                         FT_UINT32, BASE_DEC, NULL, MP2T_PUSI_MASK, NULL, HFILL
1097                 } } ,
1098                 { &hf_mp2t_tp, {
1099                         "Transport Priority", "mp2t.tp",
1100                         FT_UINT32, BASE_DEC, NULL, MP2T_TP_MASK, NULL, HFILL
1101                 } } ,
1102                 { &hf_mp2t_pid, {
1103                         "PID", "mp2t.pid",
1104                         FT_UINT32, BASE_HEX, VALS(mp2t_pid_vals), MP2T_PID_MASK, NULL, HFILL
1105                 } } ,
1106                 { &hf_mp2t_tsc, {
1107                         "Transport Scrambling Control", "mp2t.tsc",
1108                         FT_UINT32, BASE_HEX, VALS(mp2t_tsc_vals), MP2T_TSC_MASK, NULL, HFILL
1109                 } } ,
1110                 { &hf_mp2t_afc, {
1111                         "Adaption Field Control", "mp2t.afc",
1112                         FT_UINT32, BASE_HEX, VALS(mp2t_afc_vals) , MP2T_AFC_MASK, NULL, HFILL
1113                 } } ,
1114                 { &hf_mp2t_cc, {
1115                         "Continuity Counter", "mp2t.cc",
1116                         FT_UINT32, BASE_DEC, NULL, MP2T_CC_MASK, NULL, HFILL
1117                 } } ,
1118                 { &hf_mp2t_cc_drop, {
1119                         "Continuity Counter Drops", "mp2t.cc.drop",
1120                         FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL
1121                 } } ,
1122                 { &hf_mp2t_analysis_flags, {
1123                         "MPEG2-TS Analysis Flags", "mp2t.analysis.flags",
1124                         FT_NONE, BASE_NONE, NULL, 0x0,
1125                         "This frame has some of the MPEG2 analysis flags set", HFILL
1126                 } } ,
1127                 { &hf_mp2t_analysis_skips, {
1128                         "TS Continuity Counter Skips", "mp2t.analysis.skips",
1129                         FT_UINT8, BASE_DEC, NULL, 0x0,
1130                         "Missing TS frames accoding to CC counter values", HFILL
1131                 } } ,
1132                 { &hf_mp2t_analysis_drops, {
1133                         "Some frames dropped", "mp2t.analysis.drops",
1134                         FT_UINT8, BASE_DEC, NULL, 0x0,
1135                         "Discontinuity: A number of TS frames were dropped", HFILL
1136                 } } ,
1137                 { &hf_mp2t_af, {
1138                         "Adaption field", "mp2t.af",
1139                         FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1140                 } } ,
1141                 { &hf_mp2t_af_length, {
1142                         "Adaptation Field Length", "mp2t.af.length",
1143                         FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL
1144                 } } ,
1145                 { &hf_mp2t_af_di, {
1146                         "Discontinuity Indicator", "mp2t.af.di",
1147                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_DI_MASK, NULL, HFILL
1148                 } } ,
1149                 { &hf_mp2t_af_rai, {
1150                         "Random Access Indicator", "mp2t.af.rai",
1151                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_RAI_MASK, NULL, HFILL
1152                 } } ,
1153                 { &hf_mp2t_af_espi, {
1154                         "Elementary Stream Priority Indicator", "mp2t.af.espi",
1155                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_ESPI_MASK, NULL, HFILL
1156                 } } ,
1157                 { &hf_mp2t_af_pcr_flag, {
1158                         "PCR Flag", "mp2t.af.pcr_flag",
1159                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_PCR_MASK, NULL, HFILL
1160                 } } ,
1161                 { &hf_mp2t_af_opcr_flag, {
1162                         "OPCR Flag", "mp2t.af.opcr_flag",
1163                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_OPCR_MASK, NULL, HFILL
1164                 } } ,
1165                 { &hf_mp2t_af_sp_flag, {
1166                         "Splicing Point Flag", "mp2t.af.sp_flag",
1167                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_SP_MASK, NULL, HFILL
1168                 } } ,
1169                 { &hf_mp2t_af_tpd_flag, {
1170                         "Transport Private Data Flag", "mp2t.af.tpd_flag",
1171                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_TPD_MASK, NULL, HFILL
1172                 } } ,
1173                 { &hf_mp2t_af_afe_flag, {
1174                         "Adaptation Field Extension Flag", "mp2t.af.afe_flag",
1175                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_AFE_MASK, NULL, HFILL
1176                 } } ,
1177                 { &hf_mp2t_af_pcr, {
1178                         "Program Clock Reference", "mp2t.af.pcr",
1179                         FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1180                 } } ,
1181                 { &hf_mp2t_af_opcr, {
1182                         "Original Program Clock Reference", "mp2t.af.opcr",
1183                         FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL
1184                 } } ,
1185                 { &hf_mp2t_af_sc, {
1186                         "Splice Countdown", "mp2t.af.sc",
1187                         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
1188                 } } ,
1189                 { &hf_mp2t_af_tpd_length, {
1190                         "Transport Private Data Length", "mp2t.af.tpd_length",
1191                         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
1192                 } } ,
1193                 { &hf_mp2t_af_tpd, {
1194                         "Transport Private Data", "mp2t.af.tpd",
1195                         FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL
1196                 } } ,
1197                 { &hf_mp2t_af_e_length, {
1198                         "Adaptation Field Extension Length", "mp2t.af.e_length",
1199                         FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
1200                 } } ,
1201                 { &hf_mp2t_af_e_ltw_flag, {
1202                         "LTW Flag", "mp2t.af.e.ltw_flag",
1203                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_LTW_FLAG_MASK, NULL, HFILL
1204                 } } ,
1205                 { &hf_mp2t_af_e_pr_flag, {
1206                         "Piecewise Rate Flag", "mp2t.af.e.pr_flag",
1207                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_PR_FLAG_MASK, NULL, HFILL
1208                 } } ,
1209                 { &hf_mp2t_af_e_ss_flag, {
1210                         "Seamless Splice Flag", "mp2t.af.e.ss_flag",
1211                         FT_UINT8, BASE_DEC, NULL, MP2T_AF_E_SS_FLAG_MASK, NULL, HFILL
1212                 } } ,
1213                 { &hf_mp2t_af_e_reserved, {
1214                         "Reserved", "mp2t.af.e.reserved",
1215                         FT_UINT8, BASE_DEC, NULL, 0x1F, NULL, HFILL
1216                 } } ,
1217                 { &hf_mp2t_af_e_reserved_bytes, {
1218                         "Reserved", "mp2t.af.e.reserved_bytes",
1219                         FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1220                 } } ,
1221                 { &hf_mp2t_af_stuffing_bytes, {
1222                         "Stuffing", "mp2t.af.stuffing_bytes",
1223                         FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1224                 } } ,
1225                 { &hf_mp2t_af_e_ltwv_flag, {
1226                         "LTW Valid Flag", "mp2t.af.e.ltwv_flag",
1227                         FT_UINT16, BASE_DEC, NULL, 0x8000, NULL, HFILL
1228                 } } ,
1229                 { &hf_mp2t_af_e_ltwo, {
1230                         "LTW Offset", "mp2t.af.e.ltwo",
1231                         FT_UINT16, BASE_DEC, NULL, 0x7FFF, NULL, HFILL
1232                 } } ,
1233                 { &hf_mp2t_af_e_pr_reserved, {
1234                         "Reserved", "mp2t.af.e.pr_reserved",
1235                         FT_UINT24, BASE_DEC, NULL, 0xC00000, NULL, HFILL
1236                 } } ,
1237                 { &hf_mp2t_af_e_pr, {
1238                         "Piecewise Rate", "mp2t.af.e.pr",
1239                         FT_UINT24, BASE_DEC, NULL, 0x3FFFFF, NULL, HFILL
1240                 } } ,
1241                 { &hf_mp2t_af_e_st, {
1242                         "Splice Type", "mp2t.af.e.st",
1243                         FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL
1244                 } } ,
1245                 { &hf_mp2t_af_e_dnau_32_30, {
1246                         "DTS Next AU[32...30]", "mp2t.af.e.dnau_32_30",
1247                         FT_UINT8, BASE_DEC, NULL, 0x0E, NULL, HFILL
1248                 } } ,
1249                 { &hf_mp2t_af_e_m_1, {
1250                         "Marker Bit", "mp2t.af.e.m_1",
1251                         FT_UINT8, BASE_DEC, NULL, 0x01, NULL, HFILL
1252                 } } ,
1253                 { &hf_mp2t_af_e_dnau_29_15, {
1254                         "DTS Next AU[29...15]", "mp2t.af.e.dnau_29_15",
1255                         FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL
1256                 } } ,
1257                 { &hf_mp2t_af_e_m_2, {
1258                         "Marker Bit", "mp2t.af.e.m_2",
1259                         FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL
1260                 } } ,
1261                 { &hf_mp2t_af_e_dnau_14_0, {
1262                         "DTS Next AU[14...0]", "mp2t.af.e.dnau_14_0",
1263                         FT_UINT16, BASE_DEC, NULL, 0xFFFE, NULL, HFILL
1264                 } } ,
1265                 { &hf_mp2t_af_e_m_3, {
1266                         "Marker Bit", "mp2t.af.e.m_3",
1267                         FT_UINT16, BASE_DEC, NULL, 0x0001, NULL, HFILL
1268                 } } ,
1269                 { &hf_mp2t_payload, {
1270                         "Payload", "mp2t.payload",
1271                         FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1272                 } } ,
1273                 { &hf_mp2t_malformed_payload, {
1274                         "Malformed Payload", "mp2t.malformed_payload",
1275                         FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL
1276                 } },
1277                 {  &hf_depi_msg_fragments, {
1278                         "Message fragments", "mp2t.depi_msg.fragments",
1279                         FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL
1280                 } },
1281                 {  &hf_depi_msg_fragment, {
1282                         "Message fragment", "mp2t.depi_msg.fragment",
1283                         FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL
1284                 } },
1285                 {  &hf_depi_msg_fragment_overlap, {
1286                         "Message fragment overlap", "mp2t.depi_msg.fragment.overlap",
1287                         FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1288                 } },
1289                 {  &hf_depi_msg_fragment_overlap_conflicts, {
1290                         "Message fragment overlapping with conflicting data",
1291                         "mp2t.depi_msg.fragment.overlap.conflicts",
1292                         FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1293                 } },
1294                 {  &hf_depi_msg_fragment_multiple_tails, {
1295                         "Message has multiple tail fragments",
1296                         "mp2t.depi_msg.fragment.multiple_tails",
1297                         FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1298                 } },
1299                 {  &hf_depi_msg_fragment_too_long_fragment, {
1300                         "Message fragment too long", "mp2t.depi_msg.fragment.too_long_fragment",
1301                         FT_BOOLEAN, BASE_NONE, NULL, 0x00, NULL, HFILL
1302                 } },
1303                 {  &hf_depi_msg_fragment_error, {
1304                         "Message defragmentation error", "mp2t.depi_msg.fragment.error",
1305                         FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL
1306                 } },
1307                 {  &hf_depi_msg_reassembled_in, {
1308                         "Reassembled in", "mp2t.depi_msg.reassembled.in",
1309                         FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL
1310                 } },
1311                 {  &hf_depi_msg_reassembled_length, {
1312                         "Reassembled MP2T length", "mp2t.depi_msg.reassembled.length",
1313                         FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL
1314                 } }
1315         };
1316
1317         static gint *ett[] =
1318         {
1319                 &ett_mp2t,
1320                 &ett_mp2t_header,
1321                 &ett_mp2t_af,
1322                 &ett_mp2t_analysis,
1323                 &ett_dmpt,
1324                 &ett_depi_msg_fragment,
1325                 &ett_depi_msg_fragments
1326         };
1327
1328         proto_mp2t = proto_register_protocol("ISO/IEC 13818-1", "MP2T", "mp2t");
1329         register_dissector("mp2t", dissect_mp2t, proto_mp2t);
1330         proto_register_field_array(proto_mp2t, hf, array_length(hf));
1331         proto_register_subtree_array(ett, array_length(ett));
1332         /* Register processing of fragmented DEPI packets */
1333         fragment_table_init(&mp2t_depi_fragment_table);
1334         reassembled_table_init(&mp2t_depi_reassembled_table);
1335 }
1336
1337
1338
1339 void
1340 proto_reg_handoff_mp2t(void)
1341 {
1342         dissector_handle_t mp2t_handle;
1343
1344         heur_dissector_add("udp", heur_dissect_mp2t, proto_mp2t);
1345
1346         mp2t_handle = create_dissector_handle(dissect_mp2t, proto_mp2t);
1347         dissector_add("rtp.pt", PT_MP2T, mp2t_handle);
1348         dissector_add_handle("udp.port", mp2t_handle);  /* for decode-as */
1349
1350         pes_handle = find_dissector("mpeg-pes");
1351         docsis_handle = find_dissector("docsis");
1352         data_handle = find_dissector("data");
1353 }
1354