From Shaun J

Dissectors for MPEG streams


svn path=/trunk/; revision=21114
This commit is contained in:
Ronnie Sahlberg 2007-03-22 11:43:07 +00:00
parent 80525da7db
commit d824fb2979
13 changed files with 2611 additions and 0 deletions

View File

@ -203,6 +203,13 @@ EXTRA_DIST = \
mms/mms-exp.cnf \
mms/packet-mms-template.c \
mms/packet-mms-template.h \
mpeg/Makefile \
mpeg/mpeg-audio.asn \
mpeg/mpeg-audio.cnf \
mpeg/mpeg-pes.asn \
mpeg/mpeg-pes.cnf \
mpeg/packet-mpeg-audio-template.c \
mpeg/packet-mpeg-pes-template.c \
nbap/Makefile \
nbap/Makefile.nmake \
nbap/nbap.asn \

16
asn1/mpeg/Makefile Normal file
View File

@ -0,0 +1,16 @@
# $Id$
DISSECTOR_FILES=packet-mpeg-audio.c packet-mpeg-pes.c
all: $(DISSECTOR_FILES)
clean:
rm -f parsetab.py parsetab.pyc $(DISSECTOR_FILES)
copy_files: all
cp $(DISSECTOR_FILES) ../../epan/dissectors
.PHONY: all clean copy_files
packet-%.c: ../../tools/asn2wrs.py %.asn %.cnf packet-%-template.c
python ../../tools/asn2wrs.py -e -p $* -c $*.cnf -s packet-$*-template $*.asn

View File

@ -0,0 +1,12 @@
# Do not modify this file.
# It is created automatically by the ASN.1 to Wireshark dissector compiler
# ./mpeg-audio-exp.cnf
# ../../tools/asn2wrs.py -e -p mpeg-audio -c mpeg-audio.cnf -s packet-mpeg-audio-template mpeg-audio.asn
#.MODULE
MPEG mpeg-audio
#.END
#.TYPE_ATTR
#.END

75
asn1/mpeg/mpeg-audio.asn Normal file
View File

@ -0,0 +1,75 @@
-- ASN description of MPEG Audio
-- Written by Shaun Jackman <sjackman@gmail.com>
-- Copyright 2007 Shaun Jackman
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License.
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)),
must-be-zero INTEGER (0..255),
track INTEGER (0..255),
genre INTEGER {
blues(0), classic-rock(1), country(2), dance(3), disco(4),
funk(5), grunge(6), hip-hop(7), jazz(8), metal(9),
new-age(10), oldies(11), other(12), pop(13), r-and-b(14),
rap(15), reggae(16), rock(17), techno(18), industrial(19),
alternative(20), ska(21), death-metal(22), pranks(23),
soundtrack(24), euro-techno(25), ambient(26), trip-hop(27),
vocal(28), jazz-and-funk(29), fusion(30), trance(31),
classical(32), instrumental(33), acid(34), house(35),
game(36), sound-clip(37), gospel(38), noise(39),
alternative-rock(40), bass(41), soul(42), punk(43), space(44),
meditative(45), instrumental-pop(46), instrumental-rock(47),
ethnic(48), gothic(49), darkwave(50), techno-industrial(51),
electronic(52), pop-folk(53), eurodance(54), dream(55),
southern-rock(56), comedy(57), cult(58), gangsta(59),
top-40(60), christian-rap(61), pop-funk(62), jungle(63),
native-american(64), cabaret(65), new-wave(66),
psychadelic(67), rave(68), showtunes(69), trailer(70),
lo-fi(71), tribal(72), acid-punk(73), acid-jazz(74),
polka(75), retro(76), musical(77), rock-and-roll(78),
hard-rock(79), folk(80), folk-rock(81), national-folk(82),
swing(83), fast-fusion(84), bebob(85), latin(86), revival(87),
celtic(88), bluegrass(89), avantgarde(90), gothic-rock(91),
progressive-rock(92), psychedelic-rock(93),
symphonic-rock(94), slow-rock(95), big-band(96), chorus(97),
easy-listening(98), acoustic(99), humour(100), speech(101),
chanson(102), opera(103), chamber-music(104), sonata(105),
symphony(106), booty-bass(107), primus(108), porn-groove(109),
satire(110), slow-jam(111), club(112), tango(113), samba(114),
folklore(115), ballad(116), power-ballad(117),
rhythmic-soul(118), freestyle(119), duet(120), punk-rock(121),
drum-solo(122), a-cappella(123), euro-house(124),
dance-hall(125)
} (0..255)
}
END

13
asn1/mpeg/mpeg-audio.cnf Normal file
View File

@ -0,0 +1,13 @@
# mpeg-audio.cnf
# mpeg-audio conformation file
#
# $Id$
#.TYPE_ATTR
ID3v1/tag TYPE=FT_STRING
ID3v1/title TYPE=FT_STRING
ID3v1/artist TYPE=FT_STRING
ID3v1/album TYPE=FT_STRING
ID3v1/year TYPE=FT_STRING
ID3v1/comment TYPE=FT_STRING
#.END

View File

@ -0,0 +1,12 @@
# Do not modify this file.
# It is created automatically by the ASN.1 to Wireshark dissector compiler
# ./mpeg-pes-exp.cnf
# ../../tools/asn2wrs.py -e -p mpeg-pes -c mpeg-pes.cnf -s packet-mpeg-pes-template mpeg-pes.asn
#.MODULE
MPEG mpeg-pes
#.END
#.TYPE_ATTR
#.END

135
asn1/mpeg/mpeg-pes.asn Normal file
View File

