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*3448Sdh155122 * Copyright 2007 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>
36*3448Sdh155122 #include <nlist.h>
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include "ipf.h"
39*3448Sdh155122 #include "netinet/ipl.h"
400Sstevel@tonic-gate #include "netinet/ip_lookup.h"
410Sstevel@tonic-gate #include "netinet/ip_pool.h"
420Sstevel@tonic-gate #include "netinet/ip_htable.h"
430Sstevel@tonic-gate #include "kmem.h"
440Sstevel@tonic-gate
450Sstevel@tonic-gate extern int ippool_yyparse __P((void));
460Sstevel@tonic-gate extern int ippool_yydebug;
470Sstevel@tonic-gate extern FILE *ippool_yyin;
480Sstevel@tonic-gate extern char *optarg;
490Sstevel@tonic-gate extern int lineNum;
500Sstevel@tonic-gate
510Sstevel@tonic-gate void showpools __P((ip_pool_stat_t *));
520Sstevel@tonic-gate void usage __P((char *));
530Sstevel@tonic-gate int main __P((int, char **));
540Sstevel@tonic-gate int poolcommand __P((int, int, char *[]));
550Sstevel@tonic-gate int poolnodecommand __P((int, int, char *[]));
560Sstevel@tonic-gate int loadpoolfile __P((int, char *[], char *));
570Sstevel@tonic-gate int poollist __P((int, char *[]));
580Sstevel@tonic-gate int poolflush __P((int, char *[]));
590Sstevel@tonic-gate int poolstats __P((int, char *[]));
600Sstevel@tonic-gate int gettype __P((char *, u_int *));
610Sstevel@tonic-gate int getrole __P((char *));
62*3448Sdh155122 void poollist_dead __P((int, char *, int, char *, char *));
63*3448Sdh155122 void showpools_live(int, int, ip_pool_stat_t *, char *, int);
64*3448Sdh155122 void showhashs_live(int, int, iphtstat_t *, char *, int);
650Sstevel@tonic-gate
660Sstevel@tonic-gate int opts = 0;
670Sstevel@tonic-gate int fd = -1;
680Sstevel@tonic-gate int use_inet6 = 0;
690Sstevel@tonic-gate
700Sstevel@tonic-gate
usage(prog)710Sstevel@tonic-gate void usage(prog)
720Sstevel@tonic-gate char *prog;
730Sstevel@tonic-gate {
740Sstevel@tonic-gate fprintf(stderr, "Usage:\t%s\n", prog);
750Sstevel@tonic-gate fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
760Sstevel@tonic-gate fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
770Sstevel@tonic-gate fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n");
780Sstevel@tonic-gate fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n");
790Sstevel@tonic-gate fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n");
800Sstevel@tonic-gate fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
810Sstevel@tonic-gate fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
820Sstevel@tonic-gate fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
830Sstevel@tonic-gate exit(1);
840Sstevel@tonic-gate }
850Sstevel@tonic-gate
860Sstevel@tonic-gate
main(argc,argv)870Sstevel@tonic-gate int main(argc, argv)
880Sstevel@tonic-gate int argc;
890Sstevel@tonic-gate char *argv[];
900Sstevel@tonic-gate {
910Sstevel@tonic-gate int err;
920Sstevel@tonic-gate
930Sstevel@tonic-gate if (argc < 2)
940Sstevel@tonic-gate usage(argv[0]);
950Sstevel@tonic-gate
960Sstevel@tonic-gate switch (getopt(argc, argv, "aAf:FlrRs"))
970Sstevel@tonic-gate {
980Sstevel@tonic-gate case 'a' :
990Sstevel@tonic-gate err = poolnodecommand(0, argc, argv);
1000Sstevel@tonic-gate break;
1010Sstevel@tonic-gate case 'A' :
1020Sstevel@tonic-gate err = poolcommand(0, argc, argv);
1030Sstevel@tonic-gate break;
1040Sstevel@tonic-gate case 'f' :
1050Sstevel@tonic-gate err = loadpoolfile(argc, argv, optarg);
1060Sstevel@tonic-gate break;
1070Sstevel@tonic-gate case 'F' :
1080Sstevel@tonic-gate err = poolflush(argc, argv);
1090Sstevel@tonic-gate break;
1100Sstevel@tonic-gate case 'l' :
1110Sstevel@tonic-gate err = poollist(argc, argv);
1120Sstevel@tonic-gate break;
1130Sstevel@tonic-gate case 'r' :
1140Sstevel@tonic-gate err = poolnodecommand(1, argc, argv);
1150Sstevel@tonic-gate break;
1160Sstevel@tonic-gate case 'R' :
1170Sstevel@tonic-gate err = poolcommand(1, argc, argv);
1180Sstevel@tonic-gate break;
1190Sstevel@tonic-gate case 's' :
1200Sstevel@tonic-gate err = poolstats(argc, argv);
1210Sstevel@tonic-gate break;
1220Sstevel@tonic-gate default :
1230Sstevel@tonic-gate exit(1);
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate return err;
1270Sstevel@tonic-gate }
1280Sstevel@tonic-gate
1290Sstevel@tonic-gate
poolnodecommand(remove,argc,argv)1300Sstevel@tonic-gate int poolnodecommand(remove, argc, argv)
1310Sstevel@tonic-gate int remove, argc;
1320Sstevel@tonic-gate char *argv[];
1330Sstevel@tonic-gate {
1340Sstevel@tonic-gate char *poolname = NULL, *s;
1350Sstevel@tonic-gate int err, c, ipset, role;
1360Sstevel@tonic-gate ip_pool_node_t node;
1370Sstevel@tonic-gate struct in_addr mask;
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate ipset = 0;
1400Sstevel@tonic-gate role = IPL_LOGIPF;
1410Sstevel@tonic-gate bzero((char *)&node, sizeof(node));
1420Sstevel@tonic-gate
1432393Syz155240 while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1)
1440Sstevel@tonic-gate switch (c)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate case 'd' :
1470Sstevel@tonic-gate opts |= OPT_DEBUG;
1480Sstevel@tonic-gate ippool_yydebug++;
1490Sstevel@tonic-gate break;
1500Sstevel@tonic-gate case 'i' :
1510Sstevel@tonic-gate s = strchr(optarg, '/');
1520Sstevel@tonic-gate if (s == NULL)
1530Sstevel@tonic-gate mask.s_addr = 0xffffffff;
1540Sstevel@tonic-gate else if (strchr(s, '.') == NULL) {
1550Sstevel@tonic-gate if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0)
1560Sstevel@tonic-gate return -1;
1570Sstevel@tonic-gate } else {
1580Sstevel@tonic-gate mask.s_addr = inet_addr(s + 1);
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate if (s != NULL)
1610Sstevel@tonic-gate *s = '\0';
1620Sstevel@tonic-gate ipset = 1;
1632393Syz155240 node.ipn_addr.adf_len = sizeof(node.ipn_addr);
1640Sstevel@tonic-gate node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg);
1652393Syz155240 node.ipn_mask.adf_len = sizeof(node.ipn_mask);
1660Sstevel@tonic-gate node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1670Sstevel@tonic-gate break;
1680Sstevel@tonic-gate case 'm' :
1690Sstevel@tonic-gate poolname = optarg;
1700Sstevel@tonic-gate break;
1710Sstevel@tonic-gate case 'n' :
1720Sstevel@tonic-gate opts |= OPT_DONOTHING;
1730Sstevel@tonic-gate break;
1740Sstevel@tonic-gate case 'o' :
1750Sstevel@tonic-gate role = getrole(optarg);
1760Sstevel@tonic-gate if (role == IPL_LOGNONE)
1770Sstevel@tonic-gate return -1;
1780Sstevel@tonic-gate break;
1792393Syz155240 case 'R' :
1802393Syz155240 opts |= OPT_NORESOLVE;
1812393Syz155240 break;
1820Sstevel@tonic-gate case 'v' :
1830Sstevel@tonic-gate opts |= OPT_VERBOSE;
1840Sstevel@tonic-gate break;
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate
1872393Syz155240 if (opts & OPT_DEBUG)
1882393Syz155240 fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
1892393Syz155240
1900Sstevel@tonic-gate if (ipset == 0)
1910Sstevel@tonic-gate return -1;
1920Sstevel@tonic-gate if (poolname == NULL) {
1930Sstevel@tonic-gate fprintf(stderr, "poolname not given with add/remove node\n");
1940Sstevel@tonic-gate return -1;
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate if (remove == 0)
1980Sstevel@tonic-gate err = load_poolnode(0, poolname, &node, ioctl);
1990Sstevel@tonic-gate else
2000Sstevel@tonic-gate err = remove_poolnode(0, poolname, &node, ioctl);
2010Sstevel@tonic-gate return err;
2020Sstevel@tonic-gate }
2030Sstevel@tonic-gate
2040Sstevel@tonic-gate
poolcommand(remove,argc,argv)2050Sstevel@tonic-gate int poolcommand(remove, argc, argv)
2060Sstevel@tonic-gate int remove, argc;
2070Sstevel@tonic-gate char *argv[];
2080Sstevel@tonic-gate {
2090Sstevel@tonic-gate int type, role, c, err;
2100Sstevel@tonic-gate char *poolname;
2110Sstevel@tonic-gate iphtable_t iph;
2120Sstevel@tonic-gate ip_pool_t pool;
2130Sstevel@tonic-gate
2140Sstevel@tonic-gate err = 1;
2150Sstevel@tonic-gate role = 0;
2160Sstevel@tonic-gate type = 0;
2170Sstevel@tonic-gate poolname = NULL;
2180Sstevel@tonic-gate role = IPL_LOGIPF;
2190Sstevel@tonic-gate bzero((char *)&iph, sizeof(iph));
2200Sstevel@tonic-gate bzero((char *)&pool, sizeof(pool));
2210Sstevel@tonic-gate
2222934Sjojemann while ((c = getopt(argc, argv, "dm:no:RS:t:v")) != -1)
2230Sstevel@tonic-gate switch (c)
2240Sstevel@tonic-gate {
2250Sstevel@tonic-gate case 'd' :
2260Sstevel@tonic-gate opts |= OPT_DEBUG;
2270Sstevel@tonic-gate ippool_yydebug++;
2280Sstevel@tonic-gate break;
2290Sstevel@tonic-gate case 'm' :
2300Sstevel@tonic-gate poolname = optarg;
2310Sstevel@tonic-gate break;
2320Sstevel@tonic-gate case 'n' :
2330Sstevel@tonic-gate opts |= OPT_DONOTHING;
2340Sstevel@tonic-gate break;
2350Sstevel@tonic-gate case 'o' :
2360Sstevel@tonic-gate role = getrole(optarg);
2370Sstevel@tonic-gate if (role == IPL_LOGNONE) {
2380Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg);
2390Sstevel@tonic-gate return -1;
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate break;
2422393Syz155240 case 'R' :
2432393Syz155240 opts |= OPT_NORESOLVE;
2442393Syz155240 break;
2450Sstevel@tonic-gate case 'S' :
2460Sstevel@tonic-gate iph.iph_seed = atoi(optarg);
2470Sstevel@tonic-gate break;
2480Sstevel@tonic-gate case 't' :
2490Sstevel@tonic-gate type = gettype(optarg, &iph.iph_type);
2500Sstevel@tonic-gate if (type == IPLT_NONE) {
2510Sstevel@tonic-gate fprintf(stderr, "unknown type '%s'\n", optarg);
2520Sstevel@tonic-gate return -1;
2530Sstevel@tonic-gate }
2540Sstevel@tonic-gate break;
2550Sstevel@tonic-gate case 'v' :
2560Sstevel@tonic-gate opts |= OPT_VERBOSE;
2570Sstevel@tonic-gate break;
2580Sstevel@tonic-gate }
2590Sstevel@tonic-gate
2602393Syz155240 if (opts & OPT_DEBUG)
2612393Syz155240 fprintf(stderr, "poolcommand: opts = %#x\n", opts);
2622393Syz155240
2630Sstevel@tonic-gate if (poolname == NULL) {
2640Sstevel@tonic-gate fprintf(stderr, "poolname not given with add/remove pool\n");
2650Sstevel@tonic-gate return -1;
2660Sstevel@tonic-gate }
2670Sstevel@tonic-gate
2680Sstevel@tonic-gate if (type == IPLT_HASH) {
2690Sstevel@tonic-gate strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
2700Sstevel@tonic-gate iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
2710Sstevel@tonic-gate iph.iph_unit = role;
2720Sstevel@tonic-gate } else if (type == IPLT_POOL) {
2730Sstevel@tonic-gate strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
2740Sstevel@tonic-gate pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
2750Sstevel@tonic-gate pool.ipo_unit = role;
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate if (remove == 0) {
2790Sstevel@tonic-gate switch (type)
2800Sstevel@tonic-gate {
2810Sstevel@tonic-gate case IPLT_HASH :
2820Sstevel@tonic-gate err = load_hash(&iph, NULL, ioctl);
2830Sstevel@tonic-gate break;
2840Sstevel@tonic-gate case IPLT_POOL :
2850Sstevel@tonic-gate err = load_pool(&pool, ioctl);
2860Sstevel@tonic-gate break;
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate } else {
2890Sstevel@tonic-gate switch (type)
2900Sstevel@tonic-gate {
2910Sstevel@tonic-gate case IPLT_HASH :
2920Sstevel@tonic-gate err = remove_hash(&iph, ioctl);
2930Sstevel@tonic-gate break;
2940Sstevel@tonic-gate case IPLT_POOL :
2950Sstevel@tonic-gate err = remove_pool(&pool, ioctl);
2960Sstevel@tonic-gate break;
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate }
2990Sstevel@tonic-gate return err;
3000Sstevel@tonic-gate }
3010Sstevel@tonic-gate
3020Sstevel@tonic-gate
loadpoolfile(argc,argv,infile)3030Sstevel@tonic-gate int loadpoolfile(argc, argv, infile)
3040Sstevel@tonic-gate int argc;
3050Sstevel@tonic-gate char *argv[], *infile;
3060Sstevel@tonic-gate {
3070Sstevel@tonic-gate int c;
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate infile = optarg;
3100Sstevel@tonic-gate
3112393Syz155240 while ((c = getopt(argc, argv, "dnRuv")) != -1)
3120Sstevel@tonic-gate switch (c)
3130Sstevel@tonic-gate {
3140Sstevel@tonic-gate case 'd' :
3150Sstevel@tonic-gate opts |= OPT_DEBUG;
3160Sstevel@tonic-gate ippool_yydebug++;
3170Sstevel@tonic-gate break;
3180Sstevel@tonic-gate case 'n' :
3190Sstevel@tonic-gate opts |= OPT_DONOTHING;
3200Sstevel@tonic-gate break;
3212393Syz155240 case 'R' :
3222393Syz155240 opts |= OPT_NORESOLVE;
3232393Syz155240 break;
3242393Syz155240 case 'u' :
3250Sstevel@tonic-gate opts |= OPT_REMOVE;
3260Sstevel@tonic-gate break;
3270Sstevel@tonic-gate case 'v' :
3280Sstevel@tonic-gate opts |= OPT_VERBOSE;
3290Sstevel@tonic-gate break;
3300Sstevel@tonic-gate }
3310Sstevel@tonic-gate
3322393Syz155240 if (opts & OPT_DEBUG)
3332393Syz155240 fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
3342393Syz155240
3350Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) {
3360Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR);
3370Sstevel@tonic-gate if (fd == -1) {
3380Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)");
3390Sstevel@tonic-gate exit(1);
3400Sstevel@tonic-gate }
3410Sstevel@tonic-gate }
3420Sstevel@tonic-gate
3430Sstevel@tonic-gate if (ippool_parsefile(fd, infile, ioctl) != 0)
3440Sstevel@tonic-gate return -1;
3450Sstevel@tonic-gate return 0;
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate
3480Sstevel@tonic-gate
poollist(argc,argv)3490Sstevel@tonic-gate int poollist(argc, argv)
3500Sstevel@tonic-gate int argc;
3510Sstevel@tonic-gate char *argv[];
3520Sstevel@tonic-gate {
3530Sstevel@tonic-gate char *kernel, *core, *poolname;
3540Sstevel@tonic-gate int c, role, type, live_kernel;
3550Sstevel@tonic-gate ip_pool_stat_t *plstp, plstat;
356637Sml37995 iphtstat_t *htstp, htstat;
357637Sml37995 iphtable_t *hptr;
3580Sstevel@tonic-gate iplookupop_t op;
3590Sstevel@tonic-gate ip_pool_t *ptr;
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate core = NULL;
3620Sstevel@tonic-gate kernel = NULL;
3630Sstevel@tonic-gate live_kernel = 1;
3640Sstevel@tonic-gate type = IPLT_ALL;
3650Sstevel@tonic-gate poolname = NULL;
3660Sstevel@tonic-gate role = IPL_LOGALL;
3670Sstevel@tonic-gate
3682393Syz155240 while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
3690Sstevel@tonic-gate switch (c)
3700Sstevel@tonic-gate {
3710Sstevel@tonic-gate case 'd' :
3720Sstevel@tonic-gate opts |= OPT_DEBUG;
3730Sstevel@tonic-gate break;
3740Sstevel@tonic-gate case 'm' :
3750Sstevel@tonic-gate poolname = optarg;
3760Sstevel@tonic-gate break;
3770Sstevel@tonic-gate case 'M' :
3780Sstevel@tonic-gate live_kernel = 0;
3790Sstevel@tonic-gate core = optarg;
3800Sstevel@tonic-gate break;
3810Sstevel@tonic-gate case 'N' :
3820Sstevel@tonic-gate live_kernel = 0;
3830Sstevel@tonic-gate kernel = optarg;
3840Sstevel@tonic-gate break;
3850Sstevel@tonic-gate case 'o' :
3860Sstevel@tonic-gate role = getrole(optarg);
3870Sstevel@tonic-gate if (role == IPL_LOGNONE) {
3880Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg);
3890Sstevel@tonic-gate return -1;
3900Sstevel@tonic-gate }
3910Sstevel@tonic-gate break;
3922393Syz155240 case 'R' :
3932393Syz155240 opts |= OPT_NORESOLVE;
3942393Syz155240 break;
3950Sstevel@tonic-gate case 't' :
3960Sstevel@tonic-gate type = gettype(optarg, NULL);
3970Sstevel@tonic-gate if (type == IPLT_NONE) {
3980Sstevel@tonic-gate fprintf(stderr, "unknown type '%s'\n", optarg);
3990Sstevel@tonic-gate return -1;
4000Sstevel@tonic-gate }
4010Sstevel@tonic-gate break;
4020Sstevel@tonic-gate case 'v' :
4030Sstevel@tonic-gate opts |= OPT_VERBOSE;
4040Sstevel@tonic-gate break;
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate
407637Sml37995 if (opts & OPT_DEBUG)
408637Sml37995 fprintf(stderr, "poollist: opts = %#x\n", opts);
409637Sml37995
4100Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) {
4110Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR);
4120Sstevel@tonic-gate if (fd == -1) {
4130Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)");
4140Sstevel@tonic-gate exit(1);
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate }
4170Sstevel@tonic-gate
4180Sstevel@tonic-gate bzero((char *)&op, sizeof(op));
4190Sstevel@tonic-gate if (poolname != NULL) {
4200Sstevel@tonic-gate strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
4210Sstevel@tonic-gate op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
4220Sstevel@tonic-gate }
4230Sstevel@tonic-gate op.iplo_unit = role;
4240Sstevel@tonic-gate
425*3448Sdh155122 if (live_kernel == 0) {
426*3448Sdh155122 poollist_dead(role, poolname, type, kernel, core);
427*3448Sdh155122 return (0);
428*3448Sdh155122 }
4290Sstevel@tonic-gate
430637Sml37995 if (type == IPLT_ALL || type == IPLT_POOL) {
431637Sml37995 plstp = &plstat;
432637Sml37995 op.iplo_type = IPLT_POOL;
433637Sml37995 op.iplo_size = sizeof(plstat);
434637Sml37995 op.iplo_struct = &plstat;
435*3448Sdh155122 op.iplo_name[0] = '\0';
436*3448Sdh155122 op.iplo_arg = 0;
437*3448Sdh155122
438*3448Sdh155122 if (role != IPL_LOGALL) {
439*3448Sdh155122 op.iplo_unit = role;
440*3448Sdh155122
441*3448Sdh155122 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
442*3448Sdh155122 if (c == -1) {
443*3448Sdh155122 perror("ioctl(SIOCLOOKUPSTAT)");
444*3448Sdh155122 return -1;
445*3448Sdh155122 }
446*3448Sdh155122
447*3448Sdh155122 showpools_live(fd, role, &plstat, poolname, opts);
448*3448Sdh155122 } else {
449*3448Sdh155122 for (role = 0; role <= IPL_LOGMAX; role++) {
450*3448Sdh155122 op.iplo_unit = role;
451*3448Sdh155122
452*3448Sdh155122 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
453*3448Sdh155122 if (c == -1) {
454*3448Sdh155122 perror("ioctl(SIOCLOOKUPSTAT)");
455*3448Sdh155122 return -1;
456*3448Sdh155122 }
457*3448Sdh155122
458*3448Sdh155122 showpools_live(fd, role, &plstat, poolname, opts);
459*3448Sdh155122 }
460*3448Sdh155122
461*3448Sdh155122 role = IPL_LOGALL;
4620Sstevel@tonic-gate }
463*3448Sdh155122 }
464*3448Sdh155122 if (type == IPLT_ALL || type == IPLT_HASH) {
465*3448Sdh155122 htstp = &htstat;
466*3448Sdh155122 op.iplo_type = IPLT_HASH;
467*3448Sdh155122 op.iplo_size = sizeof(htstat);
468*3448Sdh155122 op.iplo_struct = &htstat;
469*3448Sdh155122 op.iplo_name[0] = '\0';
470*3448Sdh155122 op.iplo_arg = 0;
471637Sml37995
472637Sml37995 if (role != IPL_LOGALL) {
473*3448Sdh155122 op.iplo_unit = role;
474*3448Sdh155122
475*3448Sdh155122 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
476*3448Sdh155122 if (c == -1) {
477*3448Sdh155122 perror("ioctl(SIOCLOOKUPSTAT)");
478*3448Sdh155122 return -1;
479*3448Sdh155122 }
480*3448Sdh155122 showhashs_live(fd, role, &htstat, poolname, opts);
481*3448Sdh155122 } else {
482*3448Sdh155122 for (role = 0; role <= IPL_LOGMAX; role++) {
483*3448Sdh155122
484*3448Sdh155122 op.iplo_unit = role;
485*3448Sdh155122 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
486*3448Sdh155122 if (c == -1) {
487*3448Sdh155122 perror("ioctl(SIOCLOOKUPSTAT)");
488*3448Sdh155122 return -1;
489*3448Sdh155122 }
490*3448Sdh155122
491*3448Sdh155122 showhashs_live(fd, role, &htstat, poolname, opts);
492*3448Sdh155122 }
493*3448Sdh155122 }
494*3448Sdh155122 }
495*3448Sdh155122 return 0;
496*3448Sdh155122 }
497*3448Sdh155122
poollist_dead(role,poolname,type,kernel,core)498*3448Sdh155122 void poollist_dead(role, poolname, type, kernel, core)
499*3448Sdh155122 int role, type;
500*3448Sdh155122 char *poolname, *kernel, *core;
501*3448Sdh155122 {
502*3448Sdh155122 iphtable_t *hptr;
503*3448Sdh155122 ip_pool_t *ptr;
504*3448Sdh155122
505*3448Sdh155122 if (openkmem(kernel, core) == -1)
506*3448Sdh155122 exit(-1);
507*3448Sdh155122
508*3448Sdh155122 if (type == IPLT_ALL || type == IPLT_POOL) {
509*3448Sdh155122 ip_pool_t *pools[IPL_LOGSIZE];
510*3448Sdh155122 struct nlist names[2] = { { "ip_pool_list" } , { "" } };
511*3448Sdh155122
512*3448Sdh155122 if (nlist(kernel, names) != 1)
513*3448Sdh155122 return;
514*3448Sdh155122
515*3448Sdh155122 bzero(&pools, sizeof(pools));
516*3448Sdh155122 if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
517*3448Sdh155122 return;
518*3448Sdh155122
519*3448Sdh155122 if (role != IPL_LOGALL) {
520*3448Sdh155122 ptr = pools[role];
5210Sstevel@tonic-gate while (ptr != NULL) {
522*3448Sdh155122 ptr = printpool(ptr, kmemcpywrap,
523*3448Sdh155122 poolname, opts);
5240Sstevel@tonic-gate }
525637Sml37995 } else {
526637Sml37995 for (role = 0; role <= IPL_LOGMAX; role++) {
527*3448Sdh155122 ptr = pools[role];
528637Sml37995 while (ptr != NULL) {
529637Sml37995 ptr = printpool(ptr, kmemcpywrap,
5302393Syz155240 poolname, opts);
531637Sml37995 }
532637Sml37995 }
533637Sml37995 role = IPL_LOGALL;
534637Sml37995 }
535637Sml37995 }
536637Sml37995 if (type == IPLT_ALL || type == IPLT_HASH) {
537*3448Sdh155122 iphtable_t *tables[IPL_LOGSIZE];
538*3448Sdh155122 struct nlist names[2] = { { "ipf_htables" } , { "" } };
539*3448Sdh155122
540*3448Sdh155122 if (nlist(kernel, names) != 1)
541*3448Sdh155122 return;
542*3448Sdh155122
543*3448Sdh155122 bzero(&tables, sizeof(tables));
544*3448Sdh155122 if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
545*3448Sdh155122 return;
546637Sml37995
547637Sml37995 if (role != IPL_LOGALL) {
548*3448Sdh155122 hptr = tables[role];
549637Sml37995 while (hptr != NULL) {
5502393Syz155240 hptr = printhash(hptr, kmemcpywrap,
5512393Syz155240 poolname, opts);
552637Sml37995 }
553637Sml37995 } else {
554637Sml37995 for (role = 0; role <= IPL_LOGMAX; role++) {
555*3448Sdh155122 hptr = tables[role];
556637Sml37995 while (hptr != NULL) {
557637Sml37995 hptr = printhash(hptr, kmemcpywrap,
5582393Syz155240 poolname, opts);
559637Sml37995 }
560637Sml37995 }
5610Sstevel@tonic-gate }
5620Sstevel@tonic-gate }
5630Sstevel@tonic-gate }
5640Sstevel@tonic-gate
5650Sstevel@tonic-gate
566*3448Sdh155122 void
showpools_live(fd,role,plstp,poolname,opts)567*3448Sdh155122 showpools_live(fd, role, plstp, poolname, opts)
568*3448Sdh155122 int fd, role;
569*3448Sdh155122 ip_pool_stat_t *plstp;
570*3448Sdh155122 char *poolname;
571*3448Sdh155122 int opts;
572*3448Sdh155122 {
573*3448Sdh155122 ipflookupiter_t iter;
574*3448Sdh155122 ip_pool_t pool;
575*3448Sdh155122 ipfobj_t obj;
576*3448Sdh155122
577*3448Sdh155122 obj.ipfo_rev = IPFILTER_VERSION;
578*3448Sdh155122 obj.ipfo_type = IPFOBJ_LOOKUPITER;
579*3448Sdh155122 obj.ipfo_size = sizeof(iter);
580*3448Sdh155122 obj.ipfo_ptr = &iter;
581*3448Sdh155122
582*3448Sdh155122 iter.ili_type = IPLT_POOL;
583*3448Sdh155122 iter.ili_otype = IPFLOOKUPITER_LIST;
584*3448Sdh155122 iter.ili_ival = IPFGENITER_LOOKUP;
585*3448Sdh155122 iter.ili_data = &pool;
586*3448Sdh155122 iter.ili_unit = role;
587*3448Sdh155122 *iter.ili_name = '\0';
588*3448Sdh155122
589*3448Sdh155122 while (plstp->ipls_list[role] != NULL) {
590*3448Sdh155122 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
591*3448Sdh155122 perror("ioctl(SIOCLOOKUPITER)");
592*3448Sdh155122 break;
593*3448Sdh155122 }
594*3448Sdh155122 (void) printpool_live(&pool, fd, poolname, opts);
595*3448Sdh155122
596*3448Sdh155122 plstp->ipls_list[role] = pool.ipo_next;
597*3448Sdh155122 }
598*3448Sdh155122 }
599*3448Sdh155122
poolstats(argc,argv)6000Sstevel@tonic-gate int poolstats(argc, argv)
6010Sstevel@tonic-gate int argc;
6020Sstevel@tonic-gate char *argv[];
6030Sstevel@tonic-gate {
6040Sstevel@tonic-gate int c, type, role, live_kernel;
6050Sstevel@tonic-gate ip_pool_stat_t plstat;
6060Sstevel@tonic-gate char *kernel, *core;
607637Sml37995 iphtstat_t htstat;
6080Sstevel@tonic-gate iplookupop_t op;
6090Sstevel@tonic-gate
6100Sstevel@tonic-gate core = NULL;
6110Sstevel@tonic-gate kernel = NULL;
6120Sstevel@tonic-gate live_kernel = 1;
6130Sstevel@tonic-gate type = IPLT_ALL;
6140Sstevel@tonic-gate role = IPL_LOGALL;
6150Sstevel@tonic-gate
6160Sstevel@tonic-gate bzero((char *)&op, sizeof(op));
6170Sstevel@tonic-gate
6180Sstevel@tonic-gate while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
6190Sstevel@tonic-gate switch (c)
6200Sstevel@tonic-gate {
6210Sstevel@tonic-gate case 'd' :
6220Sstevel@tonic-gate opts |= OPT_DEBUG;
6230Sstevel@tonic-gate break;
6240Sstevel@tonic-gate case 'M' :
6250Sstevel@tonic-gate live_kernel = 0;
6260Sstevel@tonic-gate core = optarg;
6270Sstevel@tonic-gate break;
6280Sstevel@tonic-gate case 'N' :
6290Sstevel@tonic-gate live_kernel = 0;
6300Sstevel@tonic-gate kernel = optarg;
6310Sstevel@tonic-gate break;
6320Sstevel@tonic-gate case 'o' :
6330Sstevel@tonic-gate role = getrole(optarg);
6340Sstevel@tonic-gate if (role == IPL_LOGNONE) {
6350Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg);
6360Sstevel@tonic-gate return -1;
6370Sstevel@tonic-gate }
6380Sstevel@tonic-gate break;
6390Sstevel@tonic-gate case 't' :
6400Sstevel@tonic-gate type = gettype(optarg, NULL);
6410Sstevel@tonic-gate if (type != IPLT_POOL) {
6420Sstevel@tonic-gate fprintf(stderr,
6430Sstevel@tonic-gate "-s not supported for this type yet\n");
6440Sstevel@tonic-gate return -1;
6450Sstevel@tonic-gate }
6460Sstevel@tonic-gate break;
6470Sstevel@tonic-gate case 'v' :
6480Sstevel@tonic-gate opts |= OPT_VERBOSE;
6490Sstevel@tonic-gate break;
6500Sstevel@tonic-gate }
6510Sstevel@tonic-gate
652637Sml37995 if (opts & OPT_DEBUG)
653637Sml37995 fprintf(stderr, "poolstats: opts = %#x\n", opts);
654637Sml37995
6550Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) {
6560Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR);
6570Sstevel@tonic-gate if (fd == -1) {
6580Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)");
6590Sstevel@tonic-gate exit(1);
6600Sstevel@tonic-gate }
6610Sstevel@tonic-gate }
6620Sstevel@tonic-gate
663637Sml37995 if (type == IPLT_ALL || type == IPLT_POOL) {
664637Sml37995 op.iplo_type = IPLT_POOL;
665637Sml37995 op.iplo_struct = &plstat;
666637Sml37995 op.iplo_size = sizeof(plstat);
667637Sml37995 if (!(opts & OPT_DONOTHING)) {
668637Sml37995 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
669637Sml37995 if (c == -1) {
670637Sml37995 perror("ioctl(SIOCLOOKUPSTAT)");
671637Sml37995 return -1;
672637Sml37995 }
673637Sml37995 printf("Pools:\t%lu\n", plstat.ipls_pools);
674637Sml37995 printf("Nodes:\t%lu\n", plstat.ipls_nodes);
6750Sstevel@tonic-gate }
676637Sml37995 }
677637Sml37995
678637Sml37995 if (type == IPLT_ALL || type == IPLT_HASH) {
679637Sml37995 op.iplo_type = IPLT_HASH;
680637Sml37995 op.iplo_struct = &htstat;
681637Sml37995 op.iplo_size = sizeof(htstat);
682637Sml37995 if (!(opts & OPT_DONOTHING)) {
683637Sml37995 c = ioctl(fd, SIOCLOOKUPSTAT, &op);
684637Sml37995 if (c == -1) {
685637Sml37995 perror("ioctl(SIOCLOOKUPSTAT)");
686637Sml37995 return -1;
687637Sml37995 }
688637Sml37995 printf("Hash Tables:\t%lu\n", htstat.iphs_numtables);
689637Sml37995 printf("Nodes:\t%lu\n", htstat.iphs_numnodes);
690637Sml37995 printf("Out of Memory:\t%lu\n", htstat.iphs_nomem);
691637Sml37995 }
6920Sstevel@tonic-gate }
6930Sstevel@tonic-gate return 0;
6940Sstevel@tonic-gate }
6950Sstevel@tonic-gate
6960Sstevel@tonic-gate
poolflush(argc,argv)6970Sstevel@tonic-gate int poolflush(argc, argv)
6980Sstevel@tonic-gate int argc;
6990Sstevel@tonic-gate char *argv[];
7000Sstevel@tonic-gate {
7010Sstevel@tonic-gate int c, role, type, arg;
7020Sstevel@tonic-gate iplookupflush_t flush;
7030Sstevel@tonic-gate
7040Sstevel@tonic-gate arg = IPLT_ALL;
7050Sstevel@tonic-gate type = IPLT_ALL;
7060Sstevel@tonic-gate role = IPL_LOGALL;
7070Sstevel@tonic-gate
7080Sstevel@tonic-gate while ((c = getopt(argc, argv, "do:t:v")) != -1)
7090Sstevel@tonic-gate switch (c)
7100Sstevel@tonic-gate {
7110Sstevel@tonic-gate case 'd' :
7120Sstevel@tonic-gate opts |= OPT_DEBUG;
7130Sstevel@tonic-gate break;
7140Sstevel@tonic-gate case 'o' :
7150Sstevel@tonic-gate role = getrole(optarg);
7160Sstevel@tonic-gate if (role == IPL_LOGNONE) {
7170Sstevel@tonic-gate fprintf(stderr, "unknown role '%s'\n", optarg);
7180Sstevel@tonic-gate return -1;
7190Sstevel@tonic-gate }
7200Sstevel@tonic-gate break;
7210Sstevel@tonic-gate case 't' :
7220Sstevel@tonic-gate type = gettype(optarg, NULL);
7230Sstevel@tonic-gate if (type == IPLT_NONE) {
7240Sstevel@tonic-gate fprintf(stderr, "unknown type '%s'\n", optarg);
7250Sstevel@tonic-gate return -1;
7260Sstevel@tonic-gate }
7270Sstevel@tonic-gate break;
7280Sstevel@tonic-gate case 'v' :
7290Sstevel@tonic-gate opts |= OPT_VERBOSE;
7300Sstevel@tonic-gate break;
7310Sstevel@tonic-gate }
7320Sstevel@tonic-gate
7332393Syz155240 if (opts & OPT_DEBUG)
7342393Syz155240 fprintf(stderr, "poolflush: opts = %#x\n", opts);
7352393Syz155240
7360Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (fd == -1)) {
7370Sstevel@tonic-gate fd = open(IPLOOKUP_NAME, O_RDWR);
7380Sstevel@tonic-gate if (fd == -1) {
7390Sstevel@tonic-gate perror("open(IPLOOKUP_NAME)");
7400Sstevel@tonic-gate exit(1);
7410Sstevel@tonic-gate }
7420Sstevel@tonic-gate }
7430Sstevel@tonic-gate
7440Sstevel@tonic-gate bzero((char *)&flush, sizeof(flush));
7450Sstevel@tonic-gate flush.iplf_type = type;
7460Sstevel@tonic-gate flush.iplf_unit = role;
7470Sstevel@tonic-gate flush.iplf_arg = arg;
7480Sstevel@tonic-gate
7490Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) {
7500Sstevel@tonic-gate if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
7510Sstevel@tonic-gate perror("ioctl(SIOCLOOKUPFLUSH)");
7520Sstevel@tonic-gate exit(1);
7530Sstevel@tonic-gate }
7540Sstevel@tonic-gate
7550Sstevel@tonic-gate }
7560Sstevel@tonic-gate printf("%u object%s flushed\n", flush.iplf_count,
7570Sstevel@tonic-gate (flush.iplf_count == 1) ? "" : "s");
7580Sstevel@tonic-gate
7590Sstevel@tonic-gate return 0;
7600Sstevel@tonic-gate }
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate
getrole(rolename)7630Sstevel@tonic-gate int getrole(rolename)
7640Sstevel@tonic-gate char *rolename;
7650Sstevel@tonic-gate {
7660Sstevel@tonic-gate int role;
7670Sstevel@tonic-gate
7680Sstevel@tonic-gate if (!strcasecmp(rolename, "ipf")) {
7690Sstevel@tonic-gate role = IPL_LOGIPF;
7700Sstevel@tonic-gate #if 0
7710Sstevel@tonic-gate } else if (!strcasecmp(rolename, "nat")) {
7720Sstevel@tonic-gate role = IPL_LOGNAT;
7730Sstevel@tonic-gate } else if (!strcasecmp(rolename, "state")) {
7740Sstevel@tonic-gate role = IPL_LOGSTATE;
7750Sstevel@tonic-gate } else if (!strcasecmp(rolename, "auth")) {
7760Sstevel@tonic-gate role = IPL_LOGAUTH;
7770Sstevel@tonic-gate } else if (!strcasecmp(rolename, "sync")) {
7780Sstevel@tonic-gate role = IPL_LOGSYNC;
7790Sstevel@tonic-gate } else if (!strcasecmp(rolename, "scan")) {
7800Sstevel@tonic-gate role = IPL_LOGSCAN;
7810Sstevel@tonic-gate } else if (!strcasecmp(rolename, "pool")) {
7820Sstevel@tonic-gate role = IPL_LOGLOOKUP;
7830Sstevel@tonic-gate } else if (!strcasecmp(rolename, "count")) {
7840Sstevel@tonic-gate role = IPL_LOGCOUNT;
7850Sstevel@tonic-gate #endif
7860Sstevel@tonic-gate } else {
7870Sstevel@tonic-gate role = IPL_LOGNONE;
7880Sstevel@tonic-gate }
7890Sstevel@tonic-gate
7900Sstevel@tonic-gate return role;
7910Sstevel@tonic-gate }
7920Sstevel@tonic-gate
7930Sstevel@tonic-gate
gettype(typename,minor)7940Sstevel@tonic-gate int gettype(typename, minor)
7950Sstevel@tonic-gate char *typename;
7960Sstevel@tonic-gate u_int *minor;
7970Sstevel@tonic-gate {
7980Sstevel@tonic-gate int type;
7990Sstevel@tonic-gate
8002393Syz155240 if (!strcasecmp(optarg, "tree")) {
8010Sstevel@tonic-gate type = IPLT_POOL;
8020Sstevel@tonic-gate } else if (!strcasecmp(optarg, "hash")) {
8030Sstevel@tonic-gate type = IPLT_HASH;
8040Sstevel@tonic-gate if (minor != NULL)
8050Sstevel@tonic-gate *minor = IPHASH_LOOKUP;
8060Sstevel@tonic-gate } else if (!strcasecmp(optarg, "group-map")) {
8070Sstevel@tonic-gate type = IPLT_HASH;
8080Sstevel@tonic-gate if (minor != NULL)
8090Sstevel@tonic-gate *minor = IPHASH_GROUPMAP;
8100Sstevel@tonic-gate } else {
8110Sstevel@tonic-gate type = IPLT_NONE;
8120Sstevel@tonic-gate }
8130Sstevel@tonic-gate return type;
8140Sstevel@tonic-gate }
815*3448Sdh155122
showhashs_live(fd,role,htstp,poolname,opts)816*3448Sdh155122 void showhashs_live(fd, role, htstp, poolname, opts)
817*3448Sdh155122 int fd, role;
818*3448Sdh155122 iphtstat_t *htstp;
819*3448Sdh155122 char *poolname;
820*3448Sdh155122 int opts;
821*3448Sdh155122 {
822*3448Sdh155122 ipflookupiter_t iter;
823*3448Sdh155122 iphtable_t table;
824*3448Sdh155122 ipfobj_t obj;
825*3448Sdh155122
826*3448Sdh155122 obj.ipfo_rev = IPFILTER_VERSION;
827*3448Sdh155122 obj.ipfo_type = IPFOBJ_LOOKUPITER;
828*3448Sdh155122 obj.ipfo_size = sizeof(iter);
829*3448Sdh155122 obj.ipfo_ptr = &iter;
830*3448Sdh155122
831*3448Sdh155122 iter.ili_type = IPLT_HASH;
832*3448Sdh155122 iter.ili_otype = IPFLOOKUPITER_LIST;
833*3448Sdh155122 iter.ili_ival = IPFGENITER_LOOKUP;
834*3448Sdh155122 iter.ili_data = &table;
835*3448Sdh155122 iter.ili_unit = role;
836*3448Sdh155122 *iter.ili_name = '\0';
837*3448Sdh155122
838*3448Sdh155122 while (htstp->iphs_tables != NULL) {
839*3448Sdh155122 if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
840*3448Sdh155122 perror("ioctl(SIOCLOOKUPITER)");
841*3448Sdh155122 break;
842*3448Sdh155122 }
843*3448Sdh155122
844*3448Sdh155122 printhash_live(&table, fd, poolname, opts);
845*3448Sdh155122
846*3448Sdh155122 htstp->iphs_tables = table.iph_next;
847*3448Sdh155122 }
848*3448Sdh155122 }
849