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