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 * 8f4b3ec61Sdh155122 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 97c478bd9Sstevel@tonic-gate * Use is subject to license terms. 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate 127c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 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" 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate #ifdef __hpux 627c478bd9Sstevel@tonic-gate # define nlist nlist64 637c478bd9Sstevel@tonic-gate #endif 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #if defined(sun) && !SOLARIS2 667c478bd9Sstevel@tonic-gate # define STRERROR(x) sys_errlist[x] 677c478bd9Sstevel@tonic-gate extern char *sys_errlist[]; 687c478bd9Sstevel@tonic-gate #else 697c478bd9Sstevel@tonic-gate # define STRERROR(x) strerror(x) 707c478bd9Sstevel@tonic-gate #endif 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate #if !defined(lint) 737c478bd9Sstevel@tonic-gate static const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; 74ab25eeb5Syz155240 static const char rcsid[] = "@(#)$Id: ipnat.c,v 1.24.2.2 2005/05/10 21:19:30 darrenr Exp $"; 757c478bd9Sstevel@tonic-gate #endif 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #if SOLARIS 797c478bd9Sstevel@tonic-gate #define bzero(a,b) memset(a,0,b) 807c478bd9Sstevel@tonic-gate #endif 817c478bd9Sstevel@tonic-gate int use_inet6 = 0; 827c478bd9Sstevel@tonic-gate char thishost[MAXHOSTNAMELEN]; 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate extern char *optarg; 857c478bd9Sstevel@tonic-gate 86f4b3ec61Sdh155122 void dostats __P((int, natstat_t *, int, int)); 87f4b3ec61Sdh155122 void flushtable __P((int, int)); 887c478bd9Sstevel@tonic-gate void usage __P((char *)); 897c478bd9Sstevel@tonic-gate int main __P((int, char*[])); 907c478bd9Sstevel@tonic-gate void showhostmap __P((natstat_t *nsp)); 917c478bd9Sstevel@tonic-gate void natstat_dead __P((natstat_t *, char *)); 92f4b3ec61Sdh155122 void dostats_live __P((int, natstat_t *, int)); 93f4b3ec61Sdh155122 void showhostmap_live __P((int, natstat_t *)); 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate int opts; 967c478bd9Sstevel@tonic-gate 977c478bd9Sstevel@tonic-gate void usage(name) 987c478bd9Sstevel@tonic-gate char *name; 997c478bd9Sstevel@tonic-gate { 10034ef97d0Sjojemann fprintf(stderr, "Usage: %s [-CdFhlnrRsv] [-f filename]\n", name); 1017c478bd9Sstevel@tonic-gate exit(1); 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate int main(argc, argv) 1067c478bd9Sstevel@tonic-gate int argc; 1077c478bd9Sstevel@tonic-gate char *argv[]; 1087c478bd9Sstevel@tonic-gate { 1097c478bd9Sstevel@tonic-gate char *file, *core, *kernel; 1107c478bd9Sstevel@tonic-gate natstat_t ns, *nsp; 1117c478bd9Sstevel@tonic-gate int fd, c, mode; 1127c478bd9Sstevel@tonic-gate ipfobj_t obj; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate fd = -1; 1157c478bd9Sstevel@tonic-gate opts = 0; 1167c478bd9Sstevel@tonic-gate nsp = &ns; 1177c478bd9Sstevel@tonic-gate file = NULL; 1187c478bd9Sstevel@tonic-gate core = NULL; 1197c478bd9Sstevel@tonic-gate kernel = NULL; 1207c478bd9Sstevel@tonic-gate mode = O_RDWR; 1217c478bd9Sstevel@tonic-gate 122ab25eeb5Syz155240 while ((c = getopt(argc, argv, "CdFf:hlM:N:nrRsv")) != -1) 1237c478bd9Sstevel@tonic-gate switch (c) 1247c478bd9Sstevel@tonic-gate { 1257c478bd9Sstevel@tonic-gate case 'C' : 1267c478bd9Sstevel@tonic-gate opts |= OPT_CLEAR; 1277c478bd9Sstevel@tonic-gate break; 1287c478bd9Sstevel@tonic-gate case 'd' : 1297c478bd9Sstevel@tonic-gate opts |= OPT_DEBUG; 1307c478bd9Sstevel@tonic-gate break; 1317c478bd9Sstevel@tonic-gate case 'f' : 1327c478bd9Sstevel@tonic-gate file = optarg; 1337c478bd9Sstevel@tonic-gate break; 1347c478bd9Sstevel@tonic-gate case 'F' : 1357c478bd9Sstevel@tonic-gate opts |= OPT_FLUSH; 1367c478bd9Sstevel@tonic-gate break; 1377c478bd9Sstevel@tonic-gate case 'h' : 1387c478bd9Sstevel@tonic-gate opts |=OPT_HITS; 1397c478bd9Sstevel@tonic-gate break; 1407c478bd9Sstevel@tonic-gate case 'l' : 1417c478bd9Sstevel@tonic-gate opts |= OPT_LIST; 1427c478bd9Sstevel@tonic-gate mode = O_RDONLY; 1437c478bd9Sstevel@tonic-gate break; 1447c478bd9Sstevel@tonic-gate case 'M' : 1457c478bd9Sstevel@tonic-gate core = optarg; 1467c478bd9Sstevel@tonic-gate break; 1477c478bd9Sstevel@tonic-gate case 'N' : 1487c478bd9Sstevel@tonic-gate kernel = optarg; 1497c478bd9Sstevel@tonic-gate break; 1507c478bd9Sstevel@tonic-gate case 'n' : 1517c478bd9Sstevel@tonic-gate opts |= OPT_DONOTHING; 1527c478bd9Sstevel@tonic-gate mode = O_RDONLY; 1537c478bd9Sstevel@tonic-gate break; 154ab25eeb5Syz155240 case 'R' : 155ab25eeb5Syz155240 opts |= OPT_NORESOLVE; 156ab25eeb5Syz155240 break; 1577c478bd9Sstevel@tonic-gate case 'r' : 1587c478bd9Sstevel@tonic-gate opts |= OPT_REMOVE; 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate case 's' : 1617c478bd9Sstevel@tonic-gate opts |= OPT_STAT; 1627c478bd9Sstevel@tonic-gate mode = O_RDONLY; 1637c478bd9Sstevel@tonic-gate break; 1647c478bd9Sstevel@tonic-gate case 'v' : 1657c478bd9Sstevel@tonic-gate opts |= OPT_VERBOSE; 1667c478bd9Sstevel@tonic-gate break; 1677c478bd9Sstevel@tonic-gate default : 1687c478bd9Sstevel@tonic-gate usage(argv[0]); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate initparse(); 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate if ((kernel != NULL) || (core != NULL)) { 1747c478bd9Sstevel@tonic-gate (void) setgid(getgid()); 1757c478bd9Sstevel@tonic-gate (void) setreuid(getuid(), getuid()); 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate 1787c478bd9Sstevel@tonic-gate bzero((char *)&ns, sizeof(ns)); 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate if ((opts & OPT_DONOTHING) == 0) { 1817c478bd9Sstevel@tonic-gate if (checkrev(IPL_NAME) == -1) { 1827c478bd9Sstevel@tonic-gate fprintf(stderr, "User/kernel version check failed\n"); 1837c478bd9Sstevel@tonic-gate exit(1); 1847c478bd9Sstevel@tonic-gate } 1857c478bd9Sstevel@tonic-gate } 1867c478bd9Sstevel@tonic-gate 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && (kernel == NULL) && (core == NULL)) { 189f4b3ec61Sdh155122 #ifdef notdef 1907c478bd9Sstevel@tonic-gate if (openkmem(kernel, core) == -1) 1917c478bd9Sstevel@tonic-gate exit(1); 192f4b3ec61Sdh155122 #endif 1937c478bd9Sstevel@tonic-gate if (((fd = open(IPNAT_NAME, mode)) == -1) && 1947c478bd9Sstevel@tonic-gate ((fd = open(IPNAT_NAME, O_RDONLY)) == -1)) { 1957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s: open: %s\n", IPNAT_NAME, 1967c478bd9Sstevel@tonic-gate STRERROR(errno)); 1977c478bd9Sstevel@tonic-gate exit(1); 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate bzero((char *)&obj, sizeof(obj)); 2017c478bd9Sstevel@tonic-gate obj.ipfo_rev = IPFILTER_VERSION; 2027c478bd9Sstevel@tonic-gate obj.ipfo_size = sizeof(*nsp); 2037c478bd9Sstevel@tonic-gate obj.ipfo_type = IPFOBJ_NATSTAT; 2047c478bd9Sstevel@tonic-gate obj.ipfo_ptr = (void *)nsp; 2057c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCGNATS, &obj) == -1) { 2067c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGNATS)"); 2077c478bd9Sstevel@tonic-gate exit(1); 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate (void) setgid(getgid()); 2107c478bd9Sstevel@tonic-gate (void) setreuid(getuid(), getuid()); 2117c478bd9Sstevel@tonic-gate } else if ((kernel != NULL) || (core != NULL)) { 2127c478bd9Sstevel@tonic-gate if (openkmem(kernel, core) == -1) 2137c478bd9Sstevel@tonic-gate exit(1); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate natstat_dead(nsp, kernel); 2167c478bd9Sstevel@tonic-gate if (opts & (OPT_LIST|OPT_STAT)) 217f4b3ec61Sdh155122 dostats(fd, nsp, opts, 0); 2187c478bd9Sstevel@tonic-gate exit(0); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate if (opts & (OPT_FLUSH|OPT_CLEAR)) 2227c478bd9Sstevel@tonic-gate flushtable(fd, opts); 2237c478bd9Sstevel@tonic-gate if (file) { 2247c478bd9Sstevel@tonic-gate ipnat_parsefile(fd, ipnat_addrule, ioctl, file); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate if (opts & (OPT_LIST|OPT_STAT)) 227f4b3ec61Sdh155122 dostats(fd, nsp, opts, 1); 2287c478bd9Sstevel@tonic-gate return 0; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate /* 2337c478bd9Sstevel@tonic-gate * Read NAT statistic information in using a symbol table and memory file 2347c478bd9Sstevel@tonic-gate * rather than doing ioctl's. 2357c478bd9Sstevel@tonic-gate */ 2367c478bd9Sstevel@tonic-gate void natstat_dead(nsp, kernel) 2377c478bd9Sstevel@tonic-gate natstat_t *nsp; 2387c478bd9Sstevel@tonic-gate char *kernel; 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate struct nlist nat_nlist[10] = { 2417c478bd9Sstevel@tonic-gate { "nat_table" }, /* 0 */ 2427c478bd9Sstevel@tonic-gate { "nat_list" }, 2437c478bd9Sstevel@tonic-gate { "maptable" }, 2447c478bd9Sstevel@tonic-gate { "ipf_nattable_sz" }, 2457c478bd9Sstevel@tonic-gate { "ipf_natrules_sz" }, 2467c478bd9Sstevel@tonic-gate { "ipf_rdrrules_sz" }, /* 5 */ 2477c478bd9Sstevel@tonic-gate { "ipf_hostmap_sz" }, 2487c478bd9Sstevel@tonic-gate { "nat_instances" }, 2497c478bd9Sstevel@tonic-gate { "ap_sess_list" }, 2507c478bd9Sstevel@tonic-gate { NULL } 2517c478bd9Sstevel@tonic-gate }; 2527c478bd9Sstevel@tonic-gate void *tables[2]; 2537c478bd9Sstevel@tonic-gate 2547c478bd9Sstevel@tonic-gate if (nlist(kernel, nat_nlist) == -1) { 2557c478bd9Sstevel@tonic-gate fprintf(stderr, "nlist error\n"); 2567c478bd9Sstevel@tonic-gate return; 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* 2607c478bd9Sstevel@tonic-gate * Normally the ioctl copies all of these values into the structure 2617c478bd9Sstevel@tonic-gate * for us, before returning it to userland, so here we must copy each 2627c478bd9Sstevel@tonic-gate * one in individually. 2637c478bd9Sstevel@tonic-gate */ 2647c478bd9Sstevel@tonic-gate kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables)); 2657c478bd9Sstevel@tonic-gate nsp->ns_table[0] = tables[0]; 2667c478bd9Sstevel@tonic-gate nsp->ns_table[1] = tables[1]; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value, 2697c478bd9Sstevel@tonic-gate sizeof(nsp->ns_list)); 2707c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value, 2717c478bd9Sstevel@tonic-gate sizeof(nsp->ns_maptable)); 2727c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value, 2737c478bd9Sstevel@tonic-gate sizeof(nsp->ns_nattab_sz)); 2747c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value, 2757c478bd9Sstevel@tonic-gate sizeof(nsp->ns_rultab_sz)); 2767c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value, 2777c478bd9Sstevel@tonic-gate sizeof(nsp->ns_rdrtab_sz)); 2787c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value, 2797c478bd9Sstevel@tonic-gate sizeof(nsp->ns_hostmap_sz)); 2807c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value, 2817c478bd9Sstevel@tonic-gate sizeof(nsp->ns_instances)); 2827c478bd9Sstevel@tonic-gate kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value, 2837c478bd9Sstevel@tonic-gate sizeof(nsp->ns_apslist)); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate /* 2887c478bd9Sstevel@tonic-gate * Display NAT statistics. 2897c478bd9Sstevel@tonic-gate */ 290f4b3ec61Sdh155122 void dostats(fd, nsp, opts, alive) 2917c478bd9Sstevel@tonic-gate natstat_t *nsp; 292f4b3ec61Sdh155122 int fd, opts, alive; 2937c478bd9Sstevel@tonic-gate { 2947c478bd9Sstevel@tonic-gate nat_t *np, nat; 2957c478bd9Sstevel@tonic-gate ipnat_t ipn; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /* 2987c478bd9Sstevel@tonic-gate * Show statistics ? 2997c478bd9Sstevel@tonic-gate */ 3007c478bd9Sstevel@tonic-gate if (opts & OPT_STAT) { 3017c478bd9Sstevel@tonic-gate printf("mapped\tin\t%lu\tout\t%lu\n", 3027c478bd9Sstevel@tonic-gate nsp->ns_mapped[0], nsp->ns_mapped[1]); 3037c478bd9Sstevel@tonic-gate printf("added\t%lu\texpired\t%lu\n", 3047c478bd9Sstevel@tonic-gate nsp->ns_added, nsp->ns_expire); 3057c478bd9Sstevel@tonic-gate printf("no memory\t%lu\tbad nat\t%lu\n", 3067c478bd9Sstevel@tonic-gate nsp->ns_memfail, nsp->ns_badnat); 3077c478bd9Sstevel@tonic-gate printf("inuse\t%lu\nrules\t%lu\n", 3087c478bd9Sstevel@tonic-gate nsp->ns_inuse, nsp->ns_rules); 3097c478bd9Sstevel@tonic-gate printf("wilds\t%u\n", nsp->ns_wilds); 3107c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 3117c478bd9Sstevel@tonic-gate printf("table %p list %p\n", 3127c478bd9Sstevel@tonic-gate nsp->ns_table, nsp->ns_list); 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate /* 3167c478bd9Sstevel@tonic-gate * Show list of NAT rules and NAT sessions ? 3177c478bd9Sstevel@tonic-gate */ 3187c478bd9Sstevel@tonic-gate if (opts & OPT_LIST) { 319f4b3ec61Sdh155122 if (alive) { 320f4b3ec61Sdh155122 dostats_live(fd, nsp, opts); 321f4b3ec61Sdh155122 return; 322f4b3ec61Sdh155122 } 3237c478bd9Sstevel@tonic-gate printf("List of active MAP/Redirect filters:\n"); 3247c478bd9Sstevel@tonic-gate while (nsp->ns_list) { 3257c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&ipn, (long)nsp->ns_list, 3267c478bd9Sstevel@tonic-gate sizeof(ipn))) { 3277c478bd9Sstevel@tonic-gate perror("kmemcpy"); 3287c478bd9Sstevel@tonic-gate break; 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate if (opts & OPT_HITS) 331ab25eeb5Syz155240 printf("%lu ", ipn.in_hits); 3327c478bd9Sstevel@tonic-gate printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); 3337c478bd9Sstevel@tonic-gate nsp->ns_list = ipn.in_next; 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate printf("\nList of active sessions:\n"); 3377c478bd9Sstevel@tonic-gate 3387c478bd9Sstevel@tonic-gate for (np = nsp->ns_instances; np; np = nat.nat_next) { 3397c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) 3407c478bd9Sstevel@tonic-gate break; 341f4b3ec61Sdh155122 printactivenat(&nat, opts, 0); 342ab25eeb5Syz155240 if (nat.nat_aps) 343ab25eeb5Syz155240 printaps(nat.nat_aps, opts); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 3477c478bd9Sstevel@tonic-gate showhostmap(nsp); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate /* 3537c478bd9Sstevel@tonic-gate * Display the active host mapping table. 3547c478bd9Sstevel@tonic-gate */ 3557c478bd9Sstevel@tonic-gate void showhostmap(nsp) 3567c478bd9Sstevel@tonic-gate natstat_t *nsp; 3577c478bd9Sstevel@tonic-gate { 3587c478bd9Sstevel@tonic-gate hostmap_t hm, *hmp, **maptable; 3597c478bd9Sstevel@tonic-gate u_int hv; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate printf("\nList of active host mappings:\n"); 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) * 3647c478bd9Sstevel@tonic-gate nsp->ns_hostmap_sz); 3655e985db5Sschuster if (maptable == NULL) { 3665e985db5Sschuster perror("malloc"); 3675e985db5Sschuster exit(1); 3685e985db5Sschuster } 3697c478bd9Sstevel@tonic-gate if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable, 3707c478bd9Sstevel@tonic-gate sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) { 3717c478bd9Sstevel@tonic-gate perror("kmemcpy (maptable)"); 3727c478bd9Sstevel@tonic-gate return; 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) { 3767c478bd9Sstevel@tonic-gate hmp = maptable[hv]; 3777c478bd9Sstevel@tonic-gate 3787c478bd9Sstevel@tonic-gate while (hmp) { 3797c478bd9Sstevel@tonic-gate if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) { 3807c478bd9Sstevel@tonic-gate perror("kmemcpy (hostmap)"); 3817c478bd9Sstevel@tonic-gate return; 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate printhostmap(&hm, hv); 3857c478bd9Sstevel@tonic-gate hmp = hm.hm_next; 3867c478bd9Sstevel@tonic-gate } 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate free(maptable); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate /* 3937c478bd9Sstevel@tonic-gate * Issue an ioctl to flush either the NAT rules table or the active mapping 3947c478bd9Sstevel@tonic-gate * table or both. 3957c478bd9Sstevel@tonic-gate */ 3967c478bd9Sstevel@tonic-gate void flushtable(fd, opts) 3977c478bd9Sstevel@tonic-gate int fd, opts; 3987c478bd9Sstevel@tonic-gate { 3997c478bd9Sstevel@tonic-gate int n = 0; 4007c478bd9Sstevel@tonic-gate 4017c478bd9Sstevel@tonic-gate if (opts & OPT_FLUSH) { 4027c478bd9Sstevel@tonic-gate n = 0; 4037c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) 4047c478bd9Sstevel@tonic-gate perror("ioctl(SIOCFLNAT)"); 4057c478bd9Sstevel@tonic-gate else 4067c478bd9Sstevel@tonic-gate printf("%d entries flushed from NAT table\n", n); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate if (opts & OPT_CLEAR) { 4107c478bd9Sstevel@tonic-gate n = 1; 4117c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) 4127c478bd9Sstevel@tonic-gate perror("ioctl(SIOCCNATL)"); 4137c478bd9Sstevel@tonic-gate else 4147c478bd9Sstevel@tonic-gate printf("%d entries flushed from NAT list\n", n); 4157c478bd9Sstevel@tonic-gate } 4167c478bd9Sstevel@tonic-gate } 417f4b3ec61Sdh155122 418f4b3ec61Sdh155122 /* 419f4b3ec61Sdh155122 * Display NAT statistics. 420f4b3ec61Sdh155122 */ 421f4b3ec61Sdh155122 void dostats_live(fd, nsp, opts) 422f4b3ec61Sdh155122 natstat_t *nsp; 423f4b3ec61Sdh155122 int fd, opts; 424f4b3ec61Sdh155122 { 425f4b3ec61Sdh155122 ipfgeniter_t iter; 426f4b3ec61Sdh155122 ipfobj_t obj; 427f4b3ec61Sdh155122 ipnat_t ipn; 428f4b3ec61Sdh155122 nat_t nat; 429f4b3ec61Sdh155122 430f4b3ec61Sdh155122 bzero((char *)&obj, sizeof(obj)); 431f4b3ec61Sdh155122 obj.ipfo_rev = IPFILTER_VERSION; 432f4b3ec61Sdh155122 obj.ipfo_type = IPFOBJ_GENITER; 433f4b3ec61Sdh155122 obj.ipfo_size = sizeof(iter); 434f4b3ec61Sdh155122 obj.ipfo_ptr = &iter; 435f4b3ec61Sdh155122 436f4b3ec61Sdh155122 iter.igi_type = IPFGENITER_IPNAT; 43790b0a856Sjojemann iter.igi_nitems = 1; 438f4b3ec61Sdh155122 iter.igi_data = &ipn; 439f4b3ec61Sdh155122 440f4b3ec61Sdh155122 /* 441f4b3ec61Sdh155122 * Show list of NAT rules and NAT sessions ? 442f4b3ec61Sdh155122 */ 443f4b3ec61Sdh155122 printf("List of active MAP/Redirect filters:\n"); 444f4b3ec61Sdh155122 while (nsp->ns_list) { 445f4b3ec61Sdh155122 if (ioctl(fd, SIOCGENITER, &obj) == -1) 446f4b3ec61Sdh155122 break; 447f4b3ec61Sdh155122 if (opts & OPT_HITS) 448f4b3ec61Sdh155122 printf("%lu ", ipn.in_hits); 449f4b3ec61Sdh155122 printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); 450f4b3ec61Sdh155122 nsp->ns_list = ipn.in_next; 451f4b3ec61Sdh155122 } 452f4b3ec61Sdh155122 453*165f0692Sjojemann (void) ioctl(fd, SIOCIPFDELTOK, &iter.igi_type); 454*165f0692Sjojemann 455f4b3ec61Sdh155122 printf("\nList of active sessions:\n"); 456f4b3ec61Sdh155122 457f4b3ec61Sdh155122 iter.igi_type = IPFGENITER_NAT; 45890b0a856Sjojemann iter.igi_nitems = 1; 459f4b3ec61Sdh155122 iter.igi_data = &nat; 460f4b3ec61Sdh155122 461f4b3ec61Sdh155122 while (nsp->ns_instances != NULL) { 462f4b3ec61Sdh155122 if (ioctl(fd, SIOCGENITER, &obj) == -1) 463f4b3ec61Sdh155122 break; 464f4b3ec61Sdh155122 printactivenat(&nat, opts, 1); 465f4b3ec61Sdh155122 if (nat.nat_aps) 466f4b3ec61Sdh155122 printaps(nat.nat_aps, opts); 467f4b3ec61Sdh155122 nsp->ns_instances = nat.nat_next; 468f4b3ec61Sdh155122 } 469f4b3ec61Sdh155122 47090b0a856Sjojemann (void) ioctl(fd, SIOCIPFDELTOK, &iter.igi_type); 47190b0a856Sjojemann 472f4b3ec61Sdh155122 if (opts & OPT_VERBOSE) 473f4b3ec61Sdh155122 showhostmap_live(fd, nsp); 474f4b3ec61Sdh155122 } 475f4b3ec61Sdh155122 476f4b3ec61Sdh155122 /* 477f4b3ec61Sdh155122 * Display the active host mapping table. 478f4b3ec61Sdh155122 */ 479f4b3ec61Sdh155122 void showhostmap_live(fd, nsp) 480f4b3ec61Sdh155122 int fd; 481f4b3ec61Sdh155122 natstat_t *nsp; 482f4b3ec61Sdh155122 { 483f4b3ec61Sdh155122 hostmap_t hm, *hmp; 484f4b3ec61Sdh155122 ipfgeniter_t iter; 485f4b3ec61Sdh155122 ipfobj_t obj; 486f4b3ec61Sdh155122 487f4b3ec61Sdh155122 bzero((char *)&obj, sizeof(obj)); 488f4b3ec61Sdh155122 obj.ipfo_rev = IPFILTER_VERSION; 489f4b3ec61Sdh155122 obj.ipfo_type = IPFOBJ_GENITER; 490f4b3ec61Sdh155122 obj.ipfo_size = sizeof(iter); 491f4b3ec61Sdh155122 obj.ipfo_ptr = &iter; 492f4b3ec61Sdh155122 493f4b3ec61Sdh155122 iter.igi_type = IPFGENITER_HOSTMAP; 494*165f0692Sjojemann iter.igi_nitems = 1; 495f4b3ec61Sdh155122 iter.igi_data = &hm; 496f4b3ec61Sdh155122 497f4b3ec61Sdh155122 printf("\nList of active host mappings:\n"); 498f4b3ec61Sdh155122 499f4b3ec61Sdh155122 while (nsp->ns_maplist != NULL) { 500f4b3ec61Sdh155122 if (ioctl(fd, SIOCGENITER, &obj) == -1) 501f4b3ec61Sdh155122 break; 502f4b3ec61Sdh155122 printhostmap(&hm, 0); 503f4b3ec61Sdh155122 nsp->ns_maplist = hm.hm_next; 504f4b3ec61Sdh155122 } 505*165f0692Sjojemann 506*165f0692Sjojemann (void) ioctl(fd, SIOCIPFDELTOK, &iter.igi_type); 507f4b3ec61Sdh155122 } 508