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 45extern int yyparse __P((void)); 46extern int yydebug; 47extern FILE *yyin; 48 49static iphtable_t ipht; 50static iphtent_t iphte; 51static ip_pool_t iplo; 52static ippool_dst_t ipld; 53static ioctlfunc_t poolioctl = NULL; 54static char poolname[FR_GROUPLEN]; 55 56static iphtent_t *add_htablehosts __P((char *)); 57static ip_pool_node_t *add_poolhosts __P((char *)); 58static ip_pool_node_t *read_whoisfile __P((char *)); 59static 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%% 100file: line 101 | assign 102 | file line 103 | file assign 104 ; 105 106line: 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 146eol: ';' 147 ; 148 149assign: YY_STR assigning YY_STR ';' { set_variable($1, $3); 150 resetlexer(); 151 free($1); 152 free($3); 153 yyvarnext = 0; 154 } 155 ; 156 157assigning: 158 '=' { yyvarnext = 1; } 159 ; 160 161table: 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 171groupmap: 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 180inout: IPT_IN { $$ = FR_INQUE; } 181 | IPT_OUT { $$ = FR_OUTQUE; } 182 ; 183 184role: IPT_ROLE '=' unit { $$ = $3; } 185 ; 186 187unit: 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 194ipftree: 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 202ipfhash: 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 210ipfgroup: 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 226number: 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 238setgroup: 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 250hashopts: 251 | size 252 | seed 253 | size seed 254 ; 255 256addrlist: 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 266grouplist: 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 291setgrouplist: 292 ';' { $$ = NULL; } 293 | groupentry next { $$ = $1; } 294 | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; } 295 ; 296 297groupentry: 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 313range: 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 331hashlist: 332 ';' { $$ = NULL; } 333 | hashentry next { $$ = $1; } 334 | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; } 335 ; 336 337hashentry: 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 353addrmask: 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 373ipaddr: 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 390mask: 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 409size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; } 410 ; 411 412seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; } 413 ; 414 415ipv4: 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 425next: ';' { yyexpectaddr = 1; } 426 ; 427 428start: '{' { yyexpectaddr = 1; } 429 ; 430 431end: '}' { yyexpectaddr = 0; } 432 ; 433 434poolline: 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 506name: IPT_NAME YY_STR { $$ = $2; } 507 | IPT_NUM YY_NUMBER { char name[80]; 508 sprintf(name, "%d", $2); 509 $$ = strdup(name); 510 } 511 ; 512 513hashoptlist: 514 | hashopt ';' 515 | hashoptlist ';' hashopt ';' 516 ; 517hashopt: 518 IPT_SIZE YY_NUMBER 519 | IPT_SEED YY_NUMBER 520 ; 521 522dstlist: 523 dstentries { $$ = $1; } 524 | ';' { $$ = NULL; } 525 ; 526 527dstentries: 528 dstentry next { $$ = $1; } 529 | dstentry next dstentries { $1->ipfd_next = $3; $$ = $1; } 530 ; 531 532dstentry: 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 553dstopts: 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 563weighting: 564 IPT_CONNECTION { $$ = IPLDP_CONNECTION; } 565 ; 566%% 567static 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 601int ippool_parsefile(fd, filename, iocfunc) 602int fd; 603char *filename; 604ioctlfunc_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 636int ippool_parsesome(fd, fp, iocfunc) 637int fd; 638FILE *fp; 639ioctlfunc_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 667static iphtent_t * 668add_htablehosts(url) 669char *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 713static ip_pool_node_t * 714add_poolhosts(url) 715char *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 768ip_pool_node_t * 769read_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 803static void 804setadflen(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