1d3c56566Srmind /*-
2*b899bfd9Srmind * Copyright (c) 2011-2020 The NetBSD Foundation, Inc.
3d3c56566Srmind * All rights reserved.
4d3c56566Srmind *
5d3c56566Srmind * This code is derived from software contributed to The NetBSD Foundation
6f797733aSrmind * by Martin Husemann, Christos Zoulas and Mindaugas Rasiukevicius.
7d3c56566Srmind *
8d3c56566Srmind * Redistribution and use in source and binary forms, with or without
9d3c56566Srmind * modification, are permitted provided that the following conditions
10d3c56566Srmind * are met:
11d3c56566Srmind * 1. Redistributions of source code must retain the above copyright
12d3c56566Srmind * notice, this list of conditions and the following disclaimer.
13d3c56566Srmind * 2. Redistributions in binary form must reproduce the above copyright
14d3c56566Srmind * notice, this list of conditions and the following disclaimer in the
15d3c56566Srmind * documentation and/or other materials provided with the distribution.
16d3c56566Srmind *
17d3c56566Srmind * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18d3c56566Srmind * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19d3c56566Srmind * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20d3c56566Srmind * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21d3c56566Srmind * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22d3c56566Srmind * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23d3c56566Srmind * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24d3c56566Srmind * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25d3c56566Srmind * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26d3c56566Srmind * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27d3c56566Srmind * POSSIBILITY OF SUCH DAMAGE.
28d3c56566Srmind */
29d3c56566Srmind
30d3c56566Srmind %{
31d3c56566Srmind
32d3c56566Srmind #include <err.h>
33d3c56566Srmind #include <netdb.h>
34a668c47eSjoerg #include <stdio.h>
35a668c47eSjoerg #include <stdlib.h>
36a668c47eSjoerg #include <string.h>
3760a0ec10Srmind #ifdef __NetBSD__
38a668c47eSjoerg #include <vis.h>
3960a0ec10Srmind #endif
40d3c56566Srmind
41d3c56566Srmind #include "npfctl.h"
42d3c56566Srmind
4363f44833Srmind #define YYSTACKSIZE 4096
4463f44833Srmind
4504cb50acSrmind int yystarttoken;
46d3c56566Srmind const char * yyfilename;
47d3c56566Srmind
48d3c56566Srmind extern int yylineno, yycolumn;
4904cb50acSrmind extern int yylex(int);
50d3c56566Srmind
51d3c56566Srmind void
yyerror(const char * fmt,...)52d3c56566Srmind yyerror(const char *fmt, ...)
53d3c56566Srmind {
54d3c56566Srmind extern int yyleng;
55d3c56566Srmind extern char *yytext;
56d3c56566Srmind
577b016567Srmind char *msg, *context = estrndup(yytext, yyleng);
58e7cdd21fSrmind bool eol = (*context == '\n');
59d3c56566Srmind va_list ap;
60d3c56566Srmind
61d3c56566Srmind va_start(ap, fmt);
62d3c56566Srmind vasprintf(&msg, fmt, ap);
63d3c56566Srmind va_end(ap);
64d3c56566Srmind
65e7cdd21fSrmind fprintf(stderr, "%s:%d:%d: %s", yyfilename,
66e7cdd21fSrmind yylineno - (int)eol, yycolumn, msg);
67e7cdd21fSrmind if (!eol) {
6860a0ec10Srmind #ifdef __NetBSD__
69e7cdd21fSrmind size_t len = strlen(context);
70b4a9940eSrmind char *dst = ecalloc(1, len * 4 + 1);
71e7cdd21fSrmind
72d3c56566Srmind strvisx(dst, context, len, VIS_WHITE|VIS_CSTYLE);
73786e7497Skre context = dst;
7460a0ec10Srmind #endif
7560a0ec10Srmind fprintf(stderr, " near '%s'", context);
76e7cdd21fSrmind }
77e7cdd21fSrmind fprintf(stderr, "\n");
78d3c56566Srmind exit(EXIT_FAILURE);
79d3c56566Srmind }
80d3c56566Srmind
81d3c56566Srmind %}
82d3c56566Srmind
833d9a792dSrmind /*
843d9a792dSrmind * No conflicts allowed. Keep it this way.
853d9a792dSrmind */
863d9a792dSrmind %expect 0
873d9a792dSrmind %expect-rr 0
883d9a792dSrmind
8904cb50acSrmind /*
9004cb50acSrmind * Depending on the mode of operation, set a different start symbol.
9104cb50acSrmind * Workaround yacc limitation by passing the start token.
9204cb50acSrmind */
9304cb50acSrmind %start input
9404cb50acSrmind %token RULE_ENTRY_TOKEN MAP_ENTRY_TOKEN
9504cb50acSrmind %lex-param { int yystarttoken }
9604cb50acSrmind
9704cb50acSrmind /*
9804cb50acSrmind * General tokens.
9904cb50acSrmind */
100bc0f55deSchristos %token ALG
101068cee29Srmind %token ALGO
102d3c56566Srmind %token ALL
103d3c56566Srmind %token ANY
104d3c56566Srmind %token APPLY
1057a3e0c21Srmind %token ARROWBOTH
1067a3e0c21Srmind %token ARROWLEFT
1077a3e0c21Srmind %token ARROWRIGHT
108d3c56566Srmind %token BLOCK
109ffcdc4afSrmind %token CDB
1103d9a792dSrmind %token CONST
111d3c56566Srmind %token CURLY_CLOSE
112d3c56566Srmind %token CURLY_OPEN
113d3c56566Srmind %token CODE
114d3c56566Srmind %token COLON
115d3c56566Srmind %token COMMA
116d3c56566Srmind %token DEFAULT
117d3c56566Srmind %token TDYNAMIC
1187a3e0c21Srmind %token TSTATIC
119d3c56566Srmind %token EQ
1208334b9bcSrmind %token EXCL_MARK
121d3c56566Srmind %token TFILE
122d3c56566Srmind %token FLAGS
123d3c56566Srmind %token FROM
124d3c56566Srmind %token GROUP
125d3c56566Srmind %token HASH
126d3c56566Srmind %token ICMPTYPE
127d3c56566Srmind %token ID
1283d9a792dSrmind %token IFADDRS
129d3c56566Srmind %token IN
130d116583eSrmind %token INET4
131d3c56566Srmind %token INET6
132d3c56566Srmind %token INTERFACE
133*b899bfd9Srmind %token INVALID
1343d9a792dSrmind %token IPHASH
1353d9a792dSrmind %token IPSET
1363d9a792dSrmind %token LPM
1377a3e0c21Srmind %token MAP
138bd05c4c4Srmind %token NO_PORTS
139d3c56566Srmind %token MINUS
140d3c56566Srmind %token NAME
1413d9a792dSrmind %token NETMAP
142068cee29Srmind %token NPT66
143d3c56566Srmind %token ON
144a08b1ebdSchristos %token OFF
145d3c56566Srmind %token OUT
146d3c56566Srmind %token PAR_CLOSE
147d3c56566Srmind %token PAR_OPEN
148d3c56566Srmind %token PASS
149f797733aSrmind %token PCAP_FILTER
150d3c56566Srmind %token PORT
151d3c56566Srmind %token PROCEDURE
152d3c56566Srmind %token PROTO
153d3c56566Srmind %token FAMILY
154ac69c0c3Srmind %token FINAL
1550e218254Srmind %token FORW
156d3c56566Srmind %token RETURN
157d3c56566Srmind %token RETURNICMP
158d3c56566Srmind %token RETURNRST
1593d9a792dSrmind %token ROUNDROBIN
160543d2971Srmind %token RULESET
161d3c56566Srmind %token SEPLINE
162a08b1ebdSchristos %token SET
163d3c56566Srmind %token SLASH
164ac69c0c3Srmind %token STATEFUL
165dadc88e3Srmind %token STATEFUL_ALL
166d3c56566Srmind %token TABLE
167d3c56566Srmind %token TCP
168d3c56566Srmind %token TO
169d3c56566Srmind %token TREE
170d3c56566Srmind %token TYPE
1717cf84a83Sspz %token <num> ICMP
1727cf84a83Sspz %token <num> ICMP6
173d3c56566Srmind
174d3c56566Srmind %token <num> HEX
175d3c56566Srmind %token <str> IDENTIFIER
176d3c56566Srmind %token <str> IPV4ADDR
177d3c56566Srmind %token <str> IPV6ADDR
178d3c56566Srmind %token <num> NUM
1798c6e21bfSrmind %token <fpnum> FPNUM
180d3c56566Srmind %token <str> STRING
181dadc88e3Srmind %token <str> PARAM
182d3c56566Srmind %token <str> TABLE_ID
183d3c56566Srmind %token <str> VAR_ID
184d3c56566Srmind
1853d9a792dSrmind %type <str> addr some_name table_store dynamic_ifaddrs
1863d9a792dSrmind %type <str> proc_param_val opt_apply ifname on_ifname ifref
1873d9a792dSrmind %type <num> port opt_final number afamily opt_family
1883d9a792dSrmind %type <num> block_or_pass rule_dir group_dir block_opts
1893d9a792dSrmind %type <num> maybe_not opt_stateful icmp_type table_type
1903d9a792dSrmind %type <num> map_sd map_algo map_flags map_type
191dadc88e3Srmind %type <num> param_val
192*b899bfd9Srmind %type <var> static_ifaddrs filt_addr_element
193*b899bfd9Srmind %type <var> filt_port filt_port_list port_range icmp_type_and_code
1943d9a792dSrmind %type <var> filt_addr addr_and_mask tcp_flags tcp_flags_and_mask
1953d9a792dSrmind %type <var> procs proc_call proc_param_list proc_param
196*b899bfd9Srmind %type <var> element list_elems list value filt_addr_list
197*b899bfd9Srmind %type <var> opt_proto proto proto_elems
1987a3e0c21Srmind %type <addrport> mapseg
1993d9a792dSrmind %type <filtopts> filt_opts all_or_filt_opts
200*b899bfd9Srmind %type <optproto> rawproto
201f797733aSrmind %type <rulegroup> group_opts
202d3c56566Srmind
203d3c56566Srmind %union {
204d3c56566Srmind char * str;
205d3c56566Srmind unsigned long num;
2068c6e21bfSrmind double fpnum;
2075111d7eaSrmind npfvar_t * var;
2087a3e0c21Srmind addr_port_t addrport;
209d3c56566Srmind filt_opts_t filtopts;
210d3c56566Srmind opt_proto_t optproto;
211d3c56566Srmind rule_group_t rulegroup;
212d3c56566Srmind }
213d3c56566Srmind
214d3c56566Srmind %%
215d3c56566Srmind
216d3c56566Srmind input
21704cb50acSrmind : lines
21804cb50acSrmind | RULE_ENTRY_TOKEN rule
21904cb50acSrmind | MAP_ENTRY_TOKEN map
220d3c56566Srmind ;
221d3c56566Srmind
222d3c56566Srmind lines
2234ec7cf26Sriastradh : lines SEPLINE line
224d3c56566Srmind | line
225d3c56566Srmind ;
226d3c56566Srmind
227d3c56566Srmind line
2283fb1890bSrmind : vardef
229d3c56566Srmind | table
2307a3e0c21Srmind | map
231d3c56566Srmind | group
232d3c56566Srmind | rproc
233bc0f55deSchristos | alg
234a08b1ebdSchristos | set
235d3c56566Srmind |
236d3c56566Srmind ;
237d3c56566Srmind
2383fb1890bSrmind alg
2393fb1890bSrmind : ALG STRING
2403fb1890bSrmind {
2413fb1890bSrmind npfctl_build_alg($2);
2423fb1890bSrmind }
2433fb1890bSrmind ;
2443fb1890bSrmind
245dadc88e3Srmind param_val
246dadc88e3Srmind : number { $$ = $1; }
247dadc88e3Srmind | ON { $$ = true; }
248dadc88e3Srmind | OFF { $$ = false; }
249a08b1ebdSchristos ;
250a08b1ebdSchristos
251a08b1ebdSchristos set
252dadc88e3Srmind : SET PARAM param_val {
253dadc88e3Srmind npfctl_setparam($2, $3);
254a08b1ebdSchristos }
255a08b1ebdSchristos ;
256a08b1ebdSchristos
2573fb1890bSrmind /*
2583fb1890bSrmind * A value - an element or a list of elements.
2593fb1890bSrmind * Can be assigned to a variable or used inline.
2603fb1890bSrmind */
2613fb1890bSrmind
2623fb1890bSrmind vardef
263d116583eSrmind : VAR_ID EQ value
264d3c56566Srmind {
265d116583eSrmind npfvar_add($3, $1);
266d3c56566Srmind }
267d3c56566Srmind ;
268d3c56566Srmind
2693fb1890bSrmind value
2703fb1890bSrmind : element
2713fb1890bSrmind | list
272d3c56566Srmind ;
273d3c56566Srmind
2743fb1890bSrmind list
275d3c56566Srmind : CURLY_OPEN list_elems CURLY_CLOSE
276d116583eSrmind {
277d116583eSrmind $$ = $2;
278d116583eSrmind }
279d3c56566Srmind ;
280d3c56566Srmind
281d3c56566Srmind list_elems
2824ec7cf26Sriastradh : list_elems COMMA element
283d116583eSrmind {
284d116583eSrmind npfvar_add_elements($1, $3);
285d116583eSrmind }
2863fb1890bSrmind | element
287d3c56566Srmind ;
288d3c56566Srmind
2893fb1890bSrmind element
290d3c56566Srmind : IDENTIFIER
291d3c56566Srmind {
292d116583eSrmind $$ = npfvar_create_from_string(NPFVAR_IDENTIFIER, $1);
293d3c56566Srmind }
294d3c56566Srmind | STRING
295d3c56566Srmind {
296d116583eSrmind $$ = npfvar_create_from_string(NPFVAR_STRING, $1);
297d3c56566Srmind }
298464306f9Schristos | number MINUS number
299394473e7Schristos {
300d116583eSrmind $$ = npfctl_parse_port_range($1, $3);
301394473e7Schristos }
302464306f9Schristos | number
303d3c56566Srmind {
304d116583eSrmind $$ = npfvar_create_element(NPFVAR_NUM, &$1, sizeof($1));
305d3c56566Srmind }
306d3c56566Srmind | VAR_ID
307d3c56566Srmind {
308d116583eSrmind $$ = npfvar_create_from_string(NPFVAR_VAR_ID, $1);
309d3c56566Srmind }
310d116583eSrmind | TABLE_ID { $$ = npfctl_parse_table_id($1); }
311f095afd7Srmind | dynamic_ifaddrs { $$ = npfctl_ifnet_table($1); }
312f095afd7Srmind | static_ifaddrs { $$ = $1; }
313d116583eSrmind | addr_and_mask { $$ = $1; }
314d3c56566Srmind ;
315d3c56566Srmind
3163fb1890bSrmind /*
3173fb1890bSrmind * Table definition.
3183fb1890bSrmind */
3193fb1890bSrmind
320d3c56566Srmind table
321d3c56566Srmind : TABLE TABLE_ID TYPE table_type table_store
322d3c56566Srmind {
323d3c56566Srmind npfctl_build_table($2, $4, $5);
324d3c56566Srmind }
325d3c56566Srmind ;
326d3c56566Srmind
327d3c56566Srmind table_type
3283d9a792dSrmind : IPSET { $$ = NPF_TABLE_IPSET; }
3293d9a792dSrmind | HASH
3303d9a792dSrmind {
3313d9a792dSrmind warnx("warning - table type \"hash\" is deprecated and may be "
3323d9a792dSrmind "deleted in\nthe future; please use the \"ipset\" type "
3333d9a792dSrmind "instead.");
3343d9a792dSrmind $$ = NPF_TABLE_IPSET;
3353d9a792dSrmind }
3363d9a792dSrmind | LPM { $$ = NPF_TABLE_LPM; }
3373d9a792dSrmind | TREE
3383d9a792dSrmind {
3393d9a792dSrmind warnx("warning - table type \"tree\" is deprecated and may be "
3403d9a792dSrmind "deleted in\nthe future; please use the \"lpm\" type "
3413d9a792dSrmind "instead.");
3423d9a792dSrmind $$ = NPF_TABLE_LPM;
3433d9a792dSrmind }
3443d9a792dSrmind | CONST { $$ = NPF_TABLE_CONST; }
3453d9a792dSrmind | CDB
3463d9a792dSrmind {
3473d9a792dSrmind warnx("warning -- table type \"cdb\" is deprecated and may be "
3483d9a792dSrmind "deleted in\nthe future; please use the \"const\" type "
3493d9a792dSrmind "instead.");
3503d9a792dSrmind $$ = NPF_TABLE_CONST;
3513d9a792dSrmind }
352d3c56566Srmind ;
353d3c56566Srmind
354d3c56566Srmind table_store
3553d9a792dSrmind : TFILE STRING { $$ = $2; }
3563d9a792dSrmind | TDYNAMIC
3573d9a792dSrmind {
3583d9a792dSrmind warnx("warning - the \"dynamic\" keyword for tables is obsolete");
3593d9a792dSrmind $$ = NULL;
3603d9a792dSrmind }
3613d9a792dSrmind | { $$ = NULL; }
362d3c56566Srmind ;
363d3c56566Srmind
3643fb1890bSrmind /*
3653fb1890bSrmind * Map definition.
3663fb1890bSrmind */
3673fb1890bSrmind
3687a3e0c21Srmind map_sd
3697a3e0c21Srmind : TSTATIC { $$ = NPFCTL_NAT_STATIC; }
3707a3e0c21Srmind | TDYNAMIC { $$ = NPFCTL_NAT_DYNAMIC; }
3717a3e0c21Srmind | { $$ = NPFCTL_NAT_DYNAMIC; }
372d3c56566Srmind ;
373d3c56566Srmind
374068cee29Srmind map_algo
3753d9a792dSrmind : ALGO NETMAP { $$ = NPF_ALGO_NETMAP; }
3763d9a792dSrmind | ALGO IPHASH { $$ = NPF_ALGO_IPHASH; }
3773d9a792dSrmind | ALGO ROUNDROBIN { $$ = NPF_ALGO_RR; }
3783d9a792dSrmind | ALGO NPT66 { $$ = NPF_ALGO_NPT66; }
379068cee29Srmind | { $$ = 0; }
380068cee29Srmind ;
381068cee29Srmind
382bd05c4c4Srmind map_flags
383bd05c4c4Srmind : NO_PORTS { $$ = NPF_NAT_PORTS; }
384bd05c4c4Srmind | { $$ = 0; }
385bd05c4c4Srmind ;
386bd05c4c4Srmind
3877a3e0c21Srmind map_type
3887a3e0c21Srmind : ARROWBOTH { $$ = NPF_NATIN | NPF_NATOUT; }
3897a3e0c21Srmind | ARROWLEFT { $$ = NPF_NATIN; }
3907a3e0c21Srmind | ARROWRIGHT { $$ = NPF_NATOUT; }
3917a3e0c21Srmind ;
3927a3e0c21Srmind
3937a3e0c21Srmind mapseg
394*b899bfd9Srmind : filt_addr filt_port
395d3c56566Srmind {
3967a3e0c21Srmind $$.ap_netaddr = $1;
3977a3e0c21Srmind $$.ap_portrange = $2;
398d3c56566Srmind }
399d3c56566Srmind ;
400d3c56566Srmind
4017a3e0c21Srmind map
402bd05c4c4Srmind : MAP ifref map_sd map_algo map_flags mapseg map_type mapseg
4033d9a792dSrmind PASS opt_family opt_proto all_or_filt_opts
404d3c56566Srmind {
405*b899bfd9Srmind npfctl_build_natseg($3, $7, $5, $2, &$6, &$8, $11, &$12, $4);
406d3c56566Srmind }
407bd05c4c4Srmind | MAP ifref map_sd map_algo map_flags mapseg map_type mapseg
40882fad0d6Srmind {
409bd05c4c4Srmind npfctl_build_natseg($3, $7, $5, $2, &$6, &$8, NULL, NULL, $4);
41082fad0d6Srmind }
411bd05c4c4Srmind | MAP ifref map_sd map_algo map_flags proto mapseg map_type mapseg
412d3c56566Srmind {
413*b899bfd9Srmind npfctl_build_natseg($3, $8, $5, $2, &$7, &$9, $6, NULL, $4);
414d3c56566Srmind }
415f797733aSrmind | MAP RULESET group_opts
416543d2971Srmind {
417a79812eaSrmind npfctl_build_maprset($3.rg_name, $3.rg_attr, $3.rg_ifname);
418543d2971Srmind }
419d3c56566Srmind ;
420d3c56566Srmind
4213fb1890bSrmind /*
4223fb1890bSrmind * Rule procedure definition and its parameters.
4233fb1890bSrmind */
4243fb1890bSrmind
425d3c56566Srmind rproc
426d3c56566Srmind : PROCEDURE STRING CURLY_OPEN procs CURLY_CLOSE
427d3c56566Srmind {
428d3c56566Srmind npfctl_build_rproc($2, $4);
429d3c56566Srmind }
430d3c56566Srmind ;
431d3c56566Srmind
432d3c56566Srmind procs
4334ec7cf26Sriastradh : procs SEPLINE proc_call
434d3c56566Srmind {
435d3c56566Srmind $$ = npfvar_add_elements($1, $3);
436d3c56566Srmind }
4378c6e21bfSrmind | proc_call { $$ = $1; }
4388c6e21bfSrmind ;
4398c6e21bfSrmind
4408c6e21bfSrmind proc_call
4418c6e21bfSrmind : IDENTIFIER COLON proc_param_list
4428c6e21bfSrmind {
4438c6e21bfSrmind proc_call_t pc;
4448c6e21bfSrmind
4457b016567Srmind pc.pc_name = estrdup($1);
4468c6e21bfSrmind pc.pc_opts = $3;
447d116583eSrmind
448d116583eSrmind $$ = npfvar_create_element(NPFVAR_PROC, &pc, sizeof(pc));
4498c6e21bfSrmind }
450d3c56566Srmind | { $$ = NULL; }
451d3c56566Srmind ;
452d3c56566Srmind
4538c6e21bfSrmind proc_param_list
4544ec7cf26Sriastradh : proc_param_list COMMA proc_param
455d3c56566Srmind {
4568c6e21bfSrmind $$ = npfvar_add_elements($1, $3);
4578c6e21bfSrmind }
4588c6e21bfSrmind | proc_param { $$ = $1; }
4598c6e21bfSrmind | { $$ = NULL; }
4608c6e21bfSrmind ;
461d3c56566Srmind
4628c6e21bfSrmind proc_param
4638c6e21bfSrmind : some_name proc_param_val
4648c6e21bfSrmind {
4658c6e21bfSrmind proc_param_t pp;
4668c6e21bfSrmind
4677b016567Srmind pp.pp_param = estrdup($1);
4687b016567Srmind pp.pp_value = $2 ? estrdup($2) : NULL;
469d116583eSrmind
470d116583eSrmind $$ = npfvar_create_element(NPFVAR_PROC_PARAM, &pp, sizeof(pp));
471d3c56566Srmind }
472d3c56566Srmind ;
473d3c56566Srmind
4748c6e21bfSrmind proc_param_val
4758c6e21bfSrmind : some_name { $$ = $1; }
476464306f9Schristos | number { (void)asprintf(&$$, "%ld", $1); }
4778c6e21bfSrmind | FPNUM { (void)asprintf(&$$, "%lf", $1); }
478d3c56566Srmind | { $$ = NULL; }
479d3c56566Srmind ;
480d3c56566Srmind
4813fb1890bSrmind /*
4823fb1890bSrmind * Group and dynamic ruleset definition.
4833fb1890bSrmind */
4843fb1890bSrmind
485d3c56566Srmind group
486f797733aSrmind : GROUP group_opts
487d3c56566Srmind {
488d116583eSrmind /* Build a group. Increase the nesting level. */
489f797733aSrmind npfctl_build_group($2.rg_name, $2.rg_attr,
490a79812eaSrmind $2.rg_ifname, $2.rg_default);
491d3c56566Srmind }
4920e218254Srmind ruleset_block
4930e218254Srmind {
4940e218254Srmind /* Decrease the nesting level. */
4950e218254Srmind npfctl_build_group_end();
4960e218254Srmind }
497d3c56566Srmind ;
498d3c56566Srmind
499543d2971Srmind ruleset
500f797733aSrmind : RULESET group_opts
501543d2971Srmind {
502543d2971Srmind /* Ruleset is a dynamic group. */
503f797733aSrmind npfctl_build_group($2.rg_name, $2.rg_attr | NPF_RULE_DYNAMIC,
504a79812eaSrmind $2.rg_ifname, $2.rg_default);
505543d2971Srmind npfctl_build_group_end();
506543d2971Srmind }
507d3c56566Srmind ;
508d3c56566Srmind
509f797733aSrmind group_dir
510f797733aSrmind : FORW { $$ = NPF_RULE_FORW; }
511f797733aSrmind | rule_dir
512f797733aSrmind ;
513f797733aSrmind
514f797733aSrmind group_opts
515d3c56566Srmind : DEFAULT
516d3c56566Srmind {
5170e218254Srmind memset(&$$, 0, sizeof(rule_group_t));
5180e218254Srmind $$.rg_default = true;
519d3c56566Srmind }
520a79812eaSrmind | STRING group_dir on_ifname
521d3c56566Srmind {
5220e218254Srmind memset(&$$, 0, sizeof(rule_group_t));
523f797733aSrmind $$.rg_name = $1;
524f797733aSrmind $$.rg_attr = $2;
525a79812eaSrmind $$.rg_ifname = $3;
526d3c56566Srmind }
527d3c56566Srmind ;
528d3c56566Srmind
5290e218254Srmind ruleset_block
530543d2971Srmind : CURLY_OPEN ruleset_def CURLY_CLOSE
531d3c56566Srmind ;
532d3c56566Srmind
533543d2971Srmind ruleset_def
5344ec7cf26Sriastradh : ruleset_def SEPLINE rule_group
5350e218254Srmind | rule_group
536d3c56566Srmind ;
537d3c56566Srmind
5380e218254Srmind rule_group
5390e218254Srmind : rule
5400e218254Srmind | group
541543d2971Srmind | ruleset
5420e218254Srmind |
543ce389782Srmind ;
5440e218254Srmind
5453fb1890bSrmind /*
5463fb1890bSrmind * Rule and misc.
5473fb1890bSrmind */
5483fb1890bSrmind
549d3c56566Srmind rule
550a79812eaSrmind : block_or_pass opt_stateful rule_dir opt_final on_ifname
5515111d7eaSrmind opt_family opt_proto all_or_filt_opts opt_apply
552d3c56566Srmind {
553ac69c0c3Srmind npfctl_build_rule($1 | $2 | $3 | $4, $5,
554*b899bfd9Srmind $6, $7, &$8, NULL, $9);
555f797733aSrmind }
556a79812eaSrmind | block_or_pass opt_stateful rule_dir opt_final on_ifname
557f797733aSrmind PCAP_FILTER STRING opt_apply
558f797733aSrmind {
559f797733aSrmind npfctl_build_rule($1 | $2 | $3 | $4, $5,
560f797733aSrmind AF_UNSPEC, NULL, NULL, $7, $8);
561d3c56566Srmind }
562d3c56566Srmind ;
563d3c56566Srmind
564d3c56566Srmind block_or_pass
565d3c56566Srmind : BLOCK block_opts { $$ = $2; }
566d3c56566Srmind | PASS { $$ = NPF_RULE_PASS; }
567d3c56566Srmind ;
568d3c56566Srmind
569d3c56566Srmind rule_dir
570d3c56566Srmind : IN { $$ = NPF_RULE_IN; }
571d3c56566Srmind | OUT { $$ = NPF_RULE_OUT; }
572d3c56566Srmind | { $$ = NPF_RULE_IN | NPF_RULE_OUT; }
573d3c56566Srmind ;
574d3c56566Srmind
575ac69c0c3Srmind opt_final
576ac69c0c3Srmind : FINAL { $$ = NPF_RULE_FINAL; }
577d3c56566Srmind | { $$ = 0; }
578d3c56566Srmind ;
579d3c56566Srmind
580a79812eaSrmind on_ifname
581d116583eSrmind : ON ifref { $$ = $2; }
582a79812eaSrmind | { $$ = NULL; }
583d3c56566Srmind ;
584d3c56566Srmind
5855111d7eaSrmind afamily
586d116583eSrmind : INET4 { $$ = AF_INET; }
5875111d7eaSrmind | INET6 { $$ = AF_INET6; }
5885111d7eaSrmind ;
5895111d7eaSrmind
5908334b9bcSrmind maybe_not
5918334b9bcSrmind : EXCL_MARK { $$ = true; }
5928334b9bcSrmind | { $$ = false; }
5938334b9bcSrmind ;
5948334b9bcSrmind
59533b678d7Srmind opt_family
5965111d7eaSrmind : FAMILY afamily { $$ = $2; }
59733b678d7Srmind | { $$ = AF_UNSPEC; }
598d3c56566Srmind ;
599d3c56566Srmind
600*b899bfd9Srmind rawproto
601*b899bfd9Srmind : TCP tcp_flags_and_mask
602d3c56566Srmind {
603d3c56566Srmind $$.op_proto = IPPROTO_TCP;
604*b899bfd9Srmind $$.op_opts = $2;
605d3c56566Srmind }
606*b899bfd9Srmind | ICMP icmp_type_and_code
607d3c56566Srmind {
608d3c56566Srmind $$.op_proto = IPPROTO_ICMP;
609*b899bfd9Srmind $$.op_opts = $2;
610d3c56566Srmind }
611*b899bfd9Srmind | ICMP6 icmp_type_and_code
6127cf84a83Sspz {
6137cf84a83Sspz $$.op_proto = IPPROTO_ICMPV6;
614*b899bfd9Srmind $$.op_opts = $2;
6157cf84a83Sspz }
616*b899bfd9Srmind | some_name
617d3c56566Srmind {
618*b899bfd9Srmind $$.op_proto = npfctl_protono($1);
61933b678d7Srmind $$.op_opts = NULL;
62033b678d7Srmind }
621*b899bfd9Srmind | number
62233b678d7Srmind {
623*b899bfd9Srmind $$.op_proto = $1;
624d3c56566Srmind $$.op_opts = NULL;
625d3c56566Srmind }
62682fad0d6Srmind ;
62782fad0d6Srmind
628*b899bfd9Srmind proto_elems
629*b899bfd9Srmind : proto_elems COMMA rawproto
630*b899bfd9Srmind {
631*b899bfd9Srmind npfvar_t *pvar = npfvar_create_element(
632*b899bfd9Srmind NPFVAR_PROTO, &$3, sizeof($3));
633*b899bfd9Srmind $$ = npfvar_add_elements($1, pvar);
634*b899bfd9Srmind }
635*b899bfd9Srmind | rawproto
636*b899bfd9Srmind {
637*b899bfd9Srmind $$ = npfvar_create_element(NPFVAR_PROTO, &$1, sizeof($1));
638*b899bfd9Srmind }
639*b899bfd9Srmind ;
640*b899bfd9Srmind
641*b899bfd9Srmind proto
642*b899bfd9Srmind : PROTO rawproto
643*b899bfd9Srmind {
644*b899bfd9Srmind $$ = npfvar_create_element(NPFVAR_PROTO, &$2, sizeof($2));
645*b899bfd9Srmind }
646*b899bfd9Srmind | PROTO CURLY_OPEN proto_elems CURLY_CLOSE
647*b899bfd9Srmind {
648*b899bfd9Srmind $$ = $3;
649*b899bfd9Srmind }
650*b899bfd9Srmind ;
651*b899bfd9Srmind
65282fad0d6Srmind opt_proto
65382fad0d6Srmind : proto { $$ = $1; }
654*b899bfd9Srmind | { $$ = NULL; }
655d3c56566Srmind ;
656d3c56566Srmind
657d3c56566Srmind all_or_filt_opts
658d3c56566Srmind : ALL
659d3c56566Srmind {
6608334b9bcSrmind $$.fo_finvert = false;
6617a3e0c21Srmind $$.fo_from.ap_netaddr = NULL;
6627a3e0c21Srmind $$.fo_from.ap_portrange = NULL;
6638334b9bcSrmind $$.fo_tinvert = false;
6647a3e0c21Srmind $$.fo_to.ap_netaddr = NULL;
6657a3e0c21Srmind $$.fo_to.ap_portrange = NULL;
666d3c56566Srmind }
667d3c56566Srmind | filt_opts { $$ = $1; }
668d3c56566Srmind ;
669d3c56566Srmind
670ac69c0c3Srmind opt_stateful
67133b678d7Srmind : STATEFUL { $$ = NPF_RULE_STATEFUL; }
672dadc88e3Srmind | STATEFUL_ALL { $$ = NPF_RULE_STATEFUL | NPF_RULE_GSTATEFUL; }
673d3c56566Srmind | { $$ = 0; }
674d3c56566Srmind ;
675d3c56566Srmind
676d3c56566Srmind opt_apply
677d3c56566Srmind : APPLY STRING { $$ = $2; }
678d3c56566Srmind | { $$ = NULL; }
679d3c56566Srmind ;
680d3c56566Srmind
681d3c56566Srmind block_opts
682d3c56566Srmind : RETURNRST { $$ = NPF_RULE_RETRST; }
683d3c56566Srmind | RETURNICMP { $$ = NPF_RULE_RETICMP; }
684d3c56566Srmind | RETURN { $$ = NPF_RULE_RETRST | NPF_RULE_RETICMP; }
685d3c56566Srmind | { $$ = 0; }
686d3c56566Srmind ;
687d3c56566Srmind
688d3c56566Srmind filt_opts
689*b899bfd9Srmind : FROM maybe_not filt_addr filt_port TO maybe_not filt_addr filt_port
690d3c56566Srmind {
6918334b9bcSrmind $$.fo_finvert = $2;
6928334b9bcSrmind $$.fo_from.ap_netaddr = $3;
6938334b9bcSrmind $$.fo_from.ap_portrange = $4;
6948334b9bcSrmind $$.fo_tinvert = $6;
6958334b9bcSrmind $$.fo_to.ap_netaddr = $7;
6968334b9bcSrmind $$.fo_to.ap_portrange = $8;
697d3c56566Srmind }
698*b899bfd9Srmind | FROM maybe_not filt_addr filt_port
699d3c56566Srmind {
7008334b9bcSrmind $$.fo_finvert = $2;
7018334b9bcSrmind $$.fo_from.ap_netaddr = $3;
7028334b9bcSrmind $$.fo_from.ap_portrange = $4;
7038334b9bcSrmind $$.fo_tinvert = false;
7047a3e0c21Srmind $$.fo_to.ap_netaddr = NULL;
7057a3e0c21Srmind $$.fo_to.ap_portrange = NULL;
706d3c56566Srmind }
707*b899bfd9Srmind | TO maybe_not filt_addr filt_port
708d3c56566Srmind {
7098334b9bcSrmind $$.fo_finvert = false;
7107a3e0c21Srmind $$.fo_from.ap_netaddr = NULL;
7117a3e0c21Srmind $$.fo_from.ap_portrange = NULL;
7128334b9bcSrmind $$.fo_tinvert = $2;
7138334b9bcSrmind $$.fo_to.ap_netaddr = $3;
7148334b9bcSrmind $$.fo_to.ap_portrange = $4;
715d3c56566Srmind }
716d3c56566Srmind ;
717d3c56566Srmind
718*b899bfd9Srmind filt_addr_list
719*b899bfd9Srmind : filt_addr_list COMMA filt_addr_element
720*b899bfd9Srmind {
721*b899bfd9Srmind npfvar_add_elements($1, $3);
722*b899bfd9Srmind }
723*b899bfd9Srmind | filt_addr_element
724*b899bfd9Srmind ;
725*b899bfd9Srmind
726d3c56566Srmind filt_addr
727*b899bfd9Srmind : CURLY_OPEN filt_addr_list CURLY_CLOSE
728*b899bfd9Srmind {
729*b899bfd9Srmind $$ = $2;
730*b899bfd9Srmind }
731*b899bfd9Srmind | filt_addr_element { $$ = $1; }
732d3c56566Srmind | ANY { $$ = NULL; }
733d3c56566Srmind ;
734d3c56566Srmind
735d3c56566Srmind addr_and_mask
736464306f9Schristos : addr SLASH number
737d3c56566Srmind {
738d3c56566Srmind $$ = npfctl_parse_fam_addr_mask($1, NULL, &$3);
739d3c56566Srmind }
740d3c56566Srmind | addr SLASH addr
741d3c56566Srmind {
742d3c56566Srmind $$ = npfctl_parse_fam_addr_mask($1, $3, NULL);
743d3c56566Srmind }
744d3c56566Srmind | addr
745d3c56566Srmind {
746d3c56566Srmind $$ = npfctl_parse_fam_addr_mask($1, NULL, NULL);
747d3c56566Srmind }
748d3c56566Srmind ;
749d3c56566Srmind
750*b899bfd9Srmind filt_addr_element
7513d9a792dSrmind : addr_and_mask { assert($1 != NULL); $$ = $1; }
752f095afd7Srmind | static_ifaddrs
7532d942d9dSrmind {
754f0775766Schristos if (npfvar_get_count($1) != 1)
755f0775766Schristos yyerror("multiple interfaces are not supported");
7565111d7eaSrmind ifnet_addr_t *ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0);
7575111d7eaSrmind $$ = ifna->ifna_addrs;
7582d942d9dSrmind }
7593d9a792dSrmind | dynamic_ifaddrs { $$ = npfctl_ifnet_table($1); }
7603d9a792dSrmind | TABLE_ID { $$ = npfctl_parse_table_id($1); }
7612d942d9dSrmind | VAR_ID
7622d942d9dSrmind {
7632d942d9dSrmind npfvar_t *vp = npfvar_lookup($1);
764e0620b41Schristos int type = npfvar_get_type(vp, 0);
7655111d7eaSrmind ifnet_addr_t *ifna;
766e0620b41Schristos again:
7672d942d9dSrmind switch (type) {
768e0620b41Schristos case NPFVAR_IDENTIFIER:
769e0620b41Schristos case NPFVAR_STRING:
770e0620b41Schristos vp = npfctl_parse_ifnet(npfvar_expand_string(vp),
771e0620b41Schristos AF_UNSPEC);
772e0620b41Schristos type = npfvar_get_type(vp, 0);
773e0620b41Schristos goto again;
7742d942d9dSrmind case NPFVAR_FAM:
775f095afd7Srmind case NPFVAR_TABLE:
7762d942d9dSrmind $$ = vp;
7772d942d9dSrmind break;
7785111d7eaSrmind case NPFVAR_INTERFACE:
779247d8613Srmind $$ = NULL;
780247d8613Srmind for (u_int i = 0; i < npfvar_get_count(vp); i++) {
781247d8613Srmind ifna = npfvar_get_data(vp, type, i);
782247d8613Srmind $$ = npfvar_add_elements($$, ifna->ifna_addrs);
783247d8613Srmind }
7845111d7eaSrmind break;
7852d942d9dSrmind case -1:
7865111d7eaSrmind yyerror("undefined variable '%s'", $1);
7872d942d9dSrmind break;
7882d942d9dSrmind default:
7895111d7eaSrmind yyerror("wrong variable '%s' type '%s' for address "
7905111d7eaSrmind "or interface", $1, npfvar_type(type));
7912d942d9dSrmind break;
7922d942d9dSrmind }
7932d942d9dSrmind }
794d3c56566Srmind ;
795d3c56566Srmind
796d3c56566Srmind addr
797d3c56566Srmind : IPV4ADDR { $$ = $1; }
798d3c56566Srmind | IPV6ADDR { $$ = $1; }
799d3c56566Srmind ;
800d3c56566Srmind
801*b899bfd9Srmind filt_port
802*b899bfd9Srmind : PORT CURLY_OPEN filt_port_list CURLY_CLOSE
803d3c56566Srmind {
804*b899bfd9Srmind $$ = npfctl_parse_port_range_variable(NULL, $3);
805d3c56566Srmind }
806*b899bfd9Srmind | PORT port_range { $$ = $2; }
80760a0ec10Srmind | { $$ = NULL; }
808d3c56566Srmind ;
809d3c56566Srmind
810*b899bfd9Srmind filt_port_list
811*b899bfd9Srmind : filt_port_list COMMA port_range
812*b899bfd9Srmind {
813*b899bfd9Srmind npfvar_add_elements($1, $3);
814*b899bfd9Srmind }
815*b899bfd9Srmind | port_range
816*b899bfd9Srmind ;
817*b899bfd9Srmind
818*b899bfd9Srmind port_range
819*b899bfd9Srmind : port /* just port */
820*b899bfd9Srmind {
821*b899bfd9Srmind $$ = npfctl_parse_port_range($1, $1);
822*b899bfd9Srmind }
823*b899bfd9Srmind | port MINUS port /* port from-to */
824*b899bfd9Srmind {
825*b899bfd9Srmind $$ = npfctl_parse_port_range($1, $3);
826*b899bfd9Srmind }
827*b899bfd9Srmind | VAR_ID
828*b899bfd9Srmind {
829*b899bfd9Srmind npfvar_t *vp = npfvar_lookup($1);
830*b899bfd9Srmind $$ = npfctl_parse_port_range_variable($1, vp);
831*b899bfd9Srmind }
832*b899bfd9Srmind ;
833*b899bfd9Srmind
834d3c56566Srmind port
835464306f9Schristos : number { $$ = $1; }
836d3c56566Srmind | IDENTIFIER { $$ = npfctl_portno($1); }
83758bc4d4eSchristos | STRING { $$ = npfctl_portno($1); }
838d3c56566Srmind ;
839d3c56566Srmind
840d3c56566Srmind icmp_type_and_code
841d3c56566Srmind : ICMPTYPE icmp_type
842d3c56566Srmind {
8437cf84a83Sspz $$ = npfctl_parse_icmp($<num>0, $2, -1);
844d3c56566Srmind }
845464306f9Schristos | ICMPTYPE icmp_type CODE number
846d3c56566Srmind {
8477cf84a83Sspz $$ = npfctl_parse_icmp($<num>0, $2, $4);
848d3c56566Srmind }
849d3c56566Srmind | ICMPTYPE icmp_type CODE IDENTIFIER
850d3c56566Srmind {
8515111d7eaSrmind $$ = npfctl_parse_icmp($<num>0, $2,
8525111d7eaSrmind npfctl_icmpcode($<num>0, $2, $4));
853d3c56566Srmind }
854d3c56566Srmind | ICMPTYPE icmp_type CODE VAR_ID
855d3c56566Srmind {
856d3c56566Srmind char *s = npfvar_expand_string(npfvar_lookup($4));
8575111d7eaSrmind $$ = npfctl_parse_icmp($<num>0, $2,
8585111d7eaSrmind npfctl_icmpcode($<num>0, $2, s));
859d3c56566Srmind }
8604e592132Srmind | { $$ = NULL; }
861d3c56566Srmind ;
862d3c56566Srmind
863d3c56566Srmind tcp_flags_and_mask
864d3c56566Srmind : FLAGS tcp_flags SLASH tcp_flags
865d3c56566Srmind {
866d3c56566Srmind npfvar_add_elements($2, $4);
867d3c56566Srmind $$ = $2;
868d3c56566Srmind }
869d3c56566Srmind | FLAGS tcp_flags
870d3c56566Srmind {
871f0775766Schristos if (npfvar_get_count($2) != 1)
872f0775766Schristos yyerror("multiple tcpflags are not supported");
873d3c56566Srmind char *s = npfvar_get_data($2, NPFVAR_TCPFLAG, 0);
874d3c56566Srmind npfvar_add_elements($2, npfctl_parse_tcpflag(s));
875d3c56566Srmind $$ = $2;
876d3c56566Srmind }
877d3c56566Srmind | { $$ = NULL; }
878d3c56566Srmind ;
879d3c56566Srmind
880d3c56566Srmind tcp_flags
881d3c56566Srmind : IDENTIFIER { $$ = npfctl_parse_tcpflag($1); }
882d3c56566Srmind ;
883d3c56566Srmind
884d3c56566Srmind icmp_type
885464306f9Schristos : number { $$ = $1; }
8867cf84a83Sspz | IDENTIFIER { $$ = npfctl_icmptype($<num>-1, $1); }
887d3c56566Srmind | VAR_ID
888d3c56566Srmind {
889d3c56566Srmind char *s = npfvar_expand_string(npfvar_lookup($1));
8907cf84a83Sspz $$ = npfctl_icmptype($<num>-1, s);
891d3c56566Srmind }
892d3c56566Srmind ;
893d3c56566Srmind
894a79812eaSrmind ifname
89533b678d7Srmind : some_name
896d3c56566Srmind {
897a79812eaSrmind npfctl_note_interface($1);
898a79812eaSrmind $$ = $1;
899d3c56566Srmind }
900d3c56566Srmind | VAR_ID
901d3c56566Srmind {
902d3c56566Srmind npfvar_t *vp = npfvar_lookup($1);
903394473e7Schristos const int type = npfvar_get_type(vp, 0);
9045111d7eaSrmind ifnet_addr_t *ifna;
9053d9a792dSrmind const char *name;
9063d9a792dSrmind unsigned *tid;
9073d9a792dSrmind bool ifaddr;
908d3c56566Srmind
909d3c56566Srmind switch (type) {
910d3c56566Srmind case NPFVAR_STRING:
9115111d7eaSrmind case NPFVAR_IDENTIFIER:
912a79812eaSrmind $$ = npfvar_expand_string(vp);
913d3c56566Srmind break;
9145111d7eaSrmind case NPFVAR_INTERFACE:
915f0775766Schristos if (npfvar_get_count(vp) != 1)
916f0775766Schristos yyerror(
917f0775766Schristos "multiple interfaces are not supported");
9185111d7eaSrmind ifna = npfvar_get_data(vp, type, 0);
919a79812eaSrmind $$ = ifna->ifna_name;
9205111d7eaSrmind break;
9213d9a792dSrmind case NPFVAR_TABLE:
9223d9a792dSrmind tid = npfvar_get_data(vp, type, 0);
9233d9a792dSrmind name = npfctl_table_getname(npfctl_config_ref(),
9243d9a792dSrmind *tid, &ifaddr);
9253d9a792dSrmind if (!ifaddr) {
9263d9a792dSrmind yyerror("variable '%s' references a table "
9273d9a792dSrmind "%s instead of an interface", $1, name);
9283d9a792dSrmind }
9293d9a792dSrmind $$ = estrdup(name);
9303d9a792dSrmind break;
931d3c56566Srmind case -1:
932d3c56566Srmind yyerror("undefined variable '%s' for interface", $1);
933d3c56566Srmind break;
934d3c56566Srmind default:
935d3c56566Srmind yyerror("wrong variable '%s' type '%s' for interface",
936d3c56566Srmind $1, npfvar_type(type));
937d3c56566Srmind break;
938d3c56566Srmind }
939a79812eaSrmind npfctl_note_interface($$);
940d3c56566Srmind }
941d3c56566Srmind ;
942d3c56566Srmind
943f095afd7Srmind static_ifaddrs
944d116583eSrmind : afamily PAR_OPEN ifname PAR_CLOSE
945d116583eSrmind {
946d116583eSrmind $$ = npfctl_parse_ifnet($3, $1);
947d116583eSrmind }
948d116583eSrmind ;
949d116583eSrmind
950f095afd7Srmind dynamic_ifaddrs
951f095afd7Srmind : IFADDRS PAR_OPEN ifname PAR_CLOSE
952f095afd7Srmind {
953f095afd7Srmind $$ = $3;
954f095afd7Srmind }
955f095afd7Srmind ;
956f095afd7Srmind
957d116583eSrmind ifref
958d116583eSrmind : ifname
959f095afd7Srmind | dynamic_ifaddrs
960f095afd7Srmind | static_ifaddrs
961d116583eSrmind {
962dadc88e3Srmind ifnet_addr_t *ifna;
963dadc88e3Srmind
964dadc88e3Srmind if (npfvar_get_count($1) != 1) {
965f0775766Schristos yyerror("multiple interfaces are not supported");
966dadc88e3Srmind }
967dadc88e3Srmind ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0);
968d116583eSrmind npfctl_note_interface(ifna->ifna_name);
969d116583eSrmind $$ = ifna->ifna_name;
970d116583eSrmind }
971d116583eSrmind ;
972d116583eSrmind
973464306f9Schristos number
974464306f9Schristos : HEX { $$ = $1; }
975464306f9Schristos | NUM { $$ = $1; }
976464306f9Schristos ;
977464306f9Schristos
97833b678d7Srmind some_name
979d3c56566Srmind : IDENTIFIER { $$ = $1; }
980d3c56566Srmind | STRING { $$ = $1; }
981d3c56566Srmind ;
982d3c56566Srmind
983d3c56566Srmind %%
984