Initial support for .aps files from Aethra Telecommunications' PC108
authorGuy Harris <guy@alum.mit.edu>
Wed, 26 Oct 2011 02:18:55 +0000 (02:18 -0000)
committerGuy Harris <guy@alum.mit.edu>
Wed, 26 Oct 2011 02:18:55 +0000 (02:18 -0000)
software.  More work is needed:

we don't know where the capture start time is yet;

we aren't handling the "stop capture" record;

we don't know where the ISDN channel is;

there might be non-ISDN file formats;

but this at least is easier than trying to text2pcap hex dumps from that
software into pcap files.

svn path=/trunk/; revision=39588

wiretap/Makefile.common
wiretap/aethra.c [new file with mode: 0644]
wiretap/aethra.h [new file with mode: 0644]
wiretap/file_access.c
wiretap/wtap.h

index 3c09e93b0e4db633e7ee4ea9d28f8b40e3445866..78ddc2ad115e986a7c897f5bdaeb2e5b757b187c 100644 (file)
@@ -30,6 +30,7 @@
 # _SOURCES variables).
 NONGENERATED_C_FILES = \
        5views.c                \
+       aethra.c                \
        airopeek9.c             \
        ascendtext.c            \
        atm.c                   \
@@ -80,6 +81,7 @@ NONGENERATED_C_FILES = \
 # Header files that are not generated from other files
 NONGENERATED_HEADER_FILES = \
        5views.h                \
+       aethra.h                \
        airopeek9.h             \
        ascendtext.h            \
        ascend-int.h            \
