ippool.c revision 318206
1145857Sume/* $FreeBSD: stable/11/contrib/ipfilter/tools/ippool.c 318206 2017-05-12 02:32:01Z cy $ */ 2145857Sume 3145857Sume/* 4145857Sume * Copyright (C) 2012 by Darren Reed. 5145857Sume * 6145857Sume * See the IPFILTER.LICENCE file for details on licencing. 7145857Sume */ 8145857Sume#include <sys/types.h> 9145857Sume#include <sys/time.h> 10145857Sume#include <sys/param.h> 11145857Sume#include <sys/socket.h> 12145857Sume#if defined(BSD) && (BSD >= 199306) 13145857Sume# include <sys/cdefs.h> 14145857Sume#endif 15145857Sume#include <sys/ioctl.h> 16145857Sume 17145857Sume#include <net/if.h> 18145857Sume#include <netinet/in.h> 19145857Sume 20145857Sume#include <arpa/inet.h> 21145857Sume 22145857Sume#include <stdio.h> 23145857Sume#include <fcntl.h> 24145857Sume#include <stdlib.h> 25145857Sume#include <string.h> 26145857Sume#include <netdb.h> 27145857Sume#include <ctype.h> 28145857Sume#include <unistd.h> 29145857Sume#ifdef linux 30145857Sume# include <linux/a.out.h> 31145860Sume#else 32145857Sume# include <nlist.h> 33145857Sume#endif 34145857Sume 35145860Sume#include "ipf.h" 36145860Sume#include "netinet/ipl.h" 37145857Sume#include "netinet/ip_lookup.h" 38145857Sume#include "netinet/ip_pool.h" 39145857Sume#include "netinet/ip_htable.h" 40145857Sume#include "kmem.h" 41145857Sume 42145857Sume 43145857Sumeextern int ippool_yyparse __P((void)); 44145857Sumeextern int ippool_yydebug; 45292317Sngieextern FILE *ippool_yyin; 46292317Sngieextern char *optarg; 47145857Sumeextern int lineNum; 48145857Sume 49145857Sumevoid usage __P((char *)); 50145857Sumeint main __P((int, char **)); 51145860Sumeint poolcommand __P((int, int, char *[])); 52145860Sumeint poolnodecommand __P((int, int, char *[])); 53145860Sumeint loadpoolfile __P((int, char *[], char *)); 54145860Sumeint poollist __P((int, char *[])); 55145860Sumevoid poollist_dead __P((int, char *, int, char *, char *)); 56145860Sumevoid poollist_live __P((int, char *, int, int)); 57145857Sumeint poolflush __P((int, char *[])); 58145860Sumeint poolstats __P((int, char *[])); 59145857Sumeint gettype __P((char *, u_int *)); 60145857Sumeint getrole __P((char *)); 61145857Sumeint setnodeaddr __P((int, int, void *ptr, char *arg)); 62145857Sumevoid showpools_live __P((int, int, ipf_pool_stat_t *, char *)); 63145857Sumevoid showhashs_live __P((int, int, iphtstat_t *, char *)); 64145857Sumevoid showdstls_live __P((int, int, ipf_dstl_stat_t *, char *)); 65145857Sume 66145857Sumeint opts = 0; 67145857Sumeint fd = -1; 68145857Sumeint use_inet6 = 0; 69145857Sumewordtab_t *pool_fields = NULL; 70145857Sumeint nohdrfields = 0; 71145857Sume 72145857Sume 73145857Sumevoid 74145857Sumeusage(prog) 75145857Sume char *prog; 76145857Sume{ 77292317Sngie fprintf(stderr, "Usage:\t%s\n", prog); 78145857Sume fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n"); 79145857Sume fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n"); 80145857Sume fprintf(stderr, "\t-f <file> [-dnuv]\n"); 81145857Sume fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n"); 82291362Sngie fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-O <fields>]\n"); 83291362Sngie fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n"); 84291362Sngie fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n"); 85145857Sume fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n"); 86291362Sngie exit(1); 87145857Sume} 88145857Sume 89145857Sume 90145857Sumeint 91145857Sumemain(argc, argv) 92145857Sume int argc; 93145860Sume char *argv[]; 94145860Sume{ 95145860Sume int err = 1; 96145860Sume 97145860Sume if (argc < 2) 98145860Sume usage(argv[0]); 99145860Sume 100145860Sume assigndefined(getenv("IPPOOL_PREDEFINED")); 101145860Sume 102145860Sume switch (getopt(argc, argv, "aAf:FlnrRsv")) 103145860Sume { 104145860Sume case 'a' : 105145860Sume err = poolnodecommand(0, argc, argv); 106292317Sngie break; 107292317Sngie case 'A' : 108292317Sngie err = poolcommand(0, argc, argv); 109292317Sngie break; 110145860Sume case 'f' : 111145860Sume err = loadpoolfile(argc, argv, optarg); 112145860Sume break; 113145860Sume case 'F' : 114292317Sngie err = poolflush(argc, argv); 115292317Sngie break; 116292317Sngie case 'l' : 117145860Sume err = poollist(argc, argv); 118145860Sume break; 119145860Sume case 'n' : 120145860Sume opts |= OPT_DONOTHING|OPT_DONTOPEN; 121145860Sume break; 122145860Sume case 'r' : 123145860Sume err = poolnodecommand(1, argc, argv); 124145860Sume break; 125145860Sume case 'R' : 126145860Sume err = poolcommand(1, argc, argv); 127145860Sume break; 128145860Sume case 's' : 129145860Sume err = poolstats(argc, argv); 130145860Sume break; 131292317Sngie case 'v' : 132292317Sngie opts |= OPT_VERBOSE; 133292317Sngie break; 134292317Sngie default : 135145860Sume exit(1); 136145860Sume } 137292317Sngie 138145860Sume if (err != 0) 139145860Sume exit(1); 140145860Sume return 0; 141145860Sume} 142145860Sume 143145860Sume 144145860Sumeint 145145860Sumepoolnodecommand(remove, argc, argv) 146145860Sume int remove, argc; 147145860Sume char *argv[]; 148145860Sume{ 149145860Sume int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0; 150145860Sume char *poolname = NULL; 151145860Sume ip_pool_node_t pnode; 152145860Sume iphtent_t hnode; 153145860Sume void *ptr = &pnode; 154292317Sngie 155292317Sngie ipset = 0; 156292317Sngie role = IPL_LOGIPF; 157292317Sngie bzero((char *)&pnode, sizeof(pnode)); 158145860Sume bzero((char *)&hnode, sizeof(hnode)); 159145860Sume 160145860Sume while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1) 161292317Sngie switch (c) 162145860Sume { 163145860Sume case 'd' : 164145860Sume opts |= OPT_DEBUG; 165145860Sume ippool_yydebug++; 166145860Sume break; 167145860Sume case 'i' : 168145860Sume if (setnodeaddr(type, role, ptr, optarg) == 0) 169145860Sume ipset = 1; 170145860Sume break; 171145860Sume case 'm' : 172145860Sume poolname = optarg; 173145860Sume break; 174145857Sume case 'n' : 175145857Sume opts |= OPT_DONOTHING|OPT_DONTOPEN; 176145857Sume break; 177145857Sume case 'o' : 178145857Sume if (ipset == 1) { 179145857Sume fprintf(stderr, 180145857Sume "cannot set role after ip address\n"); 181145860Sume return -1; 182145857Sume } 183145860Sume role = getrole(optarg); 184292317Sngie if (role == IPL_LOGNONE) 185292317Sngie return -1; 186292317Sngie break; 187145860Sume case 'R' : 188145860Sume opts |= OPT_NORESOLVE; 189145860Sume break; 190145860Sume case 't' : 191145860Sume if (ipset == 1) { 192145860Sume fprintf(stderr, 193145860Sume "cannot set type after ip address\n"); 194145860Sume return -1; 195145860Sume } 196145860Sume type = gettype(optarg, NULL); 197145860Sume switch (type) { 198145860Sume case IPLT_NONE : 199145857Sume fprintf(stderr, "unknown type '%s'\n", optarg); 200145857Sume return -1; 201145857Sume case IPLT_HASH : 202145857Sume ptr = &hnode; 203145857Sume break; 204145857Sume case IPLT_POOL : 205145857Sume default : 206145857Sume break; 207145857Sume } 208145857Sume break; 209145857Sume case 'T' : 210145857Sume ttl = atoi(optarg); 211243346Semaste if (ttl < 0) { 212145857Sume fprintf(stderr, "cannot set negative ttl\n"); 213145857Sume return -1; 214145857Sume } 215145857Sume break; 216145857Sume case 'v' : 217145857Sume opts |= OPT_VERBOSE; 218145857Sume break; 219145857Sume } 220145857Sume 221292317Sngie if (argv[optind] != NULL && ipset == 0) { 222292317Sngie if (setnodeaddr(type, role, ptr, argv[optind]) == 0) 223292317Sngie ipset = 1; 224292317Sngie } 225292317Sngie 226292317Sngie if (opts & OPT_DEBUG) 227145857Sume fprintf(stderr, "poolnodecommand: opts = %#x\n", opts); 228145857Sume 229292317Sngie if (ipset == 0) { 230292317Sngie fprintf(stderr, "no IP address given with -i\n"); 231145857Sume return -1; 232145857Sume } 233145857Sume 234145857Sume if (poolname == NULL) { 235145857Sume fprintf(stderr, "poolname not given with add/remove node\n"); 236145857Sume return -1; 237145857Sume } 238145857Sume 239292317Sngie switch (type) { 240145857Sume case IPLT_POOL : 241292317Sngie if (remove == 0) 242145857Sume err = load_poolnode(role, poolname, &pnode, ttl, ioctl); 243292317Sngie else 244292317Sngie err = remove_poolnode(role, poolname, &pnode, ioctl); 245145857Sume break; 246292317Sngie case IPLT_HASH : 247292317Sngie if (remove == 0) 248145857Sume err = load_hashnode(role, poolname, &hnode, ttl, ioctl); 249292317Sngie else 250292317Sngie err = remove_hashnode(role, poolname, &hnode, ioctl); 251145857Sume break; 252145857Sume default : 253145857Sume break; 254145857Sume } 255145857Sume return err; 256145857Sume} 257145857Sume 258145857Sume 259145857Sumeint 260145857Sumepoolcommand(remove, argc, argv) 261145857Sume int remove, argc; 262145857Sume char *argv[]; 263145857Sume{ 264145857Sume int type, role, c, err; 265145857Sume char *poolname; 266145857Sume iphtable_t iph; 267145857Sume ip_pool_t pool; 268145857Sume 269145857Sume err = 1; 270292317Sngie role = 0; 271145857Sume type = 0; 272145857Sume poolname = NULL; 273145857Sume role = IPL_LOGIPF; 274145857Sume bzero((char *)&iph, sizeof(iph)); 275145857Sume bzero((char *)&pool, sizeof(pool)); 276145857Sume 277145857Sume while ((c = getopt(argc, argv, "dm:no:RSv")) != -1) 278145857Sume switch (c) 279145857Sume { 280145857Sume case 'd' : 281292317Sngie opts |= OPT_DEBUG; 282292317Sngie ippool_yydebug++; 283292317Sngie break; 284292317Sngie case 'm' : 285292317Sngie poolname = optarg; 286292317Sngie break; 287292317Sngie case 'n' : 288292317Sngie opts |= OPT_DONOTHING|OPT_DONTOPEN; 289292317Sngie break; 290292317Sngie case 'o' : 291292317Sngie role = getrole(optarg); 292292665Sngie if (role == IPL_LOGNONE) { 293292665Sngie fprintf(stderr, "unknown role '%s'\n", optarg); 294304950Sngie return -1; 295292665Sngie } 296292317Sngie break; 297292317Sngie case 'R' : 298292317Sngie opts |= OPT_NORESOLVE; 299292317Sngie break; 300292317Sngie case 'S' : 301292317Sngie iph.iph_seed = atoi(optarg); 302292665Sngie break; 303292665Sngie case 'v' : 304304950Sngie opts |= OPT_VERBOSE; 305292665Sngie break; 306292317Sngie } 307292317Sngie 308292317Sngie if (opts & OPT_DEBUG) 309292317Sngie fprintf(stderr, "poolcommand: opts = %#x\n", opts); 310292317Sngie 311292317Sngie if (poolname == NULL) { 312292665Sngie fprintf(stderr, "poolname not given with add/remove pool\n"); 313292665Sngie return -1; 314292665Sngie } 315304950Sngie 316292665Sngie type = gettype(argv[optind], &iph.iph_type); 317292317Sngie if (type == IPLT_NONE) { 318292317Sngie fprintf(stderr, "unknown type '%s'\n", argv[optind]); 319292317Sngie return -1; 320292317Sngie } 321292317Sngie 322292317Sngie if (type == IPLT_HASH) { 323292317Sngie strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); 324292317Sngie iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; 325292317Sngie iph.iph_unit = role; 326292317Sngie } else if (type == IPLT_POOL) { 327292317Sngie strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name)); 328292317Sngie pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0'; 329292317Sngie pool.ipo_unit = role; 330292317Sngie } 331292317Sngie 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#ifdef USE_INET6 1051 if (node->ipn_addr.adf_family == AF_INET) 1052#endif 1053 node->ipn_addr.adf_len = offsetof(addrfamily_t, 1054 adf_addr) + 1055 sizeof(struct in_addr); 1056#ifdef USE_INET6 1057 else 1058 node->ipn_addr.adf_len = offsetof(addrfamily_t, 1059 adf_addr) + 1060 sizeof(struct in6_addr); 1061#endif 1062 node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg); 1063 node->ipn_mask.adf_len = node->ipn_addr.adf_len; 1064 node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr; 1065 } else if (type == IPLT_HASH) { 1066 iphtent_t *node = ptr; 1067 1068 node->ipe_addr.in4.s_addr = inet_addr(arg); 1069 node->ipe_mask.in4.s_addr = mask.s_addr; 1070 node->ipe_family = AF_INET; 1071 node->ipe_unit = role; 1072 } 1073 1074 return 0; 1075} 1076