1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright (C) 1999-2001, 2003 by Darren Reed. 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * See the IPFILTER.LICENCE file for details on licencing. 5*7c478bd9Sstevel@tonic-gate * 6*7c478bd9Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 7*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 8*7c478bd9Sstevel@tonic-gate */ 9*7c478bd9Sstevel@tonic-gate 10*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 11*7c478bd9Sstevel@tonic-gate 12*7c478bd9Sstevel@tonic-gate #ifdef __FreeBSD__ 13*7c478bd9Sstevel@tonic-gate # ifndef __FreeBSD_cc_version 14*7c478bd9Sstevel@tonic-gate # include <osreldate.h> 15*7c478bd9Sstevel@tonic-gate # else 16*7c478bd9Sstevel@tonic-gate # if __FreeBSD_cc_version < 430000 17*7c478bd9Sstevel@tonic-gate # include <osreldate.h> 18*7c478bd9Sstevel@tonic-gate # endif 19*7c478bd9Sstevel@tonic-gate # endif 20*7c478bd9Sstevel@tonic-gate #endif 21*7c478bd9Sstevel@tonic-gate #include <stdio.h> 22*7c478bd9Sstevel@tonic-gate #include <unistd.h> 23*7c478bd9Sstevel@tonic-gate #include <string.h> 24*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 25*7c478bd9Sstevel@tonic-gate #include <errno.h> 26*7c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && !defined(__GNUC__) 27*7c478bd9Sstevel@tonic-gate #include <strings.h> 28*7c478bd9Sstevel@tonic-gate #endif 29*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 31*7c478bd9Sstevel@tonic-gate #include <sys/file.h> 32*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 33*7c478bd9Sstevel@tonic-gate #include <stddef.h> 34*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 35*7c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 36*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 37*7c478bd9Sstevel@tonic-gate #include <netinet/in_systm.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 39*7c478bd9Sstevel@tonic-gate #include <net/if.h> 40*7c478bd9Sstevel@tonic-gate #if __FreeBSD_version >= 300000 41*7c478bd9Sstevel@tonic-gate # include <net/if_var.h> 42*7c478bd9Sstevel@tonic-gate #endif 43*7c478bd9Sstevel@tonic-gate #include <netinet/ip.h> 44*7c478bd9Sstevel@tonic-gate #include <netdb.h> 45*7c478bd9Sstevel@tonic-gate #include <arpa/nameser.h> 46*7c478bd9Sstevel@tonic-gate #include <resolv.h> 47*7c478bd9Sstevel@tonic-gate #include "ipf.h" 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate #if !defined(lint) 50*7c478bd9Sstevel@tonic-gate static const char rcsid[] = "@(#)$Id: ipfs.c,v 1.9 2003/05/17 09:47:35 darrenr Exp $"; 51*7c478bd9Sstevel@tonic-gate #endif 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #ifndef IPF_SAVEDIR 54*7c478bd9Sstevel@tonic-gate # define IPF_SAVEDIR "/var/db/ipf" 55*7c478bd9Sstevel@tonic-gate #endif 56*7c478bd9Sstevel@tonic-gate #ifndef IPF_NATFILE 57*7c478bd9Sstevel@tonic-gate # define IPF_NATFILE "ipnat.ipf" 58*7c478bd9Sstevel@tonic-gate #endif 59*7c478bd9Sstevel@tonic-gate #ifndef IPF_STATEFILE 60*7c478bd9Sstevel@tonic-gate # define IPF_STATEFILE "ipstate.ipf" 61*7c478bd9Sstevel@tonic-gate #endif 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate #if !defined(__SVR4) && defined(__GNUC__) 64*7c478bd9Sstevel@tonic-gate extern char *index __P((const char *, int)); 65*7c478bd9Sstevel@tonic-gate #endif 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate extern char *optarg; 68*7c478bd9Sstevel@tonic-gate extern int optind; 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate int main __P((int, char *[])); 71*7c478bd9Sstevel@tonic-gate void usage __P((void)); 72*7c478bd9Sstevel@tonic-gate int changestateif __P((char *, char *)); 73*7c478bd9Sstevel@tonic-gate int changenatif __P((char *, char *)); 74*7c478bd9Sstevel@tonic-gate int readstate __P((int, char *)); 75*7c478bd9Sstevel@tonic-gate int readnat __P((int, char *)); 76*7c478bd9Sstevel@tonic-gate int writestate __P((int, char *)); 77*7c478bd9Sstevel@tonic-gate int opendevice __P((char *)); 78*7c478bd9Sstevel@tonic-gate void closedevice __P((int)); 79*7c478bd9Sstevel@tonic-gate int setlock __P((int, int)); 80*7c478bd9Sstevel@tonic-gate int writeall __P((char *)); 81*7c478bd9Sstevel@tonic-gate int readall __P((char *)); 82*7c478bd9Sstevel@tonic-gate int writenat __P((int, char *)); 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate int opts = 0; 85*7c478bd9Sstevel@tonic-gate char *progname; 86*7c478bd9Sstevel@tonic-gate 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate void usage() 89*7c478bd9Sstevel@tonic-gate { 90*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-nv] -l\n", progname); 91*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-nv] -u\n", progname); 92*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-nv] [-d <dir>] -R\n", progname); 93*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-nv] [-d <dir>] -W\n", progname); 94*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-nNSv] [-f <file>] -r\n", progname); 95*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-nNSv] [-f <file>] -w\n", progname); 96*7c478bd9Sstevel@tonic-gate fprintf(stderr, "usage: %s [-nNSv] -f <filename> -i <if1>,<if2>\n", 97*7c478bd9Sstevel@tonic-gate progname); 98*7c478bd9Sstevel@tonic-gate exit(1); 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate 102*7c478bd9Sstevel@tonic-gate /* 103*7c478bd9Sstevel@tonic-gate * Change interface names in state information saved out to disk. 104*7c478bd9Sstevel@tonic-gate */ 105*7c478bd9Sstevel@tonic-gate int changestateif(ifs, fname) 106*7c478bd9Sstevel@tonic-gate char *ifs, *fname; 107*7c478bd9Sstevel@tonic-gate { 108*7c478bd9Sstevel@tonic-gate int fd, olen, nlen, rw; 109*7c478bd9Sstevel@tonic-gate ipstate_save_t ips; 110*7c478bd9Sstevel@tonic-gate off_t pos; 111*7c478bd9Sstevel@tonic-gate char *s; 112*7c478bd9Sstevel@tonic-gate 113*7c478bd9Sstevel@tonic-gate s = strchr(ifs, ','); 114*7c478bd9Sstevel@tonic-gate if (!s) 115*7c478bd9Sstevel@tonic-gate usage(); 116*7c478bd9Sstevel@tonic-gate *s++ = '\0'; 117*7c478bd9Sstevel@tonic-gate nlen = strlen(s); 118*7c478bd9Sstevel@tonic-gate olen = strlen(ifs); 119*7c478bd9Sstevel@tonic-gate if (nlen >= sizeof(ips.ips_is.is_ifname) || 120*7c478bd9Sstevel@tonic-gate olen >= sizeof(ips.ips_is.is_ifname)) 121*7c478bd9Sstevel@tonic-gate usage(); 122*7c478bd9Sstevel@tonic-gate 123*7c478bd9Sstevel@tonic-gate fd = open(fname, O_RDWR); 124*7c478bd9Sstevel@tonic-gate if (fd == -1) { 125*7c478bd9Sstevel@tonic-gate perror("open"); 126*7c478bd9Sstevel@tonic-gate exit(1); 127*7c478bd9Sstevel@tonic-gate } 128*7c478bd9Sstevel@tonic-gate 129*7c478bd9Sstevel@tonic-gate for (pos = 0; read(fd, &ips, sizeof(ips)) == sizeof(ips); ) { 130*7c478bd9Sstevel@tonic-gate rw = 0; 131*7c478bd9Sstevel@tonic-gate if (!strncmp(ips.ips_is.is_ifname[0], ifs, olen + 1)) { 132*7c478bd9Sstevel@tonic-gate strcpy(ips.ips_is.is_ifname[0], s); 133*7c478bd9Sstevel@tonic-gate rw = 1; 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate if (!strncmp(ips.ips_is.is_ifname[1], ifs, olen + 1)) { 136*7c478bd9Sstevel@tonic-gate strcpy(ips.ips_is.is_ifname[1], s); 137*7c478bd9Sstevel@tonic-gate rw = 1; 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate if (rw == 1) { 140*7c478bd9Sstevel@tonic-gate if (lseek(fd, pos, SEEK_SET) != pos) { 141*7c478bd9Sstevel@tonic-gate perror("lseek"); 142*7c478bd9Sstevel@tonic-gate exit(1); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate if (write(fd, &ips, sizeof(ips)) != sizeof(ips)) { 145*7c478bd9Sstevel@tonic-gate perror("write"); 146*7c478bd9Sstevel@tonic-gate exit(1); 147*7c478bd9Sstevel@tonic-gate } 148*7c478bd9Sstevel@tonic-gate } 149*7c478bd9Sstevel@tonic-gate pos = lseek(fd, 0, SEEK_CUR); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate close(fd); 152*7c478bd9Sstevel@tonic-gate 153*7c478bd9Sstevel@tonic-gate return 0; 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * Change interface names in NAT information saved out to disk. 159*7c478bd9Sstevel@tonic-gate */ 160*7c478bd9Sstevel@tonic-gate int changenatif(ifs, fname) 161*7c478bd9Sstevel@tonic-gate char *ifs, *fname; 162*7c478bd9Sstevel@tonic-gate { 163*7c478bd9Sstevel@tonic-gate int fd, olen, nlen, rw; 164*7c478bd9Sstevel@tonic-gate nat_save_t ipn; 165*7c478bd9Sstevel@tonic-gate nat_t *nat; 166*7c478bd9Sstevel@tonic-gate off_t pos; 167*7c478bd9Sstevel@tonic-gate char *s; 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate s = strchr(ifs, ','); 170*7c478bd9Sstevel@tonic-gate if (!s) 171*7c478bd9Sstevel@tonic-gate usage(); 172*7c478bd9Sstevel@tonic-gate *s++ = '\0'; 173*7c478bd9Sstevel@tonic-gate nlen = strlen(s); 174*7c478bd9Sstevel@tonic-gate olen = strlen(ifs); 175*7c478bd9Sstevel@tonic-gate nat = &ipn.ipn_nat; 176*7c478bd9Sstevel@tonic-gate if (nlen >= sizeof(nat->nat_ifnames[0]) || 177*7c478bd9Sstevel@tonic-gate olen >= sizeof(nat->nat_ifnames[0])) 178*7c478bd9Sstevel@tonic-gate usage(); 179*7c478bd9Sstevel@tonic-gate 180*7c478bd9Sstevel@tonic-gate fd = open(fname, O_RDWR); 181*7c478bd9Sstevel@tonic-gate if (fd == -1) { 182*7c478bd9Sstevel@tonic-gate perror("open"); 183*7c478bd9Sstevel@tonic-gate exit(1); 184*7c478bd9Sstevel@tonic-gate } 185*7c478bd9Sstevel@tonic-gate 186*7c478bd9Sstevel@tonic-gate for (pos = 0; read(fd, &ipn, sizeof(ipn)) == sizeof(ipn); ) { 187*7c478bd9Sstevel@tonic-gate rw = 0; 188*7c478bd9Sstevel@tonic-gate if (!strncmp(nat->nat_ifnames[0], ifs, olen + 1)) { 189*7c478bd9Sstevel@tonic-gate strcpy(nat->nat_ifnames[0], s); 190*7c478bd9Sstevel@tonic-gate rw = 1; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate if (!strncmp(nat->nat_ifnames[1], ifs, olen + 1)) { 193*7c478bd9Sstevel@tonic-gate strcpy(nat->nat_ifnames[1], s); 194*7c478bd9Sstevel@tonic-gate rw = 1; 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate if (rw == 1) { 197*7c478bd9Sstevel@tonic-gate if (lseek(fd, pos, SEEK_SET) != pos) { 198*7c478bd9Sstevel@tonic-gate perror("lseek"); 199*7c478bd9Sstevel@tonic-gate exit(1); 200*7c478bd9Sstevel@tonic-gate } 201*7c478bd9Sstevel@tonic-gate if (write(fd, &ipn, sizeof(ipn)) != sizeof(ipn)) { 202*7c478bd9Sstevel@tonic-gate perror("write"); 203*7c478bd9Sstevel@tonic-gate exit(1); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate pos = lseek(fd, 0, SEEK_CUR); 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate close(fd); 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate return 0; 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate int main(argc,argv) 215*7c478bd9Sstevel@tonic-gate int argc; 216*7c478bd9Sstevel@tonic-gate char *argv[]; 217*7c478bd9Sstevel@tonic-gate { 218*7c478bd9Sstevel@tonic-gate int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0; 219*7c478bd9Sstevel@tonic-gate char *dirname = NULL, *filename = NULL, *ifs = NULL; 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate progname = argv[0]; 222*7c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "d:f:lNnSRruvWw")) != -1) 223*7c478bd9Sstevel@tonic-gate switch (c) 224*7c478bd9Sstevel@tonic-gate { 225*7c478bd9Sstevel@tonic-gate case 'd' : 226*7c478bd9Sstevel@tonic-gate if ((set == 0) && !dirname && !filename) 227*7c478bd9Sstevel@tonic-gate dirname = optarg; 228*7c478bd9Sstevel@tonic-gate else 229*7c478bd9Sstevel@tonic-gate usage(); 230*7c478bd9Sstevel@tonic-gate break; 231*7c478bd9Sstevel@tonic-gate case 'f' : 232*7c478bd9Sstevel@tonic-gate if ((set == 0) && !dirname && !filename) 233*7c478bd9Sstevel@tonic-gate filename = optarg; 234*7c478bd9Sstevel@tonic-gate else 235*7c478bd9Sstevel@tonic-gate usage(); 236*7c478bd9Sstevel@tonic-gate break; 237*7c478bd9Sstevel@tonic-gate case 'i' : 238*7c478bd9Sstevel@tonic-gate ifs = optarg; 239*7c478bd9Sstevel@tonic-gate set = 1; 240*7c478bd9Sstevel@tonic-gate break; 241*7c478bd9Sstevel@tonic-gate case 'l' : 242*7c478bd9Sstevel@tonic-gate if (filename || dirname || set) 243*7c478bd9Sstevel@tonic-gate usage(); 244*7c478bd9Sstevel@tonic-gate lock = 1; 245*7c478bd9Sstevel@tonic-gate set = 1; 246*7c478bd9Sstevel@tonic-gate break; 247*7c478bd9Sstevel@tonic-gate case 'n' : 248*7c478bd9Sstevel@tonic-gate opts |= OPT_DONOTHING; 249*7c478bd9Sstevel@tonic-gate break; 250*7c478bd9Sstevel@tonic-gate case 'N' : 251*7c478bd9Sstevel@tonic-gate if ((ns >= 0) || dirname || (rw != -1) || set) 252*7c478bd9Sstevel@tonic-gate usage(); 253*7c478bd9Sstevel@tonic-gate ns = 0; 254*7c478bd9Sstevel@tonic-gate set = 1; 255*7c478bd9Sstevel@tonic-gate break; 256*7c478bd9Sstevel@tonic-gate case 'r' : 257*7c478bd9Sstevel@tonic-gate if ((ns >= 0) || dirname || (rw != -1)) 258*7c478bd9Sstevel@tonic-gate usage(); 259*7c478bd9Sstevel@tonic-gate rw = 0; 260*7c478bd9Sstevel@tonic-gate set = 1; 261*7c478bd9Sstevel@tonic-gate break; 262*7c478bd9Sstevel@tonic-gate case 'R' : 263*7c478bd9Sstevel@tonic-gate rw = 2; 264*7c478bd9Sstevel@tonic-gate set = 1; 265*7c478bd9Sstevel@tonic-gate break; 266*7c478bd9Sstevel@tonic-gate case 'S' : 267*7c478bd9Sstevel@tonic-gate if ((ns >= 0) || dirname || (rw != -1) || set) 268*7c478bd9Sstevel@tonic-gate usage(); 269*7c478bd9Sstevel@tonic-gate ns = 1; 270*7c478bd9Sstevel@tonic-gate set = 1; 271*7c478bd9Sstevel@tonic-gate break; 272*7c478bd9Sstevel@tonic-gate case 'u' : 273*7c478bd9Sstevel@tonic-gate if (filename || dirname || set) 274*7c478bd9Sstevel@tonic-gate usage(); 275*7c478bd9Sstevel@tonic-gate lock = 0; 276*7c478bd9Sstevel@tonic-gate set = 1; 277*7c478bd9Sstevel@tonic-gate break; 278*7c478bd9Sstevel@tonic-gate case 'v' : 279*7c478bd9Sstevel@tonic-gate opts |= OPT_VERBOSE; 280*7c478bd9Sstevel@tonic-gate break; 281*7c478bd9Sstevel@tonic-gate case 'w' : 282*7c478bd9Sstevel@tonic-gate if (dirname || (rw != -1) || (ns == -1)) 283*7c478bd9Sstevel@tonic-gate usage(); 284*7c478bd9Sstevel@tonic-gate rw = 1; 285*7c478bd9Sstevel@tonic-gate set = 1; 286*7c478bd9Sstevel@tonic-gate break; 287*7c478bd9Sstevel@tonic-gate case 'W' : 288*7c478bd9Sstevel@tonic-gate rw = 3; 289*7c478bd9Sstevel@tonic-gate set = 1; 290*7c478bd9Sstevel@tonic-gate break; 291*7c478bd9Sstevel@tonic-gate case '?' : 292*7c478bd9Sstevel@tonic-gate default : 293*7c478bd9Sstevel@tonic-gate usage(); 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate if (ifs) { 297*7c478bd9Sstevel@tonic-gate if (!filename || ns < 0) 298*7c478bd9Sstevel@tonic-gate usage(); 299*7c478bd9Sstevel@tonic-gate if (ns == 0) 300*7c478bd9Sstevel@tonic-gate return changenatif(ifs, filename); 301*7c478bd9Sstevel@tonic-gate else 302*7c478bd9Sstevel@tonic-gate return changestateif(ifs, filename); 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate if ((ns >= 0) || (lock >= 0)) { 306*7c478bd9Sstevel@tonic-gate if (lock >= 0) 307*7c478bd9Sstevel@tonic-gate devfd = opendevice(NULL); 308*7c478bd9Sstevel@tonic-gate else if (ns >= 0) { 309*7c478bd9Sstevel@tonic-gate if (ns == 1) 310*7c478bd9Sstevel@tonic-gate devfd = opendevice(IPSTATE_NAME); 311*7c478bd9Sstevel@tonic-gate else if (ns == 0) 312*7c478bd9Sstevel@tonic-gate devfd = opendevice(IPNAT_NAME); 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate if (devfd == -1) 315*7c478bd9Sstevel@tonic-gate exit(1); 316*7c478bd9Sstevel@tonic-gate } 317*7c478bd9Sstevel@tonic-gate 318*7c478bd9Sstevel@tonic-gate if (lock >= 0) 319*7c478bd9Sstevel@tonic-gate err = setlock(devfd, lock); 320*7c478bd9Sstevel@tonic-gate else if (rw >= 0) { 321*7c478bd9Sstevel@tonic-gate if (rw & 1) { /* WRITE */ 322*7c478bd9Sstevel@tonic-gate if (rw & 2) 323*7c478bd9Sstevel@tonic-gate err = writeall(dirname); 324*7c478bd9Sstevel@tonic-gate else { 325*7c478bd9Sstevel@tonic-gate if (ns == 0) 326*7c478bd9Sstevel@tonic-gate err = writenat(devfd, filename); 327*7c478bd9Sstevel@tonic-gate else if (ns == 1) 328*7c478bd9Sstevel@tonic-gate err = writestate(devfd, filename); 329*7c478bd9Sstevel@tonic-gate } 330*7c478bd9Sstevel@tonic-gate } else { 331*7c478bd9Sstevel@tonic-gate if (rw & 2) 332*7c478bd9Sstevel@tonic-gate err = readall(dirname); 333*7c478bd9Sstevel@tonic-gate else { 334*7c478bd9Sstevel@tonic-gate if (ns == 0) 335*7c478bd9Sstevel@tonic-gate err = readnat(devfd, filename); 336*7c478bd9Sstevel@tonic-gate else if (ns == 1) 337*7c478bd9Sstevel@tonic-gate err = readstate(devfd, filename); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate } 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate return err; 342*7c478bd9Sstevel@tonic-gate } 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate int opendevice(ipfdev) 346*7c478bd9Sstevel@tonic-gate char *ipfdev; 347*7c478bd9Sstevel@tonic-gate { 348*7c478bd9Sstevel@tonic-gate int fd = -1; 349*7c478bd9Sstevel@tonic-gate 350*7c478bd9Sstevel@tonic-gate if (opts & OPT_DONOTHING) 351*7c478bd9Sstevel@tonic-gate return -2; 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate if (!ipfdev) 354*7c478bd9Sstevel@tonic-gate ipfdev = IPL_NAME; 355*7c478bd9Sstevel@tonic-gate 356*7c478bd9Sstevel@tonic-gate if ((fd = open(ipfdev, O_RDWR)) == -1) 357*7c478bd9Sstevel@tonic-gate if ((fd = open(ipfdev, O_RDONLY)) == -1) 358*7c478bd9Sstevel@tonic-gate perror("open device"); 359*7c478bd9Sstevel@tonic-gate return fd; 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate void closedevice(fd) 364*7c478bd9Sstevel@tonic-gate int fd; 365*7c478bd9Sstevel@tonic-gate { 366*7c478bd9Sstevel@tonic-gate close(fd); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate int setlock(fd, lock) 371*7c478bd9Sstevel@tonic-gate int fd, lock; 372*7c478bd9Sstevel@tonic-gate { 373*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 374*7c478bd9Sstevel@tonic-gate printf("Turn lock %s\n", lock ? "on" : "off"); 375*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) { 376*7c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTLCK, &lock) == -1) { 377*7c478bd9Sstevel@tonic-gate perror("SIOCSTLCK"); 378*7c478bd9Sstevel@tonic-gate return 1; 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 381*7c478bd9Sstevel@tonic-gate printf("Lock now %s\n", lock ? "on" : "off"); 382*7c478bd9Sstevel@tonic-gate } 383*7c478bd9Sstevel@tonic-gate return 0; 384*7c478bd9Sstevel@tonic-gate } 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate int writestate(fd, file) 388*7c478bd9Sstevel@tonic-gate int fd; 389*7c478bd9Sstevel@tonic-gate char *file; 390*7c478bd9Sstevel@tonic-gate { 391*7c478bd9Sstevel@tonic-gate ipstate_save_t ips, *ipsp; 392*7c478bd9Sstevel@tonic-gate int wfd = -1; 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate if (!file) 395*7c478bd9Sstevel@tonic-gate file = IPF_STATEFILE; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate wfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); 398*7c478bd9Sstevel@tonic-gate if (wfd == -1) { 399*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 400*7c478bd9Sstevel@tonic-gate perror("state:open"); 401*7c478bd9Sstevel@tonic-gate return 1; 402*7c478bd9Sstevel@tonic-gate } 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate ipsp = &ips; 405*7c478bd9Sstevel@tonic-gate bzero((char *)ipsp, sizeof(ips)); 406*7c478bd9Sstevel@tonic-gate 407*7c478bd9Sstevel@tonic-gate do { 408*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 409*7c478bd9Sstevel@tonic-gate printf("Getting state from addr %p\n", ips.ips_next); 410*7c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTGET, &ipsp)) { 411*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) 412*7c478bd9Sstevel@tonic-gate break; 413*7c478bd9Sstevel@tonic-gate perror("state:SIOCSTGET"); 414*7c478bd9Sstevel@tonic-gate close(wfd); 415*7c478bd9Sstevel@tonic-gate return 1; 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 418*7c478bd9Sstevel@tonic-gate printf("Got state next %p\n", ips.ips_next); 419*7c478bd9Sstevel@tonic-gate if (write(wfd, ipsp, sizeof(ips)) != sizeof(ips)) { 420*7c478bd9Sstevel@tonic-gate perror("state:write"); 421*7c478bd9Sstevel@tonic-gate close(wfd); 422*7c478bd9Sstevel@tonic-gate return 1; 423*7c478bd9Sstevel@tonic-gate } 424*7c478bd9Sstevel@tonic-gate } while (ips.ips_next != NULL); 425*7c478bd9Sstevel@tonic-gate close(wfd); 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate return 0; 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate int readstate(fd, file) 432*7c478bd9Sstevel@tonic-gate int fd; 433*7c478bd9Sstevel@tonic-gate char *file; 434*7c478bd9Sstevel@tonic-gate { 435*7c478bd9Sstevel@tonic-gate ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL; 436*7c478bd9Sstevel@tonic-gate int sfd = -1, i; 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate if (!file) 439*7c478bd9Sstevel@tonic-gate file = IPF_STATEFILE; 440*7c478bd9Sstevel@tonic-gate 441*7c478bd9Sstevel@tonic-gate sfd = open(file, O_RDONLY, 0600); 442*7c478bd9Sstevel@tonic-gate if (sfd == -1) { 443*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 444*7c478bd9Sstevel@tonic-gate perror("open"); 445*7c478bd9Sstevel@tonic-gate return 1; 446*7c478bd9Sstevel@tonic-gate } 447*7c478bd9Sstevel@tonic-gate 448*7c478bd9Sstevel@tonic-gate bzero((char *)&ips, sizeof(ips)); 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate /* 451*7c478bd9Sstevel@tonic-gate * 1. Read all state information in. 452*7c478bd9Sstevel@tonic-gate */ 453*7c478bd9Sstevel@tonic-gate do { 454*7c478bd9Sstevel@tonic-gate i = read(sfd, &ips, sizeof(ips)); 455*7c478bd9Sstevel@tonic-gate if (i == -1) { 456*7c478bd9Sstevel@tonic-gate perror("read"); 457*7c478bd9Sstevel@tonic-gate close(sfd); 458*7c478bd9Sstevel@tonic-gate return 1; 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate if (i == 0) 461*7c478bd9Sstevel@tonic-gate break; 462*7c478bd9Sstevel@tonic-gate if (i != sizeof(ips)) { 463*7c478bd9Sstevel@tonic-gate fprintf(stderr, "incomplete read: %d != %d\n", i, 464*7c478bd9Sstevel@tonic-gate (int)sizeof(ips)); 465*7c478bd9Sstevel@tonic-gate close(sfd); 466*7c478bd9Sstevel@tonic-gate return 1; 467*7c478bd9Sstevel@tonic-gate } 468*7c478bd9Sstevel@tonic-gate is = (ipstate_save_t *)malloc(sizeof(*is)); 469*7c478bd9Sstevel@tonic-gate if(!is) { 470*7c478bd9Sstevel@tonic-gate fprintf(stderr, "malloc failed\n"); 471*7c478bd9Sstevel@tonic-gate return 1; 472*7c478bd9Sstevel@tonic-gate } 473*7c478bd9Sstevel@tonic-gate 474*7c478bd9Sstevel@tonic-gate bcopy((char *)&ips, (char *)is, sizeof(ips)); 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate /* 477*7c478bd9Sstevel@tonic-gate * Check to see if this is the first state entry that will 478*7c478bd9Sstevel@tonic-gate * reference a particular rule and if so, flag it as such 479*7c478bd9Sstevel@tonic-gate * else just adjust the rule pointer to become a pointer to 480*7c478bd9Sstevel@tonic-gate * the other. We do this so we have a means later for tracking 481*7c478bd9Sstevel@tonic-gate * who is referencing us when we get back the real pointer 482*7c478bd9Sstevel@tonic-gate * in is_rule after doing the ioctl. 483*7c478bd9Sstevel@tonic-gate */ 484*7c478bd9Sstevel@tonic-gate for (is1 = ipshead; is1 != NULL; is1 = is1->ips_next) 485*7c478bd9Sstevel@tonic-gate if (is1->ips_rule == is->ips_rule) 486*7c478bd9Sstevel@tonic-gate break; 487*7c478bd9Sstevel@tonic-gate if (is1 == NULL) 488*7c478bd9Sstevel@tonic-gate is->ips_is.is_flags |= SI_NEWFR; 489*7c478bd9Sstevel@tonic-gate else 490*7c478bd9Sstevel@tonic-gate is->ips_rule = (void *)&is1->ips_rule; 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate /* 493*7c478bd9Sstevel@tonic-gate * Use a tail-queue type list (add things to the end).. 494*7c478bd9Sstevel@tonic-gate */ 495*7c478bd9Sstevel@tonic-gate is->ips_next = NULL; 496*7c478bd9Sstevel@tonic-gate if (!ipshead) 497*7c478bd9Sstevel@tonic-gate ipshead = is; 498*7c478bd9Sstevel@tonic-gate if (ipstail) 499*7c478bd9Sstevel@tonic-gate ipstail->ips_next = is; 500*7c478bd9Sstevel@tonic-gate ipstail = is; 501*7c478bd9Sstevel@tonic-gate } while (1); 502*7c478bd9Sstevel@tonic-gate 503*7c478bd9Sstevel@tonic-gate close(sfd); 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate for (is = ipshead; is; is = is->ips_next) { 506*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 507*7c478bd9Sstevel@tonic-gate printf("Loading new state table entry\n"); 508*7c478bd9Sstevel@tonic-gate if (is->ips_is.is_flags & SI_NEWFR) { 509*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 510*7c478bd9Sstevel@tonic-gate printf("Loading new filter rule\n"); 511*7c478bd9Sstevel@tonic-gate } 512*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) 513*7c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTPUT, &is)) { 514*7c478bd9Sstevel@tonic-gate perror("SIOCSTPUT"); 515*7c478bd9Sstevel@tonic-gate return 1; 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate 518*7c478bd9Sstevel@tonic-gate if (is->ips_is.is_flags & SI_NEWFR) { 519*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 520*7c478bd9Sstevel@tonic-gate printf("Real rule addr %p\n", is->ips_rule); 521*7c478bd9Sstevel@tonic-gate for (is1 = is->ips_next; is1; is1 = is1->ips_next) 522*7c478bd9Sstevel@tonic-gate if (is1->ips_rule == (frentry_t *)&is->ips_rule) 523*7c478bd9Sstevel@tonic-gate is1->ips_rule = is->ips_rule; 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate } 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate return 0; 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate 530*7c478bd9Sstevel@tonic-gate 531*7c478bd9Sstevel@tonic-gate int readnat(fd, file) 532*7c478bd9Sstevel@tonic-gate int fd; 533*7c478bd9Sstevel@tonic-gate char *file; 534*7c478bd9Sstevel@tonic-gate { 535*7c478bd9Sstevel@tonic-gate nat_save_t ipn, *in, *ipnhead, *in1, *ipntail, *ipnp; 536*7c478bd9Sstevel@tonic-gate int nfd, i; 537*7c478bd9Sstevel@tonic-gate nat_t *nat; 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate nfd = -1; 540*7c478bd9Sstevel@tonic-gate in = NULL; 541*7c478bd9Sstevel@tonic-gate ipnhead = NULL; 542*7c478bd9Sstevel@tonic-gate ipntail = NULL; 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate if (!file) 545*7c478bd9Sstevel@tonic-gate file = IPF_NATFILE; 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate nfd = open(file, O_RDONLY); 548*7c478bd9Sstevel@tonic-gate if (nfd == -1) { 549*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 550*7c478bd9Sstevel@tonic-gate perror("nat:open"); 551*7c478bd9Sstevel@tonic-gate return 1; 552*7c478bd9Sstevel@tonic-gate } 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate bzero((char *)&ipn, sizeof(ipn)); 555*7c478bd9Sstevel@tonic-gate ipnp = &ipn; 556*7c478bd9Sstevel@tonic-gate 557*7c478bd9Sstevel@tonic-gate /* 558*7c478bd9Sstevel@tonic-gate * 1. Read all state information in. 559*7c478bd9Sstevel@tonic-gate */ 560*7c478bd9Sstevel@tonic-gate do { 561*7c478bd9Sstevel@tonic-gate i = read(nfd, &ipn, sizeof(ipn)); 562*7c478bd9Sstevel@tonic-gate if (i == -1) { 563*7c478bd9Sstevel@tonic-gate perror("read"); 564*7c478bd9Sstevel@tonic-gate close(nfd); 565*7c478bd9Sstevel@tonic-gate return 1; 566*7c478bd9Sstevel@tonic-gate } 567*7c478bd9Sstevel@tonic-gate if (i == 0) 568*7c478bd9Sstevel@tonic-gate break; 569*7c478bd9Sstevel@tonic-gate if (i != sizeof(ipn)) { 570*7c478bd9Sstevel@tonic-gate fprintf(stderr, "incomplete read: %d != %d\n", i, 571*7c478bd9Sstevel@tonic-gate (int)sizeof(ipn)); 572*7c478bd9Sstevel@tonic-gate close(nfd); 573*7c478bd9Sstevel@tonic-gate return 1; 574*7c478bd9Sstevel@tonic-gate } 575*7c478bd9Sstevel@tonic-gate 576*7c478bd9Sstevel@tonic-gate if (ipn.ipn_dsize > 0) { 577*7c478bd9Sstevel@tonic-gate char *s = ipnp->ipn_data; 578*7c478bd9Sstevel@tonic-gate int n = ipnp->ipn_dsize; 579*7c478bd9Sstevel@tonic-gate 580*7c478bd9Sstevel@tonic-gate n -= sizeof(ipnp->ipn_data); 581*7c478bd9Sstevel@tonic-gate in = malloc(sizeof(*in) + n); 582*7c478bd9Sstevel@tonic-gate if (!in) 583*7c478bd9Sstevel@tonic-gate break; 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate s += sizeof(ipnp->ipn_data); 586*7c478bd9Sstevel@tonic-gate i = read(nfd, s, n); 587*7c478bd9Sstevel@tonic-gate if (i == 0) 588*7c478bd9Sstevel@tonic-gate break; 589*7c478bd9Sstevel@tonic-gate if (i != n) { 590*7c478bd9Sstevel@tonic-gate fprintf(stderr, "incomplete read: %d != %d\n", 591*7c478bd9Sstevel@tonic-gate i, n); 592*7c478bd9Sstevel@tonic-gate close(nfd); 593*7c478bd9Sstevel@tonic-gate free(in); 594*7c478bd9Sstevel@tonic-gate return 1; 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate } else { 597*7c478bd9Sstevel@tonic-gate ipn.ipn_dsize = 0; 598*7c478bd9Sstevel@tonic-gate in = (nat_save_t *)malloc(sizeof(*in)); 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate bcopy((char *)ipnp, (char *)in, sizeof(ipn)); 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate /* 603*7c478bd9Sstevel@tonic-gate * Check to see if this is the first state entry that will 604*7c478bd9Sstevel@tonic-gate * reference a particular rule and if so, flag it as such 605*7c478bd9Sstevel@tonic-gate * else just adjust the rule pointer to become a pointer to 606*7c478bd9Sstevel@tonic-gate * the other. We do this so we have a means later for tracking 607*7c478bd9Sstevel@tonic-gate * who is referencing us when we get back the real pointer 608*7c478bd9Sstevel@tonic-gate * in is_rule after doing the ioctl. 609*7c478bd9Sstevel@tonic-gate */ 610*7c478bd9Sstevel@tonic-gate nat = &in->ipn_nat; 611*7c478bd9Sstevel@tonic-gate if (nat->nat_fr != NULL) { 612*7c478bd9Sstevel@tonic-gate for (in1 = ipnhead; in1 != NULL; in1 = in1->ipn_next) 613*7c478bd9Sstevel@tonic-gate if (in1->ipn_rule == nat->nat_fr) 614*7c478bd9Sstevel@tonic-gate break; 615*7c478bd9Sstevel@tonic-gate if (in1 == NULL) 616*7c478bd9Sstevel@tonic-gate nat->nat_flags |= SI_NEWFR; 617*7c478bd9Sstevel@tonic-gate else 618*7c478bd9Sstevel@tonic-gate nat->nat_fr = &in1->ipn_fr; 619*7c478bd9Sstevel@tonic-gate } 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate /* 622*7c478bd9Sstevel@tonic-gate * Use a tail-queue type list (add things to the end).. 623*7c478bd9Sstevel@tonic-gate */ 624*7c478bd9Sstevel@tonic-gate in->ipn_next = NULL; 625*7c478bd9Sstevel@tonic-gate if (!ipnhead) 626*7c478bd9Sstevel@tonic-gate ipnhead = in; 627*7c478bd9Sstevel@tonic-gate if (ipntail) 628*7c478bd9Sstevel@tonic-gate ipntail->ipn_next = in; 629*7c478bd9Sstevel@tonic-gate ipntail = in; 630*7c478bd9Sstevel@tonic-gate } while (1); 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate close(nfd); 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate for (in = ipnhead; in; in = in->ipn_next) { 635*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 636*7c478bd9Sstevel@tonic-gate printf("Loading new NAT table entry\n"); 637*7c478bd9Sstevel@tonic-gate nat = &in->ipn_nat; 638*7c478bd9Sstevel@tonic-gate if (nat->nat_flags & SI_NEWFR) { 639*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 640*7c478bd9Sstevel@tonic-gate printf("Loading new filter rule\n"); 641*7c478bd9Sstevel@tonic-gate } 642*7c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING)) 643*7c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTPUT, &in)) { 644*7c478bd9Sstevel@tonic-gate perror("SIOCSTPUT"); 645*7c478bd9Sstevel@tonic-gate return 1; 646*7c478bd9Sstevel@tonic-gate } 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate if (nat->nat_flags & SI_NEWFR) { 649*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 650*7c478bd9Sstevel@tonic-gate printf("Real rule addr %p\n", nat->nat_fr); 651*7c478bd9Sstevel@tonic-gate for (in1 = in->ipn_next; in1; in1 = in1->ipn_next) 652*7c478bd9Sstevel@tonic-gate if (in1->ipn_rule == &in->ipn_fr) 653*7c478bd9Sstevel@tonic-gate in1->ipn_rule = nat->nat_fr; 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate } 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate return 0; 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate 661*7c478bd9Sstevel@tonic-gate int writenat(fd, file) 662*7c478bd9Sstevel@tonic-gate int fd; 663*7c478bd9Sstevel@tonic-gate char *file; 664*7c478bd9Sstevel@tonic-gate { 665*7c478bd9Sstevel@tonic-gate nat_save_t *ipnp = NULL, *next = NULL; 666*7c478bd9Sstevel@tonic-gate int nfd = -1; 667*7c478bd9Sstevel@tonic-gate natget_t ng; 668*7c478bd9Sstevel@tonic-gate 669*7c478bd9Sstevel@tonic-gate if (!file) 670*7c478bd9Sstevel@tonic-gate file = IPF_NATFILE; 671*7c478bd9Sstevel@tonic-gate 672*7c478bd9Sstevel@tonic-gate nfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); 673*7c478bd9Sstevel@tonic-gate if (nfd == -1) { 674*7c478bd9Sstevel@tonic-gate fprintf(stderr, "%s ", file); 675*7c478bd9Sstevel@tonic-gate perror("nat:open"); 676*7c478bd9Sstevel@tonic-gate return 1; 677*7c478bd9Sstevel@tonic-gate } 678*7c478bd9Sstevel@tonic-gate 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate do { 681*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 682*7c478bd9Sstevel@tonic-gate printf("Getting nat from addr %p\n", ipnp); 683*7c478bd9Sstevel@tonic-gate ng.ng_ptr = next; 684*7c478bd9Sstevel@tonic-gate ng.ng_sz = 0; 685*7c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTGSZ, &ng)) { 686*7c478bd9Sstevel@tonic-gate perror("nat:SIOCSTGSZ"); 687*7c478bd9Sstevel@tonic-gate close(nfd); 688*7c478bd9Sstevel@tonic-gate if (ipnp != NULL) 689*7c478bd9Sstevel@tonic-gate free(ipnp); 690*7c478bd9Sstevel@tonic-gate return 1; 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate 693*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 694*7c478bd9Sstevel@tonic-gate printf("NAT size %d from %p\n", ng.ng_sz, ng.ng_ptr); 695*7c478bd9Sstevel@tonic-gate 696*7c478bd9Sstevel@tonic-gate if (ng.ng_sz == 0) 697*7c478bd9Sstevel@tonic-gate break; 698*7c478bd9Sstevel@tonic-gate 699*7c478bd9Sstevel@tonic-gate if (!ipnp) 700*7c478bd9Sstevel@tonic-gate ipnp = malloc(ng.ng_sz); 701*7c478bd9Sstevel@tonic-gate else 702*7c478bd9Sstevel@tonic-gate ipnp = realloc((char *)ipnp, ng.ng_sz); 703*7c478bd9Sstevel@tonic-gate if (!ipnp) { 704*7c478bd9Sstevel@tonic-gate fprintf(stderr, 705*7c478bd9Sstevel@tonic-gate "malloc for %d bytes failed\n", ng.ng_sz); 706*7c478bd9Sstevel@tonic-gate break; 707*7c478bd9Sstevel@tonic-gate } 708*7c478bd9Sstevel@tonic-gate 709*7c478bd9Sstevel@tonic-gate bzero((char *)ipnp, ng.ng_sz); 710*7c478bd9Sstevel@tonic-gate ipnp->ipn_next = next; 711*7c478bd9Sstevel@tonic-gate if (ioctl(fd, SIOCSTGET, &ipnp)) { 712*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) 713*7c478bd9Sstevel@tonic-gate break; 714*7c478bd9Sstevel@tonic-gate perror("nat:SIOCSTGET"); 715*7c478bd9Sstevel@tonic-gate close(nfd); 716*7c478bd9Sstevel@tonic-gate free(ipnp); 717*7c478bd9Sstevel@tonic-gate return 1; 718*7c478bd9Sstevel@tonic-gate } 719*7c478bd9Sstevel@tonic-gate 720*7c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE) 721*7c478bd9Sstevel@tonic-gate printf("Got nat next %p\n", ipnp->ipn_next); 722*7c478bd9Sstevel@tonic-gate if (write(nfd, ipnp, ng.ng_sz) != ng.ng_sz) { 723*7c478bd9Sstevel@tonic-gate perror("nat:write"); 724*7c478bd9Sstevel@tonic-gate close(nfd); 725*7c478bd9Sstevel@tonic-gate free(ipnp); 726*7c478bd9Sstevel@tonic-gate return 1; 727*7c478bd9Sstevel@tonic-gate } 728*7c478bd9Sstevel@tonic-gate next = ipnp->ipn_next; 729*7c478bd9Sstevel@tonic-gate } while (ipnp && next); 730*7c478bd9Sstevel@tonic-gate if (ipnp != NULL) 731*7c478bd9Sstevel@tonic-gate free(ipnp); 732*7c478bd9Sstevel@tonic-gate close(nfd); 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate return 0; 735*7c478bd9Sstevel@tonic-gate } 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate 738*7c478bd9Sstevel@tonic-gate int writeall(dirname) 739*7c478bd9Sstevel@tonic-gate char *dirname; 740*7c478bd9Sstevel@tonic-gate { 741*7c478bd9Sstevel@tonic-gate int fd, devfd; 742*7c478bd9Sstevel@tonic-gate 743*7c478bd9Sstevel@tonic-gate if (!dirname) 744*7c478bd9Sstevel@tonic-gate dirname = IPF_SAVEDIR; 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate if (chdir(dirname)) { 747*7c478bd9Sstevel@tonic-gate perror("chdir(IPF_SAVEDIR)"); 748*7c478bd9Sstevel@tonic-gate return 1; 749*7c478bd9Sstevel@tonic-gate } 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate fd = opendevice(NULL); 752*7c478bd9Sstevel@tonic-gate if (fd == -1) 753*7c478bd9Sstevel@tonic-gate return 1; 754*7c478bd9Sstevel@tonic-gate if (setlock(fd, 1)) { 755*7c478bd9Sstevel@tonic-gate close(fd); 756*7c478bd9Sstevel@tonic-gate return 1; 757*7c478bd9Sstevel@tonic-gate } 758*7c478bd9Sstevel@tonic-gate 759*7c478bd9Sstevel@tonic-gate devfd = opendevice(IPSTATE_NAME); 760*7c478bd9Sstevel@tonic-gate if (devfd == -1) 761*7c478bd9Sstevel@tonic-gate goto bad; 762*7c478bd9Sstevel@tonic-gate if (writestate(devfd, NULL)) 763*7c478bd9Sstevel@tonic-gate goto bad; 764*7c478bd9Sstevel@tonic-gate close(devfd); 765*7c478bd9Sstevel@tonic-gate 766*7c478bd9Sstevel@tonic-gate devfd = opendevice(IPNAT_NAME); 767*7c478bd9Sstevel@tonic-gate if (devfd == -1) 768*7c478bd9Sstevel@tonic-gate goto bad; 769*7c478bd9Sstevel@tonic-gate if (writenat(devfd, NULL)) 770*7c478bd9Sstevel@tonic-gate goto bad; 771*7c478bd9Sstevel@tonic-gate close(devfd); 772*7c478bd9Sstevel@tonic-gate 773*7c478bd9Sstevel@tonic-gate if (setlock(fd, 0)) { 774*7c478bd9Sstevel@tonic-gate close(fd); 775*7c478bd9Sstevel@tonic-gate return 1; 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate close(fd); 779*7c478bd9Sstevel@tonic-gate return 0; 780*7c478bd9Sstevel@tonic-gate 781*7c478bd9Sstevel@tonic-gate bad: 782*7c478bd9Sstevel@tonic-gate setlock(fd, 0); 783*7c478bd9Sstevel@tonic-gate close(fd); 784*7c478bd9Sstevel@tonic-gate return 1; 785*7c478bd9Sstevel@tonic-gate } 786*7c478bd9Sstevel@tonic-gate 787*7c478bd9Sstevel@tonic-gate 788*7c478bd9Sstevel@tonic-gate int readall(dirname) 789*7c478bd9Sstevel@tonic-gate char *dirname; 790*7c478bd9Sstevel@tonic-gate { 791*7c478bd9Sstevel@tonic-gate int fd, devfd; 792*7c478bd9Sstevel@tonic-gate 793*7c478bd9Sstevel@tonic-gate if (!dirname) 794*7c478bd9Sstevel@tonic-gate dirname = IPF_SAVEDIR; 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate if (chdir(dirname)) { 797*7c478bd9Sstevel@tonic-gate perror("chdir(IPF_SAVEDIR)"); 798*7c478bd9Sstevel@tonic-gate return 1; 799*7c478bd9Sstevel@tonic-gate } 800*7c478bd9Sstevel@tonic-gate 801*7c478bd9Sstevel@tonic-gate fd = opendevice(NULL); 802*7c478bd9Sstevel@tonic-gate if (fd == -1) 803*7c478bd9Sstevel@tonic-gate return 1; 804*7c478bd9Sstevel@tonic-gate if (setlock(fd, 1)) { 805*7c478bd9Sstevel@tonic-gate close(fd); 806*7c478bd9Sstevel@tonic-gate return 1; 807*7c478bd9Sstevel@tonic-gate } 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate devfd = opendevice(IPSTATE_NAME); 810*7c478bd9Sstevel@tonic-gate if (devfd == -1) 811*7c478bd9Sstevel@tonic-gate return 1; 812*7c478bd9Sstevel@tonic-gate if (readstate(devfd, NULL)) 813*7c478bd9Sstevel@tonic-gate return 1; 814*7c478bd9Sstevel@tonic-gate close(devfd); 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate devfd = opendevice(IPNAT_NAME); 817*7c478bd9Sstevel@tonic-gate if (devfd == -1) 818*7c478bd9Sstevel@tonic-gate return 1; 819*7c478bd9Sstevel@tonic-gate if (readnat(devfd, NULL)) 820*7c478bd9Sstevel@tonic-gate return 1; 821*7c478bd9Sstevel@tonic-gate close(devfd); 822*7c478bd9Sstevel@tonic-gate 823*7c478bd9Sstevel@tonic-gate if (setlock(fd, 0)) { 824*7c478bd9Sstevel@tonic-gate close(fd); 825*7c478bd9Sstevel@tonic-gate return 1; 826*7c478bd9Sstevel@tonic-gate } 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate return 0; 829*7c478bd9Sstevel@tonic-gate } 830