Wireshark-dev: Re: [Wireshark-dev] wiretap: New MPEG file format
From: "ronnie sahlberg" <ronniesahlberg@xxxxxxxxx>
Date: Fri, 25 Aug 2006 21:51:24 +0000
Hi, Can you add the GPL boilerplate to some of the files that are missing it. Why do you create a mpeg plugin directory? To me it looks like an normal dissector generated by asn2wrs and as such it is not a plugin. am i missing something? On 8/25/06, Shaun Jackman <sjackman@xxxxxxxxx> wrote:
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> * wiretap/Makefile.common (NONGENERATED_C_FILES): Add mpeg.c. (NONGENERATED_HEADER_FILES): Add mpeg.h. * wiretap/file_access.c (open_routines): Add mpeg_open. (dump_open_table): Add mpeg. * wiretap/mpeg.c: New file. * wiretap/mpeg.h: Ditto. * wiretap/wtap.c (encap_table): Add mpeg. * wiretap/wtap.h (WTAP_ENCAP_MPEG, WTAP_FILE_MPEG): New. (WTAP_NUM_ENCAP_TYPES, WTAP_NUM_FILE_TYPES): Increase. diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/wiretap/Makefile.common wireshark-0.99.2/wiretap/Makefile.common --- wireshark-0.99.2.orig/wiretap/Makefile.common 2006-07-17 13:59:56.000000000 -0600 +++ wireshark-0.99.2/wiretap/Makefile.common 2006-08-15 10:48:26.000000000 -0600 @@ -51,6 +51,7 @@ k12.c \ lanalyzer.c \ libpcap.c \ + mpeg.c \ netmon.c \ nettl.c \ network_instruments.c \ @@ -90,6 +91,7 @@ k12.h \ lanalyzer.h \ libpcap.h \ + mpeg.h \ netmon.h \ nettl.h \ network_instruments.h \ diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/wiretap/file_access.c wireshark-0.99.2/wiretap/file_access.c --- wireshark-0.99.2.orig/wiretap/file_access.c 2006-07-17 13:59:54.000000000 -0600 +++ wireshark-0.99.2/wiretap/file_access.c 2006-08-15 14:05:39.000000000 -0600 @@ -72,6 +72,7 @@ #include "k12.h" #include "ber.h" #include "catapult_dct2000.h" +#include "mpeg.h" /* The open_file_* routines should return: * @@ -111,6 +112,7 @@ k12_open, catapult_dct2000_open, ber_open, + mpeg_open, /* Files that don't have magic bytes at a fixed location, * but that instead require a heuristic of some sort to * identify them. This includes the ASCII trace files that @@ -541,6 +543,9 @@ { "Wildpacket Ether/AiroPeek (V9)", "peek9", "*.tpc;*.apc;*.pkt;*.wpz", ".pkt", FALSE, NULL, NULL }, + /* WTAP_FILE_MPEG */ + { "MPEG", "mpeg", "*.mpeg;*.mpg;*.mp3", ".mpeg", FALSE, + NULL, NULL }, }; /* Name that should be somewhat descriptive. */ diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/wiretap/mpeg.c wireshark-0.99.2/wiretap/mpeg.c --- wireshark-0.99.2.orig/wiretap/mpeg.c 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/wiretap/mpeg.c 2006-08-25 12:08:33.000000000 -0600 @@ -0,0 +1,225 @@ +/* MPEG file format decoder for the Wiretap library. + * Written by Shaun Jackman <sjackman@xxxxxxxxx>. + * Copyright 2006 Shaun Jackman + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "wtap-int.h" +#include "buffer.h" +#include "file_wrappers.h" +#include <arpa/inet.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +static size_t mpeg_resync(wtap *wth, int *err, gchar **err_info) +{ + (void)err_info; + off_t offset = file_tell(wth->fh); + size_t count = 0; + int sync = file_getc(wth->fh); + while (sync != EOF) { + if (sync == 0xff && count > 0) { + sync = file_getc(wth->fh); + if (sync != EOF && (sync & 0xe0) == 0xe0) + break; + } else + sync = file_getc(wth->fh); + count++; + } + file_seek(wth->fh, offset, SEEK_SET, err); + return count; +} + +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 int mpeg_read_header(wtap *wth, int *err, gchar **err_info, + struct header *header) +{ + (void)err_info; + errno = WTAP_ERR_CANT_READ; + unsigned h; + int bytes_read = file_read(&h, 1, sizeof h, wth->fh); + if (bytes_read != sizeof h) { + *err = file_error(wth->fh); + if (*err == 0 && bytes_read != 0) + *err = WTAP_ERR_SHORT_READ; + return -1; + } + if (file_seek(wth->fh, -sizeof h, SEEK_CUR, err) == -1) + return -1; + h = ntohl(h); + memcpy(header, &h, sizeof *header); + return bytes_read; +} + +static gboolean +mpeg_read_rec_data(FILE_T fh, guchar *pd, int length, int *err) +{ + int bytes_read; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(pd, 1, length, fh); + + if (bytes_read != length) { + *err = file_error(fh); + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return FALSE; + } + return TRUE; +} + +static struct wtap_nstime now; + +static gboolean mpeg_read(wtap *wth, int *err, gchar **err_info, + long *data_offset) +{ + struct header header; + int bytes_read = mpeg_read_header(wth, err, err_info, &header); + if (bytes_read == -1) + return FALSE; + unsigned packet_size = 0; + unsigned t = 0; + if (header.sync == SYNC) { + int version = versions[header.version]; + int layer = layers[header.layer]; + if (layer >= 0) { + unsigned samples = samples_per_frame[version][layer]; + unsigned bitrate = bitrates[version][layer][header.bitrate] * 1000; + unsigned frequency = frequencies[version][header.frequency]; + unsigned pad = header.padding ? padding[layer] : 0; + if (bitrate > 0 && frequency > 0) { + packet_size = bitrate * samples / frequency / 8 + pad; + t = 1000000000 / frequency * samples; + } + } + } + if (packet_size == 0) { + packet_size = mpeg_resync(wth, err, err_info); + if (packet_size == 0) + return FALSE; + } + *data_offset = wth->data_offset; + + buffer_assure_space(wth->frame_buffer, packet_size); + if (!mpeg_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), + packet_size, err)) + return FALSE; + wth->data_offset += packet_size; + wth->phdr.ts = now; + wth->phdr.caplen = packet_size; + wth->phdr.len = packet_size; + + now.nsecs += t; + if (now.nsecs >= 1000000000) { + now.secs++; + now.nsecs -= 1000000000; + } + return TRUE; +} + +static gboolean +mpeg_seek_read(wtap *wth, long seek_off, + union wtap_pseudo_header *pseudo_header, guchar *pd, int length, + int *err, gchar **err_info) +{ + (void)pseudo_header; (void)err_info; + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) + return FALSE; + return mpeg_read_rec_data(wth->random_fh, pd, length, err); +} + +static void +mpeg_close(wtap *wth) +{ + (void)wth; +} + +int mpeg_open(wtap *wth, int *err, gchar **err_info) +{ + now.secs = time(NULL); + now.nsecs = 0; + + struct header header; + if (mpeg_read_header(wth, err, err_info, &header) == -1) + return -1; + if (header.sync != SYNC) { + off_t offset = file_tell(wth->fh); + if (offset == -1) + return -1; + size_t count = mpeg_resync(wth, err, err_info); + if (count == 0) + return 0; + if (file_seek(wth->fh, count, SEEK_CUR, err) == -1) + return -1; + if (mpeg_read_header(wth, err, err_info, &header) == -1 + || header.sync != SYNC) + return 0; + if (file_seek(wth->fh, offset, SEEK_SET, err)) + return -1; + } + + wth->file_type = WTAP_FILE_MPEG; + wth->file_encap = WTAP_ENCAP_MPEG; + wth->tsprecision = WTAP_FILE_TSPREC_NSEC; + wth->subtype_read = mpeg_read; + wth->subtype_seek_read = mpeg_seek_read; + wth->subtype_close = mpeg_close; + wth->snapshot_length = 0; + return 1; +} diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/wiretap/mpeg.h wireshark-0.99.2/wiretap/mpeg.h --- wireshark-0.99.2.orig/wiretap/mpeg.h 1969-12-31 17:00:00.000000000 -0700 +++ wireshark-0.99.2/wiretap/mpeg.h 2006-08-15 10:47:56.000000000 -0600 @@ -0,0 +1,6 @@ +#ifndef __W_MPEG_H__ +#define __W_MPEG_H__ + +int mpeg_open(wtap *wth, int *err, gchar **err_info); + +#endif diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/wiretap/wtap.c wireshark-0.99.2/wiretap/wtap.c --- wireshark-0.99.2.orig/wiretap/wtap.c 2006-07-17 13:59:55.000000000 -0600 +++ wireshark-0.99.2/wiretap/wtap.c 2006-08-15 14:15:41.000000000 -0600 @@ -360,6 +360,9 @@ /* WTAP_ENCAP_BER */ { "ASN.1 Basic Encoding Rules", "ber" }, + + /* WTAP_ENCAP_MPEG */ + { "MPEG", "mpeg" }, }; /* Name that should be somewhat descriptive. */ diff --unidirectional-new-file -urXX wireshark-0.99.2.orig/wiretap/wtap.h wireshark-0.99.2/wiretap/wtap.h --- wireshark-0.99.2.orig/wiretap/wtap.h 2006-07-17 13:59:55.000000000 -0600 +++ wireshark-0.99.2/wiretap/wtap.h 2006-08-15 13:51:02.000000000 -0600 @@ -181,9 +181,10 @@ #define WTAP_ENCAP_LINUX_LAPD 88 #define WTAP_ENCAP_CATAPULT_DCT2000 89 #define WTAP_ENCAP_BER 90 +#define WTAP_ENCAP_MPEG 91 /* last WTAP_ENCAP_ value + 1 */ -#define WTAP_NUM_ENCAP_TYPES 91 +#define WTAP_NUM_ENCAP_TYPES 92 /* File types that can be read by wiretap. We support writing some many of these file types, too, so we @@ -234,8 +235,9 @@ #define WTAP_FILE_ETHERPEEK_V56 43 #define WTAP_FILE_ETHERPEEK_V7 44 #define WTAP_FILE_AIROPEEK_V9 45 +#define WTAP_FILE_MPEG 46 -#define WTAP_NUM_FILE_TYPES 46 +#define WTAP_NUM_FILE_TYPES 47 /* timestamp precision (currently only these values are supported) */ #define WTAP_FILE_TSPREC_SEC 0
- Follow-Ups:
- Re: [Wireshark-dev] wiretap: New MPEG file format
- From: Shaun Jackman
- Re: [Wireshark-dev] wiretap: New MPEG file format
- References:
- [Wireshark-dev] [PATCH 1/2] wiretap: New MPEG file format
- From: Shaun Jackman
- [Wireshark-dev] [PATCH 1/2] wiretap: New MPEG file format
- Prev by Date: Re: [Wireshark-dev] Patch to packet-eth.c to clarify address ig/lg bits
- Next by Date: Re: [Wireshark-dev] Patch to packet-eth.c to clarify address ig/lg bits
- Previous by thread: [Wireshark-dev] [PATCH 1/2] wiretap: New MPEG file format
- Next by thread: Re: [Wireshark-dev] wiretap: New MPEG file format
- Index(es):