From Aaron Woo (via Jeff Weston): Optimized Link State Routing Protocol
[obnox/wireshark/wip.git] / wiretap / ascend-grammar.y
1 %{
2 /* ascend-grammar.y
3  *
4  * $Id: ascend-grammar.y,v 1.25 2004/01/06 20:05:39 guy Exp $
5  *
6  * Wiretap Library
7  * Copyright (c) 1998 by Gilbert Ramirez <gram@alumni.rice.edu>
8  * 
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.
13  * 
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.
18  * 
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.
22  *
23  */
24
25 /*
26    Example 'wandsess' output data:
27    
28 RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94
29   [0000]: FF 03 00 3D C0 06 CA 22 2F 45 00 00 28 6A 3B 40 
30   [0010]: 00 3F 03 D7 37 CE 41 62 12 CF 00 FB 08 20 27 00 
31   [0020]: 50 E4 08 DD D7 7C 4C 71 92 50 10 7D 78 67 C8 00 
32   [0030]: 00 
33 XMIT-iguana:241:(task: B04E12C0, time: 1975432.85) 53 octets @ 8009EB16
34   [0000]: FF 03 00 3D C0 09 1E 31 21 45 00 00 2C 2D BD 40 
35   [0010]: 00 7A 06 D8 B1 CF 00 FB 08 CE 41 62 12 00 50 20 
36   [0020]: 29 7C 4C 71 9C 9A 6A 93 A4 60 12 22 38 3F 10 00 
37   [0030]: 00 02 04 05 B4 
38
39     Example 'wdd' output data:
40
41 Date: 01/12/1990.  Time: 12:22:33
42 Cause an attempt to place call to 14082750382
43 WD_DIALOUT_DISP: chunk 2515EE type IP.
44 (task: 251790, time: 994953.28) 44 octets @ 2782B8
45   [0000]: 00 C0 7B 71 45 6C 00 60 08 16 AA 51 08 00 45 00
46   [0010]: 00 2C 66 1C 40 00 80 06 53 F6 AC 14 00 18 CC 47
47   [0020]: C8 45 0A 31 00 50 3B D9 5B 75 00 00
48
49     The following output comes from a MAX with Software 7.2.3:
50
51 RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0
52   [0000]: FF 03 00 21 45 00 00 60 E3 49 00 00 7F 11 FD 7B
53   [0010]: C0 A8 F7 05 8A C8 18 51 00 89 00 89 00 4C C7 C1
54   [0020]: CC 8E 40 00 00 01 00 00 00 00 00 01 20 45 4A 45
55   [0030]: 42 45 43 45 48 43 4E 46 43 46 41 43 41 43 41 43
56   [0040]: 41 43 41 43 41 43 41 43 41 43 41 42 4E 00 00 20
57   [0050]: 00 01 C0 0C 00 20 00 01 00 04 93 E0 00 06 60 00
58   [0060]: C0 A8 F7 05
59 XMIT-187:(task: B0292CA0, time: 18042248.04) 60 octets @ 800AD576
60   [0000]: FF 03 00 21 45 00 00 38 D7 EE 00 00 0F 01 11 2B
61   [0010]: 0A FF FF FE C0 A8 F7 05 03 0D 33 D3 00 00 00 00
62   [0020]: 45 00 00 60 E3 49 00 00 7E 11 FE 7B C0 A8 F7 05
63   [0030]: 8A C8 18 51 00 89 00 89 00 4C C7 C1
64 RECV-187:(task: B0292CA0, time: 18042251.92) 16 octets @ 800018E8
65   [0000]: FF 03 C0 21 09 01 00 0C DE 61 96 4B 00 30 94 92
66
67   In TAOS 8.0, Lucent slightly changed the format as follows:
68
69     Example 'wandisp' output data (TAOS 8.0.3): (same format is used 
70     for 'wanopen' and 'wannext' command)
71
72 RECV-14: (task "idle task" at 0xb05e6e00, time: 1279.01) 29 octets @ 0x8000e0fc
73   [0000]: ff 03 c0 21 01 01 00 19  01 04 05 f4 11 04 05 f4    ...!.... ........
74   [0010]: 13 09 03 00 c0 7b 9a 9f  2d 17 04 10 00             .....{.. -....
75 XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 38 octets @ 0x8007fd56
76   [0000]: ff 03 c0 21 01 01 00 22  00 04 00 00 01 04 05 f4    ...!..." ........
77   [0010]: 03 05 c2 23 05 11 04 05  f4 13 09 03 00 c0 7b 80    ...#.... ......{.
78   [0020]: 7c ef 17 04 0e 00                                   |.....
79 XMIT-14: (task "idle task" at 0xb05e6e00, time: 1279.02) 29 octets @ 0x8007fa36
80   [0000]: ff 03 c0 21 02 01 00 19  01 04 05 f4 11 04 05 f4    ...!.... ........
81   [0010]: 13 09 03 00 c0 7b 9a 9f  2d 17 04 10 00             .....{.. -....
82
83     Example 'wandsess' output data (TAOS 8.0.3): 
84
85 RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198
86   [0000]: ff 03 00 3d c0 00 00 04  80 fd 02 01 00 0a 11 06    ...=.... ........
87   [0010]: 00 01 01 03                                         ....
88 XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 26 octets @ 0x800806b6
89   [0000]: ff 03 00 3d c0 00 00 00  80 21 01 01 00 10 02 06    ...=.... .!......
90   [0010]: 00 2d 0f 01 03 06 89 64  03 08                      .-.....d ..
91 XMIT-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.51) 20 octets @ 0x8007f716
92   [0000]: ff 03 00 3d c0 00 00 01  80 fd 01 01 00 0a 11 06    ...=.... ........
93   [0010]: 00 01 01 03                                         ....
94
95   The changes since TAOS 7.X are:
96
97     1) White space is added before "(task".
98     2) Task has a name, indicated by a subsequent string surrounded by a
99        double-quote.
100     3) Address expressed in hex number has a preceeding "0x".
101     4) Hex numbers are in lower case.
102     5) There is a character display corresponding to hex data in each line.
103
104  */
105
106 #ifdef HAVE_CONFIG_H
107 #include "config.h"
108 #endif
109
110 #include <stdio.h>
111 #include <stdlib.h>
112
113 #include "wtap-int.h"
114 #include "buffer.h"
115 #include "ascend.h"
116 #include "ascend-int.h"
117
118 #define NO_USER "<none>"
119
120 extern int at_eof;
121
122 int yyparse(void);
123 void yyerror(char *);
124
125 unsigned int bcur = 0, bcount;
126 guint32 start_time, secs, usecs, caplen, wirelen;
127 ascend_pkthdr *header;
128 struct ascend_phdr *pseudo_header;
129 guint8 *pkt_data;
130
131 %}
132  
133 %union {
134 gchar  *s;
135 guint32 d;
136 guint8  b;
137 }
138
139 %token <s> STRING KEYWORD WDD_DATE WDD_CHUNK COUNTER
140 %token <d> WDS_PREFIX DECNUM HEXNUM
141 %token <b> HEXBYTE
142
143 %type <s> string dataln datagroup
144 %type <d> wds_prefix decnum hexnum
145 %type <b> byte bytegroup
146
147 %%
148
149 data_packet:
150   | wds_hdr datagroup
151   | wds8_hdr datagroup
152   | wdp7_hdr datagroup
153   | wdp8_hdr datagroup
154   | wdd_date wdd_hdr datagroup
155   | wdd_hdr datagroup
156 ;
157
158 wds_prefix: WDS_PREFIX;
159
160 string: STRING;
161
162 decnum: DECNUM;
163
164 hexnum: HEXNUM;
165
166 /* RECV-iguana:241:(task: B02614C0, time: 1975432.85) 49 octets @ 8003BD94 */
167 /*            1        2      3      4       5      6       7      8      9      10     11 */
168 wds_hdr: wds_prefix string decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
169   wirelen = $9;
170   caplen = ($9 < ASCEND_MAX_PKT_LEN) ? $9 : ASCEND_MAX_PKT_LEN;
171   /* If we don't have as many bytes of data as the octet count in
172      the header, make the capture length the number of bytes we
173      actually have. */
174   if (bcount > 0 && bcount <= caplen)
175     caplen = bcount;
176   secs = $7;
177   usecs = $8;
178   if (pseudo_header != NULL) {
179     /* pseudo_header->user is set in ascend-scanner.l */
180     pseudo_header->type = $1;
181     pseudo_header->sess = $3;
182     pseudo_header->call_num[0] = '\0';
183     pseudo_header->chunk = 0;
184     pseudo_header->task = $5;
185   }
186   
187   bcur = 0;
188 }
189 ;
190
191 /* RECV-Max7:20: (task "_brouterControlTask" at 0xb094ac20, time: 1481.50) 20 octets @ 0x8000d198 */
192 /*                1       2       3     4       5       6      7       8      9      10     11     12      13 */
193 wds8_hdr: wds_prefix string decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
194   wirelen = $11;
195   caplen = ($11 < ASCEND_MAX_PKT_LEN) ? $11 : ASCEND_MAX_PKT_LEN;
196   /* If we don't have as many bytes of data as the octet count in
197      the header, make the capture length the number of bytes we
198      actually have. */
199   if (bcount > 0 && bcount <= caplen)
200     caplen = bcount;
201   secs = $9;
202   usecs = $10;
203   if (pseudo_header != NULL) {
204     /* pseudo_header->user is set in ascend-scanner.l */
205     pseudo_header->type = $1;
206     pseudo_header->sess = $3;
207     pseudo_header->call_num[0] = '\0';
208     pseudo_header->chunk = 0;
209     pseudo_header->task = $7;
210   }
211   
212   bcur = 0;
213 }
214 ;
215
216 /* RECV-187:(task: B050B480, time: 18042248.03) 100 octets @ 800012C0 */
217 /*            1        2       3      4       5       6      7      8      9      10    */
218 wdp7_hdr: wds_prefix decnum KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
219   wirelen = $8;
220   caplen = ($8 < ASCEND_MAX_PKT_LEN) ? $8 : ASCEND_MAX_PKT_LEN;
221   /* If we don't have as many bytes of data as the octet count in
222      the header, make the capture length the number of bytes we
223      actually have. */
224   if (bcount > 0 && bcount <= caplen)
225     caplen = bcount;
226   secs = $6;
227   usecs = $7;
228   if (pseudo_header != NULL) {
229     /* pseudo_header->user is set in ascend-scanner.l */
230     pseudo_header->type = $1;
231     pseudo_header->sess = $2;
232     pseudo_header->call_num[0] = '\0';
233     pseudo_header->chunk = 0;
234     pseudo_header->task = $4;
235   }
236   
237   bcur = 0;
238 }
239 ;
240
241 /* XMIT-44: (task "freedm_task" at 0xe051fd10, time: 6258.66) 29 octets @ 0x606d1f00 */
242 /*              1        2       3      4       5      6      7       8      9      10     11      12 */
243 wdp8_hdr: wds_prefix decnum KEYWORD string KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
244   wirelen = $10;
245   caplen = ($10 < ASCEND_MAX_PKT_LEN) ? $10 : ASCEND_MAX_PKT_LEN;
246   /* If we don't have as many bytes of data as the octet count in
247      the header, make the capture length the number of bytes we
248      actually have. */
249   if (bcount > 0 && bcount <= caplen)
250     caplen = bcount;
251   secs = $8;
252   usecs = $9;
253   if (pseudo_header != NULL) {
254     /* pseudo_header->user is set in ascend-scanner.l */
255     pseudo_header->type = $1;
256     pseudo_header->sess = $2;
257     pseudo_header->call_num[0] = '\0';
258     pseudo_header->chunk = 0;
259     pseudo_header->task = $6;
260   }
261   
262   bcur = 0;
263 }
264 ;
265
266 /*
267 Date: 01/12/1990.  Time: 12:22:33
268 Cause an attempt to place call to 14082750382
269 */
270 /*           1        2      3      4      5       6      7      8      9      10*/
271 wdd_date: WDD_DATE decnum decnum decnum KEYWORD decnum decnum decnum KEYWORD string {
272   /*
273    * Supply the date/time value to the code above us; it will use the
274    * first date/time value supplied as the capture start date/time.
275    */
276   struct tm wddt;
277
278   wddt.tm_sec  = $8;
279   wddt.tm_min  = $7;
280   wddt.tm_hour = $6;
281   wddt.tm_mday = $3;
282   wddt.tm_mon  = $2 - 1;
283   wddt.tm_year = ($4 > 1970) ? $4 - 1900 : 70;
284   wddt.tm_isdst = -1;
285   
286   start_time = mktime(&wddt);
287 }
288 ;
289  
290 /*
291 WD_DIALOUT_DISP: chunk 2515EE type IP.
292 (task: 251790, time: 994953.28) 44 octets @ 2782B8
293 */
294 /*           1        2      3       4       5      6       7      8      9      10     11*/
295 wdd_hdr: WDD_CHUNK hexnum KEYWORD KEYWORD hexnum KEYWORD decnum decnum decnum KEYWORD HEXNUM {
296   wirelen = $9;
297   caplen = ($9 < ASCEND_MAX_PKT_LEN) ? $9 : ASCEND_MAX_PKT_LEN;
298   /* If we don't have as many bytes of data as the octet count in
299      the header, make the capture length the number of bytes we
300      actually have. */
301   if (bcount > 0 && bcount <= caplen)
302     caplen = bcount;
303   secs = $7;
304   usecs = $8;
305   if (pseudo_header != NULL) {
306     /* pseudo_header->call_num is set in ascend-scanner.l */
307     pseudo_header->type = ASCEND_PFX_WDD;
308     pseudo_header->user[0] = '\0';
309     pseudo_header->sess = 0;
310     pseudo_header->chunk = $2;
311     pseudo_header->task = $5;
312   }
313   
314   bcur = 0;
315 }
316 ;
317  
318 byte: HEXBYTE {
319   if (bcur < caplen) {
320     pkt_data[bcur] = $1;
321     bcur++;
322   }
323
324   if (bcur >= caplen) {
325     if (header != NULL) {
326       header->start_time = start_time;
327       header->secs = secs;
328       header->usecs = usecs;
329       header->caplen = caplen;
330       header->len = wirelen;
331     }
332     YYACCEPT;
333   }
334
335 ;
336
337 /* XXX  There must be a better way to do this... */
338 bytegroup: byte
339   | byte byte
340   | byte byte byte
341   | byte byte byte byte
342   | byte byte byte byte byte
343   | byte byte byte byte byte byte
344   | byte byte byte byte byte byte byte
345   | byte byte byte byte byte byte byte byte
346   | byte byte byte byte byte byte byte byte byte
347   | byte byte byte byte byte byte byte byte byte byte
348   | byte byte byte byte byte byte byte byte byte byte byte
349   | byte byte byte byte byte byte byte byte byte byte byte byte
350   | byte byte byte byte byte byte byte byte byte byte byte byte byte
351   | byte byte byte byte byte byte byte byte byte byte byte byte byte byte
352   | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
353   | byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte byte
354 ;
355
356 dataln: COUNTER bytegroup;
357
358 datagroup: dataln
359   | dataln dataln
360   | dataln dataln dataln
361   | dataln dataln dataln dataln
362   | dataln dataln dataln dataln dataln
363   | dataln dataln dataln dataln dataln dataln
364   | dataln dataln dataln dataln dataln dataln dataln
365   | dataln dataln dataln dataln dataln dataln dataln dataln
366 ;
367
368 %%
369
370 void
371 init_parse_ascend()
372 {
373   bcur = 0;
374   at_eof = 0;
375   start_time = 0;       /* we haven't see a date/time yet */
376 }
377
378 /* Parse the capture file.  Return the offset of the next packet, or zero
379    if there is none. */
380 int
381 parse_ascend(FILE_T fh, guint8 *pd, struct ascend_phdr *phdr,
382                 ascend_pkthdr *hdr, int len)
383 {
384   /* yydebug = 1; */
385  
386   ascend_init_lexer(fh);
387   pkt_data = pd;
388   pseudo_header = phdr;
389   header = hdr;
390   bcount = len;
391   
392   /*
393    * Not all packets in a "wdd" dump necessarily have a "Cause an
394    * attempt to place call to" header (I presume this can happen if
395    * there was a call in progress when the packet was sent or
396    * received), so we won't necessarily have the phone number for
397    * the packet.
398    *
399    * XXX - we could assume, in the sequential pass, that it's the
400    * phone number from the last call, and remember that for use
401    * when doing random access.
402    */
403   pseudo_header->call_num[0] = '\0';
404
405   if (yyparse())
406     return 0;
407   else
408     return 1;
409 }
410
411 void
412 yyerror (char *s _U_)
413 {
414 }