Added support for open TNEF files directly.
authorStig Bjørlykke <stig@bjorlykke.org>
Thu, 27 Nov 2008 16:40:45 +0000 (16:40 -0000)
committerStig Bjørlykke <stig@bjorlykke.org>
Thu, 27 Nov 2008 16:40:45 +0000 (16:40 -0000)
No we can decode those winmail.dat files.

svn path=/trunk/; revision=26864

epan/dissectors/packet-tnef.c
wiretap/Makefile.common
wiretap/file_access.c
wiretap/tnef.c [new file with mode: 0644]
wiretap/tnef.h [new file with mode: 0644]
wiretap/wtap.c
wiretap/wtap.h

index 597224950625cfb3289c9430dfb55a5bb3f53ff7..2c5048960dbf2e19619b188fe7218c5b9e145440 100644 (file)
 #include <time.h>
 #include <glib.h>
 #include <string.h>
+
 #include <epan/packet.h>
 #include <epan/conversation.h>
 #include <epan/addr_resolv.h>
 #include <epan/strutil.h>
 
+#include <wiretap/tnef.h>
+
 #include "packet-dcerpc.h"
 #include "packet-dcerpc-nspi.h"
 #include "packet-ber.h"
@@ -47,8 +50,6 @@
 #define PSNAME "TNEF"
 #define PFNAME "tnef"
 
-#define TNEF_SIGNATURE 0x223E9F78
-
 #define ATP_TRIPLES   (0x0000)
 #define ATP_STRING    (0x0001)
 #define ATP_TEXT      (0x0002)
@@ -629,6 +630,20 @@ static void dissect_tnef(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     proto_tree_add_item(tree, hf_tnef_padding, tvb, offset, tvb_length_remaining(tvb, offset), TRUE);    
 }
 
+static void dissect_tnef_file(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+  if (check_col(pinfo->cinfo, COL_PROTOCOL))
+    col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME);
+
+  if (check_col(pinfo->cinfo, COL_DEF_SRC))
+    col_set_str(pinfo->cinfo, COL_DEF_SRC, PSNAME " encoded file");
+
+  if (check_col(pinfo->cinfo, COL_INFO))
+    col_append_str(pinfo->cinfo, COL_INFO, PNAME);
+
+  dissect_tnef(tvb, pinfo, tree);
+}
+
 /* Register all the bits needed by the filtering engine */
 
 void
@@ -810,12 +825,15 @@ proto_register_tnef(void)
 void
 proto_reg_handoff_tnef(void)
 {
-  dissector_handle_t tnef_handle;
+  dissector_handle_t tnef_handle, tnef_file_handle;
 
   tnef_handle = find_dissector(PFNAME);
+  tnef_file_handle = create_dissector_handle(dissect_tnef_file, proto_tnef);
+
   dissector_add_string("media_type", "application/ms-tnef", tnef_handle);
 
   /* X.400 file transfer bodypart */
   register_ber_oid_dissector("1.2.840.113556.3.10.1", dissect_tnef, proto_tnef, "id-et-tnef");
 
+  dissector_add("wtap_encap", WTAP_ENCAP_TNEF, tnef_file_handle);
 }
index 185b57eae20a2653198ee223f5c33673d1da7b42..e56a3bf3a27b39df1313ee9e3de61ef0dfe034ca 100644 (file)
@@ -64,6 +64,7 @@ NONGENERATED_C_FILES = \
        pppdump.c               \
        radcom.c                \
        snoop.c                 \
+       tnef.c                  \
        toshiba.c               \
        visual.c                \
        vms.c                   \
@@ -107,6 +108,7 @@ NONGENERATED_HEADER_FILES = \
        pppdump.h               \
        radcom.h                \
        snoop.h                 \
+       tnef.h                  \
        toshiba.h               \
        visual.h                \
        vms.h                   \
index ce75770ba724fe645549a943cfa7efc2086b5813..9d179637f67dccc38d2b59667c3ee9302d444939 100644 (file)
@@ -77,6 +77,7 @@
 #include "commview.h"
 #include "pcapng.h"
 #include "btsnoop.h"
+#include "tnef.h"
 
 
 /* The open_file_* routines should return:
@@ -121,6 +122,7 @@ static wtap_open_routine_t open_routines_base[] = {
        mpeg_open,
        pcapng_open,
        btsnoop_open,
+       tnef_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
@@ -582,7 +584,13 @@ static const struct file_type_info dump_open_table_base[] = {
          pcapng_dump_can_write_encap, pcapng_dump_open },
 
        /* WTAP_FILE_BTSNOOP */
-       { "Symbian OS btsnoop", "btsnoop", "*.log", NULL, FALSE, NULL, NULL }
+       { "Symbian OS btsnoop", "btsnoop", "*.log", NULL, FALSE, NULL, NULL },
+        
+       /* WTAP_FILE_X2E_XORAYA */
+       { NULL, NULL, NULL, NULL, FALSE, NULL, NULL },
+
+       /* WTAP_FILE_TNEF */
+       { "Transport-Neutral Encapsulation Format", "tnef", "*.*", NULL, FALSE, NULL, NULL }
 };
 
 gint wtap_num_file_types = sizeof(dump_open_table_base) / sizeof(struct file_type_info);
