xref: /onnv-gate/usr/src/cmd/ipf/tools/ippool.c (revision 2393:76e0289ce525)
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