1145519Sdarrenr/* $FreeBSD: stable/11/contrib/ipfilter/tools/ippool_y.y 369245 2021-02-09 13:47:46Z git2svn $ */ 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# include <sys/cdefs.h> 14145510Sdarrenr#include <sys/ioctl.h> 15145510Sdarrenr 16145510Sdarrenr#include <net/if.h> 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" 33255332Scy#include "netinet/ip_dstlist.h" 34145510Sdarrenr#include "ippool_l.h" 35145510Sdarrenr#include "kmem.h" 36145510Sdarrenr 37145510Sdarrenr#define YYDEBUG 1 38170268Sdarrenr#define YYSTACKSIZE 0x00ffffff 39145510Sdarrenr 40369245Sgit2svnextern int yyparse(void); 41145510Sdarrenrextern int yydebug; 42145510Sdarrenrextern FILE *yyin; 43145510Sdarrenr 44145510Sdarrenrstatic iphtable_t ipht; 45145510Sdarrenrstatic iphtent_t iphte; 46145510Sdarrenrstatic ip_pool_t iplo; 47255332Scystatic ippool_dst_t ipld; 48145510Sdarrenrstatic ioctlfunc_t poolioctl = NULL; 49145510Sdarrenrstatic char poolname[FR_GROUPLEN]; 50145510Sdarrenr 51369245Sgit2svnstatic iphtent_t *add_htablehosts(char *); 52369245Sgit2svnstatic ip_pool_node_t *add_poolhosts(char *); 53369245Sgit2svnstatic ip_pool_node_t *read_whoisfile(char *); 54369245Sgit2svnstatic void setadflen(addrfamily_t *); 55170268Sdarrenr 56145510Sdarrenr%} 57145510Sdarrenr 58145510Sdarrenr%union { 59145510Sdarrenr char *str; 60145510Sdarrenr u_32_t num; 61255332Scy struct in_addr ip4; 62145510Sdarrenr struct alist_s *alist; 63255332Scy addrfamily_t adrmsk[2]; 64145510Sdarrenr iphtent_t *ipe; 65145510Sdarrenr ip_pool_node_t *ipp; 66255332Scy ipf_dstnode_t *ipd; 67255332Scy addrfamily_t ipa; 68255332Scy i6addr_t ip6; 69145510Sdarrenr} 70145510Sdarrenr 71255332Scy%token <num> YY_NUMBER YY_HEX 72255332Scy%token <str> YY_STR 73255332Scy%token <ip6> YY_IPV6 74255332Scy%token YY_COMMENT 75255332Scy%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 76255332Scy%token YY_RANGE_OUT YY_RANGE_IN 77255332Scy%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL 78255332Scy%token IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH 79145510Sdarrenr%token IPT_ROLE IPT_TYPE IPT_TREE 80255332Scy%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY 81255332Scy%token IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN 82255332Scy%token IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION 83255332Scy%token IPT_WHOIS IPT_FILE 84255332Scy%type <num> role table inout unit dstopts weighting 85145510Sdarrenr%type <ipp> ipftree range addrlist 86145510Sdarrenr%type <adrmsk> addrmask 87145510Sdarrenr%type <ipe> ipfgroup ipfhash hashlist hashentry 88145510Sdarrenr%type <ipe> groupentry setgrouplist grouplist 89255332Scy%type <ipa> ipaddr mask 90255332Scy%type <ip4> ipv4 91255332Scy%type <str> number setgroup name 92255332Scy%type <ipd> dstentry dstentries dstlist 93145510Sdarrenr 94145510Sdarrenr%% 95145510Sdarrenrfile: line 96145510Sdarrenr | assign 97145510Sdarrenr | file line 98145510Sdarrenr | file assign 99145510Sdarrenr ; 100145510Sdarrenr 101255332Scyline: table role ipftree eol { ip_pool_node_t *n; 102255332Scy iplo.ipo_unit = $2; 103145510Sdarrenr iplo.ipo_list = $3; 104145510Sdarrenr load_pool(&iplo, poolioctl); 105255332Scy while ((n = $3) != NULL) { 106255332Scy $3 = n->ipn_next; 107255332Scy free(n); 108255332Scy } 109145510Sdarrenr resetlexer(); 110255332Scy use_inet6 = 0; 111145510Sdarrenr } 112255332Scy | table role ipfhash eol { iphtent_t *h; 113255332Scy ipht.iph_unit = $2; 114145510Sdarrenr ipht.iph_type = IPHASH_LOOKUP; 115145510Sdarrenr load_hash(&ipht, $3, poolioctl); 116255332Scy while ((h = $3) != NULL) { 117255332Scy $3 = h->ipe_next; 118255332Scy free(h); 119255332Scy } 120145510Sdarrenr resetlexer(); 121255332Scy use_inet6 = 0; 122145510Sdarrenr } 123145510Sdarrenr | groupmap role number ipfgroup eol 124255332Scy { iphtent_t *h; 125255332Scy ipht.iph_unit = $2; 126145510Sdarrenr strncpy(ipht.iph_name, $3, 127145510Sdarrenr sizeof(ipht.iph_name)); 128145510Sdarrenr ipht.iph_type = IPHASH_GROUPMAP; 129145510Sdarrenr load_hash(&ipht, $4, poolioctl); 130255332Scy while ((h = $4) != NULL) { 131255332Scy $4 = h->ipe_next; 132255332Scy free(h); 133255332Scy } 134145510Sdarrenr resetlexer(); 135255332Scy use_inet6 = 0; 136145510Sdarrenr } 137145510Sdarrenr | YY_COMMENT 138255332Scy | poolline eol 139145510Sdarrenr ; 140145510Sdarrenr 141145510Sdarrenreol: ';' 142145510Sdarrenr ; 143145510Sdarrenr 144145510Sdarrenrassign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 145145510Sdarrenr resetlexer(); 146145510Sdarrenr free($1); 147145510Sdarrenr free($3); 148170268Sdarrenr yyvarnext = 0; 149145510Sdarrenr } 150145510Sdarrenr ; 151145510Sdarrenr 152145510Sdarrenrassigning: 153145510Sdarrenr '=' { yyvarnext = 1; } 154145510Sdarrenr ; 155145510Sdarrenr 156145510Sdarrenrtable: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); 157145510Sdarrenr bzero((char *)&iphte, sizeof(iphte)); 158145510Sdarrenr bzero((char *)&iplo, sizeof(iplo)); 159255332Scy bzero((char *)&ipld, sizeof(ipld)); 160145510Sdarrenr *ipht.iph_name = '\0'; 161145510Sdarrenr iplo.ipo_flags = IPHASH_ANON; 162145510Sdarrenr iplo.ipo_name[0] = '\0'; 163145510Sdarrenr } 164145510Sdarrenr ; 165145510Sdarrenr 166145510Sdarrenrgroupmap: 167145510Sdarrenr IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); 168145510Sdarrenr bzero((char *)&iphte, sizeof(iphte)); 169145510Sdarrenr *ipht.iph_name = '\0'; 170145510Sdarrenr ipht.iph_unit = IPHASH_GROUPMAP; 171145510Sdarrenr ipht.iph_flags = $2; 172145510Sdarrenr } 173145510Sdarrenr ; 174145510Sdarrenr 175145510Sdarrenrinout: IPT_IN { $$ = FR_INQUE; } 176145510Sdarrenr | IPT_OUT { $$ = FR_OUTQUE; } 177145510Sdarrenr ; 178255332Scy 179255332Scyrole: IPT_ROLE '=' unit { $$ = $3; } 180145510Sdarrenr ; 181145510Sdarrenr 182255332Scyunit: IPT_IPF { $$ = IPL_LOGIPF; } 183255332Scy | IPT_NAT { $$ = IPL_LOGNAT; } 184255332Scy | IPT_AUTH { $$ = IPL_LOGAUTH; } 185255332Scy | IPT_COUNT { $$ = IPL_LOGCOUNT; } 186255332Scy | IPT_ALL { $$ = IPL_LOGALL; } 187255332Scy ; 188255332Scy 189145510Sdarrenripftree: 190145510Sdarrenr IPT_TYPE '=' IPT_TREE number start addrlist end 191145510Sdarrenr { strncpy(iplo.ipo_name, $4, 192145510Sdarrenr sizeof(iplo.ipo_name)); 193145510Sdarrenr $$ = $6; 194145510Sdarrenr } 195145510Sdarrenr ; 196145510Sdarrenr 197145510Sdarrenripfhash: 198145510Sdarrenr IPT_TYPE '=' IPT_HASH number hashopts start hashlist end 199145510Sdarrenr { strncpy(ipht.iph_name, $4, 200145510Sdarrenr sizeof(ipht.iph_name)); 201145510Sdarrenr $$ = $7; 202145510Sdarrenr } 203145510Sdarrenr ; 204145510Sdarrenr 205145510Sdarrenripfgroup: 206145510Sdarrenr setgroup hashopts start grouplist end 207145510Sdarrenr { iphtent_t *e; 208145510Sdarrenr for (e = $4; e != NULL; 209145510Sdarrenr e = e->ipe_next) 210145510Sdarrenr if (e->ipe_group[0] == '\0') 211145510Sdarrenr strncpy(e->ipe_group, 212145510Sdarrenr $1, 213145510Sdarrenr FR_GROUPLEN); 214145510Sdarrenr $$ = $4; 215255332Scy free($1); 216145510Sdarrenr } 217255332Scy | hashopts start setgrouplist end 218255332Scy { $$ = $3; } 219145510Sdarrenr ; 220145510Sdarrenr 221145510Sdarrenrnumber: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3); 222145510Sdarrenr $$ = poolname; 223145510Sdarrenr } 224255332Scy | IPT_NAME '=' YY_STR { strncpy(poolname, $3, 225255332Scy FR_GROUPLEN); 226255332Scy poolname[FR_GROUPLEN-1]='\0'; 227255332Scy free($3); 228255332Scy $$ = poolname; 229255332Scy } 230145510Sdarrenr | { $$ = ""; } 231145510Sdarrenr ; 232145510Sdarrenr 233145510Sdarrenrsetgroup: 234145510Sdarrenr IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; 235145510Sdarrenr strncpy(tmp, $3, FR_GROUPLEN); 236145510Sdarrenr $$ = strdup(tmp); 237255332Scy free($3); 238145510Sdarrenr } 239145510Sdarrenr | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; 240145510Sdarrenr sprintf(tmp, "%u", $3); 241145510Sdarrenr $$ = strdup(tmp); 242145510Sdarrenr } 243145510Sdarrenr ; 244145510Sdarrenr 245145510Sdarrenrhashopts: 246145510Sdarrenr | size 247145510Sdarrenr | seed 248145510Sdarrenr | size seed 249145510Sdarrenr ; 250145510Sdarrenr 251145510Sdarrenraddrlist: 252255332Scy ';' { $$ = NULL; } 253255332Scy | range next addrlist { $$ = $1; 254255332Scy while ($1->ipn_next != NULL) 255255332Scy $1 = $1->ipn_next; 256255332Scy $1->ipn_next = $3; 257255332Scy } 258145510Sdarrenr | range next { $$ = $1; } 259145510Sdarrenr ; 260145510Sdarrenr 261145510Sdarrenrgrouplist: 262255332Scy ';' { $$ = NULL; } 263145510Sdarrenr | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } 264145510Sdarrenr | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); 265255332Scy $$->ipe_addr = $1[0].adf_addr; 266255332Scy $$->ipe_mask = $1[1].adf_addr; 267255332Scy $$->ipe_family = $1[0].adf_family; 268145510Sdarrenr $$->ipe_next = $3; 269145510Sdarrenr } 270145510Sdarrenr | groupentry next { $$ = $1; } 271145510Sdarrenr | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); 272255332Scy $$->ipe_addr = $1[0].adf_addr; 273255332Scy $$->ipe_mask = $1[1].adf_addr; 274255332Scy#ifdef AF_INET6 275255332Scy if (use_inet6) 276255332Scy $$->ipe_family = AF_INET6; 277255332Scy else 278255332Scy#endif 279255332Scy $$->ipe_family = AF_INET; 280145510Sdarrenr } 281255332Scy | YY_STR { $$ = add_htablehosts($1); 282255332Scy free($1); 283255332Scy } 284145510Sdarrenr ; 285145510Sdarrenr 286145510Sdarrenrsetgrouplist: 287255332Scy ';' { $$ = NULL; } 288145510Sdarrenr | groupentry next { $$ = $1; } 289145510Sdarrenr | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } 290145510Sdarrenr ; 291145510Sdarrenr 292145510Sdarrenrgroupentry: 293145510Sdarrenr addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); 294255332Scy $$->ipe_addr = $1[0].adf_addr; 295255332Scy $$->ipe_mask = $1[1].adf_addr; 296145510Sdarrenr strncpy($$->ipe_group, $3, 297145510Sdarrenr FR_GROUPLEN); 298255332Scy#ifdef AF_INET6 299255332Scy if (use_inet6) 300255332Scy $$->ipe_family = AF_INET6; 301255332Scy else 302255332Scy#endif 303255332Scy $$->ipe_family = AF_INET; 304145510Sdarrenr free($3); 305145510Sdarrenr } 306145510Sdarrenr ; 307145510Sdarrenr 308255332Scyrange: addrmask { $$ = calloc(1, sizeof(*$$)); 309255332Scy $$->ipn_info = 0; 310255332Scy $$->ipn_addr = $1[0]; 311255332Scy $$->ipn_mask = $1[1]; 312354111Scy#ifdef USE_INET6 313354111Scy if (use_inet6) 314354111Scy $$->ipn_addr.adf_family = 315354111Scy AF_INET6; 316354111Scy else 317354111Scy#endif 318354111Scy $$->ipn_addr.adf_family = 319354111Scy AF_INET; 320255332Scy } 321255332Scy | '!' addrmask { $$ = calloc(1, sizeof(*$$)); 322255332Scy $$->ipn_info = 1; 323255332Scy $$->ipn_addr = $2[0]; 324255332Scy $$->ipn_mask = $2[1]; 325354111Scy#ifdef USE_INET6 326354111Scy if (use_inet6) 327354111Scy $$->ipn_addr.adf_family = 328354111Scy AF_INET6; 329354111Scy else 330354111Scy#endif 331354111Scy $$->ipn_addr.adf_family = 332354111Scy AF_INET; 333255332Scy } 334255332Scy | YY_STR { $$ = add_poolhosts($1); 335255332Scy free($1); 336255332Scy } 337255332Scy | IPT_WHOIS IPT_FILE YY_STR { $$ = read_whoisfile($3); 338255332Scy free($3); 339255332Scy } 340255332Scy ; 341145510Sdarrenr 342145510Sdarrenrhashlist: 343255332Scy ';' { $$ = NULL; } 344145510Sdarrenr | hashentry next { $$ = $1; } 345145510Sdarrenr | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } 346145510Sdarrenr ; 347145510Sdarrenr 348145510Sdarrenrhashentry: 349255332Scy addrmask { $$ = calloc(1, sizeof(iphtent_t)); 350255332Scy $$->ipe_addr = $1[0].adf_addr; 351255332Scy $$->ipe_mask = $1[1].adf_addr; 352255332Scy#ifdef USE_INET6 353255332Scy if (use_inet6) 354255332Scy $$->ipe_family = AF_INET6; 355255332Scy else 356255332Scy#endif 357255332Scy $$->ipe_family = AF_INET; 358255332Scy } 359255332Scy | YY_STR { $$ = add_htablehosts($1); 360255332Scy free($1); 361255332Scy } 362145510Sdarrenr ; 363145510Sdarrenr 364145510Sdarrenraddrmask: 365255332Scy ipaddr '/' mask { $$[0] = $1; 366255332Scy setadflen(&$$[0]); 367255332Scy $$[1] = $3; 368255332Scy $$[1].adf_len = $$[0].adf_len; 369145510Sdarrenr } 370255332Scy | ipaddr { $$[0] = $1; 371255332Scy setadflen(&$$[1]); 372255332Scy $$[1].adf_len = $$[0].adf_len; 373255332Scy#ifdef USE_INET6 374255332Scy if (use_inet6) 375255332Scy memset(&$$[1].adf_addr, 0xff, 376255332Scy sizeof($$[1].adf_addr.in6)); 377255332Scy else 378255332Scy#endif 379255332Scy memset(&$$[1].adf_addr, 0xff, 380255332Scy sizeof($$[1].adf_addr.in4)); 381145510Sdarrenr } 382145510Sdarrenr ; 383145510Sdarrenr 384255332Scyipaddr: ipv4 { $$.adf_addr.in4 = $1; 385255332Scy $$.adf_family = AF_INET; 386255332Scy setadflen(&$$); 387255332Scy use_inet6 = 0; 388255332Scy } 389255332Scy | YY_NUMBER { $$.adf_addr.in4.s_addr = htonl($1); 390255332Scy $$.adf_family = AF_INET; 391255332Scy setadflen(&$$); 392255332Scy use_inet6 = 0; 393255332Scy } 394255332Scy | YY_IPV6 { $$.adf_addr = $1; 395255332Scy $$.adf_family = AF_INET6; 396255332Scy setadflen(&$$); 397255332Scy use_inet6 = 1; 398255332Scy } 399145510Sdarrenr ; 400145510Sdarrenr 401255332Scymask: YY_NUMBER { bzero(&$$, sizeof($$)); 402255332Scy if (use_inet6) { 403255332Scy if (ntomask(AF_INET6, $1, 404255332Scy (u_32_t *)&$$.adf_addr) == -1) 405255332Scy yyerror("bad bitmask"); 406255332Scy } else { 407255332Scy if (ntomask(AF_INET, $1, 408255332Scy (u_32_t *)&$$.adf_addr.in4) == -1) 409255332Scy yyerror("bad bitmask"); 410255332Scy } 411255332Scy } 412255332Scy | ipv4 { bzero(&$$, sizeof($$)); 413255332Scy $$.adf_addr.in4 = $1; 414255332Scy } 415255332Scy | YY_IPV6 { bzero(&$$, sizeof($$)); 416255332Scy $$.adf_addr = $1; 417255332Scy } 418145510Sdarrenr ; 419145510Sdarrenr 420255332Scysize: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } 421145510Sdarrenr ; 422145510Sdarrenr 423255332Scyseed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } 424145510Sdarrenr ; 425145510Sdarrenr 426145510Sdarrenripv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 427145510Sdarrenr { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 428145510Sdarrenr yyerror("Invalid octet string for IP address"); 429145510Sdarrenr return 0; 430145510Sdarrenr } 431145510Sdarrenr $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 432145510Sdarrenr $$.s_addr = htonl($$.s_addr); 433145510Sdarrenr } 434145510Sdarrenr ; 435255332Scy 436255332Scynext: ';' { yyexpectaddr = 1; } 437255332Scy ; 438255332Scy 439255332Scystart: '{' { yyexpectaddr = 1; } 440255332Scy ; 441255332Scy 442255332Scyend: '}' { yyexpectaddr = 0; } 443255332Scy ; 444255332Scy 445255332Scypoolline: 446255332Scy IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')' 447255332Scy start dstlist end 448255332Scy { bzero((char *)&ipld, sizeof(ipld)); 449255332Scy strncpy(ipld.ipld_name, $6, 450255332Scy sizeof(ipld.ipld_name)); 451255332Scy ipld.ipld_unit = $2; 452255332Scy ipld.ipld_policy = $8; 453255332Scy load_dstlist(&ipld, poolioctl, $11); 454255332Scy resetlexer(); 455255332Scy use_inet6 = 0; 456255332Scy free($6); 457255332Scy } 458255332Scy | IPT_POOL unit '/' IPT_TREE '(' name ';' ')' 459255332Scy start addrlist end 460255332Scy { bzero((char *)&iplo, sizeof(iplo)); 461255332Scy strncpy(iplo.ipo_name, $6, 462255332Scy sizeof(iplo.ipo_name)); 463255332Scy iplo.ipo_list = $10; 464255332Scy iplo.ipo_unit = $2; 465255332Scy load_pool(&iplo, poolioctl); 466255332Scy resetlexer(); 467255332Scy use_inet6 = 0; 468255332Scy free($6); 469255332Scy } 470255332Scy | IPT_POOL '(' name ';' ')' start addrlist end 471255332Scy { bzero((char *)&iplo, sizeof(iplo)); 472255332Scy strncpy(iplo.ipo_name, $3, 473255332Scy sizeof(iplo.ipo_name)); 474255332Scy iplo.ipo_list = $7; 475255332Scy iplo.ipo_unit = IPL_LOGALL; 476255332Scy load_pool(&iplo, poolioctl); 477255332Scy resetlexer(); 478255332Scy use_inet6 = 0; 479255332Scy free($3); 480255332Scy } 481255332Scy | IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')' 482255332Scy start hashlist end 483255332Scy { iphtent_t *h; 484255332Scy bzero((char *)&ipht, sizeof(ipht)); 485255332Scy strncpy(ipht.iph_name, $6, 486255332Scy sizeof(ipht.iph_name)); 487255332Scy ipht.iph_unit = $2; 488255332Scy load_hash(&ipht, $11, poolioctl); 489255332Scy while ((h = ipht.iph_list) != NULL) { 490255332Scy ipht.iph_list = h->ipe_next; 491255332Scy free(h); 492255332Scy } 493255332Scy resetlexer(); 494255332Scy use_inet6 = 0; 495255332Scy free($6); 496255332Scy } 497255332Scy | IPT_GROUPMAP '(' name ';' inout ';' ')' 498255332Scy start setgrouplist end 499255332Scy { iphtent_t *h; 500255332Scy bzero((char *)&ipht, sizeof(ipht)); 501255332Scy strncpy(ipht.iph_name, $3, 502255332Scy sizeof(ipht.iph_name)); 503255332Scy ipht.iph_type = IPHASH_GROUPMAP; 504255332Scy ipht.iph_unit = IPL_LOGIPF; 505255332Scy ipht.iph_flags = $5; 506255332Scy load_hash(&ipht, $9, poolioctl); 507255332Scy while ((h = ipht.iph_list) != NULL) { 508255332Scy ipht.iph_list = h->ipe_next; 509255332Scy free(h); 510255332Scy } 511255332Scy resetlexer(); 512255332Scy use_inet6 = 0; 513255332Scy free($3); 514255332Scy } 515255332Scy ; 516255332Scy 517255332Scyname: IPT_NAME YY_STR { $$ = $2; } 518255332Scy | IPT_NUM YY_NUMBER { char name[80]; 519255332Scy sprintf(name, "%d", $2); 520255332Scy $$ = strdup(name); 521255332Scy } 522255332Scy ; 523255332Scy 524255332Scyhashoptlist: 525255332Scy | hashopt ';' 526255332Scy | hashoptlist ';' hashopt ';' 527255332Scy ; 528255332Scyhashopt: 529255332Scy IPT_SIZE YY_NUMBER 530255332Scy | IPT_SEED YY_NUMBER 531255332Scy ; 532255332Scy 533255332Scydstlist: 534255332Scy dstentries { $$ = $1; } 535255332Scy | ';' { $$ = NULL; } 536255332Scy ; 537255332Scy 538255332Scydstentries: 539255332Scy dstentry next { $$ = $1; } 540255332Scy | dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; } 541255332Scy ; 542255332Scy 543255332Scydstentry: 544255332Scy YY_STR ':' ipaddr { int size = sizeof(*$$) + strlen($1) + 1; 545255332Scy $$ = calloc(1, size); 546255332Scy if ($$ != NULL) { 547255332Scy $$->ipfd_dest.fd_name = strlen($1) + 1; 548255332Scy bcopy($1, $$->ipfd_names, 549255332Scy $$->ipfd_dest.fd_name); 550255332Scy $$->ipfd_dest.fd_addr = $3; 551255332Scy $$->ipfd_size = size; 552255332Scy } 553255332Scy free($1); 554255332Scy } 555255332Scy | ipaddr { $$ = calloc(1, sizeof(*$$)); 556255332Scy if ($$ != NULL) { 557255332Scy $$->ipfd_dest.fd_name = -1; 558255332Scy $$->ipfd_dest.fd_addr = $1; 559255332Scy $$->ipfd_size = sizeof(*$$); 560255332Scy } 561255332Scy } 562255332Scy ; 563255332Scy 564255332Scydstopts: 565255332Scy { $$ = IPLDP_NONE; } 566255332Scy | IPT_POLICY IPT_ROUNDROBIN ';' { $$ = IPLDP_ROUNDROBIN; } 567255332Scy | IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; } 568255332Scy | IPT_POLICY IPT_RANDOM ';' { $$ = IPLDP_RANDOM; } 569255332Scy | IPT_POLICY IPT_HASH ';' { $$ = IPLDP_HASHED; } 570255332Scy | IPT_POLICY IPT_SRCHASH ';' { $$ = IPLDP_SRCHASH; } 571255332Scy | IPT_POLICY IPT_DSTHASH ';' { $$ = IPLDP_DSTHASH; } 572255332Scy ; 573255332Scy 574255332Scyweighting: 575255332Scy IPT_CONNECTION { $$ = IPLDP_CONNECTION; } 576255332Scy ; 577145510Sdarrenr%% 578145510Sdarrenrstatic wordtab_t yywords[] = { 579255332Scy { "all", IPT_ALL }, 580255332Scy { "auth", IPT_AUTH }, 581255332Scy { "connection", IPT_CONNECTION }, 582255332Scy { "count", IPT_COUNT }, 583255332Scy { "dst-hash", IPT_DSTHASH }, 584255332Scy { "dstlist", IPT_DSTLIST }, 585255332Scy { "file", IPT_FILE }, 586255332Scy { "group", IPT_GROUP }, 587255332Scy { "group-map", IPT_GROUPMAP }, 588255332Scy { "hash", IPT_HASH }, 589255332Scy { "in", IPT_IN }, 590255332Scy { "ipf", IPT_IPF }, 591255332Scy { "name", IPT_NAME }, 592255332Scy { "nat", IPT_NAT }, 593255332Scy { "number", IPT_NUM }, 594255332Scy { "out", IPT_OUT }, 595255332Scy { "policy", IPT_POLICY }, 596255332Scy { "pool", IPT_POOL }, 597255332Scy { "random", IPT_RANDOM }, 598255332Scy { "round-robin", IPT_ROUNDROBIN }, 599255332Scy { "role", IPT_ROLE }, 600255332Scy { "seed", IPT_SEED }, 601255332Scy { "size", IPT_SIZE }, 602255332Scy { "src-hash", IPT_SRCHASH }, 603255332Scy { "table", IPT_TABLE }, 604255332Scy { "tree", IPT_TREE }, 605255332Scy { "type", IPT_TYPE }, 606255332Scy { "weighted", IPT_WEIGHTED }, 607255332Scy { "whois", IPT_WHOIS }, 608255332Scy { NULL, 0 } 609145510Sdarrenr}; 610145510Sdarrenr 611145510Sdarrenr 612145510Sdarrenrint ippool_parsefile(fd, filename, iocfunc) 613145510Sdarrenrint fd; 614145510Sdarrenrchar *filename; 615145510Sdarrenrioctlfunc_t iocfunc; 616145510Sdarrenr{ 617145510Sdarrenr FILE *fp = NULL; 618145510Sdarrenr char *s; 619145510Sdarrenr 620145510Sdarrenr yylineNum = 1; 621145510Sdarrenr (void) yysettab(yywords); 622145510Sdarrenr 623145510Sdarrenr s = getenv("YYDEBUG"); 624145510Sdarrenr if (s) 625145510Sdarrenr yydebug = atoi(s); 626145510Sdarrenr else 627145510Sdarrenr yydebug = 0; 628145510Sdarrenr 629145510Sdarrenr if (strcmp(filename, "-")) { 630145510Sdarrenr fp = fopen(filename, "r"); 631145510Sdarrenr if (!fp) { 632145510Sdarrenr fprintf(stderr, "fopen(%s) failed: %s\n", filename, 633145510Sdarrenr STRERROR(errno)); 634145510Sdarrenr return -1; 635145510Sdarrenr } 636145510Sdarrenr } else 637145510Sdarrenr fp = stdin; 638145510Sdarrenr 639145510Sdarrenr while (ippool_parsesome(fd, fp, iocfunc) == 1) 640145510Sdarrenr ; 641145510Sdarrenr if (fp != NULL) 642145510Sdarrenr fclose(fp); 643145510Sdarrenr return 0; 644145510Sdarrenr} 645145510Sdarrenr 646145510Sdarrenr 647145510Sdarrenrint ippool_parsesome(fd, fp, iocfunc) 648145510Sdarrenrint fd; 649145510SdarrenrFILE *fp; 650145510Sdarrenrioctlfunc_t iocfunc; 651145510Sdarrenr{ 652145510Sdarrenr char *s; 653145510Sdarrenr int i; 654145510Sdarrenr 655145510Sdarrenr poolioctl = iocfunc; 656145510Sdarrenr 657145510Sdarrenr if (feof(fp)) 658145510Sdarrenr return 0; 659145510Sdarrenr i = fgetc(fp); 660145510Sdarrenr if (i == EOF) 661145510Sdarrenr return 0; 662145510Sdarrenr if (ungetc(i, fp) == EOF) 663145510Sdarrenr return 0; 664145510Sdarrenr if (feof(fp)) 665145510Sdarrenr return 0; 666145510Sdarrenr s = getenv("YYDEBUG"); 667145510Sdarrenr if (s) 668145510Sdarrenr yydebug = atoi(s); 669145510Sdarrenr else 670145510Sdarrenr yydebug = 0; 671145510Sdarrenr 672145510Sdarrenr yyin = fp; 673145510Sdarrenr yyparse(); 674145510Sdarrenr return 1; 675145510Sdarrenr} 676170268Sdarrenr 677170268Sdarrenr 678170268Sdarrenrstatic iphtent_t * 679170268Sdarrenradd_htablehosts(url) 680170268Sdarrenrchar *url; 681170268Sdarrenr{ 682170268Sdarrenr iphtent_t *htop, *hbot, *h; 683170268Sdarrenr alist_t *a, *hlist; 684170268Sdarrenr 685170268Sdarrenr if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 686170268Sdarrenr hlist = load_url(url); 687170268Sdarrenr } else { 688170268Sdarrenr use_inet6 = 0; 689170268Sdarrenr 690170268Sdarrenr hlist = calloc(1, sizeof(*hlist)); 691170268Sdarrenr if (hlist == NULL) 692170268Sdarrenr return NULL; 693170268Sdarrenr 694255332Scy if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 695170268Sdarrenr yyerror("Unknown hostname"); 696255332Scy } 697170268Sdarrenr } 698170268Sdarrenr 699170268Sdarrenr hbot = NULL; 700170268Sdarrenr htop = NULL; 701170268Sdarrenr 702170268Sdarrenr for (a = hlist; a != NULL; a = a->al_next) { 703170268Sdarrenr h = calloc(1, sizeof(*h)); 704170268Sdarrenr if (h == NULL) 705170268Sdarrenr break; 706170268Sdarrenr 707255332Scy h->ipe_family = a->al_family; 708255332Scy h->ipe_addr = a->al_i6addr; 709255332Scy h->ipe_mask = a->al_i6mask; 710170268Sdarrenr 711170268Sdarrenr if (hbot != NULL) 712170268Sdarrenr hbot->ipe_next = h; 713170268Sdarrenr else 714170268Sdarrenr htop = h; 715170268Sdarrenr hbot = h; 716170268Sdarrenr } 717170268Sdarrenr 718170268Sdarrenr alist_free(hlist); 719170268Sdarrenr 720170268Sdarrenr return htop; 721170268Sdarrenr} 722170268Sdarrenr 723170268Sdarrenr 724170268Sdarrenrstatic ip_pool_node_t * 725170268Sdarrenradd_poolhosts(url) 726170268Sdarrenrchar *url; 727170268Sdarrenr{ 728170268Sdarrenr ip_pool_node_t *ptop, *pbot, *p; 729170268Sdarrenr alist_t *a, *hlist; 730170268Sdarrenr 731170268Sdarrenr if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 732170268Sdarrenr hlist = load_url(url); 733170268Sdarrenr } else { 734170268Sdarrenr use_inet6 = 0; 735170268Sdarrenr 736170268Sdarrenr hlist = calloc(1, sizeof(*hlist)); 737170268Sdarrenr if (hlist == NULL) 738170268Sdarrenr return NULL; 739170268Sdarrenr 740255332Scy if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 741170268Sdarrenr yyerror("Unknown hostname"); 742255332Scy } 743170268Sdarrenr } 744170268Sdarrenr 745170268Sdarrenr pbot = NULL; 746170268Sdarrenr ptop = NULL; 747170268Sdarrenr 748170268Sdarrenr for (a = hlist; a != NULL; a = a->al_next) { 749170268Sdarrenr p = calloc(1, sizeof(*p)); 750170268Sdarrenr if (p == NULL) 751170268Sdarrenr break; 752255332Scy p->ipn_mask.adf_addr = a->al_i6mask; 753170268Sdarrenr 754255332Scy if (a->al_family == AF_INET) { 755255332Scy p->ipn_addr.adf_family = AF_INET; 756255332Scy#ifdef USE_INET6 757255332Scy } else if (a->al_family == AF_INET6) { 758255332Scy p->ipn_addr.adf_family = AF_INET6; 759255332Scy#endif 760255332Scy } 761255332Scy setadflen(&p->ipn_addr); 762255332Scy p->ipn_addr.adf_addr = a->al_i6addr; 763170268Sdarrenr p->ipn_info = a->al_not; 764255332Scy p->ipn_mask.adf_len = p->ipn_addr.adf_len; 765170268Sdarrenr 766170268Sdarrenr if (pbot != NULL) 767170268Sdarrenr pbot->ipn_next = p; 768170268Sdarrenr else 769170268Sdarrenr ptop = p; 770170268Sdarrenr pbot = p; 771170268Sdarrenr } 772170268Sdarrenr 773170268Sdarrenr alist_free(hlist); 774170268Sdarrenr 775170268Sdarrenr return ptop; 776170268Sdarrenr} 777255332Scy 778255332Scy 779255332Scyip_pool_node_t * 780255332Scyread_whoisfile(file) 781255332Scy char *file; 782255332Scy{ 783255332Scy ip_pool_node_t *ntop, *ipn, node, *last; 784255332Scy char line[1024]; 785255332Scy FILE *fp; 786255332Scy 787255332Scy fp = fopen(file, "r"); 788255332Scy if (fp == NULL) 789255332Scy return NULL; 790255332Scy 791255332Scy last = NULL; 792255332Scy ntop = NULL; 793255332Scy while (fgets(line, sizeof(line) - 1, fp) != NULL) { 794255332Scy line[sizeof(line) - 1] = '\0'; 795255332Scy 796255332Scy if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask)) 797255332Scy continue; 798255332Scy ipn = calloc(1, sizeof(*ipn)); 799255332Scy if (ipn == NULL) 800255332Scy continue; 801255332Scy ipn->ipn_addr = node.ipn_addr; 802255332Scy ipn->ipn_mask = node.ipn_mask; 803255332Scy if (last == NULL) 804255332Scy ntop = ipn; 805255332Scy else 806255332Scy last->ipn_next = ipn; 807255332Scy last = ipn; 808255332Scy } 809255332Scy fclose(fp); 810255332Scy return ntop; 811255332Scy} 812255332Scy 813255332Scy 814255332Scystatic void 815255332Scysetadflen(afp) 816255332Scy addrfamily_t *afp; 817255332Scy{ 818255332Scy afp->adf_len = offsetof(addrfamily_t, adf_addr); 819255332Scy switch (afp->adf_family) 820255332Scy { 821255332Scy case AF_INET : 822255332Scy afp->adf_len += sizeof(struct in_addr); 823255332Scy break; 824255332Scy#ifdef USE_INET6 825255332Scy case AF_INET6 : 826255332Scy afp->adf_len += sizeof(struct in6_addr); 827255332Scy break; 828255332Scy#endif 829255332Scy default : 830255332Scy break; 831255332Scy } 832255332Scy} 833