summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/tools/ipf.c
diff options
context:
space:
mode:
authordarrenr <darrenr@FreeBSD.org>2005-04-25 17:31:50 +0000
committerdarrenr <darrenr@FreeBSD.org>2005-04-25 17:31:50 +0000
commitd438802dcb3e270d6fcc65f075c808c64853a7c2 (patch)
treee2e1c7115044e6dfc86ff65598566fa32e5f7421 /contrib/ipfilter/tools/ipf.c
parent590450fec65a8e72a8965117398bc8f14938b4a8 (diff)
downloadFreeBSD-src-d438802dcb3e270d6fcc65f075c808c64853a7c2.zip
FreeBSD-src-d438802dcb3e270d6fcc65f075c808c64853a7c2.tar.gz
import ipfilter 4.1.8 into the vendor branch
Diffstat (limited to 'contrib/ipfilter/tools/ipf.c')
-rw-r--r--contrib/ipfilter/tools/ipf.c562
1 files changed, 562 insertions, 0 deletions
diff --git a/contrib/ipfilter/tools/ipf.c b/contrib/ipfilter/tools/ipf.c
new file mode 100644
index 0000000..ea39780
--- /dev/null
+++ b/contrib/ipfilter/tools/ipf.c
@@ -0,0 +1,562 @@
+/* $NetBSD$ */
+
+/*
+ * 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
+#include "ipf.h"
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "netinet/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 1.35.2.3 2004/12/15 18:27:17 darrenr Exp";
+#endif
+
+#if !defined(__SVR4) && defined(__GNUC__)
+extern char *index __P((const char *, int));
+#endif
+
+extern char *optarg;
+extern int optind;
+extern frentry_t *frtop;
+
+
+void ipf_frsync __P((void));
+void zerostats __P((void));
+int main __P((int, char *[]));
+
+int opts = 0;
+int outputc = 0;
+int use_inet6 = 0;
+
+static void procfile __P((char *, char *)), flushfilter __P((char *));
+static void set_state __P((u_int)), showstats __P((friostat_t *));
+static void packetlogon __P((char *)), swapactive __P((void));
+static int opendevice __P((char *, int));
+static void closedevice __P((void));
+static char *ipfname = IPL_NAME;
+static void usage __P((void));
+static int showversion __P((void));
+static int get_flags __P((void));
+static void ipf_interceptadd __P((int, ioctlfunc_t, void *));
+
+static int fd = -1;
+static ioctlfunc_t iocfunctions[IPL_LOGSIZE] = { ioctl, ioctl, ioctl,
+ ioctl, ioctl, ioctl,
+ ioctl, ioctl };
+
+
+static void usage()
+{
+ fprintf(stderr, "usage: ipf [-6AdDEInoPrRsvVyzZ] %s %s %s\n",
+ "[-l block|pass|nomatch|state|nat]", "[-cc] [-F i|o|a|s|S|u]",
+ "[-f filename] [-T <tuneopts>]");
+ exit(1);
+}
+
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+ int c;
+
+ if (argc < 2)
+ usage();
+
+ while ((c = getopt(argc, argv, "6Ac:dDEf:F:Il:noPrRsT:vVyzZ")) != -1) {
+ switch (c)
+ {
+ case '?' :
+ usage();
+ break;
+#ifdef USE_INET6
+ case '6' :
+ use_inet6 = 1;
+ break;
+#endif
+ case 'A' :
+ opts &= ~OPT_INACTIVE;
+ break;
+ case 'c' :
+ if (strcmp(optarg, "c") == 0)
+ outputc = 1;
+ break;
+ case 'E' :
+ set_state((u_int)1);
+ break;
+ case 'D' :
+ set_state((u_int)0);
+ 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 = IPAUTH_NAME;
+ break;
+ case 'R' :
+ opts ^= OPT_NORESOLVE;
+ break;
+ case 'r' :
+ opts ^= OPT_REMOVE;
+ break;
+ case 's' :
+ swapactive();
+ break;
+ case 'T' :
+ if (opendevice(ipfname, 1) >= 0)
+ ipf_dotuning(fd, optarg, ioctl);
+ break;
+ case 'v' :
+ opts += OPT_VERBOSE;
+ break;
+ case 'V' :
+ if (showversion())
+ exit(1);
+ break;
+ case 'y' :
+ ipf_frsync();
+ break;
+ case 'z' :
+ opts ^= OPT_ZERORULEST;
+ break;
+ case 'Z' :
+ zerostats();
+ break;
+ }
+ }
+
+ if (optind < 2)
+ usage();
+
+ if (fd != -1)
+ (void) close(fd);
+
+ return(0);
+ /* NOTREACHED */
+}
+
+
+static int opendevice(ipfdev, check)
+char *ipfdev;
+int check;
+{
+ if (opts & OPT_DONOTHING)
+ return -2;
+
+ if (check && checkrev(ipfname) == -1) {
+ fprintf(stderr, "User/kernel version check failed\n");
+ return -2;
+ }
+
+ if (!ipfdev)
+ ipfdev = ipfname;
+
+ if (fd == -1)
+ if ((fd = open(ipfdev, O_RDWR)) == -1)
+ if ((fd = open(ipfdev, O_RDONLY)) == -1)
+ perror("open device");
+ return fd;
+}
+
+
+static void closedevice()
+{
+ close(fd);
+ fd = -1;
+}
+
+
+static int get_flags()
+{
+ int i;
+
+ if ((opendevice(ipfname, 1) != -2) &&
+ (ioctl(fd, SIOCGETFF, &i) == -1)) {
+ perror("SIOCGETFF");
+ return 0;
+ }
+ return i;
+}
+
+
+static void set_state(enable)
+u_int enable;
+{
+ if (opendevice(ipfname, 0) != -2)
+ if (ioctl(fd, SIOCFRENB, &enable) == -1) {
+ if (errno == EBUSY)
+ fprintf(stderr,
+ "IP FIlter: already initialized\n");
+ else
+ perror("SIOCFRENB");
+ }
+ return;
+}
+
+
+static void procfile(name, file)
+char *name, *file;
+{
+ (void) opendevice(ipfname, 1);
+
+ initparse();
+
+ ipf_parsefile(fd, ipf_interceptadd, iocfunctions, file);
+
+ if (outputc) {
+ printC(0);
+ printC(1);
+ emit(-1, -1, NULL, NULL);
+ }
+}
+
+
+static void ipf_interceptadd(fd, ioctlfunc, ptr)
+int fd;
+ioctlfunc_t ioctlfunc;
+void *ptr;
+{
+ if (outputc)
+ printc(ptr);
+
+ ipf_addrule(fd, ioctlfunc, ptr);
+}
+
+
+static void packetlogon(opt)
+char *opt;
+{
+ int flag, xfd, logopt, change = 0;
+
+ flag = get_flags();
+ 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 (strstr(opt, "pass")) {
+ flag |= FF_LOGPASS;
+ if (opts & OPT_VERBOSE)
+ printf("set log flag: pass\n");
+ change = 1;
+ }
+ if (strstr(opt, "nomatch")) {
+ flag |= FF_LOGNOMATCH;
+ if (opts & OPT_VERBOSE)
+ printf("set log flag: nomatch\n");
+ change = 1;
+ }
+ if (strstr(opt, "block") || index(opt, 'd')) {
+ flag |= FF_LOGBLOCK;
+ if (opts & OPT_VERBOSE)
+ printf("set log flag: block\n");
+ change = 1;
+ }
+ if (strstr(opt, "none")) {
+ if (opts & OPT_VERBOSE)
+ printf("disable all log flags\n");
+ change = 1;
+ }
+
+ if (change == 1) {
+ if (opendevice(ipfname, 1) != -2 &&
+ (ioctl(fd, SIOCSETFF, &flag) != 0))
+ perror("ioctl(SIOCSETFF)");
+ }
+
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
+ flag = get_flags();
+ printf("log flags are now %#x\n", flag);
+ }
+
+ if (strstr(opt, "state")) {
+ if (opts & OPT_VERBOSE)
+ printf("set state log flag\n");
+ xfd = open(IPSTATE_NAME, O_RDWR);
+ if (xfd >= 0) {
+ logopt = 0;
+ if (ioctl(xfd, SIOCGETLG, &logopt))
+ perror("ioctl(SIOCGETLG)");
+ else {
+ logopt = 1 - logopt;
+ if (ioctl(xfd, SIOCSETLG, &logopt))
+ perror("ioctl(SIOCSETLG)");
+ }
+ close(xfd);
+ }
+ }
+
+ if (strstr(opt, "nat")) {
+ if (opts & OPT_VERBOSE)
+ printf("set nat log flag\n");
+ xfd = open(IPNAT_NAME, O_RDWR);
+ if (xfd >= 0) {
+ logopt = 0;
+ if (ioctl(xfd, SIOCGETLG, &logopt))
+ perror("ioctl(SIOCGETLG)");
+ else {
+ logopt = 1 - logopt;
+ if (ioctl(xfd, SIOCSETLG, &logopt))
+ perror("ioctl(SIOCSETLG)");
+ }
+ close(xfd);
+ }
+ }
+}
+
+
+static void flushfilter(arg)
+char *arg;
+{
+ int fl = 0, rem;
+
+ if (!arg || !*arg)
+ return;
+ if (!strcmp(arg, "s") || !strcmp(arg, "S")) {
+ if (*arg == 'S')
+ fl = 0;
+ else
+ fl = 1;
+ rem = fl;
+
+ closedevice();
+ if (opendevice(IPSTATE_NAME, 1) == -2)
+ 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;
+ }
+
+#ifdef SIOCIPFFA
+ if (!strcmp(arg, "u")) {
+ closedevice();
+ /*
+ * Flush auth rules and packets
+ */
+ if (opendevice(IPL_AUTH, 1) == -1)
+ perror("open(IPL_AUTH)");
+ else {
+ if (ioctl(fd, SIOCIPFFA, &fl) == -1)
+ perror("ioctl(SIOCIPFFA)");
+ }
+ closedevice();
+ return;
+ }
+#endif
+
+ 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;
+ if (opts & OPT_INACTIVE)
+ fl |= FR_INACTIVE;
+ rem = fl;
+
+ if (opendevice(ipfname, 1) == -2)
+ 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) != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
+ perror("ioctl(SIOCSWAPA)");
+ else
+ printf("Set %d now inactive\n", in);
+}
+
+
+void ipf_frsync()
+{
+ int frsyn = 0;
+
+ if (opendevice(ipfname, 1) != -2 && ioctl(fd, SIOCFRSYN, &frsyn) == -1)
+ perror("SIOCFRSYN");
+ else
+ printf("filter sync'd\n");
+}
+
+
+void zerostats()
+{
+ friostat_t fio;
+ friostat_t *fiop = &fio;
+
+ if (opendevice(ipfname, 1) != -2) {
+ 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;
+{
+ printf("bad packets:\t\tin %lu\tout %lu\n",
+ fp->f_st[0].fr_bad, fp->f_st[1].fr_bad);
+ 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);
+}
+
+
+static int showversion()
+{
+ struct friostat fio;
+ ipfobj_t ipfo;
+ u_32_t flags;
+ char *s;
+ int vfd;
+
+ bzero((caddr_t)&ipfo, sizeof(ipfo));
+ ipfo.ipfo_rev = IPFILTER_VERSION;
+ ipfo.ipfo_size = sizeof(fio);
+ ipfo.ipfo_ptr = (void *)&fio;
+ ipfo.ipfo_type = IPFOBJ_IPFSTAT;
+
+ 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, &ipfo)) {
+ perror("ioctl(SIOCGETFS)");
+ close(vfd);
+ return 1;
+ }
+ close(vfd);
+ flags = get_flags();
+
+ printf("Kernel: %-*.*s\n", (int)sizeof(fio.f_version),
+ (int)sizeof(fio.f_version), fio.f_version);
+ printf("Running: %s\n", (fio.f_running > 0) ? "yes" : "no");
+ 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 (FR_ISPASS(fio.f_defpass))
+ s = "pass";
+ else if (FR_ISBLOCK(fio.f_defpass))
+ 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);
+ printf("Feature mask: %#x\n", fio.f_features);
+
+ return 0;
+}
OpenPOWER on IntegriCloud