1 /*	$FreeBSD$	*/
2 
3 /*
4  * Copyright (C) 2012 by Darren Reed.
5  *
6  * See the IPFILTER.LICENCE file for details on licencing.
7  */
8 %{
9 #include <sys/types.h>
10 #include <sys/time.h>
11 #include <sys/param.h>
12 #include <sys/socket.h>
13 # include <sys/cdefs.h>
14 #include <sys/ioctl.h>
15 
16 #include <net/if.h>
17 #include <netinet/in.h>
18 
19 #include <arpa/inet.h>
20 
21 #include <stdio.h>
22 #include <fcntl.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <netdb.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 
29 #include "ipf.h"
30 #include "netinet/ip_lookup.h"
31 #include "netinet/ip_pool.h"
32 #include "netinet/ip_htable.h"
33 #include "netinet/ip_dstlist.h"
34 #include "ippool_l.h"
35 #include "kmem.h"
36 
37 #define	YYDEBUG	1
38 #define	YYSTACKSIZE	0x00ffffff
39 
40 extern	int	yyparse __P((void));
41 extern	int	yydebug;
42 extern	FILE	*yyin;
43 
44 static	iphtable_t	ipht;
45 static	iphtent_t	iphte;
46 static	ip_pool_t	iplo;
47 static	ippool_dst_t	ipld;
48 static	ioctlfunc_t	poolioctl = NULL;
49 static	char		poolname[FR_GROUPLEN];
50 
51 static iphtent_t *add_htablehosts __P((char *));
52 static ip_pool_node_t *add_poolhosts __P((char *));
53 static ip_pool_node_t *read_whoisfile __P((char *));
54 static void setadflen __P((addrfamily_t *));
55 
56 %}
57 
58 %union	{
59 	char	*str;
60 	u_32_t	num;
61 	struct	in_addr	ip4;
62 	struct	alist_s	*alist;
63 	addrfamily_t	adrmsk[2];
64 	iphtent_t	*ipe;
65 	ip_pool_node_t	*ipp;
66 	ipf_dstnode_t	*ipd;
67 	addrfamily_t	ipa;
68 	i6addr_t	ip6;
69 }
70 
71 %token  <num>	YY_NUMBER YY_HEX
72 %token  <str>	YY_STR
73 %token  <ip6>	YY_IPV6
74 %token	YY_COMMENT
75 %token	YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
76 %token	YY_RANGE_OUT YY_RANGE_IN
77 %token	IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT IPT_ALL
78 %token	IPT_TABLE IPT_GROUPMAP IPT_HASH IPT_SRCHASH IPT_DSTHASH
79 %token	IPT_ROLE IPT_TYPE IPT_TREE
80 %token	IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME IPT_POLICY
81 %token	IPT_POOL IPT_DSTLIST IPT_ROUNDROBIN
82 %token	IPT_WEIGHTED IPT_RANDOM IPT_CONNECTION
83 %token	IPT_WHOIS IPT_FILE
84 %type	<num> role table inout unit dstopts weighting
85 %type	<ipp> ipftree range addrlist
86 %type	<adrmsk> addrmask
87 %type	<ipe> ipfgroup ipfhash hashlist hashentry
88 %type	<ipe> groupentry setgrouplist grouplist
89 %type	<ipa> ipaddr mask
90 %type	<ip4> ipv4
91 %type	<str> number setgroup name
92 %type	<ipd> dstentry dstentries dstlist
93 
94 %%
95 file:	line
96 	| assign
97 	| file line
98 	| file assign
99 	;
100 
101 line:	table role ipftree eol		{ ip_pool_node_t *n;
102 					  iplo.ipo_unit = $2;
103 					  iplo.ipo_list = $3;
104 					  load_pool(&iplo, poolioctl);
105 					  while ((n = $3) != NULL) {
106 						$3 = n->ipn_next;
107 						free(n);
108 					  }
109 					  resetlexer();
110 					  use_inet6 = 0;
111 					}
112 	| table role ipfhash eol	{ iphtent_t *h;
113 					  ipht.iph_unit = $2;
114 					  ipht.iph_type = IPHASH_LOOKUP;
115 					  load_hash(&ipht, $3, poolioctl);
116 					  while ((h = $3) != NULL) {
117 						$3 = h->ipe_next;
118 						free(h);
119 					  }
120 					  resetlexer();
121 					  use_inet6 = 0;
122 					}
123 	| groupmap role number ipfgroup eol
124 					{ iphtent_t *h;
125 					  ipht.iph_unit = $2;
126 					  strncpy(ipht.iph_name, $3,
127 						  sizeof(ipht.iph_name));
128 					  ipht.iph_type = IPHASH_GROUPMAP;
129 					  load_hash(&ipht, $4, poolioctl);
130 					  while ((h = $4) != NULL) {
131 						$4 = h->ipe_next;
132 						free(h);
133 					  }
134 					  resetlexer();
135 					  use_inet6 = 0;
136 					}
137 	| YY_COMMENT
138 	| poolline eol
139 	;
140 
141 eol:	';'
142 	;
143 
144 assign:	YY_STR assigning YY_STR ';'	{ set_variable($1, $3);
145 					  resetlexer();
146 					  free($1);
147 					  free($3);
148 					  yyvarnext = 0;
149 					}
150 	;
151 
152 assigning:
153 	'='				{ yyvarnext = 1; }
154 	;
155 
156 table:	IPT_TABLE		{ bzero((char *)&ipht, sizeof(ipht));
157 				  bzero((char *)&iphte, sizeof(iphte));
158 				  bzero((char *)&iplo, sizeof(iplo));
159 				  bzero((char *)&ipld, sizeof(ipld));
160 				  *ipht.iph_name = '\0';
161 				  iplo.ipo_flags = IPHASH_ANON;
162 				  iplo.ipo_name[0] = '\0';
163 				}
164 	;
165 
166 groupmap:
167 	IPT_GROUPMAP inout	{ bzero((char *)&ipht, sizeof(ipht));
168 				  bzero((char *)&iphte, sizeof(iphte));
169 				  *ipht.iph_name = '\0';
170 				  ipht.iph_unit = IPHASH_GROUPMAP;
171 				  ipht.iph_flags = $2;
172 				}
173 	;
174 
175 inout:	IPT_IN				{ $$ = FR_INQUE; }
176 	| IPT_OUT			{ $$ = FR_OUTQUE; }
177 	;
178 
179 role:	IPT_ROLE '=' unit		{ $$ = $3; }
180 	;
181 
182 unit:	IPT_IPF				{ $$ = IPL_LOGIPF; }
183 	| IPT_NAT			{ $$ = IPL_LOGNAT; }
184 	| IPT_AUTH			{ $$ = IPL_LOGAUTH; }
185 	| IPT_COUNT			{ $$ = IPL_LOGCOUNT; }
186 	| IPT_ALL			{ $$ = IPL_LOGALL; }
187 	;
188 
189 ipftree:
190 	IPT_TYPE '=' IPT_TREE number start addrlist end
191 					{ strncpy(iplo.ipo_name, $4,
192 						  sizeof(iplo.ipo_name));
193 					  $$ = $6;
194 					}
195 	;
196 
197 ipfhash:
198 	IPT_TYPE '=' IPT_HASH number hashopts start hashlist end
199 					{ strncpy(ipht.iph_name, $4,
200 						  sizeof(ipht.iph_name));
201 					  $$ = $7;
202 					}
203 	;
204 
205 ipfgroup:
206 	setgroup hashopts start grouplist end
207 					{ iphtent_t *e;
208 					  for (e = $4; e != NULL;
209 					       e = e->ipe_next)
210 						if (e->ipe_group[0] == '\0')
211 							strncpy(e->ipe_group,
212 								$1,
213 								FR_GROUPLEN);
214 					  $$ = $4;
215 					  free($1);
216 					}
217 	| hashopts start setgrouplist end
218 					{ $$ = $3; }
219 	;
220 
221 number:	IPT_NUM '=' YY_NUMBER			{ sprintf(poolname, "%u", $3);
222 						  $$ = poolname;
223 						}
224 	| IPT_NAME '=' YY_STR			{ strncpy(poolname, $3,
225 							  FR_GROUPLEN);
226 						  poolname[FR_GROUPLEN-1]='\0';
227 						  free($3);
228 						  $$ = poolname;
229 						}
230 	|					{ $$ = ""; }
231 	;
232 
233 setgroup:
234 	IPT_GROUP '=' YY_STR		{ char tmp[FR_GROUPLEN+1];
235 					  strncpy(tmp, $3, FR_GROUPLEN);
236 					  $$ = strdup(tmp);
237 					  free($3);
238 					}
239 	| IPT_GROUP '=' YY_NUMBER	{ char tmp[FR_GROUPLEN+1];
240 					  sprintf(tmp, "%u", $3);
241 					  $$ = strdup(tmp);
242 					}
243 	;
244 
245 hashopts:
246 	| size
247 	| seed
248 	| size seed
249 	;
250 
251 addrlist:
252 	';'				{ $$ = NULL; }
253 	| range next addrlist		{ $$ = $1;
254 					  while ($1->ipn_next != NULL)
255 						$1 = $1->ipn_next;
256 					  $1->ipn_next = $3;
257 					}
258 	| range next			{ $$ = $1; }
259 	;
260 
261 grouplist:
262 	';'				{ $$ = NULL; }
263 	| groupentry next grouplist	{ $$ = $1; $1->ipe_next = $3; }
264 	| addrmask next grouplist	{ $$ = calloc(1, sizeof(iphtent_t));
265 					  $$->ipe_addr = $1[0].adf_addr;
266 					  $$->ipe_mask = $1[1].adf_addr;
267 					  $$->ipe_family = $1[0].adf_family;
268 					  $$->ipe_next = $3;
269 					}
270 	| groupentry next		{ $$ = $1; }
271 	| addrmask next			{ $$ = calloc(1, sizeof(iphtent_t));
272 					  $$->ipe_addr = $1[0].adf_addr;
273 					  $$->ipe_mask = $1[1].adf_addr;
274 #ifdef USE_INET6
275 					  if (use_inet6)
276 						$$->ipe_family = AF_INET6;
277 					  else
278 #endif
279 						$$->ipe_family = AF_INET;
280 					}
281 	| YY_STR			{ $$ = add_htablehosts($1);
282 					  free($1);
283 					}
284 	;
285 
286 setgrouplist:
287 	';'				{ $$ = NULL; }
288 	| groupentry next		{ $$ = $1; }
289 	| groupentry next setgrouplist	{ $1->ipe_next = $3; $$ = $1; }
290 	;
291 
292 groupentry:
293 	addrmask ',' setgroup		{ $$ = calloc(1, sizeof(iphtent_t));
294 					  $$->ipe_addr = $1[0].adf_addr;
295 					  $$->ipe_mask = $1[1].adf_addr;
296 					  strncpy($$->ipe_group, $3,
297 						  FR_GROUPLEN);
298 #ifdef USE_INET6
299 					  if (use_inet6)
300 						$$->ipe_family = AF_INET6;
301 					  else
302 #endif
303 						$$->ipe_family = AF_INET;
304 					  free($3);
305 					}
306 	;
307 
308 range:	addrmask			{ $$ = calloc(1, sizeof(*$$));
309 					  $$->ipn_info = 0;
310 					  $$->ipn_addr = $1[0];
311 					  $$->ipn_mask = $1[1];
312 					}
313 	| '!' addrmask			{ $$ = calloc(1, sizeof(*$$));
314 					  $$->ipn_info = 1;
315 					  $$->ipn_addr = $2[0];
316 					  $$->ipn_mask = $2[1];
317 					}
318 	| YY_STR			{ $$ = add_poolhosts($1);
319 					  free($1);
320 					}
321 	| IPT_WHOIS IPT_FILE YY_STR	{ $$ = read_whoisfile($3);
322 					  free($3);
323 					}
324 	;
325 
326 hashlist:
327 	';'				{ $$ = NULL; }
328 	| hashentry next		{ $$ = $1; }
329 	| hashentry next hashlist	{ $1->ipe_next = $3; $$ = $1; }
330 	;
331 
332 hashentry:
333 	addrmask 		{ $$ = calloc(1, sizeof(iphtent_t));
334 				  $$->ipe_addr = $1[0].adf_addr;
335 				  $$->ipe_mask = $1[1].adf_addr;
336 #ifdef USE_INET6
337 				  if (use_inet6)
338 					$$->ipe_family = AF_INET6;
339 				  else
340 #endif
341 					$$->ipe_family = AF_INET;
342 				}
343 	| YY_STR		{ $$ = add_htablehosts($1);
344 				  free($1);
345 				}
346 	;
347 
348 addrmask:
349 	ipaddr '/' mask		{ $$[0] = $1;
350 				  setadflen(&$$[0]);
351 				  $$[1] = $3;
352 				  $$[1].adf_len = $$[0].adf_len;
353 				}
354 	| ipaddr		{ $$[0] = $1;
355 				  setadflen(&$$[1]);
356 				  $$[1].adf_len = $$[0].adf_len;
357 #ifdef USE_INET6
358 				  if (use_inet6)
359 					memset(&$$[1].adf_addr, 0xff,
360 					       sizeof($$[1].adf_addr.in6));
361 				  else
362 #endif
363 					memset(&$$[1].adf_addr, 0xff,
364 					       sizeof($$[1].adf_addr.in4));
365 				}
366 	;
367 
368 ipaddr:	ipv4			{ $$.adf_addr.in4 = $1;
369 				  $$.adf_family = AF_INET;
370 				  setadflen(&$$);
371 				  use_inet6 = 0;
372 				}
373 	| YY_NUMBER		{ $$.adf_addr.in4.s_addr = htonl($1);
374 				  $$.adf_family = AF_INET;
375 				  setadflen(&$$);
376 				  use_inet6 = 0;
377 				}
378 	| YY_IPV6		{ $$.adf_addr = $1;
379 				  $$.adf_family = AF_INET6;
380 				  setadflen(&$$);
381 				  use_inet6 = 1;
382 				}
383 	;
384 
385 mask:	YY_NUMBER	{ bzero(&$$, sizeof($$));
386 			  if (use_inet6) {
387 				if (ntomask(AF_INET6, $1,
388 					    (u_32_t *)&$$.adf_addr) == -1)
389 					yyerror("bad bitmask");
390 			  } else {
391 				if (ntomask(AF_INET, $1,
392 					    (u_32_t *)&$$.adf_addr.in4) == -1)
393 					yyerror("bad bitmask");
394 			  }
395 			}
396 	| ipv4		{ bzero(&$$, sizeof($$));
397 			  $$.adf_addr.in4 = $1;
398 			}
399 	| YY_IPV6	{ bzero(&$$, sizeof($$));
400 			  $$.adf_addr = $1;
401 			}
402 	;
403 
404 size:	IPT_SIZE '=' YY_NUMBER		{ ipht.iph_size = $3; }
405 	;
406 
407 seed:	IPT_SEED '=' YY_NUMBER		{ ipht.iph_seed = $3; }
408 	;
409 
410 ipv4:	YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
411 		{ if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
412 			yyerror("Invalid octet string for IP address");
413 			return 0;
414 		  }
415 		  $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
416 		  $$.s_addr = htonl($$.s_addr);
417 		}
418 	;
419 
420 next:	';'				{ yyexpectaddr = 1; }
421 	;
422 
423 start:	'{'				{ yyexpectaddr = 1; }
424 	;
425 
426 end:	'}'				{ yyexpectaddr = 0; }
427 	;
428 
429 poolline:
430 	IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')'
431 	start dstlist end
432 					{ bzero((char *)&ipld, sizeof(ipld));
433 					  strncpy(ipld.ipld_name, $6,
434 						  sizeof(ipld.ipld_name));
435 					  ipld.ipld_unit = $2;
436 					  ipld.ipld_policy = $8;
437 					  load_dstlist(&ipld, poolioctl, $11);
438 					  resetlexer();
439 					  use_inet6 = 0;
440 					  free($6);
441 					}
442 	| IPT_POOL unit '/' IPT_TREE '(' name ';' ')'
443 	  start addrlist end
444 					{ bzero((char *)&iplo, sizeof(iplo));
445 					  strncpy(iplo.ipo_name, $6,
446 						  sizeof(iplo.ipo_name));
447 					  iplo.ipo_list = $10;
448 					  iplo.ipo_unit = $2;
449 					  load_pool(&iplo, poolioctl);
450 					  resetlexer();
451 					  use_inet6 = 0;
452 					  free($6);
453 					}
454 	| IPT_POOL '(' name ';' ')' start addrlist end
455 					{ bzero((char *)&iplo, sizeof(iplo));
456 					  strncpy(iplo.ipo_name, $3,
457 						  sizeof(iplo.ipo_name));
458 					  iplo.ipo_list = $7;
459 					  iplo.ipo_unit = IPL_LOGALL;
460 					  load_pool(&iplo, poolioctl);
461 					  resetlexer();
462 					  use_inet6 = 0;
463 					  free($3);
464 					}
465 	| IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')'
466 	  start hashlist end
467 					{ iphtent_t *h;
468 					  bzero((char *)&ipht, sizeof(ipht));
469 					  strncpy(ipht.iph_name, $6,
470 						  sizeof(ipht.iph_name));
471 					  ipht.iph_unit = $2;
472 					  load_hash(&ipht, $11, poolioctl);
473 					  while ((h = ipht.iph_list) != NULL) {
474 						ipht.iph_list = h->ipe_next;
475 						free(h);
476 					  }
477 					  resetlexer();
478 					  use_inet6 = 0;
479 					  free($6);
480 					}
481 	| IPT_GROUPMAP '(' name ';' inout ';' ')'
482 	  start setgrouplist end
483 					{ iphtent_t *h;
484 					  bzero((char *)&ipht, sizeof(ipht));
485 					  strncpy(ipht.iph_name, $3,
486 						  sizeof(ipht.iph_name));
487 					  ipht.iph_type = IPHASH_GROUPMAP;
488 					  ipht.iph_unit = IPL_LOGIPF;
489 					  ipht.iph_flags = $5;
490 					  load_hash(&ipht, $9, poolioctl);
491 					  while ((h = ipht.iph_list) != NULL) {
492 						ipht.iph_list = h->ipe_next;
493 						free(h);
494 					  }
495 					  resetlexer();
496 					  use_inet6 = 0;
497 					  free($3);
498 					}
499 	;
500 
501 name:	IPT_NAME YY_STR			{ $$ = $2; }
502 	| IPT_NUM YY_NUMBER		{ char name[80];
503 					  sprintf(name, "%d", $2);
504 					  $$ = strdup(name);
505 					}
506 	;
507 
508 hashoptlist:
509 	| hashopt ';'
510 	| hashoptlist ';' hashopt ';'
511 	;
512 hashopt:
513 	IPT_SIZE YY_NUMBER
514 	| IPT_SEED YY_NUMBER
515 	;
516 
517 dstlist:
518 	dstentries			{ $$ = $1; }
519 	| ';'				{ $$ = NULL; }
520 	;
521 
522 dstentries:
523 	dstentry next			{ $$ = $1; }
524 	| dstentry next dstentries	{ $1->ipfd_next = $3; $$ = $1; }
525 	;
526 
527 dstentry:
528 	YY_STR ':' ipaddr	{ int size = sizeof(*$$) + strlen($1) + 1;
529 				  $$ = calloc(1, size);
530 				  if ($$ != NULL) {
531 					$$->ipfd_dest.fd_name = strlen($1) + 1;
532 					bcopy($1, $$->ipfd_names,
533 					      $$->ipfd_dest.fd_name);
534 					$$->ipfd_dest.fd_addr = $3;
535 					$$->ipfd_size = size;
536 				  }
537 				  free($1);
538 				}
539 	| ipaddr		{ $$ = calloc(1, sizeof(*$$));
540 				  if ($$ != NULL) {
541 					$$->ipfd_dest.fd_name = -1;
542 					$$->ipfd_dest.fd_addr = $1;
543 					$$->ipfd_size = sizeof(*$$);
544 				  }
545 				}
546 	;
547 
548 dstopts:
549 						{ $$ = IPLDP_NONE; }
550 	| IPT_POLICY IPT_ROUNDROBIN ';'		{ $$ = IPLDP_ROUNDROBIN; }
551 	| IPT_POLICY IPT_WEIGHTED weighting ';'	{ $$ = $3; }
552 	| IPT_POLICY IPT_RANDOM ';'		{ $$ = IPLDP_RANDOM; }
553 	| IPT_POLICY IPT_HASH ';'		{ $$ = IPLDP_HASHED; }
554 	| IPT_POLICY IPT_SRCHASH ';'		{ $$ = IPLDP_SRCHASH; }
555 	| IPT_POLICY IPT_DSTHASH ';'		{ $$ = IPLDP_DSTHASH; }
556 	;
557 
558 weighting:
559 	IPT_CONNECTION				{ $$ = IPLDP_CONNECTION; }
560 	;
561 %%
562 static	wordtab_t	yywords[] = {
563 	{ "all",		IPT_ALL },
564 	{ "auth",		IPT_AUTH },
565 	{ "connection",		IPT_CONNECTION },
566 	{ "count",		IPT_COUNT },
567 	{ "dst-hash",		IPT_DSTHASH },
568 	{ "dstlist",		IPT_DSTLIST },
569 	{ "file",		IPT_FILE },
570 	{ "group",		IPT_GROUP },
571 	{ "group-map",		IPT_GROUPMAP },
572 	{ "hash",		IPT_HASH },
573 	{ "in",			IPT_IN },
574 	{ "ipf",		IPT_IPF },
575 	{ "name",		IPT_NAME },
576 	{ "nat",		IPT_NAT },
577 	{ "number",		IPT_NUM },
578 	{ "out",		IPT_OUT },
579 	{ "policy",		IPT_POLICY },
580 	{ "pool",		IPT_POOL },
581 	{ "random",		IPT_RANDOM },
582 	{ "round-robin",	IPT_ROUNDROBIN },
583 	{ "role",		IPT_ROLE },
584 	{ "seed",		IPT_SEED },
585 	{ "size",		IPT_SIZE },
586 	{ "src-hash",		IPT_SRCHASH },
587 	{ "table",		IPT_TABLE },
588 	{ "tree",		IPT_TREE },
589 	{ "type",		IPT_TYPE },
590 	{ "weighted",		IPT_WEIGHTED },
591 	{ "whois",		IPT_WHOIS },
592 	{ NULL,			0 }
593 };
594 
595 
ippool_parsefile(fd,filename,iocfunc)596 int ippool_parsefile(fd, filename, iocfunc)
597 int fd;
598 char *filename;
599 ioctlfunc_t iocfunc;
600 {
601 	FILE *fp = NULL;
602 	char *s;
603 
604 	yylineNum = 1;
605 	(void) yysettab(yywords);
606 
607 	s = getenv("YYDEBUG");
608 	if (s)
609 		yydebug = atoi(s);
610 	else
611 		yydebug = 0;
612 
613 	if (strcmp(filename, "-")) {
614 		fp = fopen(filename, "r");
615 		if (!fp) {
616 			fprintf(stderr, "fopen(%s) failed: %s\n", filename,
617 				STRERROR(errno));
618 			return -1;
619 		}
620 	} else
621 		fp = stdin;
622 
623 	while (ippool_parsesome(fd, fp, iocfunc) == 1)
624 		;
625 	if (fp != NULL)
626 		fclose(fp);
627 	return 0;
628 }
629 
630 
ippool_parsesome(fd,fp,iocfunc)631 int ippool_parsesome(fd, fp, iocfunc)
632 int fd;
633 FILE *fp;
634 ioctlfunc_t iocfunc;
635 {
636 	char *s;
637 	int i;
638 
639 	poolioctl = iocfunc;
640 
641 	if (feof(fp))
642 		return 0;
643 	i = fgetc(fp);
644 	if (i == EOF)
645 		return 0;
646 	if (ungetc(i, fp) == EOF)
647 		return 0;
648 	if (feof(fp))
649 		return 0;
650 	s = getenv("YYDEBUG");
651 	if (s)
652 		yydebug = atoi(s);
653 	else
654 		yydebug = 0;
655 
656 	yyin = fp;
657 	yyparse();
658 	return 1;
659 }
660 
661 
662 static iphtent_t *
add_htablehosts(url)663 add_htablehosts(url)
664 char *url;
665 {
666 	iphtent_t *htop, *hbot, *h;
667 	alist_t *a, *hlist;
668 
669 	if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
670 		hlist = load_url(url);
671 	} else {
672 		use_inet6 = 0;
673 
674 		hlist = calloc(1, sizeof(*hlist));
675 		if (hlist == NULL)
676 			return NULL;
677 
678 		if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
679 			yyerror("Unknown hostname");
680 		}
681 	}
682 
683 	hbot = NULL;
684 	htop = NULL;
685 
686 	for (a = hlist; a != NULL; a = a->al_next) {
687 		h = calloc(1, sizeof(*h));
688 		if (h == NULL)
689 			break;
690 
691 		h->ipe_family = a->al_family;
692 		h->ipe_addr = a->al_i6addr;
693 		h->ipe_mask = a->al_i6mask;
694 
695 		if (hbot != NULL)
696 			hbot->ipe_next = h;
697 		else
698 			htop = h;
699 		hbot = h;
700 	}
701 
702 	alist_free(hlist);
703 
704 	return htop;
705 }
706 
707 
708 static ip_pool_node_t *
add_poolhosts(url)709 add_poolhosts(url)
710 char *url;
711 {
712 	ip_pool_node_t *ptop, *pbot, *p;
713 	alist_t *a, *hlist;
714 
715 	if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
716 		hlist = load_url(url);
717 	} else {
718 		use_inet6 = 0;
719 
720 		hlist = calloc(1, sizeof(*hlist));
721 		if (hlist == NULL)
722 			return NULL;
723 
724 		if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
725 			yyerror("Unknown hostname");
726 		}
727 	}
728 
729 	pbot = NULL;
730 	ptop = NULL;
731 
732 	for (a = hlist; a != NULL; a = a->al_next) {
733 		p = calloc(1, sizeof(*p));
734 		if (p == NULL)
735 			break;
736 		p->ipn_mask.adf_addr = a->al_i6mask;
737 
738 		if (a->al_family == AF_INET) {
739 			p->ipn_addr.adf_family = AF_INET;
740 #ifdef USE_INET6
741 		} else if (a->al_family == AF_INET6) {
742 			p->ipn_addr.adf_family = AF_INET6;
743 #endif
744 		}
745 		setadflen(&p->ipn_addr);
746 		p->ipn_addr.adf_addr = a->al_i6addr;
747 		p->ipn_info = a->al_not;
748 		p->ipn_mask.adf_len = p->ipn_addr.adf_len;
749 
750 		if (pbot != NULL)
751 			pbot->ipn_next = p;
752 		else
753 			ptop = p;
754 		pbot = p;
755 	}
756 
757 	alist_free(hlist);
758 
759 	return ptop;
760 }
761 
762 
763 ip_pool_node_t *
read_whoisfile(file)764 read_whoisfile(file)
765 	char *file;
766 {
767 	ip_pool_node_t *ntop, *ipn, node, *last;
768 	char line[1024];
769 	FILE *fp;
770 
771 	fp = fopen(file, "r");
772 	if (fp == NULL)
773 		return NULL;
774 
775 	last = NULL;
776 	ntop = NULL;
777 	while (fgets(line, sizeof(line) - 1, fp) != NULL) {
778 		line[sizeof(line) - 1] = '\0';
779 
780 		if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask))
781 			continue;
782 		ipn = calloc(1, sizeof(*ipn));
783 		if (ipn == NULL)
784 			continue;
785 		ipn->ipn_addr = node.ipn_addr;
786 		ipn->ipn_mask = node.ipn_mask;
787 		if (last == NULL)
788 			ntop = ipn;
789 		else
790 			last->ipn_next = ipn;
791 		last = ipn;
792 	}
793 	fclose(fp);
794 	return ntop;
795 }
796 
797 
798 static void
setadflen(afp)799 setadflen(afp)
800 	addrfamily_t *afp;
801 {
802 	afp->adf_len = offsetof(addrfamily_t, adf_addr);
803 	switch (afp->adf_family)
804 	{
805 	case AF_INET :
806 		afp->adf_len += sizeof(struct in_addr);
807 		break;
808 #ifdef USE_INET6
809 	case AF_INET6 :
810 		afp->adf_len += sizeof(struct in6_addr);
811 		break;
812 #endif
813 	default :
814 		break;
815 	}
816 }
817