141edb306SCy Schubert /* $FreeBSD$ */ 241edb306SCy Schubert 341edb306SCy Schubert /* 441edb306SCy Schubert * Copyright (C) 2012 by Darren Reed. 541edb306SCy Schubert * 641edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing. 741edb306SCy Schubert */ 841edb306SCy Schubert %{ 941edb306SCy Schubert #include <sys/types.h> 1041edb306SCy Schubert #include <sys/time.h> 1141edb306SCy Schubert #include <sys/param.h> 1241edb306SCy Schubert #include <sys/socket.h> 1341edb306SCy Schubert # include <sys/cdefs.h> 1441edb306SCy Schubert #include <sys/ioctl.h> 1541edb306SCy Schubert 1641edb306SCy Schubert #include <net/if.h> 1741edb306SCy Schubert #include <netinet/in.h> 1841edb306SCy Schubert 1941edb306SCy Schubert #include <arpa/inet.h> 2041edb306SCy Schubert 2141edb306SCy Schubert #include <stdio.h> 2241edb306SCy Schubert #include <fcntl.h> 2341edb306SCy Schubert #include <stdlib.h> 2441edb306SCy Schubert #include <string.h> 2541edb306SCy Schubert #include <netdb.h> 2641edb306SCy Schubert #include <ctype.h> 2741edb306SCy Schubert #include <unistd.h> 2841edb306SCy Schubert 2941edb306SCy Schubert #include "ipf.h" 3041edb306SCy Schubert #include "netinet/ip_lookup.h" 3141edb306SCy Schubert #include "netinet/ip_pool.h" 3241edb306SCy Schubert #include "netinet/ip_htable.h" 3341edb306SCy Schubert #include "netinet/ip_dstlist.h" 3441edb306SCy Schubert #include "ippool_l.h" 3541edb306SCy Schubert #include "kmem.h" 3641edb306SCy Schubert 3741edb306SCy Schubert #define YYDEBUG 1 3841edb306SCy Schubert #define YYSTACKSIZE 0x00ffffff 3941edb306SCy Schubert 4041edb306SCy Schubert extern int yyparse(void); 4141edb306SCy Schubert extern int yydebug; 4241edb306SCy Schubert extern FILE *yyin; 4341edb306SCy Schubert 4441edb306SCy Schubert static iphtable_t ipht; 4541edb306SCy Schubert static iphtent_t iphte; 4641edb306SCy Schubert static ip_pool_t iplo; 4741edb306SCy Schubert static ippool_dst_t ipld; 4841edb306SCy Schubert static ioctlfunc_t poolioctl = NULL; 4941edb306SCy Schubert static char poolname[FR_GROUPLEN]; 5041edb306SCy Schubert 5141edb306SCy Schubert static iphtent_t *add_htablehosts(char *); 5241edb306SCy Schubert static ip_pool_node_t *add_poolhosts(char *); 5341edb306SCy Schubert static ip_pool_node_t *read_whoisfile(char *); 5441edb306SCy Schubert static void setadflen(addrfamily_t *); 5541edb306SCy Schubert 5641edb306SCy Schubert %} 5741edb306SCy Schubert 5841edb306SCy Schubert %union { 5941edb306SCy Schubert char *str; 6041edb306SCy Schubert u_32_t num; 6141edb306SCy Schubert struct in_addr ip4; 6241edb306SCy Schubert struct alist_s *alist; 6341edb306SCy Schubert addrfamily_t adrmsk[2]; 6441edb306SCy Schubert iphtent_t *ipe; 6541edb306SCy Schubert ip_pool_node_t *ipp; 6641edb306SCy Schubert ipf_dstnode_t *ipd; 6741edb306SCy Schubert addrfamily_t ipa; 6841edb306SCy Schubert i6addr_t ip6; 6941edb306SCy Schubert } 7041edb306SCy Schubert 7141edb306SCy Schubert %token <num> YY_NUMBER YY_HEX 7241edb306SCy Schubert %token <str> YY_STR 7341edb306SCy Schubert %token <ip6> YY_IPV6 7441edb306SCy Schubert %token YY_COMMENT 7541edb306SCy Schubert %token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT 7641edb306SCy Schubert %token YY_RANGE_OUT YY_RANGE_IN 7741edb306SCy Schubert %token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL 7841edb306SCy Schubert %token IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH 7941edb306SCy Schubert %token IPT_ROLE IPT_TYPE IPT_TREE 8041edb306SCy Schubert %token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY 8141edb306SCy Schubert %token IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN 8241edb306SCy Schubert %token IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION 8341edb306SCy Schubert %token IPT_WHOIS IPT_FILE 8441edb306SCy Schubert %type <num> role table inout unit dstopts weighting 8541edb306SCy Schubert %type <ipp> ipftree range addrlist 8641edb306SCy Schubert %type <adrmsk> addrmask 8741edb306SCy Schubert %type <ipe> ipfgroup ipfhash hashlist hashentry 8841edb306SCy Schubert %type <ipe> groupentry setgrouplist grouplist 8941edb306SCy Schubert %type <ipa> ipaddr mask 9041edb306SCy Schubert %type <ip4> ipv4 9141edb306SCy Schubert %type <str> number setgroup name 9241edb306SCy Schubert %type <ipd> dstentry dstentries dstlist 9341edb306SCy Schubert 9441edb306SCy Schubert %% 9541edb306SCy Schubert file: line 9641edb306SCy Schubert | assign 9741edb306SCy Schubert | file line 9841edb306SCy Schubert | file assign 9941edb306SCy Schubert ; 10041edb306SCy Schubert 10141edb306SCy Schubert line: table role ipftree eol { ip_pool_node_t *n; 10241edb306SCy Schubert iplo.ipo_unit = $2; 10341edb306SCy Schubert iplo.ipo_list = $3; 10441edb306SCy Schubert load_pool(&iplo, poolioctl); 10541edb306SCy Schubert while ((n = $3) != NULL) { 10641edb306SCy Schubert $3 = n->ipn_next; 10741edb306SCy Schubert free(n); 10841edb306SCy Schubert } 10941edb306SCy Schubert resetlexer(); 11041edb306SCy Schubert use_inet6 = 0; 11141edb306SCy Schubert } 11241edb306SCy Schubert | table role ipfhash eol { iphtent_t *h; 11341edb306SCy Schubert ipht.iph_unit = $2; 11441edb306SCy Schubert ipht.iph_type = IPHASH_LOOKUP; 11541edb306SCy Schubert load_hash(&ipht, $3, poolioctl); 11641edb306SCy Schubert while ((h = $3) != NULL) { 11741edb306SCy Schubert $3 = h->ipe_next; 11841edb306SCy Schubert free(h); 11941edb306SCy Schubert } 12041edb306SCy Schubert resetlexer(); 12141edb306SCy Schubert use_inet6 = 0; 12241edb306SCy Schubert } 12341edb306SCy Schubert | groupmap role number ipfgroup eol 12441edb306SCy Schubert { iphtent_t *h; 12541edb306SCy Schubert ipht.iph_unit = $2; 12641edb306SCy Schubert strncpy(ipht.iph_name, $3, 12741edb306SCy Schubert sizeof(ipht.iph_name)); 12841edb306SCy Schubert ipht.iph_type = IPHASH_GROUPMAP; 12941edb306SCy Schubert load_hash(&ipht, $4, poolioctl); 13041edb306SCy Schubert while ((h = $4) != NULL) { 13141edb306SCy Schubert $4 = h->ipe_next; 13241edb306SCy Schubert free(h); 13341edb306SCy Schubert } 13441edb306SCy Schubert resetlexer(); 13541edb306SCy Schubert use_inet6 = 0; 13641edb306SCy Schubert } 13741edb306SCy Schubert | YY_COMMENT 13841edb306SCy Schubert | poolline eol 13941edb306SCy Schubert ; 14041edb306SCy Schubert 14141edb306SCy Schubert eol: ';' 14241edb306SCy Schubert ; 14341edb306SCy Schubert 14441edb306SCy Schubert assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 14541edb306SCy Schubert resetlexer(); 14641edb306SCy Schubert free($1); 14741edb306SCy Schubert free($3); 14841edb306SCy Schubert yyvarnext = 0; 14941edb306SCy Schubert } 15041edb306SCy Schubert ; 15141edb306SCy Schubert 15241edb306SCy Schubert assigning: 15341edb306SCy Schubert '=' { yyvarnext = 1; } 15441edb306SCy Schubert ; 15541edb306SCy Schubert 15641edb306SCy Schubert table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht)); 15741edb306SCy Schubert bzero((char *)&iphte, sizeof(iphte)); 15841edb306SCy Schubert bzero((char *)&iplo, sizeof(iplo)); 15941edb306SCy Schubert bzero((char *)&ipld, sizeof(ipld)); 16041edb306SCy Schubert *ipht.iph_name = '\0'; 16141edb306SCy Schubert iplo.ipo_flags = IPHASH_ANON; 16241edb306SCy Schubert iplo.ipo_name[0] = '\0'; 16341edb306SCy Schubert } 16441edb306SCy Schubert ; 16541edb306SCy Schubert 16641edb306SCy Schubert groupmap: 16741edb306SCy Schubert IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht)); 16841edb306SCy Schubert bzero((char *)&iphte, sizeof(iphte)); 16941edb306SCy Schubert *ipht.iph_name = '\0'; 17041edb306SCy Schubert ipht.iph_unit = IPHASH_GROUPMAP; 17141edb306SCy Schubert ipht.iph_flags = $2; 17241edb306SCy Schubert } 17341edb306SCy Schubert ; 17441edb306SCy Schubert 17541edb306SCy Schubert inout: IPT_IN { $$ = FR_INQUE; } 17641edb306SCy Schubert | IPT_OUT { $$ = FR_OUTQUE; } 17741edb306SCy Schubert ; 17841edb306SCy Schubert 17941edb306SCy Schubert role: IPT_ROLE '=' unit { $$ = $3; } 18041edb306SCy Schubert ; 18141edb306SCy Schubert 18241edb306SCy Schubert unit: IPT_IPF { $$ = IPL_LOGIPF; } 18341edb306SCy Schubert | IPT_NAT { $$ = IPL_LOGNAT; } 18441edb306SCy Schubert | IPT_AUTH { $$ = IPL_LOGAUTH; } 18541edb306SCy Schubert | IPT_COUNT { $$ = IPL_LOGCOUNT; } 18641edb306SCy Schubert | IPT_ALL { $$ = IPL_LOGALL; } 18741edb306SCy Schubert ; 18841edb306SCy Schubert 18941edb306SCy Schubert ipftree: 19041edb306SCy Schubert IPT_TYPE '=' IPT_TREE number start addrlist end 19141edb306SCy Schubert { strncpy(iplo.ipo_name, $4, 19241edb306SCy Schubert sizeof(iplo.ipo_name)); 19341edb306SCy Schubert $$ = $6; 19441edb306SCy Schubert } 19541edb306SCy Schubert ; 19641edb306SCy Schubert 19741edb306SCy Schubert ipfhash: 19841edb306SCy Schubert IPT_TYPE '=' IPT_HASH number hashopts start hashlist end 19941edb306SCy Schubert { strncpy(ipht.iph_name, $4, 20041edb306SCy Schubert sizeof(ipht.iph_name)); 20141edb306SCy Schubert $$ = $7; 20241edb306SCy Schubert } 20341edb306SCy Schubert ; 20441edb306SCy Schubert 20541edb306SCy Schubert ipfgroup: 20641edb306SCy Schubert setgroup hashopts start grouplist end 20741edb306SCy Schubert { iphtent_t *e; 20841edb306SCy Schubert for (e = $4; e != NULL; 20941edb306SCy Schubert e = e->ipe_next) 21041edb306SCy Schubert if (e->ipe_group[0] == '\0') 21141edb306SCy Schubert strncpy(e->ipe_group, 21241edb306SCy Schubert $1, 21341edb306SCy Schubert FR_GROUPLEN); 21441edb306SCy Schubert $$ = $4; 21541edb306SCy Schubert free($1); 21641edb306SCy Schubert } 21741edb306SCy Schubert | hashopts start setgrouplist end 21841edb306SCy Schubert { $$ = $3; } 21941edb306SCy Schubert ; 22041edb306SCy Schubert 22141edb306SCy Schubert number: IPT_NUM '=' YY_NUMBER { snprintf(poolname, sizeof(poolname), "%u", $3); 22241edb306SCy Schubert $$ = poolname; 22341edb306SCy Schubert } 22441edb306SCy Schubert | IPT_NAME '=' YY_STR { strncpy(poolname, $3, 22541edb306SCy Schubert FR_GROUPLEN); 22641edb306SCy Schubert poolname[FR_GROUPLEN-1]='\0'; 22741edb306SCy Schubert free($3); 22841edb306SCy Schubert $$ = poolname; 22941edb306SCy Schubert } 23041edb306SCy Schubert | { $$ = ""; } 23141edb306SCy Schubert ; 23241edb306SCy Schubert 23341edb306SCy Schubert setgroup: 23441edb306SCy Schubert IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1]; 23541edb306SCy Schubert strncpy(tmp, $3, FR_GROUPLEN); 23641edb306SCy Schubert $$ = strdup(tmp); 23741edb306SCy Schubert free($3); 23841edb306SCy Schubert } 23941edb306SCy Schubert | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1]; 24041edb306SCy Schubert snprintf(tmp, sizeof(tmp), "%u", $3); 24141edb306SCy Schubert $$ = strdup(tmp); 24241edb306SCy Schubert } 24341edb306SCy Schubert ; 24441edb306SCy Schubert 24541edb306SCy Schubert hashopts: 24641edb306SCy Schubert | size 24741edb306SCy Schubert | seed 24841edb306SCy Schubert | size seed 24941edb306SCy Schubert ; 25041edb306SCy Schubert 25141edb306SCy Schubert addrlist: 25241edb306SCy Schubert ';' { $$ = NULL; } 25341edb306SCy Schubert | range next addrlist { $$ = $1; 25441edb306SCy Schubert while ($1->ipn_next != NULL) 25541edb306SCy Schubert $1 = $1->ipn_next; 25641edb306SCy Schubert $1->ipn_next = $3; 25741edb306SCy Schubert } 25841edb306SCy Schubert | range next { $$ = $1; } 25941edb306SCy Schubert ; 26041edb306SCy Schubert 26141edb306SCy Schubert grouplist: 26241edb306SCy Schubert ';' { $$ = NULL; } 26341edb306SCy Schubert | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; } 26441edb306SCy Schubert | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t)); 26541edb306SCy Schubert $$->ipe_addr = $1[0].adf_addr; 26641edb306SCy Schubert $$->ipe_mask = $1[1].adf_addr; 26741edb306SCy Schubert $$->ipe_family = $1[0].adf_family; 26841edb306SCy Schubert $$->ipe_next = $3; 26941edb306SCy Schubert } 27041edb306SCy Schubert | groupentry next { $$ = $1; } 27141edb306SCy Schubert | addrmask next { $$ = calloc(1, sizeof(iphtent_t)); 27241edb306SCy Schubert $$->ipe_addr = $1[0].adf_addr; 27341edb306SCy Schubert $$->ipe_mask = $1[1].adf_addr; 27441edb306SCy Schubert #ifdef USE_INET6 27541edb306SCy Schubert if (use_inet6) 27641edb306SCy Schubert $$->ipe_family = AF_INET6; 27741edb306SCy Schubert else 27841edb306SCy Schubert #endif 27941edb306SCy Schubert $$->ipe_family = AF_INET; 28041edb306SCy Schubert } 28141edb306SCy Schubert | YY_STR { $$ = add_htablehosts($1); 28241edb306SCy Schubert free($1); 28341edb306SCy Schubert } 28441edb306SCy Schubert ; 28541edb306SCy Schubert 28641edb306SCy Schubert setgrouplist: 28741edb306SCy Schubert ';' { $$ = NULL; } 28841edb306SCy Schubert | groupentry next { $$ = $1; } 28941edb306SCy Schubert | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } 29041edb306SCy Schubert ; 29141edb306SCy Schubert 29241edb306SCy Schubert groupentry: 29341edb306SCy Schubert addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t)); 29441edb306SCy Schubert $$->ipe_addr = $1[0].adf_addr; 29541edb306SCy Schubert $$->ipe_mask = $1[1].adf_addr; 29641edb306SCy Schubert strncpy($$->ipe_group, $3, 29741edb306SCy Schubert FR_GROUPLEN); 29841edb306SCy Schubert #ifdef USE_INET6 29941edb306SCy Schubert if (use_inet6) 30041edb306SCy Schubert $$->ipe_family = AF_INET6; 30141edb306SCy Schubert else 30241edb306SCy Schubert #endif 30341edb306SCy Schubert $$->ipe_family = AF_INET; 30441edb306SCy Schubert free($3); 30541edb306SCy Schubert } 30641edb306SCy Schubert ; 30741edb306SCy Schubert 30841edb306SCy Schubert range: addrmask { $$ = calloc(1, sizeof(*$$)); 30941edb306SCy Schubert $$->ipn_info = 0; 31041edb306SCy Schubert $$->ipn_addr = $1[0]; 31141edb306SCy Schubert $$->ipn_mask = $1[1]; 31241edb306SCy Schubert #ifdef USE_INET6 31341edb306SCy Schubert if (use_inet6) 31441edb306SCy Schubert $$->ipn_addr.adf_family = 31541edb306SCy Schubert AF_INET6; 31641edb306SCy Schubert else 31741edb306SCy Schubert #endif 31841edb306SCy Schubert $$->ipn_addr.adf_family = 31941edb306SCy Schubert AF_INET; 32041edb306SCy Schubert } 32141edb306SCy Schubert | '!' addrmask { $$ = calloc(1, sizeof(*$$)); 32241edb306SCy Schubert $$->ipn_info = 1; 32341edb306SCy Schubert $$->ipn_addr = $2[0]; 32441edb306SCy Schubert $$->ipn_mask = $2[1]; 32541edb306SCy Schubert #ifdef USE_INET6 32641edb306SCy Schubert if (use_inet6) 32741edb306SCy Schubert $$->ipn_addr.adf_family = 32841edb306SCy Schubert AF_INET6; 32941edb306SCy Schubert else 33041edb306SCy Schubert #endif 33141edb306SCy Schubert $$->ipn_addr.adf_family = 33241edb306SCy Schubert AF_INET; 33341edb306SCy Schubert } 33441edb306SCy Schubert | YY_STR { $$ = add_poolhosts($1); 33541edb306SCy Schubert free($1); 33641edb306SCy Schubert } 33741edb306SCy Schubert | IPT_WHOIS IPT_FILE YY_STR { $$ = read_whoisfile($3); 33841edb306SCy Schubert free($3); 33941edb306SCy Schubert } 34041edb306SCy Schubert ; 34141edb306SCy Schubert 34241edb306SCy Schubert hashlist: 34341edb306SCy Schubert ';' { $$ = NULL; } 34441edb306SCy Schubert | hashentry next { $$ = $1; } 34541edb306SCy Schubert | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } 34641edb306SCy Schubert ; 34741edb306SCy Schubert 34841edb306SCy Schubert hashentry: 34941edb306SCy Schubert addrmask { $$ = calloc(1, sizeof(iphtent_t)); 35041edb306SCy Schubert $$->ipe_addr = $1[0].adf_addr; 35141edb306SCy Schubert $$->ipe_mask = $1[1].adf_addr; 35241edb306SCy Schubert #ifdef USE_INET6 35341edb306SCy Schubert if (use_inet6) 35441edb306SCy Schubert $$->ipe_family = AF_INET6; 35541edb306SCy Schubert else 35641edb306SCy Schubert #endif 35741edb306SCy Schubert $$->ipe_family = AF_INET; 35841edb306SCy Schubert } 35941edb306SCy Schubert | YY_STR { $$ = add_htablehosts($1); 36041edb306SCy Schubert free($1); 36141edb306SCy Schubert } 36241edb306SCy Schubert ; 36341edb306SCy Schubert 36441edb306SCy Schubert addrmask: 36541edb306SCy Schubert ipaddr '/' mask { $$[0] = $1; 36641edb306SCy Schubert setadflen(&$$[0]); 36741edb306SCy Schubert $$[1] = $3; 36841edb306SCy Schubert $$[1].adf_len = $$[0].adf_len; 36941edb306SCy Schubert } 37041edb306SCy Schubert | ipaddr { $$[0] = $1; 37141edb306SCy Schubert setadflen(&$$[1]); 37241edb306SCy Schubert $$[1].adf_len = $$[0].adf_len; 37341edb306SCy Schubert #ifdef USE_INET6 37441edb306SCy Schubert if (use_inet6) 37541edb306SCy Schubert memset(&$$[1].adf_addr, 0xff, 37641edb306SCy Schubert sizeof($$[1].adf_addr.in6)); 37741edb306SCy Schubert else 37841edb306SCy Schubert #endif 37941edb306SCy Schubert memset(&$$[1].adf_addr, 0xff, 38041edb306SCy Schubert sizeof($$[1].adf_addr.in4)); 38141edb306SCy Schubert } 38241edb306SCy Schubert ; 38341edb306SCy Schubert 38441edb306SCy Schubert ipaddr: ipv4 { $$.adf_addr.in4 = $1; 38541edb306SCy Schubert $$.adf_family = AF_INET; 38641edb306SCy Schubert setadflen(&$$); 38741edb306SCy Schubert use_inet6 = 0; 38841edb306SCy Schubert } 38941edb306SCy Schubert | YY_NUMBER { $$.adf_addr.in4.s_addr = htonl($1); 39041edb306SCy Schubert $$.adf_family = AF_INET; 39141edb306SCy Schubert setadflen(&$$); 39241edb306SCy Schubert use_inet6 = 0; 39341edb306SCy Schubert } 39441edb306SCy Schubert | YY_IPV6 { $$.adf_addr = $1; 39541edb306SCy Schubert $$.adf_family = AF_INET6; 39641edb306SCy Schubert setadflen(&$$); 39741edb306SCy Schubert use_inet6 = 1; 39841edb306SCy Schubert } 39941edb306SCy Schubert ; 40041edb306SCy Schubert 40141edb306SCy Schubert mask: YY_NUMBER { bzero(&$$, sizeof($$)); 40241edb306SCy Schubert if (use_inet6) { 40341edb306SCy Schubert if (ntomask(AF_INET6, $1, 40441edb306SCy Schubert (u_32_t *)&$$.adf_addr) == -1) 40541edb306SCy Schubert yyerror("bad bitmask"); 40641edb306SCy Schubert } else { 40741edb306SCy Schubert if (ntomask(AF_INET, $1, 40841edb306SCy Schubert (u_32_t *)&$$.adf_addr.in4) == -1) 40941edb306SCy Schubert yyerror("bad bitmask"); 41041edb306SCy Schubert } 41141edb306SCy Schubert } 41241edb306SCy Schubert | ipv4 { bzero(&$$, sizeof($$)); 41341edb306SCy Schubert $$.adf_addr.in4 = $1; 41441edb306SCy Schubert } 41541edb306SCy Schubert | YY_IPV6 { bzero(&$$, sizeof($$)); 41641edb306SCy Schubert $$.adf_addr = $1; 41741edb306SCy Schubert } 41841edb306SCy Schubert ; 41941edb306SCy Schubert 42041edb306SCy Schubert size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } 42141edb306SCy Schubert ; 42241edb306SCy Schubert 42341edb306SCy Schubert seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } 42441edb306SCy Schubert ; 42541edb306SCy Schubert 42641edb306SCy Schubert ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER 42741edb306SCy Schubert { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) { 42841edb306SCy Schubert yyerror("Invalid octet string for IP address"); 429*2582ae57SCy Schubert return(0); 43041edb306SCy Schubert } 43141edb306SCy Schubert $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7; 43241edb306SCy Schubert $$.s_addr = htonl($$.s_addr); 43341edb306SCy Schubert } 43441edb306SCy Schubert ; 43541edb306SCy Schubert 43641edb306SCy Schubert next: ';' { yyexpectaddr = 1; } 43741edb306SCy Schubert ; 43841edb306SCy Schubert 43941edb306SCy Schubert start: '{' { yyexpectaddr = 1; } 44041edb306SCy Schubert ; 44141edb306SCy Schubert 44241edb306SCy Schubert end: '}' { yyexpectaddr = 0; } 44341edb306SCy Schubert ; 44441edb306SCy Schubert 44541edb306SCy Schubert poolline: 44641edb306SCy Schubert IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')' 44741edb306SCy Schubert start dstlist end 44841edb306SCy Schubert { bzero((char *)&ipld, sizeof(ipld)); 44941edb306SCy Schubert strncpy(ipld.ipld_name, $6, 45041edb306SCy Schubert sizeof(ipld.ipld_name)); 45141edb306SCy Schubert ipld.ipld_unit = $2; 45241edb306SCy Schubert ipld.ipld_policy = $8; 45341edb306SCy Schubert load_dstlist(&ipld, poolioctl, $11); 45441edb306SCy Schubert resetlexer(); 45541edb306SCy Schubert use_inet6 = 0; 45641edb306SCy Schubert free($6); 45741edb306SCy Schubert } 45841edb306SCy Schubert | IPT_POOL unit '/' IPT_TREE '(' name ';' ')' 45941edb306SCy Schubert start addrlist end 46041edb306SCy Schubert { bzero((char *)&iplo, sizeof(iplo)); 46141edb306SCy Schubert strncpy(iplo.ipo_name, $6, 46241edb306SCy Schubert sizeof(iplo.ipo_name)); 46341edb306SCy Schubert iplo.ipo_list = $10; 46441edb306SCy Schubert iplo.ipo_unit = $2; 46541edb306SCy Schubert load_pool(&iplo, poolioctl); 46641edb306SCy Schubert resetlexer(); 46741edb306SCy Schubert use_inet6 = 0; 46841edb306SCy Schubert free($6); 46941edb306SCy Schubert } 47041edb306SCy Schubert | IPT_POOL '(' name ';' ')' start addrlist end 47141edb306SCy Schubert { bzero((char *)&iplo, sizeof(iplo)); 47241edb306SCy Schubert strncpy(iplo.ipo_name, $3, 47341edb306SCy Schubert sizeof(iplo.ipo_name)); 47441edb306SCy Schubert iplo.ipo_list = $7; 47541edb306SCy Schubert iplo.ipo_unit = IPL_LOGALL; 47641edb306SCy Schubert load_pool(&iplo, poolioctl); 47741edb306SCy Schubert resetlexer(); 47841edb306SCy Schubert use_inet6 = 0; 47941edb306SCy Schubert free($3); 48041edb306SCy Schubert } 48141edb306SCy Schubert | IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')' 48241edb306SCy Schubert start hashlist end 48341edb306SCy Schubert { iphtent_t *h; 48441edb306SCy Schubert bzero((char *)&ipht, sizeof(ipht)); 48541edb306SCy Schubert strncpy(ipht.iph_name, $6, 48641edb306SCy Schubert sizeof(ipht.iph_name)); 48741edb306SCy Schubert ipht.iph_unit = $2; 48841edb306SCy Schubert load_hash(&ipht, $11, poolioctl); 48941edb306SCy Schubert while ((h = ipht.iph_list) != NULL) { 49041edb306SCy Schubert ipht.iph_list = h->ipe_next; 49141edb306SCy Schubert free(h); 49241edb306SCy Schubert } 49341edb306SCy Schubert resetlexer(); 49441edb306SCy Schubert use_inet6 = 0; 49541edb306SCy Schubert free($6); 49641edb306SCy Schubert } 49741edb306SCy Schubert | IPT_GROUPMAP '(' name ';' inout ';' ')' 49841edb306SCy Schubert start setgrouplist end 49941edb306SCy Schubert { iphtent_t *h; 50041edb306SCy Schubert bzero((char *)&ipht, sizeof(ipht)); 50141edb306SCy Schubert strncpy(ipht.iph_name, $3, 50241edb306SCy Schubert sizeof(ipht.iph_name)); 50341edb306SCy Schubert ipht.iph_type = IPHASH_GROUPMAP; 50441edb306SCy Schubert ipht.iph_unit = IPL_LOGIPF; 50541edb306SCy Schubert ipht.iph_flags = $5; 50641edb306SCy Schubert load_hash(&ipht, $9, poolioctl); 50741edb306SCy Schubert while ((h = ipht.iph_list) != NULL) { 50841edb306SCy Schubert ipht.iph_list = h->ipe_next; 50941edb306SCy Schubert free(h); 51041edb306SCy Schubert } 51141edb306SCy Schubert resetlexer(); 51241edb306SCy Schubert use_inet6 = 0; 51341edb306SCy Schubert free($3); 51441edb306SCy Schubert } 51541edb306SCy Schubert ; 51641edb306SCy Schubert 51741edb306SCy Schubert name: IPT_NAME YY_STR { $$ = $2; } 51841edb306SCy Schubert | IPT_NUM YY_NUMBER { char name[80]; 51941edb306SCy Schubert snprintf(name, sizeof(name), "%d", $2); 52041edb306SCy Schubert $$ = strdup(name); 52141edb306SCy Schubert } 52241edb306SCy Schubert ; 52341edb306SCy Schubert 52441edb306SCy Schubert hashoptlist: 52541edb306SCy Schubert | hashopt ';' 52641edb306SCy Schubert | hashoptlist ';' hashopt ';' 52741edb306SCy Schubert ; 52841edb306SCy Schubert hashopt: 52941edb306SCy Schubert IPT_SIZE YY_NUMBER 53041edb306SCy Schubert | IPT_SEED YY_NUMBER 53141edb306SCy Schubert ; 53241edb306SCy Schubert 53341edb306SCy Schubert dstlist: 53441edb306SCy Schubert dstentries { $$ = $1; } 53541edb306SCy Schubert | ';' { $$ = NULL; } 53641edb306SCy Schubert ; 53741edb306SCy Schubert 53841edb306SCy Schubert dstentries: 53941edb306SCy Schubert dstentry next { $$ = $1; } 54041edb306SCy Schubert | dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; } 54141edb306SCy Schubert ; 54241edb306SCy Schubert 54341edb306SCy Schubert dstentry: 54441edb306SCy Schubert YY_STR ':' ipaddr { int size = sizeof(*$$) + strlen($1) + 1; 54541edb306SCy Schubert $$ = calloc(1, size); 54641edb306SCy Schubert if ($$ != NULL) { 54741edb306SCy Schubert $$->ipfd_dest.fd_name = strlen($1) + 1; 54841edb306SCy Schubert bcopy($1, $$->ipfd_names, 54941edb306SCy Schubert $$->ipfd_dest.fd_name); 55041edb306SCy Schubert $$->ipfd_dest.fd_addr = $3; 55141edb306SCy Schubert $$->ipfd_size = size; 55241edb306SCy Schubert } 55341edb306SCy Schubert free($1); 55441edb306SCy Schubert } 55541edb306SCy Schubert | ipaddr { $$ = calloc(1, sizeof(*$$)); 55641edb306SCy Schubert if ($$ != NULL) { 55741edb306SCy Schubert $$->ipfd_dest.fd_name = -1; 55841edb306SCy Schubert $$->ipfd_dest.fd_addr = $1; 55941edb306SCy Schubert $$->ipfd_size = sizeof(*$$); 56041edb306SCy Schubert } 56141edb306SCy Schubert } 56241edb306SCy Schubert ; 56341edb306SCy Schubert 56441edb306SCy Schubert dstopts: 56541edb306SCy Schubert { $$ = IPLDP_NONE; } 56641edb306SCy Schubert | IPT_POLICY IPT_ROUNDROBIN ';' { $$ = IPLDP_ROUNDROBIN; } 56741edb306SCy Schubert | IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; } 56841edb306SCy Schubert | IPT_POLICY IPT_RANDOM ';' { $$ = IPLDP_RANDOM; } 56941edb306SCy Schubert | IPT_POLICY IPT_HASH ';' { $$ = IPLDP_HASHED; } 57041edb306SCy Schubert | IPT_POLICY IPT_SRCHASH ';' { $$ = IPLDP_SRCHASH; } 57141edb306SCy Schubert | IPT_POLICY IPT_DSTHASH ';' { $$ = IPLDP_DSTHASH; } 57241edb306SCy Schubert ; 57341edb306SCy Schubert 57441edb306SCy Schubert weighting: 57541edb306SCy Schubert IPT_CONNECTION { $$ = IPLDP_CONNECTION; } 57641edb306SCy Schubert ; 57741edb306SCy Schubert %% 57841edb306SCy Schubert static wordtab_t yywords[] = { 57941edb306SCy Schubert { "all", IPT_ALL }, 58041edb306SCy Schubert { "auth", IPT_AUTH }, 58141edb306SCy Schubert { "connection", IPT_CONNECTION }, 58241edb306SCy Schubert { "count", IPT_COUNT }, 58341edb306SCy Schubert { "dst-hash", IPT_DSTHASH }, 58441edb306SCy Schubert { "dstlist", IPT_DSTLIST }, 58541edb306SCy Schubert { "file", IPT_FILE }, 58641edb306SCy Schubert { "group", IPT_GROUP }, 58741edb306SCy Schubert { "group-map", IPT_GROUPMAP }, 58841edb306SCy Schubert { "hash", IPT_HASH }, 58941edb306SCy Schubert { "in", IPT_IN }, 59041edb306SCy Schubert { "ipf", IPT_IPF }, 59141edb306SCy Schubert { "name", IPT_NAME }, 59241edb306SCy Schubert { "nat", IPT_NAT }, 59341edb306SCy Schubert { "number", IPT_NUM }, 59441edb306SCy Schubert { "out", IPT_OUT }, 59541edb306SCy Schubert { "policy", IPT_POLICY }, 59641edb306SCy Schubert { "pool", IPT_POOL }, 59741edb306SCy Schubert { "random", IPT_RANDOM }, 59841edb306SCy Schubert { "round-robin", IPT_ROUNDROBIN }, 59941edb306SCy Schubert { "role", IPT_ROLE }, 60041edb306SCy Schubert { "seed", IPT_SEED }, 60141edb306SCy Schubert { "size", IPT_SIZE }, 60241edb306SCy Schubert { "src-hash", IPT_SRCHASH }, 60341edb306SCy Schubert { "table", IPT_TABLE }, 60441edb306SCy Schubert { "tree", IPT_TREE }, 60541edb306SCy Schubert { "type", IPT_TYPE }, 60641edb306SCy Schubert { "weighted", IPT_WEIGHTED }, 60741edb306SCy Schubert { "whois", IPT_WHOIS }, 60841edb306SCy Schubert { NULL, 0 } 60941edb306SCy Schubert }; 61041edb306SCy Schubert 61141edb306SCy Schubert 612efeb8bffSCy Schubert int 613efeb8bffSCy Schubert ippool_parsefile(int fd, char *filename, ioctlfunc_t iocfunc) 61441edb306SCy Schubert { 61541edb306SCy Schubert FILE *fp = NULL; 61641edb306SCy Schubert char *s; 61741edb306SCy Schubert 61841edb306SCy Schubert yylineNum = 1; 61941edb306SCy Schubert (void) yysettab(yywords); 62041edb306SCy Schubert 62141edb306SCy Schubert s = getenv("YYDEBUG"); 62241edb306SCy Schubert if (s) 62341edb306SCy Schubert yydebug = atoi(s); 62441edb306SCy Schubert else 62541edb306SCy Schubert yydebug = 0; 62641edb306SCy Schubert 62741edb306SCy Schubert if (strcmp(filename, "-")) { 62841edb306SCy Schubert fp = fopen(filename, "r"); 62941edb306SCy Schubert if (!fp) { 63041edb306SCy Schubert fprintf(stderr, "fopen(%s) failed: %s\n", filename, 63141edb306SCy Schubert STRERROR(errno)); 632*2582ae57SCy Schubert return(-1); 63341edb306SCy Schubert } 63441edb306SCy Schubert } else 63541edb306SCy Schubert fp = stdin; 63641edb306SCy Schubert 63741edb306SCy Schubert while (ippool_parsesome(fd, fp, iocfunc) == 1) 63841edb306SCy Schubert ; 63941edb306SCy Schubert if (fp != NULL) 64041edb306SCy Schubert fclose(fp); 641*2582ae57SCy Schubert return(0); 64241edb306SCy Schubert } 64341edb306SCy Schubert 64441edb306SCy Schubert 645efeb8bffSCy Schubert int 646efeb8bffSCy Schubert ippool_parsesome(int fd, FILE *fp, ioctlfunc_t iocfunc) 64741edb306SCy Schubert { 64841edb306SCy Schubert char *s; 64941edb306SCy Schubert int i; 65041edb306SCy Schubert 65141edb306SCy Schubert poolioctl = iocfunc; 65241edb306SCy Schubert 65341edb306SCy Schubert if (feof(fp)) 654*2582ae57SCy Schubert return(0); 65541edb306SCy Schubert i = fgetc(fp); 65641edb306SCy Schubert if (i == EOF) 657*2582ae57SCy Schubert return(0); 65841edb306SCy Schubert if (ungetc(i, fp) == EOF) 659*2582ae57SCy Schubert return(0); 66041edb306SCy Schubert if (feof(fp)) 661*2582ae57SCy Schubert return(0); 66241edb306SCy Schubert s = getenv("YYDEBUG"); 66341edb306SCy Schubert if (s) 66441edb306SCy Schubert yydebug = atoi(s); 66541edb306SCy Schubert else 66641edb306SCy Schubert yydebug = 0; 66741edb306SCy Schubert 66841edb306SCy Schubert yyin = fp; 66941edb306SCy Schubert yyparse(); 670*2582ae57SCy Schubert return(1); 67141edb306SCy Schubert } 67241edb306SCy Schubert 67341edb306SCy Schubert 67441edb306SCy Schubert static iphtent_t * 675efeb8bffSCy Schubert add_htablehosts(char *url) 67641edb306SCy Schubert { 67741edb306SCy Schubert iphtent_t *htop, *hbot, *h; 67841edb306SCy Schubert alist_t *a, *hlist; 67941edb306SCy Schubert 68041edb306SCy Schubert if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 68141edb306SCy Schubert hlist = load_url(url); 68241edb306SCy Schubert } else { 68341edb306SCy Schubert use_inet6 = 0; 68441edb306SCy Schubert 68541edb306SCy Schubert hlist = calloc(1, sizeof(*hlist)); 68641edb306SCy Schubert if (hlist == NULL) 687*2582ae57SCy Schubert return(NULL); 68841edb306SCy Schubert 68941edb306SCy Schubert if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 69041edb306SCy Schubert yyerror("Unknown hostname"); 69141edb306SCy Schubert } 69241edb306SCy Schubert } 69341edb306SCy Schubert 69441edb306SCy Schubert hbot = NULL; 69541edb306SCy Schubert htop = NULL; 69641edb306SCy Schubert 69741edb306SCy Schubert for (a = hlist; a != NULL; a = a->al_next) { 69841edb306SCy Schubert h = calloc(1, sizeof(*h)); 69941edb306SCy Schubert if (h == NULL) 70041edb306SCy Schubert break; 70141edb306SCy Schubert 70241edb306SCy Schubert h->ipe_family = a->al_family; 70341edb306SCy Schubert h->ipe_addr = a->al_i6addr; 70441edb306SCy Schubert h->ipe_mask = a->al_i6mask; 70541edb306SCy Schubert 70641edb306SCy Schubert if (hbot != NULL) 70741edb306SCy Schubert hbot->ipe_next = h; 70841edb306SCy Schubert else 70941edb306SCy Schubert htop = h; 71041edb306SCy Schubert hbot = h; 71141edb306SCy Schubert } 71241edb306SCy Schubert 71341edb306SCy Schubert alist_free(hlist); 71441edb306SCy Schubert 715*2582ae57SCy Schubert return(htop); 71641edb306SCy Schubert } 71741edb306SCy Schubert 71841edb306SCy Schubert 71941edb306SCy Schubert static ip_pool_node_t * 720efeb8bffSCy Schubert add_poolhosts(char *url) 72141edb306SCy Schubert { 72241edb306SCy Schubert ip_pool_node_t *ptop, *pbot, *p; 72341edb306SCy Schubert alist_t *a, *hlist; 72441edb306SCy Schubert 72541edb306SCy Schubert if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 72641edb306SCy Schubert hlist = load_url(url); 72741edb306SCy Schubert } else { 72841edb306SCy Schubert use_inet6 = 0; 72941edb306SCy Schubert 73041edb306SCy Schubert hlist = calloc(1, sizeof(*hlist)); 73141edb306SCy Schubert if (hlist == NULL) 732*2582ae57SCy Schubert return(NULL); 73341edb306SCy Schubert 73441edb306SCy Schubert if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 73541edb306SCy Schubert yyerror("Unknown hostname"); 73641edb306SCy Schubert } 73741edb306SCy Schubert } 73841edb306SCy Schubert 73941edb306SCy Schubert pbot = NULL; 74041edb306SCy Schubert ptop = NULL; 74141edb306SCy Schubert 74241edb306SCy Schubert for (a = hlist; a != NULL; a = a->al_next) { 74341edb306SCy Schubert p = calloc(1, sizeof(*p)); 74441edb306SCy Schubert if (p == NULL) 74541edb306SCy Schubert break; 74641edb306SCy Schubert p->ipn_mask.adf_addr = a->al_i6mask; 74741edb306SCy Schubert 74841edb306SCy Schubert if (a->al_family == AF_INET) { 74941edb306SCy Schubert p->ipn_addr.adf_family = AF_INET; 75041edb306SCy Schubert #ifdef USE_INET6 75141edb306SCy Schubert } else if (a->al_family == AF_INET6) { 75241edb306SCy Schubert p->ipn_addr.adf_family = AF_INET6; 75341edb306SCy Schubert #endif 75441edb306SCy Schubert } 75541edb306SCy Schubert setadflen(&p->ipn_addr); 75641edb306SCy Schubert p->ipn_addr.adf_addr = a->al_i6addr; 75741edb306SCy Schubert p->ipn_info = a->al_not; 75841edb306SCy Schubert p->ipn_mask.adf_len = p->ipn_addr.adf_len; 75941edb306SCy Schubert 76041edb306SCy Schubert if (pbot != NULL) 76141edb306SCy Schubert pbot->ipn_next = p; 76241edb306SCy Schubert else 76341edb306SCy Schubert ptop = p; 76441edb306SCy Schubert pbot = p; 76541edb306SCy Schubert } 76641edb306SCy Schubert 76741edb306SCy Schubert alist_free(hlist); 76841edb306SCy Schubert 769*2582ae57SCy Schubert return(ptop); 77041edb306SCy Schubert } 77141edb306SCy Schubert 77241edb306SCy Schubert 77341edb306SCy Schubert ip_pool_node_t * 774efeb8bffSCy Schubert read_whoisfile(char *file) 77541edb306SCy Schubert { 77641edb306SCy Schubert ip_pool_node_t *ntop, *ipn, node, *last; 77741edb306SCy Schubert char line[1024]; 77841edb306SCy Schubert FILE *fp; 77941edb306SCy Schubert 78041edb306SCy Schubert fp = fopen(file, "r"); 78141edb306SCy Schubert if (fp == NULL) 782*2582ae57SCy Schubert return(NULL); 78341edb306SCy Schubert 78441edb306SCy Schubert last = NULL; 78541edb306SCy Schubert ntop = NULL; 78641edb306SCy Schubert while (fgets(line, sizeof(line) - 1, fp) != NULL) { 78741edb306SCy Schubert line[sizeof(line) - 1] = '\0'; 78841edb306SCy Schubert 78941edb306SCy Schubert if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask)) 79041edb306SCy Schubert continue; 79141edb306SCy Schubert ipn = calloc(1, sizeof(*ipn)); 79241edb306SCy Schubert if (ipn == NULL) 79341edb306SCy Schubert continue; 79441edb306SCy Schubert ipn->ipn_addr = node.ipn_addr; 79541edb306SCy Schubert ipn->ipn_mask = node.ipn_mask; 79641edb306SCy Schubert if (last == NULL) 79741edb306SCy Schubert ntop = ipn; 79841edb306SCy Schubert else 79941edb306SCy Schubert last->ipn_next = ipn; 80041edb306SCy Schubert last = ipn; 80141edb306SCy Schubert } 80241edb306SCy Schubert fclose(fp); 803*2582ae57SCy Schubert return(ntop); 80441edb306SCy Schubert } 80541edb306SCy Schubert 80641edb306SCy Schubert 80741edb306SCy Schubert static void 808efeb8bffSCy Schubert setadflen(addrfamily_t *afp) 80941edb306SCy Schubert { 81041edb306SCy Schubert afp->adf_len = offsetof(addrfamily_t, adf_addr); 81141edb306SCy Schubert switch (afp->adf_family) 81241edb306SCy Schubert { 81341edb306SCy Schubert case AF_INET : 81441edb306SCy Schubert afp->adf_len += sizeof(struct in_addr); 81541edb306SCy Schubert break; 81641edb306SCy Schubert #ifdef USE_INET6 81741edb306SCy Schubert case AF_INET6 : 81841edb306SCy Schubert afp->adf_len += sizeof(struct in6_addr); 81941edb306SCy Schubert break; 82041edb306SCy Schubert #endif 82141edb306SCy Schubert default : 82241edb306SCy Schubert break; 82341edb306SCy Schubert } 82441edb306SCy Schubert } 825