diff --git a/wiretap/CMakeLists.txt b/wiretap/CMakeLists.txt index d7b8bad2e4..16be261a49 100644 --- a/wiretap/CMakeLists.txt +++ b/wiretap/CMakeLists.txt @@ -53,6 +53,7 @@ set(WIRETAP_FILES libpcap.c mpeg.c mime_file.c + mp2t.c netmon.c netscaler.c netscreen.c diff --git a/wiretap/Makefile.common b/wiretap/Makefile.common index 78ddc2ad11..702e37b979 100644 --- a/wiretap/Makefile.common +++ b/wiretap/Makefile.common @@ -59,6 +59,7 @@ NONGENERATED_C_FILES = \ lanalyzer.c \ libpcap.c \ mpeg.c \ + mp2t.c \ netmon.c \ netscaler.c \ netscreen.c \ @@ -111,6 +112,7 @@ NONGENERATED_HEADER_FILES = \ lanalyzer.h \ libpcap.h \ mpeg.h \ + mp2t.h \ netmon.h \ netscreen.h \ netscaler.h \ diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 3b604217b5..1c493c2685 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -72,6 +72,7 @@ #include "k12.h" #include "ber.h" #include "catapult_dct2000.h" +#include "mp2t.h" #include "mpeg.h" #include "netscreen.h" #include "commview.h" @@ -132,6 +133,7 @@ static wtap_open_routine_t open_routines_base[] = { packetlogger_open, /* This type does not have a magic number, but its * files are sometimes grabbed by mpeg_open. */ mpeg_open, + mp2t_open, tnef_open, dct3trace_open, daintree_sna_open, @@ -594,6 +596,10 @@ static const struct file_type_info dump_open_table_base[] = { { "MPEG", "mpeg", "mpeg", "mpg;mp3", FALSE, FALSE, NULL, NULL }, + /* WTAP_FILE_MPEG_2_TS */ + { "MP2T", "mp2t", "mp2t", "mp2t;ts;mpg", FALSE, FALSE, + NULL, NULL }, + /* WTAP_FILE_K12TEXT */ { "K12 text file", "k12text", "txt", NULL, FALSE, FALSE, k12text_dump_can_write_encap, k12text_dump_open }, diff --git a/wiretap/mp2t.c b/wiretap/mp2t.c new file mode 100644 index 0000000000..bcab1a8977 --- /dev/null +++ b/wiretap/mp2t.c @@ -0,0 +1,174 @@ +/* mp2t.c + * + * ISO/IEC 13818-1 MPEG2-TS file format decoder for the Wiretap library. + * Written by Weston Schmidt + * Copyright 2012 Weston Schmidt + * + * $Id$ + * + * Wiretap Library + * 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 + +#ifdef HAVE_SYS_TYPES_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "mp2t.h" + +#include "wtap-int.h" +#include "buffer.h" +#include "file_wrappers.h" +#include +#include +#include +#include + +#define MP2T_SYNC_BYTE 0x47 +#define MP2T_SIZE 188 +#define MP2T_QAM256_BITRATE 38810700 /* bits per second */ +#define MP2T_QAM64_BITRATE 26970350 /* bits per second */ + +typedef struct { + guint32 offset; + struct wtap_nstime now; +} mp2t_filetype_t; + +static gboolean +mp2t_read_data(guint8 *dest, int length, int *err, gchar **err_info, FILE_T fh) +{ + int bytes_read; + + bytes_read = file_read(dest, length, fh); + if (MP2T_SIZE != bytes_read) { + *err = file_error(fh, err_info); + if (*err == 0) { + *err = WTAP_ERR_SHORT_READ; + } + return FALSE; + } + + return TRUE; +} + +static gboolean +mp2t_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) +{ + mp2t_filetype_t *mp2t; + guint64 tmp; + + mp2t = (mp2t_filetype_t*) wth->priv; + + *data_offset = mp2t->offset; + buffer_assure_space(wth->frame_buffer, MP2T_SIZE); + if (FALSE == mp2t_read_data(buffer_start_ptr(wth->frame_buffer), + MP2T_SIZE, err, err_info, wth->fh)) + { + return FALSE; + } + + mp2t->offset += MP2T_SIZE; + wth->phdr.presence_flags = WTAP_HAS_TS; + + /* It would be really cool to be able to configure the bitrate... */ + tmp = MP2T_SIZE * 8; + tmp *= 1000000000; + tmp /= MP2T_QAM256_BITRATE; + + wth->phdr.ts.secs = mp2t->now.secs; + wth->phdr.ts.nsecs = mp2t->now.nsecs; + mp2t->now.nsecs += (guint32)tmp; + if (1000000000 <= mp2t->now.nsecs) { + mp2t->now.nsecs -= 1000000000; + mp2t->now.secs++; + } + wth->phdr.caplen = MP2T_SIZE; + wth->phdr.len = MP2T_SIZE; + + return TRUE; +} + +static gboolean +mp2t_seek_read(wtap *wth, gint64 seek_off, + union wtap_pseudo_header *pseudo_header _U_, guint8 *pd, int length, + int *err, gchar **err_info) +{ + if (-1 == file_seek(wth->random_fh, seek_off, SEEK_SET, err)) { + return FALSE; + } + + return mp2t_read_data(pd, length, err, err_info, wth->random_fh); +} + +int +mp2t_open(wtap *wth, int *err, gchar **err_info) +{ + int bytes_read; + guint8 buffer[MP2T_SIZE]; + int i; + int first; + mp2t_filetype_t *mp2t; + + errno = WTAP_ERR_CANT_READ; + bytes_read = file_read(buffer, sizeof(buffer), wth->fh); + + if (sizeof(buffer) != bytes_read) { + *err = file_error(wth->fh, err_info); + return (*err == 0) ? 0 : -1; + } + + first = -1; + for (i = 0; i < MP2T_SIZE; i++) { + if (MP2T_SYNC_BYTE == buffer[i]) { + first = i; + break; + } + } + + if (-1 == first) { + return 0; + } + + if (-1 == file_seek(wth->fh, first, SEEK_SET, err)) { + return -1; + } + + wth->file_type = WTAP_FILE_MPEG_2_TS; + wth->file_encap = WTAP_ENCAP_MPEG_2_TS; + wth->tsprecision = WTAP_FILE_TSPREC_NSEC; + wth->subtype_read = mp2t_read; + wth->subtype_seek_read = mp2t_seek_read; + wth->snapshot_length = 0; + + mp2t = (mp2t_filetype_t*) g_malloc(sizeof(mp2t_filetype_t)); + if (NULL == mp2t) { + return -1; + } + + wth->priv = mp2t; + mp2t->offset = (guint32) first; + mp2t->now.secs = 0; + mp2t->now.nsecs = 0; + + return 1; +} diff --git a/wiretap/mp2t.h b/wiretap/mp2t.h new file mode 100644 index 0000000000..bf4b2dde26 --- /dev/null +++ b/wiretap/mp2t.h @@ -0,0 +1,33 @@ +/* mp2t.h + * + * ISO/IEC 13818-1 MPEG2-TS file format decoder for the Wiretap library. + * Written by Weston Schmidt + * Copyright 2012 Weston Schmidt + * + * $Id$ + * + * Wiretap Library + * 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. + */ + +#ifndef __W_MP2T_H__ +#define __W_MP2T_H__ + +#include +#include + +int mp2t_open(wtap *wth, int *err, gchar **err_info); + +#endif diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 1dbbe13972..e455bc293d 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -227,7 +227,7 @@ extern "C" { #define WTAP_ENCAP_NETANALYZER 135 #define WTAP_ENCAP_NETANALYZER_TRANSPARENT 136 #define WTAP_ENCAP_IP_OVER_IB 137 -#define WTAP_ENCAP_MPEG_2_TS 138 +#define WTAP_ENCAP_MPEG_2_TS 138 #define WTAP_ENCAP_PPP_ETHER 139 #define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types() @@ -295,7 +295,8 @@ extern "C" { #define WTAP_FILE_JPEG_JFIF 57 /* obsoleted by WTAP_FILE_MIME */ #define WTAP_FILE_IPFIX 58 #define WTAP_FILE_MIME 59 -#define WTAP_FILE_AETHRA 60 +#define WTAP_FILE_AETHRA 60 +#define WTAP_FILE_MPEG_2_TS 61 #define WTAP_NUM_FILE_TYPES wtap_get_num_file_types()