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