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