- Replace jpeg_jfif decoder, with more generic mime_file (no more 64KB limit!).
authordarkjames <darkjames@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 9 Jun 2011 21:21:06 +0000 (21:21 +0000)
committerdarkjames <darkjames@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 9 Jun 2011 21:21:06 +0000 (21:21 +0000)
- Add new dissector packet-mime-encap which understands mime_file fragmentation.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@37636 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/Makefile.common
epan/dissectors/packet-image-jfif.c
epan/dissectors/packet-mime-encap.c [new file with mode: 0644]
wiretap/Makefile.common
wiretap/file_access.c
wiretap/jpeg_jfif.c [deleted file]
wiretap/mime_file.c [new file with mode: 0644]
wiretap/mime_file.h [moved from wiretap/jpeg_jfif.h with 80% similarity]
wiretap/wtap.h

index 8d9a20a4865286e30a93fda2c93216d3ae795ca3..d0c8fa0215ffe2909370a4bbb576891da9d8421b 100644 (file)
@@ -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           \
index 521d90a7fa01fb65f419e5b38122ede608392c12..b6a02278ab7ec15a8b2ed2e6df841624522c3e0c 100644 (file)
@@ -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 (file)
index 0000000..7880a7b
--- /dev/null
@@ -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);
+}
+
index 55ab78136819e70b11590ff613f4fb8a8658c0c6..3c09e93b0e4db633e7ee4ea9d28f8b40e3445866 100644 (file)
@@ -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               \
index c66a149ad2cba466d86e088f50fa267feafc770a..73c86d87004ed58d15c947cb9529ac6cf1ed4209 100644 (file)
@@ -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 (file)
index c592a80..0000000
+++ /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 (file)
index 0000000..e0d644f
--- /dev/null
@@ -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;
+}
similarity index 80%
rename from wiretap/jpeg_jfif.h
rename to wiretap/mime_file.h
index ebb9ccb996d9354901ff7ac0b1501f47040e1c74..77a5a973caf40d42ff52a2621e3696e1381e69cb 100644 (file)
@@ -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
index b65d714dcc6a586d14917d99dd498f0800fc8a54..a23364406275a6d3e287f56d5cc6d13d5278bef4 100644 (file)
@@ -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()