aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap/ascendtext.c
diff options
context:
space:
mode:
authorJörg Mayer <jmayer@loplof.de>2009-06-15 18:56:46 +0000
committerJörg Mayer <jmayer@loplof.de>2009-06-15 18:56:46 +0000
commit0d300bb6f50a3c28adac30b1c09734975f2492cc (patch)
treebddb6d9f078fb35ad94739d554522bcb751d2935 /wiretap/ascendtext.c
parentec5dbeca716fdf01465a59b4994c66fe5a8e72cf (diff)
Rename all of the ascend files:
That way we hopefully won't need the runlex.sh hack any more. Also the ylwrap stuff is (hopefully) obsolete. ascend.[hc] -> ascendtext.[hc] ascend-scanner.l -> ascend_scanner.l ascend-grammar.y -> ascend.y svn path=/trunk/; revision=28744
Diffstat (limited to 'wiretap/ascendtext.c')
-rw-r--r--wiretap/ascendtext.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/wiretap/ascendtext.c b/wiretap/ascendtext.c
new file mode 100644
index 0000000000..f8597ae245
--- /dev/null
+++ b/wiretap/ascendtext.c
@@ -0,0 +1,343 @@
+/* ascendtext.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 "wtap-int.h"
+#include "buffer.h"
+#include "ascendtext.h"
+#include "ascend-int.h"
+#include "file_wrappers.h"
+#include <wsutil/file_util.h>
+
+#include <errno.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <ctype.h>
+#include <string.h>
+
+/* Last updated: Feb 03 2005: Josh Bailey (joshbailey@lucent.com).
+
+ This module reads the text hex dump output of various TAOS
+ (Lucent/Ascend Max, Max TNT, APX, etc) debug commands, including:
+
+ * pridisplay traces primary rate ISDN
+ * ether-display traces Ethernet packets (dangerous! CPU intensive)
+ * wanopening, wandisplay, wannext, wandsess
+ traces PPP or other WAN connections
+
+ Please see ascend.y for examples.
+
+ Detailed documentation on TAOS products is at http://support.lucent.com.
+
+ Support for other commands will be added on an ongoing basis. */
+
+typedef struct _ascend_magic_string {
+ guint type;
+ const gchar *strptr;
+} ascend_magic_string;
+
+#define ASCEND_MAGIC_STRINGS 11
+#define ASCEND_DATE "Date:"
+
+/* these magic strings signify the headers of a supported debug commands */
+static const ascend_magic_string ascend_magic[] = {
+ { ASCEND_PFX_ISDN_X, "PRI-XMIT-" },
+ { ASCEND_PFX_ISDN_R, "PRI-RCV-" },
+ { ASCEND_PFX_WDS_X, "XMIT-" },
+ { ASCEND_PFX_WDS_R, "RECV-" },
+ { ASCEND_PFX_WDS_X, "XMIT:" },
+ { ASCEND_PFX_WDS_R, "RECV:" },
+ { ASCEND_PFX_WDS_X, "PPP-OUT" },
+ { ASCEND_PFX_WDS_R, "PPP-IN" },
+ { ASCEND_PFX_WDD, ASCEND_DATE },
+ { ASCEND_PFX_WDD, "WD_DIALOUT_DISP:" },
+ { ASCEND_PFX_ETHER, "ETHER" },
+};
+
+static gboolean ascend_read(wtap *wth, int *err, gchar **err_info,
+ gint64 *data_offset);
+static gboolean ascend_seek_read(wtap *wth, gint64 seek_off,
+ union wtap_pseudo_header *pseudo_head, guint8 *pd, int len,
+ int *err, gchar **err_info);
+static void ascend_close(wtap *wth);
+
+/* Seeks to the beginning of the next packet, and returns the
+ byte offset at which the header for that packet begins.
+ Returns -1 on failure. */
+static gint64 ascend_seek(wtap *wth, int *err)
+{
+ int byte;
+ gint64 date_off = -1, cur_off, packet_off;
+ size_t string_level[ASCEND_MAGIC_STRINGS];
+ guint string_i = 0, type = 0;
+ guint excessive_read_count = 262144;
+
+ memset(&string_level, 0, sizeof(string_level));
+
+ while (((byte = file_getc(wth->fh)) != EOF)) {
+ excessive_read_count--;
+
+ if (!excessive_read_count) {
+ return -1;
+ }
+
+ for (string_i = 0; string_i < ASCEND_MAGIC_STRINGS; string_i++) {
+ const gchar *strptr = ascend_magic[string_i].strptr;
+ size_t len = strlen(strptr);
+
+ if (byte == *(strptr + string_level[string_i])) {
+ string_level[string_i]++;
+ if (string_level[string_i] >= len) {
+ cur_off = file_tell(wth->fh);
+ if (cur_off == -1) {
+ /* Error. */
+ *err = file_error(wth->fh);
+ return -1;
+ }
+
+ /* Date: header is a special case. Remember the offset,
+ but keep looking for other headers. */
+ if (strcmp(strptr, ASCEND_DATE) == 0) {
+ date_off = cur_off - len;
+ } else {
+ if (date_off == -1) {
+ /* Back up over the header we just read; that's where a read
+ of this packet should start. */
+ packet_off = cur_off - len;
+ } else {
+ /* This packet has a date/time header; a read of it should
+ start at the beginning of *that* header. */
+ packet_off = date_off;
+ }
+
+ type = ascend_magic[string_i].type;
+ goto found;
+ }
+ }
+ } else {
+ string_level[string_i] = 0;
+ }
+ }
+ }
+
+ if (byte != EOF || file_eof(wth->fh)) {
+ /* Either we didn't find the offset, or we got an EOF. */
+ *err = 0;
+ } else {
+ /* We (presumably) got an error (there's no equivalent to "ferror()"
+ in zlib, alas, so we don't have a wrapper to check for an error). */
+ *err = file_error(wth->fh);
+ }
+ return -1;
+
+found:
+ /*
+ * Move to where the read for this packet should start, and return
+ * that seek offset.
+ */
+ if (file_seek(wth->fh, packet_off, SEEK_SET, err) == -1)
+ return -1;
+
+ wth->pseudo_header.ascend.type = type;
+
+ return packet_off;
+}
+
+int ascend_open(wtap *wth, int *err, gchar **err_info _U_)
+{
+ gint64 offset;
+ struct stat statbuf;
+ guint8 buf[ASCEND_MAX_PKT_LEN];
+ ascend_pkthdr header;
+ gint64 dummy_seek_start;
+
+ /* We haven't yet allocated a data structure for our private stuff;
+ set the pointer to null, so that "ascend_seek()" knows not to
+ fill it in. */
+ wth->capture.ascend = NULL;
+
+ offset = ascend_seek(wth, err);
+ if (offset == -1) {
+ if (*err == 0)
+ return 0;
+ else
+ return -1;
+ }
+
+ /* Do a trial parse of the first packet just found to see if we might really have an Ascend file */
+ init_parse_ascend();
+ if (! parse_ascend(wth->fh, buf, &wth->pseudo_header.ascend, &header, &dummy_seek_start)) {
+ return 0;
+ }
+
+ wth->data_offset = offset;
+ wth->file_type = WTAP_FILE_ASCEND;
+
+ switch(wth->pseudo_header.ascend.type) {
+ case ASCEND_PFX_ISDN_X:
+ case ASCEND_PFX_ISDN_R:
+ wth->file_encap = WTAP_ENCAP_ISDN;
+ break;
+
+ case ASCEND_PFX_ETHER:
+ wth->file_encap = WTAP_ENCAP_ETHERNET;
+ break;
+
+ default:
+ wth->file_encap = WTAP_ENCAP_ASCEND;
+ }
+
+ wth->snapshot_length = ASCEND_MAX_PKT_LEN;
+ wth->subtype_read = ascend_read;
+ wth->subtype_seek_read = ascend_seek_read;
+ wth->subtype_close = ascend_close;
+ wth->capture.ascend = g_malloc(sizeof(ascend_t));
+
+ /* The first packet we want to read is the one that "ascend_seek()"
+ just found; start searching for it at the offset at which it
+ found it. */
+ wth->capture.ascend->next_packet_seek_start = offset;
+
+ /* MAXen and Pipelines report the time since reboot. In order to keep
+ from reporting packet times near the epoch, we subtract the first
+ packet's timestamp from the capture file's ctime, which gives us an
+ offset that we can apply to each packet.
+ */
+ if (fstat(wth->fd, &statbuf) == -1) {
+ *err = errno;
+ g_free(wth->capture.ascend);
+ return -1;
+ }
+ wth->capture.ascend->inittime = statbuf.st_ctime;
+ wth->capture.ascend->adjusted = 0;
+ wth->tsprecision = WTAP_FILE_TSPREC_USEC;
+
+ init_parse_ascend();
+
+ return 1;
+}
+
+static void config_pseudo_header(union wtap_pseudo_header *pseudo_head)
+{
+ switch(pseudo_head->ascend.type) {
+ case ASCEND_PFX_ISDN_X:
+ pseudo_head->isdn.uton = TRUE;
+ pseudo_head->isdn.channel = 0;
+ break;
+
+ case ASCEND_PFX_ISDN_R:
+ pseudo_head->isdn.uton = FALSE;
+ pseudo_head->isdn.channel = 0;
+ break;
+
+ case ASCEND_PFX_ETHER:
+ pseudo_head->eth.fcs_len = 0;
+ break;
+ }
+}
+
+/* Read the next packet; called from wtap_read(). */
+static gboolean ascend_read(wtap *wth, int *err, gchar **err_info,
+ gint64 *data_offset)
+{
+ gint64 offset;
+ guint8 *buf = buffer_start_ptr(wth->frame_buffer);
+ ascend_pkthdr header;
+
+ /* parse_ascend() will advance the point at which to look for the next
+ packet's header, to just after the last packet's header (ie. at the
+ start of the last packet's data). We have to get past the last
+ packet's header because we might mistake part of it for a new header. */
+ if (file_seek(wth->fh, wth->capture.ascend->next_packet_seek_start,
+ SEEK_SET, err) == -1)
+ return FALSE;
+
+ offset = ascend_seek(wth, err);
+ if (offset == -1)
+ return FALSE;
+ if (! parse_ascend(wth->fh, buf, &wth->pseudo_header.ascend, &header, &(wth->capture.ascend->next_packet_seek_start))) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup((ascend_parse_error != NULL) ? ascend_parse_error : "parse error");
+ return FALSE;
+ }
+
+ buffer_assure_space(wth->frame_buffer, wth->snapshot_length);
+
+ config_pseudo_header(&wth->pseudo_header);
+
+ if (! wth->capture.ascend->adjusted) {
+ wth->capture.ascend->adjusted = 1;
+ if (header.start_time != 0) {
+ /*
+ * Capture file contained a date and time.
+ * We do this only if this is the very first packet we've seen -
+ * i.e., if "wth->capture.ascend->adjusted" is false - because
+ * if we get a date and time after the first packet, we can't
+ * go back and adjust the time stamps of the packets we've already
+ * processed, and basing the time stamps of this and following
+ * packets on the time stamp from the file text rather than the
+ * ctime of the capture file means times before this and after
+ * this can't be compared.
+ */
+ wth->capture.ascend->inittime = header.start_time;
+ }
+ if (wth->capture.ascend->inittime > header.secs)
+ wth->capture.ascend->inittime -= header.secs;
+ }
+ wth->phdr.ts.secs = header.secs + wth->capture.ascend->inittime;
+ wth->phdr.ts.nsecs = header.usecs * 1000;
+ wth->phdr.caplen = header.caplen;
+ wth->phdr.len = header.len;
+ wth->data_offset = offset;
+
+ *data_offset = offset;
+ return TRUE;
+}
+
+static gboolean ascend_seek_read(wtap *wth, gint64 seek_off,
+ union wtap_pseudo_header *pseudo_head, guint8 *pd, int len,
+ int *err, gchar **err_info)
+{
+ /* don't care for length. */
+ (void) len;
+
+ if (file_seek(wth->random_fh, seek_off, SEEK_SET, err) == -1)
+ return FALSE;
+ if (! parse_ascend(wth->random_fh, pd, &pseudo_head->ascend, NULL, &(wth->capture.ascend->next_packet_seek_start))) {
+ *err = WTAP_ERR_BAD_RECORD;
+ *err_info = g_strdup((ascend_parse_error != NULL) ? ascend_parse_error : "parse error");
+ return FALSE;
+ }
+
+ config_pseudo_header(pseudo_head);
+ return TRUE;
+}
+
+static void ascend_close(wtap *wth)
+{
+ g_free(wth->capture.ascend);
+}