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