xref: /netbsd-src/external/bsd/ipf/dist/tools/ippool.c (revision 64a05fe87b1061240121b2919b3f1dcb35684da5)
1 /*	$NetBSD: ippool.c,v 1.4 2013/10/20 03:09:11 christos 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
usage(prog)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
main(argc,argv)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
poolnodecommand(remove,argc,argv)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
poolcommand(remove,argc,argv)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
loadpoolfile(argc,argv,infile)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
poolstats(argc,argv)408 poolstats(argc, argv)
409 	int argc;
410 	char *argv[];
411 {
412 	int c, type, role;
413 	ipf_pool_stat_t plstat;
414 	ipf_dstl_stat_t dlstat;
415 	iphtstat_t htstat;
416 	iplookupop_t op;
417 
418 	type = IPLT_ALL;
419 	role = IPL_LOGALL;
420 
421 	bzero((char *)&op, sizeof(op));
422 
423 	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
424 		switch (c)
425 		{
426 		case 'd' :
427 			opts |= OPT_DEBUG;
428 			break;
429 		case 'M' :
430 			break;
431 		case 'N' :
432 			break;
433 		case 'o' :
434 			role = getrole(optarg);
435 			if (role == IPL_LOGNONE) {
436 				fprintf(stderr, "unknown role '%s'\n", optarg);
437 				return -1;
438 			}
439 			break;
440 		case 't' :
441 			type = gettype(optarg, NULL);
442 			if (type != IPLT_POOL) {
443 				fprintf(stderr,
444 					"-s not supported for this type yet\n");
445 				return -1;
446 			}
447 			break;
448 		case 'v' :
449 			opts |= OPT_VERBOSE;
450 			break;
451 		}
452 
453 	if (opts & OPT_DEBUG)
454 		fprintf(stderr, "poolstats: opts = %#x\n", opts);
455 
456 	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
457 		fd = open(IPLOOKUP_NAME, O_RDWR);
458 		if (fd == -1) {
459 			perror("open(IPLOOKUP_NAME)");
460 			exit(1);
461 		}
462 	}
463 
464 	if (type == IPLT_ALL || type == IPLT_POOL) {
465 		op.iplo_type = IPLT_POOL;
466 		op.iplo_struct = &plstat;
467 		op.iplo_size = sizeof(plstat);
468 		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
469 			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
470 			if (c == -1) {
471 				ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
472 				return -1;
473 			}
474 			printf("%lu\taddress pools\n", plstat.ipls_pools);
475 			printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
476 		}
477 	}
478 
479 	if (type == IPLT_ALL || type == IPLT_HASH) {
480 		op.iplo_type = IPLT_HASH;
481 		op.iplo_struct = &htstat;
482 		op.iplo_size = sizeof(htstat);
483 		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
484 			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
485 			if (c == -1) {
486 				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
487 				return -1;
488 			}
489 			printf("%lu\thash tables\n", htstat.iphs_numtables);
490 			printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
491 			printf("%lu\thash table no memory \n",
492 				htstat.iphs_nomem);
493 		}
494 	}
495 
496 	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
497 		op.iplo_type = IPLT_DSTLIST;
498 		op.iplo_struct = &dlstat;
499 		op.iplo_size = sizeof(dlstat);
500 		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
501 			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
502 			if (c == -1) {
503 				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
504 				return -1;
505 			}
506 			printf("%u\tdestination lists\n",
507 			       dlstat.ipls_numlists);
508 			printf("%u\tdestination list nodes\n",
509 			       dlstat.ipls_numnodes);
510 			printf("%lu\tdestination list no memory\n",
511 			       dlstat.ipls_nomem);
512 			printf("%u\tdestination list zombies\n",
513 			       dlstat.ipls_numdereflists);
514 			printf("%u\tdesetination list node zombies\n",
515 			       dlstat.ipls_numderefnodes);
516 		}
517 	}
518 	return 0;
519 }
520 
521 
522 int
poolflush(argc,argv)523 poolflush(argc, argv)
524 	int argc;
525 	char *argv[];
526 {
527 	int c, role, type, arg;
528 	iplookupflush_t flush;
529 
530 	arg = IPLT_ALL;
531 	type = IPLT_ALL;
532 	role = IPL_LOGALL;
533 
534 	while ((c = getopt(argc, argv, "do:t:v")) != -1)
535 		switch (c)
536 		{
537 		case 'd' :
538 			opts |= OPT_DEBUG;
539 			break;
540 		case 'o' :
541 			role = getrole(optarg);
542 			if (role == IPL_LOGNONE) {
543 				fprintf(stderr, "unknown role '%s'\n", optarg);
544 				return -1;
545 			}
546 			break;
547 		case 't' :
548 			type = gettype(optarg, NULL);
549 			if (type == IPLT_NONE) {
550 				fprintf(stderr, "unknown type '%s'\n", optarg);
551 				return -1;
552 			}
553 			break;
554 		case 'v' :
555 			opts |= OPT_VERBOSE;
556 			break;
557 		}
558 
559 	if (opts & OPT_DEBUG)
560 		fprintf(stderr, "poolflush: opts = %#x\n", opts);
561 
562 	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
563 		fd = open(IPLOOKUP_NAME, O_RDWR);
564 		if (fd == -1) {
565 			perror("open(IPLOOKUP_NAME)");
566 			exit(1);
567 		}
568 	}
569 
570 	bzero((char *)&flush, sizeof(flush));
571 	flush.iplf_type = type;
572 	flush.iplf_unit = role;
573 	flush.iplf_arg = arg;
574 
575 	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
576 		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
577 			ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
578 			exit(1);
579 		}
580 
581 	}
582 	printf("%u object%s flushed\n", flush.iplf_count,
583 	       (flush.iplf_count == 1) ? "" : "s");
584 
585 	return 0;
586 }
587 
588 
589 int
getrole(rolename)590 getrole(rolename)
591 	char *rolename;
592 {
593 	int role;
594 
595 	if (!strcasecmp(rolename, "ipf")) {
596 		role = IPL_LOGIPF;
597 #if 0
598 	} else if (!strcasecmp(rolename, "nat")) {
599 		role = IPL_LOGNAT;
600 	} else if (!strcasecmp(rolename, "state")) {
601 		role = IPL_LOGSTATE;
602 	} else if (!strcasecmp(rolename, "auth")) {
603 		role = IPL_LOGAUTH;
604 	} else if (!strcasecmp(rolename, "sync")) {
605 		role = IPL_LOGSYNC;
606 	} else if (!strcasecmp(rolename, "scan")) {
607 		role = IPL_LOGSCAN;
608 	} else if (!strcasecmp(rolename, "pool")) {
609 		role = IPL_LOGLOOKUP;
610 	} else if (!strcasecmp(rolename, "count")) {
611 		role = IPL_LOGCOUNT;
612 #endif
613 	} else {
614 		role = IPL_LOGNONE;
615 	}
616 
617 	return role;
618 }
619 
620 
621 int
gettype(typename,minor)622 gettype(typename, minor)
623 	char *typename;
624 	u_int *minor;
625 {
626 	int type;
627 
628 	if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
629 		type = IPLT_POOL;
630 	} else if (!strcasecmp(typename, "hash")) {
631 		type = IPLT_HASH;
632 		if (minor != NULL)
633 			*minor = IPHASH_LOOKUP;
634 	} else if (!strcasecmp(typename, "group-map")) {
635 		type = IPLT_HASH;
636 		if (minor != NULL)
637 			*minor = IPHASH_GROUPMAP;
638 	} else {
639 		type = IPLT_NONE;
640 	}
641 	return type;
642 }
643 
644 
645 int
poollist(argc,argv)646 poollist(argc, argv)
647 	int argc;
648 	char *argv[];
649 {
650 	char *kernel, *core, *poolname;
651 	int c, role, type, live_kernel;
652 	iplookupop_t op;
653 
654 	core = NULL;
655 	kernel = NULL;
656 	live_kernel = 1;
657 	type = IPLT_ALL;
658 	poolname = NULL;
659 	role = IPL_LOGALL;
660 
661 	while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
662 		switch (c)
663 		{
664 		case 'd' :
665 			opts |= OPT_DEBUG;
666 			break;
667 		case 'm' :
668 			poolname = optarg;
669 			break;
670 		case 'M' :
671 			live_kernel = 0;
672 			core = optarg;
673 			break;
674 		case 'N' :
675 			live_kernel = 0;
676 			kernel = optarg;
677 			break;
678 		case 'o' :
679 			role = getrole(optarg);
680 			if (role == IPL_LOGNONE) {
681 				fprintf(stderr, "unknown role '%s'\n", optarg);
682 				return -1;
683 			}
684 			break;
685 		case 'O' :
686 			pool_fields = parsefields(poolfields, optarg);
687 			break;
688 		case 'R' :
689 			opts |= OPT_NORESOLVE;
690 			break;
691 		case 't' :
692 			type = gettype(optarg, NULL);
693 			if (type == IPLT_NONE) {
694 				fprintf(stderr, "unknown type '%s'\n", optarg);
695 				return -1;
696 			}
697 			break;
698 		case 'v' :
699 			opts |= OPT_VERBOSE;
700 			break;
701 		}
702 
703 	if (opts & OPT_DEBUG)
704 		fprintf(stderr, "poollist: opts = %#x\n", opts);
705 
706 	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
707 		fd = open(IPLOOKUP_NAME, O_RDWR);
708 		if (fd == -1) {
709 			perror("open(IPLOOKUP_NAME)");
710 			exit(1);
711 		}
712 	}
713 
714 	bzero((char *)&op, sizeof(op));
715 	if (poolname != NULL) {
716 		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
717 		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
718 	}
719 	op.iplo_unit = role;
720 
721 	if (live_kernel)
722 		poollist_live(role, poolname, type, fd);
723 	else
724 		poollist_dead(role, poolname, type, kernel, core);
725 	return 0;
726 }
727 
728 
729 void
poollist_dead(role,poolname,type,kernel,core)730 poollist_dead(role, poolname, type, kernel, core)
731 	int role, type;
732 	char *poolname, *kernel, *core;
733 {
734 	iphtable_t *hptr;
735 	ip_pool_t *ptr;
736 
737 	if (openkmem(kernel, core) == -1)
738 		exit(-1);
739 
740 	if (type == IPLT_ALL || type == IPLT_POOL) {
741 		ip_pool_t *pools[IPL_LOGSIZE];
742 		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
743 
744 		if (nlist(kernel, names) != 1)
745 			return;
746 
747 		bzero(&pools, sizeof(pools));
748 		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
749 			return;
750 
751 		if (role != IPL_LOGALL) {
752 			ptr = pools[role];
753 			while (ptr != NULL) {
754 				ptr = printpool(ptr, kmemcpywrap, poolname,
755 						opts, pool_fields);
756 			}
757 		} else {
758 			for (role = 0; role <= IPL_LOGMAX; role++) {
759 				ptr = pools[role];
760 				while (ptr != NULL) {
761 					ptr = printpool(ptr, kmemcpywrap,
762 							poolname, opts,
763 							pool_fields);
764 				}
765 			}
766 			role = IPL_LOGALL;
767 		}
768 	}
769 	if (type == IPLT_ALL || type == IPLT_HASH) {
770 		iphtable_t *tables[IPL_LOGSIZE];
771 		struct nlist names[2] = { { "ipf_htables" } , { "" } };
772 
773 		if (nlist(kernel, names) != 1)
774 			return;
775 
776 		bzero(&tables, sizeof(tables));
777 		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
778 			return;
779 
780 		if (role != IPL_LOGALL) {
781 			hptr = tables[role];
782 			while (hptr != NULL) {
783 				hptr = printhash(hptr, kmemcpywrap,
784 						 poolname, opts, pool_fields);
785 			}
786 		} else {
787 			for (role = 0; role <= IPL_LOGMAX; role++) {
788 				hptr = tables[role];
789 				while (hptr != NULL) {
790 					hptr = printhash(hptr, kmemcpywrap,
791 							 poolname, opts,
792 							 pool_fields);
793 				}
794 			}
795 		}
796 	}
797 }
798 
799 
800 void
poollist_live(role,poolname,type,fd)801 poollist_live(role, poolname, type, fd)
802 	int role, type, fd;
803 	char *poolname;
804 {
805 	ipf_pool_stat_t plstat;
806 	iplookupop_t op;
807 	int unit;
808 	int c;
809 
810 	if (type == IPLT_ALL || type == IPLT_POOL) {
811 		op.iplo_type = IPLT_POOL;
812 		op.iplo_size = sizeof(plstat);
813 		op.iplo_struct = &plstat;
814 		op.iplo_name[0] = '\0';
815 		op.iplo_arg = 0;
816 
817 		if (role != IPL_LOGALL) {
818 			op.iplo_unit = role;
819 
820 			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
821 			if (c == -1) {
822 				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
823 				return;
824 			}
825 
826 			showpools_live(fd, role, &plstat, poolname);
827 		} else {
828 			for (unit = -1; unit <= IPL_LOGMAX; unit++) {
829 				op.iplo_unit = unit;
830 
831 				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
832 				if (c == -1) {
833 					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
834 					return;
835 				}
836 
837 				showpools_live(fd, unit, &plstat, poolname);
838 			}
839 		}
840 	}
841 
842 	if (type == IPLT_ALL || type == IPLT_HASH) {
843 		iphtstat_t htstat;
844 
845 		op.iplo_type = IPLT_HASH;
846 		op.iplo_size = sizeof(htstat);
847 		op.iplo_struct = &htstat;
848 		op.iplo_name[0] = '\0';
849 		op.iplo_arg = 0;
850 
851 		if (role != IPL_LOGALL) {
852 			op.iplo_unit = role;
853 
854 			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
855 			if (c == -1) {
856 				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
857 				return;
858 			}
859 			showhashs_live(fd, role, &htstat, poolname);
860 		} else {
861 			for (unit = 0; unit <= IPL_LOGMAX; unit++) {
862 
863 				op.iplo_unit = unit;
864 				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
865 				if (c == -1) {
866 					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
867 					return;
868 				}
869 
870 				showhashs_live(fd, unit, &htstat, poolname);
871 			}
872 		}
873 	}
874 
875 	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
876 		ipf_dstl_stat_t dlstat;
877 
878 		op.iplo_type = IPLT_DSTLIST;
879 		op.iplo_size = sizeof(dlstat);
880 		op.iplo_struct = &dlstat;
881 		op.iplo_name[0] = '\0';
882 		op.iplo_arg = 0;
883 
884 		if (role != IPL_LOGALL) {
885 			op.iplo_unit = role;
886 
887 			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
888 			if (c == -1) {
889 				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
890 				return;
891 			}
892 			showdstls_live(fd, role, &dlstat, poolname);
893 		} else {
894 			for (unit = 0; unit <= IPL_LOGMAX; unit++) {
895 
896 				op.iplo_unit = unit;
897 				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
898 				if (c == -1) {
899 					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
900 					return;
901 				}
902 
903 				showdstls_live(fd, unit, &dlstat, poolname);
904 			}
905 		}
906 	}
907 }
908 
909 
910 void
showpools_live(fd,role,plstp,poolname)911 showpools_live(fd, role, plstp, poolname)
912 	int fd, role;
913 	ipf_pool_stat_t *plstp;
914 	char *poolname;
915 {
916 	ipflookupiter_t iter;
917 	ip_pool_t pool;
918 	ipfobj_t obj;
919 
920 	obj.ipfo_rev = IPFILTER_VERSION;
921 	obj.ipfo_type = IPFOBJ_LOOKUPITER;
922 	obj.ipfo_size = sizeof(iter);
923 	obj.ipfo_ptr = &iter;
924 
925 	iter.ili_type = IPLT_POOL;
926 	iter.ili_otype = IPFLOOKUPITER_LIST;
927 	iter.ili_ival = IPFGENITER_LOOKUP;
928 	iter.ili_nitems = 1;
929 	iter.ili_data = &pool;
930 	iter.ili_unit = role;
931 	*iter.ili_name = '\0';
932 
933 	bzero((char *)&pool, sizeof(pool));
934 
935 	while (plstp->ipls_list[role + 1] != NULL) {
936 		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
937 			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
938 			break;
939 		}
940 		if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
941 		    ((opts & OPT_DEBUG) != 0))
942 			printpool_live(&pool, fd, poolname, opts, pool_fields);
943 
944 		plstp->ipls_list[role + 1] = pool.ipo_next;
945 	}
946 }
947 
948 
949 void
showhashs_live(fd,role,htstp,poolname)950 showhashs_live(fd, role, htstp, poolname)
951 	int fd, role;
952 	iphtstat_t *htstp;
953 	char *poolname;
954 {
955 	ipflookupiter_t iter;
956 	iphtable_t table;
957 	ipfobj_t obj;
958 
959 	obj.ipfo_rev = IPFILTER_VERSION;
960 	obj.ipfo_type = IPFOBJ_LOOKUPITER;
961 	obj.ipfo_size = sizeof(iter);
962 	obj.ipfo_ptr = &iter;
963 
964 	iter.ili_type = IPLT_HASH;
965 	iter.ili_otype = IPFLOOKUPITER_LIST;
966 	iter.ili_ival = IPFGENITER_LOOKUP;
967 	iter.ili_nitems = 1;
968 	iter.ili_data = &table;
969 	iter.ili_unit = role;
970 	*iter.ili_name = '\0';
971 
972 	while (htstp->iphs_tables != NULL) {
973 		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
974 			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
975 			break;
976 		}
977 
978 		printhash_live(&table, fd, poolname, opts, pool_fields);
979 
980 		htstp->iphs_tables = table.iph_next;
981 	}
982 }
983 
984 
985 void
showdstls_live(fd,role,dlstp,poolname)986 showdstls_live(fd, role, dlstp, poolname)
987 	int fd, role;
988 	ipf_dstl_stat_t *dlstp;
989 	char *poolname;
990 {
991 	ipflookupiter_t iter;
992 	ippool_dst_t table;
993 	ipfobj_t obj;
994 
995 	obj.ipfo_rev = IPFILTER_VERSION;
996 	obj.ipfo_type = IPFOBJ_LOOKUPITER;
997 	obj.ipfo_size = sizeof(iter);
998 	obj.ipfo_ptr = &iter;
999 
1000 	iter.ili_type = IPLT_DSTLIST;
1001 	iter.ili_otype = IPFLOOKUPITER_LIST;
1002 	iter.ili_ival = IPFGENITER_LOOKUP;
1003 	iter.ili_nitems = 1;
1004 	iter.ili_data = &table;
1005 	iter.ili_unit = role;
1006 	*iter.ili_name = '\0';
1007 
1008 	while (dlstp->ipls_list[role] != NULL) {
1009 		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1010 			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1011 			break;
1012 		}
1013 
1014 		printdstl_live(&table, fd, poolname, opts, pool_fields);
1015 
1016 		dlstp->ipls_list[role] = table.ipld_next;
1017 	}
1018 }
1019 
1020 
1021 int
setnodeaddr(int type,int role,void * ptr,char * arg)1022 setnodeaddr(int type, int role, void *ptr, char *arg)
1023 {
1024 	struct in_addr mask;
1025 	char *s;
1026 
1027 	s = strchr(arg, '/');
1028 	if (s == NULL)
1029 		mask.s_addr = 0xffffffff;
1030 	else if (strchr(s, '.') == NULL) {
1031 		if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
1032 			return -1;
1033 	} else {
1034 		mask.s_addr = inet_addr(s + 1);
1035 	}
1036 	if (s != NULL)
1037 		*s = '\0';
1038 
1039 	if (type == IPLT_POOL) {
1040 		ip_pool_node_t *node = ptr;
1041 
1042 		if (node->ipn_addr.adf_family == AF_INET)
1043 			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1044 							  adf_addr) +
1045 						 sizeof(struct in_addr);
1046 #ifdef USE_INET6
1047 		else
1048 			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1049 							  adf_addr) +
1050 						 sizeof(struct in6_addr);
1051 #endif
1052 		node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
1053 		node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1054 		node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1055 	} else if (type == IPLT_HASH) {
1056 		iphtent_t *node = ptr;
1057 
1058 		node->ipe_addr.in4.s_addr = inet_addr(arg);
1059 		node->ipe_mask.in4.s_addr = mask.s_addr;
1060         	node->ipe_family = AF_INET;
1061         	node->ipe_unit = role;
1062 	}
1063 
1064 	return 0;
1065 }
1066