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