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(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(char *); 52 static ip_pool_node_t *add_poolhosts(char *); 53 static ip_pool_node_t *read_whoisfile(char *); 54 static void setadflen(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 { snprintf(poolname, sizeof(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 snprintf(tmp, sizeof(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 snprintf(name, sizeof(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 613 ippool_parsefile(int fd, char *filename, ioctlfunc_t iocfunc) 614 { 615 FILE *fp = NULL; 616 char *s; 617 618 yylineNum = 1; 619 (void) yysettab(yywords); 620 621 s = getenv("YYDEBUG"); 622 if (s) 623 yydebug = atoi(s); 624 else 625 yydebug = 0; 626 627 if (strcmp(filename, "-")) { 628 fp = fopen(filename, "r"); 629 if (!fp) { 630 fprintf(stderr, "fopen(%s) failed: %s\n", filename, 631 STRERROR(errno)); 632 return(-1); 633 } 634 } else 635 fp = stdin; 636 637 while (ippool_parsesome(fd, fp, iocfunc) == 1) 638 ; 639 if (fp != NULL) 640 fclose(fp); 641 return(0); 642 } 643 644 645 int 646 ippool_parsesome(int fd, FILE *fp, ioctlfunc_t iocfunc) 647 { 648 char *s; 649 int i; 650 651 poolioctl = iocfunc; 652 653 if (feof(fp)) 654 return(0); 655 i = fgetc(fp); 656 if (i == EOF) 657 return(0); 658 if (ungetc(i, fp) == EOF) 659 return(0); 660 if (feof(fp)) 661 return(0); 662 s = getenv("YYDEBUG"); 663 if (s) 664 yydebug = atoi(s); 665 else 666 yydebug = 0; 667 668 yyin = fp; 669 yyparse(); 670 return(1); 671 } 672 673 674 static iphtent_t * 675 add_htablehosts(char *url) 676 { 677 iphtent_t *htop, *hbot, *h; 678 alist_t *a, *hlist; 679 680 if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 681 hlist = load_url(url); 682 } else { 683 use_inet6 = 0; 684 685 hlist = calloc(1, sizeof(*hlist)); 686 if (hlist == NULL) 687 return(NULL); 688 689 if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 690 yyerror("Unknown hostname"); 691 } 692 } 693 694 hbot = NULL; 695 htop = NULL; 696 697 for (a = hlist; a != NULL; a = a->al_next) { 698 h = calloc(1, sizeof(*h)); 699 if (h == NULL) 700 break; 701 702 h->ipe_family = a->al_family; 703 h->ipe_addr = a->al_i6addr; 704 h->ipe_mask = a->al_i6mask; 705 706 if (hbot != NULL) 707 hbot->ipe_next = h; 708 else 709 htop = h; 710 hbot = h; 711 } 712 713 alist_free(hlist); 714 715 return(htop); 716 } 717 718 719 static ip_pool_node_t * 720 add_poolhosts(char *url) 721 { 722 ip_pool_node_t *ptop, *pbot, *p; 723 alist_t *a, *hlist; 724 725 if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) { 726 hlist = load_url(url); 727 } else { 728 use_inet6 = 0; 729 730 hlist = calloc(1, sizeof(*hlist)); 731 if (hlist == NULL) 732 return(NULL); 733 734 if (gethost(hlist->al_family, url, &hlist->al_i6addr) == -1) { 735 yyerror("Unknown hostname"); 736 } 737 } 738 739 pbot = NULL; 740 ptop = NULL; 741 742 for (a = hlist; a != NULL; a = a->al_next) { 743 p = calloc(1, sizeof(*p)); 744 if (p == NULL) 745 break; 746 p->ipn_mask.adf_addr = a->al_i6mask; 747 748 if (a->al_family == AF_INET) { 749 p->ipn_addr.adf_family = AF_INET; 750 #ifdef USE_INET6 751 } else if (a->al_family == AF_INET6) { 752 p->ipn_addr.adf_family = AF_INET6; 753 #endif 754 } 755 setadflen(&p->ipn_addr); 756 p->ipn_addr.adf_addr = a->al_i6addr; 757 p->ipn_info = a->al_not; 758 p->ipn_mask.adf_len = p->ipn_addr.adf_len; 759 760 if (pbot != NULL) 761 pbot->ipn_next = p; 762 else 763 ptop = p; 764 pbot = p; 765 } 766 767 alist_free(hlist); 768 769 return(ptop); 770 } 771 772 773 ip_pool_node_t * 774 read_whoisfile(char *file) 775 { 776 ip_pool_node_t *ntop, *ipn, node, *last; 777 char line[1024]; 778 FILE *fp; 779 780 fp = fopen(file, "r"); 781 if (fp == NULL) 782 return(NULL); 783 784 last = NULL; 785 ntop = NULL; 786 while (fgets(line, sizeof(line) - 1, fp) != NULL) { 787 line[sizeof(line) - 1] = '\0'; 788 789 if (parsewhoisline(line, &node.ipn_addr, &node.ipn_mask)) 790 continue; 791 ipn = calloc(1, sizeof(*ipn)); 792 if (ipn == NULL) 793 continue; 794 ipn->ipn_addr = node.ipn_addr; 795 ipn->ipn_mask = node.ipn_mask; 796 if (last == NULL) 797 ntop = ipn; 798 else 799 last->ipn_next = ipn; 800 last = ipn; 801 } 802 fclose(fp); 803 return(ntop); 804 } 805 806 807 static void 808 setadflen(addrfamily_t *afp) 809 { 810 afp->adf_len = offsetof(addrfamily_t, adf_addr); 811 switch (afp->adf_family) 812 { 813 case AF_INET : 814 afp->adf_len += sizeof(struct in_addr); 815 break; 816 #ifdef USE_INET6 817 case AF_INET6 : 818 afp->adf_len += sizeof(struct in6_addr); 819 break; 820 #endif 821 default : 822 break; 823 } 824 } 825