1145519Sdarrenr/* $FreeBSD$ */ 2145510Sdarrenr 3145510Sdarrenr/* 4170268Sdarrenr * Copyright (C) 2001-2006 by Darren Reed. 5145510Sdarrenr * 6145510Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 7145510Sdarrenr * 8145510Sdarrenr * Added redirect stuff and a variety of bug fixes. (mcn@EnGarde.com) 9145510Sdarrenr */ 10145510Sdarrenr#include <stdio.h> 11145510Sdarrenr#include <string.h> 12145510Sdarrenr#include <fcntl.h> 13145510Sdarrenr#include <errno.h> 14145510Sdarrenr#include <sys/types.h> 15145510Sdarrenr#if !defined(__SVR4) && !defined(__svr4__) 16145510Sdarrenr#include <strings.h> 17145510Sdarrenr#else 18145510Sdarrenr#include <sys/byteorder.h> 19145510Sdarrenr#endif 20145510Sdarrenr#include <sys/time.h> 21145510Sdarrenr#include <sys/param.h> 22145510Sdarrenr#include <stdlib.h> 23145510Sdarrenr#include <unistd.h> 24145510Sdarrenr#include <stddef.h> 25145510Sdarrenr#include <sys/file.h> 26145510Sdarrenr#define _KERNEL 27145510Sdarrenr#include <sys/uio.h> 28145510Sdarrenr#undef _KERNEL 29145510Sdarrenr#include <sys/socket.h> 30145510Sdarrenr#include <sys/ioctl.h> 31145510Sdarrenr#if defined(sun) && (defined(__svr4__) || defined(__SVR4)) 32145510Sdarrenr# include <sys/ioccom.h> 33145510Sdarrenr# include <sys/sysmacros.h> 34145510Sdarrenr#endif 35145510Sdarrenr#include <netinet/in.h> 36145510Sdarrenr#include <netinet/in_systm.h> 37145510Sdarrenr#include <netinet/ip.h> 38145510Sdarrenr#include <netinet/tcp.h> 39145510Sdarrenr#include <net/if.h> 40145510Sdarrenr#if __FreeBSD_version >= 300000 41145510Sdarrenr# include <net/if_var.h> 42145510Sdarrenr#endif 43145510Sdarrenr#include <netdb.h> 44145510Sdarrenr#include <arpa/nameser.h> 45145510Sdarrenr#include <arpa/inet.h> 46145510Sdarrenr#include <resolv.h> 47145510Sdarrenr#include <ctype.h> 48145510Sdarrenr#if defined(linux) 49145510Sdarrenr# include <linux/a.out.h> 50145510Sdarrenr#else 51145510Sdarrenr# include <nlist.h> 52145510Sdarrenr#endif 53145510Sdarrenr#include "ipf.h" 54145554Sdarrenr#include "netinet/ipl.h" 55145510Sdarrenr#include "kmem.h" 56145510Sdarrenr 57145510Sdarrenr#ifdef __hpux 58145510Sdarrenr# define nlist nlist64 59145510Sdarrenr#endif 60145510Sdarrenr 61145510Sdarrenr#if defined(sun) && !SOLARIS2 62145510Sdarrenr# define STRERROR(x) sys_errlist[x] 63145510Sdarrenrextern char *sys_errlist[]; 64145510Sdarrenr#else 65145510Sdarrenr# define STRERROR(x) strerror(x) 66145510Sdarrenr#endif 67145510Sdarrenr 68145510Sdarrenr#if !defined(lint) 69145510Sdarrenrstatic const char sccsid[] ="@(#)ipnat.c 1.9 6/5/96 (C) 1993 Darren Reed"; 70172776Sdarrenrstatic const char rcsid[] = "@(#)$Id: ipnat.c,v 1.24.2.11 2007/09/25 08:27:34 darrenr Exp $"; 71145510Sdarrenr#endif 72145510Sdarrenr 73145510Sdarrenr 74145510Sdarrenr#if SOLARIS 75145510Sdarrenr#define bzero(a,b) memset(a,0,b) 76145510Sdarrenr#endif 77145510Sdarrenrint use_inet6 = 0; 78145510Sdarrenrchar thishost[MAXHOSTNAMELEN]; 79145510Sdarrenr 80145510Sdarrenrextern char *optarg; 81145510Sdarrenr 82170268Sdarrenrvoid dostats __P((int, natstat_t *, int, int)); 83172776Sdarrenrvoid dotable __P((natstat_t *, int, int)); 84170268Sdarrenrvoid flushtable __P((int, int)); 85145510Sdarrenrvoid usage __P((char *)); 86145510Sdarrenrint main __P((int, char*[])); 87145510Sdarrenrvoid showhostmap __P((natstat_t *nsp)); 88145510Sdarrenrvoid natstat_dead __P((natstat_t *, char *)); 89170268Sdarrenrvoid dostats_live __P((int, natstat_t *, int)); 90170268Sdarrenrvoid showhostmap_dead __P((natstat_t *)); 91170268Sdarrenrvoid showhostmap_live __P((int, natstat_t *)); 92170268Sdarrenrvoid dostats_dead __P((natstat_t *, int)); 93170268Sdarrenrvoid showtqtable_live __P((int)); 94145510Sdarrenr 95145510Sdarrenrint opts; 96145510Sdarrenr 97145510Sdarrenrvoid usage(name) 98145510Sdarrenrchar *name; 99145510Sdarrenr{ 100145510Sdarrenr fprintf(stderr, "Usage: %s [-CFhlnrRsv] [-f filename]\n", name); 101145510Sdarrenr exit(1); 102145510Sdarrenr} 103145510Sdarrenr 104145510Sdarrenr 105145510Sdarrenrint main(argc, argv) 106145510Sdarrenrint argc; 107145510Sdarrenrchar *argv[]; 108145510Sdarrenr{ 109145510Sdarrenr char *file, *core, *kernel; 110145510Sdarrenr natstat_t ns, *nsp; 111145510Sdarrenr int fd, c, mode; 112145510Sdarrenr ipfobj_t obj; 113145510Sdarrenr 114145510Sdarrenr fd = -1; 115145510Sdarrenr opts = 0; 116145510Sdarrenr nsp = &ns; 117145510Sdarrenr file = NULL; 118145510Sdarrenr core = NULL; 119145510Sdarrenr kernel = NULL; 120145510Sdarrenr mode = O_RDWR; 121145510Sdarrenr 122145510Sdarrenr while ((c = getopt(argc, argv, "CdFf:hlM:N:nrRsv")) != -1) 123145510Sdarrenr switch (c) 124145510Sdarrenr { 125145510Sdarrenr case 'C' : 126145510Sdarrenr opts |= OPT_CLEAR; 127145510Sdarrenr break; 128145510Sdarrenr case 'd' : 129145510Sdarrenr opts |= OPT_DEBUG; 130145510Sdarrenr break; 131145510Sdarrenr case 'f' : 132145510Sdarrenr file = optarg; 133145510Sdarrenr break; 134145510Sdarrenr case 'F' : 135145510Sdarrenr opts |= OPT_FLUSH; 136145510Sdarrenr break; 137145510Sdarrenr case 'h' : 138145510Sdarrenr opts |=OPT_HITS; 139145510Sdarrenr break; 140145510Sdarrenr case 'l' : 141145510Sdarrenr opts |= OPT_LIST; 142145510Sdarrenr mode = O_RDONLY; 143145510Sdarrenr break; 144145510Sdarrenr case 'M' : 145145510Sdarrenr core = optarg; 146145510Sdarrenr break; 147145510Sdarrenr case 'N' : 148145510Sdarrenr kernel = optarg; 149145510Sdarrenr break; 150145510Sdarrenr case 'n' : 151145510Sdarrenr opts |= OPT_DONOTHING; 152145510Sdarrenr mode = O_RDONLY; 153145510Sdarrenr break; 154145510Sdarrenr case 'R' : 155145510Sdarrenr opts |= OPT_NORESOLVE; 156145510Sdarrenr break; 157145510Sdarrenr case 'r' : 158145510Sdarrenr opts |= OPT_REMOVE; 159145510Sdarrenr break; 160145510Sdarrenr case 's' : 161145510Sdarrenr opts |= OPT_STAT; 162145510Sdarrenr mode = O_RDONLY; 163145510Sdarrenr break; 164145510Sdarrenr case 'v' : 165145510Sdarrenr opts |= OPT_VERBOSE; 166145510Sdarrenr break; 167145510Sdarrenr default : 168145510Sdarrenr usage(argv[0]); 169145510Sdarrenr } 170145510Sdarrenr 171145510Sdarrenr initparse(); 172145510Sdarrenr 173145510Sdarrenr if ((kernel != NULL) || (core != NULL)) { 174145510Sdarrenr (void) setgid(getgid()); 175145510Sdarrenr (void) setuid(getuid()); 176145510Sdarrenr } 177145510Sdarrenr 178170268Sdarrenr if (!(opts & OPT_DONOTHING)) { 179170268Sdarrenr if (((fd = open(IPNAT_NAME, mode)) == -1) && 180170268Sdarrenr ((fd = open(IPNAT_NAME, O_RDONLY)) == -1)) { 181170268Sdarrenr (void) fprintf(stderr, "%s: open: %s\n", IPNAT_NAME, 182170268Sdarrenr STRERROR(errno)); 183170268Sdarrenr exit(1); 184170268Sdarrenr } 185170268Sdarrenr } 186170268Sdarrenr 187145510Sdarrenr bzero((char *)&ns, sizeof(ns)); 188145510Sdarrenr 189145510Sdarrenr if ((opts & OPT_DONOTHING) == 0) { 190145510Sdarrenr if (checkrev(IPL_NAME) == -1) { 191145510Sdarrenr fprintf(stderr, "User/kernel version check failed\n"); 192145510Sdarrenr exit(1); 193145510Sdarrenr } 194145510Sdarrenr } 195145510Sdarrenr 196145510Sdarrenr if (!(opts & OPT_DONOTHING) && (kernel == NULL) && (core == NULL)) { 197145510Sdarrenr bzero((char *)&obj, sizeof(obj)); 198145510Sdarrenr obj.ipfo_rev = IPFILTER_VERSION; 199170268Sdarrenr obj.ipfo_type = IPFOBJ_NATSTAT; 200145510Sdarrenr obj.ipfo_size = sizeof(*nsp); 201145510Sdarrenr obj.ipfo_ptr = (void *)nsp; 202145510Sdarrenr if (ioctl(fd, SIOCGNATS, &obj) == -1) { 203145510Sdarrenr perror("ioctl(SIOCGNATS)"); 204145510Sdarrenr exit(1); 205145510Sdarrenr } 206145510Sdarrenr (void) setgid(getgid()); 207145510Sdarrenr (void) setuid(getuid()); 208145510Sdarrenr } else if ((kernel != NULL) || (core != NULL)) { 209145510Sdarrenr if (openkmem(kernel, core) == -1) 210145510Sdarrenr exit(1); 211145510Sdarrenr 212145510Sdarrenr natstat_dead(nsp, kernel); 213145510Sdarrenr if (opts & (OPT_LIST|OPT_STAT)) 214170268Sdarrenr dostats(fd, nsp, opts, 0); 215145510Sdarrenr exit(0); 216145510Sdarrenr } 217145510Sdarrenr 218145510Sdarrenr if (opts & (OPT_FLUSH|OPT_CLEAR)) 219145510Sdarrenr flushtable(fd, opts); 220145510Sdarrenr if (file) { 221145510Sdarrenr ipnat_parsefile(fd, ipnat_addrule, ioctl, file); 222145510Sdarrenr } 223145510Sdarrenr if (opts & (OPT_LIST|OPT_STAT)) 224170268Sdarrenr dostats(fd, nsp, opts, 1); 225145510Sdarrenr return 0; 226145510Sdarrenr} 227145510Sdarrenr 228145510Sdarrenr 229145510Sdarrenr/* 230145510Sdarrenr * Read NAT statistic information in using a symbol table and memory file 231145510Sdarrenr * rather than doing ioctl's. 232145510Sdarrenr */ 233145510Sdarrenrvoid natstat_dead(nsp, kernel) 234145510Sdarrenrnatstat_t *nsp; 235145510Sdarrenrchar *kernel; 236145510Sdarrenr{ 237145510Sdarrenr struct nlist nat_nlist[10] = { 238145510Sdarrenr { "nat_table" }, /* 0 */ 239145510Sdarrenr { "nat_list" }, 240145510Sdarrenr { "maptable" }, 241145510Sdarrenr { "ipf_nattable_sz" }, 242145510Sdarrenr { "ipf_natrules_sz" }, 243145510Sdarrenr { "ipf_rdrrules_sz" }, /* 5 */ 244145510Sdarrenr { "ipf_hostmap_sz" }, 245145510Sdarrenr { "nat_instances" }, 246145510Sdarrenr { "ap_sess_list" }, 247145510Sdarrenr { NULL } 248145510Sdarrenr }; 249145510Sdarrenr void *tables[2]; 250145510Sdarrenr 251145510Sdarrenr if (nlist(kernel, nat_nlist) == -1) { 252145510Sdarrenr fprintf(stderr, "nlist error\n"); 253145510Sdarrenr return; 254145510Sdarrenr } 255145510Sdarrenr 256145510Sdarrenr /* 257145510Sdarrenr * Normally the ioctl copies all of these values into the structure 258145510Sdarrenr * for us, before returning it to userland, so here we must copy each 259145510Sdarrenr * one in individually. 260145510Sdarrenr */ 261145510Sdarrenr kmemcpy((char *)&tables, nat_nlist[0].n_value, sizeof(tables)); 262145510Sdarrenr nsp->ns_table[0] = tables[0]; 263145510Sdarrenr nsp->ns_table[1] = tables[1]; 264145510Sdarrenr 265145510Sdarrenr kmemcpy((char *)&nsp->ns_list, nat_nlist[1].n_value, 266145510Sdarrenr sizeof(nsp->ns_list)); 267145510Sdarrenr kmemcpy((char *)&nsp->ns_maptable, nat_nlist[2].n_value, 268145510Sdarrenr sizeof(nsp->ns_maptable)); 269145510Sdarrenr kmemcpy((char *)&nsp->ns_nattab_sz, nat_nlist[3].n_value, 270145510Sdarrenr sizeof(nsp->ns_nattab_sz)); 271145510Sdarrenr kmemcpy((char *)&nsp->ns_rultab_sz, nat_nlist[4].n_value, 272145510Sdarrenr sizeof(nsp->ns_rultab_sz)); 273145510Sdarrenr kmemcpy((char *)&nsp->ns_rdrtab_sz, nat_nlist[5].n_value, 274145510Sdarrenr sizeof(nsp->ns_rdrtab_sz)); 275145510Sdarrenr kmemcpy((char *)&nsp->ns_hostmap_sz, nat_nlist[6].n_value, 276145510Sdarrenr sizeof(nsp->ns_hostmap_sz)); 277145510Sdarrenr kmemcpy((char *)&nsp->ns_instances, nat_nlist[7].n_value, 278145510Sdarrenr sizeof(nsp->ns_instances)); 279145510Sdarrenr kmemcpy((char *)&nsp->ns_apslist, nat_nlist[8].n_value, 280145510Sdarrenr sizeof(nsp->ns_apslist)); 281145510Sdarrenr} 282145510Sdarrenr 283145510Sdarrenr 284145510Sdarrenr/* 285170268Sdarrenr * Issue an ioctl to flush either the NAT rules table or the active mapping 286170268Sdarrenr * table or both. 287170268Sdarrenr */ 288170268Sdarrenrvoid flushtable(fd, opts) 289170268Sdarrenrint fd, opts; 290170268Sdarrenr{ 291170268Sdarrenr int n = 0; 292170268Sdarrenr 293170268Sdarrenr if (opts & OPT_FLUSH) { 294170268Sdarrenr n = 0; 295170268Sdarrenr if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) 296170268Sdarrenr perror("ioctl(SIOCFLNAT)"); 297170268Sdarrenr else 298170268Sdarrenr printf("%d entries flushed from NAT table\n", n); 299170268Sdarrenr } 300170268Sdarrenr 301170268Sdarrenr if (opts & OPT_CLEAR) { 302170268Sdarrenr n = 1; 303170268Sdarrenr if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &n) == -1) 304170268Sdarrenr perror("ioctl(SIOCCNATL)"); 305170268Sdarrenr else 306170268Sdarrenr printf("%d entries flushed from NAT list\n", n); 307170268Sdarrenr } 308170268Sdarrenr} 309170268Sdarrenr 310170268Sdarrenr 311170268Sdarrenr/* 312145510Sdarrenr * Display NAT statistics. 313145510Sdarrenr */ 314170268Sdarrenrvoid dostats_dead(nsp, opts) 315145510Sdarrenrnatstat_t *nsp; 316145510Sdarrenrint opts; 317145510Sdarrenr{ 318145510Sdarrenr nat_t *np, nat; 319145510Sdarrenr ipnat_t ipn; 320145510Sdarrenr 321170268Sdarrenr printf("List of active MAP/Redirect filters:\n"); 322170268Sdarrenr while (nsp->ns_list) { 323170268Sdarrenr if (kmemcpy((char *)&ipn, (long)nsp->ns_list, 324170268Sdarrenr sizeof(ipn))) { 325170268Sdarrenr perror("kmemcpy"); 326170268Sdarrenr break; 327170268Sdarrenr } 328170268Sdarrenr if (opts & OPT_HITS) 329170268Sdarrenr printf("%lu ", ipn.in_hits); 330170268Sdarrenr printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); 331170268Sdarrenr nsp->ns_list = ipn.in_next; 332170268Sdarrenr } 333170268Sdarrenr 334170268Sdarrenr printf("\nList of active sessions:\n"); 335170268Sdarrenr 336170268Sdarrenr for (np = nsp->ns_instances; np; np = nat.nat_next) { 337170268Sdarrenr if (kmemcpy((char *)&nat, (long)np, sizeof(nat))) 338170268Sdarrenr break; 339170268Sdarrenr printactivenat(&nat, opts, 0, nsp->ns_ticks); 340170268Sdarrenr if (nat.nat_aps) 341170268Sdarrenr printaps(nat.nat_aps, opts); 342170268Sdarrenr } 343170268Sdarrenr 344170268Sdarrenr if (opts & OPT_VERBOSE) 345170268Sdarrenr showhostmap_dead(nsp); 346170268Sdarrenr} 347170268Sdarrenr 348170268Sdarrenr 349170268Sdarrenrvoid dostats(fd, nsp, opts, alive) 350170268Sdarrenrnatstat_t *nsp; 351170268Sdarrenrint fd, opts, alive; 352170268Sdarrenr{ 353145510Sdarrenr /* 354145510Sdarrenr * Show statistics ? 355145510Sdarrenr */ 356145510Sdarrenr if (opts & OPT_STAT) { 357145510Sdarrenr printf("mapped\tin\t%lu\tout\t%lu\n", 358145510Sdarrenr nsp->ns_mapped[0], nsp->ns_mapped[1]); 359145510Sdarrenr printf("added\t%lu\texpired\t%lu\n", 360145510Sdarrenr nsp->ns_added, nsp->ns_expire); 361145510Sdarrenr printf("no memory\t%lu\tbad nat\t%lu\n", 362145510Sdarrenr nsp->ns_memfail, nsp->ns_badnat); 363172776Sdarrenr printf("inuse\t%lu\norphans\t%u\nrules\t%lu\n", 364172776Sdarrenr nsp->ns_inuse, nsp->ns_orphans, nsp->ns_rules); 365145510Sdarrenr printf("wilds\t%u\n", nsp->ns_wilds); 366172776Sdarrenr dotable(nsp, fd, alive); 367145510Sdarrenr if (opts & OPT_VERBOSE) 368145510Sdarrenr printf("table %p list %p\n", 369145510Sdarrenr nsp->ns_table, nsp->ns_list); 370170268Sdarrenr if (alive) 371170268Sdarrenr showtqtable_live(fd); 372145510Sdarrenr } 373145510Sdarrenr 374170268Sdarrenr if (opts & OPT_LIST) { 375170268Sdarrenr if (alive) 376170268Sdarrenr dostats_live(fd, nsp, opts); 377170268Sdarrenr else 378170268Sdarrenr dostats_dead(nsp, opts); 379170268Sdarrenr } 380170268Sdarrenr} 381170268Sdarrenr 382170268Sdarrenr 383172776Sdarrenrvoid dotable(nsp, fd, alive) 384172776Sdarrenrnatstat_t *nsp; 385172776Sdarrenrint fd, alive; 386172776Sdarrenr{ 387172776Sdarrenr int sz, i, used, totallen, maxlen, minlen; 388172776Sdarrenr ipftable_t table; 389172776Sdarrenr u_long *buckets; 390172776Sdarrenr ipfobj_t obj; 391172776Sdarrenr 392172776Sdarrenr sz = sizeof(*buckets) * nsp->ns_nattab_sz; 393172776Sdarrenr buckets = (u_long *)malloc(sz); 394172776Sdarrenr 395172776Sdarrenr obj.ipfo_rev = IPFILTER_VERSION; 396172776Sdarrenr obj.ipfo_type = IPFOBJ_GTABLE; 397172776Sdarrenr obj.ipfo_size = sizeof(table); 398172776Sdarrenr obj.ipfo_ptr = &table; 399172776Sdarrenr 400172776Sdarrenr table.ita_type = IPFTABLE_BUCKETS_NATIN; 401172776Sdarrenr table.ita_table = buckets; 402172776Sdarrenr 403172776Sdarrenr if (alive) { 404172776Sdarrenr if (ioctl(fd, SIOCGTABL, &obj) != 0) { 405172776Sdarrenr free(buckets); 406172776Sdarrenr return; 407172776Sdarrenr } 408172776Sdarrenr } else { 409172776Sdarrenr if (kmemcpy((char *)buckets, (u_long)nsp->ns_nattab_sz, sz)) { 410172776Sdarrenr free(buckets); 411172776Sdarrenr return; 412172776Sdarrenr } 413172776Sdarrenr } 414172776Sdarrenr 415172776Sdarrenr totallen = 0; 416172776Sdarrenr maxlen = 0; 417172776Sdarrenr minlen = nsp->ns_inuse; 418172776Sdarrenr used = 0; 419172776Sdarrenr 420172776Sdarrenr for (i = 0; i < nsp->ns_nattab_sz; i++) { 421172776Sdarrenr if (buckets[i] > maxlen) 422172776Sdarrenr maxlen = buckets[i]; 423172776Sdarrenr if (buckets[i] < minlen) 424172776Sdarrenr minlen = buckets[i]; 425172776Sdarrenr if (buckets[i] != 0) 426172776Sdarrenr used++; 427172776Sdarrenr totallen += buckets[i]; 428172776Sdarrenr } 429172776Sdarrenr 430172776Sdarrenr printf("hash efficiency\t%2.2f%%\n", 431172776Sdarrenr totallen ? ((float)used / totallen) * 100.0 : 0.0); 432172776Sdarrenr printf("bucket usage\t%2.2f%%\n", 433172776Sdarrenr ((float)used / nsp->ns_nattab_sz) * 100.0); 434172776Sdarrenr printf("minimal length\t%d\n", minlen); 435172776Sdarrenr printf("maximal length\t%d\n", maxlen); 436172776Sdarrenr printf("average length\t%.3f\n", used ? (float)totallen / used : 0.0); 437172776Sdarrenr} 438172776Sdarrenr 439172776Sdarrenr 440170268Sdarrenr/* 441170268Sdarrenr * Display NAT statistics. 442170268Sdarrenr */ 443170268Sdarrenrvoid dostats_live(fd, nsp, opts) 444170268Sdarrenrnatstat_t *nsp; 445170268Sdarrenrint fd, opts; 446170268Sdarrenr{ 447170268Sdarrenr ipfgeniter_t iter; 448170268Sdarrenr ipfobj_t obj; 449170268Sdarrenr ipnat_t ipn; 450170268Sdarrenr nat_t nat; 451170268Sdarrenr 452170268Sdarrenr bzero((char *)&obj, sizeof(obj)); 453170268Sdarrenr obj.ipfo_rev = IPFILTER_VERSION; 454170268Sdarrenr obj.ipfo_type = IPFOBJ_GENITER; 455170268Sdarrenr obj.ipfo_size = sizeof(iter); 456170268Sdarrenr obj.ipfo_ptr = &iter; 457170268Sdarrenr 458170268Sdarrenr iter.igi_type = IPFGENITER_IPNAT; 459170268Sdarrenr iter.igi_nitems = 1; 460170268Sdarrenr iter.igi_data = &ipn; 461170268Sdarrenr 462145510Sdarrenr /* 463145510Sdarrenr * Show list of NAT rules and NAT sessions ? 464145510Sdarrenr */ 465170268Sdarrenr printf("List of active MAP/Redirect filters:\n"); 466170268Sdarrenr while (nsp->ns_list) { 467170268Sdarrenr if (ioctl(fd, SIOCGENITER, &obj) == -1) 468170268Sdarrenr break; 469170268Sdarrenr if (opts & OPT_HITS) 470170268Sdarrenr printf("%lu ", ipn.in_hits); 471170268Sdarrenr printnat(&ipn, opts & (OPT_DEBUG|OPT_VERBOSE)); 472170268Sdarrenr nsp->ns_list = ipn.in_next; 473170268Sdarrenr } 474145510Sdarrenr 475170268Sdarrenr printf("\nList of active sessions:\n"); 476145510Sdarrenr 477170268Sdarrenr iter.igi_type = IPFGENITER_NAT; 478170268Sdarrenr iter.igi_nitems = 1; 479170268Sdarrenr iter.igi_data = &nat; 480145510Sdarrenr 481170268Sdarrenr while (nsp->ns_instances != NULL) { 482170268Sdarrenr if (ioctl(fd, SIOCGENITER, &obj) == -1) 483170268Sdarrenr break; 484170268Sdarrenr printactivenat(&nat, opts, 1, nsp->ns_ticks); 485170268Sdarrenr if (nat.nat_aps) 486170268Sdarrenr printaps(nat.nat_aps, opts); 487170268Sdarrenr nsp->ns_instances = nat.nat_next; 488145510Sdarrenr } 489170268Sdarrenr 490170268Sdarrenr if (opts & OPT_VERBOSE) 491170268Sdarrenr showhostmap_live(fd, nsp); 492145510Sdarrenr} 493145510Sdarrenr 494145510Sdarrenr 495145510Sdarrenr/* 496145510Sdarrenr * Display the active host mapping table. 497145510Sdarrenr */ 498170268Sdarrenrvoid showhostmap_dead(nsp) 499145510Sdarrenrnatstat_t *nsp; 500145510Sdarrenr{ 501145510Sdarrenr hostmap_t hm, *hmp, **maptable; 502145510Sdarrenr u_int hv; 503145510Sdarrenr 504145510Sdarrenr printf("\nList of active host mappings:\n"); 505145510Sdarrenr 506145510Sdarrenr maptable = (hostmap_t **)malloc(sizeof(hostmap_t *) * 507145510Sdarrenr nsp->ns_hostmap_sz); 508145510Sdarrenr if (kmemcpy((char *)maptable, (u_long)nsp->ns_maptable, 509145510Sdarrenr sizeof(hostmap_t *) * nsp->ns_hostmap_sz)) { 510145510Sdarrenr perror("kmemcpy (maptable)"); 511145510Sdarrenr return; 512145510Sdarrenr } 513145510Sdarrenr 514145510Sdarrenr for (hv = 0; hv < nsp->ns_hostmap_sz; hv++) { 515145510Sdarrenr hmp = maptable[hv]; 516145510Sdarrenr 517145510Sdarrenr while (hmp) { 518145510Sdarrenr if (kmemcpy((char *)&hm, (u_long)hmp, sizeof(hm))) { 519145510Sdarrenr perror("kmemcpy (hostmap)"); 520145510Sdarrenr return; 521145510Sdarrenr } 522145510Sdarrenr 523145510Sdarrenr printhostmap(&hm, hv); 524145510Sdarrenr hmp = hm.hm_next; 525145510Sdarrenr } 526145510Sdarrenr } 527145510Sdarrenr free(maptable); 528145510Sdarrenr} 529145510Sdarrenr 530145510Sdarrenr 531145510Sdarrenr/* 532170268Sdarrenr * Display the active host mapping table. 533145510Sdarrenr */ 534170268Sdarrenrvoid showhostmap_live(fd, nsp) 535170268Sdarrenrint fd; 536170268Sdarrenrnatstat_t *nsp; 537145510Sdarrenr{ 538170268Sdarrenr ipfgeniter_t iter; 539170268Sdarrenr hostmap_t hm; 540170268Sdarrenr ipfobj_t obj; 541145510Sdarrenr 542170268Sdarrenr bzero((char *)&obj, sizeof(obj)); 543170268Sdarrenr obj.ipfo_rev = IPFILTER_VERSION; 544170268Sdarrenr obj.ipfo_type = IPFOBJ_GENITER; 545170268Sdarrenr obj.ipfo_size = sizeof(iter); 546170268Sdarrenr obj.ipfo_ptr = &iter; 547170268Sdarrenr 548170268Sdarrenr iter.igi_type = IPFGENITER_HOSTMAP; 549170268Sdarrenr iter.igi_nitems = 1; 550170268Sdarrenr iter.igi_data = &hm; 551170268Sdarrenr 552170268Sdarrenr printf("\nList of active host mappings:\n"); 553170268Sdarrenr 554170268Sdarrenr while (nsp->ns_maplist != NULL) { 555170268Sdarrenr if (ioctl(fd, SIOCGENITER, &obj) == -1) 556170268Sdarrenr break; 557170268Sdarrenr printhostmap(&hm, 0); 558170268Sdarrenr nsp->ns_maplist = hm.hm_next; 559145510Sdarrenr } 560170268Sdarrenr} 561145510Sdarrenr 562170268Sdarrenr 563170268Sdarrenrvoid showtqtable_live(fd) 564170268Sdarrenrint fd; 565170268Sdarrenr{ 566170268Sdarrenr ipftq_t table[IPF_TCP_NSTATES]; 567170268Sdarrenr ipfobj_t obj; 568170268Sdarrenr 569170268Sdarrenr bzero((char *)&obj, sizeof(obj)); 570170268Sdarrenr obj.ipfo_rev = IPFILTER_VERSION; 571170268Sdarrenr obj.ipfo_size = sizeof(table); 572170268Sdarrenr obj.ipfo_ptr = (void *)table; 573170268Sdarrenr obj.ipfo_type = IPFOBJ_STATETQTAB; 574170268Sdarrenr 575170268Sdarrenr if (ioctl(fd, SIOCGTQTAB, &obj) == 0) { 576170268Sdarrenr printtqtable(table); 577145510Sdarrenr } 578145510Sdarrenr} 579