smb2-dissector: learn the "REPLAY_OPERATION" flag
[obnox/wireshark/wip.git] / epan / dissectors / packet-mpeg1.c
1 /* packet-mpeg1.c
2  *
3  * Routines for RFC 2250 MPEG-1 dissection
4  *
5  * $Id$
6  *
7  * Copyright 2001,
8  * Francisco Javier Cabello Torres, <fjcabello@vtools.es>
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 /*
30  * This dissector tries to dissect the MPEG-1 video streams.
31  */
32
33
34 #ifdef HAVE_CONFIG_H
35 # include "config.h"
36 #endif
37
38 #include <glib.h>
39 #include <epan/packet.h>
40
41 #include <epan/rtp_pt.h>
42
43 #define RTP_MPG_MBZ(word) ( word >> 11)
44 #define RTP_MPG_T(word)   ( (word >> 10) & 1 )
45 #define RTP_MPG_TR(word)   ( word & 0x3ff )
46
47 #define RTP_MPG_AN(octet) ( octet >> 7)
48 #define RTP_MPG_N(octet)  ( (octet >> 6) & 1 )
49 #define RTP_MPG_S(octet)  ( (octet >> 5) & 1 )
50 #define RTP_MPG_B(octet)  ( (octet >> 4) & 1 )
51 #define RTP_MPG_E(octet)  ( (octet >> 3) & 1 )
52 #define RTP_MPG_P(octet)  ( octet & 7 )
53
54 #define RTP_MPG_FBV(octet) ( (octet >> 7) & 1 )
55 #define RTP_MPG_BFC(octet) ( (octet >> 4) & 7 )
56 #define RTP_MPG_FFV(octet) ( (octet >> 3) & 1 )
57 #define RTP_MPG_FFC(octet) (  octet & 7 )
58
59
60 /* MPEG1 header fields             */
61
62
63 static int proto_mpg          = -1;
64
65 static int hf_rtp_mpg_mbz     = -1;
66 static int hf_rtp_mpg_T       = -1;
67 static int hf_rtp_mpg_tr      = -1;
68 static int hf_rtp_mpg_an      = -1;
69 static int hf_rtp_mpg_n       = -1;
70 static int hf_rtp_mpg_s       = -1;
71 static int hf_rtp_mpg_b       = -1;
72 static int hf_rtp_mpg_e       = -1;
73 static int hf_rtp_mpg_p       = -1;
74
75
76 static int hf_rtp_mpg_fbv     = -1;
77 static int hf_rtp_mpg_bfc     = -1;
78 static int hf_rtp_mpg_ffv     = -1;
79 static int hf_rtp_mpg_ffc     = -1;
80 static int hf_rtp_mpg_data    = -1;
81
82
83
84 /* MPEG-1 fields defining a sub tree */
85 static gint ett_mpg           = -1;
86
87 static const value_string rtp_mpg_picture_types_vals[] =
88 {
89         { 0, "Forbidden" },
90         { 1, "I-Picture" },
91         { 2, "P-Picture" },
92         { 3, "B-Picture" },
93         { 4, "D-Picture" },
94         { 5, "reserved" },
95         { 6, "reserved" },
96         { 7, "reserved" },
97         { 0, NULL },
98 };
99
100 static void
101 dissect_mpeg1( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
102 {
103         proto_item *ti            = NULL;
104         proto_tree *mpg_tree     = NULL;
105         unsigned int offset       = 0;
106
107         guint8      octet;
108         guint16     word;
109
110
111         guint16     mpg_mbz;
112         guint16     mpg_T;
113         guint16     mpg_tr;
114         guint16     mpg_an;
115         guint16     mpg_n;
116         gboolean    mpg_s;
117         gboolean    mpg_b;
118         gboolean    mpg_e;
119         guint16     mpg_p;
120         guint16     mpg_fbv;
121         guint16     mpg_bfc;
122         guint16     mpg_ffv;
123         guint16     mpg_ffc;
124
125         col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG-1");
126
127         col_set_str(pinfo->cinfo, COL_INFO, "MPEG-1 message");
128
129         /* Get MPEG-1  fields */
130
131         word  =   tvb_get_guint8( tvb, offset  );
132         word  = (word << 8) | tvb_get_guint8( tvb, offset +1 );
133         mpg_mbz = RTP_MPG_MBZ(word);
134         mpg_T   = RTP_MPG_T(word);
135         mpg_tr  = RTP_MPG_TR(word);
136
137         octet = tvb_get_guint8( tvb, offset + 2 );
138         mpg_an  = RTP_MPG_AN(octet);
139         mpg_n   = RTP_MPG_N(octet);
140         mpg_s   = RTP_MPG_S(octet);
141         mpg_b   = RTP_MPG_B(octet);
142         mpg_e   = RTP_MPG_E(octet);
143         mpg_p   = RTP_MPG_P(octet);
144
145         octet = tvb_get_guint8( tvb, offset + 3 );
146
147         mpg_fbv   = RTP_MPG_FBV(octet);
148         mpg_bfc   = RTP_MPG_BFC(octet);
149         mpg_ffv   = RTP_MPG_FFV(octet);
150         mpg_ffc   = RTP_MPG_FFC(octet);
151
152
153         if ( tree )
154           {
155             ti = proto_tree_add_item( tree, proto_mpg, tvb, offset, -1, ENC_NA );
156             mpg_tree = proto_item_add_subtree( ti, ett_mpg );
157
158             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_mbz, tvb, offset, 1, mpg_mbz );
159             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_T  , tvb, offset, 1, mpg_T );
160             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_tr , tvb, offset, 2, mpg_tr );
161             offset += 2;
162             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_an, tvb, offset, 1, mpg_an );
163             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_n , tvb, offset, 1, mpg_n );
164             proto_tree_add_boolean( mpg_tree, hf_rtp_mpg_s , tvb, offset, 1, mpg_s );
165             proto_tree_add_boolean( mpg_tree, hf_rtp_mpg_b , tvb, offset, 1, mpg_b );
166             proto_tree_add_boolean( mpg_tree, hf_rtp_mpg_e , tvb, offset, 1, mpg_e );
167
168             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_p, tvb , offset, 1, mpg_p );
169             offset += 1;
170
171             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_fbv, tvb, offset, 1, mpg_fbv );
172             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_bfc, tvb, offset, 1, mpg_bfc );
173             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_ffv, tvb, offset, 1, mpg_ffv );
174             proto_tree_add_uint( mpg_tree, hf_rtp_mpg_ffc, tvb, offset, 1, mpg_ffc );
175             offset += 1;
176
177             /* The rest of the packet is the MPEG-1 stream */
178             proto_tree_add_item( mpg_tree, hf_rtp_mpg_data, tvb, offset, -1, ENC_NA );
179
180           }
181 }
182
183 void
184 proto_register_mpeg1(void)
185 {
186         static hf_register_info hf[] =
187         {
188                 {
189                         &hf_rtp_mpg_mbz,
190                         {
191                                 "MBZ",
192                                 "rtp.payload_mpeg_mbz",
193                                 FT_UINT16,
194                                 BASE_DEC,
195                                 NULL,
196                                 0x0,
197                                 NULL, HFILL
198                         }
199                 },
200                 {
201                         &hf_rtp_mpg_T,
202                         {
203                                 "T",
204                                 "rtp.payload_mpeg_T",
205                                 FT_UINT16,
206                                 BASE_DEC,
207                                 NULL,
208                                 0x0,
209                                 NULL, HFILL
210                         }
211                 },
212                 {
213                         &hf_rtp_mpg_tr,
214                         {
215                                 "Temporal Reference",
216                                 "rtp.payload_mpeg_tr",
217                                 FT_UINT16,
218                                 BASE_DEC,
219                                 NULL,
220                                 0x0,
221                                 NULL, HFILL
222                         }
223                 },
224                 {
225                         &hf_rtp_mpg_an,
226                         {
227                                 "AN",
228                                 "rtp.payload_mpeg_an",
229                                 FT_UINT16,
230                                 BASE_DEC,
231                                 NULL,
232                                 0x0,
233                                 NULL, HFILL
234                         }
235                 },
236
237                 {
238                         &hf_rtp_mpg_n,
239                         {
240                                 "New Picture Header",
241                                 "rtp.payload_mpeg_n",
242                                 FT_UINT16,
243                                 BASE_DEC,
244                                 NULL,
245                                 0x0,
246                                 NULL, HFILL
247                         }
248                 },
249
250                 {
251                         &hf_rtp_mpg_s,
252                         {
253                                 "Sequence Header",
254                                 "rtp.payload_mpeg_s",
255                                 FT_BOOLEAN,
256                                 BASE_NONE,
257                                 NULL,
258                                 0x0,
259                                 NULL, HFILL
260                         }
261                 },
262
263                 {
264                         &hf_rtp_mpg_b,
265                         {
266                                 "Beginning-of-slice",
267                                 "rtp.payload_mpeg_b",
268                                 FT_BOOLEAN,
269                                 BASE_NONE,
270                                 NULL,
271                                 0x0,
272                                 NULL, HFILL
273                         }
274                 },
275
276                 {
277                         &hf_rtp_mpg_e,
278                         {
279                                 "End-of-slice",
280                                 "rtp.payload_mpeg_an",
281                                 FT_BOOLEAN,
282                                 BASE_NONE,
283                                 NULL,
284                                 0x0,
285                                 NULL, HFILL
286                         }
287                 },
288
289                 {
290                         &hf_rtp_mpg_p,
291                         {
292                                 "Picture type",
293                                 "rtp.payload_mpeg_p",
294                                 FT_UINT16,
295                                 BASE_DEC,
296                                 VALS(rtp_mpg_picture_types_vals),
297                                 0x0,
298                                 NULL, HFILL
299                         }
300                 },
301
302                 {
303                         &hf_rtp_mpg_fbv,
304                         {
305                                 "FBV",
306                                 "rtp.payload_mpeg_fbv",
307                                 FT_UINT16,
308                                 BASE_DEC,
309                                 NULL,
310                                 0x0,
311                                 NULL, HFILL
312                         }
313                 },
314
315                 {
316                         &hf_rtp_mpg_bfc,
317                         {
318                                 "BFC",
319                                 "rtp.payload_mpeg_bfc",
320                                 FT_UINT16,
321                                 BASE_DEC,
322                                 NULL,
323                                 0x0,
324                                 NULL, HFILL
325                         }
326                 },
327                 {
328                         &hf_rtp_mpg_ffv,
329                         {
330                                 "FFV",
331                                 "rtp.payload_mpeg_ffv",
332                                 FT_UINT16,
333                                 BASE_DEC,
334                                 NULL,
335                                 0x0,
336                                 NULL, HFILL
337                         }
338                 },
339
340                 {
341                         &hf_rtp_mpg_ffc,
342                         {
343                                 "FFC",
344                                 "rtp.payload_mpeg_ffc",
345                                 FT_UINT16,
346                                 BASE_DEC,
347                                 NULL,
348                                 0x0,
349                                 NULL, HFILL
350                         }
351                 },
352                 {
353                         &hf_rtp_mpg_data,
354                         {
355                                 "MPEG-1 stream",
356                                 "mpeg1.stream",
357                                 FT_BYTES,
358                                 BASE_NONE,
359                                 NULL,
360                                 0x0,
361                                 NULL, HFILL
362                         }
363                 },
364
365         };
366
367         static gint *ett[] =
368         {
369                 &ett_mpg,
370         };
371
372
373         proto_mpg = proto_register_protocol("RFC 2250 MPEG1","MPEG1","mpeg1");
374         proto_register_field_array(proto_mpg, hf, array_length(hf));
375         proto_register_subtree_array(ett, array_length(ett));
376 }
377
378 void
379 proto_reg_handoff_mpeg1(void)
380 {
381         dissector_handle_t mpeg1_handle;
382
383         mpeg1_handle = create_dissector_handle(dissect_mpeg1, proto_mpg);
384         dissector_add_uint("rtp.pt", PT_MPV, mpeg1_handle);
385 }