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