HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / wiretap / ascend.y
blobc6c5b4b6a0a767c414eabb2500fdd7b20cf0a878
1 %{
2 /* ascend.y
4 * $Id$
6 * Wiretap Library
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
31 [0000]: 00 01 01 dd
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
57 [0030]: 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
83 [0060]: C0 A8 F7 05
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
124 double-quote.
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.
131 #include "config.h"
133 #include <stdio.h>
134 #include <stdlib.h>
135 #include <string.h>
137 #include "wtap-int.h"
138 #include "buffer.h"
139 #include "ascendtext.h"
140 #include "ascend-int.h"
141 #include "file_wrappers.h"
143 #define NO_USER "<none>"
145 int yyparse(FILE_T fh);
146 void yyerror(FILE_T fh _U_, const char *);
148 const gchar *ascend_parse_error;
150 static unsigned int bcur;
151 static guint32 start_time, secs, usecs, caplen, wirelen;
152 struct ascend_phdr *pseudo_header;
153 static guint8 *pkt_data;
154 static gint64 first_hexbyte;
158 %union {
159 gchar *s;
160 guint32 d;
161 guint8 b;
164 %token <s> STRING KEYWORD WDD_DATE WDD_CHUNK COUNTER SLASH_SUFFIX
165 %token <d> WDS_PREFIX ISDN_PREFIX ETHER_PREFIX DECNUM HEXNUM
166 %token <b> HEXBYTE
168 %type <s> string dataln datagroup
169 %type <d> wds_prefix isdn_prefix ether_prefix decnum hexnum
170 %type <b> byte bytegroup
172 %parse-param { FILE_T fh }
176 data_packet:
177 | ether_hdr datagroup
178 | deferred_isdn_hdr datagroup deferred_isdn_hdr datagroup
179 | isdn_hdr datagroup
180 | wds_hdr datagroup
181 | wds8_hdr datagroup
182 | wdp7_hdr datagroup
183 | wdp8_hdr datagroup
184 | wdd_date wdd_hdr datagroup
185 | wdd_hdr datagroup
188 isdn_prefix: ISDN_PREFIX;
190 ether_prefix: ETHER_PREFIX;
192 wds_prefix: WDS_PREFIX;
194 string: STRING;
196 decnum: DECNUM;
198 hexnum: HEXNUM;
201 pridisp special case - I-frame header printed separately from contents,
202 one frame across two messages.
204 PRI-XMIT-0/1: (task "l1Task" at 0x80152b20, time: 283529.65) 4 octets @
205 0x80128220
206 [0000]: 00 01 ae b2 ....
207 PRI-XMIT-0/2 (task "l1Task" at 0x80152b20, time: 283529.65) 10 octets @
208 0x80128224
209 [0000]: 08 02 d7 e3 02 18 03 a9 83 8a ........
212 deferred_isdn_hdr: isdn_prefix decnum SLASH_SUFFIX KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
213 wirelen += $11;
214 caplen += $11;
215 secs = $9;
216 usecs = $10;
217 if (pseudo_header != NULL) {
218 pseudo_header->type = $1;
219 pseudo_header->sess = $2;
220 pseudo_header->call_num[0] = '\0';
221 pseudo_header->chunk = 0;
222 pseudo_header->task = $7;
224 /* because we have two data groups */
225 first_hexbyte = 0;
230 PRI-XMIT-19: (task "l1Task" at 0x10216840, time: 274758.67) 4 octets @ 0x1027c1c0
231 ... or ...
232 PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00
234 isdn_hdr: isdn_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
235 wirelen = $10;
236 caplen = $10;
237 secs = $8;
238 usecs = $9;
239 if (pseudo_header != NULL) {
240 pseudo_header->type = $1;
241 pseudo_header->sess = $2;
242 pseudo_header->call_num[0] = '\0';
243 pseudo_header->chunk = 0;
244 pseudo_header->task = $6;
246 first_hexbyte = 0;
251 ETHER3ND XMIT: (task "_sarTask" at 0x802c6eb0, time: 259848.11) 414 octets @ 0xa
252 885f80e
254 ether_hdr: ether_prefix string KEYWORD string KEYWORD hexnum KEYWORD decnum decnum
255 decnum KEYWORD HEXNUM {
256 wirelen = $10;
257 caplen = $10;
258 secs = $8;
259 usecs = $9;
260 if (pseudo_header != NULL) {
261 pseudo_header->type = $1;
262 pseudo_header->call_num[0] = '\0';
263 pseudo_header->chunk = 0;
264 pseudo_header->task = $6;
269 /* RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 */
270 /* 1 2 3 4 5 6 7 8 9 10 11 */
271 wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
272 wirelen = $9;
273 caplen = $9;
274 secs = $7;
275 usecs = $8;
276 if (pseudo_header != NULL) {
277 /* pseudo_header->user is set in ascend_scanner.l */
278 pseudo_header->type = $1;
279 pseudo_header->sess = $3;
280 pseudo_header->call_num[0] = '\0';
281 pseudo_header->chunk = 0;
282 pseudo_header->task = $5;
287 /* RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 */
288 /* 1 2 3 4 5 6 7 8 9 10 11 12 13 */
289 wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
290 wirelen = $11;
291 caplen = $11;
292 secs = $9;
293 usecs = $10;
294 if (pseudo_header != NULL) {
295 /* pseudo_header->user is set in ascend_scanner.l */
296 pseudo_header->type = $1;
297 pseudo_header->sess = $3;
298 pseudo_header->call_num[0] = '\0';
299 pseudo_header->chunk = 0;
300 pseudo_header->task = $7;
305 /* RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 */
306 /* 1 2 3 4 5 6 7 8 9 10 */
307 wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
308 wirelen = $8;
309 caplen = $8;
310 secs = $6;
311 usecs = $7;
312 if (pseudo_header != NULL) {
313 /* pseudo_header->user is set in ascend_scanner.l */
314 pseudo_header->type = $1;
315 pseudo_header->sess = $2;
316 pseudo_header->call_num[0] = '\0';
317 pseudo_header->chunk = 0;
318 pseudo_header->task = $4;
323 /* XMIT-44: (task "freedm_task" at 0xe051fd10, time: 6258.66) 29 octets @ 0x606d1f00 */
324 /* 1 2 3 4 5 6 7 8 9 10 11 12 */
325 wdp8_hdr: wds_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
326 wirelen = $10;
327 caplen = $10;
328 secs = $8;
329 usecs = $9;
330 if (pseudo_header != NULL) {
331 /* pseudo_header->user is set in ascend_scanner.l */
332 pseudo_header->type = $1;
333 pseudo_header->sess = $2;
334 pseudo_header->call_num[0] = '\0';
335 pseudo_header->chunk = 0;
336 pseudo_header->task = $6;
342 Date: 01/12/1990. Time: 12:22:33
343 Cause an attempt to place call to 14082750382
345 /* 1 2 3 4 5 6 7 8 9 10*/
346 wdd_date: WDD_DATE decnum decnum decnum KEYWORD decnum decnum decnum KEYWORD string {
348 * Supply the date/time value to the code above us; it will use the
349 * first date/time value supplied as the capture start date/time.
351 struct tm wddt;
353 wddt.tm_sec = $8;
354 wddt.tm_min = $7;
355 wddt.tm_hour = $6;
356 wddt.tm_mday = $3;
357 wddt.tm_mon = $2 - 1;
358 wddt.tm_year = ($4 > 1970) ? $4 - 1900 : 70;
359 wddt.tm_isdst = -1;
361 start_time = (guint32) mktime(&wddt);
366 WD_DIALOUT_DISP: chunk 2515EE type IP.
367 (task: 251790, time: 994953.28) 44 octets @ 2782B8
369 /* 1 2 3 4 5 6 7 8 9 10 11*/
370 wdd_hdr: WDD_CHUNK hexnum KEYWORD KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
371 wirelen = $9;
372 caplen = $9;
373 secs = $7;
374 usecs = $8;
375 if (pseudo_header != NULL) {
376 /* pseudo_header->call_num is set in ascend_scanner.l */
377 pseudo_header->type = ASCEND_PFX_WDD;
378 pseudo_header->user[0] = '\0';
379 pseudo_header->sess = 0;
380 pseudo_header->chunk = $2;
381 pseudo_header->task = $5;
386 byte: HEXBYTE {
387 /* remember the position of the data group in the trace, to tip
388 off ascend_seek() as to where to look for the next header. */
389 if (first_hexbyte == 0)
390 first_hexbyte = file_tell(fh);
392 if (bcur < caplen) {
393 pkt_data[bcur] = $1;
394 bcur++;
397 /* arbitrary safety maximum... */
398 if (bcur >= ASCEND_MAX_PKT_LEN)
399 YYACCEPT;
403 /* XXX There must be a better way to do this... */
404 bytegroup: byte
405 | byte byte
406 | byte byte byte
407 | byte byte byte byte
408 | byte byte byte byte byte
409 | byte byte byte byte byte byte
410 | byte byte byte byte byte byte byte
411 | byte byte byte byte byte byte byte byte
412 | byte byte byte byte byte byte byte byte byte
413 | byte byte byte byte byte byte byte byte byte byte
414 | byte byte byte byte byte byte byte byte byte byte byte
415 | byte byte byte byte byte byte byte byte byte byte byte byte
416 | byte byte byte byte byte byte byte byte byte byte byte byte byte
417 | byte byte 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 byte byte
419 | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
422 dataln: COUNTER bytegroup;
424 datagroup: dataln
425 | dataln dataln
426 | dataln dataln dataln
427 | dataln dataln dataln dataln
428 | dataln dataln dataln dataln dataln
429 | dataln dataln dataln dataln dataln dataln
430 | dataln dataln dataln dataln dataln dataln dataln
431 | dataln dataln dataln dataln dataln dataln dataln dataln
436 void
437 init_parse_ascend(void)
439 at_eof = 0;
440 start_time = 0; /* we haven't see a date/time yet */
443 /* Run the parser. */
444 static int
445 run_ascend_parser(FILE_T fh, struct wtap_pkthdr *phdr, guint8 *pd)
447 /* yydebug = 1; */
448 int retval;
450 ascend_init_lexer(fh);
451 pseudo_header = &phdr->pseudo_header.ascend;
452 pkt_data = pd;
454 bcur = 0;
455 first_hexbyte = 0;
456 wirelen = 0;
457 caplen = 0;
460 * Not all packets in a "wdd" dump necessarily have a "Cause an
461 * attempt to place call to" header (I presume this can happen if
462 * there was a call in progress when the packet was sent or
463 * received), so we won't necessarily have the phone number for
464 * the packet.
466 * XXX - we could assume, in the sequential pass, that it's the
467 * phone number from the last call, and remember that for use
468 * when doing random access.
470 pseudo_header->call_num[0] = '\0';
472 retval = yyparse(fh);
474 caplen = bcur;
476 return retval;
479 /* Parse the capture file.
480 Returns:
481 TRUE if we got a packet
482 FALSE otherwise. */
483 gboolean
484 check_ascend(FILE_T fh, struct wtap_pkthdr *phdr)
486 guint8 buf[ASCEND_MAX_PKT_LEN];
488 run_ascend_parser(fh, phdr, buf);
490 /* if we got at least some data, return success even if the parser
491 reported an error. This is because the debug header gives the number
492 of bytes on the wire, not actually how many bytes are in the trace.
493 We won't know where the data ends until we run into the next packet. */
494 return (caplen != 0);
497 /* Parse the capture file.
498 Returns:
499 PARSED_RECORD if we got a packet
500 PARSED_NONRECORD if the parser succeeded but didn't see a packet
501 PARSE_FAILED if the parser failed. */
502 parse_t
503 parse_ascend(ascend_t *ascend, FILE_T fh, struct wtap_pkthdr *phdr, Buffer *buf,
504 guint length)
506 int retval;
508 buffer_assure_space(buf, length);
509 retval = run_ascend_parser(fh, phdr, buffer_start_ptr(buf));
511 /* did we see any data (hex bytes)? if so, tip off ascend_seek()
512 as to where to look for the next packet, if any. If we didn't,
513 maybe this record was broken. Advance so we don't get into
514 an infinite loop reading a broken trace. */
515 if (first_hexbyte) {
516 ascend->next_packet_seek_start = first_hexbyte;
517 } else {
518 /* Sometimes, a header will be printed but the data will be omitted, or
519 worse -- two headers will be printed, followed by the data for each.
520 Because of this, we need to be fairly tolerant of what we accept
521 here. If we didn't find any hex bytes, skip over what we've read so
522 far so we can try reading a new packet. */
523 ascend->next_packet_seek_start = file_tell(fh);
524 retval = 0;
527 /* if we got at least some data, return success even if the parser
528 reported an error. This is because the debug header gives the number
529 of bytes on the wire, not actually how many bytes are in the trace.
530 We won't know where the data ends until we run into the next packet. */
531 if (caplen) {
532 if (! ascend->adjusted) {
533 ascend->adjusted = TRUE;
534 if (start_time != 0) {
536 * Capture file contained a date and time.
537 * We do this only if this is the very first packet we've seen -
538 * i.e., if "ascend->adjusted" is false - because
539 * if we get a date and time after the first packet, we can't
540 * go back and adjust the time stamps of the packets we've already
541 * processed, and basing the time stamps of this and following
542 * packets on the time stamp from the file text rather than the
543 * ctime of the capture file means times before this and after
544 * this can't be compared.
546 ascend->inittime = start_time;
548 if (ascend->inittime > secs)
549 ascend->inittime -= secs;
551 phdr->presence_flags = WTAP_HAS_TS|WTAP_HAS_CAP_LEN;
552 phdr->ts.secs = secs + ascend->inittime;
553 phdr->ts.nsecs = usecs * 1000;
554 phdr->caplen = caplen;
555 phdr->len = wirelen;
558 * For these types, the encapsulation we use is not WTAP_ENCAP_ASCEND,
559 * so set the pseudo-headers appropriately for the type (WTAP_ENCAP_ISDN
560 * or WTAP_ENCAP_ETHERNET).
562 switch(phdr->pseudo_header.ascend.type) {
563 case ASCEND_PFX_ISDN_X:
564 phdr->pseudo_header.isdn.uton = TRUE;
565 phdr->pseudo_header.isdn.channel = 0;
566 break;
568 case ASCEND_PFX_ISDN_R:
569 phdr->pseudo_header.isdn.uton = FALSE;
570 phdr->pseudo_header.isdn.channel = 0;
571 break;
573 case ASCEND_PFX_ETHER:
574 phdr->pseudo_header.eth.fcs_len = 0;
575 break;
577 return PARSED_RECORD;
580 /* Didn't see any data. Still, perhaps the parser was happy. */
581 if (retval)
582 return PARSE_FAILED;
583 else
584 return PARSED_NONRECORD;
587 void
588 yyerror (FILE_T fh _U_, const char *s)
590 ascend_parse_error = s;