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