]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libpcap/grammar.y
This commit was generated by cvs2svn to compensate for changes in r147021,
[FreeBSD/FreeBSD.git] / contrib / libpcap / grammar.y
1 %{
2 /*
3  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
4  *      The Regents of the University of California.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that: (1) source code distributions
8  * retain the above copyright notice and this paragraph in its entirety, (2)
9  * distributions including binary code include the above copyright notice and
10  * this paragraph in its entirety in the documentation or other materials
11  * provided with the distribution, and (3) all advertising materials mentioning
12  * features or use of this software display the following acknowledgement:
13  * ``This product includes software developed by the University of California,
14  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15  * the University nor the names of its contributors may be used to endorse
16  * or promote products derived from this software without specific prior
17  * written permission.
18  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21  *
22  * $FreeBSD$
23  */
24 #ifndef lint
25 static const char rcsid[] _U_ =
26     "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.86 2004/12/18 08:49:23 guy Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef WIN32
34 #include <pcap-stdinc.h>
35 #else /* WIN32 */
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #endif /* WIN32 */
39
40 #include <stdlib.h>
41
42 #ifndef WIN32
43 #if __STDC__
44 struct mbuf;
45 struct rtentry;
46 #endif
47
48 #include <netinet/in.h>
49 #endif /* WIN32 */
50
51 #include <stdio.h>
52
53 #include "pcap-int.h"
54
55 #include "gencode.h"
56 #include "pf.h"
57 #include <pcap-namedb.h>
58
59 #ifdef HAVE_OS_PROTO_H
60 #include "os-proto.h"
61 #endif
62
63 #define QSET(q, p, d, a) (q).proto = (p),\
64                          (q).dir = (d),\
65                          (q).addr = (a)
66
67 int n_errors = 0;
68
69 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
70
71 static void
72 yyerror(char *msg)
73 {
74         ++n_errors;
75         bpf_error("%s", msg);
76         /* NOTREACHED */
77 }
78
79 #ifndef YYBISON
80 int yyparse(void);
81
82 int
83 pcap_parse()
84 {
85         return (yyparse());
86 }
87 #endif
88
89 %}
90
91 %union {
92         int i;
93         bpf_u_int32 h;
94         u_char *e;
95         char *s;
96         struct stmt *stmt;
97         struct arth *a;
98         struct {
99                 struct qual q;
100                 int atmfieldtype;
101                 struct block *b;
102         } blk;
103         struct block *rblk;
104 }
105
106 %type   <blk>   expr id nid pid term rterm qid
107 %type   <blk>   head
108 %type   <i>     pqual dqual aqual ndaqual
109 %type   <a>     arth narth
110 %type   <i>     byteop pname pnum relop irelop
111 %type   <blk>   and or paren not null prog
112 %type   <rblk>  other pfvar
113 %type   <i>     atmtype atmmultitype
114 %type   <blk>   atmfield
115 %type   <blk>   atmfieldvalue atmvalue atmlistvalue
116
117 %token  DST SRC HOST GATEWAY
118 %token  NET NETMASK PORT LESS GREATER PROTO PROTOCHAIN CBYTE
119 %token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
120 %token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
121 %token  TK_BROADCAST TK_MULTICAST
122 %token  NUM INBOUND OUTBOUND
123 %token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
124 %token  LINK
125 %token  GEQ LEQ NEQ
126 %token  ID EID HID HID6 AID
127 %token  LSH RSH
128 %token  LEN
129 %token  IPV6 ICMPV6 AH ESP
130 %token  VLAN MPLS
131 %token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP 
132 %token  STP
133 %token  IPX
134 %token  NETBEUI
135 %token  LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
136 %token  OAM OAMF4 CONNECTMSG METACONNECT
137 %token  VPI VCI
138
139 %type   <s> ID
140 %type   <e> EID
141 %type   <e> AID
142 %type   <s> HID HID6
143 %type   <i> NUM action reason
144
145 %left OR AND
146 %nonassoc  '!'
147 %left '|'
148 %left '&'
149 %left LSH RSH
150 %left '+' '-'
151 %left '*' '/'
152 %nonassoc UMINUS
153 %%
154 prog:     null expr
155 {
156         finish_parse($2.b);
157 }
158         | null
159         ;
160 null:     /* null */            { $$.q = qerr; }
161         ;
162 expr:     term
163         | expr and term         { gen_and($1.b, $3.b); $$ = $3; }
164         | expr and id           { gen_and($1.b, $3.b); $$ = $3; }
165         | expr or term          { gen_or($1.b, $3.b); $$ = $3; }
166         | expr or id            { gen_or($1.b, $3.b); $$ = $3; }
167         ;
168 and:      AND                   { $$ = $<blk>0; }
169         ;
170 or:       OR                    { $$ = $<blk>0; }
171         ;
172 id:       nid
173         | pnum                  { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
174                                                    $$.q = $<blk>0.q); }
175         | paren pid ')'         { $$ = $2; }
176         ;
177 nid:      ID                    { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
178         | HID '/' NUM           { $$.b = gen_mcode($1, NULL, $3,
179                                     $$.q = $<blk>0.q); }
180         | HID NETMASK HID       { $$.b = gen_mcode($1, $3, 0,
181                                     $$.q = $<blk>0.q); }
182         | HID                   {
183                                   /* Decide how to parse HID based on proto */
184                                   $$.q = $<blk>0.q;
185                                   $$.b = gen_ncode($1, 0, $$.q);
186                                 }
187         | HID6 '/' NUM          {
188 #ifdef INET6
189                                   $$.b = gen_mcode6($1, NULL, $3,
190                                     $$.q = $<blk>0.q);
191 #else
192                                   bpf_error("'ip6addr/prefixlen' not supported "
193                                         "in this configuration");
194 #endif /*INET6*/
195                                 }
196         | HID6                  {
197 #ifdef INET6
198                                   $$.b = gen_mcode6($1, 0, 128,
199                                     $$.q = $<blk>0.q);
200 #else
201                                   bpf_error("'ip6addr' not supported "
202                                         "in this configuration");
203 #endif /*INET6*/
204                                 }
205         | EID                   { 
206                                   $$.b = gen_ecode($1, $$.q = $<blk>0.q);
207                                   /*
208                                    * $1 was allocated by "pcap_ether_aton()",
209                                    * so we must free it now that we're done
210                                    * with it.
211                                    */
212                                   free($1);
213                                 }
214         | AID                   {
215                                   $$.b = gen_acode($1, $$.q = $<blk>0.q);
216                                   /*
217                                    * $1 was allocated by "pcap_ether_aton()",
218                                    * so we must free it now that we're done
219                                    * with it.
220                                    */
221                                   free($1);
222                                 }
223         | not id                { gen_not($2.b); $$ = $2; }
224         ;
225 not:      '!'                   { $$ = $<blk>0; }
226         ;
227 paren:    '('                   { $$ = $<blk>0; }
228         ;
229 pid:      nid
230         | qid and id            { gen_and($1.b, $3.b); $$ = $3; }
231         | qid or id             { gen_or($1.b, $3.b); $$ = $3; }
232         ;
233 qid:      pnum                  { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
234                                                    $$.q = $<blk>0.q); }
235         | pid
236         ;
237 term:     rterm
238         | not term              { gen_not($2.b); $$ = $2; }
239         ;
240 head:     pqual dqual aqual     { QSET($$.q, $1, $2, $3); }
241         | pqual dqual           { QSET($$.q, $1, $2, Q_DEFAULT); }
242         | pqual aqual           { QSET($$.q, $1, Q_DEFAULT, $2); }
243         | pqual PROTO           { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
244         | pqual PROTOCHAIN      { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
245         | pqual ndaqual         { QSET($$.q, $1, Q_DEFAULT, $2); }
246         ;
247 rterm:    head id               { $$ = $2; }
248         | paren expr ')'        { $$.b = $2.b; $$.q = $1.q; }
249         | pname                 { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
250         | arth relop arth       { $$.b = gen_relation($2, $1, $3, 0);
251                                   $$.q = qerr; }
252         | arth irelop arth      { $$.b = gen_relation($2, $1, $3, 1);
253                                   $$.q = qerr; }
254         | other                 { $$.b = $1; $$.q = qerr; }
255         | atmtype               { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
256         | atmmultitype          { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
257         | atmfield atmvalue     { $$.b = $2.b; $$.q = qerr; }
258         ;
259 /* protocol level qualifiers */
260 pqual:    pname
261         |                       { $$ = Q_DEFAULT; }
262         ;
263 /* 'direction' qualifiers */
264 dqual:    SRC                   { $$ = Q_SRC; }
265         | DST                   { $$ = Q_DST; }
266         | SRC OR DST            { $$ = Q_OR; }
267         | DST OR SRC            { $$ = Q_OR; }
268         | SRC AND DST           { $$ = Q_AND; }
269         | DST AND SRC           { $$ = Q_AND; }
270         ;
271 /* address type qualifiers */
272 aqual:    HOST                  { $$ = Q_HOST; }
273         | NET                   { $$ = Q_NET; }
274         | PORT                  { $$ = Q_PORT; }
275         ;
276 /* non-directional address type qualifiers */
277 ndaqual:  GATEWAY               { $$ = Q_GATEWAY; }
278         ;
279 pname:    LINK                  { $$ = Q_LINK; }
280         | IP                    { $$ = Q_IP; }
281         | ARP                   { $$ = Q_ARP; }
282         | RARP                  { $$ = Q_RARP; }
283         | SCTP                  { $$ = Q_SCTP; }
284         | TCP                   { $$ = Q_TCP; }
285         | UDP                   { $$ = Q_UDP; }
286         | ICMP                  { $$ = Q_ICMP; }
287         | IGMP                  { $$ = Q_IGMP; }
288         | IGRP                  { $$ = Q_IGRP; }
289         | PIM                   { $$ = Q_PIM; }
290         | VRRP                  { $$ = Q_VRRP; }
291         | ATALK                 { $$ = Q_ATALK; }
292         | AARP                  { $$ = Q_AARP; }
293         | DECNET                { $$ = Q_DECNET; }
294         | LAT                   { $$ = Q_LAT; }
295         | SCA                   { $$ = Q_SCA; }
296         | MOPDL                 { $$ = Q_MOPDL; }
297         | MOPRC                 { $$ = Q_MOPRC; }
298         | IPV6                  { $$ = Q_IPV6; }
299         | ICMPV6                { $$ = Q_ICMPV6; }
300         | AH                    { $$ = Q_AH; }
301         | ESP                   { $$ = Q_ESP; }
302         | ISO                   { $$ = Q_ISO; }
303         | ESIS                  { $$ = Q_ESIS; }
304         | ISIS                  { $$ = Q_ISIS; }
305         | L1                    { $$ = Q_ISIS_L1; }
306         | L2                    { $$ = Q_ISIS_L2; }
307         | IIH                   { $$ = Q_ISIS_IIH; }
308         | LSP                   { $$ = Q_ISIS_LSP; }
309         | SNP                   { $$ = Q_ISIS_SNP; }
310         | PSNP                  { $$ = Q_ISIS_PSNP; }
311         | CSNP                  { $$ = Q_ISIS_CSNP; }
312         | CLNP                  { $$ = Q_CLNP; }
313         | STP                   { $$ = Q_STP; }
314         | IPX                   { $$ = Q_IPX; }
315         | NETBEUI               { $$ = Q_NETBEUI; }
316         ;
317 other:    pqual TK_BROADCAST    { $$ = gen_broadcast($1); }
318         | pqual TK_MULTICAST    { $$ = gen_multicast($1); }
319         | LESS NUM              { $$ = gen_less($2); }
320         | GREATER NUM           { $$ = gen_greater($2); }
321         | CBYTE NUM byteop NUM  { $$ = gen_byteop($3, $2, $4); }
322         | INBOUND               { $$ = gen_inbound(0); }
323         | OUTBOUND              { $$ = gen_inbound(1); }
324         | VLAN pnum             { $$ = gen_vlan($2); }
325         | VLAN                  { $$ = gen_vlan(-1); }
326         | MPLS pnum             { $$ = gen_mpls($2); }
327         | MPLS                  { $$ = gen_mpls(-1); }
328         | pfvar                 { $$ = $1; }
329         ;
330
331 pfvar:    PF_IFNAME ID          { $$ = gen_pf_ifname($2); }
332         | PF_RSET ID            { $$ = gen_pf_ruleset($2); }
333         | PF_RNR NUM            { $$ = gen_pf_rnr($2); }
334         | PF_SRNR NUM           { $$ = gen_pf_srnr($2); }
335         | PF_REASON reason      { $$ = gen_pf_reason($2); }
336         | PF_ACTION action      { $$ = gen_pf_action($2); }
337         ;
338
339 reason:   NUM                   { $$ = $1; }
340         | ID                    { const char *reasons[] = PFRES_NAMES;
341                                   int i;
342                                   for (i = 0; reasons[i]; i++) {
343                                           if (pcap_strcasecmp($1, reasons[i]) == 0) {
344                                                   $$ = i;
345                                                   break;
346                                           }
347                                   }
348                                   if (reasons[i] == NULL)
349                                           bpf_error("unknown PF reason");
350                                 }
351         ;
352
353 action:   ID                    { if (pcap_strcasecmp($1, "pass") == 0 ||
354                                       pcap_strcasecmp($1, "accept") == 0)
355                                         $$ = PF_PASS;
356                                   else if (pcap_strcasecmp($1, "drop") == 0 ||
357                                       pcap_strcasecmp($1, "block") == 0)
358                                         $$ = PF_DROP;
359                                   else
360                                           bpf_error("unknown PF action");
361                                 }
362         ;
363
364 relop:    '>'                   { $$ = BPF_JGT; }
365         | GEQ                   { $$ = BPF_JGE; }
366         | '='                   { $$ = BPF_JEQ; }
367         ;
368 irelop:   LEQ                   { $$ = BPF_JGT; }
369         | '<'                   { $$ = BPF_JGE; }
370         | NEQ                   { $$ = BPF_JEQ; }
371         ;
372 arth:     pnum                  { $$ = gen_loadi($1); }
373         | narth
374         ;
375 narth:    pname '[' arth ']'            { $$ = gen_load($1, $3, 1); }
376         | pname '[' arth ':' NUM ']'    { $$ = gen_load($1, $3, $5); }
377         | arth '+' arth                 { $$ = gen_arth(BPF_ADD, $1, $3); }
378         | arth '-' arth                 { $$ = gen_arth(BPF_SUB, $1, $3); }
379         | arth '*' arth                 { $$ = gen_arth(BPF_MUL, $1, $3); }
380         | arth '/' arth                 { $$ = gen_arth(BPF_DIV, $1, $3); }
381         | arth '&' arth                 { $$ = gen_arth(BPF_AND, $1, $3); }
382         | arth '|' arth                 { $$ = gen_arth(BPF_OR, $1, $3); }
383         | arth LSH arth                 { $$ = gen_arth(BPF_LSH, $1, $3); }
384         | arth RSH arth                 { $$ = gen_arth(BPF_RSH, $1, $3); }
385         | '-' arth %prec UMINUS         { $$ = gen_neg($2); }
386         | paren narth ')'               { $$ = $2; }
387         | LEN                           { $$ = gen_loadlen(); }
388         ;
389 byteop:   '&'                   { $$ = '&'; }
390         | '|'                   { $$ = '|'; }
391         | '<'                   { $$ = '<'; }
392         | '>'                   { $$ = '>'; }
393         | '='                   { $$ = '='; }
394         ;
395 pnum:     NUM
396         | paren pnum ')'        { $$ = $2; }
397         ;
398 atmtype: LANE                   { $$ = A_LANE; }
399         | LLC                   { $$ = A_LLC; }
400         | METAC                 { $$ = A_METAC; }
401         | BCC                   { $$ = A_BCC; }
402         | OAMF4EC               { $$ = A_OAMF4EC; }
403         | OAMF4SC               { $$ = A_OAMF4SC; }
404         | SC                    { $$ = A_SC; }
405         | ILMIC                 { $$ = A_ILMIC; }
406         ;
407 atmmultitype: OAM               { $$ = A_OAM; }
408         | OAMF4                 { $$ = A_OAMF4; }
409         | CONNECTMSG            { $$ = A_CONNECTMSG; }
410         | METACONNECT           { $$ = A_METACONNECT; }
411         ;
412         /* ATM field types quantifier */
413 atmfield: VPI                   { $$.atmfieldtype = A_VPI; }
414         | VCI                   { $$.atmfieldtype = A_VCI; }
415         ;
416 atmvalue: atmfieldvalue
417         | relop NUM             { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 0); }
418         | irelop NUM            { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (u_int)$2, (u_int)$1, 1); }
419         | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
420         ;
421 atmfieldvalue: NUM {
422         $$.atmfieldtype = $<blk>0.atmfieldtype;
423         if ($$.atmfieldtype == A_VPI ||
424             $$.atmfieldtype == A_VCI)
425                 $$.b = gen_atmfield_code($$.atmfieldtype, (u_int) $1, BPF_JEQ, 0);
426         }
427         ;
428 atmlistvalue: atmfieldvalue
429         | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
430         ;
431 %%