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