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