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