17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * Copyright (C) 1999-2001, 2003 by Darren Reed. 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 57c478bd9Sstevel@tonic-gate * 633f2fefdSDarren Reed * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 77c478bd9Sstevel@tonic-gate * Use is subject to license terms. 8*94bdecd9SRob Gulewich * 9*94bdecd9SRob Gulewich * Copyright (c) 2014, Joyent, Inc. All rights reserved. 107c478bd9Sstevel@tonic-gate */ 117c478bd9Sstevel@tonic-gate 127c478bd9Sstevel@tonic-gate #ifdef __FreeBSD__ 137c478bd9Sstevel@tonic-gate # ifndef __FreeBSD_cc_version 147c478bd9Sstevel@tonic-gate # include <osreldate.h> 157c478bd9Sstevel@tonic-gate # else 167c478bd9Sstevel@tonic-gate # if __FreeBSD_cc_version < 430000 177c478bd9Sstevel@tonic-gate # include <osreldate.h> 187c478bd9Sstevel@tonic-gate # endif 197c478bd9Sstevel@tonic-gate # endif 207c478bd9Sstevel@tonic-gate #endif 217c478bd9Sstevel@tonic-gate #include <stdio.h> 227c478bd9Sstevel@tonic-gate #include <unistd.h> 237c478bd9Sstevel@tonic-gate #include <string.h> 247c478bd9Sstevel@tonic-gate #include <fcntl.h> 257c478bd9Sstevel@tonic-gate #include <errno.h> 267c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__GNUC__) 277c478bd9Sstevel@tonic-gate #include <strings.h> 287c478bd9Sstevel@tonic-gate #endif 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 307c478bd9Sstevel@tonic-gate #include <sys/param.h> 317c478bd9Sstevel@tonic-gate #include <sys/file.h> 327c478bd9Sstevel@tonic-gate #include <stdlib.h> 337c478bd9Sstevel@tonic-gate #include <stddef.h> 347c478bd9Sstevel@tonic-gate #include <sys/socket.h> 357c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 367c478bd9Sstevel@tonic-gate #include <netinet/in.h> 377c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 387c478bd9Sstevel@tonic-gate #include <sys/time.h> 397c478bd9Sstevel@tonic-gate #include <net/if.h> 407c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000 417c478bd9Sstevel@tonic-gate # include <net/if_var.h> 427c478bd9Sstevel@tonic-gate #endif 437c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 447c478bd9Sstevel@tonic-gate #include <netdb.h> 457c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 467c478bd9Sstevel@tonic-gate #include <resolv.h> 477c478bd9Sstevel@tonic-gate #include "ipf.h" 48ab25eeb5Syz155240 #include "netinet/ipl.h" 49*94bdecd9SRob Gulewich #include "ipfzone.h" 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate #if !defined(lint) 52ab25eeb5Syz155240 static const char rcsid[] = "@(#)Id: ipfs.c,v 1.12 2003/12/01 01:56:53 darrenr Exp"; 537c478bd9Sstevel@tonic-gate #endif 547c478bd9Sstevel@tonic-gate 557c478bd9Sstevel@tonic-gate #ifndef IPF_SAVEDIR 567c478bd9Sstevel@tonic-gate # define IPF_SAVEDIR "/var/db/ipf" 577c478bd9Sstevel@tonic-gate #endif 587c478bd9Sstevel@tonic-gate #ifndef IPF_NATFILE 597c478bd9Sstevel@tonic-gate # define IPF_NATFILE "ipnat.ipf" 607c478bd9Sstevel@tonic-gate #endif 617c478bd9Sstevel@tonic-gate #ifndef IPF_STATEFILE 627c478bd9Sstevel@tonic-gate # define IPF_STATEFILE "ipstate.ipf" 637c478bd9Sstevel@tonic-gate #endif 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && defined(__GNUC__) 667c478bd9Sstevel@tonic-gate extern char *index __P((const char *, int)); 677c478bd9Sstevel@tonic-gate #endif 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate extern char *optarg; 707c478bd9Sstevel@tonic-gate extern int optind; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate int main __P((int, char *[])); 737c478bd9Sstevel@tonic-gate void usage __P((void)); 747c478bd9Sstevel@tonic-gate int changestateif __P((char *, char *)); 757c478bd9Sstevel@tonic-gate int changenatif __P((char *, char *)); 767c478bd9Sstevel@tonic-gate int readstate __P((int, char *)); 777c478bd9Sstevel@tonic-gate int readnat __P((int, char *)); 787c478bd9Sstevel@tonic-gate int writestate __P((int, char *)); 797c478bd9Sstevel@tonic-gate int opendevice __P((char *)); 807c478bd9Sstevel@tonic-gate void closedevice __P((int)); 817c478bd9Sstevel@tonic-gate int setlock __P((int, int)); 827c478bd9Sstevel@tonic-gate int writeall __P((char *)); 837c478bd9Sstevel@tonic-gate int readall __P((char *)); 847c478bd9Sstevel@tonic-gate int writenat __P((int, char *)); 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate int opts = 0; 877c478bd9Sstevel@tonic-gate char *progname; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate 907c478bd9Sstevel@tonic-gate void usage() 917c478bd9Sstevel@tonic-gate { 92*94bdecd9SRob Gulewich const char *zoneopt = "[-G|-z zonename] "; 93*94bdecd9SRob Gulewich fprintf(stderr, "usage: %s %s[-nv] -l\n", progname, zoneopt); 94*94bdecd9SRob Gulewich fprintf(stderr, "usage: %s %s[-nv] -u\n", progname, zoneopt); 95*94bdecd9SRob Gulewich fprintf(stderr, "usage: %s %s[-nv] [-d <dir>] -R\n", progname, zoneopt); 96*94bdecd9SRob Gulewich fprintf(stderr, "usage: %s %s[-nv] [-d <dir>] -W\n", progname, zoneopt); 97*94bdecd9SRob Gulewich fprintf(stderr, "usage: %s %s[-nv] [-N|-S] [-f <file>] -r\n", progname, 98*94bdecd9SRob Gulewich zoneopt); 99*94bdecd9SRob Gulewich fprintf(stderr, "usage: %s %s[-nv] [-N|-S] [-f <file>] -w\n", progname, 100*94bdecd9SRob Gulewich zoneopt); 101*94bdecd9SRob Gulewich fprintf(stderr, "usage: %s %s[-nv] [-N|-S] -f <file> -i <if1>,<if2>\n", 102*94bdecd9SRob Gulewich progname, zoneopt); 1037c478bd9Sstevel@tonic-gate exit(1); 1047c478bd9Sstevel@tonic-gate } 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate /* 1087c478bd9Sstevel@tonic-gate * Change interface names in state information saved out to disk. 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate int changestateif(ifs, fname) 1117c478bd9Sstevel@tonic-gate char *ifs, *fname; 1127c478bd9Sstevel@tonic-gate { 1137c478bd9Sstevel@tonic-gate int fd, olen, nlen, rw; 1147c478bd9Sstevel@tonic-gate ipstate_save_t ips; 1157c478bd9Sstevel@tonic-gate off_t pos; 1167c478bd9Sstevel@tonic-gate char *s; 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate s = strchr(ifs, ','); 1197c478bd9Sstevel@tonic-gate if (!s) 1207c478bd9Sstevel@tonic-gate usage(); 1217c478bd9Sstevel@tonic-gate *s++ = '\0'; 1227c478bd9Sstevel@tonic-gate nlen = strlen(s); 1237c478bd9Sstevel@tonic-gate olen = strlen(ifs); 1247c478bd9Sstevel@tonic-gate if (nlen >= sizeof(ips.ips_is.is_ifname) || 1257c478bd9Sstevel@tonic-gate olen >= sizeof(ips.ips_is.is_ifname)) 1267c478bd9Sstevel@tonic-gate usage(); 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate fd = open(fname, O_RDWR); 1297c478bd9Sstevel@tonic-gate if (fd == -1) { 1307c478bd9Sstevel@tonic-gate perror("open"); 1317c478bd9Sstevel@tonic-gate exit(1); 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate for (pos = 0; read(fd, &ips, sizeof(ips)) == sizeof(ips); ) { 1357c478bd9Sstevel@tonic-gate rw = 0; 1367c478bd9Sstevel@tonic-gate if (!strncmp(ips.ips_is.is_ifname[0], ifs, olen + 1)) { 1377c478bd9Sstevel@tonic-gate strcpy(ips.ips_is.is_ifname[0], s); 1387c478bd9Sstevel@tonic-gate rw = 1; 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate if (!strncmp(ips.ips_is.is_ifname[1], ifs, olen + 1)) { 1417c478bd9Sstevel@tonic-gate strcpy(ips.ips_is.is_ifname[1], s); 1427c478bd9Sstevel@tonic-gate rw = 1; 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate if (rw == 1) { 1457c478bd9Sstevel@tonic-gate if (lseek(fd, pos, SEEK_SET) != pos) { 1467c478bd9Sstevel@tonic-gate perror("lseek"); 1477c478bd9Sstevel@tonic-gate exit(1); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate if (write(fd, &ips, sizeof(ips)) != sizeof(ips)) { 1507c478bd9Sstevel@tonic-gate perror("write"); 1517c478bd9Sstevel@tonic-gate exit(1); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate pos = lseek(fd, 0, SEEK_CUR); 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate close(fd); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate return 0; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate /* 1637c478bd9Sstevel@tonic-gate * Change interface names in NAT information saved out to disk. 1647c478bd9Sstevel@tonic-gate */ 1657c478bd9Sstevel@tonic-gate int changenatif(ifs, fname) 1667c478bd9Sstevel@tonic-gate char *ifs, *fname; 1677c478bd9Sstevel@tonic-gate { 1687c478bd9Sstevel@tonic-gate int fd, olen, nlen, rw; 1697c478bd9Sstevel@tonic-gate nat_save_t ipn; 1707c478bd9Sstevel@tonic-gate nat_t *nat; 1717c478bd9Sstevel@tonic-gate off_t pos; 1727c478bd9Sstevel@tonic-gate char *s; 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate s = strchr(ifs, ','); 1757c478bd9Sstevel@tonic-gate if (!s) 1767c478bd9Sstevel@tonic-gate usage(); 1777c478bd9Sstevel@tonic-gate *s++ = '\0'; 1787c478bd9Sstevel@tonic-gate nlen = strlen(s); 1797c478bd9Sstevel@tonic-gate olen = strlen(ifs); 1807c478bd9Sstevel@tonic-gate nat = &ipn.ipn_nat; 1817c478bd9Sstevel@tonic-gate if (nlen >= sizeof(nat->nat_ifnames[0]) || 1827c478bd9Sstevel@tonic-gate olen >= sizeof(nat->nat_ifnames[0])) 1837c478bd9Sstevel@tonic-gate usage(); 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate fd = open(fname, O_RDWR); 1867c478bd9Sstevel@tonic-gate if (fd == -1) { 1877c478bd9Sstevel@tonic-gate perror("open"); 1887c478bd9Sstevel@tonic-gate exit(1); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate for (pos = 0; read(fd, &ipn, sizeof(ipn)) == sizeof(ipn); ) { 1927c478bd9Sstevel@tonic-gate rw = 0; 1937c478bd9Sstevel@tonic-gate if (!strncmp(nat->nat_ifnames[0], ifs, olen + 1)) { 1947c478bd9Sstevel@tonic-gate strcpy(nat->nat_ifnames[0], s); 1957c478bd9Sstevel@tonic-gate rw = 1; 1967c478bd9Sstevel@tonic-gate } 1977c478bd9Sstevel@tonic-gate if (!strncmp(nat->nat_ifnames[1], ifs, olen + 1)) { 1987c478bd9Sstevel@tonic-gate strcpy(nat->nat_ifnames[1], s); 1997c478bd9Sstevel@tonic-gate rw = 1; 2007c478bd9Sstevel@tonic-gate } 2017c478bd9Sstevel@tonic-gate if (rw == 1) { 2027c478bd9Sstevel@tonic-gate if (lseek(fd, pos, SEEK_SET) != pos) { 2037c478bd9Sstevel@tonic-gate perror("lseek"); 2047c478bd9Sstevel@tonic-gate exit(1); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate if (write(fd, &ipn, sizeof(ipn)) != sizeof(ipn)) { 2077c478bd9Sstevel@tonic-gate perror("write"); 2087c478bd9Sstevel@tonic-gate exit(1); 2097c478bd9Sstevel@tonic-gate } 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate pos = lseek(fd, 0, SEEK_CUR); 2127c478bd9Sstevel@tonic-gate } 2137c478bd9Sstevel@tonic-gate close(fd); 2147c478bd9Sstevel@tonic-gate 2157c478bd9Sstevel@tonic-gate return 0; 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate int main(argc,argv) 2207c478bd9Sstevel@tonic-gate int argc; 2217c478bd9Sstevel@tonic-gate char *argv[]; 2227c478bd9Sstevel@tonic-gate { 2237c478bd9Sstevel@tonic-gate int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0; 2247c478bd9Sstevel@tonic-gate char *dirname = NULL, *filename = NULL, *ifs = NULL; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate progname = argv[0]; 227*94bdecd9SRob Gulewich while ((c = getopt(argc, argv, "d:f:G:lNnSRruvWwz:")) != -1) 2287c478bd9Sstevel@tonic-gate switch (c) 2297c478bd9Sstevel@tonic-gate { 2307c478bd9Sstevel@tonic-gate case 'd' : 2317c478bd9Sstevel@tonic-gate if ((set == 0) && !dirname && !filename) 2327c478bd9Sstevel@tonic-gate dirname = optarg; 2337c478bd9Sstevel@tonic-gate else 2347c478bd9Sstevel@tonic-gate usage(); 2357c478bd9Sstevel@tonic-gate break; 2367c478bd9Sstevel@tonic-gate case 'f' : 2377c478bd9Sstevel@tonic-gate if ((set == 0) && !dirname && !filename) 2387c478bd9Sstevel@tonic-gate filename = optarg; 2397c478bd9Sstevel@tonic-gate else 2407c478bd9Sstevel@tonic-gate usage(); 2417c478bd9Sstevel@tonic-gate break; 242*94bdecd9SRob Gulewich case 'G' : 243*94bdecd9SRob Gulewich setzonename_global(optarg); 244*94bdecd9SRob Gulewich break; 2457c478bd9Sstevel@tonic-gate case 'i' : 2467c478bd9Sstevel@tonic-gate ifs = optarg; 2477c478bd9Sstevel@tonic-gate set = 1; 2487c478bd9Sstevel@tonic-gate break; 2497c478bd9Sstevel@tonic-gate case 'l' : 2507c478bd9Sstevel@tonic-gate if (filename || dirname || set) 2517c478bd9Sstevel@tonic-gate usage(); 2527c478bd9Sstevel@tonic-gate lock = 1; 2537c478bd9Sstevel@tonic-gate set = 1; 2547c478bd9Sstevel@tonic-gate break; 2557c478bd9Sstevel@tonic-gate case 'n' : 2567c478bd9Sstevel@tonic-gate opts |= OPT_DONOTHING; 2577c478bd9Sstevel@tonic-gate break; 2587c478bd9Sstevel@tonic-gate case 'N' : 2597c478bd9Sstevel@tonic-gate if ((ns >= 0) || dirname || (rw != -1) || set) 2607c478bd9Sstevel@tonic-gate usage(); 2617c478bd9Sstevel@tonic-gate ns = 0; 2627c478bd9Sstevel@tonic-gate set = 1; 2637c478bd9Sstevel@tonic-gate break; 2647c478bd9Sstevel@tonic-gate case 'r' : 265ab25eeb5Syz155240 if (dirname || (rw != -1) || (ns == -1)) 2667c478bd9Sstevel@tonic-gate usage(); 2677c478bd9Sstevel@tonic-gate rw = 0; 2687c478bd9Sstevel@tonic-gate set = 1; 2697c478bd9Sstevel@tonic-gate break; 2707c478bd9Sstevel@tonic-gate case 'R' : 2717c478bd9Sstevel@tonic-gate rw = 2; 2727c478bd9Sstevel@tonic-gate set = 1; 2737c478bd9Sstevel@tonic-gate break; 2747c478bd9Sstevel@tonic-gate case 'S' : 2757c478bd9Sstevel@tonic-gate if ((ns >= 0) || dirname || (rw != -1) || set) 2767c478bd9Sstevel@tonic-gate usage(); 2777c478bd9Sstevel@tonic-gate ns = 1; 2787c478bd9Sstevel@tonic-gate set = 1; 2797c478bd9Sstevel@tonic-gate break; 2807c478bd9Sstevel@tonic-gate case 'u' : 2817c478bd9Sstevel@tonic-gate if (filename || dirname || set) 2827c478bd9Sstevel@tonic-gate usage(); 2837c478bd9Sstevel@tonic-gate lock = 0; 2847c478bd9Sstevel@tonic-gate set = 1; 2857c478bd9Sstevel@tonic-gate break; 2867c478bd9Sstevel@tonic-gate case 'v' : 2877c478bd9Sstevel@tonic-gate opts |= OPT_VERBOSE; 2887c478bd9Sstevel@tonic-gate break; 2897c478bd9Sstevel@tonic-gate case 'w' : 2907c478bd9Sstevel@tonic-gate if (dirname || (rw != -1) || (ns == -1)) 2917c478bd9Sstevel@tonic-gate usage(); 2927c478bd9Sstevel@tonic-gate rw = 1; 2937c478bd9Sstevel@tonic-gate set = 1; 2947c478bd9Sstevel@tonic-gate break; 2957c478bd9Sstevel@tonic-gate case 'W' : 2967c478bd9Sstevel@tonic-gate rw = 3; 2977c478bd9Sstevel@tonic-gate set = 1; 2987c478bd9Sstevel@tonic-gate break; 299*94bdecd9SRob Gulewich case 'z' : 300*94bdecd9SRob Gulewich setzonename(optarg); 301*94bdecd9SRob Gulewich break; 3027c478bd9Sstevel@tonic-gate case '?' : 3037c478bd9Sstevel@tonic-gate default : 3047c478bd9Sstevel@tonic-gate usage(); 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate if (ifs) { 3087c478bd9Sstevel@tonic-gate if (!filename || ns < 0) 3097c478bd9Sstevel@tonic-gate usage(); 3107c478bd9Sstevel@tonic-gate if (ns == 0) 3117c478bd9Sstevel@tonic-gate return changenatif(ifs, filename); 3127c478bd9Sstevel@tonic-gate else 3137c478bd9Sstevel@tonic-gate return changestateif(ifs, filename); 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate if ((ns >= 0) || (lock >= 0)) { 3177c478bd9Sstevel@tonic-gate if (lock >= 0) 3187c478bd9Sstevel@tonic-gate devfd = opendevice(NULL); 3197c478bd9Sstevel@tonic-gate else if (ns >= 0) { 3207c478bd9Sstevel@tonic-gate if (ns == 1) 3217c478bd9Sstevel@tonic-gate devfd = opendevice(IPSTATE_NAME); 3227c478bd9Sstevel@tonic-gate else if (ns == 0) 3237c478bd9Sstevel@tonic-gate devfd = opendevice(IPNAT_NAME); 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate if (devfd == -1) 3267c478bd9Sstevel@tonic-gate exit(1); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate if (lock >= 0) 3307c478bd9Sstevel@tonic-gate err = setlock(devfd, lock); 3317c478bd9Sstevel@tonic-gate else if (rw >= 0) { 3327c478bd9Sstevel@tonic-gate if (rw & 1) { /* WRITE */ 3337c478bd9Sstevel@tonic-gate if (rw & 2) 3347c478bd9Sstevel@tonic-gate err = writeall(dirname); 3357c478bd9Sstevel@tonic-gate else { 3367c478bd9Sstevel@tonic-gate if (ns == 0) 3377c478bd9Sstevel@tonic-gate err = writenat(devfd, filename); 3387c478bd9Sstevel@tonic-gate else if (ns == 1) 3397c478bd9Sstevel@tonic-gate err = writestate(devfd, filename); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate } else { 3427c478bd9Sstevel@tonic-gate if (rw & 2) 3437c478bd9Sstevel@tonic-gate err = readall(dirname); 3447c478bd9Sstevel@tonic-gate else { 3457c478bd9Sstevel@tonic-gate if (ns == 0) 3467c478bd9Sstevel@tonic-gate err = readnat(devfd, filename); 3477c478bd9Sstevel@tonic-gate else if (ns == 1) 3487c478bd9Sstevel@tonic-gate err = readstate(devfd, filename); 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate } 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate return err; 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate int opendevice(ipfdev) 3577c478bd9Sstevel@tonic-gate char *ipfdev; 3587c478bd9Sstevel@tonic-gate { 3597c478bd9Sstevel@tonic-gate int fd = -1; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate if (opts & OPT_DONOTHING) 3627c478bd9Sstevel@tonic-gate return -2; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate if (!ipfdev) 3657c478bd9Sstevel@tonic-gate ipfdev = IPL_NAME; 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate if ((fd = open(ipfdev, O_RDWR)) == -1) 3687c478bd9Sstevel@tonic-gate if ((fd = open(ipfdev, O_RDONLY)) == -1) 3697c478bd9Sstevel@tonic-gate perror("open device"); 370*94bdecd9SRob Gulewich 371*94bdecd9SRob Gulewich if (setzone(fd) != 0) { 372*94bdecd9SRob Gulewich close(fd); 373*94bdecd9SRob Gulewich fd = -1; 374*94bdecd9SRob Gulewich } 375*94bdecd9SRob Gulewich 3767c478bd9Sstevel@tonic-gate return fd; 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate 3797c478bd9Sstevel@tonic-gate 3807c478bd9Sstevel@tonic-gate void closedevice(fd) 3817c478bd9Sstevel@tonic-gate int fd; 3827c478bd9Sstevel@tonic-gate { 3837c478bd9Sstevel@tonic-gate close(fd); 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate int setlock(fd, lock) 3887c478bd9Sstevel@tonic-gate int fd, lock; 3897c478bd9Sstevel@tonic-gate { 3907c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 3917c478bd9Sstevel@tonic-gate printf("Turn lock %s\n", lock ? "on" : "off"); 3927c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) { 3937c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTLCK, &lock) == -1) { 3947c478bd9Sstevel@tonic-gate perror("SIOCSTLCK"); 3957c478bd9Sstevel@tonic-gate return 1; 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 3987c478bd9Sstevel@tonic-gate printf("Lock now %s\n", lock ? "on" : "off"); 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate return 0; 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate int writestate(fd, file) 4057c478bd9Sstevel@tonic-gate int fd; 4067c478bd9Sstevel@tonic-gate char *file; 4077c478bd9Sstevel@tonic-gate { 4087c478bd9Sstevel@tonic-gate ipstate_save_t ips, *ipsp; 409ab25eeb5Syz155240 ipfobj_t obj; 4107c478bd9Sstevel@tonic-gate int wfd = -1; 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate if (!file) 4137c478bd9Sstevel@tonic-gate file = IPF_STATEFILE; 4147c478bd9Sstevel@tonic-gate 4157c478bd9Sstevel@tonic-gate wfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); 4167c478bd9Sstevel@tonic-gate if (wfd == -1) { 4177c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 4187c478bd9Sstevel@tonic-gate perror("state:open"); 4197c478bd9Sstevel@tonic-gate return 1; 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate 4227c478bd9Sstevel@tonic-gate ipsp = &ips; 423ab25eeb5Syz155240 bzero((char *)&obj, sizeof(obj)); 4247c478bd9Sstevel@tonic-gate bzero((char *)ipsp, sizeof(ips)); 4257c478bd9Sstevel@tonic-gate 426ab25eeb5Syz155240 obj.ipfo_rev = IPFILTER_VERSION; 427ab25eeb5Syz155240 obj.ipfo_size = sizeof(*ipsp); 428ab25eeb5Syz155240 obj.ipfo_type = IPFOBJ_STATESAVE; 429ab25eeb5Syz155240 obj.ipfo_ptr = ipsp; 430ab25eeb5Syz155240 4317c478bd9Sstevel@tonic-gate do { 432ab25eeb5Syz155240 4337c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 4347c478bd9Sstevel@tonic-gate printf("Getting state from addr %p\n", ips.ips_next); 435ab25eeb5Syz155240 if (ioctl(fd, SIOCSTGET, &obj)) { 4367c478bd9Sstevel@tonic-gate if (errno == ENOENT) 4377c478bd9Sstevel@tonic-gate break; 4387c478bd9Sstevel@tonic-gate perror("state:SIOCSTGET"); 4397c478bd9Sstevel@tonic-gate close(wfd); 4407c478bd9Sstevel@tonic-gate return 1; 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 4437c478bd9Sstevel@tonic-gate printf("Got state next %p\n", ips.ips_next); 4447c478bd9Sstevel@tonic-gate if (write(wfd, ipsp, sizeof(ips)) != sizeof(ips)) { 4457c478bd9Sstevel@tonic-gate perror("state:write"); 4467c478bd9Sstevel@tonic-gate close(wfd); 4477c478bd9Sstevel@tonic-gate return 1; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate } while (ips.ips_next != NULL); 4507c478bd9Sstevel@tonic-gate close(wfd); 4517c478bd9Sstevel@tonic-gate 4527c478bd9Sstevel@tonic-gate return 0; 4537c478bd9Sstevel@tonic-gate } 4547c478bd9Sstevel@tonic-gate 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate int readstate(fd, file) 4577c478bd9Sstevel@tonic-gate int fd; 4587c478bd9Sstevel@tonic-gate char *file; 4597c478bd9Sstevel@tonic-gate { 4607c478bd9Sstevel@tonic-gate ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL; 4617c478bd9Sstevel@tonic-gate int sfd = -1, i; 462ab25eeb5Syz155240 ipfobj_t obj; 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate if (!file) 4657c478bd9Sstevel@tonic-gate file = IPF_STATEFILE; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate sfd = open(file, O_RDONLY, 0600); 4687c478bd9Sstevel@tonic-gate if (sfd == -1) { 4697c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 4707c478bd9Sstevel@tonic-gate perror("open"); 4717c478bd9Sstevel@tonic-gate return 1; 4727c478bd9Sstevel@tonic-gate } 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate bzero((char *)&ips, sizeof(ips)); 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate /* 4777c478bd9Sstevel@tonic-gate * 1. Read all state information in. 4787c478bd9Sstevel@tonic-gate */ 4797c478bd9Sstevel@tonic-gate do { 4807c478bd9Sstevel@tonic-gate i = read(sfd, &ips, sizeof(ips)); 4817c478bd9Sstevel@tonic-gate if (i == -1) { 4827c478bd9Sstevel@tonic-gate perror("read"); 4837c478bd9Sstevel@tonic-gate close(sfd); 4847c478bd9Sstevel@tonic-gate return 1; 4857c478bd9Sstevel@tonic-gate } 4867c478bd9Sstevel@tonic-gate if (i == 0) 4877c478bd9Sstevel@tonic-gate break; 4887c478bd9Sstevel@tonic-gate if (i != sizeof(ips)) { 489ab25eeb5Syz155240 fprintf(stderr, "state:incomplete read: %d != %d\n", 490ab25eeb5Syz155240 i, (int)sizeof(ips)); 4917c478bd9Sstevel@tonic-gate close(sfd); 4927c478bd9Sstevel@tonic-gate return 1; 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate is = (ipstate_save_t *)malloc(sizeof(*is)); 4957c478bd9Sstevel@tonic-gate if(!is) { 4967c478bd9Sstevel@tonic-gate fprintf(stderr, "malloc failed\n"); 4977c478bd9Sstevel@tonic-gate return 1; 4987c478bd9Sstevel@tonic-gate } 4997c478bd9Sstevel@tonic-gate 5007c478bd9Sstevel@tonic-gate bcopy((char *)&ips, (char *)is, sizeof(ips)); 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* 5037c478bd9Sstevel@tonic-gate * Check to see if this is the first state entry that will 5047c478bd9Sstevel@tonic-gate * reference a particular rule and if so, flag it as such 5057c478bd9Sstevel@tonic-gate * else just adjust the rule pointer to become a pointer to 5067c478bd9Sstevel@tonic-gate * the other. We do this so we have a means later for tracking 5077c478bd9Sstevel@tonic-gate * who is referencing us when we get back the real pointer 5087c478bd9Sstevel@tonic-gate * in is_rule after doing the ioctl. 5097c478bd9Sstevel@tonic-gate */ 5107c478bd9Sstevel@tonic-gate for (is1 = ipshead; is1 != NULL; is1 = is1->ips_next) 5117c478bd9Sstevel@tonic-gate if (is1->ips_rule == is->ips_rule) 5127c478bd9Sstevel@tonic-gate break; 5137c478bd9Sstevel@tonic-gate if (is1 == NULL) 5147c478bd9Sstevel@tonic-gate is->ips_is.is_flags |= SI_NEWFR; 5157c478bd9Sstevel@tonic-gate else 5167c478bd9Sstevel@tonic-gate is->ips_rule = (void *)&is1->ips_rule; 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate /* 5197c478bd9Sstevel@tonic-gate * Use a tail-queue type list (add things to the end).. 5207c478bd9Sstevel@tonic-gate */ 5217c478bd9Sstevel@tonic-gate is->ips_next = NULL; 5227c478bd9Sstevel@tonic-gate if (!ipshead) 5237c478bd9Sstevel@tonic-gate ipshead = is; 5247c478bd9Sstevel@tonic-gate if (ipstail) 5257c478bd9Sstevel@tonic-gate ipstail->ips_next = is; 5267c478bd9Sstevel@tonic-gate ipstail = is; 5277c478bd9Sstevel@tonic-gate } while (1); 5287c478bd9Sstevel@tonic-gate 5297c478bd9Sstevel@tonic-gate close(sfd); 5307c478bd9Sstevel@tonic-gate 531ab25eeb5Syz155240 obj.ipfo_rev = IPFILTER_VERSION; 532ab25eeb5Syz155240 obj.ipfo_size = sizeof(*is); 533ab25eeb5Syz155240 obj.ipfo_type = IPFOBJ_STATESAVE; 534ab25eeb5Syz155240 5357c478bd9Sstevel@tonic-gate for (is = ipshead; is; is = is->ips_next) { 5367c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 5377c478bd9Sstevel@tonic-gate printf("Loading new state table entry\n"); 5387c478bd9Sstevel@tonic-gate if (is->ips_is.is_flags & SI_NEWFR) { 5397c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 5407c478bd9Sstevel@tonic-gate printf("Loading new filter rule\n"); 5417c478bd9Sstevel@tonic-gate } 542ab25eeb5Syz155240 543ab25eeb5Syz155240 obj.ipfo_ptr = is; 5447c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) 545ab25eeb5Syz155240 if (ioctl(fd, SIOCSTPUT, &obj)) { 5467c478bd9Sstevel@tonic-gate perror("SIOCSTPUT"); 5477c478bd9Sstevel@tonic-gate return 1; 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate if (is->ips_is.is_flags & SI_NEWFR) { 5517c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 5527c478bd9Sstevel@tonic-gate printf("Real rule addr %p\n", is->ips_rule); 5537c478bd9Sstevel@tonic-gate for (is1 = is->ips_next; is1; is1 = is1->ips_next) 5547c478bd9Sstevel@tonic-gate if (is1->ips_rule == (frentry_t *)&is->ips_rule) 5557c478bd9Sstevel@tonic-gate is1->ips_rule = is->ips_rule; 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate return 0; 5607c478bd9Sstevel@tonic-gate } 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate int readnat(fd, file) 5647c478bd9Sstevel@tonic-gate int fd; 5657c478bd9Sstevel@tonic-gate char *file; 5667c478bd9Sstevel@tonic-gate { 567ab25eeb5Syz155240 nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL; 568ab25eeb5Syz155240 ipfobj_t obj; 5697c478bd9Sstevel@tonic-gate int nfd, i; 5707c478bd9Sstevel@tonic-gate nat_t *nat; 571ab25eeb5Syz155240 char *s; 572ab25eeb5Syz155240 int n; 5737c478bd9Sstevel@tonic-gate 5747c478bd9Sstevel@tonic-gate nfd = -1; 5757c478bd9Sstevel@tonic-gate in = NULL; 5767c478bd9Sstevel@tonic-gate ipnhead = NULL; 5777c478bd9Sstevel@tonic-gate ipntail = NULL; 5787c478bd9Sstevel@tonic-gate 5797c478bd9Sstevel@tonic-gate if (!file) 5807c478bd9Sstevel@tonic-gate file = IPF_NATFILE; 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate nfd = open(file, O_RDONLY); 5837c478bd9Sstevel@tonic-gate if (nfd == -1) { 5847c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 5857c478bd9Sstevel@tonic-gate perror("nat:open"); 5867c478bd9Sstevel@tonic-gate return 1; 5877c478bd9Sstevel@tonic-gate } 5887c478bd9Sstevel@tonic-gate 5897c478bd9Sstevel@tonic-gate bzero((char *)&ipn, sizeof(ipn)); 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate /* 5927c478bd9Sstevel@tonic-gate * 1. Read all state information in. 5937c478bd9Sstevel@tonic-gate */ 5947c478bd9Sstevel@tonic-gate do { 5957c478bd9Sstevel@tonic-gate i = read(nfd, &ipn, sizeof(ipn)); 5967c478bd9Sstevel@tonic-gate if (i == -1) { 5977c478bd9Sstevel@tonic-gate perror("read"); 5987c478bd9Sstevel@tonic-gate close(nfd); 5997c478bd9Sstevel@tonic-gate return 1; 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate if (i == 0) 6027c478bd9Sstevel@tonic-gate break; 6037c478bd9Sstevel@tonic-gate if (i != sizeof(ipn)) { 604ab25eeb5Syz155240 fprintf(stderr, "nat:incomplete read: %d != %d\n", 605ab25eeb5Syz155240 i, (int)sizeof(ipn)); 6067c478bd9Sstevel@tonic-gate close(nfd); 6077c478bd9Sstevel@tonic-gate return 1; 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate 610ab25eeb5Syz155240 in = (nat_save_t *)malloc(ipn.ipn_dsize); 6117c478bd9Sstevel@tonic-gate if (!in) 6127c478bd9Sstevel@tonic-gate break; 6137c478bd9Sstevel@tonic-gate 614ab25eeb5Syz155240 if (ipn.ipn_dsize > sizeof(ipn)) { 615ab25eeb5Syz155240 n = ipn.ipn_dsize - sizeof(ipn); 616ab25eeb5Syz155240 if (n > 0) { 617ab25eeb5Syz155240 s = in->ipn_data + sizeof(in->ipn_data); 6187c478bd9Sstevel@tonic-gate i = read(nfd, s, n); 6197c478bd9Sstevel@tonic-gate if (i == 0) 6207c478bd9Sstevel@tonic-gate break; 6217c478bd9Sstevel@tonic-gate if (i != n) { 622ab25eeb5Syz155240 fprintf(stderr, 623ab25eeb5Syz155240 "nat:incomplete read: %d != %d\n", 6247c478bd9Sstevel@tonic-gate i, n); 6257c478bd9Sstevel@tonic-gate close(nfd); 6267c478bd9Sstevel@tonic-gate return 1; 6277c478bd9Sstevel@tonic-gate } 6287c478bd9Sstevel@tonic-gate } 629ab25eeb5Syz155240 } 630ab25eeb5Syz155240 bcopy((char *)&ipn, (char *)in, sizeof(ipn)); 6317c478bd9Sstevel@tonic-gate 6327c478bd9Sstevel@tonic-gate /* 633ab25eeb5Syz155240 * Check to see if this is the first NAT entry that will 6347c478bd9Sstevel@tonic-gate * reference a particular rule and if so, flag it as such 6357c478bd9Sstevel@tonic-gate * else just adjust the rule pointer to become a pointer to 6367c478bd9Sstevel@tonic-gate * the other. We do this so we have a means later for tracking 6377c478bd9Sstevel@tonic-gate * who is referencing us when we get back the real pointer 6387c478bd9Sstevel@tonic-gate * in is_rule after doing the ioctl. 6397c478bd9Sstevel@tonic-gate */ 6407c478bd9Sstevel@tonic-gate nat = &in->ipn_nat; 6417c478bd9Sstevel@tonic-gate if (nat->nat_fr != NULL) { 6427c478bd9Sstevel@tonic-gate for (in1 = ipnhead; in1 != NULL; in1 = in1->ipn_next) 6437c478bd9Sstevel@tonic-gate if (in1->ipn_rule == nat->nat_fr) 6447c478bd9Sstevel@tonic-gate break; 6457c478bd9Sstevel@tonic-gate if (in1 == NULL) 6467c478bd9Sstevel@tonic-gate nat->nat_flags |= SI_NEWFR; 6477c478bd9Sstevel@tonic-gate else 6487c478bd9Sstevel@tonic-gate nat->nat_fr = &in1->ipn_fr; 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate /* 6527c478bd9Sstevel@tonic-gate * Use a tail-queue type list (add things to the end).. 6537c478bd9Sstevel@tonic-gate */ 6547c478bd9Sstevel@tonic-gate in->ipn_next = NULL; 6557c478bd9Sstevel@tonic-gate if (!ipnhead) 6567c478bd9Sstevel@tonic-gate ipnhead = in; 6577c478bd9Sstevel@tonic-gate if (ipntail) 6587c478bd9Sstevel@tonic-gate ipntail->ipn_next = in; 6597c478bd9Sstevel@tonic-gate ipntail = in; 6607c478bd9Sstevel@tonic-gate } while (1); 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate close(nfd); 663ab25eeb5Syz155240 nfd = -1; 664ab25eeb5Syz155240 665ab25eeb5Syz155240 obj.ipfo_rev = IPFILTER_VERSION; 666ab25eeb5Syz155240 obj.ipfo_type = IPFOBJ_NATSAVE; 6677c478bd9Sstevel@tonic-gate 6687c478bd9Sstevel@tonic-gate for (in = ipnhead; in; in = in->ipn_next) { 6697c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 6707c478bd9Sstevel@tonic-gate printf("Loading new NAT table entry\n"); 6717c478bd9Sstevel@tonic-gate nat = &in->ipn_nat; 6727c478bd9Sstevel@tonic-gate if (nat->nat_flags & SI_NEWFR) { 6737c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 6747c478bd9Sstevel@tonic-gate printf("Loading new filter rule\n"); 6757c478bd9Sstevel@tonic-gate } 676ab25eeb5Syz155240 677ab25eeb5Syz155240 obj.ipfo_ptr = in; 678ab25eeb5Syz155240 obj.ipfo_size = in->ipn_dsize; 6797c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) 680ab25eeb5Syz155240 if (ioctl(fd, SIOCSTPUT, &obj)) { 681ab25eeb5Syz155240 fprintf(stderr, "in=%p:", in); 6827c478bd9Sstevel@tonic-gate perror("SIOCSTPUT"); 6837c478bd9Sstevel@tonic-gate return 1; 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate if (nat->nat_flags & SI_NEWFR) { 6877c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 6887c478bd9Sstevel@tonic-gate printf("Real rule addr %p\n", nat->nat_fr); 6897c478bd9Sstevel@tonic-gate for (in1 = in->ipn_next; in1; in1 = in1->ipn_next) 6907c478bd9Sstevel@tonic-gate if (in1->ipn_rule == &in->ipn_fr) 6917c478bd9Sstevel@tonic-gate in1->ipn_rule = nat->nat_fr; 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate } 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate return 0; 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate int writenat(fd, file) 7007c478bd9Sstevel@tonic-gate int fd; 7017c478bd9Sstevel@tonic-gate char *file; 7027c478bd9Sstevel@tonic-gate { 7037c478bd9Sstevel@tonic-gate nat_save_t *ipnp = NULL, *next = NULL; 704ab25eeb5Syz155240 ipfobj_t obj; 7057c478bd9Sstevel@tonic-gate int nfd = -1; 7067c478bd9Sstevel@tonic-gate natget_t ng; 7077c478bd9Sstevel@tonic-gate 7087c478bd9Sstevel@tonic-gate if (!file) 7097c478bd9Sstevel@tonic-gate file = IPF_NATFILE; 7107c478bd9Sstevel@tonic-gate 7117c478bd9Sstevel@tonic-gate nfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); 7127c478bd9Sstevel@tonic-gate if (nfd == -1) { 7137c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 7147c478bd9Sstevel@tonic-gate perror("nat:open"); 7157c478bd9Sstevel@tonic-gate return 1; 7167c478bd9Sstevel@tonic-gate } 7177c478bd9Sstevel@tonic-gate 718ab25eeb5Syz155240 obj.ipfo_rev = IPFILTER_VERSION; 719ab25eeb5Syz155240 obj.ipfo_type = IPFOBJ_NATSAVE; 7207c478bd9Sstevel@tonic-gate 7217c478bd9Sstevel@tonic-gate do { 7227c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 7237c478bd9Sstevel@tonic-gate printf("Getting nat from addr %p\n", ipnp); 7247c478bd9Sstevel@tonic-gate ng.ng_ptr = next; 7257c478bd9Sstevel@tonic-gate ng.ng_sz = 0; 7267c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTGSZ, &ng)) { 7277c478bd9Sstevel@tonic-gate perror("nat:SIOCSTGSZ"); 7287c478bd9Sstevel@tonic-gate close(nfd); 7297c478bd9Sstevel@tonic-gate if (ipnp != NULL) 7307c478bd9Sstevel@tonic-gate free(ipnp); 7317c478bd9Sstevel@tonic-gate return 1; 7327c478bd9Sstevel@tonic-gate } 7337c478bd9Sstevel@tonic-gate 7347c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 7357c478bd9Sstevel@tonic-gate printf("NAT size %d from %p\n", ng.ng_sz, ng.ng_ptr); 7367c478bd9Sstevel@tonic-gate 7377c478bd9Sstevel@tonic-gate if (ng.ng_sz == 0) 7387c478bd9Sstevel@tonic-gate break; 7397c478bd9Sstevel@tonic-gate 7407c478bd9Sstevel@tonic-gate if (!ipnp) 7417c478bd9Sstevel@tonic-gate ipnp = malloc(ng.ng_sz); 7427c478bd9Sstevel@tonic-gate else 7437c478bd9Sstevel@tonic-gate ipnp = realloc((char *)ipnp, ng.ng_sz); 7447c478bd9Sstevel@tonic-gate if (!ipnp) { 7457c478bd9Sstevel@tonic-gate fprintf(stderr, 7467c478bd9Sstevel@tonic-gate "malloc for %d bytes failed\n", ng.ng_sz); 7477c478bd9Sstevel@tonic-gate break; 7487c478bd9Sstevel@tonic-gate } 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate bzero((char *)ipnp, ng.ng_sz); 751ab25eeb5Syz155240 obj.ipfo_size = ng.ng_sz; 752ab25eeb5Syz155240 obj.ipfo_ptr = ipnp; 753ab25eeb5Syz155240 ipnp->ipn_dsize = ng.ng_sz; 7547c478bd9Sstevel@tonic-gate ipnp->ipn_next = next; 755ab25eeb5Syz155240 if (ioctl(fd, SIOCSTGET, &obj)) { 7567c478bd9Sstevel@tonic-gate if (errno == ENOENT) 7577c478bd9Sstevel@tonic-gate break; 7587c478bd9Sstevel@tonic-gate perror("nat:SIOCSTGET"); 7597c478bd9Sstevel@tonic-gate close(nfd); 7607c478bd9Sstevel@tonic-gate free(ipnp); 7617c478bd9Sstevel@tonic-gate return 1; 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate 7647c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 765ab25eeb5Syz155240 printf("Got nat next %p ipn_dsize %d ng_sz %d\n", 766ab25eeb5Syz155240 ipnp->ipn_next, ipnp->ipn_dsize, ng.ng_sz); 767ab25eeb5Syz155240 if (write(nfd, ipnp, ipnp->ipn_dsize) != ipnp->ipn_dsize) { 7687c478bd9Sstevel@tonic-gate perror("nat:write"); 7697c478bd9Sstevel@tonic-gate close(nfd); 7707c478bd9Sstevel@tonic-gate free(ipnp); 7717c478bd9Sstevel@tonic-gate return 1; 7727c478bd9Sstevel@tonic-gate } 7737c478bd9Sstevel@tonic-gate next = ipnp->ipn_next; 7747c478bd9Sstevel@tonic-gate } while (ipnp && next); 7757c478bd9Sstevel@tonic-gate if (ipnp != NULL) 7767c478bd9Sstevel@tonic-gate free(ipnp); 7777c478bd9Sstevel@tonic-gate close(nfd); 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate return 0; 7807c478bd9Sstevel@tonic-gate } 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate 7837c478bd9Sstevel@tonic-gate int writeall(dirname) 7847c478bd9Sstevel@tonic-gate char *dirname; 7857c478bd9Sstevel@tonic-gate { 7867c478bd9Sstevel@tonic-gate int fd, devfd; 7877c478bd9Sstevel@tonic-gate 7887c478bd9Sstevel@tonic-gate if (!dirname) 7897c478bd9Sstevel@tonic-gate dirname = IPF_SAVEDIR; 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate if (chdir(dirname)) { 792ab25eeb5Syz155240 fprintf(stderr, "IPF_SAVEDIR=%s: ", dirname); 7937c478bd9Sstevel@tonic-gate perror("chdir(IPF_SAVEDIR)"); 7947c478bd9Sstevel@tonic-gate return 1; 7957c478bd9Sstevel@tonic-gate } 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate fd = opendevice(NULL); 7987c478bd9Sstevel@tonic-gate if (fd == -1) 7997c478bd9Sstevel@tonic-gate return 1; 8007c478bd9Sstevel@tonic-gate if (setlock(fd, 1)) { 8017c478bd9Sstevel@tonic-gate close(fd); 8027c478bd9Sstevel@tonic-gate return 1; 8037c478bd9Sstevel@tonic-gate } 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate devfd = opendevice(IPSTATE_NAME); 8067c478bd9Sstevel@tonic-gate if (devfd == -1) 8077c478bd9Sstevel@tonic-gate goto bad; 8087c478bd9Sstevel@tonic-gate if (writestate(devfd, NULL)) 8097c478bd9Sstevel@tonic-gate goto bad; 8107c478bd9Sstevel@tonic-gate close(devfd); 8117c478bd9Sstevel@tonic-gate 8127c478bd9Sstevel@tonic-gate devfd = opendevice(IPNAT_NAME); 8137c478bd9Sstevel@tonic-gate if (devfd == -1) 8147c478bd9Sstevel@tonic-gate goto bad; 8157c478bd9Sstevel@tonic-gate if (writenat(devfd, NULL)) 8167c478bd9Sstevel@tonic-gate goto bad; 8177c478bd9Sstevel@tonic-gate close(devfd); 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate if (setlock(fd, 0)) { 8207c478bd9Sstevel@tonic-gate close(fd); 8217c478bd9Sstevel@tonic-gate return 1; 8227c478bd9Sstevel@tonic-gate } 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate close(fd); 8257c478bd9Sstevel@tonic-gate return 0; 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate bad: 8287c478bd9Sstevel@tonic-gate setlock(fd, 0); 8297c478bd9Sstevel@tonic-gate close(fd); 8307c478bd9Sstevel@tonic-gate return 1; 8317c478bd9Sstevel@tonic-gate } 8327c478bd9Sstevel@tonic-gate 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate int readall(dirname) 8357c478bd9Sstevel@tonic-gate char *dirname; 8367c478bd9Sstevel@tonic-gate { 8377c478bd9Sstevel@tonic-gate int fd, devfd; 8387c478bd9Sstevel@tonic-gate 8397c478bd9Sstevel@tonic-gate if (!dirname) 8407c478bd9Sstevel@tonic-gate dirname = IPF_SAVEDIR; 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate if (chdir(dirname)) { 8437c478bd9Sstevel@tonic-gate perror("chdir(IPF_SAVEDIR)"); 8447c478bd9Sstevel@tonic-gate return 1; 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate fd = opendevice(NULL); 8487c478bd9Sstevel@tonic-gate if (fd == -1) 8497c478bd9Sstevel@tonic-gate return 1; 8507c478bd9Sstevel@tonic-gate if (setlock(fd, 1)) { 8517c478bd9Sstevel@tonic-gate close(fd); 8527c478bd9Sstevel@tonic-gate return 1; 8537c478bd9Sstevel@tonic-gate } 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate devfd = opendevice(IPSTATE_NAME); 8567c478bd9Sstevel@tonic-gate if (devfd == -1) 8577c478bd9Sstevel@tonic-gate return 1; 8587c478bd9Sstevel@tonic-gate if (readstate(devfd, NULL)) 8597c478bd9Sstevel@tonic-gate return 1; 8607c478bd9Sstevel@tonic-gate close(devfd); 8617c478bd9Sstevel@tonic-gate 8627c478bd9Sstevel@tonic-gate devfd = opendevice(IPNAT_NAME); 8637c478bd9Sstevel@tonic-gate if (devfd == -1) 8647c478bd9Sstevel@tonic-gate return 1; 8657c478bd9Sstevel@tonic-gate if (readnat(devfd, NULL)) 8667c478bd9Sstevel@tonic-gate return 1; 8677c478bd9Sstevel@tonic-gate close(devfd); 8687c478bd9Sstevel@tonic-gate 8697c478bd9Sstevel@tonic-gate if (setlock(fd, 0)) { 8707c478bd9Sstevel@tonic-gate close(fd); 8717c478bd9Sstevel@tonic-gate return 1; 8727c478bd9Sstevel@tonic-gate } 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate return 0; 8757c478bd9Sstevel@tonic-gate } 876