ippool_y.y revision 145519
1/* $FreeBSD: head/contrib/ipfilter/tools/ippool_y.y 145519 2005-04-25 18:20:15Z darrenr $ */ 2 3%{ 4#include <sys/types.h> 5#include <sys/time.h> 6#include <sys/param.h> 7#include <sys/socket.h> 8#if defined(BSD) && (BSD >= 199306) 9# include <sys/cdefs.h> 10#endif 11#include <sys/ioctl.h> 12 13#include <net/if.h> 14#if __FreeBSD_version >= 300000 15# include <net/if_var.h> 16#endif 17#include <netinet/in.h> 18 19#include <arpa/inet.h> 20 21#include <stdio.h> 22#include <fcntl.h> 23#include <stdlib.h> 24#include <string.h> 25#include <netdb.h> 26#include <ctype.h> 27#include <unistd.h> 28 29#include "ipf.h" 30#include "netinet/ip_lookup.h" 31#include "netinet/ip_pool.h" 32#include "netinet/ip_htable.h" 33#include "ippool_l.h" 34#include "kmem.h" 35 36#define YYDEBUG 1 37 38extern int yyparse __P((void)); 39extern int yydebug; 40extern FILE *yyin; 41 42static iphtable_t ipht; 43static iphtent_t iphte; 44static ip_pool_t iplo; 45static ioctlfunc_t poolioctl = NULL; 46static char poolname[FR_GROUPLEN]; 47 48%} 49 50%union { 51 char *str; 52 u_32_t num; 53 struct in_addr addr; 54 struct alist_s *alist; 55 struct in_addr adrmsk[2]; 56 iphtent_t *ipe; 57 ip_pool_node_t *ipp; 58 union i6addr ip6; 59} 60 61%token <num> YY_NUMBER YY_HEX 62%token <str> YY_STR 63%token YY_COMMENT 64%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 65%token YY_RANGE_OUT YY_RANGE_IN 66%token <ip6> YY_IPV6 67 68%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT 69%token IPT_TABLE IPT_GROUPMAP IPT_HASH 70%token IPT_ROLE IPT_TYPE IPT_TREE 71%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME 72%type <num> role table inout 73%type <ipp> ipftree range addrlist 74%type <adrmsk> addrmask 75%type <ipe> ipfgroup ipfhash hashlist hashentry 76%type <ipe> groupentry setgrouplist grouplist 77%type <addr> ipaddr mask ipv4 78%type <str> number setgroup 79 80%% 81file: line 82 | assign 83 | file line 84 | file assign 85 ; 86 87line: table role ipftree eol { iplo.ipo_unit = $2; 88 iplo.ipo_list = $3; 89 load_pool(&iplo, poolioctl); 90 resetlexer(); 91 } 92 | table role ipfhash eol { ipht.iph_unit = $2; 93 ipht.iph_type = IPHASH_LOOKUP; 94 load_hash(&ipht, $3, poolioctl); 95 resetlexer(); 96 } 97 | groupmap role number ipfgroup eol 98 { ipht.iph_unit = $2; 99 strncpy(ipht.iph_name, $3, 100 sizeof(ipht.iph_name)); 101 ipht.iph_type = IPHASH_GROUPMAP; 102 load_hash(&ipht, $4, poolioctl); 103 resetlexer(); 104 } 105 | YY_COMMENT 106 ; 107 108eol: ';' 109 ; 110 111assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 112 resetlexer(); 113 free($1); 114 free($3); 115 } 116 ; 117 118assigning: 119 '=' { yyvarnext = 1; } 120 ; 121 122table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); 123 bzero((char *)&iphte, sizeof(iphte)); 124 bzero((char *)&iplo, sizeof(iplo)); 125 *ipht.iph_name = '\0'; 126 iplo.ipo_flags = IPHASH_ANON; 127 iplo.ipo_name[0] = '\0'; 128 } 129 ; 130 131groupmap: 132 IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); 133 bzero((char *)&iphte, sizeof(iphte)); 134 *ipht.iph_name = '\0'; 135 ipht.iph_unit = IPHASH_GROUPMAP; 136 ipht.iph_flags = $2; 137 } 138 ; 139 140inout: IPT_IN { $$ = FR_INQUE; } 141 | IPT_OUT { $$ = FR_OUTQUE; } 142 ; 143role: 144 IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; } 145 | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; } 146 | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; } 147 | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; } 148 ; 149 150ipftree: 151 IPT_TYPE '=' IPT_TREE number start addrlist end 152 { strncpy(iplo.ipo_name, $4, 153 sizeof(iplo.ipo_name)); 154 $$ = $6; 155 } 156 ; 157 158ipfhash: 159 IPT_TYPE '=' IPT_HASH number hashopts start hashlist end 160 { strncpy(ipht.iph_name, $4, 161 sizeof(ipht.iph_name)); 162 $$ = $7; 163 } 164 ; 165 166ipfgroup: 167 setgroup hashopts start grouplist end 168 { iphtent_t *e; 169 for (e = $4; e != NULL; 170 e = e->ipe_next) 171 if (e->ipe_group[0] == '\0') 172 strncpy(e->ipe_group, 173 $1, 174 FR_GROUPLEN); 175 $$ = $4; 176 } 177 | hashopts start setgrouplist end { $$ = $3; } 178 ; 179 180number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3); 181 $$ = poolname; 182 } 183 | IPT_NAME '=' YY_STR { $$ = $3; } 184 | { $$ = ""; } 185 ; 186 187setgroup: 188 IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; 189 strncpy(tmp, $3, FR_GROUPLEN); 190 $$ = strdup(tmp); 191 } 192 | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; 193 sprintf(tmp, "%u", $3); 194 $$ = strdup(tmp); 195 } 196 ; 197 198hashopts: 199 | size 200 | seed 201 | size seed 202 ; 203 204addrlist: 205 next { $$ = NULL; } 206 | range next addrlist { $1->ipn_next = $3; $$ = $1; } 207 | range next { $$ = $1; } 208 ; 209 210grouplist: 211 next { $$ = NULL; } 212 | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } 213 | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); 214 bcopy((char *)&($1[0]), 215 (char *)&($$->ipe_addr), 216 sizeof($$->ipe_addr)); 217 bcopy((char *)&($1[1]), 218 (char *)&($$->ipe_mask), 219 sizeof($$->ipe_mask)); 220 $$->ipe_next = $3; 221 } 222 | groupentry next { $$ = $1; } 223 | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); 224 bcopy((char *)&($1[0]), 225 (char *)&($$->ipe_addr), 226 sizeof($$->ipe_addr)); 227 bcopy((char *)&($1[1]), 228 (char *)&($$->ipe_mask), 229 sizeof($$->ipe_mask)); 230 } 231 ; 232 233setgrouplist: 234 next { $$ = NULL; } 235 | groupentry next { $$ = $1; } 236 | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } 237 ; 238 239groupentry: 240 addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); 241 bcopy((char *)&($1[0]), 242 (char *)&($$->ipe_addr), 243 sizeof($$->ipe_addr)); 244 bcopy((char *)&($1[1]), 245 (char *)&($$->ipe_mask), 246 sizeof($$->ipe_mask)); 247 strncpy($$->ipe_group, $3, 248 FR_GROUPLEN); 249 free($3); 250 } 251 ; 252 253range: addrmask { $$ = calloc(1, sizeof(*$$)); 254 $$->ipn_info = 0; 255 $$->ipn_addr.adf_len = sizeof($$->ipn_addr); 256 $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr; 257 $$->ipn_mask.adf_len = sizeof($$->ipn_mask); 258 $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr; 259 } 260 | '!' addrmask { $$ = calloc(1, sizeof(*$$)); 261 $$->ipn_info = 1; 262 $$->ipn_addr.adf_len = sizeof($$->ipn_addr); 263 $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr; 264 $$->ipn_mask.adf_len = sizeof($$->ipn_mask); 265 $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr; 266 } 267 268hashlist: 269 next { $$ = NULL; } 270 | hashentry next { $$ = $1; } 271 | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } 272 ; 273 274hashentry: 275 addrmask { $$ = calloc(1, sizeof(iphtent_t)); 276 bcopy((char *)&($1[0]), 277 (char *)&($$->ipe_addr), 278 sizeof($$->ipe_addr)); 279 bcopy((char *)&($1[1]), 280 (char *)&($$->ipe_mask), 281 sizeof($$->ipe_mask)); 282 } 283 ; 284 285addrmask: 286 ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr; 287 yyexpectaddr = 0; 288 } 289 | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff; 290 yyexpectaddr = 0; 291 } 292 ; 293 294ipaddr: ipv4 { $$ = $1; } 295 | YY_NUMBER { $$.s_addr = htonl($1); } 296 | YY_STR { if (gethost($1, &($$.s_addr)) == -1) 297 yyerror("Unknown hostname"); 298 } 299 ; 300 301mask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); } 302 | ipv4 { $$ = $1; } 303 ; 304 305start: '{' { yyexpectaddr = 1; } 306 ; 307 308end: '}' { yyexpectaddr = 0; } 309 ; 310 311next: ';' { yyexpectaddr = 1; } 312 ; 313 314size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } 315 ; 316 317seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } 318 ; 319 320ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 321 { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 322 yyerror("Invalid octet string for IP address"); 323 return 0; 324 } 325 $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 326 $$.s_addr = htonl($$.s_addr); 327 } 328 ; 329%% 330static wordtab_t yywords[] = { 331 { "auth", IPT_AUTH }, 332 { "count", IPT_COUNT }, 333 { "group", IPT_GROUP }, 334 { "group-map", IPT_GROUPMAP }, 335 { "hash", IPT_HASH }, 336 { "in", IPT_IN }, 337 { "ipf", IPT_IPF }, 338 { "name", IPT_NAME }, 339 { "nat", IPT_NAT }, 340 { "number", IPT_NUM }, 341 { "out", IPT_OUT }, 342 { "role", IPT_ROLE }, 343 { "seed", IPT_SEED }, 344 { "size", IPT_SIZE }, 345 { "table", IPT_TABLE }, 346 { "tree", IPT_TREE }, 347 { "type", IPT_TYPE }, 348 { NULL, 0 } 349}; 350 351 352int ippool_parsefile(fd, filename, iocfunc) 353int fd; 354char *filename; 355ioctlfunc_t iocfunc; 356{ 357 FILE *fp = NULL; 358 char *s; 359 360 yylineNum = 1; 361 (void) yysettab(yywords); 362 363 s = getenv("YYDEBUG"); 364 if (s) 365 yydebug = atoi(s); 366 else 367 yydebug = 0; 368 369 if (strcmp(filename, "-")) { 370 fp = fopen(filename, "r"); 371 if (!fp) { 372 fprintf(stderr, "fopen(%s) failed: %s\n", filename, 373 STRERROR(errno)); 374 return -1; 375 } 376 } else 377 fp = stdin; 378 379 while (ippool_parsesome(fd, fp, iocfunc) == 1) 380 ; 381 if (fp != NULL) 382 fclose(fp); 383 return 0; 384} 385 386 387int ippool_parsesome(fd, fp, iocfunc) 388int fd; 389FILE *fp; 390ioctlfunc_t iocfunc; 391{ 392 char *s; 393 int i; 394 395 poolioctl = iocfunc; 396 397 if (feof(fp)) 398 return 0; 399 i = fgetc(fp); 400 if (i == EOF) 401 return 0; 402 if (ungetc(i, fp) == EOF) 403 return 0; 404 if (feof(fp)) 405 return 0; 406 s = getenv("YYDEBUG"); 407 if (s) 408 yydebug = atoi(s); 409 else 410 yydebug = 0; 411 412 yyin = fp; 413 yyparse(); 414 return 1; 415} 416