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