ippool.c revision 170268
1145519Sdarrenr/* $FreeBSD: head/contrib/ipfilter/tools/ippool.c 170268 2007-06-04 02:54:36Z darrenr $ */ 2145510Sdarrenr 3145510Sdarrenr/* 4170268Sdarrenr * Copyright (C) 2002-2006 by Darren Reed. 5145510Sdarrenr * 6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145510Sdarrenr */ 8145510Sdarrenr#include <sys/types.h> 9145510Sdarrenr#include <sys/time.h> 10145510Sdarrenr#include <sys/param.h> 11145510Sdarrenr#include <sys/socket.h> 12145510Sdarrenr#if defined(BSD) && (BSD >= 199306) 13145510Sdarrenr# include <sys/cdefs.h> 14145510Sdarrenr#endif 15145510Sdarrenr#include <sys/ioctl.h> 16145510Sdarrenr 17145510Sdarrenr#include <net/if.h> 18145510Sdarrenr#if __FreeBSD_version >= 300000 19145510Sdarrenr# include <net/if_var.h> 20145510Sdarrenr#endif 21145510Sdarrenr#include <netinet/in.h> 22145510Sdarrenr 23145510Sdarrenr#include <arpa/inet.h> 24145510Sdarrenr 25145510Sdarrenr#include <stdio.h> 26145510Sdarrenr#include <fcntl.h> 27145510Sdarrenr#include <stdlib.h> 28145510Sdarrenr#include <string.h> 29145510Sdarrenr#include <netdb.h> 30145510Sdarrenr#include <ctype.h> 31145510Sdarrenr#include <unistd.h> 32170268Sdarrenr#ifdef linux 33170268Sdarrenr# include <linux/a.out.h> 34170268Sdarrenr#else 35170268Sdarrenr# include <nlist.h> 36170268Sdarrenr#endif 37145510Sdarrenr 38145510Sdarrenr#include "ipf.h" 39170268Sdarrenr#include "netinet/ipl.h" 40145510Sdarrenr#include "netinet/ip_lookup.h" 41145510Sdarrenr#include "netinet/ip_pool.h" 42145510Sdarrenr#include "netinet/ip_htable.h" 43145510Sdarrenr#include "kmem.h" 44145510Sdarrenr 45145510Sdarrenr 46145510Sdarrenrextern int ippool_yyparse __P((void)); 47145510Sdarrenrextern int ippool_yydebug; 48145510Sdarrenrextern FILE *ippool_yyin; 49145510Sdarrenrextern char *optarg; 50145510Sdarrenrextern int lineNum; 51145510Sdarrenr 52145510Sdarrenrvoid usage __P((char *)); 53145510Sdarrenrint main __P((int, char **)); 54145510Sdarrenrint poolcommand __P((int, int, char *[])); 55145510Sdarrenrint poolnodecommand __P((int, int, char *[])); 56145510Sdarrenrint loadpoolfile __P((int, char *[], char *)); 57145510Sdarrenrint poollist __P((int, char *[])); 58170268Sdarrenrvoid poollist_dead __P((int, char *, int, char *, char *)); 59170268Sdarrenrvoid poollist_live __P((int, char *, int, int)); 60145510Sdarrenrint poolflush __P((int, char *[])); 61145510Sdarrenrint poolstats __P((int, char *[])); 62145510Sdarrenrint gettype __P((char *, u_int *)); 63145510Sdarrenrint getrole __P((char *)); 64170268Sdarrenrint setnodeaddr __P((ip_pool_node_t *node, char *arg)); 65170268Sdarrenrvoid showpools_live __P((int, int, ip_pool_stat_t *, char *)); 66170268Sdarrenrvoid showhashs_live __P((int, int, iphtstat_t *, char *)); 67145510Sdarrenr 68145510Sdarrenrint opts = 0; 69145510Sdarrenrint fd = -1; 70145510Sdarrenrint use_inet6 = 0; 71145510Sdarrenr 72145510Sdarrenr 73145510Sdarrenrvoid usage(prog) 74145510Sdarrenrchar *prog; 75145510Sdarrenr{ 76145510Sdarrenr fprintf(stderr, "Usage:\t%s\n", prog); 77145510Sdarrenr fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n"); 78145510Sdarrenr fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n"); 79145510Sdarrenr fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n"); 80145510Sdarrenr fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n"); 81145510Sdarrenr fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n"); 82145510Sdarrenr fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n"); 83145510Sdarrenr fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n"); 84145510Sdarrenr fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n"); 85145510Sdarrenr exit(1); 86145510Sdarrenr} 87145510Sdarrenr 88145510Sdarrenr 89145510Sdarrenrint main(argc, argv) 90145510Sdarrenrint argc; 91145510Sdarrenrchar *argv[]; 92145510Sdarrenr{ 93145510Sdarrenr int err; 94145510Sdarrenr 95145510Sdarrenr if (argc < 2) 96145510Sdarrenr usage(argv[0]); 97145510Sdarrenr 98145510Sdarrenr switch (getopt(argc, argv, "aAf:FlrRs")) 99145510Sdarrenr { 100145510Sdarrenr case 'a' : 101145510Sdarrenr err = poolnodecommand(0, argc, argv); 102145510Sdarrenr break; 103145510Sdarrenr case 'A' : 104145510Sdarrenr err = poolcommand(0, argc, argv); 105145510Sdarrenr break; 106145510Sdarrenr case 'f' : 107145510Sdarrenr err = loadpoolfile(argc, argv, optarg); 108145510Sdarrenr break; 109145510Sdarrenr case 'F' : 110145510Sdarrenr err = poolflush(argc, argv); 111145510Sdarrenr break; 112145510Sdarrenr case 'l' : 113145510Sdarrenr err = poollist(argc, argv); 114145510Sdarrenr break; 115145510Sdarrenr case 'r' : 116145510Sdarrenr err = poolnodecommand(1, argc, argv); 117145510Sdarrenr break; 118145510Sdarrenr case 'R' : 119145510Sdarrenr err = poolcommand(1, argc, argv); 120145510Sdarrenr break; 121145510Sdarrenr case 's' : 122145510Sdarrenr err = poolstats(argc, argv); 123145510Sdarrenr break; 124145510Sdarrenr default : 125145510Sdarrenr exit(1); 126145510Sdarrenr } 127145510Sdarrenr 128170268Sdarrenr if (err != 0) 129170268Sdarrenr exit(1); 130170268Sdarrenr return 0; 131145510Sdarrenr} 132145510Sdarrenr 133145510Sdarrenr 134145510Sdarrenrint poolnodecommand(remove, argc, argv) 135145510Sdarrenrint remove, argc; 136145510Sdarrenrchar *argv[]; 137145510Sdarrenr{ 138145510Sdarrenr int err, c, ipset, role; 139170268Sdarrenr char *poolname = NULL; 140145510Sdarrenr ip_pool_node_t node; 141145510Sdarrenr 142145510Sdarrenr ipset = 0; 143145510Sdarrenr role = IPL_LOGIPF; 144145510Sdarrenr bzero((char *)&node, sizeof(node)); 145145510Sdarrenr 146145510Sdarrenr while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1) 147145510Sdarrenr switch (c) 148145510Sdarrenr { 149145510Sdarrenr case 'd' : 150145510Sdarrenr opts |= OPT_DEBUG; 151145510Sdarrenr ippool_yydebug++; 152145510Sdarrenr break; 153145510Sdarrenr case 'i' : 154170268Sdarrenr if (setnodeaddr(&node, optarg) == 0) 155170268Sdarrenr ipset = 1; 156145510Sdarrenr break; 157145510Sdarrenr case 'm' : 158145510Sdarrenr poolname = optarg; 159145510Sdarrenr break; 160145510Sdarrenr case 'n' : 161145510Sdarrenr opts |= OPT_DONOTHING; 162145510Sdarrenr break; 163145510Sdarrenr case 'o' : 164145510Sdarrenr role = getrole(optarg); 165145510Sdarrenr if (role == IPL_LOGNONE) 166145510Sdarrenr return -1; 167145510Sdarrenr break; 168145510Sdarrenr case 'R' : 169145510Sdarrenr opts |= OPT_NORESOLVE; 170145510Sdarrenr break; 171145510Sdarrenr case 'v' : 172145510Sdarrenr opts |= OPT_VERBOSE; 173145510Sdarrenr break; 174145510Sdarrenr } 175145510Sdarrenr 176170268Sdarrenr if (argv[optind] != NULL && ipset == 0) { 177170268Sdarrenr if (setnodeaddr(&node, argv[optind]) == 0) 178170268Sdarrenr ipset = 1; 179170268Sdarrenr } 180170268Sdarrenr 181145510Sdarrenr if (opts & OPT_DEBUG) 182145510Sdarrenr fprintf(stderr, "poolnodecommand: opts = %#x\n", opts); 183145510Sdarrenr 184170268Sdarrenr if (ipset == 0) { 185170268Sdarrenr fprintf(stderr, "no IP address given with -i\n"); 186145510Sdarrenr return -1; 187170268Sdarrenr } 188170268Sdarrenr 189145510Sdarrenr if (poolname == NULL) { 190145510Sdarrenr fprintf(stderr, "poolname not given with add/remove node\n"); 191145510Sdarrenr return -1; 192145510Sdarrenr } 193145510Sdarrenr 194145510Sdarrenr if (remove == 0) 195145510Sdarrenr err = load_poolnode(0, poolname, &node, ioctl); 196145510Sdarrenr else 197145510Sdarrenr err = remove_poolnode(0, poolname, &node, ioctl); 198145510Sdarrenr return err; 199145510Sdarrenr} 200145510Sdarrenr 201145510Sdarrenr 202145510Sdarrenrint poolcommand(remove, argc, argv) 203145510Sdarrenrint remove, argc; 204145510Sdarrenrchar *argv[]; 205145510Sdarrenr{ 206145510Sdarrenr int type, role, c, err; 207145510Sdarrenr char *poolname; 208145510Sdarrenr iphtable_t iph; 209145510Sdarrenr ip_pool_t pool; 210145510Sdarrenr 211145510Sdarrenr err = 1; 212145510Sdarrenr role = 0; 213145510Sdarrenr type = 0; 214145510Sdarrenr poolname = NULL; 215145510Sdarrenr role = IPL_LOGIPF; 216145510Sdarrenr bzero((char *)&iph, sizeof(iph)); 217145510Sdarrenr bzero((char *)&pool, sizeof(pool)); 218145510Sdarrenr 219145510Sdarrenr while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1) 220145510Sdarrenr switch (c) 221145510Sdarrenr { 222145510Sdarrenr case 'd' : 223145510Sdarrenr opts |= OPT_DEBUG; 224145510Sdarrenr ippool_yydebug++; 225145510Sdarrenr break; 226145510Sdarrenr case 'm' : 227145510Sdarrenr poolname = optarg; 228145510Sdarrenr break; 229145510Sdarrenr case 'n' : 230145510Sdarrenr opts |= OPT_DONOTHING; 231145510Sdarrenr break; 232145510Sdarrenr case 'o' : 233145510Sdarrenr role = getrole(optarg); 234145510Sdarrenr if (role == IPL_LOGNONE) { 235145510Sdarrenr fprintf(stderr, "unknown role '%s'\n", optarg); 236145510Sdarrenr return -1; 237145510Sdarrenr } 238145510Sdarrenr break; 239145510Sdarrenr case 'R' : 240145510Sdarrenr opts |= OPT_NORESOLVE; 241145510Sdarrenr break; 242145510Sdarrenr case 'S' : 243145510Sdarrenr iph.iph_seed = atoi(optarg); 244145510Sdarrenr break; 245145510Sdarrenr case 't' : 246145510Sdarrenr type = gettype(optarg, &iph.iph_type); 247145510Sdarrenr if (type == IPLT_NONE) { 248145510Sdarrenr fprintf(stderr, "unknown type '%s'\n", optarg); 249145510Sdarrenr return -1; 250145510Sdarrenr } 251145510Sdarrenr break; 252145510Sdarrenr case 'v' : 253145510Sdarrenr opts |= OPT_VERBOSE; 254145510Sdarrenr break; 255145510Sdarrenr } 256145510Sdarrenr 257145510Sdarrenr if (opts & OPT_DEBUG) 258145510Sdarrenr fprintf(stderr, "poolcommand: opts = %#x\n", opts); 259145510Sdarrenr 260145510Sdarrenr if (poolname == NULL) { 261145510Sdarrenr fprintf(stderr, "poolname not given with add/remove pool\n"); 262145510Sdarrenr return -1; 263145510Sdarrenr } 264145510Sdarrenr 265145510Sdarrenr if (type == IPLT_HASH) { 266145510Sdarrenr strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); 267145510Sdarrenr iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; 268145510Sdarrenr iph.iph_unit = role; 269145510Sdarrenr } else if (type == IPLT_POOL) { 270145510Sdarrenr strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name)); 271145510Sdarrenr pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0'; 272145510Sdarrenr pool.ipo_unit = role; 273145510Sdarrenr } 274145510Sdarrenr 275145510Sdarrenr if (remove == 0) { 276145510Sdarrenr switch (type) 277145510Sdarrenr { 278145510Sdarrenr case IPLT_HASH : 279145510Sdarrenr err = load_hash(&iph, NULL, ioctl); 280145510Sdarrenr break; 281145510Sdarrenr case IPLT_POOL : 282145510Sdarrenr err = load_pool(&pool, ioctl); 283145510Sdarrenr break; 284145510Sdarrenr } 285145510Sdarrenr } else { 286145510Sdarrenr switch (type) 287145510Sdarrenr { 288145510Sdarrenr case IPLT_HASH : 289145510Sdarrenr err = remove_hash(&iph, ioctl); 290145510Sdarrenr break; 291145510Sdarrenr case IPLT_POOL : 292145510Sdarrenr err = remove_pool(&pool, ioctl); 293145510Sdarrenr break; 294145510Sdarrenr } 295145510Sdarrenr } 296145510Sdarrenr return err; 297145510Sdarrenr} 298145510Sdarrenr 299145510Sdarrenr 300145510Sdarrenrint loadpoolfile(argc, argv, infile) 301145510Sdarrenrint argc; 302145510Sdarrenrchar *argv[], *infile; 303145510Sdarrenr{ 304145510Sdarrenr int c; 305145510Sdarrenr 306145510Sdarrenr infile = optarg; 307145510Sdarrenr 308145510Sdarrenr while ((c = getopt(argc, argv, "dnRuv")) != -1) 309145510Sdarrenr switch (c) 310145510Sdarrenr { 311145510Sdarrenr case 'd' : 312145510Sdarrenr opts |= OPT_DEBUG; 313145510Sdarrenr ippool_yydebug++; 314145510Sdarrenr break; 315145510Sdarrenr case 'n' : 316145510Sdarrenr opts |= OPT_DONOTHING; 317145510Sdarrenr break; 318145510Sdarrenr case 'R' : 319145510Sdarrenr opts |= OPT_NORESOLVE; 320145510Sdarrenr break; 321145510Sdarrenr case 'u' : 322145510Sdarrenr opts |= OPT_REMOVE; 323145510Sdarrenr break; 324145510Sdarrenr case 'v' : 325145510Sdarrenr opts |= OPT_VERBOSE; 326145510Sdarrenr break; 327145510Sdarrenr } 328145510Sdarrenr 329145510Sdarrenr if (opts & OPT_DEBUG) 330145510Sdarrenr fprintf(stderr, "loadpoolfile: opts = %#x\n", opts); 331145510Sdarrenr 332145510Sdarrenr if (!(opts & OPT_DONOTHING) && (fd == -1)) { 333145510Sdarrenr fd = open(IPLOOKUP_NAME, O_RDWR); 334145510Sdarrenr if (fd == -1) { 335145510Sdarrenr perror("open(IPLOOKUP_NAME)"); 336145510Sdarrenr exit(1); 337145510Sdarrenr } 338145510Sdarrenr } 339145510Sdarrenr 340145510Sdarrenr if (ippool_parsefile(fd, infile, ioctl) != 0) 341145510Sdarrenr return -1; 342145510Sdarrenr return 0; 343145510Sdarrenr} 344145510Sdarrenr 345145510Sdarrenr 346145510Sdarrenrint poolstats(argc, argv) 347145510Sdarrenrint argc; 348145510Sdarrenrchar *argv[]; 349145510Sdarrenr{ 350145510Sdarrenr int c, type, role, live_kernel; 351145510Sdarrenr ip_pool_stat_t plstat; 352145510Sdarrenr char *kernel, *core; 353145510Sdarrenr iphtstat_t htstat; 354145510Sdarrenr iplookupop_t op; 355145510Sdarrenr 356145510Sdarrenr core = NULL; 357145510Sdarrenr kernel = NULL; 358145510Sdarrenr live_kernel = 1; 359145510Sdarrenr type = IPLT_ALL; 360145510Sdarrenr role = IPL_LOGALL; 361145510Sdarrenr 362145510Sdarrenr bzero((char *)&op, sizeof(op)); 363145510Sdarrenr 364145510Sdarrenr while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1) 365145510Sdarrenr switch (c) 366145510Sdarrenr { 367145510Sdarrenr case 'd' : 368145510Sdarrenr opts |= OPT_DEBUG; 369145510Sdarrenr break; 370145510Sdarrenr case 'M' : 371145510Sdarrenr live_kernel = 0; 372145510Sdarrenr core = optarg; 373145510Sdarrenr break; 374145510Sdarrenr case 'N' : 375145510Sdarrenr live_kernel = 0; 376145510Sdarrenr kernel = optarg; 377145510Sdarrenr break; 378145510Sdarrenr case 'o' : 379145510Sdarrenr role = getrole(optarg); 380145510Sdarrenr if (role == IPL_LOGNONE) { 381145510Sdarrenr fprintf(stderr, "unknown role '%s'\n", optarg); 382145510Sdarrenr return -1; 383145510Sdarrenr } 384145510Sdarrenr break; 385145510Sdarrenr case 't' : 386145510Sdarrenr type = gettype(optarg, NULL); 387145510Sdarrenr if (type != IPLT_POOL) { 388145510Sdarrenr fprintf(stderr, 389145510Sdarrenr "-s not supported for this type yet\n"); 390145510Sdarrenr return -1; 391145510Sdarrenr } 392145510Sdarrenr break; 393145510Sdarrenr case 'v' : 394145510Sdarrenr opts |= OPT_VERBOSE; 395145510Sdarrenr break; 396145510Sdarrenr } 397145510Sdarrenr 398145510Sdarrenr if (opts & OPT_DEBUG) 399145510Sdarrenr fprintf(stderr, "poolstats: opts = %#x\n", opts); 400145510Sdarrenr 401145510Sdarrenr if (!(opts & OPT_DONOTHING) && (fd == -1)) { 402145510Sdarrenr fd = open(IPLOOKUP_NAME, O_RDWR); 403145510Sdarrenr if (fd == -1) { 404145510Sdarrenr perror("open(IPLOOKUP_NAME)"); 405145510Sdarrenr exit(1); 406145510Sdarrenr } 407145510Sdarrenr } 408145510Sdarrenr 409145510Sdarrenr if (type == IPLT_ALL || type == IPLT_POOL) { 410145510Sdarrenr op.iplo_type = IPLT_POOL; 411145510Sdarrenr op.iplo_struct = &plstat; 412145510Sdarrenr op.iplo_size = sizeof(plstat); 413145510Sdarrenr if (!(opts & OPT_DONOTHING)) { 414145510Sdarrenr c = ioctl(fd, SIOCLOOKUPSTAT, &op); 415145510Sdarrenr if (c == -1) { 416145510Sdarrenr perror("ioctl(SIOCLOOKUPSTAT)"); 417145510Sdarrenr return -1; 418145510Sdarrenr } 419145510Sdarrenr printf("Pools:\t%lu\n", plstat.ipls_pools); 420145510Sdarrenr printf("Nodes:\t%lu\n", plstat.ipls_nodes); 421145510Sdarrenr } 422145510Sdarrenr } 423145510Sdarrenr 424145510Sdarrenr if (type == IPLT_ALL || type == IPLT_HASH) { 425145510Sdarrenr op.iplo_type = IPLT_HASH; 426145510Sdarrenr op.iplo_struct = &htstat; 427145510Sdarrenr op.iplo_size = sizeof(htstat); 428145510Sdarrenr if (!(opts & OPT_DONOTHING)) { 429145510Sdarrenr c = ioctl(fd, SIOCLOOKUPSTAT, &op); 430145510Sdarrenr if (c == -1) { 431145510Sdarrenr perror("ioctl(SIOCLOOKUPSTAT)"); 432145510Sdarrenr return -1; 433145510Sdarrenr } 434145510Sdarrenr printf("Hash Tables:\t%lu\n", htstat.iphs_numtables); 435145510Sdarrenr printf("Nodes:\t%lu\n", htstat.iphs_numnodes); 436145510Sdarrenr printf("Out of Memory:\t%lu\n", htstat.iphs_nomem); 437145510Sdarrenr } 438145510Sdarrenr } 439145510Sdarrenr return 0; 440145510Sdarrenr} 441145510Sdarrenr 442145510Sdarrenr 443145510Sdarrenrint poolflush(argc, argv) 444145510Sdarrenrint argc; 445145510Sdarrenrchar *argv[]; 446145510Sdarrenr{ 447145510Sdarrenr int c, role, type, arg; 448145510Sdarrenr iplookupflush_t flush; 449145510Sdarrenr 450145510Sdarrenr arg = IPLT_ALL; 451145510Sdarrenr type = IPLT_ALL; 452145510Sdarrenr role = IPL_LOGALL; 453145510Sdarrenr 454145510Sdarrenr while ((c = getopt(argc, argv, "do:t:v")) != -1) 455145510Sdarrenr switch (c) 456145510Sdarrenr { 457145510Sdarrenr case 'd' : 458145510Sdarrenr opts |= OPT_DEBUG; 459145510Sdarrenr break; 460145510Sdarrenr case 'o' : 461145510Sdarrenr role = getrole(optarg); 462145510Sdarrenr if (role == IPL_LOGNONE) { 463145510Sdarrenr fprintf(stderr, "unknown role '%s'\n", optarg); 464145510Sdarrenr return -1; 465145510Sdarrenr } 466145510Sdarrenr break; 467145510Sdarrenr case 't' : 468145510Sdarrenr type = gettype(optarg, NULL); 469145510Sdarrenr if (type == IPLT_NONE) { 470145510Sdarrenr fprintf(stderr, "unknown type '%s'\n", optarg); 471145510Sdarrenr return -1; 472145510Sdarrenr } 473145510Sdarrenr break; 474145510Sdarrenr case 'v' : 475145510Sdarrenr opts |= OPT_VERBOSE; 476145510Sdarrenr break; 477145510Sdarrenr } 478145510Sdarrenr 479145510Sdarrenr if (opts & OPT_DEBUG) 480145510Sdarrenr fprintf(stderr, "poolflush: opts = %#x\n", opts); 481145510Sdarrenr 482145510Sdarrenr if (!(opts & OPT_DONOTHING) && (fd == -1)) { 483145510Sdarrenr fd = open(IPLOOKUP_NAME, O_RDWR); 484145510Sdarrenr if (fd == -1) { 485145510Sdarrenr perror("open(IPLOOKUP_NAME)"); 486145510Sdarrenr exit(1); 487145510Sdarrenr } 488145510Sdarrenr } 489145510Sdarrenr 490145510Sdarrenr bzero((char *)&flush, sizeof(flush)); 491145510Sdarrenr flush.iplf_type = type; 492145510Sdarrenr flush.iplf_unit = role; 493145510Sdarrenr flush.iplf_arg = arg; 494145510Sdarrenr 495145510Sdarrenr if (!(opts & OPT_DONOTHING)) { 496145510Sdarrenr if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { 497145510Sdarrenr perror("ioctl(SIOCLOOKUPFLUSH)"); 498145510Sdarrenr exit(1); 499145510Sdarrenr } 500145510Sdarrenr 501145510Sdarrenr } 502145630Sdarrenr printf("%zd object%s flushed\n", flush.iplf_count, 503145510Sdarrenr (flush.iplf_count == 1) ? "" : "s"); 504145510Sdarrenr 505145510Sdarrenr return 0; 506145510Sdarrenr} 507145510Sdarrenr 508145510Sdarrenr 509145510Sdarrenrint getrole(rolename) 510145510Sdarrenrchar *rolename; 511145510Sdarrenr{ 512145510Sdarrenr int role; 513145510Sdarrenr 514145510Sdarrenr if (!strcasecmp(rolename, "ipf")) { 515145510Sdarrenr role = IPL_LOGIPF; 516145510Sdarrenr#if 0 517145510Sdarrenr } else if (!strcasecmp(rolename, "nat")) { 518145510Sdarrenr role = IPL_LOGNAT; 519145510Sdarrenr } else if (!strcasecmp(rolename, "state")) { 520145510Sdarrenr role = IPL_LOGSTATE; 521145510Sdarrenr } else if (!strcasecmp(rolename, "auth")) { 522145510Sdarrenr role = IPL_LOGAUTH; 523145510Sdarrenr } else if (!strcasecmp(rolename, "sync")) { 524145510Sdarrenr role = IPL_LOGSYNC; 525145510Sdarrenr } else if (!strcasecmp(rolename, "scan")) { 526145510Sdarrenr role = IPL_LOGSCAN; 527145510Sdarrenr } else if (!strcasecmp(rolename, "pool")) { 528145510Sdarrenr role = IPL_LOGLOOKUP; 529145510Sdarrenr } else if (!strcasecmp(rolename, "count")) { 530145510Sdarrenr role = IPL_LOGCOUNT; 531145510Sdarrenr#endif 532145510Sdarrenr } else { 533145510Sdarrenr role = IPL_LOGNONE; 534145510Sdarrenr } 535145510Sdarrenr 536145510Sdarrenr return role; 537145510Sdarrenr} 538145510Sdarrenr 539145510Sdarrenr 540145510Sdarrenrint gettype(typename, minor) 541145510Sdarrenrchar *typename; 542145510Sdarrenru_int *minor; 543145510Sdarrenr{ 544145510Sdarrenr int type; 545145510Sdarrenr 546170268Sdarrenr if (!strcasecmp(optarg, "tree") || !strcasecmp(optarg, "pool")) { 547145510Sdarrenr type = IPLT_POOL; 548145510Sdarrenr } else if (!strcasecmp(optarg, "hash")) { 549145510Sdarrenr type = IPLT_HASH; 550145510Sdarrenr if (minor != NULL) 551145510Sdarrenr *minor = IPHASH_LOOKUP; 552145510Sdarrenr } else if (!strcasecmp(optarg, "group-map")) { 553145510Sdarrenr type = IPLT_HASH; 554145510Sdarrenr if (minor != NULL) 555145510Sdarrenr *minor = IPHASH_GROUPMAP; 556145510Sdarrenr } else { 557145510Sdarrenr type = IPLT_NONE; 558145510Sdarrenr } 559145510Sdarrenr return type; 560145510Sdarrenr} 561170268Sdarrenr 562170268Sdarrenr 563170268Sdarrenrint poollist(argc, argv) 564170268Sdarrenrint argc; 565170268Sdarrenrchar *argv[]; 566170268Sdarrenr{ 567170268Sdarrenr char *kernel, *core, *poolname; 568170268Sdarrenr int c, role, type, live_kernel; 569170268Sdarrenr iplookupop_t op; 570170268Sdarrenr 571170268Sdarrenr core = NULL; 572170268Sdarrenr kernel = NULL; 573170268Sdarrenr live_kernel = 1; 574170268Sdarrenr type = IPLT_ALL; 575170268Sdarrenr poolname = NULL; 576170268Sdarrenr role = IPL_LOGALL; 577170268Sdarrenr 578170268Sdarrenr while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1) 579170268Sdarrenr switch (c) 580170268Sdarrenr { 581170268Sdarrenr case 'd' : 582170268Sdarrenr opts |= OPT_DEBUG; 583170268Sdarrenr break; 584170268Sdarrenr case 'm' : 585170268Sdarrenr poolname = optarg; 586170268Sdarrenr break; 587170268Sdarrenr case 'M' : 588170268Sdarrenr live_kernel = 0; 589170268Sdarrenr core = optarg; 590170268Sdarrenr break; 591170268Sdarrenr case 'N' : 592170268Sdarrenr live_kernel = 0; 593170268Sdarrenr kernel = optarg; 594170268Sdarrenr break; 595170268Sdarrenr case 'o' : 596170268Sdarrenr role = getrole(optarg); 597170268Sdarrenr if (role == IPL_LOGNONE) { 598170268Sdarrenr fprintf(stderr, "unknown role '%s'\n", optarg); 599170268Sdarrenr return -1; 600170268Sdarrenr } 601170268Sdarrenr break; 602170268Sdarrenr case 'R' : 603170268Sdarrenr opts |= OPT_NORESOLVE; 604170268Sdarrenr break; 605170268Sdarrenr case 't' : 606170268Sdarrenr type = gettype(optarg, NULL); 607170268Sdarrenr if (type == IPLT_NONE) { 608170268Sdarrenr fprintf(stderr, "unknown type '%s'\n", optarg); 609170268Sdarrenr return -1; 610170268Sdarrenr } 611170268Sdarrenr break; 612170268Sdarrenr case 'v' : 613170268Sdarrenr opts |= OPT_VERBOSE; 614170268Sdarrenr break; 615170268Sdarrenr } 616170268Sdarrenr 617170268Sdarrenr if (opts & OPT_DEBUG) 618170268Sdarrenr fprintf(stderr, "poollist: opts = %#x\n", opts); 619170268Sdarrenr 620170268Sdarrenr if (!(opts & OPT_DONOTHING) && (fd == -1)) { 621170268Sdarrenr fd = open(IPLOOKUP_NAME, O_RDWR); 622170268Sdarrenr if (fd == -1) { 623170268Sdarrenr perror("open(IPLOOKUP_NAME)"); 624170268Sdarrenr exit(1); 625170268Sdarrenr } 626170268Sdarrenr } 627170268Sdarrenr 628170268Sdarrenr bzero((char *)&op, sizeof(op)); 629170268Sdarrenr if (poolname != NULL) { 630170268Sdarrenr strncpy(op.iplo_name, poolname, sizeof(op.iplo_name)); 631170268Sdarrenr op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 632170268Sdarrenr } 633170268Sdarrenr op.iplo_unit = role; 634170268Sdarrenr 635170268Sdarrenr if (live_kernel) 636170268Sdarrenr poollist_live(role, poolname, type, fd); 637170268Sdarrenr else 638170268Sdarrenr poollist_dead(role, poolname, type, kernel, core); 639170268Sdarrenr return 0; 640170268Sdarrenr} 641170268Sdarrenr 642170268Sdarrenr 643170268Sdarrenrvoid poollist_dead(role, poolname, type, kernel, core) 644170268Sdarrenrint role, type; 645170268Sdarrenrchar *poolname, *kernel, *core; 646170268Sdarrenr{ 647170268Sdarrenr iphtable_t *hptr; 648170268Sdarrenr ip_pool_t *ptr; 649170268Sdarrenr 650170268Sdarrenr if (openkmem(kernel, core) == -1) 651170268Sdarrenr exit(-1); 652170268Sdarrenr 653170268Sdarrenr if (type == IPLT_ALL || type == IPLT_POOL) { 654170268Sdarrenr ip_pool_t *pools[IPL_LOGSIZE]; 655170268Sdarrenr struct nlist names[2] = { { "ip_pool_list" } , { "" } }; 656170268Sdarrenr 657170268Sdarrenr if (nlist(kernel, names) != 1) 658170268Sdarrenr return; 659170268Sdarrenr 660170268Sdarrenr bzero(&pools, sizeof(pools)); 661170268Sdarrenr if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools))) 662170268Sdarrenr return; 663170268Sdarrenr 664170268Sdarrenr if (role != IPL_LOGALL) { 665170268Sdarrenr ptr = pools[role]; 666170268Sdarrenr while (ptr != NULL) { 667170268Sdarrenr ptr = printpool(ptr, kmemcpywrap, poolname, 668170268Sdarrenr opts); 669170268Sdarrenr } 670170268Sdarrenr } else { 671170268Sdarrenr for (role = 0; role <= IPL_LOGMAX; role++) { 672170268Sdarrenr ptr = pools[role]; 673170268Sdarrenr while (ptr != NULL) { 674170268Sdarrenr ptr = printpool(ptr, kmemcpywrap, 675170268Sdarrenr poolname, opts); 676170268Sdarrenr } 677170268Sdarrenr } 678170268Sdarrenr role = IPL_LOGALL; 679170268Sdarrenr } 680170268Sdarrenr } 681170268Sdarrenr if (type == IPLT_ALL || type == IPLT_HASH) { 682170268Sdarrenr iphtable_t *tables[IPL_LOGSIZE]; 683170268Sdarrenr struct nlist names[2] = { { "ipf_htables" } , { "" } }; 684170268Sdarrenr 685170268Sdarrenr if (nlist(kernel, names) != 1) 686170268Sdarrenr return; 687170268Sdarrenr 688170268Sdarrenr bzero(&tables, sizeof(tables)); 689170268Sdarrenr if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables))) 690170268Sdarrenr return; 691170268Sdarrenr 692170268Sdarrenr if (role != IPL_LOGALL) { 693170268Sdarrenr hptr = tables[role]; 694170268Sdarrenr while (hptr != NULL) { 695170268Sdarrenr hptr = printhash(hptr, kmemcpywrap, 696170268Sdarrenr poolname, opts); 697170268Sdarrenr } 698170268Sdarrenr } else { 699170268Sdarrenr for (role = 0; role <= IPL_LOGMAX; role++) { 700170268Sdarrenr hptr = tables[role]; 701170268Sdarrenr while (hptr != NULL) { 702170268Sdarrenr hptr = printhash(hptr, kmemcpywrap, 703170268Sdarrenr poolname, opts); 704170268Sdarrenr } 705170268Sdarrenr } 706170268Sdarrenr } 707170268Sdarrenr } 708170268Sdarrenr} 709170268Sdarrenr 710170268Sdarrenr 711170268Sdarrenrvoid poollist_live(role, poolname, type, fd) 712170268Sdarrenrint role, type, fd; 713170268Sdarrenrchar *poolname; 714170268Sdarrenr{ 715170268Sdarrenr ip_pool_stat_t plstat; 716170268Sdarrenr iphtstat_t htstat; 717170268Sdarrenr iplookupop_t op; 718170268Sdarrenr int c; 719170268Sdarrenr 720170268Sdarrenr if (type == IPLT_ALL || type == IPLT_POOL) { 721170268Sdarrenr op.iplo_type = IPLT_POOL; 722170268Sdarrenr op.iplo_size = sizeof(plstat); 723170268Sdarrenr op.iplo_struct = &plstat; 724170268Sdarrenr op.iplo_name[0] = '\0'; 725170268Sdarrenr op.iplo_arg = 0; 726170268Sdarrenr 727170268Sdarrenr if (role != IPL_LOGALL) { 728170268Sdarrenr op.iplo_unit = role; 729170268Sdarrenr 730170268Sdarrenr c = ioctl(fd, SIOCLOOKUPSTAT, &op); 731170268Sdarrenr if (c == -1) { 732170268Sdarrenr perror("ioctl(SIOCLOOKUPSTAT)"); 733170268Sdarrenr return; 734170268Sdarrenr } 735170268Sdarrenr 736170268Sdarrenr showpools_live(fd, role, &plstat, poolname); 737170268Sdarrenr } else { 738170268Sdarrenr for (role = 0; role <= IPL_LOGMAX; role++) { 739170268Sdarrenr op.iplo_unit = role; 740170268Sdarrenr 741170268Sdarrenr c = ioctl(fd, SIOCLOOKUPSTAT, &op); 742170268Sdarrenr if (c == -1) { 743170268Sdarrenr perror("ioctl(SIOCLOOKUPSTAT)"); 744170268Sdarrenr return; 745170268Sdarrenr } 746170268Sdarrenr 747170268Sdarrenr showpools_live(fd, role, &plstat, poolname); 748170268Sdarrenr } 749170268Sdarrenr 750170268Sdarrenr role = IPL_LOGALL; 751170268Sdarrenr } 752170268Sdarrenr } 753170268Sdarrenr 754170268Sdarrenr if (type == IPLT_ALL || type == IPLT_HASH) { 755170268Sdarrenr op.iplo_type = IPLT_HASH; 756170268Sdarrenr op.iplo_size = sizeof(htstat); 757170268Sdarrenr op.iplo_struct = &htstat; 758170268Sdarrenr op.iplo_name[0] = '\0'; 759170268Sdarrenr op.iplo_arg = 0; 760170268Sdarrenr 761170268Sdarrenr if (role != IPL_LOGALL) { 762170268Sdarrenr op.iplo_unit = role; 763170268Sdarrenr 764170268Sdarrenr c = ioctl(fd, SIOCLOOKUPSTAT, &op); 765170268Sdarrenr if (c == -1) { 766170268Sdarrenr perror("ioctl(SIOCLOOKUPSTAT)"); 767170268Sdarrenr return; 768170268Sdarrenr } 769170268Sdarrenr showhashs_live(fd, role, &htstat, poolname); 770170268Sdarrenr } else { 771170268Sdarrenr for (role = 0; role <= IPL_LOGMAX; role++) { 772170268Sdarrenr 773170268Sdarrenr op.iplo_unit = role; 774170268Sdarrenr c = ioctl(fd, SIOCLOOKUPSTAT, &op); 775170268Sdarrenr if (c == -1) { 776170268Sdarrenr perror("ioctl(SIOCLOOKUPSTAT)"); 777170268Sdarrenr return; 778170268Sdarrenr } 779170268Sdarrenr 780170268Sdarrenr showhashs_live(fd, role, &htstat, poolname); 781170268Sdarrenr } 782170268Sdarrenr } 783170268Sdarrenr } 784170268Sdarrenr} 785170268Sdarrenr 786170268Sdarrenr 787170268Sdarrenrvoid showpools_live(fd, role, plstp, poolname) 788170268Sdarrenrint fd, role; 789170268Sdarrenrip_pool_stat_t *plstp; 790170268Sdarrenrchar *poolname; 791170268Sdarrenr{ 792170268Sdarrenr ipflookupiter_t iter; 793170268Sdarrenr ip_pool_t pool; 794170268Sdarrenr ipfobj_t obj; 795170268Sdarrenr 796170268Sdarrenr obj.ipfo_rev = IPFILTER_VERSION; 797170268Sdarrenr obj.ipfo_type = IPFOBJ_LOOKUPITER; 798170268Sdarrenr obj.ipfo_size = sizeof(iter); 799170268Sdarrenr obj.ipfo_ptr = &iter; 800170268Sdarrenr 801170268Sdarrenr iter.ili_type = IPLT_POOL; 802170268Sdarrenr iter.ili_otype = IPFLOOKUPITER_LIST; 803170268Sdarrenr iter.ili_ival = IPFGENITER_LOOKUP; 804170268Sdarrenr iter.ili_nitems = 1; 805170268Sdarrenr iter.ili_data = &pool; 806170268Sdarrenr iter.ili_unit = role; 807170268Sdarrenr *iter.ili_name = '\0'; 808170268Sdarrenr 809170268Sdarrenr while (plstp->ipls_list[role] != NULL) { 810170268Sdarrenr if (ioctl(fd, SIOCLOOKUPITER, &obj)) { 811170268Sdarrenr perror("ioctl(SIOCLOOKUPITER)"); 812170268Sdarrenr break; 813170268Sdarrenr } 814170268Sdarrenr printpool_live(&pool, fd, poolname, opts); 815170268Sdarrenr 816170268Sdarrenr plstp->ipls_list[role] = pool.ipo_next; 817170268Sdarrenr } 818170268Sdarrenr} 819170268Sdarrenr 820170268Sdarrenr 821170268Sdarrenrvoid showhashs_live(fd, role, htstp, poolname) 822170268Sdarrenrint fd, role; 823170268Sdarrenriphtstat_t *htstp; 824170268Sdarrenrchar *poolname; 825170268Sdarrenr{ 826170268Sdarrenr ipflookupiter_t iter; 827170268Sdarrenr iphtable_t table; 828170268Sdarrenr ipfobj_t obj; 829170268Sdarrenr 830170268Sdarrenr obj.ipfo_rev = IPFILTER_VERSION; 831170268Sdarrenr obj.ipfo_type = IPFOBJ_LOOKUPITER; 832170268Sdarrenr obj.ipfo_size = sizeof(iter); 833170268Sdarrenr obj.ipfo_ptr = &iter; 834170268Sdarrenr 835170268Sdarrenr iter.ili_type = IPLT_HASH; 836170268Sdarrenr iter.ili_otype = IPFLOOKUPITER_LIST; 837170268Sdarrenr iter.ili_ival = IPFGENITER_LOOKUP; 838170268Sdarrenr iter.ili_nitems = 1; 839170268Sdarrenr iter.ili_data = &table; 840170268Sdarrenr iter.ili_unit = role; 841170268Sdarrenr *iter.ili_name = '\0'; 842170268Sdarrenr 843170268Sdarrenr while (htstp->iphs_tables != NULL) { 844170268Sdarrenr if (ioctl(fd, SIOCLOOKUPITER, &obj)) { 845170268Sdarrenr perror("ioctl(SIOCLOOKUPITER)"); 846170268Sdarrenr break; 847170268Sdarrenr } 848170268Sdarrenr 849170268Sdarrenr printhash_live(&table, fd, poolname, opts); 850170268Sdarrenr 851170268Sdarrenr htstp->iphs_tables = table.iph_next; 852170268Sdarrenr } 853170268Sdarrenr} 854170268Sdarrenr 855170268Sdarrenr 856170268Sdarrenrint setnodeaddr(ip_pool_node_t *node, char *arg) 857170268Sdarrenr{ 858170268Sdarrenr struct in_addr mask; 859170268Sdarrenr char *s; 860170268Sdarrenr 861170268Sdarrenr s = strchr(arg, '/'); 862170268Sdarrenr if (s == NULL) 863170268Sdarrenr mask.s_addr = 0xffffffff; 864170268Sdarrenr else if (strchr(s, '.') == NULL) { 865170268Sdarrenr if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0) 866170268Sdarrenr return -1; 867170268Sdarrenr } else { 868170268Sdarrenr mask.s_addr = inet_addr(s + 1); 869170268Sdarrenr } 870170268Sdarrenr if (s != NULL) 871170268Sdarrenr *s = '\0'; 872170268Sdarrenr node->ipn_addr.adf_len = sizeof(node->ipn_addr); 873170268Sdarrenr node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg); 874170268Sdarrenr node->ipn_mask.adf_len = sizeof(node->ipn_mask); 875170268Sdarrenr node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr; 876170268Sdarrenr 877170268Sdarrenr return 0; 878170268Sdarrenr} 879