diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-06-14 09:25:25 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-06-14 09:25:25 +0000 |
commit | 278d0dcf9058a68e463f3ebaaa364cc847c3d713 (patch) | |
tree | 93d5f6b5646383acd2eb086122bc70723b32548c /packet-mpeg1.c | |
parent | 899df7ef83162fded6163da6874b8627b025c50f (diff) | |
download | wireshark-278d0dcf9058a68e463f3ebaaa364cc847c3d713.tar.gz wireshark-278d0dcf9058a68e463f3ebaaa364cc847c3d713.tar.bz2 wireshark-278d0dcf9058a68e463f3ebaaa364cc847c3d713.zip |
RFC 2250 MPEG1 support, from Francisco Javier Cabello.
svn path=/trunk/; revision=3544
Diffstat (limited to 'packet-mpeg1.c')
-rw-r--r-- | packet-mpeg1.c | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/packet-mpeg1.c b/packet-mpeg1.c new file mode 100644 index 0000000000..e9cf500bd0 --- /dev/null +++ b/packet-mpeg1.c @@ -0,0 +1,395 @@ +/* packet-mpeg1.c + * + * Routines for RFC 2250 MPEG-1 dissection + * + * $Id: packet-mpeg1.c,v 1.1 2001/06/14 09:25:23 guy Exp $ + * + * Copyright 2001, + * Francisco Javier Cabello Torres, <fjcabello@vtools.es> + * + * Ethereal - Network traffic analyzer + * By Gerald Combs <gerald@ethereal.com> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * This dissector tries to dissect the MPEG-1 video streams. + * + * This dissector is called by the RTP dissector + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <glib.h> +#include "packet.h" + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif + +#include <stdio.h> +#include <string.h> + +#define RTP_MPG_MBZ(word) ( word >> 11) +#define RTP_MPG_T(word) ( (word >> 10) & 1 ) +#define RTP_MPG_TR(word) ( word & 0x3ff ) + +#define RTP_MPG_AN(octet) ( octet >> 7) +#define RTP_MPG_N(octet) ( (octet >> 6) & 1 ) +#define RTP_MPG_S(octet) ( (octet >> 5) & 1 ) +#define RTP_MPG_B(octet) ( (octet >> 4) & 1 ) +#define RTP_MPG_E(octet) ( (octet >> 3) & 1 ) +#define RTP_MPG_P(octet) ( octet & 7 ) + +#define RTP_MPG_FBV(octet) ( (octet >> 7) & 1 ) +#define RTP_MPG_BFC(octet) ( (octet >> 4) & 7 ) +#define RTP_MPG_FFV(octet) ( (octet >> 3) & 1 ) +#define RTP_MPG_FFC(octet) ( octet & 7 ) + + +/* MPEG1 header fields */ + + +static int proto_mpg = -1; + +static int hf_rtp_mpg_mbz = -1; +static int hf_rtp_mpg_T = -1; +static int hf_rtp_mpg_tr = -1; +static int hf_rtp_mpg_an = -1; +static int hf_rtp_mpg_n = -1; +static int hf_rtp_mpg_s = -1; +static int hf_rtp_mpg_b = -1; +static int hf_rtp_mpg_e = -1; +static int hf_rtp_mpg_p = -1; + + +static int hf_rtp_mpg_fbv = -1; +static int hf_rtp_mpg_bfc = -1; +static int hf_rtp_mpg_ffv = -1; +static int hf_rtp_mpg_ffc = -1; +static int hf_rtp_mpg_data = -1; + + + +/* MPEG-1 fields defining a sub tree */ +static gint ett_mpg = -1; + +static const value_string rtp_mpg_picture_types_vals[] = +{ + { 0, "Forbidden" }, + { 1, "I-Picture" }, + { 2, "P-Picture" }, + { 3, "B-Picture" }, + { 4, "D-Picture" }, + { 5, "reserved" }, + { 6, "reserved" }, + { 7, "reserved" }, + { 0, NULL }, +}; + +static void +dissect_mpeg1( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) +{ + proto_item *ti = NULL; + proto_tree *mpg_tree = NULL; + unsigned int offset = 0; + + guint8 octet; + guint16 word; + + + guint16 mpg_mbz; + guint16 mpg_T; + guint16 mpg_tr; + guint16 mpg_an; + guint16 mpg_n; + gboolean mpg_s; + gboolean mpg_b; + gboolean mpg_e; + guint16 mpg_p; + guint16 mpg_fbv; + guint16 mpg_bfc; + guint16 mpg_ffv; + guint16 mpg_ffc; + + if ( check_col( pinfo->fd, COL_PROTOCOL ) ) + { + col_set_str( pinfo->fd, COL_PROTOCOL, "MPEG-1" ); + } + + if ( check_col( pinfo->fd, COL_INFO) ) + { + col_set_str( pinfo->fd, COL_INFO, "MPEG-1 message"); + } + + /* Get MPEG-1 fields */ + + word = tvb_get_guint8( tvb, offset ); + word = (word << 8) | tvb_get_guint8( tvb, offset +1 ); + mpg_mbz = RTP_MPG_MBZ(word); + mpg_T = RTP_MPG_T(word); + mpg_tr = RTP_MPG_TR(word); + + octet = tvb_get_guint8( tvb, offset + 2 ); + mpg_an = RTP_MPG_AN(octet); + mpg_n = RTP_MPG_N(octet); + mpg_s = RTP_MPG_S(octet); + mpg_b = RTP_MPG_B(octet); + mpg_e = RTP_MPG_E(octet); + mpg_p = RTP_MPG_P(octet); + + octet = tvb_get_guint8( tvb, offset + 3 ); + + mpg_fbv = RTP_MPG_FBV(octet); + mpg_bfc = RTP_MPG_BFC(octet); + mpg_ffv = RTP_MPG_FFV(octet); + mpg_ffc = RTP_MPG_FFC(octet); + + + if ( tree ) + { + ti = proto_tree_add_item( tree, proto_mpg, tvb, offset, tvb_length( tvb ), FALSE ); + mpg_tree = proto_item_add_subtree( ti, ett_mpg ); + + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_mbz, tvb, offset, 1, mpg_mbz ); + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_T , tvb, offset, 1, mpg_T ); + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_tr , tvb, offset, 2, mpg_tr ); + offset += 2; + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_an, tvb, offset, 1, mpg_an ); + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_n , tvb, offset, 1, mpg_n ); + proto_tree_add_boolean( mpg_tree, hf_rtp_mpg_s , tvb, offset, 1, mpg_s ); + proto_tree_add_boolean( mpg_tree, hf_rtp_mpg_b , tvb, offset, 1, mpg_b ); + proto_tree_add_boolean( mpg_tree, hf_rtp_mpg_e , tvb, offset, 1, mpg_e ); + + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_p, tvb , offset, 1, mpg_p ); + offset += 1; + + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_fbv, tvb, offset, 1, mpg_fbv ); + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_bfc, tvb, offset, 1, mpg_bfc ); + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_ffv, tvb, offset, 1, mpg_ffv ); + proto_tree_add_uint( mpg_tree, hf_rtp_mpg_ffc, tvb, offset, 1, mpg_ffc ); + offset += 1; + + /* The rest of the packet is the MPEG-1 stream */ + proto_tree_add_bytes( mpg_tree, hf_rtp_mpg_data, tvb, offset, tvb_length_remaining( tvb, offset ), tvb_get_ptr( tvb, offset, tvb_length_remaining( tvb, offset ) ) ); + + } +} + +void +proto_register_mpeg1(void) +{ + static hf_register_info hf[] = + { + { + &hf_rtp_mpg_mbz, + { + "MBZ", + "rtp.payload_mpeg_mbz", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + { + &hf_rtp_mpg_T, + { + "T", + "rtp.payload_mpeg_T", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + { + &hf_rtp_mpg_tr, + { + "Temporal Reference", + "rtp.payload_mpeg_tr", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + { + &hf_rtp_mpg_an, + { + "AN", + "rtp.payload_mpeg_an", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_n, + { + "New Picture Header", + "rtp.payload_mpeg_n", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_s, + { + "Sequence Header", + "rtp.payload_mpeg_s", + FT_BOOLEAN, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_b, + { + "Beginning-of-slice", + "rtp.payload_mpeg_b", + FT_BOOLEAN, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_e, + { + "End-of-slice", + "rtp.payload_mpeg_an", + FT_BOOLEAN, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_p, + { + "Picture type", + "rtp.payload_mpeg_p", + FT_UINT16, + BASE_DEC, + VALS(rtp_mpg_picture_types_vals), + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_fbv, + { + "FBV", + "rtp.payload_mpeg_fbv", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_bfc, + { + "BFC", + "rtp.payload_mpeg_bfc", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + { + &hf_rtp_mpg_ffv, + { + "FFV", + "rtp.payload_mpeg_ffv", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + + { + &hf_rtp_mpg_ffc, + { + "FFC", + "rtp.payload_mpeg_ffc", + FT_UINT16, + BASE_DEC, + NULL, + 0x0, + "" + } + }, + { + &hf_rtp_mpg_data, + { + "MPEG-1 stream", + "mpeg1.stream", + FT_BYTES, + BASE_NONE, + NULL, + 0x0, + "" + } + }, + + }; + + static gint *ett[] = + { + &ett_mpg, + }; + + + proto_mpg = proto_register_protocol("RFC 2250 MPEG1","MPEG1","mpeg1"); + proto_register_field_array(proto_mpg, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + register_dissector("mpeg1", dissect_mpeg1, proto_mpg); +} |