7 * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 Example 'pridisp' output data - one paragraph/frame:
28 PRI-XMIT-27: (task "l1Task" at 0x10216fe0, time: 560194.01) 4 octets @ 0x1027c5b0
29 [0000]: 00 01 01 a9 ....
30 PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00
33 Example 'pridisp' output data - two paragraphs/frame for XMIT case only:
35 PRI-XMIT-19/1: (task "l1Task" at 0x10216840, time: 274759.98) 4 octets @ 0x1027f230
36 [0000]: 00 01 30 d8 ..0.
37 PRI-XMIT-19/2 (task "l1Task" at 0x10216840, time: 274759.98) 11 octets @ 0x1027f234
38 [0000]: 08 02 8c bf 02 18 04 e9 82 83 8f ........ ...
40 Example 'ether-disp' output data:
42 ETHER3ND RECV: (task "_sarTask" at 0x802c6eb0, time: 259848.03) 775 octets @ 0xa8fb2020
43 [0000]: 00 d0 52 04 e7 1e 08 00 20 ae 51 b5 08 00 45 00 ..R..... .Q...E.
44 [0010]: 02 f9 05 e6 40 00 3f 11 6e 39 87 fe c4 95 3c 3c ....@.?. n9....<<
45 [0020]: 3c 05 13 c4 13 c4 02 e5 ef ed 49 4e 56 49 54 45 <....... ..INVITE
46 [0030]: 20 73 69 70 3a 35 32 30 37 33 40 36 30 2e 36 30 sip:520 73@60.60
47 [0040]: 2e 36 30 2e 35 20 53 49 50 2f 32 2e 30 0d 0a 56 .60.5 SI P/2.0..V
48 [0050]: 69 61 3a 20 53 49 50 2f 32 2e 30 2f 55 44 50 20 ia: SIP/ 2.0/UDP
49 [0060]: 31 33 35 2e 135.
51 Example 'wandsess' output data:
53 RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94
54 [0000]: FF 03 00 3D C0 06 CA 22 2F 45 00 00 28 6A 3B 40
55 [0010]: 00 3F 03 D7 37 CE 41 62 12 CF 00 FB 08 20 27 00
56 [0020]: 50 E4 08 DD D7 7C 4C 71 92 50 10 7D 78 67 C8 00
58 XMIT-iguana:241:(task: B04E12C0, time: 1975432.85) 53 octets @ 8009EB16
59 [0000]: FF 03 00 3D C0 09 1E 31 21 45 00 00 2C 2D BD 40
60 [0010]: 00 7A 06 D8 B1 CF 00 FB 08 CE 41 62 12 00 50 20
61 [0020]: 29 7C 4C 71 9C 9A 6A 93 A4 60 12 22 38 3F 10 00
62 [0030]: 00 02 04 05 B4
64 Example 'wdd' output data:
66 Date: 01/12/1990. Time: 12:22:33
67 Cause an attempt to place call to 14082750382
68 WD_DIALOUT_DISP: chunk 2515EE type IP.
69 (task: 251790, time: 994953.28) 44 octets @ 2782B8
70 [0000]: 00 C0 7B 71 45 6C 00 60 08 16 AA 51 08 00 45 00
71 [0010]: 00 2C 66 1C 40 00 80 06 53 F6 AC 14 00 18 CC 47
72 [0020]: C8 45 0A 31 00 50 3B D9 5B 75 00 00
74 The following output comes from a MAX with Software 7.2.3:
76 RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0
77 [0000]: FF 03 00 21 45 00 00 60 E3 49 00 00 7F 11 FD 7B
78 [0010]: C0 A8 F7 05 8A C8 18 51 00 89 00 89 00 4C C7 C1
79 [0020]: CC 8E 40 00 00 01 00 00 00 00 00 01 20 45 4A 45
80 [0030]: 42 45 43 45 48 43 4E 46 43 46 41 43 41 43 41 43
81 [0040]: 41 43 41 43 41 43 41 43 41 43 41 42 4E 00 00 20
82 [0050]: 00 01 C0 0C 00 20 00 01 00 04 93 E0 00 06 60 00
84 XMIT-187:(task: B0292CA0, time: 18042248.04) 60 octets @ 800AD576
85 [0000]: FF 03 00 21 45 00 00 38 D7 EE 00 00 0F 01 11 2B
86 [0010]: 0A FF FF FE C0 A8 F7 05 03 0D 33 D3 00 00 00 00
87 [0020]: 45 00 00 60 E3 49 00 00 7E 11 FE 7B C0 A8 F7 05
88 [0030]: 8A C8 18 51 00 89 00 89 00 4C C7 C1
89 RECV-187:(task: B0292CA0, time: 18042251.92) 16 octets @ 800018E8
90 [0000]: FF 03 C0 21 09 01 00 0C DE 61 96 4B 00 30 94 92
92 In TAOS 8.0, Lucent slightly changed the format as follows:
94 Example 'wandisp' output data (TAOS 8.0.3): (same format is used
95 for 'wanopen' and 'wannext' command)
97 RECV-14: (task "idle task" at 0xb05e6e00, time: 1279.01) 29 octets @ 0x8000e0fc
98 [0000]: ff 03 c0 21 01 01 00 19 01 04 05 f4 11 04 05 f4 ...!.... ........
99 [0010]: 13 09 03 00 c0 7b 9a 9f 2d 17 04 10 00 .....{.. -....
100 XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 38 octets @ 0x8007fd56
101 [0000]: ff 03 c0 21 01 01 00 22 00 04 00 00 01 04 05 f4 ...!..." ........
102 [0010]: 03 05 c2 23 05 11 04 05 f4 13 09 03 00 c0 7b 80 ...#.... ......{.
103 [0020]: 7c ef 17 04 0e 00 |.....
104 XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 29 octets @ 0x8007fa36
105 [0000]: ff 03 c0 21 02 01 00 19 01 04 05 f4 11 04 05 f4 ...!.... ........
106 [0010]: 13 09 03 00 c0 7b 9a 9f 2d 17 04 10 00 .....{.. -....
108 Example 'wandsess' output data (TAOS 8.0.3):
110 RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198
111 [0000]: ff 03 00 3d c0 00 00 04 80 fd 02 01 00 0a 11 06 ...=.... ........
112 [0010]: 00 01 01 03 ....
113 XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 26 octets @ 0x800806b6
114 [0000]: ff 03 00 3d c0 00 00 00 80 21 01 01 00 10 02 06 ...=.... .!......
115 [0010]: 00 2d 0f 01 03 06 89 64 03 08 .-.....d ..
116 XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 20 octets @ 0x8007f716
117 [0000]: ff 03 00 3d c0 00 00 01 80 fd 01 01 00 0a 11 06 ...=.... ........
118 [0010]: 00 01 01 03 ....
120 The changes since TAOS 7.X are:
122 1) White space is added before "(task".
123 2) Task has a name, indicated by a subsequent string surrounded by a
125 3) Address expressed in hex number has a preceeding "0x".
126 4) Hex numbers are in lower case.
127 5) There is a character display corresponding to hex data in each line.
139 #include "wtap-int.h"
141 #include "ascendtext.h"
142 #include "ascend-int.h"
143 #include "file_wrappers.h"
145 #define NO_USER "<none>"
148 void yyerror(const char *);
150 const gchar *ascend_parse_error;
152 static unsigned int bcur;
153 static guint32 start_time, secs, usecs, caplen, wirelen;
154 static ascend_pkthdr *header;
155 struct ascend_phdr *pseudo_header;
156 static guint8 *pkt_data;
157 static gint64 first_hexbyte;
158 static FILE_T *fh_ptr;
168 %token <s> STRING KEYWORD WDD_DATE WDD_CHUNK COUNTER SLASH_SUFFIX
169 %token <d> WDS_PREFIX ISDN_PREFIX ETHER_PREFIX DECNUM HEXNUM
172 %type <s> string dataln datagroup
173 %type <d> wds_prefix isdn_prefix ether_prefix decnum hexnum
174 %type <b> byte bytegroup
179 | ether_hdr datagroup
180 | deferred_isdn_hdr datagroup deferred_isdn_hdr datagroup
186 | wdd_date wdd_hdr datagroup
190 isdn_prefix: ISDN_PREFIX;
192 ether_prefix: ETHER_PREFIX;
194 wds_prefix: WDS_PREFIX;
203 pridisp special case - I-frame header printed separately from contents,
204 one frame across two messages.
206 PRI-XMIT-0/1: (task "l1Task" at 0x80152b20, time: 283529.65) 4 octets @
208 [0000]: 00 01 ae b2 ....
209 PRI-XMIT-0/2 (task "l1Task" at 0x80152b20, time: 283529.65) 10 octets @
211 [0000]: 08 02 d7 e3 02 18 03 a9 83 8a ........
214 deferred_isdn_hdr: isdn_prefix decnum SLASH_SUFFIX KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
219 if (pseudo_header != NULL) {
220 pseudo_header->type = $1;
221 pseudo_header->sess = $2;
222 pseudo_header->call_num[0] = '\0';
223 pseudo_header->chunk = 0;
224 pseudo_header->task = $7;
226 /* because we have two data groups */
232 PRI-XMIT-19: (task "l1Task" at 0x10216840, time: 274758.67) 4 octets @ 0x1027c1c0
234 PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00
236 isdn_hdr: isdn_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
241 if (pseudo_header != NULL) {
242 pseudo_header->type = $1;
243 pseudo_header->sess = $2;
244 pseudo_header->call_num[0] = '\0';
245 pseudo_header->chunk = 0;
246 pseudo_header->task = $6;
253 ETHER3ND XMIT: (task "_sarTask" at 0x802c6eb0, time: 259848.11) 414 octets @ 0xa
256 ether_hdr: ether_prefix string KEYWORD string KEYWORD hexnum KEYWORD decnum decnum
257 decnum KEYWORD HEXNUM {
262 if (pseudo_header != NULL) {
263 pseudo_header->type = $1;
264 pseudo_header->call_num[0] = '\0';
265 pseudo_header->chunk = 0;
266 pseudo_header->task = $6;
271 /* RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 */
272 /* 1 2 3 4 5 6 7 8 9 10 11 */
273 wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
278 if (pseudo_header != NULL) {
279 /* pseudo_header->user is set in ascend_scanner.l */
280 pseudo_header->type = $1;
281 pseudo_header->sess = $3;
282 pseudo_header->call_num[0] = '\0';
283 pseudo_header->chunk = 0;
284 pseudo_header->task = $5;
289 /* RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 */
290 /* 1 2 3 4 5 6 7 8 9 10 11 12 13 */
291 wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
296 if (pseudo_header != NULL) {
297 /* pseudo_header->user is set in ascend_scanner.l */
298 pseudo_header->type = $1;
299 pseudo_header->sess = $3;
300 pseudo_header->call_num[0] = '\0';
301 pseudo_header->chunk = 0;
302 pseudo_header->task = $7;
307 /* RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 */
308 /* 1 2 3 4 5 6 7 8 9 10 */
309 wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
314 if (pseudo_header != NULL) {
315 /* pseudo_header->user is set in ascend_scanner.l */
316 pseudo_header->type = $1;
317 pseudo_header->sess = $2;
318 pseudo_header->call_num[0] = '\0';
319 pseudo_header->chunk = 0;
320 pseudo_header->task = $4;
325 /* XMIT-44: (task "freedm_task" at 0xe051fd10, time: 6258.66) 29 octets @ 0x606d1f00 */
326 /* 1 2 3 4 5 6 7 8 9 10 11 12 */
327 wdp8_hdr: wds_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
332 if (pseudo_header != NULL) {
333 /* pseudo_header->user is set in ascend_scanner.l */
334 pseudo_header->type = $1;
335 pseudo_header->sess = $2;
336 pseudo_header->call_num[0] = '\0';
337 pseudo_header->chunk = 0;
338 pseudo_header->task = $6;
344 Date: 01/12/1990. Time: 12:22:33
345 Cause an attempt to place call to 14082750382
347 /* 1 2 3 4 5 6 7 8 9 10*/
348 wdd_date: WDD_DATE decnum decnum decnum KEYWORD decnum decnum decnum KEYWORD string {
350 * Supply the date/time value to the code above us; it will use the
351 * first date/time value supplied as the capture start date/time.
359 wddt.tm_mon = $2 - 1;
360 wddt.tm_year = ($4 > 1970) ? $4 - 1900 : 70;
363 start_time = (guint32) mktime(&wddt);
368 WD_DIALOUT_DISP: chunk 2515EE type IP.
369 (task: 251790, time: 994953.28) 44 octets @ 2782B8
371 /* 1 2 3 4 5 6 7 8 9 10 11*/
372 wdd_hdr: WDD_CHUNK hexnum KEYWORD KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
377 if (pseudo_header != NULL) {
378 /* pseudo_header->call_num is set in ascend_scanner.l */
379 pseudo_header->type = ASCEND_PFX_WDD;
380 pseudo_header->user[0] = '\0';
381 pseudo_header->sess = 0;
382 pseudo_header->chunk = $2;
383 pseudo_header->task = $5;
389 /* remember the position of the data group in the trace, to tip
390 off ascend_seek() as to where to look for the next header. */
391 if (first_hexbyte == 0)
392 first_hexbyte = file_tell(*fh_ptr);
399 /* arbitrary safety maximum... */
400 if (bcur >= ASCEND_MAX_PKT_LEN)
405 /* XXX There must be a better way to do this... */
409 | byte byte byte byte
410 | byte byte byte byte byte
411 | byte byte byte byte byte byte
412 | byte byte byte byte byte byte byte
413 | byte byte byte byte byte byte byte byte
414 | byte byte byte byte byte byte byte byte byte
415 | byte byte byte byte byte byte byte byte byte byte
416 | byte byte byte byte byte byte byte byte byte byte byte
417 | byte byte byte byte byte byte byte byte byte byte byte byte
418 | byte byte byte byte byte byte byte byte byte byte byte byte byte
419 | byte byte byte byte byte byte byte byte byte byte byte byte byte byte
420 | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
421 | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
424 dataln: COUNTER bytegroup;
428 | dataln dataln dataln
429 | dataln dataln dataln dataln
430 | dataln dataln dataln dataln dataln
431 | dataln dataln dataln dataln dataln dataln
432 | dataln dataln dataln dataln dataln dataln dataln
433 | dataln dataln dataln dataln dataln dataln dataln dataln
439 init_parse_ascend(void)
442 start_time = 0; /* we haven't see a date/time yet */
445 /* Parse the capture file.
447 PARSED_RECORD if we got a packet
448 PARSED_NONRECORD if the parser succeeded but didn't see a packet
449 PARSE_FAILED if the parser failed. */
451 parse_ascend(FILE_T fh, guint8 *pd, struct ascend_phdr *phdr,
452 ascend_pkthdr *hdr, gint64 *start_of_data)
456 ascend_init_lexer(fh);
458 pseudo_header = phdr;
468 * Not all packets in a "wdd" dump necessarily have a "Cause an
469 * attempt to place call to" header (I presume this can happen if
470 * there was a call in progress when the packet was sent or
471 * received), so we won't necessarily have the phone number for
474 * XXX - we could assume, in the sequential pass, that it's the
475 * phone number from the last call, and remember that for use
476 * when doing random access.
478 pseudo_header->call_num[0] = '\0';
484 /* did we see any data (hex bytes)? if so, tip off ascend_seek()
485 as to where to look for the next packet, if any. If we didn't,
486 maybe this record was broken. Advance so we don't get into
487 an infinite loop reading a broken trace. */
489 *start_of_data = first_hexbyte;
491 /* Sometimes, a header will be printed but the data will be omitted, or
492 worse -- two headers will be printed, followed by the data for each.
493 Because of this, we need to be fairly tolerant of what we accept
494 here. If we didn't find any hex bytes, skip over what we've read so
495 far so we can try reading a new packet. */
496 *start_of_data = file_tell(*fh_ptr);
500 /* if we got at least some data, return success even if the parser
501 reported an error. This is because the debug header gives the number
502 of bytes on the wire, not actually how many bytes are in the trace.
503 We won't know where the data ends until we run into the next packet. */
506 header->start_time = start_time;
508 header->usecs = usecs;
509 header->caplen = caplen;
510 header->len = wirelen;
513 return PARSED_RECORD;
516 /* Didn't see any data. Still, perhaps the parser was happy. */
520 return PARSED_NONRECORD;
524 yyerror (const char *s)
526 ascend_parse_error = s;