ippool.c revision 353086
1/*	$FreeBSD: stable/11/contrib/ipfilter/tools/ippool.c 353086 2019-10-04 02:01:23Z cy $	*/
2
3/*
4 * Copyright (C) 2012 by Darren Reed.
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 */
8#include <sys/types.h>
9#include <sys/time.h>
10#include <sys/param.h>
11#include <sys/socket.h>
12# include <sys/cdefs.h>
13#include <sys/ioctl.h>
14
15#include <net/if.h>
16#include <netinet/in.h>
17
18#include <arpa/inet.h>
19
20#include <stdio.h>
21#include <fcntl.h>
22#include <stdlib.h>
23#include <string.h>
24#include <netdb.h>
25#include <ctype.h>
26#include <unistd.h>
27# include <nlist.h>
28
29#include "ipf.h"
30#include "netinet/ipl.h"
31#include "netinet/ip_lookup.h"
32#include "netinet/ip_pool.h"
33#include "netinet/ip_htable.h"
34#include "kmem.h"
35
36
37extern	int	ippool_yyparse __P((void));
38extern	int	ippool_yydebug;
39extern	FILE	*ippool_yyin;
40extern	char	*optarg;
41extern	int	lineNum;
42
43void	usage __P((char *));
44int	main __P((int, char **));
45int	poolcommand __P((int, int, char *[]));
46int	poolnodecommand __P((int, int, char *[]));
47int	loadpoolfile __P((int, char *[], char *));
48int	poollist __P((int, char *[]));
49void	poollist_dead __P((int, char *, int, char *, char *));
50void	poollist_live __P((int, char *, int, int));
51int	poolflush __P((int, char *[]));
52int	poolstats __P((int, char *[]));
53int	gettype __P((char *, u_int *));
54int	getrole __P((char *));
55int	setnodeaddr __P((int, int, void *ptr, char *arg));
56void	showpools_live __P((int, int, ipf_pool_stat_t *, char *));
57void	showhashs_live __P((int, int, iphtstat_t *, char *));
58void	showdstls_live __P((int, int, ipf_dstl_stat_t *, char *));
59
60int	opts = 0;
61int	fd = -1;
62int	use_inet6 = 0;
63wordtab_t *pool_fields = NULL;
64int	nohdrfields = 0;
65
66
67void
68usage(prog)
69	char *prog;
70{
71	fprintf(stderr, "Usage:\t%s\n", prog);
72	fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
73	fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
74	fprintf(stderr, "\t-f <file> [-dnuv]\n");
75	fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
76	fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>]\n");
77	fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
78	fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
79	fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
80	exit(1);
81}
82
83
84int
85main(argc, argv)
86	int argc;
87	char *argv[];
88{
89	int err = 1;
90
91	if (argc < 2)
92		usage(argv[0]);
93
94	assigndefined(getenv("IPPOOL_PREDEFINED"));
95
96	switch (getopt(argc, argv, "aAf:FlrRs"))
97	{
98	case 'a' :
99		err = poolnodecommand(0, argc, argv);
100		break;
101	case 'A' :
102		err = poolcommand(0, argc, argv);
103		break;
104	case 'f' :
105		err = loadpoolfile(argc, argv, optarg);
106		break;
107	case 'F' :
108		err = poolflush(argc, argv);
109		break;
110	case 'l' :
111		err = poollist(argc, argv);
112		break;
113	case 'r' :
114		err = poolnodecommand(1, argc, argv);
115		break;
116	case 'R' :
117		err = poolcommand(1, argc, argv);
118		break;
119	case 's' :
120		err = poolstats(argc, argv);
121		break;
122	default :
123		exit(1);
124	}
125
126	if (err != 0)
127		exit(1);
128	return 0;
129}
130
131
132int
133poolnodecommand(remove, argc, argv)
134	int remove, argc;
135	char *argv[];
136{
137	int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
138	char *poolname = NULL;
139	ip_pool_node_t pnode;
140	iphtent_t hnode;
141	void *ptr = &pnode;
142
143	ipset = 0;
144	role = IPL_LOGIPF;
145	bzero((char *)&pnode, sizeof(pnode));
146	bzero((char *)&hnode, sizeof(hnode));
147
148	while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1)
149		switch (c)
150		{
151		case 'd' :
152			opts |= OPT_DEBUG;
153			ippool_yydebug++;
154			break;
155		case 'i' :
156			if (setnodeaddr(type, role, ptr, optarg) == 0)
157				ipset = 1;
158			break;
159		case 'm' :
160			poolname = optarg;
161			break;
162		case 'n' :
163			opts |= OPT_DONOTHING|OPT_DONTOPEN;
164			break;
165		case 'o' :
166			if (ipset == 1) {
167				fprintf(stderr,
168					"cannot set role after ip address\n");
169				return -1;
170			}
171			role = getrole(optarg);
172			if (role == IPL_LOGNONE)
173				return -1;
174			break;
175		case 'R' :
176			opts |= OPT_NORESOLVE;
177			break;
178		case 't' :
179			if (ipset == 1) {
180				fprintf(stderr,
181					"cannot set type after ip address\n");
182				return -1;
183			}
184			type = gettype(optarg, NULL);
185			switch (type) {
186			case IPLT_NONE :
187				fprintf(stderr, "unknown type '%s'\n", optarg);
188				return -1;
189			case IPLT_HASH :
190				ptr = &hnode;
191				break;
192			case IPLT_POOL :
193			default :
194				break;
195			}
196			break;
197		case 'T' :
198			ttl = atoi(optarg);
199			if (ttl < 0) {
200				fprintf(stderr, "cannot set negative ttl\n");
201				return -1;
202			}
203			break;
204		case 'v' :
205			opts |= OPT_VERBOSE;
206			break;
207		default :
208			usage(argv[0]);
209			break;		/* keep compiler happy */
210		}
211
212	if (argc - 1 - optind > 0)
213		usage(argv[0]);
214
215	if (argv[optind] != NULL && ipset == 0) {
216		if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
217			ipset = 1;
218	}
219
220	if (opts & OPT_DEBUG)
221		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
222
223	if (ipset == 0) {
224		fprintf(stderr, "no IP address given with -i\n");
225		return -1;
226	}
227
228	if (poolname == NULL) {
229		fprintf(stderr, "poolname not given with add/remove node\n");
230		return -1;
231	}
232
233	switch (type) {
234	case IPLT_POOL :
235		if (remove == 0)
236			err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
237		else
238			err = remove_poolnode(role, poolname, &pnode, ioctl);
239		break;
240	case IPLT_HASH :
241		if (remove == 0)
242			err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
243		else
244			err = remove_hashnode(role, poolname, &hnode, ioctl);
245		break;
246	default :
247		break;
248	}
249	return err;
250}
251
252
253int
254poolcommand(remove, argc, argv)
255	int remove, argc;
256	char *argv[];
257{
258	int type, role, c, err;
259	char *poolname;
260	iphtable_t iph;
261	ip_pool_t pool;
262
263	err = 1;
264	role = 0;
265	type = 0;
266	poolname = NULL;
267	role = IPL_LOGIPF;
268	bzero((char *)&iph, sizeof(iph));
269	bzero((char *)&pool, sizeof(pool));
270
271	while ((c = getopt(argc, argv, "dm:no:RS:v")) != -1)
272		switch (c)
273		{
274		case 'd' :
275			opts |= OPT_DEBUG;
276			ippool_yydebug++;
277			break;
278		case 'm' :
279			poolname = optarg;
280			break;
281		case 'n' :
282			opts |= OPT_DONOTHING|OPT_DONTOPEN;
283			break;
284		case 'o' :
285			role = getrole(optarg);
286			if (role == IPL_LOGNONE) {
287				fprintf(stderr, "unknown role '%s'\n", optarg);
288				return -1;
289			}
290			break;
291		case 'R' :
292			opts |= OPT_NORESOLVE;
293			break;
294		case 'S' :
295			iph.iph_seed = atoi(optarg);
296			break;
297		case 'v' :
298			opts |= OPT_VERBOSE;
299			break;
300		default :
301			usage(argv[0]);
302			break;		/* keep compiler happy */
303		}
304
305	if (argc - 1 - optind > 0)
306		usage(argv[0]);
307
308	if (opts & OPT_DEBUG)
309		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
310
311	if (poolname == NULL) {
312		fprintf(stderr, "poolname not given with add/remove pool\n");
313		return -1;
314	}
315
316	type = gettype(argv[optind], &iph.iph_type);
317	if (type == IPLT_NONE) {
318		fprintf(stderr, "unknown type '%s'\n", argv[optind]);
319		return -1;
320	}
321
322	if (type == IPLT_HASH) {
323		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
324		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
325		iph.iph_unit = role;
326	} else if (type == IPLT_POOL) {
327		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
328		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
329		pool.ipo_unit = role;
330	}
331
332	if (remove == 0) {
333		switch (type)
334		{
335		case IPLT_HASH :
336			err = load_hash(&iph, NULL, ioctl);
337			break;
338		case IPLT_POOL :
339			err = load_pool(&pool, ioctl);
340			break;
341		}
342	} else {
343		switch (type)
344		{
345		case IPLT_HASH :
346			err = remove_hash(&iph, ioctl);
347			break;
348		case IPLT_POOL :
349			err = remove_pool(&pool, ioctl);
350			break;
351		}
352	}
353	return err;
354}
355
356
357int
358loadpoolfile(argc, argv, infile)
359	int argc;
360	char *argv[], *infile;
361{
362	int c;
363
364	while ((c = getopt(argc, argv, "dnRuv")) != -1)
365		switch (c)
366		{
367		case 'd' :
368			opts |= OPT_DEBUG;
369			ippool_yydebug++;
370			break;
371		case 'n' :
372			opts |= OPT_DONOTHING|OPT_DONTOPEN;
373			break;
374		case 'R' :
375			opts |= OPT_NORESOLVE;
376			break;
377		case 'u' :
378			opts |= OPT_REMOVE;
379			break;
380		case 'v' :
381			opts |= OPT_VERBOSE;
382			break;
383		default :
384			usage(argv[0]);
385			break;		/* keep compiler happy */
386		}
387
388	if (argc - 1 - optind > 0)
389		usage(argv[0]);
390
391	if (opts & OPT_DEBUG)
392		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
393
394	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
395		fd = open(IPLOOKUP_NAME, O_RDWR);
396		if (fd == -1) {
397			perror("open(IPLOOKUP_NAME)");
398			exit(1);
399		}
400	}
401
402	if (ippool_parsefile(fd, infile, ioctl) != 0)
403		return -1;
404	return 0;
405}
406
407
408int
409poolstats(argc, argv)
410	int argc;
411	char *argv[];
412{
413	int c, type, role, live_kernel;
414	ipf_pool_stat_t plstat;
415	ipf_dstl_stat_t dlstat;
416	char *kernel, *core;
417	iphtstat_t htstat;
418	iplookupop_t op;
419
420	core = NULL;
421	kernel = NULL;
422	live_kernel = 1;
423	type = IPLT_ALL;
424	role = IPL_LOGALL;
425
426	bzero((char *)&op, sizeof(op));
427
428	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
429		switch (c)
430		{
431		case 'd' :
432			opts |= OPT_DEBUG;
433			break;
434		case 'M' :
435			live_kernel = 0;
436			core = optarg;
437			break;
438		case 'N' :
439			live_kernel = 0;
440			kernel = optarg;
441			break;
442		case 'o' :
443			role = getrole(optarg);
444			if (role == IPL_LOGNONE) {
445				fprintf(stderr, "unknown role '%s'\n", optarg);
446				return -1;
447			}
448			break;
449		case 't' :
450			type = gettype(optarg, NULL);
451			if (type != IPLT_POOL) {
452				fprintf(stderr,
453					"-s not supported for this type yet\n");
454				return -1;
455			}
456			break;
457		case 'v' :
458			opts |= OPT_VERBOSE;
459			break;
460		default :
461			usage(argv[0]);
462			break;		/* keep compiler happy */
463		}
464
465	if (argc - 1 - optind > 0)
466		usage(argv[0]);
467
468	if (opts & OPT_DEBUG)
469		fprintf(stderr, "poolstats: opts = %#x\n", opts);
470
471	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
472		fd = open(IPLOOKUP_NAME, O_RDWR);
473		if (fd == -1) {
474			perror("open(IPLOOKUP_NAME)");
475			exit(1);
476		}
477	}
478
479	if (type == IPLT_ALL || type == IPLT_POOL) {
480		op.iplo_type = IPLT_POOL;
481		op.iplo_struct = &plstat;
482		op.iplo_size = sizeof(plstat);
483		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
484			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
485			if (c == -1) {
486				ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
487				return -1;
488			}
489			printf("%lu\taddress pools\n", plstat.ipls_pools);
490			printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
491		}
492	}
493
494	if (type == IPLT_ALL || type == IPLT_HASH) {
495		op.iplo_type = IPLT_HASH;
496		op.iplo_struct = &htstat;
497		op.iplo_size = sizeof(htstat);
498		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
499			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
500			if (c == -1) {
501				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
502				return -1;
503			}
504			printf("%lu\thash tables\n", htstat.iphs_numtables);
505			printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
506			printf("%lu\thash table no memory \n",
507				htstat.iphs_nomem);
508		}
509	}
510
511	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
512		op.iplo_type = IPLT_DSTLIST;
513		op.iplo_struct = &dlstat;
514		op.iplo_size = sizeof(dlstat);
515		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
516			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
517			if (c == -1) {
518				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
519				return -1;
520			}
521			printf("%u\tdestination lists\n",
522			       dlstat.ipls_numlists);
523			printf("%u\tdestination list nodes\n",
524			       dlstat.ipls_numnodes);
525			printf("%lu\tdestination list no memory\n",
526			       dlstat.ipls_nomem);
527			printf("%u\tdestination list zombies\n",
528			       dlstat.ipls_numdereflists);
529			printf("%u\tdesetination list node zombies\n",
530			       dlstat.ipls_numderefnodes);
531		}
532	}
533	return 0;
534}
535
536
537int
538poolflush(argc, argv)
539	int argc;
540	char *argv[];
541{
542	int c, role, type, arg;
543	iplookupflush_t flush;
544
545	arg = IPLT_ALL;
546	type = IPLT_ALL;
547	role = IPL_LOGALL;
548
549	while ((c = getopt(argc, argv, "do:t:v")) != -1)
550		switch (c)
551		{
552		case 'd' :
553			opts |= OPT_DEBUG;
554			break;
555		case 'o' :
556			role = getrole(optarg);
557			if (role == IPL_LOGNONE) {
558				fprintf(stderr, "unknown role '%s'\n", optarg);
559				return -1;
560			}
561			break;
562		case 't' :
563			type = gettype(optarg, NULL);
564			if (type == IPLT_NONE) {
565				fprintf(stderr, "unknown type '%s'\n", optarg);
566				return -1;
567			}
568			break;
569		case 'v' :
570			opts |= OPT_VERBOSE;
571			break;
572		default :
573			usage(argv[0]);
574			break;		/* keep compiler happy */
575		}
576
577	if (argc - 1 - optind > 0)
578		usage(argv[0]);
579
580	if (opts & OPT_DEBUG)
581		fprintf(stderr, "poolflush: opts = %#x\n", opts);
582
583	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
584		fd = open(IPLOOKUP_NAME, O_RDWR);
585		if (fd == -1) {
586			perror("open(IPLOOKUP_NAME)");
587			exit(1);
588		}
589	}
590
591	bzero((char *)&flush, sizeof(flush));
592	flush.iplf_type = type;
593	flush.iplf_unit = role;
594	flush.iplf_arg = arg;
595
596	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
597		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
598			ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
599			exit(1);
600		}
601
602	}
603	printf("%u object%s flushed\n", flush.iplf_count,
604	       (flush.iplf_count == 1) ? "" : "s");
605
606	return 0;
607}
608
609
610int
611getrole(rolename)
612	char *rolename;
613{
614	int role;
615
616	if (!strcasecmp(rolename, "ipf")) {
617		role = IPL_LOGIPF;
618#if 0
619	} else if (!strcasecmp(rolename, "nat")) {
620		role = IPL_LOGNAT;
621	} else if (!strcasecmp(rolename, "state")) {
622		role = IPL_LOGSTATE;
623	} else if (!strcasecmp(rolename, "auth")) {
624		role = IPL_LOGAUTH;
625	} else if (!strcasecmp(rolename, "sync")) {
626		role = IPL_LOGSYNC;
627	} else if (!strcasecmp(rolename, "scan")) {
628		role = IPL_LOGSCAN;
629	} else if (!strcasecmp(rolename, "pool")) {
630		role = IPL_LOGLOOKUP;
631	} else if (!strcasecmp(rolename, "count")) {
632		role = IPL_LOGCOUNT;
633#endif
634	} else {
635		role = IPL_LOGNONE;
636	}
637
638	return role;
639}
640
641
642int
643gettype(typename, minor)
644	char *typename;
645	u_int *minor;
646{
647	int type;
648
649	if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
650		type = IPLT_POOL;
651	} else if (!strcasecmp(typename, "hash")) {
652		type = IPLT_HASH;
653		if (minor != NULL)
654			*minor = IPHASH_LOOKUP;
655	} else if (!strcasecmp(typename, "group-map")) {
656		type = IPLT_HASH;
657		if (minor != NULL)
658			*minor = IPHASH_GROUPMAP;
659	} else {
660		type = IPLT_NONE;
661	}
662	return type;
663}
664
665
666int
667poollist(argc, argv)
668	int argc;
669	char *argv[];
670{
671	char *kernel, *core, *poolname;
672	int c, role, type, live_kernel;
673	iplookupop_t op;
674
675	core = NULL;
676	kernel = NULL;
677	live_kernel = 1;
678	type = IPLT_ALL;
679	poolname = NULL;
680	role = IPL_LOGALL;
681
682	while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1)
683		switch (c)
684		{
685		case 'd' :
686			opts |= OPT_DEBUG;
687			break;
688		case 'm' :
689			poolname = optarg;
690			break;
691		case 'M' :
692			live_kernel = 0;
693			core = optarg;
694			break;
695		case 'N' :
696			live_kernel = 0;
697			kernel = optarg;
698			break;
699		case 'o' :
700			role = getrole(optarg);
701			if (role == IPL_LOGNONE) {
702				fprintf(stderr, "unknown role '%s'\n", optarg);
703				return -1;
704			}
705			break;
706#if 0
707		case 'O' :
708			/* XXX This option does not work. This function as  */
709			/* XXX used by state and nat can be used to format  */
710			/* XXX output especially useful for scripting. It   */
711			/* XXX is left here with the intention of making    */
712			/* XXX it work for the same purpose at some point.  */
713			pool_fields = parsefields(poolfields, optarg);
714			break;
715#endif
716		case 't' :
717			type = gettype(optarg, NULL);
718			if (type == IPLT_NONE) {
719				fprintf(stderr, "unknown type '%s'\n", optarg);
720				return -1;
721			}
722			break;
723		case 'v' :
724			opts |= OPT_VERBOSE;
725			break;
726		default :
727			usage(argv[0]);
728			break;		/* keep compiler happy */
729		}
730
731	if (argc - optind > 0)
732		usage(argv[0]);
733
734	if (opts & OPT_DEBUG)
735		fprintf(stderr, "poollist: opts = %#x\n", opts);
736
737	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
738		fd = open(IPLOOKUP_NAME, O_RDWR);
739		if (fd == -1) {
740			perror("open(IPLOOKUP_NAME)");
741			exit(1);
742		}
743	}
744
745	bzero((char *)&op, sizeof(op));
746	if (poolname != NULL) {
747		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
748		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
749	}
750	op.iplo_unit = role;
751
752	if (live_kernel)
753		poollist_live(role, poolname, type, fd);
754	else
755		poollist_dead(role, poolname, type, kernel, core);
756	return 0;
757}
758
759
760void
761poollist_dead(role, poolname, type, kernel, core)
762	int role, type;
763	char *poolname, *kernel, *core;
764{
765	iphtable_t *hptr;
766	ip_pool_t *ptr;
767
768	if (openkmem(kernel, core) == -1)
769		exit(-1);
770
771	if (type == IPLT_ALL || type == IPLT_POOL) {
772		ip_pool_t *pools[IPL_LOGSIZE];
773		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
774
775		if (nlist(kernel, names) != 1)
776			return;
777
778		bzero(&pools, sizeof(pools));
779		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
780			return;
781
782		if (role != IPL_LOGALL) {
783			ptr = pools[role];
784			while (ptr != NULL) {
785				ptr = printpool(ptr, kmemcpywrap, poolname,
786						opts, pool_fields);
787			}
788		} else {
789			for (role = 0; role <= IPL_LOGMAX; role++) {
790				ptr = pools[role];
791				while (ptr != NULL) {
792					ptr = printpool(ptr, kmemcpywrap,
793							poolname, opts,
794							pool_fields);
795				}
796			}
797			role = IPL_LOGALL;
798		}
799	}
800	if (type == IPLT_ALL || type == IPLT_HASH) {
801		iphtable_t *tables[IPL_LOGSIZE];
802		struct nlist names[2] = { { "ipf_htables" } , { "" } };
803
804		if (nlist(kernel, names) != 1)
805			return;
806
807		bzero(&tables, sizeof(tables));
808		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
809			return;
810
811		if (role != IPL_LOGALL) {
812			hptr = tables[role];
813			while (hptr != NULL) {
814				hptr = printhash(hptr, kmemcpywrap,
815						 poolname, opts, pool_fields);
816			}
817		} else {
818			for (role = 0; role <= IPL_LOGMAX; role++) {
819				hptr = tables[role];
820				while (hptr != NULL) {
821					hptr = printhash(hptr, kmemcpywrap,
822							 poolname, opts,
823							 pool_fields);
824				}
825			}
826		}
827	}
828}
829
830
831void
832poollist_live(role, poolname, type, fd)
833	int role, type, fd;
834	char *poolname;
835{
836	ipf_pool_stat_t plstat;
837	iplookupop_t op;
838	int c;
839
840	if (type == IPLT_ALL || type == IPLT_POOL) {
841		op.iplo_type = IPLT_POOL;
842		op.iplo_size = sizeof(plstat);
843		op.iplo_struct = &plstat;
844		op.iplo_name[0] = '\0';
845		op.iplo_arg = 0;
846
847		if (role != IPL_LOGALL) {
848			op.iplo_unit = role;
849
850			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
851			if (c == -1) {
852				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
853				return;
854			}
855
856			showpools_live(fd, role, &plstat, poolname);
857		} else {
858			for (role = -1; role <= IPL_LOGMAX; role++) {
859				op.iplo_unit = role;
860
861				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
862				if (c == -1) {
863					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
864					return;
865				}
866
867				showpools_live(fd, role, &plstat, poolname);
868			}
869
870			role = IPL_LOGALL;
871		}
872	}
873
874	if (type == IPLT_ALL || type == IPLT_HASH) {
875		iphtstat_t htstat;
876
877		op.iplo_type = IPLT_HASH;
878		op.iplo_size = sizeof(htstat);
879		op.iplo_struct = &htstat;
880		op.iplo_name[0] = '\0';
881		op.iplo_arg = 0;
882
883		if (role != IPL_LOGALL) {
884			op.iplo_unit = role;
885
886			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
887			if (c == -1) {
888				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
889				return;
890			}
891			showhashs_live(fd, role, &htstat, poolname);
892		} else {
893			for (role = 0; role <= IPL_LOGMAX; role++) {
894
895				op.iplo_unit = role;
896				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
897				if (c == -1) {
898					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
899					return;
900				}
901
902				showhashs_live(fd, role, &htstat, poolname);
903			}
904			role = IPL_LOGALL;
905		}
906	}
907
908	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
909		ipf_dstl_stat_t dlstat;
910
911		op.iplo_type = IPLT_DSTLIST;
912		op.iplo_size = sizeof(dlstat);
913		op.iplo_struct = &dlstat;
914		op.iplo_name[0] = '\0';
915		op.iplo_arg = 0;
916
917		if (role != IPL_LOGALL) {
918			op.iplo_unit = role;
919
920			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
921			if (c == -1) {
922				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
923				return;
924			}
925			showdstls_live(fd, role, &dlstat, poolname);
926		} else {
927			for (role = 0; role <= IPL_LOGMAX; role++) {
928
929				op.iplo_unit = role;
930				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
931				if (c == -1) {
932					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
933					return;
934				}
935
936				showdstls_live(fd, role, &dlstat, poolname);
937			}
938			role = IPL_LOGALL;
939		}
940	}
941}
942
943
944void
945showpools_live(fd, role, plstp, poolname)
946	int fd, role;
947	ipf_pool_stat_t *plstp;
948	char *poolname;
949{
950	ipflookupiter_t iter;
951	ip_pool_t pool;
952	ipfobj_t obj;
953
954	obj.ipfo_rev = IPFILTER_VERSION;
955	obj.ipfo_type = IPFOBJ_LOOKUPITER;
956	obj.ipfo_size = sizeof(iter);
957	obj.ipfo_ptr = &iter;
958
959	iter.ili_type = IPLT_POOL;
960	iter.ili_otype = IPFLOOKUPITER_LIST;
961	iter.ili_ival = IPFGENITER_LOOKUP;
962	iter.ili_nitems = 1;
963	iter.ili_data = &pool;
964	iter.ili_unit = role;
965	*iter.ili_name = '\0';
966
967	bzero((char *)&pool, sizeof(pool));
968
969	while (plstp->ipls_list[role + 1] != NULL) {
970		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
971			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
972			break;
973		}
974		if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
975		    ((opts & OPT_DEBUG) != 0))
976			printpool_live(&pool, fd, poolname, opts, pool_fields);
977
978		plstp->ipls_list[role + 1] = pool.ipo_next;
979	}
980}
981
982
983void
984showhashs_live(fd, role, htstp, poolname)
985	int fd, role;
986	iphtstat_t *htstp;
987	char *poolname;
988{
989	ipflookupiter_t iter;
990	iphtable_t table;
991	ipfobj_t obj;
992
993	obj.ipfo_rev = IPFILTER_VERSION;
994	obj.ipfo_type = IPFOBJ_LOOKUPITER;
995	obj.ipfo_size = sizeof(iter);
996	obj.ipfo_ptr = &iter;
997
998	iter.ili_type = IPLT_HASH;
999	iter.ili_otype = IPFLOOKUPITER_LIST;
1000	iter.ili_ival = IPFGENITER_LOOKUP;
1001	iter.ili_nitems = 1;
1002	iter.ili_data = &table;
1003	iter.ili_unit = role;
1004	*iter.ili_name = '\0';
1005
1006	while (htstp->iphs_tables != NULL) {
1007		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1008			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1009			break;
1010		}
1011
1012		printhash_live(&table, fd, poolname, opts, pool_fields);
1013
1014		htstp->iphs_tables = table.iph_next;
1015	}
1016}
1017
1018
1019void
1020showdstls_live(fd, role, dlstp, poolname)
1021	int fd, role;
1022	ipf_dstl_stat_t *dlstp;
1023	char *poolname;
1024{
1025	ipflookupiter_t iter;
1026	ippool_dst_t table;
1027	ipfobj_t obj;
1028
1029	obj.ipfo_rev = IPFILTER_VERSION;
1030	obj.ipfo_type = IPFOBJ_LOOKUPITER;
1031	obj.ipfo_size = sizeof(iter);
1032	obj.ipfo_ptr = &iter;
1033
1034	iter.ili_type = IPLT_DSTLIST;
1035	iter.ili_otype = IPFLOOKUPITER_LIST;
1036	iter.ili_ival = IPFGENITER_LOOKUP;
1037	iter.ili_nitems = 1;
1038	iter.ili_data = &table;
1039	iter.ili_unit = role;
1040	*iter.ili_name = '\0';
1041
1042	while (dlstp->ipls_list[role] != NULL) {
1043		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1044			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1045			break;
1046		}
1047
1048		printdstl_live(&table, fd, poolname, opts, pool_fields);
1049
1050		dlstp->ipls_list[role] = table.ipld_next;
1051	}
1052}
1053
1054
1055int
1056setnodeaddr(int type, int role, void *ptr, char *arg)
1057{
1058	struct in_addr mask;
1059	char *s;
1060
1061	s = strchr(arg, '/');
1062	if (s == NULL)
1063		mask.s_addr = 0xffffffff;
1064	else if (strchr(s, '.') == NULL) {
1065		if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
1066			return -1;
1067	} else {
1068		mask.s_addr = inet_addr(s + 1);
1069	}
1070	if (s != NULL)
1071		*s = '\0';
1072
1073	if (type == IPLT_POOL) {
1074		ip_pool_node_t *node = ptr;
1075
1076#ifdef USE_INET6
1077		if (node->ipn_addr.adf_family == AF_INET)
1078#endif
1079			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1080							  adf_addr) +
1081						 sizeof(struct in_addr);
1082#ifdef USE_INET6
1083		else
1084			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1085							  adf_addr) +
1086						 sizeof(struct in6_addr);
1087#endif
1088		node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
1089		node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1090		node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1091	} else if (type == IPLT_HASH) {
1092		iphtent_t *node = ptr;
1093
1094		node->ipe_addr.in4.s_addr = inet_addr(arg);
1095		node->ipe_mask.in4.s_addr = mask.s_addr;
1096        	node->ipe_family = AF_INET;
1097        	node->ipe_unit = role;
1098	}
1099
1100	return 0;
1101}
1102