]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - contrib/libpcap/grammar.y
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.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.2.9 2007/09/12 19:17:25 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 #ifdef HAVE_NET_PFVAR_H
57 #include <net/if.h>
58 #include <net/pfvar.h>
59 #include <net/if_pflog.h>
60 #endif
61 #include <pcap-namedb.h>
62
63 #ifdef HAVE_OS_PROTO_H
64 #include "os-proto.h"
65 #endif
66
67 #define QSET(q, p, d, a) (q).proto = (p),\
68                          (q).dir = (d),\
69                          (q).addr = (a)
70
71 int n_errors = 0;
72
73 static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
74
75 static void
76 yyerror(const char *msg)
77 {
78         ++n_errors;
79         bpf_error("%s", msg);
80         /* NOTREACHED */
81 }
82
83 #ifndef YYBISON
84 int yyparse(void);
85
86 int
87 pcap_parse()
88 {
89         return (yyparse());
90 }
91 #endif
92
93 #ifdef HAVE_NET_PFVAR_H
94 static int
95 pfreason_to_num(const char *reason)
96 {
97         const char *reasons[] = PFRES_NAMES;
98         int i;
99
100         for (i = 0; reasons[i]; i++) {
101                 if (pcap_strcasecmp(reason, reasons[i]) == 0)
102                         return (i);
103         }
104         bpf_error("unknown PF reason");
105         /*NOTREACHED*/
106 }
107
108 static int
109 pfaction_to_num(const char *action)
110 {
111         if (pcap_strcasecmp(action, "pass") == 0 ||
112             pcap_strcasecmp(action, "accept") == 0)
113                 return (PF_PASS);
114         else if (pcap_strcasecmp(action, "drop") == 0 ||
115                 pcap_strcasecmp(action, "block") == 0)
116                 return (PF_DROP);
117         else {
118                 bpf_error("unknown PF action");
119                 /*NOTREACHED*/
120         }
121 }
122 #else /* !HAVE_NET_PFVAR_H */
123 static int
124 pfreason_to_num(const char *reason)
125 {
126         bpf_error("libpcap was compiled on a machine without pf support");
127         /*NOTREACHED*/
128 }
129
130 static int
131 pfaction_to_num(const char *action)
132 {
133         bpf_error("libpcap was compiled on a machine without pf support");
134         /*NOTREACHED*/
135 }
136 #endif /* HAVE_NET_PFVAR_H */
137 %}
138
139 %union {
140         int i;
141         bpf_u_int32 h;
142         u_char *e;
143         char *s;
144         struct stmt *stmt;
145         struct arth *a;
146         struct {
147                 struct qual q;
148                 int atmfieldtype;
149                 int mtp3fieldtype;
150                 struct block *b;
151         } blk;
152         struct block *rblk;
153 }
154
155 %type   <blk>   expr id nid pid term rterm qid
156 %type   <blk>   head
157 %type   <i>     pqual dqual aqual ndaqual
158 %type   <a>     arth narth
159 %type   <i>     byteop pname pnum relop irelop
160 %type   <blk>   and or paren not null prog
161 %type   <rblk>  other pfvar
162 %type   <i>     atmtype atmmultitype
163 %type   <blk>   atmfield
164 %type   <blk>   atmfieldvalue atmvalue atmlistvalue
165 %type   <i>     mtp2type
166 %type   <blk>   mtp3field
167 %type   <blk>   mtp3fieldvalue mtp3value mtp3listvalue
168
169
170 %token  DST SRC HOST GATEWAY
171 %token  NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
172 %token  ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP
173 %token  ATALK AARP DECNET LAT SCA MOPRC MOPDL
174 %token  TK_BROADCAST TK_MULTICAST
175 %token  NUM INBOUND OUTBOUND
176 %token  PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
177 %token  LINK
178 %token  GEQ LEQ NEQ
179 %token  ID EID HID HID6 AID
180 %token  LSH RSH
181 %token  LEN
182 %token  IPV6 ICMPV6 AH ESP
183 %token  VLAN MPLS
184 %token  PPPOED PPPOES
185 %token  ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP 
186 %token  STP
187 %token  IPX
188 %token  NETBEUI
189 %token  LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
190 %token  OAM OAMF4 CONNECTMSG METACONNECT
191 %token  VPI VCI
192 %token  RADIO
193 %token  FISU LSSU MSU
194 %token  SIO OPC DPC SLS
195
196 %type   <s> ID
197 %type   <e> EID
198 %type   <e> AID
199 %type   <s> HID HID6
200 %type   <i> NUM action reason
201
202 %left OR AND
203 %nonassoc  '!'
204 %left '|'
205 %left '&'
206 %left LSH RSH
207 %left '+' '-'
208 %left '*' '/'
209 %nonassoc UMINUS
210 %%
211 prog:     null expr
212 {
213         finish_parse($2.b);
214 }
215         | null
216         ;
217 null:     /* null */            { $$.q = qerr; }
218         ;
219 expr:     term
220         | expr and term         { gen_and($1.b, $3.b); $$ = $3; }
221         | expr and id           { gen_and($1.b, $3.b); $$ = $3; }
222         | expr or term          { gen_or($1.b, $3.b); $$ = $3; }
223         | expr or id            { gen_or($1.b, $3.b); $$ = $3; }
224         ;
225 and:      AND                   { $$ = $<blk>0; }
226         ;
227 or:       OR                    { $$ = $<blk>0; }
228         ;
229 id:       nid
230         | pnum                  { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
231                                                    $$.q = $<blk>0.q); }
232         | paren pid ')'         { $$ = $2; }
233         ;
234 nid:      ID                    { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
235         | HID '/' NUM           { $$.b = gen_mcode($1, NULL, $3,
236                                     $$.q = $<blk>0.q); }
237         | HID NETMASK HID       { $$.b = gen_mcode($1, $3, 0,
238                                     $$.q = $<blk>0.q); }
239         | HID                   {
240                                   /* Decide how to parse HID based on proto */
241                                   $$.q = $<blk>0.q;
242                                   $$.b = gen_ncode($1, 0, $$.q);
243                                 }
244         | HID6 '/' NUM          {
245 #ifdef INET6
246                                   $$.b = gen_mcode6($1, NULL, $3,
247                                     $$.q = $<blk>0.q);
248 #else
249                                   bpf_error("'ip6addr/prefixlen' not supported "
250                                         "in this configuration");
251 #endif /*INET6*/
252                                 }
253         | HID6                  {
254 #ifdef INET6
255                                   $$.b = gen_mcode6($1, 0, 128,
256                                     $$.q = $<blk>0.q);
257 #else
258                                   bpf_error("'ip6addr' not supported "
259                                         "in this configuration");
260 #endif /*INET6*/
261                                 }
262         | EID                   { 
263                                   $$.b = gen_ecode($1, $$.q = $<blk>0.q);
264                                   /*
265                                    * $1 was allocated by "pcap_ether_aton()",
266                                    * so we must free it now that we're done
267                                    * with it.
268                                    */
269                                   free($1);
270                                 }
271         | AID                   {
272                                   $$.b = gen_acode($1, $$.q = $<blk>0.q);
273                                   /*
274                                    * $1 was allocated by "pcap_ether_aton()",
275                                    * so we must free it now that we're done
276                                    * with it.
277                                    */
278                                   free($1);
279                                 }
280         | not id                { gen_not($2.b); $$ = $2; }
281         ;
282 not:      '!'                   { $$ = $<blk>0; }
283         ;
284 paren:    '('                   { $$ = $<blk>0; }
285         ;
286 pid:      nid
287         | qid and id            { gen_and($1.b, $3.b); $$ = $3; }
288         | qid or id             { gen_or($1.b, $3.b); $$ = $3; }
289         ;
290 qid:      pnum                  { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
291                                                    $$.q = $<blk>0.q); }
292         | pid
293         ;
294 term:     rterm
295         | not term              { gen_not($2.b); $$ = $2; }
296         ;
297 head:     pqual dqual aqual     { QSET($$.q, $1, $2, $3); }
298         | pqual dqual           { QSET($$.q, $1, $2, Q_DEFAULT); }
299         | pqual aqual           { QSET($$.q, $1, Q_DEFAULT, $2); }
300         | pqual PROTO           { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
301         | pqual PROTOCHAIN      { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
302         | pqual ndaqual         { QSET($$.q, $1, Q_DEFAULT, $2); }
303         ;
304 rterm:    head id               { $$ = $2; }
305         | paren expr ')'        { $$.b = $2.b; $$.q = $1.q; }
306         | pname                 { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
307         | arth relop arth       { $$.b = gen_relation($2, $1, $3, 0);
308                                   $$.q = qerr; }
309         | arth irelop arth      { $$.b = gen_relation($2, $1, $3, 1);
310                                   $$.q = qerr; }
311         | other                 { $$.b = $1; $$.q = qerr; }
312         | atmtype               { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
313         | atmmultitype          { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
314         | atmfield atmvalue     { $$.b = $2.b; $$.q = qerr; }
315         | mtp2type              { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
316         | mtp3field mtp3value   { $$.b = $2.b; $$.q = qerr; }
317         ;
318 /* protocol level qualifiers */
319 pqual:    pname
320         |                       { $$ = Q_DEFAULT; }
321         ;
322 /* 'direction' qualifiers */
323 dqual:    SRC                   { $$ = Q_SRC; }
324         | DST                   { $$ = Q_DST; }
325         | SRC OR DST            { $$ = Q_OR; }
326         | DST OR SRC            { $$ = Q_OR; }
327         | SRC AND DST           { $$ = Q_AND; }
328         | DST AND SRC           { $$ = Q_AND; }
329         ;
330 /* address type qualifiers */
331 aqual:    HOST                  { $$ = Q_HOST; }
332         | NET                   { $$ = Q_NET; }
333         | PORT                  { $$ = Q_PORT; }
334         | PORTRANGE             { $$ = Q_PORTRANGE; }
335         ;
336 /* non-directional address type qualifiers */
337 ndaqual:  GATEWAY               { $$ = Q_GATEWAY; }
338         ;
339 pname:    LINK                  { $$ = Q_LINK; }
340         | IP                    { $$ = Q_IP; }
341         | ARP                   { $$ = Q_ARP; }
342         | RARP                  { $$ = Q_RARP; }
343         | SCTP                  { $$ = Q_SCTP; }
344         | TCP                   { $$ = Q_TCP; }
345         | UDP                   { $$ = Q_UDP; }
346         | ICMP                  { $$ = Q_ICMP; }
347         | IGMP                  { $$ = Q_IGMP; }
348         | IGRP                  { $$ = Q_IGRP; }
349         | PIM                   { $$ = Q_PIM; }
350         | VRRP                  { $$ = Q_VRRP; }
351         | ATALK                 { $$ = Q_ATALK; }
352         | AARP                  { $$ = Q_AARP; }
353         | DECNET                { $$ = Q_DECNET; }
354         | LAT                   { $$ = Q_LAT; }
355         | SCA                   { $$ = Q_SCA; }
356         | MOPDL                 { $$ = Q_MOPDL; }
357         | MOPRC                 { $$ = Q_MOPRC; }
358         | IPV6                  { $$ = Q_IPV6; }
359         | ICMPV6                { $$ = Q_ICMPV6; }
360         | AH                    { $$ = Q_AH; }
361         | ESP                   { $$ = Q_ESP; }
362         | ISO                   { $$ = Q_ISO; }
363         | ESIS                  { $$ = Q_ESIS; }
364         | ISIS                  { $$ = Q_ISIS; }
365         | L1                    { $$ = Q_ISIS_L1; }
366         | L2                    { $$ = Q_ISIS_L2; }
367         | IIH                   { $$ = Q_ISIS_IIH; }
368         | LSP                   { $$ = Q_ISIS_LSP; }
369         | SNP                   { $$ = Q_ISIS_SNP; }
370         | PSNP                  { $$ = Q_ISIS_PSNP; }
371         | CSNP                  { $$ = Q_ISIS_CSNP; }
372         | CLNP                  { $$ = Q_CLNP; }
373         | STP                   { $$ = Q_STP; }
374         | IPX                   { $$ = Q_IPX; }
375         | NETBEUI               { $$ = Q_NETBEUI; }
376         | RADIO                 { $$ = Q_RADIO; }
377         ;
378 other:    pqual TK_BROADCAST    { $$ = gen_broadcast($1); }
379         | pqual TK_MULTICAST    { $$ = gen_multicast($1); }
380         | LESS NUM              { $$ = gen_less($2); }
381         | GREATER NUM           { $$ = gen_greater($2); }
382         | CBYTE NUM byteop NUM  { $$ = gen_byteop($3, $2, $4); }
383         | INBOUND               { $$ = gen_inbound(0); }
384         | OUTBOUND              { $$ = gen_inbound(1); }
385         | VLAN pnum             { $$ = gen_vlan($2); }
386         | VLAN                  { $$ = gen_vlan(-1); }
387         | MPLS pnum             { $$ = gen_mpls($2); }
388         | MPLS                  { $$ = gen_mpls(-1); }
389         | PPPOED                { $$ = gen_pppoed(); }
390         | PPPOES                { $$ = gen_pppoes(); }
391         | pfvar                 { $$ = $1; }
392         ;
393
394 pfvar:    PF_IFNAME ID          { $$ = gen_pf_ifname($2); }
395         | PF_RSET ID            { $$ = gen_pf_ruleset($2); }
396         | PF_RNR NUM            { $$ = gen_pf_rnr($2); }
397         | PF_SRNR NUM           { $$ = gen_pf_srnr($2); }
398         | PF_REASON reason      { $$ = gen_pf_reason($2); }
399         | PF_ACTION action      { $$ = gen_pf_action($2); }
400         ;
401
402 reason:   NUM                   { $$ = $1; }
403         | ID                    { $$ = pfreason_to_num($1); }
404         ;
405
406 action:   ID                    { $$ = pfaction_to_num($1); }
407         ;
408
409 relop:    '>'                   { $$ = BPF_JGT; }
410         | GEQ                   { $$ = BPF_JGE; }
411         | '='                   { $$ = BPF_JEQ; }
412         ;
413 irelop:   LEQ                   { $$ = BPF_JGT; }
414         | '<'                   { $$ = BPF_JGE; }
415         | NEQ                   { $$ = BPF_JEQ; }
416         ;
417 arth:     pnum                  { $$ = gen_loadi($1); }
418         | narth
419         ;
420 narth:    pname '[' arth ']'            { $$ = gen_load($1, $3, 1); }
421         | pname '[' arth ':' NUM ']'    { $$ = gen_load($1, $3, $5); }
422         | arth '+' arth                 { $$ = gen_arth(BPF_ADD, $1, $3); }
423         | arth '-' arth                 { $$ = gen_arth(BPF_SUB, $1, $3); }
424         | arth '*' arth                 { $$ = gen_arth(BPF_MUL, $1, $3); }
425         | arth '/' arth                 { $$ = gen_arth(BPF_DIV, $1, $3); }
426         | arth '&' arth                 { $$ = gen_arth(BPF_AND, $1, $3); }
427         | arth '|' arth                 { $$ = gen_arth(BPF_OR, $1, $3); }
428         | arth LSH arth                 { $$ = gen_arth(BPF_LSH, $1, $3); }
429         | arth RSH arth                 { $$ = gen_arth(BPF_RSH, $1, $3); }
430         | '-' arth %prec UMINUS         { $$ = gen_neg($2); }
431         | paren narth ')'               { $$ = $2; }
432         | LEN                           { $$ = gen_loadlen(); }
433         ;
434 byteop:   '&'                   { $$ = '&'; }
435         | '|'                   { $$ = '|'; }
436         | '<'                   { $$ = '<'; }
437         | '>'                   { $$ = '>'; }
438         | '='                   { $$ = '='; }
439         ;
440 pnum:     NUM
441         | paren pnum ')'        { $$ = $2; }
442         ;
443 atmtype: LANE                   { $$ = A_LANE; }
444         | LLC                   { $$ = A_LLC; }
445         | METAC                 { $$ = A_METAC; }
446         | BCC                   { $$ = A_BCC; }
447         | OAMF4EC               { $$ = A_OAMF4EC; }
448         | OAMF4SC               { $$ = A_OAMF4SC; }
449         | SC                    { $$ = A_SC; }
450         | ILMIC                 { $$ = A_ILMIC; }
451         ;
452 atmmultitype: OAM               { $$ = A_OAM; }
453         | OAMF4                 { $$ = A_OAMF4; }
454         | CONNECTMSG            { $$ = A_CONNECTMSG; }
455         | METACONNECT           { $$ = A_METACONNECT; }
456         ;
457         /* ATM field types quantifier */
458 atmfield: VPI                   { $$.atmfieldtype = A_VPI; }
459         | VCI                   { $$.atmfieldtype = A_VCI; }
460         ;
461 atmvalue: atmfieldvalue
462         | relop NUM             { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
463         | irelop NUM            { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
464         | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
465         ;
466 atmfieldvalue: NUM {
467         $$.atmfieldtype = $<blk>0.atmfieldtype;
468         if ($$.atmfieldtype == A_VPI ||
469             $$.atmfieldtype == A_VCI)
470                 $$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
471         }
472         ;
473 atmlistvalue: atmfieldvalue
474         | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
475         ;
476         /* MTP2 types quantifier */
477 mtp2type: FISU                  { $$ = M_FISU; }
478         | LSSU                  { $$ = M_LSSU; }
479         | MSU                   { $$ = M_MSU; }
480         ;
481         /* MTP3 field types quantifier */
482 mtp3field: SIO                  { $$.mtp3fieldtype = M_SIO; }
483         | OPC                   { $$.mtp3fieldtype = M_OPC; }
484         | DPC                   { $$.mtp3fieldtype = M_DPC; }
485         | SLS                   { $$.mtp3fieldtype = M_SLS; }
486         ;
487 mtp3value: mtp3fieldvalue
488         | relop NUM             { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
489         | irelop NUM            { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
490         | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
491         ;
492 mtp3fieldvalue: NUM {
493         $$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
494         if ($$.mtp3fieldtype == M_SIO ||
495             $$.mtp3fieldtype == M_OPC ||
496             $$.mtp3fieldtype == M_DPC ||
497             $$.mtp3fieldtype == M_SLS )
498                 $$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
499         }
500         ;
501 mtp3listvalue: mtp3fieldvalue
502         | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
503         ;
504 %%