1145519Sdarrenr/*	$FreeBSD: stable/11/contrib/ipfilter/tools/ippool.c 369245 2021-02-09 13:47:46Z git2svn $	*/
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
37369245Sgit2svnextern	int	ippool_yyparse(void);
38145510Sdarrenrextern	int	ippool_yydebug;
39145510Sdarrenrextern	FILE	*ippool_yyin;
40145510Sdarrenrextern	char	*optarg;
41145510Sdarrenrextern	int	lineNum;
42145510Sdarrenr
43369245Sgit2svnvoid	usage(char *);
44369245Sgit2svnint	main(int, char **);
45369245Sgit2svnint	poolcommand(int, int, char *[]);
46369245Sgit2svnint	poolnodecommand(int, int, char *[]);
47369245Sgit2svnint	loadpoolfile(int, char *[], char *);
48369245Sgit2svnint	poollist(int, char *[]);
49369245Sgit2svnvoid	poollist_dead(int, char *, int, char *, char *);
50369245Sgit2svnvoid	poollist_live(int, char *, int, int);
51369245Sgit2svnint	poolflush(int, char *[]);
52369245Sgit2svnint	poolstats(int, char *[]);
53369245Sgit2svnint	gettype(char *, u_int *);
54369245Sgit2svnint	getrole(char *);
55369245Sgit2svnint	setnodeaddr(int, int, void *ptr, char *arg);
56369245Sgit2svnvoid	showpools_live(int, int, ipf_pool_stat_t *, char *);
57369245Sgit2svnvoid	showhashs_live(int, int, iphtstat_t *, char *);
58369245Sgit2svnvoid	showdstls_live(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);
72353089Scy	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");
74353092Scy	fprintf(stderr, "\t-f <file> [-dnuvR]\n");
75255332Scy	fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
76353091Scy	fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-o <role>] [-M <core>] [-N <namelist>]\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
96353083Scy	switch (getopt(argc, argv, "aAf:FlrRs"))
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;
113145510Sdarrenr	case 'r' :
114145510Sdarrenr		err = poolnodecommand(1, argc, argv);
115145510Sdarrenr		break;
116145510Sdarrenr	case 'R' :
117145510Sdarrenr		err = poolcommand(1, argc, argv);
118145510Sdarrenr		break;
119145510Sdarrenr	case 's' :
120145510Sdarrenr		err = poolstats(argc, argv);
121145510Sdarrenr		break;
122145510Sdarrenr	default :
123145510Sdarrenr		exit(1);
124145510Sdarrenr	}
125145510Sdarrenr
126170268Sdarrenr	if (err != 0)
127170268Sdarrenr		exit(1);
128170268Sdarrenr	return 0;
129145510Sdarrenr}
130145510Sdarrenr
131145510Sdarrenr
132255332Scyint
133255332Scypoolnodecommand(remove, argc, argv)
134255332Scy	int remove, argc;
135255332Scy	char *argv[];
136145510Sdarrenr{
137255332Scy	int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
138170268Sdarrenr	char *poolname = NULL;
139255332Scy	ip_pool_node_t pnode;
140255332Scy	iphtent_t hnode;
141255332Scy	void *ptr = &pnode;
142145510Sdarrenr
143145510Sdarrenr	ipset = 0;
144145510Sdarrenr	role = IPL_LOGIPF;
145255332Scy	bzero((char *)&pnode, sizeof(pnode));
146255332Scy	bzero((char *)&hnode, sizeof(hnode));
147145510Sdarrenr
148353093Scy	while ((c = getopt(argc, argv, "di:m:no:t:T:v")) != -1)
149145510Sdarrenr		switch (c)
150145510Sdarrenr		{
151145510Sdarrenr		case 'd' :
152145510Sdarrenr			opts |= OPT_DEBUG;
153145510Sdarrenr			ippool_yydebug++;
154145510Sdarrenr			break;
155145510Sdarrenr		case 'i' :
156255332Scy			if (setnodeaddr(type, role, ptr, optarg) == 0)
157170268Sdarrenr				ipset = 1;
158145510Sdarrenr			break;
159145510Sdarrenr		case 'm' :
160145510Sdarrenr			poolname = optarg;
161145510Sdarrenr			break;
162145510Sdarrenr		case 'n' :
163255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
164145510Sdarrenr			break;
165145510Sdarrenr		case 'o' :
166255332Scy			if (ipset == 1) {
167255332Scy				fprintf(stderr,
168255332Scy					"cannot set role after ip address\n");
169255332Scy				return -1;
170255332Scy			}
171145510Sdarrenr			role = getrole(optarg);
172145510Sdarrenr			if (role == IPL_LOGNONE)
173145510Sdarrenr				return -1;
174145510Sdarrenr			break;
175255332Scy		case 't' :
176255332Scy			if (ipset == 1) {
177255332Scy				fprintf(stderr,
178255332Scy					"cannot set type after ip address\n");
179255332Scy				return -1;
180255332Scy			}
181255332Scy			type = gettype(optarg, NULL);
182255332Scy			switch (type) {
183255332Scy			case IPLT_NONE :
184255332Scy				fprintf(stderr, "unknown type '%s'\n", optarg);
185255332Scy				return -1;
186255332Scy			case IPLT_HASH :
187255332Scy				ptr = &hnode;
188255332Scy				break;
189255332Scy			case IPLT_POOL :
190255332Scy			default :
191255332Scy				break;
192255332Scy			}
193255332Scy			break;
194255332Scy		case 'T' :
195255332Scy			ttl = atoi(optarg);
196255332Scy			if (ttl < 0) {
197255332Scy				fprintf(stderr, "cannot set negative ttl\n");
198255332Scy				return -1;
199255332Scy			}
200255332Scy			break;
201145510Sdarrenr		case 'v' :
202145510Sdarrenr			opts |= OPT_VERBOSE;
203145510Sdarrenr			break;
204353086Scy		default :
205353086Scy			usage(argv[0]);
206353086Scy			break;		/* keep compiler happy */
207145510Sdarrenr		}
208145510Sdarrenr
209353086Scy	if (argc - 1 - optind > 0)
210353086Scy		usage(argv[0]);
211353086Scy
212170268Sdarrenr	if (argv[optind] != NULL && ipset == 0) {
213255332Scy		if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
214170268Sdarrenr			ipset = 1;
215170268Sdarrenr	}
216170268Sdarrenr
217145510Sdarrenr	if (opts & OPT_DEBUG)
218145510Sdarrenr		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
219145510Sdarrenr
220170268Sdarrenr	if (ipset == 0) {
221170268Sdarrenr		fprintf(stderr, "no IP address given with -i\n");
222145510Sdarrenr		return -1;
223170268Sdarrenr	}
224170268Sdarrenr
225145510Sdarrenr	if (poolname == NULL) {
226145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove node\n");
227145510Sdarrenr		return -1;
228145510Sdarrenr	}
229145510Sdarrenr
230255332Scy	switch (type) {
231255332Scy	case IPLT_POOL :
232255332Scy		if (remove == 0)
233255332Scy			err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
234255332Scy		else
235255332Scy			err = remove_poolnode(role, poolname, &pnode, ioctl);
236255332Scy		break;
237255332Scy	case IPLT_HASH :
238255332Scy		if (remove == 0)
239255332Scy			err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
240255332Scy		else
241255332Scy			err = remove_hashnode(role, poolname, &hnode, ioctl);
242255332Scy		break;
243255332Scy	default :
244255332Scy		break;
245255332Scy	}
246145510Sdarrenr	return err;
247145510Sdarrenr}
248145510Sdarrenr
249145510Sdarrenr
250255332Scyint
251255332Scypoolcommand(remove, argc, argv)
252255332Scy	int remove, argc;
253255332Scy	char *argv[];
254145510Sdarrenr{
255145510Sdarrenr	int type, role, c, err;
256353094Scy	char *poolname, *typearg = NULL;
257145510Sdarrenr	iphtable_t iph;
258145510Sdarrenr	ip_pool_t pool;
259145510Sdarrenr
260145510Sdarrenr	err = 1;
261145510Sdarrenr	role = 0;
262145510Sdarrenr	type = 0;
263145510Sdarrenr	poolname = NULL;
264145510Sdarrenr	role = IPL_LOGIPF;
265145510Sdarrenr	bzero((char *)&iph, sizeof(iph));
266145510Sdarrenr	bzero((char *)&pool, sizeof(pool));
267145510Sdarrenr
268353094Scy	while ((c = getopt(argc, argv, "dm:no:S:vt:")) != -1)
269145510Sdarrenr		switch (c)
270145510Sdarrenr		{
271145510Sdarrenr		case 'd' :
272145510Sdarrenr			opts |= OPT_DEBUG;
273145510Sdarrenr			ippool_yydebug++;
274145510Sdarrenr			break;
275145510Sdarrenr		case 'm' :
276145510Sdarrenr			poolname = optarg;
277145510Sdarrenr			break;
278145510Sdarrenr		case 'n' :
279255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
280145510Sdarrenr			break;
281145510Sdarrenr		case 'o' :
282145510Sdarrenr			role = getrole(optarg);
283145510Sdarrenr			if (role == IPL_LOGNONE) {
284145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
285145510Sdarrenr				return -1;
286145510Sdarrenr			}
287145510Sdarrenr			break;
288145510Sdarrenr		case 'S' :
289353087Scy			if (remove == 0)
290353087Scy				iph.iph_seed = atoi(optarg);
291353087Scy			else
292353087Scy				usage(argv[0]);
293145510Sdarrenr			break;
294353094Scy		case 't' :
295353094Scy			type = gettype(optarg, &iph.iph_type);
296353094Scy			typearg = optarg;
297353094Scy			break;
298145510Sdarrenr		case 'v' :
299145510Sdarrenr			opts |= OPT_VERBOSE;
300145510Sdarrenr			break;
301353084Scy		default :
302353084Scy			usage(argv[0]);
303353084Scy			break;		/* keep compiler happy */
304145510Sdarrenr		}
305145510Sdarrenr
306353084Scy	if (argc - 1 - optind > 0)
307353084Scy		usage(argv[0]);
308353084Scy
309145510Sdarrenr	if (opts & OPT_DEBUG)
310145510Sdarrenr		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
311145510Sdarrenr
312145510Sdarrenr	if (poolname == NULL) {
313145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove pool\n");
314145510Sdarrenr		return -1;
315145510Sdarrenr	}
316145510Sdarrenr
317353094Scy	if (type == IPLT_NONE && remove == 0) {
318353094Scy		if (typearg == NULL) {
319353094Scy			fprintf(stderr, "type must be specified\n");
320353094Scy			usage(argv[0]);
321353094Scy		} else {
322353094Scy			fprintf(stderr, "unknown type '%s'\n", typearg);
323353094Scy		}
324255332Scy		return -1;
325255332Scy	}
326255332Scy
327353094Scy	if (type == IPLT_HASH || (type == IPLT_NONE && remove == 1)) {
328145510Sdarrenr		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
329145510Sdarrenr		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
330145510Sdarrenr		iph.iph_unit = role;
331353094Scy	}
332353094Scy	if (type == IPLT_POOL || (type == IPLT_NONE && remove == 1)) {
333145510Sdarrenr		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
334145510Sdarrenr		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
335145510Sdarrenr		pool.ipo_unit = role;
336145510Sdarrenr	}
337145510Sdarrenr
338145510Sdarrenr	if (remove == 0) {
339145510Sdarrenr		switch (type)
340145510Sdarrenr		{
341145510Sdarrenr		case IPLT_HASH :
342145510Sdarrenr			err = load_hash(&iph, NULL, ioctl);
343145510Sdarrenr			break;
344145510Sdarrenr		case IPLT_POOL :
345145510Sdarrenr			err = load_pool(&pool, ioctl);
346145510Sdarrenr			break;
347145510Sdarrenr		}
348145510Sdarrenr	} else {
349145510Sdarrenr		switch (type)
350145510Sdarrenr		{
351145510Sdarrenr		case IPLT_HASH :
352145510Sdarrenr			err = remove_hash(&iph, ioctl);
353145510Sdarrenr			break;
354145510Sdarrenr		case IPLT_POOL :
355145510Sdarrenr			err = remove_pool(&pool, ioctl);
356145510Sdarrenr			break;
357353094Scy		case IPLT_NONE :
358353094Scy			err = 1;
359353094Scy			{
360353094Scy				int err_h, err_p;
361353094Scy				err_h = remove_hash(&iph, ioctl);
362353094Scy				err_p = remove_pool(&pool, ioctl);
363353094Scy				if (err_h == 0 || err_p == 0)
364353094Scy					err = 0;
365353094Scy			}
366353094Scy			break;
367145510Sdarrenr		}
368145510Sdarrenr	}
369145510Sdarrenr	return err;
370145510Sdarrenr}
371145510Sdarrenr
372145510Sdarrenr
373255332Scyint
374255332Scyloadpoolfile(argc, argv, infile)
375255332Scy	int argc;
376255332Scy	char *argv[], *infile;
377145510Sdarrenr{
378145510Sdarrenr	int c;
379145510Sdarrenr
380358321Scy	while ((c = getopt(argc, argv, "dnuvf:")) != -1)
381145510Sdarrenr		switch (c)
382145510Sdarrenr		{
383145510Sdarrenr		case 'd' :
384145510Sdarrenr			opts |= OPT_DEBUG;
385145510Sdarrenr			ippool_yydebug++;
386145510Sdarrenr			break;
387358321Scy		case 'f' :
388358321Scy			if (loadpoolfile(argc, argv, optarg) != 0)
389358321Scy				return(-1);
390358321Scy			break;
391145510Sdarrenr		case 'n' :
392255332Scy			opts |= OPT_DONOTHING|OPT_DONTOPEN;
393145510Sdarrenr			break;
394145510Sdarrenr		case 'u' :
395145510Sdarrenr			opts |= OPT_REMOVE;
396145510Sdarrenr			break;
397145510Sdarrenr		case 'v' :
398145510Sdarrenr			opts |= OPT_VERBOSE;
399145510Sdarrenr			break;
400353080Scy		default :
401353080Scy			usage(argv[0]);
402353080Scy			break;		/* keep compiler happy */
403145510Sdarrenr		}
404145510Sdarrenr
405353080Scy	if (argc - 1 - optind > 0)
406353080Scy		usage(argv[0]);
407353080Scy
408145510Sdarrenr	if (opts & OPT_DEBUG)
409145510Sdarrenr		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
410145510Sdarrenr
411255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
412145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
413145510Sdarrenr		if (fd == -1) {
414145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
415145510Sdarrenr			exit(1);
416145510Sdarrenr		}
417145510Sdarrenr	}
418145510Sdarrenr
419145510Sdarrenr	if (ippool_parsefile(fd, infile, ioctl) != 0)
420145510Sdarrenr		return -1;
421145510Sdarrenr	return 0;
422145510Sdarrenr}
423145510Sdarrenr
424145510Sdarrenr
425255332Scyint
426255332Scypoolstats(argc, argv)
427255332Scy	int argc;
428255332Scy	char *argv[];
429145510Sdarrenr{
430145510Sdarrenr	int c, type, role, live_kernel;
431255332Scy	ipf_pool_stat_t plstat;
432255332Scy	ipf_dstl_stat_t dlstat;
433145510Sdarrenr	char *kernel, *core;
434145510Sdarrenr	iphtstat_t htstat;
435145510Sdarrenr	iplookupop_t op;
436145510Sdarrenr
437145510Sdarrenr	core = NULL;
438145510Sdarrenr	kernel = NULL;
439145510Sdarrenr	live_kernel = 1;
440145510Sdarrenr	type = IPLT_ALL;
441145510Sdarrenr	role = IPL_LOGALL;
442145510Sdarrenr
443145510Sdarrenr	bzero((char *)&op, sizeof(op));
444145510Sdarrenr
445145510Sdarrenr	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
446145510Sdarrenr		switch (c)
447145510Sdarrenr		{
448145510Sdarrenr		case 'd' :
449145510Sdarrenr			opts |= OPT_DEBUG;
450145510Sdarrenr			break;
451145510Sdarrenr		case 'M' :
452145510Sdarrenr			live_kernel = 0;
453145510Sdarrenr			core = optarg;
454145510Sdarrenr			break;
455145510Sdarrenr		case 'N' :
456145510Sdarrenr			live_kernel = 0;
457145510Sdarrenr			kernel = optarg;
458145510Sdarrenr			break;
459145510Sdarrenr		case 'o' :
460145510Sdarrenr			role = getrole(optarg);
461145510Sdarrenr			if (role == IPL_LOGNONE) {
462145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
463145510Sdarrenr				return -1;
464145510Sdarrenr			}
465145510Sdarrenr			break;
466145510Sdarrenr		case 't' :
467145510Sdarrenr			type = gettype(optarg, NULL);
468145510Sdarrenr			if (type != IPLT_POOL) {
469145510Sdarrenr				fprintf(stderr,
470145510Sdarrenr					"-s not supported for this type yet\n");
471145510Sdarrenr				return -1;
472145510Sdarrenr			}
473145510Sdarrenr			break;
474145510Sdarrenr		case 'v' :
475145510Sdarrenr			opts |= OPT_VERBOSE;
476145510Sdarrenr			break;
477353079Scy		default :
478353079Scy			usage(argv[0]);
479353079Scy			break;		/* keep compiler happy */
480145510Sdarrenr		}
481145510Sdarrenr
482353079Scy	if (argc - 1 - optind > 0)
483353079Scy		usage(argv[0]);
484353079Scy
485145510Sdarrenr	if (opts & OPT_DEBUG)
486145510Sdarrenr		fprintf(stderr, "poolstats: opts = %#x\n", opts);
487145510Sdarrenr
488255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
489145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
490145510Sdarrenr		if (fd == -1) {
491145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
492145510Sdarrenr			exit(1);
493145510Sdarrenr		}
494145510Sdarrenr	}
495145510Sdarrenr
496145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
497145510Sdarrenr		op.iplo_type = IPLT_POOL;
498145510Sdarrenr		op.iplo_struct = &plstat;
499145510Sdarrenr		op.iplo_size = sizeof(plstat);
500255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
501145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
502145510Sdarrenr			if (c == -1) {
503255332Scy				ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
504145510Sdarrenr				return -1;
505145510Sdarrenr			}
506255332Scy			printf("%lu\taddress pools\n", plstat.ipls_pools);
507255332Scy			printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
508145510Sdarrenr		}
509145510Sdarrenr	}
510145510Sdarrenr
511145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
512145510Sdarrenr		op.iplo_type = IPLT_HASH;
513145510Sdarrenr		op.iplo_struct = &htstat;
514145510Sdarrenr		op.iplo_size = sizeof(htstat);
515255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
516145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
517145510Sdarrenr			if (c == -1) {
518255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
519145510Sdarrenr				return -1;
520145510Sdarrenr			}
521255332Scy			printf("%lu\thash tables\n", htstat.iphs_numtables);
522255332Scy			printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
523255332Scy			printf("%lu\thash table no memory \n",
524255332Scy				htstat.iphs_nomem);
525145510Sdarrenr		}
526145510Sdarrenr	}
527255332Scy
528255332Scy	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
529255332Scy		op.iplo_type = IPLT_DSTLIST;
530255332Scy		op.iplo_struct = &dlstat;
531255332Scy		op.iplo_size = sizeof(dlstat);
532255332Scy		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
533255332Scy			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
534255332Scy			if (c == -1) {
535255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
536255332Scy				return -1;
537255332Scy			}
538255332Scy			printf("%u\tdestination lists\n",
539255332Scy			       dlstat.ipls_numlists);
540255332Scy			printf("%u\tdestination list nodes\n",
541255332Scy			       dlstat.ipls_numnodes);
542255332Scy			printf("%lu\tdestination list no memory\n",
543255332Scy			       dlstat.ipls_nomem);
544255332Scy			printf("%u\tdestination list zombies\n",
545255332Scy			       dlstat.ipls_numdereflists);
546255332Scy			printf("%u\tdesetination list node zombies\n",
547255332Scy			       dlstat.ipls_numderefnodes);
548255332Scy		}
549255332Scy	}
550145510Sdarrenr	return 0;
551145510Sdarrenr}
552145510Sdarrenr
553145510Sdarrenr
554255332Scyint
555255332Scypoolflush(argc, argv)
556255332Scy	int argc;
557255332Scy	char *argv[];
558145510Sdarrenr{
559145510Sdarrenr	int c, role, type, arg;
560145510Sdarrenr	iplookupflush_t flush;
561145510Sdarrenr
562145510Sdarrenr	arg = IPLT_ALL;
563145510Sdarrenr	type = IPLT_ALL;
564145510Sdarrenr	role = IPL_LOGALL;
565145510Sdarrenr
566145510Sdarrenr	while ((c = getopt(argc, argv, "do:t:v")) != -1)
567145510Sdarrenr		switch (c)
568145510Sdarrenr		{
569145510Sdarrenr		case 'd' :
570145510Sdarrenr			opts |= OPT_DEBUG;
571145510Sdarrenr			break;
572145510Sdarrenr		case 'o' :
573145510Sdarrenr			role = getrole(optarg);
574145510Sdarrenr			if (role == IPL_LOGNONE) {
575145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
576145510Sdarrenr				return -1;
577145510Sdarrenr			}
578145510Sdarrenr			break;
579145510Sdarrenr		case 't' :
580145510Sdarrenr			type = gettype(optarg, NULL);
581145510Sdarrenr			if (type == IPLT_NONE) {
582145510Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
583145510Sdarrenr				return -1;
584145510Sdarrenr			}
585145510Sdarrenr			break;
586145510Sdarrenr		case 'v' :
587145510Sdarrenr			opts |= OPT_VERBOSE;
588145510Sdarrenr			break;
589353078Scy		default :
590353078Scy			usage(argv[0]);
591353078Scy			break;		/* keep compiler happy */
592145510Sdarrenr		}
593145510Sdarrenr
594353088Scy	if (argc - optind > 0)
595353078Scy		usage(argv[0]);
596353078Scy
597145510Sdarrenr	if (opts & OPT_DEBUG)
598145510Sdarrenr		fprintf(stderr, "poolflush: opts = %#x\n", opts);
599145510Sdarrenr
600255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
601145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
602145510Sdarrenr		if (fd == -1) {
603145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
604145510Sdarrenr			exit(1);
605145510Sdarrenr		}
606145510Sdarrenr	}
607145510Sdarrenr
608145510Sdarrenr	bzero((char *)&flush, sizeof(flush));
609145510Sdarrenr	flush.iplf_type = type;
610145510Sdarrenr	flush.iplf_unit = role;
611145510Sdarrenr	flush.iplf_arg = arg;
612145510Sdarrenr
613255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
614145510Sdarrenr		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
615255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
616145510Sdarrenr			exit(1);
617145510Sdarrenr		}
618145510Sdarrenr
619145510Sdarrenr	}
620255332Scy	printf("%u object%s flushed\n", flush.iplf_count,
621145510Sdarrenr	       (flush.iplf_count == 1) ? "" : "s");
622145510Sdarrenr
623145510Sdarrenr	return 0;
624145510Sdarrenr}
625145510Sdarrenr
626145510Sdarrenr
627255332Scyint
628255332Scygetrole(rolename)
629255332Scy	char *rolename;
630145510Sdarrenr{
631145510Sdarrenr	int role;
632145510Sdarrenr
633145510Sdarrenr	if (!strcasecmp(rolename, "ipf")) {
634145510Sdarrenr		role = IPL_LOGIPF;
635145510Sdarrenr#if 0
636145510Sdarrenr	} else if (!strcasecmp(rolename, "nat")) {
637145510Sdarrenr		role = IPL_LOGNAT;
638145510Sdarrenr	} else if (!strcasecmp(rolename, "state")) {
639145510Sdarrenr		role = IPL_LOGSTATE;
640145510Sdarrenr	} else if (!strcasecmp(rolename, "auth")) {
641145510Sdarrenr		role = IPL_LOGAUTH;
642145510Sdarrenr	} else if (!strcasecmp(rolename, "sync")) {
643145510Sdarrenr		role = IPL_LOGSYNC;
644145510Sdarrenr	} else if (!strcasecmp(rolename, "scan")) {
645145510Sdarrenr		role = IPL_LOGSCAN;
646145510Sdarrenr	} else if (!strcasecmp(rolename, "pool")) {
647145510Sdarrenr		role = IPL_LOGLOOKUP;
648145510Sdarrenr	} else if (!strcasecmp(rolename, "count")) {
649145510Sdarrenr		role = IPL_LOGCOUNT;
650145510Sdarrenr#endif
651145510Sdarrenr	} else {
652145510Sdarrenr		role = IPL_LOGNONE;
653145510Sdarrenr	}
654145510Sdarrenr
655145510Sdarrenr	return role;
656145510Sdarrenr}
657145510Sdarrenr
658145510Sdarrenr
659255332Scyint
660255332Scygettype(typename, minor)
661255332Scy	char *typename;
662255332Scy	u_int *minor;
663145510Sdarrenr{
664145510Sdarrenr	int type;
665145510Sdarrenr
666255332Scy	if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
667145510Sdarrenr		type = IPLT_POOL;
668255332Scy	} else if (!strcasecmp(typename, "hash")) {
669145510Sdarrenr		type = IPLT_HASH;
670145510Sdarrenr		if (minor != NULL)
671145510Sdarrenr			*minor = IPHASH_LOOKUP;
672255332Scy	} else if (!strcasecmp(typename, "group-map")) {
673145510Sdarrenr		type = IPLT_HASH;
674145510Sdarrenr		if (minor != NULL)
675145510Sdarrenr			*minor = IPHASH_GROUPMAP;
676145510Sdarrenr	} else {
677145510Sdarrenr		type = IPLT_NONE;
678145510Sdarrenr	}
679145510Sdarrenr	return type;
680145510Sdarrenr}
681170268Sdarrenr
682170268Sdarrenr
683255332Scyint
684255332Scypoollist(argc, argv)
685255332Scy	int argc;
686255332Scy	char *argv[];
687170268Sdarrenr{
688170268Sdarrenr	char *kernel, *core, *poolname;
689170268Sdarrenr	int c, role, type, live_kernel;
690170268Sdarrenr	iplookupop_t op;
691170268Sdarrenr
692170268Sdarrenr	core = NULL;
693170268Sdarrenr	kernel = NULL;
694170268Sdarrenr	live_kernel = 1;
695170268Sdarrenr	type = IPLT_ALL;
696170268Sdarrenr	poolname = NULL;
697170268Sdarrenr	role = IPL_LOGALL;
698170268Sdarrenr
699353074Scy	while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1)
700170268Sdarrenr		switch (c)
701170268Sdarrenr		{
702170268Sdarrenr		case 'd' :
703170268Sdarrenr			opts |= OPT_DEBUG;
704170268Sdarrenr			break;
705170268Sdarrenr		case 'm' :
706170268Sdarrenr			poolname = optarg;
707170268Sdarrenr			break;
708170268Sdarrenr		case 'M' :
709170268Sdarrenr			live_kernel = 0;
710170268Sdarrenr			core = optarg;
711170268Sdarrenr			break;
712170268Sdarrenr		case 'N' :
713170268Sdarrenr			live_kernel = 0;
714170268Sdarrenr			kernel = optarg;
715170268Sdarrenr			break;
716170268Sdarrenr		case 'o' :
717170268Sdarrenr			role = getrole(optarg);
718170268Sdarrenr			if (role == IPL_LOGNONE) {
719170268Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
720170268Sdarrenr				return -1;
721170268Sdarrenr			}
722170268Sdarrenr			break;
723353076Scy#if 0
724255332Scy		case 'O' :
725353076Scy			/* XXX This option does not work. This function as  */
726353076Scy			/* XXX used by state and nat can be used to format  */
727353076Scy			/* XXX output especially useful for scripting. It   */
728353076Scy			/* XXX is left here with the intention of making    */
729353076Scy			/* XXX it work for the same purpose at some point.  */
730255332Scy			pool_fields = parsefields(poolfields, optarg);
731255332Scy			break;
732353076Scy#endif
733170268Sdarrenr		case 't' :
734170268Sdarrenr			type = gettype(optarg, NULL);
735170268Sdarrenr			if (type == IPLT_NONE) {
736170268Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
737170268Sdarrenr				return -1;
738170268Sdarrenr			}
739170268Sdarrenr			break;
740170268Sdarrenr		case 'v' :
741170268Sdarrenr			opts |= OPT_VERBOSE;
742170268Sdarrenr			break;
743353075Scy		default :
744353075Scy			usage(argv[0]);
745353075Scy			break;		/* keep compiler happy */
746170268Sdarrenr		}
747170268Sdarrenr
748353075Scy	if (argc - optind > 0)
749353075Scy		usage(argv[0]);
750353075Scy
751170268Sdarrenr	if (opts & OPT_DEBUG)
752170268Sdarrenr		fprintf(stderr, "poollist: opts = %#x\n", opts);
753170268Sdarrenr
754255332Scy	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
755170268Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
756170268Sdarrenr		if (fd == -1) {
757170268Sdarrenr			perror("open(IPLOOKUP_NAME)");
758170268Sdarrenr			exit(1);
759170268Sdarrenr		}
760170268Sdarrenr	}
761170268Sdarrenr
762170268Sdarrenr	bzero((char *)&op, sizeof(op));
763170268Sdarrenr	if (poolname != NULL) {
764170268Sdarrenr		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
765170268Sdarrenr		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
766170268Sdarrenr	}
767170268Sdarrenr	op.iplo_unit = role;
768170268Sdarrenr
769170268Sdarrenr	if (live_kernel)
770170268Sdarrenr		poollist_live(role, poolname, type, fd);
771170268Sdarrenr	else
772170268Sdarrenr		poollist_dead(role, poolname, type, kernel, core);
773170268Sdarrenr	return 0;
774170268Sdarrenr}
775170268Sdarrenr
776170268Sdarrenr
777255332Scyvoid
778255332Scypoollist_dead(role, poolname, type, kernel, core)
779255332Scy	int role, type;
780255332Scy	char *poolname, *kernel, *core;
781170268Sdarrenr{
782170268Sdarrenr	iphtable_t *hptr;
783170268Sdarrenr	ip_pool_t *ptr;
784170268Sdarrenr
785170268Sdarrenr	if (openkmem(kernel, core) == -1)
786170268Sdarrenr		exit(-1);
787170268Sdarrenr
788170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
789170268Sdarrenr		ip_pool_t *pools[IPL_LOGSIZE];
790170268Sdarrenr		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
791170268Sdarrenr
792170268Sdarrenr		if (nlist(kernel, names) != 1)
793170268Sdarrenr			return;
794170268Sdarrenr
795170268Sdarrenr		bzero(&pools, sizeof(pools));
796170268Sdarrenr		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
797170268Sdarrenr			return;
798170268Sdarrenr
799170268Sdarrenr		if (role != IPL_LOGALL) {
800170268Sdarrenr			ptr = pools[role];
801170268Sdarrenr			while (ptr != NULL) {
802170268Sdarrenr				ptr = printpool(ptr, kmemcpywrap, poolname,
803255332Scy						opts, pool_fields);
804170268Sdarrenr			}
805170268Sdarrenr		} else {
806170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
807170268Sdarrenr				ptr = pools[role];
808170268Sdarrenr				while (ptr != NULL) {
809170268Sdarrenr					ptr = printpool(ptr, kmemcpywrap,
810255332Scy							poolname, opts,
811255332Scy							pool_fields);
812170268Sdarrenr				}
813170268Sdarrenr			}
814170268Sdarrenr			role = IPL_LOGALL;
815170268Sdarrenr		}
816170268Sdarrenr	}
817170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
818170268Sdarrenr		iphtable_t *tables[IPL_LOGSIZE];
819170268Sdarrenr		struct nlist names[2] = { { "ipf_htables" } , { "" } };
820170268Sdarrenr
821170268Sdarrenr		if (nlist(kernel, names) != 1)
822170268Sdarrenr			return;
823170268Sdarrenr
824170268Sdarrenr		bzero(&tables, sizeof(tables));
825170268Sdarrenr		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
826170268Sdarrenr			return;
827170268Sdarrenr
828170268Sdarrenr		if (role != IPL_LOGALL) {
829170268Sdarrenr			hptr = tables[role];
830170268Sdarrenr			while (hptr != NULL) {
831170268Sdarrenr				hptr = printhash(hptr, kmemcpywrap,
832255332Scy						 poolname, opts, pool_fields);
833170268Sdarrenr			}
834170268Sdarrenr		} else {
835170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
836170268Sdarrenr				hptr = tables[role];
837170268Sdarrenr				while (hptr != NULL) {
838170268Sdarrenr					hptr = printhash(hptr, kmemcpywrap,
839255332Scy							 poolname, opts,
840255332Scy							 pool_fields);
841170268Sdarrenr				}
842170268Sdarrenr			}
843170268Sdarrenr		}
844170268Sdarrenr	}
845170268Sdarrenr}
846170268Sdarrenr
847170268Sdarrenr
848255332Scyvoid
849255332Scypoollist_live(role, poolname, type, fd)
850255332Scy	int role, type, fd;
851255332Scy	char *poolname;
852170268Sdarrenr{
853255332Scy	ipf_pool_stat_t plstat;
854170268Sdarrenr	iplookupop_t op;
855170268Sdarrenr	int c;
856170268Sdarrenr
857170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
858170268Sdarrenr		op.iplo_type = IPLT_POOL;
859170268Sdarrenr		op.iplo_size = sizeof(plstat);
860170268Sdarrenr		op.iplo_struct = &plstat;
861170268Sdarrenr		op.iplo_name[0] = '\0';
862170268Sdarrenr		op.iplo_arg = 0;
863170268Sdarrenr
864170268Sdarrenr		if (role != IPL_LOGALL) {
865170268Sdarrenr			op.iplo_unit = role;
866170268Sdarrenr
867170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
868170268Sdarrenr			if (c == -1) {
869255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
870170268Sdarrenr				return;
871170268Sdarrenr			}
872170268Sdarrenr
873170268Sdarrenr			showpools_live(fd, role, &plstat, poolname);
874170268Sdarrenr		} else {
875255332Scy			for (role = -1; role <= IPL_LOGMAX; role++) {
876170268Sdarrenr				op.iplo_unit = role;
877170268Sdarrenr
878170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
879170268Sdarrenr				if (c == -1) {
880255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
881170268Sdarrenr					return;
882170268Sdarrenr				}
883170268Sdarrenr
884170268Sdarrenr				showpools_live(fd, role, &plstat, poolname);
885170268Sdarrenr			}
886170268Sdarrenr
887170268Sdarrenr			role = IPL_LOGALL;
888170268Sdarrenr		}
889170268Sdarrenr	}
890170268Sdarrenr
891170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
892255332Scy		iphtstat_t htstat;
893255332Scy
894170268Sdarrenr		op.iplo_type = IPLT_HASH;
895170268Sdarrenr		op.iplo_size = sizeof(htstat);
896170268Sdarrenr		op.iplo_struct = &htstat;
897170268Sdarrenr		op.iplo_name[0] = '\0';
898170268Sdarrenr		op.iplo_arg = 0;
899170268Sdarrenr
900170268Sdarrenr		if (role != IPL_LOGALL) {
901170268Sdarrenr			op.iplo_unit = role;
902170268Sdarrenr
903170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
904170268Sdarrenr			if (c == -1) {
905255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
906170268Sdarrenr				return;
907170268Sdarrenr			}
908170268Sdarrenr			showhashs_live(fd, role, &htstat, poolname);
909170268Sdarrenr		} else {
910170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
911170268Sdarrenr
912170268Sdarrenr				op.iplo_unit = role;
913170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
914170268Sdarrenr				if (c == -1) {
915255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
916170268Sdarrenr					return;
917170268Sdarrenr				}
918170268Sdarrenr
919170268Sdarrenr				showhashs_live(fd, role, &htstat, poolname);
920170268Sdarrenr			}
921255332Scy			role = IPL_LOGALL;
922170268Sdarrenr		}
923170268Sdarrenr	}
924255332Scy
925255332Scy	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
926255332Scy		ipf_dstl_stat_t dlstat;
927255332Scy
928255332Scy		op.iplo_type = IPLT_DSTLIST;
929255332Scy		op.iplo_size = sizeof(dlstat);
930255332Scy		op.iplo_struct = &dlstat;
931255332Scy		op.iplo_name[0] = '\0';
932255332Scy		op.iplo_arg = 0;
933255332Scy
934255332Scy		if (role != IPL_LOGALL) {
935255332Scy			op.iplo_unit = role;
936255332Scy
937255332Scy			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
938255332Scy			if (c == -1) {
939255332Scy				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
940255332Scy				return;
941255332Scy			}
942255332Scy			showdstls_live(fd, role, &dlstat, poolname);
943255332Scy		} else {
944255332Scy			for (role = 0; role <= IPL_LOGMAX; role++) {
945255332Scy
946255332Scy				op.iplo_unit = role;
947255332Scy				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
948255332Scy				if (c == -1) {
949255332Scy					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
950255332Scy					return;
951255332Scy				}
952255332Scy
953255332Scy				showdstls_live(fd, role, &dlstat, poolname);
954255332Scy			}
955255332Scy			role = IPL_LOGALL;
956255332Scy		}
957255332Scy	}
958170268Sdarrenr}
959170268Sdarrenr
960170268Sdarrenr
961255332Scyvoid
962255332Scyshowpools_live(fd, role, plstp, poolname)
963255332Scy	int fd, role;
964255332Scy	ipf_pool_stat_t *plstp;
965255332Scy	char *poolname;
966170268Sdarrenr{
967170268Sdarrenr	ipflookupiter_t iter;
968170268Sdarrenr	ip_pool_t pool;
969170268Sdarrenr	ipfobj_t obj;
970170268Sdarrenr
971170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
972170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
973170268Sdarrenr	obj.ipfo_size = sizeof(iter);
974170268Sdarrenr	obj.ipfo_ptr = &iter;
975170268Sdarrenr
976170268Sdarrenr	iter.ili_type = IPLT_POOL;
977170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
978170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
979170268Sdarrenr	iter.ili_nitems = 1;
980170268Sdarrenr	iter.ili_data = &pool;
981170268Sdarrenr	iter.ili_unit = role;
982170268Sdarrenr	*iter.ili_name = '\0';
983170268Sdarrenr
984255332Scy	bzero((char *)&pool, sizeof(pool));
985255332Scy
986255332Scy	while (plstp->ipls_list[role + 1] != NULL) {
987170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
988255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
989170268Sdarrenr			break;
990170268Sdarrenr		}
991255332Scy		if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
992255332Scy		    ((opts & OPT_DEBUG) != 0))
993255332Scy			printpool_live(&pool, fd, poolname, opts, pool_fields);
994170268Sdarrenr
995255332Scy		plstp->ipls_list[role + 1] = pool.ipo_next;
996170268Sdarrenr	}
997170268Sdarrenr}
998170268Sdarrenr
999170268Sdarrenr
1000255332Scyvoid
1001255332Scyshowhashs_live(fd, role, htstp, poolname)
1002255332Scy	int fd, role;
1003255332Scy	iphtstat_t *htstp;
1004255332Scy	char *poolname;
1005170268Sdarrenr{
1006170268Sdarrenr	ipflookupiter_t iter;
1007170268Sdarrenr	iphtable_t table;
1008170268Sdarrenr	ipfobj_t obj;
1009170268Sdarrenr
1010170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
1011170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
1012170268Sdarrenr	obj.ipfo_size = sizeof(iter);
1013170268Sdarrenr	obj.ipfo_ptr = &iter;
1014170268Sdarrenr
1015170268Sdarrenr	iter.ili_type = IPLT_HASH;
1016170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
1017170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
1018170268Sdarrenr	iter.ili_nitems = 1;
1019170268Sdarrenr	iter.ili_data = &table;
1020170268Sdarrenr	iter.ili_unit = role;
1021170268Sdarrenr	*iter.ili_name = '\0';
1022170268Sdarrenr
1023170268Sdarrenr	while (htstp->iphs_tables != NULL) {
1024170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1025255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1026170268Sdarrenr			break;
1027170268Sdarrenr		}
1028170268Sdarrenr
1029255332Scy		printhash_live(&table, fd, poolname, opts, pool_fields);
1030170268Sdarrenr
1031170268Sdarrenr		htstp->iphs_tables = table.iph_next;
1032170268Sdarrenr	}
1033170268Sdarrenr}
1034170268Sdarrenr
1035170268Sdarrenr
1036255332Scyvoid
1037255332Scyshowdstls_live(fd, role, dlstp, poolname)
1038255332Scy	int fd, role;
1039255332Scy	ipf_dstl_stat_t *dlstp;
1040255332Scy	char *poolname;
1041170268Sdarrenr{
1042255332Scy	ipflookupiter_t iter;
1043255332Scy	ippool_dst_t table;
1044255332Scy	ipfobj_t obj;
1045255332Scy
1046255332Scy	obj.ipfo_rev = IPFILTER_VERSION;
1047255332Scy	obj.ipfo_type = IPFOBJ_LOOKUPITER;
1048255332Scy	obj.ipfo_size = sizeof(iter);
1049255332Scy	obj.ipfo_ptr = &iter;
1050255332Scy
1051255332Scy	iter.ili_type = IPLT_DSTLIST;
1052255332Scy	iter.ili_otype = IPFLOOKUPITER_LIST;
1053255332Scy	iter.ili_ival = IPFGENITER_LOOKUP;
1054255332Scy	iter.ili_nitems = 1;
1055255332Scy	iter.ili_data = &table;
1056255332Scy	iter.ili_unit = role;
1057255332Scy	*iter.ili_name = '\0';
1058255332Scy
1059255332Scy	while (dlstp->ipls_list[role] != NULL) {
1060255332Scy		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1061255332Scy			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1062255332Scy			break;
1063255332Scy		}
1064255332Scy
1065255332Scy		printdstl_live(&table, fd, poolname, opts, pool_fields);
1066255332Scy
1067255332Scy		dlstp->ipls_list[role] = table.ipld_next;
1068255332Scy	}
1069255332Scy}
1070255332Scy
1071255332Scy
1072255332Scyint
1073255332Scysetnodeaddr(int type, int role, void *ptr, char *arg)
1074255332Scy{
1075170268Sdarrenr	struct in_addr mask;
1076170268Sdarrenr	char *s;
1077170268Sdarrenr
1078170268Sdarrenr	s = strchr(arg, '/');
1079170268Sdarrenr	if (s == NULL)
1080170268Sdarrenr		mask.s_addr = 0xffffffff;
1081170268Sdarrenr	else if (strchr(s, '.') == NULL) {
1082255332Scy		if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
1083170268Sdarrenr			return -1;
1084170268Sdarrenr	} else {
1085170268Sdarrenr		mask.s_addr = inet_addr(s + 1);
1086170268Sdarrenr	}
1087170268Sdarrenr	if (s != NULL)
1088170268Sdarrenr		*s = '\0';
1089170268Sdarrenr
1090255332Scy	if (type == IPLT_POOL) {
1091255332Scy		ip_pool_node_t *node = ptr;
1092255332Scy
1093318206Scy#ifdef USE_INET6
1094255332Scy		if (node->ipn_addr.adf_family == AF_INET)
1095318206Scy#endif
1096255332Scy			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1097255332Scy							  adf_addr) +
1098255332Scy						 sizeof(struct in_addr);
1099255332Scy#ifdef USE_INET6
1100255332Scy		else
1101255332Scy			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1102255332Scy							  adf_addr) +
1103255332Scy						 sizeof(struct in6_addr);
1104255332Scy#endif
1105255332Scy		node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
1106255332Scy		node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1107255332Scy		node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1108255332Scy	} else if (type == IPLT_HASH) {
1109255332Scy		iphtent_t *node = ptr;
1110255332Scy
1111255332Scy		node->ipe_addr.in4.s_addr = inet_addr(arg);
1112255332Scy		node->ipe_mask.in4.s_addr = mask.s_addr;
1113255332Scy        	node->ipe_family = AF_INET;
1114255332Scy        	node->ipe_unit = role;
1115255332Scy	}
1116255332Scy
1117170268Sdarrenr	return 0;
1118170268Sdarrenr}
1119