1/*
2 * Copyright (C) 2003 by Darren Reed.
3 *
4 * See the IPFILTER.LICENCE file for details on licencing.
5 *
6 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
7 * Use is subject to license terms.
8 *
9 * Copyright (c) 2014, Joyent, Inc.  All rights reserved.
10 * Copyright 2017 Gary Mills
11 */
12
13#include <sys/types.h>
14#include <sys/time.h>
15#include <sys/param.h>
16#include <sys/socket.h>
17#if defined(BSD) && (BSD >= 199306)
18# include <sys/cdefs.h>
19#endif
20#include <sys/ioctl.h>
21
22#include <net/if.h>
23#if __FreeBSD_version >= 300000
24# include <net/if_var.h>
25#endif
26#include <netinet/in.h>
27
28#include <arpa/inet.h>
29
30#include <stdio.h>
31#include <fcntl.h>
32#include <stdlib.h>
33#include <string.h>
34#include <netdb.h>
35#include <ctype.h>
36#include <unistd.h>
37#include <nlist.h>
38
39#include "ipf.h"
40#include "netinet/ipl.h"
41#include "netinet/ip_lookup.h"
42#include "netinet/ip_pool.h"
43#include "netinet/ip_htable.h"
44#include "kmem.h"
45#include "ipfzone.h"
46
47extern	int	ippool_yyparse __P((void));
48extern	int	ippool_yydebug;
49extern	FILE	*ippool_yyin;
50extern	char	*optarg;
51extern	int	lineNum;
52
53void	showpools __P((ip_pool_stat_t *));
54void	usage __P((char *));
55int	main __P((int, char **));
56int	poolcommand __P((int, int, char *[]));
57int	poolnodecommand __P((int, int, char *[]));
58int	loadpoolfile __P((int, char *[], char *));
59int	poollist __P((int, char *[]));
60int	poolflush __P((int, char *[]));
61int	poolstats __P((int, char *[]));
62int	gettype __P((char *, u_int *));
63int	getrole __P((char *));
64void	poollist_dead __P((int, char *, int, char *, char *));
65void	showpools_live(int, int, ip_pool_stat_t *, char *, int);
66void	showhashs_live(int, int, iphtstat_t *, char *, int);
67
68int	opts = 0;
69int	fd = -1;
70int	use_inet6 = 0;
71
72
73void usage(prog)
74char *prog;
75{
76	const char *zoneopt = "[-G|-z zonename] ";
77	fprintf(stderr, "Usage:\t%s\n", prog);
78	fprintf(stderr, "\t\t\t-a [-dnv] %s[-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n",
79	    zoneopt);
80	fprintf(stderr, "\t\t\t-A [-dnv] %s[-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n",
81	    zoneopt);
82	fprintf(stderr, "\t\t\t-f <file> %s[-dnuv]\n", zoneopt);
83	fprintf(stderr, "\t\t\t-F [-dv] %s[-o <role>] [-t <type>]\n", zoneopt);
84	fprintf(stderr, "\t\t\t-l [-dv] %s[-m <name>] [-t <type>]\n", zoneopt);
85	fprintf(stderr, "\t\t\t-r [-dnv] %s[-m <name>] [-o <role>] -i <ipaddr>[/netmask]\n",
86	    zoneopt);
87	fprintf(stderr, "\t\t\t-R [-dnv] %s[-m <name>] [-o <role>] [-t <type>]\n",
88	    zoneopt);
89	fprintf(stderr, "\t\t\t-s [-dtv] %s[-M <core>] [-N <namelist>]\n",
90	    zoneopt);
91	exit(1);
92}
93
94
95int main(argc, argv)
96int argc;
97char *argv[];
98{
99	int err;
100
101	if (argc < 2)
102		usage(argv[0]);
103
104	switch (getopt(argc, argv, "aAf:FlrRs"))
105	{
106	case 'a' :
107		err = poolnodecommand(0, argc, argv);
108		break;
109	case 'A' :
110		err = poolcommand(0, argc, argv);
111		break;
112	case 'f' :
113		err = loadpoolfile(argc, argv, optarg);
114		break;
115	case 'F' :
116		err = poolflush(argc, argv);
117		break;
118	case 'l' :
119		err = poollist(argc, argv);
120		break;
121	case 'r' :
122		err = poolnodecommand(1, argc, argv);
123		break;
124	case 'R' :
125		err = poolcommand(1, argc, argv);
126		break;
127	case 's' :
128		err = poolstats(argc, argv);
129		break;
130	default :
131		exit(1);
132	}
133
134	return err;
135}
136
137
138int poolnodecommand(remove, argc, argv)
139int remove, argc;
140char *argv[];
141{
142	char *poolname = NULL, *s;
143	int err, c, ipset, role;
144	ip_pool_node_t node;
145	struct in_addr mask;
146
147	ipset = 0;
148	role = IPL_LOGIPF;
149	bzero((char *)&node, sizeof(node));
150
151	while ((c = getopt(argc, argv, "di:G:m:no:Rvz:")) != -1)
152		switch (c)
153		{
154		case 'd' :
155			opts |= OPT_DEBUG;
156			ippool_yydebug++;
157			break;
158		case 'G' :
159			setzonename_global(optarg);
160			break;
161		case 'i' :
162			s = strchr(optarg, '/');
163			if (s == NULL)
164				mask.s_addr = 0xffffffff;
165			else if (strchr(s, '.') == NULL) {
166				if (ntomask(4, atoi(s + 1), &mask.s_addr) != 0)
167					return -1;
168			} else {
169				mask.s_addr = inet_addr(s + 1);
170			}
171			if (s != NULL)
172				*s = '\0';
173			ipset = 1;
174			node.ipn_addr.adf_len = sizeof(node.ipn_addr);
175			node.ipn_addr.adf_addr.in4.s_addr = inet_addr(optarg);
176			node.ipn_mask.adf_len = sizeof(node.ipn_mask);
177			node.ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
178			break;
179		case 'm' :
180			poolname = optarg;
181			break;
182		case 'n' :
183			opts |= OPT_DONOTHING;
184			break;
185		case 'o' :
186			role = getrole(optarg);
187			if (role == IPL_LOGNONE)
188				return -1;
189			break;
190		case 'R' :
191			opts |= OPT_NORESOLVE;
192			break;
193		case 'v' :
194			opts |= OPT_VERBOSE;
195			break;
196		case 'z' :
197			setzonename(optarg);
198			break;
199		}
200
201	if (opts & OPT_DEBUG)
202		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
203
204	if (ipset == 0)
205		return -1;
206	if (poolname == NULL) {
207		fprintf(stderr, "poolname not given with add/remove node\n");
208		return -1;
209	}
210
211	if (remove == 0)
212		err = load_poolnode(0, poolname, &node, ioctl);
213	else
214		err = remove_poolnode(0, poolname, &node, ioctl);
215	return err;
216}
217
218
219int poolcommand(remove, argc, argv)
220int remove, argc;
221char *argv[];
222{
223	int type, role, c, err;
224	char *poolname;
225	iphtable_t iph;
226	ip_pool_t pool;
227
228	err = 1;
229	role = 0;
230	type = 0;
231	poolname = NULL;
232	role = IPL_LOGIPF;
233	bzero((char *)&iph, sizeof(iph));
234	bzero((char *)&pool, sizeof(pool));
235
236	while ((c = getopt(argc, argv, "dG:m:no:RS:t:vz:")) != -1)
237		switch (c)
238		{
239		case 'd' :
240			opts |= OPT_DEBUG;
241			ippool_yydebug++;
242			break;
243		case 'G' :
244			setzonename_global(optarg);
245			break;
246		case 'm' :
247			poolname = optarg;
248			break;
249		case 'n' :
250			opts |= OPT_DONOTHING;
251			break;
252		case 'o' :
253			role = getrole(optarg);
254			if (role == IPL_LOGNONE) {
255				fprintf(stderr, "unknown role '%s'\n", optarg);
256				return -1;
257			}
258			break;
259		case 'R' :
260			opts |= OPT_NORESOLVE;
261			break;
262		case 'S' :
263			iph.iph_seed = atoi(optarg);
264			break;
265		case 't' :
266			type = gettype(optarg, &iph.iph_type);
267			if (type == IPLT_NONE) {
268				fprintf(stderr, "unknown type '%s'\n", optarg);
269				return -1;
270			}
271			break;
272		case 'v' :
273			opts |= OPT_VERBOSE;
274			break;
275		case 'z' :
276			setzonename(optarg);
277			break;
278		}
279
280	if (opts & OPT_DEBUG)
281		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
282
283	if (poolname == NULL) {
284		fprintf(stderr, "poolname not given with add/remove pool\n");
285		return -1;
286	}
287
288	if (type == IPLT_HASH) {
289		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
290		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
291		iph.iph_unit = role;
292	} else if (type == IPLT_POOL) {
293		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
294		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
295		pool.ipo_unit = role;
296	}
297
298	if (remove == 0) {
299		switch (type)
300		{
301		case IPLT_HASH :
302			err = load_hash(&iph, NULL, ioctl);
303			break;
304		case IPLT_POOL :
305			err = load_pool(&pool, ioctl);
306			break;
307		}
308	} else {
309		switch (type)
310		{
311		case IPLT_HASH :
312			err = remove_hash(&iph, ioctl);
313			break;
314		case IPLT_POOL :
315			err = remove_pool(&pool, ioctl);
316			break;
317		}
318	}
319	return err;
320}
321
322
323int loadpoolfile(argc, argv, infile)
324int argc;
325char *argv[], *infile;
326{
327	int c;
328
329	infile = optarg;
330
331	while ((c = getopt(argc, argv, "dG:nRuvz:")) != -1)
332		switch (c)
333		{
334		case 'd' :
335			opts |= OPT_DEBUG;
336			ippool_yydebug++;
337			break;
338		case 'G' :
339			setzonename_global(optarg);
340			break;
341		case 'n' :
342			opts |= OPT_DONOTHING;
343			break;
344		case 'R' :
345			opts |= OPT_NORESOLVE;
346			break;
347		case 'u' :
348			opts |= OPT_REMOVE;
349			break;
350		case 'v' :
351			opts |= OPT_VERBOSE;
352			break;
353		case 'z' :
354			setzonename(optarg);
355			break;
356		}
357
358	if (opts & OPT_DEBUG)
359		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
360
361	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
362		fd = open(IPLOOKUP_NAME, O_RDWR);
363		if (fd == -1) {
364			perror("open(IPLOOKUP_NAME)");
365			exit(1);
366		}
367
368		if (setzone(fd) != 0) {
369			close(fd);
370			exit(1);
371		}
372	}
373
374	if (ippool_parsefile(fd, infile, ioctl) != 0)
375		return -1;
376	return 0;
377}
378
379
380int poollist(argc, argv)
381int argc;
382char *argv[];
383{
384	char *kernel, *core, *poolname;
385	int c, role, type, live_kernel;
386	ip_pool_stat_t  plstat;
387	iphtstat_t  htstat;
388	iphtable_t *hptr;
389	iplookupop_t op;
390	ip_pool_t *ptr;
391
392	core = NULL;
393	kernel = NULL;
394	live_kernel = 1;
395	type = IPLT_ALL;
396	poolname = NULL;
397	role = IPL_LOGALL;
398
399	while ((c = getopt(argc, argv, "dG:m:M:N:o:Rt:vz:")) != -1)
400		switch (c)
401		{
402		case 'd' :
403			opts |= OPT_DEBUG;
404			break;
405		case 'G' :
406			setzonename_global(optarg);
407			break;
408		case 'm' :
409			poolname = optarg;
410			break;
411		case 'M' :
412			live_kernel = 0;
413			core = optarg;
414			break;
415		case 'N' :
416			live_kernel = 0;
417			kernel = optarg;
418			break;
419		case 'o' :
420			role = getrole(optarg);
421			if (role == IPL_LOGNONE) {
422				fprintf(stderr, "unknown role '%s'\n", optarg);
423				return -1;
424			}
425			break;
426		case 'R' :
427			opts |= OPT_NORESOLVE;
428			break;
429		case 't' :
430			type = gettype(optarg, NULL);
431			if (type == IPLT_NONE) {
432				fprintf(stderr, "unknown type '%s'\n", optarg);
433				return -1;
434			}
435			break;
436		case 'v' :
437			opts |= OPT_VERBOSE;
438			break;
439		case 'z' :
440			setzonename(optarg);
441			break;
442		}
443
444	if (opts & OPT_DEBUG)
445		fprintf(stderr, "poollist: opts = %#x\n", opts);
446
447	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
448		fd = open(IPLOOKUP_NAME, O_RDWR);
449		if (fd == -1) {
450			perror("open(IPLOOKUP_NAME)");
451			exit(1);
452		}
453
454		if (setzone(fd) != 0) {
455			close(fd);
456			exit(1);
457		}
458	}
459
460	bzero((char *)&op, sizeof(op));
461	if (poolname != NULL) {
462		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
463		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
464	}
465	op.iplo_unit = role;
466
467	if (live_kernel == 0) {
468		poollist_dead(role, poolname, type, kernel, core);
469		return (0);
470	}
471
472	if (type == IPLT_ALL || type == IPLT_POOL) {
473		op.iplo_type = IPLT_POOL;
474		op.iplo_size = sizeof(plstat);
475		op.iplo_struct = &plstat;
476		op.iplo_name[0] = '\0';
477		op.iplo_arg = 0;
478
479		if (role != IPL_LOGALL) {
480			op.iplo_unit = role;
481
482			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
483			if (c == -1) {
484				perror("ioctl(SIOCLOOKUPSTAT)");
485				return -1;
486			}
487
488			showpools_live(fd, role, &plstat, poolname, opts);
489		} else {
490			for (role = 0; role <= IPL_LOGMAX; role++) {
491				op.iplo_unit = role;
492
493				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
494				if (c == -1) {
495					perror("ioctl(SIOCLOOKUPSTAT)");
496					return -1;
497				}
498
499				showpools_live(fd, role, &plstat, poolname, opts);
500			}
501
502			role = IPL_LOGALL;
503		}
504	}
505	if (type == IPLT_ALL || type == IPLT_HASH) {
506		op.iplo_type = IPLT_HASH;
507		op.iplo_size = sizeof(htstat);
508		op.iplo_struct = &htstat;
509		op.iplo_name[0] = '\0';
510		op.iplo_arg = 0;
511
512		if (role != IPL_LOGALL) {
513			op.iplo_unit = role;
514
515			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
516			if (c == -1) {
517				perror("ioctl(SIOCLOOKUPSTAT)");
518				return -1;
519			}
520			showhashs_live(fd, role, &htstat, poolname, opts);
521		} else {
522			for (role = 0; role <= IPL_LOGMAX; role++) {
523
524				op.iplo_unit = role;
525				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
526				if (c == -1) {
527					perror("ioctl(SIOCLOOKUPSTAT)");
528					return -1;
529				}
530
531				showhashs_live(fd, role, &htstat, poolname, opts);
532			}
533		}
534	}
535	return 0;
536}
537
538void poollist_dead(role, poolname, type, kernel, core)
539int role, type;
540char *poolname, *kernel, *core;
541{
542	iphtable_t *hptr;
543	ip_pool_t *ptr;
544
545	if (openkmem(kernel, core) == -1)
546		exit(-1);
547
548	if (type == IPLT_ALL || type == IPLT_POOL) {
549		ip_pool_t *pools[IPL_LOGSIZE];
550		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
551
552		if (nlist(kernel, names) != 1)
553			return;
554
555		bzero(&pools, sizeof(pools));
556		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
557			return;
558
559		if (role != IPL_LOGALL) {
560			ptr = pools[role];
561			while (ptr != NULL) {
562				ptr = printpool(ptr, kmemcpywrap,
563						poolname, opts);
564			}
565		} else {
566			for (role = 0; role <= IPL_LOGMAX; role++) {
567				ptr = pools[role];
568				while (ptr != NULL) {
569					ptr = printpool(ptr, kmemcpywrap,
570							poolname, opts);
571				}
572			}
573			role = IPL_LOGALL;
574		}
575	}
576	if (type == IPLT_ALL || type == IPLT_HASH) {
577		iphtable_t *tables[IPL_LOGSIZE];
578		struct nlist names[2] = { { "ipf_htables" } , { "" } };
579
580		if (nlist(kernel, names) != 1)
581			return;
582
583		bzero(&tables, sizeof(tables));
584		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
585			return;
586
587		if (role != IPL_LOGALL) {
588			hptr = tables[role];
589			while (hptr != NULL) {
590				hptr = printhash(hptr, kmemcpywrap,
591						 poolname, opts);
592			}
593		} else {
594			for (role = 0; role <= IPL_LOGMAX; role++) {
595				hptr = tables[role];
596				while (hptr != NULL) {
597					hptr = printhash(hptr, kmemcpywrap,
598							 poolname, opts);
599				}
600			}
601		}
602	}
603}
604
605
606void
607showpools_live(fd, role, plstp, poolname, opts)
608int fd, role;
609ip_pool_stat_t *plstp;
610char *poolname;
611int opts;
612{
613	ipflookupiter_t iter;
614	ip_pool_t pool;
615	ipfobj_t obj;
616
617	obj.ipfo_rev = IPFILTER_VERSION;
618	obj.ipfo_type = IPFOBJ_LOOKUPITER;
619	obj.ipfo_size = sizeof(iter);
620	obj.ipfo_ptr = &iter;
621
622	iter.ili_type = IPLT_POOL;
623	iter.ili_otype = IPFLOOKUPITER_LIST;
624	iter.ili_ival = IPFGENITER_LOOKUP;
625	iter.ili_data = &pool;
626	iter.ili_unit = role;
627	*iter.ili_name = '\0';
628
629	while (plstp->ipls_list[role] != NULL) {
630		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
631			perror("ioctl(SIOCLOOKUPITER)");
632			break;
633		}
634		(void) printpool_live(&pool, fd, poolname, opts);
635
636		plstp->ipls_list[role] = pool.ipo_next;
637	}
638}
639
640int poolstats(argc, argv)
641int argc;
642char *argv[];
643{
644	int c, type, role;
645	ip_pool_stat_t plstat;
646	iphtstat_t htstat;
647	iplookupop_t op;
648
649	type = IPLT_ALL;
650	role = IPL_LOGALL;
651
652	bzero((char *)&op, sizeof(op));
653
654	while ((c = getopt(argc, argv, "dG:M:N:o:t:vz:")) != -1)
655		switch (c)
656		{
657		case 'd' :
658			opts |= OPT_DEBUG;
659			break;
660		case 'G' :
661			setzonename_global(optarg);
662			break;
663		case 'M' :
664			break;
665		case 'N' :
666			break;
667		case 'o' :
668			role = getrole(optarg);
669			if (role == IPL_LOGNONE) {
670				fprintf(stderr, "unknown role '%s'\n", optarg);
671				return -1;
672			}
673			break;
674		case 't' :
675			type = gettype(optarg, NULL);
676			if (type != IPLT_POOL) {
677				fprintf(stderr,
678					"-s not supported for this type yet\n");
679				return -1;
680			}
681			break;
682		case 'v' :
683			opts |= OPT_VERBOSE;
684			break;
685		case 'z' :
686			setzonename(optarg);
687			break;
688		}
689
690	if (opts & OPT_DEBUG)
691		fprintf(stderr, "poolstats: opts = %#x\n", opts);
692
693	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
694		fd = open(IPLOOKUP_NAME, O_RDWR);
695		if (fd == -1) {
696			perror("open(IPLOOKUP_NAME)");
697			exit(1);
698		}
699
700		if (setzone(fd) != 0) {
701			close(fd);
702			exit(1);
703		}
704	}
705
706	if (type == IPLT_ALL || type == IPLT_POOL) {
707		op.iplo_type = IPLT_POOL;
708		op.iplo_struct = &plstat;
709		op.iplo_size = sizeof(plstat);
710		if (!(opts & OPT_DONOTHING)) {
711			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
712			if (c == -1) {
713				perror("ioctl(SIOCLOOKUPSTAT)");
714				return -1;
715			}
716			printf("Pools:\t%lu\n", plstat.ipls_pools);
717			printf("Nodes:\t%lu\n", plstat.ipls_nodes);
718		}
719	}
720
721	if (type == IPLT_ALL || type == IPLT_HASH) {
722		op.iplo_type = IPLT_HASH;
723		op.iplo_struct = &htstat;
724		op.iplo_size = sizeof(htstat);
725		if (!(opts & OPT_DONOTHING)) {
726			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
727			if (c == -1) {
728				perror("ioctl(SIOCLOOKUPSTAT)");
729				return -1;
730			}
731			printf("Hash Tables:\t%lu\n", htstat.iphs_numtables);
732			printf("Nodes:\t%lu\n", htstat.iphs_numnodes);
733			printf("Out of Memory:\t%lu\n", htstat.iphs_nomem);
734		}
735	}
736	return 0;
737}
738
739
740int poolflush(argc, argv)
741int argc;
742char *argv[];
743{
744	int c, role, type, arg;
745	iplookupflush_t flush;
746
747	arg = IPLT_ALL;
748	type = IPLT_ALL;
749	role = IPL_LOGALL;
750
751	while ((c = getopt(argc, argv, "do:t:vz:")) != -1)
752		switch (c)
753		{
754		case 'd' :
755			opts |= OPT_DEBUG;
756			break;
757		case 'o' :
758			role = getrole(optarg);
759			if (role == IPL_LOGNONE) {
760				fprintf(stderr, "unknown role '%s'\n", optarg);
761				return -1;
762			}
763			break;
764		case 't' :
765			type = gettype(optarg, NULL);
766			if (type == IPLT_NONE) {
767				fprintf(stderr, "unknown type '%s'\n", optarg);
768				return -1;
769			}
770			break;
771		case 'v' :
772			opts |= OPT_VERBOSE;
773			break;
774		case 'z' :
775			setzonename(optarg);
776			break;
777		}
778
779	if (opts & OPT_DEBUG)
780		fprintf(stderr, "poolflush: opts = %#x\n", opts);
781
782	if (!(opts & OPT_DONOTHING) && (fd == -1)) {
783		fd = open(IPLOOKUP_NAME, O_RDWR);
784		if (fd == -1) {
785			perror("open(IPLOOKUP_NAME)");
786			exit(1);
787		}
788
789		if (setzone(fd) != 0) {
790			close(fd);
791			exit(1);
792		}
793	}
794
795	bzero((char *)&flush, sizeof(flush));
796	flush.iplf_type = type;
797	flush.iplf_unit = role;
798	flush.iplf_arg = arg;
799
800	if (!(opts & OPT_DONOTHING)) {
801		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
802			perror("ioctl(SIOCLOOKUPFLUSH)");
803			exit(1);
804		}
805
806	}
807	printf("%u object%s flushed\n", flush.iplf_count,
808	       (flush.iplf_count == 1) ? "" : "s");
809
810	return 0;
811}
812
813
814int getrole(rolename)
815char *rolename;
816{
817	int role;
818
819	if (!strcasecmp(rolename, "ipf")) {
820		role = IPL_LOGIPF;
821#if 0
822	} else if (!strcasecmp(rolename, "nat")) {
823		role = IPL_LOGNAT;
824	} else if (!strcasecmp(rolename, "state")) {
825		role = IPL_LOGSTATE;
826	} else if (!strcasecmp(rolename, "auth")) {
827		role = IPL_LOGAUTH;
828	} else if (!strcasecmp(rolename, "sync")) {
829		role = IPL_LOGSYNC;
830	} else if (!strcasecmp(rolename, "scan")) {
831		role = IPL_LOGSCAN;
832	} else if (!strcasecmp(rolename, "pool")) {
833		role = IPL_LOGLOOKUP;
834	} else if (!strcasecmp(rolename, "count")) {
835		role = IPL_LOGCOUNT;
836#endif
837	} else {
838		role = IPL_LOGNONE;
839	}
840
841	return role;
842}
843
844
845int gettype(typename, minor)
846char *typename;
847u_int *minor;
848{
849	int type;
850
851	if (!strcasecmp(optarg, "tree")) {
852		type = IPLT_POOL;
853	} else if (!strcasecmp(optarg, "hash")) {
854		type = IPLT_HASH;
855		if (minor != NULL)
856			*minor = IPHASH_LOOKUP;
857	} else if (!strcasecmp(optarg, "group-map")) {
858		type = IPLT_HASH;
859		if (minor != NULL)
860			*minor = IPHASH_GROUPMAP;
861	} else {
862		type = IPLT_NONE;
863	}
864	return type;
865}
866
867void showhashs_live(fd, role, htstp, poolname, opts)
868int fd, role;
869iphtstat_t *htstp;
870char *poolname;
871int opts;
872{
873	ipflookupiter_t iter;
874	iphtable_t table;
875	ipfobj_t obj;
876
877	obj.ipfo_rev = IPFILTER_VERSION;
878	obj.ipfo_type = IPFOBJ_LOOKUPITER;
879	obj.ipfo_size = sizeof(iter);
880	obj.ipfo_ptr = &iter;
881
882	iter.ili_type = IPLT_HASH;
883	iter.ili_otype = IPFLOOKUPITER_LIST;
884	iter.ili_ival = IPFGENITER_LOOKUP;
885	iter.ili_data = &table;
886	iter.ili_unit = role;
887	*iter.ili_name = '\0';
888
889	while (htstp->iphs_tables != NULL) {
890		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
891			perror("ioctl(SIOCLOOKUPITER)");
892			break;
893		}
894
895		printhash_live(&table, fd, poolname, opts);
896
897		htstp->iphs_tables = table.iph_next;
898	}
899}
900