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