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