@ -0,0 +1,135 @@
-- ASN description of MPEG Packetized Elementary Stream (PES)
-- Written by Shaun Jackman <sjackman@gmail.com>
-- Copyright 2007 Shaun Jackman
--
-- This program is free software; you can redistribute it and/or
-- modify it under the terms of the GNU General Public License.
MPEG DEFINITIONS ::= BEGIN
PES ::= SEQUENCE {
prefix OCTET STRING (SIZE (3)),
stream INTEGER {
picture (0),
sequence-header (179),
sequence-header-extension (181),
group-of-pictures (184),
program-end (185),
pack-header (186),
system-header (187),
program-stream-map (188),
private-stream-1 (189),
padding-stream (190),
private-stream-2 (191),
audio-stream (192),
video-stream (224)
} (0..255)
}
Pack ::= SEQUENCE {
must-be-zero BOOLEAN,
must-be-one0 BOOLEAN,
scr30 BIT STRING (SIZE (3)),
must-be-one1 BOOLEAN,
scr15 BIT STRING (SIZE (15)),
must-be-one2 BOOLEAN,
scr0 BIT STRING (SIZE (15)),
must-be-one3 BOOLEAN,
scr-ext BIT STRING (SIZE (9)),
must-be-one4 BOOLEAN,
program-mux-rate BIT STRING (SIZE (22)),
must-be-one5 BOOLEAN,
must-be-one6 BOOLEAN,
reserved BIT STRING (SIZE (5)),
stuffing-length INTEGER (0..7)
}
Stream ::= SEQUENCE {
length INTEGER (0..65535),
must-be-one BOOLEAN,
must-be-zero BOOLEAN,
scrambling-control INTEGER {
not-scrambled (0)
} (0..3),
priority BOOLEAN,
data-alignment BOOLEAN,
copyright BOOLEAN,
original BOOLEAN,
pts-flag BOOLEAN,
dts-flag BOOLEAN,
escr-flag BOOLEAN,
es-rate-flag BOOLEAN,
dsm-trick-mode-flag BOOLEAN,
additional-copy-info-flag BOOLEAN,
crc-flag BOOLEAN,
extension-flag BOOLEAN,
header-data-length INTEGER (0..255)
}
Sequence-header ::= SEQUENCE {
horizontal-size BIT STRING (SIZE (12)),
vertical-size BIT STRING (SIZE (12)),
aspect-ratio INTEGER {
aspect-1to1 (1),
aspect-4to3 (2),
aspect-16to9 (3),
aspect-2-21to1 (4)
} (0..15),
frame-rate ENUMERATED {
reserved (0),
fr (23976),
fr (24000),
fr (25000),
fr (29970),
fr (30000),
fr (50000),
fr (59940),
fr (60000)
},
bit-rate BIT STRING (SIZE (18)),
must-be-one BOOLEAN,
vbv-buffer-size BIT STRING (SIZE (10)),
constrained-parameters-flag BOOLEAN,
load-intra-quantiser-matrix BOOLEAN,
load-non-intra-quantiser-matrix BOOLEAN
}
Sequence-extension ::= SEQUENCE {
must-be-0001 BIT STRING (SIZE (4)),
profile-and-level INTEGER (0..255),
progressive-sequence BOOLEAN,
chroma-format INTEGER (0..3),
horizontal-size-extension INTEGER (0..3),
vertical-size-extension INTEGER (0..3),
bit-rate-extension BIT STRING (SIZE (12)),
must-be-one BOOLEAN,
vbv-buffer-size-extension INTEGER (0..255),
low-delay BOOLEAN,
frame-rate-extension-n INTEGER (0..3),
frame-rate-extension-d INTEGER (0..3)
}
Group-of-pictures ::= SEQUENCE {
drop-frame-flag BOOLEAN,
hour INTEGER (0..32),
minute INTEGER (0..64),
must-be-one BOOLEAN,
second INTEGER (0..64),
frame INTEGER (0..64),
closed-gop BOOLEAN,
broken-gop BOOLEAN,
must-be-zero BIT STRING (SIZE (5))
}
Picture ::= SEQUENCE {
temporal-sequence-number BIT STRING (SIZE (10)),
frame-type INTEGER {
i-frame (1),
p-frame (2),
b-frame (3),
d-frame (4)
} (0..7),
vbv-delay BIT STRING (SIZE (16))
}
END

10
asn1/mpeg/mpeg-pes.cnf Normal file
View File

@ -0,0 +1,10 @@
# mpeg-pes.cnf
# mpeg-pes conformation file
#
# $Id$
#.TYPE_ATTR
PES/stream TYPE=FT_UINT8 DISPLAY=BASE_HEX
Pack/program-mux-rate TYPE=FT_UINT32 DISPLAY=BASE_DEC
Stream/length TYPE=FT_UINT16 DISPLAY=BASE_DEC
#.END

View File

