]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ipfilter/tools/ippool_y.y
Merge sendmail 8.16.1 to HEAD: See contrib/sendmail/RELEASE_NOTES for details
[FreeBSD/FreeBSD.git] / contrib / ipfilter / tools / ippool_y.y
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 #ifdef USE_INET6
313                                           if (use_inet6)
314                                                 $$->ipn_addr.adf_family =
315                                                         AF_INET6;
316                                           else
317 #endif
318                                                 $$->ipn_addr.adf_family =
319                                                         AF_INET;
320                                         }
321         | '!' addrmask                  { $$ = calloc(1, sizeof(*$$));
322                                           $$->ipn_info = 1;
323                                           $$->ipn_addr = $2[0];
324                                           $$->ipn_mask = $2[1];
325 #ifdef USE_INET6
326                                           if (use_inet6)
327                                                 $$->ipn_addr.adf_family =
328                                                         AF_INET6;
329                                           else
330 #endif
331                                                 $$->ipn_addr.adf_family =
332                                                         AF_INET;
333                                         }
334         | YY_STR                        { $$ = add_poolhosts($1);
335                                           free($1);
336                                         }
337         | IPT_WHOIS IPT_FILE YY_STR     { $$ = read_whoisfile($3);
338                                           free($3);
339                                         }
340         ;
341
342 hashlist:
343         ';'                             { $$ = NULL; }
344         | hashentry next                { $$ = $1; }
345         | hashentry next hashlist       { $1->ipe_next = $3; $$ = $1; }
346         ;
347
348 hashentry:
349         addrmask                { $$ = calloc(1, sizeof(iphtent_t));
350                                   $$->ipe_addr = $1[0].adf_addr;
351                                   $$->ipe_mask = $1[1].adf_addr;
352 #ifdef USE_INET6
353                                   if (use_inet6)
354                                         $$->ipe_family = AF_INET6;
355                                   else
356 #endif
357                                         $$->ipe_family = AF_INET;
358                                 }
359         | YY_STR                { $$ = add_htablehosts($1);
360                                   free($1);
361                                 }
362         ;
363
364 addrmask:
365         ipaddr '/' mask         { $$[0] = $1;
366                                   setadflen(&$$[0]);
367                                   $$[1] = $3;
368                                   $$[1].adf_len = $$[0].adf_len;
369                                 }
370         | ipaddr                { $$[0] = $1;
371                                   setadflen(&$$[1]);
372                                   $$[1].adf_len = $$[0].adf_len;
373 #ifdef USE_INET6
374                                   if (use_inet6)
375                                         memset(&$$[1].adf_addr, 0xff,
376                                                sizeof($$[1].adf_addr.in6));
377                                   else
378 #endif
379                                         memset(&$$[1].adf_addr, 0xff, 
380                                                sizeof($$[1].adf_addr.in4));
381                                 }
382         ;
383
384 ipaddr: ipv4                    { $$.adf_addr.in4 = $1;
385                                   $$.adf_family = AF_INET;
386                                   setadflen(&$$);
387                                   use_inet6 = 0;
388                                 }
389         | YY_NUMBER             { $$.adf_addr.in4.s_addr = htonl($1);
390                                   $$.adf_family = AF_INET;
391                                   setadflen(&$$);
392                                   use_inet6 = 0;
393                                 }
394         | YY_IPV6               { $$.adf_addr = $1;
395                                   $$.adf_family = AF_INET6;
396                                   setadflen(&$$);
397                                   use_inet6 = 1;
398                                 }
399         ;
400
401 mask:   YY_NUMBER       { bzero(&$$, sizeof($$));
402                           if (use_inet6) {
403                                 if (ntomask(AF_INET6, $1,
404                                             (u_32_t *)&$$.adf_addr) == -1)
405                                         yyerror("bad bitmask");
406                           } else {
407                                 if (ntomask(AF_INET, $1,
408                                             (u_32_t *)&$$.adf_addr.in4) == -1)
409                                         yyerror("bad bitmask");
410                           }
411                         }
412         | ipv4          { bzero(&$$, sizeof($$));
413                           $$.adf_addr.in4 = $1;
414                         }
415         | YY_IPV6       { bzero(&$$, sizeof($$));
416                           $$.adf_addr = $1;
417                         }
418         ;
419
420 size:   IPT_SIZE '=' YY_NUMBER          { ipht.iph_size = $3; }
421         ;
422
423 seed:   IPT_SEED '=' YY_NUMBER          { ipht.iph_seed = $3; }
424         ;
425
426 ipv4:   YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
427                 { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
428                         yyerror("Invalid octet string for IP address");
429                         return 0;
430                   }
431                   $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
432                   $$.s_addr = htonl($$.s_addr);
433                 }
434         ;
435
436 next:   ';'                             { yyexpectaddr = 1; }
437         ;
438
439 start:  '{'                             { yyexpectaddr = 1; }
440         ;
441
442 end:    '}'                             { yyexpectaddr = 0; }
443         ;
444
445 poolline:
446         IPT_POOL unit '/' IPT_DSTLIST '(' name ';' dstopts ')'
447         start dstlist end
448                                         { bzero((char *)&ipld, sizeof(ipld));
449                                           strncpy(ipld.ipld_name, $6,
450                                                   sizeof(ipld.ipld_name));
451                                           ipld.ipld_unit = $2;
452                                           ipld.ipld_policy = $8;
453                                           load_dstlist(&ipld, poolioctl, $11);
454                                           resetlexer();
455                                           use_inet6 = 0;
456                                           free($6);
457                                         }
458         | IPT_POOL unit '/' IPT_TREE '(' name ';' ')'
459           start addrlist end
460                                         { bzero((char *)&iplo, sizeof(iplo));
461                                           strncpy(iplo.ipo_name, $6,
462                                                   sizeof(iplo.ipo_name));
463                                           iplo.ipo_list = $10;
464                                           iplo.ipo_unit = $2;
465                                           load_pool(&iplo, poolioctl);
466                                           resetlexer();
467                                           use_inet6 = 0;
468                                           free($6);
469                                         }
470         | IPT_POOL '(' name ';' ')' start addrlist end
471                                         { bzero((char *)&iplo, sizeof(iplo));
472                                           strncpy(iplo.ipo_name, $3,
473                                                   sizeof(iplo.ipo_name));
474                                           iplo.ipo_list = $7;
475                                           iplo.ipo_unit = IPL_LOGALL;
476                                           load_pool(&iplo, poolioctl);
477                                           resetlexer();
478                                           use_inet6 = 0;
479                                           free($3);
480                                         }
481         | IPT_POOL unit '/' IPT_HASH '(' name ';' hashoptlist ')'
482           start hashlist end
483                                         { iphtent_t *h;
484                                           bzero((char *)&ipht, sizeof(ipht));
485                                           strncpy(ipht.iph_name, $6,
486                                                   sizeof(ipht.iph_name));
487                                           ipht.iph_unit = $2;
488                                           load_hash(&ipht, $11, poolioctl);
489                                           while ((h = ipht.iph_list) != NULL) {
490                                                 ipht.iph_list = h->ipe_next;
491                                                 free(h);
492                                           }
493                                           resetlexer();
494                                           use_inet6 = 0;
495                                           free($6);
496                                         }
497         | IPT_GROUPMAP '(' name ';' inout ';' ')'
498           start setgrouplist end
499                                         { iphtent_t *h;
500                                           bzero((char *)&ipht, sizeof(ipht));
501                                           strncpy(ipht.iph_name, $3,
502                                                   sizeof(ipht.iph_name));
503                                           ipht.iph_type = IPHASH_GROUPMAP;
504                                           ipht.iph_unit = IPL_LOGIPF;
505                                           ipht.iph_flags = $5;
506                                           load_hash(&ipht, $9, poolioctl);
507                                           while ((h = ipht.iph_list) != NULL) {
508                                                 ipht.iph_list = h->ipe_next;
509                                                 free(h);
510                                           }
511                                           resetlexer();
512                                           use_inet6 = 0;
513                                           free($3);
514                                         }
515         ;
516
517 name:   IPT_NAME YY_STR                 { $$ = $2; }
518         | IPT_NUM YY_NUMBER             { char name[80];
519                                           sprintf(name, "%d", $2);
520                                           $$ = strdup(name);
521                                         }
522         ;
523
524 hashoptlist:
525         | hashopt ';'
526         | hashoptlist ';' hashopt ';'
527         ;
528 hashopt:
529         IPT_SIZE YY_NUMBER
530         | IPT_SEED YY_NUMBER
531         ;
532
533 dstlist:
534         dstentries                      { $$ = $1; }
535         | ';'                           { $$ = NULL; }
536         ;
537
538 dstentries:
539         dstentry next                   { $$ = $1; }
540         | dstentry next dstentries      { $1->ipfd_next = $3; $$ = $1; }
541         ;
542
543 dstentry:
544         YY_STR ':' ipaddr       { int size = sizeof(*$$) + strlen($1) + 1;
545                                   $$ = calloc(1, size);
546                                   if ($$ != NULL) {
547                                         $$->ipfd_dest.fd_name = strlen($1) + 1;
548                                         bcopy($1, $$->ipfd_names,
549                                               $$->ipfd_dest.fd_name);
550                                         $$->ipfd_dest.fd_addr = $3;
551                                         $$->ipfd_size = size;
552                                   }
553                                   free($1);
554                                 }
555         | ipaddr                { $$ = calloc(1, sizeof(*$$));
556                                   if ($$ != NULL) {
557                                         $$->ipfd_dest.fd_name = -1;
558                                         $$->ipfd_dest.fd_addr = $1;
559                                         $$->ipfd_size = sizeof(*$$);
560                                   }
561                                 }
562         ;
563
564 dstopts:
565                                                 { $$ = IPLDP_NONE; }
566         | IPT_POLICY IPT_ROUNDROBIN ';'         { $$ = IPLDP_ROUNDROBIN; }
567         | IPT_POLICY IPT_WEIGHTED weighting ';' { $$ = $3; }
568         | IPT_POLICY IPT_RANDOM ';'             { $$ = IPLDP_RANDOM; }
569         | IPT_POLICY IPT_HASH ';'               { $$ = IPLDP_HASHED; }
570         | IPT_POLICY IPT_SRCHASH ';'            { $$ = IPLDP_SRCHASH; }
571         | IPT_POLICY IPT_DSTHASH ';'            { $$ = IPLDP_DSTHASH; }
572         ;
573
574 weighting:
575         IPT_CONNECTION                          { $$ = IPLDP_CONNECTION; }
576         ;
577 %%
578 static  wordtab_t       yywords[] = {
579         { "all",                IPT_ALL },
580         { "auth",               IPT_AUTH },
581         { "connection",         IPT_CONNECTION },
582         { "count",              IPT_COUNT },
583         { "dst-hash",           IPT_DSTHASH },
584         { "dstlist",            IPT_DSTLIST },
585         { "file",               IPT_FILE },
586         { "group",              IPT_GROUP },
587         { "group-map",          IPT_GROUPMAP },
588         { "hash",               IPT_HASH },
589         { "in",                 IPT_IN },
590         { "ipf",                IPT_IPF },
591         { "name",               IPT_NAME },
592         { "nat",                IPT_NAT },
593         { "number",             IPT_NUM },
594         { "out",                IPT_OUT },
595         { "policy",             IPT_POLICY },
596         { "pool",               IPT_POOL },
597         { "random",             IPT_RANDOM },
598         { "round-robin",        IPT_ROUNDROBIN },
599         { "role",               IPT_ROLE },
600         { "seed",               IPT_SEED },
601         { "size",               IPT_SIZE },
602         { "src-hash",           IPT_SRCHASH },
603         { "table",              IPT_TABLE },
604         { "tree",               IPT_TREE },
605         { "type",               IPT_TYPE },
606         { "weighted",           IPT_WEIGHTED },
607         { "whois",              IPT_WHOIS },
608         { NULL,                 0 }
609 };
610
611
612 int ippool_parsefile(fd, filename, iocfunc)
613 int fd;
614 char *filename;
615 ioctlfunc_t iocfunc;
616 {
617         FILE *fp = NULL;
618         char *s;
619
620         yylineNum = 1;
621         (void) yysettab(yywords);
622
623         s = getenv("YYDEBUG");
624         if (s)
625                 yydebug = atoi(s);
626         else
627                 yydebug = 0;
628
629         if (strcmp(filename, "-")) {
630                 fp = fopen(filename, "r");
631                 if (!fp) {
632                         fprintf(stderr, "fopen(%s) failed: %s\n", filename,
633                                 STRERROR(errno));
634                         return -1;
635                 }
636         } else
637                 fp = stdin;
638
639         while (ippool_parsesome(fd, fp, iocfunc) == 1)
640                 ;
641         if (fp != NULL)
642                 fclose(fp);
643         return 0;
644 }
645
646
647 int ippool_parsesome(fd, fp, iocfunc)
648 int fd;
649 FILE *fp;
650 ioctlfunc_t iocfunc;
651 {
652         char *s;
653         int i;
654
655         poolioctl = iocfunc;
656
657         if (feof(fp))
658                 return 0;
659         i = fgetc(fp);
660         if (i == EOF)
661                 return 0;
662         if (ungetc(i, fp) == EOF)
663                 return 0;
664         if (feof(fp))
665                 return 0;
666         s = getenv("YYDEBUG");
667         if (s)
668                 yydebug = atoi(s);
669         else
670                 yydebug = 0;
671
672         yyin = fp;
673         yyparse();
674         return 1;
675 }
676
677
678 static iphtent_t *
679 add_htablehosts(url)
680 char *url;
681 {
682         iphtent_t *htop, *hbot, *h;
683         alist_t *a, *hlist;
684
685         if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
686                 hlist = load_url(url);
687         } else {
688                 use_inet6 = 0;
689
690                 hlist = calloc(1, sizeof(*hlist));
691                 if (hlist == NULL)
692                         return NULL;
693
694                 if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
695                         yyerror("Unknown hostname");
696                 }
697         }
698
699         hbot = NULL;
700         htop = NULL;
701
702         for (a = hlist; a != NULL; a = a->al_next) {
703                 h = calloc(1, sizeof(*h));
704                 if (h == NULL)
705                         break;
706
707                 h->ipe_family = a->al_family;
708                 h->ipe_addr = a->al_i6addr;
709                 h->ipe_mask = a->al_i6mask;
710
711                 if (hbot != NULL)
712                         hbot->ipe_next = h;
713                 else
714                         htop = h;
715                 hbot = h;
716         }
717
718         alist_free(hlist);
719
720         return htop;
721 }
722
723
724 static ip_pool_node_t *
725 add_poolhosts(url)
726 char *url;
727 {
728         ip_pool_node_t *ptop, *pbot, *p;
729         alist_t *a, *hlist;
730
731         if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
732                 hlist = load_url(url);
733         } else {
734                 use_inet6 = 0;
735
736                 hlist = calloc(1, sizeof(*hlist));
737                 if (hlist == NULL)
738                         return NULL;
739
740                 if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) {
741                         yyerror("Unknown hostname");
742                 }
743         }
744
745         pbot = NULL;
746         ptop = NULL;
747
748         for (a = hlist; a != NULL; a = a->al_next) {
749                 p = calloc(1, sizeof(*p));
750                 if (p == NULL)
751                         break;
752                 p->ipn_mask.adf_addr = a->al_i6mask;
753
754                 if (a->al_family == AF_INET) {
755                         p->ipn_addr.adf_family = AF_INET;
756 #ifdef USE_INET6
757                 } else if (a->al_family == AF_INET6) {
758                         p->ipn_addr.adf_family = AF_INET6;
759 #endif
760                 }
761                 setadflen(&p->ipn_addr);
762                 p->ipn_addr.adf_addr = a->al_i6addr;
763                 p->ipn_info = a->al_not;
764                 p->ipn_mask.adf_len = p->ipn_addr.adf_len;
765
766                 if (pbot != NULL)
767                         pbot->ipn_next = p;
768                 else
769                         ptop = p;
770                 pbot = p;
771         }
772
773         alist_free(hlist);
774
775         return ptop;
776 }
777
778
779 ip_pool_node_t *
780 read_whoisfile(file)
781         char *file;
782 {
783         ip_pool_node_t *ntop, *ipn, node, *last;
784         char line[1024];
785         FILE *fp;
786
787         fp = fopen(file, "r");
788         if (fp == NULL)
789                 return NULL;
790
791         last = NULL;
792         ntop = NULL;
793         while (fgets(line, sizeof(line) - 1, fp) != NULL) {
794                 line[sizeof(line) - 1] = '\0';
795
796                 if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask))
797                         continue;
798                 ipn = calloc(1, sizeof(*ipn));
799                 if (ipn == NULL)
800                         continue;
801                 ipn->ipn_addr = node.ipn_addr;
802                 ipn->ipn_mask = node.ipn_mask;
803                 if (last == NULL)
804                         ntop = ipn;
805                 else
806                         last->ipn_next = ipn;
807                 last = ipn;
808         }
809         fclose(fp);
810         return ntop;
811 }
812
813
814 static void
815 setadflen(afp)
816         addrfamily_t *afp;
817 {
818         afp->adf_len = offsetof(addrfamily_t, adf_addr);
819         switch (afp->adf_family)
820         {
821         case AF_INET :
822                 afp->adf_len += sizeof(struct in_addr);
823                 break;
824 #ifdef USE_INET6
825         case AF_INET6 :
826                 afp->adf_len += sizeof(struct in6_addr);
827                 break;
828 #endif
829         default :
830                 break;
831         }
832 }