summaryrefslogtreecommitdiff
path: root/sbin/ipf
diff options
context:
space:
mode:
authordm <dm@cvs.openbsd.org>1996-07-18 05:11:04 +0000
committerdm <dm@cvs.openbsd.org>1996-07-18 05:11:04 +0000
commit855450577164de85ddee7341a7ed13c7073882ca (patch)
tree7c401e870b4cbd2624bb531bd9d11a1adcf08383 /sbin/ipf
parentd863770dbf1c7b1d87285f2c65bde3fe93cd1b9d (diff)
ipfilter 3.1.0
Diffstat (limited to 'sbin/ipf')
-rw-r--r--sbin/ipf/ipf.497
-rw-r--r--sbin/ipf/ipf.543
-rw-r--r--sbin/ipf/ipf.c131
-rw-r--r--sbin/ipf/ipf.h38
-rw-r--r--sbin/ipf/opt.c3
-rw-r--r--sbin/ipf/parse.c147
6 files changed, 319 insertions, 140 deletions
diff --git a/sbin/ipf/ipf.4 b/sbin/ipf/ipf.4
index a355c08185c..5cbfbd001c5 100644
--- a/sbin/ipf/ipf.4
+++ b/sbin/ipf/ipf.4
@@ -1,5 +1,3 @@
-.\" $OpenBSD: ipf.4,v 1.3 1996/06/23 14:30:53 deraadt Exp $
-.\"
.TH IPF 4
.SH NAME
ipf - packet filtering kernel interface
@@ -41,51 +39,70 @@ and insertion of a rule into the list (SIOCIN*). The rule place into
which it is inserted is stored in the "fr_hits" field, below.
.LP
.nf
-
typedef struct frentry {
struct frentry *fr_next;
struct ifnet *fr_ifa;
- u_int fr_hits;
-
+ u_long fr_hits;
+ u_long fr_bytes; /* this is only incremented when a packet */
+ /* stops matching on this rule */
/*
* Fields after this may not change whilst in the kernel.
*/
- struct ip fr_ip;
- struct ip fr_mip;
+ struct fr_ip fr_ip;
+ struct fr_ip fr_mip;
+
+ u_char fr_tcpfm; /* tcp flags mask */
+ u_char fr_tcpf; /* tcp flags */
u_short fr_icmpm; /* data for ICMP packets (mask) */
u_short fr_icmp;
- char fr_tcpfm; /* tcp flags mask */
- char fr_tcpf; /* tcp flags */
-
u_char fr_scmp; /* data for port comparisons */
u_char fr_dcmp;
u_short fr_dport;
u_short fr_sport;
u_short fr_stop; /* top port for <> and >< */
u_short fr_dtop; /* top port for <> and >< */
- u_short fr_flags; /* per-rule flags && options */
+ u_long fr_flags; /* per-rule flags && options (see below) */
+ int (*fr_func)(); /* call this function */
+ char fr_icode; /* return ICMP code */
char fr_ifname[IFNAMSIZ];
+ struct frdest fr_tif; /* "to" interface */
+ struct frdest fr_dif; /* duplicate packet interfaces */
} frentry_t;
.fi
.PP
+When adding a new rule, all unused fields (in the filter rule) should be
+initialised to be zero. To insert a rule, at a particular position in the
+filter list, the number of the rule which it is to be inserted before must
+be put in the "fr_hits" field (the first rule is number 0).
+.LP
+.PP
Flags which are recognised in fr_pass:
.nf
- FR_BLOCK 0x0001 /* do not allow packet to pass */
- FR_PASS 0x0002 /* allow packet to pass */
- FR_OUTQUE 0x0004 /* outgoing packets */
- FR_QUICK 0x0008 /* quick-match and return */
- FR_LOGP 0x0010 /* Log-pass */
- FR_INQUE 0x0020 /* ingoing packets */
- FR_LOGB 0x0040 /* Log-fail */
- FR_LOG 0x0080 /* Log */
- FR_RETRST 0x0100 /* return a TCP RST packet if blocked */
- FR_OPTFRAG 0x0200 /* filter packets which are fragments */
- FR_OPTSHORT 0x0400 /* filter short TCP packets */
- FR_RETICMP 0x0800 /* return an ICMP packet if blocked */
- FR_TCPUDP 0x1000 /* TCP/UCP implied comparison involved */
+ FR_BLOCK 0x00001 /* do not allow packet to pass */
+ FR_PASS 0x00002 /* allow packet to pass */
+ FR_OUTQUE 0x00004 /* outgoing packets */
+ FR_INQUE 0x00008 /* ingoing packets */
+ FR_LOG 0x00010 /* Log */
+ FR_LOGP 0x00011 /* Log-pass */
+ FR_LOGB 0x00012 /* Log-fail */
+ FR_LOGBODY 0x00020 /* log the body of packets too */
+ FR_LOGFIRST 0x00040 /* log only the first packet to match */
+ FR_RETRST 0x00080 /* return a TCP RST packet if blocked */
+ FR_RETICMP 0x00100 /* return an ICMP packet if blocked */
+ FR_NOMATCH 0x00200 /* no match occured */
+ FR_ACCOUNT 0x00400 /* count packet bytes */
+ FR_KEEPFRAG 0x00800
+ FR_KEEPSTATE 0x01000 /* keep packet flow state information */
+ FR_INACTIVE 0x02000
+ FR_QUICK 0x04000 /* quick-match and return */
+ FR_FASTROUTE 0x08000
+ FR_CALLFUNC 0x10000
+ FR_CALLNOW 0x20000
+ FR_DUP 0x40000 /* duplicate the packet (not Solaris2)
+
.fi
.PP
Values for fr_scomp and fr_dcomp (source and destination port value
@@ -123,7 +140,7 @@ those provided (clearing/setting all in one).
.fi
.IP SIOCGETFF 16
Takes a pointer to an unsigned integer as the parameter. A copy of the
-fags currently in used is copied to user space.
+flags currently in used is copied to user space.
.LP
\fBFilter statistics\fP
Statistics on the various operations performed by this package on packets
@@ -140,16 +157,28 @@ struct friostat {
};
struct filterstats {
- u_long fr_pass; /* packets allowed */
- u_long fr_block; /* packets denied */
- u_long fr_ppkl; /* packets allowed and logged */
- u_long fr_bpkl; /* packets denied and logged */
- u_long fr_pkl; /* packets logged */
- u_long fr_skip; /* packets to be logged but buffer full */
+ u_long fr_pass; /* packets allowed */
+ u_long fr_block; /* packets denied */
+ u_long fr_nom; /* packets which don't match any rule */
+ u_long fr_ppkl; /* packets allowed and logged */
+ u_long fr_bpkl; /* packets denied and logged */
+ u_long fr_npkl; /* packets unmatched and logged */
+ u_long fr_pkl; /* packets logged */
+ u_long fr_skip; /* packets to be logged but buffer full */
+ u_long fr_ret; /* packets for which a return is sent */
+ u_long fr_acct; /* packets for which counting was performed */
+ u_long fr_bnfr; /* bad attempts to allocate fragment state */
+ u_long fr_nfr; /* new fragment state kept */
+ u_long fr_cfr; /* add new fragment state but complete pkt */
+ u_long fr_bads; /* bad attempts to allocate packet state */
+ u_long fr_ads; /* new packet state kept */
+ u_long fr_chit; /* cached hit */
+#if SOLARIS
+ u_long fr_bad; /* bad IP packets to the filter */
+ u_long fr_notip; /* packets passed through no on ip queue */
+ u_long fr_drop; /* packets dropped - no info for them! */
+#endif
};
.fi
-.SH BUGS
-It would be nice if there were more flexibility when adding and deleting
-filter rules.
.SH SEE ALSO
ipfstat(1), ipf(1), ipf(5)
diff --git a/sbin/ipf/ipf.5 b/sbin/ipf/ipf.5
index 00b1fdeff38..fc8cbd84e78 100644
--- a/sbin/ipf/ipf.5
+++ b/sbin/ipf/ipf.5
@@ -1,5 +1,3 @@
-.\" $OpenBSD: ipf.5,v 1.3 1996/06/23 14:30:53 deraadt Exp $
-.\"
.LP
.TH IPF 5
.SH NAME
@@ -23,30 +21,33 @@ described using the following grammar in BNF:
filter-rule = [ insert ] action in-out [ options ] [ tos ] [ ttl ]
[ proto ] [ ip ] .
-insert = "@" decnumber
-action = block | "pass" | log | "count" .
+insert = "@" decnumber .
+action = block | "pass" | log | "count" | call .
in-out = "in" | "out" .
-options = [ log ] [ "quick" ] [ "on" interface-name] .
+options = [ log ] [ "quick" ] [ "on" interface-name [ dup ] [ froute ] ] .
tos = "tos" decnumber | "tos" hexnumber .
ttl = "ttl" decnumber .
proto = "proto" protocol .
ip = srcdst [ flags ] [ with withopt ] [ icmp ] [ keep ] .
-block = "block" [ "return-icmp" [ return-code ] | "return-rst" ].
-log = "log" [ "body" ] [ "first" ] .
+block = "block" [ "return-icmp"[return-code] | "return-rst" ] .
+log = "log" [ "body" ] [ "first" ] .
+call = "call" [ "now" ] function-name .
+dup = "dup-to" interface-name[":"ipaddr] .
+froute = "fastroute" | "to" interface-name .
protocol = "tcp/udp" | "udp" | "tcp" | "icmp" | decnumber .
srcdst = "all" | fromto .
fromto = "from" object "to" object .
object = addr [ port-comp | port-range ] .
-addr = "any" | nummask | host-name [ "mask" ipaddr | hexnumber ] .
+addr = "any" | nummask | host-name [ "mask" ipaddr | "mask" hexnumber ] .
port-comp = "port" compare port-num .
port-range = "port" port-num range port-num .
flags = "flags" flag { flag } [ "/" flag { flag } ] .
-with = "with" | "and" .
-icmp = "icmp-type" icmp-type .
-return-code = "(" icmp-code ")" .
-keep = "keep" "state" | "keep" "frags" .
+with = "with" | "and" .
+icmp = "icmp-type" icmp-type [ "code" decnumber ] .
+return-code = "("icmp-code")" .
+keep = "keep" "state" | "keep" "frags" .
nummask = host-name [ "/" decnumber ] .
host-name = ipaddr | hostname | "any" .
@@ -55,24 +56,28 @@ host-num = digit [ digit [ digit ] ] .
port-num = service-name | decnumber .
withopt = [ "not" | "no" ] opttype [ withopt ] .
-opttype = "ipopts" | "short" | "frag" | "opt" ipopts .
-ipopts = "nop" | "rr" | "ts" | "security" | "sec-class" [ "=" seclvl ] |
- "lsrr" | "satid" | "rsrr" .
+opttype = "ipopts" | "short" | "frag" | "opt" ipopts .
+optname = ipopts [ "," optname ] .
+ipopts = optlist | "sec-class" [ secname ] .
+secname = seclvl [ "," secname ] .
seclvl = "unclass" | "confid" | "reserv-1" | "reserv-2" | "reserv-3" |
- "reserv-4" | "secret" | "topsecret" .
+ "reserv-4" | "secret" | "topsecret" .
icmp-type = "unreach" | "echo" | "echorep" | "squench" | "redir" |
"timex" | "paramprob" | "timest" | "timestrep" | "inforeq" |
"inforep" | "maskreq" | "maskrep" | decnumber .
icmp-code = decumber | "net-unr" | "host-unr" | "proto-unr" | "port-unr" |
- "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
- "net-prohib" | "host-prohib" | "net-tos" | "host-tos" .
+ "needfrag" | "srcfail" | "net-unk" | "host-unk" | "isolate" |
+ "net-prohib" | "host-prohib" | "net-tos" | "host-tos" .
+optlist = "nop" | "rr" | "zsu" | "mtup" | "mtur" | "encode" | "ts" | "tr" |
+ "sec" | "lsrr" | "e-sec" | "cipso" | "satid" | "ssrr" | "addext" |
+ "visa" | "imitd" | "eip" | "finn" .
hexnumber = "0" "x" hexstring .
hexstring = hexdigit [ hexstring ] .
decnumber = digit [ decnumber ] .
compare = "=" | "!=" | "<" | ">" | "<=" | ">=" | "eq" | "ne" | "lt" | "gt" |
- "le" | "ge" .
+ "le" | "ge" .
range = "<>" | "><" .
hexdigit = digit | "a" | "b" | "c" | "d" | "e" | "f" .
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" .
diff --git a/sbin/ipf/ipf.c b/sbin/ipf/ipf.c
index a688c99f0bd..af7f100911b 100644
--- a/sbin/ipf/ipf.c
+++ b/sbin/ipf/ipf.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: ipf.c,v 1.4 1996/06/23 14:30:54 deraadt Exp $ */
-
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@@ -11,6 +9,7 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
+#include <errno.h>
#if !defined(__SVR4) && !defined(__GNUC__)
#include <strings.h>
#endif
@@ -36,7 +35,8 @@ extern char *index();
#include "ipf.h"
#ifndef lint
-static char sccsid[] = "@(#)ipf.c 1.22 2/3/96 (C) 1993-1995 Darren Reed";
+static char sccsid[] = "@(#)ipf.c 1.23 6/5/96 (C) 1993-1995 Darren Reed";
+static char rcsid[] = "$Id: ipf.c,v 1.5 1996/07/18 05:11:01 dm Exp $";
#endif
#if SOLARIS
@@ -49,8 +49,9 @@ extern char *optarg;
int opts = 0;
static int fd = -1;
+
static void procfile(), flushfilter(), set_state();
-static void packetlogon(), swapactive();
+static void packetlogon(), swapactive(), showstats();
int main(argc,argv)
int argc;
@@ -58,10 +59,7 @@ char *argv[];
{
char c;
- if ((fd = open(IPL_NAME, O_RDONLY)) == -1)
- perror("open device");
-
- while ((c = getopt(argc, argv, "AsInovdryf:F:l:EDZ")) != -1)
+ while ((c = getopt(argc, argv, "AsInopvdryf:F:l:EDzZ")) != -1) {
switch (c)
{
case 'E' :
@@ -77,7 +75,7 @@ char *argv[];
opts |= OPT_DEBUG;
break;
case 'f' :
- procfile(optarg);
+ procfile(argv[0], optarg);
break;
case 'F' :
flushfilter(optarg);
@@ -94,6 +92,9 @@ char *argv[];
case 'o' :
opts |= OPT_OUTQUE;
break;
+ case 'p' :
+ opts |= OPT_PRINTFR;
+ break;
case 'r' :
opts |= OPT_REMOVE;
break;
@@ -108,32 +109,55 @@ char *argv[];
frsync();
break;
#endif
+ case 'z' :
+ opts |= OPT_ZERORULEST;
+ break;
case 'Z' :
zerostats();
break;
}
+ }
if (fd != -1)
(void) close(fd);
- return 0;
+
+ exit(0);
+ /* NOTREACHED */
+}
+
+
+static int opendevice()
+{
+ if (opts & OPT_DONOTHING)
+ return -2;
+
+ if (!(opts & OPT_DONOTHING) && fd == -1)
+ if ((fd = open(IPL_NAME, O_RDWR)) == -1)
+ if ((fd = open(IPL_NAME, O_RDONLY)) == -1)
+ perror("open device");
+ return fd;
}
+
static void set_state(enable)
u_int enable;
{
- if (ioctl(fd, SIOCFRENB, &enable) == -1)
- perror("SIOCFRENB");
+ if (opendevice() != -2)
+ if (ioctl(fd, SIOCFRENB, &enable) == -1)
+ perror("SIOCFRENB");
return;
}
-static void procfile(file)
-char *file;
+static void procfile(name, file)
+char *name, *file;
{
FILE *fp;
char line[513], *s;
struct frentry *fr;
u_int add = SIOCADAFR, del = SIOCRMAFR;
+ (void) opendevice();
+
if (opts & OPT_INACTIVE) {
add = SIOCADIFR;
del = SIOCRMIFR;
@@ -146,8 +170,9 @@ char *file;
if (!strcmp(file, "-"))
fp = stdin;
else if (!(fp = fopen(file, "r"))) {
- perror("fopen");
- exit(1);;
+ fprintf(stderr, "%s: fopen(%s) failed: %s", name, file,
+ STRERROR(errno));
+ exit(1);
}
while (fgets(line, sizeof(line)-1, fp)) {
@@ -174,7 +199,9 @@ char *file;
(void)fflush(stdout);
if (fr) {
- if (opts & OPT_INACTIVE)
+ if (opts & OPT_ZERORULEST)
+ add = SIOCZRLST;
+ else if (opts & OPT_INACTIVE)
add = fr->fr_hits ? SIOCINIFR : SIOCADIFR;
else
add = fr->fr_hits ? SIOCINAFR : SIOCADAFR;
@@ -187,8 +214,16 @@ char *file;
if (opts & OPT_DEBUG)
binprint(fr);
-
- if ((opts & OPT_REMOVE) && !(opts & OPT_DONOTHING)) {
+
+ if ((opts & OPT_ZERORULEST) &&
+ !(opts & OPT_DONOTHING)) {
+ if (ioctl(fd, add, fr) == -1)
+ perror("ioctl(SIOCZRLST)");
+ else
+ printf("hits %d bytes %d\n",
+ fr->fr_hits, fr->fr_bytes);
+ } else if ((opts & OPT_REMOVE) &&
+ !(opts & OPT_DONOTHING)) {
if (ioctl(fd, del, fr) == -1)
perror("ioctl(SIOCDELFR)");
} else if (!(opts & OPT_DONOTHING)) {
@@ -206,7 +241,7 @@ char *opt;
{
int err, flag;
- if (opts & OPT_VERBOSE) {
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
if ((err = ioctl(fd, SIOCGETFF, &flag)))
perror("ioctl(SIOCGETFF)");
@@ -231,11 +266,10 @@ char *opt;
printf("set log flag: block\n");
}
- if (!(opts & OPT_DONOTHING) &&
- (err = ioctl(fd, SIOCSETFF, &flag)))
+ if (opendevice() != -2 && (err = ioctl(fd, SIOCSETFF, &flag)))
perror("ioctl(SIOCSETFF)");
- if (opts & OPT_VERBOSE) {
+ if ((opts & (OPT_DONOTHING|OPT_VERBOSE)) == OPT_VERBOSE) {
if ((err = ioctl(fd, SIOCGETFF, &flag)))
perror("ioctl(SIOCGETFF)");
@@ -260,9 +294,9 @@ char *arg;
fl |= (opts & FR_INACTIVE);
rem = fl;
- if (!(opts & OPT_DONOTHING) && ioctl(fd, SIOCIPFFL, &fl) == -1)
+ if (opendevice() == -2 || ioctl(fd, SIOCIPFFL, &fl) == -1)
perror("ioctl(SIOCIPFFL)");
- if (opts & OPT_VERBOSE){
+ 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);
@@ -275,7 +309,7 @@ static void swapactive()
{
int in = 2;
- if (ioctl(fd, SIOCSWAPA, &in) == -1)
+ if (opendevice() != -2 && ioctl(fd, SIOCSWAPA, &in) == -1)
perror("ioctl(SIOCSWAPA)");
else
printf("Set %d now inactive\n", in);
@@ -285,7 +319,7 @@ static void swapactive()
#if defined(sun) && (defined(__SVR4) || defined(__svr4__))
void frsync()
{
- if (ioctl(fd, SIOCFRSYN, 0) == -1)
+ if (opendevice() != -2 && ioctl(fd, SIOCFRSYN, 0) == -1)
perror("SIOCFRSYN");
else
printf("filter sync'd\n");
@@ -295,11 +329,46 @@ void frsync()
void zerostats()
{
- struct friostat fio;
+ friostat_t fio;
- if (ioctl(fd, SIOCFRZST, &fio) == -1) {
- perror("ioctl(SIOCFRZST)");
- exit(-1);
+ if (opendevice() != -2) {
+ if (ioctl(fd, SIOCFRZST, &fio) == -1) {
+ perror("ioctl(SIOCFRZST)");
+ exit(-1);
+ }
+ showstats(&fio);
}
}
+
+
+/*
+ * 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);
+}
diff --git a/sbin/ipf/ipf.h b/sbin/ipf/ipf.h
index c17f64f3aa9..86a60fa7adc 100644
--- a/sbin/ipf/ipf.h
+++ b/sbin/ipf/ipf.h
@@ -1,5 +1,3 @@
-/* $OpenBSD: ipf.h,v 1.4 1996/06/23 14:30:54 deraadt Exp $ */
-
/*
* (C)opyright 1993-1996 by Darren Reed.
*
@@ -7,24 +5,27 @@
* provided that this notice is preserved and due credit is given
* to the original author and the contributors.
*
- * @(#)ipf.h 1.11 4/10/96
+ * @(#)ipf.h 1.12 6/5/96
+ * $Id: ipf.h,v 1.5 1996/07/18 05:11:02 dm Exp $
*/
-#define OPT_REMOVE 0x0001
-#define OPT_DEBUG 0x0002
+#define OPT_REMOVE 0x00001
+#define OPT_DEBUG 0x00002
#define OPT_OUTQUE FR_OUTQUE /* 0x0004 */
#define OPT_INQUE FR_INQUE /* 0x0008 */
#define OPT_LOG FR_LOG /* 0x0010 */
-#define OPT_SHOWLIST 0x0020
-#define OPT_VERBOSE 0x0040
-#define OPT_DONOTHING 0x0080
-#define OPT_HITS 0x100
-#define OPT_BRIEF 0x200
-#define OPT_ACCNT FR_ACCOUNT /* 0x0800 */
-#define OPT_FRSTATES FR_KEEPFRAG /* 0x1000 */
-#define OPT_IPSTATES FR_KEEPSTATE /* 0x2000 */
-#define OPT_INACTIVE FR_INACTIVE /* 0x4000 */
-#define OPT_SHOWLINENO 0x8000
+#define OPT_SHOWLIST 0x00020
+#define OPT_VERBOSE 0x00040
+#define OPT_DONOTHING 0x00080
+#define OPT_HITS 0x00100
+#define OPT_BRIEF 0x00200
+#define OPT_ACCNT FR_ACCOUNT /* 0x0400 */
+#define OPT_FRSTATES FR_KEEPFRAG /* 0x0800 */
+#define OPT_IPSTATES FR_KEEPSTATE /* 0x1000 */
+#define OPT_INACTIVE FR_INACTIVE /* 0x2000 */
+#define OPT_SHOWLINENO 0x04000
+#define OPT_PRINTFR 0x08000
+#define OPT_ZERORULEST 0x10000
extern struct frentry *parse();
@@ -47,3 +48,10 @@ struct ipopt_names {
extern u_long hostnum(), optname();
extern void printpacket();
+#ifdef sun
+#define STRERROR(x) sys_errlist[x]
+extern char *sys_errlist[];
+#else
+#define STRERROR(x) strerror(x)
+#endif
+
diff --git a/sbin/ipf/opt.c b/sbin/ipf/opt.c
index 5f130386f99..6efedf121c3 100644
--- a/sbin/ipf/opt.c
+++ b/sbin/ipf/opt.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: opt.c,v 1.4 1996/06/23 14:30:55 deraadt Exp $ */
-
/*
* (C)opyright 1993,1994,1995 by Darren Reed.
*
@@ -24,6 +22,7 @@
#ifndef lint
static char sccsid[] = "@(#)opt.c 1.8 4/10/96 (C) 1993-1995 Darren Reed";
+static char rcsid[] = "$Id: opt.c,v 1.5 1996/07/18 05:11:02 dm Exp $";
#endif
extern int opts;
diff --git a/sbin/ipf/parse.c b/sbin/ipf/parse.c
index 059add08b0d..1be828c51da 100644
--- a/sbin/ipf/parse.c
+++ b/sbin/ipf/parse.c
@@ -1,5 +1,3 @@
-/* $OpenBSD: parse.c,v 1.5 1996/06/26 16:48:44 dm Exp $ */
-
/*
* (C)opyright 1993-1996 by Darren Reed.
*
@@ -34,7 +32,8 @@
#include <ctype.h>
#ifndef lint
-static char sccsid[] ="@(#)parse.c 1.41 4/10/96 (C) 1993-1996 Darren Reed";
+static char sccsid[] ="@(#)parse.c 1.44 6/5/96 (C) 1993-1996 Darren Reed";
+static char rcsid[] = "$Id: parse.c,v 1.6 1996/07/18 05:11:03 dm Exp $";
#endif
extern struct ipopt_names ionames[], secclass[];
@@ -123,9 +122,9 @@ char *line;
}
} else if (**cpp == 'c')
fil.fr_flags = FR_ACCOUNT;
- else if (**cpp == 'p')
+ else if (**cpp == 'p') {
fil.fr_flags = FR_PASS;
- else if (**cpp == 'l') {
+ } else if (**cpp == 'l') {
fil.fr_flags = FR_LOG;
if (!strcasecmp(*(cpp+1), "body")) {
fil.fr_flags |= FR_LOGBODY;
@@ -189,8 +188,35 @@ char *line;
}
return &fil;
}
- }
+ if (*cpp) {
+#if SOLARIS
+ if (!strcasecmp(*cpp, "dup-to") ||
+ !strcasecmp(*cpp, "to") ||
+ !strcasecmp(*cpp, "fastroute")) {
+ (void) fprintf(stderr,
+ "%s not supported under SunOS5\n",
+ *cpp);
+ return NULL;
+ }
+#endif
+ if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) {
+ cpp++;
+ if (to_interface(&fil.fr_dif, *cpp))
+ return NULL;
+ cpp++;
+ }
+ if (!strcasecmp(*cpp, "to") && *(cpp + 1)) {
+ cpp++;
+ if (to_interface(&fil.fr_tif, *cpp))
+ return NULL;
+ cpp++;
+ } else if (!strcasecmp(*cpp, "fastroute")) {
+ fil.fr_flags |= FR_FASTROUTE;
+ cpp++;
+ }
+ }
+ }
if (!strcasecmp(*cpp, "tos")) {
if (!*++cpp) {
(void)fprintf(stderr, "tos missing value\n");
@@ -388,6 +414,40 @@ char *line;
return &fil;
}
+
+int to_interface(fdp, to)
+frdest_t *fdp;
+char *to;
+{
+ int r = 0;
+ char *s;
+
+ s = index(to, ':');
+ fdp->fd_ifp = NULL;
+ if (s) {
+ *s++ = '\0';
+ fdp->fd_ip.s_addr = hostnum(s, &r);
+ if (r == -1)
+ return -1;
+ }
+ (void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1);
+ fdp->fd_ifname[sizeof(fdp->fd_ifname) - 1] = '\0';
+ return 0;
+}
+
+
+void print_toif(tag, fdp)
+char *tag;
+frdest_t *fdp;
+{
+ (void)printf("%s %s%s", tag, fdp->fd_ifname,
+ (fdp->fd_ifp || (int)fdp->fd_ifp == -1) ? "" : "(!)");
+ if (fdp->fd_ip.s_addr)
+ (void)printf(":%s", inet_ntoa(fdp->fd_ip));
+ putchar(' ');
+}
+
+
/*
* returns false if neither "hostmask/num" or "hostmask mask addr" are
* found in the line segments
@@ -753,7 +813,7 @@ u_long optmsk, optbits;
char *s;
int secflag = 0;
- s = "opt ";
+ s = " opt ";
for (io = ionames; io->on_name; io++)
if ((io->on_bit & optmsk) &&
((io->on_bit & optmsk) == (io->on_bit & optbits))) {
@@ -773,18 +833,16 @@ u_long optmsk, optbits;
s = " ";
for (so = secclass; so->on_name; so++)
if ((secmsk & so->on_bit) &&
- ((io->on_bit & secmsk) == (io->on_bit & secbits))) {
+ ((so->on_bit & secmsk) == (so->on_bit & secbits))) {
printf("%s%s", s, so->on_name);
s = ",";
}
}
- if (strcmp(s, "opt "))
- putchar(' ');
if ((optmsk && (optmsk != optbits)) ||
(secmsk && (secmsk != secbits))) {
s = " ";
- printf("not opt");
+ printf(" not opt");
if (optmsk != optbits) {
for (io = ionames; io->on_name; io++)
if ((io->on_bit & optmsk) &&
@@ -909,7 +967,7 @@ char ***cp;
struct frentry *fp;
{
if (fp->fr_proto != IPPROTO_TCP && fp->fr_proto != IPPROTO_UDP &&
- fp->fr_proto != IPPROTO_ICMP) {
+ fp->fr_proto != IPPROTO_ICMP && !(fp->fr_ip.fi_fl & FI_TCPUDP)) {
(void)fprintf(stderr, "Can only use keep with UDP/ICMP/TCP\n");
return -1;
}
@@ -998,18 +1056,13 @@ struct frentry *fp;
static char *pcmp1[] = { "*", "=", "!=", "<", ">", "<=", ">=",
"<>", "><"};
struct protoent *p;
+ frdest_t *fdp;
int ones = 0, pr;
char *s;
u_char *t;
- if (fp->fr_flags & FR_PASS)
+ if (fp->fr_flags & FR_PASS) {
(void)printf("pass");
- else if (fp->fr_flags & FR_LOG) {
- (void)printf("log");
- if (fp->fr_flags & FR_LOGBODY)
- (void)printf(" body");
- if (fp->fr_flags & FR_LOGFIRST)
- (void)printf(" first");
} else if (fp->fr_flags & FR_BLOCK) {
(void)printf("block");
if (fp->fr_flags & FR_RETICMP) {
@@ -1023,6 +1076,12 @@ struct frentry *fp;
}
if (fp->fr_flags & FR_RETRST)
(void)printf(" return-rst");
+ } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
+ (void)printf("log");
+ if (fp->fr_flags & FR_LOGBODY)
+ (void)printf(" body");
+ if (fp->fr_flags & FR_LOGFIRST)
+ (void)printf(" first");
} else if (fp->fr_flags & FR_ACCOUNT)
(void)printf("count");
@@ -1042,9 +1101,17 @@ struct frentry *fp;
if (fp->fr_flags & FR_QUICK)
(void)printf("quick ");
- if (*fp->fr_ifname)
+ if (*fp->fr_ifname) {
(void)printf("on %s%s ", fp->fr_ifname,
(fp->fr_ifa || (int)fp->fr_ifa == -1) ? "" : "(!)");
+ if (*fp->fr_dif.fd_ifname)
+ print_toif("dup-to", &fp->fr_dif);
+ if (*fp->fr_tif.fd_ifname)
+ print_toif("to", &fp->fr_tif);
+ if (fp->fr_flags & FR_FASTROUTE)
+ (void)printf("fastroute ");
+
+ }
if (fp->fr_mip.fi_tos)
(void)printf("tos %#x ", fp->fr_tos);
if (fp->fr_mip.fi_ttl)
@@ -1076,27 +1143,27 @@ struct frentry *fp;
(void)printf("port %s %s ", pcmp1[fp->fr_scmp],
portname(pr, fp->fr_sport));
if (!fp->fr_dst.s_addr & !fp->fr_dmsk.s_addr)
- (void)printf("to any ");
+ (void)printf("to any");
else {
(void)printf("to %s", inet_ntoa(fp->fr_dst));
if ((ones = countbits(fp->fr_dmsk.s_addr)) == -1)
- (void)printf("/%s ", inet_ntoa(fp->fr_dmsk));
+ (void)printf("/%s", inet_ntoa(fp->fr_dmsk));
else
- (void)printf("/%d ", ones);
+ (void)printf("/%d", ones);
}
if (fp->fr_dcmp) {
if (fp->fr_dcmp == FR_INRANGE || fp->fr_dcmp == FR_OUTRANGE)
- (void)printf("port %d %s %d ", fp->fr_dport,
+ (void)printf(" port %d %s %d", fp->fr_dport,
pcmp1[fp->fr_dcmp], fp->fr_dtop);
else
- (void)printf("port %s %s ", pcmp1[fp->fr_dcmp],
+ (void)printf(" port %s %s", pcmp1[fp->fr_dcmp],
portname(pr, fp->fr_dport));
}
if ((fp->fr_ip.fi_fl & ~FI_TCPUDP) ||
(fp->fr_mip.fi_fl & ~FI_TCPUDP) ||
fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk ||
fp->fr_ip.fi_secmsk || fp->fr_mip.fi_secmsk) {
- (void)printf("with ");
+ (void)printf(" with");
if (fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk ||
fp->fr_ip.fi_secmsk || fp->fr_mip.fi_secmsk)
optprint(fp->fr_mip.fi_secmsk,
@@ -1105,18 +1172,18 @@ struct frentry *fp;
fp->fr_ip.fi_optmsk);
else if (fp->fr_mip.fi_fl & FI_OPTIONS) {
if (!(fp->fr_ip.fi_fl & FI_OPTIONS))
- (void)printf("not ");
- (void)printf("ipopt ");
+ (void)printf(" not");
+ (void)printf(" ipopt");
}
if (fp->fr_mip.fi_fl & FI_SHORT) {
if (!(fp->fr_ip.fi_fl & FI_SHORT))
- (void)printf("not ");
- (void)printf("short ");
+ (void)printf(" not");
+ (void)printf(" short");
}
if (fp->fr_mip.fi_fl & FI_FRAG) {
if (!(fp->fr_ip.fi_fl & FI_FRAG))
- (void)printf("not ");
- (void)printf("frag ");
+ (void)printf(" not");
+ (void)printf(" frag");
}
}
if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm) {
@@ -1127,14 +1194,14 @@ struct frentry *fp;
type /= 256;
if (type < (sizeof(icmptypes) / sizeof(char *)) &&
icmptypes[type])
- (void)printf("icmp-type %s ", icmptypes[type]);
+ (void)printf(" icmp-type %s", icmptypes[type]);
else
- (void)printf("icmp-type %d ", type);
+ (void)printf(" icmp-type %d", type);
if (code)
- (void)printf("code %d ", code);
+ (void)printf(" code %d", code);
}
if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) {
- (void)printf("flags ");
+ (void)printf(" flags ");
for (s = flagset, t = flags; *s; s++, t++)
if (fp->fr_tcpf & *t)
(void)putchar(*s);
@@ -1145,9 +1212,11 @@ struct frentry *fp;
(void)putchar(*s);
}
}
- if (fp->fr_flags & (FR_KEEPFRAG|FR_KEEPSTATE))
- printf(" keep %s ",
- (fp->fr_flags & FR_KEEPFRAG) ? "frags" : "state");
+
+ if (fp->fr_flags & FR_KEEPSTATE)
+ printf(" keep state");
+ if (fp->fr_flags & FR_KEEPFRAG)
+ printf(" keep frags");
(void)putchar('\n');
}