@ -0,0 +1,210 @@
/* MPEG audio packet decoder.
* Written by Shaun Jackman <sjackman@gmail.com>.
* Copyright 2007 Shaun Jackman
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
*
* 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.
*/
#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 <wiretap/mpeg-audio.h>
#include "packet-per.h"
#include "packet-mpeg-audio-hf.c"
#include "packet-mpeg-audio-ett.c"
#include "packet-mpeg-audio-fn.c"
static int hf_mpeg_audio = -1;
static int hf_mpeg_audio_data = -1;
static int hf_mpeg_audio_padbytes = -1;
static int hf_id3v1 = -1;
static int hf_id3v2 = -1;
static size_t
read_header(tvbuff_t *tvb, packet_info *pinfo, struct mpa *mpa)
{
size_t data_size = 0;
guint32 h = tvb_get_ntohl(tvb, 0);
MPA_UNMARSHAL(mpa, h);
if (MPA_SYNC_VALID(mpa)) {
if (MPA_VERSION_VALID(mpa) && MPA_LAYER_VALID(mpa)) {
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[MPA_VERSION(mpa)]);
}
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO,
"Audio Layer %d", MPA_LAYER(mpa) + 1);
if (MPA_BITRATE_VALID(mpa) && MPA_FREQUENCY_VALID(mpa)) {
data_size = MPA_DATA_BYTES(mpa) - sizeof mpa;
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", MPA_BITRATE(mpa) / 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", MPA_FREQUENCY(mpa) / (float)1000);
}
}
} else {
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_add_str(pinfo->cinfo, COL_PROTOCOL, "MPEG");
}
}
return data_size;
}
static gboolean
dissect_mpeg_audio_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
struct mpa mpa;
size_t data_size;
asn1_ctx_t asn1_ctx;
int offset = 0;
data_size = read_header(tvb, pinfo, &mpa);
if (!MPA_SYNC_VALID(&mpa))
return FALSE;
if (tree == NULL)
return TRUE;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
offset = dissect_mpeg_audio_Audio(tvb, offset, &asn1_ctx,
tree, hf_mpeg_audio);
if (data_size > 0) {
unsigned int padding;
proto_tree_add_item(tree, hf_mpeg_audio_data, tvb,
offset / 8, data_size, FALSE);
offset += data_size * 8;
padding = MPA_PADDING(&mpa);
if (padding > 0) {
proto_tree_add_item(tree, hf_mpeg_audio_padbytes, tvb,
offset / 8, padding, FALSE);
offset += padding * 8;
}
}
return TRUE;
}
static void
dissect_id3v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
asn1_ctx_t asn1_ctx;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v1");
if (tree == NULL)
return;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
dissect_mpeg_audio_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 gboolean
dissect_mpeg_audio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int magic;
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);
magic = tvb_get_ntoh24(tvb, 0);
switch (magic) {
case 0x544147: /* TAG */
dissect_id3v1(tvb, pinfo, tree);
return TRUE;
case 0x494433: /* ID3 */
dissect_id3v2(tvb, pinfo, tree);
return TRUE;
default:
return dissect_mpeg_audio_frame(tvb, pinfo, tree);
}
}
static int proto_mpeg_audio = -1;
void
proto_register_mpeg_audio(void)
{
static hf_register_info hf[] = {
#include "packet-mpeg-audio-hfarr.c"
{ &hf_mpeg_audio,
{ "MPEG Audio", "mpeg.audio",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_audio_data,
{ "Data", "mpeg.audio.data",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_audio_padbytes,
{ "Padding", "mpeg.audio.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-audio-ettarr.c"
};
if (proto_mpeg_audio != -1)
return;
proto_mpeg_audio = proto_register_protocol(
"Moving Picture Experts Group Audio", "MPEG Audio", "mpeg.audio");
proto_register_field_array(proto_mpeg_audio, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_mpeg_audio(void)
{
heur_dissector_add("mpeg", dissect_mpeg_audio, proto_mpeg_audio);
}

View File

@ -0,0 +1,295 @@
/* MPEG Packetized Elementary Stream (PES) packet decoder.
* Written by Shaun Jackman <sjackman@gmail.com>.
* Copyright 2007 Shaun Jackman
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
*
* 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.
*/
#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-pes-hf.c"
#include "packet-mpeg-pes-ett.c"
#include "packet-mpeg-pes-fn.c"
static int proto_mpeg = -1;
static int proto_mpeg_pes = -1;
static int hf_mpeg_pes_pack_header = -1;
static int hf_mpeg_pes_stuffing = -1;
static int hf_mpeg_pes_extension = -1;
static int hf_mpeg_pes_header_data = -1;
static int hf_mpeg_pes_padding = -1;
static int hf_mpeg_pes_data = -1;
static int hf_mpeg_video_sequence_header = -1;
static int hf_mpeg_video_sequence_extension = -1;
static int hf_mpeg_video_group_of_pictures = -1;
static int hf_mpeg_video_picture = -1;
static int hf_mpeg_video_quantization_matrix = -1;
static int hf_mpeg_video_data = -1;
enum { PES_PREFIX = 1 };
enum {
STREAM_PICTURE = 0x00,
STREAM_SEQUENCE = 0xb3,
STREAM_SEQUENCE_EXTENSION = 0xb5,
STREAM_GOP = 0xb8,
STREAM_END = 0xb9,
STREAM_PACK = 0xba,
STREAM_SYSTEM = 0xbb,
STREAM_PROGRAM = 0xbc,
STREAM_PRIVATE1 = 0xbd,
STREAM_PADDING = 0xbe,
STREAM_PRIVATE2 = 0xbf,
STREAM_AUDIO = 0xc0,
STREAM_VIDEO = 0xe0,
};
void
dissect_mpeg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static gboolean
dissect_mpeg_pes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int prefix;
int stream;
asn1_ctx_t asn1_ctx;
int offset = 0;
prefix = tvb_get_ntoh24(tvb, 0);
if (prefix != PES_PREFIX)
return FALSE;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "MPEG PES");
stream = tvb_get_guint8(tvb, 3);
if (check_col(pinfo->cinfo, COL_INFO)) {
const char *s = match_strval(stream, mpeg_pes_T_stream_vals);
if (s != NULL)
col_set_str(pinfo->cinfo, COL_INFO, s);
}
#if 0
if (tree == NULL)
return TRUE;
#endif
asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
offset = dissect_mpeg_pes_PES(tvb, offset, &asn1_ctx,
tree, proto_mpeg_pes);
if (stream == STREAM_PICTURE) {
int frame_type;
frame_type = tvb_get_guint8(tvb, 5) >> 3 & 0x07;
if (check_col(pinfo->cinfo, COL_INFO)) {
const char *s = match_strval(frame_type,
mpeg_pes_T_frame_type_vals);
if (s != NULL)
col_set_str(pinfo->cinfo, COL_INFO, s);
}
offset = dissect_mpeg_pes_Picture(tvb, offset, &asn1_ctx,
tree, hf_mpeg_video_picture);
proto_tree_add_item(tree, hf_mpeg_video_data, tvb,
offset / 8, -1, FALSE);
} else if (stream == STREAM_SEQUENCE) {
tvbuff_t *es;
offset = dissect_mpeg_pes_Sequence_header(tvb, offset, &asn1_ctx,
tree, hf_mpeg_video_sequence_header);
proto_tree_add_item(tree, hf_mpeg_video_quantization_matrix, tvb,
offset / 8, 64, FALSE);
offset += 64 * 8;
es = tvb_new_subset(tvb, offset / 8, -1, -1);
dissect_mpeg_pes(es, pinfo, tree);
} else if (stream == STREAM_SEQUENCE_EXTENSION) {
tvbuff_t *es;
offset = dissect_mpeg_pes_Sequence_extension(tvb, offset, &asn1_ctx,
tree, hf_mpeg_video_sequence_extension);
es = tvb_new_subset(tvb, offset / 8, -1, -1);
dissect_mpeg_pes(es, pinfo, tree);
} else if (stream == STREAM_GOP) {
tvbuff_t *es;
offset = dissect_mpeg_pes_Group_of_pictures(tvb, offset, &asn1_ctx,
tree, hf_mpeg_video_group_of_pictures);
es = tvb_new_subset(tvb, offset / 8, -1, -1);
dissect_mpeg_pes(es, pinfo, tree);
} else if (stream == STREAM_PACK) {
int length;
switch (tvb_get_guint8(tvb, 4) >> 6) {
case 1:
length = tvb_get_guint8(tvb, 13) & 0x07;
offset = dissect_mpeg_pes_Pack(tvb, offset, &asn1_ctx,
tree, hf_mpeg_pes_pack_header);
if (length > 0)
proto_tree_add_item(tree, hf_mpeg_pes_stuffing, tvb,
offset / 8, length, FALSE);
break;
default:
length = 8;
proto_tree_add_item(tree, hf_mpeg_pes_data, tvb,
offset / 8, length, FALSE);
}
offset += length * 8;
} else if (stream == STREAM_SYSTEM) {
offset = dissect_mpeg_pes_Stream(tvb, offset, &asn1_ctx,
tree, hf_mpeg_pes_extension);
proto_tree_add_item(tree, hf_mpeg_pes_data, tvb,
offset / 8, -1, FALSE);
} else if (stream == STREAM_PADDING) {
int padding_length;
padding_length = tvb_get_ntohs(tvb, 4);
proto_tree_add_item(tree, hf_mpeg_pes_length, tvb,
offset / 8, 2, FALSE);
offset += 2 * 8;
proto_tree_add_item(tree, hf_mpeg_pes_padding, tvb,
offset / 8, padding_length, FALSE);
} else if (stream == STREAM_PRIVATE1
|| stream >= STREAM_AUDIO) {
int length;
int header_length;
tvbuff_t *es;
length = tvb_get_ntohs(tvb, 4);
offset = dissect_mpeg_pes_Stream(tvb, offset, &asn1_ctx,
tree, hf_mpeg_pes_extension);
length -= 5 * 8;
header_length = tvb_get_guint8(tvb, 8);
if (header_length > 0) {
proto_tree_add_item(tree, hf_mpeg_pes_header_data, tvb,
offset / 8, header_length, FALSE);
offset += header_length * 8;
length -= header_length * 8;
}
es = tvb_new_subset(tvb, offset / 8, -1, length / 8);
if (tvb_get_ntoh24(es, 0) == PES_PREFIX)
dissect_mpeg_pes(es, pinfo, tree);
else if (tvb_get_guint8(es, 0) == 0xff)
dissect_mpeg(es, pinfo, tree);
else
proto_tree_add_item(tree, hf_mpeg_pes_data, es,
0, -1, FALSE);
} else {
proto_tree_add_item(tree, hf_mpeg_pes_data, tvb,
offset / 8, -1, FALSE);
}
return TRUE;
}
static heur_dissector_list_t heur_subdissector_list;
void
dissect_mpeg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree);
}
void
proto_register_mpeg_pes(void)
{
static hf_register_info hf[] = {
#include "packet-mpeg-pes-hfarr.c"
{ &hf_mpeg_pes_pack_header,
{ "Pack header", "mpeg-pes.pack",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_pes_stuffing,
{ "PES stuffing bytes", "mpeg-pes.stuffing",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_pes_extension,
{ "PES extension", "mpeg-pes.extension",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_pes_header_data,
{ "PES header data", "mpeg-pes.header-data",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_pes_padding,
{ "PES padding", "mpeg-pes.padding",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_pes_data,
{ "PES data", "mpeg-pes.data",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_video_sequence_header,
{ "MPEG sequence header", "mpeg-video.sequence",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_video_sequence_extension,
{ "MPEG sequence extension", "mpeg-video.sequence-ext",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_video_group_of_pictures,
{ "MPEG group of pictures", "mpeg-video.gop",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_video_picture,
{ "MPEG picture", "mpeg-video.picture",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_video_quantization_matrix,
{ "MPEG quantization matrix", "mpeg-video.quant",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_video_data,
{ "MPEG picture data", "mpeg-video.data",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
};
static gint *ett[] = {
#include "packet-mpeg-pes-ettarr.c"
};
proto_mpeg = proto_register_protocol(
"Moving Picture Experts Group", "MPEG", "mpeg");
register_heur_dissector_list("mpeg", &heur_subdissector_list);
if (proto_mpeg_pes != -1)
return;
proto_mpeg_pes = proto_register_protocol(
"Packetized Elementary Stream", "MPEG PES", "mpeg-pes");
proto_register_field_array(proto_mpeg_pes, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_mpeg_pes(void)
{
dissector_handle_t mpeg_handle = create_dissector_handle(
dissect_mpeg, proto_mpeg);
dissector_add("wtap_encap", WTAP_ENCAP_MPEG, mpeg_handle);
heur_dissector_add("mpeg", dissect_mpeg_pes, proto_mpeg_pes);
}

View File

@ -463,6 +463,8 @@ DISSECTOR_SRC = \
packet-mount.c \
packet-mp2t.c \
packet-mpeg1.c \
packet-mpeg-audio.c \
packet-mpeg-pes.c \
packet-mpls.c \
packet-mpls-echo.c \
packet-mq.c \

View File

@ -0,0 +1,722 @@
/* Do not modify this file. */
/* It is created automatically by the ASN.1 to Wireshark dissector compiler */
/* ./packet-mpeg-audio.c */
/* ../../tools/asn2wrs.py -e -p mpeg-audio -c mpeg-audio.cnf -s packet-mpeg-audio-template mpeg-audio.asn */
/* Input file: packet-mpeg-audio-template.c */
#line 1 "packet-mpeg-audio-template.c"
/* MPEG audio packet decoder.
* Written by Shaun Jackman <sjackman@gmail.com>.
* Copyright 2007 Shaun Jackman
*
* $Id$
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
*
* 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.
*/
#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 <wiretap/mpeg-audio.h>
#include "packet-per.h"
/*--- Included file: packet-mpeg-audio-hf.c ---*/
#line 1 "packet-mpeg-audio-hf.c"
static int hf_mpeg_audio_sync = -1; /* BIT_STRING_SIZE_11 */
static int hf_mpeg_audio_version = -1; /* T_version */
static int hf_mpeg_audio_layer = -1; /* T_layer */
static int hf_mpeg_audio_protection = -1; /* T_protection */
static int hf_mpeg_audio_bitrate = -1; /* INTEGER_0_15 */
static int hf_mpeg_audio_frequency = -1; /* INTEGER_0_3 */
static int hf_mpeg_audio_padding = -1; /* BOOLEAN */
static int hf_mpeg_audio_private = -1; /* BOOLEAN */
static int hf_mpeg_audio_channel_mode = -1; /* T_channel_mode */
static int hf_mpeg_audio_mode_extension = -1; /* INTEGER_0_3 */
static int hf_mpeg_audio_copyright = -1; /* BOOLEAN */
static int hf_mpeg_audio_original = -1; /* BOOLEAN */
static int hf_mpeg_audio_emphasis = -1; /* T_emphasis */
static int hf_mpeg_audio_tag = -1; /* OCTET_STRING_SIZE_3 */
static int hf_mpeg_audio_title = -1; /* OCTET_STRING_SIZE_30 */
static int hf_mpeg_audio_artist = -1; /* OCTET_STRING_SIZE_30 */
static int hf_mpeg_audio_album = -1; /* OCTET_STRING_SIZE_30 */
static int hf_mpeg_audio_year = -1; /* OCTET_STRING_SIZE_4 */
static int hf_mpeg_audio_comment = -1; /* OCTET_STRING_SIZE_28 */
static int hf_mpeg_audio_must_be_zero = -1; /* INTEGER_0_255 */
static int hf_mpeg_audio_track = -1; /* INTEGER_0_255 */
static int hf_mpeg_audio_genre = -1; /* T_genre */
/*--- End of included file: packet-mpeg-audio-hf.c ---*/
#line 42 "packet-mpeg-audio-template.c"
/*--- Included file: packet-mpeg-audio-ett.c ---*/
#line 1 "packet-mpeg-audio-ett.c"
static gint ett_mpeg_audio_Audio = -1;
static gint ett_mpeg_audio_ID3v1 = -1;
/*--- End of included file: packet-mpeg-audio-ett.c ---*/
#line 43 "packet-mpeg-audio-template.c"
/*--- Included file: packet-mpeg-audio-fn.c ---*/
#line 1 "packet-mpeg-audio-fn.c"
static int
dissect_mpeg_audio_BIT_STRING_SIZE_11(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_bit_string(tvb, offset, actx, tree, hf_index,
11, 11, FALSE, NULL);
return offset;
}
static const value_string mpeg_audio_T_version_vals[] = {
{ 0, "mpeg-2-5" },
{ 1, "reserved" },
{ 2, "mpeg-2" },
{ 3, "mpeg-1" },
{ 0, NULL }
};
static int
dissect_mpeg_audio_T_version(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index,
4, NULL, FALSE, 0, NULL);
return offset;
}
static const value_string mpeg_audio_T_layer_vals[] = {
{ 0, "reserved" },
{ 1, "layer-3" },
{ 2, "layer-2" },
{ 3, "layer-1" },
{ 0, NULL }
};
static int
dissect_mpeg_audio_T_layer(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index,
4, NULL, FALSE, 0, NULL);
return offset;
}
static const value_string mpeg_audio_T_protection_vals[] = {
{ 0, "crc" },
{ 1, "none" },
{ 0, NULL }
};
static int
dissect_mpeg_audio_T_protection(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index,
2, NULL, FALSE, 0, NULL);
return offset;
}
static int
dissect_mpeg_audio_INTEGER_0_15(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
0U, 15U, NULL, FALSE);
return offset;
}
static int
dissect_mpeg_audio_INTEGER_0_3(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
0U, 3U, NULL, FALSE);
return offset;
}
static int
dissect_mpeg_audio_BOOLEAN(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_boolean(tvb, offset, actx, tree, hf_index, NULL);
return offset;
}
static const value_string mpeg_audio_T_channel_mode_vals[] = {
{ 0, "stereo" },
{ 1, "joint-stereo" },
{ 2, "dual-channel" },
{ 3, "single-channel" },
{ 0, NULL }
};
static int
dissect_mpeg_audio_T_channel_mode(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index,
4, NULL, FALSE, 0, NULL);
return offset;
}
static const value_string mpeg_audio_T_emphasis_vals[] = {
{ 0, "none" },
{ 1, "em-50-15-ms" },
{ 2, "reserved" },
{ 3, "ccit-j-17" },
{ 0, NULL }
};
static int
dissect_mpeg_audio_T_emphasis(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_enumerated(tvb, offset, actx, tree, hf_index,
4, NULL, FALSE, 0, NULL);
return offset;
}
static const per_sequence_t Audio_sequence[] = {
{ &hf_mpeg_audio_sync , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BIT_STRING_SIZE_11 },
{ &hf_mpeg_audio_version , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_version },
{ &hf_mpeg_audio_layer , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_layer },
{ &hf_mpeg_audio_protection, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_protection },
{ &hf_mpeg_audio_bitrate , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_15 },
{ &hf_mpeg_audio_frequency, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_3 },
{ &hf_mpeg_audio_padding , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN },
{ &hf_mpeg_audio_private , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN },
{ &hf_mpeg_audio_channel_mode, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_channel_mode },
{ &hf_mpeg_audio_mode_extension, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_3 },
{ &hf_mpeg_audio_copyright, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN },
{ &hf_mpeg_audio_original , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_BOOLEAN },
{ &hf_mpeg_audio_emphasis , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_emphasis },
{ NULL, 0, 0, NULL }
};
static int
dissect_mpeg_audio_Audio(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
ett_mpeg_audio_Audio, Audio_sequence);
return offset;
}
static int
dissect_mpeg_audio_OCTET_STRING_SIZE_3(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
3, 3, NULL);
return offset;
}
static int
dissect_mpeg_audio_OCTET_STRING_SIZE_30(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
30, 30, NULL);
return offset;
}
static int
dissect_mpeg_audio_OCTET_STRING_SIZE_4(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
4, 4, NULL);
return offset;
}
static int
dissect_mpeg_audio_OCTET_STRING_SIZE_28(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_octet_string(tvb, offset, actx, tree, hf_index,
28, 28, NULL);
return offset;
}
static int
dissect_mpeg_audio_INTEGER_0_255(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
0U, 255U, NULL, FALSE);
return offset;
}
static const value_string mpeg_audio_T_genre_vals[] = {
{ 0, "blues" },
{ 1, "classic-rock" },
{ 2, "country" },
{ 3, "dance" },
{ 4, "disco" },
{ 5, "funk" },
{ 6, "grunge" },
{ 7, "hip-hop" },
{ 8, "jazz" },
{ 9, "metal" },
{ 10, "new-age" },
{ 11, "oldies" },
{ 12, "other" },
{ 13, "pop" },
{ 14, "r-and-b" },
{ 15, "rap" },
{ 16, "reggae" },
{ 17, "rock" },
{ 18, "techno" },
{ 19, "industrial" },
{ 20, "alternative" },
{ 21, "ska" },
{ 22, "death-metal" },
{ 23, "pranks" },
{ 24, "soundtrack" },
{ 25, "euro-techno" },
{ 26, "ambient" },
{ 27, "trip-hop" },
{ 28, "vocal" },
{ 29, "jazz-and-funk" },
{ 30, "fusion" },
{ 31, "trance" },
{ 32, "classical" },
{ 33, "instrumental" },
{ 34, "acid" },
{ 35, "house" },
{ 36, "game" },
{ 37, "sound-clip" },
{ 38, "gospel" },
{ 39, "noise" },
{ 40, "alternative-rock" },
{ 41, "bass" },
{ 42, "soul" },
{ 43, "punk" },
{ 44, "space" },
{ 45, "meditative" },
{ 46, "instrumental-pop" },
{ 47, "instrumental-rock" },
{ 48, "ethnic" },
{ 49, "gothic" },
{ 50, "darkwave" },
{ 51, "techno-industrial" },
{ 52, "electronic" },
{ 53, "pop-folk" },
{ 54, "eurodance" },
{ 55, "dream" },
{ 56, "southern-rock" },
{ 57, "comedy" },
{ 58, "cult" },
{ 59, "gangsta" },
{ 60, "top-40" },
{ 61, "christian-rap" },
{ 62, "pop-funk" },
{ 63, "jungle" },
{ 64, "native-american" },
{ 65, "cabaret" },
{ 66, "new-wave" },
{ 67, "psychadelic" },
{ 68, "rave" },
{ 69, "showtunes" },
{ 70, "trailer" },
{ 71, "lo-fi" },
{ 72, "tribal" },
{ 73, "acid-punk" },
{ 74, "acid-jazz" },
{ 75, "polka" },
{ 76, "retro" },
{ 77, "musical" },
{ 78, "rock-and-roll" },
{ 79, "hard-rock" },
{ 80, "folk" },
{ 81, "folk-rock" },
{ 82, "national-folk" },
{ 83, "swing" },
{ 84, "fast-fusion" },
{ 85, "bebob" },
{ 86, "latin" },
{ 87, "revival" },
{ 88, "celtic" },
{ 89, "bluegrass" },
{ 90, "avantgarde" },
{ 91, "gothic-rock" },
{ 92, "progressive-rock" },
{ 93, "psychedelic-rock" },
{ 94, "symphonic-rock" },
{ 95, "slow-rock" },
{ 96, "big-band" },
{ 97, "chorus" },
{ 98, "easy-listening" },
{ 99, "acoustic" },
{ 100, "humour" },
{ 101, "speech" },
{ 102, "chanson" },
{ 103, "opera" },
{ 104, "chamber-music" },
{ 105, "sonata" },
{ 106, "symphony" },
{ 107, "booty-bass" },
{ 108, "primus" },
{ 109, "porn-groove" },
{ 110, "satire" },
{ 111, "slow-jam" },
{ 112, "club" },
{ 113, "tango" },
{ 114, "samba" },
{ 115, "folklore" },
{ 116, "ballad" },
{ 117, "power-ballad" },
{ 118, "rhythmic-soul" },
{ 119, "freestyle" },
{ 120, "duet" },
{ 121, "punk-rock" },
{ 122, "drum-solo" },
{ 123, "a-cappella" },
{ 124, "euro-house" },
{ 125, "dance-hall" },
{ 0, NULL }
};
static int
dissect_mpeg_audio_T_genre(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_constrained_integer(tvb, offset, actx, tree, hf_index,
0U, 255U, NULL, FALSE);
return offset;
}
static const per_sequence_t ID3v1_sequence[] = {
{ &hf_mpeg_audio_tag , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_3 },
{ &hf_mpeg_audio_title , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_30 },
{ &hf_mpeg_audio_artist , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_30 },
{ &hf_mpeg_audio_album , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_30 },
{ &hf_mpeg_audio_year , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_4 },
{ &hf_mpeg_audio_comment , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_OCTET_STRING_SIZE_28 },
{ &hf_mpeg_audio_must_be_zero, ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_255 },
{ &hf_mpeg_audio_track , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_INTEGER_0_255 },
{ &hf_mpeg_audio_genre , ASN1_NO_EXTENSIONS , ASN1_NOT_OPTIONAL, dissect_mpeg_audio_T_genre },
{ NULL, 0, 0, NULL }
};
static int
dissect_mpeg_audio_ID3v1(tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
offset = dissect_per_sequence(tvb, offset, actx, tree, hf_index,
ett_mpeg_audio_ID3v1, ID3v1_sequence);
return offset;
}
/*--- End of included file: packet-mpeg-audio-fn.c ---*/
#line 44 "packet-mpeg-audio-template.c"
static int hf_mpeg_audio = -1;
static int hf_mpeg_audio_data = -1;
static int hf_mpeg_audio_padbytes = -1;
static int hf_id3v1 = -1;
static int hf_id3v2 = -1;
static size_t
read_header(tvbuff_t *tvb, packet_info *pinfo, struct mpa *mpa)
{
size_t data_size = 0;
guint32 h = tvb_get_ntohl(tvb, 0);
MPA_UNMARSHAL(mpa, h);
if (MPA_SYNC_VALID(mpa)) {
if (MPA_VERSION_VALID(mpa) && MPA_LAYER_VALID(mpa)) {
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[MPA_VERSION(mpa)]);
}
if (check_col(pinfo->cinfo, COL_INFO))
col_add_fstr(pinfo->cinfo, COL_INFO,
"Audio Layer %d", MPA_LAYER(mpa) + 1);
if (MPA_BITRATE_VALID(mpa) && MPA_FREQUENCY_VALID(mpa)) {
data_size = MPA_DATA_BYTES(mpa) - sizeof mpa;
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", MPA_BITRATE(mpa) / 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", MPA_FREQUENCY(mpa) / (float)1000);
}
}
} else {
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_add_str(pinfo->cinfo, COL_PROTOCOL, "MPEG");
}
}
return data_size;
}
static gboolean
dissect_mpeg_audio_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
struct mpa mpa;
size_t data_size;
asn1_ctx_t asn1_ctx;
int offset = 0;
data_size = read_header(tvb, pinfo, &mpa);
if (!MPA_SYNC_VALID(&mpa))
return FALSE;
if (tree == NULL)
return TRUE;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
offset = dissect_mpeg_audio_Audio(tvb, offset, &asn1_ctx,
tree, hf_mpeg_audio);
if (data_size > 0) {
unsigned int padding;
proto_tree_add_item(tree, hf_mpeg_audio_data, tvb,
offset / 8, data_size, FALSE);
offset += data_size * 8;
padding = MPA_PADDING(&mpa);
if (padding > 0) {
proto_tree_add_item(tree, hf_mpeg_audio_padbytes, tvb,
offset / 8, padding, FALSE);
offset += padding * 8;
}
}
return TRUE;
}
static void
dissect_id3v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
asn1_ctx_t asn1_ctx;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "ID3v1");
if (tree == NULL)
return;
asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
dissect_mpeg_audio_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 gboolean
dissect_mpeg_audio(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int magic;
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);
magic = tvb_get_ntoh24(tvb, 0);
switch (magic) {
case 0x544147: /* TAG */
dissect_id3v1(tvb, pinfo, tree);
return TRUE;
case 0x494433: /* ID3 */
dissect_id3v2(tvb, pinfo, tree);
return TRUE;
default:
return dissect_mpeg_audio_frame(tvb, pinfo, tree);
}
}
static int proto_mpeg_audio = -1;
void
proto_register_mpeg_audio(void)
{
static hf_register_info hf[] = {
/*--- Included file: packet-mpeg-audio-hfarr.c ---*/
#line 1 "packet-mpeg-audio-hfarr.c"
{ &hf_mpeg_audio_sync,
{ "sync", "mpeg-audio.sync",
FT_BYTES, BASE_HEX, NULL, 0,
"mpeg_audio.BIT_STRING_SIZE_11", HFILL }},
{ &hf_mpeg_audio_version,
{ "version", "mpeg-audio.version",
FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_version_vals), 0,
"mpeg_audio.T_version", HFILL }},
{ &hf_mpeg_audio_layer,
{ "layer", "mpeg-audio.layer",
FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_layer_vals), 0,
"mpeg_audio.T_layer", HFILL }},
{ &hf_mpeg_audio_protection,
{ "protection", "mpeg-audio.protection",
FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_protection_vals), 0,
"mpeg_audio.T_protection", HFILL }},
{ &hf_mpeg_audio_bitrate,
{ "bitrate", "mpeg-audio.bitrate",
FT_UINT32, BASE_DEC, NULL, 0,
"mpeg_audio.INTEGER_0_15", HFILL }},
{ &hf_mpeg_audio_frequency,
{ "frequency", "mpeg-audio.frequency",
FT_UINT32, BASE_DEC, NULL, 0,
"mpeg_audio.INTEGER_0_3", HFILL }},
{ &hf_mpeg_audio_padding,
{ "padding", "mpeg-audio.padding",
FT_BOOLEAN, 8, NULL, 0,
"mpeg_audio.BOOLEAN", HFILL }},
{ &hf_mpeg_audio_private,
{ "private", "mpeg-audio.private",
FT_BOOLEAN, 8, NULL, 0,
"mpeg_audio.BOOLEAN", HFILL }},
{ &hf_mpeg_audio_channel_mode,
{ "channel-mode", "mpeg-audio.channel_mode",
FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_channel_mode_vals), 0,
"mpeg_audio.T_channel_mode", HFILL }},
{ &hf_mpeg_audio_mode_extension,
{ "mode-extension", "mpeg-audio.mode_extension",
FT_UINT32, BASE_DEC, NULL, 0,
"mpeg_audio.INTEGER_0_3", HFILL }},
{ &hf_mpeg_audio_copyright,
{ "copyright", "mpeg-audio.copyright",
FT_BOOLEAN, 8, NULL, 0,
"mpeg_audio.BOOLEAN", HFILL }},
{ &hf_mpeg_audio_original,
{ "original", "mpeg-audio.original",
FT_BOOLEAN, 8, NULL, 0,
"mpeg_audio.BOOLEAN", HFILL }},
{ &hf_mpeg_audio_emphasis,
{ "emphasis", "mpeg-audio.emphasis",
FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_emphasis_vals), 0,
"mpeg_audio.T_emphasis", HFILL }},
{ &hf_mpeg_audio_tag,
{ "tag", "mpeg-audio.tag",
FT_STRING, BASE_HEX, NULL, 0,
"mpeg_audio.OCTET_STRING_SIZE_3", HFILL }},
{ &hf_mpeg_audio_title,
{ "title", "mpeg-audio.title",
FT_STRING, BASE_HEX, NULL, 0,
"mpeg_audio.OCTET_STRING_SIZE_30", HFILL }},
{ &hf_mpeg_audio_artist,
{ "artist", "mpeg-audio.artist",
FT_STRING, BASE_HEX, NULL, 0,
"mpeg_audio.OCTET_STRING_SIZE_30", HFILL }},
{ &hf_mpeg_audio_album,
{ "album", "mpeg-audio.album",
FT_STRING, BASE_HEX, NULL, 0,
"mpeg_audio.OCTET_STRING_SIZE_30", HFILL }},
{ &hf_mpeg_audio_year,
{ "year", "mpeg-audio.year",
FT_STRING, BASE_HEX, NULL, 0,
"mpeg_audio.OCTET_STRING_SIZE_4", HFILL }},
{ &hf_mpeg_audio_comment,
{ "comment", "mpeg-audio.comment",
FT_STRING, BASE_HEX, NULL, 0,
"mpeg_audio.OCTET_STRING_SIZE_28", HFILL }},
{ &hf_mpeg_audio_must_be_zero,
{ "must-be-zero", "mpeg-audio.must_be_zero",
FT_UINT32, BASE_DEC, NULL, 0,
"mpeg_audio.INTEGER_0_255", HFILL }},
{ &hf_mpeg_audio_track,
{ "track", "mpeg-audio.track",
FT_UINT32, BASE_DEC, NULL, 0,
"mpeg_audio.INTEGER_0_255", HFILL }},
{ &hf_mpeg_audio_genre,
{ "genre", "mpeg-audio.genre",
FT_UINT32, BASE_DEC, VALS(mpeg_audio_T_genre_vals), 0,
"mpeg_audio.T_genre", HFILL }},
/*--- End of included file: packet-mpeg-audio-hfarr.c ---*/
#line 175 "packet-mpeg-audio-template.c"
{ &hf_mpeg_audio,
{ "MPEG Audio", "mpeg.audio",
FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_audio_data,
{ "Data", "mpeg.audio.data",
FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
{ &hf_mpeg_audio_padbytes,
{ "Padding", "mpeg.audio.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[] = {
/*--- Included file: packet-mpeg-audio-ettarr.c ---*/
#line 1 "packet-mpeg-audio-ettarr.c"
&ett_mpeg_audio_Audio,
&ett_mpeg_audio_ID3v1,
/*--- End of included file: packet-mpeg-audio-ettarr.c ---*/
#line 195 "packet-mpeg-audio-template.c"
};
if (proto_mpeg_audio != -1)
return;
proto_mpeg_audio = proto_register_protocol(
"Moving Picture Experts Group Audio", "MPEG Audio", "mpeg.audio");
proto_register_field_array(proto_mpeg_audio, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
}
void
proto_reg_handoff_mpeg_audio(void)
{
heur_dissector_add("mpeg", dissect_mpeg_audio, proto_mpeg_audio);
}

File diff suppressed because it is too large Load Diff