xref: /titanic_53/usr/src/cmd/ipf/tools/ipnat.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
5*7c478bd9Sstevel@tonic-gate  *
6*7c478bd9Sstevel@tonic-gate  * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
7*7c478bd9Sstevel@tonic-gate  *
8*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
9*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
10*7c478bd9Sstevel@tonic-gate  */
11*7c478bd9Sstevel@tonic-gate 
12*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
13*7c478bd9Sstevel@tonic-gate 
14*7c478bd9Sstevel@tonic-gate #include <stdio.h>
15*7c478bd9Sstevel@tonic-gate #include <string.h>
16*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
17*7c478bd9Sstevel@tonic-gate #include <errno.h>
18*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
19*7c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__svr4__)
20*7c478bd9Sstevel@tonic-gate #include <strings.h>
21*7c478bd9Sstevel@tonic-gate #else
22*7c478bd9Sstevel@tonic-gate #include <sys/byteorder.h>
23*7c478bd9Sstevel@tonic-gate #endif
24*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
25*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
26*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
27*7c478bd9Sstevel@tonic-gate #include <unistd.h>
28*7c478bd9Sstevel@tonic-gate #include <stddef.h>
29*7c478bd9Sstevel@tonic-gate #include <sys/file.h>
30*7c478bd9Sstevel@tonic-gate #define _KERNEL
31*7c478bd9Sstevel@tonic-gate #include <sys/uio.h>
32*7c478bd9Sstevel@tonic-gate #undef _KERNEL
33*7c478bd9Sstevel@tonic-gate #include <sys/socket.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
35*7c478bd9Sstevel@tonic-gate #if defined(sun) && (defined(__svr4__) || defined(__SVR4))
36*7c478bd9Sstevel@tonic-gate # include <sys/ioccom.h>
37*7c478bd9Sstevel@tonic-gate # include <sys/sysmacros.h>
38*7c478bd9Sstevel@tonic-gate #endif
39*7c478bd9Sstevel@tonic-gate #include <netinet/in.h>
40*7c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h>
41*7c478bd9Sstevel@tonic-gate #include <netinet/ip.h>
42*7c478bd9Sstevel@tonic-gate #include <netinet/tcp.h>
43*7c478bd9Sstevel@tonic-gate #include <net/if.h>
44*7c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000
45*7c478bd9Sstevel@tonic-gate # include <net/if_var.h>
46*7c478bd9Sstevel@tonic-gate #endif
47*7c478bd9Sstevel@tonic-gate #include <netdb.h>
48*7c478bd9Sstevel@tonic-gate #include <arpa/nameser.h>
49*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h>
50*7c478bd9Sstevel@tonic-gate #include <resolv.h>
51*7c478bd9Sstevel@tonic-gate #include <ctype.h>
52*7c478bd9Sstevel@tonic-gate #include <nlist.h>
53*7c478bd9Sstevel@tonic-gate #include "ipf.h"
54*7c478bd9Sstevel@tonic-gate #include "ipl.h"
55*7c478bd9Sstevel@tonic-gate #include "kmem.h"
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate #ifdef	__hpux
58*7c478bd9Sstevel@tonic-gate # define	nlist	nlist64
59*7c478bd9Sstevel@tonic-gate #endif
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate #if	defined(sun) && !SOLARIS2
62*7c478bd9Sstevel@tonic-gate # define	STRERROR(x)	sys_errlist[x]
63*7c478bd9Sstevel@tonic-gate extern	char	*sys_errlist[];
64*7c478bd9Sstevel@tonic-gate #else
65*7c478bd9Sstevel@tonic-gate # define	STRERROR(x)	strerror(x)
66*7c478bd9Sstevel@tonic-gate #endif
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate #if !defined(lint)
69*7c478bd9Sstevel@tonic-gate static const char sccsid[] ="@(#)ipnat.c	1.9 6/5/96 (C) 1993 Darren Reed";
70*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.20 2003/07/01 16:30:27 darrenr Exp $";
71*7c478bd9Sstevel@tonic-gate #endif
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate #if	SOLARIS
75*7c478bd9Sstevel@tonic-gate #define	bzero(a,b)	memset(a,0,b)
76*7c478bd9Sstevel@tonic-gate #endif
77*7c478bd9Sstevel@tonic-gate int	use_inet6 = 0;
78*7c478bd9Sstevel@tonic-gate char	thishost[MAXHOSTNAMELEN];
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate extern	char	*optarg;
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate void	dostats __P((natstat_t *, int)), flushtable __P((int, int));
83*7c478bd9Sstevel@tonic-gate void	usage __P((char *));
84*7c478bd9Sstevel@tonic-gate int	main __P((int, char*[]));
85*7c478bd9Sstevel@tonic-gate void	showhostmap __P((natstat_t *nsp));
86*7c478bd9Sstevel@tonic-gate void	natstat_dead __P((natstat_t *, char *));
87*7c478bd9Sstevel@tonic-gate 
88*7c478bd9Sstevel@tonic-gate int	opts;
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate void usage(name)
91*7c478bd9Sstevel@tonic-gate char *name;
92*7c478bd9Sstevel@tonic-gate {
93*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "Usage: %s [-CdFhlnrsv] [-f filename]\n", name);
94*7c478bd9Sstevel@tonic-gate 	exit(1);
95*7c478bd9Sstevel@tonic-gate }
96*7c478bd9Sstevel@tonic-gate 
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate int main(argc, argv)
99*7c478bd9Sstevel@tonic-gate int argc;
100*7c478bd9Sstevel@tonic-gate char *argv[];
101*7c478bd9Sstevel@tonic-gate {
102*7c478bd9Sstevel@tonic-gate 	char *file, *core, *kernel;
103*7c478bd9Sstevel@tonic-gate 	natstat_t ns, *nsp;
104*7c478bd9Sstevel@tonic-gate 	int fd, c, mode;
105*7c478bd9Sstevel@tonic-gate 	ipfobj_t obj;
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 	fd = -1;
108*7c478bd9Sstevel@tonic-gate 	opts = 0;
109*7c478bd9Sstevel@tonic-gate 	nsp = &ns;
110*7c478bd9Sstevel@tonic-gate 	file = NULL;
111*7c478bd9Sstevel@tonic-gate 	core = NULL;
112*7c478bd9Sstevel@tonic-gate 	kernel = NULL;
113*7c478bd9Sstevel@tonic-gate 	mode = O_RDWR;
114*7c478bd9Sstevel@tonic-gate 
115*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "CdFf:hlM:N:nrsv")) != -1)
116*7c478bd9Sstevel@tonic-gate 		switch (c)
117*7c478bd9Sstevel@tonic-gate 		{
118*7c478bd9Sstevel@tonic-gate 		case 'C' :
119*7c478bd9Sstevel@tonic-gate 			opts |= OPT_CLEAR;
120*7c478bd9Sstevel@tonic-gate 			break;
121*7c478bd9Sstevel@tonic-gate 		case 'd' :
122*7c478bd9Sstevel@tonic-gate 			opts |= OPT_DEBUG;
123*7c478bd9Sstevel@tonic-gate 			break;
124*7c478bd9Sstevel@tonic-gate 		case 'f' :
125*7c478bd9Sstevel@tonic-gate 			file = optarg;
126*7c478bd9Sstevel@tonic-gate 			break;
127*7c478bd9Sstevel@tonic-gate 		case 'F' :
128*7c478bd9Sstevel@tonic-gate 			opts |= OPT_FLUSH;
129*7c478bd9Sstevel@tonic-gate 			break;
130*7c478bd9Sstevel@tonic-gate 		case 'h' :
131*7c478bd9Sstevel@tonic-gate 			opts |=OPT_HITS;
132*7c478bd9Sstevel@tonic-gate 			break;
133*7c478bd9Sstevel@tonic-gate 		case 'l' :
134*7c478bd9Sstevel@tonic-gate 			opts |= OPT_LIST;
135*7c478bd9Sstevel@tonic-gate 			mode = O_RDONLY;
136*7c478bd9Sstevel@tonic-gate 			break;
137*7c478bd9Sstevel@tonic-gate 		case 'M' :
138*7c478bd9Sstevel@tonic-gate 			core = optarg;
139*7c478bd9Sstevel@tonic-gate 			break;
140*7c478bd9Sstevel@tonic-gate 		case 'N' :
141*7c478bd9Sstevel@tonic-gate 			kernel = optarg;
142*7c478bd9Sstevel@tonic-gate 			break;
143*7c478bd9Sstevel@tonic-gate 		case 'n' :
144*7c478bd9Sstevel@tonic-gate 			opts |= OPT_DONOTHING;
145*7c478bd9Sstevel@tonic-gate 			mode = O_RDONLY;
146*7c478bd9Sstevel@tonic-gate 			break;
147*7c478bd9Sstevel@tonic-gate 		case 'r' :
148*7c478bd9Sstevel@tonic-gate 			opts |= OPT_REMOVE;
149*7c478bd9Sstevel@tonic-gate 			break;
150*7c478bd9Sstevel@tonic-gate 		case 's' :
151*7c478bd9Sstevel@tonic-gate 			opts |= OPT_STAT;
152*7c478bd9Sstevel@tonic-gate 			mode = O_RDONLY;
153*7c478bd9Sstevel@tonic-gate 			break;
154*7c478bd9Sstevel@tonic-gate 		case 'v' :
155*7c478bd9Sstevel@tonic-gate 			opts |= OPT_VERBOSE;
156*7c478bd9Sstevel@tonic-gate 			break;
157*7c478bd9Sstevel@tonic-gate 		default :
158*7c478bd9Sstevel@tonic-gate 			usage(argv[0]);
159*7c478bd9Sstevel@tonic-gate 		}
160*7c478bd9Sstevel@tonic-gate 
161*7c478bd9Sstevel@tonic-gate 	initparse();
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate 	if ((kernel != NULL) || (core != NULL)) {
164*7c478bd9Sstevel@tonic-gate 		(void) setgid(getgid());
165*7c478bd9Sstevel@tonic-gate 		(void) setreuid(getuid(), getuid());
166*7c478bd9Sstevel@tonic-gate 	}
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 	bzero((char *)&ns, sizeof(ns));
169*7c478bd9Sstevel@tonic-gate 
170*7c478bd9Sstevel@tonic-gate 	if ((opts & OPT_DONOTHING) == 0) {
171*7c478bd9Sstevel@tonic-gate 		if (checkrev(IPL_NAME) == -1) {
172*7c478bd9Sstevel@tonic-gate 			fprintf(stderr, "User/kernel version check failed\n");
173*7c478bd9Sstevel@tonic-gate 			exit(1);
174*7c478bd9Sstevel@tonic-gate 		}
175*7c478bd9Sstevel@tonic-gate 	}
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	if (!(opts & OPT_DONOTHING) && (kernel == NULL) && (core == NULL)) {
179*7c478bd9Sstevel@tonic-gate 		if (openkmem(kernel, core) == -1)
180*7c478bd9Sstevel@tonic-gate 			exit(1);
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 		if (((fd = open(IPNAT_NAME, mode)) == -1) &&
183*7c478bd9Sstevel@tonic-gate 		    ((fd = open(IPNAT_NAME, O_RDONLY)) == -1)) {
184*7c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: open: %s\n", IPNAT_NAME,
185*7c478bd9Sstevel@tonic-gate 				STRERROR(errno));
186*7c478bd9Sstevel@tonic-gate 			exit(1);
187*7c478bd9Sstevel@tonic-gate 		}
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 		bzero((char *)&obj, sizeof(obj));
190*7c478bd9Sstevel@tonic-gate 		obj.ipfo_rev = IPFILTER_VERSION;
191*7c478bd9Sstevel@tonic-gate 		obj.ipfo_size = sizeof(*nsp);
192*7c478bd9Sstevel@tonic-gate 		obj.ipfo_type = IPFOBJ_NATSTAT;
193*7c478bd9Sstevel@tonic-gate 		obj.ipfo_ptr = (void *)nsp;
194*7c478bd9Sstevel@tonic-gate 		if (ioctl(fd, SIOCGNATS, &obj) == -1) {
195*7c478bd9Sstevel@tonic-gate 			perror("ioctl(SIOCGNATS)");
196*7c478bd9Sstevel@tonic-gate 			exit(1);
197*7c478bd9Sstevel@tonic-gate 		}
198*7c478bd9Sstevel@tonic-gate 		(void) setgid(getgid());
199*7c478bd9Sstevel@tonic-gate 		(void) setreuid(getuid(), getuid());
200*7c478bd9Sstevel@tonic-gate 	} else if ((kernel != NULL) || (core != NULL)) {
201*7c478bd9Sstevel@tonic-gate 		if (openkmem(kernel, core) == -1)
202*7c478bd9Sstevel@tonic-gate 			exit(1);
203*7c478bd9Sstevel@tonic-gate 
204*7c478bd9Sstevel@tonic-gate 		natstat_dead(nsp, kernel);
205*7c478bd9Sstevel@tonic-gate 		if (opts & (OPT_LIST|OPT_STAT))
206*7c478bd9Sstevel@tonic-gate 			dostats(nsp, opts);
207*7c478bd9Sstevel@tonic-gate 		exit(0);
208*7c478bd9Sstevel@tonic-gate 	}
209*7c478bd9Sstevel@tonic-gate 
210*7c478bd9Sstevel@tonic-gate 	if (opts & (OPT_FLUSH|OPT_CLEAR))
211*7c478bd9Sstevel@tonic-gate 		flushtable(fd, opts);
212*7c478bd9Sstevel@tonic-gate 	if (file) {
213*7c478bd9Sstevel@tonic-gate 		ipnat_parsefile(fd, ipnat_addrule, ioctl, file);
214*7c478bd9Sstevel@tonic-gate 	}
215*7c478bd9Sstevel@tonic-gate 	if (opts & (OPT_LIST|OPT_STAT))
216*7c478bd9Sstevel@tonic-gate 		dostats(nsp, opts);
217*7c478bd9Sstevel@tonic-gate 	return 0;
218*7c478bd9Sstevel@tonic-gate }
219*7c478bd9Sstevel@tonic-gate 
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate /*
222*7c478bd9Sstevel@tonic-gate  * Read NAT statistic information in using a symbol table and memory file
223*7c478bd9Sstevel@tonic-gate  * rather than doing ioctl's.
224*7c478bd9Sstevel@tonic-gate  */
225*7c478bd9Sstevel@tonic-gate void natstat_dead(nsp, kernel)
226*7c478bd9Sstevel@tonic-gate natstat_t *nsp;
227*7c478bd9Sstevel@tonic-gate char *kernel;
228*7c478bd9Sstevel@tonic-gate {
229*7c478bd9Sstevel@tonic-gate 	struct nlist nat_nlist[10] = {
230*7c478bd9Sstevel@tonic-gate 		{ "nat_table" },		/* 0 */
231*7c478bd9Sstevel@tonic-gate 		{ "nat_list" },
232*7c478bd9Sstevel@tonic-gate 		{ "maptable" },
233*7c478bd9Sstevel@tonic-gate 		{ "ipf_nattable_sz" },
234*7c478bd9Sstevel@tonic-gate 		{ "ipf_natrules_sz" },
235*7c478bd9Sstevel@tonic-gate 		{ "ipf_rdrrules_sz" },		/* 5 */
236*7c478bd9Sstevel@tonic-gate 		{ "ipf_hostmap_sz" },
237*7c478bd9Sstevel@tonic-gate 		{ "nat_instances" },
238*7c478bd9Sstevel@tonic-gate 		{ "ap_sess_list" },
239*7c478bd9Sstevel@tonic-gate 		{ NULL }
240*7c478bd9Sstevel@tonic-gate 	};
241*7c478bd9Sstevel@tonic-gate 	void *tables[2];
242*7c478bd9Sstevel@tonic-gate 
243*7c478bd9Sstevel@tonic-gate 	if (nlist(kernel, nat_nlist) == -1) {
244*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "nlist error\n");
245*7c478bd9Sstevel@tonic-gate 		return;
246*7c478bd9Sstevel@tonic-gate 	}
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	/*
249*7c478bd9Sstevel@tonic-gate 	 * Normally the ioctl copies all of these values into the structure
250*7c478bd9Sstevel@tonic-gate 	 * for us, before returning it to userland, so here we must copy each
251*7c478bd9Sstevel@tonic-gate 	 * one in individually.
252*7c478bd9Sstevel@tonic-gate 	 */
253*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables));
254*7c478bd9Sstevel@tonic-gate 	nsp->ns_table[0] = tables[0];
255*7c478bd9Sstevel@tonic-gate 	nsp->ns_table[1] = tables[1];
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value,
258*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_list));
259*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value,
260*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_maptable));
261*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value,
262*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_nattab_sz));
263*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value,
264*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_rultab_sz));
265*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value,
266*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_rdrtab_sz));
267*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value,
268*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_hostmap_sz));
269*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value,
270*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_instances));
271*7c478bd9Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value,
272*7c478bd9Sstevel@tonic-gate 		sizeof(nsp->ns_apslist));
273*7c478bd9Sstevel@tonic-gate }
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 
276*7c478bd9Sstevel@tonic-gate /*
277*7c478bd9Sstevel@tonic-gate  * Display NAT statistics.
278*7c478bd9Sstevel@tonic-gate  */
279*7c478bd9Sstevel@tonic-gate void dostats(nsp, opts)
280*7c478bd9Sstevel@tonic-gate natstat_t *nsp;
281*7c478bd9Sstevel@tonic-gate int opts;
282*7c478bd9Sstevel@tonic-gate {
283*7c478bd9Sstevel@tonic-gate 	nat_t *np, nat;
284*7c478bd9Sstevel@tonic-gate 	ipnat_t	ipn;
285*7c478bd9Sstevel@tonic-gate 
286*7c478bd9Sstevel@tonic-gate 	/*
287*7c478bd9Sstevel@tonic-gate 	 * Show statistics ?
288*7c478bd9Sstevel@tonic-gate 	 */
289*7c478bd9Sstevel@tonic-gate 	if (opts & OPT_STAT) {
290*7c478bd9Sstevel@tonic-gate 		printf("mapped\tin\t%lu\tout\t%lu\n",
291*7c478bd9Sstevel@tonic-gate 			nsp->ns_mapped[0], nsp->ns_mapped[1]);
292*7c478bd9Sstevel@tonic-gate 		printf("added\t%lu\texpired\t%lu\n",
293*7c478bd9Sstevel@tonic-gate 			nsp->ns_added, nsp->ns_expire);
294*7c478bd9Sstevel@tonic-gate 		printf("no memory\t%lu\tbad nat\t%lu\n",
295*7c478bd9Sstevel@tonic-gate 			nsp->ns_memfail, nsp->ns_badnat);
296*7c478bd9Sstevel@tonic-gate 		printf("inuse\t%lu\nrules\t%lu\n",
297*7c478bd9Sstevel@tonic-gate 			nsp->ns_inuse, nsp->ns_rules);
298*7c478bd9Sstevel@tonic-gate 		printf("wilds\t%u\n", nsp->ns_wilds);
299*7c478bd9Sstevel@tonic-gate 		if (opts & OPT_VERBOSE)
300*7c478bd9Sstevel@tonic-gate 			printf("table %p list %p\n",
301*7c478bd9Sstevel@tonic-gate 				nsp->ns_table, nsp->ns_list);
302*7c478bd9Sstevel@tonic-gate 	}
303*7c478bd9Sstevel@tonic-gate 
304*7c478bd9Sstevel@tonic-gate 	/*
305*7c478bd9Sstevel@tonic-gate 	 * Show list of NAT rules and NAT sessions ?
306*7c478bd9Sstevel@tonic-gate 	 */
307*7c478bd9Sstevel@tonic-gate 	if (opts & OPT_LIST) {
308*7c478bd9Sstevel@tonic-gate 		printf("List of active MAP/Redirect filters:\n");
309*7c478bd9Sstevel@tonic-gate 		while (nsp->ns_list) {
310*7c478bd9Sstevel@tonic-gate 			if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
311*7c478bd9Sstevel@tonic-gate 				    sizeof(ipn))) {
312*7c478bd9Sstevel@tonic-gate 				perror("kmemcpy");
313*7c478bd9Sstevel@tonic-gate 				break;
314*7c478bd9Sstevel@tonic-gate 			}
315*7c478bd9Sstevel@tonic-gate 			if (opts & OPT_HITS)
316*7c478bd9Sstevel@tonic-gate 				printf("%d ", ipn.in_hits);
317*7c478bd9Sstevel@tonic-gate 			printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
318*7c478bd9Sstevel@tonic-gate 			nsp->ns_list = ipn.in_next;
319*7c478bd9Sstevel@tonic-gate 		}
320*7c478bd9Sstevel@tonic-gate 
321*7c478bd9Sstevel@tonic-gate 		printf("\nList of active sessions:\n");
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 		for (np = nsp->ns_instances; np; np = nat.nat_next) {
324*7c478bd9Sstevel@tonic-gate 			if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
325*7c478bd9Sstevel@tonic-gate 				break;
326*7c478bd9Sstevel@tonic-gate 			printactivenat(&nat, opts);
327*7c478bd9Sstevel@tonic-gate 		}
328*7c478bd9Sstevel@tonic-gate 
329*7c478bd9Sstevel@tonic-gate 		if (opts & OPT_VERBOSE)
330*7c478bd9Sstevel@tonic-gate 			showhostmap(nsp);
331*7c478bd9Sstevel@tonic-gate 	}
332*7c478bd9Sstevel@tonic-gate }
333*7c478bd9Sstevel@tonic-gate 
334*7c478bd9Sstevel@tonic-gate 
335*7c478bd9Sstevel@tonic-gate /*
336*7c478bd9Sstevel@tonic-gate  * Display the active host mapping table.
337*7c478bd9Sstevel@tonic-gate  */
338*7c478bd9Sstevel@tonic-gate void showhostmap(nsp)
339*7c478bd9Sstevel@tonic-gate natstat_t *nsp;
340*7c478bd9Sstevel@tonic-gate {
341*7c478bd9Sstevel@tonic-gate 	hostmap_t hm, *hmp, **maptable;
342*7c478bd9Sstevel@tonic-gate 	u_int hv;
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 	printf("\nList of active host mappings:\n");
345*7c478bd9Sstevel@tonic-gate 
346*7c478bd9Sstevel@tonic-gate 	maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) *
347*7c478bd9Sstevel@tonic-gate 					nsp->ns_hostmap_sz);
348*7c478bd9Sstevel@tonic-gate 	if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable,
349*7c478bd9Sstevel@tonic-gate 		    sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) {
350*7c478bd9Sstevel@tonic-gate 		perror("kmemcpy (maptable)");
351*7c478bd9Sstevel@tonic-gate 		return;
352*7c478bd9Sstevel@tonic-gate 	}
353*7c478bd9Sstevel@tonic-gate 
354*7c478bd9Sstevel@tonic-gate 	for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) {
355*7c478bd9Sstevel@tonic-gate 		hmp = maptable[hv];
356*7c478bd9Sstevel@tonic-gate 
357*7c478bd9Sstevel@tonic-gate 		while (hmp) {
358*7c478bd9Sstevel@tonic-gate 			if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) {
359*7c478bd9Sstevel@tonic-gate 				perror("kmemcpy (hostmap)");
360*7c478bd9Sstevel@tonic-gate 				return;
361*7c478bd9Sstevel@tonic-gate 			}
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate 			printhostmap(&hm, hv);
364*7c478bd9Sstevel@tonic-gate 			hmp = hm.hm_next;
365*7c478bd9Sstevel@tonic-gate 		}
366*7c478bd9Sstevel@tonic-gate 	}
367*7c478bd9Sstevel@tonic-gate 	free(maptable);
368*7c478bd9Sstevel@tonic-gate }
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate /*
372*7c478bd9Sstevel@tonic-gate  * Issue an ioctl to flush either the NAT rules table or the active mapping
373*7c478bd9Sstevel@tonic-gate  * table or both.
374*7c478bd9Sstevel@tonic-gate  */
375*7c478bd9Sstevel@tonic-gate void flushtable(fd, opts)
376*7c478bd9Sstevel@tonic-gate int fd, opts;
377*7c478bd9Sstevel@tonic-gate {
378*7c478bd9Sstevel@tonic-gate 	int n = 0;
379*7c478bd9Sstevel@tonic-gate 
380*7c478bd9Sstevel@tonic-gate 	if (opts & OPT_FLUSH) {
381*7c478bd9Sstevel@tonic-gate 		n = 0;
382*7c478bd9Sstevel@tonic-gate 		if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1)
383*7c478bd9Sstevel@tonic-gate 			perror("ioctl(SIOCFLNAT)");
384*7c478bd9Sstevel@tonic-gate 		else
385*7c478bd9Sstevel@tonic-gate 			printf("%d entries flushed from NAT table\n", n);
386*7c478bd9Sstevel@tonic-gate 	}
387*7c478bd9Sstevel@tonic-gate 
388*7c478bd9Sstevel@tonic-gate 	if (opts & OPT_CLEAR) {
389*7c478bd9Sstevel@tonic-gate 		n = 1;
390*7c478bd9Sstevel@tonic-gate 		if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1)
391*7c478bd9Sstevel@tonic-gate 			perror("ioctl(SIOCCNATL)");
392*7c478bd9Sstevel@tonic-gate 		else
393*7c478bd9Sstevel@tonic-gate 			printf("%d entries flushed from NAT list\n", n);
394*7c478bd9Sstevel@tonic-gate 	}
395*7c478bd9Sstevel@tonic-gate }
396