ippool.c revision 353081
1/* $FreeBSD: stable/11/contrib/ipfilter/tools/ippool.c 353081 2019-10-04 01:55:03Z cy $ */ 2 3/* 4 * Copyright (C) 2012 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 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# include <nlist.h> 28 29#include "ipf.h" 30#include "netinet/ipl.h" 31#include "netinet/ip_lookup.h" 32#include "netinet/ip_pool.h" 33#include "netinet/ip_htable.h" 34#include "kmem.h" 35 36 37extern int ippool_yyparse __P((void)); 38extern int ippool_yydebug; 39extern FILE *ippool_yyin; 40extern char *optarg; 41extern int lineNum; 42 43void usage __P((char *)); 44int main __P((int, char **)); 45int poolcommand __P((int, int, char *[])); 46int poolnodecommand __P((int, int, char *[])); 47int loadpoolfile __P((int, char *[], char *)); 48int poollist __P((int, char *[])); 49void poollist_dead __P((int, char *, int, char *, char *)); 50void poollist_live __P((int, char *, int, int)); 51int poolflush __P((int, char *[])); 52int poolstats __P((int, char *[])); 53int gettype __P((char *, u_int *)); 54int getrole __P((char *)); 55int setnodeaddr __P((int, int, void *ptr, char *arg)); 56void showpools_live __P((int, int, ipf_pool_stat_t *, char *)); 57void showhashs_live __P((int, int, iphtstat_t *, char *)); 58void showdstls_live __P((int, int, ipf_dstl_stat_t *, char *)); 59 60int opts = 0; 61int fd = -1; 62int use_inet6 = 0; 63wordtab_t *pool_fields = NULL; 64int nohdrfields = 0; 65 66 67void 68usage(prog) 69 char *prog; 70{ 71 fprintf(stderr, "Usage:\t%s\n", prog); 72 fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n"); 73 fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n"); 74 fprintf(stderr, "\t-f <file> [-dnuv]\n"); 75 fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n"); 76 fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>]\n"); 77 fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n"); 78 fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n"); 79 fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n"); 80 exit(1); 81} 82 83 84int 85main(argc, argv) 86 int argc; 87 char *argv[]; 88{ 89 int err = 1; 90 91 if (argc < 2) 92 usage(argv[0]); 93 94 assigndefined(getenv("IPPOOL_PREDEFINED")); 95 96 switch (getopt(argc, argv, "aAf:FlnrRsv")) 97 { 98 case 'a' : 99 err = poolnodecommand(0, argc, argv); 100 break; 101 case 'A' : 102 err = poolcommand(0, argc, argv); 103 break; 104 case 'f' : 105 err = loadpoolfile(argc, argv, optarg); 106 break; 107 case 'F' : 108 err = poolflush(argc, argv); 109 break; 110 case 'l' : 111 err = poollist(argc, argv); 112 break; 113 case 'n' : 114 opts |= OPT_DONOTHING|OPT_DONTOPEN; 115 break; 116 case 'r' : 117 err = poolnodecommand(1, argc, argv); 118 break; 119 case 'R' : 120 err = poolcommand(1, argc, argv); 121 break; 122 case 's' : 123 err = poolstats(argc, argv); 124 break; 125 default : 126 exit(1); 127 } 128 129 if (err != 0) 130 exit(1); 131 return 0; 132} 133 134 135int 136poolnodecommand(remove, argc, argv) 137 int remove, argc; 138 char *argv[]; 139{ 140 int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0; 141 char *poolname = NULL; 142 ip_pool_node_t pnode; 143 iphtent_t hnode; 144 void *ptr = &pnode; 145 146 ipset = 0; 147 role = IPL_LOGIPF; 148 bzero((char *)&pnode, sizeof(pnode)); 149 bzero((char *)&hnode, sizeof(hnode)); 150 151 while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1) 152 switch (c) 153 { 154 case 'd' : 155 opts |= OPT_DEBUG; 156 ippool_yydebug++; 157 break; 158 case 'i' : 159 if (setnodeaddr(type, role, ptr, optarg) == 0) 160 ipset = 1; 161 break; 162 case 'm' : 163 poolname = optarg; 164 break; 165 case 'n' : 166 opts |= OPT_DONOTHING|OPT_DONTOPEN; 167 break; 168 case 'o' : 169 if (ipset == 1) { 170 fprintf(stderr, 171 "cannot set role after ip address\n"); 172 return -1; 173 } 174 role = getrole(optarg); 175 if (role == IPL_LOGNONE) 176 return -1; 177 break; 178 case 'R' : 179 opts |= OPT_NORESOLVE; 180 break; 181 case 't' : 182 if (ipset == 1) { 183 fprintf(stderr, 184 "cannot set type after ip address\n"); 185 return -1; 186 } 187 type = gettype(optarg, NULL); 188 switch (type) { 189 case IPLT_NONE : 190 fprintf(stderr, "unknown type '%s'\n", optarg); 191 return -1; 192 case IPLT_HASH : 193 ptr = &hnode; 194 break; 195 case IPLT_POOL : 196 default : 197 break; 198 } 199 break; 200 case 'T' : 201 ttl = atoi(optarg); 202 if (ttl < 0) { 203 fprintf(stderr, "cannot set negative ttl\n"); 204 return -1; 205 } 206 break; 207 case 'v' : 208 opts |= OPT_VERBOSE; 209 break; 210 } 211 212 if (argv[optind] != NULL && ipset == 0) { 213 if (setnodeaddr(type, role, ptr, argv[optind]) == 0) 214 ipset = 1; 215 } 216 217 if (opts & OPT_DEBUG) 218 fprintf(stderr, "poolnodecommand: opts = %#x\n", opts); 219 220 if (ipset == 0) { 221 fprintf(stderr, "no IP address given with -i\n"); 222 return -1; 223 } 224 225 if (poolname == NULL) { 226 fprintf(stderr, "poolname not given with add/remove node\n"); 227 return -1; 228 } 229 230 switch (type) { 231 case IPLT_POOL : 232 if (remove == 0) 233 err = load_poolnode(role, poolname, &pnode, ttl, ioctl); 234 else 235 err = remove_poolnode(role, poolname, &pnode, ioctl); 236 break; 237 case IPLT_HASH : 238 if (remove == 0) 239 err = load_hashnode(role, poolname, &hnode, ttl, ioctl); 240 else 241 err = remove_hashnode(role, poolname, &hnode, ioctl); 242 break; 243 default : 244 break; 245 } 246 return err; 247} 248 249 250int 251poolcommand(remove, argc, argv) 252 int remove, argc; 253 char *argv[]; 254{ 255 int type, role, c, err; 256 char *poolname; 257 iphtable_t iph; 258 ip_pool_t pool; 259 260 err = 1; 261 role = 0; 262 type = 0; 263 poolname = NULL; 264 role = IPL_LOGIPF; 265 bzero((char *)&iph, sizeof(iph)); 266 bzero((char *)&pool, sizeof(pool)); 267 268 while ((c = getopt(argc, argv, "dm:no:RSv")) != -1) 269 switch (c) 270 { 271 case 'd' : 272 opts |= OPT_DEBUG; 273 ippool_yydebug++; 274 break; 275 case 'm' : 276 poolname = optarg; 277 break; 278 case 'n' : 279 opts |= OPT_DONOTHING|OPT_DONTOPEN; 280 break; 281 case 'o' : 282 role = getrole(optarg); 283 if (role == IPL_LOGNONE) { 284 fprintf(stderr, "unknown role '%s'\n", optarg); 285 return -1; 286 } 287 break; 288 case 'R' : 289 opts |= OPT_NORESOLVE; 290 break; 291 case 'S' : 292 iph.iph_seed = atoi(optarg); 293 break; 294 case 'v' : 295 opts |= OPT_VERBOSE; 296 break; 297 } 298 299 if (opts & OPT_DEBUG) 300 fprintf(stderr, "poolcommand: opts = %#x\n", opts); 301 302 if (poolname == NULL) { 303 fprintf(stderr, "poolname not given with add/remove pool\n"); 304 return -1; 305 } 306 307 type = gettype(argv[optind], &iph.iph_type); 308 if (type == IPLT_NONE) { 309 fprintf(stderr, "unknown type '%s'\n", argv[optind]); 310 return -1; 311 } 312 313 if (type == IPLT_HASH) { 314 strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); 315 iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; 316 iph.iph_unit = role; 317 } else if (type == IPLT_POOL) { 318 strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name)); 319 pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0'; 320 pool.ipo_unit = role; 321 } 322 323 if (remove == 0) { 324 switch (type) 325 { 326 case IPLT_HASH : 327 err = load_hash(&iph, NULL, ioctl); 328 break; 329 case IPLT_POOL : 330 err = load_pool(&pool, ioctl); 331 break; 332 } 333 } else { 334 switch (type) 335 { 336 case IPLT_HASH : 337 err = remove_hash(&iph, ioctl); 338 break; 339 case IPLT_POOL : 340 err = remove_pool(&pool, ioctl); 341 break; 342 } 343 } 344 return err; 345} 346 347 348int 349loadpoolfile(argc, argv, infile) 350 int argc; 351 char *argv[], *infile; 352{ 353 int c; 354 355 while ((c = getopt(argc, argv, "dnRuv")) != -1) 356 switch (c) 357 { 358 case 'd' : 359 opts |= OPT_DEBUG; 360 ippool_yydebug++; 361 break; 362 case 'n' : 363 opts |= OPT_DONOTHING|OPT_DONTOPEN; 364 break; 365 case 'R' : 366 opts |= OPT_NORESOLVE; 367 break; 368 case 'u' : 369 opts |= OPT_REMOVE; 370 break; 371 case 'v' : 372 opts |= OPT_VERBOSE; 373 break; 374 default : 375 usage(argv[0]); 376 break; /* keep compiler happy */ 377 } 378 379 if (argc - 1 - optind > 0) 380 usage(argv[0]); 381 382 if (opts & OPT_DEBUG) 383 fprintf(stderr, "loadpoolfile: opts = %#x\n", opts); 384 385 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { 386 fd = open(IPLOOKUP_NAME, O_RDWR); 387 if (fd == -1) { 388 perror("open(IPLOOKUP_NAME)"); 389 exit(1); 390 } 391 } 392 393 if (ippool_parsefile(fd, infile, ioctl) != 0) 394 return -1; 395 return 0; 396} 397 398 399int 400poolstats(argc, argv) 401 int argc; 402 char *argv[]; 403{ 404 int c, type, role, live_kernel; 405 ipf_pool_stat_t plstat; 406 ipf_dstl_stat_t dlstat; 407 char *kernel, *core; 408 iphtstat_t htstat; 409 iplookupop_t op; 410 411 core = NULL; 412 kernel = NULL; 413 live_kernel = 1; 414 type = IPLT_ALL; 415 role = IPL_LOGALL; 416 417 bzero((char *)&op, sizeof(op)); 418 419 while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1) 420 switch (c) 421 { 422 case 'd' : 423 opts |= OPT_DEBUG; 424 break; 425 case 'M' : 426 live_kernel = 0; 427 core = optarg; 428 break; 429 case 'N' : 430 live_kernel = 0; 431 kernel = optarg; 432 break; 433 case 'o' : 434 role = getrole(optarg); 435 if (role == IPL_LOGNONE) { 436 fprintf(stderr, "unknown role '%s'\n", optarg); 437 return -1; 438 } 439 break; 440 case 't' : 441 type = gettype(optarg, NULL); 442 if (type != IPLT_POOL) { 443 fprintf(stderr, 444 "-s not supported for this type yet\n"); 445 return -1; 446 } 447 break; 448 case 'v' : 449 opts |= OPT_VERBOSE; 450 break; 451 default : 452 usage(argv[0]); 453 break; /* keep compiler happy */ 454 } 455 456 if (argc - 1 - optind > 0) 457 usage(argv[0]); 458 459 if (opts & OPT_DEBUG) 460 fprintf(stderr, "poolstats: opts = %#x\n", opts); 461 462 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { 463 fd = open(IPLOOKUP_NAME, O_RDWR); 464 if (fd == -1) { 465 perror("open(IPLOOKUP_NAME)"); 466 exit(1); 467 } 468 } 469 470 if (type == IPLT_ALL || type == IPLT_POOL) { 471 op.iplo_type = IPLT_POOL; 472 op.iplo_struct = &plstat; 473 op.iplo_size = sizeof(plstat); 474 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { 475 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 476 if (c == -1) { 477 ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)"); 478 return -1; 479 } 480 printf("%lu\taddress pools\n", plstat.ipls_pools); 481 printf("%lu\taddress pool nodes\n", plstat.ipls_nodes); 482 } 483 } 484 485 if (type == IPLT_ALL || type == IPLT_HASH) { 486 op.iplo_type = IPLT_HASH; 487 op.iplo_struct = &htstat; 488 op.iplo_size = sizeof(htstat); 489 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { 490 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 491 if (c == -1) { 492 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 493 return -1; 494 } 495 printf("%lu\thash tables\n", htstat.iphs_numtables); 496 printf("%lu\thash table nodes\n", htstat.iphs_numnodes); 497 printf("%lu\thash table no memory \n", 498 htstat.iphs_nomem); 499 } 500 } 501 502 if (type == IPLT_ALL || type == IPLT_DSTLIST) { 503 op.iplo_type = IPLT_DSTLIST; 504 op.iplo_struct = &dlstat; 505 op.iplo_size = sizeof(dlstat); 506 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { 507 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 508 if (c == -1) { 509 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 510 return -1; 511 } 512 printf("%u\tdestination lists\n", 513 dlstat.ipls_numlists); 514 printf("%u\tdestination list nodes\n", 515 dlstat.ipls_numnodes); 516 printf("%lu\tdestination list no memory\n", 517 dlstat.ipls_nomem); 518 printf("%u\tdestination list zombies\n", 519 dlstat.ipls_numdereflists); 520 printf("%u\tdesetination list node zombies\n", 521 dlstat.ipls_numderefnodes); 522 } 523 } 524 return 0; 525} 526 527 528int 529poolflush(argc, argv) 530 int argc; 531 char *argv[]; 532{ 533 int c, role, type, arg; 534 iplookupflush_t flush; 535 536 arg = IPLT_ALL; 537 type = IPLT_ALL; 538 role = IPL_LOGALL; 539 540 while ((c = getopt(argc, argv, "do:t:v")) != -1) 541 switch (c) 542 { 543 case 'd' : 544 opts |= OPT_DEBUG; 545 break; 546 case 'o' : 547 role = getrole(optarg); 548 if (role == IPL_LOGNONE) { 549 fprintf(stderr, "unknown role '%s'\n", optarg); 550 return -1; 551 } 552 break; 553 case 't' : 554 type = gettype(optarg, NULL); 555 if (type == IPLT_NONE) { 556 fprintf(stderr, "unknown type '%s'\n", optarg); 557 return -1; 558 } 559 break; 560 case 'v' : 561 opts |= OPT_VERBOSE; 562 break; 563 default : 564 usage(argv[0]); 565 break; /* keep compiler happy */ 566 } 567 568 if (argc - 1 - optind > 0) 569 usage(argv[0]); 570 571 if (opts & OPT_DEBUG) 572 fprintf(stderr, "poolflush: opts = %#x\n", opts); 573 574 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { 575 fd = open(IPLOOKUP_NAME, O_RDWR); 576 if (fd == -1) { 577 perror("open(IPLOOKUP_NAME)"); 578 exit(1); 579 } 580 } 581 582 bzero((char *)&flush, sizeof(flush)); 583 flush.iplf_type = type; 584 flush.iplf_unit = role; 585 flush.iplf_arg = arg; 586 587 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) { 588 if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { 589 ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)"); 590 exit(1); 591 } 592 593 } 594 printf("%u object%s flushed\n", flush.iplf_count, 595 (flush.iplf_count == 1) ? "" : "s"); 596 597 return 0; 598} 599 600 601int 602getrole(rolename) 603 char *rolename; 604{ 605 int role; 606 607 if (!strcasecmp(rolename, "ipf")) { 608 role = IPL_LOGIPF; 609#if 0 610 } else if (!strcasecmp(rolename, "nat")) { 611 role = IPL_LOGNAT; 612 } else if (!strcasecmp(rolename, "state")) { 613 role = IPL_LOGSTATE; 614 } else if (!strcasecmp(rolename, "auth")) { 615 role = IPL_LOGAUTH; 616 } else if (!strcasecmp(rolename, "sync")) { 617 role = IPL_LOGSYNC; 618 } else if (!strcasecmp(rolename, "scan")) { 619 role = IPL_LOGSCAN; 620 } else if (!strcasecmp(rolename, "pool")) { 621 role = IPL_LOGLOOKUP; 622 } else if (!strcasecmp(rolename, "count")) { 623 role = IPL_LOGCOUNT; 624#endif 625 } else { 626 role = IPL_LOGNONE; 627 } 628 629 return role; 630} 631 632 633int 634gettype(typename, minor) 635 char *typename; 636 u_int *minor; 637{ 638 int type; 639 640 if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) { 641 type = IPLT_POOL; 642 } else if (!strcasecmp(typename, "hash")) { 643 type = IPLT_HASH; 644 if (minor != NULL) 645 *minor = IPHASH_LOOKUP; 646 } else if (!strcasecmp(typename, "group-map")) { 647 type = IPLT_HASH; 648 if (minor != NULL) 649 *minor = IPHASH_GROUPMAP; 650 } else { 651 type = IPLT_NONE; 652 } 653 return type; 654} 655 656 657int 658poollist(argc, argv) 659 int argc; 660 char *argv[]; 661{ 662 char *kernel, *core, *poolname; 663 int c, role, type, live_kernel; 664 iplookupop_t op; 665 666 core = NULL; 667 kernel = NULL; 668 live_kernel = 1; 669 type = IPLT_ALL; 670 poolname = NULL; 671 role = IPL_LOGALL; 672 673 while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1) 674 switch (c) 675 { 676 case 'd' : 677 opts |= OPT_DEBUG; 678 break; 679 case 'm' : 680 poolname = optarg; 681 break; 682 case 'M' : 683 live_kernel = 0; 684 core = optarg; 685 break; 686 case 'N' : 687 live_kernel = 0; 688 kernel = optarg; 689 break; 690 case 'o' : 691 role = getrole(optarg); 692 if (role == IPL_LOGNONE) { 693 fprintf(stderr, "unknown role '%s'\n", optarg); 694 return -1; 695 } 696 break; 697#if 0 698 case 'O' : 699 /* XXX This option does not work. This function as */ 700 /* XXX used by state and nat can be used to format */ 701 /* XXX output especially useful for scripting. It */ 702 /* XXX is left here with the intention of making */ 703 /* XXX it work for the same purpose at some point. */ 704 pool_fields = parsefields(poolfields, optarg); 705 break; 706#endif 707 case 't' : 708 type = gettype(optarg, NULL); 709 if (type == IPLT_NONE) { 710 fprintf(stderr, "unknown type '%s'\n", optarg); 711 return -1; 712 } 713 break; 714 case 'v' : 715 opts |= OPT_VERBOSE; 716 break; 717 default : 718 usage(argv[0]); 719 break; /* keep compiler happy */ 720 } 721 722 if (argc - optind > 0) 723 usage(argv[0]); 724 725 if (opts & OPT_DEBUG) 726 fprintf(stderr, "poollist: opts = %#x\n", opts); 727 728 if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) { 729 fd = open(IPLOOKUP_NAME, O_RDWR); 730 if (fd == -1) { 731 perror("open(IPLOOKUP_NAME)"); 732 exit(1); 733 } 734 } 735 736 bzero((char *)&op, sizeof(op)); 737 if (poolname != NULL) { 738 strncpy(op.iplo_name, poolname, sizeof(op.iplo_name)); 739 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 740 } 741 op.iplo_unit = role; 742 743 if (live_kernel) 744 poollist_live(role, poolname, type, fd); 745 else 746 poollist_dead(role, poolname, type, kernel, core); 747 return 0; 748} 749 750 751void 752poollist_dead(role, poolname, type, kernel, core) 753 int role, type; 754 char *poolname, *kernel, *core; 755{ 756 iphtable_t *hptr; 757 ip_pool_t *ptr; 758 759 if (openkmem(kernel, core) == -1) 760 exit(-1); 761 762 if (type == IPLT_ALL || type == IPLT_POOL) { 763 ip_pool_t *pools[IPL_LOGSIZE]; 764 struct nlist names[2] = { { "ip_pool_list" } , { "" } }; 765 766 if (nlist(kernel, names) != 1) 767 return; 768 769 bzero(&pools, sizeof(pools)); 770 if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools))) 771 return; 772 773 if (role != IPL_LOGALL) { 774 ptr = pools[role]; 775 while (ptr != NULL) { 776 ptr = printpool(ptr, kmemcpywrap, poolname, 777 opts, pool_fields); 778 } 779 } else { 780 for (role = 0; role <= IPL_LOGMAX; role++) { 781 ptr = pools[role]; 782 while (ptr != NULL) { 783 ptr = printpool(ptr, kmemcpywrap, 784 poolname, opts, 785 pool_fields); 786 } 787 } 788 role = IPL_LOGALL; 789 } 790 } 791 if (type == IPLT_ALL || type == IPLT_HASH) { 792 iphtable_t *tables[IPL_LOGSIZE]; 793 struct nlist names[2] = { { "ipf_htables" } , { "" } }; 794 795 if (nlist(kernel, names) != 1) 796 return; 797 798 bzero(&tables, sizeof(tables)); 799 if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables))) 800 return; 801 802 if (role != IPL_LOGALL) { 803 hptr = tables[role]; 804 while (hptr != NULL) { 805 hptr = printhash(hptr, kmemcpywrap, 806 poolname, opts, pool_fields); 807 } 808 } else { 809 for (role = 0; role <= IPL_LOGMAX; role++) { 810 hptr = tables[role]; 811 while (hptr != NULL) { 812 hptr = printhash(hptr, kmemcpywrap, 813 poolname, opts, 814 pool_fields); 815 } 816 } 817 } 818 } 819} 820 821 822void 823poollist_live(role, poolname, type, fd) 824 int role, type, fd; 825 char *poolname; 826{ 827 ipf_pool_stat_t plstat; 828 iplookupop_t op; 829 int c; 830 831 if (type == IPLT_ALL || type == IPLT_POOL) { 832 op.iplo_type = IPLT_POOL; 833 op.iplo_size = sizeof(plstat); 834 op.iplo_struct = &plstat; 835 op.iplo_name[0] = '\0'; 836 op.iplo_arg = 0; 837 838 if (role != IPL_LOGALL) { 839 op.iplo_unit = role; 840 841 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 842 if (c == -1) { 843 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 844 return; 845 } 846 847 showpools_live(fd, role, &plstat, poolname); 848 } else { 849 for (role = -1; role <= IPL_LOGMAX; role++) { 850 op.iplo_unit = role; 851 852 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 853 if (c == -1) { 854 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 855 return; 856 } 857 858 showpools_live(fd, role, &plstat, poolname); 859 } 860 861 role = IPL_LOGALL; 862 } 863 } 864 865 if (type == IPLT_ALL || type == IPLT_HASH) { 866 iphtstat_t htstat; 867 868 op.iplo_type = IPLT_HASH; 869 op.iplo_size = sizeof(htstat); 870 op.iplo_struct = &htstat; 871 op.iplo_name[0] = '\0'; 872 op.iplo_arg = 0; 873 874 if (role != IPL_LOGALL) { 875 op.iplo_unit = role; 876 877 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 878 if (c == -1) { 879 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 880 return; 881 } 882 showhashs_live(fd, role, &htstat, poolname); 883 } else { 884 for (role = 0; role <= IPL_LOGMAX; role++) { 885 886 op.iplo_unit = role; 887 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 888 if (c == -1) { 889 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 890 return; 891 } 892 893 showhashs_live(fd, role, &htstat, poolname); 894 } 895 role = IPL_LOGALL; 896 } 897 } 898 899 if (type == IPLT_ALL || type == IPLT_DSTLIST) { 900 ipf_dstl_stat_t dlstat; 901 902 op.iplo_type = IPLT_DSTLIST; 903 op.iplo_size = sizeof(dlstat); 904 op.iplo_struct = &dlstat; 905 op.iplo_name[0] = '\0'; 906 op.iplo_arg = 0; 907 908 if (role != IPL_LOGALL) { 909 op.iplo_unit = role; 910 911 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 912 if (c == -1) { 913 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 914 return; 915 } 916 showdstls_live(fd, role, &dlstat, poolname); 917 } else { 918 for (role = 0; role <= IPL_LOGMAX; role++) { 919 920 op.iplo_unit = role; 921 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 922 if (c == -1) { 923 ipferror(fd, "ioctl(SIOCLOOKUPSTAT)"); 924 return; 925 } 926 927 showdstls_live(fd, role, &dlstat, poolname); 928 } 929 role = IPL_LOGALL; 930 } 931 } 932} 933 934 935void 936showpools_live(fd, role, plstp, poolname) 937 int fd, role; 938 ipf_pool_stat_t *plstp; 939 char *poolname; 940{ 941 ipflookupiter_t iter; 942 ip_pool_t pool; 943 ipfobj_t obj; 944 945 obj.ipfo_rev = IPFILTER_VERSION; 946 obj.ipfo_type = IPFOBJ_LOOKUPITER; 947 obj.ipfo_size = sizeof(iter); 948 obj.ipfo_ptr = &iter; 949 950 iter.ili_type = IPLT_POOL; 951 iter.ili_otype = IPFLOOKUPITER_LIST; 952 iter.ili_ival = IPFGENITER_LOOKUP; 953 iter.ili_nitems = 1; 954 iter.ili_data = &pool; 955 iter.ili_unit = role; 956 *iter.ili_name = '\0'; 957 958 bzero((char *)&pool, sizeof(pool)); 959 960 while (plstp->ipls_list[role + 1] != NULL) { 961 if (ioctl(fd, SIOCLOOKUPITER, &obj)) { 962 ipferror(fd, "ioctl(SIOCLOOKUPITER)"); 963 break; 964 } 965 if (((pool.ipo_flags & IPOOL_DELETE) == 0) || 966 ((opts & OPT_DEBUG) != 0)) 967 printpool_live(&pool, fd, poolname, opts, pool_fields); 968 969 plstp->ipls_list[role + 1] = pool.ipo_next; 970 } 971} 972 973 974void 975showhashs_live(fd, role, htstp, poolname) 976 int fd, role; 977 iphtstat_t *htstp; 978 char *poolname; 979{ 980 ipflookupiter_t iter; 981 iphtable_t table; 982 ipfobj_t obj; 983 984 obj.ipfo_rev = IPFILTER_VERSION; 985 obj.ipfo_type = IPFOBJ_LOOKUPITER; 986 obj.ipfo_size = sizeof(iter); 987 obj.ipfo_ptr = &iter; 988 989 iter.ili_type = IPLT_HASH; 990 iter.ili_otype = IPFLOOKUPITER_LIST; 991 iter.ili_ival = IPFGENITER_LOOKUP; 992 iter.ili_nitems = 1; 993 iter.ili_data = &table; 994 iter.ili_unit = role; 995 *iter.ili_name = '\0'; 996 997 while (htstp->iphs_tables != NULL) { 998 if (ioctl(fd, SIOCLOOKUPITER, &obj)) { 999 ipferror(fd, "ioctl(SIOCLOOKUPITER)"); 1000 break; 1001 } 1002 1003 printhash_live(&table, fd, poolname, opts, pool_fields); 1004 1005 htstp->iphs_tables = table.iph_next; 1006 } 1007} 1008 1009 1010void 1011showdstls_live(fd, role, dlstp, poolname) 1012 int fd, role; 1013 ipf_dstl_stat_t *dlstp; 1014 char *poolname; 1015{ 1016 ipflookupiter_t iter; 1017 ippool_dst_t table; 1018 ipfobj_t obj; 1019 1020 obj.ipfo_rev = IPFILTER_VERSION; 1021 obj.ipfo_type = IPFOBJ_LOOKUPITER; 1022 obj.ipfo_size = sizeof(iter); 1023 obj.ipfo_ptr = &iter; 1024 1025 iter.ili_type = IPLT_DSTLIST; 1026 iter.ili_otype = IPFLOOKUPITER_LIST; 1027 iter.ili_ival = IPFGENITER_LOOKUP; 1028 iter.ili_nitems = 1; 1029 iter.ili_data = &table; 1030 iter.ili_unit = role; 1031 *iter.ili_name = '\0'; 1032 1033 while (dlstp->ipls_list[role] != NULL) { 1034 if (ioctl(fd, SIOCLOOKUPITER, &obj)) { 1035 ipferror(fd, "ioctl(SIOCLOOKUPITER)"); 1036 break; 1037 } 1038 1039 printdstl_live(&table, fd, poolname, opts, pool_fields); 1040 1041 dlstp->ipls_list[role] = table.ipld_next; 1042 } 1043} 1044 1045 1046int 1047setnodeaddr(int type, int role, void *ptr, char *arg) 1048{ 1049 struct in_addr mask; 1050 char *s; 1051 1052 s = strchr(arg, '/'); 1053 if (s == NULL) 1054 mask.s_addr = 0xffffffff; 1055 else if (strchr(s, '.') == NULL) { 1056 if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0) 1057 return -1; 1058 } else { 1059 mask.s_addr = inet_addr(s + 1); 1060 } 1061 if (s != NULL) 1062 *s = '\0'; 1063 1064 if (type == IPLT_POOL) { 1065 ip_pool_node_t *node = ptr; 1066 1067#ifdef USE_INET6 1068 if (node->ipn_addr.adf_family == AF_INET) 1069#endif 1070 node->ipn_addr.adf_len = offsetof(addrfamily_t, 1071 adf_addr) + 1072 sizeof(struct in_addr); 1073#ifdef USE_INET6 1074 else 1075 node->ipn_addr.adf_len = offsetof(addrfamily_t, 1076 adf_addr) + 1077 sizeof(struct in6_addr); 1078#endif 1079 node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg); 1080 node->ipn_mask.adf_len = node->ipn_addr.adf_len; 1081 node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr; 1082 } else if (type == IPLT_HASH) { 1083 iphtent_t *node = ptr; 1084 1085 node->ipe_addr.in4.s_addr = inet_addr(arg); 1086 node->ipe_mask.in4.s_addr = mask.s_addr; 1087 node->ipe_family = AF_INET; 1088 node->ipe_unit = role; 1089 } 1090 1091 return 0; 1092} 1093