Home | History | Annotate | Line # | Download | only in npfctl
      1 /*-
      2  * Copyright (c) 2011-2025 The NetBSD Foundation, Inc.
      3  * All rights reserved.
      4  *
      5  * This code is derived from software contributed to The NetBSD Foundation
      6  * by Martin Husemann.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     27  * POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 %{
     31 #include <stdio.h>
     32 #include <stdlib.h>
     33 #include <unistd.h>
     34 #include <err.h>
     35 
     36 #include "npfctl.h"
     37 #include "npf_parse.h"
     38 
     39 int	yycolumn;
     40 
     41 #define	YY_USER_ACTION	yycolumn += yyleng;
     42 
     43 extern int		yystarttoken;
     44 extern int		yylineno;
     45 extern const char *	yyfilename;
     46 extern int		yyparse(void);
     47 extern void		yyrestart(FILE *);
     48 
     49 void
     50 npfctl_parse_file(const char *name)
     51 {
     52 	const bool use_stdin = strcmp(name, "-") == 0;
     53 	FILE *fp;
     54 
     55 	fp = use_stdin ? fdopen(STDIN_FILENO, "r") : fopen(name, "r");
     56 	if (fp == NULL) {
     57 		err(EXIT_FAILURE, "open '%s'", name);
     58 	}
     59 	yystarttoken = 0;
     60 	yyrestart(fp);
     61 	yylineno = 1;
     62 	yycolumn = 0;
     63 	yyfilename = use_stdin ? "stdin" : name;
     64 	yyparse();
     65 	fclose(fp);
     66 }
     67 
     68 void
     69 npfctl_parse_string(const char *str, parse_entry_t entry)
     70 {
     71 	YY_BUFFER_STATE bs;
     72 
     73 	switch (entry) {
     74 	case NPFCTL_PARSE_RULE:
     75 		yystarttoken = RULE_ENTRY_TOKEN;
     76 		break;
     77 	case NPFCTL_PARSE_MAP:
     78 		yystarttoken = MAP_ENTRY_TOKEN;
     79 		break;
     80 	default:
     81 		abort();
     82 	}
     83 
     84 	bs = yy_scan_string(str);
     85 	yyfilename = "stdin";
     86 	yyparse();
     87 	yy_delete_buffer(bs);
     88 }
     89 
     90 %}
     91 
     92 %option noyywrap nounput noinput
     93 
     94 ID	[a-zA-Z_][a-zA-Z_0-9]*
     95 DID	[a-zA-Z_][a-zA-Z_0-9-]*
     96 SPID	[a-zA-Z][a-zA-Z_0-9.]*
     97 NUMBER	[0-9]+
     98 HEXDIG	[0-9a-fA-F]+
     99 
    100 %%
    101 %{
    102 	/* This is prepended to yylex(). */
    103 	if (yystarttoken) {
    104 		int token = yystarttoken;
    105 		yystarttoken = 0;
    106 		return token;
    107 	}
    108 %}
    109 
    110 alg			return ALG;
    111 table			return TABLE;
    112 type			return TYPE;
    113 hash			return HASH;
    114 tree			return TREE;
    115 lpm			return LPM;
    116 cdb			return CDB;
    117 const			return CONST;
    118 static			return TSTATIC;
    119 dynamic			return TDYNAMIC;
    120 file			return TFILE;
    121 map			return MAP;
    122 no-ports		return NO_PORTS;
    123 set			return SET;
    124 "<->"			return ARROWBOTH;
    125 "<-"			return ARROWLEFT;
    126 "->"			return ARROWRIGHT;
    127 algo			return ALGO;
    128 netmap			return NETMAP;
    129 ipset			return IPSET;
    130 "ip-hash"		return IPHASH;
    131 "round-robin"		return ROUNDROBIN;
    132 npt66			return NPT66;
    133 "-"			return MINUS;
    134 procedure		return PROCEDURE;
    135 \\\n			yylineno++; yycolumn = 0;
    136 \n			yylineno++; yycolumn = 0; return NEWLINE;
    137 ;			return SEMICOLON;
    138 name			return NAME;
    139 group			return GROUP;
    140 default			return DEFAULT;
    141 in			return IN;
    142 out			return OUT;
    143 forw			return FORW;
    144 interface		return INTERFACE;
    145 all			return ALL;
    146 block			return BLOCK;
    147 pass			return PASS;
    148 pcap-filter		return PCAP_FILTER;
    149 stateful		return STATEFUL;
    150 stateful-all		return STATEFUL_ALL;
    151 apply			return APPLY;
    152 final			return FINAL;
    153 quick			return FINAL;
    154 on			return ON;
    155 off			return OFF;
    156 inet6			return INET6;
    157 inet4			return INET4;
    158 ifaddrs			return IFADDRS;
    159 proto			return PROTO;
    160 family			return FAMILY;
    161 tcp			return TCP;
    162 icmp			{ yylval.num = IPPROTO_ICMP; return ICMP; }
    163 ipv6-icmp		{ yylval.num = IPPROTO_ICMPV6; return ICMP6; }
    164 \"ipv6-icmp\"		{ yylval.num = IPPROTO_ICMPV6; return ICMP6; }
    165 return-rst		return RETURNRST;
    166 return-icmp		return RETURNICMP;
    167 return			return RETURN;
    168 ruleset			return RULESET;
    169 from			return FROM;
    170 to			return TO;
    171 port			return PORT;
    172 flags			return FLAGS;
    173 icmp-type		return ICMPTYPE;
    174 code			return CODE;
    175 any			return ANY;
    176 user			return USER;
    177 ether			return ETHER;
    178 layer-2			return L2;
    179 
    180 "/"			return SLASH;
    181 "{"			return CURLY_OPEN;
    182 "}"			return CURLY_CLOSE;
    183 "("			return PAR_OPEN;
    184 ")"			return PAR_CLOSE;
    185 ","			return COMMA;
    186 "="			return EQ;
    187 "!"			return EXCL_MARK;
    188 "<"			return LT;
    189 ">"			return GT;
    190 "<>"			return XRG;
    191 "><"			return IRG;
    192 
    193 "0x"{HEXDIG} {
    194 			char *endp, *buf = ecalloc(1, yyleng + 1);
    195 			buf[yyleng] = 0;
    196 			yylval.num = strtoul(buf+2, &endp, 16);
    197 			free(buf);
    198 			return HEX;
    199 		}
    200 
    201 "Ex"{HEXDIG} {
    202 			yylval.str = estrndup(yytext, yyleng);
    203 			return ETHERHEX;
    204 		}
    205 
    206 {NUMBER}"."{NUMBER} {
    207 			char *endp, *buf = estrndup(yytext, yyleng);
    208 			yylval.fpnum = strtod(buf, &endp);
    209 			free(buf);
    210 			return FPNUM;
    211 		}
    212 
    213 {HEXDIG}(":"{HEXDIG}){5} {
    214 			yylval.str = estrndup(yytext, yyleng);
    215 			return MACADDR;
    216 		}
    217 
    218 {HEXDIG}":"[0-9a-fA-F:]* {
    219 			yylval.str = estrndup(yytext, yyleng);
    220 			return IPV6ADDR;
    221 		}
    222 
    223 "::"{HEXDIG}[0-9a-fA-F:.]* {
    224 			yylval.str = estrndup(yytext, yyleng);
    225 			return IPV6ADDR;
    226 		}
    227 
    228 {NUMBER}"."[0-9][0-9.]* {
    229 			yylval.str = estrndup(yytext, yyleng);
    230 			return IPV4ADDR;
    231 		}
    232 
    233 {NUMBER}	{
    234 			char *endp, *buf = estrndup(yytext, yyleng);
    235 			yylval.num = strtoul(buf, &endp, 10);
    236 			free(buf);
    237 			return NUM;
    238 		}
    239 
    240 "<"{DID}">"	{
    241 			yylval.str = estrndup(yytext + 1, yyleng - 2);
    242 			return TABLE_ID;
    243 		}
    244 
    245 "$"{ID}		{
    246 			yylval.str = estrndup(yytext + 1, yyleng - 1);
    247 			return VAR_ID;
    248 		}
    249 
    250 {ID}"."{SPID}+	{
    251 			yylval.str = estrndup(yytext, yyleng);
    252 			return PARAM;
    253 		}
    254 
    255 {ID}		{
    256 			yylval.str = estrndup(yytext, yyleng);
    257 			return IDENTIFIER;
    258 		}
    259 
    260 \"[^\"]*\"	{
    261 			yylval.str = estrndup(yytext + 1, yyleng - 2);
    262 			return STRING;
    263 		}
    264 
    265 #.*$		/* drop comment until end of line */
    266 [ \t]		/* eat whitespace */
    267 
    268 :		return COLON;
    269 
    270 .		return INVALID;
    271