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 <err.h> 34 35 #include "npfctl.h" 36 #include "npf_parse.h" 37 38 int yycolumn; 39 40 #define YY_USER_ACTION yycolumn += yyleng; 41 42 extern int yystarttoken; 43 extern int yylineno; 44 extern const char * yyfilename; 45 extern int yyparse(void); 46 extern void yyrestart(FILE *); 47 48 void 49 npfctl_parse_file(const char *name) 50 { 51 FILE *fp; 52 53 fp = fopen(name, "r"); 54 if (fp == NULL) { 55 err(EXIT_FAILURE, "open '%s'", name); 56 } 57 yystarttoken = 0; 58 yyrestart(fp); 59 yylineno = 1; 60 yycolumn = 0; 61 yyfilename = name; 62 yyparse(); 63 fclose(fp); 64 } 65 66 void 67 npfctl_parse_string(const char *str, parse_entry_t entry) 68 { 69 YY_BUFFER_STATE bs; 70 71 switch (entry) { 72 case NPFCTL_PARSE_RULE: 73 yystarttoken = RULE_ENTRY_TOKEN; 74 break; 75 case NPFCTL_PARSE_MAP: 76 yystarttoken = MAP_ENTRY_TOKEN; 77 break; 78 default: 79 abort(); 80 } 81 82 bs = yy_scan_string(str); 83 yyfilename = "stdin"; 84 yyparse(); 85 yy_delete_buffer(bs); 86 } 87 88 %} 89 90 %option noyywrap nounput noinput 91 92 ID [a-zA-Z_][a-zA-Z_0-9]* 93 DID [a-zA-Z_][a-zA-Z_0-9-]* 94 NUMBER [0-9]+ 95 HEXDIG [0-9a-fA-F]+ 96 97 %% 98 %{ 99 /* This is prepended to yylex(). */ 100 if (yystarttoken) { 101 int token = yystarttoken; 102 yystarttoken = 0; 103 return token; 104 } 105 %} 106 107 alg return ALG; 108 table return TABLE; 109 type return TYPE; 110 hash return HASH; 111 tree return TREE; 112 lpm return LPM; 113 cdb return CDB; 114 const return CONST; 115 static return TSTATIC; 116 dynamic return TDYNAMIC; 117 file return TFILE; 118 map return MAP; 119 no-ports return NO_PORTS; 120 set return SET; 121 "<->" return ARROWBOTH; 122 "<-" return ARROWLEFT; 123 "->" return ARROWRIGHT; 124 algo return ALGO; 125 netmap return NETMAP; 126 ipset return IPSET; 127 "ip-hash" return IPHASH; 128 "round-robin" return ROUNDROBIN; 129 npt66 return NPT66; 130 "-" return MINUS; 131 procedure return PROCEDURE; 132 \\\n yylineno++; yycolumn = 0; 133 \n yylineno++; yycolumn = 0; return SEPLINE; 134 ; return SEPLINE; 135 name return NAME; 136 group return GROUP; 137 default return DEFAULT; 138 in return IN; 139 out return OUT; 140 forw return FORW; 141 interface return INTERFACE; 142 all return ALL; 143 block return BLOCK; 144 pass return PASS; 145 pcap-filter return PCAP_FILTER; 146 stateful return STATEFUL; 147 stateful-all return STATEFUL_ALL; 148 apply return APPLY; 149 final return FINAL; 150 quick return FINAL; 151 on return ON; 152 off return OFF; 153 inet6 return INET6; 154 inet4 return INET4; 155 ifaddrs return IFADDRS; 156 proto return PROTO; 157 family return FAMILY; 158 tcp return TCP; 159 icmp { yylval.num = IPPROTO_ICMP; return ICMP; } 160 ipv6-icmp { yylval.num = IPPROTO_ICMPV6; return ICMP6; } 161 \"ipv6-icmp\" { yylval.num = IPPROTO_ICMPV6; return ICMP6; } 162 return-rst return RETURNRST; 163 return-icmp return RETURNICMP; 164 return return RETURN; 165 ruleset return RULESET; 166 from return FROM; 167 to return TO; 168 port return PORT; 169 flags return FLAGS; 170 icmp-type return ICMPTYPE; 171 code return CODE; 172 any return ANY; 173 174 "/" return SLASH; 175 "{" return CURLY_OPEN; 176 "}" return CURLY_CLOSE; 177 "(" return PAR_OPEN; 178 ")" return PAR_CLOSE; 179 "," return COMMA; 180 "=" return EQ; 181 "!" return EXCL_MARK; 182 183 "0x"{HEXDIG} { 184 char *endp, *buf = ecalloc(1, yyleng + 1); 185 buf[yyleng] = 0; 186 yylval.num = strtoul(buf+2, &endp, 16); 187 free(buf); 188 return HEX; 189 } 190 191 {NUMBER}"."{NUMBER} { 192 char *endp, *buf = estrndup(yytext, yyleng); 193 yylval.fpnum = strtod(buf, &endp); 194 free(buf); 195 return FPNUM; 196 } 197 198 {HEXDIG}":"[0-9a-fA-F:]* { 199 yylval.str = estrndup(yytext, yyleng); 200 return IPV6ADDR; 201 } 202 203 "::"{HEXDIG}[0-9a-fA-F:.]* { 204 yylval.str = estrndup(yytext, yyleng); 205 return IPV6ADDR; 206 } 207 208 {NUMBER}"."[0-9][0-9.]* { 209 yylval.str = estrndup(yytext, yyleng); 210 return IPV4ADDR; 211 } 212 213 {NUMBER} { 214 char *endp, *buf = estrndup(yytext, yyleng); 215 yylval.num = strtoul(buf, &endp, 10); 216 free(buf); 217 return NUM; 218 } 219 220 "<"{DID}">" { 221 yylval.str = estrndup(yytext + 1, yyleng - 2); 222 return TABLE_ID; 223 } 224 225 "$"{ID} { 226 yylval.str = estrndup(yytext + 1, yyleng - 1); 227 return VAR_ID; 228 } 229 230 [a-z]*"."[a-z.]* { 231 yylval.str = estrndup(yytext, yyleng); 232 return PARAM; 233 } 234 235 {ID} { 236 yylval.str = estrndup(yytext, yyleng); 237 return IDENTIFIER; 238 } 239 240 \"[^\"]*\" { 241 yylval.str = estrndup(yytext + 1, yyleng - 2); 242 return STRING; 243 } 244 245 #.*$ /* drop comment until end of line */ 246 [ \t] /* eat whitespace */ 247 248 : return COLON; 249