aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--wiretap/ascend-grammar.y184
-rw-r--r--wiretap/ascend-scanner.l129
-rw-r--r--wiretap/ascend.c186
-rw-r--r--wiretap/ascend.h50
4 files changed, 549 insertions, 0 deletions
diff --git a/wiretap/ascend-grammar.y b/wiretap/ascend-grammar.y
new file mode 100644
index 0000000000..a726be8fe8
--- /dev/null
+++ b/wiretap/ascend-grammar.y
@@ -0,0 +1,184 @@
+/*
+ Example 'wandsess' output data:
+
+RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94
+ [0000]: FF 03 00 3D C0 06 CA 22 2F 45 00 00 28 6A 3B 40
+ [0010]: 00 3F 03 D7 37 CE 41 62 12 CF 00 FB 08 20 27 00
+ [0020]: 50 E4 08 DD D7 7C 4C 71 92 50 10 7D 78 67 C8 00
+ [0030]: 00
+XMIT-iguana:241:(task: B04E12C0, time: 1975432.85) 53 octets @ 8009EB16
+ [0000]: FF 03 00 3D C0 09 1E 31 21 45 00 00 2C 2D BD 40
+ [0010]: 00 7A 06 D8 B1 CF 00 FB 08 CE 41 62 12 00 50 20
+ [0020]: 29 7C 4C 71 9C 9A 6A 93 A4 60 12 22 38 3F 10 00
+ [0030]: 00 02 04 05 B4
+ */
+
+%{
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "wtap.h"
+#include "buffer.h"
+#include "ascend.h"
+
+#define NFH_PATH "/dev/null"
+
+extern void ascend_init_lexer(FILE *fh, FILE *nfh);
+extern int at_eof;
+
+int yyparse(void);
+void yyerror(char *);
+
+int bcur = 0, bcount;
+guint32 secs, usecs, caplen, wirelen;
+ascend_pkthdr header;
+char *pkt_data;
+FILE *nfh = NULL;
+
+%}
+
+%union {
+gchar *s;
+guint32 d;
+char b;
+}
+
+%token <s> USERNAME HEXNUM KEYWORD COUNTER
+%token <d> PREFIX SESSNUM TASKNUM TIMEVAL OCTETS
+%token <b> BYTE
+
+%type <s> username hexnum dataln datagroup
+%type <d> prefix sessnum tasknum timeval octets
+%type <b> byte bytegroup
+
+%%
+
+data_packet:
+ | header datagroup
+;
+
+prefix: PREFIX;
+
+username: USERNAME;
+
+sessnum: SESSNUM;
+
+tasknum: TASKNUM;
+
+timeval: TIMEVAL;
+
+octets: OCTETS;
+
+hexnum: HEXNUM;
+
+/* 1 2 3 4 5 6 7 8 9 10 11 */
+header: prefix username sessnum KEYWORD tasknum KEYWORD timeval timeval octets KEYWORD HEXNUM {
+ wirelen = $9;
+ caplen = ($9 < ASCEND_MAX_PKT_LEN) ? $9 : ASCEND_MAX_PKT_LEN;
+ if (bcount > 0 && bcount <= caplen)
+ caplen = bcount;
+ else
+ secs = $7;
+ usecs = $8;
+ /* header.user is set in ascend-scanner.l */
+ header.type = $1;
+ header.sess = $3;
+ header.task = $5;
+
+ bcur = 0;
+}
+;
+
+byte: BYTE {
+ if (bcur < caplen) {
+ pkt_data[bcur + ASCEND_PKTHDR_OFFSET] = $1;
+ bcur++;
+ }
+
+ if (bcur >= caplen) {
+ header.secs = secs;
+ header.usecs = usecs;
+ header.caplen = caplen;
+ header.len = wirelen;
+ memcpy(pkt_data, &header, ASCEND_PKTHDR_OFFSET);
+ YYACCEPT;
+ }
+}
+;
+
+/* There must be a better way to do this... */
+bytegroup: byte
+ | byte byte
+ | byte byte byte
+ | byte byte byte byte
+ | byte byte byte byte byte
+ | byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
+ | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
+;
+
+dataln: COUNTER bytegroup;
+
+datagroup: dataln
+ | dataln dataln
+ | dataln dataln dataln
+ | dataln dataln dataln dataln
+ | dataln dataln dataln dataln dataln
+ | dataln dataln dataln dataln dataln dataln
+ | dataln dataln dataln dataln dataln dataln dataln
+ | dataln dataln dataln dataln dataln dataln dataln dataln
+;
+
+%%
+
+void
+init_parse_ascend()
+{
+ bcur = 0;
+ at_eof = 0;
+
+ /* In order to keep flex from printing a lot of newlines while reading
+ the capture data, we open up /dev/null and point yyout at the null
+ file handle. */
+ if (! nfh) {
+ nfh = fopen(NFH_PATH, "r");
+ }
+}
+
+/* Parse the capture file. Return the offset of the next packet, or zero
+ if there is none. */
+int
+parse_ascend(FILE *fh, void *pd, int len)
+{
+ int res;
+
+ /* yydebug = 1; */
+
+ ascend_init_lexer(fh, nfh);
+ pkt_data = pd;
+ bcount = len;
+
+ /* Skip errors until we get something parsed. */
+ if (yyparse())
+ return 0;
+ else
+ return 1;
+}
+
+void
+yyerror (char *s)
+{
+ /* fprintf (stderr, "%s\n", s); */
+}
diff --git a/wiretap/ascend-scanner.l b/wiretap/ascend-scanner.l
new file mode 100644
index 0000000000..e70f162778
--- /dev/null
+++ b/wiretap/ascend-scanner.l
@@ -0,0 +1,129 @@
+%{
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "wtap.h"
+#include "ascend.h"
+#include "ascend-grammar.h"
+
+extern ascend_pkthdr header;
+
+int at_eof;
+int mul, scratch;
+%}
+
+/* %option debug */
+%option nostdinit
+
+D [0-9]
+H [A-Fa-f0-9]
+
+XPFX XMIT-
+RPFX RECV-
+EPFX "ETHER "
+
+%s sc_user
+%s sc_sess
+%s sc_task
+%s sc_time_s
+%s sc_time_u
+%s sc_octets
+%s sc_counter
+%s sc_byte
+
+%%
+
+<INITIAL,sc_byte>{EPFX} {
+ BEGIN(sc_user);
+ ascendlval.d = ASCEND_PFX_ETHER;
+ return PREFIX;
+}
+
+<INITIAL,sc_byte>{XPFX} {
+ BEGIN(sc_user);
+ ascendlval.d = ASCEND_PFX_PPP_X;
+ return PREFIX;
+}
+
+<INITIAL,sc_byte>{RPFX} {
+ BEGIN(sc_user);
+ ascendlval.d = ASCEND_PFX_PPP_R;
+ return PREFIX;
+}
+
+<sc_user>[^:]+ {
+ BEGIN(sc_sess);
+ strncpy(header.user, ascendtext, ASCEND_MAX_STR_LEN);
+ header.user[ASCEND_MAX_STR_LEN - 1] = '\0';
+ return USERNAME;
+}
+
+<sc_sess>{D}+ {
+ BEGIN(sc_task);
+ ascendlval.d = strtol(ascendtext, NULL, 10);
+ return SESSNUM;
+}
+
+<sc_task>{H}+ {
+ BEGIN(sc_time_s);
+ ascendlval.d = strtoul(ascendtext, NULL, 16);
+ return TASKNUM;
+}
+
+<sc_time_s>{D}+ {
+ BEGIN(sc_time_u);
+ ascendlval.d = strtol(ascendtext, NULL, 10);
+ return TIMEVAL;
+}
+
+<sc_time_u>{D}+ {
+ BEGIN(sc_octets);
+ /* We have the fractional portion of the time. We want it converted
+ to microseconds. */
+ mul = 1000000;
+ ascendlval.d = strtol(ascendtext, NULL, 10);
+ for (scratch = ascendlval.d; scratch > 0; scratch /= 10)
+ mul /= 10;
+ ascendlval.d *= mul;
+ return TIMEVAL;
+}
+
+<sc_octets>{D}+ {
+ BEGIN(sc_counter);
+ ascendlval.d = strtol(ascendtext, NULL, 10);
+ return OCTETS;
+}
+
+<sc_counter,sc_byte>"["{H}{4}"]:" {
+ BEGIN(sc_byte);
+ return COUNTER;
+}
+
+<sc_byte>{H}{2} {
+ ascendlval.b = strtol(ascendtext, NULL, 16);
+ return BYTE;
+}
+
+{H}+ { return HEXNUM; }
+
+task:|time:|octets { return KEYWORD; }
+
+<<EOF>> { at_eof++; yyterminate(); }
+
+. ;
+
+%%
+
+int ascendwrap() { return 1; };
+
+void ascend_init_lexer(FILE *fh, FILE *nfh)
+{
+ yyin = fh;
+ yyout = nfh;
+ yyrestart(fh);
+ BEGIN(INITIAL);
+}
diff --git a/wiretap/ascend.c b/wiretap/ascend.c
new file mode 100644
index 0000000000..a225e64dba
--- /dev/null
+++ b/wiretap/ascend.c
@@ -0,0 +1,186 @@
+/* ascend.c
+ *
+ * $Id: ascend.c,v 1.1 1999/09/11 04:53:26 gerald Exp $
+ *
+ * Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.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.h"
+#include "buffer.h"
+#include "ascend.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+
+/* This module reads the output of the 'wandsession', 'wannext',
+ 'wandisplay', and similar commands available on Lucent/Ascend access
+ equipment. The output is text, with a header line followed by the
+ packet data. Usage instructions for the commands can be found by
+ searching http://aos.ascend.com . Ascend likes to move their pages
+ around quite a bit, otherwise I'd put a more specific URL here.
+
+ Example 'wandsess' output data:
+
+RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94
+ [0000]: FF 03 00 3D C0 06 CA 22 2F 45 00 00 28 6A 3B 40
+ [0010]: 00 3F 03 D7 37 CE 41 62 12 CF 00 FB 08 20 27 00
+ [0020]: 50 E4 08 DD D7 7C 4C 71 92 50 10 7D 78 67 C8 00
+ [0030]: 00
+XMIT-iguana:241:(task: B04E12C0, time: 1975432.85) 53 octets @ 8009EB16
+ [0000]: FF 03 00 3D C0 09 1E 31 21 45 00 00 2C 2D BD 40
+ [0010]: 00 7A 06 D8 B1 CF 00 FB 08 CE 41 62 12 00 50 20
+ [0020]: 29 7C 4C 71 9C 9A 6A 93 A4 60 12 22 38 3F 10 00
+ [0030]: 00 02 04 05 B4
+
+ Note that a maximum of eight rows will be displayed (for a maximum of
+ 128 bytes), no matter what the octet count is.
+
+ When reading a packet, the module prepends an ascend_pkt_hdr to the
+ data.
+
+ */
+
+/* How far into the file we should look for packet headers */
+#define ASCEND_MAX_SEEK 1000000
+
+/* Magic numbers for Ascend wandsession/wanopening/ether-display data */
+static const char ascend_xmagic[] = { 'X', 'M', 'I', 'T', '-' };
+static const char ascend_rmagic[] = { 'R', 'E', 'C', 'V', '-' };
+static const char ascend_emagic[] = { 'E', 'T', 'H', 'E', 'R', ' ' };
+
+#define ASCEND_X_SIZE (sizeof ascend_xmagic / sizeof ascend_xmagic[0])
+#define ASCEND_R_SIZE (sizeof ascend_rmagic / sizeof ascend_rmagic[0])
+#define ASCEND_E_SIZE (sizeof ascend_emagic / sizeof ascend_emagic[0])
+
+/* Seeks to the beginning of the next packet, and returns the
+ byte offset. Returns 0 on failure. A valid offset is 0; since
+ that causes problems with wtap_loop, offsets are incremented by one. */
+/* XXX - Handle I/O errors. */
+int ascend_seek(wtap *wth, int max_seek)
+{
+ int byte, bytes_read = 0;
+ int x_level = 0, r_level = 0, e_level = 0;
+
+ while (((byte = fgetc(wth->fh)) != EOF) && bytes_read < max_seek) {
+ if (byte == ascend_xmagic[x_level]) {
+ x_level++;
+ if (x_level >= ASCEND_X_SIZE) {
+ fseek(wth->fh, -(ASCEND_X_SIZE), SEEK_CUR);
+ return ftell(wth->fh) + 1;
+ }
+ } else if (byte == ascend_rmagic[r_level]) {
+ r_level++;
+ if (r_level >= ASCEND_R_SIZE) {
+ fseek(wth->fh, -(ASCEND_R_SIZE), SEEK_CUR);
+ return ftell(wth->fh) + 1;
+ }
+ } else if (byte == ascend_emagic[e_level]) {
+ e_level++;
+ if (e_level >= ASCEND_E_SIZE) {
+ fseek(wth->fh, -(ASCEND_E_SIZE), SEEK_CUR);
+ return ftell(wth->fh) + 1;
+ }
+ } else {
+ x_level = r_level = e_level = 0;
+ }
+ bytes_read++;
+ }
+ return -1;
+}
+
+/* XXX - return -1 on I/O error and actually do something with 'err'. */
+int ascend_open(wtap *wth, int *err)
+{
+ int offset;
+ struct stat statbuf;
+
+ fseek(wth->fh, 0, SEEK_SET);
+ offset = ascend_seek(wth, ASCEND_MAX_SEEK);
+ if (offset < 1) {
+ return 0;
+ }
+
+ wth->data_offset = offset;
+ wth->file_encap = WTAP_ENCAP_ASCEND;
+ wth->file_type = WTAP_FILE_ASCEND;
+ wth->snapshot_length = ASCEND_MAX_PKT_LEN;
+ wth->subtype_read = ascend_read;
+ wth->capture.ascend = g_malloc(sizeof(ascend_t));
+
+ fstat(fileno(wth->fh), &statbuf);
+ wth->capture.ascend->inittime = statbuf.st_ctime;
+ wth->capture.ascend->adjusted = 0;
+ wth->capture.ascend->seek_add = -1;
+
+ init_parse_ascend();
+
+ return 1;
+}
+
+/* Read the next packet; called from wtap_loop(). */
+static int ascend_read(wtap *wth, int *err)
+{
+ int offset;
+ guint8 *buf = buffer_start_ptr(wth->frame_buffer);
+ ascend_pkthdr header;
+
+ /* (f)lex reads large chunks of the file into memory, so ftell() doesn't
+ give us the correct location of the packet. Instead, we seek to the
+ location of the last packet and try to find the next packet. In
+ addition, we fool around with the seek offset in case a valid packet
+ starts at the beginning of the file. */
+ fseek(wth->fh, wth->data_offset + wth->capture.ascend->seek_add, SEEK_SET);
+ wth->capture.ascend->seek_add = 0;
+ offset = ascend_seek(wth, ASCEND_MAX_SEEK);
+ if (offset < 1) {
+ return 0;
+ }
+ if (! parse_ascend(wth->fh, buf, 0)) {
+ *err = WTAP_ERR_BAD_RECORD;
+ return -1;
+ }
+
+ buffer_assure_space(wth->frame_buffer, wth->snapshot_length +
+ ASCEND_PKTHDR_OFFSET);
+
+ memcpy(&header, buf, ASCEND_PKTHDR_OFFSET);
+ if (! wth->capture.ascend->adjusted) {
+ wth->capture.ascend->adjusted = 1;
+ if (wth->capture.ascend->inittime > header.secs)
+ wth->capture.ascend->inittime -= header.secs;
+ }
+ wth->phdr.ts.tv_sec = header.secs + wth->capture.ascend->inittime;
+ wth->phdr.ts.tv_usec = header.usecs;
+ wth->phdr.caplen = header.caplen;
+ wth->phdr.len = header.len;
+ wth->phdr.pkt_encap = wth->file_encap;
+ wth->data_offset = offset;
+
+ return offset;
+}
+
+int ascend_seek_read (FILE *fh, int seek_off, guint8 *pd, int len)
+{
+ fseek(fh, seek_off - 1, SEEK_SET);
+ return parse_ascend(fh, pd, len);
+}
diff --git a/wiretap/ascend.h b/wiretap/ascend.h
new file mode 100644
index 0000000000..ab43fd3962
--- /dev/null
+++ b/wiretap/ascend.h
@@ -0,0 +1,50 @@
+/* ascend.h
+ *
+ * $Id: ascend.h,v 1.1 1999/09/11 04:53:26 gerald Exp $
+ *
+ * Wiretap Library
+ * Copyright (c) 1998 by Gilbert Ramirez <gram@verdict.uthscsa.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.
+ *
+ */
+
+#define ASCEND_MAX_STR_LEN 64
+#define ASCEND_MAX_DATA_ROWS 8
+#define ASCEND_MAX_DATA_COLS 16
+#define ASCEND_MAX_PKT_LEN (ASCEND_MAX_DATA_ROWS * ASCEND_MAX_DATA_COLS)
+
+#define ASCEND_PFX_ETHER 1
+#define ASCEND_PFX_PPP_X 2
+#define ASCEND_PFX_PPP_R 3
+
+typedef struct {
+ guint16 type; /* ASCEND_PFX_*, as defined above */
+ char user[ASCEND_MAX_STR_LEN]; /* Username, from header */
+ guint32 sess; /* Session number */
+ guint32 task; /* Task number */
+ guint32 secs;
+ guint32 usecs;
+ guint32 caplen;
+ guint32 len;
+} ascend_pkthdr;
+
+#define ASCEND_PKTHDR_OFFSET sizeof(ascend_pkthdr)
+
+int ascend_open(wtap *wth, int *err);
+static int ascend_read(wtap *wth, int *err);
+void init_parse_ascend();
+int parse_ascend(FILE *fh, void *pd, int len);
+int ascend_seek_read (FILE *fh, int seek_off, guint8 *pd, int len);