diff --git a/wiretap/aethra.c b/wiretap/aethra.c
new file mode 100644 (file)
index 0000000..774f454
--- /dev/null
@@ -0,0 +1,218 @@
+/* aethra.c
+ *
+ * $Id$
+ *
+ * Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
+ *
+ * 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>
+#include <string.h>
+#include "wtap-int.h"
+#include "file_wrappers.h"
+#include "buffer.h"
+#include "aethra.h"
+
+/* Magic number in Aethra PC108 files. */
+static const char aethra_magic[5] = "V0208";
+
+/* Aethra file header (minus magic number). */
+struct aethra_hdr {
+       guint8  unknown[5415];
+};
+
+/* Aethra record header.  Yes, the alignment is weird.
+   All multi-byte fields are little-endian. */
+struct aethrarec_hdr {
+       guint8 rec_size[2];     /* record length, not counting the length itself */
+       guint8 unknown1;
+       guint8 timestamp[4];    /* milliseconds since start of capture */
+       guint8 flags;           /* low-order bit: 0 = N->U, 1 = U->N */
+};
+
+/*
+ * Flags.
+ */
+#define AETHRA_U_TO_N          0x01
+
+static gboolean aethra_read(wtap *wth, int *err, gchar **err_info,
+    gint64 *data_offset);
+static gboolean aethra_seek_read(wtap *wth, gint64 seek_off,
+    union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
+    int *err, gchar **err_info);
+static gboolean aethra_read_rec_header(FILE_T fh, struct aethrarec_hdr *hdr,
+    union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info);
+static gboolean aethra_read_rec_data(FILE_T fh, guint8 *pd, int length,
+    int *err, gchar **err_info);
+
+int aethra_open(wtap *wth, int *err, gchar **err_info)
+{
+       int bytes_read;
+       char magic[sizeof aethra_magic];
+       struct aethra_hdr hdr;
+
+       /* Read in the string that should be at the start of a "aethra" file */
+       errno = WTAP_ERR_CANT_READ;
+       bytes_read = file_read(magic, sizeof magic, wth->fh);
+       if (bytes_read != sizeof magic) {
+               *err = file_error(wth->fh, err_info);
+               if (*err != 0)
+                       return -1;
+               return 0;
+       }
+       wth->data_offset += sizeof magic;
+
+       if (memcmp(magic, aethra_magic, sizeof aethra_magic) != 0) {
+               return 0;
+       }
+
+       /* Read the rest of the header. */
+       errno = WTAP_ERR_CANT_READ;
+       bytes_read = file_read(&hdr, sizeof hdr, wth->fh);
+       if (bytes_read != sizeof hdr) {
+               *err = file_error(wth->fh, err_info);
+               if (*err != 0)
+                       return -1;
+               return 0;
+       }
+       wth->data_offset += sizeof hdr;
+       wth->file_type = WTAP_FILE_AETHRA;
+       wth->subtype_read = aethra_read;
+       wth->subtype_seek_read = aethra_seek_read;
+
+       /*
+        * We've only seen ISDN files, so, for now, we treat all
+        * files as ISDN.
+        */
+       wth->file_encap = WTAP_ENCAP_ISDN;
+       wth->snapshot_length = 0;       /* not available in header */
+       wth->tsprecision = WTAP_FILE_TSPREC_MSEC;
+       return 1;
+}
+
+/* Read the next packet */
+static gboolean aethra_read(wtap *wth, int *err, gchar **err_info,
+    gint64 *data_offset)
+{
+       struct aethrarec_hdr hdr;
+       guint32 rec_size;
+       guint32 packet_size;
+       guint32 msecs;
+
+       *data_offset = wth->data_offset;
+
+       /* Read record header. */
+       if (!aethra_read_rec_header(wth->fh, &hdr, &wth->pseudo_header, err,
+           err_info))
+               return FALSE;
+
+       rec_size = pletohs(hdr.rec_size);
+       if (rec_size < (sizeof hdr - sizeof hdr.rec_size)) {
+               /* The record is shorter than a record header. */
+               *err = WTAP_ERR_BAD_RECORD;
+               *err_info = g_strdup_printf("aethra: File has %u-byte record, less than minimum of %u",
+                   rec_size, (unsigned int)(sizeof hdr - sizeof hdr.rec_size));
+               return FALSE;
+       }
+
+       wth->data_offset += sizeof hdr;
+
+       packet_size = rec_size - (sizeof hdr - sizeof hdr.rec_size);
+       if (packet_size != 0) {
+               buffer_assure_space(wth->frame_buffer, packet_size);
+               if (!aethra_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer),
+                   packet_size, err, err_info))
+                       return FALSE;   /* Read error */
+               wth->data_offset += packet_size;
+       }
+
+       /*
+        * XXX - need to find start time in file header.
+        */
+       msecs = pletohl(hdr.timestamp);
+       wth->phdr.ts.secs = msecs / 1000;
+       wth->phdr.ts.nsecs = (msecs % 1000) * 1000000;
+       wth->phdr.caplen = packet_size;
+       wth->phdr.len = packet_size;
+
+       return TRUE;
+}
+
+static gboolean
+aethra_seek_read(wtap *wth, gint64 seek_off,
+    union wtap_pseudo_header *pseudo_header, guint8 *pd, int length,
+    int *err, gchar **err_info)
+{
+       struct aethrarec_hdr hdr;
+
+       if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
+               return FALSE;
+
+       if (!aethra_read_rec_header(wth->random_fh, &hdr, pseudo_header, err, err_info))
+               return FALSE;
+
+       /*
+        * Read the packet data.
+        */
+       if (!aethra_read_rec_data(wth->random_fh, pd, length, err, err_info))
+               return FALSE;   /* failed */
+
+       return TRUE;
+}
+
+static gboolean
+aethra_read_rec_header(FILE_T fh, struct aethrarec_hdr *hdr,
+    union wtap_pseudo_header *pseudo_header, int *err, gchar **err_info)
+{
+       int     bytes_read;
+
+       /* Read record header. */
+       errno = WTAP_ERR_CANT_READ;
+       bytes_read = file_read(hdr, sizeof hdr, fh);
+       if (bytes_read != sizeof *hdr) {
+               *err = file_error(fh, err_info);
+               if (*err == 0 && bytes_read != 0)
+                       *err = WTAP_ERR_SHORT_READ;
+               return FALSE;
+       }
+
+       pseudo_header->isdn.uton = hdr->flags & AETHRA_U_TO_N;
+       pseudo_header->isdn.channel = 0;        /* XXX - D channel */
+
+       return TRUE;
+}
+
+static gboolean
+aethra_read_rec_data(FILE_T fh, guint8 *pd, int length, int *err,
+    gchar **err_info)
+{
+       int     bytes_read;
+
+       errno = WTAP_ERR_CANT_READ;
+       bytes_read = file_read(pd, length, fh);
+
+       if (bytes_read != length) {
+               *err = file_error(fh, err_info);
+               if (*err == 0)
+                       *err = WTAP_ERR_SHORT_READ;
+               return FALSE;
+       }
+       return TRUE;
+}
diff --git a/wiretap/aethra.h b/wiretap/aethra.h
new file mode 100644 (file)
index 0000000..240a6a7
--- /dev/null
@@ -0,0 +1,31 @@
+/* aethra.h
+ *
+ * $Id$
+ *
+ * Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
+ *
+ * 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 __W_AETHRA_H__
+#define __W_AETHRA_H__
+
+#include <glib.h>
+#include <wtap.h>
+
+int aethra_open(wtap *wth, int *err, gchar **err_info);
+
+#endif
index 5090ea627f756034466f11b2e82e9398ec741e5d..5ba7d685e514b27bceadc09cea106e794d991b97 100644 (file)
@@ -76,6 +76,7 @@
 #include "netscreen.h"
 #include "commview.h"
 #include "pcapng.h"
+#include "aethra.h"
 #include "btsnoop.h"
 #include "tnef.h"
 #include "dct3trace.h"
@@ -126,6 +127,7 @@ static wtap_open_routine_t open_routines_base[] = {
        catapult_dct2000_open,
        ber_open,
        pcapng_open,
+       aethra_open,
        btsnoop_open,
        packetlogger_open, /* This type does not have a magic number, but its
                            * files are sometimes grabbed by mpeg_open. */
@@ -650,7 +652,11 @@ static const struct file_type_info dump_open_table_base[] = {
 
        /* WTAP_ENCAP_MIME */
        { "MIME File Format", "mime", NULL, NULL, FALSE, FALSE,
-          NULL, NULL }
+          NULL, NULL },
+
+       /* WTAP_FILE_AETHRA */
+       { "Aethra .aps file", "aethra", "*.aps", NULL, FALSE, FALSE,
+         NULL, NULL },
 };
 
 gint wtap_num_file_types = sizeof(dump_open_table_base) / sizeof(struct file_type_info);
index 6025d64e02bcadf492902b548938d96a23abb3fd..d963a86ed88a5922817f04041cc67cb9ffaddfc1 100644 (file)
@@ -292,6 +292,7 @@ extern "C" {
 #define WTAP_FILE_JPEG_JFIF                     59 /* obsoleted by WTAP_FILE_MIME */
 #define WTAP_FILE_IPFIX                         60
 #define WTAP_FILE_MIME                          61
+#define WTAP_FILE_AETHRA                       62
 
 #define WTAP_NUM_FILE_TYPES                     wtap_get_num_file_types()