1145519Sdarrenr/* $FreeBSD: releng/10.3/contrib/ipfilter/tools/ippool_y.y 255332 2013-09-06 23:11:19Z cy $ */ 2145510Sdarrenr 3170268Sdarrenr/* 4255332Scy * Copyright (C) 2012 by Darren Reed. 5170268Sdarrenr * 6170268Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7170268Sdarrenr */ 8145510Sdarrenr%{ 9145510Sdarrenr#include <sys/types.h> 10145510Sdarrenr#include <sys/time.h> 11145510Sdarrenr#include <sys/param.h> 12145510Sdarrenr#include <sys/socket.h> 13145510Sdarrenr#if defined(BSD) && (BSD >= 199306) 14145510Sdarrenr# include <sys/cdefs.h> 15145510Sdarrenr#endif 16145510Sdarrenr#include <sys/ioctl.h> 17145510Sdarrenr 18145510Sdarrenr#include <net/if.h> 19145510Sdarrenr#if __FreeBSD_version >= 300000 20145510Sdarrenr# include <net/if_var.h> 21145510Sdarrenr#endif 22145510Sdarrenr#include <netinet/in.h> 23145510Sdarrenr 24145510Sdarrenr#include <arpa/inet.h> 25145510Sdarrenr 26145510Sdarrenr#include <stdio.h> 27145510Sdarrenr#include <fcntl.h> 28145510Sdarrenr#include <stdlib.h> 29145510Sdarrenr#include <string.h> 30145510Sdarrenr#include <netdb.h> 31145510Sdarrenr#include <ctype.h> 32145510Sdarrenr#include <unistd.h> 33145510Sdarrenr 34145510Sdarrenr#include "ipf.h" 35145510Sdarrenr#include "netinet/ip_lookup.h" 36145510Sdarrenr#include "netinet/ip_pool.h" 37145510Sdarrenr#include "netinet/ip_htable.h" 38255332Scy#include "netinet/ip_dstlist.h" 39145510Sdarrenr#include "ippool_l.h" 40145510Sdarrenr#include "kmem.h" 41145510Sdarrenr 42145510Sdarrenr#define YYDEBUG 1 43170268Sdarrenr#define YYSTACKSIZE 0x00ffffff 44145510Sdarrenr 45145510Sdarrenrextern int yyparse __P((void)); 46145510Sdarrenrextern int yydebug; 47145510Sdarrenrextern FILE *yyin; 48145510Sdarrenr 49145510Sdarrenrstatic iphtable_t ipht; 50145510Sdarrenrstatic iphtent_t iphte; 51145510Sdarrenrstatic ip_pool_t iplo; 52255332Scystatic ippool_dst_t ipld; 53145510Sdarrenrstatic ioctlfunc_t poolioctl = NULL; 54145510Sdarrenrstatic char poolname[FR_GROUPLEN]; 55145510Sdarrenr 56170268Sdarrenrstatic iphtent_t *add_htablehosts __P((char *)); 57170268Sdarrenrstatic ip_pool_node_t *add_poolhosts __P((char *)); 58255332Scystatic ip_pool_node_t *read_whoisfile __P((char *)); 59255332Scystatic void setadflen __P((addrfamily_t *)); 60170268Sdarrenr 61145510Sdarrenr%} 62145510Sdarrenr 63145510Sdarrenr%union { 64145510Sdarrenr char *str; 65145510Sdarrenr u_32_t num; 66255332Scy struct in_addr ip4; 67145510Sdarrenr struct alist_s *alist; 68255332Scy addrfamily_t adrmsk[2]; 69145510Sdarrenr iphtent_t *ipe; 70145510Sdarrenr ip_pool_node_t *ipp; 71255332Scy ipf_dstnode_t *ipd; 72255332Scy addrfamily_t ipa; 73255332Scy i6addr_t ip6; 74145510Sdarrenr} 75145510Sdarrenr 76255332Scy%token <num> YY_NUMBER YY_HEX 77255332Scy%token <str> YY_STR 78255332Scy%token <ip6> YY_IPV6 79255332Scy%token YY_COMMENT 80255332Scy%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 81255332Scy%token YY_RANGE_OUT YY_RANGE_IN 82255332Scy%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL 83255332Scy%token IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH 84145510Sdarrenr%token IPT_ROLE IPT_TYPE IPT_TREE 85255332Scy%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY 86255332Scy%token IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN 87255332Scy%token IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION 88255332Scy%token IPT_WHOIS IPT_FILE 89255332Scy%type <num> role table inout unit dstopts weighting 90145510Sdarrenr%type <ipp> ipftree range addrlist 91145510Sdarrenr%type <adrmsk> addrmask 92145510Sdarrenr%type <ipe> ipfgroup ipfhash hashlist hashentry 93145510Sdarrenr%type <ipe> groupentry setgrouplist grouplist 94255332Scy%type <ipa> ipaddr mask 95255332Scy%type <ip4> ipv4 96255332Scy%type <str> number setgroup name 97255332Scy%type <ipd> dstentry dstentries dstlist 98145510Sdarrenr 99145510Sdarrenr%% 100145510Sdarrenrfile: line 101145510Sdarrenr | assign 102145510Sdarrenr | file line 103145510Sdarrenr | file assign 104145510Sdarrenr ; 105145510Sdarrenr 106255332Scyline: table role ipftree eol { ip_pool_node_t *n; 107255332Scy iplo.ipo_unit = $2; 108145510Sdarrenr iplo.ipo_list = $3; 109145510Sdarrenr load_pool(&iplo, poolioctl); 110255332Scy while ((n = $3) != NULL) { 111255332Scy $3 = n->ipn_next; 112255332Scy free(n); 113255332Scy } 114145510Sdarrenr resetlexer(); 115255332Scy use_inet6 = 0; 116145510Sdarrenr } 117255332Scy | table role ipfhash eol { iphtent_t *h; 118255332Scy ipht.iph_unit = $2; 119145510Sdarrenr ipht.iph_type = IPHASH_LOOKUP; 120145510Sdarrenr load_hash(&ipht, $3, poolioctl); 121255332Scy while ((h = $3) != NULL) { 122255332Scy $3 = h->ipe_next; 123255332Scy free(h); 124255332Scy } 125145510Sdarrenr resetlexer(); 126255332Scy use_inet6 = 0; 127145510Sdarrenr } 128145510Sdarrenr | groupmap role number ipfgroup eol 129255332Scy { iphtent_t *h; 130255332Scy ipht.iph_unit = $2; 131145510Sdarrenr strncpy(ipht.iph_name, $3, 132145510Sdarrenr sizeof(ipht.iph_name)); 133145510Sdarrenr ipht.iph_type = IPHASH_GROUPMAP; 134145510Sdarrenr load_hash(&ipht, $4, poolioctl); 135255332Scy while ((h = $4) != NULL) { 136255332Scy $4 = h->ipe_next; 137255332Scy free(h); 138255332Scy } 139145510Sdarrenr resetlexer(); 140255332Scy use_inet6 = 0; 141145510Sdarrenr } 142145510Sdarrenr | YY_COMMENT 143255332Scy | poolline eol 144145510Sdarrenr ; 145145510Sdarrenr 146145510Sdarrenreol: ';' 147145510Sdarrenr ; 148145510Sdarrenr 149145510Sdarrenrassign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 150145510Sdarrenr resetlexer(); 151145510Sdarrenr free($1); 152145510Sdarrenr free($3); 153170268Sdarrenr yyvarnext = 0; 154145510Sdarrenr } 155145510Sdarrenr ; 156145510Sdarrenr 157145510Sdarrenrassigning: 158145510Sdarrenr '=' { yyvarnext = 1; } 159145510Sdarrenr ; 160145510Sdarrenr 161145510Sdarrenrtable: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); 162145510Sdarrenr bzero((char *)&iphte, sizeof(iphte)); 163145510Sdarrenr bzero((char *)&iplo, sizeof(iplo)); 164255332Scy bzero((char *)&ipld, sizeof(ipld)); 165145510Sdarrenr *ipht.iph_name = '\0'; 166145510Sdarrenr iplo.ipo_flags = IPHASH_ANON; 167145510Sdarrenr iplo.ipo_name[0] = '\0'; 168145510Sdarrenr } 169145510Sdarrenr ; 170145510Sdarrenr 171145510Sdarrenrgroupmap: 172145510Sdarrenr IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); 173145510Sdarrenr bzero((char *)&iphte, sizeof(iphte)); 174145510Sdarrenr *ipht.iph_name = '\0'; 175145510Sdarrenr ipht.iph_unit = IPHASH_GROUPMAP; 176145510Sdarrenr ipht.iph_flags = $2; 177145510Sdarrenr } 178145510Sdarrenr ; 179145510Sdarrenr 180145510Sdarrenrinout: IPT_IN { $$ = FR_INQUE; } 181145510Sdarrenr | IPT_OUT { $$ = FR_OUTQUE; } 182145510Sdarrenr ; 183255332Scy 184255332Scyrole: IPT_ROLE '=' unit { $$ = $3; } 185145510Sdarrenr ; 186145510Sdarrenr 187255332Scyunit: IPT_IPF { $$ = IPL_LOGIPF; } 188255332Scy | IPT_NAT { $$ = IPL_LOGNAT; } 189255332Scy | IPT_AUTH { $$ = IPL_LOGAUTH; } 190255332Scy | IPT_COUNT { $$ = IPL_LOGCOUNT; } 191255332Scy | IPT_ALL { $$ = IPL_LOGALL; } 192255332Scy ; 193255332Scy 194145510Sdarrenripftree: 195145510Sdarrenr IPT_TYPE '=' IPT_TREE number start addrlist end 196145510Sdarrenr { strncpy(iplo.ipo_name, $4, 197145510Sdarrenr sizeof(iplo.ipo_name)); 198145510Sdarrenr $$ = $6; 199145510Sdarrenr } 200145510Sdarrenr ; 201145510Sdarrenr 202145510Sdarrenripfhash: 203145510Sdarrenr IPT_TYPE '=' IPT_HASH number hashopts start hashlist end 204145510Sdarrenr { strncpy(ipht.iph_name, $4, 205145510Sdarrenr sizeof(ipht.iph_name)); 206145510Sdarrenr $$ = $7; 207145510Sdarrenr } 208145510Sdarrenr ; 209145510Sdarrenr 210145510Sdarrenripfgroup: 211145510Sdarrenr setgroup hashopts start grouplist end 212145510Sdarrenr { iphtent_t *e; 213145510Sdarrenr for (e = $4; e != NULL; 214145510Sdarrenr e = e->ipe_next) 215145510Sdarrenr if (e->ipe_group[0] == '\0') 216145510Sdarrenr strncpy(e->ipe_group, 217145510Sdarrenr $1, 218145510Sdarrenr FR_GROUPLEN); 219145510Sdarrenr $$ = $4; 220255332Scy free($1); 221145510Sdarrenr } 222255332Scy | hashopts start setgrouplist end 223255332Scy { $$ = $3; } 224145510Sdarrenr ; 225145510Sdarrenr 226145510Sdarrenrnumber: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3); 227145510Sdarrenr $$ = poolname; 228145510Sdarrenr } 229255332Scy | IPT_NAME '=' YY_STR { strncpy(poolname, $3, 230255332Scy FR_GROUPLEN); 231255332Scy poolname[FR_GROUPLEN-1]='\0'; 232255332Scy free($3); 233255332Scy $$ = poolname; 234255332Scy } 235145510Sdarrenr | { $$ = ""; } 236145510Sdarrenr ; 237145510Sdarrenr 238145510Sdarrenrsetgroup: 239145510Sdarrenr IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; 240145510Sdarrenr strncpy(tmp, $3, FR_GROUPLEN); 241145510Sdarrenr $$ = strdup(tmp); 242255332Scy free($3); 243145510Sdarrenr } 244145510Sdarrenr | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; 245145510Sdarrenr sprintf(tmp, "%u", $3); 246145510Sdarrenr $$ = strdup(tmp); 247145510Sdarrenr } 248145510Sdarrenr ; 249145510Sdarrenr 250145510Sdarrenrhashopts: 251145510Sdarrenr | size 252145510Sdarrenr | seed 253145510Sdarrenr | size seed 254145510Sdarrenr ; 255145510Sdarrenr 256145510Sdarrenraddrlist: 257255332Scy ';' { $$ = NULL; } 258255332Scy | range next addrlist { $$ = $1; 259255332Scy while ($1->ipn_next != NULL) 260255332Scy $1 = $1->ipn_next; 261255332Scy $1->ipn_next = $3; 262255332Scy } 263145510Sdarrenr | range next { $$ = $1; } 264145510Sdarrenr ; 265145510Sdarrenr 266145510Sdarrenrgrouplist: 267255332Scy ';' { $$ = NULL; } 268145510Sdarrenr | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } 269145510Sdarrenr | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); 270255332Scy $$->ipe_addr = $1[0].adf_addr; 271255332Scy $$->ipe_mask = $1[1].adf_addr; 272255332Scy $$->ipe_family = $1[0].adf_family; 273145510Sdarrenr $$->ipe_next = $3; 274145510Sdarrenr } 275145510Sdarrenr | groupentry next { $$ = $1; } 276145510Sdarrenr | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); 277255332Scy $$->ipe_addr = $1[0].adf_addr; 278255332Scy $$->ipe_mask = $1[1].adf_addr; 279255332Scy#ifdef AF_INET6 280255332Scy if (use_inet6) 281255332Scy $$->ipe_family = AF_INET6; 282255332Scy else 283255332Scy#endif 284255332Scy $$->ipe_family = AF_INET; 285145510Sdarrenr } 286255332Scy | YY_STR { $$ = add_htablehosts($1); 287255332Scy free($1); 288255332Scy } 289145510Sdarrenr ; 290145510Sdarrenr 291145510Sdarrenrsetgrouplist: 292255332Scy ';' { $$ = NULL; } 293145510Sdarrenr | groupentry next { $$ = $1; } 294145510Sdarrenr | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } 295145510Sdarrenr ; 296145510Sdarrenr 297145510Sdarrenrgroupentry: 298145510Sdarrenr addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); 299255332Scy $$->ipe_addr = $1[0].adf_addr; 300255332Scy $$->ipe_mask = $1[1].adf_addr; 301145510Sdarrenr strncpy($$->ipe_group, $3, 302145510Sdarrenr FR_GROUPLEN); 303255332Scy#ifdef AF_INET6 304255332Scy if (use_inet6) 305255332Scy $$->ipe_family = AF_INET6; 306255332Scy else 307255332Scy#endif 308255332Scy $$->ipe_family = AF_INET; 309145510Sdarrenr free($3); 310145510Sdarrenr } 311145510Sdarrenr ; 312145510Sdarrenr 313255332Scyrange: addrmask { $$ = calloc(1, sizeof(*$$)); 314255332Scy $$->ipn_info = 0; 315255332Scy $$->ipn_addr = $1[0]; 316255332Scy $$->ipn_mask = $1[1]; 317255332Scy } 318255332Scy | '!' addrmask { $$ = calloc(1, sizeof(*$$)); 319255332Scy $$->ipn_info = 1; 320255332Scy $$->ipn_addr = $2[0]; 321255332Scy $$->ipn_mask = $2[1]; 322255332Scy } 323255332Scy | YY_STR { $$ = add_poolhosts($1); 324255332Scy free($1); 325255332Scy } 326255332Scy | IPT_WHOIS IPT_FILE YY_STR { $$ = read_whoisfile($3); 327255332Scy free($3); 328255332Scy } 329255332Scy ; 330145510Sdarrenr 331145510Sdarrenrhashlist: 332255332Scy ';' { $$ = NULL; } 333145510Sdarrenr | hashentry next { $$ = $1; } 334145510Sdarrenr | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } 335145510Sdarrenr ; 336145510Sdarrenr 337145510Sdarrenrhashentry: 338255332Scy addrmask { $$ = calloc(1, sizeof(iphtent_t)); 339255332Scy $$->ipe_addr = $1[0].adf_addr; 340255332Scy $$->ipe_mask = $1[1].adf_addr; 341255332Scy#ifdef USE_INET6 342255332Scy if (use_inet6) 343255332Scy $$->ipe_family = AF_INET6; 344255332Scy else 345255332Scy#endif 346255332Scy $$->ipe_family = AF_INET; 347255332Scy } 348255332Scy | YY_STR { $$ = add_htablehosts($1); 349255332Scy free($1); 350255332Scy } 351145510Sdarrenr ; 352145510Sdarrenr 353145510Sdarrenraddrmask: 354255332Scy ipaddr '/' mask { $$[0] = $1; 355255332Scy setadflen(&$$[0]); 356255332Scy $$[1] = $3; 357255332Scy $$[1].adf_len = $$[0].adf_len; 358145510Sdarrenr } 359255332Scy | ipaddr { $$[0] = $1; 360255332Scy setadflen(&$$[1]); 361255332Scy $$[1].adf_len = $$[0].adf_len; 362255332Scy#ifdef USE_INET6 363255332Scy if (use_inet6) 364255332Scy memset(&$$[1].adf_addr, 0xff, 365255332Scy sizeof($$[1].adf_addr.in6)); 366255332Scy else 367255332Scy#endif 368255332Scy memset(&$$[1].adf_addr, 0xff, 369255332Scy sizeof($$[1].adf_addr.in4)); 370145510Sdarrenr } 371145510Sdarrenr ; 372145510Sdarrenr 373255332Scyipaddr: ipv4 { $$.adf_addr.in4 = $1; 374255332Scy $$.adf_family = AF_INET; 375255332Scy setadflen(&$$); 376255332Scy use_inet6 = 0; 377255332Scy } 378255332Scy | YY_NUMBER { $$.adf_addr.in4.s_addr = htonl($1); 379255332Scy $$.adf_family = AF_INET; 380255332Scy setadflen(&$$); 381255332Scy use_inet6 = 0; 382255332Scy } 383255332Scy | YY_IPV6 { $$.adf_addr = $1; 384255332Scy $$.adf_family = AF_INET6; 385255332Scy setadflen(&$$); 386255332Scy use_inet6 = 1; 387255332Scy } 388145510Sdarrenr ; 389145510Sdarrenr 390255332Scymask: YY_NUMBER { bzero(&$$, sizeof($$)); 391255332Scy if (use_inet6) { 392255332Scy if (ntomask(AF_INET6, $1, 393255332Scy (u_32_t *)&$$.adf_addr) == -1) 394255332Scy yyerror("bad bitmask"); 395255332Scy } else { 396255332Scy if (ntomask(AF_INET, $1, 397255332Scy (u_32_t *)&$$.adf_addr.in4) == -1) 398255332Scy yyerror("bad bitmask"); 399255332Scy } 400255332Scy } 401255332Scy | ipv4 { bzero(&$$, sizeof($$)); 402255332Scy $$.adf_addr.in4 = $1; 403255332Scy } 404255332Scy | YY_IPV6 { bzero(&$$, sizeof($$)); 405255332Scy $$.adf_addr = $1; 406255332Scy } 407145510Sdarrenr ; 408145510Sdarrenr 409255332Scysize: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } 410145510Sdarrenr ; 411145510Sdarrenr 412255332Scyseed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } 413145510Sdarrenr ; 414145510Sdarrenr 415145510Sdarrenripv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 416145510Sdarrenr { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 417145510Sdarrenr yyerror("Invalid octet string for IP address"); 418145510Sdarrenr return 0; 419145510Sdarrenr } 420145510Sdarrenr $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 421145510Sdarrenr $$.s_addr = htonl($$.s_addr); 422145510Sdarrenr } 423145510Sdarrenr ; 424255332Scy 425255332Scynext: ';' { yyexpectaddr = 1; } 426255332Scy ; 427255332Scy 428255332Scystart: '{' { yyexpectaddr = 1; } 429255332Scy ; 430255332Scy 431255332Scyend: '}' { yyexpectaddr = 0; } 432255332Scy ; 433255332Scy 434255332Scypoolline: 435255332Scy IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')' 436255332Scy start dstlist end 437255332Scy { bzero((char *)&ipld, sizeof(ipld)); 438255332Scy strncpy(ipld.ipld_name, $6, 439255332Scy sizeof(ipld.ipld_name)); 440255332Scy ipld.ipld_unit = $2; 441255332Scy ipld.ipld_policy = $8; 442255332Scy load_dstlist(&ipld, poolioctl, $11); 443255332Scy resetlexer(); 444255332Scy use_inet6 = 0; 445255332Scy free($6); 446255332Scy } 447255332Scy | IPT_POOL unit '/' IPT_TREE '(' name ';' ')' 448255332Scy start addrlist end 449255332Scy { bzero((char *)&iplo, sizeof(iplo)); 450255332Scy strncpy(iplo.ipo_name, $6, 451255332Scy sizeof(iplo.ipo_name)); 452255332Scy iplo.ipo_list = $10; 453255332Scy iplo.ipo_unit = $2; 454255332Scy load_pool(&iplo, poolioctl); 455255332Scy resetlexer(); 456255332Scy use_inet6 = 0; 457255332Scy free($6); 458255332Scy } 459255332Scy | IPT_POOL '(' name ';' ')' start addrlist end 460255332Scy { bzero((char *)&iplo, sizeof(iplo)); 461255332Scy strncpy(iplo.ipo_name, $3, 462255332Scy sizeof(iplo.ipo_name)); 463255332Scy iplo.ipo_list = $7; 464255332Scy iplo.ipo_unit = IPL_LOGALL; 465255332Scy load_pool(&iplo, poolioctl); 466255332Scy resetlexer(); 467255332Scy use_inet6 = 0; 468255332Scy free($3); 469255332Scy } 470255332Scy | IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')' 471255332Scy start hashlist end 472255332Scy { iphtent_t *h; 473255332Scy bzero((char *)&ipht, sizeof(ipht)); 474255332Scy strncpy(ipht.iph_name, $6, 475255332Scy sizeof(ipht.iph_name)); 476255332Scy ipht.iph_unit = $2; 477255332Scy load_hash(&ipht, $11, poolioctl); 478255332Scy while ((h = ipht.iph_list) != NULL) { 479255332Scy ipht.iph_list = h->ipe_next; 480255332Scy free(h); 481255332Scy } 482255332Scy resetlexer(); 483255332Scy use_inet6 = 0; 484255332Scy free($6); 485255332Scy } 486255332Scy | IPT_GROUPMAP '(' name ';' inout ';' ')' 487255332Scy start setgrouplist end 488255332Scy { iphtent_t *h; 489255332Scy bzero((char *)&ipht, sizeof(ipht)); 490255332Scy strncpy(ipht.iph_name, $3, 491255332Scy sizeof(ipht.iph_name)); 492255332Scy ipht.iph_type = IPHASH_GROUPMAP; 493255332Scy ipht.iph_unit = IPL_LOGIPF; 494255332Scy ipht.iph_flags = $5; 495255332Scy load_hash(&ipht, $9, poolioctl); 496255332Scy while ((h = ipht.iph_list) != NULL) { 497255332Scy ipht.iph_list = h->ipe_next; 498255332Scy free(h); 499255332Scy } 500255332Scy resetlexer(); 501255332Scy use_inet6 = 0; 502255332Scy free($3); 503255332Scy } 504255332Scy ; 505255332Scy 506255332Scyname: IPT_NAME YY_STR { $$ = $2; } 507255332Scy | IPT_NUM YY_NUMBER { char name[80]; 508255332Scy sprintf(name, "%d", $2); 509255332Scy $$ = strdup(name); 510255332Scy } 511255332Scy ; 512255332Scy 513255332Scyhashoptlist: 514255332Scy | hashopt ';' 515255332Scy | hashoptlist ';' hashopt ';' 516255332Scy ; 517255332Scyhashopt: 518255332Scy IPT_SIZE YY_NUMBER 519255332Scy | IPT_SEED YY_NUMBER 520255332Scy ; 521255332Scy 522255332Scydstlist: 523255332Scy dstentries { $$ = $1; } 524255332Scy | ';' { $$ = NULL; } 525255332Scy ; 526255332Scy 527255332Scydstentries: 528255332Scy dstentry next { $$ = $1; } 529255332Scy | dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; } 530255332Scy ; 531255332Scy 532255332Scydstentry: 533255332Scy YY_STR ':' ipaddr { int size = sizeof(*$$) + strlen($1) + 1; 534255332Scy $$ = calloc(1, size); 535255332Scy if ($$ != NULL) { 536255332Scy $$->ipfd_dest.fd_name = strlen($1) + 1; 537255332Scy bcopy($1, $$->ipfd_names, 538255332Scy $$->ipfd_dest.fd_name); 539255332Scy $$->ipfd_dest.fd_addr = $3; 540255332Scy $$->ipfd_size = size; 541255332Scy } 542255332Scy free($1); 543255332Scy } 544255332Scy | ipaddr { $$ = calloc(1, sizeof(*$$)); 545255332Scy if ($$ != NULL) { 546255332Scy $$->ipfd_dest.fd_name = -1; 547255332Scy $$->ipfd_dest.fd_addr = $1; 548255332Scy $$->ipfd_size = sizeof(*$$); 549255332Scy } 550255332Scy } 551255332Scy ; 552255332Scy 553255332Scydstopts: 554255332Scy { $$ = IPLDP_NONE; } 555255332Scy | IPT_POLICY IPT_ROUNDROBIN ';' { $$ = IPLDP_ROUNDROBIN; } 556255332Scy | IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; } 557255332Scy | IPT_POLICY IPT_RANDOM ';' { $$ = IPLDP_RANDOM; } 558255332Scy | IPT_POLICY IPT_HASH ';' { $$ = IPLDP_HASHED; } 559255332Scy | IPT_POLICY IPT_SRCHASH ';' { $$ = IPLDP_SRCHASH; } 560255332Scy | IPT_POLICY IPT_DSTHASH ';' { $$ = IPLDP_DSTHASH; } 561255332Scy ; 562255332Scy 563255332Scyweighting: 564255332Scy IPT_CONNECTION { $$ = IPLDP_CONNECTION; } 565255332Scy ; 566145510Sdarrenr%% 567145510Sdarrenrstatic wordtab_t yywords[] = { 568255332Scy { "all", IPT_ALL }, 569255332Scy { "auth", IPT_AUTH }, 570255332Scy { "connection", IPT_CONNECTION }, 571255332Scy { "count", IPT_COUNT }, 572255332Scy { "dst-hash", IPT_DSTHASH }, 573255332Scy { "dstlist", IPT_DSTLIST }, 574255332Scy { "file", IPT_FILE }, 575255332Scy { "group", IPT_GROUP }, 576255332Scy { "group-map", IPT_GROUPMAP }, 577255332Scy { "hash", IPT_HASH }, 578255332Scy { "in", IPT_IN }, 579255332Scy { "ipf", IPT_IPF }, 580255332Scy { "name", IPT_NAME }, 581255332Scy { "nat", IPT_NAT }, 582255332Scy { "number", IPT_NUM }, 583255332Scy { "out", IPT_OUT }, 584255332Scy { "policy", IPT_POLICY }, 585255332Scy { "pool", IPT_POOL }, 586255332Scy { "random", IPT_RANDOM }, 587255332Scy { "round-robin", IPT_ROUNDROBIN }, 588255332Scy { "role", IPT_ROLE }, 589255332Scy { "seed", IPT_SEED }, 590255332Scy { "size", IPT_SIZE }, 591255332Scy { "src-hash", IPT_SRCHASH }, 592255332Scy { "table", IPT_TABLE }, 593255332Scy { "tree", IPT_TREE }, 594255332Scy { "type", IPT_TYPE }, 595255332Scy { "weighted", IPT_WEIGHTED }, 596255332Scy { "whois", IPT_WHOIS }, 597255332Scy { NULL, 0 } 598145510Sdarrenr}; 599145510Sdarrenr 600145510Sdarrenr 601145510Sdarrenrint ippool_parsefile(fd, filename, iocfunc) 602145510Sdarrenrint fd; 603145510Sdarrenrchar *filename; 604145510Sdarrenrioctlfunc_t iocfunc; 605145510Sdarrenr{ 606145510Sdarrenr FILE *fp = NULL; 607145510Sdarrenr char *s; 608145510Sdarrenr 609145510Sdarrenr yylineNum = 1; 610145510Sdarrenr (void) yysettab(yywords); 611145510Sdarrenr 612145510Sdarrenr s = getenv("YYDEBUG"); 613145510Sdarrenr if (s) 614145510Sdarrenr yydebug = atoi(s); 615145510Sdarrenr else 616145510Sdarrenr yydebug = 0; 617145510Sdarrenr 618145510Sdarrenr if (strcmp(filename, "-")) { 619145510Sdarrenr fp = fopen(filename, "r"); 620145510Sdarrenr if (!fp) { 621145510Sdarrenr fprintf(stderr, "fopen(%s) failed: %s\n", filename, 622145510Sdarrenr STRERROR(errno)); 623145510Sdarrenr return -1; 624145510Sdarrenr } 625145510Sdarrenr } else 626145510Sdarrenr fp = stdin; 627145510Sdarrenr 628145510Sdarrenr while (ippool_parsesome(fd, fp, iocfunc) == 1) 629145510Sdarrenr ; 630145510Sdarrenr if (fp != NULL) 631145510Sdarrenr fclose(fp); 632145510Sdarrenr return 0; 633145510Sdarrenr} 634145510Sdarrenr 635145510Sdarrenr 636145510Sdarrenrint ippool_parsesome(fd, fp, iocfunc) 637145510Sdarrenrint fd; 638145510SdarrenrFILE *fp; 639145510Sdarrenrioctlfunc_t iocfunc; 640145510Sdarrenr{ 641145510Sdarrenr char *s; 642145510Sdarrenr int i; 643145510Sdarrenr 644145510Sdarrenr poolioctl = iocfunc; 645145510Sdarrenr 646145510Sdarrenr if (feof(fp)) 647145510Sdarrenr return 0; 648145510Sdarrenr i = fgetc(fp); 649145510Sdarrenr if (i == EOF) 650145510Sdarrenr return 0; 651145510Sdarrenr if (ungetc(i, fp) == EOF) 652145510Sdarrenr return 0; 653145510Sdarrenr if (feof(fp)) 654145510Sdarrenr return 0; 655145510Sdarrenr s = getenv("YYDEBUG"); 656145510Sdarrenr if (s) 657145510Sdarrenr yydebug = atoi(s); 658145510Sdarrenr else 659145510Sdarrenr yydebug = 0; 660145510Sdarrenr 661145510Sdarrenr yyin = fp; 662145510Sdarrenr yyparse(); 663145510Sdarrenr return 1; 664145510Sdarrenr} 665170268Sdarrenr 666170268Sdarrenr 667170268Sdarrenrstatic iphtent_t * 668170268Sdarrenradd_htablehosts(url) 669170268Sdarrenrchar *url; 670170268Sdarrenr{ 671170268Sdarrenr iphtent_t *htop, *hbot, *h; 672170268Sdarrenr alist_t *a, *hlist; 673170268Sdarrenr 674170268Sdarrenr if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 675170268Sdarrenr hlist = load_url(url); 676170268Sdarrenr } else { 677170268Sdarrenr use_inet6 = 0; 678170268Sdarrenr 679170268Sdarrenr hlist = calloc(1, sizeof(*hlist)); 680170268Sdarrenr if (hlist == NULL) 681170268Sdarrenr return NULL; 682170268Sdarrenr 683255332Scy if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 684170268Sdarrenr yyerror("Unknown hostname"); 685255332Scy } 686170268Sdarrenr } 687170268Sdarrenr 688170268Sdarrenr hbot = NULL; 689170268Sdarrenr htop = NULL; 690170268Sdarrenr 691170268Sdarrenr for (a = hlist; a != NULL; a = a->al_next) { 692170268Sdarrenr h = calloc(1, sizeof(*h)); 693170268Sdarrenr if (h == NULL) 694170268Sdarrenr break; 695170268Sdarrenr 696255332Scy h->ipe_family = a->al_family; 697255332Scy h->ipe_addr = a->al_i6addr; 698255332Scy h->ipe_mask = a->al_i6mask; 699170268Sdarrenr 700170268Sdarrenr if (hbot != NULL) 701170268Sdarrenr hbot->ipe_next = h; 702170268Sdarrenr else 703170268Sdarrenr htop = h; 704170268Sdarrenr hbot = h; 705170268Sdarrenr } 706170268Sdarrenr 707170268Sdarrenr alist_free(hlist); 708170268Sdarrenr 709170268Sdarrenr return htop; 710170268Sdarrenr} 711170268Sdarrenr 712170268Sdarrenr 713170268Sdarrenrstatic ip_pool_node_t * 714170268Sdarrenradd_poolhosts(url) 715170268Sdarrenrchar *url; 716170268Sdarrenr{ 717170268Sdarrenr ip_pool_node_t *ptop, *pbot, *p; 718170268Sdarrenr alist_t *a, *hlist; 719170268Sdarrenr 720170268Sdarrenr if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 721170268Sdarrenr hlist = load_url(url); 722170268Sdarrenr } else { 723170268Sdarrenr use_inet6 = 0; 724170268Sdarrenr 725170268Sdarrenr hlist = calloc(1, sizeof(*hlist)); 726170268Sdarrenr if (hlist == NULL) 727170268Sdarrenr return NULL; 728170268Sdarrenr 729255332Scy if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 730170268Sdarrenr yyerror("Unknown hostname"); 731255332Scy } 732170268Sdarrenr } 733170268Sdarrenr 734170268Sdarrenr pbot = NULL; 735170268Sdarrenr ptop = NULL; 736170268Sdarrenr 737170268Sdarrenr for (a = hlist; a != NULL; a = a->al_next) { 738170268Sdarrenr p = calloc(1, sizeof(*p)); 739170268Sdarrenr if (p == NULL) 740170268Sdarrenr break; 741255332Scy p->ipn_mask.adf_addr = a->al_i6mask; 742170268Sdarrenr 743255332Scy if (a->al_family == AF_INET) { 744255332Scy p->ipn_addr.adf_family = AF_INET; 745255332Scy#ifdef USE_INET6 746255332Scy } else if (a->al_family == AF_INET6) { 747255332Scy p->ipn_addr.adf_family = AF_INET6; 748255332Scy#endif 749255332Scy } 750255332Scy setadflen(&p->ipn_addr); 751255332Scy p->ipn_addr.adf_addr = a->al_i6addr; 752170268Sdarrenr p->ipn_info = a->al_not; 753255332Scy p->ipn_mask.adf_len = p->ipn_addr.adf_len; 754170268Sdarrenr 755170268Sdarrenr if (pbot != NULL) 756170268Sdarrenr pbot->ipn_next = p; 757170268Sdarrenr else 758170268Sdarrenr ptop = p; 759170268Sdarrenr pbot = p; 760170268Sdarrenr } 761170268Sdarrenr 762170268Sdarrenr alist_free(hlist); 763170268Sdarrenr 764170268Sdarrenr return ptop; 765170268Sdarrenr} 766255332Scy 767255332Scy 768255332Scyip_pool_node_t * 769255332Scyread_whoisfile(file) 770255332Scy char *file; 771255332Scy{ 772255332Scy ip_pool_node_t *ntop, *ipn, node, *last; 773255332Scy char line[1024]; 774255332Scy FILE *fp; 775255332Scy 776255332Scy fp = fopen(file, "r"); 777255332Scy if (fp == NULL) 778255332Scy return NULL; 779255332Scy 780255332Scy last = NULL; 781255332Scy ntop = NULL; 782255332Scy while (fgets(line, sizeof(line) - 1, fp) != NULL) { 783255332Scy line[sizeof(line) - 1] = '\0'; 784255332Scy 785255332Scy if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask)) 786255332Scy continue; 787255332Scy ipn = calloc(1, sizeof(*ipn)); 788255332Scy if (ipn == NULL) 789255332Scy continue; 790255332Scy ipn->ipn_addr = node.ipn_addr; 791255332Scy ipn->ipn_mask = node.ipn_mask; 792255332Scy if (last == NULL) 793255332Scy ntop = ipn; 794255332Scy else 795255332Scy last->ipn_next = ipn; 796255332Scy last = ipn; 797255332Scy } 798255332Scy fclose(fp); 799255332Scy return ntop; 800255332Scy} 801255332Scy 802255332Scy 803255332Scystatic void 804255332Scysetadflen(afp) 805255332Scy addrfamily_t *afp; 806255332Scy{ 807255332Scy afp->adf_len = offsetof(addrfamily_t, adf_addr); 808255332Scy switch (afp->adf_family) 809255332Scy { 810255332Scy case AF_INET : 811255332Scy afp->adf_len += sizeof(struct in_addr); 812255332Scy break; 813255332Scy#ifdef USE_INET6 814255332Scy case AF_INET6 : 815255332Scy afp->adf_len += sizeof(struct in6_addr); 816255332Scy break; 817255332Scy#endif 818255332Scy default : 819255332Scy break; 820255332Scy } 821255332Scy} 822