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