ippool.c revision 353080
1145519Sdarrenr/*	$FreeBSD: stable/11/contrib/ipfilter/tools/ippool.c 353080 2019-10-04 01:47:00Z cy $	*/
2145510Sdarrenr
3145510Sdarrenr/*
4255332Scy * Copyright (C) 2012 by Darren Reed.
5145510Sdarrenr *
6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing.
7145510Sdarrenr */
8145510Sdarrenr#include <sys/types.h>
9145510Sdarrenr#include <sys/time.h>
10145510Sdarrenr#include <sys/param.h>
11145510Sdarrenr#include <sys/socket.h>
12145510Sdarrenr# include <sys/cdefs.h>
13145510Sdarrenr#include <sys/ioctl.h>
14145510Sdarrenr
15145510Sdarrenr#include <net/if.h>
16145510Sdarrenr#include <netinet/in.h>
17145510Sdarrenr
18145510Sdarrenr#include <arpa/inet.h>
19145510Sdarrenr
20145510Sdarrenr#include <stdio.h>
21145510Sdarrenr#include <fcntl.h>
22145510Sdarrenr#include <stdlib.h>
23145510Sdarrenr#include <string.h>
24145510Sdarrenr#include <netdb.h>
25145510Sdarrenr#include <ctype.h>
26145510Sdarrenr#include <unistd.h>
27170268Sdarrenr# include <nlist.h>
28145510Sdarrenr
29145510Sdarrenr#include "ipf.h"
30170268Sdarrenr#include "netinet/ipl.h"
31145510Sdarrenr#include "netinet/ip_lookup.h"
32145510Sdarrenr#include "netinet/ip_pool.h"
33145510Sdarrenr#include "netinet/ip_htable.h"
34145510Sdarrenr#include "kmem.h"
35145510Sdarrenr
36145510Sdarrenr
37145510Sdarrenrextern	int	ippool_yyparse __P((void));
38145510Sdarrenrextern	int	ippool_yydebug;
39145510Sdarrenrextern	FILE	*ippool_yyin;
40145510Sdarrenrextern	char	*optarg;
41145510Sdarrenrextern	int	lineNum;
42145510Sdarrenr
43145510Sdarrenrvoid	usage __P((char *));
44145510Sdarrenrint	main __P((int, char **));
45145510Sdarrenrint	poolcommand __P((int, int, char *[]));
46145510Sdarrenrint	poolnodecommand __P((int, int, char *[]));
47145510Sdarrenrint	loadpoolfile __P((int, char *[], char *));
48145510Sdarrenrint	poollist __P((int, char *[]));
49170268Sdarrenrvoid	poollist_dead __P((int, char *, int, char *, char *));
50170268Sdarrenrvoid	poollist_live __P((int, char *, int, int));
51145510Sdarrenrint	poolflush __P((int, char *[]));
52145510Sdarrenrint	poolstats __P((int, char *[]));
53145510Sdarrenrint	gettype __P((char *, u_int *));
54145510Sdarrenrint	getrole __P((char *));
55255332Scyint	setnodeaddr __P((int, int, void *ptr, char *arg));
56255332Scyvoid	showpools_live __P((int, int, ipf_pool_stat_t *, char *));
57170268Sdarrenrvoid	showhashs_live __P((int, int, iphtstat_t *, char *));
58255332Scyvoid	showdstls_live __P((int, int, ipf_dstl_stat_t *, char *));
59145510Sdarrenr
60145510Sdarrenrint	opts = 0;
61145510Sdarrenrint	fd = -1;
62145510Sdarrenrint	use_inet6 = 0;
63255332Scywordtab_t *pool_fields = NULL;
64255332Scyint	nohdrfields = 0;
65145510Sdarrenr
66145510Sdarrenr
67255332Scyvoid
68255332Scyusage(prog)
69255332Scy	char *prog;
70145510Sdarrenr{
71145510Sdarrenr	fprintf(stderr, "Usage:\t%s\n", prog);
72255332Scy	fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
73255332Scy	fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
74255332Scy	fprintf(stderr, "\t-f <file> [-dnuv]\n");
75255332Scy	fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
76353076Scy	fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>]\n");
77255332Scy	fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
78255332Scy	fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
79255332Scy	fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
80145510Sdarrenr	exit(1);
81145510Sdarrenr}
82145510Sdarrenr
83145510Sdarrenr
84255332Scyint
85255332Scymain(argc, argv)
86255332Scy	int argc;
87255332Scy	char *argv[];
88145510Sdarrenr{
89255332Scy	int err = 1;
90145510Sdarrenr
91145510Sdarrenr	if (argc < 2)
92145510Sdarrenr		usage(argv[0]);
93145510Sdarrenr
94255332Scy	assigndefined(getenv("IPPOOL_PREDEFINED"));
95255332Scy
96255332Scy	switch (getopt(argc, argv, "aAf:FlnrRsv"))
97145510Sdarrenr	{
98145510Sdarrenr	case 'a' :
99145510Sdarrenr		err = poolnodecommand(0, argc, argv);
100145510Sdarrenr		break;
101145510Sdarrenr	case 'A' :
102145510Sdarrenr		err = poolcommand(0, argc, argv);
103145510Sdarrenr		break;
104145510Sdarrenr	case 'f' :
105145510Sdarrenr		err = loadpoolfile(argc, argv, optarg);
106145510Sdarrenr		break;
107145510Sdarrenr	case 'F' :
108145510Sdarrenr		err = poolflush(argc, argv);
109145510Sdarrenr		break;
110145510Sdarrenr	case 'l' :
111145510Sdarrenr		err = poollist(argc, argv);
112145510Sdarrenr		break;
113255332Scy	case 'n' :
114255332Scy		opts |= OPT_DONOTHING|OPT_DONTOPEN;
115255332Scy		break;
116145510Sdarrenr	case 'r' :
117145510Sdarrenr		err = poolnodecommand(1, argc, argv);
118145510Sdarrenr		break;
119145510Sdarrenr	case 'R' :
120145510Sdarrenr		err = poolcommand(1, argc, argv);
121145510Sdarrenr		break;
122145510Sdarrenr	case 's' :
123145510Sdarrenr		err = poolstats(argc, argv);
124145510Sdarrenr		break;
125255332Scy	case 'v' :
126255332Scy		opts |= OPT_VERBOSE;
127255332Scy		break;
128145510Sdarrenr	default :
129145510Sdarrenr		exit(1);
130145510Sdarrenr	}
131145510Sdarrenr
132170268Sdarrenr	if (err != 0)
133170268Sdarrenr		exit(1);
134170268Sdarrenr	return 0;
135145510Sdarrenr}
136145510Sdarrenr
137145510Sdarrenr
138255332Scyint
139255332Scypoolnodecommand(remove, argc, argv)
140255332Scy	int remove, argc;
141255332Scy	char *argv[];
142145510Sdarrenr{
143255332Scy	int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
144170268Sdarrenr	char *poolname = NULL;
145255332Scy	ip_pool_node_t pnode;
146255332Scy	iphtent_t hnode;
147255332Scy	void *ptr = &pnode;
148145510Sdarrenr
149145510Sdarrenr	ipset = 0;
150145510Sdarrenr	role = IPL_LOGIPF;
151255332Scy	bzero((char *)&pnode, sizeof(pnode));
152255332Scy	bzero((char *)&hnode, sizeof(hnode));
153145510Sdarrenr
154255332Scy	while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1)
155145510Sdarrenr		switch (c)
156145510Sdarrenr		{
157145510Sdarrenr		case 'd' :
158145510Sdarrenr			opts |= OPT_DEBUG;
159145510Sdarrenr			ippool_yydebug++;
160145510Sdarrenr			break;
161145510Sdarrenr		case 'i' :
162255332Scy			if (setnodeaddr(type, role, ptr, optarg) == 0)
163170268Sdarrenr				ipset = 1;
164145510Sdarrenr			break;
165145510Sdarrenr		case 'm' :
166145510Sdarrenr			poolname = optarg;
167145510Sdarrenr			break;
168145510Sdarrenr		case 'n' :
169255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
170145510Sdarrenr			break;
171145510Sdarrenr		case 'o' :
172255332Scy			if (ipset == 1) {
173255332Scy				fprintf(stderr,
174255332Scy					"cannot set role after ip address\n");
175255332Scy				return -1;
176255332Scy			}
177145510Sdarrenr			role = getrole(optarg);
178145510Sdarrenr			if (role == IPL_LOGNONE)
179145510Sdarrenr				return -1;
180145510Sdarrenr			break;
181145510Sdarrenr		case 'R' :
182145510Sdarrenr			opts |= OPT_NORESOLVE;
183145510Sdarrenr			break;
184255332Scy		case 't' :
185255332Scy			if (ipset == 1) {
186255332Scy				fprintf(stderr,
187255332Scy					"cannot set type after ip address\n");
188255332Scy				return -1;
189255332Scy			}
190255332Scy			type = gettype(optarg, NULL);
191255332Scy			switch (type) {
192255332Scy			case IPLT_NONE :
193255332Scy				fprintf(stderr, "unknown type '%s'\n", optarg);
194255332Scy				return -1;
195255332Scy			case IPLT_HASH :
196255332Scy				ptr = &hnode;
197255332Scy				break;
198255332Scy			case IPLT_POOL :
199255332Scy			default :
200255332Scy				break;
201255332Scy			}
202255332Scy			break;
203255332Scy		case 'T' :
204255332Scy			ttl = atoi(optarg);
205255332Scy			if (ttl < 0) {
206255332Scy				fprintf(stderr, "cannot set negative ttl\n");
207255332Scy				return -1;
208255332Scy			}
209255332Scy			break;
210145510Sdarrenr		case 'v' :
211145510Sdarrenr			opts |= OPT_VERBOSE;
212145510Sdarrenr			break;
213145510Sdarrenr		}
214145510Sdarrenr
215170268Sdarrenr	if (argv[optind] != NULL && ipset == 0) {
216255332Scy		if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
217170268Sdarrenr			ipset = 1;
218170268Sdarrenr	}
219170268Sdarrenr
220145510Sdarrenr	if (opts & OPT_DEBUG)
221145510Sdarrenr		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
222145510Sdarrenr
223170268Sdarrenr	if (ipset == 0) {
224170268Sdarrenr		fprintf(stderr, "no IP address given with -i\n");
225145510Sdarrenr		return -1;
226170268Sdarrenr	}
227170268Sdarrenr
228145510Sdarrenr	if (poolname == NULL) {
229145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove node\n");
230145510Sdarrenr		return -1;
231145510Sdarrenr	}
232145510Sdarrenr
233255332Scy	switch (type) {
234255332Scy	case IPLT_POOL :
235255332Scy		if (remove == 0)
236255332Scy			err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
237255332Scy		else
238255332Scy			err = remove_poolnode(role, poolname, &pnode, ioctl);
239255332Scy		break;
240255332Scy	case IPLT_HASH :
241255332Scy		if (remove == 0)
242255332Scy			err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
243255332Scy		else
244255332Scy			err = remove_hashnode(role, poolname, &hnode, ioctl);
245255332Scy		break;
246255332Scy	default :
247255332Scy		break;
248255332Scy	}
249145510Sdarrenr	return err;
250145510Sdarrenr}
251145510Sdarrenr
252145510Sdarrenr
253255332Scyint
254255332Scypoolcommand(remove, argc, argv)
255255332Scy	int remove, argc;
256255332Scy	char *argv[];
257145510Sdarrenr{
258145510Sdarrenr	int type, role, c, err;
259145510Sdarrenr	char *poolname;
260145510Sdarrenr	iphtable_t iph;
261145510Sdarrenr	ip_pool_t pool;
262145510Sdarrenr
263145510Sdarrenr	err = 1;
264145510Sdarrenr	role = 0;
265145510Sdarrenr	type = 0;
266145510Sdarrenr	poolname = NULL;
267145510Sdarrenr	role = IPL_LOGIPF;
268145510Sdarrenr	bzero((char *)&iph, sizeof(iph));
269145510Sdarrenr	bzero((char *)&pool, sizeof(pool));
270145510Sdarrenr
271255332Scy	while ((c = getopt(argc, argv, "dm:no:RSv")) != -1)
272145510Sdarrenr		switch (c)
273145510Sdarrenr		{
274145510Sdarrenr		case 'd' :
275145510Sdarrenr			opts |= OPT_DEBUG;
276145510Sdarrenr			ippool_yydebug++;
277145510Sdarrenr			break;
278145510Sdarrenr		case 'm' :
279145510Sdarrenr			poolname = optarg;
280145510Sdarrenr			break;
281145510Sdarrenr		case 'n' :
282255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
283145510Sdarrenr			break;
284145510Sdarrenr		case 'o' :
285145510Sdarrenr			role = getrole(optarg);
286145510Sdarrenr			if (role == IPL_LOGNONE) {
287145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
288145510Sdarrenr				return -1;
289145510Sdarrenr			}
290145510Sdarrenr			break;
291145510Sdarrenr		case 'R' :
292145510Sdarrenr			opts |= OPT_NORESOLVE;
293145510Sdarrenr			break;
294145510Sdarrenr		case 'S' :
295145510Sdarrenr			iph.iph_seed = atoi(optarg);
296145510Sdarrenr			break;
297145510Sdarrenr		case 'v' :
298145510Sdarrenr			opts |= OPT_VERBOSE;
299145510Sdarrenr			break;
300145510Sdarrenr		}
301145510Sdarrenr
302145510Sdarrenr	if (opts & OPT_DEBUG)
303145510Sdarrenr		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
304145510Sdarrenr
305145510Sdarrenr	if (poolname == NULL) {
306145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove pool\n");
307145510Sdarrenr		return -1;
308145510Sdarrenr	}
309145510Sdarrenr
310255332Scy	type = gettype(argv[optind], &iph.iph_type);
311255332Scy	if (type == IPLT_NONE) {
312255332Scy		fprintf(stderr, "unknown type '%s'\n", argv[optind]);
313255332Scy		return -1;
314255332Scy	}
315255332Scy
316145510Sdarrenr	if (type == IPLT_HASH) {
317145510Sdarrenr		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
318145510Sdarrenr		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
319145510Sdarrenr		iph.iph_unit = role;
320145510Sdarrenr	} else if (type == IPLT_POOL) {
321145510Sdarrenr		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
322145510Sdarrenr		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
323145510Sdarrenr		pool.ipo_unit = role;
324145510Sdarrenr	}
325145510Sdarrenr
326145510Sdarrenr	if (remove == 0) {
327145510Sdarrenr		switch (type)
328145510Sdarrenr		{
329145510Sdarrenr		case IPLT_HASH :
330145510Sdarrenr			err = load_hash(&iph, NULL, ioctl);
331145510Sdarrenr			break;
332145510Sdarrenr		case IPLT_POOL :
333145510Sdarrenr			err = load_pool(&pool, ioctl);
334145510Sdarrenr			break;
335145510Sdarrenr		}
336145510Sdarrenr	} else {
337145510Sdarrenr		switch (type)
338145510Sdarrenr		{
339145510Sdarrenr		case IPLT_HASH :
340145510Sdarrenr			err = remove_hash(&iph, ioctl);
341145510Sdarrenr			break;
342145510Sdarrenr		case IPLT_POOL :
343145510Sdarrenr			err = remove_pool(&pool, ioctl);
344145510Sdarrenr			break;
345145510Sdarrenr		}
346145510Sdarrenr	}
347145510Sdarrenr	return err;
348145510Sdarrenr}
349145510Sdarrenr
350145510Sdarrenr
351255332Scyint
352255332Scyloadpoolfile(argc, argv, infile)
353255332Scy	int argc;
354255332Scy	char *argv[], *infile;
355145510Sdarrenr{
356145510Sdarrenr	int c;
357145510Sdarrenr
358145510Sdarrenr	while ((c = getopt(argc, argv, "dnRuv")) != -1)
359145510Sdarrenr		switch (c)
360145510Sdarrenr		{
361145510Sdarrenr		case 'd' :
362145510Sdarrenr			opts |= OPT_DEBUG;
363145510Sdarrenr			ippool_yydebug++;
364145510Sdarrenr			break;
365145510Sdarrenr		case 'n' :
366255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
367145510Sdarrenr			break;
368145510Sdarrenr		case 'R' :
369145510Sdarrenr			opts |= OPT_NORESOLVE;
370145510Sdarrenr			break;
371145510Sdarrenr		case 'u' :
372145510Sdarrenr			opts |= OPT_REMOVE;
373145510Sdarrenr			break;
374145510Sdarrenr		case 'v' :
375145510Sdarrenr			opts |= OPT_VERBOSE;
376145510Sdarrenr			break;
377353080Scy		default :
378353080Scy			usage(argv[0]);
379353080Scy			break;		/* keep compiler happy */
380145510Sdarrenr		}
381145510Sdarrenr
382353080Scy	if (argc - 1 - optind > 0)
383353080Scy		usage(argv[0]);
384353080Scy
385145510Sdarrenr	if (opts & OPT_DEBUG)
386145510Sdarrenr		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
387145510Sdarrenr
388255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
389145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
390145510Sdarrenr		if (fd == -1) {
391145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
392145510Sdarrenr			exit(1);
393145510Sdarrenr		}
394145510Sdarrenr	}
395145510Sdarrenr
396145510Sdarrenr	if (ippool_parsefile(fd, infile, ioctl) != 0)
397145510Sdarrenr		return -1;
398145510Sdarrenr	return 0;
399145510Sdarrenr}
400145510Sdarrenr
401145510Sdarrenr
402255332Scyint
403255332Scypoolstats(argc, argv)
404255332Scy	int argc;
405255332Scy	char *argv[];
406145510Sdarrenr{
407145510Sdarrenr	int c, type, role, live_kernel;
408255332Scy	ipf_pool_stat_t plstat;
409255332Scy	ipf_dstl_stat_t dlstat;
410145510Sdarrenr	char *kernel, *core;
411145510Sdarrenr	iphtstat_t htstat;
412145510Sdarrenr	iplookupop_t op;
413145510Sdarrenr
414145510Sdarrenr	core = NULL;
415145510Sdarrenr	kernel = NULL;
416145510Sdarrenr	live_kernel = 1;
417145510Sdarrenr	type = IPLT_ALL;
418145510Sdarrenr	role = IPL_LOGALL;
419145510Sdarrenr
420145510Sdarrenr	bzero((char *)&op, sizeof(op));
421145510Sdarrenr
422145510Sdarrenr	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
423145510Sdarrenr		switch (c)
424145510Sdarrenr		{
425145510Sdarrenr		case 'd' :
426145510Sdarrenr			opts |= OPT_DEBUG;
427145510Sdarrenr			break;
428145510Sdarrenr		case 'M' :
429145510Sdarrenr			live_kernel = 0;
430145510Sdarrenr			core = optarg;
431145510Sdarrenr			break;
432145510Sdarrenr		case 'N' :
433145510Sdarrenr			live_kernel = 0;
434145510Sdarrenr			kernel = optarg;
435145510Sdarrenr			break;
436145510Sdarrenr		case 'o' :
437145510Sdarrenr			role = getrole(optarg);
438145510Sdarrenr			if (role == IPL_LOGNONE) {
439145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
440145510Sdarrenr				return -1;
441145510Sdarrenr			}
442145510Sdarrenr			break;
443145510Sdarrenr		case 't' :
444145510Sdarrenr			type = gettype(optarg, NULL);
445145510Sdarrenr			if (type != IPLT_POOL) {
446145510Sdarrenr				fprintf(stderr,
447145510Sdarrenr					"-s not supported for this type yet\n");
448145510Sdarrenr				return -1;
449145510Sdarrenr			}
450145510Sdarrenr			break;
451145510Sdarrenr		case 'v' :
452145510Sdarrenr			opts |= OPT_VERBOSE;
453145510Sdarrenr			break;
454353079Scy		default :
455353079Scy			usage(argv[0]);
456353079Scy			break;		/* keep compiler happy */
457145510Sdarrenr		}
458145510Sdarrenr
459353079Scy	if (argc - 1 - optind > 0)
460353079Scy		usage(argv[0]);
461353079Scy
462145510Sdarrenr	if (opts & OPT_DEBUG)
463145510Sdarrenr		fprintf(stderr, "poolstats: opts = %#x\n", opts);
464145510Sdarrenr
465255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
466145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
467145510Sdarrenr		if (fd == -1) {
468145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
469145510Sdarrenr			exit(1);
470145510Sdarrenr		}
471145510Sdarrenr	}
472145510Sdarrenr
473145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
474145510Sdarrenr		op.iplo_type = IPLT_POOL;
475145510Sdarrenr		op.iplo_struct = &plstat;
476145510Sdarrenr		op.iplo_size = sizeof(plstat);
477255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
478145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
479145510Sdarrenr			if (c == -1) {
480255332Scy				ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
481145510Sdarrenr				return -1;
482145510Sdarrenr			}
483255332Scy			printf("%lu\taddress pools\n", plstat.ipls_pools);
484255332Scy			printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
485145510Sdarrenr		}
486145510Sdarrenr	}
487145510Sdarrenr
488145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
489145510Sdarrenr		op.iplo_type = IPLT_HASH;
490145510Sdarrenr		op.iplo_struct = &htstat;
491145510Sdarrenr		op.iplo_size = sizeof(htstat);
492255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
493145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
494145510Sdarrenr			if (c == -1) {
495255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
496145510Sdarrenr				return -1;
497145510Sdarrenr			}
498255332Scy			printf("%lu\thash tables\n", htstat.iphs_numtables);
499255332Scy			printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
500255332Scy			printf("%lu\thash table no memory \n",
501255332Scy				htstat.iphs_nomem);
502145510Sdarrenr		}
503145510Sdarrenr	}
504255332Scy
505255332Scy	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
506255332Scy		op.iplo_type = IPLT_DSTLIST;
507255332Scy		op.iplo_struct = &dlstat;
508255332Scy		op.iplo_size = sizeof(dlstat);
509255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
510255332Scy			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
511255332Scy			if (c == -1) {
512255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
513255332Scy				return -1;
514255332Scy			}
515255332Scy			printf("%u\tdestination lists\n",
516255332Scy			       dlstat.ipls_numlists);
517255332Scy			printf("%u\tdestination list nodes\n",
518255332Scy			       dlstat.ipls_numnodes);
519255332Scy			printf("%lu\tdestination list no memory\n",
520255332Scy			       dlstat.ipls_nomem);
521255332Scy			printf("%u\tdestination list zombies\n",
522255332Scy			       dlstat.ipls_numdereflists);
523255332Scy			printf("%u\tdesetination list node zombies\n",
524255332Scy			       dlstat.ipls_numderefnodes);
525255332Scy		}
526255332Scy	}
527145510Sdarrenr	return 0;
528145510Sdarrenr}
529145510Sdarrenr
530145510Sdarrenr
531255332Scyint
532255332Scypoolflush(argc, argv)
533255332Scy	int argc;
534255332Scy	char *argv[];
535145510Sdarrenr{
536145510Sdarrenr	int c, role, type, arg;
537145510Sdarrenr	iplookupflush_t flush;
538145510Sdarrenr
539145510Sdarrenr	arg = IPLT_ALL;
540145510Sdarrenr	type = IPLT_ALL;
541145510Sdarrenr	role = IPL_LOGALL;
542145510Sdarrenr
543145510Sdarrenr	while ((c = getopt(argc, argv, "do:t:v")) != -1)
544145510Sdarrenr		switch (c)
545145510Sdarrenr		{
546145510Sdarrenr		case 'd' :
547145510Sdarrenr			opts |= OPT_DEBUG;
548145510Sdarrenr			break;
549145510Sdarrenr		case 'o' :
550145510Sdarrenr			role = getrole(optarg);
551145510Sdarrenr			if (role == IPL_LOGNONE) {
552145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
553145510Sdarrenr				return -1;
554145510Sdarrenr			}
555145510Sdarrenr			break;
556145510Sdarrenr		case 't' :
557145510Sdarrenr			type = gettype(optarg, NULL);
558145510Sdarrenr			if (type == IPLT_NONE) {
559145510Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
560145510Sdarrenr				return -1;
561145510Sdarrenr			}
562145510Sdarrenr			break;
563145510Sdarrenr		case 'v' :
564145510Sdarrenr			opts |= OPT_VERBOSE;
565145510Sdarrenr			break;
566353078Scy		default :
567353078Scy			usage(argv[0]);
568353078Scy			break;		/* keep compiler happy */
569145510Sdarrenr		}
570145510Sdarrenr
571353078Scy	if (argc - 1 - optind > 0)
572353078Scy		usage(argv[0]);
573353078Scy
574145510Sdarrenr	if (opts & OPT_DEBUG)
575145510Sdarrenr		fprintf(stderr, "poolflush: opts = %#x\n", opts);
576145510Sdarrenr
577255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
578145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
579145510Sdarrenr		if (fd == -1) {
580145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
581145510Sdarrenr			exit(1);
582145510Sdarrenr		}
583145510Sdarrenr	}
584145510Sdarrenr
585145510Sdarrenr	bzero((char *)&flush, sizeof(flush));
586145510Sdarrenr	flush.iplf_type = type;
587145510Sdarrenr	flush.iplf_unit = role;
588145510Sdarrenr	flush.iplf_arg = arg;
589145510Sdarrenr
590255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
591145510Sdarrenr		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
592255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
593145510Sdarrenr			exit(1);
594145510Sdarrenr		}
595145510Sdarrenr
596145510Sdarrenr	}
597255332Scy	printf("%u object%s flushed\n", flush.iplf_count,
598145510Sdarrenr	       (flush.iplf_count == 1) ? "" : "s");
599145510Sdarrenr
600145510Sdarrenr	return 0;
601145510Sdarrenr}
602145510Sdarrenr
603145510Sdarrenr
604255332Scyint
605255332Scygetrole(rolename)
606255332Scy	char *rolename;
607145510Sdarrenr{
608145510Sdarrenr	int role;
609145510Sdarrenr
610145510Sdarrenr	if (!strcasecmp(rolename, "ipf")) {
611145510Sdarrenr		role = IPL_LOGIPF;
612145510Sdarrenr#if 0
613145510Sdarrenr	} else if (!strcasecmp(rolename, "nat")) {
614145510Sdarrenr		role = IPL_LOGNAT;
615145510Sdarrenr	} else if (!strcasecmp(rolename, "state")) {
616145510Sdarrenr		role = IPL_LOGSTATE;
617145510Sdarrenr	} else if (!strcasecmp(rolename, "auth")) {
618145510Sdarrenr		role = IPL_LOGAUTH;
619145510Sdarrenr	} else if (!strcasecmp(rolename, "sync")) {
620145510Sdarrenr		role = IPL_LOGSYNC;
621145510Sdarrenr	} else if (!strcasecmp(rolename, "scan")) {
622145510Sdarrenr		role = IPL_LOGSCAN;
623145510Sdarrenr	} else if (!strcasecmp(rolename, "pool")) {
624145510Sdarrenr		role = IPL_LOGLOOKUP;
625145510Sdarrenr	} else if (!strcasecmp(rolename, "count")) {
626145510Sdarrenr		role = IPL_LOGCOUNT;
627145510Sdarrenr#endif
628145510Sdarrenr	} else {
629145510Sdarrenr		role = IPL_LOGNONE;
630145510Sdarrenr	}
631145510Sdarrenr
632145510Sdarrenr	return role;
633145510Sdarrenr}
634145510Sdarrenr
635145510Sdarrenr
636255332Scyint
637255332Scygettype(typename, minor)
638255332Scy	char *typename;
639255332Scy	u_int *minor;
640145510Sdarrenr{
641145510Sdarrenr	int type;
642145510Sdarrenr
643255332Scy	if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
644145510Sdarrenr		type = IPLT_POOL;
645255332Scy	} else if (!strcasecmp(typename, "hash")) {
646145510Sdarrenr		type = IPLT_HASH;
647145510Sdarrenr		if (minor != NULL)
648145510Sdarrenr			*minor = IPHASH_LOOKUP;
649255332Scy	} else if (!strcasecmp(typename, "group-map")) {
650145510Sdarrenr		type = IPLT_HASH;
651145510Sdarrenr		if (minor != NULL)
652145510Sdarrenr			*minor = IPHASH_GROUPMAP;
653145510Sdarrenr	} else {
654145510Sdarrenr		type = IPLT_NONE;
655145510Sdarrenr	}
656145510Sdarrenr	return type;
657145510Sdarrenr}
658170268Sdarrenr
659170268Sdarrenr
660255332Scyint
661255332Scypoollist(argc, argv)
662255332Scy	int argc;
663255332Scy	char *argv[];
664170268Sdarrenr{
665170268Sdarrenr	char *kernel, *core, *poolname;
666170268Sdarrenr	int c, role, type, live_kernel;
667170268Sdarrenr	iplookupop_t op;
668170268Sdarrenr
669170268Sdarrenr	core = NULL;
670170268Sdarrenr	kernel = NULL;
671170268Sdarrenr	live_kernel = 1;
672170268Sdarrenr	type = IPLT_ALL;
673170268Sdarrenr	poolname = NULL;
674170268Sdarrenr	role = IPL_LOGALL;
675170268Sdarrenr
676353074Scy	while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1)
677170268Sdarrenr		switch (c)
678170268Sdarrenr		{
679170268Sdarrenr		case 'd' :
680170268Sdarrenr			opts |= OPT_DEBUG;
681170268Sdarrenr			break;
682170268Sdarrenr		case 'm' :
683170268Sdarrenr			poolname = optarg;
684170268Sdarrenr			break;
685170268Sdarrenr		case 'M' :
686170268Sdarrenr			live_kernel = 0;
687170268Sdarrenr			core = optarg;
688170268Sdarrenr			break;
689170268Sdarrenr		case 'N' :
690170268Sdarrenr			live_kernel = 0;
691170268Sdarrenr			kernel = optarg;
692170268Sdarrenr			break;
693170268Sdarrenr		case 'o' :
694170268Sdarrenr			role = getrole(optarg);
695170268Sdarrenr			if (role == IPL_LOGNONE) {
696170268Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
697170268Sdarrenr				return -1;
698170268Sdarrenr			}
699170268Sdarrenr			break;
700353076Scy#if 0
701255332Scy		case 'O' :
702353076Scy			/* XXX This option does not work. This function as  */
703353076Scy			/* XXX used by state and nat can be used to format  */
704353076Scy			/* XXX output especially useful for scripting. It   */
705353076Scy			/* XXX is left here with the intention of making    */
706353076Scy			/* XXX it work for the same purpose at some point.  */
707255332Scy			pool_fields = parsefields(poolfields, optarg);
708255332Scy			break;
709353076Scy#endif
710170268Sdarrenr		case 't' :
711170268Sdarrenr			type = gettype(optarg, NULL);
712170268Sdarrenr			if (type == IPLT_NONE) {
713170268Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
714170268Sdarrenr				return -1;
715170268Sdarrenr			}
716170268Sdarrenr			break;
717170268Sdarrenr		case 'v' :
718170268Sdarrenr			opts |= OPT_VERBOSE;
719170268Sdarrenr			break;
720353075Scy		default :
721353075Scy			usage(argv[0]);
722353075Scy			break;		/* keep compiler happy */
723170268Sdarrenr		}
724170268Sdarrenr
725353075Scy	if (argc - optind > 0)
726353075Scy		usage(argv[0]);
727353075Scy
728170268Sdarrenr	if (opts & OPT_DEBUG)
729170268Sdarrenr		fprintf(stderr, "poollist: opts = %#x\n", opts);
730170268Sdarrenr
731255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
732170268Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
733170268Sdarrenr		if (fd == -1) {
734170268Sdarrenr			perror("open(IPLOOKUP_NAME)");
735170268Sdarrenr			exit(1);
736170268Sdarrenr		}
737170268Sdarrenr	}
738170268Sdarrenr
739170268Sdarrenr	bzero((char *)&op, sizeof(op));
740170268Sdarrenr	if (poolname != NULL) {
741170268Sdarrenr		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
742170268Sdarrenr		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
743170268Sdarrenr	}
744170268Sdarrenr	op.iplo_unit = role;
745170268Sdarrenr
746170268Sdarrenr	if (live_kernel)
747170268Sdarrenr		poollist_live(role, poolname, type, fd);
748170268Sdarrenr	else
749170268Sdarrenr		poollist_dead(role, poolname, type, kernel, core);
750170268Sdarrenr	return 0;
751170268Sdarrenr}
752170268Sdarrenr
753170268Sdarrenr
754255332Scyvoid
755255332Scypoollist_dead(role, poolname, type, kernel, core)
756255332Scy	int role, type;
757255332Scy	char *poolname, *kernel, *core;
758170268Sdarrenr{
759170268Sdarrenr	iphtable_t *hptr;
760170268Sdarrenr	ip_pool_t *ptr;
761170268Sdarrenr
762170268Sdarrenr	if (openkmem(kernel, core) == -1)
763170268Sdarrenr		exit(-1);
764170268Sdarrenr
765170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
766170268Sdarrenr		ip_pool_t *pools[IPL_LOGSIZE];
767170268Sdarrenr		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
768170268Sdarrenr
769170268Sdarrenr		if (nlist(kernel, names) != 1)
770170268Sdarrenr			return;
771170268Sdarrenr
772170268Sdarrenr		bzero(&pools, sizeof(pools));
773170268Sdarrenr		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
774170268Sdarrenr			return;
775170268Sdarrenr
776170268Sdarrenr		if (role != IPL_LOGALL) {
777170268Sdarrenr			ptr = pools[role];
778170268Sdarrenr			while (ptr != NULL) {
779170268Sdarrenr				ptr = printpool(ptr, kmemcpywrap, poolname,
780255332Scy						opts, pool_fields);
781170268Sdarrenr			}
782170268Sdarrenr		} else {
783170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
784170268Sdarrenr				ptr = pools[role];
785170268Sdarrenr				while (ptr != NULL) {
786170268Sdarrenr					ptr = printpool(ptr, kmemcpywrap,
787255332Scy							poolname, opts,
788255332Scy							pool_fields);
789170268Sdarrenr				}
790170268Sdarrenr			}
791170268Sdarrenr			role = IPL_LOGALL;
792170268Sdarrenr		}
793170268Sdarrenr	}
794170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
795170268Sdarrenr		iphtable_t *tables[IPL_LOGSIZE];
796170268Sdarrenr		struct nlist names[2] = { { "ipf_htables" } , { "" } };
797170268Sdarrenr
798170268Sdarrenr		if (nlist(kernel, names) != 1)
799170268Sdarrenr			return;
800170268Sdarrenr
801170268Sdarrenr		bzero(&tables, sizeof(tables));
802170268Sdarrenr		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
803170268Sdarrenr			return;
804170268Sdarrenr
805170268Sdarrenr		if (role != IPL_LOGALL) {
806170268Sdarrenr			hptr = tables[role];
807170268Sdarrenr			while (hptr != NULL) {
808170268Sdarrenr				hptr = printhash(hptr, kmemcpywrap,
809255332Scy						 poolname, opts, pool_fields);
810170268Sdarrenr			}
811170268Sdarrenr		} else {
812170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
813170268Sdarrenr				hptr = tables[role];
814170268Sdarrenr				while (hptr != NULL) {
815170268Sdarrenr					hptr = printhash(hptr, kmemcpywrap,
816255332Scy							 poolname, opts,
817255332Scy							 pool_fields);
818170268Sdarrenr				}
819170268Sdarrenr			}
820170268Sdarrenr		}
821170268Sdarrenr	}
822170268Sdarrenr}
823170268Sdarrenr
824170268Sdarrenr
825255332Scyvoid
826255332Scypoollist_live(role, poolname, type, fd)
827255332Scy	int role, type, fd;
828255332Scy	char *poolname;
829170268Sdarrenr{
830255332Scy	ipf_pool_stat_t plstat;
831170268Sdarrenr	iplookupop_t op;
832170268Sdarrenr	int c;
833170268Sdarrenr
834170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
835170268Sdarrenr		op.iplo_type = IPLT_POOL;
836170268Sdarrenr		op.iplo_size = sizeof(plstat);
837170268Sdarrenr		op.iplo_struct = &plstat;
838170268Sdarrenr		op.iplo_name[0] = '\0';
839170268Sdarrenr		op.iplo_arg = 0;
840170268Sdarrenr
841170268Sdarrenr		if (role != IPL_LOGALL) {
842170268Sdarrenr			op.iplo_unit = role;
843170268Sdarrenr
844170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
845170268Sdarrenr			if (c == -1) {
846255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
847170268Sdarrenr				return;
848170268Sdarrenr			}
849170268Sdarrenr
850170268Sdarrenr			showpools_live(fd, role, &plstat, poolname);
851170268Sdarrenr		} else {
852255332Scy			for (role = -1; role <= IPL_LOGMAX; role++) {
853170268Sdarrenr				op.iplo_unit = role;
854170268Sdarrenr
855170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
856170268Sdarrenr				if (c == -1) {
857255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
858170268Sdarrenr					return;
859170268Sdarrenr				}
860170268Sdarrenr
861170268Sdarrenr				showpools_live(fd, role, &plstat, poolname);
862170268Sdarrenr			}
863170268Sdarrenr
864170268Sdarrenr			role = IPL_LOGALL;
865170268Sdarrenr		}
866170268Sdarrenr	}
867170268Sdarrenr
868170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
869255332Scy		iphtstat_t htstat;
870255332Scy
871170268Sdarrenr		op.iplo_type = IPLT_HASH;
872170268Sdarrenr		op.iplo_size = sizeof(htstat);
873170268Sdarrenr		op.iplo_struct = &htstat;
874170268Sdarrenr		op.iplo_name[0] = '\0';
875170268Sdarrenr		op.iplo_arg = 0;
876170268Sdarrenr
877170268Sdarrenr		if (role != IPL_LOGALL) {
878170268Sdarrenr			op.iplo_unit = role;
879170268Sdarrenr
880170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
881170268Sdarrenr			if (c == -1) {
882255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
883170268Sdarrenr				return;
884170268Sdarrenr			}
885170268Sdarrenr			showhashs_live(fd, role, &htstat, poolname);
886170268Sdarrenr		} else {
887170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
888170268Sdarrenr
889170268Sdarrenr				op.iplo_unit = role;
890170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
891170268Sdarrenr				if (c == -1) {
892255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
893170268Sdarrenr					return;
894170268Sdarrenr				}
895170268Sdarrenr
896170268Sdarrenr				showhashs_live(fd, role, &htstat, poolname);
897170268Sdarrenr			}
898255332Scy			role = IPL_LOGALL;
899170268Sdarrenr		}
900170268Sdarrenr	}
901255332Scy
902255332Scy	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
903255332Scy		ipf_dstl_stat_t dlstat;
904255332Scy
905255332Scy		op.iplo_type = IPLT_DSTLIST;
906255332Scy		op.iplo_size = sizeof(dlstat);
907255332Scy		op.iplo_struct = &dlstat;
908255332Scy		op.iplo_name[0] = '\0';
909255332Scy		op.iplo_arg = 0;
910255332Scy
911255332Scy		if (role != IPL_LOGALL) {
912255332Scy			op.iplo_unit = role;
913255332Scy
914255332Scy			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
915255332Scy			if (c == -1) {
916255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
917255332Scy				return;
918255332Scy			}
919255332Scy			showdstls_live(fd, role, &dlstat, poolname);
920255332Scy		} else {
921255332Scy			for (role = 0; role <= IPL_LOGMAX; role++) {
922255332Scy
923255332Scy				op.iplo_unit = role;
924255332Scy				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
925255332Scy				if (c == -1) {
926255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
927255332Scy					return;
928255332Scy				}
929255332Scy
930255332Scy				showdstls_live(fd, role, &dlstat, poolname);
931255332Scy			}
932255332Scy			role = IPL_LOGALL;
933255332Scy		}
934255332Scy	}
935170268Sdarrenr}
936170268Sdarrenr
937170268Sdarrenr
938255332Scyvoid
939255332Scyshowpools_live(fd, role, plstp, poolname)
940255332Scy	int fd, role;
941255332Scy	ipf_pool_stat_t *plstp;
942255332Scy	char *poolname;
943170268Sdarrenr{
944170268Sdarrenr	ipflookupiter_t iter;
945170268Sdarrenr	ip_pool_t pool;
946170268Sdarrenr	ipfobj_t obj;
947170268Sdarrenr
948170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
949170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
950170268Sdarrenr	obj.ipfo_size = sizeof(iter);
951170268Sdarrenr	obj.ipfo_ptr = &iter;
952170268Sdarrenr
953170268Sdarrenr	iter.ili_type = IPLT_POOL;
954170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
955170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
956170268Sdarrenr	iter.ili_nitems = 1;
957170268Sdarrenr	iter.ili_data = &pool;
958170268Sdarrenr	iter.ili_unit = role;
959170268Sdarrenr	*iter.ili_name = '\0';
960170268Sdarrenr
961255332Scy	bzero((char *)&pool, sizeof(pool));
962255332Scy
963255332Scy	while (plstp->ipls_list[role + 1] != NULL) {
964170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
965255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
966170268Sdarrenr			break;
967170268Sdarrenr		}
968255332Scy		if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
969255332Scy		    ((opts & OPT_DEBUG) != 0))
970255332Scy			printpool_live(&pool, fd, poolname, opts, pool_fields);
971170268Sdarrenr
972255332Scy		plstp->ipls_list[role + 1] = pool.ipo_next;
973170268Sdarrenr	}
974170268Sdarrenr}
975170268Sdarrenr
976170268Sdarrenr
977255332Scyvoid
978255332Scyshowhashs_live(fd, role, htstp, poolname)
979255332Scy	int fd, role;
980255332Scy	iphtstat_t *htstp;
981255332Scy	char *poolname;
982170268Sdarrenr{
983170268Sdarrenr	ipflookupiter_t iter;
984170268Sdarrenr	iphtable_t table;
985170268Sdarrenr	ipfobj_t obj;
986170268Sdarrenr
987170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
988170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
989170268Sdarrenr	obj.ipfo_size = sizeof(iter);
990170268Sdarrenr	obj.ipfo_ptr = &iter;
991170268Sdarrenr
992170268Sdarrenr	iter.ili_type = IPLT_HASH;
993170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
994170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
995170268Sdarrenr	iter.ili_nitems = 1;
996170268Sdarrenr	iter.ili_data = &table;
997170268Sdarrenr	iter.ili_unit = role;
998170268Sdarrenr	*iter.ili_name = '\0';
999170268Sdarrenr
1000170268Sdarrenr	while (htstp->iphs_tables != NULL) {
1001170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1002255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1003170268Sdarrenr			break;
1004170268Sdarrenr		}
1005170268Sdarrenr
1006255332Scy		printhash_live(&table, fd, poolname, opts, pool_fields);
1007170268Sdarrenr
1008170268Sdarrenr		htstp->iphs_tables = table.iph_next;
1009170268Sdarrenr	}
1010170268Sdarrenr}
1011170268Sdarrenr
1012170268Sdarrenr
1013255332Scyvoid
1014255332Scyshowdstls_live(fd, role, dlstp, poolname)
1015255332Scy	int fd, role;
1016255332Scy	ipf_dstl_stat_t *dlstp;
1017255332Scy	char *poolname;
1018170268Sdarrenr{
1019255332Scy	ipflookupiter_t iter;
1020255332Scy	ippool_dst_t table;
1021255332Scy	ipfobj_t obj;
1022255332Scy
1023255332Scy	obj.ipfo_rev = IPFILTER_VERSION;
1024255332Scy	obj.ipfo_type = IPFOBJ_LOOKUPITER;
1025255332Scy	obj.ipfo_size = sizeof(iter);
1026255332Scy	obj.ipfo_ptr = &iter;
1027255332Scy
1028255332Scy	iter.ili_type = IPLT_DSTLIST;
1029255332Scy	iter.ili_otype = IPFLOOKUPITER_LIST;
1030255332Scy	iter.ili_ival = IPFGENITER_LOOKUP;
1031255332Scy	iter.ili_nitems = 1;
1032255332Scy	iter.ili_data = &table;
1033255332Scy	iter.ili_unit = role;
1034255332Scy	*iter.ili_name = '\0';
1035255332Scy
1036255332Scy	while (dlstp->ipls_list[role] != NULL) {
1037255332Scy		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1038255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1039255332Scy			break;
1040255332Scy		}
1041255332Scy
1042255332Scy		printdstl_live(&table, fd, poolname, opts, pool_fields);
1043255332Scy
1044255332Scy		dlstp->ipls_list[role] = table.ipld_next;
1045255332Scy	}
1046255332Scy}
1047255332Scy
1048255332Scy
1049255332Scyint
1050255332Scysetnodeaddr(int type, int role, void *ptr, char *arg)
1051255332Scy{
1052170268Sdarrenr	struct in_addr mask;
1053170268Sdarrenr	char *s;
1054170268Sdarrenr
1055170268Sdarrenr	s = strchr(arg, '/');
1056170268Sdarrenr	if (s == NULL)
1057170268Sdarrenr		mask.s_addr = 0xffffffff;
1058170268Sdarrenr	else if (strchr(s, '.') == NULL) {
1059255332Scy		if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
1060170268Sdarrenr			return -1;
1061170268Sdarrenr	} else {
1062170268Sdarrenr		mask.s_addr = inet_addr(s + 1);
1063170268Sdarrenr	}
1064170268Sdarrenr	if (s != NULL)
1065170268Sdarrenr		*s = '\0';
1066170268Sdarrenr
1067255332Scy	if (type == IPLT_POOL) {
1068255332Scy		ip_pool_node_t *node = ptr;
1069255332Scy
1070318206Scy#ifdef USE_INET6
1071255332Scy		if (node->ipn_addr.adf_family == AF_INET)
1072318206Scy#endif
1073255332Scy			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1074255332Scy							  adf_addr) +
1075255332Scy						 sizeof(struct in_addr);
1076255332Scy#ifdef USE_INET6
1077255332Scy		else
1078255332Scy			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1079255332Scy							  adf_addr) +
1080255332Scy						 sizeof(struct in6_addr);
1081255332Scy#endif
1082255332Scy		node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
1083255332Scy		node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1084255332Scy		node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1085255332Scy	} else if (type == IPLT_HASH) {
1086255332Scy		iphtent_t *node = ptr;
1087255332Scy
1088255332Scy		node->ipe_addr.in4.s_addr = inet_addr(arg);
1089255332Scy		node->ipe_mask.in4.s_addr = mask.s_addr;
1090255332Scy        	node->ipe_family = AF_INET;
1091255332Scy        	node->ipe_unit = role;
1092255332Scy	}
1093255332Scy
1094170268Sdarrenr	return 0;
1095170268Sdarrenr}
1096