create_dissector_handle -> new_create_dissector_handle
[metze/wireshark/wip.git] / epan / dissectors / packet-mpeg-pat.c
1 /* packet-mpeg-pat.c
2  * Routines for MPEG2 (ISO/ISO 13818-1) Program Associate Table (PAT) dissection
3  * Copyright 2012, Guy Martin <gmsoft@tuxicoman.be>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "config.h"
25
26 #include <epan/packet.h>
27 #include "packet-mpeg-sect.h"
28
29 void proto_register_mpeg_pat(void);
30 void proto_reg_handoff_mpeg_pat(void);
31
32 static int proto_mpeg_pat = -1;
33 static int hf_mpeg_pat_transport_stream_id = -1;
34 static int hf_mpeg_pat_reserved = -1;
35 static int hf_mpeg_pat_version_number = -1;
36 static int hf_mpeg_pat_current_next_indicator = -1;
37 static int hf_mpeg_pat_section_number = -1;
38 static int hf_mpeg_pat_last_section_number = -1;
39
40 static int hf_mpeg_pat_program_number = -1;
41 static int hf_mpeg_pat_program_reserved = -1;
42 static int hf_mpeg_pat_program_map_pid = -1;
43
44
45 static gint ett_mpeg_pat = -1;
46 static gint ett_mpeg_pat_prog = -1;
47
48 #define MPEG_PAT_RESERVED_MASK                    0xC0
49 #define MPEG_PAT_VERSION_NUMBER_MASK              0x3E
50 #define MPEG_PAT_CURRENT_NEXT_INDICATOR_MASK      0x01
51
52 #define MPEG_PAT_PROGRAM_RESERVED_MASK          0xE000
53 #define MPEG_PAT_PROGRAM_MAP_PID_MASK           0x1FFF
54
55 static const true_false_string mpeg_pat_cur_next_vals = {
56
57     "Currently applicable", "Not yet applicable"
58
59 };
60
61 static int
62 dissect_mpeg_pat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
63 {
64     guint offset = 0, length = 0;
65     guint16 prog_num, prog_pid;
66
67     proto_item *ti;
68     proto_tree *mpeg_pat_tree;
69     proto_tree *mpeg_pat_prog_tree;
70
71     /* The TVB should start right after the section_length in the Section packet */
72
73     col_set_str(pinfo->cinfo, COL_INFO, "Program Association Table (PAT)");
74
75     ti = proto_tree_add_item(tree, proto_mpeg_pat, tvb, offset, -1, ENC_NA);
76     mpeg_pat_tree = proto_item_add_subtree(ti, ett_mpeg_pat);
77
78     offset += packet_mpeg_sect_header(tvb, offset, mpeg_pat_tree, &length, NULL);
79     length -= 4;
80
81     proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_transport_stream_id, tvb, offset, 2, ENC_BIG_ENDIAN);
82     offset += 2;
83
84     proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
85     proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_version_number, tvb, offset, 1, ENC_BIG_ENDIAN);
86     proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_current_next_indicator, tvb, offset, 1, ENC_BIG_ENDIAN);
87     offset += 1;
88
89     proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_section_number, tvb, offset, 1, ENC_BIG_ENDIAN);
90     offset += 1;
91
92     proto_tree_add_item(mpeg_pat_tree, hf_mpeg_pat_last_section_number, tvb, offset, 1, ENC_BIG_ENDIAN);
93     offset += 1;
94
95     if (offset >= length)
96         return offset;
97
98
99     /* Parse all the programs */
100     while (offset < length) {
101
102         prog_num = tvb_get_ntohs(tvb, offset);
103         prog_pid = tvb_get_ntohs(tvb, offset + 2) & MPEG_PAT_PROGRAM_MAP_PID_MASK;
104
105         mpeg_pat_prog_tree = proto_tree_add_subtree_format(mpeg_pat_tree, tvb, offset, 4,
106                         ett_mpeg_pat_prog, NULL, "Program 0x%04hx -> PID 0x%04hx", prog_num, prog_pid);
107
108         proto_tree_add_item(mpeg_pat_prog_tree, hf_mpeg_pat_program_number, tvb, offset, 2, ENC_BIG_ENDIAN);
109         offset += 2;
110
111         proto_tree_add_item(mpeg_pat_prog_tree, hf_mpeg_pat_program_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
112         proto_tree_add_item(mpeg_pat_prog_tree, hf_mpeg_pat_program_map_pid, tvb, offset, 2, ENC_BIG_ENDIAN);
113         offset += 2;
114
115     }
116
117     offset += packet_mpeg_sect_crc(tvb, pinfo, mpeg_pat_tree, 0, offset);
118     proto_item_set_len(ti, offset);
119     return tvb_captured_length(tvb);
120 }
121
122
123 void
124 proto_register_mpeg_pat(void)
125 {
126
127     static hf_register_info hf[] = {
128
129         { &hf_mpeg_pat_transport_stream_id, {
130             "Transport Stream ID", "mpeg_pat.tsid",
131             FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL
132         } },
133
134         { &hf_mpeg_pat_reserved, {
135             "Reserved", "mpeg_pat.reserved",
136             FT_UINT8, BASE_HEX, NULL, MPEG_PAT_RESERVED_MASK, NULL, HFILL
137         } },
138
139         { &hf_mpeg_pat_version_number, {
140             "Version Number", "mpeg_pat.version",
141             FT_UINT8, BASE_HEX, NULL, MPEG_PAT_VERSION_NUMBER_MASK, NULL, HFILL
142         } },
143
144         { &hf_mpeg_pat_current_next_indicator, {
145             "Current/Next Indicator", "mpeg_pat.cur_next_ind",
146             FT_BOOLEAN, 8, TFS(&mpeg_pat_cur_next_vals), MPEG_PAT_CURRENT_NEXT_INDICATOR_MASK, NULL, HFILL
147         } },
148
149         { &hf_mpeg_pat_section_number, {
150             "Section Number", "mpeg_pat.sect_num",
151             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
152         } },
153
154         { &hf_mpeg_pat_last_section_number, {
155             "Last Section Number", "mpeg_pat.last_sect_num",
156             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL
157         } },
158
159         { &hf_mpeg_pat_program_number, {
160             "Program Number", "mpeg_pat.prog_num",
161             FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL
162         } },
163
164         { &hf_mpeg_pat_program_reserved, {
165             "Reserved", "mpeg_pat.prog_reserved",
166             FT_UINT16, BASE_HEX, NULL, MPEG_PAT_PROGRAM_RESERVED_MASK, NULL, HFILL
167         } },
168
169         { &hf_mpeg_pat_program_map_pid, {
170             "Program Map PID", "mpeg_pat.prog_map_pid",
171             FT_UINT16, BASE_HEX, NULL, MPEG_PAT_PROGRAM_MAP_PID_MASK, NULL, HFILL
172         } },
173
174     };
175
176     static gint *ett[] = {
177         &ett_mpeg_pat,
178         &ett_mpeg_pat_prog
179     };
180
181     proto_mpeg_pat = proto_register_protocol("MPEG2 Program Association Table", "MPEG PAT", "mpeg_pat");
182
183     proto_register_field_array(proto_mpeg_pat, hf, array_length(hf));
184     proto_register_subtree_array(ett, array_length(ett));
185
186 }
187
188
189 void proto_reg_handoff_mpeg_pat(void)
190 {
191     dissector_handle_t mpeg_pat_handle;
192
193     mpeg_pat_handle = new_create_dissector_handle(dissect_mpeg_pat, proto_mpeg_pat);
194     dissector_add_uint("mpeg_sect.tid", MPEG_PAT_TID, mpeg_pat_handle);
195 }
196
197 /*
198  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
199  *
200  * Local variables:
201  * c-basic-offset: 4
202  * tab-width: 8
203  * indent-tabs-mode: nil
204  * End:
205  *
206  * vi: set shiftwidth=4 tabstop=8 expandtab:
207  * :indentSize=4:tabSize=8:noTabs=true:
208  */