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