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