10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * Copyright (C) 2003 by Darren Reed. 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 50Sstevel@tonic-gate * 6*2393Syz155240 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 70Sstevel@tonic-gate * Use is subject to license terms. 80Sstevel@tonic-gate */ 90Sstevel@tonic-gate 100Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 110Sstevel@tonic-gate 120Sstevel@tonic-gate #include <sys/types.h> 130Sstevel@tonic-gate #include <sys/time.h> 140Sstevel@tonic-gate #include <sys/param.h> 150Sstevel@tonic-gate #include <sys/socket.h> 160Sstevel@tonic-gate #if defined(BSD) && (BSD >= 199306) 170Sstevel@tonic-gate # include <sys/cdefs.h> 180Sstevel@tonic-gate #endif 190Sstevel@tonic-gate #include <sys/ioctl.h> 200Sstevel@tonic-gate 210Sstevel@tonic-gate #include <net/if.h> 220Sstevel@tonic-gate #if __FreeBSD_version >= 300000 230Sstevel@tonic-gate # include <net/if_var.h> 240Sstevel@tonic-gate #endif 250Sstevel@tonic-gate #include <netinet/in.h> 260Sstevel@tonic-gate 270Sstevel@tonic-gate #include <arpa/inet.h> 280Sstevel@tonic-gate 290Sstevel@tonic-gate #include <stdio.h> 300Sstevel@tonic-gate #include <fcntl.h> 310Sstevel@tonic-gate #include <stdlib.h> 320Sstevel@tonic-gate #include <string.h> 330Sstevel@tonic-gate #include <netdb.h> 340Sstevel@tonic-gate #include <ctype.h> 350Sstevel@tonic-gate #include <unistd.h> 360Sstevel@tonic-gate 370Sstevel@tonic-gate #include "ipf.h" 380Sstevel@tonic-gate #include "netinet/ip_lookup.h" 390Sstevel@tonic-gate #include "netinet/ip_pool.h" 400Sstevel@tonic-gate #include "netinet/ip_htable.h" 410Sstevel@tonic-gate #include "kmem.h" 420Sstevel@tonic-gate 430Sstevel@tonic-gate 440Sstevel@tonic-gate extern int ippool_yyparse __P((void)); 450Sstevel@tonic-gate extern int ippool_yydebug; 460Sstevel@tonic-gate extern FILE *ippool_yyin; 470Sstevel@tonic-gate extern char *optarg; 480Sstevel@tonic-gate extern int lineNum; 490Sstevel@tonic-gate 500Sstevel@tonic-gate void showpools __P((ip_pool_stat_t *)); 510Sstevel@tonic-gate void usage __P((char *)); 520Sstevel@tonic-gate int main __P((int, char **)); 530Sstevel@tonic-gate int poolcommand __P((int, int, char *[])); 540Sstevel@tonic-gate int poolnodecommand __P((int, int, char *[])); 550Sstevel@tonic-gate int loadpoolfile __P((int, char *[], char *)); 560Sstevel@tonic-gate int poollist __P((int, char *[])); 570Sstevel@tonic-gate int poolflush __P((int, char *[])); 580Sstevel@tonic-gate int poolstats __P((int, char *[])); 590Sstevel@tonic-gate int gettype __P((char *, u_int *)); 600Sstevel@tonic-gate int getrole __P((char *)); 610Sstevel@tonic-gate 620Sstevel@tonic-gate int opts = 0; 630Sstevel@tonic-gate int fd = -1; 640Sstevel@tonic-gate int use_inet6 = 0; 650Sstevel@tonic-gate 660Sstevel@tonic-gate 670Sstevel@tonic-gate void usage(prog) 680Sstevel@tonic-gate char *prog; 690Sstevel@tonic-gate { 700Sstevel@tonic-gate fprintf(stderr, "Usage:\t%s\n", prog); 710Sstevel@tonic-gate fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n"); 720Sstevel@tonic-gate fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n"); 730Sstevel@tonic-gate fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n"); 740Sstevel@tonic-gate fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n"); 750Sstevel@tonic-gate fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n"); 760Sstevel@tonic-gate fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n"); 770Sstevel@tonic-gate fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n"); 780Sstevel@tonic-gate fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n"); 790Sstevel@tonic-gate exit(1); 800Sstevel@tonic-gate } 810Sstevel@tonic-gate 820Sstevel@tonic-gate 830Sstevel@tonic-gate int main(argc, argv) 840Sstevel@tonic-gate int argc; 850Sstevel@tonic-gate char *argv[]; 860Sstevel@tonic-gate { 870Sstevel@tonic-gate int err; 880Sstevel@tonic-gate 890Sstevel@tonic-gate if (argc < 2) 900Sstevel@tonic-gate usage(argv[0]); 910Sstevel@tonic-gate 920Sstevel@tonic-gate switch (getopt(argc, argv, "aAf:FlrRs")) 930Sstevel@tonic-gate { 940Sstevel@tonic-gate case 'a' : 950Sstevel@tonic-gate err = poolnodecommand(0, argc, argv); 960Sstevel@tonic-gate break; 970Sstevel@tonic-gate case 'A' : 980Sstevel@tonic-gate err = poolcommand(0, argc, argv); 990Sstevel@tonic-gate break; 1000Sstevel@tonic-gate case 'f' : 1010Sstevel@tonic-gate err = loadpoolfile(argc, argv, optarg); 1020Sstevel@tonic-gate break; 1030Sstevel@tonic-gate case 'F' : 1040Sstevel@tonic-gate err = poolflush(argc, argv); 1050Sstevel@tonic-gate break; 1060Sstevel@tonic-gate case 'l' : 1070Sstevel@tonic-gate err = poollist(argc, argv); 1080Sstevel@tonic-gate break; 1090Sstevel@tonic-gate case 'r' : 1100Sstevel@tonic-gate err = poolnodecommand(1, argc, argv); 1110Sstevel@tonic-gate break; 1120Sstevel@tonic-gate case 'R' : 1130Sstevel@tonic-gate err = poolcommand(1, argc, argv); 1140Sstevel@tonic-gate break; 1150Sstevel@tonic-gate case 's' : 1160Sstevel@tonic-gate err = poolstats(argc, argv); 1170Sstevel@tonic-gate break; 1180Sstevel@tonic-gate default : 1190Sstevel@tonic-gate exit(1); 1200Sstevel@tonic-gate } 1210Sstevel@tonic-gate 1220Sstevel@tonic-gate return err; 1230Sstevel@tonic-gate } 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate int poolnodecommand(remove, argc, argv) 1270Sstevel@tonic-gate int remove, argc; 1280Sstevel@tonic-gate char *argv[]; 1290Sstevel@tonic-gate { 1300Sstevel@tonic-gate char *poolname = NULL, *s; 1310Sstevel@tonic-gate int err, c, ipset, role; 1320Sstevel@tonic-gate ip_pool_node_t node; 1330Sstevel@tonic-gate struct in_addr mask; 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate ipset = 0; 1360Sstevel@tonic-gate role = IPL_LOGIPF; 1370Sstevel@tonic-gate bzero((char *)&node, sizeof(node)); 1380Sstevel@tonic-gate 139*2393Syz155240 while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1) 1400Sstevel@tonic-gate switch (c) 1410Sstevel@tonic-gate { 1420Sstevel@tonic-gate case 'd' : 1430Sstevel@tonic-gate opts |= OPT_DEBUG; 1440Sstevel@tonic-gate ippool_yydebug++; 1450Sstevel@tonic-gate break; 1460Sstevel@tonic-gate case 'i' : 1470Sstevel@tonic-gate s = strchr(optarg, '/'); 1480Sstevel@tonic-gate if (s == NULL) 1490Sstevel@tonic-gate mask.s_addr = 0xffffffff; 1500Sstevel@tonic-gate else if (strchr(s, '.') == NULL) { 1510Sstevel@tonic-gate if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0) 1520Sstevel@tonic-gate return -1; 1530Sstevel@tonic-gate } else { 1540Sstevel@tonic-gate mask.s_addr = inet_addr(s + 1); 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate if (s != NULL) 1570Sstevel@tonic-gate *s = '\0'; 1580Sstevel@tonic-gate ipset = 1; 159*2393Syz155240 node.ipn_addr.adf_len = sizeof(node.ipn_addr); 1600Sstevel@tonic-gate node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg); 161*2393Syz155240 node.ipn_mask.adf_len = sizeof(node.ipn_mask); 1620Sstevel@tonic-gate node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr; 1630Sstevel@tonic-gate break; 1640Sstevel@tonic-gate case 'm' : 1650Sstevel@tonic-gate poolname = optarg; 1660Sstevel@tonic-gate break; 1670Sstevel@tonic-gate case 'n' : 1680Sstevel@tonic-gate opts |= OPT_DONOTHING; 1690Sstevel@tonic-gate break; 1700Sstevel@tonic-gate case 'o' : 1710Sstevel@tonic-gate role = getrole(optarg); 1720Sstevel@tonic-gate if (role == IPL_LOGNONE) 1730Sstevel@tonic-gate return -1; 1740Sstevel@tonic-gate break; 175*2393Syz155240 case 'R' : 176*2393Syz155240 opts |= OPT_NORESOLVE; 177*2393Syz155240 break; 1780Sstevel@tonic-gate case 'v' : 1790Sstevel@tonic-gate opts |= OPT_VERBOSE; 1800Sstevel@tonic-gate break; 1810Sstevel@tonic-gate } 1820Sstevel@tonic-gate 183*2393Syz155240 if (opts & OPT_DEBUG) 184*2393Syz155240 fprintf(stderr, "poolnodecommand: opts = %#x\n", opts); 185*2393Syz155240 1860Sstevel@tonic-gate if (ipset == 0) 1870Sstevel@tonic-gate return -1; 1880Sstevel@tonic-gate if (poolname == NULL) { 1890Sstevel@tonic-gate fprintf(stderr, "poolname not given with add/remove node\n"); 1900Sstevel@tonic-gate return -1; 1910Sstevel@tonic-gate } 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate if (remove == 0) 1940Sstevel@tonic-gate err = load_poolnode(0, poolname, &node, ioctl); 1950Sstevel@tonic-gate else 1960Sstevel@tonic-gate err = remove_poolnode(0, poolname, &node, ioctl); 1970Sstevel@tonic-gate return err; 1980Sstevel@tonic-gate } 1990Sstevel@tonic-gate 2000Sstevel@tonic-gate 2010Sstevel@tonic-gate int poolcommand(remove, argc, argv) 2020Sstevel@tonic-gate int remove, argc; 2030Sstevel@tonic-gate char *argv[]; 2040Sstevel@tonic-gate { 2050Sstevel@tonic-gate int type, role, c, err; 2060Sstevel@tonic-gate char *poolname; 2070Sstevel@tonic-gate iphtable_t iph; 2080Sstevel@tonic-gate ip_pool_t pool; 2090Sstevel@tonic-gate 2100Sstevel@tonic-gate err = 1; 2110Sstevel@tonic-gate role = 0; 2120Sstevel@tonic-gate type = 0; 2130Sstevel@tonic-gate poolname = NULL; 2140Sstevel@tonic-gate role = IPL_LOGIPF; 2150Sstevel@tonic-gate bzero((char *)&iph, sizeof(iph)); 2160Sstevel@tonic-gate bzero((char *)&pool, sizeof(pool)); 2170Sstevel@tonic-gate 218*2393Syz155240 while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1) 2190Sstevel@tonic-gate switch (c) 2200Sstevel@tonic-gate { 2210Sstevel@tonic-gate case 'd' : 2220Sstevel@tonic-gate opts |= OPT_DEBUG; 2230Sstevel@tonic-gate ippool_yydebug++; 2240Sstevel@tonic-gate break; 2250Sstevel@tonic-gate case 'm' : 2260Sstevel@tonic-gate poolname = optarg; 2270Sstevel@tonic-gate break; 2280Sstevel@tonic-gate case 'n' : 2290Sstevel@tonic-gate opts |= OPT_DONOTHING; 2300Sstevel@tonic-gate break; 2310Sstevel@tonic-gate case 'o' : 2320Sstevel@tonic-gate role = getrole(optarg); 2330Sstevel@tonic-gate if (role == IPL_LOGNONE) { 2340Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg); 2350Sstevel@tonic-gate return -1; 2360Sstevel@tonic-gate } 2370Sstevel@tonic-gate break; 238*2393Syz155240 case 'R' : 239*2393Syz155240 opts |= OPT_NORESOLVE; 240*2393Syz155240 break; 2410Sstevel@tonic-gate case 'S' : 2420Sstevel@tonic-gate iph.iph_seed = atoi(optarg); 2430Sstevel@tonic-gate break; 2440Sstevel@tonic-gate case 't' : 2450Sstevel@tonic-gate type = gettype(optarg, &iph.iph_type); 2460Sstevel@tonic-gate if (type == IPLT_NONE) { 2470Sstevel@tonic-gate fprintf(stderr, "unknown type '%s'\n", optarg); 2480Sstevel@tonic-gate return -1; 2490Sstevel@tonic-gate } 2500Sstevel@tonic-gate break; 2510Sstevel@tonic-gate case 'v' : 2520Sstevel@tonic-gate opts |= OPT_VERBOSE; 2530Sstevel@tonic-gate break; 2540Sstevel@tonic-gate } 2550Sstevel@tonic-gate 256*2393Syz155240 if (opts & OPT_DEBUG) 257*2393Syz155240 fprintf(stderr, "poolcommand: opts = %#x\n", opts); 258*2393Syz155240 2590Sstevel@tonic-gate if (poolname == NULL) { 2600Sstevel@tonic-gate fprintf(stderr, "poolname not given with add/remove pool\n"); 2610Sstevel@tonic-gate return -1; 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate if (type == IPLT_HASH) { 2650Sstevel@tonic-gate strncpy(iph.iph_name, poolname, sizeof(iph.iph_name)); 2660Sstevel@tonic-gate iph.iph_name[sizeof(iph.iph_name) - 1] = '\0'; 2670Sstevel@tonic-gate iph.iph_unit = role; 2680Sstevel@tonic-gate } else if (type == IPLT_POOL) { 2690Sstevel@tonic-gate strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name)); 2700Sstevel@tonic-gate pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0'; 2710Sstevel@tonic-gate pool.ipo_unit = role; 2720Sstevel@tonic-gate } 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate if (remove == 0) { 2750Sstevel@tonic-gate switch (type) 2760Sstevel@tonic-gate { 2770Sstevel@tonic-gate case IPLT_HASH : 2780Sstevel@tonic-gate err = load_hash(&iph, NULL, ioctl); 2790Sstevel@tonic-gate break; 2800Sstevel@tonic-gate case IPLT_POOL : 2810Sstevel@tonic-gate err = load_pool(&pool, ioctl); 2820Sstevel@tonic-gate break; 2830Sstevel@tonic-gate } 2840Sstevel@tonic-gate } else { 2850Sstevel@tonic-gate switch (type) 2860Sstevel@tonic-gate { 2870Sstevel@tonic-gate case IPLT_HASH : 2880Sstevel@tonic-gate err = remove_hash(&iph, ioctl); 2890Sstevel@tonic-gate break; 2900Sstevel@tonic-gate case IPLT_POOL : 2910Sstevel@tonic-gate err = remove_pool(&pool, ioctl); 2920Sstevel@tonic-gate break; 2930Sstevel@tonic-gate } 2940Sstevel@tonic-gate } 2950Sstevel@tonic-gate return err; 2960Sstevel@tonic-gate } 2970Sstevel@tonic-gate 2980Sstevel@tonic-gate 2990Sstevel@tonic-gate int loadpoolfile(argc, argv, infile) 3000Sstevel@tonic-gate int argc; 3010Sstevel@tonic-gate char *argv[], *infile; 3020Sstevel@tonic-gate { 3030Sstevel@tonic-gate int c; 3040Sstevel@tonic-gate 3050Sstevel@tonic-gate infile = optarg; 3060Sstevel@tonic-gate 307*2393Syz155240 while ((c = getopt(argc, argv, "dnRuv")) != -1) 3080Sstevel@tonic-gate switch (c) 3090Sstevel@tonic-gate { 3100Sstevel@tonic-gate case 'd' : 3110Sstevel@tonic-gate opts |= OPT_DEBUG; 3120Sstevel@tonic-gate ippool_yydebug++; 3130Sstevel@tonic-gate break; 3140Sstevel@tonic-gate case 'n' : 3150Sstevel@tonic-gate opts |= OPT_DONOTHING; 3160Sstevel@tonic-gate break; 317*2393Syz155240 case 'R' : 318*2393Syz155240 opts |= OPT_NORESOLVE; 319*2393Syz155240 break; 320*2393Syz155240 case 'u' : 3210Sstevel@tonic-gate opts |= OPT_REMOVE; 3220Sstevel@tonic-gate break; 3230Sstevel@tonic-gate case 'v' : 3240Sstevel@tonic-gate opts |= OPT_VERBOSE; 3250Sstevel@tonic-gate break; 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate 328*2393Syz155240 if (opts & OPT_DEBUG) 329*2393Syz155240 fprintf(stderr, "loadpoolfile: opts = %#x\n", opts); 330*2393Syz155240 3310Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) { 3320Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR); 3330Sstevel@tonic-gate if (fd == -1) { 3340Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)"); 3350Sstevel@tonic-gate exit(1); 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate } 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate if (ippool_parsefile(fd, infile, ioctl) != 0) 3400Sstevel@tonic-gate return -1; 3410Sstevel@tonic-gate return 0; 3420Sstevel@tonic-gate } 3430Sstevel@tonic-gate 3440Sstevel@tonic-gate 3450Sstevel@tonic-gate int poollist(argc, argv) 3460Sstevel@tonic-gate int argc; 3470Sstevel@tonic-gate char *argv[]; 3480Sstevel@tonic-gate { 3490Sstevel@tonic-gate char *kernel, *core, *poolname; 3500Sstevel@tonic-gate int c, role, type, live_kernel; 3510Sstevel@tonic-gate ip_pool_stat_t *plstp, plstat; 352637Sml37995 iphtstat_t *htstp, htstat; 353637Sml37995 iphtable_t *hptr; 3540Sstevel@tonic-gate iplookupop_t op; 3550Sstevel@tonic-gate ip_pool_t *ptr; 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate core = NULL; 3580Sstevel@tonic-gate kernel = NULL; 3590Sstevel@tonic-gate live_kernel = 1; 3600Sstevel@tonic-gate type = IPLT_ALL; 3610Sstevel@tonic-gate poolname = NULL; 3620Sstevel@tonic-gate role = IPL_LOGALL; 3630Sstevel@tonic-gate 364*2393Syz155240 while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1) 3650Sstevel@tonic-gate switch (c) 3660Sstevel@tonic-gate { 3670Sstevel@tonic-gate case 'd' : 3680Sstevel@tonic-gate opts |= OPT_DEBUG; 3690Sstevel@tonic-gate break; 3700Sstevel@tonic-gate case 'm' : 3710Sstevel@tonic-gate poolname = optarg; 3720Sstevel@tonic-gate break; 3730Sstevel@tonic-gate case 'M' : 3740Sstevel@tonic-gate live_kernel = 0; 3750Sstevel@tonic-gate core = optarg; 3760Sstevel@tonic-gate break; 3770Sstevel@tonic-gate case 'N' : 3780Sstevel@tonic-gate live_kernel = 0; 3790Sstevel@tonic-gate kernel = optarg; 3800Sstevel@tonic-gate break; 3810Sstevel@tonic-gate case 'o' : 3820Sstevel@tonic-gate role = getrole(optarg); 3830Sstevel@tonic-gate if (role == IPL_LOGNONE) { 3840Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg); 3850Sstevel@tonic-gate return -1; 3860Sstevel@tonic-gate } 3870Sstevel@tonic-gate break; 388*2393Syz155240 case 'R' : 389*2393Syz155240 opts |= OPT_NORESOLVE; 390*2393Syz155240 break; 3910Sstevel@tonic-gate case 't' : 3920Sstevel@tonic-gate type = gettype(optarg, NULL); 3930Sstevel@tonic-gate if (type == IPLT_NONE) { 3940Sstevel@tonic-gate fprintf(stderr, "unknown type '%s'\n", optarg); 3950Sstevel@tonic-gate return -1; 3960Sstevel@tonic-gate } 3970Sstevel@tonic-gate break; 3980Sstevel@tonic-gate case 'v' : 3990Sstevel@tonic-gate opts |= OPT_VERBOSE; 4000Sstevel@tonic-gate break; 4010Sstevel@tonic-gate } 4020Sstevel@tonic-gate 403637Sml37995 if (opts & OPT_DEBUG) 404637Sml37995 fprintf(stderr, "poollist: opts = %#x\n", opts); 405637Sml37995 4060Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) { 4070Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR); 4080Sstevel@tonic-gate if (fd == -1) { 4090Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)"); 4100Sstevel@tonic-gate exit(1); 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate } 4130Sstevel@tonic-gate 4140Sstevel@tonic-gate bzero((char *)&op, sizeof(op)); 4150Sstevel@tonic-gate if (poolname != NULL) { 4160Sstevel@tonic-gate strncpy(op.iplo_name, poolname, sizeof(op.iplo_name)); 4170Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0'; 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate op.iplo_unit = role; 4200Sstevel@tonic-gate 4210Sstevel@tonic-gate if (openkmem(kernel, core) == -1) 4220Sstevel@tonic-gate exit(-1); 4230Sstevel@tonic-gate 424637Sml37995 if (type == IPLT_ALL || type == IPLT_POOL) { 425637Sml37995 plstp = &plstat; 426637Sml37995 op.iplo_type = IPLT_POOL; 427637Sml37995 op.iplo_size = sizeof(plstat); 428637Sml37995 op.iplo_struct = &plstat; 429637Sml37995 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 430637Sml37995 if (c == -1) { 431637Sml37995 perror("ioctl(SIOCLOOKUPSTAT)"); 432637Sml37995 return -1; 4330Sstevel@tonic-gate } 434637Sml37995 435637Sml37995 if (role != IPL_LOGALL) { 4360Sstevel@tonic-gate ptr = plstp->ipls_list[role]; 4370Sstevel@tonic-gate while (ptr != NULL) { 438*2393Syz155240 ptr = printpool(ptr, kmemcpywrap, poolname, 439*2393Syz155240 opts); 4400Sstevel@tonic-gate } 441637Sml37995 } else { 442637Sml37995 for (role = 0; role <= IPL_LOGMAX; role++) { 443637Sml37995 ptr = plstp->ipls_list[role]; 444637Sml37995 while (ptr != NULL) { 445637Sml37995 ptr = printpool(ptr, kmemcpywrap, 446*2393Syz155240 poolname, opts); 447637Sml37995 } 448637Sml37995 } 449637Sml37995 role = IPL_LOGALL; 450637Sml37995 } 451637Sml37995 } 452637Sml37995 if (type == IPLT_ALL || type == IPLT_HASH) { 453637Sml37995 htstp = &htstat; 454637Sml37995 op.iplo_type = IPLT_HASH; 455637Sml37995 op.iplo_size = sizeof(htstat); 456637Sml37995 op.iplo_struct = &htstat; 457637Sml37995 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 458637Sml37995 if (c == -1) { 459637Sml37995 perror("ioctl(SIOCLOOKUPSTAT)"); 460637Sml37995 return -1; 461637Sml37995 } 462637Sml37995 463637Sml37995 if (role != IPL_LOGALL) { 464637Sml37995 hptr = htstp->iphs_tables; 465637Sml37995 while (hptr != NULL) { 466*2393Syz155240 hptr = printhash(hptr, kmemcpywrap, 467*2393Syz155240 poolname, opts); 468637Sml37995 } 469637Sml37995 } else { 470637Sml37995 for (role = 0; role <= IPL_LOGMAX; role++) { 471637Sml37995 hptr = htstp->iphs_tables; 472637Sml37995 while (hptr != NULL) { 473637Sml37995 hptr = printhash(hptr, kmemcpywrap, 474*2393Syz155240 poolname, opts); 475637Sml37995 } 476637Sml37995 477637Sml37995 op.iplo_unit = role; 478637Sml37995 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 479637Sml37995 if (c == -1) { 480637Sml37995 perror("ioctl(SIOCLOOKUPSTAT)"); 481637Sml37995 return -1; 482637Sml37995 } 483637Sml37995 } 4840Sstevel@tonic-gate } 4850Sstevel@tonic-gate } 4860Sstevel@tonic-gate return 0; 4870Sstevel@tonic-gate } 4880Sstevel@tonic-gate 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate int poolstats(argc, argv) 4910Sstevel@tonic-gate int argc; 4920Sstevel@tonic-gate char *argv[]; 4930Sstevel@tonic-gate { 4940Sstevel@tonic-gate int c, type, role, live_kernel; 4950Sstevel@tonic-gate ip_pool_stat_t plstat; 4960Sstevel@tonic-gate char *kernel, *core; 497637Sml37995 iphtstat_t htstat; 4980Sstevel@tonic-gate iplookupop_t op; 4990Sstevel@tonic-gate 5000Sstevel@tonic-gate core = NULL; 5010Sstevel@tonic-gate kernel = NULL; 5020Sstevel@tonic-gate live_kernel = 1; 5030Sstevel@tonic-gate type = IPLT_ALL; 5040Sstevel@tonic-gate role = IPL_LOGALL; 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate bzero((char *)&op, sizeof(op)); 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1) 5090Sstevel@tonic-gate switch (c) 5100Sstevel@tonic-gate { 5110Sstevel@tonic-gate case 'd' : 5120Sstevel@tonic-gate opts |= OPT_DEBUG; 5130Sstevel@tonic-gate break; 5140Sstevel@tonic-gate case 'M' : 5150Sstevel@tonic-gate live_kernel = 0; 5160Sstevel@tonic-gate core = optarg; 5170Sstevel@tonic-gate break; 5180Sstevel@tonic-gate case 'N' : 5190Sstevel@tonic-gate live_kernel = 0; 5200Sstevel@tonic-gate kernel = optarg; 5210Sstevel@tonic-gate break; 5220Sstevel@tonic-gate case 'o' : 5230Sstevel@tonic-gate role = getrole(optarg); 5240Sstevel@tonic-gate if (role == IPL_LOGNONE) { 5250Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg); 5260Sstevel@tonic-gate return -1; 5270Sstevel@tonic-gate } 5280Sstevel@tonic-gate break; 5290Sstevel@tonic-gate case 't' : 5300Sstevel@tonic-gate type = gettype(optarg, NULL); 5310Sstevel@tonic-gate if (type != IPLT_POOL) { 5320Sstevel@tonic-gate fprintf(stderr, 5330Sstevel@tonic-gate "-s not supported for this type yet\n"); 5340Sstevel@tonic-gate return -1; 5350Sstevel@tonic-gate } 5360Sstevel@tonic-gate break; 5370Sstevel@tonic-gate case 'v' : 5380Sstevel@tonic-gate opts |= OPT_VERBOSE; 5390Sstevel@tonic-gate break; 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate 542637Sml37995 if (opts & OPT_DEBUG) 543637Sml37995 fprintf(stderr, "poolstats: opts = %#x\n", opts); 544637Sml37995 5450Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) { 5460Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR); 5470Sstevel@tonic-gate if (fd == -1) { 5480Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)"); 5490Sstevel@tonic-gate exit(1); 5500Sstevel@tonic-gate } 5510Sstevel@tonic-gate } 5520Sstevel@tonic-gate 553637Sml37995 if (type == IPLT_ALL || type == IPLT_POOL) { 554637Sml37995 op.iplo_type = IPLT_POOL; 555637Sml37995 op.iplo_struct = &plstat; 556637Sml37995 op.iplo_size = sizeof(plstat); 557637Sml37995 if (!(opts & OPT_DONOTHING)) { 558637Sml37995 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 559637Sml37995 if (c == -1) { 560637Sml37995 perror("ioctl(SIOCLOOKUPSTAT)"); 561637Sml37995 return -1; 562637Sml37995 } 563637Sml37995 printf("Pools:\t%lu\n", plstat.ipls_pools); 564637Sml37995 printf("Nodes:\t%lu\n", plstat.ipls_nodes); 5650Sstevel@tonic-gate } 566637Sml37995 } 567637Sml37995 568637Sml37995 if (type == IPLT_ALL || type == IPLT_HASH) { 569637Sml37995 op.iplo_type = IPLT_HASH; 570637Sml37995 op.iplo_struct = &htstat; 571637Sml37995 op.iplo_size = sizeof(htstat); 572637Sml37995 if (!(opts & OPT_DONOTHING)) { 573637Sml37995 c = ioctl(fd, SIOCLOOKUPSTAT, &op); 574637Sml37995 if (c == -1) { 575637Sml37995 perror("ioctl(SIOCLOOKUPSTAT)"); 576637Sml37995 return -1; 577637Sml37995 } 578637Sml37995 printf("Hash Tables:\t%lu\n", htstat.iphs_numtables); 579637Sml37995 printf("Nodes:\t%lu\n", htstat.iphs_numnodes); 580637Sml37995 printf("Out of Memory:\t%lu\n", htstat.iphs_nomem); 581637Sml37995 } 5820Sstevel@tonic-gate } 5830Sstevel@tonic-gate return 0; 5840Sstevel@tonic-gate } 5850Sstevel@tonic-gate 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate int poolflush(argc, argv) 5880Sstevel@tonic-gate int argc; 5890Sstevel@tonic-gate char *argv[]; 5900Sstevel@tonic-gate { 5910Sstevel@tonic-gate int c, role, type, arg; 5920Sstevel@tonic-gate iplookupflush_t flush; 5930Sstevel@tonic-gate 5940Sstevel@tonic-gate arg = IPLT_ALL; 5950Sstevel@tonic-gate type = IPLT_ALL; 5960Sstevel@tonic-gate role = IPL_LOGALL; 5970Sstevel@tonic-gate 5980Sstevel@tonic-gate while ((c = getopt(argc, argv, "do:t:v")) != -1) 5990Sstevel@tonic-gate switch (c) 6000Sstevel@tonic-gate { 6010Sstevel@tonic-gate case 'd' : 6020Sstevel@tonic-gate opts |= OPT_DEBUG; 6030Sstevel@tonic-gate break; 6040Sstevel@tonic-gate case 'o' : 6050Sstevel@tonic-gate role = getrole(optarg); 6060Sstevel@tonic-gate if (role == IPL_LOGNONE) { 6070Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg); 6080Sstevel@tonic-gate return -1; 6090Sstevel@tonic-gate } 6100Sstevel@tonic-gate break; 6110Sstevel@tonic-gate case 't' : 6120Sstevel@tonic-gate type = gettype(optarg, NULL); 6130Sstevel@tonic-gate if (type == IPLT_NONE) { 6140Sstevel@tonic-gate fprintf(stderr, "unknown type '%s'\n", optarg); 6150Sstevel@tonic-gate return -1; 6160Sstevel@tonic-gate } 6170Sstevel@tonic-gate break; 6180Sstevel@tonic-gate case 'v' : 6190Sstevel@tonic-gate opts |= OPT_VERBOSE; 6200Sstevel@tonic-gate break; 6210Sstevel@tonic-gate } 6220Sstevel@tonic-gate 623*2393Syz155240 if (opts & OPT_DEBUG) 624*2393Syz155240 fprintf(stderr, "poolflush: opts = %#x\n", opts); 625*2393Syz155240 6260Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) { 6270Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR); 6280Sstevel@tonic-gate if (fd == -1) { 6290Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)"); 6300Sstevel@tonic-gate exit(1); 6310Sstevel@tonic-gate } 6320Sstevel@tonic-gate } 6330Sstevel@tonic-gate 6340Sstevel@tonic-gate bzero((char *)&flush, sizeof(flush)); 6350Sstevel@tonic-gate flush.iplf_type = type; 6360Sstevel@tonic-gate flush.iplf_unit = role; 6370Sstevel@tonic-gate flush.iplf_arg = arg; 6380Sstevel@tonic-gate 6390Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) { 6400Sstevel@tonic-gate if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) { 6410Sstevel@tonic-gate perror("ioctl(SIOCLOOKUPFLUSH)"); 6420Sstevel@tonic-gate exit(1); 6430Sstevel@tonic-gate } 6440Sstevel@tonic-gate 6450Sstevel@tonic-gate } 6460Sstevel@tonic-gate printf("%u object%s flushed\n", flush.iplf_count, 6470Sstevel@tonic-gate (flush.iplf_count == 1) ? "" : "s"); 6480Sstevel@tonic-gate 6490Sstevel@tonic-gate return 0; 6500Sstevel@tonic-gate } 6510Sstevel@tonic-gate 6520Sstevel@tonic-gate 6530Sstevel@tonic-gate int getrole(rolename) 6540Sstevel@tonic-gate char *rolename; 6550Sstevel@tonic-gate { 6560Sstevel@tonic-gate int role; 6570Sstevel@tonic-gate 6580Sstevel@tonic-gate if (!strcasecmp(rolename, "ipf")) { 6590Sstevel@tonic-gate role = IPL_LOGIPF; 6600Sstevel@tonic-gate #if 0 6610Sstevel@tonic-gate } else if (!strcasecmp(rolename, "nat")) { 6620Sstevel@tonic-gate role = IPL_LOGNAT; 6630Sstevel@tonic-gate } else if (!strcasecmp(rolename, "state")) { 6640Sstevel@tonic-gate role = IPL_LOGSTATE; 6650Sstevel@tonic-gate } else if (!strcasecmp(rolename, "auth")) { 6660Sstevel@tonic-gate role = IPL_LOGAUTH; 6670Sstevel@tonic-gate } else if (!strcasecmp(rolename, "sync")) { 6680Sstevel@tonic-gate role = IPL_LOGSYNC; 6690Sstevel@tonic-gate } else if (!strcasecmp(rolename, "scan")) { 6700Sstevel@tonic-gate role = IPL_LOGSCAN; 6710Sstevel@tonic-gate } else if (!strcasecmp(rolename, "pool")) { 6720Sstevel@tonic-gate role = IPL_LOGLOOKUP; 6730Sstevel@tonic-gate } else if (!strcasecmp(rolename, "count")) { 6740Sstevel@tonic-gate role = IPL_LOGCOUNT; 6750Sstevel@tonic-gate #endif 6760Sstevel@tonic-gate } else { 6770Sstevel@tonic-gate role = IPL_LOGNONE; 6780Sstevel@tonic-gate } 6790Sstevel@tonic-gate 6800Sstevel@tonic-gate return role; 6810Sstevel@tonic-gate } 6820Sstevel@tonic-gate 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate int gettype(typename, minor) 6850Sstevel@tonic-gate char *typename; 6860Sstevel@tonic-gate u_int *minor; 6870Sstevel@tonic-gate { 6880Sstevel@tonic-gate int type; 6890Sstevel@tonic-gate 690*2393Syz155240 if (!strcasecmp(optarg, "tree")) { 6910Sstevel@tonic-gate type = IPLT_POOL; 6920Sstevel@tonic-gate } else if (!strcasecmp(optarg, "hash")) { 6930Sstevel@tonic-gate type = IPLT_HASH; 6940Sstevel@tonic-gate if (minor != NULL) 6950Sstevel@tonic-gate *minor = IPHASH_LOOKUP; 6960Sstevel@tonic-gate } else if (!strcasecmp(optarg, "group-map")) { 6970Sstevel@tonic-gate type = IPLT_HASH; 6980Sstevel@tonic-gate if (minor != NULL) 6990Sstevel@tonic-gate *minor = IPHASH_GROUPMAP; 7000Sstevel@tonic-gate } else { 7010Sstevel@tonic-gate type = IPLT_NONE; 7020Sstevel@tonic-gate } 7030Sstevel@tonic-gate return type; 7040Sstevel@tonic-gate } 705