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