wtap_opttypes: fix no previous prototype for function 'wtap_opttype_write_data_uint64...
[metze/wireshark/wip.git] / wiretap / ascend.y
1 /*
2  * We want a reentrant parser.
3  */
4 %pure-parser
5
6 /*
7  * We also want a reentrant scanner, so we have to pass the
8  * handle for the reentrant scanner to the parser, and the
9  * parser has to pass it to the lexical analyzer.
10  *
11  * We use void * rather than yyscan_t because, at least with some
12  * versions of Flex and Bison, if you use yyscan_t in %parse-param and
13  * %lex-param, you have to include the ascend_lex_scanner.h before
14  * ascend.h to get yyscan_t declared, and you have to include ascend.h
15  * before ascend_lex_scanner.h to get YYSTYPE declared.  Using void *
16  * breaks the cycle; the Flex documentation says yyscan_t is just a void *.
17  */
18 %parse-param {void *yyscanner}
19 %lex-param {void *yyscanner}
20
21 /*
22  * And we need to pass the parser/scanner state to the parser.
23  */
24 %parse-param {ascend_state_t *parser_state}
25
26 %{
27 /* ascend.y
28  *
29  * Wiretap Library
30  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
31  *
32  * This program is free software; you can redistribute it and/or
33  * modify it under the terms of the GNU General Public License
34  * as published by the Free Software Foundation; either version 2
35  * of the License, or (at your option) any later version.
36  *
37  * This program is distributed in the hope that it will be useful,
38  * but WITHOUT ANY WARRANTY; without even the implied warranty of
39  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40  * GNU General Public License for more details.
41  *
42  * You should have received a copy of the GNU General Public License
43  * along with this program; if not, write to the Free Software
44  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
45  *
46  */
47
48 /*
49     Example 'pridisp' output data - one paragraph/frame:
50
51 PRI-XMIT-27: (task "l1Task" at 0x10216fe0, time: 560194.01) 4 octets @ 0x1027c5b0
52   [0000]: 00 01 01 a9                                         ....
53 PRI-RCV-27: (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00
54   [0000]: 00 01 01 dd
55
56     Example 'pridisp' output data - two paragraphs/frame for XMIT case only:
57
58 PRI-XMIT-19/1:  (task "l1Task" at 0x10216840, time: 274759.98) 4 octets @ 0x1027f230
59   [0000]: 00 01 30 d8                                         ..0.
60 PRI-XMIT-19/2 (task "l1Task" at 0x10216840, time: 274759.98) 11 octets @ 0x1027f234
61   [0000]: 08 02 8c bf 02 18 04 e9  82 83 8f                   ........ ...
62
63     Example 'ether-disp' output data:
64
65 ETHER3ND RECV: (task "_sarTask" at 0x802c6eb0, time: 259848.03) 775 octets @ 0xa8fb2020
66   [0000]: 00 d0 52 04 e7 1e 08 00  20 ae 51 b5 08 00 45 00    ..R..... .Q...E.
67   [0010]: 02 f9 05 e6 40 00 3f 11  6e 39 87 fe c4 95 3c 3c    ....@.?.  n9....<<
68   [0020]: 3c 05 13 c4 13 c4 02 e5  ef ed 49 4e 56 49 54 45    <.......  ..INVITE
69   [0030]: 20 73 69 70 3a 35 32 30  37 33 40 36 30 2e 36 30     sip:520 73@60.60
70   [0040]: 2e 36 30 2e 35 20 53 49  50 2f 32 2e 30 0d 0a 56    .60.5 SI P/2.0..V
71   [0050]: 69 61 3a 20 53 49 50 2f  32 2e 30 2f 55 44 50 20    ia: SIP/ 2.0/UDP
72   [0060]: 31 33 35 2e                                         135.
73
74     Example 'wandsess' output data:
75
76 RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94
77   [0000]: FF 03 00 3D C0 06 CA 22 2F 45 00 00 28 6A 3B 40
78   [0010]: 00 3F 03 D7 37 CE 41 62 12 CF 00 FB 08 20 27 00
79   [0020]: 50 E4 08 DD D7 7C 4C 71 92 50 10 7D 78 67 C8 00
80   [0030]: 00
81 XMIT-iguana:241:(task: B04E12C0, time: 1975432.85) 53 octets @ 8009EB16
82   [0000]: FF 03 00 3D C0 09 1E 31 21 45 00 00 2C 2D BD 40
83   [0010]: 00 7A 06 D8 B1 CF 00 FB 08 CE 41 62 12 00 50 20
84   [0020]: 29 7C 4C 71 9C 9A 6A 93 A4 60 12 22 38 3F 10 00
85   [0030]: 00 02 04 05 B4
86
87     Example 'wdd' output data:
88
89 Date: 01/12/1990.  Time: 12:22:33
90 Cause an attempt to place call to 14082750382
91 WD_DIALOUT_DISP: chunk 2515EE type IP.
92 (task: 251790, time: 994953.28) 44 octets @ 2782B8
93   [0000]: 00 C0 7B 71 45 6C 00 60 08 16 AA 51 08 00 45 00
94   [0010]: 00 2C 66 1C 40 00 80 06 53 F6 AC 14 00 18 CC 47
95   [0020]: C8 45 0A 31 00 50 3B D9 5B 75 00 00
96
97     The following output comes from a MAX with Software 7.2.3:
98
99 RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0
100   [0000]: FF 03 00 21 45 00 00 60 E3 49 00 00 7F 11 FD 7B
101   [0010]: C0 A8 F7 05 8A C8 18 51 00 89 00 89 00 4C C7 C1
102   [0020]: CC 8E 40 00 00 01 00 00 00 00 00 01 20 45 4A 45
103   [0030]: 42 45 43 45 48 43 4E 46 43 46 41 43 41 43 41 43
104   [0040]: 41 43 41 43 41 43 41 43 41 43 41 42 4E 00 00 20
105   [0050]: 00 01 C0 0C 00 20 00 01 00 04 93 E0 00 06 60 00
106   [0060]: C0 A8 F7 05
107 XMIT-187:(task: B0292CA0, time: 18042248.04) 60 octets @ 800AD576
108   [0000]: FF 03 00 21 45 00 00 38 D7 EE 00 00 0F 01 11 2B
109   [0010]: 0A FF FF FE C0 A8 F7 05 03 0D 33 D3 00 00 00 00
110   [0020]: 45 00 00 60 E3 49 00 00 7E 11 FE 7B C0 A8 F7 05
111   [0030]: 8A C8 18 51 00 89 00 89 00 4C C7 C1
112 RECV-187:(task: B0292CA0, time: 18042251.92) 16 octets @ 800018E8
113   [0000]: FF 03 C0 21 09 01 00 0C DE 61 96 4B 00 30 94 92
114
115   In TAOS 8.0, Lucent slightly changed the format as follows:
116
117     Example 'wandisp' output data (TAOS 8.0.3): (same format is used
118     for 'wanopen' and 'wannext' command)
119
120 RECV-14: (task "idle task" at 0xb05e6e00, time: 1279.01) 29 octets @ 0x8000e0fc
121   [0000]: ff 03 c0 21 01 01 00 19  01 04 05 f4 11 04 05 f4    ...!.... ........
122   [0010]: 13 09 03 00 c0 7b 9a 9f  2d 17 04 10 00             .....{.. -....
123 XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 38 octets @ 0x8007fd56
124   [0000]: ff 03 c0 21 01 01 00 22  00 04 00 00 01 04 05 f4    ...!..." ........
125   [0010]: 03 05 c2 23 05 11 04 05  f4 13 09 03 00 c0 7b 80    ...#.... ......{.
126   [0020]: 7c ef 17 04 0e 00                                   |.....
127 XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 29 octets @ 0x8007fa36
128   [0000]: ff 03 c0 21 02 01 00 19  01 04 05 f4 11 04 05 f4    ...!.... ........
129   [0010]: 13 09 03 00 c0 7b 9a 9f  2d 17 04 10 00             .....{.. -....
130
131     Example 'wandsess' output data (TAOS 8.0.3):
132
133 RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198
134   [0000]: ff 03 00 3d c0 00 00 04  80 fd 02 01 00 0a 11 06    ...=.... ........
135   [0010]: 00 01 01 03                                         ....
136 XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 26 octets @ 0x800806b6
137   [0000]: ff 03 00 3d c0 00 00 00  80 21 01 01 00 10 02 06    ...=.... .!......
138   [0010]: 00 2d 0f 01 03 06 89 64  03 08                      .-.....d ..
139 XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 20 octets @ 0x8007f716
140   [0000]: ff 03 00 3d c0 00 00 01  80 fd 01 01 00 0a 11 06    ...=.... ........
141   [0010]: 00 01 01 03                                         ....
142
143   The changes since TAOS 7.X are:
144
145     1) White space is added before "(task".
146     2) Task has a name, indicated by a subsequent string surrounded by a
147        double-quote.
148     3) Address expressed in hex number has a preceeding "0x".
149     4) Hex numbers are in lower case.
150     5) There is a character display corresponding to hex data in each line.
151
152  */
153
154 #include "config.h"
155
156 #include <stdlib.h>
157 #include <string.h>
158
159 #include "wtap-int.h"
160 #include <wsutil/buffer.h>
161 #include "ascendtext.h"
162 #include "ascend-int.h"
163 #include "ascend.h"
164 #include "ascend_scanner_lex.h"
165 #include "file_wrappers.h"
166
167 #define NO_USER "<none>"
168
169 extern void yyerror (void *yyscanner, ascend_state_t *state, FILE_T fh _U_, const char *s);
170 %}
171
172 %union {
173 gchar  *s;
174 guint32 d;
175 guint8  b;
176 }
177
178 %token <s> STRING KEYWORD WDD_DATE WDD_CHUNK COUNTER SLASH_SUFFIX
179 %token <d> WDS_PREFIX ISDN_PREFIX ETHER_PREFIX DECNUM HEXNUM
180 %token <b> HEXBYTE
181
182 %type <s> string dataln datagroup
183 %type <d> wds_prefix isdn_prefix ether_prefix decnum hexnum
184 %type <b> byte bytegroup
185
186 %parse-param { FILE_T fh }
187
188 %%
189
190 data_packet:
191   | ether_hdr datagroup
192   | deferred_isdn_hdr datagroup deferred_isdn_hdr datagroup
193   | isdn_hdr datagroup
194   | wds_hdr datagroup
195   | wds8_hdr datagroup
196   | wdp7_hdr datagroup
197   | wdp8_hdr datagroup
198   | wdd_date wdd_hdr datagroup
199   | wdd_hdr datagroup
200 ;
201
202 isdn_prefix: ISDN_PREFIX;
203
204 ether_prefix: ETHER_PREFIX;
205
206 wds_prefix: WDS_PREFIX;
207
208 string: STRING;
209
210 decnum: DECNUM;
211
212 hexnum: HEXNUM;
213
214 /*
215   pridisp special case - I-frame header printed separately from contents,
216   one frame across two messages.
217
218 PRI-XMIT-0/1:  (task "l1Task" at 0x80152b20, time: 283529.65) 4 octets @
219 0x80128220
220   [0000]: 00 01 ae b2                                         ....
221 PRI-XMIT-0/2 (task "l1Task" at 0x80152b20, time: 283529.65) 10 octets @
222 0x80128224
223   [0000]: 08 02 d7 e3 02 18 03 a9  83 8a                      ........
224
225 */
226 deferred_isdn_hdr: isdn_prefix decnum SLASH_SUFFIX KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
227   parser_state->wirelen += $11;
228   parser_state->caplen += $11;
229   parser_state->secs = $9;
230   parser_state->usecs = $10;
231   if (parser_state->pseudo_header != NULL) {
232     parser_state->pseudo_header->type = $1;
233     parser_state->pseudo_header->sess = $2;
234     parser_state->pseudo_header->call_num[0] = '\0';
235     parser_state->pseudo_header->chunk = 0;
236     parser_state->pseudo_header->task = $7;
237   }
238   /* because we have two data groups */
239   parser_state->first_hexbyte = 0;
240 }
241 ;
242
243 /*
244 PRI-XMIT-19:  (task "l1Task" at 0x10216840, time: 274758.67) 4 octets @ 0x1027c1c0
245  ... or ...
246 PRI-RCV-27:  (task "idle task" at 0x10123570, time: 560194.01) 4 octets @ 0x1027fb00
247 */
248 isdn_hdr: isdn_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
249   parser_state->wirelen = $10;
250   parser_state->caplen = $10;
251   parser_state->secs = $8;
252   parser_state->usecs = $9;
253   if (parser_state->pseudo_header != NULL) {
254     parser_state->pseudo_header->type = $1;
255     parser_state->pseudo_header->sess = $2;
256     parser_state->pseudo_header->call_num[0] = '\0';
257     parser_state->pseudo_header->chunk = 0;
258     parser_state->pseudo_header->task = $6;
259   }
260   parser_state->first_hexbyte = 0;
261 }
262 ;
263
264 /*
265 ETHER3ND XMIT: (task "_sarTask" at 0x802c6eb0, time: 259848.11) 414 octets @ 0xa
266 885f80e
267 */
268 ether_hdr: ether_prefix string KEYWORD string KEYWORD hexnum KEYWORD decnum decnum
269  decnum KEYWORD HEXNUM {
270   parser_state->wirelen = $10;
271   parser_state->caplen = $10;
272   parser_state->secs = $8;
273   parser_state->usecs = $9;
274   if (parser_state->pseudo_header != NULL) {
275     parser_state->pseudo_header->type = $1;
276     parser_state->pseudo_header->call_num[0] = '\0';
277     parser_state->pseudo_header->chunk = 0;
278     parser_state->pseudo_header->task = $6;
279   }
280 }
281 ;
282
283 /* RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 */
284 /*            1        2      3      4       5      6       7      8      9      10     11 */
285 wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
286   parser_state->wirelen = $9;
287   parser_state->caplen = $9;
288   parser_state->secs = $7;
289   parser_state->usecs = $8;
290   if (parser_state->pseudo_header != NULL) {
291     /* parser_state->pseudo_header->user is set in ascend_scanner.l */
292     parser_state->pseudo_header->type = $1;
293     parser_state->pseudo_header->sess = $3;
294     parser_state->pseudo_header->call_num[0] = '\0';
295     parser_state->pseudo_header->chunk = 0;
296     parser_state->pseudo_header->task = $5;
297   }
298 }
299 ;
300
301 /* RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 */
302 /*                1       2       3     4       5       6      7       8      9      10     11     12      13 */
303 wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
304   parser_state->wirelen = $11;
305   parser_state->caplen = $11;
306   parser_state->secs = $9;
307   parser_state->usecs = $10;
308   if (parser_state->pseudo_header != NULL) {
309     /* parser_state->pseudo_header->user is set in ascend_scanner.l */
310     parser_state->pseudo_header->type = $1;
311     parser_state->pseudo_header->sess = $3;
312     parser_state->pseudo_header->call_num[0] = '\0';
313     parser_state->pseudo_header->chunk = 0;
314     parser_state->pseudo_header->task = $7;
315   }
316 }
317 ;
318
319 /* RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 */
320 /*            1        2       3      4       5       6      7      8      9      10    */
321 wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
322   parser_state->wirelen = $8;
323   parser_state->caplen = $8;
324   parser_state->secs = $6;
325   parser_state->usecs = $7;
326   if (parser_state->pseudo_header != NULL) {
327     /* parser_state->pseudo_header->user is set in ascend_scanner.l */
328     parser_state->pseudo_header->type = $1;
329     parser_state->pseudo_header->sess = $2;
330     parser_state->pseudo_header->call_num[0] = '\0';
331     parser_state->pseudo_header->chunk = 0;
332     parser_state->pseudo_header->task = $4;
333   }
334 }
335 ;
336
337 /* XMIT-44: (task "freedm_task" at 0xe051fd10, time: 6258.66) 29 octets @ 0x606d1f00 */
338 /*              1        2       3      4       5      6      7       8      9      10     11      12 */
339 wdp8_hdr: wds_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
340   parser_state->wirelen = $10;
341   parser_state->caplen = $10;
342   parser_state->secs = $8;
343   parser_state->usecs = $9;
344   if (parser_state->pseudo_header != NULL) {
345     /* parser_state->pseudo_header->user is set in ascend_scanner.l */
346     parser_state->pseudo_header->type = $1;
347     parser_state->pseudo_header->sess = $2;
348     parser_state->pseudo_header->call_num[0] = '\0';
349     parser_state->pseudo_header->chunk = 0;
350     parser_state->pseudo_header->task = $6;
351   }
352 }
353 ;
354
355 /*
356 Date: 01/12/1990.  Time: 12:22:33
357 Cause an attempt to place call to 14082750382
358 */
359 /*           1        2      3      4      5       6      7      8      9      10*/
360 wdd_date: WDD_DATE decnum decnum decnum KEYWORD decnum decnum decnum KEYWORD string {
361   /*
362    * Supply the date/time value to the code above us; it will use the
363    * first date/time value supplied as the capture start date/time.
364    */
365   struct tm wddt;
366
367   wddt.tm_sec  = $8;
368   wddt.tm_min  = $7;
369   wddt.tm_hour = $6;
370   wddt.tm_mday = $3;
371   wddt.tm_mon  = $2 - 1;
372   wddt.tm_year = ($4 > 1970) ? $4 - 1900 : 70;
373   wddt.tm_isdst = -1;
374
375   parser_state->timestamp = (guint32) mktime(&wddt);
376   parser_state->saw_timestamp = TRUE;
377 }
378 ;
379
380 /*
381 WD_DIALOUT_DISP: chunk 2515EE type IP.
382 (task: 251790, time: 994953.28) 44 octets @ 2782B8
383 */
384 /*           1        2      3       4       5      6       7      8      9      10     11*/
385 wdd_hdr: WDD_CHUNK hexnum KEYWORD KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
386   parser_state->wirelen = $9;
387   parser_state->caplen = $9;
388   parser_state->secs = $7;
389   parser_state->usecs = $8;
390   if (parser_state->pseudo_header != NULL) {
391     /* parser_state->pseudo_header->call_num is set in ascend_scanner.l */
392     parser_state->pseudo_header->type = ASCEND_PFX_WDD;
393     parser_state->pseudo_header->user[0] = '\0';
394     parser_state->pseudo_header->sess = 0;
395     parser_state->pseudo_header->chunk = $2;
396     parser_state->pseudo_header->task = $5;
397   }
398 }
399 ;
400
401 byte: HEXBYTE {
402   /* remember the position of the data group in the trace, to tip
403      off ascend_seek() as to where to look for the next header. */
404   if (parser_state->first_hexbyte == 0)
405     parser_state->first_hexbyte = file_tell(fh);
406
407   if (parser_state->bcur < parser_state->caplen) {
408     parser_state->pkt_data[parser_state->bcur] = $1;
409     parser_state->bcur++;
410   }
411
412   /* arbitrary safety maximum... */
413   if (parser_state->bcur >= ASCEND_MAX_PKT_LEN)
414     YYACCEPT;
415 }
416 ;
417
418 /* XXX  There must be a better way to do this... */
419 bytegroup: byte
420   | byte byte
421   | byte byte byte
422   | byte byte byte byte
423   | byte byte byte byte byte
424   | byte byte byte byte byte byte
425   | byte byte byte byte byte byte byte
426   | byte byte byte byte byte byte byte byte
427   | byte byte byte byte byte byte byte byte byte
428   | byte byte byte byte byte byte byte byte byte byte
429   | byte byte byte byte byte byte byte byte byte byte byte
430   | byte byte byte byte byte byte byte byte byte byte byte byte
431   | byte byte byte byte byte byte byte byte byte byte byte byte byte
432   | byte byte byte byte byte byte byte byte byte byte byte byte byte byte
433   | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
434   | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
435 ;
436
437 dataln: COUNTER bytegroup;
438
439 datagroup: dataln
440   | dataln dataln
441   | dataln dataln dataln
442   | dataln dataln dataln dataln
443   | dataln dataln dataln dataln dataln
444   | dataln dataln dataln dataln dataln dataln
445   | dataln dataln dataln dataln dataln dataln dataln
446   | dataln dataln dataln dataln dataln dataln dataln dataln
447 ;
448
449 %%
450
451 /* Run the parser. */
452 int
453 run_ascend_parser(FILE_T fh, struct wtap_pkthdr *phdr, guint8 *pd,
454                   ascend_state_t *parser_state, int *err, gchar **err_info)
455 {
456   yyscan_t scanner = NULL;
457   int retval;
458
459   if (ascendlex_init(&scanner) != 0) {
460     /* errno is set if this fails */
461     *err = errno;
462     *err_info = NULL;
463     return 1;
464   }
465   /* Associate the parser state with the lexical analyzer state */
466   ascendset_extra(parser_state, scanner);
467   parser_state->fh = fh;
468   parser_state->ascend_parse_error = NULL;
469   parser_state->err = err;
470   parser_state->err_info = err_info;
471   parser_state->pseudo_header = &phdr->pseudo_header.ascend;
472   parser_state->pkt_data = pd;
473
474   /*
475    * We haven't seen a time stamp yet.
476    */
477   parser_state->saw_timestamp = FALSE;
478   parser_state->timestamp = 0;
479
480   parser_state->bcur = 0;
481   parser_state->first_hexbyte = 0;
482   parser_state->wirelen = 0;
483   parser_state->caplen = 0;
484
485   parser_state->secs = 0;
486   parser_state->usecs = 0;
487
488   /*
489    * Not all packets in a "wdd" dump necessarily have a "Cause an
490    * attempt to place call to" header (I presume this can happen if
491    * there was a call in progress when the packet was sent or
492    * received), so we won't necessarily have the phone number for
493    * the packet.
494    *
495    * XXX - we could assume, in the sequential pass, that it's the
496    * phone number from the last call, and remember that for use
497    * when doing random access.
498    */
499   parser_state->pseudo_header->call_num[0] = '\0';
500
501   retval = yyparse(scanner, parser_state, fh);
502   if (retval == 0)
503     parser_state->caplen = parser_state->bcur;
504   return retval;
505 }
506
507 void
508 yyerror (void *yyscanner, ascend_state_t *state _U_, FILE_T fh _U_, const char *s)
509 {
510   ascendget_extra(yyscanner)->ascend_parse_error = s;
511 }