From 8387a45fcc1f5cf586e1714e45d10fea20dc20d3 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Tue, 31 Dec 2013 23:47:24 +0000 Subject: When reading MIME-encapsulated files, read the entire file at once, don't break it into chunks. This means we don't need to do reassembly in the MIME-encapsulated-data dissector. svn path=/trunk/; revision=54524 --- wiretap/mpeg.c | 106 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 43 deletions(-) (limited to 'wiretap') diff --git a/wiretap/mpeg.c b/wiretap/mpeg.c index 3767978747..62d929af83 100644 --- a/wiretap/mpeg.c +++ b/wiretap/mpeg.c @@ -52,41 +52,41 @@ typedef struct { } mpeg_t; static int -mpeg_resync(wtap *wth, int *err, gchar **err_info _U_) +mpeg_resync(FILE_T fh, int *err) { - gint64 offset = file_tell(wth->fh); + gint64 offset = file_tell(fh); int count = 0; - int byte = file_getc(wth->fh); + int byte = file_getc(fh); while (byte != EOF) { if (byte == 0xff && count > 0) { - byte = file_getc(wth->fh); + byte = file_getc(fh); if (byte != EOF && (byte & 0xe0) == 0xe0) break; } else - byte = file_getc(wth->fh); + byte = file_getc(fh); count++; } - if (file_seek(wth->fh, offset, SEEK_SET, err) == -1) + if (file_seek(fh, offset, SEEK_SET, err) == -1) return 0; return count; } static int -mpeg_read_header(wtap *wth, int *err, gchar **err_info, guint32 *n) +mpeg_read_header(FILE_T fh, int *err, gchar **err_info, guint32 *n) { int bytes_read; errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(n, sizeof *n, wth->fh); + bytes_read = file_read(n, sizeof *n, fh); if (bytes_read != sizeof *n) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return -1; } *n = g_ntohl(*n); - if (file_seek(wth->fh, -(gint64)(sizeof *n), SEEK_CUR, err) == -1) + if (file_seek(fh, -(gint64)(sizeof *n), SEEK_CUR, err) == -1) return -1; return bytes_read; } @@ -94,28 +94,28 @@ mpeg_read_header(wtap *wth, int *err, gchar **err_info, guint32 *n) #define SCRHZ 27000000 static gboolean -mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) +mpeg_read_packet(wtap *wth, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf, + gboolean is_random, int *err, gchar **err_info) { mpeg_t *mpeg = (mpeg_t *)wth->priv; guint32 n; - int bytes_read = mpeg_read_header(wth, err, err_info, &n); + int bytes_read; unsigned int packet_size; nstime_t ts = mpeg->now; + bytes_read = mpeg_read_header(fh, err, err_info, &n); if (bytes_read == -1) return FALSE; if (PES_VALID(n)) { - gint64 offset = file_tell(wth->fh); + gint64 offset = file_tell(fh); guint8 stream; - if (offset == -1) - return -1; - if (file_seek(wth->fh, 3, SEEK_CUR, err) == -1) + if (file_seek(fh, 3, SEEK_CUR, err) == -1) return FALSE; - bytes_read = file_read(&stream, sizeof stream, wth->fh); + bytes_read = file_read(&stream, sizeof stream, fh); if (bytes_read != sizeof stream) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); return FALSE; } @@ -125,16 +125,16 @@ mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) guint64 pack; guint8 stuffing; - bytes_read = file_read(&pack1, sizeof pack1, wth->fh); + bytes_read = file_read(&pack1, sizeof pack1, fh); if (bytes_read != sizeof pack1) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; } - bytes_read = file_read(&pack0, sizeof pack0, wth->fh); + bytes_read = file_read(&pack0, sizeof pack0, fh); if (bytes_read != sizeof pack0) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; @@ -143,18 +143,18 @@ mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) switch (pack >> 62) { case 1: - if (file_seek(wth->fh, 1, SEEK_CUR, err) == -1) + if (file_seek(fh, 1, SEEK_CUR, err) == -1) return FALSE; bytes_read = file_read(&stuffing, - sizeof stuffing, wth->fh); + sizeof stuffing, fh); if (bytes_read != sizeof stuffing) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); return FALSE; } stuffing &= 0x07; packet_size = 14 + stuffing; - { + if (!is_random) { guint64 bytes = pack >> 16; guint64 ts_val = (bytes >> 43 & 0x0007) << 30 | @@ -175,9 +175,9 @@ mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) } } else { guint16 length; - bytes_read = file_read(&length, sizeof length, wth->fh); + bytes_read = file_read(&length, sizeof length, fh); if (bytes_read != sizeof length) { - *err = file_error(wth->fh, err_info); + *err = file_error(fh, err_info); if (*err == 0 && bytes_read != 0) *err = WTAP_ERR_SHORT_READ; return FALSE; @@ -186,7 +186,7 @@ mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) packet_size = 6 + length; } - if (file_seek(wth->fh, offset, SEEK_SET, err) == -1) + if (file_seek(fh, offset, SEEK_SET, err) == -1) return FALSE; } else { struct mpa mpa; @@ -194,38 +194,58 @@ mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) MPA_UNMARSHAL(&mpa, n); if (MPA_VALID(&mpa)) { packet_size = MPA_BYTES(&mpa); - mpeg->now.nsecs += MPA_DURATION_NS(&mpa); - if (mpeg->now.nsecs >= 1000000000) { - mpeg->now.secs++; - mpeg->now.nsecs -= 1000000000; + if (!is_random) { + mpeg->now.nsecs += MPA_DURATION_NS(&mpa); + if (mpeg->now.nsecs >= 1000000000) { + mpeg->now.secs++; + mpeg->now.nsecs -= 1000000000; + } } } else { - packet_size = mpeg_resync(wth, err, err_info); + packet_size = mpeg_resync(fh, err); if (packet_size == 0) return FALSE; } } - *data_offset = file_tell(wth->fh); - if (!wtap_read_packet_bytes(wth->fh, wth->frame_buffer, - packet_size, err, err_info)) + if (!wtap_read_packet_bytes(fh, buf, packet_size, err, err_info)) return FALSE; + /* XXX - relative, not absolute, time stamps */ - wth->phdr.presence_flags = WTAP_HAS_TS; - wth->phdr.ts = ts; - wth->phdr.caplen = packet_size; - wth->phdr.len = packet_size; + if (!is_random) { + phdr->presence_flags = WTAP_HAS_TS; + phdr->ts = ts; + } + phdr->caplen = packet_size; + phdr->len = packet_size; + return TRUE; } +static gboolean +mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) +{ + *data_offset = file_tell(wth->fh); + + return mpeg_read_packet(wth, wth->fh, &wth->phdr, wth->frame_buffer, + FALSE, err, err_info); +} + static gboolean mpeg_seek_read(wtap *wth, gint64 seek_off, - struct wtap_pkthdr *phdr _U_, Buffer *buf, int length, + struct wtap_pkthdr *phdr, Buffer *buf, int length _U_, int *err, gchar **err_info) { if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) return FALSE; - return wtap_read_packet_bytes(wth->random_fh, buf, length, err, err_info); + + if (!mpeg_read_packet(wth, wth->random_fh, phdr, buf, TRUE, err, + err_info)) { + if (*err == 0) + *err = WTAP_ERR_SHORT_READ; + return FALSE; + } + return TRUE; } struct _mpeg_magic { -- cgit v1.2.3