ippool.c revision 288683
138032Speter/*	$FreeBSD: head/contrib/ipfilter/tools/ippool.c 281143 2015-04-06 09:42:23Z glebius $	*/
2168515Sgshapiro
364562Sgshapiro/*
438032Speter * Copyright (C) 2012 by Darren Reed.
538032Speter *
638032Speter * See the IPFILTER.LICENCE file for details on licencing.
738032Speter */
838032Speter#include <sys/types.h>
938032Speter#include <sys/time.h>
1038032Speter#include <sys/param.h>
1138032Speter#include <sys/socket.h>
1238032Speter#if defined(BSD) && (BSD >= 199306)
1338032Speter# include <sys/cdefs.h>
1464562Sgshapiro#endif
1538032Speter#include <sys/ioctl.h>
16182352Sgshapiro
1790792Sgshapiro#include <net/if.h>
18168515Sgshapiro#include <netinet/in.h>
19168515Sgshapiro
20168515Sgshapiro#include <arpa/inet.h>
2190792Sgshapiro
2264562Sgshapiro#include <stdio.h>
2364562Sgshapiro#include <fcntl.h>
2464562Sgshapiro#include <stdlib.h>
2594334Sgshapiro#include <string.h>
2664562Sgshapiro#include <netdb.h>
2794334Sgshapiro#include <ctype.h>
2894334Sgshapiro#include <unistd.h>
2994334Sgshapiro#ifdef linux
3038032Speter# include <linux/a.out.h>
3138032Speter#else
3238032Speter# include <nlist.h>
3338032Speter#endif
3438032Speter
3538032Speter#include "ipf.h"
3638032Speter#include "netinet/ipl.h"
3738032Speter#include "netinet/ip_lookup.h"
3838032Speter#include "netinet/ip_pool.h"
3938032Speter#include "netinet/ip_htable.h"
4038032Speter#include "kmem.h"
4138032Speter
4238032Speter
4338032Speterextern	int	ippool_yyparse __P((void));
4438032Speterextern	int	ippool_yydebug;
4538032Speterextern	FILE	*ippool_yyin;
4638032Speterextern	char	*optarg;
4790792Sgshapiroextern	int	lineNum;
4838032Speter
4938032Spetervoid	usage __P((char *));
5038032Speterint	main __P((int, char **));
5138032Speterint	poolcommand __P((int, int, char *[]));
5238032Speterint	poolnodecommand __P((int, int, char *[]));
5338032Speterint	loadpoolfile __P((int, char *[], char *));
5438032Speterint	poollist __P((int, char *[]));
5590792Sgshapirovoid	poollist_dead __P((int, char *, int, char *, char *));
5690792Sgshapirovoid	poollist_live __P((int, char *, int, int));
5738032Speterint	poolflush __P((int, char *[]));
5838032Speterint	poolstats __P((int, char *[]));
5938032Speterint	gettype __P((char *, u_int *));
6038032Speterint	getrole __P((char *));
6138032Speterint	setnodeaddr __P((int, int, void *ptr, char *arg));
6238032Spetervoid	showpools_live __P((int, int, ipf_pool_stat_t *, char *));
6338032Spetervoid	showhashs_live __P((int, int, iphtstat_t *, char *));
6490792Sgshapirovoid	showdstls_live __P((int, int, ipf_dstl_stat_t *, char *));
6538032Speter
6638032Speterint	opts = 0;
6738032Speterint	fd = -1;
6864562Sgshapiroint	use_inet6 = 0;
6938032Speterwordtab_t *pool_fields = NULL;
7038032Speterint	nohdrfields = 0;
7190792Sgshapiro
7238032Speter
7338032Spetervoid
7438032Speterusage(prog)
7538032Speter	char *prog;
7638032Speter{
7738032Speter	fprintf(stderr, "Usage:\t%s\n", prog);
7890792Sgshapiro	fprintf(stderr, "\t-a [-dnv] [-m <name>] [-o <role>] [-t type] [-T ttl] -i <ipaddr>[/netmask]\n");
7938032Speter	fprintf(stderr, "\t-A [-dnv] [-m <name>] [-o <role>] [-S <seed>] [-t <type>]\n");
8090792Sgshapiro	fprintf(stderr, "\t-f <file> [-dnuv]\n");
8138032Speter	fprintf(stderr, "\t-F [-dv] [-o <role>] [-t <type>]\n");
8264562Sgshapiro	fprintf(stderr, "\t-l [-dv] [-m <name>] [-t <type>] [-O <fields>]\n");
8338032Speter	fprintf(stderr, "\t-r [-dnv] [-m <name>] [-o <role>] [-t type] -i <ipaddr>[/netmask]\n");
8438032Speter	fprintf(stderr, "\t-R [-dnv] [-m <name>] [-o <role>] [-t <type>]\n");
8538032Speter	fprintf(stderr, "\t-s [-dtv] [-M <core>] [-N <namelist>]\n");
8638032Speter	exit(1);
8738032Speter}
8838032Speter
8938032Speter
9038032Speterint
9190792Sgshapiromain(argc, argv)
9238032Speter	int argc;
9338032Speter	char *argv[];
9438032Speter{
9538032Speter	int err = 1;
96168515Sgshapiro
97168515Sgshapiro	if (argc < 2)
9838032Speter		usage(argv[0]);
9938032Speter
10038032Speter	assigndefined(getenv("IPPOOL_PREDEFINED"));
10190792Sgshapiro
10264562Sgshapiro	switch (getopt(argc, argv, "aAf:FlnrRsv"))
10338032Speter	{
10438032Speter	case 'a' :
10590792Sgshapiro		err = poolnodecommand(0, argc, argv);
10638032Speter		break;
10738032Speter	case 'A' :
10890792Sgshapiro		err = poolcommand(0, argc, argv);
10938032Speter		break;
11038032Speter	case 'f' :
11138032Speter		err = loadpoolfile(argc, argv, optarg);
11238032Speter		break;
11338032Speter	case 'F' :
11438032Speter		err = poolflush(argc, argv);
11538032Speter		break;
11638032Speter	case 'l' :
11738032Speter		err = poollist(argc, argv);
11838032Speter		break;
11938032Speter	case 'n' :
12038032Speter		opts |= OPT_DONOTHING|OPT_DONTOPEN;
12138032Speter		break;
12238032Speter	case 'r' :
12338032Speter		err = poolnodecommand(1, argc, argv);
12438032Speter		break;
12538032Speter	case 'R' :
12690792Sgshapiro		err = poolcommand(1, argc, argv);
12738032Speter		break;
12838032Speter	case 's' :
12938032Speter		err = poolstats(argc, argv);
13038032Speter		break;
13138032Speter	case 'v' :
13238032Speter		opts |= OPT_VERBOSE;
13338032Speter		break;
13438032Speter	default :
13538032Speter		exit(1);
13690792Sgshapiro	}
13790792Sgshapiro
13890792Sgshapiro	if (err != 0)
13990792Sgshapiro		exit(1);
14090792Sgshapiro	return 0;
14138032Speter}
14238032Speter
14338032Speter
14438032Speterint
14538032Speterpoolnodecommand(remove, argc, argv)
14638032Speter	int remove, argc;
14738032Speter	char *argv[];
14894334Sgshapiro{
14990792Sgshapiro	int err = 0, c, ipset, role, type = IPLT_POOL, ttl = 0;
15090792Sgshapiro	char *poolname = NULL;
15190792Sgshapiro	ip_pool_node_t pnode;
15294334Sgshapiro	iphtent_t hnode;
15394334Sgshapiro	void *ptr = &pnode;
15494334Sgshapiro
15594334Sgshapiro	ipset = 0;
15694334Sgshapiro	role = IPL_LOGIPF;
15794334Sgshapiro	bzero((char *)&pnode, sizeof(pnode));
15894334Sgshapiro	bzero((char *)&hnode, sizeof(hnode));
15994334Sgshapiro
16090792Sgshapiro	while ((c = getopt(argc, argv, "di:m:no:Rt:T:v")) != -1)
16190792Sgshapiro		switch (c)
16238032Speter		{
16338032Speter		case 'd' :
16438032Speter			opts |= OPT_DEBUG;
16538032Speter			ippool_yydebug++;
16638032Speter			break;
16790792Sgshapiro		case 'i' :
16864562Sgshapiro			if (setnodeaddr(type, role, ptr, optarg) == 0)
16994334Sgshapiro				ipset = 1;
17094334Sgshapiro			break;
17194334Sgshapiro		case 'm' :
17238032Speter			poolname = optarg;
17394334Sgshapiro			break;
17438032Speter		case 'n' :
17538032Speter			opts |= OPT_DONOTHING|OPT_DONTOPEN;
17690792Sgshapiro			break;
17790792Sgshapiro		case 'o' :
17890792Sgshapiro			if (ipset == 1) {
17990792Sgshapiro				fprintf(stderr,
18090792Sgshapiro					"cannot set role after ip address\n");
18190792Sgshapiro				return -1;
18290792Sgshapiro			}
183168515Sgshapiro			role = getrole(optarg);
18490792Sgshapiro			if (role == IPL_LOGNONE)
18590792Sgshapiro				return -1;
18690792Sgshapiro			break;
18790792Sgshapiro		case 'R' :
18890792Sgshapiro			opts |= OPT_NORESOLVE;
18990792Sgshapiro			break;
19090792Sgshapiro		case 't' :
19190792Sgshapiro			if (ipset == 1) {
19290792Sgshapiro				fprintf(stderr,
19390792Sgshapiro					"cannot set type after ip address\n");
19490792Sgshapiro				return -1;
19590792Sgshapiro			}
19690792Sgshapiro			type = gettype(optarg, NULL);
19790792Sgshapiro			switch (type) {
19890792Sgshapiro			case IPLT_NONE :
19990792Sgshapiro				fprintf(stderr, "unknown type '%s'\n", optarg);
20090792Sgshapiro				return -1;
20190792Sgshapiro			case IPLT_HASH :
20290792Sgshapiro				ptr = &hnode;
20390792Sgshapiro				break;
20490792Sgshapiro			case IPLT_POOL :
20590792Sgshapiro			default :
20690792Sgshapiro				break;
20790792Sgshapiro			}
20890792Sgshapiro			break;
20990792Sgshapiro		case 'T' :
21038032Speter			ttl = atoi(optarg);
21138032Speter			if (ttl < 0) {
21238032Speter				fprintf(stderr, "cannot set negative ttl\n");
21364562Sgshapiro				return -1;
21438032Speter			}
21538032Speter			break;
21638032Speter		case 'v' :
21738032Speter			opts |= OPT_VERBOSE;
21838032Speter			break;
21938032Speter		}
220173340Sgshapiro
22138032Speter	if (argv[optind] != NULL && ipset == 0) {
22238032Speter		if (setnodeaddr(type, role, ptr, argv[optind]) == 0)
22390792Sgshapiro			ipset = 1;
22464562Sgshapiro	}
22538032Speter
22638032Speter	if (opts & OPT_DEBUG)
22738032Speter		fprintf(stderr, "poolnodecommand: opts = %#x\n", opts);
22838032Speter
22938032Speter	if (ipset == 0) {
23038032Speter		fprintf(stderr, "no IP address given with -i\n");
23138032Speter		return -1;
23238032Speter	}
23338032Speter
23490792Sgshapiro	if (poolname == NULL) {
235132943Sgshapiro		fprintf(stderr, "poolname not given with add/remove node\n");
23638032Speter		return -1;
23738032Speter	}
23864562Sgshapiro
23938032Speter	switch (type) {
24090792Sgshapiro	case IPLT_POOL :
24190792Sgshapiro		if (remove == 0)
24238032Speter			err = load_poolnode(role, poolname, &pnode, ttl, ioctl);
24338032Speter		else
24438032Speter			err = remove_poolnode(role, poolname, &pnode, ioctl);
24590792Sgshapiro		break;
24690792Sgshapiro	case IPLT_HASH :
24790792Sgshapiro		if (remove == 0)
24838032Speter			err = load_hashnode(role, poolname, &hnode, ttl, ioctl);
24938032Speter		else
25090792Sgshapiro			err = remove_hashnode(role, poolname, &hnode, ioctl);
25190792Sgshapiro		break;
25290792Sgshapiro	default :
25338032Speter		break;
25438032Speter	}
25538032Speter	return err;
25690792Sgshapiro}
25738032Speter
25838032Speter
25990792Sgshapiroint
26038032Speterpoolcommand(remove, argc, argv)
26190792Sgshapiro	int remove, argc;
26238032Speter	char *argv[];
26394334Sgshapiro{
26490792Sgshapiro	int type, role, c, err;
26538032Speter	char *poolname;
26638032Speter	iphtable_t iph;
26738032Speter	ip_pool_t pool;
26890792Sgshapiro
26938032Speter	err = 1;
27090792Sgshapiro	role = 0;
27190792Sgshapiro	type = 0;
27238032Speter	poolname = NULL;
27390792Sgshapiro	role = IPL_LOGIPF;
27438032Speter	bzero((char *)&iph, sizeof(iph));
275168515Sgshapiro	bzero((char *)&pool, sizeof(pool));
27690792Sgshapiro
27790792Sgshapiro	while ((c = getopt(argc, argv, "dm:no:RSv")) != -1)
27890792Sgshapiro		switch (c)
27994334Sgshapiro		{
28090792Sgshapiro		case 'd' :
28190792Sgshapiro			opts |= OPT_DEBUG;
28290792Sgshapiro			ippool_yydebug++;
28394334Sgshapiro			break;
28494334Sgshapiro		case 'm' :
28594334Sgshapiro			poolname = optarg;
28694334Sgshapiro			break;
28794334Sgshapiro		case 'n' :
28894334Sgshapiro			opts |= OPT_DONOTHING|OPT_DONTOPEN;
28990792Sgshapiro			break;
29090792Sgshapiro		case 'o' :
29190792Sgshapiro			role = getrole(optarg);
29238032Speter			if (role == IPL_LOGNONE) {
29390792Sgshapiro				fprintf(stderr, "unknown role '%s'\n", optarg);
29490792Sgshapiro				return -1;
29590792Sgshapiro			}
29694334Sgshapiro			break;
29794334Sgshapiro		case 'R' :
29890792Sgshapiro			opts |= OPT_NORESOLVE;
29994334Sgshapiro			break;
30094334Sgshapiro		case 'S' :
30190792Sgshapiro			iph.iph_seed = atoi(optarg);
30290792Sgshapiro			break;
30390792Sgshapiro		case 'v' :
30490792Sgshapiro			opts |= OPT_VERBOSE;
30590792Sgshapiro			break;
30690792Sgshapiro		}
30790792Sgshapiro
30890792Sgshapiro	if (opts & OPT_DEBUG)
30990792Sgshapiro		fprintf(stderr, "poolcommand: opts = %#x\n", opts);
31090792Sgshapiro
31190792Sgshapiro	if (poolname == NULL) {
31290792Sgshapiro		fprintf(stderr, "poolname not given with add/remove pool\n");
31390792Sgshapiro		return -1;
31490792Sgshapiro	}
31590792Sgshapiro
31690792Sgshapiro	type = gettype(argv[optind], &iph.iph_type);
31790792Sgshapiro	if (type == IPLT_NONE) {
31894334Sgshapiro		fprintf(stderr, "unknown type '%s'\n", argv[optind]);
31994334Sgshapiro		return -1;
32090792Sgshapiro	}
32190792Sgshapiro
32290792Sgshapiro	if (type == IPLT_HASH) {
32390792Sgshapiro		strncpy(iph.iph_name, poolname, sizeof(iph.iph_name));
32490792Sgshapiro		iph.iph_name[sizeof(iph.iph_name) - 1] = '\0';
32590792Sgshapiro		iph.iph_unit = role;
32690792Sgshapiro	} else if (type == IPLT_POOL) {
32790792Sgshapiro		strncpy(pool.ipo_name, poolname, sizeof(pool.ipo_name));
32894334Sgshapiro		pool.ipo_name[sizeof(pool.ipo_name) - 1] = '\0';
32990792Sgshapiro		pool.ipo_unit = role;
33094334Sgshapiro	}
33190792Sgshapiro
33294334Sgshapiro	if (remove == 0) {
33390792Sgshapiro		switch (type)
33494334Sgshapiro		{
33594334Sgshapiro		case IPLT_HASH :
33690792Sgshapiro			err = load_hash(&iph, NULL, ioctl);
33790792Sgshapiro			break;
33890792Sgshapiro		case IPLT_POOL :
33938032Speter			err = load_pool(&pool, ioctl);
34038032Speter			break;
34194334Sgshapiro		}
34294334Sgshapiro	} else {
34394334Sgshapiro		switch (type)
34494334Sgshapiro		{
34594334Sgshapiro		case IPLT_HASH :
34694334Sgshapiro			err = remove_hash(&iph, ioctl);
34794334Sgshapiro			break;
34894334Sgshapiro		case IPLT_POOL :
34994334Sgshapiro			err = remove_pool(&pool, ioctl);
35094334Sgshapiro			break;
35194334Sgshapiro		}
352168515Sgshapiro	}
35390792Sgshapiro	return err;
35494334Sgshapiro}
35594334Sgshapiro
35694334Sgshapiro
35790792Sgshapiroint
35890792Sgshapiroloadpoolfile(argc, argv, infile)
35990792Sgshapiro	int argc;
36090792Sgshapiro	char *argv[], *infile;
36190792Sgshapiro{
36290792Sgshapiro	int c;
36390792Sgshapiro
36490792Sgshapiro	infile = optarg;
36594334Sgshapiro
36694334Sgshapiro	while ((c = getopt(argc, argv, "dnRuv")) != -1)
36790792Sgshapiro		switch (c)
36890792Sgshapiro		{
36990792Sgshapiro		case 'd' :
370168515Sgshapiro			opts |= OPT_DEBUG;
37190792Sgshapiro			ippool_yydebug++;
37290792Sgshapiro			break;
37394334Sgshapiro		case 'n' :
37494334Sgshapiro			opts |= OPT_DONOTHING|OPT_DONTOPEN;
37594334Sgshapiro			break;
37690792Sgshapiro		case 'R' :
37738032Speter			opts |= OPT_NORESOLVE;
37890792Sgshapiro			break;
37994334Sgshapiro		case 'u' :
38094334Sgshapiro			opts |= OPT_REMOVE;
38138032Speter			break;
38290792Sgshapiro		case 'v' :
38394334Sgshapiro			opts |= OPT_VERBOSE;
38494334Sgshapiro			break;
38590792Sgshapiro		}
38694334Sgshapiro
38794334Sgshapiro	if (opts & OPT_DEBUG)
38838032Speter		fprintf(stderr, "loadpoolfile: opts = %#x\n", opts);
38994334Sgshapiro
39038032Speter	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
39190792Sgshapiro		fd = open(IPLOOKUP_NAME, O_RDWR);
39238032Speter		if (fd == -1) {
39338032Speter			perror("open(IPLOOKUP_NAME)");
39438032Speter			exit(1);
39538032Speter		}
39638032Speter	}
39738032Speter
39838032Speter	if (ippool_parsefile(fd, infile, ioctl) != 0)
39938032Speter		return -1;
40038032Speter	return 0;
40190792Sgshapiro}
40238032Speter
40338032Speter
40438032Speterint
40538032Speterpoolstats(argc, argv)
40638032Speter	int argc;
40738032Speter	char *argv[];
40838032Speter{
40938032Speter	int c, type, role, live_kernel;
41064562Sgshapiro	ipf_pool_stat_t plstat;
41190792Sgshapiro	ipf_dstl_stat_t dlstat;
41238032Speter	char *kernel, *core;
41338032Speter	iphtstat_t htstat;
41438032Speter	iplookupop_t op;
41590792Sgshapiro
41638032Speter	core = NULL;
41738032Speter	kernel = NULL;
41890792Sgshapiro	live_kernel = 1;
41938032Speter	type = IPLT_ALL;
42038032Speter	role = IPL_LOGALL;
42138032Speter
42238032Speter	bzero((char *)&op, sizeof(op));
42390792Sgshapiro
42438032Speter	while ((c = getopt(argc, argv, "dM:N:o:t:v")) != -1)
42590792Sgshapiro		switch (c)
42638032Speter		{
42738032Speter		case 'd' :
42838032Speter			opts |= OPT_DEBUG;
42990792Sgshapiro			break;
43038032Speter		case 'M' :
43190792Sgshapiro			live_kernel = 0;
43238032Speter			core = optarg;
43338032Speter			break;
43438032Speter		case 'N' :
43590792Sgshapiro			live_kernel = 0;
43690792Sgshapiro			kernel = optarg;
43738032Speter			break;
438168515Sgshapiro		case 'o' :
43990792Sgshapiro			role = getrole(optarg);
44038032Speter			if (role == IPL_LOGNONE) {
44138032Speter				fprintf(stderr, "unknown role '%s'\n", optarg);
44238032Speter				return -1;
44364562Sgshapiro			}
44464562Sgshapiro			break;
44538032Speter		case 't' :
44638032Speter			type = gettype(optarg, NULL);
44738032Speter			if (type != IPLT_POOL) {
44838032Speter				fprintf(stderr,
44938032Speter					"-s not supported for this type yet\n");
45038032Speter				return -1;
45138032Speter			}
45238032Speter			break;
45338032Speter		case 'v' :
45438032Speter			opts |= OPT_VERBOSE;
45538032Speter			break;
45638032Speter		}
45738032Speter
45838032Speter	if (opts & OPT_DEBUG)
45938032Speter		fprintf(stderr, "poolstats: opts = %#x\n", opts);
46038032Speter
46138032Speter	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
46238032Speter		fd = open(IPLOOKUP_NAME, O_RDWR);
46338032Speter		if (fd == -1) {
46438032Speter			perror("open(IPLOOKUP_NAME)");
46538032Speter			exit(1);
46638032Speter		}
46738032Speter	}
468132943Sgshapiro
46938032Speter	if (type == IPLT_ALL || type == IPLT_POOL) {
47038032Speter		op.iplo_type = IPLT_POOL;
47138032Speter		op.iplo_struct = &plstat;
47238032Speter		op.iplo_size = sizeof(plstat);
47338032Speter		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
47438032Speter			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
47538032Speter			if (c == -1) {
47664562Sgshapiro				ipferror(fd, "ioctl(S0IOCLOOKUPSTAT)");
47764562Sgshapiro				return -1;
47864562Sgshapiro			}
47964562Sgshapiro			printf("%lu\taddress pools\n", plstat.ipls_pools);
48064562Sgshapiro			printf("%lu\taddress pool nodes\n", plstat.ipls_nodes);
48164562Sgshapiro		}
48238032Speter	}
48364562Sgshapiro
48464562Sgshapiro	if (type == IPLT_ALL || type == IPLT_HASH) {
48538032Speter		op.iplo_type = IPLT_HASH;
48638032Speter		op.iplo_struct = &htstat;
48764562Sgshapiro		op.iplo_size = sizeof(htstat);
48864562Sgshapiro		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
48964562Sgshapiro			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
49038032Speter			if (c == -1) {
49138032Speter				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
49238032Speter				return -1;
49338032Speter			}
49438032Speter			printf("%lu\thash tables\n", htstat.iphs_numtables);
49538032Speter			printf("%lu\thash table nodes\n", htstat.iphs_numnodes);
49638032Speter			printf("%lu\thash table no memory \n",
49738032Speter				htstat.iphs_nomem);
49838032Speter		}
499168515Sgshapiro	}
50038032Speter
50138032Speter	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
502168515Sgshapiro		op.iplo_type = IPLT_DSTLIST;
503168515Sgshapiro		op.iplo_struct = &dlstat;
504168515Sgshapiro		op.iplo_size = sizeof(dlstat);
505168515Sgshapiro		if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
50638032Speter			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
50738032Speter			if (c == -1) {
50838032Speter				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
50938032Speter				return -1;
51038032Speter			}
51138032Speter			printf("%u\tdestination lists\n",
51264562Sgshapiro			       dlstat.ipls_numlists);
51338032Speter			printf("%u\tdestination list nodes\n",
51438032Speter			       dlstat.ipls_numnodes);
51538032Speter			printf("%lu\tdestination list no memory\n",
51638032Speter			       dlstat.ipls_nomem);
51738032Speter			printf("%u\tdestination list zombies\n",
51838032Speter			       dlstat.ipls_numdereflists);
51938032Speter			printf("%u\tdesetination list node zombies\n",
52038032Speter			       dlstat.ipls_numderefnodes);
52138032Speter		}
52238032Speter	}
52338032Speter	return 0;
52438032Speter}
525168515Sgshapiro
526168515Sgshapiro
527168515Sgshapiroint
528168515Sgshapiropoolflush(argc, argv)
529168515Sgshapiro	int argc;
530168515Sgshapiro	char *argv[];
531168515Sgshapiro{
532168515Sgshapiro	int c, role, type, arg;
533168515Sgshapiro	iplookupflush_t flush;
534168515Sgshapiro
535168515Sgshapiro	arg = IPLT_ALL;
536168515Sgshapiro	type = IPLT_ALL;
537168515Sgshapiro	role = IPL_LOGALL;
538168515Sgshapiro
539168515Sgshapiro	while ((c = getopt(argc, argv, "do:t:v")) != -1)
540168515Sgshapiro		switch (c)
541168515Sgshapiro		{
542168515Sgshapiro		case 'd' :
543168515Sgshapiro			opts |= OPT_DEBUG;
544168515Sgshapiro			break;
545168515Sgshapiro		case 'o' :
546168515Sgshapiro			role = getrole(optarg);
547168515Sgshapiro			if (role == IPL_LOGNONE) {
548168515Sgshapiro				fprintf(stderr, "unknown role '%s'\n", optarg);
549168515Sgshapiro				return -1;
550168515Sgshapiro			}
551168515Sgshapiro			break;
552168515Sgshapiro		case 't' :
553168515Sgshapiro			type = gettype(optarg, NULL);
554168515Sgshapiro			if (type == IPLT_NONE) {
555168515Sgshapiro				fprintf(stderr, "unknown type '%s'\n", optarg);
556168515Sgshapiro				return -1;
557168515Sgshapiro			}
558168515Sgshapiro			break;
559168515Sgshapiro		case 'v' :
560168515Sgshapiro			opts |= OPT_VERBOSE;
561168515Sgshapiro			break;
562168515Sgshapiro		}
56338032Speter
56438032Speter	if (opts & OPT_DEBUG)
56538032Speter		fprintf(stderr, "poolflush: opts = %#x\n", opts);
56638032Speter
56738032Speter	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
56838032Speter		fd = open(IPLOOKUP_NAME, O_RDWR);
56938032Speter		if (fd == -1) {
57038032Speter			perror("open(IPLOOKUP_NAME)");
57138032Speter			exit(1);
57238032Speter		}
57338032Speter	}
57438032Speter
57538032Speter	bzero((char *)&flush, sizeof(flush));
57638032Speter	flush.iplf_type = type;
577168515Sgshapiro	flush.iplf_unit = role;
57838032Speter	flush.iplf_arg = arg;
57938032Speter
58038032Speter	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN))) {
58190792Sgshapiro		if (ioctl(fd, SIOCLOOKUPFLUSH, &flush) == -1) {
58238032Speter			ipferror(fd, "ioctl(SIOCLOOKUPFLUSH)");
58338032Speter			exit(1);
58438032Speter		}
58538032Speter
58638032Speter	}
58738032Speter	printf("%u object%s flushed\n", flush.iplf_count,
58864562Sgshapiro	       (flush.iplf_count == 1) ? "" : "s");
58938032Speter
59038032Speter	return 0;
59138032Speter}
59238032Speter
59338032Speter
59438032Speterint
59538032Spetergetrole(rolename)
59638032Speter	char *rolename;
59738032Speter{
59838032Speter	int role;
59938032Speter
60038032Speter	if (!strcasecmp(rolename, "ipf")) {
60138032Speter		role = IPL_LOGIPF;
60238032Speter#if 0
60338032Speter	} else if (!strcasecmp(rolename, "nat")) {
60438032Speter		role = IPL_LOGNAT;
60538032Speter	} else if (!strcasecmp(rolename, "state")) {
60638032Speter		role = IPL_LOGSTATE;
60738032Speter	} else if (!strcasecmp(rolename, "auth")) {
60838032Speter		role = IPL_LOGAUTH;
60938032Speter	} else if (!strcasecmp(rolename, "sync")) {
61038032Speter		role = IPL_LOGSYNC;
61138032Speter	} else if (!strcasecmp(rolename, "scan")) {
61238032Speter		role = IPL_LOGSCAN;
61338032Speter	} else if (!strcasecmp(rolename, "pool")) {
61438032Speter		role = IPL_LOGLOOKUP;
615168515Sgshapiro	} else if (!strcasecmp(rolename, "count")) {
61638032Speter		role = IPL_LOGCOUNT;
61738032Speter#endif
61864562Sgshapiro	} else {
61990792Sgshapiro		role = IPL_LOGNONE;
62064562Sgshapiro	}
62164562Sgshapiro
62264562Sgshapiro	return role;
62364562Sgshapiro}
62464562Sgshapiro
62564562Sgshapiro
62664562Sgshapiroint
62764562Sgshapirogettype(typename, minor)
62864562Sgshapiro	char *typename;
62964562Sgshapiro	u_int *minor;
63064562Sgshapiro{
63164562Sgshapiro	int type;
63264562Sgshapiro
63364562Sgshapiro	if (!strcasecmp(typename, "tree") || !strcasecmp(typename, "pool")) {
63464562Sgshapiro		type = IPLT_POOL;
63564562Sgshapiro	} else if (!strcasecmp(typename, "hash")) {
63664562Sgshapiro		type = IPLT_HASH;
63738032Speter		if (minor != NULL)
63864562Sgshapiro			*minor = IPHASH_LOOKUP;
63964562Sgshapiro	} else if (!strcasecmp(typename, "group-map")) {
64064562Sgshapiro		type = IPLT_HASH;
64164562Sgshapiro		if (minor != NULL)
64264562Sgshapiro			*minor = IPHASH_GROUPMAP;
64364562Sgshapiro	} else {
64464562Sgshapiro		type = IPLT_NONE;
64564562Sgshapiro	}
64664562Sgshapiro	return type;
64764562Sgshapiro}
64864562Sgshapiro
64964562Sgshapiro
65064562Sgshapiroint
65164562Sgshapiropoollist(argc, argv)
65264562Sgshapiro	int argc;
653168515Sgshapiro	char *argv[];
65464562Sgshapiro{
65538032Speter	char *kernel, *core, *poolname;
65664562Sgshapiro	int c, role, type, live_kernel;
657112810Sgshapiro	iplookupop_t op;
65864562Sgshapiro
65938032Speter	core = NULL;
660132943Sgshapiro	kernel = NULL;
66138032Speter	live_kernel = 1;
66238032Speter	type = IPLT_ALL;
66338032Speter	poolname = NULL;
66438032Speter	role = IPL_LOGALL;
66538032Speter
66690792Sgshapiro	while ((c = getopt(argc, argv, "dm:M:N:o:Rt:v")) != -1)
667132943Sgshapiro		switch (c)
66838032Speter		{
66938032Speter		case 'd' :
67038032Speter			opts |= OPT_DEBUG;
67138032Speter			break;
67238032Speter		case 'm' :
67338032Speter			poolname = optarg;
67438032Speter			break;
67538032Speter		case 'M' :
67638032Speter			live_kernel = 0;
67738032Speter			core = optarg;
67838032Speter			break;
67938032Speter		case 'N' :
68038032Speter			live_kernel = 0;
68164562Sgshapiro			kernel = optarg;
68290792Sgshapiro			break;
68338032Speter		case 'o' :
68438032Speter			role = getrole(optarg);
68538032Speter			if (role == IPL_LOGNONE) {
68638032Speter				fprintf(stderr, "unknown role '%s'\n", optarg);
68738032Speter				return -1;
68838032Speter			}
68990792Sgshapiro			break;
69038032Speter		case 'O' :
69138032Speter			pool_fields = parsefields(poolfields, optarg);
69238032Speter			break;
69338032Speter		case 'R' :
69438032Speter			opts |= OPT_NORESOLVE;
69538032Speter			break;
69638032Speter		case 't' :
697168515Sgshapiro			type = gettype(optarg, NULL);
69864562Sgshapiro			if (type == IPLT_NONE) {
699168515Sgshapiro				fprintf(stderr, "unknown type '%s'\n", optarg);
70038032Speter				return -1;
70138032Speter			}
702168515Sgshapiro			break;
703168515Sgshapiro		case 'v' :
704168515Sgshapiro			opts |= OPT_VERBOSE;
705168515Sgshapiro			break;
70664562Sgshapiro		}
70764562Sgshapiro
70838032Speter	if (opts & OPT_DEBUG)
70938032Speter		fprintf(stderr, "poollist: opts = %#x\n", opts);
71038032Speter
711168515Sgshapiro	if (!(opts & (OPT_DONOTHING|OPT_DONTOPEN)) && (fd == -1)) {
71238032Speter		fd = open(IPLOOKUP_NAME, O_RDWR);
71338032Speter		if (fd == -1) {
71438032Speter			perror("open(IPLOOKUP_NAME)");
71538032Speter			exit(1);
71638032Speter		}
71790792Sgshapiro	}
71890792Sgshapiro
71938032Speter	bzero((char *)&op, sizeof(op));
72038032Speter	if (poolname != NULL) {
72138032Speter		strncpy(op.iplo_name, poolname, sizeof(op.iplo_name));
72238032Speter		op.iplo_name[sizeof(op.iplo_name) - 1] = '\0';
72338032Speter	}
72438032Speter	op.iplo_unit = role;
72538032Speter
72638032Speter	if (live_kernel)
72738032Speter		poollist_live(role, poolname, type, fd);
72890792Sgshapiro	else
729132943Sgshapiro		poollist_dead(role, poolname, type, kernel, core);
73090792Sgshapiro	return 0;
73138032Speter}
73238032Speter
73338032Speter
73438032Spetervoid
73538032Speterpoollist_dead(role, poolname, type, kernel, core)
73638032Speter	int role, type;
73738032Speter	char *poolname, *kernel, *core;
73838032Speter{
73938032Speter	iphtable_t *hptr;
74038032Speter	ip_pool_t *ptr;
74138032Speter
74238032Speter	if (openkmem(kernel, core) == -1)
74338032Speter		exit(-1);
74438032Speter
745112810Sgshapiro	if (type == IPLT_ALL || type == IPLT_POOL) {
74664562Sgshapiro		ip_pool_t *pools[IPL_LOGSIZE];
74790792Sgshapiro		struct nlist names[2] = { { "ip_pool_list" } , { "" } };
74838032Speter
74938032Speter		if (nlist(kernel, names) != 1)
75038032Speter			return;
751120169Snectar
752120169Snectar		bzero(&pools, sizeof(pools));
753120256Sgshapiro		if (kmemcpy((char *)&pools, names[0].n_value, sizeof(pools)))
75438032Speter			return;
755120169Snectar
75638032Speter		if (role != IPL_LOGALL) {
75764562Sgshapiro			ptr = pools[role];
75838032Speter			while (ptr != NULL) {
75938032Speter				ptr = printpool(ptr, kmemcpywrap, poolname,
76038032Speter						opts, pool_fields);
761112810Sgshapiro			}
762168515Sgshapiro		} else {
763168515Sgshapiro			for (role = 0; role <= IPL_LOGMAX; role++) {
764112810Sgshapiro				ptr = pools[role];
765112810Sgshapiro				while (ptr != NULL) {
76638032Speter					ptr = printpool(ptr, kmemcpywrap,
76738032Speter							poolname, opts,
76838032Speter							pool_fields);
76938032Speter				}
770112810Sgshapiro			}
77138032Speter			role = IPL_LOGALL;
77238032Speter		}
77338032Speter	}
774132943Sgshapiro	if (type == IPLT_ALL || type == IPLT_HASH) {
775132943Sgshapiro		iphtable_t *tables[IPL_LOGSIZE];
776132943Sgshapiro		struct nlist names[2] = { { "ipf_htables" } , { "" } };
77738032Speter
77890792Sgshapiro		if (nlist(kernel, names) != 1)
77938032Speter			return;
78038032Speter
78138032Speter		bzero(&tables, sizeof(tables));
78238032Speter		if (kmemcpy((char *)&tables, names[0].n_value, sizeof(tables)))
78390792Sgshapiro			return;
78438032Speter
78538032Speter		if (role != IPL_LOGALL) {
78638032Speter			hptr = tables[role];
78738032Speter			while (hptr != NULL) {
78838032Speter				hptr = printhash(hptr, kmemcpywrap,
78990792Sgshapiro						 poolname, opts, pool_fields);
79038032Speter			}
79138032Speter		} else {
79238032Speter			for (role = 0; role <= IPL_LOGMAX; role++) {
79338032Speter				hptr = tables[role];
79438032Speter				while (hptr != NULL) {
79538032Speter					hptr = printhash(hptr, kmemcpywrap,
79638032Speter							 poolname, opts,
79738032Speter							 pool_fields);
79838032Speter				}
79938032Speter			}
80038032Speter		}
80138032Speter	}
802132943Sgshapiro}
80338032Speter
80490792Sgshapiro
80538032Spetervoid
80638032Speterpoollist_live(role, poolname, type, fd)
80738032Speter	int role, type, fd;
80838032Speter	char *poolname;
80938032Speter{
81038032Speter	ipf_pool_stat_t plstat;
81190792Sgshapiro	iplookupop_t op;
81238032Speter	int c;
81338032Speter
81438032Speter	if (type == IPLT_ALL || type == IPLT_POOL) {
81538032Speter		op.iplo_type = IPLT_POOL;
81638032Speter		op.iplo_size = sizeof(plstat);
81790792Sgshapiro		op.iplo_struct = &plstat;
81838032Speter		op.iplo_name[0] = '\0';
81938032Speter		op.iplo_arg = 0;
82038032Speter
82138032Speter		if (role != IPL_LOGALL) {
82238032Speter			op.iplo_unit = role;
82338032Speter
82438032Speter			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
82538032Speter			if (c == -1) {
82638032Speter				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
827112810Sgshapiro				return;
828112810Sgshapiro			}
829112810Sgshapiro
83038032Speter			showpools_live(fd, role, &plstat, poolname);
83138032Speter		} else {
83238032Speter			for (role = -1; role <= IPL_LOGMAX; role++) {
83338032Speter				op.iplo_unit = role;
83438032Speter
83538032Speter				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
83638032Speter				if (c == -1) {
83790792Sgshapiro					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
83838032Speter					return;
83938032Speter				}
84038032Speter
84164562Sgshapiro				showpools_live(fd, role, &plstat, poolname);
84238032Speter			}
84338032Speter
84464562Sgshapiro			role = IPL_LOGALL;
84538032Speter		}
84638032Speter	}
84738032Speter
84838032Speter	if (type == IPLT_ALL || type == IPLT_HASH) {
84964562Sgshapiro		iphtstat_t htstat;
85038032Speter
85138032Speter		op.iplo_type = IPLT_HASH;
85238032Speter		op.iplo_size = sizeof(htstat);
853132943Sgshapiro		op.iplo_struct = &htstat;
854132943Sgshapiro		op.iplo_name[0] = '\0';
855132943Sgshapiro		op.iplo_arg = 0;
856132943Sgshapiro
857132943Sgshapiro		if (role != IPL_LOGALL) {
85838032Speter			op.iplo_unit = role;
85938032Speter
86038032Speter			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
86138032Speter			if (c == -1) {
86238032Speter				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
86364562Sgshapiro				return;
86438032Speter			}
86564562Sgshapiro			showhashs_live(fd, role, &htstat, poolname);
86638032Speter		} else {
86738032Speter			for (role = 0; role <= IPL_LOGMAX; role++) {
86864562Sgshapiro
86938032Speter				op.iplo_unit = role;
87038032Speter				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
87164562Sgshapiro				if (c == -1) {
87264562Sgshapiro					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
87364562Sgshapiro					return;
87490792Sgshapiro				}
87538032Speter
87638032Speter				showhashs_live(fd, role, &htstat, poolname);
87738032Speter			}
87838032Speter			role = IPL_LOGALL;
87938032Speter		}
880132943Sgshapiro	}
881132943Sgshapiro
882132943Sgshapiro	if (type == IPLT_ALL || type == IPLT_DSTLIST) {
883132943Sgshapiro		ipf_dstl_stat_t dlstat;
884132943Sgshapiro
88538032Speter		op.iplo_type = IPLT_DSTLIST;
88638032Speter		op.iplo_size = sizeof(dlstat);
88738032Speter		op.iplo_struct = &dlstat;
88890792Sgshapiro		op.iplo_name[0] = '\0';
88938032Speter		op.iplo_arg = 0;
89038032Speter
89138032Speter		if (role != IPL_LOGALL) {
89238032Speter			op.iplo_unit = role;
89338032Speter
89438032Speter			c = ioctl(fd, SIOCLOOKUPSTAT, &op);
89538032Speter			if (c == -1) {
89638032Speter				ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
89738032Speter				return;
89838032Speter			}
89938032Speter			showdstls_live(fd, role, &dlstat, poolname);
90038032Speter		} else {
90138032Speter			for (role = 0; role <= IPL_LOGMAX; role++) {
90290792Sgshapiro
90338032Speter				op.iplo_unit = role;
90438032Speter				c = ioctl(fd, SIOCLOOKUPSTAT, &op);
90538032Speter				if (c == -1) {
90638032Speter					ipferror(fd, "ioctl(SIOCLOOKUPSTAT)");
90790792Sgshapiro					return;
90838032Speter				}
90990792Sgshapiro
91090792Sgshapiro				showdstls_live(fd, role, &dlstat, poolname);
91138032Speter			}
91238032Speter			role = IPL_LOGALL;
91338032Speter		}
91438032Speter	}
91538032Speter}
91638032Speter
91738032Speter
91838032Spetervoid
91938032Spetershowpools_live(fd, role, plstp, poolname)
92038032Speter	int fd, role;
921112810Sgshapiro	ipf_pool_stat_t *plstp;
922112810Sgshapiro	char *poolname;
923112810Sgshapiro{
92438032Speter	ipflookupiter_t iter;
92538032Speter	ip_pool_t pool;
92638032Speter	ipfobj_t obj;
92790792Sgshapiro
928132943Sgshapiro	obj.ipfo_rev = IPFILTER_VERSION;
92990792Sgshapiro	obj.ipfo_type = IPFOBJ_LOOKUPITER;
93038032Speter	obj.ipfo_size = sizeof(iter);
93138032Speter	obj.ipfo_ptr = &iter;
93238032Speter
93364562Sgshapiro	iter.ili_type = IPLT_POOL;
93438032Speter	iter.ili_otype = IPFLOOKUPITER_LIST;
93538032Speter	iter.ili_ival = IPFGENITER_LOOKUP;
93638032Speter	iter.ili_nitems = 1;
93738032Speter	iter.ili_data = &pool;
93864562Sgshapiro	iter.ili_unit = role;
93938032Speter	*iter.ili_name = '\0';
94038032Speter
94138032Speter	bzero((char *)&pool, sizeof(pool));
94238032Speter
94338032Speter	while (plstp->ipls_list[role + 1] != NULL) {
94438032Speter		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
94538032Speter			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
946120256Sgshapiro			break;
947120256Sgshapiro		}
948120256Sgshapiro		if (((pool.ipo_flags & IPOOL_DELETE) == 0) ||
94938032Speter		    ((opts & OPT_DEBUG) != 0))
950120256Sgshapiro			printpool_live(&pool, fd, poolname, opts, pool_fields);
95138032Speter
95238032Speter		plstp->ipls_list[role + 1] = pool.ipo_next;
95390792Sgshapiro	}
954132943Sgshapiro}
95538032Speter
95638032Speter
95738032Spetervoid
95838032Spetershowhashs_live(fd, role, htstp, poolname)
95938032Speter	int fd, role;
96090792Sgshapiro	iphtstat_t *htstp;
96164562Sgshapiro	char *poolname;
96238032Speter{
96364562Sgshapiro	ipflookupiter_t iter;
96438032Speter	iphtable_t table;
96590792Sgshapiro	ipfobj_t obj;
96638032Speter
96738032Speter	obj.ipfo_rev = IPFILTER_VERSION;
96838032Speter	obj.ipfo_type = IPFOBJ_LOOKUPITER;
96938032Speter	obj.ipfo_size = sizeof(iter);
97038032Speter	obj.ipfo_ptr = &iter;
97138032Speter
97238032Speter	iter.ili_type = IPLT_HASH;
97338032Speter	iter.ili_otype = IPFLOOKUPITER_LIST;
97438032Speter	iter.ili_ival = IPFGENITER_LOOKUP;
97538032Speter	iter.ili_nitems = 1;
97638032Speter	iter.ili_data = &table;
97738032Speter	iter.ili_unit = role;
97838032Speter	*iter.ili_name = '\0';
97938032Speter
98038032Speter	while (htstp->iphs_tables != NULL) {
98138032Speter		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
98238032Speter			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
98338032Speter			break;
98438032Speter		}
98538032Speter
98638032Speter		printhash_live(&table, fd, poolname, opts, pool_fields);
98738032Speter
98838032Speter		htstp->iphs_tables = table.iph_next;
98938032Speter	}
99038032Speter}
99138032Speter
99290792Sgshapiro
99338032Spetervoid
99438032Spetershowdstls_live(fd, role, dlstp, poolname)
99538032Speter	int fd, role;
99638032Speter	ipf_dstl_stat_t *dlstp;
99738032Speter	char *poolname;
99838032Speter{
99938032Speter	ipflookupiter_t iter;
100038032Speter	ippool_dst_t table;
100138032Speter	ipfobj_t obj;
100238032Speter
100338032Speter	obj.ipfo_rev = IPFILTER_VERSION;
100464562Sgshapiro	obj.ipfo_type = IPFOBJ_LOOKUPITER;
100564562Sgshapiro	obj.ipfo_size = sizeof(iter);
100664562Sgshapiro	obj.ipfo_ptr = &iter;
100738032Speter
100838032Speter	iter.ili_type = IPLT_DSTLIST;
100938032Speter	iter.ili_otype = IPFLOOKUPITER_LIST;
101090792Sgshapiro	iter.ili_ival = IPFGENITER_LOOKUP;
101138032Speter	iter.ili_nitems = 1;
101238032Speter	iter.ili_data = &table;
101338032Speter	iter.ili_unit = role;
101438032Speter	*iter.ili_name = '\0';
101590792Sgshapiro
101638032Speter	while (dlstp->ipls_list[role] != NULL) {
101738032Speter		if (ioctl(fd, SIOCLOOKUPITER, &obj)) {
101838032Speter			ipferror(fd, "ioctl(SIOCLOOKUPITER)");
101964562Sgshapiro			break;
102064562Sgshapiro		}
102138032Speter
102238032Speter		printdstl_live(&table, fd, poolname, opts, pool_fields);
102338032Speter
102438032Speter		dlstp->ipls_list[role] = table.ipld_next;
102538032Speter	}
102638032Speter}
102738032Speter
102838032Speter
102964562Sgshapiroint
103038032Spetersetnodeaddr(int type, int role, void *ptr, char *arg)
103164562Sgshapiro{
103238032Speter	struct in_addr mask;
1033120256Sgshapiro	char *s;
1034120256Sgshapiro
1035120256Sgshapiro	s = strchr(arg, '/');
1036120256Sgshapiro	if (s == NULL)
1037120256Sgshapiro		mask.s_addr = 0xffffffff;
103864562Sgshapiro	else if (strchr(s, '.') == NULL) {
103938032Speter		if (ntomask(AF_INET, atoi(s + 1), &mask.s_addr) != 0)
104064562Sgshapiro			return -1;
104164562Sgshapiro	} else {
104264562Sgshapiro		mask.s_addr = inet_addr(s + 1);
104364562Sgshapiro	}
104464562Sgshapiro	if (s != NULL)
104564562Sgshapiro		*s = '\0';
1046168515Sgshapiro
104764562Sgshapiro	if (type == IPLT_POOL) {
104864562Sgshapiro		ip_pool_node_t *node = ptr;
104964562Sgshapiro
105064562Sgshapiro		if (node->ipn_addr.adf_family == AF_INET)
105164562Sgshapiro			node->ipn_addr.adf_len = offsetof(addrfamily_t,
105264562Sgshapiro							  adf_addr) +
105364562Sgshapiro						 sizeof(struct in_addr);
105464562Sgshapiro#ifdef USE_INET6
105590792Sgshapiro		else
105690792Sgshapiro			node->ipn_addr.adf_len = offsetof(addrfamily_t,
1057132943Sgshapiro							  adf_addr) +
105838032Speter						 sizeof(struct in6_addr);
105964562Sgshapiro#endif
106038032Speter		node->ipn_addr.adf_addr.in4.s_addr = inet_addr(arg);
106190792Sgshapiro		node->ipn_mask.adf_len = node->ipn_addr.adf_len;
1062132943Sgshapiro		node->ipn_mask.adf_addr.in4.s_addr = mask.s_addr;
106338032Speter	} else if (type == IPLT_HASH) {
106438032Speter		iphtent_t *node = ptr;
106538032Speter
106664562Sgshapiro		node->ipe_addr.in4.s_addr = inet_addr(arg);
106764562Sgshapiro		node->ipe_mask.in4.s_addr = mask.s_addr;
106838032Speter        	node->ipe_family = AF_INET;
106938032Speter        	node->ipe_unit = role;
107038032Speter	}
107138032Speter
1072120256Sgshapiro	return 0;
1073120256Sgshapiro}
107438032Speter