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