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"
48ab25eeb5Syz #include "netinet/ipl.h"
49*94bdecd9SRob Gulewich #include "ipfzone.h"
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate #if !defined(lint)
52ab25eeb5Syz 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
usage()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 */
changestateif(ifs,fname)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 */
changenatif(ifs,fname)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
main(argc,argv)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' :
265ab25eeb5Syz 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
opendevice(ipfdev)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
closedevice(fd)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
setlock(fd,lock)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
writestate(fd,file)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;
409ab25eeb5Syz 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;
423ab25eeb5Syz bzero((char *)&obj, sizeof(obj));
4247c478bd9Sstevel@tonic-gate bzero((char *)ipsp, sizeof(ips));
4257c478bd9Sstevel@tonic-gate
426ab25eeb5Syz obj.ipfo_rev = IPFILTER_VERSION;
427ab25eeb5Syz obj.ipfo_size = sizeof(*ipsp);
428ab25eeb5Syz obj.ipfo_type = IPFOBJ_STATESAVE;
429ab25eeb5Syz obj.ipfo_ptr = ipsp;
430ab25eeb5Syz
4317c478bd9Sstevel@tonic-gate do {
432ab25eeb5Syz
4337c478bd9Sstevel@tonic-gate if (opts & OPT_VERBOSE)
4347c478bd9Sstevel@tonic-gate printf("Getting state from addr %p\n", ips.ips_next);
435ab25eeb5Syz 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
readstate(fd,file)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;
462ab25eeb5Syz 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)) {
489ab25eeb5Syz fprintf(stderr, "state:incomplete read: %d != %d\n",
490ab25eeb5Syz 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
531ab25eeb5Syz obj.ipfo_rev = IPFILTER_VERSION;
532ab25eeb5Syz obj.ipfo_size = sizeof(*is);
533ab25eeb5Syz obj.ipfo_type = IPFOBJ_STATESAVE;
534ab25eeb5Syz
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 }
542ab25eeb5Syz
543ab25eeb5Syz obj.ipfo_ptr = is;
5447c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING))
545ab25eeb5Syz 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
readnat(fd,file)5637c478bd9Sstevel@tonic-gate int readnat(fd, file)
5647c478bd9Sstevel@tonic-gate int fd;
5657c478bd9Sstevel@tonic-gate char *file;
5667c478bd9Sstevel@tonic-gate {
567ab25eeb5Syz nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL;
568ab25eeb5Syz ipfobj_t obj;
5697c478bd9Sstevel@tonic-gate int nfd, i;
5707c478bd9Sstevel@tonic-gate nat_t *nat;
571ab25eeb5Syz char *s;
572ab25eeb5Syz 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)) {
604ab25eeb5Syz fprintf(stderr, "nat:incomplete read: %d != %d\n",
605ab25eeb5Syz i, (int)sizeof(ipn));
6067c478bd9Sstevel@tonic-gate close(nfd);
6077c478bd9Sstevel@tonic-gate return 1;
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate
610ab25eeb5Syz in = (nat_save_t *)malloc(ipn.ipn_dsize);
611ab25eeb5Syz if (!in)
612ab25eeb5Syz break;
6137c478bd9Sstevel@tonic-gate
614ab25eeb5Syz if (ipn.ipn_dsize > sizeof(ipn)) {
615ab25eeb5Syz n = ipn.ipn_dsize - sizeof(ipn);
616ab25eeb5Syz if (n > 0) {
617ab25eeb5Syz s = in->ipn_data + sizeof(in->ipn_data);
618ab25eeb5Syz i = read(nfd, s, n);
619ab25eeb5Syz if (i == 0)
620ab25eeb5Syz break;
621ab25eeb5Syz if (i != n) {
622ab25eeb5Syz fprintf(stderr,
623ab25eeb5Syz "nat:incomplete read: %d != %d\n",
624ab25eeb5Syz i, n);
625ab25eeb5Syz close(nfd);
626ab25eeb5Syz return 1;
627ab25eeb5Syz }
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate }
630ab25eeb5Syz bcopy((char *)&ipn, (char *)in, sizeof(ipn));
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate /*
633ab25eeb5Syz * 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);
663ab25eeb5Syz nfd = -1;
664ab25eeb5Syz
665ab25eeb5Syz obj.ipfo_rev = IPFILTER_VERSION;
666ab25eeb5Syz 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 }
676ab25eeb5Syz
677ab25eeb5Syz obj.ipfo_ptr = in;
678ab25eeb5Syz obj.ipfo_size = in->ipn_dsize;
6797c478bd9Sstevel@tonic-gate if (!(opts & OPT_DONOTHING))
680ab25eeb5Syz if (ioctl(fd, SIOCSTPUT, &obj)) {
681ab25eeb5Syz 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
writenat(fd,file)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;
704ab25eeb5Syz 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
718ab25eeb5Syz obj.ipfo_rev = IPFILTER_VERSION;
719ab25eeb5Syz 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);
751ab25eeb5Syz obj.ipfo_size = ng.ng_sz;
752ab25eeb5Syz obj.ipfo_ptr = ipnp;
753ab25eeb5Syz ipnp->ipn_dsize = ng.ng_sz;
7547c478bd9Sstevel@tonic-gate ipnp->ipn_next = next;
755ab25eeb5Syz 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)
765ab25eeb5Syz printf("Got nat next %p ipn_dsize %d ng_sz %d\n",
766ab25eeb5Syz ipnp->ipn_next, ipnp->ipn_dsize, ng.ng_sz);
767ab25eeb5Syz 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
writeall(dirname)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)) {
792ab25eeb5Syz 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
readall(dirname)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