1 /*- 2 * Copyright (c) 2011-2012 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 SEPLINE; 137 ; return SEPLINE; 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 177 "/" return SLASH; 178 "{" return CURLY_OPEN; 179 "}" return CURLY_CLOSE; 180 "(" return PAR_OPEN; 181 ")" return PAR_CLOSE; 182 "," return COMMA; 183 "=" return EQ; 184 "!" return EXCL_MARK; 185 186 "0x"{HEXDIG} { 187 char *endp, *buf = ecalloc(1, yyleng + 1); 188 buf[yyleng] = 0; 189 yylval.num = strtoul(buf+2, &endp, 16); 190 free(buf); 191 return HEX; 192 } 193 194 {NUMBER}"."{NUMBER} { 195 char *endp, *buf = estrndup(yytext, yyleng); 196 yylval.fpnum = strtod(buf, &endp); 197 free(buf); 198 return FPNUM; 199 } 200 201 {HEXDIG}":"[0-9a-fA-F:]* { 202 yylval.str = estrndup(yytext, yyleng); 203 return IPV6ADDR; 204 } 205 206 "::"{HEXDIG}[0-9a-fA-F:.]* { 207 yylval.str = estrndup(yytext, yyleng); 208 return IPV6ADDR; 209 } 210 211 {NUMBER}"."[0-9][0-9.]* { 212 yylval.str = estrndup(yytext, yyleng); 213 return IPV4ADDR; 214 } 215 216 {NUMBER} { 217 char *endp, *buf = estrndup(yytext, yyleng); 218 yylval.num = strtoul(buf, &endp, 10); 219 free(buf); 220 return NUM; 221 } 222 223 "<"{DID}">" { 224 yylval.str = estrndup(yytext + 1, yyleng - 2); 225 return TABLE_ID; 226 } 227 228 "$"{ID} { 229 yylval.str = estrndup(yytext + 1, yyleng - 1); 230 return VAR_ID; 231 } 232 233 {ID}"."{SPID}+ { 234 yylval.str = estrndup(yytext, yyleng); 235 return PARAM; 236 } 237 238 {ID} { 239 yylval.str = estrndup(yytext, yyleng); 240 return IDENTIFIER; 241 } 242 243 \"[^\"]*\" { 244 yylval.str = estrndup(yytext + 1, yyleng - 2); 245 return STRING; 246 } 247 248 #.*$ /* drop comment until end of line */ 249 [ \t] /* eat whitespace */ 250 251 : return COLON; 252 253 . return INVALID; 254