diff --git a/wiretap/tnef.c b/wiretap/tnef.c
new file mode 100644 (file)
index 0000000..9ad0586
--- /dev/null
@@ -0,0 +1,137 @@
+/* tnef.c
+ *
+ * Transport-Neutral Encapsulation Format (TNEF) file reading
+ *
+ * $Id$
+ *
+ * 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 <errno.h>
+
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#include "wtap-int.h"
+#include "file_wrappers.h"
+#include "buffer.h"
+#include "tnef.h"
+
+
+static gboolean tnef_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset)
+{
+  guint8 *buf;
+  gint64 file_size;
+  int packet_size;
+  struct stat statb;
+
+  *err = 0;
+
+  /* there is only ever one packet */
+  if(wth->data_offset)
+    return FALSE;
+
+  *data_offset = wth->data_offset;
+
+  if ((file_size = wtap_file_size(wth, err)) == -1)
+    return FALSE;
+
+  if (file_size > WTAP_MAX_PACKET_SIZE) {
+    /*
+     * Probably a corrupt capture file; don't blow up trying
+     * to allocate space for an immensely-large packet.
+     */
+    *err = WTAP_ERR_BAD_RECORD;
+    *err_info = g_strdup_printf("tnef: File has %" G_GINT64_MODIFIER "d-byte packet, bigger than maximum of %u",
+                               file_size, WTAP_MAX_PACKET_SIZE);
+    return FALSE;
+  }
+  packet_size = (int)file_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);
+
+  wth->data_offset += packet_size;
+
+  wth->phdr.caplen = packet_size;
+  wth->phdr.len = packet_size;
+
+  if (fstat(wth->fd, &statb) == -1) {
+    *err = errno;
+    return FALSE;
+  }
+
+  wth->phdr.ts.secs = statb.st_mtime;
+  wth->phdr.ts.nsecs = 0;
+
+  return TRUE;
+}
+
+static gboolean tnef_seek_read(wtap *wth, gint64 seek_off,
+                               union wtap_pseudo_header *pseudo_header _U_,
+                               guint8 *pd, int length, int *err, gchar **err_info _U_)
+{
+  int packet_size = length;
+
+  /* there is only one packet */
+  if(seek_off > 0) {
+    *err = 0;
+    return FALSE;
+  }
+
+  if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
+    return FALSE;
+
+  wtap_file_read_expected_bytes(pd, packet_size, wth->random_fh, err);
+
+  return TRUE;
+}
+
+int tnef_open(wtap *wth, int *err, gchar **err_info _U_)
+{
+  int bytes_read;
+  guint32 magic;
+
+  bytes_read = file_read(&magic, 1, sizeof magic, wth->fh);
+  if (bytes_read != sizeof magic) {
+    *err = file_error(wth->fh);
+    return (*err != 0) ? -1 : 0;
+  }
+
+  if (htolel(magic) != TNEF_SIGNATURE)
+     /* Not a tnef file */
+     return 0;
+
+  /* seek back to the start of the file  */
+  if (file_seek(wth->fh, 0, SEEK_SET, err) == -1)
+    return -1;
+
+  wth->file_type = WTAP_FILE_TNEF;
+  wth->file_encap = WTAP_ENCAP_TNEF;
+  wth->snapshot_length = 0;
+
+  wth->subtype_read = tnef_read;
+  wth->subtype_seek_read = tnef_seek_read;
+  wth->tsprecision = WTAP_FILE_TSPREC_SEC;
+
+  return 1;
+}
diff --git a/wiretap/tnef.h b/wiretap/tnef.h
new file mode 100644 (file)
index 0000000..35f4714
--- /dev/null
@@ -0,0 +1,30 @@
+/* tnef.h
+ *
+ * Transport-Neutral Encapsulation Format (TNEF) file reading
+ *
+ * $Id$
+ *
+ * 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 __TNEF_H__
+#define __TNEF_H__
+
+#define TNEF_SIGNATURE 0x223E9F78
+
+int tnef_open(wtap *wth, int *err, gchar **err_info);
+
+#endif
index e31e58bbe283cd7b8235caf6486a591e0e353ef1..02946c7dbdfd053b4ffa994134282c7135d7319c 100644 (file)
@@ -430,7 +430,10 @@ static struct encap_type_info encap_table_base[] = {
        { "I2C", "i2c" },
 
        /* WTAP_ENCAP_IEEE802_15_4_NONASK_PHY */
-       { "IEEE 802.15.4 Wireless PAN non-ASK PHY", "wpan-nonask-phy" }
+       { "IEEE 802.15.4 Wireless PAN non-ASK PHY", "wpan-nonask-phy" },
+
+       /* WTAP_ENCAP_TNEF */
+       { "Transport-Neutral Encapsulation Format", "tnef" }
 };
 
 gint wtap_num_encap_types = sizeof(encap_table_base) / sizeof(struct encap_type_info);
index 62243db20757ce979f2e0c6013e4647b8ca2b185..c4e54158f378b1043b905af0db4516a3798914c2 100644 (file)
@@ -204,6 +204,7 @@ extern "C" {
 #define WTAP_ENCAP_X2E_SERIAL                   111
 #define WTAP_ENCAP_I2C                          112
 #define WTAP_ENCAP_IEEE802_15_4_NONASK_PHY      113
+#define WTAP_ENCAP_TNEF                         114
 
 #define WTAP_NUM_ENCAP_TYPES                    wtap_get_num_encap_types()
 
@@ -263,6 +264,7 @@ extern "C" {
 #define WTAP_FILE_PCAPNG                        50
 #define WTAP_FILE_BTSNOOP                       51
 #define WTAP_FILE_X2E_XORAYA                    52
+#define WTAP_FILE_TNEF                          53
 
 #define WTAP_NUM_FILE_TYPES                     wtap_get_num_file_types()