diff options
author | Gerald Combs <gerald@wireshark.org> | 1999-09-11 04:53:26 +0000 |
---|---|---|
committer | Gerald Combs <gerald@wireshark.org> | 1999-09-11 04:53:26 +0000 |
commit | 70481fcc846e1455adcc5fa50b02cad71b28b966 (patch) | |
tree | bd279c84be5cf7a85b77c3f0b5d4cd7930b82a1b | |
parent | 9386f23feeb16591875734ba98c32604c9f44441 (diff) | |
download | wireshark-70481fcc846e1455adcc5fa50b02cad71b28b966.tar.gz wireshark-70481fcc846e1455adcc5fa50b02cad71b28b966.tar.bz2 wireshark-70481fcc846e1455adcc5fa50b02cad71b28b966.zip |
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
-rw-r--r-- | wiretap/ascend-grammar.y | 184 | ||||
-rw-r--r-- | wiretap/ascend-scanner.l | 129 | ||||
-rw-r--r-- | wiretap/ascend.c | 186 | ||||
-rw-r--r-- | wiretap/ascend.h | 50 |
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); |