From 3c94bf0d215f5a5f46dbc55ca03ecaa8dd21069b Mon Sep 17 00:00:00 2001 From: guy Date: Wed, 26 Oct 2011 02:18:55 +0000 Subject: Initial support for .aps files from Aethra Telecommunications' PC108 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. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@39588 f5534014-38df-0310-8fa8-9805f1628bb7 --- wiretap/Makefile.common | 2 + wiretap/aethra.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++ wiretap/aethra.h | 31 +++++++ wiretap/file_access.c | 8 +- wiretap/wtap.h | 1 + 5 files changed, 259 insertions(+), 1 deletion(-) create mode 100644 wiretap/aethra.c create mode 100644 wiretap/aethra.h (limited to 'wiretap') diff --git a/wiretap/Makefile.common b/wiretap/Makefile.common index 3c09e93b0e..78ddc2ad11 100644 --- a/wiretap/Makefile.common +++ b/wiretap/Makefile.common @@ -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 index 0000000000..774f454641 --- /dev/null +++ b/wiretap/aethra.c @@ -0,0 +1,218 @@ +/* aethra.c + * + * $Id$ + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez + * + * 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 +#include +#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 index 0000000000..240a6a734f --- /dev/null +++ b/wiretap/aethra.h @@ -0,0 +1,31 @@ +/* aethra.h + * + * $Id$ + * + * Wiretap Library + * Copyright (c) 1998 by Gilbert Ramirez + * + * 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 +#include + +int aethra_open(wtap *wth, int *err, gchar **err_info); + +#endif diff --git a/wiretap/file_access.c b/wiretap/file_access.c index 5090ea627f..5ba7d685e5 100644 --- a/wiretap/file_access.c +++ b/wiretap/file_access.c @@ -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); diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 6025d64e02..d963a86ed8 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -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() -- cgit v1.2.3