141edb306SCy Schubert
241edb306SCy Schubert /*
341edb306SCy Schubert * Copyright (C) 2012 by Darren Reed.
441edb306SCy Schubert *
541edb306SCy Schubert * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert */
741edb306SCy Schubert #include <sys/types.h>
841edb306SCy Schubert #include <sys/time.h>
941edb306SCy Schubert #include <sys/param.h>
1041edb306SCy Schubert #include <sys/socket.h>
1141edb306SCy Schubert # include <sys/cdefs.h>
1241edb306SCy Schubert #include <sys/ioctl.h>
1341edb306SCy Schubert
1441edb306SCy Schubert #include <net/if.h>
1541edb306SCy Schubert #include <netinet/in.h>
1641edb306SCy Schubert
1741edb306SCy Schubert #include <arpa/inet.h>
1841edb306SCy Schubert
1941edb306SCy Schubert #include <stdio.h>
2041edb306SCy Schubert #include <fcntl.h>
2141edb306SCy Schubert #include <stdlib.h>
2241edb306SCy Schubert #include <string.h>
2341edb306SCy Schubert #include <netdb.h>
2441edb306SCy Schubert #include <ctype.h>
2541edb306SCy Schubert #include <unistd.h>
2641edb306SCy Schubert # include <nlist.h>
2741edb306SCy Schubert
2841edb306SCy Schubert #include "ipf.h"
2941edb306SCy Schubert #include "netinet/ipl.h"
3041edb306SCy Schubert #include "netinet/ip_lookup.h"
3141edb306SCy Schubert #include "netinet/ip_pool.h"
3241edb306SCy Schubert #include "netinet/ip_htable.h"
3341edb306SCy Schubert #include "kmem.h"
3441edb306SCy Schubert
3541edb306SCy Schubert
3641edb306SCy Schubert extern int ippool_yyparse(void);
3741edb306SCy Schubert extern int ippool_yydebug;
3841edb306SCy Schubert extern FILE *ippool_yyin;
3941edb306SCy Schubert extern char *optarg;
4041edb306SCy Schubert extern int lineNum;
4141edb306SCy Schubert
4241edb306SCy Schubert void usage(char *);
4341edb306SCy Schubert int main(int, char **);
4441edb306SCy Schubert int poolcommand(int, int, char *[]);
4541edb306SCy Schubert int poolnodecommand(int, int, char *[]);
4641edb306SCy Schubert int loadpoolfile(int, char *[], char *);
4741edb306SCy Schubert int poollist(int, char *[]);
4841edb306SCy Schubert void poollist_dead(int, char *, int, char *, char *);
49*5568c8b2SCy Schubert int poollist_live(int, char *, int, int);
5041edb306SCy Schubert int poolflush(int, char *[]);
5141edb306SCy Schubert int poolstats(int, char *[]);
5241edb306SCy Schubert int gettype(char *, u_int *);
5341edb306SCy Schubert int getrole(char *);
5441edb306SCy Schubert int setnodeaddr(int, int, void *ptr, char *arg);
55*5568c8b2SCy Schubert int showpools_live(int, int, ipf_pool_stat_t *, char *);
56*5568c8b2SCy Schubert int showhashs_live(int, int, iphtstat_t *, char *);
57*5568c8b2SCy Schubert int showdstls_live(int, int, ipf_dstl_stat_t *, char *);
5841edb306SCy Schubert
5941edb306SCy Schubert int opts = 0;
6041edb306SCy Schubert int fd = -1;
6141edb306SCy Schubert int use_inet6 = 0;
6241edb306SCy Schubert wordtab_t *pool_fields = NULL;
6341edb306SCy Schubert int nohdrfields = 0;
6441edb306SCy Schubert
6541edb306SCy Schubert
6641edb306SCy Schubert void
usage(char * prog)67efeb8bffSCy Schubert usage(char *prog)
6841edb306SCy Schubert {
6941edb306SCy Schubert fprintf(stderr, "Usage:\t%s\n", prog);
7041edb306SCy Schubert fprintf(stderr, "\t-a [-dnv] -m <name> [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
7141edb306SCy Schubert fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
7241edb306SCy Schubert fprintf(stderr, "\t-f <file> [-dnuvR]\n");
7341edb306SCy Schubert fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
7441edb306SCy Schubert fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-o <role>] [-M <core>] [-N <namelist>]\n");
7541edb306SCy Schubert fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
7641edb306SCy Schubert fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
7741edb306SCy Schubert fprintf(stderr, "\t-s [-dtv]\n");
7841edb306SCy Schubert exit(1);
7941edb306SCy Schubert }
8041edb306SCy Schubert
8141edb306SCy Schubert
8241edb306SCy Schubert int
main(int argc,char * argv[])83efeb8bffSCy Schubert main(int argc, char *argv[])
8441edb306SCy Schubert {
8541edb306SCy Schubert int err = 1;
8641edb306SCy Schubert
8741edb306SCy Schubert if (argc < 2)
8841edb306SCy Schubert usage(argv[0]);
8941edb306SCy Schubert
9041edb306SCy Schubert assigndefined(getenv("IPPOOL_PREDEFINED"));
9141edb306SCy Schubert
9241edb306SCy Schubert switch (getopt(argc, argv, "aAf:FlrRs"))
9341edb306SCy Schubert {
9441edb306SCy Schubert case 'a' :
9541edb306SCy Schubert err = poolnodecommand(0, argc, argv);
9641edb306SCy Schubert break;
9741edb306SCy Schubert case 'A' :
9841edb306SCy Schubert err = poolcommand(0, argc, argv);
9941edb306SCy Schubert break;
10041edb306SCy Schubert case 'f' :
10141edb306SCy Schubert err = loadpoolfile(argc, argv, optarg);
10241edb306SCy Schubert break;
10341edb306SCy Schubert case 'F' :
10441edb306SCy Schubert err = poolflush(argc, argv);
10541edb306SCy Schubert break;
10641edb306SCy Schubert case 'l' :
10741edb306SCy Schubert err = poollist(argc, argv);
10841edb306SCy Schubert break;
10941edb306SCy Schubert case 'r' :
11041edb306SCy Schubert err = poolnodecommand(1, argc, argv);
11141edb306SCy Schubert break;
11241edb306SCy Schubert case 'R' :
11341edb306SCy Schubert err = poolcommand(1, argc, argv);
11441edb306SCy Schubert break;
11541edb306SCy Schubert case 's' :
11641edb306SCy Schubert err = poolstats(argc, argv);
11741edb306SCy Schubert break;
11841edb306SCy Schubert default :
11941edb306SCy Schubert exit(1);
12041edb306SCy Schubert }
12141edb306SCy Schubert
12241edb306SCy Schubert if (err != 0)
12341edb306SCy Schubert exit(1);
1242582ae57SCy Schubert return (0);
12541edb306SCy Schubert }
12641edb306SCy Schubert
12741edb306SCy Schubert
12841edb306SCy Schubert int
poolnodecommand(int remove,int argc,char * argv[])129efeb8bffSCy Schubert poolnodecommand(int remove, int argc, char *argv[])
13041edb306SCy Schubert {
13141edb306SCy Schubert int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
13241edb306SCy Schubert char *poolname = NULL;
13341edb306SCy Schubert ip_pool_node_t pnode;
13441edb306SCy Schubert iphtent_t hnode;
13541edb306SCy Schubert void *ptr = &pnode;
13641edb306SCy Schubert
13741edb306SCy Schubert ipset = 0;
13841edb306SCy Schubert role = IPL_LOGIPF;
13941edb306SCy Schubert bzero((char *)&pnode, sizeof(pnode));
14041edb306SCy Schubert bzero((char *)&hnode, sizeof(hnode));
14141edb306SCy Schubert
14241edb306SCy Schubert while ((c = getopt(argc, argv, "di:m:no:t:T:v")) != -1)
14341edb306SCy Schubert switch (c)
14441edb306SCy Schubert {
14541edb306SCy Schubert case 'd' :
14641edb306SCy Schubert opts |= OPT_DEBUG;
14741edb306SCy Schubert ippool_yydebug++;
14841edb306SCy Schubert break;
14941edb306SCy Schubert case 'i' :
15041edb306SCy Schubert if (setnodeaddr(type, role, ptr, optarg) == 0)
15141edb306SCy Schubert ipset = 1;
15241edb306SCy Schubert break;
15341edb306SCy Schubert case 'm' :
15441edb306SCy Schubert poolname = optarg;
15541edb306SCy Schubert break;
15641edb306SCy Schubert case 'n' :
15741edb306SCy Schubert opts |= OPT_DONOTHING|OPT_DONTOPEN;
15841edb306SCy Schubert break;
15941edb306SCy Schubert case 'o' :
16041edb306SCy Schubert if (ipset == 1) {
16141edb306SCy Schubert fprintf(stderr,
16241edb306SCy Schubert "cannot set role after ip address\n");
1632582ae57SCy Schubert return (-1);
16441edb306SCy Schubert }
16541edb306SCy Schubert role = getrole(optarg);
16641edb306SCy Schubert if (role == IPL_LOGNONE)
1672582ae57SCy Schubert return (-1);
16841edb306SCy Schubert break;
16941edb306SCy Schubert case 't' :
17041edb306SCy Schubert if (ipset == 1) {
17141edb306SCy Schubert fprintf(stderr,
17241edb306SCy Schubert "cannot set type after ip address\n");
1732582ae57SCy Schubert return (-1);
17441edb306SCy Schubert }
17541edb306SCy Schubert type = gettype(optarg, NULL);
17641edb306SCy Schubert switch (type) {
17741edb306SCy Schubert case IPLT_NONE :
17841edb306SCy Schubert fprintf(stderr, "unknown type '%s'\n", optarg);
1792582ae57SCy Schubert return (-1);
18041edb306SCy Schubert case IPLT_HASH :
18141edb306SCy Schubert ptr = &hnode;
18241edb306SCy Schubert break;
18341edb306SCy Schubert case IPLT_POOL :
18441edb306SCy Schubert default :
18541edb306SCy Schubert break;
18641edb306SCy Schubert }
18741edb306SCy Schubert break;
18841edb306SCy Schubert case 'T' :
18941edb306SCy Schubert if (remove == 0) {
19041edb306SCy Schubert ttl = atoi(optarg);
19141edb306SCy Schubert if (ttl < 0) {
19241edb306SCy Schubert fprintf(stderr, "cannot set negative ttl\n");
1932582ae57SCy Schubert return (-1);
19441edb306SCy Schubert }
19541edb306SCy Schubert } else {
19641edb306SCy Schubert usage(argv[0]);
19741edb306SCy Schubert }
19841edb306SCy Schubert break;
19941edb306SCy Schubert case 'v' :
20041edb306SCy Schubert opts |= OPT_VERBOSE;
20141edb306SCy Schubert break;
20241edb306SCy Schubert default :
20341edb306SCy Schubert usage(argv[0]);
20441edb306SCy Schubert break; /* keep compiler happy */
20541edb306SCy Schubert }
20641edb306SCy Schubert
20741edb306SCy Schubert if (argc - 1 - optind > 0)
20841edb306SCy Schubert usage(argv[0]);
20941edb306SCy Schubert
21041edb306SCy Schubert if (argv[optind] != NULL && ipset == 0) {
21141edb306SCy Schubert if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
21241edb306SCy Schubert ipset = 1;
21341edb306SCy Schubert }
21441edb306SCy Schubert
21541edb306SCy Schubert if (opts & OPT_DEBUG)
21641edb306SCy Schubert fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
21741edb306SCy Schubert
21841edb306SCy Schubert if (ipset == 0) {
21941edb306SCy Schubert fprintf(stderr, "no IP address given with -i\n");
2202582ae57SCy Schubert return (-1);
22141edb306SCy Schubert }
22241edb306SCy Schubert
22341edb306SCy Schubert if (poolname == NULL) {
22441edb306SCy Schubert fprintf(stderr, "poolname not given with add/remove node\n");
2252582ae57SCy Schubert return (-1);
22641edb306SCy Schubert }
22741edb306SCy Schubert
22841edb306SCy Schubert switch (type) {
22941edb306SCy Schubert case IPLT_POOL :
23041edb306SCy Schubert if (remove == 0)
23141edb306SCy Schubert err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
23241edb306SCy Schubert else
23341edb306SCy Schubert err = remove_poolnode(role, poolname, &pnode, ioctl);
23441edb306SCy Schubert break;
23541edb306SCy Schubert case IPLT_HASH :
23641edb306SCy Schubert if (remove == 0)
23741edb306SCy Schubert err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
23841edb306SCy Schubert else
23941edb306SCy Schubert err = remove_hashnode(role, poolname, &hnode, ioctl);
24041edb306SCy Schubert break;
24141edb306SCy Schubert default :
24241edb306SCy Schubert break;
24341edb306SCy Schubert }
2442582ae57SCy Schubert return (err);
24541edb306SCy Schubert }
24641edb306SCy Schubert
24741edb306SCy Schubert
24841edb306SCy Schubert int
poolcommand(int remove,int argc,char * argv[])249efeb8bffSCy Schubert poolcommand(int remove, int argc, char *argv[])
25041edb306SCy Schubert {
25141edb306SCy Schubert int type, role, c, err;
25241edb306SCy Schubert char *poolname, *typearg = NULL;
25341edb306SCy Schubert iphtable_t iph;
25441edb306SCy Schubert ip_pool_t pool;
25541edb306SCy Schubert
25641edb306SCy Schubert err = 1;
25741edb306SCy Schubert role = 0;
25841edb306SCy Schubert type = 0;
25941edb306SCy Schubert poolname = NULL;
26041edb306SCy Schubert role = IPL_LOGIPF;
26141edb306SCy Schubert bzero((char *)&iph, sizeof(iph));
26241edb306SCy Schubert bzero((char *)&pool, sizeof(pool));
26341edb306SCy Schubert
26441edb306SCy Schubert while ((c = getopt(argc, argv, "dm:no:S:vt:")) != -1)
26541edb306SCy Schubert switch (c)
26641edb306SCy Schubert {
26741edb306SCy Schubert case 'd' :
26841edb306SCy Schubert opts |= OPT_DEBUG;
26941edb306SCy Schubert ippool_yydebug++;
27041edb306SCy Schubert break;
27141edb306SCy Schubert case 'm' :
27241edb306SCy Schubert poolname = optarg;
27341edb306SCy Schubert break;
27441edb306SCy Schubert case 'n' :
27541edb306SCy Schubert opts |= OPT_DONOTHING|OPT_DONTOPEN;
27641edb306SCy Schubert break;
27741edb306SCy Schubert case 'o' :
27841edb306SCy Schubert role = getrole(optarg);
27941edb306SCy Schubert if (role == IPL_LOGNONE) {
28041edb306SCy Schubert fprintf(stderr, "unknown role '%s'\n", optarg);
2812582ae57SCy Schubert return (-1);
28241edb306SCy Schubert }
28341edb306SCy Schubert break;
28441edb306SCy Schubert case 'S' :
28541edb306SCy Schubert if (remove == 0)
28641edb306SCy Schubert iph.iph_seed = atoi(optarg);
28741edb306SCy Schubert else
28841edb306SCy Schubert usage(argv[0]);
28941edb306SCy Schubert break;
29041edb306SCy Schubert case 't' :
29141edb306SCy Schubert type = gettype(optarg, &iph.iph_type);
29241edb306SCy Schubert typearg = optarg;
29341edb306SCy Schubert break;
29441edb306SCy Schubert case 'v' :
29541edb306SCy Schubert opts |= OPT_VERBOSE;
29641edb306SCy Schubert break;
29741edb306SCy Schubert default :
29841edb306SCy Schubert usage(argv[0]);
29941edb306SCy Schubert break; /* keep compiler happy */
30041edb306SCy Schubert }
30141edb306SCy Schubert
30241edb306SCy Schubert if (argc - 1 - optind > 0)
30341edb306SCy Schubert usage(argv[0]);
30441edb306SCy Schubert
30541edb306SCy Schubert if (opts & OPT_DEBUG)
30641edb306SCy Schubert fprintf(stderr, "poolcommand: opts = %#x\n", opts);
30741edb306SCy Schubert
30841edb306SCy Schubert if (poolname == NULL) {
30941edb306SCy Schubert fprintf(stderr, "poolname not given with add/remove pool\n");
3102582ae57SCy Schubert return (-1);
31141edb306SCy Schubert }
31241edb306SCy Schubert
31341edb306SCy Schubert if (type == IPLT_NONE && remove == 0) {
31441edb306SCy Schubert if (typearg == NULL) {
31541edb306SCy Schubert fprintf(stderr, "type must be specified\n");
31641edb306SCy Schubert usage(argv[0]);
31741edb306SCy Schubert } else {
31841edb306SCy Schubert fprintf(stderr, "unknown type '%s'\n", typearg);
31941edb306SCy Schubert }
3202582ae57SCy Schubert return (-1);
32141edb306SCy Schubert }
32241edb306SCy Schubert
32341edb306SCy Schubert if (type == IPLT_HASH || (type == IPLT_NONE && remove == 1)) {
32441edb306SCy Schubert strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
32541edb306SCy Schubert iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
32641edb306SCy Schubert iph.iph_unit = role;
32741edb306SCy Schubert }
32841edb306SCy Schubert if (type == IPLT_POOL || (type == IPLT_NONE && remove == 1)) {
32941edb306SCy Schubert strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
33041edb306SCy Schubert pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
33141edb306SCy Schubert pool.ipo_unit = role;
33241edb306SCy Schubert }
33341edb306SCy Schubert
33441edb306SCy Schubert if (remove == 0) {
33541edb306SCy Schubert switch (type)
33641edb306SCy Schubert {
33741edb306SCy Schubert case IPLT_HASH :
33841edb306SCy Schubert err = load_hash(&iph, NULL, ioctl);
33941edb306SCy Schubert break;
34041edb306SCy Schubert case IPLT_POOL :
34141edb306SCy Schubert err = load_pool(&pool, ioctl);
34241edb306SCy Schubert break;
34341edb306SCy Schubert }
34441edb306SCy Schubert } else {
34541edb306SCy Schubert switch (type)
34641edb306SCy Schubert {
34741edb306SCy Schubert case IPLT_HASH :
34841edb306SCy Schubert err = remove_hash(&iph, ioctl);
34941edb306SCy Schubert break;
35041edb306SCy Schubert case IPLT_POOL :
35141edb306SCy Schubert err = remove_pool(&pool, ioctl);
35241edb306SCy Schubert break;
35341edb306SCy Schubert case IPLT_NONE :
35441edb306SCy Schubert err = 1;
35541edb306SCy Schubert {
35641edb306SCy Schubert int err_h, err_p;
35741edb306SCy Schubert err_h = remove_hash(&iph, ioctl);
35841edb306SCy Schubert err_p = remove_pool(&pool, ioctl);
35941edb306SCy Schubert if (err_h == 0 || err_p == 0)
36041edb306SCy Schubert err = 0;
36141edb306SCy Schubert }
36241edb306SCy Schubert break;
36341edb306SCy Schubert }
36441edb306SCy Schubert }
3652582ae57SCy Schubert return (err);
36641edb306SCy Schubert }
36741edb306SCy Schubert
36841edb306SCy Schubert
36941edb306SCy Schubert int
loadpoolfile(int argc,char * argv[],char * infile)370efeb8bffSCy Schubert loadpoolfile(int argc, char *argv[], char *infile)
37141edb306SCy Schubert {
37241edb306SCy Schubert int c;
37341edb306SCy Schubert
37441edb306SCy Schubert while ((c = getopt(argc, argv, "dnuvf:")) != -1)
37541edb306SCy Schubert switch (c)
37641edb306SCy Schubert {
37741edb306SCy Schubert case 'd' :
37841edb306SCy Schubert opts |= OPT_DEBUG;
37941edb306SCy Schubert ippool_yydebug++;
38041edb306SCy Schubert break;
38141edb306SCy Schubert case 'f' :
38241edb306SCy Schubert if (loadpoolfile(argc, argv, optarg) != 0)
38341edb306SCy Schubert return (-1);
38441edb306SCy Schubert break;
38541edb306SCy Schubert case 'n' :
38641edb306SCy Schubert opts |= OPT_DONOTHING|OPT_DONTOPEN;
38741edb306SCy Schubert break;
38841edb306SCy Schubert case 'u' :
38941edb306SCy Schubert opts |= OPT_REMOVE;
39041edb306SCy Schubert break;
39141edb306SCy Schubert case 'v' :
39241edb306SCy Schubert opts |= OPT_VERBOSE;
39341edb306SCy Schubert break;
39441edb306SCy Schubert default :
39541edb306SCy Schubert usage(argv[0]);
39641edb306SCy Schubert break; /* keep compiler happy */
39741edb306SCy Schubert }
39841edb306SCy Schubert
39941edb306SCy Schubert if (argc - 1 - optind > 0)
40041edb306SCy Schubert usage(argv[0]);
40141edb306SCy Schubert
40241edb306SCy Schubert if (opts & OPT_DEBUG)
40341edb306SCy Schubert fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
40441edb306SCy Schubert
40541edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
40641edb306SCy Schubert fd = open(IPLOOKUP_NAME, O_RDWR);
40741edb306SCy Schubert if (fd == -1) {
40841edb306SCy Schubert perror("open(IPLOOKUP_NAME)");
40941edb306SCy Schubert exit(1);
41041edb306SCy Schubert }
41141edb306SCy Schubert }
41241edb306SCy Schubert
41341edb306SCy Schubert if (ippool_parsefile(fd, infile, ioctl) != 0)
4142582ae57SCy Schubert return (-1);
4152582ae57SCy Schubert return (0);
41641edb306SCy Schubert }
41741edb306SCy Schubert
41841edb306SCy Schubert
41941edb306SCy Schubert int
poolstats(int argc,char * argv[])420efeb8bffSCy Schubert poolstats(int argc, char *argv[])
42141edb306SCy Schubert {
42241edb306SCy Schubert int c, type, role;
42341edb306SCy Schubert ipf_pool_stat_t plstat;
42441edb306SCy Schubert ipf_dstl_stat_t dlstat;
42541edb306SCy Schubert iphtstat_t htstat;
42641edb306SCy Schubert iplookupop_t op;
42741edb306SCy Schubert
42841edb306SCy Schubert type = IPLT_ALL;
42941edb306SCy Schubert role = IPL_LOGALL;
43041edb306SCy Schubert
43141edb306SCy Schubert bzero((char *)&op, sizeof(op));
43241edb306SCy Schubert
43341edb306SCy Schubert while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
43441edb306SCy Schubert switch (c)
43541edb306SCy Schubert {
43641edb306SCy Schubert case 'd' :
43741edb306SCy Schubert opts |= OPT_DEBUG;
43841edb306SCy Schubert break;
43941edb306SCy Schubert case 'o' :
44041edb306SCy Schubert role = getrole(optarg);
44141edb306SCy Schubert if (role == IPL_LOGNONE) {
44241edb306SCy Schubert fprintf(stderr, "unknown role '%s'\n", optarg);
4432582ae57SCy Schubert return (-1);
44441edb306SCy Schubert }
44541edb306SCy Schubert break;
44641edb306SCy Schubert case 't' :
44741edb306SCy Schubert type = gettype(optarg, NULL);
44841edb306SCy Schubert if (type != IPLT_POOL) {
44941edb306SCy Schubert fprintf(stderr,
45041edb306SCy Schubert "-s not supported for this type yet\n");
4512582ae57SCy Schubert return (-1);
45241edb306SCy Schubert }
45341edb306SCy Schubert break;
45441edb306SCy Schubert case 'v' :
45541edb306SCy Schubert opts |= OPT_VERBOSE;
45641edb306SCy Schubert break;
45741edb306SCy Schubert default :
45841edb306SCy Schubert usage(argv[0]);
45941edb306SCy Schubert break; /* keep compiler happy */
46041edb306SCy Schubert }
46141edb306SCy Schubert
46241edb306SCy Schubert if (argc - 1 - optind > 0)
46341edb306SCy Schubert usage(argv[0]);
46441edb306SCy Schubert
46541edb306SCy Schubert if (opts & OPT_DEBUG)
46641edb306SCy Schubert fprintf(stderr, "poolstats: opts = %#x\n", opts);
46741edb306SCy Schubert
46841edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
46941edb306SCy Schubert fd = open(IPLOOKUP_NAME, O_RDWR);
47041edb306SCy Schubert if (fd == -1) {
47141edb306SCy Schubert perror("open(IPLOOKUP_NAME)");
47241edb306SCy Schubert exit(1);
47341edb306SCy Schubert }
47441edb306SCy Schubert }
47541edb306SCy Schubert
47641edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_POOL) {
47741edb306SCy Schubert op.iplo_type = IPLT_POOL;
47841edb306SCy Schubert op.iplo_struct = &plstat;
47941edb306SCy Schubert op.iplo_size = sizeof(plstat);
48041edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
48141edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
48241edb306SCy Schubert if (c == -1) {
48341edb306SCy Schubert ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
4842582ae57SCy Schubert return (-1);
48541edb306SCy Schubert }
48641edb306SCy Schubert printf("%lu\taddress pools\n", plstat.ipls_pools);
48741edb306SCy Schubert printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
48841edb306SCy Schubert }
48941edb306SCy Schubert }
49041edb306SCy Schubert
49141edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_HASH) {
49241edb306SCy Schubert op.iplo_type = IPLT_HASH;
49341edb306SCy Schubert op.iplo_struct = &htstat;
49441edb306SCy Schubert op.iplo_size = sizeof(htstat);
49541edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
49641edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
49741edb306SCy Schubert if (c == -1) {
49841edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
4992582ae57SCy Schubert return (-1);
50041edb306SCy Schubert }
50141edb306SCy Schubert printf("%lu\thash tables\n", htstat.iphs_numtables);
50241edb306SCy Schubert printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
50341edb306SCy Schubert printf("%lu\thash table no memory \n",
50441edb306SCy Schubert htstat.iphs_nomem);
50541edb306SCy Schubert }
50641edb306SCy Schubert }
50741edb306SCy Schubert
50841edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_DSTLIST) {
50941edb306SCy Schubert op.iplo_type = IPLT_DSTLIST;
51041edb306SCy Schubert op.iplo_struct = &dlstat;
51141edb306SCy Schubert op.iplo_size = sizeof(dlstat);
51241edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
51341edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
51441edb306SCy Schubert if (c == -1) {
51541edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
5162582ae57SCy Schubert return (-1);
51741edb306SCy Schubert }
51841edb306SCy Schubert printf("%u\tdestination lists\n",
51941edb306SCy Schubert dlstat.ipls_numlists);
52041edb306SCy Schubert printf("%u\tdestination list nodes\n",
52141edb306SCy Schubert dlstat.ipls_numnodes);
52241edb306SCy Schubert printf("%lu\tdestination list no memory\n",
52341edb306SCy Schubert dlstat.ipls_nomem);
52441edb306SCy Schubert printf("%u\tdestination list zombies\n",
52541edb306SCy Schubert dlstat.ipls_numdereflists);
52641edb306SCy Schubert printf("%u\tdesetination list node zombies\n",
52741edb306SCy Schubert dlstat.ipls_numderefnodes);
52841edb306SCy Schubert }
52941edb306SCy Schubert }
5302582ae57SCy Schubert return (0);
53141edb306SCy Schubert }
53241edb306SCy Schubert
53341edb306SCy Schubert
53441edb306SCy Schubert int
poolflush(int argc,char * argv[])535efeb8bffSCy Schubert poolflush(int argc, char *argv[])
53641edb306SCy Schubert {
53741edb306SCy Schubert int c, role, type, arg;
53841edb306SCy Schubert iplookupflush_t flush;
53941edb306SCy Schubert
54041edb306SCy Schubert arg = IPLT_ALL;
54141edb306SCy Schubert type = IPLT_ALL;
54241edb306SCy Schubert role = IPL_LOGALL;
54341edb306SCy Schubert
54441edb306SCy Schubert while ((c = getopt(argc, argv, "do:t:v")) != -1)
54541edb306SCy Schubert switch (c)
54641edb306SCy Schubert {
54741edb306SCy Schubert case 'd' :
54841edb306SCy Schubert opts |= OPT_DEBUG;
54941edb306SCy Schubert break;
55041edb306SCy Schubert case 'o' :
55141edb306SCy Schubert role = getrole(optarg);
55241edb306SCy Schubert if (role == IPL_LOGNONE) {
55341edb306SCy Schubert fprintf(stderr, "unknown role '%s'\n", optarg);
5542582ae57SCy Schubert return (-1);
55541edb306SCy Schubert }
55641edb306SCy Schubert break;
55741edb306SCy Schubert case 't' :
55841edb306SCy Schubert type = gettype(optarg, NULL);
55941edb306SCy Schubert if (type == IPLT_NONE) {
56041edb306SCy Schubert fprintf(stderr, "unknown type '%s'\n", optarg);
5612582ae57SCy Schubert return (-1);
56241edb306SCy Schubert }
56341edb306SCy Schubert break;
56441edb306SCy Schubert case 'v' :
56541edb306SCy Schubert opts |= OPT_VERBOSE;
56641edb306SCy Schubert break;
56741edb306SCy Schubert default :
56841edb306SCy Schubert usage(argv[0]);
56941edb306SCy Schubert break; /* keep compiler happy */
57041edb306SCy Schubert }
57141edb306SCy Schubert
57241edb306SCy Schubert if (argc - optind > 0)
57341edb306SCy Schubert usage(argv[0]);
57441edb306SCy Schubert
57541edb306SCy Schubert if (opts & OPT_DEBUG)
57641edb306SCy Schubert fprintf(stderr, "poolflush: opts = %#x\n", opts);
57741edb306SCy Schubert
57841edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
57941edb306SCy Schubert fd = open(IPLOOKUP_NAME, O_RDWR);
58041edb306SCy Schubert if (fd == -1) {
58141edb306SCy Schubert perror("open(IPLOOKUP_NAME)");
58241edb306SCy Schubert exit(1);
58341edb306SCy Schubert }
58441edb306SCy Schubert }
58541edb306SCy Schubert
58641edb306SCy Schubert bzero((char *)&flush, sizeof(flush));
58741edb306SCy Schubert flush.iplf_type = type;
58841edb306SCy Schubert flush.iplf_unit = role;
58941edb306SCy Schubert flush.iplf_arg = arg;
59041edb306SCy Schubert
59141edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
59241edb306SCy Schubert if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
59341edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
59441edb306SCy Schubert exit(1);
59541edb306SCy Schubert }
59641edb306SCy Schubert
59741edb306SCy Schubert }
59841edb306SCy Schubert printf("%u object%s flushed\n", flush.iplf_count,
59941edb306SCy Schubert (flush.iplf_count == 1) ? "" : "s");
60041edb306SCy Schubert
6012582ae57SCy Schubert return (0);
60241edb306SCy Schubert }
60341edb306SCy Schubert
60441edb306SCy Schubert
60541edb306SCy Schubert int
getrole(char * rolename)606efeb8bffSCy Schubert getrole(char *rolename)
60741edb306SCy Schubert {
60841edb306SCy Schubert int role;
60941edb306SCy Schubert
61041edb306SCy Schubert if (!strcasecmp(rolename, "ipf")) {
61141edb306SCy Schubert role = IPL_LOGIPF;
61241edb306SCy Schubert #if 0
61341edb306SCy Schubert } else if (!strcasecmp(rolename, "nat")) {
61441edb306SCy Schubert role = IPL_LOGNAT;
61541edb306SCy Schubert } else if (!strcasecmp(rolename, "state")) {
61641edb306SCy Schubert role = IPL_LOGSTATE;
61741edb306SCy Schubert } else if (!strcasecmp(rolename, "auth")) {
61841edb306SCy Schubert role = IPL_LOGAUTH;
61941edb306SCy Schubert } else if (!strcasecmp(rolename, "sync")) {
62041edb306SCy Schubert role = IPL_LOGSYNC;
62141edb306SCy Schubert } else if (!strcasecmp(rolename, "scan")) {
62241edb306SCy Schubert role = IPL_LOGSCAN;
62341edb306SCy Schubert } else if (!strcasecmp(rolename, "pool")) {
62441edb306SCy Schubert role = IPL_LOGLOOKUP;
62541edb306SCy Schubert } else if (!strcasecmp(rolename, "count")) {
62641edb306SCy Schubert role = IPL_LOGCOUNT;
62741edb306SCy Schubert #endif
62841edb306SCy Schubert } else {
62941edb306SCy Schubert role = IPL_LOGNONE;
63041edb306SCy Schubert }
63141edb306SCy Schubert
6322582ae57SCy Schubert return (role);
63341edb306SCy Schubert }
63441edb306SCy Schubert
63541edb306SCy Schubert
63641edb306SCy Schubert int
gettype(char * typename,u_int * minor)637efeb8bffSCy Schubert gettype(char *typename, u_int *minor)
63841edb306SCy Schubert {
63941edb306SCy Schubert int type;
64041edb306SCy Schubert
64141edb306SCy Schubert if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
64241edb306SCy Schubert type = IPLT_POOL;
64341edb306SCy Schubert } else if (!strcasecmp(typename, "hash")) {
64441edb306SCy Schubert type = IPLT_HASH;
64541edb306SCy Schubert if (minor != NULL)
64641edb306SCy Schubert *minor = IPHASH_LOOKUP;
64741edb306SCy Schubert } else if (!strcasecmp(typename, "group-map")) {
64841edb306SCy Schubert type = IPLT_HASH;
64941edb306SCy Schubert if (minor != NULL)
65041edb306SCy Schubert *minor = IPHASH_GROUPMAP;
65141edb306SCy Schubert } else {
65241edb306SCy Schubert type = IPLT_NONE;
65341edb306SCy Schubert }
6542582ae57SCy Schubert return (type);
65541edb306SCy Schubert }
65641edb306SCy Schubert
65741edb306SCy Schubert
65841edb306SCy Schubert int
poollist(int argc,char * argv[])659efeb8bffSCy Schubert poollist(int argc, char *argv[])
66041edb306SCy Schubert {
66141edb306SCy Schubert char *kernel, *core, *poolname;
66241edb306SCy Schubert int c, role, type, live_kernel;
66341edb306SCy Schubert iplookupop_t op;
66441edb306SCy Schubert
66541edb306SCy Schubert core = NULL;
66641edb306SCy Schubert kernel = NULL;
66741edb306SCy Schubert live_kernel = 1;
66841edb306SCy Schubert type = IPLT_ALL;
66941edb306SCy Schubert poolname = NULL;
67041edb306SCy Schubert role = IPL_LOGALL;
67141edb306SCy Schubert
6727531c434SCy Schubert while ((c = getopt(argc, argv, "dDm:M:N:o:t:v")) != -1)
67341edb306SCy Schubert switch (c)
67441edb306SCy Schubert {
67541edb306SCy Schubert case 'd' :
67641edb306SCy Schubert opts |= OPT_DEBUG;
67741edb306SCy Schubert break;
6787531c434SCy Schubert case 'D' :
6797531c434SCy Schubert opts |= OPT_SAVEOUT;
6807531c434SCy Schubert break;
68141edb306SCy Schubert case 'm' :
68241edb306SCy Schubert poolname = optarg;
68341edb306SCy Schubert break;
68441edb306SCy Schubert case 'M' :
68541edb306SCy Schubert live_kernel = 0;
68641edb306SCy Schubert core = optarg;
68741edb306SCy Schubert break;
68841edb306SCy Schubert case 'N' :
68941edb306SCy Schubert live_kernel = 0;
69041edb306SCy Schubert kernel = optarg;
69141edb306SCy Schubert break;
69241edb306SCy Schubert case 'o' :
69341edb306SCy Schubert role = getrole(optarg);
69441edb306SCy Schubert if (role == IPL_LOGNONE) {
69541edb306SCy Schubert fprintf(stderr, "unknown role '%s'\n", optarg);
6962582ae57SCy Schubert return (-1);
69741edb306SCy Schubert }
69841edb306SCy Schubert break;
69941edb306SCy Schubert #if 0
70041edb306SCy Schubert case 'O' :
70141edb306SCy Schubert /* XXX This option does not work. This function as */
70241edb306SCy Schubert /* XXX used by state and nat can be used to format */
70341edb306SCy Schubert /* XXX output especially useful for scripting. It */
70441edb306SCy Schubert /* XXX is left here with the intention of making */
70541edb306SCy Schubert /* XXX it work for the same purpose at some point. */
70641edb306SCy Schubert pool_fields = parsefields(poolfields, optarg);
70741edb306SCy Schubert break;
70841edb306SCy Schubert #endif
70941edb306SCy Schubert case 't' :
71041edb306SCy Schubert type = gettype(optarg, NULL);
71141edb306SCy Schubert if (type == IPLT_NONE) {
71241edb306SCy Schubert fprintf(stderr, "unknown type '%s'\n", optarg);
7132582ae57SCy Schubert return (-1);
71441edb306SCy Schubert }
71541edb306SCy Schubert break;
71641edb306SCy Schubert case 'v' :
71741edb306SCy Schubert opts |= OPT_VERBOSE;
71841edb306SCy Schubert break;
71941edb306SCy Schubert default :
72041edb306SCy Schubert usage(argv[0]);
72141edb306SCy Schubert break; /* keep compiler happy */
72241edb306SCy Schubert }
72341edb306SCy Schubert
72441edb306SCy Schubert if (argc - optind > 0)
72541edb306SCy Schubert usage(argv[0]);
72641edb306SCy Schubert
72741edb306SCy Schubert if (opts & OPT_DEBUG)
72841edb306SCy Schubert fprintf(stderr, "poollist: opts = %#x\n", opts);
72941edb306SCy Schubert
73041edb306SCy Schubert if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
73141edb306SCy Schubert fd = open(IPLOOKUP_NAME, O_RDWR);
73241edb306SCy Schubert if (fd == -1) {
73341edb306SCy Schubert perror("open(IPLOOKUP_NAME)");
73441edb306SCy Schubert exit(1);
73541edb306SCy Schubert }
73641edb306SCy Schubert }
73741edb306SCy Schubert
73841edb306SCy Schubert bzero((char *)&op, sizeof(op));
73941edb306SCy Schubert if (poolname != NULL) {
74041edb306SCy Schubert strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
74141edb306SCy Schubert op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
74241edb306SCy Schubert }
74341edb306SCy Schubert op.iplo_unit = role;
74441edb306SCy Schubert
745*5568c8b2SCy Schubert if (live_kernel) {
746*5568c8b2SCy Schubert if (poollist_live(role, poolname, type, fd) != 0)
747*5568c8b2SCy Schubert return (1);
748*5568c8b2SCy Schubert } else
74941edb306SCy Schubert poollist_dead(role, poolname, type, kernel, core);
7502582ae57SCy Schubert return (0);
75141edb306SCy Schubert }
75241edb306SCy Schubert
75341edb306SCy Schubert
75441edb306SCy Schubert void
poollist_dead(int role,char * poolname,int type,char * kernel,char * core)755efeb8bffSCy Schubert poollist_dead(int role, char *poolname, int type, char *kernel, char *core)
75641edb306SCy Schubert {
75741edb306SCy Schubert iphtable_t *hptr;
75841edb306SCy Schubert ip_pool_t *ptr;
75941edb306SCy Schubert
76041edb306SCy Schubert if (openkmem(kernel, core) == -1)
76141edb306SCy Schubert exit(-1);
76241edb306SCy Schubert
76341edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_POOL) {
76441edb306SCy Schubert ip_pool_t *pools[IPL_LOGSIZE];
76541edb306SCy Schubert struct nlist names[2] = { { "ip_pool_list" } , { "" } };
76641edb306SCy Schubert
76741edb306SCy Schubert if (nlist(kernel, names) != 1)
76841edb306SCy Schubert return;
76941edb306SCy Schubert
77041edb306SCy Schubert bzero(&pools, sizeof(pools));
77141edb306SCy Schubert if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
77241edb306SCy Schubert return;
77341edb306SCy Schubert
77441edb306SCy Schubert if (role != IPL_LOGALL) {
77541edb306SCy Schubert ptr = pools[role];
77641edb306SCy Schubert while (ptr != NULL) {
77741edb306SCy Schubert ptr = printpool(ptr, kmemcpywrap, poolname,
77841edb306SCy Schubert opts, pool_fields);
77941edb306SCy Schubert }
78041edb306SCy Schubert } else {
78141edb306SCy Schubert for (role = 0; role <= IPL_LOGMAX; role++) {
78241edb306SCy Schubert ptr = pools[role];
78341edb306SCy Schubert while (ptr != NULL) {
78441edb306SCy Schubert ptr = printpool(ptr, kmemcpywrap,
78541edb306SCy Schubert poolname, opts,
78641edb306SCy Schubert pool_fields);
78741edb306SCy Schubert }
78841edb306SCy Schubert }
78941edb306SCy Schubert role = IPL_LOGALL;
79041edb306SCy Schubert }
79141edb306SCy Schubert }
79241edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_HASH) {
79341edb306SCy Schubert iphtable_t *tables[IPL_LOGSIZE];
79441edb306SCy Schubert struct nlist names[2] = { { "ipf_htables" } , { "" } };
79541edb306SCy Schubert
79641edb306SCy Schubert if (nlist(kernel, names) != 1)
79741edb306SCy Schubert return;
79841edb306SCy Schubert
79941edb306SCy Schubert bzero(&tables, sizeof(tables));
80041edb306SCy Schubert if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
80141edb306SCy Schubert return;
80241edb306SCy Schubert
80341edb306SCy Schubert if (role != IPL_LOGALL) {
80441edb306SCy Schubert hptr = tables[role];
80541edb306SCy Schubert while (hptr != NULL) {
80641edb306SCy Schubert hptr = printhash(hptr, kmemcpywrap,
80741edb306SCy Schubert poolname, opts, pool_fields);
80841edb306SCy Schubert }
80941edb306SCy Schubert } else {
81041edb306SCy Schubert for (role = 0; role <= IPL_LOGMAX; role++) {
81141edb306SCy Schubert hptr = tables[role];
81241edb306SCy Schubert while (hptr != NULL) {
81341edb306SCy Schubert hptr = printhash(hptr, kmemcpywrap,
81441edb306SCy Schubert poolname, opts,
81541edb306SCy Schubert pool_fields);
81641edb306SCy Schubert }
81741edb306SCy Schubert }
81841edb306SCy Schubert }
81941edb306SCy Schubert }
82041edb306SCy Schubert }
82141edb306SCy Schubert
82241edb306SCy Schubert
823*5568c8b2SCy Schubert int
poollist_live(int role,char * poolname,int type,int fd)824efeb8bffSCy Schubert poollist_live(int role, char *poolname, int type, int fd)
82541edb306SCy Schubert {
82641edb306SCy Schubert ipf_pool_stat_t plstat;
82741edb306SCy Schubert iplookupop_t op;
82841edb306SCy Schubert int c;
82941edb306SCy Schubert
83041edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_POOL) {
83141edb306SCy Schubert op.iplo_type = IPLT_POOL;
83241edb306SCy Schubert op.iplo_size = sizeof(plstat);
83341edb306SCy Schubert op.iplo_struct = &plstat;
83441edb306SCy Schubert op.iplo_name[0] = '\0';
83541edb306SCy Schubert op.iplo_arg = 0;
83641edb306SCy Schubert
83741edb306SCy Schubert if (role != IPL_LOGALL) {
83841edb306SCy Schubert op.iplo_unit = role;
83941edb306SCy Schubert
84041edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
84141edb306SCy Schubert if (c == -1) {
84241edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
843*5568c8b2SCy Schubert return (1);
84441edb306SCy Schubert }
84541edb306SCy Schubert
846*5568c8b2SCy Schubert if (showpools_live(fd, role, &plstat, poolname))
847*5568c8b2SCy Schubert return (1);
84841edb306SCy Schubert } else {
84941edb306SCy Schubert for (role = -1; role <= IPL_LOGMAX; role++) {
85041edb306SCy Schubert op.iplo_unit = role;
85141edb306SCy Schubert
85241edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
85341edb306SCy Schubert if (c == -1) {
85441edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
855*5568c8b2SCy Schubert return (1);
85641edb306SCy Schubert }
85741edb306SCy Schubert
858*5568c8b2SCy Schubert if (showpools_live(fd, role, &plstat, poolname))
859*5568c8b2SCy Schubert return (1);
86041edb306SCy Schubert }
86141edb306SCy Schubert
86241edb306SCy Schubert role = IPL_LOGALL;
86341edb306SCy Schubert }
86441edb306SCy Schubert }
86541edb306SCy Schubert
86641edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_HASH) {
86741edb306SCy Schubert iphtstat_t htstat;
86841edb306SCy Schubert
86941edb306SCy Schubert op.iplo_type = IPLT_HASH;
87041edb306SCy Schubert op.iplo_size = sizeof(htstat);
87141edb306SCy Schubert op.iplo_struct = &htstat;
87241edb306SCy Schubert op.iplo_name[0] = '\0';
87341edb306SCy Schubert op.iplo_arg = 0;
87441edb306SCy Schubert
87541edb306SCy Schubert if (role != IPL_LOGALL) {
87641edb306SCy Schubert op.iplo_unit = role;
87741edb306SCy Schubert
87841edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
87941edb306SCy Schubert if (c == -1) {
88041edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
881*5568c8b2SCy Schubert return (1);
88241edb306SCy Schubert }
883*5568c8b2SCy Schubert if (showhashs_live(fd, role, &htstat, poolname))
884*5568c8b2SCy Schubert return (1);
88541edb306SCy Schubert } else {
88641edb306SCy Schubert for (role = 0; role <= IPL_LOGMAX; role++) {
88741edb306SCy Schubert
88841edb306SCy Schubert op.iplo_unit = role;
88941edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
89041edb306SCy Schubert if (c == -1) {
89141edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
892*5568c8b2SCy Schubert return (1);
89341edb306SCy Schubert }
89441edb306SCy Schubert
895*5568c8b2SCy Schubert if (showhashs_live(fd, role, &htstat, poolname))
896*5568c8b2SCy Schubert return(1);
89741edb306SCy Schubert }
89841edb306SCy Schubert role = IPL_LOGALL;
89941edb306SCy Schubert }
90041edb306SCy Schubert }
90141edb306SCy Schubert
90241edb306SCy Schubert if (type == IPLT_ALL || type == IPLT_DSTLIST) {
90341edb306SCy Schubert ipf_dstl_stat_t dlstat;
90441edb306SCy Schubert
90541edb306SCy Schubert op.iplo_type = IPLT_DSTLIST;
90641edb306SCy Schubert op.iplo_size = sizeof(dlstat);
90741edb306SCy Schubert op.iplo_struct = &dlstat;
90841edb306SCy Schubert op.iplo_name[0] = '\0';
90941edb306SCy Schubert op.iplo_arg = 0;
91041edb306SCy Schubert
91141edb306SCy Schubert if (role != IPL_LOGALL) {
91241edb306SCy Schubert op.iplo_unit = role;
91341edb306SCy Schubert
91441edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
91541edb306SCy Schubert if (c == -1) {
91641edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
917*5568c8b2SCy Schubert return (1);
91841edb306SCy Schubert }
919*5568c8b2SCy Schubert if (showdstls_live(fd, role, &dlstat, poolname))
920*5568c8b2SCy Schubert return (1);
92141edb306SCy Schubert } else {
92241edb306SCy Schubert for (role = 0; role <= IPL_LOGMAX; role++) {
92341edb306SCy Schubert
92441edb306SCy Schubert op.iplo_unit = role;
92541edb306SCy Schubert c = ioctl(fd, SIOCLOOKUPSTAT, &op);
92641edb306SCy Schubert if (c == -1) {
92741edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
928*5568c8b2SCy Schubert return (1);
92941edb306SCy Schubert }
93041edb306SCy Schubert
931*5568c8b2SCy Schubert if (showdstls_live(fd, role, &dlstat, poolname))
932*5568c8b2SCy Schubert return (1);
93341edb306SCy Schubert }
93441edb306SCy Schubert role = IPL_LOGALL;
93541edb306SCy Schubert }
93641edb306SCy Schubert }
937*5568c8b2SCy Schubert return (0);
93841edb306SCy Schubert }
93941edb306SCy Schubert
94041edb306SCy Schubert
941*5568c8b2SCy Schubert int
showpools_live(int fd,int role,ipf_pool_stat_t * plstp,char * poolname)942efeb8bffSCy Schubert showpools_live(int fd, int role, ipf_pool_stat_t *plstp, char *poolname)
94341edb306SCy Schubert {
94441edb306SCy Schubert ipflookupiter_t iter;
94541edb306SCy Schubert ip_pool_t pool;
94641edb306SCy Schubert ipfobj_t obj;
94741edb306SCy Schubert
94841edb306SCy Schubert obj.ipfo_rev = IPFILTER_VERSION;
94941edb306SCy Schubert obj.ipfo_type = IPFOBJ_LOOKUPITER;
95041edb306SCy Schubert obj.ipfo_size = sizeof(iter);
95141edb306SCy Schubert obj.ipfo_ptr = &iter;
95241edb306SCy Schubert
95341edb306SCy Schubert iter.ili_type = IPLT_POOL;
95441edb306SCy Schubert iter.ili_otype = IPFLOOKUPITER_LIST;
95541edb306SCy Schubert iter.ili_ival = IPFGENITER_LOOKUP;
95641edb306SCy Schubert iter.ili_nitems = 1;
95741edb306SCy Schubert iter.ili_data = &pool;
95841edb306SCy Schubert iter.ili_unit = role;
95941edb306SCy Schubert *iter.ili_name = '\0';
96041edb306SCy Schubert
96141edb306SCy Schubert bzero((char *)&pool, sizeof(pool));
96241edb306SCy Schubert
96341edb306SCy Schubert while (plstp->ipls_list[role + 1] != NULL) {
96441edb306SCy Schubert if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
96541edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPITER)");
966*5568c8b2SCy Schubert return (1);
96741edb306SCy Schubert }
96841edb306SCy Schubert if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
96941edb306SCy Schubert ((opts & OPT_DEBUG) != 0))
97041edb306SCy Schubert printpool_live(&pool, fd, poolname, opts, pool_fields);
97141edb306SCy Schubert
97241edb306SCy Schubert plstp->ipls_list[role + 1] = pool.ipo_next;
97341edb306SCy Schubert }
974*5568c8b2SCy Schubert return (0);
97541edb306SCy Schubert }
97641edb306SCy Schubert
97741edb306SCy Schubert
978*5568c8b2SCy Schubert int
showhashs_live(int fd,int role,iphtstat_t * htstp,char * poolname)979efeb8bffSCy Schubert showhashs_live(int fd, int role, iphtstat_t *htstp, char *poolname)
98041edb306SCy Schubert {
98141edb306SCy Schubert ipflookupiter_t iter;
98241edb306SCy Schubert iphtable_t table;
98341edb306SCy Schubert ipfobj_t obj;
98441edb306SCy Schubert
98541edb306SCy Schubert obj.ipfo_rev = IPFILTER_VERSION;
98641edb306SCy Schubert obj.ipfo_type = IPFOBJ_LOOKUPITER;
98741edb306SCy Schubert obj.ipfo_size = sizeof(iter);
98841edb306SCy Schubert obj.ipfo_ptr = &iter;
98941edb306SCy Schubert
99041edb306SCy Schubert iter.ili_type = IPLT_HASH;
99141edb306SCy Schubert iter.ili_otype = IPFLOOKUPITER_LIST;
99241edb306SCy Schubert iter.ili_ival = IPFGENITER_LOOKUP;
99341edb306SCy Schubert iter.ili_nitems = 1;
99441edb306SCy Schubert iter.ili_data = &table;
99541edb306SCy Schubert iter.ili_unit = role;
99641edb306SCy Schubert *iter.ili_name = '\0';
99741edb306SCy Schubert
99841edb306SCy Schubert while (htstp->iphs_tables != NULL) {
99941edb306SCy Schubert if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
100041edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1001*5568c8b2SCy Schubert return (1);
100241edb306SCy Schubert }
100341edb306SCy Schubert
100441edb306SCy Schubert printhash_live(&table, fd, poolname, opts, pool_fields);
100541edb306SCy Schubert
100641edb306SCy Schubert htstp->iphs_tables = table.iph_next;
100741edb306SCy Schubert }
1008*5568c8b2SCy Schubert return (0);
100941edb306SCy Schubert }
101041edb306SCy Schubert
101141edb306SCy Schubert
1012*5568c8b2SCy Schubert int
showdstls_live(int fd,int role,ipf_dstl_stat_t * dlstp,char * poolname)1013efeb8bffSCy Schubert showdstls_live(int fd, int role, ipf_dstl_stat_t *dlstp, char *poolname)
101441edb306SCy Schubert {
101541edb306SCy Schubert ipflookupiter_t iter;
101641edb306SCy Schubert ippool_dst_t table;
101741edb306SCy Schubert ipfobj_t obj;
101841edb306SCy Schubert
101941edb306SCy Schubert obj.ipfo_rev = IPFILTER_VERSION;
102041edb306SCy Schubert obj.ipfo_type = IPFOBJ_LOOKUPITER;
102141edb306SCy Schubert obj.ipfo_size = sizeof(iter);
102241edb306SCy Schubert obj.ipfo_ptr = &iter;
102341edb306SCy Schubert
102441edb306SCy Schubert iter.ili_type = IPLT_DSTLIST;
102541edb306SCy Schubert iter.ili_otype = IPFLOOKUPITER_LIST;
102641edb306SCy Schubert iter.ili_ival = IPFGENITER_LOOKUP;
102741edb306SCy Schubert iter.ili_nitems = 1;
102841edb306SCy Schubert iter.ili_data = &table;
102941edb306SCy Schubert iter.ili_unit = role;
103041edb306SCy Schubert *iter.ili_name = '\0';
103141edb306SCy Schubert
103241edb306SCy Schubert while (dlstp->ipls_list[role] != NULL) {
103341edb306SCy Schubert if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
103441edb306SCy Schubert ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1035*5568c8b2SCy Schubert return (1);
103641edb306SCy Schubert }
103741edb306SCy Schubert
103841edb306SCy Schubert printdstl_live(&table, fd, poolname, opts, pool_fields);
103941edb306SCy Schubert
104041edb306SCy Schubert dlstp->ipls_list[role] = table.ipld_next;
104141edb306SCy Schubert }
1042*5568c8b2SCy Schubert return (0);
104341edb306SCy Schubert }
104441edb306SCy Schubert
104541edb306SCy Schubert
104641edb306SCy Schubert int
setnodeaddr(int type,int role,void * ptr,char * arg)104741edb306SCy Schubert setnodeaddr(int type, int role, void *ptr, char *arg)
104841edb306SCy Schubert {
104941edb306SCy Schubert struct in_addr mask;
105041edb306SCy Schubert sa_family_t family;
105141edb306SCy Schubert char *s;
105241edb306SCy Schubert
105341edb306SCy Schubert if (strchr(arg, ':') == NULL) {
105441edb306SCy Schubert family = AF_INET;
105541edb306SCy Schubert s = strchr(arg, '/');
105641edb306SCy Schubert if (s == NULL)
105741edb306SCy Schubert mask.s_addr = 0xffffffff;
105841edb306SCy Schubert else if (strchr(s, '.') == NULL) {
105941edb306SCy Schubert if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
10602582ae57SCy Schubert return (-1);
106141edb306SCy Schubert } else {
106241edb306SCy Schubert mask.s_addr = inet_addr(s + 1);
106341edb306SCy Schubert }
106441edb306SCy Schubert if (s != NULL)
106541edb306SCy Schubert *s = '\0';
106641edb306SCy Schubert } else {
106741edb306SCy Schubert family = AF_INET6;
106841edb306SCy Schubert
106941edb306SCy Schubert /* XXX for now we use mask for IPv6 prefix length */
107041edb306SCy Schubert /* XXX mask should be a union with prefix */
107141edb306SCy Schubert /* XXX Currently address handling is sloppy. */
107241edb306SCy Schubert
107341edb306SCy Schubert if ((s = strchr(arg, '/')) == NULL)
107441edb306SCy Schubert mask.s_addr = 128;
107541edb306SCy Schubert else
107641edb306SCy Schubert mask.s_addr = atoi(s + 1);
107741edb306SCy Schubert }
107841edb306SCy Schubert
107941edb306SCy Schubert if (type == IPLT_POOL) {
108041edb306SCy Schubert ip_pool_node_t *node = ptr;
108141edb306SCy Schubert
108241edb306SCy Schubert node->ipn_addr.adf_family = family;
108341edb306SCy Schubert
108441edb306SCy Schubert #ifdef USE_INET6
108541edb306SCy Schubert if (node->ipn_addr.adf_family == AF_INET) {
108641edb306SCy Schubert #endif
108741edb306SCy Schubert node->ipn_addr.adf_len = offsetof(addrfamily_t,
108841edb306SCy Schubert adf_addr) +
108941edb306SCy Schubert sizeof(struct in_addr);
109041edb306SCy Schubert node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
109141edb306SCy Schubert #ifdef USE_INET6
109241edb306SCy Schubert } else {
109341edb306SCy Schubert node->ipn_addr.adf_len = offsetof(addrfamily_t,
109441edb306SCy Schubert adf_addr) +
109541edb306SCy Schubert sizeof(struct in6_addr);
109641edb306SCy Schubert inet_pton(AF_INET6, arg,
109741edb306SCy Schubert &node->ipn_addr.adf_addr.in6.s6_addr);
109841edb306SCy Schubert }
109941edb306SCy Schubert #endif
110041edb306SCy Schubert node->ipn_mask.adf_len = node->ipn_addr.adf_len;
110141edb306SCy Schubert node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
110241edb306SCy Schubert } else if (type == IPLT_HASH) {
110341edb306SCy Schubert iphtent_t *node = ptr;
110441edb306SCy Schubert
110541edb306SCy Schubert node->ipe_family = family;
110641edb306SCy Schubert node->ipe_unit = role;
110741edb306SCy Schubert
110841edb306SCy Schubert #ifdef USE_INET6
110941edb306SCy Schubert if (node->ipe_family == AF_INET) {
111041edb306SCy Schubert #endif
111141edb306SCy Schubert node->ipe_addr.in4.s_addr = inet_addr(arg);
111241edb306SCy Schubert node->ipe_mask.in4.s_addr = mask.s_addr;
111341edb306SCy Schubert #ifdef USE_INET6
111441edb306SCy Schubert } else {
111541edb306SCy Schubert inet_pton(AF_INET6, arg,
111641edb306SCy Schubert &node->ipe_addr.in6.__u6_addr.__u6_addr32);
111741edb306SCy Schubert node->ipe_mask.in6.__u6_addr.__u6_addr32[0] =
111841edb306SCy Schubert mask.s_addr;
111941edb306SCy Schubert node->ipe_mask.in6.__u6_addr.__u6_addr32[1] =
112041edb306SCy Schubert node->ipe_mask.in6.__u6_addr.__u6_addr32[2] =
112141edb306SCy Schubert node->ipe_mask.in6.__u6_addr.__u6_addr32[3] = 0;
112241edb306SCy Schubert }
112341edb306SCy Schubert #endif
112441edb306SCy Schubert }
112541edb306SCy Schubert
11262582ae57SCy Schubert return (0);
112741edb306SCy Schubert }
1128