aboutsummaryrefslogtreecommitdiffstats
path: root/wiretap
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2005-02-05 17:39:12 +0000
committerGerald Combs <gerald@wireshark.org>2005-02-05 17:39:12 +0000
commit9e93bf474710d9ef0eb4ba33bde284b6685fd360 (patch)
tree59d8d2204fb8fef65bf8a637ed5c4284558230fc /wiretap
parent17608107ff86cd057a7a46983616a01b4ff25cd8 (diff)
From Josh Bailey:
Attached is an update to Lucent/Ascend trace parsing: fix a few bugs, add support for ISDN and Ethernet captures - diffs to 0.10.9. svn path=/trunk/; revision=13311
Diffstat (limited to 'wiretap')
-rw-r--r--wiretap/ascend-grammar.y228
-rw-r--r--wiretap/ascend-int.h2
-rw-r--r--wiretap/ascend-scanner.l75
-rw-r--r--wiretap/ascend.c288
-rw-r--r--wiretap/wtap.h3
5 files changed, 363 insertions, 233 deletions
diff --git a/wiretap/ascend-grammar.y b/wiretap/ascend-grammar.y
index 323b5c497d..50dc36d6cf 100644
--- a/wiretap/ascend-grammar.y
+++ b/wiretap/ascend-grammar.y
@@ -23,7 +23,32 @@
*/
/*
- Example 'wandsess' output data:
+ Example 'pridisp' output data - one paragraph/frame:
+
+PRI-XMIT-27: (task "l1Task" at 0x10216fe0, time: 560194.01) 4 octets @ 0x1027c5b0
+ [0000]: 00 01 01 a9 ....
+PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00
+ [0000]: 00 01 01 dd
+
+ Example 'pridisp' output data - two paragraphs/frame for XMIT case only:
+
+PRI-XMIT-19/1: (task "l1Task" at 0x10216840, time: 274759.98) 4 octets @ 0x1027f230
+ [0000]: 00 01 30 d8 ..0.
+PRI-XMIT-19/2 (task "l1Task" at 0x10216840, time: 274759.98) 11 octets @ 0x1027f234
+ [0000]: 08 02 8c bf 02 18 04 e9 82 83 8f ........ ...
+
+ Example 'ether-disp' output data:
+
+ETHER3ND RECV: (task "_sarTask" at 0x802c6eb0, time: 259848.03) 775 octets @ 0xa8fb2020
+ [0000]: 00 d0 52 04 e7 1e 08 00 20 ae 51 b5 08 00 45 00 ..R..... .Q...E.
+ [0010]: 02 f9 05 e6 40 00 3f 11 6e 39 87 fe c4 95 3c 3c ....@.?. n9....<<
+ [0020]: 3c 05 13 c4 13 c4 02 e5 ef ed 49 4e 56 49 54 45 <....... ..INVITE
+ [0030]: 20 73 69 70 3a 35 32 30 37 33 40 36 30 2e 36 30 sip:520 73@60.60
+ [0040]: 2e 36 30 2e 35 20 53 49 50 2f 32 2e 30 0d 0a 56 .60.5 SI P/2.0..V
+ [0050]: 69 61 3a 20 53 49 50 2f 32 2e 30 2f 55 44 50 20 ia: SIP/ 2.0/UDP
+ [0060]: 31 33 35 2e 135.
+
+ 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
@@ -109,11 +134,13 @@ XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 20 octet
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "wtap-int.h"
#include "buffer.h"
#include "ascend.h"
#include "ascend-int.h"
+#include "file_wrappers.h"
#define NO_USER "<none>"
@@ -122,11 +149,13 @@ void yyerror(char *);
gchar *ascend_parse_error;
-static unsigned int bcur = 0, bcount;
+static unsigned int bcur;
static guint32 start_time, secs, usecs, caplen, wirelen;
static ascend_pkthdr *header;
struct ascend_phdr *pseudo_header;
static guint8 *pkt_data;
+static long first_hexbyte;
+static FILE_T *fh_ptr;
%}
@@ -136,17 +165,20 @@ guint32 d;
guint8 b;
}
-%token <s> STRING KEYWORD WDD_DATE WDD_CHUNK COUNTER
-%token <d> WDS_PREFIX DECNUM HEXNUM
+%token <s> STRING KEYWORD WDD_DATE WDD_CHUNK COUNTER SLASH_SUFFIX
+%token <d> WDS_PREFIX ISDN_PREFIX ETHER_PREFIX DECNUM HEXNUM
%token <b> HEXBYTE
-%type <s> string dataln datagroup
-%type <d> wds_prefix decnum hexnum
+%type <s> string dataln datagroup
+%type <d> wds_prefix isdn_prefix ether_prefix decnum hexnum
%type <b> byte bytegroup
%%
data_packet:
+ | ether_hdr datagroup
+ | deferred_isdn_hdr datagroup deferred_isdn_hdr datagroup
+ | isdn_hdr datagroup
| wds_hdr datagroup
| wds8_hdr datagroup
| wdp7_hdr datagroup
@@ -155,6 +187,10 @@ data_packet:
| wdd_hdr datagroup
;
+isdn_prefix: ISDN_PREFIX;
+
+ether_prefix: ETHER_PREFIX;
+
wds_prefix: WDS_PREFIX;
string: STRING;
@@ -163,16 +199,80 @@ decnum: DECNUM;
hexnum: HEXNUM;
+/*
+ pridisp special case - I-frame header printed separately from contents,
+ one frame across two messages.
+
+PRI-XMIT-0/1: (task "l1Task" at 0x80152b20, time: 283529.65) 4 octets @
+0x80128220
+ [0000]: 00 01 ae b2 ....
+PRI-XMIT-0/2 (task "l1Task" at 0x80152b20, time: 283529.65) 10 octets @
+0x80128224
+ [0000]: 08 02 d7 e3 02 18 03 a9 83 8a ........
+
+*/
+deferred_isdn_hdr: isdn_prefix decnum SLASH_SUFFIX KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
+ wirelen += $11;
+ caplen += $11;
+ secs = $9;
+ usecs = $10;
+ if (pseudo_header != NULL) {
+ pseudo_header->type = $1;
+ pseudo_header->sess = $2;
+ pseudo_header->call_num[0] = '\0';
+ pseudo_header->chunk = 0;
+ pseudo_header->task = $7;
+ }
+ /* because we have two data groups */
+ first_hexbyte = 0;
+}
+;
+
+/*
+PRI-XMIT-19: (task "l1Task" at 0x10216840, time: 274758.67) 4 octets @ 0x1027c1c0
+ ... or ...
+PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00
+*/
+isdn_hdr: isdn_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
+ wirelen = $10;
+ caplen = $10;
+ secs = $8;
+ usecs = $9;
+ if (pseudo_header != NULL) {
+ pseudo_header->type = $1;
+ pseudo_header->sess = $2;
+ pseudo_header->call_num[0] = '\0';
+ pseudo_header->chunk = 0;
+ pseudo_header->task = $6;
+ }
+ first_hexbyte = 0;
+}
+;
+
+/*
+ETHER3ND XMIT: (task "_sarTask" at 0x802c6eb0, time: 259848.11) 414 octets @ 0xa
+885f80e
+*/
+ether_hdr: ether_prefix string KEYWORD string KEYWORD hexnum KEYWORD decnum decnum
+ decnum KEYWORD HEXNUM {
+ wirelen = $10;
+ caplen = $10;
+ secs = $8;
+ usecs = $9;
+ if (pseudo_header != NULL) {
+ pseudo_header->type = $1;
+ pseudo_header->call_num[0] = '\0';
+ pseudo_header->chunk = 0;
+ pseudo_header->task = $6;
+ }
+}
+;
+
/* RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 */
/* 1 2 3 4 5 6 7 8 9 10 11 */
wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
wirelen = $9;
- caplen = ($9 < ASCEND_MAX_PKT_LEN) ? $9 : ASCEND_MAX_PKT_LEN;
- /* If we don't have as many bytes of data as the octet count in
- the header, make the capture length the number of bytes we
- actually have. */
- if (bcount > 0 && bcount <= caplen)
- caplen = bcount;
+ caplen = $9;
secs = $7;
usecs = $8;
if (pseudo_header != NULL) {
@@ -183,8 +283,6 @@ wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KE
pseudo_header->chunk = 0;
pseudo_header->task = $5;
}
-
- bcur = 0;
}
;
@@ -192,12 +290,7 @@ wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KE
/* 1 2 3 4 5 6 7 8 9 10 11 12 13 */
wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
wirelen = $11;
- caplen = ($11 < ASCEND_MAX_PKT_LEN) ? $11 : ASCEND_MAX_PKT_LEN;
- /* If we don't have as many bytes of data as the octet count in
- the header, make the capture length the number of bytes we
- actually have. */
- if (bcount > 0 && bcount <= caplen)
- caplen = bcount;
+ caplen = $11;
secs = $9;
usecs = $10;
if (pseudo_header != NULL) {
@@ -208,8 +301,6 @@ wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum
pseudo_header->chunk = 0;
pseudo_header->task = $7;
}
-
- bcur = 0;
}
;
@@ -217,12 +308,7 @@ wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum
/* 1 2 3 4 5 6 7 8 9 10 */
wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
wirelen = $8;
- caplen = ($8 < ASCEND_MAX_PKT_LEN) ? $8 : ASCEND_MAX_PKT_LEN;
- /* If we don't have as many bytes of data as the octet count in
- the header, make the capture length the number of bytes we
- actually have. */
- if (bcount > 0 && bcount <= caplen)
- caplen = bcount;
+ caplen = $8;
secs = $6;
usecs = $7;
if (pseudo_header != NULL) {
@@ -233,8 +319,6 @@ wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD
pseudo_header->chunk = 0;
pseudo_header->task = $4;
}
-
- bcur = 0;
}
;
@@ -242,12 +326,7 @@ wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD
/* 1 2 3 4 5 6 7 8 9 10 11 12 */
wdp8_hdr: wds_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
wirelen = $10;
- caplen = ($10 < ASCEND_MAX_PKT_LEN) ? $10 : ASCEND_MAX_PKT_LEN;
- /* If we don't have as many bytes of data as the octet count in
- the header, make the capture length the number of bytes we
- actually have. */
- if (bcount > 0 && bcount <= caplen)
- caplen = bcount;
+ caplen = $10;
secs = $8;
usecs = $9;
if (pseudo_header != NULL) {
@@ -258,8 +337,6 @@ wdp8_hdr: wds_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum
pseudo_header->chunk = 0;
pseudo_header->task = $6;
}
-
- bcur = 0;
}
;
@@ -286,7 +363,7 @@ wdd_date: WDD_DATE decnum decnum decnum KEYWORD decnum decnum decnum KEYWORD str
start_time = mktime(&wddt);
}
;
-
+
/*
WD_DIALOUT_DISP: chunk 2515EE type IP.
(task: 251790, time: 994953.28) 44 octets @ 2782B8
@@ -294,12 +371,7 @@ WD_DIALOUT_DISP: chunk 2515EE type IP.
/* 1 2 3 4 5 6 7 8 9 10 11*/
wdd_hdr: WDD_CHUNK hexnum KEYWORD KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
wirelen = $9;
- caplen = ($9 < ASCEND_MAX_PKT_LEN) ? $9 : ASCEND_MAX_PKT_LEN;
- /* If we don't have as many bytes of data as the octet count in
- the header, make the capture length the number of bytes we
- actually have. */
- if (bcount > 0 && bcount <= caplen)
- caplen = bcount;
+ caplen = $9;
secs = $7;
usecs = $8;
if (pseudo_header != NULL) {
@@ -310,27 +382,23 @@ wdd_hdr: WDD_CHUNK hexnum KEYWORD KEYWORD hexnum KEYWORD decnum decnum decnum KE
pseudo_header->chunk = $2;
pseudo_header->task = $5;
}
-
- bcur = 0;
}
;
byte: HEXBYTE {
+ /* remember the position of the data group in the trace, to tip
+ off ascend_seek() as to where to look for the next header. */
+ if (first_hexbyte == 0)
+ first_hexbyte = file_tell(*fh_ptr);
+
if (bcur < caplen) {
pkt_data[bcur] = $1;
bcur++;
}
- if (bcur >= caplen) {
- if (header != NULL) {
- header->start_time = start_time;
- header->secs = secs;
- header->usecs = usecs;
- header->caplen = caplen;
- header->len = wirelen;
- }
+ /* arbitrary safety maximum... */
+ if (bcur >= ASCEND_MAX_PKT_LEN)
YYACCEPT;
- }
}
;
@@ -370,7 +438,6 @@ datagroup: dataln
void
init_parse_ascend()
{
- bcur = 0;
at_eof = 0;
start_time = 0; /* we haven't see a date/time yet */
}
@@ -379,16 +446,21 @@ init_parse_ascend()
if there is none. */
int
parse_ascend(FILE_T fh, guint8 *pd, struct ascend_phdr *phdr,
- ascend_pkthdr *hdr, int len)
+ ascend_pkthdr *hdr, long *start_of_data)
{
/* yydebug = 1; */
-
+ int retval;
ascend_init_lexer(fh);
pkt_data = pd;
pseudo_header = phdr;
header = hdr;
- bcount = len;
-
+ fh_ptr = &fh;
+
+ bcur = 0;
+ first_hexbyte = 0;
+ wirelen = 0;
+ caplen = 0;
+
/*
* Not all packets in a "wdd" dump necessarily have a "Cause an
* attempt to place call to" header (I presume this can happen if
@@ -402,9 +474,39 @@ parse_ascend(FILE_T fh, guint8 *pd, struct ascend_phdr *phdr,
*/
pseudo_header->call_num[0] = '\0';
- if (yyparse())
- return 0;
+ retval = yyparse();
+
+ caplen = bcur;
+
+ /* did we see any data (hex bytes)? if so, tip off ascend_seek()
+ as to where to look for the next packet, if any. If we didn't,
+ maybe this record was broken. Advance so we don't get into
+ an infinite loop reading a broken trace. */
+ if (first_hexbyte)
+ *start_of_data = first_hexbyte;
else
+ *start_of_data++;
+
+ /* if we got at least some data, return success even if the parser
+ reported an error. This is because the debug header gives the number
+ of bytes on the wire, not actually how many bytes are in the trace.
+ We won't know where the data ends until we run into the next packet. */
+ if (caplen) {
+ if (header) {
+ header->start_time = start_time;
+ header->secs = secs;
+ header->usecs = usecs;
+ header->caplen = caplen;
+ header->len = wirelen;
+ }
+
+ return 1;
+ }
+
+ /* Didn't see any data. Still, perhaps the parser was happy. */
+ if (retval)
+ return 0;
+ else
return 1;
}
diff --git a/wiretap/ascend-int.h b/wiretap/ascend-int.h
index 137984cf5f..f46825db7d 100644
--- a/wiretap/ascend-int.h
+++ b/wiretap/ascend-int.h
@@ -49,6 +49,6 @@ int ascendlex(void);
void init_parse_ascend(void);
void ascend_init_lexer(FILE_T fh);
int parse_ascend(FILE_T fh, guint8 *pd, struct ascend_phdr *phdr,
- ascend_pkthdr *hdr, int len);
+ ascend_pkthdr *hdr, long *start_of_data);
#endif /* ! __ASCEND_INT_H__ */
diff --git a/wiretap/ascend-scanner.l b/wiretap/ascend-scanner.l
index 0f3658f6b8..655db6254e 100644
--- a/wiretap/ascend-scanner.l
+++ b/wiretap/ascend-scanner.l
@@ -56,17 +56,22 @@ int mul, scratch;
#define YY_NO_UNISTD_H
#endif
+
%}
-/* %option debug */
%option nostdinit
%option noyywrap
D [0-9]
H [A-Fa-f0-9]
-XPFX XMIT-
-RPFX RECV-
+PPP_XPFX PPP-IN
+PPP_RPFX PPP-OUT
+ISDN_XPFX PRI-XMIT-
+ISDN_RPFX PRI-RCV-
+WAN_XPFX XMIT[\-:]*
+WAN_RPFX RECV[\-:]*
+ETHER_PFX ETHER
WDD_DATE "Date:"
WDD_TIME "Time:"
@@ -100,20 +105,63 @@ WDD_TYPE "type "[^\n\r\t ]+
%s sc_chardisp
+%s sc_isdn_call
+%s sc_ether_direction
+
%%
-<INITIAL,sc_gen_byte>{XPFX} {
+<INITIAL,sc_gen_byte>{ETHER_PFX} {
+ BEGIN(sc_ether_direction);
+ ascendlval.d = ASCEND_PFX_ETHER;
+ return ETHER_PREFIX;
+}
+
+<INITIAL,sc_gen_byte>{ISDN_XPFX} {
+ BEGIN(sc_isdn_call);
+ ascendlval.d = ASCEND_PFX_ISDN_X;
+ return ISDN_PREFIX;
+}
+
+<INITIAL,sc_gen_byte>{ISDN_RPFX} {
+ BEGIN(sc_isdn_call);
+ ascendlval.d = ASCEND_PFX_ISDN_R;
+ return ISDN_PREFIX;
+}
+
+<INITIAL,sc_gen_byte>{WAN_XPFX} {
BEGIN(sc_wds_user);
ascendlval.d = ASCEND_PFX_WDS_X;
return WDS_PREFIX;
}
-<INITIAL,sc_gen_byte>{RPFX} {
+<INITIAL,sc_gen_byte>{WAN_RPFX} {
BEGIN(sc_wds_user);
ascendlval.d = ASCEND_PFX_WDS_R;
return WDS_PREFIX;
}
+<INITIAL,sc_gen_byte>{PPP_XPFX} {
+ BEGIN(sc_wds_user);
+ ascendlval.d = ASCEND_PFX_WDS_X;
+ return WDS_PREFIX;
+}
+
+<INITIAL,sc_gen_byte>{PPP_RPFX} {
+ BEGIN(sc_wds_user);
+ ascendlval.d = ASCEND_PFX_WDS_R;
+ return WDS_PREFIX;
+}
+
+<sc_ether_direction>[^\(]+ {
+ BEGIN(sc_gen_task);
+ return STRING;
+}
+
+<sc_isdn_call>[^\/\(:]+ {
+ BEGIN(sc_gen_task);
+ return DECNUM;
+}
+
<sc_wds_user>[^:]+ {
char *atcopy = strdup(ascendtext);
char colon = input();
@@ -163,14 +211,13 @@ WDD_TYPE "type "[^\n\r\t ]+
}
<sc_gen_time_u>{D}+ {
+ char *atcopy = strdup(ascendtext);
BEGIN(sc_gen_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;
+ /* only want the most significant 2 digits. convert to usecs */
+ if (strlen(atcopy) > 2)
+ atcopy[2] = '\0';
+ ascendlval.d = strtol(atcopy, NULL, 10) * 10000;
+ free(atcopy);
return DECNUM;
}
@@ -274,6 +321,10 @@ WDD_TYPE "type "[^\n\r\t ]+
return KEYWORD;
}
+<sc_gen_task>\/{D}+ {
+ return SLASH_SUFFIX;
+}
+
(0x|0X)?{H}+ { return HEXNUM; }
task:|task|at|time:|octets { return KEYWORD; }
diff --git a/wiretap/ascend.c b/wiretap/ascend.c
index b145afb6e4..95ad5cd3c9 100644
--- a/wiretap/ascend.c
+++ b/wiretap/ascend.c
@@ -42,64 +42,47 @@
#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
-
- Example 'wdd' output data:
-
-Date: 01/12/1990. Time: 12:22:33
-Cause an attempt to place call to 14082750382
-WD_DIALOUT_DISP: chunk 2515EE type IP.
-(task: 251790, time: 994953.28) 44 octets @ 2782B8
- [0000]: 00 C0 7B 71 45 6C 00 60 08 16 AA 51 08 00 45 00
- [0010]: 00 2C 66 1C 40 00 80 06 53 F6 AC 14 00 18 CC 47
- [0020]: C8 45 0A 31 00 50 3B D9 5B 75 00 00
-
- (note that the capture whence this came dates back to January
- *1999*; I presume that either the person who sent it to me
- hadn't bothered keeping its internal clock set, or that its
- internal clock or the date it displays in those messages
- is only loosely connected to reality)
-
- 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.
+/* 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-grammar.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. */
/* How far into the file we should look for packet headers */
#define ASCEND_MAX_SEEK 100000
-/* XXX Should we replace this with a more generalized array? */
-/* 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_w1magic[] = { 'D', 'a', 't', 'e', ':', };
-static const char ascend_w2magic[] = { 'W', 'D', '_', 'D', 'I', 'A', 'L', 'O', 'U', 'T', '_', 'D', 'I', 'S', 'P', ':' };
-
-#define ASCEND_X_SIZE (sizeof ascend_xmagic / sizeof ascend_xmagic[0])
-#define ASCEND_R_SIZE (sizeof ascend_rmagic / sizeof ascend_rmagic[0])
-#define ASCEND_W1_SIZE (sizeof ascend_w1magic / sizeof ascend_w1magic[0])
-#define ASCEND_W2_SIZE (sizeof ascend_w2magic / sizeof ascend_w2magic[0])
+typedef struct _ascend_magic_string {
+ guint type;
+ 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,
long *data_offset);
@@ -109,102 +92,58 @@ static gboolean ascend_seek_read(wtap *wth, long seek_off,
static void ascend_close(wtap *wth);
/* Seeks to the beginning of the next packet, and returns the
- byte offset at which the heade for that packet begins.
- Returns -1 on failure.
-
- If it finds a packet, then, if "wth->capture.ascend" is non-null,
- it sets "wth->capture.ascend->next_packet_seek_start" to the point
- at which the seek pointer should be set before this routine is called
- to find the packet *after* the packet it finds. */
+ byte offset at which the header for that packet begins.
+ Returns -1 on failure. */
static long ascend_seek(wtap *wth, int max_seek, int *err)
{
int byte, bytes_read = 0;
long date_off = -1, cur_off, packet_off;
- unsigned int r_level = 0, x_level = 0, w1_level = 0, w2_level = 0;
+ guint string_level[ASCEND_MAGIC_STRINGS];
+ guint string_i = 0, type = 0;
- while (((byte = file_getc(wth->fh)) != EOF) && bytes_read < max_seek) {
- if (byte == ascend_xmagic[x_level]) {
- x_level++;
- if (x_level >= ASCEND_X_SIZE) {
- /* At what offset are we now? */
- cur_off = file_tell(wth->fh);
- if (cur_off == -1) {
- /* Error. */
- *err = file_error(wth->fh);
- return -1;
- }
+ memset(&string_level, 0, sizeof(string_level));
- /* Back up over the header we just read; that's where a read
- of this packet should start. */
- packet_off = cur_off - ASCEND_X_SIZE;
- goto found;
- }
- } else {
- x_level = 0;
- }
- if (byte == ascend_rmagic[r_level]) {
- r_level++;
- if (r_level >= ASCEND_R_SIZE) {
- /* At what offset are we now? */
- cur_off = file_tell(wth->fh);
- if (cur_off == -1) {
- /* Error. */
- *err = file_error(wth->fh);
- return -1;
- }
-
- /* Back up over the header we just read; that's where a read
- of this packet should start. */
- packet_off = cur_off - ASCEND_R_SIZE;
- goto found;
- }
- } else {
- r_level = 0;
- }
- if (byte == ascend_w1magic[w1_level]) {
- w1_level++;
- if (w1_level >= ASCEND_W1_SIZE) {
- /* Get the offset at which the "Date:" header started. */
- cur_off = file_tell(wth->fh);
- if (cur_off == -1) {
- /* Error. */
- *err = file_error(wth->fh);
- return -1;
- }
-
- date_off = cur_off - ASCEND_W1_SIZE;
- }
- } else {
- w1_level = 0;
- }
- if (byte == ascend_w2magic[w2_level]) {
- w2_level++;
- if (w2_level >= ASCEND_W2_SIZE) {
- /* At what offset are we now? */
- cur_off = file_tell(wth->fh);
- if (cur_off == -1) {
- /* Error. */
- *err = file_error(wth->fh);
- return -1;
- }
+ while (((byte = file_getc(wth->fh)) != EOF) && bytes_read < max_seek) {
- if (date_off != -1) {
- /* This packet has a date/time header; a read of it should
- start at the beginning of *that* header. */
- packet_off = date_off;
- } else {
- /* This packet has only a per-packet header.
- Back up over that header, which we just read; that's where
- a read of this packet should start. */
- packet_off = cur_off - ASCEND_W2_SIZE;
+ for (string_i = 0; string_i < ASCEND_MAGIC_STRINGS; string_i++) {
+ gchar *strptr = ascend_magic[string_i].strptr;
+ guint 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;
+ }
}
- goto found;
+ } else {
+ string_level[string_i] = 0;
}
- } else {
- w2_level = 0;
}
- bytes_read++;
}
+
if (byte != EOF || file_eof(wth->fh)) {
/* Either we didn't find the offset, or we got an EOF. */
*err = 0;
@@ -217,20 +156,14 @@ static long ascend_seek(wtap *wth, int max_seek, int *err)
found:
/*
- * The search for the packet after this one should start right
- * after the header for this packet. (Ideally, it should
- * start after the *data* for this one, but we haven't
- * read that yet.)
- */
- if (wth->capture.ascend != NULL)
- wth->capture.ascend->next_packet_seek_start = cur_off + 1;
-
- /*
* 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;
}
@@ -253,8 +186,22 @@ int ascend_open(wtap *wth, int *err, gchar **err_info _U_)
}
wth->data_offset = offset;
- wth->file_encap = WTAP_ENCAP_ASCEND;
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;
@@ -284,6 +231,25 @@ int ascend_open(wtap *wth, int *err, gchar **err_info _U_)
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_loop(). */
static gboolean ascend_read(wtap *wth, int *err, gchar **err_info,
long *data_offset)
@@ -292,17 +258,18 @@ static gboolean ascend_read(wtap *wth, int *err, gchar **err_info,
guint8 *buf = buffer_start_ptr(wth->frame_buffer);
ascend_pkthdr header;
- /* (f)lex reads large chunks of the file into memory, so file_tell() doesn't
- give us the correct location of the packet. Instead, we seek to the
- offset after the header of the previous packet and try to find the next
- packet. */
+ /* 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, ASCEND_MAX_SEEK, err);
- if (offset == -1)
- return FALSE;
- if (! parse_ascend(wth->fh, buf, &wth->pseudo_header.ascend, &header, 0)) {
+
+ offset = ascend_seek(wth, ASCEND_MAX_SEEK, 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;
@@ -310,6 +277,8 @@ static gboolean ascend_read(wtap *wth, int *err, gchar **err_info,
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) {
@@ -343,13 +312,18 @@ static gboolean ascend_seek_read(wtap *wth, long 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, len)) {
+ 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;
}
diff --git a/wiretap/wtap.h b/wiretap/wtap.h
index bda40aa2ea..05b4a36ed7 100644
--- a/wiretap/wtap.h
+++ b/wiretap/wtap.h
@@ -342,6 +342,9 @@ struct atm_phdr {
#define ASCEND_PFX_WDS_X 1
#define ASCEND_PFX_WDS_R 2
#define ASCEND_PFX_WDD 3
+#define ASCEND_PFX_ISDN_X 4
+#define ASCEND_PFX_ISDN_R 5
+#define ASCEND_PFX_ETHER 6
struct ascend_phdr {
guint16 type; /* ASCEND_PFX_*, as defined above */