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 --- epan/dissectors/packet-mime-encap.c | 63 ++------------------- wiretap/mpeg.c | 106 +++++++++++++++++++++--------------- 2 files changed, 67 insertions(+), 102 deletions(-) diff --git a/epan/dissectors/packet-mime-encap.c b/epan/dissectors/packet-mime-encap.c index 29c0902ab7..58b44f3837 100644 --- a/epan/dissectors/packet-mime-encap.c +++ b/epan/dissectors/packet-mime-encap.c @@ -26,9 +26,8 @@ #include #include -#include -#include "tvbuff-int.h" +#include void proto_register_mime_encap(void); void proto_reg_handoff_mime_encap(void); @@ -38,72 +37,19 @@ static int proto_mime_encap = -1; static heur_dissector_list_t heur_subdissector_list; static dissector_handle_t data_handle; -static tvbuff_t *file_tvbs; -static tvbuff_t *whole_tvb; - -static void -mime_encap_init(void) -{ - if (file_tvbs) { - tvb_free_chain(file_tvbs); - file_tvbs = NULL; - whole_tvb = NULL; - } -} - static void dissect_mime_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item* item; - guint len; /* XXX, COL_INFO */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "MIME_FILE"); item = proto_tree_add_item(tree, proto_mime_encap, tvb, 0, -1, ENC_NA); - /* frames with nsec >= 1000000000 means errors :) */ - if (pinfo->fd->abs_ts.nsecs >= 1000000000) { - proto_item_append_text(item, " (Error)"); - /* return; */ /* dissect what we have */ - } - - len = tvb_length(tvb); - if (!pinfo->fd->flags.visited) { - if (len) { - tvbuff_t *cloned_tvb = tvb_clone(tvb); - - if (!file_tvbs) { - file_tvbs = cloned_tvb; - whole_tvb = tvb_new_composite(); - } else - tvb_add_to_chain(file_tvbs, cloned_tvb); - - tvb_composite_append(whole_tvb, cloned_tvb); - } else - tvb_composite_finalize(whole_tvb); - } - - /* End of file? */ - if (!len && whole_tvb) { - /* - * Here we're doing some trick. - * - * We don't want to call dissectors with composite tvb, cause dissectors can create subsets or real data child - * on it, which would append to whole_tvb chain and would be freed only in mime_encap_init. - * - * So we create some tvb which pass all calls to whole_tvb, but chain with tvb (which is freed in dissection cleanup) - */ - tvbuff_t *tmp_tvb = tvb_new_chain(tvb, whole_tvb); - - proto_item_append_text(item, " (Final)"); - - add_new_data_source(pinfo, tmp_tvb, "Whole file"); - - if (!dissector_try_heuristic(heur_subdissector_list, tmp_tvb, pinfo, tree, NULL)) { - proto_item_append_text(item, " (Unhandled)"); - call_dissector(data_handle, tmp_tvb, pinfo, tree); - } + if (!dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, NULL)) { + proto_item_append_text(item, " (Unhandled)"); + call_dissector(data_handle, tvb, pinfo, tree); } } @@ -113,7 +59,6 @@ proto_register_mime_encap(void) proto_mime_encap = proto_register_protocol("MIME file", "MIME_FILE", "mime_dlt"); register_dissector("mime_dlt", dissect_mime_encap, proto_mime_encap); - register_init_routine(mime_encap_init); register_heur_dissector_list("wtap_file", &heur_subdissector_list); } 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