1 /*
   2  * Copyright (C) 2003 by Darren Reed.
   3  *
   4  * See the IPFILTER.LICENCE file for details on licencing.
   5  *
   6  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
   7  * Use is subject to license terms.
   8  *
   9  * Copyright (c) 2014, Joyent, Inc.  All rights reserved.
  10  */
  11 
  12 #include <sys/types.h>
  13 #include <sys/time.h>
  14 #include <sys/param.h>
  15 #include <sys/socket.h>
  16 #if defined(BSD) && (BSD >= 199306)
  17 # include <sys/cdefs.h>
  18 #endif
  19 #include <sys/ioctl.h>
  20 
  21 #include <net/if.h>
  22 #if __FreeBSD_version >= 300000
  23 # include <net/if_var.h>
  24 #endif
  25 #include <netinet/in.h>
  26 
  27 #include <arpa/inet.h>
  28 
  29 #include <stdio.h>
  30 #include <fcntl.h>
  31 #include <stdlib.h>
  32 #include <string.h>
  33 #include <netdb.h>
  34 #include <ctype.h>
  35 #include <unistd.h>
  36 #include <nlist.h>
  37 
  38 #include "ipf.h"
  39 #include "netinet/ipl.h"
  40 #include "netinet/ip_lookup.h"
  41 #include "netinet/ip_pool.h"
  42 #include "netinet/ip_htable.h"
  43 #include "kmem.h"
  44 #include "ipfzone.h"
  45 
  46 extern  int     ippool_yyparse __P((void));
  47 extern  int     ippool_yydebug;
  48 extern  FILE    *ippool_yyin;
  49 extern  char    *optarg;
  50 extern  int     lineNum;
  51 
  52 void    showpools __P((ip_pool_stat_t *));
  53 void    usage __P((char *));
  54 int     main __P((int, char **));
  55 int     poolcommand __P((int, int, char *[]));
  56 int     poolnodecommand __P((int, int, char *[]));
  57 int     loadpoolfile __P((int, char *[], char *));
  58 int     poollist __P((int, char *[]));
  59 int     poolflush __P((int, char *[]));
  60 int     poolstats __P((int, char *[]));
  61 int     gettype __P((char *, u_int *));
  62 int     getrole __P((char *));
  63 void    poollist_dead __P((int, char *, int, char *, char *));
  64 void    showpools_live(int, int, ip_pool_stat_t *, char *, int);
  65 void    showhashs_live(int, int, iphtstat_t *, char *, int);
  66 
  67 int     opts = 0;
  68 int     fd = -1;
  69 int     use_inet6 = 0;
  70 
  71 
  72 void usage(prog)
  73 char *prog;
  74 {
  75         const char *zoneopt = "[-G|-z zonename] ";
  76         fprintf(stderr, "Usage:\t%s\n", prog);
  77         fprintf(stderr, "\t\t\t-a [-dnv] %s[-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n",
  78             zoneopt);
  79         fprintf(stderr, "\t\t\t-A [-dnv] %s[-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n",
  80             zoneopt);
  81         fprintf(stderr, "\t\t\t-f <file> %s[-dnuv]\n", zoneopt);
  82         fprintf(stderr, "\t\t\t-F [-dv] %s[-o <role>] [-t <type>]\n", zoneopt);
  83         fprintf(stderr, "\t\t\t-l [-dv] %s[-m <name>] [-t <type>]\n", zoneopt);
  84         fprintf(stderr, "\t\t\t-r [-dnv] %s[-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n",
  85             zoneopt);
  86         fprintf(stderr, "\t\t\t-R [-dnv] %s[-m <name>] [-o <role>] [-t <type>]\n",
  87             zoneopt);
  88         fprintf(stderr, "\t\t\t-s [-dtv] %s[-M <core>] [-N <namelist>]\n",
  89             zoneopt);
  90         exit(1);
  91 }
  92 
  93 
  94 int main(argc, argv)
  95 int argc;
  96 char *argv[];
  97 {
  98         int err;
  99 
 100         if (argc < 2)
 101                 usage(argv[0]);
 102 
 103         switch (getopt(argc, argv, "aAf:FlrRs"))
 104         {
 105         case 'a' :
 106                 err = poolnodecommand(0, argc, argv);
 107                 break;
 108         case 'A' :
 109                 err = poolcommand(0, argc, argv);
 110                 break;
 111         case 'f' :
 112                 err = loadpoolfile(argc, argv, optarg);
 113                 break;
 114         case 'F' :
 115                 err = poolflush(argc, argv);
 116                 break;
 117         case 'l' :
 118                 err = poollist(argc, argv);
 119                 break;
 120         case 'r' :
 121                 err = poolnodecommand(1, argc, argv);
 122                 break;
 123         case 'R' :
 124                 err = poolcommand(1, argc, argv);
 125                 break;
 126         case 's' :
 127                 err = poolstats(argc, argv);
 128                 break;
 129         default :
 130                 exit(1);
 131         }
 132 
 133         return err;
 134 }
 135 
 136 
 137 int poolnodecommand(remove, argc, argv)
 138 int remove, argc;
 139 char *argv[];
 140 {
 141         char *poolname = NULL, *s;
 142         int err, c, ipset, role;
 143         ip_pool_node_t node;
 144         struct in_addr mask;
 145 
 146         ipset = 0;
 147         role = IPL_LOGIPF;
 148         bzero((char *)&node, sizeof(node));
 149 
 150         while ((c = getopt(argc, argv, "di:G:m:no:Rvz:")) != -1)
 151                 switch (c)
 152                 {
 153                 case 'd' :
 154                         opts |= OPT_DEBUG;
 155                         ippool_yydebug++;
 156                         break;
 157                 case 'G' :
 158                         setzonename_global(optarg);
 159                         break;
 160                 case 'i' :
 161                         s = strchr(optarg, '/');
 162                         if (s == NULL)
 163                                 mask.s_addr = 0xffffffff;
 164                         else if (strchr(s, '.') == NULL) {
 165                                 if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0)
 166                                         return -1;
 167                         } else {
 168                                 mask.s_addr = inet_addr(s + 1);
 169                         }
 170                         if (s != NULL)
 171                                 *s = '\0';
 172                         ipset = 1;
 173                         node.ipn_addr.adf_len = sizeof(node.ipn_addr);
 174                         node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg);
 175                         node.ipn_mask.adf_len = sizeof(node.ipn_mask);
 176                         node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
 177                         break;
 178                 case 'm' :
 179                         poolname = optarg;
 180                         break;
 181                 case 'n' :
 182                         opts |= OPT_DONOTHING;
 183                         break;
 184                 case 'o' :
 185                         role = getrole(optarg);
 186                         if (role == IPL_LOGNONE)
 187                                 return -1;
 188                         break;
 189                 case 'R' :
 190                         opts |= OPT_NORESOLVE;
 191                         break;
 192                 case 'v' :
 193                         opts |= OPT_VERBOSE;
 194                         break;
 195                 case 'z' :
 196                         setzonename(optarg);
 197                         break;
 198                 }
 199 
 200         if (opts & OPT_DEBUG)
 201                 fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
 202 
 203         if (ipset == 0)
 204                 return -1;
 205         if (poolname == NULL) {
 206                 fprintf(stderr, "poolname not given with add/remove node\n");
 207                 return -1;
 208         }
 209 
 210         if (remove == 0)
 211                 err = load_poolnode(0, poolname, &node, ioctl);
 212         else
 213                 err = remove_poolnode(0, poolname, &node, ioctl);
 214         return err;
 215 }
 216 
 217 
 218 int poolcommand(remove, argc, argv)
 219 int remove, argc;
 220 char *argv[];
 221 {
 222         int type, role, c, err;
 223         char *poolname;
 224         iphtable_t iph;
 225         ip_pool_t pool;
 226 
 227         err = 1;
 228         role = 0;
 229         type = 0;
 230         poolname = NULL;
 231         role = IPL_LOGIPF;
 232         bzero((char *)&iph, sizeof(iph));
 233         bzero((char *)&pool, sizeof(pool));
 234 
 235         while ((c = getopt(argc, argv, "dG:m:no:RS:t:vz:")) != -1)
 236                 switch (c)
 237                 {
 238                 case 'd' :
 239                         opts |= OPT_DEBUG;
 240                         ippool_yydebug++;
 241                         break;
 242                 case 'G' :
 243                         setzonename_global(optarg);
 244                         break;
 245                 case 'm' :
 246                         poolname = optarg;
 247                         break;
 248                 case 'n' :
 249                         opts |= OPT_DONOTHING;
 250                         break;
 251                 case 'o' :
 252                         role = getrole(optarg);
 253                         if (role == IPL_LOGNONE) {
 254                                 fprintf(stderr, "unknown role '%s'\n", optarg);
 255                                 return -1;
 256                         }
 257                         break;
 258                 case 'R' :
 259                         opts |= OPT_NORESOLVE;
 260                         break;
 261                 case 'S' :
 262                         iph.iph_seed = atoi(optarg);
 263                         break;
 264                 case 't' :
 265                         type = gettype(optarg, &iph.iph_type);
 266                         if (type == IPLT_NONE) {
 267                                 fprintf(stderr, "unknown type '%s'\n", optarg);
 268                                 return -1;
 269                         }
 270                         break;
 271                 case 'v' :
 272                         opts |= OPT_VERBOSE;
 273                         break;
 274                 case 'z' :
 275                         setzonename(optarg);
 276                         break;
 277                 }
 278 
 279         if (opts & OPT_DEBUG)
 280                 fprintf(stderr, "poolcommand: opts = %#x\n", opts);
 281 
 282         if (poolname == NULL) {
 283                 fprintf(stderr, "poolname not given with add/remove pool\n");
 284                 return -1;
 285         }
 286 
 287         if (type == IPLT_HASH) {
 288                 strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
 289                 iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
 290                 iph.iph_unit = role;
 291         } else if (type == IPLT_POOL) {
 292                 strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
 293                 pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
 294                 pool.ipo_unit = role;
 295         }
 296 
 297         if (remove == 0) {
 298                 switch (type)
 299                 {
 300                 case IPLT_HASH :
 301                         err = load_hash(&iph, NULL, ioctl);
 302                         break;
 303                 case IPLT_POOL :
 304                         err = load_pool(&pool, ioctl);
 305                         break;
 306                 }
 307         } else {
 308                 switch (type)
 309                 {
 310                 case IPLT_HASH :
 311                         err = remove_hash(&iph, ioctl);
 312                         break;
 313                 case IPLT_POOL :
 314                         err = remove_pool(&pool, ioctl);
 315                         break;
 316                 }
 317         }
 318         return err;
 319 }
 320 
 321 
 322 int loadpoolfile(argc, argv, infile)
 323 int argc;
 324 char *argv[], *infile;
 325 {
 326         int c;
 327 
 328         infile = optarg;
 329 
 330         while ((c = getopt(argc, argv, "dG:nRuvz:")) != -1)
 331                 switch (c)
 332                 {
 333                 case 'd' :
 334                         opts |= OPT_DEBUG;
 335                         ippool_yydebug++;
 336                         break;
 337                 case 'G' :
 338                         setzonename_global(optarg);
 339                         break;
 340                 case 'n' :
 341                         opts |= OPT_DONOTHING;
 342                         break;
 343                 case 'R' :
 344                         opts |= OPT_NORESOLVE;
 345                         break;
 346                 case 'u' :
 347                         opts |= OPT_REMOVE;
 348                         break;
 349                 case 'v' :
 350                         opts |= OPT_VERBOSE;
 351                         break;
 352                 case 'z' :
 353                         setzonename(optarg);
 354                         break;
 355                 }
 356 
 357         if (opts & OPT_DEBUG)
 358                 fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
 359 
 360         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
 361                 fd = open(IPLOOKUP_NAME, O_RDWR);
 362                 if (fd == -1) {
 363                         perror("open(IPLOOKUP_NAME)");
 364                         exit(1);
 365                 }
 366 
 367                 if (setzone(fd) != 0) {
 368                         close(fd);
 369                         exit(1);
 370                 }
 371         }
 372 
 373         if (ippool_parsefile(fd, infile, ioctl) != 0)
 374                 return -1;
 375         return 0;
 376 }
 377 
 378 
 379 int poollist(argc, argv)
 380 int argc;
 381 char *argv[];
 382 {
 383         char *kernel, *core, *poolname;
 384         int c, role, type, live_kernel;
 385         ip_pool_stat_t *plstp, plstat;
 386         iphtstat_t *htstp, htstat;
 387         iphtable_t *hptr;
 388         iplookupop_t op;
 389         ip_pool_t *ptr;
 390 
 391         core = NULL;
 392         kernel = NULL;
 393         live_kernel = 1;
 394         type = IPLT_ALL;
 395         poolname = NULL;
 396         role = IPL_LOGALL;
 397 
 398         while ((c = getopt(argc, argv, "dG:m:M:N:o:Rt:vz:")) != -1)
 399                 switch (c)
 400                 {
 401                 case 'd' :
 402                         opts |= OPT_DEBUG;
 403                         break;
 404                 case 'G' :
 405                         setzonename_global(optarg);
 406                         break;
 407                 case 'm' :
 408                         poolname = optarg;
 409                         break;
 410                 case 'M' :
 411                         live_kernel = 0;
 412                         core = optarg;
 413                         break;
 414                 case 'N' :
 415                         live_kernel = 0;
 416                         kernel = optarg;
 417                         break;
 418                 case 'o' :
 419                         role = getrole(optarg);
 420                         if (role == IPL_LOGNONE) {
 421                                 fprintf(stderr, "unknown role '%s'\n", optarg);
 422                                 return -1;
 423                         }
 424                         break;
 425                 case 'R' :
 426                         opts |= OPT_NORESOLVE;
 427                         break;
 428                 case 't' :
 429                         type = gettype(optarg, NULL);
 430                         if (type == IPLT_NONE) {
 431                                 fprintf(stderr, "unknown type '%s'\n", optarg);
 432                                 return -1;
 433                         }
 434                         break;
 435                 case 'v' :
 436                         opts |= OPT_VERBOSE;
 437                         break;
 438                 case 'z' :
 439                         setzonename(optarg);
 440                         break;
 441                 }
 442 
 443         if (opts & OPT_DEBUG)
 444                 fprintf(stderr, "poollist: opts = %#x\n", opts);
 445 
 446         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
 447                 fd = open(IPLOOKUP_NAME, O_RDWR);
 448                 if (fd == -1) {
 449                         perror("open(IPLOOKUP_NAME)");
 450                         exit(1);
 451                 }
 452 
 453                 if (setzone(fd) != 0) {
 454                         close(fd);
 455                         exit(1);
 456                 }
 457         }
 458 
 459         bzero((char *)&op, sizeof(op));
 460         if (poolname != NULL) {
 461                 strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
 462                 op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
 463         }
 464         op.iplo_unit = role;
 465 
 466         if (live_kernel == 0) {
 467                 poollist_dead(role, poolname, type, kernel, core);
 468                 return (0);
 469         }
 470 
 471         if (type == IPLT_ALL || type == IPLT_POOL) {
 472                 plstp = &plstat;
 473                 op.iplo_type = IPLT_POOL;
 474                 op.iplo_size = sizeof(plstat);
 475                 op.iplo_struct = &plstat;
 476                 op.iplo_name[0] = '\0';
 477                 op.iplo_arg = 0;
 478 
 479                 if (role != IPL_LOGALL) {
 480                         op.iplo_unit = role;
 481 
 482                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
 483                         if (c == -1) {
 484                                 perror("ioctl(SIOCLOOKUPSTAT)");
 485                                 return -1;
 486                         }
 487 
 488                         showpools_live(fd, role, &plstat, poolname, opts);
 489                 } else {
 490                         for (role = 0; role <= IPL_LOGMAX; role++) {
 491                                 op.iplo_unit = role;
 492 
 493                                 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
 494                                 if (c == -1) {
 495                                         perror("ioctl(SIOCLOOKUPSTAT)");
 496                                         return -1;
 497                                 }
 498 
 499                                 showpools_live(fd, role, &plstat, poolname, opts);
 500                         }
 501 
 502                         role = IPL_LOGALL;
 503                 }
 504         }
 505         if (type == IPLT_ALL || type == IPLT_HASH) {
 506                 htstp = &htstat;
 507                 op.iplo_type = IPLT_HASH;
 508                 op.iplo_size = sizeof(htstat);
 509                 op.iplo_struct = &htstat;
 510                 op.iplo_name[0] = '\0';
 511                 op.iplo_arg = 0;
 512 
 513                 if (role != IPL_LOGALL) {
 514                         op.iplo_unit = role;
 515 
 516                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
 517                         if (c == -1) {
 518                                 perror("ioctl(SIOCLOOKUPSTAT)");
 519                                 return -1;
 520                         }
 521                         showhashs_live(fd, role, &htstat, poolname, opts);
 522                 } else {
 523                         for (role = 0; role <= IPL_LOGMAX; role++) {
 524 
 525                                 op.iplo_unit = role;
 526                                 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
 527                                 if (c == -1) {
 528                                         perror("ioctl(SIOCLOOKUPSTAT)");
 529                                         return -1;
 530                                 }
 531 
 532                                 showhashs_live(fd, role, &htstat, poolname, opts);
 533                         }
 534                 }
 535         }
 536         return 0;
 537 }
 538 
 539 void poollist_dead(role, poolname, type, kernel, core)
 540 int role, type;
 541 char *poolname, *kernel, *core;
 542 {
 543         iphtable_t *hptr;
 544         ip_pool_t *ptr;
 545 
 546         if (openkmem(kernel, core) == -1)
 547                 exit(-1);
 548 
 549         if (type == IPLT_ALL || type == IPLT_POOL) {
 550                 ip_pool_t *pools[IPL_LOGSIZE];
 551                 struct nlist names[2] = { { "ip_pool_list" } , { "" } };
 552 
 553                 if (nlist(kernel, names) != 1)
 554                         return;
 555 
 556                 bzero(&pools, sizeof(pools));
 557                 if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
 558                         return;
 559 
 560                 if (role != IPL_LOGALL) {
 561                         ptr = pools[role];
 562                         while (ptr != NULL) {
 563                                 ptr = printpool(ptr, kmemcpywrap,
 564                                                 poolname, opts);
 565                         }
 566                 } else {
 567                         for (role = 0; role <= IPL_LOGMAX; role++) {
 568                                 ptr = pools[role];
 569                                 while (ptr != NULL) {
 570                                         ptr = printpool(ptr, kmemcpywrap,
 571                                                         poolname, opts);
 572                                 }
 573                         }
 574                         role = IPL_LOGALL;
 575                 }
 576         }
 577         if (type == IPLT_ALL || type == IPLT_HASH) {
 578                 iphtable_t *tables[IPL_LOGSIZE];
 579                 struct nlist names[2] = { { "ipf_htables" } , { "" } };
 580 
 581                 if (nlist(kernel, names) != 1)
 582                         return;
 583 
 584                 bzero(&tables, sizeof(tables));
 585                 if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
 586                         return;
 587 
 588                 if (role != IPL_LOGALL) {
 589                         hptr = tables[role];
 590                         while (hptr != NULL) {
 591                                 hptr = printhash(hptr, kmemcpywrap,
 592                                                  poolname, opts);
 593                         }
 594                 } else {
 595                         for (role = 0; role <= IPL_LOGMAX; role++) {
 596                                 hptr = tables[role];
 597                                 while (hptr != NULL) {
 598                                         hptr = printhash(hptr, kmemcpywrap,
 599                                                          poolname, opts);
 600                                 }
 601                         }
 602                 }
 603         }
 604 }
 605 
 606 
 607 void
 608 showpools_live(fd, role, plstp, poolname, opts)
 609 int fd, role;
 610 ip_pool_stat_t *plstp;
 611 char *poolname;
 612 int opts;
 613 {
 614         ipflookupiter_t iter;
 615         ip_pool_t pool;
 616         ipfobj_t obj;
 617 
 618         obj.ipfo_rev = IPFILTER_VERSION;
 619         obj.ipfo_type = IPFOBJ_LOOKUPITER;
 620         obj.ipfo_size = sizeof(iter);
 621         obj.ipfo_ptr = &iter;
 622 
 623         iter.ili_type = IPLT_POOL;
 624         iter.ili_otype = IPFLOOKUPITER_LIST;
 625         iter.ili_ival = IPFGENITER_LOOKUP;
 626         iter.ili_data = &pool;
 627         iter.ili_unit = role;
 628         *iter.ili_name = '\0';
 629 
 630         while (plstp->ipls_list[role] != NULL) {
 631                 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
 632                         perror("ioctl(SIOCLOOKUPITER)");
 633                         break;
 634                 }
 635                 (void) printpool_live(&pool, fd, poolname, opts);
 636 
 637                 plstp->ipls_list[role] = pool.ipo_next;
 638         }
 639 }
 640 
 641 int poolstats(argc, argv)
 642 int argc;
 643 char *argv[];
 644 {
 645         int c, type, role, live_kernel;
 646         ip_pool_stat_t plstat;
 647         char *kernel, *core;
 648         iphtstat_t htstat;
 649         iplookupop_t op;
 650 
 651         core = NULL;
 652         kernel = NULL;
 653         live_kernel = 1;
 654         type = IPLT_ALL;
 655         role = IPL_LOGALL;
 656 
 657         bzero((char *)&op, sizeof(op));
 658 
 659         while ((c = getopt(argc, argv, "dG:M:N:o:t:vz:")) != -1)
 660                 switch (c)
 661                 {
 662                 case 'd' :
 663                         opts |= OPT_DEBUG;
 664                         break;
 665                 case 'G' :
 666                         setzonename_global(optarg);
 667                         break;
 668                 case 'M' :
 669                         live_kernel = 0;
 670                         core = optarg;
 671                         break;
 672                 case 'N' :
 673                         live_kernel = 0;
 674                         kernel = optarg;
 675                         break;
 676                 case 'o' :
 677                         role = getrole(optarg);
 678                         if (role == IPL_LOGNONE) {
 679                                 fprintf(stderr, "unknown role '%s'\n", optarg);
 680                                 return -1;
 681                         }
 682                         break;
 683                 case 't' :
 684                         type = gettype(optarg, NULL);
 685                         if (type != IPLT_POOL) {
 686                                 fprintf(stderr,
 687                                         "-s not supported for this type yet\n");
 688                                 return -1;
 689                         }
 690                         break;
 691                 case 'v' :
 692                         opts |= OPT_VERBOSE;
 693                         break;
 694                 case 'z' :
 695                         setzonename(optarg);
 696                         break;
 697                 }
 698 
 699         if (opts & OPT_DEBUG)
 700                 fprintf(stderr, "poolstats: opts = %#x\n", opts);
 701 
 702         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
 703                 fd = open(IPLOOKUP_NAME, O_RDWR);
 704                 if (fd == -1) {
 705                         perror("open(IPLOOKUP_NAME)");
 706                         exit(1);
 707                 }
 708 
 709                 if (setzone(fd) != 0) {
 710                         close(fd);
 711                         exit(1);
 712                 }
 713         }
 714 
 715         if (type == IPLT_ALL || type == IPLT_POOL) {
 716                 op.iplo_type = IPLT_POOL;
 717                 op.iplo_struct = &plstat;
 718                 op.iplo_size = sizeof(plstat);
 719                 if (!(opts & OPT_DONOTHING)) {
 720                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
 721                         if (c == -1) {
 722                                 perror("ioctl(SIOCLOOKUPSTAT)");
 723                                 return -1;
 724                         }
 725                         printf("Pools:\t%lu\n", plstat.ipls_pools);
 726                         printf("Nodes:\t%lu\n", plstat.ipls_nodes);
 727                 }
 728         }
 729 
 730         if (type == IPLT_ALL || type == IPLT_HASH) {
 731                 op.iplo_type = IPLT_HASH;
 732                 op.iplo_struct = &htstat;
 733                 op.iplo_size = sizeof(htstat);
 734                 if (!(opts & OPT_DONOTHING)) {
 735                         c = ioctl(fd, SIOCLOOKUPSTAT, &op);
 736                         if (c == -1) {
 737                                 perror("ioctl(SIOCLOOKUPSTAT)");
 738                                 return -1;
 739                         }
 740                         printf("Hash Tables:\t%lu\n", htstat.iphs_numtables);
 741                         printf("Nodes:\t%lu\n", htstat.iphs_numnodes);
 742                         printf("Out of Memory:\t%lu\n", htstat.iphs_nomem);
 743                 }
 744         }
 745         return 0;
 746 }
 747 
 748 
 749 int poolflush(argc, argv)
 750 int argc;
 751 char *argv[];
 752 {
 753         int c, role, type, arg;
 754         iplookupflush_t flush;
 755 
 756         arg = IPLT_ALL;
 757         type = IPLT_ALL;
 758         role = IPL_LOGALL;
 759 
 760         while ((c = getopt(argc, argv, "do:t:vz:")) != -1)
 761                 switch (c)
 762                 {
 763                 case 'd' :
 764                         opts |= OPT_DEBUG;
 765                         break;
 766                 case 'o' :
 767                         role = getrole(optarg);
 768                         if (role == IPL_LOGNONE) {
 769                                 fprintf(stderr, "unknown role '%s'\n", optarg);
 770                                 return -1;
 771                         }
 772                         break;
 773                 case 't' :
 774                         type = gettype(optarg, NULL);
 775                         if (type == IPLT_NONE) {
 776                                 fprintf(stderr, "unknown type '%s'\n", optarg);
 777                                 return -1;
 778                         }
 779                         break;
 780                 case 'v' :
 781                         opts |= OPT_VERBOSE;
 782                         break;
 783                 case 'z' :
 784                         setzonename(optarg);
 785                         break;
 786                 }
 787 
 788         if (opts & OPT_DEBUG)
 789                 fprintf(stderr, "poolflush: opts = %#x\n", opts);
 790 
 791         if (!(opts & OPT_DONOTHING) && (fd == -1)) {
 792                 fd = open(IPLOOKUP_NAME, O_RDWR);
 793                 if (fd == -1) {
 794                         perror("open(IPLOOKUP_NAME)");
 795                         exit(1);
 796                 }
 797 
 798                 if (setzone(fd) != 0) {
 799                         close(fd);
 800                         exit(1);
 801                 }
 802         }
 803 
 804         bzero((char *)&flush, sizeof(flush));
 805         flush.iplf_type = type;
 806         flush.iplf_unit = role;
 807         flush.iplf_arg = arg;
 808 
 809         if (!(opts & OPT_DONOTHING)) {
 810                 if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
 811                         perror("ioctl(SIOCLOOKUPFLUSH)");
 812                         exit(1);
 813                 }
 814 
 815         }
 816         printf("%u object%s flushed\n", flush.iplf_count,
 817                (flush.iplf_count == 1) ? "" : "s");
 818 
 819         return 0;
 820 }
 821 
 822 
 823 int getrole(rolename)
 824 char *rolename;
 825 {
 826         int role;
 827 
 828         if (!strcasecmp(rolename, "ipf")) {
 829                 role = IPL_LOGIPF;
 830 #if 0
 831         } else if (!strcasecmp(rolename, "nat")) {
 832                 role = IPL_LOGNAT;
 833         } else if (!strcasecmp(rolename, "state")) {
 834                 role = IPL_LOGSTATE;
 835         } else if (!strcasecmp(rolename, "auth")) {
 836                 role = IPL_LOGAUTH;
 837         } else if (!strcasecmp(rolename, "sync")) {
 838                 role = IPL_LOGSYNC;
 839         } else if (!strcasecmp(rolename, "scan")) {
 840                 role = IPL_LOGSCAN;
 841         } else if (!strcasecmp(rolename, "pool")) {
 842                 role = IPL_LOGLOOKUP;
 843         } else if (!strcasecmp(rolename, "count")) {
 844                 role = IPL_LOGCOUNT;
 845 #endif
 846         } else {
 847                 role = IPL_LOGNONE;
 848         }
 849 
 850         return role;
 851 }
 852 
 853 
 854 int gettype(typename, minor)
 855 char *typename;
 856 u_int *minor;
 857 {
 858         int type;
 859 
 860         if (!strcasecmp(optarg, "tree")) {
 861                 type = IPLT_POOL;
 862         } else if (!strcasecmp(optarg, "hash")) {
 863                 type = IPLT_HASH;
 864                 if (minor != NULL)
 865                         *minor = IPHASH_LOOKUP;
 866         } else if (!strcasecmp(optarg, "group-map")) {
 867                 type = IPLT_HASH;
 868                 if (minor != NULL)
 869                         *minor = IPHASH_GROUPMAP;
 870         } else {
 871                 type = IPLT_NONE;
 872         }
 873         return type;
 874 }
 875 
 876 void showhashs_live(fd, role, htstp, poolname, opts)
 877 int fd, role;
 878 iphtstat_t *htstp;
 879 char *poolname;
 880 int opts;
 881 {
 882         ipflookupiter_t iter;
 883         iphtable_t table;
 884         ipfobj_t obj;
 885 
 886         obj.ipfo_rev = IPFILTER_VERSION;
 887         obj.ipfo_type = IPFOBJ_LOOKUPITER;
 888         obj.ipfo_size = sizeof(iter);
 889         obj.ipfo_ptr = &iter;
 890 
 891         iter.ili_type = IPLT_HASH;
 892         iter.ili_otype = IPFLOOKUPITER_LIST;
 893         iter.ili_ival = IPFGENITER_LOOKUP;
 894         iter.ili_data = &table;
 895         iter.ili_unit = role;
 896         *iter.ili_name = '\0';
 897 
 898         while (htstp->iphs_tables != NULL) {
 899                 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
 900                         perror("ioctl(SIOCLOOKUPITER)");
 901                         break;
 902                 }
 903 
 904                 printhash_live(&table, fd, poolname, opts);
 905 
 906                 htstp->iphs_tables = table.iph_next;
 907         }
 908 }