ippool_y.y revision 145519
1145519Sdarrenr/* $FreeBSD: head/contrib/ipfilter/tools/ippool_y.y 145519 2005-04-25 18:20:15Z darrenr $ */ 2145510Sdarrenr 3145510Sdarrenr%{ 4145510Sdarrenr#include <sys/types.h> 5145510Sdarrenr#include <sys/time.h> 6145510Sdarrenr#include <sys/param.h> 7145510Sdarrenr#include <sys/socket.h> 8145510Sdarrenr#if defined(BSD) && (BSD >= 199306) 9145510Sdarrenr# include <sys/cdefs.h> 10145510Sdarrenr#endif 11145510Sdarrenr#include <sys/ioctl.h> 12145510Sdarrenr 13145510Sdarrenr#include <net/if.h> 14145510Sdarrenr#if __FreeBSD_version >= 300000 15145510Sdarrenr# include <net/if_var.h> 16145510Sdarrenr#endif 17145510Sdarrenr#include <netinet/in.h> 18145510Sdarrenr 19145510Sdarrenr#include <arpa/inet.h> 20145510Sdarrenr 21145510Sdarrenr#include <stdio.h> 22145510Sdarrenr#include <fcntl.h> 23145510Sdarrenr#include <stdlib.h> 24145510Sdarrenr#include <string.h> 25145510Sdarrenr#include <netdb.h> 26145510Sdarrenr#include <ctype.h> 27145510Sdarrenr#include <unistd.h> 28145510Sdarrenr 29145510Sdarrenr#include "ipf.h" 30145510Sdarrenr#include "netinet/ip_lookup.h" 31145510Sdarrenr#include "netinet/ip_pool.h" 32145510Sdarrenr#include "netinet/ip_htable.h" 33145510Sdarrenr#include "ippool_l.h" 34145510Sdarrenr#include "kmem.h" 35145510Sdarrenr 36145510Sdarrenr#define YYDEBUG 1 37145510Sdarrenr 38145510Sdarrenrextern int yyparse __P((void)); 39145510Sdarrenrextern int yydebug; 40145510Sdarrenrextern FILE *yyin; 41145510Sdarrenr 42145510Sdarrenrstatic iphtable_t ipht; 43145510Sdarrenrstatic iphtent_t iphte; 44145510Sdarrenrstatic ip_pool_t iplo; 45145510Sdarrenrstatic ioctlfunc_t poolioctl = NULL; 46145510Sdarrenrstatic char poolname[FR_GROUPLEN]; 47145510Sdarrenr 48145510Sdarrenr%} 49145510Sdarrenr 50145510Sdarrenr%union { 51145510Sdarrenr char *str; 52145510Sdarrenr u_32_t num; 53145510Sdarrenr struct in_addr addr; 54145510Sdarrenr struct alist_s *alist; 55145510Sdarrenr struct in_addr adrmsk[2]; 56145510Sdarrenr iphtent_t *ipe; 57145510Sdarrenr ip_pool_node_t *ipp; 58145510Sdarrenr union i6addr ip6; 59145510Sdarrenr} 60145510Sdarrenr 61145510Sdarrenr%token <num> YY_NUMBER YY_HEX 62145510Sdarrenr%token <str> YY_STR 63145510Sdarrenr%token YY_COMMENT 64145510Sdarrenr%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 65145510Sdarrenr%token YY_RANGE_OUT YY_RANGE_IN 66145510Sdarrenr%token <ip6> YY_IPV6 67145510Sdarrenr 68145510Sdarrenr%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT 69145510Sdarrenr%token IPT_TABLE IPT_GROUPMAP IPT_HASH 70145510Sdarrenr%token IPT_ROLE IPT_TYPE IPT_TREE 71145510Sdarrenr%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME 72145510Sdarrenr%type <num> role table inout 73145510Sdarrenr%type <ipp> ipftree range addrlist 74145510Sdarrenr%type <adrmsk> addrmask 75145510Sdarrenr%type <ipe> ipfgroup ipfhash hashlist hashentry 76145510Sdarrenr%type <ipe> groupentry setgrouplist grouplist 77145510Sdarrenr%type <addr> ipaddr mask ipv4 78145510Sdarrenr%type <str> number setgroup 79145510Sdarrenr 80145510Sdarrenr%% 81145510Sdarrenrfile: line 82145510Sdarrenr | assign 83145510Sdarrenr | file line 84145510Sdarrenr | file assign 85145510Sdarrenr ; 86145510Sdarrenr 87145510Sdarrenrline: table role ipftree eol { iplo.ipo_unit = $2; 88145510Sdarrenr iplo.ipo_list = $3; 89145510Sdarrenr load_pool(&iplo, poolioctl); 90145510Sdarrenr resetlexer(); 91145510Sdarrenr } 92145510Sdarrenr | table role ipfhash eol { ipht.iph_unit = $2; 93145510Sdarrenr ipht.iph_type = IPHASH_LOOKUP; 94145510Sdarrenr load_hash(&ipht, $3, poolioctl); 95145510Sdarrenr resetlexer(); 96145510Sdarrenr } 97145510Sdarrenr | groupmap role number ipfgroup eol 98145510Sdarrenr { ipht.iph_unit = $2; 99145510Sdarrenr strncpy(ipht.iph_name, $3, 100145510Sdarrenr sizeof(ipht.iph_name)); 101145510Sdarrenr ipht.iph_type = IPHASH_GROUPMAP; 102145510Sdarrenr load_hash(&ipht, $4, poolioctl); 103145510Sdarrenr resetlexer(); 104145510Sdarrenr } 105145510Sdarrenr | YY_COMMENT 106145510Sdarrenr ; 107145510Sdarrenr 108145510Sdarrenreol: ';' 109145510Sdarrenr ; 110145510Sdarrenr 111145510Sdarrenrassign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 112145510Sdarrenr resetlexer(); 113145510Sdarrenr free($1); 114145510Sdarrenr free($3); 115145510Sdarrenr } 116145510Sdarrenr ; 117145510Sdarrenr 118145510Sdarrenrassigning: 119145510Sdarrenr '=' { yyvarnext = 1; } 120145510Sdarrenr ; 121145510Sdarrenr 122145510Sdarrenrtable: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); 123145510Sdarrenr bzero((char *)&iphte, sizeof(iphte)); 124145510Sdarrenr bzero((char *)&iplo, sizeof(iplo)); 125145510Sdarrenr *ipht.iph_name = '\0'; 126145510Sdarrenr iplo.ipo_flags = IPHASH_ANON; 127145510Sdarrenr iplo.ipo_name[0] = '\0'; 128145510Sdarrenr } 129145510Sdarrenr ; 130145510Sdarrenr 131145510Sdarrenrgroupmap: 132145510Sdarrenr IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); 133145510Sdarrenr bzero((char *)&iphte, sizeof(iphte)); 134145510Sdarrenr *ipht.iph_name = '\0'; 135145510Sdarrenr ipht.iph_unit = IPHASH_GROUPMAP; 136145510Sdarrenr ipht.iph_flags = $2; 137145510Sdarrenr } 138145510Sdarrenr ; 139145510Sdarrenr 140145510Sdarrenrinout: IPT_IN { $$ = FR_INQUE; } 141145510Sdarrenr | IPT_OUT { $$ = FR_OUTQUE; } 142145510Sdarrenr ; 143145510Sdarrenrrole: 144145510Sdarrenr IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; } 145145510Sdarrenr | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; } 146145510Sdarrenr | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; } 147145510Sdarrenr | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; } 148145510Sdarrenr ; 149145510Sdarrenr 150145510Sdarrenripftree: 151145510Sdarrenr IPT_TYPE '=' IPT_TREE number start addrlist end 152145510Sdarrenr { strncpy(iplo.ipo_name, $4, 153145510Sdarrenr sizeof(iplo.ipo_name)); 154145510Sdarrenr $$ = $6; 155145510Sdarrenr } 156145510Sdarrenr ; 157145510Sdarrenr 158145510Sdarrenripfhash: 159145510Sdarrenr IPT_TYPE '=' IPT_HASH number hashopts start hashlist end 160145510Sdarrenr { strncpy(ipht.iph_name, $4, 161145510Sdarrenr sizeof(ipht.iph_name)); 162145510Sdarrenr $$ = $7; 163145510Sdarrenr } 164145510Sdarrenr ; 165145510Sdarrenr 166145510Sdarrenripfgroup: 167145510Sdarrenr setgroup hashopts start grouplist end 168145510Sdarrenr { iphtent_t *e; 169145510Sdarrenr for (e = $4; e != NULL; 170145510Sdarrenr e = e->ipe_next) 171145510Sdarrenr if (e->ipe_group[0] == '\0') 172145510Sdarrenr strncpy(e->ipe_group, 173145510Sdarrenr $1, 174145510Sdarrenr FR_GROUPLEN); 175145510Sdarrenr $$ = $4; 176145510Sdarrenr } 177145510Sdarrenr | hashopts start setgrouplist end { $$ = $3; } 178145510Sdarrenr ; 179145510Sdarrenr 180145510Sdarrenrnumber: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3); 181145510Sdarrenr $$ = poolname; 182145510Sdarrenr } 183145510Sdarrenr | IPT_NAME '=' YY_STR { $$ = $3; } 184145510Sdarrenr | { $$ = ""; } 185145510Sdarrenr ; 186145510Sdarrenr 187145510Sdarrenrsetgroup: 188145510Sdarrenr IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; 189145510Sdarrenr strncpy(tmp, $3, FR_GROUPLEN); 190145510Sdarrenr $$ = strdup(tmp); 191145510Sdarrenr } 192145510Sdarrenr | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; 193145510Sdarrenr sprintf(tmp, "%u", $3); 194145510Sdarrenr $$ = strdup(tmp); 195145510Sdarrenr } 196145510Sdarrenr ; 197145510Sdarrenr 198145510Sdarrenrhashopts: 199145510Sdarrenr | size 200145510Sdarrenr | seed 201145510Sdarrenr | size seed 202145510Sdarrenr ; 203145510Sdarrenr 204145510Sdarrenraddrlist: 205145510Sdarrenr next { $$ = NULL; } 206145510Sdarrenr | range next addrlist { $1->ipn_next = $3; $$ = $1; } 207145510Sdarrenr | range next { $$ = $1; } 208145510Sdarrenr ; 209145510Sdarrenr 210145510Sdarrenrgrouplist: 211145510Sdarrenr next { $$ = NULL; } 212145510Sdarrenr | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } 213145510Sdarrenr | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); 214145510Sdarrenr bcopy((char *)&($1[0]), 215145510Sdarrenr (char *)&($$->ipe_addr), 216145510Sdarrenr sizeof($$->ipe_addr)); 217145510Sdarrenr bcopy((char *)&($1[1]), 218145510Sdarrenr (char *)&($$->ipe_mask), 219145510Sdarrenr sizeof($$->ipe_mask)); 220145510Sdarrenr $$->ipe_next = $3; 221145510Sdarrenr } 222145510Sdarrenr | groupentry next { $$ = $1; } 223145510Sdarrenr | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); 224145510Sdarrenr bcopy((char *)&($1[0]), 225145510Sdarrenr (char *)&($$->ipe_addr), 226145510Sdarrenr sizeof($$->ipe_addr)); 227145510Sdarrenr bcopy((char *)&($1[1]), 228145510Sdarrenr (char *)&($$->ipe_mask), 229145510Sdarrenr sizeof($$->ipe_mask)); 230145510Sdarrenr } 231145510Sdarrenr ; 232145510Sdarrenr 233145510Sdarrenrsetgrouplist: 234145510Sdarrenr next { $$ = NULL; } 235145510Sdarrenr | groupentry next { $$ = $1; } 236145510Sdarrenr | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } 237145510Sdarrenr ; 238145510Sdarrenr 239145510Sdarrenrgroupentry: 240145510Sdarrenr addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); 241145510Sdarrenr bcopy((char *)&($1[0]), 242145510Sdarrenr (char *)&($$->ipe_addr), 243145510Sdarrenr sizeof($$->ipe_addr)); 244145510Sdarrenr bcopy((char *)&($1[1]), 245145510Sdarrenr (char *)&($$->ipe_mask), 246145510Sdarrenr sizeof($$->ipe_mask)); 247145510Sdarrenr strncpy($$->ipe_group, $3, 248145510Sdarrenr FR_GROUPLEN); 249145510Sdarrenr free($3); 250145510Sdarrenr } 251145510Sdarrenr ; 252145510Sdarrenr 253145510Sdarrenrrange: addrmask { $$ = calloc(1, sizeof(*$$)); 254145510Sdarrenr $$->ipn_info = 0; 255145510Sdarrenr $$->ipn_addr.adf_len = sizeof($$->ipn_addr); 256145510Sdarrenr $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr; 257145510Sdarrenr $$->ipn_mask.adf_len = sizeof($$->ipn_mask); 258145510Sdarrenr $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr; 259145510Sdarrenr } 260145510Sdarrenr | '!' addrmask { $$ = calloc(1, sizeof(*$$)); 261145510Sdarrenr $$->ipn_info = 1; 262145510Sdarrenr $$->ipn_addr.adf_len = sizeof($$->ipn_addr); 263145510Sdarrenr $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr; 264145510Sdarrenr $$->ipn_mask.adf_len = sizeof($$->ipn_mask); 265145510Sdarrenr $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr; 266145510Sdarrenr } 267145510Sdarrenr 268145510Sdarrenrhashlist: 269145510Sdarrenr next { $$ = NULL; } 270145510Sdarrenr | hashentry next { $$ = $1; } 271145510Sdarrenr | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } 272145510Sdarrenr ; 273145510Sdarrenr 274145510Sdarrenrhashentry: 275145510Sdarrenr addrmask { $$ = calloc(1, sizeof(iphtent_t)); 276145510Sdarrenr bcopy((char *)&($1[0]), 277145510Sdarrenr (char *)&($$->ipe_addr), 278145510Sdarrenr sizeof($$->ipe_addr)); 279145510Sdarrenr bcopy((char *)&($1[1]), 280145510Sdarrenr (char *)&($$->ipe_mask), 281145510Sdarrenr sizeof($$->ipe_mask)); 282145510Sdarrenr } 283145510Sdarrenr ; 284145510Sdarrenr 285145510Sdarrenraddrmask: 286145510Sdarrenr ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr; 287145510Sdarrenr yyexpectaddr = 0; 288145510Sdarrenr } 289145510Sdarrenr | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff; 290145510Sdarrenr yyexpectaddr = 0; 291145510Sdarrenr } 292145510Sdarrenr ; 293145510Sdarrenr 294145510Sdarrenripaddr: ipv4 { $$ = $1; } 295145510Sdarrenr | YY_NUMBER { $$.s_addr = htonl($1); } 296145510Sdarrenr | YY_STR { if (gethost($1, &($$.s_addr)) == -1) 297145510Sdarrenr yyerror("Unknown hostname"); 298145510Sdarrenr } 299145510Sdarrenr ; 300145510Sdarrenr 301145510Sdarrenrmask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); } 302145510Sdarrenr | ipv4 { $$ = $1; } 303145510Sdarrenr ; 304145510Sdarrenr 305145510Sdarrenrstart: '{' { yyexpectaddr = 1; } 306145510Sdarrenr ; 307145510Sdarrenr 308145510Sdarrenrend: '}' { yyexpectaddr = 0; } 309145510Sdarrenr ; 310145510Sdarrenr 311145510Sdarrenrnext: ';' { yyexpectaddr = 1; } 312145510Sdarrenr ; 313145510Sdarrenr 314145510Sdarrenrsize: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } 315145510Sdarrenr ; 316145510Sdarrenr 317145510Sdarrenrseed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } 318145510Sdarrenr ; 319145510Sdarrenr 320145510Sdarrenripv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 321145510Sdarrenr { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 322145510Sdarrenr yyerror("Invalid octet string for IP address"); 323145510Sdarrenr return 0; 324145510Sdarrenr } 325145510Sdarrenr $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 326145510Sdarrenr $$.s_addr = htonl($$.s_addr); 327145510Sdarrenr } 328145510Sdarrenr ; 329145510Sdarrenr%% 330145510Sdarrenrstatic wordtab_t yywords[] = { 331145510Sdarrenr { "auth", IPT_AUTH }, 332145510Sdarrenr { "count", IPT_COUNT }, 333145510Sdarrenr { "group", IPT_GROUP }, 334145510Sdarrenr { "group-map", IPT_GROUPMAP }, 335145510Sdarrenr { "hash", IPT_HASH }, 336145510Sdarrenr { "in", IPT_IN }, 337145510Sdarrenr { "ipf", IPT_IPF }, 338145510Sdarrenr { "name", IPT_NAME }, 339145510Sdarrenr { "nat", IPT_NAT }, 340145510Sdarrenr { "number", IPT_NUM }, 341145510Sdarrenr { "out", IPT_OUT }, 342145510Sdarrenr { "role", IPT_ROLE }, 343145510Sdarrenr { "seed", IPT_SEED }, 344145510Sdarrenr { "size", IPT_SIZE }, 345145510Sdarrenr { "table", IPT_TABLE }, 346145510Sdarrenr { "tree", IPT_TREE }, 347145510Sdarrenr { "type", IPT_TYPE }, 348145510Sdarrenr { NULL, 0 } 349145510Sdarrenr}; 350145510Sdarrenr 351145510Sdarrenr 352145510Sdarrenrint ippool_parsefile(fd, filename, iocfunc) 353145510Sdarrenrint fd; 354145510Sdarrenrchar *filename; 355145510Sdarrenrioctlfunc_t iocfunc; 356145510Sdarrenr{ 357145510Sdarrenr FILE *fp = NULL; 358145510Sdarrenr char *s; 359145510Sdarrenr 360145510Sdarrenr yylineNum = 1; 361145510Sdarrenr (void) yysettab(yywords); 362145510Sdarrenr 363145510Sdarrenr s = getenv("YYDEBUG"); 364145510Sdarrenr if (s) 365145510Sdarrenr yydebug = atoi(s); 366145510Sdarrenr else 367145510Sdarrenr yydebug = 0; 368145510Sdarrenr 369145510Sdarrenr if (strcmp(filename, "-")) { 370145510Sdarrenr fp = fopen(filename, "r"); 371145510Sdarrenr if (!fp) { 372145510Sdarrenr fprintf(stderr, "fopen(%s) failed: %s\n", filename, 373145510Sdarrenr STRERROR(errno)); 374145510Sdarrenr return -1; 375145510Sdarrenr } 376145510Sdarrenr } else 377145510Sdarrenr fp = stdin; 378145510Sdarrenr 379145510Sdarrenr while (ippool_parsesome(fd, fp, iocfunc) == 1) 380145510Sdarrenr ; 381145510Sdarrenr if (fp != NULL) 382145510Sdarrenr fclose(fp); 383145510Sdarrenr return 0; 384145510Sdarrenr} 385145510Sdarrenr 386145510Sdarrenr 387145510Sdarrenrint ippool_parsesome(fd, fp, iocfunc) 388145510Sdarrenrint fd; 389145510SdarrenrFILE *fp; 390145510Sdarrenrioctlfunc_t iocfunc; 391145510Sdarrenr{ 392145510Sdarrenr char *s; 393145510Sdarrenr int i; 394145510Sdarrenr 395145510Sdarrenr poolioctl = iocfunc; 396145510Sdarrenr 397145510Sdarrenr if (feof(fp)) 398145510Sdarrenr return 0; 399145510Sdarrenr i = fgetc(fp); 400145510Sdarrenr if (i == EOF) 401145510Sdarrenr return 0; 402145510Sdarrenr if (ungetc(i, fp) == EOF) 403145510Sdarrenr return 0; 404145510Sdarrenr if (feof(fp)) 405145510Sdarrenr return 0; 406145510Sdarrenr s = getenv("YYDEBUG"); 407145510Sdarrenr if (s) 408145510Sdarrenr yydebug = atoi(s); 409145510Sdarrenr else 410145510Sdarrenr yydebug = 0; 411145510Sdarrenr 412145510Sdarrenr yyin = fp; 413145510Sdarrenr yyparse(); 414145510Sdarrenr return 1; 415145510Sdarrenr} 416