17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright (C) 1993-2001 by Darren Reed. 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 57c478bd9Sstevel@tonic-gate * 67c478bd9Sstevel@tonic-gate * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) 77c478bd9Sstevel@tonic-gate * 8786c7074Sjojemann * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 97c478bd9Sstevel@tonic-gate * Use is subject to license terms. 1094bdecd9SRob Gulewich * 1194bdecd9SRob Gulewich * Copyright (c) 2014, Joyent, Inc. All rights reserved. 127c478bd9Sstevel@tonic-gate */ 137c478bd9Sstevel@tonic-gate 147c478bd9Sstevel@tonic-gate #include <stdio.h> 157c478bd9Sstevel@tonic-gate #include <string.h> 167c478bd9Sstevel@tonic-gate #include <fcntl.h> 177c478bd9Sstevel@tonic-gate #include <errno.h> 187c478bd9Sstevel@tonic-gate #include <sys/types.h> 197c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__svr4__) 207c478bd9Sstevel@tonic-gate #include <strings.h> 217c478bd9Sstevel@tonic-gate #else 227c478bd9Sstevel@tonic-gate #include <sys/byteorder.h> 237c478bd9Sstevel@tonic-gate #endif 247c478bd9Sstevel@tonic-gate #include <sys/time.h> 257c478bd9Sstevel@tonic-gate #include <sys/param.h> 267c478bd9Sstevel@tonic-gate #include <stdlib.h> 277c478bd9Sstevel@tonic-gate #include <unistd.h> 287c478bd9Sstevel@tonic-gate #include <stddef.h> 297c478bd9Sstevel@tonic-gate #include <sys/file.h> 307c478bd9Sstevel@tonic-gate #define _KERNEL 317c478bd9Sstevel@tonic-gate #include <sys/uio.h> 327c478bd9Sstevel@tonic-gate #undef _KERNEL 337c478bd9Sstevel@tonic-gate #include <sys/socket.h> 347c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 357c478bd9Sstevel@tonic-gate #if defined(sun) && (defined(__svr4__) || defined(__SVR4)) 367c478bd9Sstevel@tonic-gate # include <sys/ioccom.h> 377c478bd9Sstevel@tonic-gate # include <sys/sysmacros.h> 387c478bd9Sstevel@tonic-gate #endif 397c478bd9Sstevel@tonic-gate #include <netinet/in.h> 407c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 417c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 427c478bd9Sstevel@tonic-gate #include <netinet/tcp.h> 437c478bd9Sstevel@tonic-gate #include <net/if.h> 447c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000 457c478bd9Sstevel@tonic-gate # include <net/if_var.h> 467c478bd9Sstevel@tonic-gate #endif 477c478bd9Sstevel@tonic-gate #include <netdb.h> 487c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 497c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 507c478bd9Sstevel@tonic-gate #include <resolv.h> 517c478bd9Sstevel@tonic-gate #include <ctype.h> 52ab25eeb5Syz155240 #if defined(linux) 53ab25eeb5Syz155240 # include <linux/a.out.h> 54ab25eeb5Syz155240 #else 557c478bd9Sstevel@tonic-gate # include <nlist.h> 56ab25eeb5Syz155240 #endif 577c478bd9Sstevel@tonic-gate #include "ipf.h" 58ab25eeb5Syz155240 #include "netinet/ipl.h" 597c478bd9Sstevel@tonic-gate #include "kmem.h" 6094bdecd9SRob Gulewich #include "ipfzone.h" 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate #ifdef __hpux 637c478bd9Sstevel@tonic-gate # define nlist nlist64 647c478bd9Sstevel@tonic-gate #endif 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate #if defined(sun) && !SOLARIS2 677c478bd9Sstevel@tonic-gate # define STRERROR(x) sys_errlist[x] 687c478bd9Sstevel@tonic-gate extern char *sys_errlist[]; 697c478bd9Sstevel@tonic-gate #else 707c478bd9Sstevel@tonic-gate # define STRERROR(x) strerror(x) 717c478bd9Sstevel@tonic-gate #endif 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate #if !defined(lint) 747c478bd9Sstevel@tonic-gate static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; 75ab25eeb5Syz155240 static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.24.2.2 2005/05/10 21:19:30 darrenr Exp $"; 767c478bd9Sstevel@tonic-gate #endif 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate 79*f56257d8SToomas Soome #ifdef SOLARIS 807c478bd9Sstevel@tonic-gate #define bzero(a,b) memset(a,0,b) 817c478bd9Sstevel@tonic-gate #endif 827c478bd9Sstevel@tonic-gate int use_inet6 = 0; 837c478bd9Sstevel@tonic-gate char thishost[MAXHOSTNAMELEN]; 847c478bd9Sstevel@tonic-gate 857c478bd9Sstevel@tonic-gate extern char *optarg; 867c478bd9Sstevel@tonic-gate 87f4b3ec61Sdh155122 void dostats __P((int, natstat_t *, int, int)); 88f4b3ec61Sdh155122 void flushtable __P((int, int)); 897c478bd9Sstevel@tonic-gate void usage __P((char *)); 907c478bd9Sstevel@tonic-gate int main __P((int, char*[])); 917c478bd9Sstevel@tonic-gate void showhostmap __P((natstat_t *nsp)); 927c478bd9Sstevel@tonic-gate void natstat_dead __P((natstat_t *, char *)); 93f4b3ec61Sdh155122 void dostats_live __P((int, natstat_t *, int)); 94f4b3ec61Sdh155122 void showhostmap_live __P((int, natstat_t *)); 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate int opts; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate void usage(name) 997c478bd9Sstevel@tonic-gate char *name; 1007c478bd9Sstevel@tonic-gate { 10194bdecd9SRob Gulewich fprintf(stderr, "Usage: %s [-CdFhlnrRsv] [-f filename]", name); 10294bdecd9SRob Gulewich fprintf(stderr, " [-G|-z zonename]\n"); 1037c478bd9Sstevel@tonic-gate exit(1); 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate int main(argc, argv) 1087c478bd9Sstevel@tonic-gate int argc; 1097c478bd9Sstevel@tonic-gate char *argv[]; 1107c478bd9Sstevel@tonic-gate { 1117c478bd9Sstevel@tonic-gate char *file, *core, *kernel; 1127c478bd9Sstevel@tonic-gate natstat_t ns, *nsp; 1137c478bd9Sstevel@tonic-gate int fd, c, mode; 1147c478bd9Sstevel@tonic-gate ipfobj_t obj; 1157c478bd9Sstevel@tonic-gate 1167c478bd9Sstevel@tonic-gate fd = -1; 1177c478bd9Sstevel@tonic-gate opts = 0; 1187c478bd9Sstevel@tonic-gate nsp = &ns; 1197c478bd9Sstevel@tonic-gate file = NULL; 1207c478bd9Sstevel@tonic-gate core = NULL; 1217c478bd9Sstevel@tonic-gate kernel = NULL; 1227c478bd9Sstevel@tonic-gate mode = O_RDWR; 1237c478bd9Sstevel@tonic-gate 12494bdecd9SRob Gulewich while ((c = getopt(argc, argv, "CdFf:G:hlM:N:nrRsvz:")) != -1) 1257c478bd9Sstevel@tonic-gate switch (c) 1267c478bd9Sstevel@tonic-gate { 1277c478bd9Sstevel@tonic-gate case 'C' : 1287c478bd9Sstevel@tonic-gate opts |= OPT_CLEAR; 1297c478bd9Sstevel@tonic-gate break; 1307c478bd9Sstevel@tonic-gate case 'd' : 1317c478bd9Sstevel@tonic-gate opts |= OPT_DEBUG; 1327c478bd9Sstevel@tonic-gate break; 1337c478bd9Sstevel@tonic-gate case 'f' : 1347c478bd9Sstevel@tonic-gate file = optarg; 1357c478bd9Sstevel@tonic-gate break; 1367c478bd9Sstevel@tonic-gate case 'F' : 1377c478bd9Sstevel@tonic-gate opts |= OPT_FLUSH; 1387c478bd9Sstevel@tonic-gate break; 13994bdecd9SRob Gulewich case 'G' : 14094bdecd9SRob Gulewich setzonename_global(optarg); 14194bdecd9SRob Gulewich break; 1427c478bd9Sstevel@tonic-gate case 'h' : 1437c478bd9Sstevel@tonic-gate opts |=OPT_HITS; 1447c478bd9Sstevel@tonic-gate break; 1457c478bd9Sstevel@tonic-gate case 'l' : 1467c478bd9Sstevel@tonic-gate opts |= OPT_LIST; 1477c478bd9Sstevel@tonic-gate mode = O_RDONLY; 1487c478bd9Sstevel@tonic-gate break; 1497c478bd9Sstevel@tonic-gate case 'M' : 1507c478bd9Sstevel@tonic-gate core = optarg; 1517c478bd9Sstevel@tonic-gate break; 1527c478bd9Sstevel@tonic-gate case 'N' : 1537c478bd9Sstevel@tonic-gate kernel = optarg; 1547c478bd9Sstevel@tonic-gate break; 1557c478bd9Sstevel@tonic-gate case 'n' : 1567c478bd9Sstevel@tonic-gate opts |= OPT_DONOTHING; 1577c478bd9Sstevel@tonic-gate mode = O_RDONLY; 1587c478bd9Sstevel@tonic-gate break; 159ab25eeb5Syz155240 case 'R' : 160ab25eeb5Syz155240 opts |= OPT_NORESOLVE; 161ab25eeb5Syz155240 break; 1627c478bd9Sstevel@tonic-gate case 'r' : 1637c478bd9Sstevel@tonic-gate opts |= OPT_REMOVE; 1647c478bd9Sstevel@tonic-gate break; 1657c478bd9Sstevel@tonic-gate case 's' : 1667c478bd9Sstevel@tonic-gate opts |= OPT_STAT; 1677c478bd9Sstevel@tonic-gate mode = O_RDONLY; 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate case 'v' : 1707c478bd9Sstevel@tonic-gate opts |= OPT_VERBOSE; 1717c478bd9Sstevel@tonic-gate break; 17294bdecd9SRob Gulewich case 'z' : 17394bdecd9SRob Gulewich setzonename(optarg); 17494bdecd9SRob Gulewich break; 1757c478bd9Sstevel@tonic-gate default : 1767c478bd9Sstevel@tonic-gate usage(argv[0]); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate initparse(); 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if ((kernel != NULL) || (core != NULL)) { 1827c478bd9Sstevel@tonic-gate (void) setgid(getgid()); 1837c478bd9Sstevel@tonic-gate (void) setreuid(getuid(), getuid()); 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate 1867c478bd9Sstevel@tonic-gate bzero((char *)&ns, sizeof(ns)); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate if ((opts & OPT_DONOTHING) == 0) { 1897c478bd9Sstevel@tonic-gate if (checkrev(IPL_NAME) == -1) { 1907c478bd9Sstevel@tonic-gate fprintf(stderr, "User/kernel version check failed\n"); 1917c478bd9Sstevel@tonic-gate exit(1); 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate } 1947c478bd9Sstevel@tonic-gate 1957c478bd9Sstevel@tonic-gate 1967c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (kernel == NULL) && (core == NULL)) { 197f4b3ec61Sdh155122 #ifdef notdef 1987c478bd9Sstevel@tonic-gate if (openkmem(kernel, core) == -1) 1997c478bd9Sstevel@tonic-gate exit(1); 200f4b3ec61Sdh155122 #endif 2017c478bd9Sstevel@tonic-gate if (((fd = open(IPNAT_NAME, mode)) == -1) && 2027c478bd9Sstevel@tonic-gate ((fd = open(IPNAT_NAME, O_RDONLY)) == -1)) { 2037c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: open: %s\n", IPNAT_NAME, 2047c478bd9Sstevel@tonic-gate STRERROR(errno)); 2057c478bd9Sstevel@tonic-gate exit(1); 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 20894bdecd9SRob Gulewich if (setzone(fd) != 0) { 20994bdecd9SRob Gulewich close(fd); 21094bdecd9SRob Gulewich exit(1); 21194bdecd9SRob Gulewich } 21294bdecd9SRob Gulewich 2137c478bd9Sstevel@tonic-gate bzero((char *)&obj, sizeof(obj)); 2147c478bd9Sstevel@tonic-gate obj.ipfo_rev = IPFILTER_VERSION; 2157c478bd9Sstevel@tonic-gate obj.ipfo_size = sizeof(*nsp); 2167c478bd9Sstevel@tonic-gate obj.ipfo_type = IPFOBJ_NATSTAT; 2177c478bd9Sstevel@tonic-gate obj.ipfo_ptr = (void *)nsp; 2187c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCGNATS, &obj) == -1) { 2197c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGNATS)"); 2207c478bd9Sstevel@tonic-gate exit(1); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate (void) setgid(getgid()); 2237c478bd9Sstevel@tonic-gate (void) setreuid(getuid(), getuid()); 2247c478bd9Sstevel@tonic-gate } else if ((kernel != NULL) || (core != NULL)) { 2257c478bd9Sstevel@tonic-gate if (openkmem(kernel, core) == -1) 2267c478bd9Sstevel@tonic-gate exit(1); 2277c478bd9Sstevel@tonic-gate 2287c478bd9Sstevel@tonic-gate natstat_dead(nsp, kernel); 2297c478bd9Sstevel@tonic-gate if (opts & (OPT_LIST|OPT_STAT)) 230f4b3ec61Sdh155122 dostats(fd, nsp, opts, 0); 2317c478bd9Sstevel@tonic-gate exit(0); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate 2347c478bd9Sstevel@tonic-gate if (opts & (OPT_FLUSH|OPT_CLEAR)) 2357c478bd9Sstevel@tonic-gate flushtable(fd, opts); 2367c478bd9Sstevel@tonic-gate if (file) { 2377c478bd9Sstevel@tonic-gate ipnat_parsefile(fd, ipnat_addrule, ioctl, file); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate if (opts & (OPT_LIST|OPT_STAT)) 240f4b3ec61Sdh155122 dostats(fd, nsp, opts, 1); 2417c478bd9Sstevel@tonic-gate return 0; 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate /* 2467c478bd9Sstevel@tonic-gate * Read NAT statistic information in using a symbol table and memory file 2477c478bd9Sstevel@tonic-gate * rather than doing ioctl's. 2487c478bd9Sstevel@tonic-gate */ 2497c478bd9Sstevel@tonic-gate void natstat_dead(nsp, kernel) 2507c478bd9Sstevel@tonic-gate natstat_t *nsp; 2517c478bd9Sstevel@tonic-gate char *kernel; 2527c478bd9Sstevel@tonic-gate { 2537c478bd9Sstevel@tonic-gate struct nlist nat_nlist[10] = { 2547c478bd9Sstevel@tonic-gate { "nat_table" }, /* 0 */ 2557c478bd9Sstevel@tonic-gate { "nat_list" }, 2567c478bd9Sstevel@tonic-gate { "maptable" }, 2577c478bd9Sstevel@tonic-gate { "ipf_nattable_sz" }, 2587c478bd9Sstevel@tonic-gate { "ipf_natrules_sz" }, 2597c478bd9Sstevel@tonic-gate { "ipf_rdrrules_sz" }, /* 5 */ 2607c478bd9Sstevel@tonic-gate { "ipf_hostmap_sz" }, 2617c478bd9Sstevel@tonic-gate { "nat_instances" }, 2627c478bd9Sstevel@tonic-gate { "ap_sess_list" }, 2637c478bd9Sstevel@tonic-gate { NULL } 2647c478bd9Sstevel@tonic-gate }; 2657c478bd9Sstevel@tonic-gate void *tables[2]; 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate if (nlist(kernel, nat_nlist) == -1) { 2687c478bd9Sstevel@tonic-gate fprintf(stderr, "nlist error\n"); 2697c478bd9Sstevel@tonic-gate return; 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate /* 2737c478bd9Sstevel@tonic-gate * Normally the ioctl copies all of these values into the structure 2747c478bd9Sstevel@tonic-gate * for us, before returning it to userland, so here we must copy each 2757c478bd9Sstevel@tonic-gate * one in individually. 2767c478bd9Sstevel@tonic-gate */ 2777c478bd9Sstevel@tonic-gate kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables)); 2787c478bd9Sstevel@tonic-gate nsp->ns_table[0] = tables[0]; 2797c478bd9Sstevel@tonic-gate nsp->ns_table[1] = tables[1]; 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value, 2827c478bd9Sstevel@tonic-gate sizeof(nsp->ns_list)); 2837c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value, 2847c478bd9Sstevel@tonic-gate sizeof(nsp->ns_maptable)); 2857c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value, 2867c478bd9Sstevel@tonic-gate sizeof(nsp->ns_nattab_sz)); 2877c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value, 2887c478bd9Sstevel@tonic-gate sizeof(nsp->ns_rultab_sz)); 2897c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value, 2907c478bd9Sstevel@tonic-gate sizeof(nsp->ns_rdrtab_sz)); 2917c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value, 2927c478bd9Sstevel@tonic-gate sizeof(nsp->ns_hostmap_sz)); 2937c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value, 2947c478bd9Sstevel@tonic-gate sizeof(nsp->ns_instances)); 2957c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value, 2967c478bd9Sstevel@tonic-gate sizeof(nsp->ns_apslist)); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate /* 3017c478bd9Sstevel@tonic-gate * Display NAT statistics. 3027c478bd9Sstevel@tonic-gate */ 303f4b3ec61Sdh155122 void dostats(fd, nsp, opts, alive) 3047c478bd9Sstevel@tonic-gate natstat_t *nsp; 305f4b3ec61Sdh155122 int fd, opts, alive; 3067c478bd9Sstevel@tonic-gate { 3077c478bd9Sstevel@tonic-gate nat_t *np, nat; 3087c478bd9Sstevel@tonic-gate ipnat_t ipn; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate /* 3117c478bd9Sstevel@tonic-gate * Show statistics ? 3127c478bd9Sstevel@tonic-gate */ 3137c478bd9Sstevel@tonic-gate if (opts & OPT_STAT) { 3147c478bd9Sstevel@tonic-gate printf("mapped\tin\t%lu\tout\t%lu\n", 3157c478bd9Sstevel@tonic-gate nsp->ns_mapped[0], nsp->ns_mapped[1]); 3167c478bd9Sstevel@tonic-gate printf("added\t%lu\texpired\t%lu\n", 3177c478bd9Sstevel@tonic-gate nsp->ns_added, nsp->ns_expire); 3187c478bd9Sstevel@tonic-gate printf("no memory\t%lu\tbad nat\t%lu\n", 3197c478bd9Sstevel@tonic-gate nsp->ns_memfail, nsp->ns_badnat); 3205b48165cSJohn Ojemann printf("inuse\t%lu\norphans\t%u\nrules\t%lu\n", 3215b48165cSJohn Ojemann nsp->ns_inuse, nsp->ns_orphans, nsp->ns_rules); 3227c478bd9Sstevel@tonic-gate printf("wilds\t%u\n", nsp->ns_wilds); 3237c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 3247c478bd9Sstevel@tonic-gate printf("table %p list %p\n", 3257c478bd9Sstevel@tonic-gate nsp->ns_table, nsp->ns_list); 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate /* 3297c478bd9Sstevel@tonic-gate * Show list of NAT rules and NAT sessions ? 3307c478bd9Sstevel@tonic-gate */ 3317c478bd9Sstevel@tonic-gate if (opts & OPT_LIST) { 332f4b3ec61Sdh155122 if (alive) { 333f4b3ec61Sdh155122 dostats_live(fd, nsp, opts); 334f4b3ec61Sdh155122 return; 335f4b3ec61Sdh155122 } 3367c478bd9Sstevel@tonic-gate printf("List of active MAP/Redirect filters:\n"); 3377c478bd9Sstevel@tonic-gate while (nsp->ns_list) { 3387c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&ipn, (long)nsp->ns_list, 3397c478bd9Sstevel@tonic-gate sizeof(ipn))) { 3407c478bd9Sstevel@tonic-gate perror("kmemcpy"); 3417c478bd9Sstevel@tonic-gate break; 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate if (opts & OPT_HITS) 344ab25eeb5Syz155240 printf("%lu ", ipn.in_hits); 3457c478bd9Sstevel@tonic-gate printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); 3467c478bd9Sstevel@tonic-gate nsp->ns_list = ipn.in_next; 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate printf("\nList of active sessions:\n"); 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate for (np = nsp->ns_instances; np; np = nat.nat_next) { 3527c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) 3537c478bd9Sstevel@tonic-gate break; 354f4b3ec61Sdh155122 printactivenat(&nat, opts, 0); 355ab25eeb5Syz155240 if (nat.nat_aps) 356ab25eeb5Syz155240 printaps(nat.nat_aps, opts); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 3607c478bd9Sstevel@tonic-gate showhostmap(nsp); 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate } 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate /* 3667c478bd9Sstevel@tonic-gate * Display the active host mapping table. 3677c478bd9Sstevel@tonic-gate */ 3687c478bd9Sstevel@tonic-gate void showhostmap(nsp) 3697c478bd9Sstevel@tonic-gate natstat_t *nsp; 3707c478bd9Sstevel@tonic-gate { 3717c478bd9Sstevel@tonic-gate hostmap_t hm, *hmp, **maptable; 3727c478bd9Sstevel@tonic-gate u_int hv; 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate printf("\nList of active host mappings:\n"); 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) * 3777c478bd9Sstevel@tonic-gate nsp->ns_hostmap_sz); 3785e985db5Sschuster if (maptable == NULL) { 3795e985db5Sschuster perror("malloc"); 3805e985db5Sschuster exit(1); 3815e985db5Sschuster } 3827c478bd9Sstevel@tonic-gate if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable, 3837c478bd9Sstevel@tonic-gate sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) { 3847c478bd9Sstevel@tonic-gate perror("kmemcpy (maptable)"); 3857c478bd9Sstevel@tonic-gate return; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) { 3897c478bd9Sstevel@tonic-gate hmp = maptable[hv]; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate while (hmp) { 3927c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) { 3937c478bd9Sstevel@tonic-gate perror("kmemcpy (hostmap)"); 3947c478bd9Sstevel@tonic-gate return; 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate printhostmap(&hm, hv); 3987c478bd9Sstevel@tonic-gate hmp = hm.hm_next; 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate } 4017c478bd9Sstevel@tonic-gate free(maptable); 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate /* 4067c478bd9Sstevel@tonic-gate * Issue an ioctl to flush either the NAT rules table or the active mapping 4077c478bd9Sstevel@tonic-gate * table or both. 4087c478bd9Sstevel@tonic-gate */ 4097c478bd9Sstevel@tonic-gate void flushtable(fd, opts) 4107c478bd9Sstevel@tonic-gate int fd, opts; 4117c478bd9Sstevel@tonic-gate { 4127c478bd9Sstevel@tonic-gate int n = 0; 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate if (opts & OPT_FLUSH) { 415ea8244dcSJohn Ojemann n = FLUSH_TABLE_ALL; 4167c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) 4177c478bd9Sstevel@tonic-gate perror("ioctl(SIOCFLNAT)"); 4187c478bd9Sstevel@tonic-gate else 4197c478bd9Sstevel@tonic-gate printf("%d entries flushed from NAT table\n", n); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate if (opts & OPT_CLEAR) { 423ea8244dcSJohn Ojemann n = FLUSH_LIST; 4247c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) 4257c478bd9Sstevel@tonic-gate perror("ioctl(SIOCCNATL)"); 4267c478bd9Sstevel@tonic-gate else 4277c478bd9Sstevel@tonic-gate printf("%d entries flushed from NAT list\n", n); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate } 430f4b3ec61Sdh155122 431f4b3ec61Sdh155122 /* 432f4b3ec61Sdh155122 * Display NAT statistics. 433f4b3ec61Sdh155122 */ 434f4b3ec61Sdh155122 void dostats_live(fd, nsp, opts) 435f4b3ec61Sdh155122 natstat_t *nsp; 436f4b3ec61Sdh155122 int fd, opts; 437f4b3ec61Sdh155122 { 438f4b3ec61Sdh155122 ipfgeniter_t iter; 439f4b3ec61Sdh155122 ipfobj_t obj; 440f4b3ec61Sdh155122 ipnat_t ipn; 441f4b3ec61Sdh155122 nat_t nat; 442f4b3ec61Sdh155122 443f4b3ec61Sdh155122 bzero((char *)&obj, sizeof(obj)); 444f4b3ec61Sdh155122 obj.ipfo_rev = IPFILTER_VERSION; 445f4b3ec61Sdh155122 obj.ipfo_type = IPFOBJ_GENITER; 446f4b3ec61Sdh155122 obj.ipfo_size = sizeof(iter); 447f4b3ec61Sdh155122 obj.ipfo_ptr = &iter; 448f4b3ec61Sdh155122 449f4b3ec61Sdh155122 iter.igi_type = IPFGENITER_IPNAT; 45090b0a856Sjojemann iter.igi_nitems = 1; 451f4b3ec61Sdh155122 iter.igi_data = &ipn; 452f4b3ec61Sdh155122 453f4b3ec61Sdh155122 /* 454f4b3ec61Sdh155122 * Show list of NAT rules and NAT sessions ? 455f4b3ec61Sdh155122 */ 456f4b3ec61Sdh155122 printf("List of active MAP/Redirect filters:\n"); 457f4b3ec61Sdh155122 while (nsp->ns_list) { 458f4b3ec61Sdh155122 if (ioctl(fd, SIOCGENITER, &obj) == -1) 459f4b3ec61Sdh155122 break; 460f4b3ec61Sdh155122 if (opts & OPT_HITS) 461f4b3ec61Sdh155122 printf("%lu ", ipn.in_hits); 462f4b3ec61Sdh155122 printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); 463f4b3ec61Sdh155122 nsp->ns_list = ipn.in_next; 464f4b3ec61Sdh155122 } 465f4b3ec61Sdh155122 466f4b3ec61Sdh155122 printf("\nList of active sessions:\n"); 467f4b3ec61Sdh155122 468f4b3ec61Sdh155122 iter.igi_type = IPFGENITER_NAT; 46990b0a856Sjojemann iter.igi_nitems = 1; 470f4b3ec61Sdh155122 iter.igi_data = &nat; 471f4b3ec61Sdh155122 472f4b3ec61Sdh155122 while (nsp->ns_instances != NULL) { 473f4b3ec61Sdh155122 if (ioctl(fd, SIOCGENITER, &obj) == -1) 474f4b3ec61Sdh155122 break; 475f4b3ec61Sdh155122 printactivenat(&nat, opts, 1); 476f4b3ec61Sdh155122 if (nat.nat_aps) 477f4b3ec61Sdh155122 printaps(nat.nat_aps, opts); 478f4b3ec61Sdh155122 nsp->ns_instances = nat.nat_next; 479f4b3ec61Sdh155122 } 480f4b3ec61Sdh155122 481f4b3ec61Sdh155122 if (opts & OPT_VERBOSE) 482f4b3ec61Sdh155122 showhostmap_live(fd, nsp); 483f4b3ec61Sdh155122 } 484f4b3ec61Sdh155122 485f4b3ec61Sdh155122 /* 486f4b3ec61Sdh155122 * Display the active host mapping table. 487f4b3ec61Sdh155122 */ 488f4b3ec61Sdh155122 void showhostmap_live(fd, nsp) 489f4b3ec61Sdh155122 int fd; 490f4b3ec61Sdh155122 natstat_t *nsp; 491f4b3ec61Sdh155122 { 492f4b3ec61Sdh155122 hostmap_t hm, *hmp; 493f4b3ec61Sdh155122 ipfgeniter_t iter; 494f4b3ec61Sdh155122 ipfobj_t obj; 495f4b3ec61Sdh155122 496f4b3ec61Sdh155122 bzero((char *)&obj, sizeof(obj)); 497f4b3ec61Sdh155122 obj.ipfo_rev = IPFILTER_VERSION; 498f4b3ec61Sdh155122 obj.ipfo_type = IPFOBJ_GENITER; 499f4b3ec61Sdh155122 obj.ipfo_size = sizeof(iter); 500f4b3ec61Sdh155122 obj.ipfo_ptr = &iter; 501f4b3ec61Sdh155122 502f4b3ec61Sdh155122 iter.igi_type = IPFGENITER_HOSTMAP; 503165f0692Sjojemann iter.igi_nitems = 1; 504f4b3ec61Sdh155122 iter.igi_data = &hm; 505f4b3ec61Sdh155122 506f4b3ec61Sdh155122 printf("\nList of active host mappings:\n"); 507f4b3ec61Sdh155122 508f4b3ec61Sdh155122 while (nsp->ns_maplist != NULL) { 509f4b3ec61Sdh155122 if (ioctl(fd, SIOCGENITER, &obj) == -1) 510f4b3ec61Sdh155122 break; 511f4b3ec61Sdh155122 printhostmap(&hm, 0); 512f4b3ec61Sdh155122 nsp->ns_maplist = hm.hm_next; 513f4b3ec61Sdh155122 } 514f4b3ec61Sdh155122 } 515