diff options
Diffstat (limited to 'contrib/ipfilter/tools/ipfs.c')
-rw-r--r-- | contrib/ipfilter/tools/ipfs.c | 890 |
1 files changed, 0 insertions, 890 deletions
diff --git a/contrib/ipfilter/tools/ipfs.c b/contrib/ipfilter/tools/ipfs.c deleted file mode 100644 index 3acb5d4..0000000 --- a/contrib/ipfilter/tools/ipfs.c +++ /dev/null @@ -1,890 +0,0 @@ -/* - * Copyright (C) 2001-2006 by Darren Reed. - * - * See the IPFILTER.LICENCE file for details on licencing. - */ -#ifdef __FreeBSD__ -# ifndef __FreeBSD_cc_version -# include <osreldate.h> -# else -# if __FreeBSD_cc_version < 430000 -# include <osreldate.h> -# endif -# endif -#endif -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#if !defined(__SVR4) && !defined(__GNUC__) -#include <strings.h> -#endif -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> -#include <stdlib.h> -#include <stddef.h> -#include <sys/socket.h> -#include <sys/ioctl.h> -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <sys/time.h> -#include <net/if.h> -#if __FreeBSD_version >= 300000 -# include <net/if_var.h> -#endif -#include <netinet/ip.h> -#include <netdb.h> -#include <arpa/nameser.h> -#include <resolv.h> -#include "ipf.h" -#include "netinet/ipl.h" - -#if !defined(lint) -static const char rcsid[] = "@(#)Id: ipfs.c,v 1.12 2003/12/01 01:56:53 darrenr Exp"; -#endif - -#ifndef IPF_SAVEDIR -# define IPF_SAVEDIR "/var/db/ipf" -#endif -#ifndef IPF_NATFILE -# define IPF_NATFILE "ipnat.ipf" -#endif -#ifndef IPF_STATEFILE -# define IPF_STATEFILE "ipstate.ipf" -#endif - -#if !defined(__SVR4) && defined(__GNUC__) -extern char *index __P((const char *, int)); -#endif - -extern char *optarg; -extern int optind; - -int main __P((int, char *[])); -void usage __P((void)); -int changestateif __P((char *, char *)); -int changenatif __P((char *, char *)); -int readstate __P((int, char *)); -int readnat __P((int, char *)); -int writestate __P((int, char *)); -int opendevice __P((char *)); -void closedevice __P((int)); -int setlock __P((int, int)); -int writeall __P((char *)); -int readall __P((char *)); -int writenat __P((int, char *)); - -int opts = 0; -char *progname; - - -void usage() -{ - fprintf(stderr, "usage: %s [-nv] -l\n", progname); - fprintf(stderr, "usage: %s [-nv] -u\n", progname); - fprintf(stderr, "usage: %s [-nv] [-d <dir>] -R\n", progname); - fprintf(stderr, "usage: %s [-nv] [-d <dir>] -W\n", progname); - fprintf(stderr, "usage: %s [-nNSv] [-f <file>] -r\n", progname); - fprintf(stderr, "usage: %s [-nNSv] [-f <file>] -w\n", progname); - fprintf(stderr, "usage: %s [-nNSv] -f <filename> -i <if1>,<if2>\n", - progname); - exit(1); -} - - -/* - * Change interface names in state information saved out to disk. - */ -int changestateif(ifs, fname) -char *ifs, *fname; -{ - int fd, olen, nlen, rw; - ipstate_save_t ips; - off_t pos; - char *s; - - s = strchr(ifs, ','); - if (!s) - usage(); - *s++ = '\0'; - nlen = strlen(s); - olen = strlen(ifs); - if (nlen >= sizeof(ips.ips_is.is_ifname) || - olen >= sizeof(ips.ips_is.is_ifname)) - usage(); - - fd = open(fname, O_RDWR); - if (fd == -1) { - perror("open"); - exit(1); - } - - for (pos = 0; read(fd, &ips, sizeof(ips)) == sizeof(ips); ) { - rw = 0; - if (!strncmp(ips.ips_is.is_ifname[0], ifs, olen + 1)) { - strcpy(ips.ips_is.is_ifname[0], s); - rw = 1; - } - if (!strncmp(ips.ips_is.is_ifname[1], ifs, olen + 1)) { - strcpy(ips.ips_is.is_ifname[1], s); - rw = 1; - } - if (!strncmp(ips.ips_is.is_ifname[2], ifs, olen + 1)) { - strcpy(ips.ips_is.is_ifname[2], s); - rw = 1; - } - if (!strncmp(ips.ips_is.is_ifname[3], ifs, olen + 1)) { - strcpy(ips.ips_is.is_ifname[3], s); - rw = 1; - } - if (rw == 1) { - if (lseek(fd, pos, SEEK_SET) != pos) { - perror("lseek"); - exit(1); - } - if (write(fd, &ips, sizeof(ips)) != sizeof(ips)) { - perror("write"); - exit(1); - } - } - pos = lseek(fd, 0, SEEK_CUR); - } - close(fd); - - return 0; -} - - -/* - * Change interface names in NAT information saved out to disk. - */ -int changenatif(ifs, fname) -char *ifs, *fname; -{ - int fd, olen, nlen, rw; - nat_save_t ipn; - nat_t *nat; - off_t pos; - char *s; - - s = strchr(ifs, ','); - if (!s) - usage(); - *s++ = '\0'; - nlen = strlen(s); - olen = strlen(ifs); - nat = &ipn.ipn_nat; - if (nlen >= sizeof(nat->nat_ifnames[0]) || - olen >= sizeof(nat->nat_ifnames[0])) - usage(); - - fd = open(fname, O_RDWR); - if (fd == -1) { - perror("open"); - exit(1); - } - - for (pos = 0; read(fd, &ipn, sizeof(ipn)) == sizeof(ipn); ) { - rw = 0; - if (!strncmp(nat->nat_ifnames[0], ifs, olen + 1)) { - strcpy(nat->nat_ifnames[0], s); - rw = 1; - } - if (!strncmp(nat->nat_ifnames[1], ifs, olen + 1)) { - strcpy(nat->nat_ifnames[1], s); - rw = 1; - } - if (!strncmp(nat->nat_ifnames[2], ifs, olen + 1)) { - strcpy(nat->nat_ifnames[2], s); - rw = 1; - } - if (!strncmp(nat->nat_ifnames[3], ifs, olen + 1)) { - strcpy(nat->nat_ifnames[3], s); - rw = 1; - } - if (rw == 1) { - if (lseek(fd, pos, SEEK_SET) != pos) { - perror("lseek"); - exit(1); - } - if (write(fd, &ipn, sizeof(ipn)) != sizeof(ipn)) { - perror("write"); - exit(1); - } - } - pos = lseek(fd, 0, SEEK_CUR); - } - close(fd); - - return 0; -} - - -int main(argc,argv) -int argc; -char *argv[]; -{ - int c, lock = -1, devfd = -1, err = 0, rw = -1, ns = -1, set = 0; - char *dirname = NULL, *filename = NULL, *ifs = NULL; - - progname = argv[0]; - while ((c = getopt(argc, argv, "d:f:i:lNnSRruvWw")) != -1) - switch (c) - { - case 'd' : - if ((set == 0) && !dirname && !filename) - dirname = optarg; - else - usage(); - break; - case 'f' : - if ((set != 0) && !dirname && !filename) - filename = optarg; - else - usage(); - break; - case 'i' : - ifs = optarg; - set = 1; - break; - case 'l' : - if (filename || dirname || set) - usage(); - lock = 1; - set = 1; - break; - case 'n' : - opts |= OPT_DONOTHING; - break; - case 'N' : - if ((ns >= 0) || dirname || (rw != -1) || set) - usage(); - ns = 0; - set = 1; - break; - case 'r' : - if (dirname || (rw != -1) || (ns == -1)) - usage(); - rw = 0; - set = 1; - break; - case 'R' : - rw = 2; - set = 1; - break; - case 'S' : - if ((ns >= 0) || dirname || (rw != -1) || set) - usage(); - ns = 1; - set = 1; - break; - case 'u' : - if (filename || dirname || set) - usage(); - lock = 0; - set = 1; - break; - case 'v' : - opts |= OPT_VERBOSE; - break; - case 'w' : - if (dirname || (rw != -1) || (ns == -1)) - usage(); - rw = 1; - set = 1; - break; - case 'W' : - rw = 3; - set = 1; - break; - case '?' : - default : - usage(); - } - - if (ifs) { - if (!filename || ns < 0) - usage(); - if (ns == 0) - return changenatif(ifs, filename); - else - return changestateif(ifs, filename); - } - - if ((ns >= 0) || (lock >= 0)) { - if (lock >= 0) - devfd = opendevice(NULL); - else if (ns >= 0) { - if (ns == 1) - devfd = opendevice(IPSTATE_NAME); - else if (ns == 0) - devfd = opendevice(IPNAT_NAME); - } - if (devfd == -1) - exit(1); - } - - if (lock >= 0) - err = setlock(devfd, lock); - else if (rw >= 0) { - if (rw & 1) { /* WRITE */ - if (rw & 2) - err = writeall(dirname); - else { - if (ns == 0) - err = writenat(devfd, filename); - else if (ns == 1) - err = writestate(devfd, filename); - } - } else { - if (rw & 2) - err = readall(dirname); - else { - if (ns == 0) - err = readnat(devfd, filename); - else if (ns == 1) - err = readstate(devfd, filename); - } - } - } - return err; -} - - -int opendevice(ipfdev) -char *ipfdev; -{ - int fd = -1; - - if (opts & OPT_DONOTHING) - return -2; - - if (!ipfdev) - ipfdev = IPL_NAME; - - if ((fd = open(ipfdev, O_RDWR)) == -1) - if ((fd = open(ipfdev, O_RDONLY)) == -1) - perror("open device"); - return fd; -} - - -void closedevice(fd) -int fd; -{ - close(fd); -} - - -int setlock(fd, lock) -int fd, lock; -{ - if (opts & OPT_VERBOSE) - printf("Turn lock %s\n", lock ? "on" : "off"); - if (!(opts & OPT_DONOTHING)) { - if (ioctl(fd, SIOCSTLCK, &lock) == -1) { - perror("SIOCSTLCK"); - return 1; - } - if (opts & OPT_VERBOSE) - printf("Lock now %s\n", lock ? "on" : "off"); - } - return 0; -} - - -int writestate(fd, file) -int fd; -char *file; -{ - ipstate_save_t ips, *ipsp; - ipfobj_t obj; - int wfd = -1; - - if (!file) - file = IPF_STATEFILE; - - wfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); - if (wfd == -1) { - fprintf(stderr, "%s ", file); - perror("state:open"); - return 1; - } - - ipsp = &ips; - bzero((char *)&obj, sizeof(obj)); - bzero((char *)ipsp, sizeof(ips)); - - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_size = sizeof(*ipsp); - obj.ipfo_type = IPFOBJ_STATESAVE; - obj.ipfo_ptr = ipsp; - - do { - - if (opts & OPT_VERBOSE) - printf("Getting state from addr %p\n", ips.ips_next); - if (ioctl(fd, SIOCSTGET, &obj)) { - if (errno == ENOENT) - break; - perror("state:SIOCSTGET"); - close(wfd); - return 1; - } - if (opts & OPT_VERBOSE) - printf("Got state next %p\n", ips.ips_next); - if (write(wfd, ipsp, sizeof(ips)) != sizeof(ips)) { - perror("state:write"); - close(wfd); - return 1; - } - } while (ips.ips_next != NULL); - close(wfd); - - return 0; -} - - -int readstate(fd, file) -int fd; -char *file; -{ - ipstate_save_t ips, *is, *ipshead = NULL, *is1, *ipstail = NULL; - int sfd = -1, i; - ipfobj_t obj; - - if (!file) - file = IPF_STATEFILE; - - sfd = open(file, O_RDONLY, 0600); - if (sfd == -1) { - fprintf(stderr, "%s ", file); - perror("open"); - return 1; - } - - bzero((char *)&ips, sizeof(ips)); - - /* - * 1. Read all state information in. - */ - do { - i = read(sfd, &ips, sizeof(ips)); - if (i == -1) { - perror("read"); - goto freeipshead; - } - if (i == 0) - break; - if (i != sizeof(ips)) { - fprintf(stderr, "state:incomplete read: %d != %d\n", - i, (int)sizeof(ips)); - goto freeipshead; - } - is = (ipstate_save_t *)malloc(sizeof(*is)); - if (is == NULL) { - fprintf(stderr, "malloc failed\n"); - goto freeipshead; - } - - bcopy((char *)&ips, (char *)is, sizeof(ips)); - - /* - * Check to see if this is the first state entry that will - * reference a particular rule and if so, flag it as such - * else just adjust the rule pointer to become a pointer to - * the other. We do this so we have a means later for tracking - * who is referencing us when we get back the real pointer - * in is_rule after doing the ioctl. - */ - for (is1 = ipshead; is1 != NULL; is1 = is1->ips_next) - if (is1->ips_rule == is->ips_rule) - break; - if (is1 == NULL) - is->ips_is.is_flags |= SI_NEWFR; - else - is->ips_rule = (void *)&is1->ips_rule; - - /* - * Use a tail-queue type list (add things to the end).. - */ - is->ips_next = NULL; - if (!ipshead) - ipshead = is; - if (ipstail) - ipstail->ips_next = is; - ipstail = is; - } while (1); - - close(sfd); - - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_size = sizeof(*is); - obj.ipfo_type = IPFOBJ_STATESAVE; - - while ((is = ipshead) != NULL) { - if (opts & OPT_VERBOSE) - printf("Loading new state table entry\n"); - if (is->ips_is.is_flags & SI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Loading new filter rule\n"); - } - - obj.ipfo_ptr = is; - if (!(opts & OPT_DONOTHING)) - if (ioctl(fd, SIOCSTPUT, &obj)) { - perror("SIOCSTPUT"); - goto freeipshead; - } - - if (is->ips_is.is_flags & SI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Real rule addr %p\n", is->ips_rule); - for (is1 = is->ips_next; is1; is1 = is1->ips_next) - if (is1->ips_rule == (frentry_t *)&is->ips_rule) - is1->ips_rule = is->ips_rule; - } - - ipshead = is->ips_next; - free(is); - } - - return 0; - -freeipshead: - while ((is = ipshead) != NULL) { - ipshead = is->ips_next; - free(is); - } - if (sfd != -1) - close(sfd); - return 1; -} - - -int readnat(fd, file) -int fd; -char *file; -{ - nat_save_t ipn, *in, *ipnhead = NULL, *in1, *ipntail = NULL; - ipfobj_t obj; - int nfd, i; - nat_t *nat; - char *s; - int n; - - nfd = -1; - in = NULL; - ipnhead = NULL; - ipntail = NULL; - - if (!file) - file = IPF_NATFILE; - - nfd = open(file, O_RDONLY); - if (nfd == -1) { - fprintf(stderr, "%s ", file); - perror("nat:open"); - return 1; - } - - bzero((char *)&ipn, sizeof(ipn)); - - /* - * 1. Read all state information in. - */ - do { - i = read(nfd, &ipn, sizeof(ipn)); - if (i == -1) { - perror("read"); - goto freenathead; - } - if (i == 0) - break; - if (i != sizeof(ipn)) { - fprintf(stderr, "nat:incomplete read: %d != %d\n", - i, (int)sizeof(ipn)); - goto freenathead; - } - - in = (nat_save_t *)malloc(ipn.ipn_dsize); - if (in == NULL) { - fprintf(stderr, "nat:cannot malloc nat save atruct\n"); - goto freenathead; - } - - if (ipn.ipn_dsize > sizeof(ipn)) { - n = ipn.ipn_dsize - sizeof(ipn); - if (n > 0) { - s = in->ipn_data + sizeof(in->ipn_data); - i = read(nfd, s, n); - if (i == 0) - break; - if (i != n) { - fprintf(stderr, - "nat:incomplete read: %d != %d\n", - i, n); - goto freenathead; - } - } - } - bcopy((char *)&ipn, (char *)in, sizeof(ipn)); - - /* - * Check to see if this is the first NAT entry that will - * reference a particular rule and if so, flag it as such - * else just adjust the rule pointer to become a pointer to - * the other. We do this so we have a means later for tracking - * who is referencing us when we get back the real pointer - * in is_rule after doing the ioctl. - */ - nat = &in->ipn_nat; - if (nat->nat_fr != NULL) { - for (in1 = ipnhead; in1 != NULL; in1 = in1->ipn_next) - if (in1->ipn_rule == nat->nat_fr) - break; - if (in1 == NULL) - nat->nat_flags |= SI_NEWFR; - else - nat->nat_fr = &in1->ipn_fr; - } - - /* - * Use a tail-queue type list (add things to the end).. - */ - in->ipn_next = NULL; - if (!ipnhead) - ipnhead = in; - if (ipntail) - ipntail->ipn_next = in; - ipntail = in; - } while (1); - - close(nfd); - nfd = -1; - - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_type = IPFOBJ_NATSAVE; - - while ((in = ipnhead) != NULL) { - if (opts & OPT_VERBOSE) - printf("Loading new NAT table entry\n"); - nat = &in->ipn_nat; - if (nat->nat_flags & SI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Loading new filter rule\n"); - } - - obj.ipfo_ptr = in; - obj.ipfo_size = in->ipn_dsize; - if (!(opts & OPT_DONOTHING)) - if (ioctl(fd, SIOCSTPUT, &obj)) { - fprintf(stderr, "in=%p:", in); - perror("SIOCSTPUT"); - return 1; - } - - if (nat->nat_flags & SI_NEWFR) { - if (opts & OPT_VERBOSE) - printf("Real rule addr %p\n", nat->nat_fr); - for (in1 = in->ipn_next; in1; in1 = in1->ipn_next) - if (in1->ipn_rule == &in->ipn_fr) - in1->ipn_rule = nat->nat_fr; - } - - ipnhead = in->ipn_next; - free(in); - } - - return 0; - -freenathead: - while ((in = ipnhead) != NULL) { - ipnhead = in->ipn_next; - free(in); - } - if (nfd != -1) - close(nfd); - return 1; -} - - -int writenat(fd, file) -int fd; -char *file; -{ - nat_save_t *ipnp = NULL, *next = NULL; - ipfobj_t obj; - int nfd = -1; - natget_t ng; - - if (!file) - file = IPF_NATFILE; - - nfd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0600); - if (nfd == -1) { - fprintf(stderr, "%s ", file); - perror("nat:open"); - return 1; - } - - obj.ipfo_rev = IPFILTER_VERSION; - obj.ipfo_type = IPFOBJ_NATSAVE; - - do { - if (opts & OPT_VERBOSE) - printf("Getting nat from addr %p\n", ipnp); - ng.ng_ptr = next; - ng.ng_sz = 0; - if (ioctl(fd, SIOCSTGSZ, &ng)) { - perror("nat:SIOCSTGSZ"); - close(nfd); - if (ipnp != NULL) - free(ipnp); - return 1; - } - - if (opts & OPT_VERBOSE) - printf("NAT size %d from %p\n", ng.ng_sz, ng.ng_ptr); - - if (ng.ng_sz == 0) - break; - - if (!ipnp) - ipnp = malloc(ng.ng_sz); - else - ipnp = realloc((char *)ipnp, ng.ng_sz); - if (!ipnp) { - fprintf(stderr, - "malloc for %d bytes failed\n", ng.ng_sz); - break; - } - - bzero((char *)ipnp, ng.ng_sz); - obj.ipfo_size = ng.ng_sz; - obj.ipfo_ptr = ipnp; - ipnp->ipn_dsize = ng.ng_sz; - ipnp->ipn_next = next; - if (ioctl(fd, SIOCSTGET, &obj)) { - if (errno == ENOENT) - break; - perror("nat:SIOCSTGET"); - close(nfd); - free(ipnp); - return 1; - } - - if (opts & OPT_VERBOSE) - printf("Got nat next %p ipn_dsize %d ng_sz %d\n", - ipnp->ipn_next, ipnp->ipn_dsize, ng.ng_sz); - if (write(nfd, ipnp, ipnp->ipn_dsize) != ipnp->ipn_dsize) { - perror("nat:write"); - close(nfd); - free(ipnp); - return 1; - } - next = ipnp->ipn_next; - } while (ipnp && next); - if (ipnp != NULL) - free(ipnp); - close(nfd); - - return 0; -} - - -int writeall(dirname) -char *dirname; -{ - int fd, devfd; - - if (!dirname) - dirname = IPF_SAVEDIR; - - if (chdir(dirname)) { - fprintf(stderr, "IPF_SAVEDIR=%s: ", dirname); - perror("chdir(IPF_SAVEDIR)"); - return 1; - } - - fd = opendevice(NULL); - if (fd == -1) - return 1; - if (setlock(fd, 1)) { - close(fd); - return 1; - } - - devfd = opendevice(IPSTATE_NAME); - if (devfd == -1) - goto bad; - if (writestate(devfd, NULL)) - goto bad; - close(devfd); - - devfd = opendevice(IPNAT_NAME); - if (devfd == -1) - goto bad; - if (writenat(devfd, NULL)) - goto bad; - close(devfd); - - if (setlock(fd, 0)) { - close(fd); - return 1; - } - - close(fd); - return 0; - -bad: - setlock(fd, 0); - close(fd); - return 1; -} - - -int readall(dirname) -char *dirname; -{ - int fd, devfd; - - if (!dirname) - dirname = IPF_SAVEDIR; - - if (chdir(dirname)) { - perror("chdir(IPF_SAVEDIR)"); - return 1; - } - - fd = opendevice(NULL); - if (fd == -1) - return 1; - if (setlock(fd, 1)) { - close(fd); - return 1; - } - - devfd = opendevice(IPSTATE_NAME); - if (devfd == -1) - return 1; - if (readstate(devfd, NULL)) - return 1; - close(devfd); - - devfd = opendevice(IPNAT_NAME); - if (devfd == -1) - return 1; - if (readnat(devfd, NULL)) - return 1; - close(devfd); - - if (setlock(fd, 0)) { - close(fd); - return 1; - } - - return 0; -} |