]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ipfilter/tools/ippool_y.y
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.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 #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
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
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 *
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 *
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 *
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
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 }