From 70481fcc846e1455adcc5fa50b02cad71b28b966 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Sat, 11 Sep 1999 04:53:26 +0000 Subject: Add in ascend.c, ascend.h, ascend-grammar.y and ascend-scanner.l. These read and parse the Lucent/Ascend trace output. svn path=/trunk/; revision=653 --- wiretap/ascend.c | 186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 wiretap/ascend.c (limited to 'wiretap/ascend.c') 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 + * + * 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 +#include +#include +#include + +/* 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); +} -- cgit v1.2.3