1145519Sdarrenr/*	$FreeBSD$	*/
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#if defined(BSD) && (BSD >= 199306)
13145510Sdarrenr# include <sys/cdefs.h>
14145510Sdarrenr#endif
15145510Sdarrenr#include <sys/ioctl.h>
16145510Sdarrenr
17145510Sdarrenr#include <net/if.h>
18145510Sdarrenr#if __FreeBSD_version >= 300000
19145510Sdarrenr# include <net/if_var.h>
20145510Sdarrenr#endif
21145510Sdarrenr#include <netinet/in.h>
22145510Sdarrenr
23145510Sdarrenr#include <arpa/inet.h>
24145510Sdarrenr
25145510Sdarrenr#include <stdio.h>
26145510Sdarrenr#include <fcntl.h>
27145510Sdarrenr#include <stdlib.h>
28145510Sdarrenr#include <string.h>
29145510Sdarrenr#include <netdb.h>
30145510Sdarrenr#include <ctype.h>
31145510Sdarrenr#include <unistd.h>
32170268Sdarrenr#ifdef linux
33170268Sdarrenr# include <linux/a.out.h>
34170268Sdarrenr#else
35170268Sdarrenr# include <nlist.h>
36170268Sdarrenr#endif
37145510Sdarrenr
38145510Sdarrenr#include "ipf.h"
39170268Sdarrenr#include "netinet/ipl.h"
40145510Sdarrenr#include "netinet/ip_lookup.h"
41145510Sdarrenr#include "netinet/ip_pool.h"
42145510Sdarrenr#include "netinet/ip_htable.h"
43145510Sdarrenr#include "kmem.h"
44145510Sdarrenr
45145510Sdarrenr
46145510Sdarrenrextern	int	ippool_yyparse __P((void));
47145510Sdarrenrextern	int	ippool_yydebug;
48145510Sdarrenrextern	FILE	*ippool_yyin;
49145510Sdarrenrextern	char	*optarg;
50145510Sdarrenrextern	int	lineNum;
51145510Sdarrenr
52145510Sdarrenrvoid	usage __P((char *));
53145510Sdarrenrint	main __P((int, char **));
54145510Sdarrenrint	poolcommand __P((int, int, char *[]));
55145510Sdarrenrint	poolnodecommand __P((int, int, char *[]));
56145510Sdarrenrint	loadpoolfile __P((int, char *[], char *));
57145510Sdarrenrint	poollist __P((int, char *[]));
58170268Sdarrenrvoid	poollist_dead __P((int, char *, int, char *, char *));
59170268Sdarrenrvoid	poollist_live __P((int, char *, int, int));
60145510Sdarrenrint	poolflush __P((int, char *[]));
61145510Sdarrenrint	poolstats __P((int, char *[]));
62145510Sdarrenrint	gettype __P((char *, u_int *));
63145510Sdarrenrint	getrole __P((char *));
64255332Scyint	setnodeaddr __P((int, int, void *ptr, char *arg));
65255332Scyvoid	showpools_live __P((int, int, ipf_pool_stat_t *, char *));
66170268Sdarrenrvoid	showhashs_live __P((int, int, iphtstat_t *, char *));
67255332Scyvoid	showdstls_live __P((int, int, ipf_dstl_stat_t *, char *));
68145510Sdarrenr
69145510Sdarrenrint	opts = 0;
70145510Sdarrenrint	fd = -1;
71145510Sdarrenrint	use_inet6 = 0;
72255332Scywordtab_t *pool_fields = NULL;
73255332Scyint	nohdrfields = 0;
74145510Sdarrenr
75145510Sdarrenr
76255332Scyvoid
77255332Scyusage(prog)
78255332Scy	char *prog;
79145510Sdarrenr{
80145510Sdarrenr	fprintf(stderr, "Usage:\t%s\n", prog);
81255332Scy	fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
82255332Scy	fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
83255332Scy	fprintf(stderr, "\t-f <file> [-dnuv]\n");
84255332Scy	fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
85255332Scy	fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-O <fields>]\n");
86255332Scy	fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
87255332Scy	fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
88255332Scy	fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
89145510Sdarrenr	exit(1);
90145510Sdarrenr}
91145510Sdarrenr
92145510Sdarrenr
93255332Scyint
94255332Scymain(argc, argv)
95255332Scy	int argc;
96255332Scy	char *argv[];
97145510Sdarrenr{
98255332Scy	int err = 1;
99145510Sdarrenr
100145510Sdarrenr	if (argc < 2)
101145510Sdarrenr		usage(argv[0]);
102145510Sdarrenr
103255332Scy	assigndefined(getenv("IPPOOL_PREDEFINED"));
104255332Scy
105255332Scy	switch (getopt(argc, argv, "aAf:FlnrRsv"))
106145510Sdarrenr	{
107145510Sdarrenr	case 'a' :
108145510Sdarrenr		err = poolnodecommand(0, argc, argv);
109145510Sdarrenr		break;
110145510Sdarrenr	case 'A' :
111145510Sdarrenr		err = poolcommand(0, argc, argv);
112145510Sdarrenr		break;
113145510Sdarrenr	case 'f' :
114145510Sdarrenr		err = loadpoolfile(argc, argv, optarg);
115145510Sdarrenr		break;
116145510Sdarrenr	case 'F' :
117145510Sdarrenr		err = poolflush(argc, argv);
118145510Sdarrenr		break;
119145510Sdarrenr	case 'l' :
120145510Sdarrenr		err = poollist(argc, argv);
121145510Sdarrenr		break;
122255332Scy	case 'n' :
123255332Scy		opts |= OPT_DONOTHING|OPT_DONTOPEN;
124255332Scy		break;
125145510Sdarrenr	case 'r' :
126145510Sdarrenr		err = poolnodecommand(1, argc, argv);
127145510Sdarrenr		break;
128145510Sdarrenr	case 'R' :
129145510Sdarrenr		err = poolcommand(1, argc, argv);
130145510Sdarrenr		break;
131145510Sdarrenr	case 's' :
132145510Sdarrenr		err = poolstats(argc, argv);
133145510Sdarrenr		break;
134255332Scy	case 'v' :
135255332Scy		opts |= OPT_VERBOSE;
136255332Scy		break;
137145510Sdarrenr	default :
138145510Sdarrenr		exit(1);
139145510Sdarrenr	}
140145510Sdarrenr
141170268Sdarrenr	if (err != 0)
142170268Sdarrenr		exit(1);
143170268Sdarrenr	return 0;
144145510Sdarrenr}
145145510Sdarrenr
146145510Sdarrenr
147255332Scyint
148255332Scypoolnodecommand(remove, argc, argv)
149255332Scy	int remove, argc;
150255332Scy	char *argv[];
151145510Sdarrenr{
152255332Scy	int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
153170268Sdarrenr	char *poolname = NULL;
154255332Scy	ip_pool_node_t pnode;
155255332Scy	iphtent_t hnode;
156255332Scy	void *ptr = &pnode;
157145510Sdarrenr
158145510Sdarrenr	ipset = 0;
159145510Sdarrenr	role = IPL_LOGIPF;
160255332Scy	bzero((char *)&pnode, sizeof(pnode));
161255332Scy	bzero((char *)&hnode, sizeof(hnode));
162145510Sdarrenr
163255332Scy	while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1)
164145510Sdarrenr		switch (c)
165145510Sdarrenr		{
166145510Sdarrenr		case 'd' :
167145510Sdarrenr			opts |= OPT_DEBUG;
168145510Sdarrenr			ippool_yydebug++;
169145510Sdarrenr			break;
170145510Sdarrenr		case 'i' :
171255332Scy			if (setnodeaddr(type, role, ptr, optarg) == 0)
172170268Sdarrenr				ipset = 1;
173145510Sdarrenr			break;
174145510Sdarrenr		case 'm' :
175145510Sdarrenr			poolname = optarg;
176145510Sdarrenr			break;
177145510Sdarrenr		case 'n' :
178255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
179145510Sdarrenr			break;
180145510Sdarrenr		case 'o' :
181255332Scy			if (ipset == 1) {
182255332Scy				fprintf(stderr,
183255332Scy					"cannot set role after ip address\n");
184255332Scy				return -1;
185255332Scy			}
186145510Sdarrenr			role = getrole(optarg);
187145510Sdarrenr			if (role == IPL_LOGNONE)
188145510Sdarrenr				return -1;
189145510Sdarrenr			break;
190145510Sdarrenr		case 'R' :
191145510Sdarrenr			opts |= OPT_NORESOLVE;
192145510Sdarrenr			break;
193255332Scy		case 't' :
194255332Scy			if (ipset == 1) {
195255332Scy				fprintf(stderr,
196255332Scy					"cannot set type after ip address\n");
197255332Scy				return -1;
198255332Scy			}
199255332Scy			type = gettype(optarg, NULL);
200255332Scy			switch (type) {
201255332Scy			case IPLT_NONE :
202255332Scy				fprintf(stderr, "unknown type '%s'\n", optarg);
203255332Scy				return -1;
204255332Scy			case IPLT_HASH :
205255332Scy				ptr = &hnode;
206255332Scy				break;
207255332Scy			case IPLT_POOL :
208255332Scy			default :
209255332Scy				break;
210255332Scy			}
211255332Scy			break;
212255332Scy		case 'T' :
213255332Scy			ttl = atoi(optarg);
214255332Scy			if (ttl < 0) {
215255332Scy				fprintf(stderr, "cannot set negative ttl\n");
216255332Scy				return -1;
217255332Scy			}
218255332Scy			break;
219145510Sdarrenr		case 'v' :
220145510Sdarrenr			opts |= OPT_VERBOSE;
221145510Sdarrenr			break;
222145510Sdarrenr		}
223145510Sdarrenr
224170268Sdarrenr	if (argv[optind] != NULL && ipset == 0) {
225255332Scy		if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
226170268Sdarrenr			ipset = 1;
227170268Sdarrenr	}
228170268Sdarrenr
229145510Sdarrenr	if (opts & OPT_DEBUG)
230145510Sdarrenr		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
231145510Sdarrenr
232170268Sdarrenr	if (ipset == 0) {
233170268Sdarrenr		fprintf(stderr, "no IP address given with -i\n");
234145510Sdarrenr		return -1;
235170268Sdarrenr	}
236170268Sdarrenr
237145510Sdarrenr	if (poolname == NULL) {
238145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove node\n");
239145510Sdarrenr		return -1;
240145510Sdarrenr	}
241145510Sdarrenr
242255332Scy	switch (type) {
243255332Scy	case IPLT_POOL :
244255332Scy		if (remove == 0)
245255332Scy			err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
246255332Scy		else
247255332Scy			err = remove_poolnode(role, poolname, &pnode, ioctl);
248255332Scy		break;
249255332Scy	case IPLT_HASH :
250255332Scy		if (remove == 0)
251255332Scy			err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
252255332Scy		else
253255332Scy			err = remove_hashnode(role, poolname, &hnode, ioctl);
254255332Scy		break;
255255332Scy	default :
256255332Scy		break;
257255332Scy	}
258145510Sdarrenr	return err;
259145510Sdarrenr}
260145510Sdarrenr
261145510Sdarrenr
262255332Scyint
263255332Scypoolcommand(remove, argc, argv)
264255332Scy	int remove, argc;
265255332Scy	char *argv[];
266145510Sdarrenr{
267145510Sdarrenr	int type, role, c, err;
268145510Sdarrenr	char *poolname;
269145510Sdarrenr	iphtable_t iph;
270145510Sdarrenr	ip_pool_t pool;
271145510Sdarrenr
272145510Sdarrenr	err = 1;
273145510Sdarrenr	role = 0;
274145510Sdarrenr	type = 0;
275145510Sdarrenr	poolname = NULL;
276145510Sdarrenr	role = IPL_LOGIPF;
277145510Sdarrenr	bzero((char *)&iph, sizeof(iph));
278145510Sdarrenr	bzero((char *)&pool, sizeof(pool));
279145510Sdarrenr
280255332Scy	while ((c = getopt(argc, argv, "dm:no:RSv")) != -1)
281145510Sdarrenr		switch (c)
282145510Sdarrenr		{
283145510Sdarrenr		case 'd' :
284145510Sdarrenr			opts |= OPT_DEBUG;
285145510Sdarrenr			ippool_yydebug++;
286145510Sdarrenr			break;
287145510Sdarrenr		case 'm' :
288145510Sdarrenr			poolname = optarg;
289145510Sdarrenr			break;
290145510Sdarrenr		case 'n' :
291255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
292145510Sdarrenr			break;
293145510Sdarrenr		case 'o' :
294145510Sdarrenr			role = getrole(optarg);
295145510Sdarrenr			if (role == IPL_LOGNONE) {
296145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
297145510Sdarrenr				return -1;
298145510Sdarrenr			}
299145510Sdarrenr			break;
300145510Sdarrenr		case 'R' :
301145510Sdarrenr			opts |= OPT_NORESOLVE;
302145510Sdarrenr			break;
303145510Sdarrenr		case 'S' :
304145510Sdarrenr			iph.iph_seed = atoi(optarg);
305145510Sdarrenr			break;
306145510Sdarrenr		case 'v' :
307145510Sdarrenr			opts |= OPT_VERBOSE;
308145510Sdarrenr			break;
309145510Sdarrenr		}
310145510Sdarrenr
311145510Sdarrenr	if (opts & OPT_DEBUG)
312145510Sdarrenr		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
313145510Sdarrenr
314145510Sdarrenr	if (poolname == NULL) {
315145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove pool\n");
316145510Sdarrenr		return -1;
317145510Sdarrenr	}
318145510Sdarrenr
319255332Scy	type = gettype(argv[optind], &iph.iph_type);
320255332Scy	if (type == IPLT_NONE) {
321255332Scy		fprintf(stderr, "unknown type '%s'\n", argv[optind]);
322255332Scy		return -1;
323255332Scy	}
324255332Scy
325145510Sdarrenr	if (type == IPLT_HASH) {
326145510Sdarrenr		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
327145510Sdarrenr		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
328145510Sdarrenr		iph.iph_unit = role;
329145510Sdarrenr	} else if (type == IPLT_POOL) {
330145510Sdarrenr		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
331145510Sdarrenr		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
332145510Sdarrenr		pool.ipo_unit = role;
333145510Sdarrenr	}
334145510Sdarrenr
335145510Sdarrenr	if (remove == 0) {
336145510Sdarrenr		switch (type)
337145510Sdarrenr		{
338145510Sdarrenr		case IPLT_HASH :
339145510Sdarrenr			err = load_hash(&iph, NULL, ioctl);
340145510Sdarrenr			break;
341145510Sdarrenr		case IPLT_POOL :
342145510Sdarrenr			err = load_pool(&pool, ioctl);
343145510Sdarrenr			break;
344145510Sdarrenr		}
345145510Sdarrenr	} else {
346145510Sdarrenr		switch (type)
347145510Sdarrenr		{
348145510Sdarrenr		case IPLT_HASH :
349145510Sdarrenr			err = remove_hash(&iph, ioctl);
350145510Sdarrenr			break;
351145510Sdarrenr		case IPLT_POOL :
352145510Sdarrenr			err = remove_pool(&pool, ioctl);
353145510Sdarrenr			break;
354145510Sdarrenr		}
355145510Sdarrenr	}
356145510Sdarrenr	return err;
357145510Sdarrenr}
358145510Sdarrenr
359145510Sdarrenr
360255332Scyint
361255332Scyloadpoolfile(argc, argv, infile)
362255332Scy	int argc;
363255332Scy	char *argv[], *infile;
364145510Sdarrenr{
365145510Sdarrenr	int c;
366145510Sdarrenr
367145510Sdarrenr	infile = optarg;
368145510Sdarrenr
369145510Sdarrenr	while ((c = getopt(argc, argv, "dnRuv")) != -1)
370145510Sdarrenr		switch (c)
371145510Sdarrenr		{
372145510Sdarrenr		case 'd' :
373145510Sdarrenr			opts |= OPT_DEBUG;
374145510Sdarrenr			ippool_yydebug++;
375145510Sdarrenr			break;
376145510Sdarrenr		case 'n' :
377255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
378145510Sdarrenr			break;
379145510Sdarrenr		case 'R' :
380145510Sdarrenr			opts |= OPT_NORESOLVE;
381145510Sdarrenr			break;
382145510Sdarrenr		case 'u' :
383145510Sdarrenr			opts |= OPT_REMOVE;
384145510Sdarrenr			break;
385145510Sdarrenr		case 'v' :
386145510Sdarrenr			opts |= OPT_VERBOSE;
387145510Sdarrenr			break;
388145510Sdarrenr		}
389145510Sdarrenr
390145510Sdarrenr	if (opts & OPT_DEBUG)
391145510Sdarrenr		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
392145510Sdarrenr
393255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
394145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
395145510Sdarrenr		if (fd == -1) {
396145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
397145510Sdarrenr			exit(1);
398145510Sdarrenr		}
399145510Sdarrenr	}
400145510Sdarrenr
401145510Sdarrenr	if (ippool_parsefile(fd, infile, ioctl) != 0)
402145510Sdarrenr		return -1;
403145510Sdarrenr	return 0;
404145510Sdarrenr}
405145510Sdarrenr
406145510Sdarrenr
407255332Scyint
408255332Scypoolstats(argc, argv)
409255332Scy	int argc;
410255332Scy	char *argv[];
411145510Sdarrenr{
412145510Sdarrenr	int c, type, role, live_kernel;
413255332Scy	ipf_pool_stat_t plstat;
414255332Scy	ipf_dstl_stat_t dlstat;
415145510Sdarrenr	char *kernel, *core;
416145510Sdarrenr	iphtstat_t htstat;
417145510Sdarrenr	iplookupop_t op;
418145510Sdarrenr
419145510Sdarrenr	core = NULL;
420145510Sdarrenr	kernel = NULL;
421145510Sdarrenr	live_kernel = 1;
422145510Sdarrenr	type = IPLT_ALL;
423145510Sdarrenr	role = IPL_LOGALL;
424145510Sdarrenr
425145510Sdarrenr	bzero((char *)&op, sizeof(op));
426145510Sdarrenr
427145510Sdarrenr	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
428145510Sdarrenr		switch (c)
429145510Sdarrenr		{
430145510Sdarrenr		case 'd' :
431145510Sdarrenr			opts |= OPT_DEBUG;
432145510Sdarrenr			break;
433145510Sdarrenr		case 'M' :
434145510Sdarrenr			live_kernel = 0;
435145510Sdarrenr			core = optarg;
436145510Sdarrenr			break;
437145510Sdarrenr		case 'N' :
438145510Sdarrenr			live_kernel = 0;
439145510Sdarrenr			kernel = optarg;
440145510Sdarrenr			break;
441145510Sdarrenr		case 'o' :
442145510Sdarrenr			role = getrole(optarg);
443145510Sdarrenr			if (role == IPL_LOGNONE) {
444145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
445145510Sdarrenr				return -1;
446145510Sdarrenr			}
447145510Sdarrenr			break;
448145510Sdarrenr		case 't' :
449145510Sdarrenr			type = gettype(optarg, NULL);
450145510Sdarrenr			if (type != IPLT_POOL) {
451145510Sdarrenr				fprintf(stderr,
452145510Sdarrenr					"-s not supported for this type yet\n");
453145510Sdarrenr				return -1;
454145510Sdarrenr			}
455145510Sdarrenr			break;
456145510Sdarrenr		case 'v' :
457145510Sdarrenr			opts |= OPT_VERBOSE;
458145510Sdarrenr			break;
459145510Sdarrenr		}
460145510Sdarrenr
461145510Sdarrenr	if (opts & OPT_DEBUG)
462145510Sdarrenr		fprintf(stderr, "poolstats: opts = %#x\n", opts);
463145510Sdarrenr
464255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
465145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
466145510Sdarrenr		if (fd == -1) {
467145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
468145510Sdarrenr			exit(1);
469145510Sdarrenr		}
470145510Sdarrenr	}
471145510Sdarrenr
472145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
473145510Sdarrenr		op.iplo_type = IPLT_POOL;
474145510Sdarrenr		op.iplo_struct = &plstat;
475145510Sdarrenr		op.iplo_size = sizeof(plstat);
476255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
477145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
478145510Sdarrenr			if (c == -1) {
479255332Scy				ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
480145510Sdarrenr				return -1;
481145510Sdarrenr			}
482255332Scy			printf("%lu\taddress pools\n", plstat.ipls_pools);
483255332Scy			printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
484145510Sdarrenr		}
485145510Sdarrenr	}
486145510Sdarrenr
487145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
488145510Sdarrenr		op.iplo_type = IPLT_HASH;
489145510Sdarrenr		op.iplo_struct = &htstat;
490145510Sdarrenr		op.iplo_size = sizeof(htstat);
491255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
492145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
493145510Sdarrenr			if (c == -1) {
494255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
495145510Sdarrenr				return -1;
496145510Sdarrenr			}
497255332Scy			printf("%lu\thash tables\n", htstat.iphs_numtables);
498255332Scy			printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
499255332Scy			printf("%lu\thash table no memory \n",
500255332Scy				htstat.iphs_nomem);
501145510Sdarrenr		}
502145510Sdarrenr	}
503255332Scy
504255332Scy	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
505255332Scy		op.iplo_type = IPLT_DSTLIST;
506255332Scy		op.iplo_struct = &dlstat;
507255332Scy		op.iplo_size = sizeof(dlstat);
508255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
509255332Scy			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
510255332Scy			if (c == -1) {
511255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
512255332Scy				return -1;
513255332Scy			}
514255332Scy			printf("%u\tdestination lists\n",
515255332Scy			       dlstat.ipls_numlists);
516255332Scy			printf("%u\tdestination list nodes\n",
517255332Scy			       dlstat.ipls_numnodes);
518255332Scy			printf("%lu\tdestination list no memory\n",
519255332Scy			       dlstat.ipls_nomem);
520255332Scy			printf("%u\tdestination list zombies\n",
521255332Scy			       dlstat.ipls_numdereflists);
522255332Scy			printf("%u\tdesetination list node zombies\n",
523255332Scy			       dlstat.ipls_numderefnodes);
524255332Scy		}
525255332Scy	}
526145510Sdarrenr	return 0;
527145510Sdarrenr}
528145510Sdarrenr
529145510Sdarrenr
530255332Scyint
531255332Scypoolflush(argc, argv)
532255332Scy	int argc;
533255332Scy	char *argv[];
534145510Sdarrenr{
535145510Sdarrenr	int c, role, type, arg;
536145510Sdarrenr	iplookupflush_t flush;
537145510Sdarrenr
538145510Sdarrenr	arg = IPLT_ALL;
539145510Sdarrenr	type = IPLT_ALL;
540145510Sdarrenr	role = IPL_LOGALL;
541145510Sdarrenr
542145510Sdarrenr	while ((c = getopt(argc, argv, "do:t:v")) != -1)
543145510Sdarrenr		switch (c)
544145510Sdarrenr		{
545145510Sdarrenr		case 'd' :
546145510Sdarrenr			opts |= OPT_DEBUG;
547145510Sdarrenr			break;
548145510Sdarrenr		case 'o' :
549145510Sdarrenr			role = getrole(optarg);
550145510Sdarrenr			if (role == IPL_LOGNONE) {
551145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
552145510Sdarrenr				return -1;
553145510Sdarrenr			}
554145510Sdarrenr			break;
555145510Sdarrenr		case 't' :
556145510Sdarrenr			type = gettype(optarg, NULL);
557145510Sdarrenr			if (type == IPLT_NONE) {
558145510Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
559145510Sdarrenr				return -1;
560145510Sdarrenr			}
561145510Sdarrenr			break;
562145510Sdarrenr		case 'v' :
563145510Sdarrenr			opts |= OPT_VERBOSE;
564145510Sdarrenr			break;
565145510Sdarrenr		}
566145510Sdarrenr
567145510Sdarrenr	if (opts & OPT_DEBUG)
568145510Sdarrenr		fprintf(stderr, "poolflush: opts = %#x\n", opts);
569145510Sdarrenr
570255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
571145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
572145510Sdarrenr		if (fd == -1) {
573145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
574145510Sdarrenr			exit(1);
575145510Sdarrenr		}
576145510Sdarrenr	}
577145510Sdarrenr
578145510Sdarrenr	bzero((char *)&flush, sizeof(flush));
579145510Sdarrenr	flush.iplf_type = type;
580145510Sdarrenr	flush.iplf_unit = role;
581145510Sdarrenr	flush.iplf_arg = arg;
582145510Sdarrenr
583255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
584145510Sdarrenr		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
585255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
586145510Sdarrenr			exit(1);
587145510Sdarrenr		}
588145510Sdarrenr
589145510Sdarrenr	}
590255332Scy	printf("%u object%s flushed\n", flush.iplf_count,
591145510Sdarrenr	       (flush.iplf_count == 1) ? "" : "s");
592145510Sdarrenr
593145510Sdarrenr	return 0;
594145510Sdarrenr}
595145510Sdarrenr
596145510Sdarrenr
597255332Scyint
598255332Scygetrole(rolename)
599255332Scy	char *rolename;
600145510Sdarrenr{
601145510Sdarrenr	int role;
602145510Sdarrenr
603145510Sdarrenr	if (!strcasecmp(rolename, "ipf")) {
604145510Sdarrenr		role = IPL_LOGIPF;
605145510Sdarrenr#if 0
606145510Sdarrenr	} else if (!strcasecmp(rolename, "nat")) {
607145510Sdarrenr		role = IPL_LOGNAT;
608145510Sdarrenr	} else if (!strcasecmp(rolename, "state")) {
609145510Sdarrenr		role = IPL_LOGSTATE;
610145510Sdarrenr	} else if (!strcasecmp(rolename, "auth")) {
611145510Sdarrenr		role = IPL_LOGAUTH;
612145510Sdarrenr	} else if (!strcasecmp(rolename, "sync")) {
613145510Sdarrenr		role = IPL_LOGSYNC;
614145510Sdarrenr	} else if (!strcasecmp(rolename, "scan")) {
615145510Sdarrenr		role = IPL_LOGSCAN;
616145510Sdarrenr	} else if (!strcasecmp(rolename, "pool")) {
617145510Sdarrenr		role = IPL_LOGLOOKUP;
618145510Sdarrenr	} else if (!strcasecmp(rolename, "count")) {
619145510Sdarrenr		role = IPL_LOGCOUNT;
620145510Sdarrenr#endif
621145510Sdarrenr	} else {
622145510Sdarrenr		role = IPL_LOGNONE;
623145510Sdarrenr	}
624145510Sdarrenr
625145510Sdarrenr	return role;
626145510Sdarrenr}
627145510Sdarrenr
628145510Sdarrenr
629255332Scyint
630255332Scygettype(typename, minor)
631255332Scy	char *typename;
632255332Scy	u_int *minor;
633145510Sdarrenr{
634145510Sdarrenr	int type;
635145510Sdarrenr
636255332Scy	if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
637145510Sdarrenr		type = IPLT_POOL;
638255332Scy	} else if (!strcasecmp(typename, "hash")) {
639145510Sdarrenr		type = IPLT_HASH;
640145510Sdarrenr		if (minor != NULL)
641145510Sdarrenr			*minor = IPHASH_LOOKUP;
642255332Scy	} else if (!strcasecmp(typename, "group-map")) {
643145510Sdarrenr		type = IPLT_HASH;
644145510Sdarrenr		if (minor != NULL)
645145510Sdarrenr			*minor = IPHASH_GROUPMAP;
646145510Sdarrenr	} else {
647145510Sdarrenr		type = IPLT_NONE;
648145510Sdarrenr	}
649145510Sdarrenr	return type;
650145510Sdarrenr}
651170268Sdarrenr
652170268Sdarrenr
653255332Scyint
654255332Scypoollist(argc, argv)
655255332Scy	int argc;
656255332Scy	char *argv[];
657170268Sdarrenr{
658170268Sdarrenr	char *kernel, *core, *poolname;
659170268Sdarrenr	int c, role, type, live_kernel;
660170268Sdarrenr	iplookupop_t op;
661170268Sdarrenr
662170268Sdarrenr	core = NULL;
663170268Sdarrenr	kernel = NULL;
664170268Sdarrenr	live_kernel = 1;
665170268Sdarrenr	type = IPLT_ALL;
666170268Sdarrenr	poolname = NULL;
667170268Sdarrenr	role = IPL_LOGALL;
668170268Sdarrenr
669170268Sdarrenr	while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
670170268Sdarrenr		switch (c)
671170268Sdarrenr		{
672170268Sdarrenr		case 'd' :
673170268Sdarrenr			opts |= OPT_DEBUG;
674170268Sdarrenr			break;
675170268Sdarrenr		case 'm' :
676170268Sdarrenr			poolname = optarg;
677170268Sdarrenr			break;
678170268Sdarrenr		case 'M' :
679170268Sdarrenr			live_kernel = 0;
680170268Sdarrenr			core = optarg;
681170268Sdarrenr			break;
682170268Sdarrenr		case 'N' :
683170268Sdarrenr			live_kernel = 0;
684170268Sdarrenr			kernel = optarg;
685170268Sdarrenr			break;
686170268Sdarrenr		case 'o' :
687170268Sdarrenr			role = getrole(optarg);
688170268Sdarrenr			if (role == IPL_LOGNONE) {
689170268Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
690170268Sdarrenr				return -1;
691170268Sdarrenr			}
692170268Sdarrenr			break;
693255332Scy		case 'O' :
694255332Scy			pool_fields = parsefields(poolfields, optarg);
695255332Scy			break;
696170268Sdarrenr		case 'R' :
697170268Sdarrenr			opts |= OPT_NORESOLVE;
698170268Sdarrenr			break;
699170268Sdarrenr		case 't' :
700170268Sdarrenr			type = gettype(optarg, NULL);
701170268Sdarrenr			if (type == IPLT_NONE) {
702170268Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
703170268Sdarrenr				return -1;
704170268Sdarrenr			}
705170268Sdarrenr			break;
706170268Sdarrenr		case 'v' :
707170268Sdarrenr			opts |= OPT_VERBOSE;
708170268Sdarrenr			break;
709170268Sdarrenr		}
710170268Sdarrenr
711170268Sdarrenr	if (opts & OPT_DEBUG)
712170268Sdarrenr		fprintf(stderr, "poollist: opts = %#x\n", opts);
713170268Sdarrenr
714255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
715170268Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
716170268Sdarrenr		if (fd == -1) {
717170268Sdarrenr			perror("open(IPLOOKUP_NAME)");
718170268Sdarrenr			exit(1);
719170268Sdarrenr		}
720170268Sdarrenr	}
721170268Sdarrenr
722170268Sdarrenr	bzero((char *)&op, sizeof(op));
723170268Sdarrenr	if (poolname != NULL) {
724170268Sdarrenr		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
725170268Sdarrenr		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
726170268Sdarrenr	}
727170268Sdarrenr	op.iplo_unit = role;
728170268Sdarrenr
729170268Sdarrenr	if (live_kernel)
730170268Sdarrenr		poollist_live(role, poolname, type, fd);
731170268Sdarrenr	else
732170268Sdarrenr		poollist_dead(role, poolname, type, kernel, core);
733170268Sdarrenr	return 0;
734170268Sdarrenr}
735170268Sdarrenr
736170268Sdarrenr
737255332Scyvoid
738255332Scypoollist_dead(role, poolname, type, kernel, core)
739255332Scy	int role, type;
740255332Scy	char *poolname, *kernel, *core;
741170268Sdarrenr{
742170268Sdarrenr	iphtable_t *hptr;
743170268Sdarrenr	ip_pool_t *ptr;
744170268Sdarrenr
745170268Sdarrenr	if (openkmem(kernel, core) == -1)
746170268Sdarrenr		exit(-1);
747170268Sdarrenr
748170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
749170268Sdarrenr		ip_pool_t *pools[IPL_LOGSIZE];
750170268Sdarrenr		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
751170268Sdarrenr
752170268Sdarrenr		if (nlist(kernel, names) != 1)
753170268Sdarrenr			return;
754170268Sdarrenr
755170268Sdarrenr		bzero(&pools, sizeof(pools));
756170268Sdarrenr		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
757170268Sdarrenr			return;
758170268Sdarrenr
759170268Sdarrenr		if (role != IPL_LOGALL) {
760170268Sdarrenr			ptr = pools[role];
761170268Sdarrenr			while (ptr != NULL) {
762170268Sdarrenr				ptr = printpool(ptr, kmemcpywrap, poolname,
763255332Scy						opts, pool_fields);
764170268Sdarrenr			}
765170268Sdarrenr		} else {
766170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
767170268Sdarrenr				ptr = pools[role];
768170268Sdarrenr				while (ptr != NULL) {
769170268Sdarrenr					ptr = printpool(ptr, kmemcpywrap,
770255332Scy							poolname, opts,
771255332Scy							pool_fields);
772170268Sdarrenr				}
773170268Sdarrenr			}
774170268Sdarrenr			role = IPL_LOGALL;
775170268Sdarrenr		}
776170268Sdarrenr	}
777170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
778170268Sdarrenr		iphtable_t *tables[IPL_LOGSIZE];
779170268Sdarrenr		struct nlist names[2] = { { "ipf_htables" } , { "" } };
780170268Sdarrenr
781170268Sdarrenr		if (nlist(kernel, names) != 1)
782170268Sdarrenr			return;
783170268Sdarrenr
784170268Sdarrenr		bzero(&tables, sizeof(tables));
785170268Sdarrenr		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
786170268Sdarrenr			return;
787170268Sdarrenr
788170268Sdarrenr		if (role != IPL_LOGALL) {
789170268Sdarrenr			hptr = tables[role];
790170268Sdarrenr			while (hptr != NULL) {
791170268Sdarrenr				hptr = printhash(hptr, kmemcpywrap,
792255332Scy						 poolname, opts, pool_fields);
793170268Sdarrenr			}
794170268Sdarrenr		} else {
795170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
796170268Sdarrenr				hptr = tables[role];
797170268Sdarrenr				while (hptr != NULL) {
798170268Sdarrenr					hptr = printhash(hptr, kmemcpywrap,
799255332Scy							 poolname, opts,
800255332Scy							 pool_fields);
801170268Sdarrenr				}
802170268Sdarrenr			}
803170268Sdarrenr		}
804170268Sdarrenr	}
805170268Sdarrenr}
806170268Sdarrenr
807170268Sdarrenr
808255332Scyvoid
809255332Scypoollist_live(role, poolname, type, fd)
810255332Scy	int role, type, fd;
811255332Scy	char *poolname;
812170268Sdarrenr{
813255332Scy	ipf_pool_stat_t plstat;
814170268Sdarrenr	iplookupop_t op;
815170268Sdarrenr	int c;
816170268Sdarrenr
817170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
818170268Sdarrenr		op.iplo_type = IPLT_POOL;
819170268Sdarrenr		op.iplo_size = sizeof(plstat);
820170268Sdarrenr		op.iplo_struct = &plstat;
821170268Sdarrenr		op.iplo_name[0] = '\0';
822170268Sdarrenr		op.iplo_arg = 0;
823170268Sdarrenr
824170268Sdarrenr		if (role != IPL_LOGALL) {
825170268Sdarrenr			op.iplo_unit = role;
826170268Sdarrenr
827170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
828170268Sdarrenr			if (c == -1) {
829255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
830170268Sdarrenr				return;
831170268Sdarrenr			}
832170268Sdarrenr
833170268Sdarrenr			showpools_live(fd, role, &plstat, poolname);
834170268Sdarrenr		} else {
835255332Scy			for (role = -1; role <= IPL_LOGMAX; role++) {
836170268Sdarrenr				op.iplo_unit = role;
837170268Sdarrenr
838170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
839170268Sdarrenr				if (c == -1) {
840255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
841170268Sdarrenr					return;
842170268Sdarrenr				}
843170268Sdarrenr
844170268Sdarrenr				showpools_live(fd, role, &plstat, poolname);
845170268Sdarrenr			}
846170268Sdarrenr
847170268Sdarrenr			role = IPL_LOGALL;
848170268Sdarrenr		}
849170268Sdarrenr	}
850170268Sdarrenr
851170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
852255332Scy		iphtstat_t htstat;
853255332Scy
854170268Sdarrenr		op.iplo_type = IPLT_HASH;
855170268Sdarrenr		op.iplo_size = sizeof(htstat);
856170268Sdarrenr		op.iplo_struct = &htstat;
857170268Sdarrenr		op.iplo_name[0] = '\0';
858170268Sdarrenr		op.iplo_arg = 0;
859170268Sdarrenr
860170268Sdarrenr		if (role != IPL_LOGALL) {
861170268Sdarrenr			op.iplo_unit = role;
862170268Sdarrenr
863170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
864170268Sdarrenr			if (c == -1) {
865255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
866170268Sdarrenr				return;
867170268Sdarrenr			}
868170268Sdarrenr			showhashs_live(fd, role, &htstat, poolname);
869170268Sdarrenr		} else {
870170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
871170268Sdarrenr
872170268Sdarrenr				op.iplo_unit = role;
873170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
874170268Sdarrenr				if (c == -1) {
875255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
876170268Sdarrenr					return;
877170268Sdarrenr				}
878170268Sdarrenr
879170268Sdarrenr				showhashs_live(fd, role, &htstat, poolname);
880170268Sdarrenr			}
881255332Scy			role = IPL_LOGALL;
882170268Sdarrenr		}
883170268Sdarrenr	}
884255332Scy
885255332Scy	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
886255332Scy		ipf_dstl_stat_t dlstat;
887255332Scy
888255332Scy		op.iplo_type = IPLT_DSTLIST;
889255332Scy		op.iplo_size = sizeof(dlstat);
890255332Scy		op.iplo_struct = &dlstat;
891255332Scy		op.iplo_name[0] = '\0';
892255332Scy		op.iplo_arg = 0;
893255332Scy
894255332Scy		if (role != IPL_LOGALL) {
895255332Scy			op.iplo_unit = role;
896255332Scy
897255332Scy			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
898255332Scy			if (c == -1) {
899255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
900255332Scy				return;
901255332Scy			}
902255332Scy			showdstls_live(fd, role, &dlstat, poolname);
903255332Scy		} else {
904255332Scy			for (role = 0; role <= IPL_LOGMAX; role++) {
905255332Scy
906255332Scy				op.iplo_unit = role;
907255332Scy				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
908255332Scy				if (c == -1) {
909255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
910255332Scy					return;
911255332Scy				}
912255332Scy
913255332Scy				showdstls_live(fd, role, &dlstat, poolname);
914255332Scy			}
915255332Scy			role = IPL_LOGALL;
916255332Scy		}
917255332Scy	}
918170268Sdarrenr}
919170268Sdarrenr
920170268Sdarrenr
921255332Scyvoid
922255332Scyshowpools_live(fd, role, plstp, poolname)
923255332Scy	int fd, role;
924255332Scy	ipf_pool_stat_t *plstp;
925255332Scy	char *poolname;
926170268Sdarrenr{
927170268Sdarrenr	ipflookupiter_t iter;
928170268Sdarrenr	ip_pool_t pool;
929170268Sdarrenr	ipfobj_t obj;
930170268Sdarrenr
931170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
932170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
933170268Sdarrenr	obj.ipfo_size = sizeof(iter);
934170268Sdarrenr	obj.ipfo_ptr = &iter;
935170268Sdarrenr
936170268Sdarrenr	iter.ili_type = IPLT_POOL;
937170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
938170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
939170268Sdarrenr	iter.ili_nitems = 1;
940170268Sdarrenr	iter.ili_data = &pool;
941170268Sdarrenr	iter.ili_unit = role;
942170268Sdarrenr	*iter.ili_name = '\0';
943170268Sdarrenr
944255332Scy	bzero((char *)&pool, sizeof(pool));
945255332Scy
946255332Scy	while (plstp->ipls_list[role + 1] != NULL) {
947170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
948255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
949170268Sdarrenr			break;
950170268Sdarrenr		}
951255332Scy		if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
952255332Scy		    ((opts & OPT_DEBUG) != 0))
953255332Scy			printpool_live(&pool, fd, poolname, opts, pool_fields);
954170268Sdarrenr
955255332Scy		plstp->ipls_list[role + 1] = pool.ipo_next;
956170268Sdarrenr	}
957170268Sdarrenr}
958170268Sdarrenr
959170268Sdarrenr
960255332Scyvoid
961255332Scyshowhashs_live(fd, role, htstp, poolname)
962255332Scy	int fd, role;
963255332Scy	iphtstat_t *htstp;
964255332Scy	char *poolname;
965170268Sdarrenr{
966170268Sdarrenr	ipflookupiter_t iter;
967170268Sdarrenr	iphtable_t table;
968170268Sdarrenr	ipfobj_t obj;
969170268Sdarrenr
970170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
971170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
972170268Sdarrenr	obj.ipfo_size = sizeof(iter);
973170268Sdarrenr	obj.ipfo_ptr = &iter;
974170268Sdarrenr
975170268Sdarrenr	iter.ili_type = IPLT_HASH;
976170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
977170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
978170268Sdarrenr	iter.ili_nitems = 1;
979170268Sdarrenr	iter.ili_data = &table;
980170268Sdarrenr	iter.ili_unit = role;
981170268Sdarrenr	*iter.ili_name = '\0';
982170268Sdarrenr
983170268Sdarrenr	while (htstp->iphs_tables != NULL) {
984170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
985255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
986170268Sdarrenr			break;
987170268Sdarrenr		}
988170268Sdarrenr
989255332Scy		printhash_live(&table, fd, poolname, opts, pool_fields);
990170268Sdarrenr
991170268Sdarrenr		htstp->iphs_tables = table.iph_next;
992170268Sdarrenr	}
993170268Sdarrenr}
994170268Sdarrenr
995170268Sdarrenr
996255332Scyvoid
997255332Scyshowdstls_live(fd, role, dlstp, poolname)
998255332Scy	int fd, role;
999255332Scy	ipf_dstl_stat_t *dlstp;
1000255332Scy	char *poolname;
1001170268Sdarrenr{
1002255332Scy	ipflookupiter_t iter;
1003255332Scy	ippool_dst_t table;
1004255332Scy	ipfobj_t obj;
1005255332Scy
1006255332Scy	obj.ipfo_rev = IPFILTER_VERSION;
1007255332Scy	obj.ipfo_type = IPFOBJ_LOOKUPITER;
1008255332Scy	obj.ipfo_size = sizeof(iter);
1009255332Scy	obj.ipfo_ptr = &iter;
1010255332Scy
1011255332Scy	iter.ili_type = IPLT_DSTLIST;
1012255332Scy	iter.ili_otype = IPFLOOKUPITER_LIST;
1013255332Scy	iter.ili_ival = IPFGENITER_LOOKUP;
1014255332Scy	iter.ili_nitems = 1;
1015255332Scy	iter.ili_data = &table;
1016255332Scy	iter.ili_unit = role;
1017255332Scy	*iter.ili_name = '\0';
1018255332Scy
1019255332Scy	while (dlstp->ipls_list[role] != NULL) {
1020255332Scy		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1021255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1022255332Scy			break;
1023255332Scy		}
1024255332Scy
1025255332Scy		printdstl_live(&table, fd, poolname, opts, pool_fields);
1026255332Scy
1027255332Scy		dlstp->ipls_list[role] = table.ipld_next;
1028255332Scy	}
1029255332Scy}
1030255332Scy
1031255332Scy
1032255332Scyint
1033255332Scysetnodeaddr(int type, int role, void *ptr, char *arg)
1034255332Scy{
1035170268Sdarrenr	struct in_addr mask;
1036170268Sdarrenr	char *s;
1037170268Sdarrenr
1038170268Sdarrenr	s = strchr(arg, '/');
1039170268Sdarrenr	if (s == NULL)
1040170268Sdarrenr		mask.s_addr = 0xffffffff;
1041170268Sdarrenr	else if (strchr(s, '.') == NULL) {
1042255332Scy		if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
1043170268Sdarrenr			return -1;
1044170268Sdarrenr	} else {
1045170268Sdarrenr		mask.s_addr = inet_addr(s + 1);
1046170268Sdarrenr	}
1047170268Sdarrenr	if (s != NULL)
1048170268Sdarrenr		*s = '\0';
1049170268Sdarrenr
1050255332Scy	if (type == IPLT_POOL) {
1051255332Scy		ip_pool_node_t *node = ptr;
1052255332Scy
1053255332Scy		if (node->ipn_addr.adf_family == AF_INET)
1054255332Scy			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1055255332Scy							  adf_addr) +
1056255332Scy						 sizeof(struct in_addr);
1057255332Scy#ifdef USE_INET6
1058255332Scy		else
1059255332Scy			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1060255332Scy							  adf_addr) +
1061255332Scy						 sizeof(struct in6_addr);
1062255332Scy#endif
1063255332Scy		node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
1064255332Scy		node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1065255332Scy		node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1066255332Scy	} else if (type == IPLT_HASH) {
1067255332Scy		iphtent_t *node = ptr;
1068255332Scy
1069255332Scy		node->ipe_addr.in4.s_addr = inet_addr(arg);
1070255332Scy		node->ipe_mask.in4.s_addr = mask.s_addr;
1071255332Scy        	node->ipe_family = AF_INET;
1072255332Scy        	node->ipe_unit = role;
1073255332Scy	}
1074255332Scy
1075170268Sdarrenr	return 0;
1076170268Sdarrenr}
1077