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