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