1 1.1 rmind /*- 2 1.55 joe * Copyright (c) 2011-2025 The NetBSD Foundation, Inc. 3 1.1 rmind * All rights reserved. 4 1.1 rmind * 5 1.1 rmind * This code is derived from software contributed to The NetBSD Foundation 6 1.26 rmind * by Martin Husemann, Christos Zoulas and Mindaugas Rasiukevicius. 7 1.1 rmind * 8 1.1 rmind * Redistribution and use in source and binary forms, with or without 9 1.1 rmind * modification, are permitted provided that the following conditions 10 1.1 rmind * are met: 11 1.1 rmind * 1. Redistributions of source code must retain the above copyright 12 1.1 rmind * notice, this list of conditions and the following disclaimer. 13 1.1 rmind * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 rmind * notice, this list of conditions and the following disclaimer in the 15 1.1 rmind * documentation and/or other materials provided with the distribution. 16 1.1 rmind * 17 1.1 rmind * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 1.1 rmind * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 1.1 rmind * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 1.1 rmind * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 1.1 rmind * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 1.1 rmind * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 1.1 rmind * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 1.1 rmind * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 1.1 rmind * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 1.1 rmind * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 1.1 rmind * POSSIBILITY OF SUCH DAMAGE. 28 1.1 rmind */ 29 1.1 rmind 30 1.1 rmind %{ 31 1.1 rmind 32 1.37 joerg #include <err.h> 33 1.37 joerg #include <netdb.h> 34 1.1 rmind #include <stdio.h> 35 1.37 joerg #include <stdlib.h> 36 1.37 joerg #include <string.h> 37 1.42 rmind #ifdef __NetBSD__ 38 1.1 rmind #include <vis.h> 39 1.42 rmind #endif 40 1.1 rmind 41 1.1 rmind #include "npfctl.h" 42 1.1 rmind 43 1.12 rmind #define YYSTACKSIZE 4096 44 1.12 rmind 45 1.50 rmind int yystarttoken; 46 1.1 rmind const char * yyfilename; 47 1.1 rmind 48 1.1 rmind extern int yylineno, yycolumn; 49 1.50 rmind extern int yylex(int); 50 1.1 rmind 51 1.1 rmind void 52 1.1 rmind yyerror(const char *fmt, ...) 53 1.1 rmind { 54 1.1 rmind extern int yyleng; 55 1.1 rmind extern char *yytext; 56 1.1 rmind 57 1.15 rmind char *msg, *context = estrndup(yytext, yyleng); 58 1.14 rmind bool eol = (*context == '\n'); 59 1.1 rmind va_list ap; 60 1.1 rmind 61 1.1 rmind va_start(ap, fmt); 62 1.1 rmind vasprintf(&msg, fmt, ap); 63 1.1 rmind va_end(ap); 64 1.1 rmind 65 1.14 rmind fprintf(stderr, "%s:%d:%d: %s", yyfilename, 66 1.14 rmind yylineno - (int)eol, yycolumn, msg); 67 1.14 rmind if (!eol) { 68 1.42 rmind #ifdef __NetBSD__ 69 1.14 rmind size_t len = strlen(context); 70 1.16 rmind char *dst = ecalloc(1, len * 4 + 1); 71 1.14 rmind 72 1.14 rmind strvisx(dst, context, len, VIS_WHITE|VIS_CSTYLE); 73 1.43 kre context = dst; 74 1.42 rmind #endif 75 1.42 rmind fprintf(stderr, " near '%s'", context); 76 1.14 rmind } 77 1.14 rmind fprintf(stderr, "\n"); 78 1.1 rmind exit(EXIT_FAILURE); 79 1.1 rmind } 80 1.1 rmind 81 1.1 rmind %} 82 1.1 rmind 83 1.48 rmind /* 84 1.48 rmind * No conflicts allowed. Keep it this way. 85 1.48 rmind */ 86 1.48 rmind %expect 0 87 1.48 rmind %expect-rr 0 88 1.48 rmind 89 1.50 rmind /* 90 1.50 rmind * Depending on the mode of operation, set a different start symbol. 91 1.50 rmind * Workaround yacc limitation by passing the start token. 92 1.50 rmind */ 93 1.50 rmind %start input 94 1.50 rmind %token RULE_ENTRY_TOKEN MAP_ENTRY_TOKEN 95 1.50 rmind %lex-param { int yystarttoken } 96 1.50 rmind 97 1.50 rmind /* 98 1.50 rmind * General tokens. 99 1.50 rmind */ 100 1.22 christos %token ALG 101 1.32 rmind %token ALGO 102 1.1 rmind %token ALL 103 1.1 rmind %token ANY 104 1.1 rmind %token APPLY 105 1.8 rmind %token ARROWBOTH 106 1.8 rmind %token ARROWLEFT 107 1.8 rmind %token ARROWRIGHT 108 1.1 rmind %token BLOCK 109 1.30 rmind %token CDB 110 1.48 rmind %token CONST 111 1.1 rmind %token CURLY_CLOSE 112 1.1 rmind %token CURLY_OPEN 113 1.1 rmind %token CODE 114 1.1 rmind %token COLON 115 1.1 rmind %token COMMA 116 1.1 rmind %token DEFAULT 117 1.1 rmind %token TDYNAMIC 118 1.8 rmind %token TSTATIC 119 1.1 rmind %token EQ 120 1.57 joe %token ETHER 121 1.39 rmind %token EXCL_MARK 122 1.1 rmind %token TFILE 123 1.1 rmind %token FLAGS 124 1.1 rmind %token FROM 125 1.1 rmind %token GROUP 126 1.58 joe %token GT 127 1.1 rmind %token HASH 128 1.1 rmind %token ICMPTYPE 129 1.1 rmind %token ID 130 1.48 rmind %token IFADDRS 131 1.1 rmind %token IN 132 1.29 rmind %token INET4 133 1.1 rmind %token INET6 134 1.1 rmind %token INTERFACE 135 1.51 rmind %token INVALID 136 1.48 rmind %token IPHASH 137 1.48 rmind %token IPSET 138 1.58 joe %token IRG 139 1.48 rmind %token LPM 140 1.57 joe %token L2 141 1.58 joe %token LT 142 1.8 rmind %token MAP 143 1.52 christos %token NEWLINE 144 1.46 rmind %token NO_PORTS 145 1.1 rmind %token MINUS 146 1.1 rmind %token NAME 147 1.48 rmind %token NETMAP 148 1.32 rmind %token NPT66 149 1.1 rmind %token ON 150 1.36 christos %token OFF 151 1.1 rmind %token OUT 152 1.1 rmind %token PAR_CLOSE 153 1.1 rmind %token PAR_OPEN 154 1.1 rmind %token PASS 155 1.26 rmind %token PCAP_FILTER 156 1.1 rmind %token PORT 157 1.1 rmind %token PROCEDURE 158 1.1 rmind %token PROTO 159 1.1 rmind %token FAMILY 160 1.7 rmind %token FINAL 161 1.18 rmind %token FORW 162 1.1 rmind %token RETURN 163 1.1 rmind %token RETURNICMP 164 1.1 rmind %token RETURNRST 165 1.48 rmind %token ROUNDROBIN 166 1.21 rmind %token RULESET 167 1.52 christos %token SEMICOLON 168 1.36 christos %token SET 169 1.1 rmind %token SLASH 170 1.7 rmind %token STATEFUL 171 1.49 rmind %token STATEFUL_ALL 172 1.1 rmind %token TABLE 173 1.1 rmind %token TCP 174 1.1 rmind %token TO 175 1.1 rmind %token TREE 176 1.1 rmind %token TYPE 177 1.54 joe %token USER 178 1.58 joe %token XRG 179 1.11 spz %token <num> ICMP 180 1.11 spz %token <num> ICMP6 181 1.1 rmind 182 1.1 rmind %token <num> HEX 183 1.57 joe %token <str> ETHERHEX 184 1.1 rmind %token <str> IDENTIFIER 185 1.1 rmind %token <str> IPV4ADDR 186 1.1 rmind %token <str> IPV6ADDR 187 1.57 joe %token <str> MACADDR 188 1.1 rmind %token <num> NUM 189 1.13 rmind %token <fpnum> FPNUM 190 1.1 rmind %token <str> STRING 191 1.49 rmind %token <str> PARAM 192 1.1 rmind %token <str> TABLE_ID 193 1.1 rmind %token <str> VAR_ID 194 1.1 rmind 195 1.48 rmind %type <str> addr some_name table_store dynamic_ifaddrs 196 1.48 rmind %type <str> proc_param_val opt_apply ifname on_ifname ifref 197 1.48 rmind %type <num> port opt_final number afamily opt_family 198 1.48 rmind %type <num> block_or_pass rule_dir group_dir block_opts 199 1.48 rmind %type <num> maybe_not opt_stateful icmp_type table_type 200 1.57 joe %type <num> map_sd map_algo map_flags map_type layer 201 1.54 joe %type <num> param_val op_unary op_binary 202 1.57 joe %type <etype> ether_type 203 1.54 joe %type <rid> uid gid 204 1.51 rmind %type <var> static_ifaddrs filt_addr_element 205 1.51 rmind %type <var> filt_port filt_port_list port_range icmp_type_and_code 206 1.48 rmind %type <var> filt_addr addr_and_mask tcp_flags tcp_flags_and_mask 207 1.57 joe %type <var> procs proc_call proc_param_list proc_param mac_addr 208 1.52 christos %type <var> element list_elems list_trail list value filt_addr_list 209 1.51 rmind %type <var> opt_proto proto proto_elems 210 1.8 rmind %type <addrport> mapseg 211 1.58 joe %type <uid> uids uid_item user_id 212 1.58 joe %type <gid> gids gid_item group_id 213 1.57 joe %type <filtopts> filt_opts all_or_filt_opts l2_filt_opts l2_all_of_filt_opts 214 1.51 rmind %type <optproto> rawproto 215 1.26 rmind %type <rulegroup> group_opts 216 1.1 rmind 217 1.1 rmind %union { 218 1.1 rmind char * str; 219 1.57 joe uint16_t etype; 220 1.1 rmind unsigned long num; 221 1.54 joe uint32_t rid; 222 1.13 rmind double fpnum; 223 1.17 rmind npfvar_t * var; 224 1.8 rmind addr_port_t addrport; 225 1.1 rmind filt_opts_t filtopts; 226 1.1 rmind opt_proto_t optproto; 227 1.1 rmind rule_group_t rulegroup; 228 1.54 joe struct r_id uid; 229 1.54 joe struct r_id gid; 230 1.1 rmind } 231 1.1 rmind 232 1.1 rmind %% 233 1.1 rmind 234 1.1 rmind input 235 1.50 rmind : lines 236 1.50 rmind | RULE_ENTRY_TOKEN rule 237 1.50 rmind | MAP_ENTRY_TOKEN map 238 1.1 rmind ; 239 1.1 rmind 240 1.1 rmind lines 241 1.52 christos : lines sepline line 242 1.1 rmind | line 243 1.1 rmind ; 244 1.1 rmind 245 1.1 rmind line 246 1.28 rmind : vardef 247 1.1 rmind | table 248 1.8 rmind | map 249 1.1 rmind | group 250 1.1 rmind | rproc 251 1.22 christos | alg 252 1.36 christos | set 253 1.1 rmind | 254 1.1 rmind ; 255 1.1 rmind 256 1.28 rmind alg 257 1.28 rmind : ALG STRING 258 1.28 rmind { 259 1.28 rmind npfctl_build_alg($2); 260 1.28 rmind } 261 1.28 rmind ; 262 1.28 rmind 263 1.52 christos sepline 264 1.52 christos : NEWLINE 265 1.52 christos | SEMICOLON 266 1.52 christos ; 267 1.52 christos 268 1.49 rmind param_val 269 1.49 rmind : number { $$ = $1; } 270 1.49 rmind | ON { $$ = true; } 271 1.49 rmind | OFF { $$ = false; } 272 1.36 christos ; 273 1.36 christos 274 1.36 christos set 275 1.49 rmind : SET PARAM param_val { 276 1.49 rmind npfctl_setparam($2, $3); 277 1.36 christos } 278 1.36 christos ; 279 1.36 christos 280 1.28 rmind /* 281 1.28 rmind * A value - an element or a list of elements. 282 1.28 rmind * Can be assigned to a variable or used inline. 283 1.28 rmind */ 284 1.28 rmind 285 1.28 rmind vardef 286 1.29 rmind : VAR_ID EQ value 287 1.1 rmind { 288 1.29 rmind npfvar_add($3, $1); 289 1.1 rmind } 290 1.1 rmind ; 291 1.1 rmind 292 1.28 rmind value 293 1.28 rmind : element 294 1.28 rmind | list 295 1.1 rmind ; 296 1.1 rmind 297 1.28 rmind list 298 1.52 christos : CURLY_OPEN opt_nl list_elems CURLY_CLOSE 299 1.29 rmind { 300 1.52 christos $$ = $3; 301 1.29 rmind } 302 1.1 rmind ; 303 1.1 rmind 304 1.1 rmind list_elems 305 1.52 christos : element list_trail 306 1.29 rmind { 307 1.52 christos $$ = npfvar_add_elements($1, $2); 308 1.29 rmind } 309 1.1 rmind ; 310 1.1 rmind 311 1.28 rmind element 312 1.1 rmind : IDENTIFIER 313 1.1 rmind { 314 1.29 rmind $$ = npfvar_create_from_string(NPFVAR_IDENTIFIER, $1); 315 1.1 rmind } 316 1.1 rmind | STRING 317 1.1 rmind { 318 1.29 rmind $$ = npfvar_create_from_string(NPFVAR_STRING, $1); 319 1.1 rmind } 320 1.23 christos | number MINUS number 321 1.5 christos { 322 1.29 rmind $$ = npfctl_parse_port_range($1, $3); 323 1.5 christos } 324 1.23 christos | number 325 1.1 rmind { 326 1.56 martin uint32_t val = $1; 327 1.56 martin $$ = npfvar_create_element(NPFVAR_NUM, &val, sizeof(val)); 328 1.1 rmind } 329 1.1 rmind | VAR_ID 330 1.1 rmind { 331 1.29 rmind $$ = npfvar_create_from_string(NPFVAR_VAR_ID, $1); 332 1.1 rmind } 333 1.29 rmind | TABLE_ID { $$ = npfctl_parse_table_id($1); } 334 1.40 rmind | dynamic_ifaddrs { $$ = npfctl_ifnet_table($1); } 335 1.40 rmind | static_ifaddrs { $$ = $1; } 336 1.29 rmind | addr_and_mask { $$ = $1; } 337 1.57 joe | mac_addr { $$ = $1; } 338 1.1 rmind ; 339 1.1 rmind 340 1.52 christos list_trail 341 1.52 christos : element_sep element list_trail 342 1.52 christos { 343 1.52 christos $$ = npfvar_add_elements($2, $3); 344 1.52 christos } 345 1.52 christos | opt_nl { $$ = NULL; } 346 1.52 christos | element_sep { $$ = NULL; } 347 1.52 christos ; 348 1.52 christos 349 1.52 christos element_sep 350 1.52 christos : opt_nl COMMA opt_nl 351 1.52 christos ; 352 1.52 christos 353 1.52 christos opt_nl 354 1.52 christos : opt_nl NEWLINE 355 1.52 christos | 356 1.52 christos ; 357 1.52 christos 358 1.28 rmind /* 359 1.28 rmind * Table definition. 360 1.28 rmind */ 361 1.28 rmind 362 1.1 rmind table 363 1.1 rmind : TABLE TABLE_ID TYPE table_type table_store 364 1.1 rmind { 365 1.1 rmind npfctl_build_table($2, $4, $5); 366 1.1 rmind } 367 1.1 rmind ; 368 1.1 rmind 369 1.1 rmind table_type 370 1.48 rmind : IPSET { $$ = NPF_TABLE_IPSET; } 371 1.48 rmind | HASH 372 1.48 rmind { 373 1.48 rmind warnx("warning - table type \"hash\" is deprecated and may be " 374 1.48 rmind "deleted in\nthe future; please use the \"ipset\" type " 375 1.48 rmind "instead."); 376 1.48 rmind $$ = NPF_TABLE_IPSET; 377 1.48 rmind } 378 1.48 rmind | LPM { $$ = NPF_TABLE_LPM; } 379 1.48 rmind | TREE 380 1.48 rmind { 381 1.48 rmind warnx("warning - table type \"tree\" is deprecated and may be " 382 1.48 rmind "deleted in\nthe future; please use the \"lpm\" type " 383 1.48 rmind "instead."); 384 1.48 rmind $$ = NPF_TABLE_LPM; 385 1.48 rmind } 386 1.48 rmind | CONST { $$ = NPF_TABLE_CONST; } 387 1.48 rmind | CDB 388 1.48 rmind { 389 1.48 rmind warnx("warning -- table type \"cdb\" is deprecated and may be " 390 1.48 rmind "deleted in\nthe future; please use the \"const\" type " 391 1.48 rmind "instead."); 392 1.48 rmind $$ = NPF_TABLE_CONST; 393 1.48 rmind } 394 1.1 rmind ; 395 1.1 rmind 396 1.1 rmind table_store 397 1.48 rmind : TFILE STRING { $$ = $2; } 398 1.48 rmind | TDYNAMIC 399 1.48 rmind { 400 1.48 rmind warnx("warning - the \"dynamic\" keyword for tables is obsolete"); 401 1.48 rmind $$ = NULL; 402 1.48 rmind } 403 1.48 rmind | { $$ = NULL; } 404 1.1 rmind ; 405 1.1 rmind 406 1.28 rmind /* 407 1.28 rmind * Map definition. 408 1.28 rmind */ 409 1.28 rmind 410 1.8 rmind map_sd 411 1.8 rmind : TSTATIC { $$ = NPFCTL_NAT_STATIC; } 412 1.8 rmind | TDYNAMIC { $$ = NPFCTL_NAT_DYNAMIC; } 413 1.8 rmind | { $$ = NPFCTL_NAT_DYNAMIC; } 414 1.1 rmind ; 415 1.1 rmind 416 1.32 rmind map_algo 417 1.48 rmind : ALGO NETMAP { $$ = NPF_ALGO_NETMAP; } 418 1.48 rmind | ALGO IPHASH { $$ = NPF_ALGO_IPHASH; } 419 1.48 rmind | ALGO ROUNDROBIN { $$ = NPF_ALGO_RR; } 420 1.48 rmind | ALGO NPT66 { $$ = NPF_ALGO_NPT66; } 421 1.48 rmind | { $$ = 0; } 422 1.32 rmind ; 423 1.32 rmind 424 1.46 rmind map_flags 425 1.46 rmind : NO_PORTS { $$ = NPF_NAT_PORTS; } 426 1.46 rmind | { $$ = 0; } 427 1.46 rmind ; 428 1.46 rmind 429 1.8 rmind map_type 430 1.8 rmind : ARROWBOTH { $$ = NPF_NATIN | NPF_NATOUT; } 431 1.8 rmind | ARROWLEFT { $$ = NPF_NATIN; } 432 1.8 rmind | ARROWRIGHT { $$ = NPF_NATOUT; } 433 1.8 rmind ; 434 1.8 rmind 435 1.8 rmind mapseg 436 1.51 rmind : filt_addr filt_port 437 1.1 rmind { 438 1.8 rmind $$.ap_netaddr = $1; 439 1.8 rmind $$.ap_portrange = $2; 440 1.1 rmind } 441 1.1 rmind ; 442 1.1 rmind 443 1.8 rmind map 444 1.46 rmind : MAP ifref map_sd map_algo map_flags mapseg map_type mapseg 445 1.48 rmind PASS opt_family opt_proto all_or_filt_opts 446 1.1 rmind { 447 1.51 rmind npfctl_build_natseg($3, $7, $5, $2, &$6, &$8, $11, &$12, $4); 448 1.1 rmind } 449 1.46 rmind | MAP ifref map_sd map_algo map_flags mapseg map_type mapseg 450 1.44 rmind { 451 1.46 rmind npfctl_build_natseg($3, $7, $5, $2, &$6, &$8, NULL, NULL, $4); 452 1.44 rmind } 453 1.46 rmind | MAP ifref map_sd map_algo map_flags proto mapseg map_type mapseg 454 1.1 rmind { 455 1.51 rmind npfctl_build_natseg($3, $8, $5, $2, &$7, &$9, $6, NULL, $4); 456 1.1 rmind } 457 1.26 rmind | MAP RULESET group_opts 458 1.21 rmind { 459 1.27 rmind npfctl_build_maprset($3.rg_name, $3.rg_attr, $3.rg_ifname); 460 1.21 rmind } 461 1.1 rmind ; 462 1.1 rmind 463 1.28 rmind /* 464 1.28 rmind * Rule procedure definition and its parameters. 465 1.28 rmind */ 466 1.28 rmind 467 1.1 rmind rproc 468 1.1 rmind : PROCEDURE STRING CURLY_OPEN procs CURLY_CLOSE 469 1.1 rmind { 470 1.1 rmind npfctl_build_rproc($2, $4); 471 1.1 rmind } 472 1.1 rmind ; 473 1.1 rmind 474 1.1 rmind procs 475 1.52 christos : procs sepline proc_call 476 1.13 rmind { 477 1.13 rmind $$ = npfvar_add_elements($1, $3); 478 1.13 rmind } 479 1.13 rmind | proc_call { $$ = $1; } 480 1.1 rmind ; 481 1.1 rmind 482 1.13 rmind proc_call 483 1.13 rmind : IDENTIFIER COLON proc_param_list 484 1.1 rmind { 485 1.13 rmind proc_call_t pc; 486 1.1 rmind 487 1.15 rmind pc.pc_name = estrdup($1); 488 1.13 rmind pc.pc_opts = $3; 489 1.29 rmind 490 1.29 rmind $$ = npfvar_create_element(NPFVAR_PROC, &pc, sizeof(pc)); 491 1.1 rmind } 492 1.29 rmind | { $$ = NULL; } 493 1.1 rmind ; 494 1.1 rmind 495 1.13 rmind proc_param_list 496 1.35 riastrad : proc_param_list COMMA proc_param 497 1.1 rmind { 498 1.1 rmind $$ = npfvar_add_elements($1, $3); 499 1.1 rmind } 500 1.13 rmind | proc_param { $$ = $1; } 501 1.1 rmind | { $$ = NULL; } 502 1.1 rmind ; 503 1.1 rmind 504 1.13 rmind proc_param 505 1.13 rmind : some_name proc_param_val 506 1.1 rmind { 507 1.13 rmind proc_param_t pp; 508 1.1 rmind 509 1.15 rmind pp.pp_param = estrdup($1); 510 1.15 rmind pp.pp_value = $2 ? estrdup($2) : NULL; 511 1.29 rmind 512 1.29 rmind $$ = npfvar_create_element(NPFVAR_PROC_PARAM, &pp, sizeof(pp)); 513 1.1 rmind } 514 1.1 rmind ; 515 1.1 rmind 516 1.13 rmind proc_param_val 517 1.13 rmind : some_name { $$ = $1; } 518 1.23 christos | number { (void)asprintf(&$$, "%ld", $1); } 519 1.13 rmind | FPNUM { (void)asprintf(&$$, "%lf", $1); } 520 1.13 rmind | { $$ = NULL; } 521 1.1 rmind ; 522 1.1 rmind 523 1.28 rmind /* 524 1.28 rmind * Group and dynamic ruleset definition. 525 1.28 rmind */ 526 1.28 rmind 527 1.1 rmind group 528 1.26 rmind : GROUP group_opts 529 1.1 rmind { 530 1.29 rmind /* Build a group. Increase the nesting level. */ 531 1.26 rmind npfctl_build_group($2.rg_name, $2.rg_attr, 532 1.27 rmind $2.rg_ifname, $2.rg_default); 533 1.18 rmind } 534 1.18 rmind ruleset_block 535 1.18 rmind { 536 1.18 rmind /* Decrease the nesting level. */ 537 1.18 rmind npfctl_build_group_end(); 538 1.1 rmind } 539 1.1 rmind ; 540 1.1 rmind 541 1.21 rmind ruleset 542 1.26 rmind : RULESET group_opts 543 1.21 rmind { 544 1.21 rmind /* Ruleset is a dynamic group. */ 545 1.26 rmind npfctl_build_group($2.rg_name, $2.rg_attr | NPF_RULE_DYNAMIC, 546 1.27 rmind $2.rg_ifname, $2.rg_default); 547 1.21 rmind npfctl_build_group_end(); 548 1.21 rmind } 549 1.26 rmind ; 550 1.21 rmind 551 1.26 rmind group_dir 552 1.26 rmind : FORW { $$ = NPF_RULE_FORW; } 553 1.26 rmind | rule_dir 554 1.1 rmind ; 555 1.1 rmind 556 1.26 rmind group_opts 557 1.57 joe : DEFAULT layer 558 1.1 rmind { 559 1.18 rmind memset(&$$, 0, sizeof(rule_group_t)); 560 1.18 rmind $$.rg_default = true; 561 1.57 joe $$.rg_attr |= $2; 562 1.1 rmind } 563 1.57 joe | STRING group_dir on_ifname layer 564 1.1 rmind { 565 1.18 rmind memset(&$$, 0, sizeof(rule_group_t)); 566 1.26 rmind $$.rg_name = $1; 567 1.57 joe $$.rg_attr = $2 | $4; 568 1.27 rmind $$.rg_ifname = $3; 569 1.1 rmind } 570 1.1 rmind ; 571 1.1 rmind 572 1.57 joe layer 573 1.57 joe : L2 { $$ = NPF_RULE_LAYER_2; } 574 1.59 andvar | { $$ = NPF_RULE_LAYER_3; } /* ret layer3 by default */ 575 1.57 joe ; 576 1.57 joe 577 1.18 rmind ruleset_block 578 1.21 rmind : CURLY_OPEN ruleset_def CURLY_CLOSE 579 1.18 rmind ; 580 1.18 rmind 581 1.21 rmind ruleset_def 582 1.52 christos : ruleset_def sepline rule_group 583 1.18 rmind | rule_group 584 1.1 rmind ; 585 1.1 rmind 586 1.18 rmind rule_group 587 1.18 rmind : rule 588 1.18 rmind | group 589 1.21 rmind | ruleset 590 1.18 rmind | 591 1.24 rmind ; 592 1.1 rmind 593 1.28 rmind /* 594 1.28 rmind * Rule and misc. 595 1.28 rmind */ 596 1.28 rmind 597 1.1 rmind rule 598 1.27 rmind : block_or_pass opt_stateful rule_dir opt_final on_ifname 599 1.17 rmind opt_family opt_proto all_or_filt_opts opt_apply 600 1.1 rmind { 601 1.7 rmind npfctl_build_rule($1 | $2 | $3 | $4, $5, 602 1.51 rmind $6, $7, &$8, NULL, $9); 603 1.26 rmind } 604 1.27 rmind | block_or_pass opt_stateful rule_dir opt_final on_ifname 605 1.26 rmind PCAP_FILTER STRING opt_apply 606 1.26 rmind { 607 1.26 rmind npfctl_build_rule($1 | $2 | $3 | $4, $5, 608 1.26 rmind AF_UNSPEC, NULL, NULL, $7, $8); 609 1.1 rmind } 610 1.57 joe | block_or_pass ETHER rule_dir opt_final on_ifname 611 1.57 joe l2_all_of_filt_opts 612 1.57 joe { 613 1.57 joe npfctl_build_rule($1 | $3 | $4, $5, 0, NULL, &$6, NULL, NULL); 614 1.57 joe } 615 1.1 rmind ; 616 1.1 rmind 617 1.1 rmind block_or_pass 618 1.1 rmind : BLOCK block_opts { $$ = $2; } 619 1.1 rmind | PASS { $$ = NPF_RULE_PASS; } 620 1.1 rmind ; 621 1.1 rmind 622 1.1 rmind rule_dir 623 1.1 rmind : IN { $$ = NPF_RULE_IN; } 624 1.1 rmind | OUT { $$ = NPF_RULE_OUT; } 625 1.1 rmind | { $$ = NPF_RULE_IN | NPF_RULE_OUT; } 626 1.1 rmind ; 627 1.1 rmind 628 1.7 rmind opt_final 629 1.7 rmind : FINAL { $$ = NPF_RULE_FINAL; } 630 1.1 rmind | { $$ = 0; } 631 1.1 rmind ; 632 1.1 rmind 633 1.27 rmind on_ifname 634 1.29 rmind : ON ifref { $$ = $2; } 635 1.27 rmind | { $$ = NULL; } 636 1.1 rmind ; 637 1.1 rmind 638 1.17 rmind afamily 639 1.29 rmind : INET4 { $$ = AF_INET; } 640 1.17 rmind | INET6 { $$ = AF_INET6; } 641 1.17 rmind ; 642 1.17 rmind 643 1.39 rmind maybe_not 644 1.39 rmind : EXCL_MARK { $$ = true; } 645 1.39 rmind | { $$ = false; } 646 1.39 rmind ; 647 1.39 rmind 648 1.9 rmind opt_family 649 1.17 rmind : FAMILY afamily { $$ = $2; } 650 1.9 rmind | { $$ = AF_UNSPEC; } 651 1.1 rmind ; 652 1.1 rmind 653 1.51 rmind rawproto 654 1.51 rmind : TCP tcp_flags_and_mask 655 1.1 rmind { 656 1.1 rmind $$.op_proto = IPPROTO_TCP; 657 1.51 rmind $$.op_opts = $2; 658 1.1 rmind } 659 1.51 rmind | ICMP icmp_type_and_code 660 1.1 rmind { 661 1.1 rmind $$.op_proto = IPPROTO_ICMP; 662 1.51 rmind $$.op_opts = $2; 663 1.1 rmind } 664 1.51 rmind | ICMP6 icmp_type_and_code 665 1.11 spz { 666 1.11 spz $$.op_proto = IPPROTO_ICMPV6; 667 1.51 rmind $$.op_opts = $2; 668 1.11 spz } 669 1.51 rmind | some_name 670 1.9 rmind { 671 1.51 rmind $$.op_proto = npfctl_protono($1); 672 1.9 rmind $$.op_opts = NULL; 673 1.9 rmind } 674 1.51 rmind | number 675 1.1 rmind { 676 1.51 rmind $$.op_proto = $1; 677 1.1 rmind $$.op_opts = NULL; 678 1.1 rmind } 679 1.44 rmind ; 680 1.44 rmind 681 1.51 rmind proto_elems 682 1.51 rmind : proto_elems COMMA rawproto 683 1.51 rmind { 684 1.51 rmind npfvar_t *pvar = npfvar_create_element( 685 1.51 rmind NPFVAR_PROTO, &$3, sizeof($3)); 686 1.51 rmind $$ = npfvar_add_elements($1, pvar); 687 1.51 rmind } 688 1.51 rmind | rawproto 689 1.51 rmind { 690 1.51 rmind $$ = npfvar_create_element(NPFVAR_PROTO, &$1, sizeof($1)); 691 1.51 rmind } 692 1.51 rmind ; 693 1.51 rmind 694 1.51 rmind proto 695 1.51 rmind : PROTO rawproto 696 1.51 rmind { 697 1.51 rmind $$ = npfvar_create_element(NPFVAR_PROTO, &$2, sizeof($2)); 698 1.51 rmind } 699 1.51 rmind | PROTO CURLY_OPEN proto_elems CURLY_CLOSE 700 1.51 rmind { 701 1.51 rmind $$ = $3; 702 1.51 rmind } 703 1.51 rmind ; 704 1.51 rmind 705 1.44 rmind opt_proto 706 1.44 rmind : proto { $$ = $1; } 707 1.51 rmind | { $$ = NULL; } 708 1.1 rmind ; 709 1.1 rmind 710 1.1 rmind all_or_filt_opts 711 1.54 joe : ALL user_id group_id 712 1.1 rmind { 713 1.57 joe $$ = npfctl_parse_l3filt_opt(NULL, NULL, false, NULL, NULL, false, $2, $3); 714 1.1 rmind } 715 1.1 rmind | filt_opts { $$ = $1; } 716 1.1 rmind ; 717 1.1 rmind 718 1.57 joe l2_all_of_filt_opts 719 1.57 joe : ALL 720 1.57 joe { 721 1.57 joe $$ = npfctl_parse_l2filt_opt(NULL, false, NULL, false, 0); 722 1.57 joe } 723 1.57 joe | l2_filt_opts { $$ = $1; } 724 1.57 joe ; 725 1.57 joe 726 1.7 rmind opt_stateful 727 1.9 rmind : STATEFUL { $$ = NPF_RULE_STATEFUL; } 728 1.49 rmind | STATEFUL_ALL { $$ = NPF_RULE_STATEFUL | NPF_RULE_GSTATEFUL; } 729 1.1 rmind | { $$ = 0; } 730 1.1 rmind ; 731 1.1 rmind 732 1.1 rmind opt_apply 733 1.1 rmind : APPLY STRING { $$ = $2; } 734 1.1 rmind | { $$ = NULL; } 735 1.1 rmind ; 736 1.1 rmind 737 1.1 rmind block_opts 738 1.1 rmind : RETURNRST { $$ = NPF_RULE_RETRST; } 739 1.1 rmind | RETURNICMP { $$ = NPF_RULE_RETICMP; } 740 1.1 rmind | RETURN { $$ = NPF_RULE_RETRST | NPF_RULE_RETICMP; } 741 1.1 rmind | { $$ = 0; } 742 1.1 rmind ; 743 1.1 rmind 744 1.1 rmind filt_opts 745 1.51 rmind : FROM maybe_not filt_addr filt_port TO maybe_not filt_addr filt_port 746 1.54 joe user_id group_id 747 1.1 rmind { 748 1.57 joe $$ = npfctl_parse_l3filt_opt($3, $4, $2, $7, $8, $6, $9, $10); 749 1.39 rmind } 750 1.54 joe | FROM maybe_not filt_addr filt_port user_id group_id 751 1.39 rmind { 752 1.57 joe $$ = npfctl_parse_l3filt_opt($3, $4, $2, NULL, NULL, false, $5, $6); 753 1.1 rmind } 754 1.54 joe | TO maybe_not filt_addr filt_port user_id group_id 755 1.1 rmind { 756 1.57 joe $$ = npfctl_parse_l3filt_opt(NULL, NULL, false, $3, $4, $2, $5, $6); 757 1.1 rmind } 758 1.1 rmind ; 759 1.1 rmind 760 1.57 joe l2_filt_opts 761 1.57 joe : FROM maybe_not filt_addr TO maybe_not filt_addr ether_type 762 1.57 joe { 763 1.57 joe $$ = npfctl_parse_l2filt_opt($3, $2, $6, $5, $7); 764 1.57 joe 765 1.57 joe } 766 1.57 joe | FROM maybe_not filt_addr ether_type 767 1.57 joe { 768 1.57 joe $$ = npfctl_parse_l2filt_opt($3, $2, NULL, false, $4); 769 1.57 joe } 770 1.57 joe | TO maybe_not filt_addr ether_type 771 1.57 joe { 772 1.57 joe $$ = npfctl_parse_l2filt_opt(NULL, false, $3, $2, $4); 773 1.57 joe } 774 1.57 joe ; 775 1.57 joe 776 1.57 joe ether_type 777 1.57 joe : TYPE ETHERHEX { $$ = npfctl_parse_ether_type($2); } 778 1.57 joe | { $$ = 0; } 779 1.57 joe ; 780 1.57 joe 781 1.51 rmind filt_addr_list 782 1.51 rmind : filt_addr_list COMMA filt_addr_element 783 1.51 rmind { 784 1.51 rmind npfvar_add_elements($1, $3); 785 1.51 rmind } 786 1.51 rmind | filt_addr_element 787 1.51 rmind ; 788 1.51 rmind 789 1.1 rmind filt_addr 790 1.51 rmind : CURLY_OPEN filt_addr_list CURLY_CLOSE 791 1.51 rmind { 792 1.51 rmind $$ = $2; 793 1.51 rmind } 794 1.51 rmind | filt_addr_element { $$ = $1; } 795 1.4 rmind | ANY { $$ = NULL; } 796 1.1 rmind ; 797 1.1 rmind 798 1.1 rmind addr_and_mask 799 1.23 christos : addr SLASH number 800 1.1 rmind { 801 1.1 rmind $$ = npfctl_parse_fam_addr_mask($1, NULL, &$3); 802 1.1 rmind } 803 1.1 rmind | addr SLASH addr 804 1.1 rmind { 805 1.1 rmind $$ = npfctl_parse_fam_addr_mask($1, $3, NULL); 806 1.1 rmind } 807 1.1 rmind | addr 808 1.1 rmind { 809 1.1 rmind $$ = npfctl_parse_fam_addr_mask($1, NULL, NULL); 810 1.1 rmind } 811 1.1 rmind ; 812 1.1 rmind 813 1.57 joe mac_addr 814 1.57 joe : MACADDR 815 1.57 joe { 816 1.57 joe $$ = npfctl_parse_mac_addr($1); 817 1.57 joe } 818 1.57 joe ; 819 1.57 joe 820 1.51 rmind filt_addr_element 821 1.48 rmind : addr_and_mask { assert($1 != NULL); $$ = $1; } 822 1.57 joe | mac_addr { assert($1 != NULL); $$ = $1; } 823 1.40 rmind | static_ifaddrs 824 1.4 rmind { 825 1.41 christos if (npfvar_get_count($1) != 1) 826 1.41 christos yyerror("multiple interfaces are not supported"); 827 1.17 rmind ifnet_addr_t *ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0); 828 1.17 rmind $$ = ifna->ifna_addrs; 829 1.4 rmind } 830 1.48 rmind | dynamic_ifaddrs { $$ = npfctl_ifnet_table($1); } 831 1.48 rmind | TABLE_ID { $$ = npfctl_parse_table_id($1); } 832 1.4 rmind | VAR_ID 833 1.4 rmind { 834 1.4 rmind npfvar_t *vp = npfvar_lookup($1); 835 1.19 christos int type = npfvar_get_type(vp, 0); 836 1.17 rmind ifnet_addr_t *ifna; 837 1.19 christos again: 838 1.4 rmind switch (type) { 839 1.19 christos case NPFVAR_IDENTIFIER: 840 1.19 christos case NPFVAR_STRING: 841 1.19 christos vp = npfctl_parse_ifnet(npfvar_expand_string(vp), 842 1.19 christos AF_UNSPEC); 843 1.19 christos type = npfvar_get_type(vp, 0); 844 1.19 christos goto again; 845 1.4 rmind case NPFVAR_FAM: 846 1.57 joe case NPFVAR_MAC: 847 1.40 rmind case NPFVAR_TABLE: 848 1.4 rmind $$ = vp; 849 1.4 rmind break; 850 1.17 rmind case NPFVAR_INTERFACE: 851 1.33 rmind $$ = NULL; 852 1.33 rmind for (u_int i = 0; i < npfvar_get_count(vp); i++) { 853 1.33 rmind ifna = npfvar_get_data(vp, type, i); 854 1.33 rmind $$ = npfvar_add_elements($$, ifna->ifna_addrs); 855 1.33 rmind } 856 1.17 rmind break; 857 1.4 rmind case -1: 858 1.17 rmind yyerror("undefined variable '%s'", $1); 859 1.4 rmind break; 860 1.4 rmind default: 861 1.17 rmind yyerror("wrong variable '%s' type '%s' for address " 862 1.17 rmind "or interface", $1, npfvar_type(type)); 863 1.4 rmind break; 864 1.4 rmind } 865 1.4 rmind } 866 1.1 rmind ; 867 1.1 rmind 868 1.1 rmind addr 869 1.1 rmind : IPV4ADDR { $$ = $1; } 870 1.1 rmind | IPV6ADDR { $$ = $1; } 871 1.1 rmind ; 872 1.1 rmind 873 1.51 rmind filt_port 874 1.51 rmind : PORT CURLY_OPEN filt_port_list CURLY_CLOSE 875 1.51 rmind { 876 1.51 rmind $$ = npfctl_parse_port_range_variable(NULL, $3); 877 1.51 rmind } 878 1.51 rmind | PORT port_range { $$ = $2; } 879 1.51 rmind | { $$ = NULL; } 880 1.51 rmind ; 881 1.51 rmind 882 1.51 rmind filt_port_list 883 1.51 rmind : filt_port_list COMMA port_range 884 1.1 rmind { 885 1.51 rmind npfvar_add_elements($1, $3); 886 1.1 rmind } 887 1.51 rmind | port_range 888 1.51 rmind ; 889 1.51 rmind 890 1.51 rmind port_range 891 1.51 rmind : port /* just port */ 892 1.1 rmind { 893 1.51 rmind $$ = npfctl_parse_port_range($1, $1); 894 1.1 rmind } 895 1.51 rmind | port MINUS port /* port from-to */ 896 1.8 rmind { 897 1.51 rmind $$ = npfctl_parse_port_range($1, $3); 898 1.5 christos } 899 1.51 rmind | VAR_ID 900 1.1 rmind { 901 1.53 joe npfvar_t *vp; 902 1.53 joe if ((vp = npfvar_lookup($1)) == NULL) 903 1.53 joe yyerror("undefined port variable %s", $1); 904 1.51 rmind $$ = npfctl_parse_port_range_variable($1, vp); 905 1.1 rmind } 906 1.1 rmind ; 907 1.1 rmind 908 1.1 rmind port 909 1.23 christos : number { $$ = $1; } 910 1.1 rmind | IDENTIFIER { $$ = npfctl_portno($1); } 911 1.20 christos | STRING { $$ = npfctl_portno($1); } 912 1.1 rmind ; 913 1.1 rmind 914 1.1 rmind icmp_type_and_code 915 1.1 rmind : ICMPTYPE icmp_type 916 1.1 rmind { 917 1.11 spz $$ = npfctl_parse_icmp($<num>0, $2, -1); 918 1.1 rmind } 919 1.23 christos | ICMPTYPE icmp_type CODE number 920 1.1 rmind { 921 1.11 spz $$ = npfctl_parse_icmp($<num>0, $2, $4); 922 1.1 rmind } 923 1.1 rmind | ICMPTYPE icmp_type CODE IDENTIFIER 924 1.1 rmind { 925 1.17 rmind $$ = npfctl_parse_icmp($<num>0, $2, 926 1.17 rmind npfctl_icmpcode($<num>0, $2, $4)); 927 1.1 rmind } 928 1.1 rmind | ICMPTYPE icmp_type CODE VAR_ID 929 1.1 rmind { 930 1.1 rmind char *s = npfvar_expand_string(npfvar_lookup($4)); 931 1.17 rmind $$ = npfctl_parse_icmp($<num>0, $2, 932 1.17 rmind npfctl_icmpcode($<num>0, $2, s)); 933 1.1 rmind } 934 1.25 rmind | { $$ = NULL; } 935 1.1 rmind ; 936 1.1 rmind 937 1.1 rmind tcp_flags_and_mask 938 1.1 rmind : FLAGS tcp_flags SLASH tcp_flags 939 1.1 rmind { 940 1.1 rmind npfvar_add_elements($2, $4); 941 1.1 rmind $$ = $2; 942 1.1 rmind } 943 1.1 rmind | FLAGS tcp_flags 944 1.1 rmind { 945 1.41 christos if (npfvar_get_count($2) != 1) 946 1.41 christos yyerror("multiple tcpflags are not supported"); 947 1.1 rmind char *s = npfvar_get_data($2, NPFVAR_TCPFLAG, 0); 948 1.1 rmind npfvar_add_elements($2, npfctl_parse_tcpflag(s)); 949 1.1 rmind $$ = $2; 950 1.1 rmind } 951 1.1 rmind | { $$ = NULL; } 952 1.1 rmind ; 953 1.1 rmind 954 1.1 rmind tcp_flags 955 1.1 rmind : IDENTIFIER { $$ = npfctl_parse_tcpflag($1); } 956 1.1 rmind ; 957 1.1 rmind 958 1.1 rmind icmp_type 959 1.23 christos : number { $$ = $1; } 960 1.11 spz | IDENTIFIER { $$ = npfctl_icmptype($<num>-1, $1); } 961 1.1 rmind | VAR_ID 962 1.1 rmind { 963 1.1 rmind char *s = npfvar_expand_string(npfvar_lookup($1)); 964 1.11 spz $$ = npfctl_icmptype($<num>-1, s); 965 1.1 rmind } 966 1.1 rmind ; 967 1.1 rmind 968 1.29 rmind ifname 969 1.29 rmind : some_name 970 1.19 christos { 971 1.29 rmind npfctl_note_interface($1); 972 1.19 christos $$ = $1; 973 1.19 christos } 974 1.19 christos | VAR_ID 975 1.19 christos { 976 1.19 christos npfvar_t *vp = npfvar_lookup($1); 977 1.19 christos const int type = npfvar_get_type(vp, 0); 978 1.29 rmind ifnet_addr_t *ifna; 979 1.48 rmind const char *name; 980 1.48 rmind unsigned *tid; 981 1.48 rmind bool ifaddr; 982 1.19 christos 983 1.19 christos switch (type) { 984 1.19 christos case NPFVAR_STRING: 985 1.19 christos case NPFVAR_IDENTIFIER: 986 1.19 christos $$ = npfvar_expand_string(vp); 987 1.19 christos break; 988 1.29 rmind case NPFVAR_INTERFACE: 989 1.41 christos if (npfvar_get_count(vp) != 1) 990 1.41 christos yyerror( 991 1.41 christos "multiple interfaces are not supported"); 992 1.29 rmind ifna = npfvar_get_data(vp, type, 0); 993 1.29 rmind $$ = ifna->ifna_name; 994 1.29 rmind break; 995 1.48 rmind case NPFVAR_TABLE: 996 1.48 rmind tid = npfvar_get_data(vp, type, 0); 997 1.48 rmind name = npfctl_table_getname(npfctl_config_ref(), 998 1.48 rmind *tid, &ifaddr); 999 1.48 rmind if (!ifaddr) { 1000 1.48 rmind yyerror("variable '%s' references a table " 1001 1.48 rmind "%s instead of an interface", $1, name); 1002 1.48 rmind } 1003 1.48 rmind $$ = estrdup(name); 1004 1.48 rmind break; 1005 1.19 christos case -1: 1006 1.19 christos yyerror("undefined variable '%s' for interface", $1); 1007 1.19 christos break; 1008 1.19 christos default: 1009 1.29 rmind yyerror("wrong variable '%s' type '%s' for interface", 1010 1.19 christos $1, npfvar_type(type)); 1011 1.19 christos break; 1012 1.19 christos } 1013 1.29 rmind npfctl_note_interface($$); 1014 1.19 christos } 1015 1.19 christos ; 1016 1.19 christos 1017 1.40 rmind static_ifaddrs 1018 1.29 rmind : afamily PAR_OPEN ifname PAR_CLOSE 1019 1.17 rmind { 1020 1.17 rmind $$ = npfctl_parse_ifnet($3, $1); 1021 1.17 rmind } 1022 1.19 christos ; 1023 1.17 rmind 1024 1.40 rmind dynamic_ifaddrs 1025 1.40 rmind : IFADDRS PAR_OPEN ifname PAR_CLOSE 1026 1.40 rmind { 1027 1.40 rmind $$ = $3; 1028 1.40 rmind } 1029 1.40 rmind ; 1030 1.40 rmind 1031 1.29 rmind ifref 1032 1.29 rmind : ifname 1033 1.40 rmind | dynamic_ifaddrs 1034 1.40 rmind | static_ifaddrs 1035 1.17 rmind { 1036 1.49 rmind ifnet_addr_t *ifna; 1037 1.49 rmind 1038 1.49 rmind if (npfvar_get_count($1) != 1) { 1039 1.41 christos yyerror("multiple interfaces are not supported"); 1040 1.49 rmind } 1041 1.49 rmind ifna = npfvar_get_data($1, NPFVAR_INTERFACE, 0); 1042 1.27 rmind npfctl_note_interface(ifna->ifna_name); 1043 1.27 rmind $$ = ifna->ifna_name; 1044 1.17 rmind } 1045 1.1 rmind ; 1046 1.1 rmind 1047 1.54 joe user_id 1048 1.54 joe : /* empty */ { $$.op = NPF_OP_NONE; } 1049 1.54 joe | USER uids { $$ = $2; } 1050 1.54 joe ; 1051 1.54 joe 1052 1.54 joe uids 1053 1.54 joe : uid_item { $$ = $1; } 1054 1.54 joe ; 1055 1.54 joe 1056 1.54 joe uid_item 1057 1.54 joe : uid 1058 1.54 joe { 1059 1.54 joe npfctl_init_rid(&$$, $1, $1, NPF_OP_EQ); 1060 1.54 joe } 1061 1.54 joe | op_unary uid 1062 1.54 joe { 1063 1.54 joe npfctl_init_rid(&$$, $2, $2, $1); 1064 1.54 joe } 1065 1.54 joe | uid op_binary uid 1066 1.54 joe { 1067 1.54 joe npfctl_init_rid(&$$, $1, $3, $2); 1068 1.54 joe } 1069 1.54 joe ; 1070 1.54 joe 1071 1.54 joe uid 1072 1.54 joe : NUM 1073 1.54 joe { 1074 1.54 joe if ($1 >= UID_MAX) { 1075 1.54 joe yyerror("illegal uid value %lu", $1); 1076 1.54 joe } 1077 1.54 joe $$ = $1; 1078 1.54 joe } 1079 1.54 joe | IDENTIFIER 1080 1.54 joe { 1081 1.54 joe if (npfctl_parse_user($1, &$$) == -1) { 1082 1.54 joe yyerror("unknown user %s", $1); 1083 1.54 joe } 1084 1.54 joe } 1085 1.54 joe | VAR_ID 1086 1.54 joe { 1087 1.54 joe npf_var_rid($1, npfctl_parse_user, &$$, "user"); 1088 1.54 joe } 1089 1.54 joe ; 1090 1.54 joe 1091 1.54 joe group_id 1092 1.54 joe : /* empty */ { $$.op = NPF_OP_NONE; } 1093 1.54 joe | GROUP gids { $$ = $2; } 1094 1.54 joe ; 1095 1.54 joe 1096 1.54 joe gids 1097 1.54 joe : gid_item { $$ = $1; } 1098 1.54 joe ; 1099 1.54 joe 1100 1.54 joe gid_item 1101 1.54 joe : gid 1102 1.54 joe { 1103 1.54 joe npfctl_init_rid(&$$, $1, $1, NPF_OP_EQ); 1104 1.54 joe } 1105 1.54 joe | op_unary gid 1106 1.54 joe { 1107 1.54 joe npfctl_init_rid(&$$, $2, $2, $1); 1108 1.54 joe } 1109 1.54 joe | gid op_binary gid 1110 1.54 joe { 1111 1.54 joe npfctl_init_rid(&$$, $1, $3, $2); 1112 1.54 joe } 1113 1.54 joe ; 1114 1.54 joe 1115 1.54 joe gid 1116 1.54 joe : NUM 1117 1.54 joe { 1118 1.54 joe if ($1 >= GID_MAX) { 1119 1.54 joe yyerror("illegal gid value %lu", $1); 1120 1.54 joe } 1121 1.54 joe $$ = $1; 1122 1.54 joe } 1123 1.54 joe | IDENTIFIER 1124 1.54 joe { 1125 1.54 joe if (npfctl_parse_group($1, &$$) == -1) { 1126 1.54 joe yyerror("unknown group %s", $1); 1127 1.54 joe } 1128 1.54 joe } 1129 1.54 joe | VAR_ID 1130 1.54 joe { 1131 1.54 joe npf_var_rid($1, npfctl_parse_group, &$$, "group"); 1132 1.54 joe } 1133 1.54 joe ; 1134 1.54 joe 1135 1.54 joe op_unary 1136 1.54 joe : EQ { $$ = NPF_OP_EQ; } 1137 1.54 joe | EXCL_MARK EQ { $$ = NPF_OP_NE; } 1138 1.54 joe | LT EQ { $$ = NPF_OP_LE; } 1139 1.54 joe | LT { $$ = NPF_OP_LT; } 1140 1.54 joe | GT EQ { $$ = NPF_OP_GE; } 1141 1.54 joe | GT { $$ = NPF_OP_GT; } 1142 1.54 joe ; 1143 1.54 joe 1144 1.54 joe op_binary 1145 1.54 joe : XRG { $$ = NPF_OP_XRG; } 1146 1.54 joe | IRG { $$ = NPF_OP_IRG; } 1147 1.54 joe ; 1148 1.54 joe 1149 1.23 christos number 1150 1.23 christos : HEX { $$ = $1; } 1151 1.23 christos | NUM { $$ = $1; } 1152 1.23 christos ; 1153 1.23 christos 1154 1.9 rmind some_name 1155 1.1 rmind : IDENTIFIER { $$ = $1; } 1156 1.1 rmind | STRING { $$ = $1; } 1157 1.1 rmind ; 1158 1.1 rmind 1159 1.1 rmind %% 1160