diff options
author | dm <dm@cvs.openbsd.org> | 1996-07-18 05:11:04 +0000 |
---|---|---|
committer | dm <dm@cvs.openbsd.org> | 1996-07-18 05:11:04 +0000 |
commit | 855450577164de85ddee7341a7ed13c7073882ca (patch) | |
tree | 7c401e870b4cbd2624bb531bd9d11a1adcf08383 /sbin/ipf | |
parent | d863770dbf1c7b1d87285f2c65bde3fe93cd1b9d (diff) |
ipfilter 3.1.0
Diffstat (limited to 'sbin/ipf')
-rw-r--r-- | sbin/ipf/ipf.4 | 97 | ||||
-rw-r--r-- | sbin/ipf/ipf.5 | 43 | ||||
-rw-r--r-- | sbin/ipf/ipf.c | 131 | ||||
-rw-r--r-- | sbin/ipf/ipf.h | 38 | ||||
-rw-r--r-- | sbin/ipf/opt.c | 3 | ||||
-rw-r--r-- | sbin/ipf/parse.c | 147 |
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'); } |