xref: /onnv-gate/usr/src/cmd/ipf/tools/ipnat.c (revision 8170:daf52af21f03)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * Copyright (C) 1993-2001 by Darren Reed.
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * See the IPFILTER.LICENCE file for details on licencing.
50Sstevel@tonic-gate  *
60Sstevel@tonic-gate  * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com)
70Sstevel@tonic-gate  *
86518Sjojemann  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
90Sstevel@tonic-gate  * Use is subject to license terms.
100Sstevel@tonic-gate  */
110Sstevel@tonic-gate 
120Sstevel@tonic-gate #include <stdio.h>
130Sstevel@tonic-gate #include <string.h>
140Sstevel@tonic-gate #include <fcntl.h>
150Sstevel@tonic-gate #include <errno.h>
160Sstevel@tonic-gate #include <sys/types.h>
170Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__svr4__)
180Sstevel@tonic-gate #include <strings.h>
190Sstevel@tonic-gate #else
200Sstevel@tonic-gate #include <sys/byteorder.h>
210Sstevel@tonic-gate #endif
220Sstevel@tonic-gate #include <sys/time.h>
230Sstevel@tonic-gate #include <sys/param.h>
240Sstevel@tonic-gate #include <stdlib.h>
250Sstevel@tonic-gate #include <unistd.h>
260Sstevel@tonic-gate #include <stddef.h>
270Sstevel@tonic-gate #include <sys/file.h>
280Sstevel@tonic-gate #define _KERNEL
290Sstevel@tonic-gate #include <sys/uio.h>
300Sstevel@tonic-gate #undef _KERNEL
310Sstevel@tonic-gate #include <sys/socket.h>
320Sstevel@tonic-gate #include <sys/ioctl.h>
330Sstevel@tonic-gate #if defined(sun) && (defined(__svr4__) || defined(__SVR4))
340Sstevel@tonic-gate # include <sys/ioccom.h>
350Sstevel@tonic-gate # include <sys/sysmacros.h>
360Sstevel@tonic-gate #endif
370Sstevel@tonic-gate #include <netinet/in.h>
380Sstevel@tonic-gate #include <netinet/in_systm.h>
390Sstevel@tonic-gate #include <netinet/ip.h>
400Sstevel@tonic-gate #include <netinet/tcp.h>
410Sstevel@tonic-gate #include <net/if.h>
420Sstevel@tonic-gate #if __FreeBSD_version >= 300000
430Sstevel@tonic-gate # include <net/if_var.h>
440Sstevel@tonic-gate #endif
450Sstevel@tonic-gate #include <netdb.h>
460Sstevel@tonic-gate #include <arpa/nameser.h>
470Sstevel@tonic-gate #include <arpa/inet.h>
480Sstevel@tonic-gate #include <resolv.h>
490Sstevel@tonic-gate #include <ctype.h>
502393Syz155240 #if defined(linux)
512393Syz155240 # include <linux/a.out.h>
522393Syz155240 #else
532393Syz155240 # include <nlist.h>
542393Syz155240 #endif
550Sstevel@tonic-gate #include "ipf.h"
562393Syz155240 #include "netinet/ipl.h"
570Sstevel@tonic-gate #include "kmem.h"
580Sstevel@tonic-gate 
590Sstevel@tonic-gate #ifdef	__hpux
600Sstevel@tonic-gate # define	nlist	nlist64
610Sstevel@tonic-gate #endif
620Sstevel@tonic-gate 
630Sstevel@tonic-gate #if	defined(sun) && !SOLARIS2
640Sstevel@tonic-gate # define	STRERROR(x)	sys_errlist[x]
650Sstevel@tonic-gate extern	char	*sys_errlist[];
660Sstevel@tonic-gate #else
670Sstevel@tonic-gate # define	STRERROR(x)	strerror(x)
680Sstevel@tonic-gate #endif
690Sstevel@tonic-gate 
700Sstevel@tonic-gate #if !defined(lint)
710Sstevel@tonic-gate static const char sccsid[] ="@(#)ipnat.c	1.9 6/5/96 (C) 1993 Darren Reed";
722393Syz155240 static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.24.2.2 2005/05/10 21:19:30 darrenr Exp $";
730Sstevel@tonic-gate #endif
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 
760Sstevel@tonic-gate #if	SOLARIS
770Sstevel@tonic-gate #define	bzero(a,b)	memset(a,0,b)
780Sstevel@tonic-gate #endif
790Sstevel@tonic-gate int	use_inet6 = 0;
800Sstevel@tonic-gate char	thishost[MAXHOSTNAMELEN];
810Sstevel@tonic-gate 
820Sstevel@tonic-gate extern	char	*optarg;
830Sstevel@tonic-gate 
843448Sdh155122 void	dostats __P((int, natstat_t *, int, int));
853448Sdh155122 void	flushtable __P((int, int));
860Sstevel@tonic-gate void	usage __P((char *));
870Sstevel@tonic-gate int	main __P((int, char*[]));
880Sstevel@tonic-gate void	showhostmap __P((natstat_t *nsp));
890Sstevel@tonic-gate void	natstat_dead __P((natstat_t *, char *));
903448Sdh155122 void	dostats_live __P((int, natstat_t *, int));
913448Sdh155122 void	showhostmap_live __P((int, natstat_t *));
920Sstevel@tonic-gate 
930Sstevel@tonic-gate int	opts;
940Sstevel@tonic-gate 
usage(name)950Sstevel@tonic-gate void usage(name)
960Sstevel@tonic-gate char *name;
970Sstevel@tonic-gate {
982934Sjojemann 	fprintf(stderr, "Usage: %s [-CdFhlnrRsv] [-f filename]\n", name);
990Sstevel@tonic-gate 	exit(1);
1000Sstevel@tonic-gate }
1010Sstevel@tonic-gate 
1020Sstevel@tonic-gate 
main(argc,argv)1030Sstevel@tonic-gate int main(argc, argv)
1040Sstevel@tonic-gate int argc;
1050Sstevel@tonic-gate char *argv[];
1060Sstevel@tonic-gate {
1070Sstevel@tonic-gate 	char *file, *core, *kernel;
1080Sstevel@tonic-gate 	natstat_t ns, *nsp;
1090Sstevel@tonic-gate 	int fd, c, mode;
1100Sstevel@tonic-gate 	ipfobj_t obj;
1110Sstevel@tonic-gate 
1120Sstevel@tonic-gate 	fd = -1;
1130Sstevel@tonic-gate 	opts = 0;
1140Sstevel@tonic-gate 	nsp = &ns;
1150Sstevel@tonic-gate 	file = NULL;
1160Sstevel@tonic-gate 	core = NULL;
1170Sstevel@tonic-gate 	kernel = NULL;
1180Sstevel@tonic-gate 	mode = O_RDWR;
1190Sstevel@tonic-gate 
1202393Syz155240 	while ((c = getopt(argc, argv, "CdFf:hlM:N:nrRsv")) != -1)
1210Sstevel@tonic-gate 		switch (c)
1220Sstevel@tonic-gate 		{
1230Sstevel@tonic-gate 		case 'C' :
1240Sstevel@tonic-gate 			opts |= OPT_CLEAR;
1250Sstevel@tonic-gate 			break;
1260Sstevel@tonic-gate 		case 'd' :
1270Sstevel@tonic-gate 			opts |= OPT_DEBUG;
1280Sstevel@tonic-gate 			break;
1290Sstevel@tonic-gate 		case 'f' :
1300Sstevel@tonic-gate 			file = optarg;
1310Sstevel@tonic-gate 			break;
1320Sstevel@tonic-gate 		case 'F' :
1330Sstevel@tonic-gate 			opts |= OPT_FLUSH;
1340Sstevel@tonic-gate 			break;
1350Sstevel@tonic-gate 		case 'h' :
1360Sstevel@tonic-gate 			opts |=OPT_HITS;
1370Sstevel@tonic-gate 			break;
1380Sstevel@tonic-gate 		case 'l' :
1390Sstevel@tonic-gate 			opts |= OPT_LIST;
1400Sstevel@tonic-gate 			mode = O_RDONLY;
1410Sstevel@tonic-gate 			break;
1420Sstevel@tonic-gate 		case 'M' :
1430Sstevel@tonic-gate 			core = optarg;
1440Sstevel@tonic-gate 			break;
1450Sstevel@tonic-gate 		case 'N' :
1460Sstevel@tonic-gate 			kernel = optarg;
1470Sstevel@tonic-gate 			break;
1480Sstevel@tonic-gate 		case 'n' :
1490Sstevel@tonic-gate 			opts |= OPT_DONOTHING;
1500Sstevel@tonic-gate 			mode = O_RDONLY;
1510Sstevel@tonic-gate 			break;
1522393Syz155240 		case 'R' :
1532393Syz155240 			opts |= OPT_NORESOLVE;
1542393Syz155240 			break;
1550Sstevel@tonic-gate 		case 'r' :
1560Sstevel@tonic-gate 			opts |= OPT_REMOVE;
1570Sstevel@tonic-gate 			break;
1580Sstevel@tonic-gate 		case 's' :
1590Sstevel@tonic-gate 			opts |= OPT_STAT;
1600Sstevel@tonic-gate 			mode = O_RDONLY;
1610Sstevel@tonic-gate 			break;
1620Sstevel@tonic-gate 		case 'v' :
1630Sstevel@tonic-gate 			opts |= OPT_VERBOSE;
1640Sstevel@tonic-gate 			break;
1650Sstevel@tonic-gate 		default :
1660Sstevel@tonic-gate 			usage(argv[0]);
1670Sstevel@tonic-gate 		}
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	initparse();
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 	if ((kernel != NULL) || (core != NULL)) {
1720Sstevel@tonic-gate 		(void) setgid(getgid());
1730Sstevel@tonic-gate 		(void) setreuid(getuid(), getuid());
1740Sstevel@tonic-gate 	}
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate 	bzero((char *)&ns, sizeof(ns));
1770Sstevel@tonic-gate 
1780Sstevel@tonic-gate 	if ((opts & OPT_DONOTHING) == 0) {
1790Sstevel@tonic-gate 		if (checkrev(IPL_NAME) == -1) {
1800Sstevel@tonic-gate 			fprintf(stderr, "User/kernel version check failed\n");
1810Sstevel@tonic-gate 			exit(1);
1820Sstevel@tonic-gate 		}
1830Sstevel@tonic-gate 	}
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 
1860Sstevel@tonic-gate 	if (!(opts & OPT_DONOTHING) && (kernel == NULL) && (core == NULL)) {
1873448Sdh155122 #ifdef notdef
1880Sstevel@tonic-gate 		if (openkmem(kernel, core) == -1)
1890Sstevel@tonic-gate 			exit(1);
1903448Sdh155122 #endif
1910Sstevel@tonic-gate 		if (((fd = open(IPNAT_NAME, mode)) == -1) &&
1920Sstevel@tonic-gate 		    ((fd = open(IPNAT_NAME, O_RDONLY)) == -1)) {
1930Sstevel@tonic-gate 			(void) fprintf(stderr, "%s: open: %s\n", IPNAT_NAME,
1940Sstevel@tonic-gate 				STRERROR(errno));
1950Sstevel@tonic-gate 			exit(1);
1960Sstevel@tonic-gate 		}
1970Sstevel@tonic-gate 
1980Sstevel@tonic-gate 		bzero((char *)&obj, sizeof(obj));
1990Sstevel@tonic-gate 		obj.ipfo_rev = IPFILTER_VERSION;
2000Sstevel@tonic-gate 		obj.ipfo_size = sizeof(*nsp);
2010Sstevel@tonic-gate 		obj.ipfo_type = IPFOBJ_NATSTAT;
2020Sstevel@tonic-gate 		obj.ipfo_ptr = (void *)nsp;
2030Sstevel@tonic-gate 		if (ioctl(fd, SIOCGNATS, &obj) == -1) {
2040Sstevel@tonic-gate 			perror("ioctl(SIOCGNATS)");
2050Sstevel@tonic-gate 			exit(1);
2060Sstevel@tonic-gate 		}
2070Sstevel@tonic-gate 		(void) setgid(getgid());
2080Sstevel@tonic-gate 		(void) setreuid(getuid(), getuid());
2090Sstevel@tonic-gate 	} else if ((kernel != NULL) || (core != NULL)) {
2100Sstevel@tonic-gate 		if (openkmem(kernel, core) == -1)
2110Sstevel@tonic-gate 			exit(1);
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 		natstat_dead(nsp, kernel);
2140Sstevel@tonic-gate 		if (opts & (OPT_LIST|OPT_STAT))
2153448Sdh155122 			dostats(fd, nsp, opts, 0);
2160Sstevel@tonic-gate 		exit(0);
2170Sstevel@tonic-gate 	}
2180Sstevel@tonic-gate 
2190Sstevel@tonic-gate 	if (opts & (OPT_FLUSH|OPT_CLEAR))
2200Sstevel@tonic-gate 		flushtable(fd, opts);
2210Sstevel@tonic-gate 	if (file) {
2220Sstevel@tonic-gate 		ipnat_parsefile(fd, ipnat_addrule, ioctl, file);
2230Sstevel@tonic-gate 	}
2240Sstevel@tonic-gate 	if (opts & (OPT_LIST|OPT_STAT))
2253448Sdh155122 		dostats(fd, nsp, opts, 1);
2260Sstevel@tonic-gate 	return 0;
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate 
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate /*
2310Sstevel@tonic-gate  * Read NAT statistic information in using a symbol table and memory file
2320Sstevel@tonic-gate  * rather than doing ioctl's.
2330Sstevel@tonic-gate  */
natstat_dead(nsp,kernel)2340Sstevel@tonic-gate void natstat_dead(nsp, kernel)
2350Sstevel@tonic-gate natstat_t *nsp;
2360Sstevel@tonic-gate char *kernel;
2370Sstevel@tonic-gate {
2380Sstevel@tonic-gate 	struct nlist nat_nlist[10] = {
2390Sstevel@tonic-gate 		{ "nat_table" },		/* 0 */
2400Sstevel@tonic-gate 		{ "nat_list" },
2410Sstevel@tonic-gate 		{ "maptable" },
2420Sstevel@tonic-gate 		{ "ipf_nattable_sz" },
2430Sstevel@tonic-gate 		{ "ipf_natrules_sz" },
2440Sstevel@tonic-gate 		{ "ipf_rdrrules_sz" },		/* 5 */
2450Sstevel@tonic-gate 		{ "ipf_hostmap_sz" },
2460Sstevel@tonic-gate 		{ "nat_instances" },
2470Sstevel@tonic-gate 		{ "ap_sess_list" },
2480Sstevel@tonic-gate 		{ NULL }
2490Sstevel@tonic-gate 	};
2500Sstevel@tonic-gate 	void *tables[2];
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	if (nlist(kernel, nat_nlist) == -1) {
2530Sstevel@tonic-gate 		fprintf(stderr, "nlist error\n");
2540Sstevel@tonic-gate 		return;
2550Sstevel@tonic-gate 	}
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 	/*
2580Sstevel@tonic-gate 	 * Normally the ioctl copies all of these values into the structure
2590Sstevel@tonic-gate 	 * for us, before returning it to userland, so here we must copy each
2600Sstevel@tonic-gate 	 * one in individually.
2610Sstevel@tonic-gate 	 */
2620Sstevel@tonic-gate 	kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables));
2630Sstevel@tonic-gate 	nsp->ns_table[0] = tables[0];
2640Sstevel@tonic-gate 	nsp->ns_table[1] = tables[1];
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value,
2670Sstevel@tonic-gate 		sizeof(nsp->ns_list));
2680Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value,
2690Sstevel@tonic-gate 		sizeof(nsp->ns_maptable));
2700Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value,
2710Sstevel@tonic-gate 		sizeof(nsp->ns_nattab_sz));
2720Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value,
2730Sstevel@tonic-gate 		sizeof(nsp->ns_rultab_sz));
2740Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value,
2750Sstevel@tonic-gate 		sizeof(nsp->ns_rdrtab_sz));
2760Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value,
2770Sstevel@tonic-gate 		sizeof(nsp->ns_hostmap_sz));
2780Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value,
2790Sstevel@tonic-gate 		sizeof(nsp->ns_instances));
2800Sstevel@tonic-gate 	kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value,
2810Sstevel@tonic-gate 		sizeof(nsp->ns_apslist));
2820Sstevel@tonic-gate }
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 
2850Sstevel@tonic-gate /*
2860Sstevel@tonic-gate  * Display NAT statistics.
2870Sstevel@tonic-gate  */
dostats(fd,nsp,opts,alive)2883448Sdh155122 void dostats(fd, nsp, opts, alive)
2890Sstevel@tonic-gate natstat_t *nsp;
2903448Sdh155122 int fd, opts, alive;
2910Sstevel@tonic-gate {
2920Sstevel@tonic-gate 	nat_t *np, nat;
2930Sstevel@tonic-gate 	ipnat_t	ipn;
2940Sstevel@tonic-gate 
2950Sstevel@tonic-gate 	/*
2960Sstevel@tonic-gate 	 * Show statistics ?
2970Sstevel@tonic-gate 	 */
2980Sstevel@tonic-gate 	if (opts & OPT_STAT) {
2990Sstevel@tonic-gate 		printf("mapped\tin\t%lu\tout\t%lu\n",
3000Sstevel@tonic-gate 			nsp->ns_mapped[0], nsp->ns_mapped[1]);
3010Sstevel@tonic-gate 		printf("added\t%lu\texpired\t%lu\n",
3020Sstevel@tonic-gate 			nsp->ns_added, nsp->ns_expire);
3030Sstevel@tonic-gate 		printf("no memory\t%lu\tbad nat\t%lu\n",
3040Sstevel@tonic-gate 			nsp->ns_memfail, nsp->ns_badnat);
3057432SJohn.Ojemann@Sun.COM 		printf("inuse\t%lu\norphans\t%u\nrules\t%lu\n",
3067432SJohn.Ojemann@Sun.COM 			nsp->ns_inuse, nsp->ns_orphans, nsp->ns_rules);
3070Sstevel@tonic-gate 		printf("wilds\t%u\n", nsp->ns_wilds);
3080Sstevel@tonic-gate 		if (opts & OPT_VERBOSE)
3090Sstevel@tonic-gate 			printf("table %p list %p\n",
3100Sstevel@tonic-gate 				nsp->ns_table, nsp->ns_list);
3110Sstevel@tonic-gate 	}
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate 	/*
3140Sstevel@tonic-gate 	 * Show list of NAT rules and NAT sessions ?
3150Sstevel@tonic-gate 	 */
3160Sstevel@tonic-gate 	if (opts & OPT_LIST) {
3173448Sdh155122 		if (alive) {
3183448Sdh155122 			dostats_live(fd, nsp, opts);
3193448Sdh155122 			return;
3203448Sdh155122 		}
3210Sstevel@tonic-gate 		printf("List of active MAP/Redirect filters:\n");
3220Sstevel@tonic-gate 		while (nsp->ns_list) {
3230Sstevel@tonic-gate 			if (kmemcpy((char *)&ipn, (long)nsp->ns_list,
3240Sstevel@tonic-gate 				    sizeof(ipn))) {
3250Sstevel@tonic-gate 				perror("kmemcpy");
3260Sstevel@tonic-gate 				break;
3270Sstevel@tonic-gate 			}
3280Sstevel@tonic-gate 			if (opts & OPT_HITS)
3292393Syz155240 				printf("%lu ", ipn.in_hits);
3300Sstevel@tonic-gate 			printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
3310Sstevel@tonic-gate 			nsp->ns_list = ipn.in_next;
3320Sstevel@tonic-gate 		}
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate 		printf("\nList of active sessions:\n");
3350Sstevel@tonic-gate 
3360Sstevel@tonic-gate 		for (np = nsp->ns_instances; np; np = nat.nat_next) {
3370Sstevel@tonic-gate 			if (kmemcpy((char *)&nat, (long)np, sizeof(nat)))
3380Sstevel@tonic-gate 				break;
3393448Sdh155122 			printactivenat(&nat, opts, 0);
3402393Syz155240 			if (nat.nat_aps)
3412393Syz155240 				printaps(nat.nat_aps, opts);
3420Sstevel@tonic-gate 		}
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 		if (opts & OPT_VERBOSE)
3450Sstevel@tonic-gate 			showhostmap(nsp);
3460Sstevel@tonic-gate 	}
3470Sstevel@tonic-gate }
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 
3500Sstevel@tonic-gate /*
3510Sstevel@tonic-gate  * Display the active host mapping table.
3520Sstevel@tonic-gate  */
showhostmap(nsp)3530Sstevel@tonic-gate void showhostmap(nsp)
3540Sstevel@tonic-gate natstat_t *nsp;
3550Sstevel@tonic-gate {
3560Sstevel@tonic-gate 	hostmap_t hm, *hmp, **maptable;
3570Sstevel@tonic-gate 	u_int hv;
3580Sstevel@tonic-gate 
3590Sstevel@tonic-gate 	printf("\nList of active host mappings:\n");
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) *
3620Sstevel@tonic-gate 					nsp->ns_hostmap_sz);
3631448Sschuster 	if (maptable == NULL) {
3641448Sschuster 		perror("malloc");
3651448Sschuster 		exit(1);
3661448Sschuster 	}
3670Sstevel@tonic-gate 	if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable,
3680Sstevel@tonic-gate 		    sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) {
3690Sstevel@tonic-gate 		perror("kmemcpy (maptable)");
3700Sstevel@tonic-gate 		return;
3710Sstevel@tonic-gate 	}
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate 	for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) {
3740Sstevel@tonic-gate 		hmp = maptable[hv];
3750Sstevel@tonic-gate 
3760Sstevel@tonic-gate 		while (hmp) {
3770Sstevel@tonic-gate 			if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) {
3780Sstevel@tonic-gate 				perror("kmemcpy (hostmap)");
3790Sstevel@tonic-gate 				return;
3800Sstevel@tonic-gate 			}
3810Sstevel@tonic-gate 
3820Sstevel@tonic-gate 			printhostmap(&hm, hv);
3830Sstevel@tonic-gate 			hmp = hm.hm_next;
3840Sstevel@tonic-gate 		}
3850Sstevel@tonic-gate 	}
3860Sstevel@tonic-gate 	free(maptable);
3870Sstevel@tonic-gate }
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate /*
3910Sstevel@tonic-gate  * Issue an ioctl to flush either the NAT rules table or the active mapping
3920Sstevel@tonic-gate  * table or both.
3930Sstevel@tonic-gate  */
flushtable(fd,opts)3940Sstevel@tonic-gate void flushtable(fd, opts)
3950Sstevel@tonic-gate int fd, opts;
3960Sstevel@tonic-gate {
3970Sstevel@tonic-gate 	int n = 0;
3980Sstevel@tonic-gate 
3990Sstevel@tonic-gate 	if (opts & OPT_FLUSH) {
400*8170SJohn.Ojemann@Sun.COM 		n = FLUSH_TABLE_ALL;
4010Sstevel@tonic-gate 		if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1)
4020Sstevel@tonic-gate 			perror("ioctl(SIOCFLNAT)");
4030Sstevel@tonic-gate 		else
4040Sstevel@tonic-gate 			printf("%d entries flushed from NAT table\n", n);
4050Sstevel@tonic-gate 	}
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	if (opts & OPT_CLEAR) {
408*8170SJohn.Ojemann@Sun.COM 		n = FLUSH_LIST;
4090Sstevel@tonic-gate 		if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1)
4100Sstevel@tonic-gate 			perror("ioctl(SIOCCNATL)");
4110Sstevel@tonic-gate 		else
4120Sstevel@tonic-gate 			printf("%d entries flushed from NAT list\n", n);
4130Sstevel@tonic-gate 	}
4140Sstevel@tonic-gate }
4153448Sdh155122 
4163448Sdh155122 /*
4173448Sdh155122  * Display NAT statistics.
4183448Sdh155122  */
dostats_live(fd,nsp,opts)4193448Sdh155122 void dostats_live(fd, nsp, opts)
4203448Sdh155122 natstat_t *nsp;
4213448Sdh155122 int fd, opts;
4223448Sdh155122 {
4233448Sdh155122 	ipfgeniter_t iter;
4243448Sdh155122 	ipfobj_t obj;
4253448Sdh155122 	ipnat_t	ipn;
4263448Sdh155122 	nat_t nat;
4273448Sdh155122 
4283448Sdh155122 	bzero((char *)&obj, sizeof(obj));
4293448Sdh155122 	obj.ipfo_rev = IPFILTER_VERSION;
4303448Sdh155122 	obj.ipfo_type = IPFOBJ_GENITER;
4313448Sdh155122 	obj.ipfo_size = sizeof(iter);
4323448Sdh155122 	obj.ipfo_ptr = &iter;
4333448Sdh155122 
4343448Sdh155122 	iter.igi_type = IPFGENITER_IPNAT;
4355417Sjojemann 	iter.igi_nitems = 1;
4363448Sdh155122 	iter.igi_data = &ipn;
4373448Sdh155122 
4383448Sdh155122 	/*
4393448Sdh155122 	 * Show list of NAT rules and NAT sessions ?
4403448Sdh155122 	 */
4413448Sdh155122 	printf("List of active MAP/Redirect filters:\n");
4423448Sdh155122 	while (nsp->ns_list) {
4433448Sdh155122 		if (ioctl(fd, SIOCGENITER, &obj) == -1)
4443448Sdh155122 			break;
4453448Sdh155122 		if (opts & OPT_HITS)
4463448Sdh155122 			printf("%lu ", ipn.in_hits);
4473448Sdh155122 		printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE));
4483448Sdh155122 		nsp->ns_list = ipn.in_next;
4493448Sdh155122 	}
4503448Sdh155122 
4513448Sdh155122 	printf("\nList of active sessions:\n");
4523448Sdh155122 
4533448Sdh155122 	iter.igi_type = IPFGENITER_NAT;
4545417Sjojemann 	iter.igi_nitems = 1;
4553448Sdh155122 	iter.igi_data = &nat;
4563448Sdh155122 
4573448Sdh155122 	while (nsp->ns_instances != NULL) {
4583448Sdh155122 		if (ioctl(fd, SIOCGENITER, &obj) == -1)
4593448Sdh155122 			break;
4603448Sdh155122 		printactivenat(&nat, opts, 1);
4613448Sdh155122 		if (nat.nat_aps)
4623448Sdh155122 			printaps(nat.nat_aps, opts);
4633448Sdh155122 		nsp->ns_instances = nat.nat_next;
4643448Sdh155122 	}
4653448Sdh155122 
4663448Sdh155122 	if (opts & OPT_VERBOSE)
4673448Sdh155122 		showhostmap_live(fd, nsp);
4683448Sdh155122 }
4693448Sdh155122 
4703448Sdh155122 /*
4713448Sdh155122  * Display the active host mapping table.
4723448Sdh155122  */
showhostmap_live(fd,nsp)4733448Sdh155122 void showhostmap_live(fd, nsp)
4743448Sdh155122 int fd;
4753448Sdh155122 natstat_t *nsp;
4763448Sdh155122 {
4773448Sdh155122 	hostmap_t hm, *hmp;
4783448Sdh155122 	ipfgeniter_t iter;
4793448Sdh155122 	ipfobj_t obj;
4803448Sdh155122 
4813448Sdh155122 	bzero((char *)&obj, sizeof(obj));
4823448Sdh155122 	obj.ipfo_rev = IPFILTER_VERSION;
4833448Sdh155122 	obj.ipfo_type = IPFOBJ_GENITER;
4843448Sdh155122 	obj.ipfo_size = sizeof(iter);
4853448Sdh155122 	obj.ipfo_ptr = &iter;
4863448Sdh155122 
4873448Sdh155122 	iter.igi_type = IPFGENITER_HOSTMAP;
4885458Sjojemann 	iter.igi_nitems = 1;
4893448Sdh155122 	iter.igi_data = &hm;
4903448Sdh155122 
4913448Sdh155122 	printf("\nList of active host mappings:\n");
4923448Sdh155122 
4933448Sdh155122 	while (nsp->ns_maplist != NULL) {
4943448Sdh155122 		if (ioctl(fd, SIOCGENITER, &obj) == -1)
4953448Sdh155122 			break;
4963448Sdh155122 		printhostmap(&hm, 0);
4973448Sdh155122 		nsp->ns_maplist = hm.hm_next;
4983448Sdh155122 	}
4993448Sdh155122 }
500