diff options
-rw-r--r-- | epan/dissectors/Makefile.common | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-image-jfif.c | 1 | ||||
-rw-r--r-- | epan/dissectors/packet-mime-encap.c | 111 | ||||
-rw-r--r-- | wiretap/Makefile.common | 4 | ||||
-rw-r--r-- | wiretap/file_access.c | 4 | ||||
-rw-r--r-- | wiretap/jpeg_jfif.c | 163 | ||||
-rw-r--r-- | wiretap/mime_file.c | 186 | ||||
-rw-r--r-- | wiretap/mime_file.h (renamed from wiretap/jpeg_jfif.h) | 8 | ||||
-rw-r--r-- | wiretap/wtap.h | 6 |
9 files changed, 310 insertions, 174 deletions
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common index 8d9a20a486..d0c8fa0215 100644 --- a/epan/dissectors/Makefile.common +++ b/epan/dissectors/Makefile.common @@ -671,6 +671,7 @@ DISSECTOR_SRC = \ packet-meta.c \ packet-mgcp.c \ packet-mikey.c \ + packet-mime-encap.c \ packet-miop.c \ packet-mip.c \ packet-mip6.c \ diff --git a/epan/dissectors/packet-image-jfif.c b/epan/dissectors/packet-image-jfif.c index 521d90a7fa..b6a02278ab 100644 --- a/epan/dissectors/packet-image-jfif.c +++ b/epan/dissectors/packet-image-jfif.c @@ -1176,4 +1176,5 @@ proto_reg_handoff_jfif(void) dissector_add_uint("wtap_encap", WTAP_ENCAP_JPEG_JFIF, jfif_handle); heur_dissector_add("http", dissect_jfif_heur, proto_jfif); + heur_dissector_add("wtap_file", dissect_jfif_heur, proto_jfif); } diff --git a/epan/dissectors/packet-mime-encap.c b/epan/dissectors/packet-mime-encap.c new file mode 100644 index 0000000000..7880a7b95f --- /dev/null +++ b/epan/dissectors/packet-mime-encap.c @@ -0,0 +1,111 @@ +/* packet-mime-encap.c + * + * $Id$ + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 + * + * 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 + +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include <epan/packet.h> +#include <epan/expert.h> +#include <epan/prefs.h> +#include <epan/uat.h> +#include <epan/emem.h> + +static int proto_mime_encap = -1; + +static heur_dissector_list_t heur_subdissector_list; +static dissector_handle_t data_handle; + +/* XXX, orginal version was using composite tvb, sorry I can't force it to work */ +static GString *whole_file; + +static void +mime_encap_init(void) +{ + if (whole_file) { + g_string_free(whole_file, TRUE); + whole_file = NULL; + } +} + +static void +dissect_mime_encap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_item* item; + guint len; + + item = proto_tree_add_item(tree, proto_mime_encap, tvb, 0, -1, FALSE); + + /* frames with nsec >= 1000000000 means errors :) */ + if (pinfo->fd->abs_ts.nsecs >= 1000000000) { + proto_item_append_text(item, " (Error)"); + /* return; */ /* dissect what we have */ + } + + if (!whole_file) + whole_file = g_string_new(""); + + /* eof? */ + if (!(len = tvb_length(tvb))) { + tvbuff_t *comp_tvb; + + proto_item_append_text(item, " (Final)"); + + comp_tvb = tvb_new_child_real_data(tvb, whole_file->str, whole_file->len, whole_file->len); + add_new_data_source(pinfo, comp_tvb, "Whole file"); + + if (!dissector_try_heuristic(heur_subdissector_list, comp_tvb, pinfo, tree)) { + proto_item_append_text(item, " (Unhandled)"); + call_dissector(data_handle, comp_tvb, pinfo, tree); + } + } else { + if (!pinfo->fd->flags.visited) { + g_string_set_size(whole_file, pinfo->fd->file_off + len); + tvb_memcpy(tvb, whole_file->str + pinfo->fd->file_off, 0, len); + } + } +} + +void +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); +} + +void +proto_reg_handoff_mime_encap(void) +{ + dissector_handle_t mime_encap_handle; + + data_handle = find_dissector("data"); + mime_encap_handle = find_dissector("mime_dlt"); + dissector_add_uint("wtap_encap", WTAP_ENCAP_MIME, mime_encap_handle); +} + diff --git a/wiretap/Makefile.common b/wiretap/Makefile.common index 55ab781368..3c09e93b0e 100644 --- a/wiretap/Makefile.common +++ b/wiretap/Makefile.common @@ -53,7 +53,7 @@ NONGENERATED_C_FILES = \ ipfix.c \ iptrace.c \ iseries.c \ - jpeg_jfif.c \ + mime_file.c \ k12.c \ lanalyzer.c \ libpcap.c \ @@ -104,7 +104,7 @@ NONGENERATED_HEADER_FILES = \ ipfix.h \ iptrace.h \ iseries.h \ - jpeg_jfif.h \ + mime_file.h \ k12.h \ lanalyzer.h \ libpcap.h \ diff --git a/wiretap/file_access.c b/wiretap/file_access.c index c66a149ad2..73c86d8700 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -82,7 +82,7 @@ #include "packetlogger.h" #include "daintree-sna.h" #include "netscaler.h" -#include "jpeg_jfif.h" +#include "mime_file.h" #include "ipfix.h" @@ -133,7 +133,7 @@ static wtap_open_routine_t open_routines_base[] = { tnef_open, dct3trace_open, daintree_sna_open, - jpeg_jfif_open, + mime_file_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 diff --git a/wiretap/jpeg_jfif.c b/wiretap/jpeg_jfif.c deleted file mode 100644 index c592a8075f..0000000000 --- a/wiretap/jpeg_jfif.c +++ /dev/null @@ -1,163 +0,0 @@ -/* jpeg_jfif.c - * - * JPEG/JFIF file format decoder for the Wiretap library. - * Written by Marton Nemeth <nm127@freemail.hu> - * Copyright 2009 Marton Nemeth - * - * $Id$ - * - * The JPEG and JFIF specification can be found at: - * http://www.jpeg.org/public/jfif.pdf - * http://www.w3.org/Graphics/JPEG/itu-t81.pdf - * - * 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 <sys/types.h> -#endif - -#ifdef HAVE_UNISTD_H -#include <unistd.h> -#endif - -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> - -#include "wtap-int.h" -#include "file_wrappers.h" -#include "buffer.h" -#include "jpeg_jfif.h" - -static const guchar jpeg_jfif_magic[] = { 0xFF, 0xD8, /* SOF */ - 0xFF /* start of the next marker */ - }; - -static gboolean -jpeg_jfif_read(wtap *wth, int *err, gchar **err_info, - gint64 *data_offset) -{ - guint8 *buf; - gint64 file_size; - int packet_size; - gint64 capture_size; - - *err = 0; - - /* interpret the file as one packet only */ - if (wth->data_offset) - return FALSE; - - *data_offset = wth->data_offset; - - if ((file_size = wtap_file_size(wth, err)) == -1) - return FALSE; - - /* Read maximum possible packet size */ - if (file_size <= WTAP_MAX_PACKET_SIZE) { - capture_size = file_size; - } else { - capture_size = WTAP_MAX_PACKET_SIZE; - } - packet_size = (int)capture_size; - - buffer_assure_space(wth->frame_buffer, packet_size); - buf = buffer_start_ptr(wth->frame_buffer); - - wtap_file_read_expected_bytes(buf, packet_size, wth->fh, err, err_info); - - wth->data_offset += packet_size; - - wth->phdr.caplen = packet_size; - wth->phdr.len = (int)file_size; - - wth->phdr.ts.secs = 0; - wth->phdr.ts.nsecs = 0; - - *err_info = NULL; - return TRUE; -} - -static gboolean -jpeg_jfif_seek_read(wtap *wth, gint64 seek_off, - union wtap_pseudo_header *pseudo_header _U_, guchar *pd, int length, - int *err, gchar **err_info) -{ - int packet_size = length; - - /* interpret the file as one packet only */ - if (0 < seek_off) { - *err = 0; - *err_info = NULL; - return FALSE; - } - - if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) { - *err_info = NULL; - return FALSE; - } - - wtap_file_read_expected_bytes(pd, packet_size, wth->random_fh, err, - err_info); - - *err = 0; - *err_info = NULL; - return TRUE; -} - -int -jpeg_jfif_open(wtap *wth, int *err, gchar **err_info) -{ - int bytes_read; - char magic_buf[3]; - int ret = 0; - - errno = WTAP_ERR_CANT_READ; - bytes_read = file_read(magic_buf, sizeof(magic_buf), wth->fh); - if (bytes_read != (int) sizeof(magic_buf)) { - *err = file_error(wth->fh, err_info); - if (*err != 0) { - *err_info = NULL; - ret = -1; - } - } else { - if (memcmp(magic_buf, jpeg_jfif_magic, sizeof(magic_buf)) == 0) { - ret = 1; - - wth->file_type = WTAP_FILE_JPEG_JFIF; - wth->file_encap = WTAP_ENCAP_JPEG_JFIF; - wth->tsprecision = WTAP_FILE_TSPREC_SEC; - wth->subtype_read = jpeg_jfif_read; - wth->subtype_seek_read = jpeg_jfif_seek_read; - wth->snapshot_length = 0; - } - } - - /* Seek to the start of the file */ - if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) { - *err = -1; - *err_info = NULL; - ret = -1; - } - - return ret; -} diff --git a/wiretap/mime_file.c b/wiretap/mime_file.c new file mode 100644 index 0000000000..e0d644f1e7 --- /dev/null +++ b/wiretap/mime_file.c @@ -0,0 +1,186 @@ +/* mime_file.c + * + * MIME file format decoder for the Wiretap library. + * + * $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 <sys/types.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#include "wtap-int.h" +#include "file_wrappers.h" +#include "buffer.h" +#include "mime_file.h" + +typedef struct { + gboolean last_packet; + +} mime_file_private_t; + +typedef struct { + const guchar *magic; + size_t magic_len; +} mime_files_t; + +/* + * Written by Marton Nemeth <nm127@freemail.hu> + * Copyright 2009 Marton Nemeth + * The JPEG and JFIF specification can be found at: + * + * http://www.jpeg.org/public/jfif.pdf + * http://www.w3.org/Graphics/JPEG/itu-t81.pdf + */ +static const guchar jpeg_jfif_magic[] = { 0xFF, 0xD8, /* SOF */ + 0xFF /* start of the next marker */ + }; + +static const mime_files_t magic_files[] = { + { jpeg_jfif_magic, sizeof(jpeg_jfif_magic) } +}; + +#define N_MAGIC_TYPES (sizeof(magic_files) / sizeof(magic_files[0])) + +static gboolean +mime_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) +{ + mime_file_private_t *priv = (mime_file_private_t *) wth->priv; + + char _buf[WTAP_MAX_PACKET_SIZE]; + + guint8 *buf; + int packet_size; + + if (priv->last_packet) { + *err = file_error(wth->fh, err_info); + return FALSE; + } + + /* XXX, mtime of file? */ + wth->phdr.ts.secs = 0; + wth->phdr.ts.nsecs = 0; + + *data_offset = wth->data_offset; + + /* try to read max WTAP_MAX_PACKET_SIZE bytes */ + packet_size = file_read(_buf, sizeof(_buf), wth->fh); + + if (packet_size <= 0) { + priv->last_packet = TRUE; + /* signal error for packet-mime-encap */ + if (packet_size < 0) + wth->phdr.ts.nsecs = 1000000000; + + wth->phdr.caplen = 0; + wth->phdr.len = 0; + return TRUE; + } + + /* copy to wth frame buffer */ + buffer_assure_space(wth->frame_buffer, packet_size); + buf = buffer_start_ptr(wth->frame_buffer); + + memcpy(buf, _buf, packet_size); + + wth->data_offset += packet_size; + wth->phdr.caplen = packet_size; + wth->phdr.len = packet_size; + return TRUE; +} + +static gboolean +mime_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_header *pseudo_header _U_, guchar *pd, int length, int *err, gchar **err_info) +{ + if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1) { + *err_info = NULL; + return FALSE; + } + + wtap_file_read_expected_bytes(pd, length, wth->random_fh, err, err_info); + + *err = 0; + *err_info = NULL; + return TRUE; +} + +int +mime_file_open(wtap *wth, int *err, gchar **err_info) +{ + char magic_buf[128]; /* increase when needed */ + int bytes_read; + int ret = 0; + guint i; + + gsize read_bytes = 0; + + for (i = 0; i < N_MAGIC_TYPES; i++) + read_bytes = MAX(read_bytes, magic_files[i].magic_len); + + read_bytes = MIN(read_bytes, sizeof(magic_buf)); + bytes_read = file_read(magic_buf, read_bytes, wth->fh); + + if (bytes_read > 0) { + gboolean found_file = FALSE; + guint file_ok; + + for (i = 0; i < N_MAGIC_TYPES; i++) { + if ((gsize) bytes_read >= magic_files[i].magic_len && !memcmp(magic_buf, magic_files[i].magic, MIN(magic_files[i].magic_len, (gsize) bytes_read))) { + if (!found_file) { + found_file = TRUE; + file_ok = i; + } else + return 0; /* many files matched, bad file */ + } + } + + if (!found_file) + return 0; + + if (file_seek(wth->fh, 0, SEEK_SET, err) == -1) + return -1; + + wth->file_type = WTAP_FILE_MIME; + wth->file_encap = WTAP_ENCAP_MIME; + wth->tsprecision = WTAP_FILE_TSPREC_SEC; + wth->subtype_read = mime_read; + wth->subtype_seek_read = mime_seek_read; + wth->snapshot_length = 0; + ret = 1; + + wth->priv = g_malloc0(sizeof(mime_file_private_t)); + + } else { + *err = file_error(wth->fh, err_info); + ret = -1; + } + return ret; +} diff --git a/wiretap/jpeg_jfif.h b/wiretap/mime_file.h index ebb9ccb996..77a5a973ca 100644 --- a/wiretap/jpeg_jfif.h +++ b/wiretap/mime_file.h @@ -1,8 +1,6 @@ -/* jpeg_jfif.h +/* mime_file.h * - * JPEG/JFIF file format decoder for the Wiretap library. - * Written by Marton Nemeth <nm127@freemail.hu> - * Copyright 2009 Marton Nemeth + * MIME file format decoder for the Wiretap library. * * $Id$ * @@ -28,6 +26,6 @@ #include <glib.h> #include <wtap.h> -int jpeg_jfif_open(wtap *wth, int *err, gchar **err_info); +int mime_file_open(wtap *wth, int *err, gchar **err_info); #endif diff --git a/wiretap/wtap.h b/wiretap/wtap.h index b65d714dcc..a233644062 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -212,7 +212,7 @@ extern "C" { #define WTAP_ENCAP_NSTRACE_2_0 120 #define WTAP_ENCAP_FIBRE_CHANNEL_FC2 121 #define WTAP_ENCAP_FIBRE_CHANNEL_FC2_WITH_FRAME_DELIMS 122 -#define WTAP_ENCAP_JPEG_JFIF 123 +#define WTAP_ENCAP_JPEG_JFIF 123 /* obsoleted by WTAP_ENCAP_MIME*/ #define WTAP_ENCAP_IPNET 124 #define WTAP_ENCAP_SOCKETCAN 125 #define WTAP_ENCAP_IEEE802_11_NETMON_RADIO 126 @@ -223,6 +223,7 @@ extern "C" { #define WTAP_ENCAP_LAPD 131 #define WTAP_ENCAP_DVBCI 132 #define WTAP_ENCAP_MUX27010 133 +#define WTAP_ENCAP_MIME 134 #define WTAP_NUM_ENCAP_TYPES wtap_get_num_encap_types() @@ -288,8 +289,9 @@ extern "C" { #define WTAP_FILE_DAINTREE_SNA 56 #define WTAP_FILE_NETSCALER_1_0 57 #define WTAP_FILE_NETSCALER_2_0 58 -#define WTAP_FILE_JPEG_JFIF 59 +#define WTAP_FILE_JPEG_JFIF 59 /* obsoleted by WTAP_FILE_MIME */ #define WTAP_FILE_IPFIX 60 +#define WTAP_FILE_MIME 61 #define WTAP_NUM_FILE_TYPES wtap_get_num_file_types() |