Wireshark-dev: [Wireshark-dev] [PATCH 2/2] plugins: New MPEG dissector
From: "Shaun Jackman" <sjackman@xxxxxxxxx>
Date: Fri, 25 Aug 2006 14:45:33 -0600
I've created an MPEG stream decoder for Wireshark. It's useful for decoding streaming audio. It currently supports MPEG-1, MPEG-2, MPEG-2.5 audio, layers 1, 2, 3. To test out the protocol decoder, the first half of the patch adds a wiretap file format to allow opening your favourite MPEG audio file (mp3 for example). The second half of the patch adds the protocol decoder. This patch is generated against wireshark 0.99.2. Cheers, Shaun Signed-off-by: Shaun Jackman <sjackman@xxxxxxxxx> 2006-08-25 Shaun Jackman <sjackman@xxxxxxxxx> * asn1/mpeg/Makefile: New file. * asn1/mpeg/mpeg.asn: Ditto. * asn1/mpeg/packet-mpeg-template.c: Ditto. * configure.in (AC_OUTPUT): Add plugins/mpeg/Makefile. * plugins/Makefile.am (SUBDIRS): Add mpeg. * plugins/Makefile.in: Regenerate. * plugins/mpeg/Makefile.am: New file. * plugins/mpeg/Makefile.in: Regenerate. * plugins/mpeg/Makefile.common: Ditto. * plugins/mpeg/moduleinfo.h: Ditto. * plugins/mpeg/packet-mpeg.c: Regenerate. diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/asn1/mpeg/Makefile wireshark-0.99.2/asn1/mpeg/Makefile --- wireshark-0.99.2.orig/asn1/mpeg/Makefile 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/asn1/mpeg/Makefile 2006-08-15 15:58:43.000000000 -0600 @@ -0,0 +1,14 @@ +DISSECTOR_FILES=packet-mpeg.c packet-mpeg.h + +all: generate_dissector + +generate_dissector: $(DISSECTOR_FILES) + +$(DISSECTOR_FILES): ../../tools/asn2wrs.py mpeg.asn packet-mpeg-template.c + python ../../tools/asn2wrs.py -e -p mpeg -s packet-mpeg-template mpeg.asn + +clean: + rm -f parsetab.py parsetab.pyc $(DISSECTOR_FILES) + +copy_files: generate_dissector + cp $(DISSECTOR_FILES) ../../epan/dissectors diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/asn1/mpeg/mpeg.asn wireshark-0.99.2/asn1/mpeg/mpeg.asn --- wireshark-0.99.2.orig/asn1/mpeg/mpeg.asn 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/asn1/mpeg/mpeg.asn 2006-08-24 17:09:03.000000000 -0600 @@ -0,0 +1,35 @@ +MPEG DEFINITIONS ::= BEGIN + +Audio ::= SEQUENCE { + sync BIT STRING (SIZE (11)), + version ENUMERATED + { mpeg-2-5(0), reserved(1), mpeg-2(2), mpeg-1(3) }, + layer ENUMERATED + { reserved(0), layer-3(1), layer-2(2), layer-1(3) }, + protection ENUMERATED { crc(0), none(1) }, + bitrate INTEGER (0..15), + frequency INTEGER (0..3), + padding BOOLEAN, + private BOOLEAN, + channel-mode ENUMERATED + { stereo(0), joint-stereo(1), dual-channel(2), single-channel(3) }, + mode-extension INTEGER (0..3), + copyright BOOLEAN, + original BOOLEAN, + emphasis ENUMERATED + { none(0), em-50-15-ms(1), reserved(2), ccit-j-17(3) } +} + +ID3v1 ::= SEQUENCE { + tag OCTET STRING (SIZE (3)), + title OCTET STRING (SIZE (30)), + artist OCTET STRING (SIZE (30)), + album OCTET STRING (SIZE (30)), + year OCTET STRING (SIZE (4)), + comment OCTET STRING (SIZE (28)), + zero INTEGER (0..255), + track INTEGER (0..255), + genre INTEGER (0..255) +} + +END diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/asn1/mpeg/packet-mpeg-template.c wireshark-0.99.2/asn1/mpeg/packet-mpeg-template.c --- wireshark-0.99.2.orig/asn1/mpeg/packet-mpeg-template.c 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/asn1/mpeg/packet-mpeg-template.c 2006-08-24 17:23:57.000000000 -0600 @@ -0,0 +1,235 @@ +/* MPEG packet decoder. + * Written by Shaun Jackman <sjackman@xxxxxxxxx>. + * Copyright 2006 Shaun Jackman. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <string.h> + +#include <glib.h> + +#include <epan/packet.h> +#include <epan/prefs.h> + +#include "packet-per.h" + +#include "packet-mpeg-hf.c" +#include "packet-mpeg-ett.c" +#include "packet-mpeg-fn.c" + +static int hf_mpeg_audio = -1; +static int hf_mpeg_data = -1; +static int hf_mpeg_padbytes = -1; +static int hf_id3v1 = -1; +static int hf_id3v2 = -1; + +struct header { + unsigned emphasis :2; + unsigned original :1; + unsigned copyright :1; + unsigned mode_ext :2; + unsigned mode :2; + unsigned private :1; + unsigned padding :1; + unsigned frequency :2; + unsigned bitrate :4; + unsigned protection :1; + unsigned layer :2; + unsigned version :2; + unsigned sync :11; +}; + +enum { SYNC = 0x7ff }; +static const int versions[4] = { 2, -1, 1, 0 }; +static const int layers[4] = { -1, 2, 1, 0 }; + +static const unsigned samples_per_frame[3][3] = { + { 384, 1152, 1152 }, + { 384, 1152, 576 }, + { 384, 1152, 576 }, +}; + +static const unsigned bitrates[3][3][16] = { /* kb/s */ + { + { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, + { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }, + }, + { + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + }, + { + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + }, +}; + +static const unsigned frequencies[3][4] = { + { 44100, 48000, 32000 }, + { 22050, 24000, 16000 }, + { 11025, 12000, 8000 }, +}; +static const unsigned padding[3] = { 4, 1, 1 }; + +static size_t +read_header(tvbuff_t *tvb, packet_info *pinfo, struct header *header) +{ + size_t data_size = 0; + uint32_t h = tvb_get_ntohl(tvb, 0); + memcpy(header, &h, sizeof *header); + if (header->sync == SYNC) { + int version = versions[header->version]; + int layer = layers[header->layer]; + if (version >= 0 && layer >= 0) { + unsigned bitrate = bitrates[version][layer][header->bitrate] * 1000; + unsigned frequency = frequencies[version][header->frequency]; + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { + static const char *version_names[] = { "1", "2", "2.5" }; + col_add_fstr(pinfo->cinfo, COL_PROTOCOL, + "MPEG-%s", version_names[version]); + } + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Audio Layer %d", layer+1); + if (bitrate > 0 && frequency > 0) { + unsigned samples = samples_per_frame[version][layer]; + data_size = bitrate * samples / frequency / 8 - sizeof header; + if (check_col(pinfo->cinfo, COL_DEF_SRC)) { + SET_ADDRESS(&pinfo->src, AT_NONE, 0, NULL); + col_add_fstr(pinfo->cinfo, COL_DEF_SRC, + "%d kb/s", bitrate / 1000); + } + if (check_col(pinfo->cinfo, COL_DEF_DST)) { + SET_ADDRESS(&pinfo->dst, AT_NONE, 0, NULL); + col_add_fstr(pinfo->cinfo, COL_DEF_DST, + "%g kHz", frequency / (float)1000); + } + } + } else { + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_add_str(pinfo->cinfo, COL_PROTOCOL, "MPEG"); + } + } + return data_size; +} + +static void +dissect_mpa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + struct header header; + size_t data_size = read_header(tvb, pinfo, &header); + if (tree == NULL) + return; + + if (header.sync != SYNC) + return; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); + int offset = 0; + offset = dissect_mpeg_Audio(tvb, offset, &asn1_ctx, + tree, hf_mpeg_audio); + if (data_size > 0) { + proto_tree_add_item(tree, hf_mpeg_data, tvb, + offset / 8, data_size, FALSE); + offset += data_size * 8; + if (header.padding) + proto_tree_add_item(tree, hf_mpeg_padbytes, tvb, + offset / 8, 1, FALSE); + } +} + +static void +dissect_id3v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v1"); + if (tree == NULL) + return; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); + dissect_mpeg_ID3v1(tvb, 0, &asn1_ctx, + tree, hf_id3v1); +} + +static void +dissect_id3v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v2"); + proto_tree_add_item(tree, hf_id3v2, tvb, + 0, -1, FALSE); +} + +static void +dissect_mpeg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_clear(pinfo->cinfo, COL_PROTOCOL); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + int magic = tvb_get_ntoh24(tvb, 0); + switch (magic) { + case 0x544147: + dissect_id3v1(tvb, pinfo, tree); + break; + case 0x494433: + dissect_id3v2(tvb, pinfo, tree); + break; + default: + dissect_mpa(tvb, pinfo, tree); + } +} + +static int proto_mpeg = -1; + +void +proto_register_mpeg(void) +{ + static hf_register_info hf[] = { +#include "packet-mpeg-hfarr.c" + { &hf_mpeg_audio, + { "MPEG Audio", "mpeg.audio", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_data, + { "Data", "mpeg.data", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_padbytes, + { "Padding", "mpeg.padbytes", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + + { &hf_id3v1, + { "ID3v1", "id3v1", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_id3v2, + { "ID3v2", "id3v2", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + }; + + static gint *ett[] = { +#include "packet-mpeg-ettarr.c" + }; + + if (proto_mpeg != -1) + return; + + proto_mpeg = proto_register_protocol( + "Moving Picture Experts Group", "MPEG", "mpeg"); + proto_register_field_array(proto_mpeg, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_mpeg(void) +{ + dissector_handle_t mpeg_handle = create_dissector_handle( + dissect_mpeg, proto_mpeg); + dissector_add("wtap_encap", WTAP_ENCAP_MPEG, mpeg_handle); +} diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/configure.in wireshark-0.99.2/configure.in --- wireshark-0.99.2.orig/configure.in 2006-07-17 14:00:03.000000000 -0600 +++ wireshark-0.99.2/configure.in 2006-08-25 13:14:12.000000000 -0600 @@ -1350,6 +1350,7 @@ plugins/mate/Makefile plugins/megaco/Makefile plugins/mgcp/Makefile + plugins/mpeg/Makefile plugins/opsi/Makefile plugins/pcli/Makefile plugins/profinet/Makefile diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/Makefile.am wireshark-0.99.2/plugins/Makefile.am --- wireshark-0.99.2.orig/plugins/Makefile.am 2006-07-17 13:57:16.000000000 -0600 +++ wireshark-0.99.2/plugins/Makefile.am 2006-08-15 16:00:45.000000000 -0600 @@ -45,6 +45,7 @@ mate \ megaco \ mgcp \ + mpeg \ opsi \ pcli \ profinet \ diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/mpeg/Makefile.am wireshark-0.99.2/plugins/mpeg/Makefile.am --- wireshark-0.99.2.orig/plugins/mpeg/Makefile.am 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/plugins/mpeg/Makefile.am 2006-08-15 16:14:12.000000000 -0600 @@ -0,0 +1,118 @@ +# Makefile.am +# Automake file for MPEG plugin +# +# $Id: Makefile.am 18312 2006-06-02 06:53:30Z jmayer $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@xxxxxxxxxxxxx> +# 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. +# + +INCLUDES = -I$(top_srcdir) -I$(includedir) -I$(top_srcdir)/epan/dissectors + +include Makefile.common + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = mpeg.la +mpeg_la_SOURCES = \ + plugin.c \ + moduleinfo.h \ + $(DISSECTOR_SRC) \ + $(DISSECTOR_INCLUDES) +mpeg_la_LDFLAGS = -module -avoid-version +mpeg_la_LIBADD = @PLUGIN_LIBS@ + +# Libs must be cleared, or else libtool won't create a shared module. +# If your module needs to be linked against any particular libraries, +# add them here. +LIBS = + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \ + $(top_srcdir)/tools/make-dissector-reg.py + @if test -n $(PYTHON); then \ + echo Making plugin.c with python ; \ + $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + plugin $(DISSECTOR_SRC) ; \ + else \ + echo Making plugin.c with shell script ; \ + $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + $(plugin_src) plugin $(DISSECTOR_SRC) ; \ + fi + +# +# Currently plugin.c can be included in the distribution because +# we always build all protocol dissectors. We used to have to check +# whether or not to build the snmp dissector. If we again need to +# variably build something, making plugin.c non-portable, uncomment +# the dist-hook line below. +# +# Oh, yuk. We don't want to include "plugin.c" in the distribution, as +# its contents depend on the configuration, and therefore we want it +# to be built when the first "make" is done; however, Automake insists +# on putting *all* source into the distribution. +# +# We work around this by having a "dist-hook" rule that deletes +# "plugin.c", so that "dist" won't pick it up. +# +#dist-hook: +# @rm -f $(distdir)/plugin.c + +CLEANFILES = \ + mpeg \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in \ + plugin.c + +EXTRA_DIST = \ + Makefile.common \ + Makefile.nmake diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/mpeg/Makefile.common wireshark-0.99.2/plugins/mpeg/Makefile.common --- wireshark-0.99.2.orig/plugins/mpeg/Makefile.common 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/plugins/mpeg/Makefile.common 2006-08-15 16:03:34.000000000 -0600 @@ -0,0 +1,31 @@ +# Makefile.common for MPEG plugin +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id: Makefile.common 18197 2006-05-21 05:12:17Z sahlberg $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@xxxxxxxxxxxxx> +# 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. + +# the name of the plugin +PLUGIN_NAME = mpeg + +# the dissector sources (without any helpers) +DISSECTOR_SRC = \ + packet-mpeg.c diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/mpeg/moduleinfo.h wireshark-0.99.2/plugins/mpeg/moduleinfo.h --- wireshark-0.99.2.orig/plugins/mpeg/moduleinfo.h 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/plugins/mpeg/moduleinfo.h 2006-08-15 16:04:48.000000000 -0600 @@ -0,0 +1,16 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "mpeg" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.1.0"
[PATCH 2/2] plugins: New MPEG dissector Signed-off-by: Shaun Jackman <sjackman@xxxxxxxxx> 2006-08-25 Shaun Jackman <sjackman@xxxxxxxxx> * asn1/mpeg/Makefile: New file. * asn1/mpeg/mpeg.asn: Ditto. * asn1/mpeg/packet-mpeg-template.c: Ditto. * configure.in (AC_OUTPUT): Add plugins/mpeg/Makefile. * plugins/Makefile.am (SUBDIRS): Add mpeg. * plugins/Makefile.in: Regenerate. * plugins/mpeg/Makefile.am: New file. * plugins/mpeg/Makefile.in: Regenerate. * plugins/mpeg/Makefile.common: Ditto. * plugins/mpeg/moduleinfo.h: Ditto. * plugins/mpeg/packet-mpeg.c: Regenerate. diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/asn1/mpeg/Makefile wireshark-0.99.2/asn1/mpeg/Makefile --- wireshark-0.99.2.orig/asn1/mpeg/Makefile 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/asn1/mpeg/Makefile 2006-08-15 15:58:43.000000000 -0600 @@ -0,0 +1,14 @@ +DISSECTOR_FILES=packet-mpeg.c packet-mpeg.h + +all: generate_dissector + +generate_dissector: $(DISSECTOR_FILES) + +$(DISSECTOR_FILES): ../../tools/asn2wrs.py mpeg.asn packet-mpeg-template.c + python ../../tools/asn2wrs.py -e -p mpeg -s packet-mpeg-template mpeg.asn + +clean: + rm -f parsetab.py parsetab.pyc $(DISSECTOR_FILES) + +copy_files: generate_dissector + cp $(DISSECTOR_FILES) ../../epan/dissectors diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/asn1/mpeg/mpeg.asn wireshark-0.99.2/asn1/mpeg/mpeg.asn --- wireshark-0.99.2.orig/asn1/mpeg/mpeg.asn 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/asn1/mpeg/mpeg.asn 2006-08-24 17:09:03.000000000 -0600 @@ -0,0 +1,35 @@ +MPEG DEFINITIONS ::= BEGIN + +Audio ::= SEQUENCE { + sync BIT STRING (SIZE (11)), + version ENUMERATED + { mpeg-2-5(0), reserved(1), mpeg-2(2), mpeg-1(3) }, + layer ENUMERATED + { reserved(0), layer-3(1), layer-2(2), layer-1(3) }, + protection ENUMERATED { crc(0), none(1) }, + bitrate INTEGER (0..15), + frequency INTEGER (0..3), + padding BOOLEAN, + private BOOLEAN, + channel-mode ENUMERATED + { stereo(0), joint-stereo(1), dual-channel(2), single-channel(3) }, + mode-extension INTEGER (0..3), + copyright BOOLEAN, + original BOOLEAN, + emphasis ENUMERATED + { none(0), em-50-15-ms(1), reserved(2), ccit-j-17(3) } +} + +ID3v1 ::= SEQUENCE { + tag OCTET STRING (SIZE (3)), + title OCTET STRING (SIZE (30)), + artist OCTET STRING (SIZE (30)), + album OCTET STRING (SIZE (30)), + year OCTET STRING (SIZE (4)), + comment OCTET STRING (SIZE (28)), + zero INTEGER (0..255), + track INTEGER (0..255), + genre INTEGER (0..255) +} + +END diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/asn1/mpeg/packet-mpeg-template.c wireshark-0.99.2/asn1/mpeg/packet-mpeg-template.c --- wireshark-0.99.2.orig/asn1/mpeg/packet-mpeg-template.c 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/asn1/mpeg/packet-mpeg-template.c 2006-08-24 17:23:57.000000000 -0600 @@ -0,0 +1,235 @@ +/* MPEG packet decoder. + * Written by Shaun Jackman <sjackman@xxxxxxxxx>. + * Copyright 2006 Shaun Jackman. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <stdio.h> +#include <string.h> + +#include <glib.h> + +#include <epan/packet.h> +#include <epan/prefs.h> + +#include "packet-per.h" + +#include "packet-mpeg-hf.c" +#include "packet-mpeg-ett.c" +#include "packet-mpeg-fn.c" + +static int hf_mpeg_audio = -1; +static int hf_mpeg_data = -1; +static int hf_mpeg_padbytes = -1; +static int hf_id3v1 = -1; +static int hf_id3v2 = -1; + +struct header { + unsigned emphasis :2; + unsigned original :1; + unsigned copyright :1; + unsigned mode_ext :2; + unsigned mode :2; + unsigned private :1; + unsigned padding :1; + unsigned frequency :2; + unsigned bitrate :4; + unsigned protection :1; + unsigned layer :2; + unsigned version :2; + unsigned sync :11; +}; + +enum { SYNC = 0x7ff }; +static const int versions[4] = { 2, -1, 1, 0 }; +static const int layers[4] = { -1, 2, 1, 0 }; + +static const unsigned samples_per_frame[3][3] = { + { 384, 1152, 1152 }, + { 384, 1152, 576 }, + { 384, 1152, 576 }, +}; + +static const unsigned bitrates[3][3][16] = { /* kb/s */ + { + { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 }, + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 }, + { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 }, + }, + { + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + }, + { + { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160 }, + }, +}; + +static const unsigned frequencies[3][4] = { + { 44100, 48000, 32000 }, + { 22050, 24000, 16000 }, + { 11025, 12000, 8000 }, +}; +static const unsigned padding[3] = { 4, 1, 1 }; + +static size_t +read_header(tvbuff_t *tvb, packet_info *pinfo, struct header *header) +{ + size_t data_size = 0; + uint32_t h = tvb_get_ntohl(tvb, 0); + memcpy(header, &h, sizeof *header); + if (header->sync == SYNC) { + int version = versions[header->version]; + int layer = layers[header->layer]; + if (version >= 0 && layer >= 0) { + unsigned bitrate = bitrates[version][layer][header->bitrate] * 1000; + unsigned frequency = frequencies[version][header->frequency]; + if (check_col(pinfo->cinfo, COL_PROTOCOL)) { + static const char *version_names[] = { "1", "2", "2.5" }; + col_add_fstr(pinfo->cinfo, COL_PROTOCOL, + "MPEG-%s", version_names[version]); + } + if (check_col(pinfo->cinfo, COL_INFO)) + col_add_fstr(pinfo->cinfo, COL_INFO, + "Audio Layer %d", layer+1); + if (bitrate > 0 && frequency > 0) { + unsigned samples = samples_per_frame[version][layer]; + data_size = bitrate * samples / frequency / 8 - sizeof header; + if (check_col(pinfo->cinfo, COL_DEF_SRC)) { + SET_ADDRESS(&pinfo->src, AT_NONE, 0, NULL); + col_add_fstr(pinfo->cinfo, COL_DEF_SRC, + "%d kb/s", bitrate / 1000); + } + if (check_col(pinfo->cinfo, COL_DEF_DST)) { + SET_ADDRESS(&pinfo->dst, AT_NONE, 0, NULL); + col_add_fstr(pinfo->cinfo, COL_DEF_DST, + "%g kHz", frequency / (float)1000); + } + } + } else { + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_add_str(pinfo->cinfo, COL_PROTOCOL, "MPEG"); + } + } + return data_size; +} + +static void +dissect_mpa(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + struct header header; + size_t data_size = read_header(tvb, pinfo, &header); + if (tree == NULL) + return; + + if (header.sync != SYNC) + return; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); + int offset = 0; + offset = dissect_mpeg_Audio(tvb, offset, &asn1_ctx, + tree, hf_mpeg_audio); + if (data_size > 0) { + proto_tree_add_item(tree, hf_mpeg_data, tvb, + offset / 8, data_size, FALSE); + offset += data_size * 8; + if (header.padding) + proto_tree_add_item(tree, hf_mpeg_padbytes, tvb, + offset / 8, 1, FALSE); + } +} + +static void +dissect_id3v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v1"); + if (tree == NULL) + return; + asn1_ctx_t asn1_ctx; + asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); + dissect_mpeg_ID3v1(tvb, 0, &asn1_ctx, + tree, hf_id3v1); +} + +static void +dissect_id3v2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v2"); + proto_tree_add_item(tree, hf_id3v2, tvb, + 0, -1, FALSE); +} + +static void +dissect_mpeg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_clear(pinfo->cinfo, COL_PROTOCOL); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + int magic = tvb_get_ntoh24(tvb, 0); + switch (magic) { + case 0x544147: + dissect_id3v1(tvb, pinfo, tree); + break; + case 0x494433: + dissect_id3v2(tvb, pinfo, tree); + break; + default: + dissect_mpa(tvb, pinfo, tree); + } +} + +static int proto_mpeg = -1; + +void +proto_register_mpeg(void) +{ + static hf_register_info hf[] = { +#include "packet-mpeg-hfarr.c" + { &hf_mpeg_audio, + { "MPEG Audio", "mpeg.audio", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_data, + { "Data", "mpeg.data", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_mpeg_padbytes, + { "Padding", "mpeg.padbytes", + FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }}, + + { &hf_id3v1, + { "ID3v1", "id3v1", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + { &hf_id3v2, + { "ID3v2", "id3v2", + FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }}, + }; + + static gint *ett[] = { +#include "packet-mpeg-ettarr.c" + }; + + if (proto_mpeg != -1) + return; + + proto_mpeg = proto_register_protocol( + "Moving Picture Experts Group", "MPEG", "mpeg"); + proto_register_field_array(proto_mpeg, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); +} + +void +proto_reg_handoff_mpeg(void) +{ + dissector_handle_t mpeg_handle = create_dissector_handle( + dissect_mpeg, proto_mpeg); + dissector_add("wtap_encap", WTAP_ENCAP_MPEG, mpeg_handle); +} diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/configure.in wireshark-0.99.2/configure.in --- wireshark-0.99.2.orig/configure.in 2006-07-17 14:00:03.000000000 -0600 +++ wireshark-0.99.2/configure.in 2006-08-25 13:14:12.000000000 -0600 @@ -1350,6 +1350,7 @@ plugins/mate/Makefile plugins/megaco/Makefile plugins/mgcp/Makefile + plugins/mpeg/Makefile plugins/opsi/Makefile plugins/pcli/Makefile plugins/profinet/Makefile diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/Makefile.am wireshark-0.99.2/plugins/Makefile.am --- wireshark-0.99.2.orig/plugins/Makefile.am 2006-07-17 13:57:16.000000000 -0600 +++ wireshark-0.99.2/plugins/Makefile.am 2006-08-15 16:00:45.000000000 -0600 @@ -45,6 +45,7 @@ mate \ megaco \ mgcp \ + mpeg \ opsi \ pcli \ profinet \ diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/mpeg/Makefile.am wireshark-0.99.2/plugins/mpeg/Makefile.am --- wireshark-0.99.2.orig/plugins/mpeg/Makefile.am 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/plugins/mpeg/Makefile.am 2006-08-15 16:14:12.000000000 -0600 @@ -0,0 +1,118 @@ +# Makefile.am +# Automake file for MPEG plugin +# +# $Id: Makefile.am 18312 2006-06-02 06:53:30Z jmayer $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@xxxxxxxxxxxxx> +# 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. +# + +INCLUDES = -I$(top_srcdir) -I$(includedir) -I$(top_srcdir)/epan/dissectors + +include Makefile.common + +plugindir = @plugindir@ + +plugin_LTLIBRARIES = mpeg.la +mpeg_la_SOURCES = \ + plugin.c \ + moduleinfo.h \ + $(DISSECTOR_SRC) \ + $(DISSECTOR_INCLUDES) +mpeg_la_LDFLAGS = -module -avoid-version +mpeg_la_LIBADD = @PLUGIN_LIBS@ + +# Libs must be cleared, or else libtool won't create a shared module. +# If your module needs to be linked against any particular libraries, +# add them here. +LIBS = + +# +# Build plugin.c, which contains the plugin version[] string, a +# function plugin_register() that calls the register routines for all +# protocols, and a function plugin_reg_handoff() that calls the handoff +# registration routines for all protocols. +# +# We do this by scanning sources. If that turns out to be too slow, +# maybe we could just require every .o file to have an register routine +# of a given name (packet-aarp.o -> proto_register_aarp, etc.). +# +# Formatting conventions: The name of the proto_register_* routines an +# proto_reg_handoff_* routines must start in column zero, or must be +# preceded only by "void " starting in column zero, and must not be +# inside #if. +# +# DISSECTOR_SRC is assumed to have all the files that need to be scanned. +# +# For some unknown reason, having a big "for" loop in the Makefile +# to scan all the files doesn't work with some "make"s; they seem to +# pass only the first few names in the list to the shell, for some +# reason. +# +# Therefore, we have a script to generate the plugin.c file. +# The shell script runs slowly, as multiple greps and seds are run +# for each input file; this is especially slow on Windows. Therefore, +# if Python is present (as indicated by PYTHON being defined), we run +# a faster Python script to do that work instead. +# +# The first argument is the directory in which the source files live. +# The second argument is "plugin", to indicate that we should build +# a plugin.c file for a plugin. +# All subsequent arguments are the files to scan. +# +plugin.c: $(DISSECTOR_SRC) $(top_srcdir)/tools/make-dissector-reg \ + $(top_srcdir)/tools/make-dissector-reg.py + @if test -n $(PYTHON); then \ + echo Making plugin.c with python ; \ + $(PYTHON) $(top_srcdir)/tools/make-dissector-reg.py $(srcdir) \ + plugin $(DISSECTOR_SRC) ; \ + else \ + echo Making plugin.c with shell script ; \ + $(top_srcdir)/tools/make-dissector-reg $(srcdir) \ + $(plugin_src) plugin $(DISSECTOR_SRC) ; \ + fi + +# +# Currently plugin.c can be included in the distribution because +# we always build all protocol dissectors. We used to have to check +# whether or not to build the snmp dissector. If we again need to +# variably build something, making plugin.c non-portable, uncomment +# the dist-hook line below. +# +# Oh, yuk. We don't want to include "plugin.c" in the distribution, as +# its contents depend on the configuration, and therefore we want it +# to be built when the first "make" is done; however, Automake insists +# on putting *all* source into the distribution. +# +# We work around this by having a "dist-hook" rule that deletes +# "plugin.c", so that "dist" won't pick it up. +# +#dist-hook: +# @rm -f $(distdir)/plugin.c + +CLEANFILES = \ + mpeg \ + *~ + +MAINTAINERCLEANFILES = \ + Makefile.in \ + plugin.c + +EXTRA_DIST = \ + Makefile.common \ + Makefile.nmake diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/mpeg/Makefile.common wireshark-0.99.2/plugins/mpeg/Makefile.common --- wireshark-0.99.2.orig/plugins/mpeg/Makefile.common 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/plugins/mpeg/Makefile.common 2006-08-15 16:03:34.000000000 -0600 @@ -0,0 +1,31 @@ +# Makefile.common for MPEG plugin +# Contains the stuff from Makefile.am and Makefile.nmake that is +# a) common to both files and +# b) portable between both files +# +# $Id: Makefile.common 18197 2006-05-21 05:12:17Z sahlberg $ +# +# Wireshark - Network traffic analyzer +# By Gerald Combs <gerald@xxxxxxxxxxxxx> +# 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. + +# the name of the plugin +PLUGIN_NAME = mpeg + +# the dissector sources (without any helpers) +DISSECTOR_SRC = \ + packet-mpeg.c diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/plugins/mpeg/moduleinfo.h wireshark-0.99.2/plugins/mpeg/moduleinfo.h --- wireshark-0.99.2.orig/plugins/mpeg/moduleinfo.h 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/plugins/mpeg/moduleinfo.h 2006-08-15 16:04:48.000000000 -0600 @@ -0,0 +1,16 @@ +/* Included *after* config.h, in order to re-define these macros */ + +#ifdef PACKAGE +#undef PACKAGE +#endif + +/* Name of package */ +#define PACKAGE "mpeg" + + +#ifdef VERSION +#undef VERSION +#endif + +/* Version number of package */ +#define VERSION "0.1.0"
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH 2/2] plugins: New MPEG dissector
- From: Mike Duigou
- Re: [Wireshark-dev] [PATCH 2/2] plugins: New MPEG dissector
- From: Guy Harris
- Re: [Wireshark-dev] [PATCH 2/2] plugins: New MPEG dissector
- Prev by Date: [Wireshark-dev] [PATCH 1/2] wiretap: New MPEG file format
- Next by Date: Re: [Wireshark-dev] Missing include
- Previous by thread: Re: [Wireshark-dev] wiretap: New MPEG file format
- Next by thread: Re: [Wireshark-dev] [PATCH 2/2] plugins: New MPEG dissector
- Index(es):