Wireshark-dev: Re: [Wireshark-dev] asn1: New MPEG dissector
From: "Shaun Jackman" <sjackman@xxxxxxxxx>
Date: Fri, 25 Aug 2006 22:13:44 -0600
This patch is against svn 19041. It fixes two of the three comments below.

Cheers,
Shaun

On 8/25/06, ronnie sahlberg <ronniesahlberg@xxxxxxxxx> wrote:
Can you change the wiretap reader file to
1, add a GPL banner

Done.

in the wiretap files
1, dont read sizeof unsigned  bytes
unsigned may differ between platforms and compilers    hardcode the
exact number of bytes to read instead

Done.

2, dont read straight into a bitfield struct.
c does not define the packing order or padding of fields in a bitfield
and this would be nonportable.
please change to read into an array of char and then add code to
manually unmarshall it into the fields of the bitfield

Not yet done.

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
Index: wiretap/file_access.c
===================================================================
--- wiretap/file_access.c	(revision 19041)
+++ wiretap/file_access.c	(working copy)
@@ -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. */
Index: wiretap/mpeg.c
===================================================================
--- wiretap/mpeg.c	(revision 0)
+++ wiretap/mpeg.c	(revision 0)
@@ -0,0 +1,229 @@
+/* MPEG file format decoder for the Wiretap library.
+ * Written by Shaun Jackman <sjackman@xxxxxxxxx>.
+ * Copyright 2006 Shaun Jackman
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ */
+
+#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 <stdint.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;
+	uint32_t 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;
+}
Index: wiretap/mpeg.h
===================================================================
--- wiretap/mpeg.h	(revision 0)
+++ wiretap/mpeg.h	(revision 0)
@@ -0,0 +1,6 @@
+#ifndef __W_MPEG_H__
+#define __W_MPEG_H__
+
+int mpeg_open(wtap *wth, int *err, gchar **err_info);
+
+#endif
Index: wiretap/wtap.c
===================================================================
--- wiretap/wtap.c	(revision 19041)
+++ wiretap/wtap.c	(working copy)
@@ -363,6 +363,9 @@
 
 	/* WTAP_ENCAP_JUNIPER_VP */
 	{ "Juniper Voice PIC", "juniper-vp" },
+
+	/* WTAP_ENCAP_MPEG */
+	{ "MPEG", "mpeg" },
 };
 
 /* Name that should be somewhat descriptive. */
Index: wiretap/wtap.h
===================================================================
--- wiretap/wtap.h	(revision 19041)
+++ wiretap/wtap.h	(working copy)
@@ -182,9 +182,10 @@
 #define WTAP_ENCAP_CATAPULT_DCT2000             89
 #define WTAP_ENCAP_BER                          90
 #define WTAP_ENCAP_JUNIPER_VP                   91
+#define WTAP_ENCAP_MPEG                         92
 
 /* last WTAP_ENCAP_ value + 1 */
-#define WTAP_NUM_ENCAP_TYPES			92
+#define WTAP_NUM_ENCAP_TYPES			93
 
 /* File types that can be read by wiretap.
    We support writing some many of these file types, too, so we
@@ -235,8 +236,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
Index: wiretap/Makefile.common
===================================================================
--- wiretap/Makefile.common	(revision 19041)
+++ wiretap/Makefile.common	(working copy)
@@ -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	\