ippool.c revision 358321
1103285Sikob/*	$FreeBSD: stable/11/contrib/ipfilter/tools/ippool.c 358321 2020-02-25 21:02:52Z cy $	*/
2103285Sikob
3103285Sikob/*
4103285Sikob * Copyright (C) 2012 by Darren Reed.
5103285Sikob *
6103285Sikob * See the IPFILTER.LICENCE file for details on licencing.
7103285Sikob */
8103285Sikob#include <sys/types.h>
9103285Sikob#include <sys/time.h>
10103285Sikob#include <sys/param.h>
11103285Sikob#include <sys/socket.h>
12103285Sikob# include <sys/cdefs.h>
13103285Sikob#include <sys/ioctl.h>
14103285Sikob
15103285Sikob#include <net/if.h>
16103285Sikob#include <netinet/in.h>
17103285Sikob
18103285Sikob#include <arpa/inet.h>
19103285Sikob
20103285Sikob#include <stdio.h>
21103285Sikob#include <fcntl.h>
22103285Sikob#include <stdlib.h>
23103285Sikob#include <string.h>
24103285Sikob#include <netdb.h>
25103285Sikob#include <ctype.h>
26103285Sikob#include <unistd.h>
27103285Sikob# include <nlist.h>
28103285Sikob
29103285Sikob#include "ipf.h"
30103285Sikob#include "netinet/ipl.h"
31103285Sikob#include "netinet/ip_lookup.h"
32103285Sikob#include "netinet/ip_pool.h"
33103285Sikob#include "netinet/ip_htable.h"
34103285Sikob#include "kmem.h"
35103285Sikob
36103285Sikob
37103285Sikobextern	int	ippool_yyparse __P((void));
38103285Sikobextern	int	ippool_yydebug;
39103285Sikobextern	FILE	*ippool_yyin;
40103285Sikobextern	char	*optarg;
41103285Sikobextern	int	lineNum;
42103285Sikob
43103285Sikobvoid	usage __P((char *));
44103285Sikobint	main __P((int, char **));
45103285Sikobint	poolcommand __P((int, int, char *[]));
46103285Sikobint	poolnodecommand __P((int, int, char *[]));
47103285Sikobint	loadpoolfile __P((int, char *[], char *));
48103285Sikobint	poollist __P((int, char *[]));
49103285Sikobvoid	poollist_dead __P((int, char *, int, char *, char *));
50103285Sikobvoid	poollist_live __P((int, char *, int, int));
51103285Sikobint	poolflush __P((int, char *[]));
52103285Sikobint	poolstats __P((int, char *[]));
53103285Sikobint	gettype __P((char *, u_int *));
54103285Sikobint	getrole __P((char *));
55103285Sikobint	setnodeaddr __P((int, int, void *ptr, char *arg));
56103285Sikobvoid	showpools_live __P((int, int, ipf_pool_stat_t *, char *));
57103285Sikobvoid	showhashs_live __P((int, int, iphtstat_t *, char *));
58103285Sikobvoid	showdstls_live __P((int, int, ipf_dstl_stat_t *, char *));
59103285Sikob
60103285Sikobint	opts = 0;
61108281Ssimokawaint	fd = -1;
62103285Sikobint	use_inet6 = 0;
63108281Ssimokawawordtab_t *pool_fields = NULL;
64103285Sikobint	nohdrfields = 0;
65103285Sikob
66103285Sikob
67103285Sikobvoid
68103285Sikobusage(prog)
69103285Sikob	char *prog;
70103285Sikob{
71103285Sikob	fprintf(stderr, "Usage:\t%s\n", prog);
72103285Sikob	fprintf(stderr, "\t-a [-dnv] -m <name> [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
73103285Sikob	fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
74103285Sikob	fprintf(stderr, "\t-f <file> [-dnuvR]\n");
75103285Sikob	fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
76103285Sikob	fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-o <role>] [-M <core>] [-N <namelist>]\n");
77103285Sikob	fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
78103285Sikob	fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
79103285Sikob	fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
80103285Sikob	exit(1);
81103285Sikob}
82103285Sikob
83103285Sikob
84103285Sikobint
85103285Sikobmain(argc, argv)
86103285Sikob	int argc;
87106543Ssimokawa	char *argv[];
88103285Sikob{
89106543Ssimokawa	int err = 1;
90103285Sikob
91105620Ssimokawa	if (argc < 2)
92103285Sikob		usage(argv[0]);
93103285Sikob
94103285Sikob	assigndefined(getenv("IPPOOL_PREDEFINED"));
95103285Sikob
96103285Sikob	switch (getopt(argc, argv, "aAf:FlrRs"))
97103285Sikob	{
98108642Ssimokawa	case 'a' :
99108642Ssimokawa		err = poolnodecommand(0, argc, argv);
100103285Sikob		break;
101103285Sikob	case 'A' :
102103285Sikob		err = poolcommand(0, argc, argv);
103103285Sikob		break;
104103285Sikob	case 'f' :
105103285Sikob		err = loadpoolfile(argc, argv, optarg);
106103285Sikob		break;
107103285Sikob	case 'F' :
108103285Sikob		err = poolflush(argc, argv);
109103285Sikob		break;
110103285Sikob	case 'l' :
111103285Sikob		err = poollist(argc, argv);
112103285Sikob		break;
113103285Sikob	case 'r' :
114106813Ssimokawa		err = poolnodecommand(1, argc, argv);
115106813Ssimokawa		break;
116106813Ssimokawa	case 'R' :
117103285Sikob		err = poolcommand(1, argc, argv);
118103285Sikob		break;
119103285Sikob	case 's' :
120103285Sikob		err = poolstats(argc, argv);
121103285Sikob		break;
122103285Sikob	default :
123103285Sikob		exit(1);
124103285Sikob	}
125103285Sikob
126103285Sikob	if (err != 0)
127103285Sikob		exit(1);
128103285Sikob	return 0;
129103285Sikob}
130103285Sikob
131103285Sikob
132103285Sikobint
133103285Sikobpoolnodecommand(remove, argc, argv)
134103285Sikob	int remove, argc;
135103285Sikob	char *argv[];
136103285Sikob{
137103285Sikob	int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
138103285Sikob	char *poolname = NULL;
139103285Sikob	ip_pool_node_t pnode;
140103285Sikob	iphtent_t hnode;
141103285Sikob	void *ptr = &pnode;
142103285Sikob
143103285Sikob	ipset = 0;
144103285Sikob	role = IPL_LOGIPF;
145103285Sikob	bzero((char *)&pnode, sizeof(pnode));
146103285Sikob	bzero((char *)&hnode, sizeof(hnode));
147103285Sikob
148103285Sikob	while ((c = getopt(argc, argv, "di:m:no:t:T:v")) != -1)
149103285Sikob		switch (c)
150103285Sikob		{
151103285Sikob		case 'd' :
152103285Sikob			opts |= OPT_DEBUG;
153103285Sikob			ippool_yydebug++;
154103285Sikob			break;
155103285Sikob		case 'i' :
156103285Sikob			if (setnodeaddr(type, role, ptr, optarg) == 0)
157103285Sikob				ipset = 1;
158103285Sikob			break;
159103285Sikob		case 'm' :
160103285Sikob			poolname = optarg;
161103285Sikob			break;
162103285Sikob		case 'n' :
163103285Sikob			opts |= OPT_DONOTHING|OPT_DONTOPEN;
164103285Sikob			break;
165103285Sikob		case 'o' :
166103285Sikob			if (ipset == 1) {
167103285Sikob				fprintf(stderr,
168103285Sikob					"cannot set role after ip address\n");
169103285Sikob				return -1;
170103285Sikob			}
171103285Sikob			role = getrole(optarg);
172103285Sikob			if (role == IPL_LOGNONE)
173103285Sikob				return -1;
174103285Sikob			break;
175103285Sikob		case 't' :
176103285Sikob			if (ipset == 1) {
177103285Sikob				fprintf(stderr,
178103285Sikob					"cannot set type after ip address\n");
179103285Sikob				return -1;
180103285Sikob			}
181103285Sikob			type = gettype(optarg, NULL);
182103285Sikob			switch (type) {
183103285Sikob			case IPLT_NONE :
184103285Sikob				fprintf(stderr, "unknown type '%s'\n", optarg);
185103285Sikob				return -1;
186103285Sikob			case IPLT_HASH :
187103285Sikob				ptr = &hnode;
188103285Sikob				break;
189103285Sikob			case IPLT_POOL :
190103285Sikob			default :
191103285Sikob				break;
192103285Sikob			}
193103285Sikob			break;
194103285Sikob		case 'T' :
195103285Sikob			ttl = atoi(optarg);
196103285Sikob			if (ttl < 0) {
197103285Sikob				fprintf(stderr, "cannot set negative ttl\n");
198103285Sikob				return -1;
199103285Sikob			}
200103285Sikob			break;
201103285Sikob		case 'v' :
202103285Sikob			opts |= OPT_VERBOSE;
203103485Sikob			break;
204103285Sikob		default :
205103285Sikob			usage(argv[0]);
206103285Sikob			break;		/* keep compiler happy */
207103285Sikob		}
208103285Sikob
209103285Sikob	if (argc - 1 - optind > 0)
210103285Sikob		usage(argv[0]);
211103285Sikob
212103285Sikob	if (argv[optind] != NULL && ipset == 0) {
213103285Sikob		if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
214103285Sikob			ipset = 1;
215103285Sikob	}
216103285Sikob
217103285Sikob	if (opts & OPT_DEBUG)
218103285Sikob		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
219103285Sikob
220103285Sikob	if (ipset == 0) {
221103285Sikob		fprintf(stderr, "no IP address given with -i\n");
222103285Sikob		return -1;
223103285Sikob	}
224103285Sikob
225103285Sikob	if (poolname == NULL) {
226103285Sikob		fprintf(stderr, "poolname not given with add/remove node\n");
227103285Sikob		return -1;
228103285Sikob	}
229103285Sikob
230103285Sikob	switch (type) {
231103285Sikob	case IPLT_POOL :
232103285Sikob		if (remove == 0)
233103285Sikob			err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
234103285Sikob		else
235103285Sikob			err = remove_poolnode(role, poolname, &pnode, ioctl);
236103285Sikob		break;
237103285Sikob	case IPLT_HASH :
238103285Sikob		if (remove == 0)
239103285Sikob			err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
240103285Sikob		else
241103285Sikob			err = remove_hashnode(role, poolname, &hnode, ioctl);
242103285Sikob		break;
243103285Sikob	default :
244103285Sikob		break;
245103285Sikob	}
246103285Sikob	return err;
247103285Sikob}
248103285Sikob
249103285Sikob
250103285Sikobint
251103285Sikobpoolcommand(remove, argc, argv)
252103285Sikob	int remove, argc;
253103285Sikob	char *argv[];
254103285Sikob{
255103285Sikob	int type, role, c, err;
256103285Sikob	char *poolname, *typearg = NULL;
257103285Sikob	iphtable_t iph;
258103285Sikob	ip_pool_t pool;
259103285Sikob
260103285Sikob	err = 1;
261103285Sikob	role = 0;
262103285Sikob	type = 0;
263103285Sikob	poolname = NULL;
264103285Sikob	role = IPL_LOGIPF;
265103285Sikob	bzero((char *)&iph, sizeof(iph));
266103285Sikob	bzero((char *)&pool, sizeof(pool));
267103285Sikob
268103285Sikob	while ((c = getopt(argc, argv, "dm:no:S:vt:")) != -1)
269103285Sikob		switch (c)
270103285Sikob		{
271103285Sikob		case 'd' :
272103285Sikob			opts |= OPT_DEBUG;
273103285Sikob			ippool_yydebug++;
274103285Sikob			break;
275103285Sikob		case 'm' :
276103285Sikob			poolname = optarg;
277103285Sikob			break;
278103285Sikob		case 'n' :
279103285Sikob			opts |= OPT_DONOTHING|OPT_DONTOPEN;
280103285Sikob			break;
281103285Sikob		case 'o' :
282103285Sikob			role = getrole(optarg);
283103285Sikob			if (role == IPL_LOGNONE) {
284103285Sikob				fprintf(stderr, "unknown role '%s'\n", optarg);
285103285Sikob				return -1;
286103285Sikob			}
287103285Sikob			break;
288103285Sikob		case 'S' :
289103285Sikob			if (remove == 0)
290103285Sikob				iph.iph_seed = atoi(optarg);
291103285Sikob			else
292103285Sikob				usage(argv[0]);
293103285Sikob			break;
294103285Sikob		case 't' :
295103285Sikob			type = gettype(optarg, &iph.iph_type);
296103285Sikob			typearg = optarg;
297103285Sikob			break;
298103285Sikob		case 'v' :
299103285Sikob			opts |= OPT_VERBOSE;
300103285Sikob			break;
301103285Sikob		default :
302103285Sikob			usage(argv[0]);
303103285Sikob			break;		/* keep compiler happy */
304103285Sikob		}
305103285Sikob
306106810Ssimokawa	if (argc - 1 - optind > 0)
307106790Ssimokawa		usage(argv[0]);
308103285Sikob
309103285Sikob	if (opts & OPT_DEBUG)
310103285Sikob		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
311103285Sikob
312103285Sikob	if (poolname == NULL) {
313103285Sikob		fprintf(stderr, "poolname not given with add/remove pool\n");
314103285Sikob		return -1;
315103285Sikob	}
316106810Ssimokawa
317106810Ssimokawa	if (type == IPLT_NONE && remove == 0) {
318106810Ssimokawa		if (typearg == NULL) {
319103285Sikob			fprintf(stderr, "type must be specified\n");
320106813Ssimokawa			usage(argv[0]);
321103285Sikob		} else {
322103285Sikob			fprintf(stderr, "unknown type '%s'\n", typearg);
323103285Sikob		}
324103285Sikob		return -1;
325103285Sikob	}
326103285Sikob
327103285Sikob	if (type == IPLT_HASH || (type == IPLT_NONE && remove == 1)) {
328103285Sikob		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
329103285Sikob		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
330103285Sikob		iph.iph_unit = role;
331103285Sikob	}
332103285Sikob	if (type == IPLT_POOL || (type == IPLT_NONE && remove == 1)) {
333103285Sikob		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
334103285Sikob		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
335103285Sikob		pool.ipo_unit = role;
336103285Sikob	}
337103285Sikob
338103285Sikob	if (remove == 0) {
339103285Sikob		switch (type)
340103285Sikob		{
341103285Sikob		case IPLT_HASH :
342103285Sikob			err = load_hash(&iph, NULL, ioctl);
343103285Sikob			break;
344103285Sikob		case IPLT_POOL :
345103285Sikob			err = load_pool(&pool, ioctl);
346103285Sikob			break;
347103285Sikob		}
348103285Sikob	} else {
349103285Sikob		switch (type)
350103285Sikob		{
351103285Sikob		case IPLT_HASH :
352103285Sikob			err = remove_hash(&iph, ioctl);
353103285Sikob			break;
354103285Sikob		case IPLT_POOL :
355103285Sikob			err = remove_pool(&pool, ioctl);
356103285Sikob			break;
357103285Sikob		case IPLT_NONE :
358103285Sikob			err = 1;
359103285Sikob			{
360103285Sikob				int err_h, err_p;
361103285Sikob				err_h = remove_hash(&iph, ioctl);
362103285Sikob				err_p = remove_pool(&pool, ioctl);
363103285Sikob				if (err_h == 0 || err_p == 0)
364103285Sikob					err = 0;
365103285Sikob			}
366106790Ssimokawa			break;
367103285Sikob		}
368103285Sikob	}
369103285Sikob	return err;
370103285Sikob}
371103285Sikob
372103285Sikob
373103285Sikobint
374103285Sikobloadpoolfile(argc, argv, infile)
375103285Sikob	int argc;
376103285Sikob	char *argv[], *infile;
377103285Sikob{
378103285Sikob	int c;
379103285Sikob
380103285Sikob	while ((c = getopt(argc, argv, "dnuvf:")) != -1)
381103285Sikob		switch (c)
382103285Sikob		{
383103285Sikob		case 'd' :
384103285Sikob			opts |= OPT_DEBUG;
385103285Sikob			ippool_yydebug++;
386103285Sikob			break;
387103285Sikob		case 'f' :
388103285Sikob			if (loadpoolfile(argc, argv, optarg) != 0)
389103285Sikob				return(-1);
390103285Sikob			break;
391103285Sikob		case 'n' :
392103285Sikob			opts |= OPT_DONOTHING|OPT_DONTOPEN;
393103285Sikob			break;
394103285Sikob		case 'u' :
395103285Sikob			opts |= OPT_REMOVE;
396103285Sikob			break;
397103285Sikob		case 'v' :
398103285Sikob			opts |= OPT_VERBOSE;
399103285Sikob			break;
400103285Sikob		default :
401103285Sikob			usage(argv[0]);
402103285Sikob			break;		/* keep compiler happy */
403103285Sikob		}
404103285Sikob
405103285Sikob	if (argc - 1 - optind > 0)
406103285Sikob		usage(argv[0]);
407106815Ssimokawa
408103285Sikob	if (opts & OPT_DEBUG)
409103285Sikob		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
410103285Sikob
411103285Sikob	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
412103285Sikob		fd = open(IPLOOKUP_NAME, O_RDWR);
413103285Sikob		if (fd == -1) {
414103285Sikob			perror("open(IPLOOKUP_NAME)");
415103285Sikob			exit(1);
416103285Sikob		}
417103285Sikob	}
418103285Sikob
419103285Sikob	if (ippool_parsefile(fd, infile, ioctl) != 0)
420103285Sikob		return -1;
421103285Sikob	return 0;
422103285Sikob}
423103285Sikob
424103285Sikob
425103285Sikobint
426103285Sikobpoolstats(argc, argv)
427103285Sikob	int argc;
428103285Sikob	char *argv[];
429103285Sikob{
430103285Sikob	int c, type, role, live_kernel;
431103285Sikob	ipf_pool_stat_t plstat;
432103285Sikob	ipf_dstl_stat_t dlstat;
433103285Sikob	char *kernel, *core;
434103285Sikob	iphtstat_t htstat;
435103285Sikob	iplookupop_t op;
436103285Sikob
437103285Sikob	core = NULL;
438103285Sikob	kernel = NULL;
439103285Sikob	live_kernel = 1;
440103285Sikob	type = IPLT_ALL;
441106790Ssimokawa	role = IPL_LOGALL;
442106790Ssimokawa
443106790Ssimokawa	bzero((char *)&op, sizeof(op));
444103285Sikob
445103285Sikob	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
446103285Sikob		switch (c)
447103285Sikob		{
448103285Sikob		case 'd' :
449103285Sikob			opts |= OPT_DEBUG;
450103285Sikob			break;
451103285Sikob		case 'M' :
452103285Sikob			live_kernel = 0;
453103285Sikob			core = optarg;
454103285Sikob			break;
455103285Sikob		case 'N' :
456103285Sikob			live_kernel = 0;
457103285Sikob			kernel = optarg;
458103285Sikob			break;
459103285Sikob		case 'o' :
460103285Sikob			role = getrole(optarg);
461103285Sikob			if (role == IPL_LOGNONE) {
462103285Sikob				fprintf(stderr, "unknown role '%s'\n", optarg);
463103285Sikob				return -1;
464103285Sikob			}
465103285Sikob			break;
466103285Sikob		case 't' :
467103285Sikob			type = gettype(optarg, NULL);
468103285Sikob			if (type != IPLT_POOL) {
469103285Sikob				fprintf(stderr,
470103285Sikob					"-s not supported for this type yet\n");
471103285Sikob				return -1;
472103285Sikob			}
473103285Sikob			break;
474103285Sikob		case 'v' :
475106790Ssimokawa			opts |= OPT_VERBOSE;
476103285Sikob			break;
477103285Sikob		default :
478103285Sikob			usage(argv[0]);
479108281Ssimokawa			break;		/* keep compiler happy */
480103285Sikob		}
481103285Sikob
482106790Ssimokawa	if (argc - 1 - optind > 0)
483103285Sikob		usage(argv[0]);
484103285Sikob
485103285Sikob	if (opts & OPT_DEBUG)
486103285Sikob		fprintf(stderr, "poolstats: opts = %#x\n", opts);
487103285Sikob
488103285Sikob	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
489103285Sikob		fd = open(IPLOOKUP_NAME, O_RDWR);
490103285Sikob		if (fd == -1) {
491103285Sikob			perror("open(IPLOOKUP_NAME)");
492103285Sikob			exit(1);
493103285Sikob		}
494103285Sikob	}
495103285Sikob
496103285Sikob	if (type == IPLT_ALL || type == IPLT_POOL) {
497103285Sikob		op.iplo_type = IPLT_POOL;
498103285Sikob		op.iplo_struct = &plstat;
499103285Sikob		op.iplo_size = sizeof(plstat);
500103285Sikob		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
501103285Sikob			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
502103285Sikob			if (c == -1) {
503103285Sikob				ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
504103285Sikob				return -1;
505103285Sikob			}
506108276Ssimokawa			printf("%lu\taddress pools\n", plstat.ipls_pools);
507103285Sikob			printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
508103285Sikob		}
509103285Sikob	}
510103285Sikob
511103285Sikob	if (type == IPLT_ALL || type == IPLT_HASH) {
512103285Sikob		op.iplo_type = IPLT_HASH;
513103285Sikob		op.iplo_struct = &htstat;
514103285Sikob		op.iplo_size = sizeof(htstat);
515103285Sikob		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
516103285Sikob			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
517103285Sikob			if (c == -1) {
518108276Ssimokawa				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
519103285Sikob				return -1;
520103285Sikob			}
521103285Sikob			printf("%lu\thash tables\n", htstat.iphs_numtables);
522103285Sikob			printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
523103285Sikob			printf("%lu\thash table no memory \n",
524103285Sikob				htstat.iphs_nomem);
525103285Sikob		}
526103285Sikob	}
527103285Sikob
528103285Sikob	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
529103285Sikob		op.iplo_type = IPLT_DSTLIST;
530103285Sikob		op.iplo_struct = &dlstat;
531103285Sikob		op.iplo_size = sizeof(dlstat);
532103285Sikob		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
533103285Sikob			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
534103285Sikob			if (c == -1) {
535103285Sikob				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
536103285Sikob				return -1;
537103285Sikob			}
538103285Sikob			printf("%u\tdestination lists\n",
539103285Sikob			       dlstat.ipls_numlists);
540103285Sikob			printf("%u\tdestination list nodes\n",
541103285Sikob			       dlstat.ipls_numnodes);
542103285Sikob			printf("%lu\tdestination list no memory\n",
543103285Sikob			       dlstat.ipls_nomem);
544103285Sikob			printf("%u\tdestination list zombies\n",
545103285Sikob			       dlstat.ipls_numdereflists);
546103285Sikob			printf("%u\tdesetination list node zombies\n",
547103285Sikob			       dlstat.ipls_numderefnodes);
548103285Sikob		}
549103285Sikob	}
550103285Sikob	return 0;
551103285Sikob}
552103285Sikob
553103285Sikob
554103285Sikobint
555103285Sikobpoolflush(argc, argv)
556103285Sikob	int argc;
557106790Ssimokawa	char *argv[];
558103285Sikob{
559103285Sikob	int c, role, type, arg;
560103285Sikob	iplookupflush_t flush;
561103285Sikob
562103285Sikob	arg = IPLT_ALL;
563103285Sikob	type = IPLT_ALL;
564103285Sikob	role = IPL_LOGALL;
565103285Sikob
566103285Sikob	while ((c = getopt(argc, argv, "do:t:v")) != -1)
567106790Ssimokawa		switch (c)
568103285Sikob		{
569103285Sikob		case 'd' :
570103285Sikob			opts |= OPT_DEBUG;
571103285Sikob			break;
572103285Sikob		case 'o' :
573103285Sikob			role = getrole(optarg);
574103285Sikob			if (role == IPL_LOGNONE) {
575103285Sikob				fprintf(stderr, "unknown role '%s'\n", optarg);
576103285Sikob				return -1;
577103285Sikob			}
578103285Sikob			break;
579103285Sikob		case 't' :
580103285Sikob			type = gettype(optarg, NULL);
581103285Sikob			if (type == IPLT_NONE) {
582103285Sikob				fprintf(stderr, "unknown type '%s'\n", optarg);
583103285Sikob				return -1;
584103285Sikob			}
585103285Sikob			break;
586103285Sikob		case 'v' :
587103285Sikob			opts |= OPT_VERBOSE;
588103285Sikob			break;
589103285Sikob		default :
590103285Sikob			usage(argv[0]);
591106790Ssimokawa			break;		/* keep compiler happy */
592103285Sikob		}
593106790Ssimokawa
594103285Sikob	if (argc - optind > 0)
595106790Ssimokawa		usage(argv[0]);
596106790Ssimokawa
597103285Sikob	if (opts & OPT_DEBUG)
598103285Sikob		fprintf(stderr, "poolflush: opts = %#x\n", opts);
599103285Sikob
600103285Sikob	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
601103285Sikob		fd = open(IPLOOKUP_NAME, O_RDWR);
602103285Sikob		if (fd == -1) {
603103285Sikob			perror("open(IPLOOKUP_NAME)");
604103285Sikob			exit(1);
605103285Sikob		}
606103285Sikob	}
607103285Sikob
608103285Sikob	bzero((char *)&flush, sizeof(flush));
609103285Sikob	flush.iplf_type = type;
610103285Sikob	flush.iplf_unit = role;
611103285Sikob	flush.iplf_arg = arg;
612103285Sikob
613103285Sikob	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
614103285Sikob		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
615103285Sikob			ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
616103285Sikob			exit(1);
617103285Sikob		}
618103285Sikob
619103285Sikob	}
620103285Sikob	printf("%u object%s flushed\n", flush.iplf_count,
621103285Sikob	       (flush.iplf_count == 1) ? "" : "s");
622103285Sikob
623103285Sikob	return 0;
624103285Sikob}
625103285Sikob
626103285Sikob
627103285Sikobint
628103285Sikobgetrole(rolename)
629103285Sikob	char *rolename;
630103285Sikob{
631103285Sikob	int role;
632103285Sikob
633103285Sikob	if (!strcasecmp(rolename, "ipf")) {
634103285Sikob		role = IPL_LOGIPF;
635103285Sikob#if 0
636103285Sikob	} else if (!strcasecmp(rolename, "nat")) {
637103285Sikob		role = IPL_LOGNAT;
638103285Sikob	} else if (!strcasecmp(rolename, "state")) {
639103285Sikob		role = IPL_LOGSTATE;
640103285Sikob	} else if (!strcasecmp(rolename, "auth")) {
641103285Sikob		role = IPL_LOGAUTH;
642103285Sikob	} else if (!strcasecmp(rolename, "sync")) {
643103285Sikob		role = IPL_LOGSYNC;
644103285Sikob	} else if (!strcasecmp(rolename, "scan")) {
645103285Sikob		role = IPL_LOGSCAN;
646103285Sikob	} else if (!strcasecmp(rolename, "pool")) {
647103285Sikob		role = IPL_LOGLOOKUP;
648103285Sikob	} else if (!strcasecmp(rolename, "count")) {
649103285Sikob		role = IPL_LOGCOUNT;
650103285Sikob#endif
651103285Sikob	} else {
652103285Sikob		role = IPL_LOGNONE;
653103285Sikob	}
654103285Sikob
655103285Sikob	return role;
656103285Sikob}
657103285Sikob
658103285Sikob
659103285Sikobint
660103285Sikobgettype(typename, minor)
661103285Sikob	char *typename;
662103285Sikob	u_int *minor;
663103285Sikob{
664103285Sikob	int type;
665103285Sikob
666103285Sikob	if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
667103285Sikob		type = IPLT_POOL;
668103285Sikob	} else if (!strcasecmp(typename, "hash")) {
669103285Sikob		type = IPLT_HASH;
670103285Sikob		if (minor != NULL)
671103285Sikob			*minor = IPHASH_LOOKUP;
672103285Sikob	} else if (!strcasecmp(typename, "group-map")) {
673103285Sikob		type = IPLT_HASH;
674103285Sikob		if (minor != NULL)
675103285Sikob			*minor = IPHASH_GROUPMAP;
676103285Sikob	} else {
677103285Sikob		type = IPLT_NONE;
678103285Sikob	}
679103285Sikob	return type;
680103285Sikob}
681103285Sikob
682103285Sikob
683103285Sikobint
684103285Sikobpoollist(argc, argv)
685103285Sikob	int argc;
686106790Ssimokawa	char *argv[];
687103285Sikob{
688106790Ssimokawa	char *kernel, *core, *poolname;
689103285Sikob	int c, role, type, live_kernel;
690103285Sikob	iplookupop_t op;
691106543Ssimokawa
692106543Ssimokawa	core = NULL;
693103285Sikob	kernel = NULL;
694103285Sikob	live_kernel = 1;
695106543Ssimokawa	type = IPLT_ALL;
696103285Sikob	poolname = NULL;
697103285Sikob	role = IPL_LOGALL;
698103285Sikob
699103285Sikob	while ((c = getopt(argc, argv, "dm:M:N:o:t:v")) != -1)
700103285Sikob		switch (c)
701103285Sikob		{
702103285Sikob		case 'd' :
703103285Sikob			opts |= OPT_DEBUG;
704103285Sikob			break;
705103285Sikob		case 'm' :
706103285Sikob			poolname = optarg;
707103285Sikob			break;
708103285Sikob		case 'M' :
709103285Sikob			live_kernel = 0;
710103285Sikob			core = optarg;
711103285Sikob			break;
712103285Sikob		case 'N' :
713103285Sikob			live_kernel = 0;
714103285Sikob			kernel = optarg;
715103285Sikob			break;
716103285Sikob		case 'o' :
717103285Sikob			role = getrole(optarg);
718103285Sikob			if (role == IPL_LOGNONE) {
719103285Sikob				fprintf(stderr, "unknown role '%s'\n", optarg);
720103285Sikob				return -1;
721103285Sikob			}
722103285Sikob			break;
723103285Sikob#if 0
724103285Sikob		case 'O' :
725103285Sikob			/* XXX This option does not work. This function as  */
726103285Sikob			/* XXX used by state and nat can be used to format  */
727103285Sikob			/* XXX output especially useful for scripting. It   */
728103285Sikob			/* XXX is left here with the intention of making    */
729103285Sikob			/* XXX it work for the same purpose at some point.  */
730103285Sikob			pool_fields = parsefields(poolfields, optarg);
731103285Sikob			break;
732103285Sikob#endif
733103285Sikob		case 't' :
734103285Sikob			type = gettype(optarg, NULL);
735103285Sikob			if (type == IPLT_NONE) {
736103285Sikob				fprintf(stderr, "unknown type '%s'\n", optarg);
737103285Sikob				return -1;
738103285Sikob			}
739103285Sikob			break;
740103285Sikob		case 'v' :
741103285Sikob			opts |= OPT_VERBOSE;
742103285Sikob			break;
743103285Sikob		default :
744103285Sikob			usage(argv[0]);
745103285Sikob			break;		/* keep compiler happy */
746103285Sikob		}
747103285Sikob
748103285Sikob	if (argc - optind > 0)
749103285Sikob		usage(argv[0]);
750103285Sikob
751103285Sikob	if (opts & OPT_DEBUG)
752103285Sikob		fprintf(stderr, "poollist: opts = %#x\n", opts);
753103285Sikob
754103285Sikob	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
755103285Sikob		fd = open(IPLOOKUP_NAME, O_RDWR);
756103285Sikob		if (fd == -1) {
757103285Sikob			perror("open(IPLOOKUP_NAME)");
758103285Sikob			exit(1);
759103285Sikob		}
760103285Sikob	}
761103285Sikob
762103285Sikob	bzero((char *)&op, sizeof(op));
763103285Sikob	if (poolname != NULL) {
764103285Sikob		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
765103285Sikob		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
766103285Sikob	}
767103285Sikob	op.iplo_unit = role;
768103285Sikob
769103285Sikob	if (live_kernel)
770103285Sikob		poollist_live(role, poolname, type, fd);
771103285Sikob	else
772103285Sikob		poollist_dead(role, poolname, type, kernel, core);
773103285Sikob	return 0;
774103285Sikob}
775103285Sikob
776103285Sikob
777103285Sikobvoid
778103285Sikobpoollist_dead(role, poolname, type, kernel, core)
779103285Sikob	int role, type;
780103285Sikob	char *poolname, *kernel, *core;
781103285Sikob{
782103285Sikob	iphtable_t *hptr;
783103285Sikob	ip_pool_t *ptr;
784103285Sikob
785103285Sikob	if (openkmem(kernel, core) == -1)
786103285Sikob		exit(-1);
787103285Sikob
788103285Sikob	if (type == IPLT_ALL || type == IPLT_POOL) {
789103285Sikob		ip_pool_t *pools[IPL_LOGSIZE];
790103285Sikob		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
791103285Sikob
792103285Sikob		if (nlist(kernel, names) != 1)
793103285Sikob			return;
794103285Sikob
795103285Sikob		bzero(&pools, sizeof(pools));
796103285Sikob		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
797103285Sikob			return;
798106543Ssimokawa
799103285Sikob		if (role != IPL_LOGALL) {
800103285Sikob			ptr = pools[role];
801103285Sikob			while (ptr != NULL) {
802103285Sikob				ptr = printpool(ptr, kmemcpywrap, poolname,
803103285Sikob						opts, pool_fields);
804103285Sikob			}
805103285Sikob		} else {
806103285Sikob			for (role = 0; role <= IPL_LOGMAX; role++) {
807103285Sikob				ptr = pools[role];
808103285Sikob				while (ptr != NULL) {
809103285Sikob					ptr = printpool(ptr, kmemcpywrap,
810103285Sikob							poolname, opts,
811103285Sikob							pool_fields);
812103285Sikob				}
813103285Sikob			}
814103285Sikob			role = IPL_LOGALL;
815103285Sikob		}
816106543Ssimokawa	}
817103285Sikob	if (type == IPLT_ALL || type == IPLT_HASH) {
818106790Ssimokawa		iphtable_t *tables[IPL_LOGSIZE];
819103285Sikob		struct nlist names[2] = { { "ipf_htables" } , { "" } };
820103285Sikob
821103285Sikob		if (nlist(kernel, names) != 1)
822106813Ssimokawa			return;
823106790Ssimokawa
824103285Sikob		bzero(&tables, sizeof(tables));
825103285Sikob		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
826103285Sikob			return;
827103285Sikob
828103285Sikob		if (role != IPL_LOGALL) {
829103285Sikob			hptr = tables[role];
830103285Sikob			while (hptr != NULL) {
831103285Sikob				hptr = printhash(hptr, kmemcpywrap,
832103285Sikob						 poolname, opts, pool_fields);
833103285Sikob			}
834103285Sikob		} else {
835103285Sikob			for (role = 0; role <= IPL_LOGMAX; role++) {
836103285Sikob				hptr = tables[role];
837106790Ssimokawa				while (hptr != NULL) {
838103285Sikob					hptr = printhash(hptr, kmemcpywrap,
839103285Sikob							 poolname, opts,
840103285Sikob							 pool_fields);
841106790Ssimokawa				}
842106790Ssimokawa			}
843103285Sikob		}
844103285Sikob	}
845103285Sikob}
846103285Sikob
847103285Sikob
848103285Sikobvoid
849103285Sikobpoollist_live(role, poolname, type, fd)
850103285Sikob	int role, type, fd;
851103285Sikob	char *poolname;
852103285Sikob{
853103285Sikob	ipf_pool_stat_t plstat;
854103285Sikob	iplookupop_t op;
855103285Sikob	int c;
856103285Sikob
857103285Sikob	if (type == IPLT_ALL || type == IPLT_POOL) {
858103285Sikob		op.iplo_type = IPLT_POOL;
859103285Sikob		op.iplo_size = sizeof(plstat);
860103285Sikob		op.iplo_struct = &plstat;
861103285Sikob		op.iplo_name[0] = '\0';
862103285Sikob		op.iplo_arg = 0;
863103285Sikob
864103285Sikob		if (role != IPL_LOGALL) {
865103285Sikob			op.iplo_unit = role;
866103285Sikob
867103285Sikob			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
868103285Sikob			if (c == -1) {
869103285Sikob				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
870103285Sikob				return;
871103285Sikob			}
872103285Sikob
873103285Sikob			showpools_live(fd, role, &plstat, poolname);
874103285Sikob		} else {
875103285Sikob			for (role = -1; role <= IPL_LOGMAX; role++) {
876103285Sikob				op.iplo_unit = role;
877103285Sikob
878103285Sikob				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
879103285Sikob				if (c == -1) {
880103285Sikob					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
881103285Sikob					return;
882103285Sikob				}
883103285Sikob
884103285Sikob				showpools_live(fd, role, &plstat, poolname);
885103285Sikob			}
886103285Sikob
887103285Sikob			role = IPL_LOGALL;
888103285Sikob		}
889106790Ssimokawa	}
890106790Ssimokawa
891103285Sikob	if (type == IPLT_ALL || type == IPLT_HASH) {
892103285Sikob		iphtstat_t htstat;
893103285Sikob
894103285Sikob		op.iplo_type = IPLT_HASH;
895103285Sikob		op.iplo_size = sizeof(htstat);
896103285Sikob		op.iplo_struct = &htstat;
897103285Sikob		op.iplo_name[0] = '\0';
898103285Sikob		op.iplo_arg = 0;
899103285Sikob
900103285Sikob		if (role != IPL_LOGALL) {
901103285Sikob			op.iplo_unit = role;
902103285Sikob
903103285Sikob			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
904103285Sikob			if (c == -1) {
905103285Sikob				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
906103285Sikob				return;
907106790Ssimokawa			}
908106790Ssimokawa			showhashs_live(fd, role, &htstat, poolname);
909103285Sikob		} else {
910103285Sikob			for (role = 0; role <= IPL_LOGMAX; role++) {
911103285Sikob
912103285Sikob				op.iplo_unit = role;
913103285Sikob				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
914103285Sikob				if (c == -1) {
915103285Sikob					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
916103285Sikob					return;
917103285Sikob				}
918103285Sikob
919103285Sikob				showhashs_live(fd, role, &htstat, poolname);
920103285Sikob			}
921103285Sikob			role = IPL_LOGALL;
922103285Sikob		}
923103285Sikob	}
924103285Sikob
925106790Ssimokawa	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
926103285Sikob		ipf_dstl_stat_t dlstat;
927103285Sikob
928103285Sikob		op.iplo_type = IPLT_DSTLIST;
929106790Ssimokawa		op.iplo_size = sizeof(dlstat);
930106790Ssimokawa		op.iplo_struct = &dlstat;
931103285Sikob		op.iplo_name[0] = '\0';
932103285Sikob		op.iplo_arg = 0;
933103285Sikob
934103285Sikob		if (role != IPL_LOGALL) {
935103285Sikob			op.iplo_unit = role;
936103285Sikob
937103285Sikob			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
938103285Sikob			if (c == -1) {
939103285Sikob				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
940103285Sikob				return;
941103285Sikob			}
942103285Sikob			showdstls_live(fd, role, &dlstat, poolname);
943103285Sikob		} else {
944103285Sikob			for (role = 0; role <= IPL_LOGMAX; role++) {
945103285Sikob
946103285Sikob				op.iplo_unit = role;
947106790Ssimokawa				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
948103285Sikob				if (c == -1) {
949103285Sikob					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
950103285Sikob					return;
951106790Ssimokawa				}
952106790Ssimokawa
953103285Sikob				showdstls_live(fd, role, &dlstat, poolname);
954103285Sikob			}
955106790Ssimokawa			role = IPL_LOGALL;
956103285Sikob		}
957106790Ssimokawa	}
958106790Ssimokawa}
959106790Ssimokawa
960103285Sikob
961103285Sikobvoid
962106790Ssimokawashowpools_live(fd, role, plstp, poolname)
963103285Sikob	int fd, role;
964103285Sikob	ipf_pool_stat_t *plstp;
965106790Ssimokawa	char *poolname;
966103285Sikob{
967103285Sikob	ipflookupiter_t iter;
968103285Sikob	ip_pool_t pool;
969103285Sikob	ipfobj_t obj;
970103285Sikob
971103285Sikob	obj.ipfo_rev = IPFILTER_VERSION;
972103285Sikob	obj.ipfo_type = IPFOBJ_LOOKUPITER;
973103285Sikob	obj.ipfo_size = sizeof(iter);
974103285Sikob	obj.ipfo_ptr = &iter;
975103285Sikob
976103285Sikob	iter.ili_type = IPLT_POOL;
977103285Sikob	iter.ili_otype = IPFLOOKUPITER_LIST;
978103285Sikob	iter.ili_ival = IPFGENITER_LOOKUP;
979103285Sikob	iter.ili_nitems = 1;
980103285Sikob	iter.ili_data = &pool;
981103285Sikob	iter.ili_unit = role;
982103285Sikob	*iter.ili_name = '\0';
983103285Sikob
984103285Sikob	bzero((char *)&pool, sizeof(pool));
985103285Sikob
986103285Sikob	while (plstp->ipls_list[role + 1] != NULL) {
987103285Sikob		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
988103285Sikob			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
989103285Sikob			break;
990103285Sikob		}
991103285Sikob		if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
992103285Sikob		    ((opts & OPT_DEBUG) != 0))
993106790Ssimokawa			printpool_live(&pool, fd, poolname, opts, pool_fields);
994106790Ssimokawa
995103285Sikob		plstp->ipls_list[role + 1] = pool.ipo_next;
996103285Sikob	}
997103285Sikob}
998103285Sikob
999103285Sikob
1000103285Sikobvoid
1001103285Sikobshowhashs_live(fd, role, htstp, poolname)
1002103285Sikob	int fd, role;
1003103285Sikob	iphtstat_t *htstp;
1004103285Sikob	char *poolname;
1005103285Sikob{
1006103285Sikob	ipflookupiter_t iter;
1007103285Sikob	iphtable_t table;
1008103285Sikob	ipfobj_t obj;
1009103285Sikob
1010103285Sikob	obj.ipfo_rev = IPFILTER_VERSION;
1011103285Sikob	obj.ipfo_type = IPFOBJ_LOOKUPITER;
1012103285Sikob	obj.ipfo_size = sizeof(iter);
1013103285Sikob	obj.ipfo_ptr = &iter;
1014103285Sikob
1015103285Sikob	iter.ili_type = IPLT_HASH;
1016103285Sikob	iter.ili_otype = IPFLOOKUPITER_LIST;
1017103285Sikob	iter.ili_ival = IPFGENITER_LOOKUP;
1018103285Sikob	iter.ili_nitems = 1;
1019103285Sikob	iter.ili_data = &table;
1020103285Sikob	iter.ili_unit = role;
1021103285Sikob	*iter.ili_name = '\0';
1022103285Sikob
1023103285Sikob	while (htstp->iphs_tables != NULL) {
1024103285Sikob		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1025103285Sikob			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1026103285Sikob			break;
1027103285Sikob		}
1028103285Sikob
1029103285Sikob		printhash_live(&table, fd, poolname, opts, pool_fields);
1030103285Sikob
1031103285Sikob		htstp->iphs_tables = table.iph_next;
1032103285Sikob	}
1033103285Sikob}
1034103285Sikob
1035103285Sikob
1036103285Sikobvoid
1037103285Sikobshowdstls_live(fd, role, dlstp, poolname)
1038103285Sikob	int fd, role;
1039103285Sikob	ipf_dstl_stat_t *dlstp;
1040103285Sikob	char *poolname;
1041103285Sikob{
1042103285Sikob	ipflookupiter_t iter;
1043103285Sikob	ippool_dst_t table;
1044103285Sikob	ipfobj_t obj;
1045103285Sikob
1046103285Sikob	obj.ipfo_rev = IPFILTER_VERSION;
1047103285Sikob	obj.ipfo_type = IPFOBJ_LOOKUPITER;
1048103285Sikob	obj.ipfo_size = sizeof(iter);
1049103285Sikob	obj.ipfo_ptr = &iter;
1050103285Sikob
1051103285Sikob	iter.ili_type = IPLT_DSTLIST;
1052103285Sikob	iter.ili_otype = IPFLOOKUPITER_LIST;
1053103285Sikob	iter.ili_ival = IPFGENITER_LOOKUP;
1054103285Sikob	iter.ili_nitems = 1;
1055103285Sikob	iter.ili_data = &table;
1056103285Sikob	iter.ili_unit = role;
1057103285Sikob	*iter.ili_name = '\0';
1058103285Sikob
1059103285Sikob	while (dlstp->ipls_list[role] != NULL) {
1060103285Sikob		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
1061103285Sikob			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
1062103285Sikob			break;
1063103285Sikob		}
1064103285Sikob
1065103285Sikob		printdstl_live(&table, fd, poolname, opts, pool_fields);
1066103285Sikob
1067103285Sikob		dlstp->ipls_list[role] = table.ipld_next;
1068103285Sikob	}
1069103285Sikob}
1070103285Sikob
1071103285Sikob
1072103285Sikobint
1073107653Ssimokawasetnodeaddr(int type, int role, void *ptr, char *arg)
1074107653Ssimokawa{
1075103285Sikob	struct in_addr mask;
1076103285Sikob	char *s;
1077103285Sikob
1078103285Sikob	s = strchr(arg, '/');
1079103285Sikob	if (s == NULL)
1080103285Sikob		mask.s_addr = 0xffffffff;
1081103285Sikob	else if (strchr(s, '.') == NULL) {
1082103285Sikob		if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
1083103285Sikob			return -1;
1084103285Sikob	} else {
1085103285Sikob		mask.s_addr = inet_addr(s + 1);
1086103285Sikob	}
1087103285Sikob	if (s != NULL)
1088103285Sikob		*s = '\0';
1089103285Sikob
1090103285Sikob	if (type == IPLT_POOL) {
1091103285Sikob		ip_pool_node_t *node = ptr;
1092103285Sikob
1093103285Sikob#ifdef USE_INET6
1094103285Sikob		if (node->ipn_addr.adf_family == AF_INET)
1095103285Sikob#endif
1096103285Sikob			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1097103285Sikob							  adf_addr) +
1098103285Sikob						 sizeof(struct in_addr);
1099103285Sikob#ifdef USE_INET6
1100103285Sikob		else
1101103285Sikob			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1102103285Sikob							  adf_addr) +
1103103285Sikob						 sizeof(struct in6_addr);
1104103285Sikob#endif
1105103285Sikob		node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
1106103285Sikob		node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1107103285Sikob		node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
1108103285Sikob	} else if (type == IPLT_HASH) {
1109103285Sikob		iphtent_t *node = ptr;
1110103285Sikob
1111103285Sikob		node->ipe_addr.in4.s_addr = inet_addr(arg);
1112103285Sikob		node->ipe_mask.in4.s_addr = mask.s_addr;
1113103285Sikob        	node->ipe_family = AF_INET;
1114103285Sikob        	node->ipe_unit = role;
1115103285Sikob	}
1116103285Sikob
1117103285Sikob	return 0;
1118103285Sikob}
1119103285Sikob