summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/ipf.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ipfilter/ipf.c')
-rw-r--r--contrib/ipfilter/ipf.c764
1 files changed, 0 insertions, 764 deletions
diff --git a/contrib/ipfilter/ipf.c b/contrib/ipfilter/ipf.c
deleted file mode 100644
index cf85280..0000000
--- a/contrib/ipfilter/ipf.c
+++ /dev/null
@@ -1,764 +0,0 @@
-/*
- * Copyright (C) 1993-2001 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
-#if defined(__sgi) && (IRIX > 602)
-# include <sys/ptimers.h>
-#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 "ip_compat.h"
-#include "ip_fil.h"
-#include "ip_nat.h"
-#include "ip_state.h"
-#include "ipf.h"
-#include "ipl.h"
-
-#if !defined(lint)
-static const char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$Id: ipf.c,v 2.10.2.23 2003/06/27 14:39:13 darrenr Exp $";
-#endif
-
-#if SOLARIS
-static void blockunknown __P((void));
-#endif
-#if !defined(__SVR4) && defined(__GNUC__)
-extern char *index __P((const char *, int));
-#endif
-
-extern char *optarg;
-extern int optind;
-
-void frsync __P((void));
-void zerostats __P((void));
-int main __P((int, char *[]));
-
-int opts = 0;
-int use_inet6 = 0;
-
-static int fd = -1;
-
-static void procfile __P((char *, char *)), flushfilter __P((char *));
-static int set_state __P((u_int));
-static void showstats __P((friostat_t *));
-static void packetlogon __P((char *)), swapactive __P((void));
-static int opendevice __P((char *));
-static void closedevice __P((void));
-static char *getline __P((char *, size_t, FILE *, int *));
-static char *ipfname = IPL_NAME;
-static void usage __P((char *));
-static int showversion __P((void));
-static int get_flags __P((int *));
-
-
-#if SOLARIS
-# define OPTS "6AdDEf:F:Il:noPrsUvVyzZ"
-#else
-# define OPTS "6AdDEf:F:Il:noPrsvVyzZ"
-#endif
-
-static void usage(name)
-char *name;
-{
- fprintf(stderr, "usage: %s [-%s] %s %s %s\n", name, OPTS,
- "[-l block|pass|nomatch]", "[-F i|o|a|s|S]", "[-f filename]");
- exit(1);
-}
-
-
-int main(argc,argv)
-int argc;
-char *argv[];
-{
- int c;
-
- if (argc < 2)
- usage(argv[0]);
-
- while ((c = getopt(argc, argv, OPTS)) != -1) {
- switch (c)
- {
- case '6' :
- use_inet6 = 1;
- break;
- case 'A' :
- opts &= ~OPT_INACTIVE;
- break;
- case 'E' :
- if (set_state((u_int)1))
- exit(1);
- break;
- case 'D' :
- if (set_state((u_int)0))
- exit(1);
- break;
- case 'd' :
- opts |= OPT_DEBUG;
- break;
- case 'f' :
- procfile(argv[0], optarg);
- break;
- case 'F' :
- flushfilter(optarg);
- break;
- case 'I' :
- opts |= OPT_INACTIVE;
- break;
- case 'l' :
- packetlogon(optarg);
- break;
- case 'n' :
- opts |= OPT_DONOTHING;
- break;
- case 'o' :
- break;
- case 'P' :
- ipfname = IPL_AUTH;
- break;
- case 'r' :
- opts |= OPT_REMOVE;
- break;
- case 's' :
- swapactive();
- break;
-#if SOLARIS
- case 'U' :
- blockunknown();
- break;
-#endif
- case 'v' :
- opts += OPT_VERBOSE;
- break;
- case 'V' :
- if (showversion())
- exit(1);
- break;
- case 'y' :
- frsync();
- break;
- case 'z' :
- opts |= OPT_ZERORULEST;
- break;
- case 'Z' :
- zerostats();
- break;
- case '?' :
- default :
- usage(argv[0]);
- break;
- }
- }
-
- if (optind < 2)
- usage(argv[0]);
-
- if (fd != -1)
- (void) close(fd);
-
- exit(0);
- /* NOTREACHED */
-}
-
-
-static int opendevice(ipfdev)
-char *ipfdev;
-{
- if (opts & OPT_DONOTHING)
- return 0;
-
- if (!ipfdev)
- ipfdev = ipfname;
-
- /*
- * shouldn't we really be testing for fd < 0 here and below?
- */
-
- if (fd != -1)
- return 0;
-
- if ((fd = open(ipfdev, O_RDWR)) == -1) {
- if ((fd = open(ipfdev, O_RDONLY)) == -1) {
- perror("open device");
- if (errno == ENODEV)
- fprintf(stderr, "IPFilter enabled?\n");
- return -1;
- }
- }
-
- return 0;
-}
-
-
-static void closedevice()
-{
- if (fd != -1)
- close(fd);
- fd = -1;
-}
-
-
-/*
- * Return codes:
- * 0 Success
- * !0 Failure (and an error message has already been printed)
- */
-static int get_flags(i)
-int *i;
-{
-
- if (opts & OPT_DONOTHING)
- return 0;
-
- if (opendevice(ipfname) < 0)
- return -1;
-
- if (ioctl(fd, SIOCGETFF, i) == -1) {
- perror("SIOCGETFF");
- return -1;
- }
- return 0;
-}
-
-
-static int set_state(enable)
-u_int enable;
-{
- if (opts & OPT_DONOTHING)
- return 0;
-
- if (opendevice(ipfname))
- return -1;
-
- if (ioctl(fd, SIOCFRENB, &enable) == -1) {
- if (errno == EBUSY)
- /* Not really an error */
- fprintf(stderr,
- "IP Filter: already initialized\n");
- else {
- perror("SIOCFRENB");
- return -1;
- }
- }
- return 0;
-}
-
-static void procfile(name, file)
-char *name, *file;
-{
- FILE *fp;
- char line[513], *s;
- struct frentry *fr;
- u_int add, del;
- int linenum = 0;
- int parsestatus;
-
- if (opendevice(ipfname) == -1)
- exit(1);
-
- if (opts & OPT_INACTIVE) {
- add = SIOCADIFR;
- del = SIOCRMIFR;
- } else {
- add = SIOCADAFR;
- del = SIOCRMAFR;
- }
- if (opts & OPT_DEBUG)
- printf("add %x del %x\n", add, del);
-
- initparse();
-
- if (!strcmp(file, "-"))
- fp = stdin;
- else if (!(fp = fopen(file, "r"))) {
- fprintf(stderr, "%s: fopen(%s) failed: %s\n", name, file,
- STRERROR(errno));
- exit(1);
- }
-
- while (getline(line, sizeof(line), fp, &linenum)) {
- /*
- * treat CR as EOL. LF is converted to NUL by getline().
- */
- if ((s = index(line, '\r')))
- *s = '\0';
- /*
- * # is comment marker, everything after is a ignored
- */
- if ((s = index(line, '#')))
- *s = '\0';
-
- if (!*line)
- continue;
-
- if (opts & OPT_VERBOSE)
- (void)fprintf(stderr, "[%s]\n", line);
-
- parsestatus = 1;
- fr = parse(line, linenum, &parsestatus);
- (void)fflush(stdout);
-
- if (parsestatus != 0) {
- fprintf(stderr, "%s: %s: %s error (%d), quitting\n",
- name, file,
- ((parsestatus < 0)? "parse": "internal"),
- parsestatus);
- exit(1);
- }
-
- if (fr) {
- if (opts & OPT_ZERORULEST)
- add = SIOCZRLST;
- else if (opts & OPT_INACTIVE)
- add = (u_int)fr->fr_hits ? SIOCINIFR :
- SIOCADIFR;
- else
- add = (u_int)fr->fr_hits ? SIOCINAFR :
- SIOCADAFR;
- if (fr->fr_hits)
- fr->fr_hits--;
- if (fr && (opts & OPT_VERBOSE))
- printfr(fr);
- if (fr && (opts & OPT_OUTQUE))
- fr->fr_flags |= FR_OUTQUE;
-
- if (opts & OPT_DEBUG)
- binprint(fr);
-
- if ((opts & OPT_ZERORULEST) &&
- !(opts & OPT_DONOTHING)) {
- if (ioctl(fd, add, &fr) == -1) {
- fprintf(stderr, "%d:", linenum);
- perror("ioctl(SIOCZRLST)");
- exit(1);
- } else {
-#ifdef USE_QUAD_T
- printf("hits %qd bytes %qd ",
- (long long)fr->fr_hits,
- (long long)fr->fr_bytes);
-#else
- printf("hits %ld bytes %ld ",
- fr->fr_hits, fr->fr_bytes);
-#endif
- printfr(fr);
- }
- } else if ((opts & OPT_REMOVE) &&
- !(opts & OPT_DONOTHING)) {
- if (ioctl(fd, del, &fr) == -1) {
- fprintf(stderr, "%d:", linenum);
- perror("ioctl(delete rule)");
- exit(1);
- }
- } else if (!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, add, &fr) == -1) {
- fprintf(stderr, "%d:", linenum);
- perror("ioctl(add/insert rule)");
- exit(1);
- }
- }
- }
- }
- if (ferror(fp) || !feof(fp)) {
- fprintf(stderr, "%s: %s: file error or line too long\n",
- name, file);
- exit(1);
- }
- (void)fclose(fp);
-}
-
-/*
- * Similar to fgets(3) but can handle '\\' and NL is converted to NUL.
- * Returns NULL if error occurred, EOF encounterd or input line is too long.
- */
-static char *getline(str, size, file, linenum)
-register char *str;
-size_t size;
-FILE *file;
-int *linenum;
-{
- char *p;
- int s, len;
-
- do {
- for (p = str, s = size;; p += (len - 1), s -= (len - 1)) {
- /*
- * if an error occurred, EOF was encounterd, or there
- * was no room to put NUL, return NULL.
- */
- if (fgets(p, s, file) == NULL)
- return (NULL);
- len = strlen(p);
- if (p[len - 1] != '\n') {
- p[len] = '\0';
- break;
- }
- (*linenum)++;
- p[len - 1] = '\0';
- if (len < 2 || p[len - 2] != '\\')
- break;
- else
- /*
- * Convert '\\' to a space so words don't
- * run together
- */
- p[len - 2] = ' ';
- }
- } while (*str == '\0');
- return (str);
-}
-
-
-static void packetlogon(opt)
-char *opt;
-{
- int flag;
-
- if (get_flags(&flag))
- exit(1);
-
- if (flag != 0) {
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
- printf("log flag is currently %#x\n", flag);
- }
-
- flag &= ~(FF_LOGPASS|FF_LOGNOMATCH|FF_LOGBLOCK);
-
- if (index(opt, 'p')) {
- flag |= FF_LOGPASS;
- if (opts & OPT_VERBOSE)
- printf("set log flag: pass\n");
- }
- if (index(opt, 'm') && (*opt == 'n' || *opt == 'N')) {
- flag |= FF_LOGNOMATCH;
- if (opts & OPT_VERBOSE)
- printf("set log flag: nomatch\n");
- }
- if (index(opt, 'b') || index(opt, 'd')) {
- flag |= FF_LOGBLOCK;
- if (opts & OPT_VERBOSE)
- printf("set log flag: block\n");
- }
-
- if (opendevice(ipfname) == -1) {
- exit(1);
- }
-
- if (!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, SIOCSETFF, &flag) != 0) {
- perror("ioctl(SIOCSETFF)");
- exit(1);
- }
- }
-
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
- /*
- * Even though the ioctls above succeeded, it
- * is possible that a calling script/program
- * relies on the following verbose mode string.
- * Thus, we still take an error exit if get_flags
- * fails here.
- */
- if (get_flags(&flag))
- exit(1);
- printf("log flag is now %#x\n", flag);
- }
-}
-
-
-static void flushfilter(arg)
-char *arg;
-{
- int fl = 0, rem;
-
- if (!arg || !*arg) {
- fprintf(stderr, "-F: no filter specified\n");
- exit(1);
- }
-
- if (!strcmp(arg, "s") || !strcmp(arg, "S")) {
- if (*arg == 'S')
- fl = 0;
- else
- fl = 1;
- rem = fl;
-
- closedevice();
-
- if (opendevice(IPL_STATE) == -1) {
- exit(1);
- }
-
- if (!(opts & OPT_DONOTHING)) {
- if (use_inet6) {
- if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
- perror("ioctl(SIOCIPFL6)");
- exit(1);
- }
- } else {
- if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
- perror("ioctl(SIOCIPFFL)");
- exit(1);
- }
- }
- }
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
- printf("remove flags %s (%d)\n", arg, rem);
- printf("removed %d filter rules\n", fl);
- }
- closedevice();
- return;
- }
- if (strchr(arg, 'i') || strchr(arg, 'I'))
- fl = FR_INQUE;
- if (strchr(arg, 'o') || strchr(arg, 'O'))
- fl = FR_OUTQUE;
- if (strchr(arg, 'a') || strchr(arg, 'A'))
- fl = FR_OUTQUE|FR_INQUE;
- fl |= (opts & FR_INACTIVE);
- rem = fl;
-
- if (opendevice(ipfname) == -1) {
- exit(1);
- }
-
- if (!(opts & OPT_DONOTHING)) {
- if (use_inet6) {
- if (ioctl(fd, SIOCIPFL6, &fl) == -1) {
- perror("ioctl(SIOCIPFL6)");
- exit(1);
- }
- } else {
- if (ioctl(fd, SIOCIPFFL, &fl) == -1) {
- perror("ioctl(SIOCIPFFL)");
- exit(1);
- }
- }
- }
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
- printf("remove flags %s%s (%d)\n", (rem & FR_INQUE) ? "I" : "",
- (rem & FR_OUTQUE) ? "O" : "", rem);
- printf("removed %d filter rules\n", fl);
- }
- return;
-}
-
-
-static void swapactive()
-{
- int in = 2;
-
- if (opendevice(ipfname) == -1) {
- exit(1);
- }
-
-
- if (!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, SIOCSWAPA, &in) == -1) {
- perror("ioctl(SIOCSWAPA)");
- exit(1);
- }
- }
- printf("Set %d now inactive\n", in);
-}
-
-
-void frsync()
-{
- int frsyn = 0;
-
- if (opendevice(ipfname) == -1)
- exit(1);
-
- if (!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, SIOCFRSYN, &frsyn) == -1) {
- perror("SIOCFRSYN");
- exit(1);
- }
- }
- printf("filter sync'd\n");
-}
-
-
-void zerostats()
-{
- friostat_t fio;
- friostat_t *fiop = &fio;
-
- if (opendevice(ipfname) == -1)
- exit(1);
-
- if (!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, SIOCFRZST, &fiop) == -1) {
- perror("ioctl(SIOCFRZST)");
- exit(-1);
- }
- showstats(fiop);
- }
-
-}
-
-
-/*
- * Read the kernel stats for packets blocked and passed
- */
-static void showstats(fp)
-friostat_t *fp;
-{
-#if SOLARIS
- printf("dropped packets:\tin %lu\tout %lu\n",
- fp->f_st[0].fr_drop, fp->f_st[1].fr_drop);
- printf("non-ip packets:\t\tin %lu\tout %lu\n",
- fp->f_st[0].fr_notip, fp->f_st[1].fr_notip);
- printf(" bad packets:\t\tin %lu\tout %lu\n",
- fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
-#endif
- printf(" input packets:\t\tblocked %lu passed %lu nomatch %lu",
- fp->f_st[0].fr_block, fp->f_st[0].fr_pass,
- fp->f_st[0].fr_nom);
- printf(" counted %lu\n", fp->f_st[0].fr_acct);
- printf("output packets:\t\tblocked %lu passed %lu nomatch %lu",
- fp->f_st[1].fr_block, fp->f_st[1].fr_pass,
- fp->f_st[1].fr_nom);
- printf(" counted %lu\n", fp->f_st[0].fr_acct);
- printf(" input packets logged:\tblocked %lu passed %lu\n",
- fp->f_st[0].fr_bpkl, fp->f_st[0].fr_ppkl);
- printf("output packets logged:\tblocked %lu passed %lu\n",
- fp->f_st[1].fr_bpkl, fp->f_st[1].fr_ppkl);
- printf(" packets logged:\tinput %lu-%lu output %lu-%lu\n",
- fp->f_st[0].fr_pkl, fp->f_st[0].fr_skip,
- fp->f_st[1].fr_pkl, fp->f_st[1].fr_skip);
-}
-
-
-#if SOLARIS
-static void blockunknown()
-{
- int flag;
-
- if (opendevice(ipfname) == -1)
- exit(1);
-
- if (get_flags(&flag))
- exit(1);
-
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE)
- printf("log flag is currently %#x\n", flag);
-
- flag ^= FF_BLOCKNONIP;
-
- if (opendevice(ipfname) == -1)
- exit(1);
-
- if (!(opts & OPT_DONOTHING)) {
- if (ioctl(fd, SIOCSETFF, &flag))
- perror("ioctl(SIOCSETFF)");
- }
-
- if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
- if (ioctl(fd, SIOCGETFF, &flag))
- perror("ioctl(SIOCGETFF)");
-
- printf("log flag is now %#x\n", flag);
- }
-}
-#endif
-
-
-/*
- * nonzero return value means caller should exit with error
- */
-static int showversion()
-{
- struct friostat fio;
- struct friostat *fiop=&fio;
- int flags, vfd;
- char *s;
-
- printf("ipf: %s (%d)\n", IPL_VERSION, (int)sizeof(frentry_t));
-
- if ((vfd = open(ipfname, O_RDONLY)) == -1) {
- perror("open device");
- return 1;
- }
-
- if (ioctl(vfd, SIOCGETFS, &fiop)) {
- perror("ioctl(SIOCGETFS)");
- close(vfd);
- return 1;
- }
- close(vfd);
-
- printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),
- (int)sizeof(fio.f_version), fio.f_version);
- printf("Running: %s\n", fio.f_running ? "yes" : "no");
-
- if (get_flags(&flags)) {
- return 1;
- }
- printf("Log Flags: %#x = ", flags);
- s = "";
- if (flags & FF_LOGPASS) {
- printf("pass");
- s = ", ";
- }
- if (flags & FF_LOGBLOCK) {
- printf("%sblock", s);
- s = ", ";
- }
- if (flags & FF_LOGNOMATCH) {
- printf("%snomatch", s);
- s = ", ";
- }
- if (flags & FF_BLOCKNONIP) {
- printf("%snonip", s);
- s = ", ";
- }
- if (!*s)
- printf("none set");
- putchar('\n');
-
- printf("Default: ");
- if (fio.f_defpass & FR_PASS)
- s = "pass";
- else if (fio.f_defpass & FR_BLOCK)
- s = "block";
- else
- s = "nomatch -> block";
- printf("%s all, Logging: %savailable\n", s, fio.f_logging ? "" : "un");
- printf("Active list: %d\n", fio.f_active);
-
- return 0;
-}
OpenPOWER on IntegriCloud