ippool.c revision 170268
1145519Sdarrenr/*	$FreeBSD: head/contrib/ipfilter/tools/ippool.c 170268 2007-06-04 02:54:36Z darrenr $	*/
2145510Sdarrenr
3145510Sdarrenr/*
4170268Sdarrenr * Copyright (C) 2002-2006 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 *));
64170268Sdarrenrint	setnodeaddr __P((ip_pool_node_t *node, char *arg));
65170268Sdarrenrvoid	showpools_live __P((int, int, ip_pool_stat_t *, char *));
66170268Sdarrenrvoid	showhashs_live __P((int, int, iphtstat_t *, char *));
67145510Sdarrenr
68145510Sdarrenrint	opts = 0;
69145510Sdarrenrint	fd = -1;
70145510Sdarrenrint	use_inet6 = 0;
71145510Sdarrenr
72145510Sdarrenr
73145510Sdarrenrvoid usage(prog)
74145510Sdarrenrchar *prog;
75145510Sdarrenr{
76145510Sdarrenr	fprintf(stderr, "Usage:\t%s\n", prog);
77145510Sdarrenr	fprintf(stderr, "\t\t\t-a [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
78145510Sdarrenr	fprintf(stderr, "\t\t\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
79145510Sdarrenr	fprintf(stderr, "\t\t\t-f <file> [-dnuv]\n");
80145510Sdarrenr	fprintf(stderr, "\t\t\t-F [-dv] [-o <role>] [-t <type>]\n");
81145510Sdarrenr	fprintf(stderr, "\t\t\t-l [-dv] [-m <name>] [-t <type>]\n");
82145510Sdarrenr	fprintf(stderr, "\t\t\t-r [-dnv] [-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n");
83145510Sdarrenr	fprintf(stderr, "\t\t\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
84145510Sdarrenr	fprintf(stderr, "\t\t\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
85145510Sdarrenr	exit(1);
86145510Sdarrenr}
87145510Sdarrenr
88145510Sdarrenr
89145510Sdarrenrint main(argc, argv)
90145510Sdarrenrint argc;
91145510Sdarrenrchar *argv[];
92145510Sdarrenr{
93145510Sdarrenr	int err;
94145510Sdarrenr
95145510Sdarrenr	if (argc < 2)
96145510Sdarrenr		usage(argv[0]);
97145510Sdarrenr
98145510Sdarrenr	switch (getopt(argc, argv, "aAf:FlrRs"))
99145510Sdarrenr	{
100145510Sdarrenr	case 'a' :
101145510Sdarrenr		err = poolnodecommand(0, argc, argv);
102145510Sdarrenr		break;
103145510Sdarrenr	case 'A' :
104145510Sdarrenr		err = poolcommand(0, argc, argv);
105145510Sdarrenr		break;
106145510Sdarrenr	case 'f' :
107145510Sdarrenr		err = loadpoolfile(argc, argv, optarg);
108145510Sdarrenr		break;
109145510Sdarrenr	case 'F' :
110145510Sdarrenr		err = poolflush(argc, argv);
111145510Sdarrenr		break;
112145510Sdarrenr	case 'l' :
113145510Sdarrenr		err = poollist(argc, argv);
114145510Sdarrenr		break;
115145510Sdarrenr	case 'r' :
116145510Sdarrenr		err = poolnodecommand(1, argc, argv);
117145510Sdarrenr		break;
118145510Sdarrenr	case 'R' :
119145510Sdarrenr		err = poolcommand(1, argc, argv);
120145510Sdarrenr		break;
121145510Sdarrenr	case 's' :
122145510Sdarrenr		err = poolstats(argc, argv);
123145510Sdarrenr		break;
124145510Sdarrenr	default :
125145510Sdarrenr		exit(1);
126145510Sdarrenr	}
127145510Sdarrenr
128170268Sdarrenr	if (err != 0)
129170268Sdarrenr		exit(1);
130170268Sdarrenr	return 0;
131145510Sdarrenr}
132145510Sdarrenr
133145510Sdarrenr
134145510Sdarrenrint poolnodecommand(remove, argc, argv)
135145510Sdarrenrint remove, argc;
136145510Sdarrenrchar *argv[];
137145510Sdarrenr{
138145510Sdarrenr	int err, c, ipset, role;
139170268Sdarrenr	char *poolname = NULL;
140145510Sdarrenr	ip_pool_node_t node;
141145510Sdarrenr
142145510Sdarrenr	ipset = 0;
143145510Sdarrenr	role = IPL_LOGIPF;
144145510Sdarrenr	bzero((char *)&node, sizeof(node));
145145510Sdarrenr
146145510Sdarrenr	while ((c = getopt(argc, argv, "di:m:no:Rv")) != -1)
147145510Sdarrenr		switch (c)
148145510Sdarrenr		{
149145510Sdarrenr		case 'd' :
150145510Sdarrenr			opts |= OPT_DEBUG;
151145510Sdarrenr			ippool_yydebug++;
152145510Sdarrenr			break;
153145510Sdarrenr		case 'i' :
154170268Sdarrenr			if (setnodeaddr(&node, optarg) == 0)
155170268Sdarrenr				ipset = 1;
156145510Sdarrenr			break;
157145510Sdarrenr		case 'm' :
158145510Sdarrenr			poolname = optarg;
159145510Sdarrenr			break;
160145510Sdarrenr		case 'n' :
161145510Sdarrenr			opts |= OPT_DONOTHING;
162145510Sdarrenr			break;
163145510Sdarrenr		case 'o' :
164145510Sdarrenr			role = getrole(optarg);
165145510Sdarrenr			if (role == IPL_LOGNONE)
166145510Sdarrenr				return -1;
167145510Sdarrenr			break;
168145510Sdarrenr		case 'R' :
169145510Sdarrenr			opts |= OPT_NORESOLVE;
170145510Sdarrenr			break;
171145510Sdarrenr		case 'v' :
172145510Sdarrenr			opts |= OPT_VERBOSE;
173145510Sdarrenr			break;
174145510Sdarrenr		}
175145510Sdarrenr
176170268Sdarrenr	if (argv[optind] != NULL && ipset == 0) {
177170268Sdarrenr		if (setnodeaddr(&node, argv[optind]) == 0)
178170268Sdarrenr			ipset = 1;
179170268Sdarrenr	}
180170268Sdarrenr
181145510Sdarrenr	if (opts & OPT_DEBUG)
182145510Sdarrenr		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
183145510Sdarrenr
184170268Sdarrenr	if (ipset == 0) {
185170268Sdarrenr		fprintf(stderr, "no IP address given with -i\n");
186145510Sdarrenr		return -1;
187170268Sdarrenr	}
188170268Sdarrenr
189145510Sdarrenr	if (poolname == NULL) {
190145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove node\n");
191145510Sdarrenr		return -1;
192145510Sdarrenr	}
193145510Sdarrenr
194145510Sdarrenr	if (remove == 0)
195145510Sdarrenr		err = load_poolnode(0, poolname, &node, ioctl);
196145510Sdarrenr	else
197145510Sdarrenr		err = remove_poolnode(0, poolname, &node, ioctl);
198145510Sdarrenr	return err;
199145510Sdarrenr}
200145510Sdarrenr
201145510Sdarrenr
202145510Sdarrenrint poolcommand(remove, argc, argv)
203145510Sdarrenrint remove, argc;
204145510Sdarrenrchar *argv[];
205145510Sdarrenr{
206145510Sdarrenr	int type, role, c, err;
207145510Sdarrenr	char *poolname;
208145510Sdarrenr	iphtable_t iph;
209145510Sdarrenr	ip_pool_t pool;
210145510Sdarrenr
211145510Sdarrenr	err = 1;
212145510Sdarrenr	role = 0;
213145510Sdarrenr	type = 0;
214145510Sdarrenr	poolname = NULL;
215145510Sdarrenr	role = IPL_LOGIPF;
216145510Sdarrenr	bzero((char *)&iph, sizeof(iph));
217145510Sdarrenr	bzero((char *)&pool, sizeof(pool));
218145510Sdarrenr
219145510Sdarrenr	while ((c = getopt(argc, argv, "dm:no:RSt:v")) != -1)
220145510Sdarrenr		switch (c)
221145510Sdarrenr		{
222145510Sdarrenr		case 'd' :
223145510Sdarrenr			opts |= OPT_DEBUG;
224145510Sdarrenr			ippool_yydebug++;
225145510Sdarrenr			break;
226145510Sdarrenr		case 'm' :
227145510Sdarrenr			poolname = optarg;
228145510Sdarrenr			break;
229145510Sdarrenr		case 'n' :
230145510Sdarrenr			opts |= OPT_DONOTHING;
231145510Sdarrenr			break;
232145510Sdarrenr		case 'o' :
233145510Sdarrenr			role = getrole(optarg);
234145510Sdarrenr			if (role == IPL_LOGNONE) {
235145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
236145510Sdarrenr				return -1;
237145510Sdarrenr			}
238145510Sdarrenr			break;
239145510Sdarrenr		case 'R' :
240145510Sdarrenr			opts |= OPT_NORESOLVE;
241145510Sdarrenr			break;
242145510Sdarrenr		case 'S' :
243145510Sdarrenr			iph.iph_seed = atoi(optarg);
244145510Sdarrenr			break;
245145510Sdarrenr		case 't' :
246145510Sdarrenr			type = gettype(optarg, &iph.iph_type);
247145510Sdarrenr			if (type == IPLT_NONE) {
248145510Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
249145510Sdarrenr				return -1;
250145510Sdarrenr			}
251145510Sdarrenr			break;
252145510Sdarrenr		case 'v' :
253145510Sdarrenr			opts |= OPT_VERBOSE;
254145510Sdarrenr			break;
255145510Sdarrenr		}
256145510Sdarrenr
257145510Sdarrenr	if (opts & OPT_DEBUG)
258145510Sdarrenr		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
259145510Sdarrenr
260145510Sdarrenr	if (poolname == NULL) {
261145510Sdarrenr		fprintf(stderr, "poolname not given with add/remove pool\n");
262145510Sdarrenr		return -1;
263145510Sdarrenr	}
264145510Sdarrenr
265145510Sdarrenr	if (type == IPLT_HASH) {
266145510Sdarrenr		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
267145510Sdarrenr		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
268145510Sdarrenr		iph.iph_unit = role;
269145510Sdarrenr	} else if (type == IPLT_POOL) {
270145510Sdarrenr		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
271145510Sdarrenr		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
272145510Sdarrenr		pool.ipo_unit = role;
273145510Sdarrenr	}
274145510Sdarrenr
275145510Sdarrenr	if (remove == 0) {
276145510Sdarrenr		switch (type)
277145510Sdarrenr		{
278145510Sdarrenr		case IPLT_HASH :
279145510Sdarrenr			err = load_hash(&iph, NULL, ioctl);
280145510Sdarrenr			break;
281145510Sdarrenr		case IPLT_POOL :
282145510Sdarrenr			err = load_pool(&pool, ioctl);
283145510Sdarrenr			break;
284145510Sdarrenr		}
285145510Sdarrenr	} else {
286145510Sdarrenr		switch (type)
287145510Sdarrenr		{
288145510Sdarrenr		case IPLT_HASH :
289145510Sdarrenr			err = remove_hash(&iph, ioctl);
290145510Sdarrenr			break;
291145510Sdarrenr		case IPLT_POOL :
292145510Sdarrenr			err = remove_pool(&pool, ioctl);
293145510Sdarrenr			break;
294145510Sdarrenr		}
295145510Sdarrenr	}
296145510Sdarrenr	return err;
297145510Sdarrenr}
298145510Sdarrenr
299145510Sdarrenr
300145510Sdarrenrint loadpoolfile(argc, argv, infile)
301145510Sdarrenrint argc;
302145510Sdarrenrchar *argv[], *infile;
303145510Sdarrenr{
304145510Sdarrenr	int c;
305145510Sdarrenr
306145510Sdarrenr	infile = optarg;
307145510Sdarrenr
308145510Sdarrenr	while ((c = getopt(argc, argv, "dnRuv")) != -1)
309145510Sdarrenr		switch (c)
310145510Sdarrenr		{
311145510Sdarrenr		case 'd' :
312145510Sdarrenr			opts |= OPT_DEBUG;
313145510Sdarrenr			ippool_yydebug++;
314145510Sdarrenr			break;
315145510Sdarrenr		case 'n' :
316145510Sdarrenr			opts |= OPT_DONOTHING;
317145510Sdarrenr			break;
318145510Sdarrenr		case 'R' :
319145510Sdarrenr			opts |= OPT_NORESOLVE;
320145510Sdarrenr			break;
321145510Sdarrenr		case 'u' :
322145510Sdarrenr			opts |= OPT_REMOVE;
323145510Sdarrenr			break;
324145510Sdarrenr		case 'v' :
325145510Sdarrenr			opts |= OPT_VERBOSE;
326145510Sdarrenr			break;
327145510Sdarrenr		}
328145510Sdarrenr
329145510Sdarrenr	if (opts & OPT_DEBUG)
330145510Sdarrenr		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
331145510Sdarrenr
332145510Sdarrenr	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
333145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
334145510Sdarrenr		if (fd == -1) {
335145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
336145510Sdarrenr			exit(1);
337145510Sdarrenr		}
338145510Sdarrenr	}
339145510Sdarrenr
340145510Sdarrenr	if (ippool_parsefile(fd, infile, ioctl) != 0)
341145510Sdarrenr		return -1;
342145510Sdarrenr	return 0;
343145510Sdarrenr}
344145510Sdarrenr
345145510Sdarrenr
346145510Sdarrenrint poolstats(argc, argv)
347145510Sdarrenrint argc;
348145510Sdarrenrchar *argv[];
349145510Sdarrenr{
350145510Sdarrenr	int c, type, role, live_kernel;
351145510Sdarrenr	ip_pool_stat_t plstat;
352145510Sdarrenr	char *kernel, *core;
353145510Sdarrenr	iphtstat_t htstat;
354145510Sdarrenr	iplookupop_t op;
355145510Sdarrenr
356145510Sdarrenr	core = NULL;
357145510Sdarrenr	kernel = NULL;
358145510Sdarrenr	live_kernel = 1;
359145510Sdarrenr	type = IPLT_ALL;
360145510Sdarrenr	role = IPL_LOGALL;
361145510Sdarrenr
362145510Sdarrenr	bzero((char *)&op, sizeof(op));
363145510Sdarrenr
364145510Sdarrenr	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
365145510Sdarrenr		switch (c)
366145510Sdarrenr		{
367145510Sdarrenr		case 'd' :
368145510Sdarrenr			opts |= OPT_DEBUG;
369145510Sdarrenr			break;
370145510Sdarrenr		case 'M' :
371145510Sdarrenr			live_kernel = 0;
372145510Sdarrenr			core = optarg;
373145510Sdarrenr			break;
374145510Sdarrenr		case 'N' :
375145510Sdarrenr			live_kernel = 0;
376145510Sdarrenr			kernel = optarg;
377145510Sdarrenr			break;
378145510Sdarrenr		case 'o' :
379145510Sdarrenr			role = getrole(optarg);
380145510Sdarrenr			if (role == IPL_LOGNONE) {
381145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
382145510Sdarrenr				return -1;
383145510Sdarrenr			}
384145510Sdarrenr			break;
385145510Sdarrenr		case 't' :
386145510Sdarrenr			type = gettype(optarg, NULL);
387145510Sdarrenr			if (type != IPLT_POOL) {
388145510Sdarrenr				fprintf(stderr,
389145510Sdarrenr					"-s not supported for this type yet\n");
390145510Sdarrenr				return -1;
391145510Sdarrenr			}
392145510Sdarrenr			break;
393145510Sdarrenr		case 'v' :
394145510Sdarrenr			opts |= OPT_VERBOSE;
395145510Sdarrenr			break;
396145510Sdarrenr		}
397145510Sdarrenr
398145510Sdarrenr	if (opts & OPT_DEBUG)
399145510Sdarrenr		fprintf(stderr, "poolstats: opts = %#x\n", opts);
400145510Sdarrenr
401145510Sdarrenr	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
402145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
403145510Sdarrenr		if (fd == -1) {
404145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
405145510Sdarrenr			exit(1);
406145510Sdarrenr		}
407145510Sdarrenr	}
408145510Sdarrenr
409145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
410145510Sdarrenr		op.iplo_type = IPLT_POOL;
411145510Sdarrenr		op.iplo_struct = &plstat;
412145510Sdarrenr		op.iplo_size = sizeof(plstat);
413145510Sdarrenr		if (!(opts & OPT_DONOTHING)) {
414145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
415145510Sdarrenr			if (c == -1) {
416145510Sdarrenr				perror("ioctl(SIOCLOOKUPSTAT)");
417145510Sdarrenr				return -1;
418145510Sdarrenr			}
419145510Sdarrenr			printf("Pools:\t%lu\n", plstat.ipls_pools);
420145510Sdarrenr			printf("Nodes:\t%lu\n", plstat.ipls_nodes);
421145510Sdarrenr		}
422145510Sdarrenr	}
423145510Sdarrenr
424145510Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
425145510Sdarrenr		op.iplo_type = IPLT_HASH;
426145510Sdarrenr		op.iplo_struct = &htstat;
427145510Sdarrenr		op.iplo_size = sizeof(htstat);
428145510Sdarrenr		if (!(opts & OPT_DONOTHING)) {
429145510Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
430145510Sdarrenr			if (c == -1) {
431145510Sdarrenr				perror("ioctl(SIOCLOOKUPSTAT)");
432145510Sdarrenr				return -1;
433145510Sdarrenr			}
434145510Sdarrenr			printf("Hash Tables:\t%lu\n", htstat.iphs_numtables);
435145510Sdarrenr			printf("Nodes:\t%lu\n", htstat.iphs_numnodes);
436145510Sdarrenr			printf("Out of Memory:\t%lu\n", htstat.iphs_nomem);
437145510Sdarrenr		}
438145510Sdarrenr	}
439145510Sdarrenr	return 0;
440145510Sdarrenr}
441145510Sdarrenr
442145510Sdarrenr
443145510Sdarrenrint poolflush(argc, argv)
444145510Sdarrenrint argc;
445145510Sdarrenrchar *argv[];
446145510Sdarrenr{
447145510Sdarrenr	int c, role, type, arg;
448145510Sdarrenr	iplookupflush_t flush;
449145510Sdarrenr
450145510Sdarrenr	arg = IPLT_ALL;
451145510Sdarrenr	type = IPLT_ALL;
452145510Sdarrenr	role = IPL_LOGALL;
453145510Sdarrenr
454145510Sdarrenr	while ((c = getopt(argc, argv, "do:t:v")) != -1)
455145510Sdarrenr		switch (c)
456145510Sdarrenr		{
457145510Sdarrenr		case 'd' :
458145510Sdarrenr			opts |= OPT_DEBUG;
459145510Sdarrenr			break;
460145510Sdarrenr		case 'o' :
461145510Sdarrenr			role = getrole(optarg);
462145510Sdarrenr			if (role == IPL_LOGNONE) {
463145510Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
464145510Sdarrenr				return -1;
465145510Sdarrenr			}
466145510Sdarrenr			break;
467145510Sdarrenr		case 't' :
468145510Sdarrenr			type = gettype(optarg, NULL);
469145510Sdarrenr			if (type == IPLT_NONE) {
470145510Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
471145510Sdarrenr				return -1;
472145510Sdarrenr			}
473145510Sdarrenr			break;
474145510Sdarrenr		case 'v' :
475145510Sdarrenr			opts |= OPT_VERBOSE;
476145510Sdarrenr			break;
477145510Sdarrenr		}
478145510Sdarrenr
479145510Sdarrenr	if (opts & OPT_DEBUG)
480145510Sdarrenr		fprintf(stderr, "poolflush: opts = %#x\n", opts);
481145510Sdarrenr
482145510Sdarrenr	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
483145510Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
484145510Sdarrenr		if (fd == -1) {
485145510Sdarrenr			perror("open(IPLOOKUP_NAME)");
486145510Sdarrenr			exit(1);
487145510Sdarrenr		}
488145510Sdarrenr	}
489145510Sdarrenr
490145510Sdarrenr	bzero((char *)&flush, sizeof(flush));
491145510Sdarrenr	flush.iplf_type = type;
492145510Sdarrenr	flush.iplf_unit = role;
493145510Sdarrenr	flush.iplf_arg = arg;
494145510Sdarrenr
495145510Sdarrenr	if (!(opts & OPT_DONOTHING)) {
496145510Sdarrenr		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
497145510Sdarrenr			perror("ioctl(SIOCLOOKUPFLUSH)");
498145510Sdarrenr			exit(1);
499145510Sdarrenr		}
500145510Sdarrenr
501145510Sdarrenr	}
502145630Sdarrenr	printf("%zd object%s flushed\n", flush.iplf_count,
503145510Sdarrenr	       (flush.iplf_count == 1) ? "" : "s");
504145510Sdarrenr
505145510Sdarrenr	return 0;
506145510Sdarrenr}
507145510Sdarrenr
508145510Sdarrenr
509145510Sdarrenrint getrole(rolename)
510145510Sdarrenrchar *rolename;
511145510Sdarrenr{
512145510Sdarrenr	int role;
513145510Sdarrenr
514145510Sdarrenr	if (!strcasecmp(rolename, "ipf")) {
515145510Sdarrenr		role = IPL_LOGIPF;
516145510Sdarrenr#if 0
517145510Sdarrenr	} else if (!strcasecmp(rolename, "nat")) {
518145510Sdarrenr		role = IPL_LOGNAT;
519145510Sdarrenr	} else if (!strcasecmp(rolename, "state")) {
520145510Sdarrenr		role = IPL_LOGSTATE;
521145510Sdarrenr	} else if (!strcasecmp(rolename, "auth")) {
522145510Sdarrenr		role = IPL_LOGAUTH;
523145510Sdarrenr	} else if (!strcasecmp(rolename, "sync")) {
524145510Sdarrenr		role = IPL_LOGSYNC;
525145510Sdarrenr	} else if (!strcasecmp(rolename, "scan")) {
526145510Sdarrenr		role = IPL_LOGSCAN;
527145510Sdarrenr	} else if (!strcasecmp(rolename, "pool")) {
528145510Sdarrenr		role = IPL_LOGLOOKUP;
529145510Sdarrenr	} else if (!strcasecmp(rolename, "count")) {
530145510Sdarrenr		role = IPL_LOGCOUNT;
531145510Sdarrenr#endif
532145510Sdarrenr	} else {
533145510Sdarrenr		role = IPL_LOGNONE;
534145510Sdarrenr	}
535145510Sdarrenr
536145510Sdarrenr	return role;
537145510Sdarrenr}
538145510Sdarrenr
539145510Sdarrenr
540145510Sdarrenrint gettype(typename, minor)
541145510Sdarrenrchar *typename;
542145510Sdarrenru_int *minor;
543145510Sdarrenr{
544145510Sdarrenr	int type;
545145510Sdarrenr
546170268Sdarrenr	if (!strcasecmp(optarg, "tree") || !strcasecmp(optarg, "pool")) {
547145510Sdarrenr		type = IPLT_POOL;
548145510Sdarrenr	} else if (!strcasecmp(optarg, "hash")) {
549145510Sdarrenr		type = IPLT_HASH;
550145510Sdarrenr		if (minor != NULL)
551145510Sdarrenr			*minor = IPHASH_LOOKUP;
552145510Sdarrenr	} else if (!strcasecmp(optarg, "group-map")) {
553145510Sdarrenr		type = IPLT_HASH;
554145510Sdarrenr		if (minor != NULL)
555145510Sdarrenr			*minor = IPHASH_GROUPMAP;
556145510Sdarrenr	} else {
557145510Sdarrenr		type = IPLT_NONE;
558145510Sdarrenr	}
559145510Sdarrenr	return type;
560145510Sdarrenr}
561170268Sdarrenr
562170268Sdarrenr
563170268Sdarrenrint poollist(argc, argv)
564170268Sdarrenrint argc;
565170268Sdarrenrchar *argv[];
566170268Sdarrenr{
567170268Sdarrenr	char *kernel, *core, *poolname;
568170268Sdarrenr	int c, role, type, live_kernel;
569170268Sdarrenr	iplookupop_t op;
570170268Sdarrenr
571170268Sdarrenr	core = NULL;
572170268Sdarrenr	kernel = NULL;
573170268Sdarrenr	live_kernel = 1;
574170268Sdarrenr	type = IPLT_ALL;
575170268Sdarrenr	poolname = NULL;
576170268Sdarrenr	role = IPL_LOGALL;
577170268Sdarrenr
578170268Sdarrenr	while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
579170268Sdarrenr		switch (c)
580170268Sdarrenr		{
581170268Sdarrenr		case 'd' :
582170268Sdarrenr			opts |= OPT_DEBUG;
583170268Sdarrenr			break;
584170268Sdarrenr		case 'm' :
585170268Sdarrenr			poolname = optarg;
586170268Sdarrenr			break;
587170268Sdarrenr		case 'M' :
588170268Sdarrenr			live_kernel = 0;
589170268Sdarrenr			core = optarg;
590170268Sdarrenr			break;
591170268Sdarrenr		case 'N' :
592170268Sdarrenr			live_kernel = 0;
593170268Sdarrenr			kernel = optarg;
594170268Sdarrenr			break;
595170268Sdarrenr		case 'o' :
596170268Sdarrenr			role = getrole(optarg);
597170268Sdarrenr			if (role == IPL_LOGNONE) {
598170268Sdarrenr				fprintf(stderr, "unknown role '%s'\n", optarg);
599170268Sdarrenr				return -1;
600170268Sdarrenr			}
601170268Sdarrenr			break;
602170268Sdarrenr		case 'R' :
603170268Sdarrenr			opts |= OPT_NORESOLVE;
604170268Sdarrenr			break;
605170268Sdarrenr		case 't' :
606170268Sdarrenr			type = gettype(optarg, NULL);
607170268Sdarrenr			if (type == IPLT_NONE) {
608170268Sdarrenr				fprintf(stderr, "unknown type '%s'\n", optarg);
609170268Sdarrenr				return -1;
610170268Sdarrenr			}
611170268Sdarrenr			break;
612170268Sdarrenr		case 'v' :
613170268Sdarrenr			opts |= OPT_VERBOSE;
614170268Sdarrenr			break;
615170268Sdarrenr		}
616170268Sdarrenr
617170268Sdarrenr	if (opts & OPT_DEBUG)
618170268Sdarrenr		fprintf(stderr, "poollist: opts = %#x\n", opts);
619170268Sdarrenr
620170268Sdarrenr	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
621170268Sdarrenr		fd = open(IPLOOKUP_NAME, O_RDWR);
622170268Sdarrenr		if (fd == -1) {
623170268Sdarrenr			perror("open(IPLOOKUP_NAME)");
624170268Sdarrenr			exit(1);
625170268Sdarrenr		}
626170268Sdarrenr	}
627170268Sdarrenr
628170268Sdarrenr	bzero((char *)&op, sizeof(op));
629170268Sdarrenr	if (poolname != NULL) {
630170268Sdarrenr		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
631170268Sdarrenr		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
632170268Sdarrenr	}
633170268Sdarrenr	op.iplo_unit = role;
634170268Sdarrenr
635170268Sdarrenr	if (live_kernel)
636170268Sdarrenr		poollist_live(role, poolname, type, fd);
637170268Sdarrenr	else
638170268Sdarrenr		poollist_dead(role, poolname, type, kernel, core);
639170268Sdarrenr	return 0;
640170268Sdarrenr}
641170268Sdarrenr
642170268Sdarrenr
643170268Sdarrenrvoid poollist_dead(role, poolname, type, kernel, core)
644170268Sdarrenrint role, type;
645170268Sdarrenrchar *poolname, *kernel, *core;
646170268Sdarrenr{
647170268Sdarrenr	iphtable_t *hptr;
648170268Sdarrenr	ip_pool_t *ptr;
649170268Sdarrenr
650170268Sdarrenr	if (openkmem(kernel, core) == -1)
651170268Sdarrenr		exit(-1);
652170268Sdarrenr
653170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
654170268Sdarrenr		ip_pool_t *pools[IPL_LOGSIZE];
655170268Sdarrenr		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
656170268Sdarrenr
657170268Sdarrenr		if (nlist(kernel, names) != 1)
658170268Sdarrenr			return;
659170268Sdarrenr
660170268Sdarrenr		bzero(&pools, sizeof(pools));
661170268Sdarrenr		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
662170268Sdarrenr			return;
663170268Sdarrenr
664170268Sdarrenr		if (role != IPL_LOGALL) {
665170268Sdarrenr			ptr = pools[role];
666170268Sdarrenr			while (ptr != NULL) {
667170268Sdarrenr				ptr = printpool(ptr, kmemcpywrap, poolname,
668170268Sdarrenr						opts);
669170268Sdarrenr			}
670170268Sdarrenr		} else {
671170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
672170268Sdarrenr				ptr = pools[role];
673170268Sdarrenr				while (ptr != NULL) {
674170268Sdarrenr					ptr = printpool(ptr, kmemcpywrap,
675170268Sdarrenr							poolname, opts);
676170268Sdarrenr				}
677170268Sdarrenr			}
678170268Sdarrenr			role = IPL_LOGALL;
679170268Sdarrenr		}
680170268Sdarrenr	}
681170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
682170268Sdarrenr		iphtable_t *tables[IPL_LOGSIZE];
683170268Sdarrenr		struct nlist names[2] = { { "ipf_htables" } , { "" } };
684170268Sdarrenr
685170268Sdarrenr		if (nlist(kernel, names) != 1)
686170268Sdarrenr			return;
687170268Sdarrenr
688170268Sdarrenr		bzero(&tables, sizeof(tables));
689170268Sdarrenr		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
690170268Sdarrenr			return;
691170268Sdarrenr
692170268Sdarrenr		if (role != IPL_LOGALL) {
693170268Sdarrenr			hptr = tables[role];
694170268Sdarrenr			while (hptr != NULL) {
695170268Sdarrenr				hptr = printhash(hptr, kmemcpywrap,
696170268Sdarrenr						 poolname, opts);
697170268Sdarrenr			}
698170268Sdarrenr		} else {
699170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
700170268Sdarrenr				hptr = tables[role];
701170268Sdarrenr				while (hptr != NULL) {
702170268Sdarrenr					hptr = printhash(hptr, kmemcpywrap,
703170268Sdarrenr							 poolname, opts);
704170268Sdarrenr				}
705170268Sdarrenr			}
706170268Sdarrenr		}
707170268Sdarrenr	}
708170268Sdarrenr}
709170268Sdarrenr
710170268Sdarrenr
711170268Sdarrenrvoid poollist_live(role, poolname, type, fd)
712170268Sdarrenrint role, type, fd;
713170268Sdarrenrchar *poolname;
714170268Sdarrenr{
715170268Sdarrenr	ip_pool_stat_t plstat;
716170268Sdarrenr	iphtstat_t htstat;
717170268Sdarrenr	iplookupop_t op;
718170268Sdarrenr	int c;
719170268Sdarrenr
720170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_POOL) {
721170268Sdarrenr		op.iplo_type = IPLT_POOL;
722170268Sdarrenr		op.iplo_size = sizeof(plstat);
723170268Sdarrenr		op.iplo_struct = &plstat;
724170268Sdarrenr		op.iplo_name[0] = '\0';
725170268Sdarrenr		op.iplo_arg = 0;
726170268Sdarrenr
727170268Sdarrenr		if (role != IPL_LOGALL) {
728170268Sdarrenr			op.iplo_unit = role;
729170268Sdarrenr
730170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
731170268Sdarrenr			if (c == -1) {
732170268Sdarrenr				perror("ioctl(SIOCLOOKUPSTAT)");
733170268Sdarrenr				return;
734170268Sdarrenr			}
735170268Sdarrenr
736170268Sdarrenr			showpools_live(fd, role, &plstat, poolname);
737170268Sdarrenr		} else {
738170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
739170268Sdarrenr				op.iplo_unit = role;
740170268Sdarrenr
741170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
742170268Sdarrenr				if (c == -1) {
743170268Sdarrenr					perror("ioctl(SIOCLOOKUPSTAT)");
744170268Sdarrenr					return;
745170268Sdarrenr				}
746170268Sdarrenr
747170268Sdarrenr				showpools_live(fd, role, &plstat, poolname);
748170268Sdarrenr			}
749170268Sdarrenr
750170268Sdarrenr			role = IPL_LOGALL;
751170268Sdarrenr		}
752170268Sdarrenr	}
753170268Sdarrenr
754170268Sdarrenr	if (type == IPLT_ALL || type == IPLT_HASH) {
755170268Sdarrenr		op.iplo_type = IPLT_HASH;
756170268Sdarrenr		op.iplo_size = sizeof(htstat);
757170268Sdarrenr		op.iplo_struct = &htstat;
758170268Sdarrenr		op.iplo_name[0] = '\0';
759170268Sdarrenr		op.iplo_arg = 0;
760170268Sdarrenr
761170268Sdarrenr		if (role != IPL_LOGALL) {
762170268Sdarrenr			op.iplo_unit = role;
763170268Sdarrenr
764170268Sdarrenr			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
765170268Sdarrenr			if (c == -1) {
766170268Sdarrenr				perror("ioctl(SIOCLOOKUPSTAT)");
767170268Sdarrenr				return;
768170268Sdarrenr			}
769170268Sdarrenr			showhashs_live(fd, role, &htstat, poolname);
770170268Sdarrenr		} else {
771170268Sdarrenr			for (role = 0; role <= IPL_LOGMAX; role++) {
772170268Sdarrenr
773170268Sdarrenr				op.iplo_unit = role;
774170268Sdarrenr				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
775170268Sdarrenr				if (c == -1) {
776170268Sdarrenr					perror("ioctl(SIOCLOOKUPSTAT)");
777170268Sdarrenr					return;
778170268Sdarrenr				}
779170268Sdarrenr
780170268Sdarrenr				showhashs_live(fd, role, &htstat, poolname);
781170268Sdarrenr			}
782170268Sdarrenr		}
783170268Sdarrenr	}
784170268Sdarrenr}
785170268Sdarrenr
786170268Sdarrenr
787170268Sdarrenrvoid showpools_live(fd, role, plstp, poolname)
788170268Sdarrenrint fd, role;
789170268Sdarrenrip_pool_stat_t *plstp;
790170268Sdarrenrchar *poolname;
791170268Sdarrenr{
792170268Sdarrenr	ipflookupiter_t iter;
793170268Sdarrenr	ip_pool_t pool;
794170268Sdarrenr	ipfobj_t obj;
795170268Sdarrenr
796170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
797170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
798170268Sdarrenr	obj.ipfo_size = sizeof(iter);
799170268Sdarrenr	obj.ipfo_ptr = &iter;
800170268Sdarrenr
801170268Sdarrenr	iter.ili_type = IPLT_POOL;
802170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
803170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
804170268Sdarrenr	iter.ili_nitems = 1;
805170268Sdarrenr	iter.ili_data = &pool;
806170268Sdarrenr	iter.ili_unit = role;
807170268Sdarrenr	*iter.ili_name = '\0';
808170268Sdarrenr
809170268Sdarrenr	while (plstp->ipls_list[role] != NULL) {
810170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
811170268Sdarrenr			perror("ioctl(SIOCLOOKUPITER)");
812170268Sdarrenr			break;
813170268Sdarrenr		}
814170268Sdarrenr		printpool_live(&pool, fd, poolname, opts);
815170268Sdarrenr
816170268Sdarrenr		plstp->ipls_list[role] = pool.ipo_next;
817170268Sdarrenr	}
818170268Sdarrenr}
819170268Sdarrenr
820170268Sdarrenr
821170268Sdarrenrvoid showhashs_live(fd, role, htstp, poolname)
822170268Sdarrenrint fd, role;
823170268Sdarrenriphtstat_t *htstp;
824170268Sdarrenrchar *poolname;
825170268Sdarrenr{
826170268Sdarrenr	ipflookupiter_t iter;
827170268Sdarrenr	iphtable_t table;
828170268Sdarrenr	ipfobj_t obj;
829170268Sdarrenr
830170268Sdarrenr	obj.ipfo_rev = IPFILTER_VERSION;
831170268Sdarrenr	obj.ipfo_type = IPFOBJ_LOOKUPITER;
832170268Sdarrenr	obj.ipfo_size = sizeof(iter);
833170268Sdarrenr	obj.ipfo_ptr = &iter;
834170268Sdarrenr
835170268Sdarrenr	iter.ili_type = IPLT_HASH;
836170268Sdarrenr	iter.ili_otype = IPFLOOKUPITER_LIST;
837170268Sdarrenr	iter.ili_ival = IPFGENITER_LOOKUP;
838170268Sdarrenr	iter.ili_nitems = 1;
839170268Sdarrenr	iter.ili_data = &table;
840170268Sdarrenr	iter.ili_unit = role;
841170268Sdarrenr	*iter.ili_name = '\0';
842170268Sdarrenr
843170268Sdarrenr	while (htstp->iphs_tables != NULL) {
844170268Sdarrenr		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
845170268Sdarrenr			perror("ioctl(SIOCLOOKUPITER)");
846170268Sdarrenr			break;
847170268Sdarrenr		}
848170268Sdarrenr
849170268Sdarrenr		printhash_live(&table, fd, poolname, opts);
850170268Sdarrenr
851170268Sdarrenr		htstp->iphs_tables = table.iph_next;
852170268Sdarrenr	}
853170268Sdarrenr}
854170268Sdarrenr
855170268Sdarrenr
856170268Sdarrenrint setnodeaddr(ip_pool_node_t *node, char *arg)
857170268Sdarrenr{
858170268Sdarrenr	struct in_addr mask;
859170268Sdarrenr	char *s;
860170268Sdarrenr
861170268Sdarrenr	s = strchr(arg, '/');
862170268Sdarrenr	if (s == NULL)
863170268Sdarrenr		mask.s_addr = 0xffffffff;
864170268Sdarrenr	else if (strchr(s, '.') == NULL) {
865170268Sdarrenr		if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0)
866170268Sdarrenr			return -1;
867170268Sdarrenr	} else {
868170268Sdarrenr		mask.s_addr = inet_addr(s + 1);
869170268Sdarrenr	}
870170268Sdarrenr	if (s != NULL)
871170268Sdarrenr		*s = '\0';
872170268Sdarrenr	node->ipn_addr.adf_len = sizeof(node->ipn_addr);
873170268Sdarrenr	node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
874170268Sdarrenr	node->ipn_mask.adf_len = sizeof(node->ipn_mask);
875170268Sdarrenr	node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
876170268Sdarrenr
877170268Sdarrenr	return 0;
878170268Sdarrenr}
879